twd-m4sc0 1.4.0__tar.gz → 1.5.1__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: twd_m4sc0
3
- Version: 1.4.0
3
+ Version: 1.5.1
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
@@ -35,7 +35,7 @@ pip install twd-m4sc0
35
35
  2. Add the following line to your `.bashrc` or `.zshrc` to set up the shell function:
36
36
 
37
37
  ```bash
38
- eval $(twd --shell)
38
+ eval $(python3 -m twd --shell)
39
39
  ```
40
40
 
41
41
  3. Exit and reopen the terminal or reload using:
@@ -110,6 +110,19 @@ user:~/.config $ twd -s
110
110
  Saved TWD to /home/user/.config
111
111
  ```
112
112
 
113
+ #### Force
114
+
115
+ Forces an action
116
+
117
+ > Currently only implemented on the `-u` flag
118
+
119
+ - Example
120
+
121
+ ```bash
122
+ user:~/.config $ twd -u --force
123
+ TWD File deleted and TWD unset
124
+ ```
125
+
113
126
  # Contribution
114
127
 
115
128
  To set up a dev environment:
@@ -22,7 +22,7 @@ pip install twd-m4sc0
22
22
  2. Add the following line to your `.bashrc` or `.zshrc` to set up the shell function:
23
23
 
24
24
  ```bash
25
- eval $(twd --shell)
25
+ eval $(python3 -m twd --shell)
26
26
  ```
27
27
 
28
28
  3. Exit and reopen the terminal or reload using:
@@ -97,6 +97,19 @@ user:~/.config $ twd -s
97
97
  Saved TWD to /home/user/.config
98
98
  ```
99
99
 
100
+ #### Force
101
+
102
+ Forces an action
103
+
104
+ > Currently only implemented on the `-u` flag
105
+
106
+ - Example
107
+
108
+ ```bash
109
+ user:~/.config $ twd -u --force
110
+ TWD File deleted and TWD unset
111
+ ```
112
+
100
113
  # Contribution
101
114
 
102
115
  To set up a dev environment:
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="twd_m4sc0",
5
- version="1.4.0",
5
+ version="1.5.1",
6
6
  packages=find_packages(),
