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.
- {twd_m4sc0-1.4.0/twd_m4sc0.egg-info → twd_m4sc0-1.5.1}/PKG-INFO +15 -2
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/README.md +14 -1
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/setup.py +1 -1
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/twd/twd.py +105 -29
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1/twd_m4sc0.egg-info}/PKG-INFO +15 -2
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/LICENSE +0 -0
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/setup.cfg +0 -0
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/tests/__init__.py +0 -0
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/tests/test_twd.py +0 -0
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/twd/__init__.py +0 -0
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/twd/__main__.py +0 -0
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/twd_m4sc0.egg-info/SOURCES.txt +0 -0
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/twd_m4sc0.egg-info/dependency_links.txt +0 -0
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/twd_m4sc0.egg-info/entry_points.txt +0 -0
- {twd_m4sc0-1.4.0 → twd_m4sc0-1.5.1}/twd_m4sc0.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: twd_m4sc0
|
|
3
|
-
Version: 1.
|
|
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,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
|
-
|
|
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
|
|
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
|
-
|
|
66
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
110
|
+
dirs = load_directory()
|
|
78
111
|
|
|
79
|
-
if
|
|
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
|
-
|
|
127
|
+
dirs = load_directory()
|
|
92
128
|
|
|
93
|
-
if
|
|
129
|
+
if not dirs:
|
|
94
130
|
output_handler("No TWD set", None, output, simple_output)
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|