| Hash | Commit message | Author | Date | Files | + | - |
1 | commit 972c9829e0755b28fb0013bcf95cab96e8f55d6d |
2 | Author: Connor Etherington <[email protected]> |
3 | Date: Sat Jul 29 13:13:32 2023 +0200 |
4 | |
5 | Auto-Commit Update 29.07.2023 - 13:13:32 |
6 | --- |
7 | PKGBUILD | 2 +- |
8 | ptrack.egg-info/PKG-INFO | 7 ---- |
9 | ptrack.egg-info/SOURCES.txt | 12 ------ |
10 | ptrack.egg-info/dependency_links.txt | 1 - |
11 | ptrack.egg-info/entry_points.txt | 4 -- |
12 | ptrack.egg-info/requires.txt | 3 -- |
13 | ptrack.egg-info/top_level.txt | 1 - |
14 | ptrack/__init__.py | 2 + |
15 | ptrack/main.py | 25 +++++++++--- |
16 | ptrack/methods.py | 75 ++++++++++++++++++++++++------------ |
17 | recipe/meta.yaml | 29 ++++++++++++++ |
18 | setup.py | 2 +- |
19 | 12 files changed, 103 insertions(+), 60 deletions(-) |
20 | |
21 | diff --git a/PKGBUILD b/PKGBUILD |
22 | index 3e6a68c..ba4b793 100644 |
23 | --- a/PKGBUILD |
24 | +++ b/PKGBUILD |
25 | @@ -1,7 +1,7 @@ |
26 | # Maintainer: Connor Etherington <[email protected]> |
27 | # --- |
28 | pkgname=ptrack |
29 | -pkgver=0.1.0 |
30 | +pkgver=0.1.2 |
31 | pkgrel=1 |
32 | pkgdesc="A simple CLI utility for asthetically tracking progress when copying or moving files" |
33 | arch=(x86_64) |
34 | diff --git a/ptrack.egg-info/PKG-INFO b/ptrack.egg-info/PKG-INFO |
35 | deleted file mode 100644 |
36 | index e347788..0000000 |
37 | --- a/ptrack.egg-info/PKG-INFO |
38 | +++ /dev/null |
39 | @@ -1,7 +0,0 @@ |
40 | -Metadata-Version: 2.1 |
41 | -Name: ptrack |
42 | -Version: 0.1.0 |
43 | -Summary: A simple CLI utility for asthetically tracking progress when copying or moving files. |
44 | -Author: Connor Etherington |
45 | -Author-email: [email protected] |
46 | -License-File: LICENSE |
47 | diff --git a/ptrack.egg-info/SOURCES.txt b/ptrack.egg-info/SOURCES.txt |
48 | deleted file mode 100644 |
49 | index 086a784..0000000 |
50 | --- a/ptrack.egg-info/SOURCES.txt |
51 | +++ /dev/null |
52 | @@ -1,12 +0,0 @@ |
53 | -LICENSE |
54 | -README.md |
55 | -setup.py |
56 | -ptrack/__init__.py |
57 | -ptrack/main.py |
58 | -ptrack/methods.py |
59 | -ptrack.egg-info/PKG-INFO |
60 | -ptrack.egg-info/SOURCES.txt |
61 | -ptrack.egg-info/dependency_links.txt |
62 | -ptrack.egg-info/entry_points.txt |
63 | -ptrack.egg-info/requires.txt |
64 | -ptrack.egg-info/top_level.txt |
65 | diff --git a/ptrack.egg-info/dependency_links.txt b/ptrack.egg-info/dependency_links.txt |
66 | deleted file mode 100644 |
67 | index 8b13789..0000000 |
68 | --- a/ptrack.egg-info/dependency_links.txt |
69 | +++ /dev/null |
70 | @@ -1 +0,0 @@ |
71 | - |
72 | diff --git a/ptrack.egg-info/entry_points.txt b/ptrack.egg-info/entry_points.txt |
73 | deleted file mode 100644 |
74 | index 32a28e4..0000000 |
75 | --- a/ptrack.egg-info/entry_points.txt |
76 | +++ /dev/null |
77 | @@ -1,4 +0,0 @@ |
78 | -[console_scripts] |
79 | -ptc = ptrack.main:copy |
80 | -ptm = ptrack.main:move |
81 | -ptrack = ptrack.main:main |
82 | diff --git a/ptrack.egg-info/requires.txt b/ptrack.egg-info/requires.txt |
83 | deleted file mode 100644 |
84 | index 382c1b3..0000000 |
85 | --- a/ptrack.egg-info/requires.txt |
86 | +++ /dev/null |
87 | @@ -1,3 +0,0 @@ |
88 | -rich |
89 | -argparse |
90 | -argcomplete |
91 | diff --git a/ptrack.egg-info/top_level.txt b/ptrack.egg-info/top_level.txt |
92 | deleted file mode 100644 |
93 | index c003217..0000000 |
94 | --- a/ptrack.egg-info/top_level.txt |
95 | +++ /dev/null |
96 | @@ -1 +0,0 @@ |
97 | -ptrack |
98 | diff --git a/ptrack/__init__.py b/ptrack/__init__.py |
99 | index 919fce7..8104dff 100644 |
100 | --- a/ptrack/__init__.py |
101 | +++ b/ptrack/__init__.py |
102 | @@ -1,10 +1,12 @@ |
103 | import argparse |
104 | import argcomplete |
105 | +version = '0.1.2' |
106 | |
107 | parser = argparse.ArgumentParser(description='A simple CLI utility for asthetically tracking progress when copying or moving files.') |
108 | parser.add_argument('-v', '--verbose', action='store_true', help='verbose output') |
109 | parser.add_argument('-c', '--copy', action='store_true', help='copy files (You can use `ptc` instead of `ptrack -c`)') |
110 | parser.add_argument('-m', '--move', action='store_true', help='move files (You can use `ptm` instead of `ptrack -m`)') |
111 | +parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + version) |
112 | |
113 | argcomplete.autocomplete(parser) |
114 | args, unknown = parser.parse_known_args() |
115 | diff --git a/ptrack/main.py b/ptrack/main.py |
116 | index e52edf0..cc43997 100644 |
117 | --- a/ptrack/main.py |
118 | +++ b/ptrack/main.py |
119 | @@ -1,7 +1,7 @@ |
120 | import os |
121 | import sys |
122 | import ptrack |
123 | -from ptrack.methods import format_file_size, regular_copy, verbose_copy, hlp |
124 | +from ptrack.methods import format_file_size, regular_copy, verbose_copy, hlp, getTotalSize |
125 | from rich.progress import Progress, BarColumn, TextColumn, TimeRemainingColumn, FileSizeColumn |
126 | from rich.console import Console |
127 | import shutil |
128 | @@ -39,7 +39,8 @@ def run(process): |
129 | new_name = os.path.basename(dst) |
130 | |
131 | total_files = sum(len(files) for path in srcPaths for r, d, files in os.walk(path) if os.path.isdir(path)) + sum(1 for path in srcPaths if os.path.isfile(path)) |
132 | - total_size = sum(os.path.getsize(os.path.join(r, f)) for path in srcPaths for r, d, files in os.walk(path) for f in files) + sum(os.path.getsize(path) for path in srcPaths if os.path.isfile(path)) |
133 | + total_size = getTotalSize(srcPaths) |
134 | + |
135 | current_file = 1 |
136 | |
137 | if total_files > 1: |
138 | @@ -53,8 +54,11 @@ def run(process): |
139 | for src_path in srcPaths: |
140 | if os.path.isfile(src_path): |
141 | dst_path = os.path.join(dst_dir, os.path.basename(src_path) if not new_name else new_name) |
142 | - verbose_copy(src_path, dst_path, console, current_file, total_files) |
143 | + terminate = verbose_copy(src_path, dst_path, console, current_file, total_files) |
144 | current_file += 1 |
145 | + if terminate == 'c': |
146 | + console.print("\n[bold red]\[-][/bold red][bold white] Operation cancelled by user.[/bold white]\n") |
147 | + sys.exit(1) |
148 | else: |
149 | for root, dirs, files in os.walk(src_path): |
150 | for file in files: |
151 | @@ -62,8 +66,11 @@ def run(process): |
152 | relative_path = os.path.relpath(src_file_path, start=src_path) |
153 | dst_file_path = os.path.join(dst_dir, os.path.basename(src_path) if not new_name else new_name, relative_path) |
154 | os.makedirs(os.path.dirname(dst_file_path), exist_ok=True) |
155 | - verbose_copy(src_file_path, dst_file_path, console, current_file, total_files) |
156 | + terminate = verbose_copy(src_file_path, dst_file_path, console, current_file, total_files) |
157 | current_file += 1 |
158 | + if terminate == 'c': |
159 | + console.print("\n[bold red]\[-][/bold red][bold white] Operation cancelled by user.[/bold white]\n") |
160 | + sys.exit(1) |
161 | else: |
162 | with Progress( |
163 | BarColumn(bar_width=50), |
164 | @@ -82,7 +89,10 @@ def run(process): |
165 | for src_path in srcPaths: |
166 | if os.path.isfile(src_path): |
167 | dst_file_path = os.path.join(dst_dir, os.path.basename(src_path) if not new_name else new_name) |
168 | - regular_copy(src_path, dst_file_path, console, task, progress) |
169 | + terminate = regular_copy(src_path, dst_file_path, console, task, progress) |
170 | + if terminate == 'c': |
171 | + console.print("\n[bold red]\[-][/bold red][bold white] Operation cancelled by user.[/bold white]\n") |
172 | + sys.exit(1) |
173 | else: |
174 | for root, dirs, files in os.walk(src_path): |
175 | for file in files: |
176 | @@ -90,7 +100,10 @@ def run(process): |
177 | relative_path = os.path.relpath(src_file_path, start=src_path) |
178 | dst_file_path = os.path.join(dst_dir, os.path.basename(src_path) if not new_name else new_name, relative_path) |
179 | os.makedirs(os.path.dirname(dst_file_path), exist_ok=True) |
180 | - regular_copy(src_file_path, dst_file_path, console, task, progress) |
181 | + terminate = regular_copy(src_file_path, dst_file_path, console, task, progress) |
182 | + if terminate == 'c': |
183 | + console.print("\n[bold red]\[-][/bold red][bold white] Operation cancelled by user.[/bold white]\n") |
184 | + sys.exit(1) |
185 | |
186 | return srcPaths |
187 | |
188 | diff --git a/ptrack/methods.py b/ptrack/methods.py |
189 | index 1c5e851..674c7e3 100644 |
190 | --- a/ptrack/methods.py |
191 | +++ b/ptrack/methods.py |
192 | @@ -2,30 +2,52 @@ import os |
193 | from rich.progress import Progress, BarColumn, TextColumn, TimeRemainingColumn, FileSizeColumn |
194 | |
195 | |
196 | +def getTotalSize(srcPaths): |
197 | + total_size = 0 |
198 | + for path in srcPaths: |
199 | + if os.path.isfile(path): |
200 | + total_size += os.path.getsize(path) |
201 | + else: |
202 | + for r, d, files in os.walk(path): |
203 | + for f in files: |
204 | + fp = os.path.join(r, f) |
205 | + total_size += os.path.getsize(fp) |
206 | + return total_size |
207 | + |
208 | + |
209 | def format_file_size(file_size): |
210 | - if file_size >= 1024 * 1024 * 1024: |
211 | - return f"{file_size / (1024*1024*1024):.2f} GB" |
212 | - elif file_size >= 1024 * 1024: |
213 | - return f"{file_size / (1024*1024):.2f} MB" |
214 | - elif file_size >= 1024: |
215 | - return f"{file_size / 1024:.2f} kB" |
216 | - else: |
217 | + if file_size >= 1000 ** 4: # Terabyte |
218 | + return f"{round(file_size / (1000 ** 4))} TB" |
219 | + elif file_size >= 1000 ** 3: # Gigabyte |
220 | + return f"{round(file_size / (1000 ** 3))} GB" |
221 | + elif file_size >= 1000 ** 2: # Megabyte |
222 | + return f"{round(file_size / (1000 ** 2))} MB" |
223 | + elif file_size >= 1000: # Kilobyte |
224 | + return f"{round(file_size / 1000)} kB" |
225 | + else: # Byte |
226 | return f"{file_size} bytes" |
227 | |
228 | |
229 | def regular_copy(src, dst, console, task, progress): |
230 | - with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst: |
231 | - while True: |
232 | - buf = fsrc.read(1024*1024) |
233 | - if not buf: |
234 | - break |
235 | - fdst.write(buf) |
236 | - progress.update(task, advance=len(buf)) |
237 | - progress.refresh() |
238 | + operation_cancelled = False |
239 | + try: |
240 | + with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst: |
241 | + while True: |
242 | + buf = fsrc.read(1024*1024) |
243 | + if operation_cancelled: |
244 | + return "c" |
245 | + fdst.write(buf) |
246 | + progress.update(task, advance=len(buf)) |
247 | + progress.refresh() |
248 | |
249 | + except KeyboardInterrupt: |
250 | + operation_cancelled = True |
251 | + progress.stop() |
252 | + return "c" |
253 | |
254 | -def verbose_copy(src, dst, console, current, total_files): |
255 | |
256 | +def verbose_copy(src, dst, console, current, total_files): |
257 | + operation_cancelled = False |
258 | file_size = os.path.getsize(src) |
259 | |
260 | with Progress( |
261 | @@ -43,14 +65,19 @@ def verbose_copy(src, dst, console, current, total_files): |
262 | ) as progress: |
263 | task = progress.add_task("", total=file_size, file_size=format_file_size(file_size)) |
264 | |
265 | - with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst: |
266 | - while not progress.finished: |
267 | - buf = fsrc.read(1024*1024) |
268 | - if not buf: |
269 | - break |
270 | - fdst.write(buf) |
271 | - progress.update(task, advance=len(buf)) |
272 | - progress.refresh() |
273 | + try: |
274 | + with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst: |
275 | + while not progress.finished: |
276 | + buf = fsrc.read(1024*1024) |
277 | + if operation_cancelled: |
278 | + return "c" |
279 | + fdst.write(buf) |
280 | + progress.update(task, advance=len(buf)) |
281 | + progress.refresh() |
282 | + except KeyboardInterrupt: |
283 | + operation_cancelled = True |
284 | + progress.stop() |
285 | + return "c" |
286 | |
287 | |
288 | def hlp(): |
289 | diff --git a/recipe/meta.yaml b/recipe/meta.yaml |
290 | new file mode 100644 |
291 | index 0000000..a42a955 |
292 | --- /dev/null |
293 | +++ b/recipe/meta.yaml |
294 | @@ -0,0 +1,29 @@ |
295 | +package: |
296 | + name: ptrack |
297 | + version: 0.1.2 |
298 | + |
299 | +source: |
300 | + path: .. |
301 | + |
302 | +build: |
303 | + number: 0 |
304 | + script: '{{ PYTHON }} -m pip install . --no-deps -vv' |
305 | + |
306 | +requirements: |
307 | + host: |
308 | + - python |
309 | + - pip |
310 | + run: |
311 | + - python |
312 | + - "numpy<=1.24" |
313 | + - pandas |
314 | + |
315 | +about: |
316 | + home: https://gitlab.com/a4to/ptrack |
317 | + license: MIT |
318 | + license_file: LICENSE |
319 | + summary: 'A simple CLI utility for aesthetically tracking progress when copying or moving files' |
320 | + |
321 | +extra: |
322 | + recipe-maintainers: |
323 | + - concise |
324 | diff --git a/setup.py b/setup.py |
325 | index fdea560..b67d259 100644 |
326 | --- a/setup.py |
327 | +++ b/setup.py |
328 | @@ -2,7 +2,7 @@ from setuptools import setup, find_packages |
329 | |
330 | setup( |
331 | name='ptrack', |
332 | - version='0.1.0', |
333 | + version='0.1.2', |
334 | description='A simple CLI utility for asthetically tracking progress when copying or moving files.', |
335 | author='Connor Etherington', |
336 | author_email='[email protected]', |