7
7
  entry_points={
8
8
  "console_scripts": [
@@ -2,6 +2,9 @@ import os
2
2
  import argparse
3
3
  import sys
4
4
  import json
5
+ import hashlib
6
+ import time
7
+ import re
5
8
  from importlib.metadata import version, PackageNotFoundError
6
9
 
7
10
  TWD_DIR = os.path.join(os.path.expanduser("~"), ".twd")
@@ -14,6 +17,10 @@ DEFAULT_CONFIG = {
14
17
 
15
18
  os.makedirs(TWD_DIR, exist_ok=True)
16
19
 
20
+ def create_alias_id():
21
+ data = str(time.time()) + str(os.urandom(16))
22
+ return hashlib.sha256(data.encode()).hexdigest()[:12]
23
+
17
24
  def load_config():
18
25
  if not os.path.exists(CONFIG_FILE):
19
26
  with open(CONFIG_FILE, 'w') as file:
@@ -34,18 +41,24 @@ TWD_FILE = os.path.expanduser(CONFIG.get("data_file", "~/.twd/data"))
34
41
  def ensure_data_file_exists():
35
42
  if not os.path.exists(TWD_FILE):
36
43
  with open(TWD_FILE, 'w') as f:
37
- f.write("")
44
+ json.dump({}, f)
38
45
 
39
46
  ensure_data_file_exists()
40
47
 
41
48
  def get_absolute_path(path):
42
49
  return os.path.abspath(path)
43
50
 
51
+ def validate_alias(alias):
52
+ """Ensure the alias contains only valid characters."""
53
+ if not re.match(r'^[\w-]+$', alias):
54
+ raise ValueError(f"Invalid alias: '{alias}'. Aliases can only contain alphanumeric characters, dashes, and underscores.")
55
+ return alias
56
+
44
57
  def output_handler(message=None, path=None, output=True, simple_output=False, message_type=0):
45
- if not output:
58
+ if not output or CONFIG["output_behaviour"] == 0:
46
59
  return
47
60
 
48
- if CONFIG["output_behaviour"] == 0:
61
+ if not message and not path:
49
62
  return
50
63
 
51
64
  if message_type == 1:
@@ -56,30 +69,53 @@ def output_handler(message=None, path=None, output=True, simple_output=False, me
56
69
  elif not simple_output and message:
57
70
  print(f"0;{message}")
58
71
 
59
- def save_directory(path=None, output=True, simple_output=False):
72
+ def save_directory(path=None, alias=None, output=True, simple_output=False):
60
73
  if path is None:
61
74
  path = os.getcwd()
62
75
  else:
63
76
  path = get_absolute_path(path)
64
77
 
65
- with open(TWD_FILE, "w") as f:
66
- f.write(path)
78
+ if alias:
79
+ alias = validate_alias(alias)
80
+
81
+ try:
82
+ with open(TWD_FILE, 'r') as f:
83
+ data = json.load(f)
84
+ except json.JSONDecodeError:
85
+ data = {}
86
+
87
+ alias_id = create_alias_id()
88
+ data[alias_id] = {
89
+ "path": path,
90
+ "alias": alias if alias else alias_id,
91
+ "created_at": time.time()
92
+ }
67
93
 
68
- output_handler(f"Saved TWD to {path}", path, output, simple_output)
94
+ with open(TWD_FILE, 'w') as f:
95
+ json.dump(data, f, indent=4)
96
+
97
+ output_handler(f"Saved TWD to {path} with alias '{alias or alias_id}'", path, output, simple_output)
69
98
 
70
99
  def load_directory():
71
100
  if not os.path.exists(TWD_FILE):
72
101
  return None
102
+
73
103
  with open(TWD_FILE, "r") as f:
74
- return f.read().strip()
104
+ try:
105
+ return json.load(f)
106
+ except json.JSONDecodeError:
107
+ return None
75
108
 
76
109
  def go_to_directory(output=True, simple_output=False):
77
- TWD = load_directory()
110
+ dirs = load_directory()
78
111
 
79
- if TWD is None:
112
+ if not dirs:
80
113
  output_handler("No TWD found", None, output, simple_output)
81
114
  return 1
82
115
  else:
116
+ last_alias, last_entry = list(dirs.items())[-1]
117
+ TWD = last_entry['path']
118
+
83
119
  if os.path.exists(TWD):
84
120
  output_handler(f"cd {TWD}", TWD, output, simple_output, message_type=1)
85
121
  return 0
@@ -88,17 +124,38 @@ def go_to_directory(output=True, simple_output=False):
88
124
  return 1
89
125
 
90
126
  def show_directory(output=True, simple_output=False):
91
- TWD = load_directory()
127
+ dirs = load_directory()
92
128
 
93
- if TWD is None:
129
+ if not dirs:
94
130
  output_handler("No TWD set", None, output, simple_output)
95
- else:
96
- output_handler(f"Current TWD: {TWD}", TWD, output, simple_output)
131
+ return
132
+
133
+ max_alias_len = max(len(entry['alias']) for entry in dirs.values()) if dirs else 0
134
+ max_id_len = max(len(alias_id) for alias_id in dirs.keys()) if dirs else 0
135
+ max_path_len = max(len(entry['path']) for entry in dirs.values()) if dirs else 0
97
136
 
98
- def unset_directory(output=True, simple_output=False):
137
+ header = f"{'Alias'.ljust(max_alias_len)} {'ID'.ljust(max_id_len)} {'Path'.ljust(max_path_len)} Created At"
138
+ print(header)
139
+ print("-" * len(header))
140
+
141
+ for alias_id, entry in dirs.items():
142
+ alias = entry['alias'].ljust(max_alias_len)
143
+ path = entry['path'].ljust(max_path_len)
144
+ created_at = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(entry['created_at']))
145
+ alias_id_str = alias_id.ljust(max_id_len)
146
+ output_handler(f"{alias} {alias_id_str} {path} {created_at}", None, output, simple_output)
147
+
148
+
149
+ def unset_directory(output=True, simple_output=False, force=False):
99
150
  if not os.path.exists(TWD_FILE):
100
151
  output_handler(f"No TWD file found", None, output, simple_output)
101
152
  else:
153
+ if not force:
154
+ output_handler(r'''If you want to execute deleting and therefore unsetting all set TWD's, please use "--force" or "-f" and run again.
155
+
156
+
157
+ This feature is to prevent accidental execution.''', None, True, False)
158
+ return
102
159
  os.remove(TWD_FILE)
103
160
  output_handler(f"TWD File deleted and TWD unset", None, output, simple_output)
104
161
 
@@ -113,45 +170,64 @@ def main():
113
170
 
114
171
  parser = argparse.ArgumentParser(description="Temporarily save and navigate to working directories.")
115
172
 
116
- parser.add_argument('-s', '--save', nargs='?', const='', help="Save the current or specified directory")
173
+ # Positional arguments
174
+ parser.add_argument('directory', nargs='?', help="Directory to save")
175
+ parser.add_argument('alias', nargs='?', help="Alias for the saved directory (optional)")
176
+
177
+ # Optional Arguments/Flags
178
+ parser.add_argument('-s', '--save', action='store_true', help="Save the current or specified directory")
179
+ parser.add_argument('-d', '--directory', help="Directory to save")
180
+ parser.add_argument('-a', '--alias', help="Alias for the saved directory")
117
181
  parser.add_argument('-g', '--go', action='store_true', help="Go to the saved directory")
118
182
  parser.add_argument('-l', '--list', action='store_true', help="Show saved TWD")
119
183
  parser.add_argument('-u', '--unset', action='store_true', help="Unset the saved TWD")
120
184
  parser.add_argument('-v', '--version', action='version', version=f'TWD Version: {get_package_version()}', help='Show the current version of TWD installed')
185
+ parser.add_argument('-f', '--force', action='store_true', help="Force an action")
121
186
  parser.add_argument('--shell', action='store_true', help="Output shell function for integration")
122
187
  parser.add_argument('--simple-output', action='store_true', help="Only print essential output (new directory, absolute path, etc.)")
123
188
  parser.add_argument('--no-output', action='store_true', help="Prevents the console from sending output")
124
-
125
189
  args = parser.parse_args()
126
190
 
127
191
  output = not args.no_output
128
192
  simple_output = args.simple_output
129
193
 
130
194
  if args.shell:
131
- print('''
195
+ print(r'''
132
196
  function twd() {
133
- output=$(python3 -m twd "$@");
197
+ output=$(python3 -m twd "$@");
134
198
  while IFS= read -r line; do
135
- type=$(echo "$line" | cut -d';' -f1);
136
- message=$(echo "$line" | cut -d';' -f2-);
137
- if [[ "$type" == "1" ]]; then
138
- eval "$message";
139
- else
140
- echo "$message";
141
- fi;
199
+ if [[ -z "$line" ]]; then
200
+ continue;
201
+ fi;
202
+ type=$(echo "$line" | cut -d';' -f1);
203
+ message=$(echo "$line" | cut -d';' -f2-);
204
+ if [[ "$type" == "1" ]]; then
205
+ eval "$message";
206
+ else
207
+ echo "$message";
208
+ fi;
142
209
  done <<< "$output";
143
210
  }
144
211
  ''')
145
212
  return 0
146
213
 
147
- if args.save is not None:
148
- save_directory(args.save if args.save else None, output, simple_output)
214
+ directory = args.directory or args.directory
215
+ alias = args.alias or args.alias
216
+
217
+ if args.save:
218
+ if not directory:
219
+ directory = args.directory or os.getcwd()
220
+
221
+ alias = args.alias or args.alias
222
+
223
+ save_directory(directory, alias, output, simple_output)
149
224
  elif args.go:
150
225
  return go_to_directory(output, simple_output)
151
226
  elif args.list:
152
227
  show_directory(output, simple_output)
153
228
  elif args.unset:
154
- unset_directory(output, simple_output)
229
+ force = args.force
230
+ unset_directory(output, simple_output, force)
155
231
  else:
156
232
  parser.print_help()
157
233
  return 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: twd_m4sc0
3
- Version: 1.4.0
3
+ Version: 1.5.1
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
@@ -35,7 +35,7 @@ pip install twd-m4sc0
35
35
  2. Add the following line to your `.bashrc` or `.zshrc` to set up the shell function:
36
36
 
37
37
  ```bash
38
- eval $(twd --shell)
38
+ eval $(python3 -m twd --shell)
39
39
  ```
40
40
 
41
41
  3. Exit and reopen the terminal or reload using:
@@ -110,6 +110,19 @@ user:~/.config $ twd -s
110
110
  Saved TWD to /home/user/.config
111
111
  ```
112
112
 
113
+ #### Force
114
+
115
+ Forces an action
116
+
117
+ > Currently only implemented on the `-u` flag
118
+
119
+ - Example
120
+
121
+ ```bash
122
+ user:~/.config $ twd -u --force
123
+ TWD File deleted and TWD unset
124
+ ```
125
+
113
126
  # Contribution
114
127
 
115
128
  To set up a dev environment:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes