twd-m4sc0 2.0.3__py3-none-any.whl → 3.0.1__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/twd.py DELETED
@@ -1,361 +0,0 @@
1
- import os
2
- import argparse
3
- import json
4
- import time
5
- import re
6
- import logging
7
- from importlib.metadata import version, PackageNotFoundError
8
- from .logger import initialize_logging
9
- from .screen import display_select
10
- from . import crud
11
-
12
- log = logging.getLogger("log")
13
- error_log = logging.getLogger("error")
14
-
15
- TWD_DIR = os.path.join(os.path.expanduser("~"), ".twd")
16
- CONFIG_FILE = os.path.join(TWD_DIR, "config")
17
-
18
- DEFAULT_CONFIG = {
19
- "data_file": os.path.expanduser("~/.twd/data"),
20
- "output_behaviour": 2,
21
- "clear_after_screen": False,
22
- "log_file": os.path.expanduser("~/.twd/log"),
23
- "error_file": os.path.expanduser("~/.twd/error"),
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,
28
- }
29
-
30
-
31
- def load_config():
32
- if not os.path.exists(CONFIG_FILE):
33
- os.makedirs(TWD_DIR, exist_ok=True)
34
- with open(CONFIG_FILE, "w") as file:
35
- json.dump(DEFAULT_CONFIG, file, indent=4)
36
- return DEFAULT_CONFIG
37
- else:
38
- with open(CONFIG_FILE, "r") as file:
39
- try:
40
- return json.load(file)
41
- except json.JSONDecodeError as e:
42
- error_log.error(f"Error loading config: {e}")
43
- return DEFAULT_CONFIG
44
-
45
-
46
- CONFIG = load_config()
47
- initialize_logging(CONFIG)
48
-
49
- crud.ensure_data_file_exists(CONFIG)
50
-
51
-
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
-
57
- if not os.path.exists(log_file):
58
- try:
59
- with open(log_file, "w+") as f:
60
- f.write("")
61
- except OSError as e:
62
- error_log.error(f"Error creating log file: {e}")
63
-
64
- if not os.path.exists(error_file):
65
- try:
66
- with open(error_file, "w+") as f:
67
- f.write("")
68
- except OSError as e:
69
- error_log.error(f"Error creating error file: {e}")
70
-
71
-
72
- ensure_log_error_files()
73
-
74
-
75
- def get_absolute_path(path):
76
- try:
77
- return os.path.abspath(path)
78
- except Exception as e:
79
- error_log.error(f"Error getting absolute path for {path}: {e}")
80
- raise
81
-
82
-
83
- def validate_alias(alias):
84
- """Ensure the alias contains only valid characters."""
85
- if not re.match(r"^[\w-]+$", alias):
86
- error_log.error(f"Invalid alias provided: {alias}")
87
- raise ValueError(
88
- f"Invalid alias: '{alias}'. Aliases can only contain alphanumeric characters, dashes, and underscores."
89
- )
90
- return alias
91
-
92
-
93
- def output_handler(
94
- message=None, path=None, output=True, simple_output=False, message_type=0
95
- ):
96
- log.info(message or path)
97
-
98
- if CONFIG["output_behaviour"] == 1 or simple_output:
99
- if path:
100
- with open("/tmp/twd_path", "w") as f:
101
- f.write(path)
102
- if CONFIG["clear_after_screen"]:
103
- with open("/tmp/twd_clear", "w") as f:
104
- f.write(path)
105
- if output:
106
- print(path)
107
- elif CONFIG["output_behaviour"] == 2:
108
- if path:
109
- with open("/tmp/twd_path", "w") as f:
110
- f.write(path)
111
- if CONFIG["clear_after_screen"]:
112
- with open("/tmp/twd_clear", "w") as f:
113
- f.write(path)
114
- if output:
115
- print(message)
116
-
117
-
118
- def save_directory(path=None, alias=None, output=True, simple_output=False):
119
- if path is None:
120
- path = os.getcwd()
121
- else:
122
- path = get_absolute_path(path)
123
-
124
- if alias:
125
- alias = validate_alias(alias)
126
-
127
- data = crud.load_data(CONFIG)
128
- alias_id = crud.create_entry(CONFIG, data, path, alias)
129
-
130
- output_handler(
131
- f"Saved TWD to {path} with alias '{alias or alias_id}'",
132
- path,
133
- output,
134
- simple_output,
135
- )
136
-
137
-
138
- def load_directory():
139
- data = crud.load_data(CONFIG)
140
- return data if data else None
141
-
142
-
143
- def show_main(alias=None, output=True, simple_output=False):
144
- dirs = load_directory()
145
- if dirs is None:
146
- output_handler("No TWD found", None, output, simple_output)
147
- return 1
148
- else:
149
- if alias:
150
- matched_dirs = []
151
-
152
- for entry_id, entry in dirs.items():
153
- if (
154
- "alias" in entry
155
- and entry["alias"]
156
- and entry["alias"].startswith(alias)
157
- ):
158
- entry["id"] = entry_id
159
- matched_dirs.append(entry)
160
- elif entry_id.startswith(alias):
161
- entry["id"] = entry_id
162
- matched_dirs.append(entry)
163
-
164
- if len(matched_dirs) == 1:
165
- TWD = matched_dirs[0]["path"]
166
- if os.path.exists(TWD):
167
- output_handler(
168
- f"cd {TWD}", TWD, output, simple_output, message_type=1
169
- )
170
- return 0
171
- else:
172
- error_log.error(f"Directory does not exist: {TWD}")
173
- output_handler(
174
- f"Directory does not exist: {TWD}", None, output, simple_output
175
- )
176
- return 1
177
- elif len(matched_dirs) > 1:
178
- output_handler(
179
- f"Multiple TWDs match for '{alias}':", None, output, simple_output
180
- )
181
- for match in matched_dirs:
182
- output_handler(
183
- f"{match['alias']} {match['id']} {match['path']}",
184
- None,
185
- output,
186
- simple_output,
187
- )
188
- return 1
189
- else:
190
- output_handler("No TWD with alias found", None, output, simple_output)
191
- return 1
192
-
193
- selected_dir = display_select(CONFIG, dirs)
194
- if selected_dir is None:
195
- output_handler("No TWD selected", None, output, simple_output)
196
- return 0
197
- else:
198
- TWD = selected_dir["path"]
199
- if os.path.exists(TWD):
200
- output_handler(f"cd {TWD}", TWD, output, simple_output, message_type=1)
201
- return 0
202
- else:
203
- error_log.error(f"Directory does not exist: {TWD}")
204
- output_handler(
205
- f"Directory does not exist: {TWD}", None, output, simple_output
206
- )
207
- return 1
208
-
209
-
210
- def show_directory(output=True, simple_output=False):
211
- dirs = load_directory()
212
- if not dirs:
213
- output_handler("No TWD set", None, output, simple_output)
214
- return
215
-
216
- max_alias_len = max(len(entry["alias"]) for entry in dirs.values()) if dirs else 0
217
- max_id_len = max(len(alias_id) for alias_id in dirs.keys()) if dirs else 0
218
- max_path_len = max(len(entry["path"]) for entry in dirs.values()) if dirs else 0
219
-
220
- header = f"{'Alias'.ljust(max_alias_len)} {'ID'.ljust(max_id_len)} {'Path'.ljust(max_path_len)} Created At"
221
- print(header)
222
- print("-" * len(header))
223
-
224
- for alias_id, entry in dirs.items():
225
- alias = entry["alias"].ljust(max_alias_len)
226
- path = entry["path"].ljust(max_path_len)
227
- created_at = time.strftime(
228
- "%Y-%m-%d %H:%M:%S", time.localtime(entry["created_at"])
229
- )
230
- alias_id_str = alias_id.ljust(max_id_len)
231
- output_handler(
232
- f"{alias} {alias_id_str} {path} {created_at}",
233
- None,
234
- output,
235
- simple_output,
236
- )
237
-
238
-
239
- def unset_directory(output=True, simple_output=False, force=False):
240
- if not force:
241
- output_handler(
242
- r"""If you want to execute deleting and therefore unsetting all set TWD's, please use "--force" or "-f" and run again.
243
-
244
- This feature is to prevent accidental execution.""",
245
- None,
246
- True,
247
- False,
248
- )
249
- return
250
- try:
251
- crud.delete_data_file(CONFIG)
252
- except OSError as e:
253
- error_log.error(f"Error deleting TWD file: {e}")
254
- raise
255
- output_handler("TWD File deleted and TWD unset", None, output, simple_output)
256
-
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
-
268
- def get_package_version():
269
- try:
270
- return version("twd_m4sc0")
271
- except PackageNotFoundError as e:
272
- error_log.error(f"Package version not found: {e}")
273
- return "Unknown version"
274
-
275
-
276
- def main():
277
- parser = argparse.ArgumentParser(
278
- description="Temporarily save and navigate to working directories."
279
- )
280
-
281
- parser.add_argument(
282
- "--setup", nargs="?", const="twd", help="Automatic setup in the .bashrc file"
283
- )
284
-
285
- parser.add_argument("directory", nargs="?", help="Directory to save")
286
- parser.add_argument(
287
- "alias", nargs="?", help="Alias for the saved directory (optional)"
288
- )
289
- parser.add_argument(
290
- "-s",
291
- "--save",
292
- action="store_true",
293
- help="Save the current or specified directory",
294
- )
295
- parser.add_argument("-d", "--dir", nargs="?", help="Directory to save")
296
- parser.add_argument("-a", "--ali", nargs="?", help="Alias for the saved directory")
297
- parser.add_argument(
298
- "-g", "--go", nargs="?", const=" ", help="Go to the saved directory"
299
- )
300
- parser.add_argument("-l", "--list", action="store_true", help="Show saved TWD")
301
- parser.add_argument(
302
- "-u", "--unset", action="store_true", help="Unset the saved TWD"
303
- )
304
- parser.add_argument(
305
- "-v",
306
- "--version",
307
- action="version",
308
- version=f"TWD Version: v{get_package_version()}",
309
- )
310
- parser.add_argument("-f", "--force", action="store_true", help="Force an action")
311
- parser.add_argument(
312
- "--shell", nargs="?", const="twd", help="Output shell function for integration"
313
- )
314
- parser.add_argument(
315
- "--simple-output", action="store_true", help="Only print essential output"
316
- )
317
- parser.add_argument(
318
- "--no-output",
319
- action="store_true",
320
- help="Prevents the console from sending output",
321
- )
322
-
323
- args = parser.parse_args()
324
- output = not args.no_output
325
- simple_output = args.simple_output
326
-
327
- if args.shell:
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)
343
- return 0
344
-
345
- directory = args.directory or args.dir
346
- alias = args.alias or args.ali
347
-
348
- if args.save:
349
- save_directory(directory, alias, output, simple_output)
350
- elif args.go:
351
- show_main(alias, output, simple_output)
352
- elif args.list:
353
- show_directory(output, simple_output)
354
- elif args.unset:
355
- unset_directory(output, simple_output, force=args.force)
356
- else:
357
- show_main(None, output, simple_output)
358
-
359
-
360
- if __name__ == "__main__":
361
- main()
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Masco
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,179 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: twd_m4sc0
3
- Version: 2.0.3
4
- Summary: A tool to temporarily save and go to a working directory
5
- Home-page: https://github.com/m4sc0/twd
6
- Author: m4sc0
7
- Classifier: Programming Language :: Python :: 3
8
- Classifier: License :: OSI Approved :: MIT License
9
- Classifier: Operating System :: OS Independent
10
- Requires-Python: >=3.6
11
- Description-Content-Type: text/markdown
12
- License-File: LICENSE
13
-
14
- # twd-m4sc0
15
-
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.
17
-
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.
19
-
20
- ## Features
21
-
22
- - Save the current or specified working directory.
23
- - Go back to a saved directory using an optional alias.
24
- - List all saved directories with metadata.
25
- - Unset and delete saved directories.
26
- - Integrates with your shell for seamless directory management.
27
- - Some options can be configured using the `config` file. For more information please visit the [Config](CONFIG.md) documentation.
28
-
29
- ## Installation
30
-
31
- ### Installation using `pip`
32
-
33
- 1. Install the package from the `pypi` repository:
34
-
35
- ```bash
36
- pip install twd-m4sc0
37
- ```
38
-
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
58
-
59
- 1. Add the following line to your shell configuration file:
60
-
61
- ```bash
62
- eval $(python3 -m twd --shell [alias])
63
- ```
64
-
65
- 2. Run the following command to apply the new configuration:
66
-
67
- ```bash
68
- source ~/.bashrc
69
- ```
70
-
71
- or
72
-
73
- ```bash
74
- source ~/.zshrc
75
- ```
76
-
77
- ## Usage
78
-
79
- ### Save a directory
80
-
81
- - Save the current directory or a specified directory:
82
-
83
- ```bash
84
- twd -s [path] [alias]
85
- ```
86
-
87
- If no path is specified, the current directory is saved. The alias is optional, and if not provided, an auto-generated ID will be used.
88
-
89
- ### Go to a saved directory
90
-
91
- - Navigate to a saved directory using an optional alias:
92
-
93
- ```bash
94
- twd -g [alias]
95
- ```
96
-
97
- If no alias is provided, the most recently saved directory will be used. If an alias is provided, it will navigate to the directory associated with that alias.
98
-
99
- ### List saved directories
100
-
101
- - Display a list of all saved directories:
102
-
103
- ```bash
104
- twd -l
105
- ```
106
-
107
- ### Unset the TWD and delete the data file
108
-
109
- - Unset and delete the saved directories:
110
-
111
- ```bash
112
- twd -u
113
- ```
114
-
115
- You can force this action using the `--force` flag to avoid accidental execution.
116
-
117
- ```bash
118
- twd -u --force
119
- ```
120
-
121
- ### Optional Parameters
122
-
123
- #### Simple Output
124
-
125
- For cleaner, minimal output intended for scripting or piping.
126
-
127
- - Example with `--simple-output`:
128
-
129
- ```bash
130
- twd -s --simple-output
131
- /home/user/.config
132
- ```
133
-
134
- - Example without `--simple-output`:
135
-
136
- ```bash
137
- Saved TWD to /home/user/.config
138
- ```
139
-
140
- #### No Output
141
-
142
- Suppresses all output (including confirmation messages).
143
-
144
- - Example with `--no-output`:
145
-
146
- ```bash
147
- twd -s --no-output
148
- # No output
149
- ```
150
-
151
- #### Force
152
-
153
- Use the `--force` flag to force certain actions, such as when unsetting directories with the `-u` flag.
154
-
155
- - Example:
156
-
157
- ```bash
158
- twd -u --force
159
- TWD File deleted and TWD unset
160
- ```
161
-
162
- ## Contribution
163
-
164
- To set up a development environment:
165
-
166
- 1. Clone the repository:
167
-
168
- ```bash
169
- git clone https://github.com/m4sc0/twd
170
- cd twd
171
- ```
172
-
173
- 2. Install the package in editable mode using `pip`:
174
-
175
- ```bash
176
- pip install -e .
177
- ```
178
-
179
- 3. Make your changes, and contribute!
@@ -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=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,2 +0,0 @@
1
- [console_scripts]
2
- twd = twd.twd:main
@@ -1,2 +0,0 @@
1
- tests
2
- twd