twd-m4sc0 2.0.0__py3-none-any.whl → 2.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
twd/crud.py CHANGED
@@ -2,9 +2,12 @@ import os
2
2
  import json
3
3
  import hashlib
4
4
  import time
5
- from .logger import log, error
5
+ import logging
6
6
  from collections import OrderedDict
7
7
 
8
+ log = logging.getLogger("log")
9
+ error_log = logging.getLogger("error")
10
+
8
11
 
9
12
  def create_alias_id():
10
13
  data = str(time.time()) + str(os.urandom(16))
@@ -21,8 +24,9 @@ def ensure_data_file_exists(config):
21
24
  try:
22
25
  with open(data_file, "w") as f:
23
26
  json.dump({}, f)
27
+ log.info(f"Created data file at {data_file}")
24
28
  except OSError as e:
25
- error(f"Error creating data file: {e}", config)
29
+ error_log.error(f"Error creating data file: {e}")
26
30
 
27
31
 
28
32
  def load_data(config):
@@ -32,12 +36,13 @@ def load_data(config):
32
36
  try:
33
37
  with open(data_file, "r") as f:
34
38
  data = json.load(f)
39
+ log.info(f"Loaded data from {data_file}")
35
40
  return data
36
41
  except json.JSONDecodeError as e:
37
- error(f"Error reading data file: {e}", config)
42
+ error_log.error(f"Error reading data file: {e}")
38
43
  return {}
39
44
  except OSError as e:
40
- error(f"Error reading data file: {e}", config)
45
+ error_log.error(f"Error reading data file: {e}")
41
46
  return {}
42
47
 
43
48
 
@@ -49,8 +54,9 @@ def save_data(config, data):
49
54
  )
50
55
  with open(data_file, "w") as f:
51
56
  json.dump(sorted_data, f, indent=4)
57
+ log.info(f"Saved data to {data_file}")
52
58
  except OSError as e:
53
- error(f"Error writing to data file: {e}", config)
59
+ error_log.error(f"Error writing to data file: {e}")
54
60
 
55
61
 
56
62
  def create_entry(config, data, path, alias=None):
@@ -61,6 +67,7 @@ def create_entry(config, data, path, alias=None):
61
67
  "created_at": time.time(),
62
68
  }
63
69
  save_data(config, data)
70
+ log.info(f"Created new entry with alias_id '{alias_id}' and path '{path}'")
64
71
  return alias_id
65
72
 
66
73
 
@@ -68,8 +75,9 @@ def delete_entry(config, data, entry_id):
68
75
  if entry_id in data:
69
76
  del data[entry_id]
70
77
  save_data(config, data)
78
+ log.info(f"Deleted entry with alias_id '{entry_id}'")
71
79
  else:
72
- error(f"Entry ID {entry_id} not found", config)
80
+ error_log.error(f"Entry ID '{entry_id}' not found")
73
81
  raise KeyError(f"Entry ID {entry_id} not found")
74
82
 
75
83
 
@@ -77,8 +85,9 @@ def update_entry(config, data, entry_id, entry):
77
85
  if entry_id in data:
78
86
  data[entry_id] = entry
79
87
  save_data(config, data)
88
+ log.info(f"Updated entry with alias_id '{entry_id}'")
80
89
  else:
81
- error(f"Entry ID {entry_id} not found", config)
90
+ error_log.error(f"Entry ID '{entry_id}' not found")
82
91
  raise KeyError(f"Entry ID {entry_id} not found")
83
92
 
84
93
 
@@ -87,8 +96,9 @@ def delete_data_file(config):
87
96
  if os.path.exists(data_file):
88
97
  try:
89
98
  os.remove(data_file)
99
+ log.info(f"Deleted data file at {data_file}")
90
100
  except OSError as e:
91
- error(f"Error deleting data file: {e}", config)
101
+ error_log.error(f"Error deleting data file: {e}")
92
102
  raise
93
103
  else:
94
- error("No data file found to delete", config)
104
+ error_log.error("No data file found to delete")
twd/logger.py CHANGED
@@ -1,47 +1,47 @@
1
+ import logging
1
2
  import os
2
- import time
3
+ from logging.handlers import RotatingFileHandler
3
4
 
4
5
 
5
- def format_message(message, config):
6
- """Format the log message according to the provided config."""
7
- result = config.get("log_format", "[$T]: $M")
8
- result = result.replace("$T", time.strftime("%Y-%m-%d %H:%M:%S"))
9
- result = result.replace("$M", message)
10
- return result
11
-
12
-
13
- def ensure_directory_exists(file_path):
14
- """Ensure the directory for the given file path exists."""
15
- directory = os.path.dirname(file_path)
16
- if not os.path.exists(directory):
17
- os.makedirs(directory, exist_ok=True)
18
-
19
-
20
- def write_log(message, config):
21
- """Write log message to the log file specified in the config."""
6
+ def setup_logger(config):
7
+ """Set up loggers based on the configuration provided."""
22
8
  log_file = os.path.expanduser(config.get("log_file"))
23
- log_file = os.path.abspath(log_file)
24
- ensure_directory_exists(log_file) # Ensure the directory exists
25
- with open(log_file, "a+") as f:
26
- f.write(message + "\n")
27
-
28
-
29
- def write_error(message, config):
30
- """Write error message to the error file specified in the config."""
31
9
  error_file = os.path.expanduser(config.get("error_file"))
32
- error_file = os.path.abspath(error_file)
33
- ensure_directory_exists(error_file) # Ensure the directory exists
34
- with open(error_file, "a+") as f:
35
- f.write(message + "\n")
36
-
37
-
38
- def log(message, config):
39
- """Log the message using the provided config."""
40
- formatted_message = format_message(message, config)
41
- write_log(formatted_message, config)
42
-
10
+ log_level = config.get("log_level", "INFO").upper()
11
+ max_bytes = config.get("log_max_bytes", 5 * 1024 * 1024) # Default 5MB
12
+ backup_count = config.get("log_backup_count", 3) # Default 3 backup files
13
+
14
+ os.makedirs(os.path.dirname(log_file), exist_ok=True)
15
+ os.makedirs(os.path.dirname(error_file), exist_ok=True)
16
+
17
+ # General log configuration
18
+ log_formatter = logging.Formatter(
19
+ config.get("log_format", "%(asctime)s - %(levelname)s - %(message)s")
20
+ )
21
+
22
+ # Avoid duplicate handlers
23
+ logger = logging.getLogger("log")
24
+ if not logger.hasHandlers():
25
+ logger.setLevel(log_level)
26
+ log_handler = RotatingFileHandler(
27
+ log_file, maxBytes=max_bytes, backupCount=backup_count
28
+ )
29
+ log_handler.setFormatter(log_formatter)
30
+ logger.addHandler(log_handler)
31
+
32
+ # Error log configuration
33
+ error_logger = logging.getLogger("error")
34
+ if not error_logger.hasHandlers():
35
+ error_logger.setLevel(logging.ERROR)
36
+ error_handler = RotatingFileHandler(
37
+ error_file, maxBytes=max_bytes, backupCount=backup_count
38
+ )
39
+ error_handler.setFormatter(log_formatter)
40
+ error_logger.addHandler(error_handler)
41
+
42
+ return logger, error_logger
43
+
44
+
45
+ def initialize_logging(config):
46
+ setup_logger(config)
43
47
 
44
- def error(message, config):
45
- """Log the error using the provided config."""
46
- formatted_message = format_message(message, config)
47
- write_error(formatted_message, config)
twd/screen.py CHANGED
@@ -2,7 +2,10 @@ import curses
2
2
  import time
3
3
  import os
4
4
  from . import crud
5
- from .logger import error
5
+ import logging
6
+
7
+ log = logging.getLogger("log")
8
+ error_log = logging.getLogger("error")
6
9
 
7
10
  CONFIG = None
8
11
  DIRS = None
@@ -163,7 +166,7 @@ def display_select_screen(stdscr):
163
166
  try:
164
167
  crud.delete_entry(CONFIG, data, selected_entry_id)
165
168
  except KeyError:
166
- error(f"Entry ID {selected_entry_id} not found", CONFIG)
169
+ error_log.error(f"Entry ID {selected_entry_id} not found")
167
170
  del filtered_DIRS[selected_entry_id]
168
171
  if selected_entry >= len(filtered_DIRS):
169
172
  selected_entry = max(len(filtered_DIRS) - 1, 0)
@@ -196,4 +199,3 @@ def display_select(config, dirs):
196
199
  original_DIRS = DIRS
197
200
  search_query = ""
198
201
  return curses.wrapper(display_select_screen)
199
-
twd/twd.py CHANGED
@@ -3,20 +3,28 @@ import argparse
3
3
  import json
4
4
  import time
5
5
  import re
6
+ import logging
6
7
  from importlib.metadata import version, PackageNotFoundError
7
- from .logger import log, error
8
+ from .logger import initialize_logging
8
9
  from .screen import display_select
9
10
  from . import crud
10
11
 
12
+ log = logging.getLogger("log")
13
+ error_log = logging.getLogger("error")
14
+
11
15
  TWD_DIR = os.path.join(os.path.expanduser("~"), ".twd")
12
16
  CONFIG_FILE = os.path.join(TWD_DIR, "config")
13
17
 
14
18
  DEFAULT_CONFIG = {
15
19
  "data_file": os.path.expanduser("~/.twd/data"),
16
20
  "output_behaviour": 2,
21
+ "clear_after_screen": False,
17
22
  "log_file": os.path.expanduser("~/.twd/log"),
18
23
  "error_file": os.path.expanduser("~/.twd/error"),
19
- "log_format": "[$T]: $M",
24
+ "log_format": "%(asctime)s - %(levelname)s - %(message)s",
25
+ "log_level": "INFO",
26
+ "log_max_bytes": 5 * 1024 * 1024, # 5 MB log rotation
27
+ "log_backup_count": 3,
20
28
  }
21
29
 
22
30
 
@@ -31,32 +39,34 @@ def load_config():
31
39
  try:
32
40
  return json.load(file)
33
41
  except json.JSONDecodeError as e:
34
- error(f"Error loading config: {e}", DEFAULT_CONFIG)
42
+ error_log.error(f"Error loading config: {e}")
35
43
  return DEFAULT_CONFIG
36
44
 
37
45
 
38
46
  CONFIG = load_config()
47
+ initialize_logging(CONFIG)
39
48
 
40
- # Ensure data files exist
41
49
  crud.ensure_data_file_exists(CONFIG)
42
- log_file = os.path.expanduser(CONFIG.get("log_file"))
43
- error_file = os.path.expanduser(CONFIG.get("error_file"))
44
50
 
45
51
 
46
52
  def ensure_log_error_files():
53
+ """Ensure that log and error files exist based on configuration settings."""
54
+ log_file = os.path.expanduser(CONFIG.get("log_file"))
55
+ error_file = os.path.expanduser(CONFIG.get("error_file"))
56
+
47
57
  if not os.path.exists(log_file):
48
58
  try:
49
59
  with open(log_file, "w+") as f:
50
60
  f.write("")
51
61
  except OSError as e:
52
- error(f"Error creating log file: {e}", CONFIG)
62
+ error_log.error(f"Error creating log file: {e}")
53
63
 
54
64
  if not os.path.exists(error_file):
55
65
  try:
56
66
  with open(error_file, "w+") as f:
57
67
  f.write("")
58
68
  except OSError as e:
59
- error(f"Error creating error file: {e}", CONFIG)
69
+ error_log.error(f"Error creating error file: {e}")
60
70
 
61
71
 
62
72
  ensure_log_error_files()
@@ -66,14 +76,14 @@ def get_absolute_path(path):
66
76
  try:
67
77
  return os.path.abspath(path)
68
78
  except Exception as e:
69
- error(f"Error getting absolute path for {path}: {e}", CONFIG)
79
+ error_log.error(f"Error getting absolute path for {path}: {e}")
70
80
  raise
71
81
 
72
82
 
73
83
  def validate_alias(alias):
74
84
  """Ensure the alias contains only valid characters."""
75
85
  if not re.match(r"^[\w-]+$", alias):
76
- error(f"Invalid alias provided: {alias}", CONFIG)
86
+ error_log.error(f"Invalid alias provided: {alias}")
77
87
  raise ValueError(
78
88
  f"Invalid alias: '{alias}'. Aliases can only contain alphanumeric characters, dashes, and underscores."
79
89
  )
@@ -83,18 +93,24 @@ def validate_alias(alias):
83
93
  def output_handler(
84
94
  message=None, path=None, output=True, simple_output=False, message_type=0
85
95
  ):
86
- log(f"Type: {message_type}, Msg: {message or path}", CONFIG)
96
+ log.info(message or path)
87
97
 
88
98
  if CONFIG["output_behaviour"] == 1 or simple_output:
89
99
  if path:
90
100
  with open("/tmp/twd_path", "w") as f:
91
101
  f.write(path)
102
+ if CONFIG["clear_after_screen"]:
103
+ with open("/tmp/twd_clear", "w") as f:
104
+ f.write(path)
92
105
  if output:
93
106
  print(path)
94
107
  elif CONFIG["output_behaviour"] == 2:
95
108
  if path:
96
109
  with open("/tmp/twd_path", "w") as f:
97
110
  f.write(path)
111
+ if CONFIG["clear_after_screen"]:
112
+ with open("/tmp/twd_clear", "w") as f:
113
+ f.write(path)
98
114
  if output:
99
115
  print(message)
100
116
 
@@ -126,12 +142,10 @@ def load_directory():
126
142
 
127
143
  def show_main(alias=None, output=True, simple_output=False):
128
144
  dirs = load_directory()
129
-
130
145
  if dirs is None:
131
146
  output_handler("No TWD found", None, output, simple_output)
132
147
  return 1
133
148
  else:
134
- # Use alias if provided
135
149
  if alias:
136
150
  matched_dirs = []
137
151
 
@@ -149,14 +163,13 @@ def show_main(alias=None, output=True, simple_output=False):
149
163
 
150
164
  if len(matched_dirs) == 1:
151
165
  TWD = matched_dirs[0]["path"]
152
-
153
166
  if os.path.exists(TWD):
154
167
  output_handler(
155
168
  f"cd {TWD}", TWD, output, simple_output, message_type=1
156
169
  )
157
170
  return 0
158
171
  else:
159
- error(f"Directory does not exist: {TWD}", CONFIG)
172
+ error_log.error(f"Directory does not exist: {TWD}")
160
173
  output_handler(
161
174
  f"Directory does not exist: {TWD}", None, output, simple_output
162
175
  )
@@ -177,19 +190,17 @@ def show_main(alias=None, output=True, simple_output=False):
177
190
  output_handler("No TWD with alias found", None, output, simple_output)
178
191
  return 1
179
192
 
180
- # Display selection using curses if alias is not given
181
193
  selected_dir = display_select(CONFIG, dirs)
182
194
  if selected_dir is None:
183
195
  output_handler("No TWD selected", None, output, simple_output)
184
196
  return 0
185
197
  else:
186
198
  TWD = selected_dir["path"]
187
-
188
199
  if os.path.exists(TWD):
189
200
  output_handler(f"cd {TWD}", TWD, output, simple_output, message_type=1)
190
201
  return 0
191
202
  else:
192
- error(f"Directory does not exist: {TWD}", CONFIG)
203
+ error_log.error(f"Directory does not exist: {TWD}")
193
204
  output_handler(
194
205
  f"Directory does not exist: {TWD}", None, output, simple_output
195
206
  )
@@ -198,7 +209,6 @@ def show_main(alias=None, output=True, simple_output=False):
198
209
 
199
210
  def show_directory(output=True, simple_output=False):
200
211
  dirs = load_directory()
201
-
202
212
  if not dirs:
203
213
  output_handler("No TWD set", None, output, simple_output)
204
214
  return
@@ -240,16 +250,26 @@ This feature is to prevent accidental execution.""",
240
250
  try:
241
251
  crud.delete_data_file(CONFIG)
242
252
  except OSError as e:
243
- error(f"Error deleting TWD file: {e}", CONFIG)
253
+ error_log.error(f"Error deleting TWD file: {e}")
244
254
  raise
245
255
  output_handler("TWD File deleted and TWD unset", None, output, simple_output)
246
256
 
247
257
 
258
+ def setup(alias):
259
+ bashrc_path = os.path.expanduser("~/.bashrc")
260
+ alias = "twd" if not alias else alias
261
+ with open(bashrc_path, "a") as file:
262
+ file.write(f"\neval $(python3 -m twd --shell {alias})\n")
263
+ print("Please execute the following command to activate TWD:")
264
+ print("")
265
+ print(f"source {bashrc_path}")
266
+
267
+
248
268
  def get_package_version():
249
269
  try:
250
270
  return version("twd_m4sc0")
251
271
  except PackageNotFoundError as e:
252
- error(f"Package version not found: {e}", CONFIG)
272
+ error_log.error(f"Package version not found: {e}")
253
273
  return "Unknown version"
254
274
 
255
275
 
@@ -258,13 +278,14 @@ def main():
258
278
  description="Temporarily save and navigate to working directories."
259
279
  )
260
280
 
261
- # Positional arguments
281
+ parser.add_argument(
282
+ "--setup", nargs="?", const="twd", help="Automatic setup in the .bashrc file"
283
+ )
284
+
262
285
  parser.add_argument("directory", nargs="?", help="Directory to save")
263
286
  parser.add_argument(
264
287
  "alias", nargs="?", help="Alias for the saved directory (optional)"
265
288
  )
266
-
267
- # Optional Arguments/Flags
268
289
  parser.add_argument(
269
290
  "-s",
270
291
  "--save",
@@ -285,63 +306,56 @@ def main():
285
306
  "--version",
286
307
  action="version",
287
308
  version=f"TWD Version: v{get_package_version()}",
288
- help="Show the current version of TWD installed",
289
309
  )
290
310
  parser.add_argument("-f", "--force", action="store_true", help="Force an action")
291
311
  parser.add_argument(
292
312
  "--shell", nargs="?", const="twd", help="Output shell function for integration"
293
313
  )
294
314
  parser.add_argument(
295
- "--simple-output",
296
- action="store_true",
297
- help="Only print essential output (new directory, absolute path, etc.)",
315
+ "--simple-output", action="store_true", help="Only print essential output"
298
316
  )
299
317
  parser.add_argument(
300
318
  "--no-output",
301
319
  action="store_true",
302
320
  help="Prevents the console from sending output",
303
321
  )
304
- args = parser.parse_args()
305
322
 
323
+ args = parser.parse_args()
306
324
  output = not args.no_output
307
325
  simple_output = args.simple_output
308
326
 
309
- # Shell function
310
327
  if args.shell:
311
- print(rf"""
312
- function {args.shell}() {{
313
- python3 -m twd "$@"
314
- if [[ -f /tmp/twd_path ]]; then
315
- cd "$(cat /tmp/twd_path)"
316
- /bin/rm -f /tmp/twd_path
317
- fi
318
- }}
319
- """)
328
+ print(rf"""function {args.shell}() {{
329
+ python3 -m twd "$@";
330
+ if [ -f /tmp/twd_path ]; then
331
+ cd "$(cat /tmp/twd_path)";
332
+ /bin/rm -f /tmp/twd_path;
333
+ fi;
334
+ if [ -f /tmp/twd_clear ]; then
335
+ clear;
336
+ /bin/rm -f /tmp/twd_clear;
337
+ fi;
338
+ }}""")
339
+ return 0
340
+
341
+ if args.setup:
342
+ setup(args.setup)
320
343
  return 0
321
344
 
322
345
  directory = args.directory or args.dir
323
346
  alias = args.alias or args.ali
324
347
 
325
348
  if args.save:
326
- if not directory:
327
- directory = os.getcwd()
328
-
329
- alias = args.alias or args.ali
330
-
331
349
  save_directory(directory, alias, output, simple_output)
332
350
  elif args.go:
333
- alias = args.go
334
- return show_main(alias, output, simple_output)
351
+ show_main(alias, output, simple_output)
335
352
  elif args.list:
336
353
  show_directory(output, simple_output)
337
354
  elif args.unset:
338
- force = args.force
339
- unset_directory(output, simple_output, force)
355
+ unset_directory(output, simple_output, force=args.force)
340
356
  else:
341
357
  show_main(None, output, simple_output)
342
- return 1
343
358
 
344
359
 
345
360
  if __name__ == "__main__":
346
361
  main()
347
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: twd_m4sc0
3
- Version: 2.0.0
3
+ Version: 2.0.3
4
4
  Summary: A tool to temporarily save and go to a working directory
5
5
  Home-page: https://github.com/m4sc0/twd
6
6
  Author: m4sc0
@@ -11,12 +11,11 @@ Requires-Python: >=3.6
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
13
 
14
-
15
14
  # twd-m4sc0
16
15
 
17
16
  `twd-m4sc0` is a command-line tool that allows you to temporarily save a working directory and easily navigate back to it. It's designed for developers and users who frequently need to switch between directories in the terminal.
18
17
 
19
- > All Versions `< v1.5` are considered deprecated and should not be used anymore because of the `config` file that was introduced in that version. This file is incompatible with newer versions and might cause issues or break the program.
18
+ > All Versions `< v1.5` are considered deprecated and should not be used anymore because of the `config` file that was introduced in that version. This file is incompatible with newer versions and might cause issues or break the program.
20
19
 
21
20
  ## Features
22
21
 
@@ -29,7 +28,7 @@ License-File: LICENSE
29
28
 
30
29
  ## Installation
31
30
 
32
- ### Installation using `pip`:
31
+ ### Installation using `pip`
33
32
 
34
33
  1. Install the package from the `pypi` repository:
35
34
 
@@ -37,19 +36,41 @@ License-File: LICENSE
37
36
  pip install twd-m4sc0
38
37
  ```
39
38
 
40
- 2. Add the following line to your `.bashrc` or `.zshrc` to set up the shell function:
39
+ 2. Ensure proper installation by checking the version
40
+
41
+ ```bash
42
+ python3 -m twd -v
43
+ ```
44
+
45
+ ### Setup using in-built commands
46
+
47
+ > This setup information is only recommend if you're system is using the `.bashrc` file provided by debian based systems and it's located at `~/.bashrc`. If you're unsure what you're shell configuration file is called or where it's located please refer to your official OS documentation to ensure proper functionality.
48
+
49
+ 1. Run the following command to activate the `twd` shell function
50
+
51
+ > Replace `[alias]` with an alias of your choice to customize the way you're calling the script and follow the given instructions
52
+
53
+ ```bash
54
+ python3 -m twd --setup [alias]
55
+ ```
56
+
57
+ ### Manual setup
41
58
 
42
- > Since 1.5.4 you can also set a different command for the `twd` program by replacing `[alias]` in the following code by your custom alias
59
+ 1. Add the following line to your shell configuration file:
43
60
 
44
61
  ```bash
45
62
  eval $(python3 -m twd --shell [alias])
46
63
  ```
47
64
 
48
- 3. Exit and reopen the terminal or reload using:
65
+ 2. Run the following command to apply the new configuration:
49
66
 
50
67
  ```bash
51
68
  source ~/.bashrc
52
- # or
69
+ ```
70
+
71
+ or
72
+
73
+ ```bash
53
74
  source ~/.zshrc
54
75
  ```
55
76
 
@@ -0,0 +1,14 @@
1
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ tests/test_twd.py,sha256=XrxOo99oqida_7qZ48pA6BCazZekDmG5syw9NvjZWDU,484
3
+ twd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ twd/__main__.py,sha256=gM_Py51pQFH3CXdDIuPzBW6eNlFH1UHeRAmgAPWQyik,61
5
+ twd/crud.py,sha256=QTruLgK9aBorJ1VKpeBS-joeD1DZbK2JfQm9tl3v5Bc,3057
6
+ twd/logger.py,sha256=WG-JBbkdizR2KMODGcxREj1N--CgY-PdIC_agyZ5PHU,1590
7
+ twd/screen.py,sha256=vQFNtast5-P_XrdvbY7XyIx2MGoNR7TUoVHHkXUTbvc,7066
8
+ twd/twd.py,sha256=-YEu8JizOccuu3OeZzKecaRRelqzw-f92knG9shTJNM,11398
9
+ twd_m4sc0-2.0.3.dist-info/LICENSE,sha256=eQSDjcD_fvOwfjmrzxKJhtZsSI39seMawuvsgeD_dfw,1062
10
+ twd_m4sc0-2.0.3.dist-info/METADATA,sha256=FGQSzmNf6LcLOflPD7z6suetLy6-TOiw0YWy5lJryKs,4084
11
+ twd_m4sc0-2.0.3.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
12
+ twd_m4sc0-2.0.3.dist-info/entry_points.txt,sha256=QfYDHHjipkVN4oalpACFmIeYHb7GQCJY4SC12bTsiQQ,37
13
+ twd_m4sc0-2.0.3.dist-info/top_level.txt,sha256=PXToru2Yr2Xh3F_F-pHXtuOQVp5x7KKCPFf94P_VI5U,10
14
+ twd_m4sc0-2.0.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,14 +0,0 @@
1
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- tests/test_twd.py,sha256=XrxOo99oqida_7qZ48pA6BCazZekDmG5syw9NvjZWDU,484
3
- twd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- twd/__main__.py,sha256=gM_Py51pQFH3CXdDIuPzBW6eNlFH1UHeRAmgAPWQyik,61
5
- twd/crud.py,sha256=pp5QPt1NEC5Hxc-O5foqgjVnQnek7jUohW15bOOoJ98,2561
6
- twd/logger.py,sha256=Pmhh4sOB-HyJAVBSwiESGRJElJoJ4Anhn-HVF8vxXzY,1595
7
- twd/screen.py,sha256=X3531u1MysSwyqmmPWZUkkU-0PSOJowz319h6cr9vrA,7005
8
- twd/twd.py,sha256=NS0-2Lbs1v4keG2itfxb2b5vYhpvEfmt2xPV9CdORE4,10563
9
- twd_m4sc0-2.0.0.dist-info/LICENSE,sha256=eQSDjcD_fvOwfjmrzxKJhtZsSI39seMawuvsgeD_dfw,1062
10
- twd_m4sc0-2.0.0.dist-info/METADATA,sha256=D0McQXnvy5PS_hLCRAARbn_8z7mq3YgoZrA9pA5UF3E,3528
11
- twd_m4sc0-2.0.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
12
- twd_m4sc0-2.0.0.dist-info/entry_points.txt,sha256=QfYDHHjipkVN4oalpACFmIeYHb7GQCJY4SC12bTsiQQ,37
13
- twd_m4sc0-2.0.0.dist-info/top_level.txt,sha256=PXToru2Yr2Xh3F_F-pHXtuOQVp5x7KKCPFf94P_VI5U,10
14
- twd_m4sc0-2.0.0.dist-info/RECORD,,