ptrack


Logs | Files | README | README | LICENSE | LICENSE | GitLab


1
commit dda9a73be807cf08e65895e2796decaeae0109b9
2
Author: Connor Etherington <[email protected]>
3
Date:   Sat Jul 29 19:08:50 2023 +0200
4
5
    Auto-Commit Update - 20230729
6
---
7
 PKGBUILD                             |   2 +-
8
 README.md                            |  14 ++--
9
 build/lib/ptrack/__init__.py         |  16 +++++
10
 build/lib/ptrack/main.py             | 134 +++++++++++++++++++++++++++++++++++
11
 build/lib/ptrack/methods.py          |  94 ++++++++++++++++++++++++
12
 dist/ptrack-0.1.4-py3-none-any.whl   | Bin 0 -> 5267 bytes
13
 dist/ptrack-0.1.4.tar.gz             | Bin 0 -> 4096 bytes
14
 ptrack.egg-info/PKG-INFO             |   7 ++
15
 ptrack.egg-info/SOURCES.txt          |  12 ++++
16
 ptrack.egg-info/dependency_links.txt |   1 +
17
 ptrack.egg-info/entry_points.txt     |   4 ++
18
 ptrack.egg-info/requires.txt         |   3 +
19
 ptrack.egg-info/top_level.txt        |   1 +
20
 ptrack/__init__.py                   |   4 +-
21
 recipe/meta.yaml                     |   2 +-
22
 setup.py                             |   2 +-
23
 16 files changed, 284 insertions(+), 12 deletions(-)
24
25
diff --git a/PKGBUILD b/PKGBUILD
26
index ba4b793..90ce729 100644
27
--- a/PKGBUILD
28
+++ b/PKGBUILD
29
@@ -1,7 +1,7 @@
30
 # Maintainer: Connor Etherington <[email protected]>
31
 # ---
32
 pkgname=ptrack
33
-pkgver=0.1.2
34
+pkgver=0.1.4
35
 pkgrel=1
36
 pkgdesc="A simple CLI utility for asthetically tracking progress when copying or moving files"
37
 arch=(x86_64)
38
diff --git a/README.md b/README.md
39
index 650dcf4..b3f3218 100644
40
--- a/README.md
41
+++ b/README.md
42
@@ -1,11 +1,11 @@
43
 
44
-usage: ptrack [-h] [-v] [-c] [-m]
45
+    usage: ptrack [-h] [-v] [-c] [-m]
46
 
47
-A simple CLI utility for asthetically tracking progress when copying or moving files.
48
+    A simple CLI utility for asthetically tracking progress when copying or moving files.
49
 
50
-options:
51
-  -h, --help     show this help message and exit
52
-  -v, --verbose  verbose output
53
-  -c, --copy     copy files (You can use `ptc` instead of `ptrack -c`)
54
-  -m, --move     move files (You can use `ptm` instead of `ptrack -m`)
55
+    options:
56
+      -h, --help     show this help message and exit
57
+      -v, --verbose  verbose output
58
+      -c, --copy     copy files (You can use `ptc` instead of `ptrack -c`)
59
+      -m, --move     move files (You can use `ptm` instead of `ptrack -m`)
60
 
61
diff --git a/build/lib/ptrack/__init__.py b/build/lib/ptrack/__init__.py
62
new file mode 100644
63
index 0000000..57693c9
64
--- /dev/null
65
+++ b/build/lib/ptrack/__init__.py
66
@@ -0,0 +1,16 @@
67
+import argparse
68
+import argcomplete
69
+version="0.1.4"
70
+
71
+parser = argparse.ArgumentParser(description='A simple CLI utility for asthetically tracking progress when copying or moving files.')
72
+parser.add_argument('-v', '--verbose', action='store_true', help='verbose output')
73
+parser.add_argument('-c', '--copy', action='store_true', help='copy files (You can use `ptc` instead of `ptrack -c`)')
74
+parser.add_argument('-m', '--move', action='store_true', help='move files (You can use `ptm` instead of `ptrack -m`)')
75
+parser.add_argument('-V', '--version', action='version', version='%(prog)s' + version)
76
+
77
+argcomplete.autocomplete(parser)
78
+args, unknown = parser.parse_known_args()
79
+
80
+verbose = args.verbose
81
+copy = args.copy
82
+move = args.move
83
diff --git a/build/lib/ptrack/main.py b/build/lib/ptrack/main.py
84
new file mode 100644
85
index 0000000..cc43997
86
--- /dev/null
87
+++ b/build/lib/ptrack/main.py
88
@@ -0,0 +1,134 @@
89
+import os
90
+import sys
91
+import ptrack
92
+from ptrack.methods import format_file_size, regular_copy, verbose_copy, hlp, getTotalSize
93
+from rich.progress import Progress, BarColumn, TextColumn, TimeRemainingColumn, FileSizeColumn
94
+from rich.console import Console
95
+import shutil
96
+
97
+verbose = ptrack.verbose
98
+argCopy = ptrack.copy
99
+argMove = ptrack.move
100
+
101
+
102
+def run(process):
103
+    console = Console()
104
+
105
+    if len(sys.argv) < 3:
106
+        hlp()
107
+        if process == "Copying":
108
+            console.print("[bold cyan]Usage: ptc [OPTIONS] SOURCE... DESTINATION[/bold cyan]")
109
+        elif process == "Moving":
110
+            console.print("[bold cyan]Usage: ptm [OPTIONS] SOURCE... DESTINATION[/bold cyan]")
111
+        sys.exit(1)
112
+
113
+    src_paths = sys.argv[1:-1]
114
+    dst = sys.argv[-1]
115
+    srcPaths = []
116
+
117
+    for path in src_paths:
118
+        if path.endswith('/'):
119
+            path = path[:-1]
120
+        srcPaths.append(path)
121
+
122
+    if os.path.isdir(dst):
123
+        dst_dir = dst
124
+        new_name = None
125
+    else:
126
+        dst_dir = os.path.dirname(dst)
127
+        new_name = os.path.basename(dst)
128
+
129
+    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))
130
+    total_size = getTotalSize(srcPaths)
131
+
132
+    current_file = 1
133
+
134
+    if total_files > 1:
135
+        console.print(f"\n[#ea2a6f]{process}:[/#ea2a6f] [bold cyan]{total_files} files[/bold cyan]\n")
136
+    else:
137
+        for src_path in srcPaths:
138
+            if os.path.isfile(src_path):
139
+                console.print(f"\n[#ea2a6f]{process}:[/#ea2a6f] [bold cyan] {os.path.basename(src_path)} [/bold cyan]\n")
140
+
141
+    if verbose:
142
+        for src_path in srcPaths:
143
+            if os.path.isfile(src_path):
144
+                dst_path = os.path.join(dst_dir, os.path.basename(src_path) if not new_name else new_name)
145
+                terminate = verbose_copy(src_path, dst_path, console, current_file, total_files)
146
+                current_file += 1
147
+                if terminate == 'c':
148
+                    console.print("\n[bold red]\[-][/bold red][bold white] Operation cancelled by user.[/bold white]\n")
149
+                    sys.exit(1)
150
+            else:
151
+                for root, dirs, files in os.walk(src_path):
152
+                    for file in files:
153
+                        src_file_path = os.path.join(root, file)
154
+                        relative_path = os.path.relpath(src_file_path, start=src_path)
155
+                        dst_file_path = os.path.join(dst_dir, os.path.basename(src_path) if not new_name else new_name, relative_path)
156
+                        os.makedirs(os.path.dirname(dst_file_path), exist_ok=True)
157
+                        terminate = verbose_copy(src_file_path, dst_file_path, console, current_file, total_files)
158
+                        current_file += 1
159
+                        if terminate == 'c':
160
+                            console.print("\n[bold red]\[-][/bold red][bold white] Operation cancelled by user.[/bold white]\n")
161
+                            sys.exit(1)
162
+    else:
163
+        with Progress(
164
+            BarColumn(bar_width=50),
165
+            "[progress.percentage]{task.percentage:>3.0f}%",
166
+            TimeRemainingColumn(),
167
+            "[#ea2a6f][[/#ea2a6f]",
168
+            FileSizeColumn(),
169
+            "[#ea2a6f]/[/#ea2a6f]",
170
+            TextColumn("[bold cyan]{task.fields[total_size]}[/bold cyan]"),
171
+            "[#ea2a6f]][/#ea2a6f]",
172
+            console=console,
173
+            auto_refresh=False
174
+        ) as progress:
175
+            task = progress.add_task("", total=total_size, total_size=format_file_size(total_size))
176
+
177
+            for src_path in srcPaths:
178
+                if os.path.isfile(src_path):
179
+                    dst_file_path = os.path.join(dst_dir, os.path.basename(src_path) if not new_name else new_name)
180
+                    terminate = regular_copy(src_path, dst_file_path, console, task, progress)
181
+                    if terminate == 'c':
182
+                        console.print("\n[bold red]\[-][/bold red][bold white] Operation cancelled by user.[/bold white]\n")
183
+                        sys.exit(1)
184
+                else:
185
+                    for root, dirs, files in os.walk(src_path):
186
+                        for file in files:
187
+                            src_file_path = os.path.join(root, file)
188
+                            relative_path = os.path.relpath(src_file_path, start=src_path)
189
+                            dst_file_path = os.path.join(dst_dir, os.path.basename(src_path) if not new_name else new_name, relative_path)
190
+                            os.makedirs(os.path.dirname(dst_file_path), exist_ok=True)
191
+                            terminate = regular_copy(src_file_path, dst_file_path, console, task, progress)
192
+                            if terminate == 'c':
193
+                                console.print("\n[bold red]\[-][/bold red][bold white] Operation cancelled by user.[/bold white]\n")
194
+                                sys.exit(1)
195
+
196
+    return srcPaths
197
+
198
+
199
+def copy():
200
+    run('Copying')
201
+
202
+
203
+def move():
204
+    src_paths = run('Moving')
205
+    for src_path in src_paths:
206
+        if os.path.isfile(src_path):
207
+            os.remove(src_path)
208
+        else:
209
+            shutil.rmtree(src_path)
210
+
211
+
212
+def main():
213
+    if argMove:
214
+        move()
215
+    elif argCopy:
216
+        copy()
217
+    else:
218
+        hlp()
219
+
220
+
221
+if __name__ == "__main__":
222
+    main()
223
diff --git a/build/lib/ptrack/methods.py b/build/lib/ptrack/methods.py
224
new file mode 100644
225
index 0000000..cbe9420
226
--- /dev/null
227
+++ b/build/lib/ptrack/methods.py
228
@@ -0,0 +1,94 @@
229
+import os
230
+from rich.progress import Progress, BarColumn, TextColumn, TimeRemainingColumn, FileSizeColumn
231
+
232
+
233
+def getTotalSize(srcPaths):
234
+    total_size = 0
235
+    for path in srcPaths:
236
+        if os.path.isfile(path):
237
+            total_size += os.path.getsize(path)
238
+        else:
239
+            for r, d, files in os.walk(path):
240
+                for f in files:
241
+                    fp = os.path.join(r, f)
242
+                    total_size += os.path.getsize(fp)
243
+    return total_size
244
+
245
+
246
+def format_file_size(file_size):
247
+    if file_size >= 1000 ** 4:  # Terabyte
248
+        return f"{round(file_size / (1000 ** 4))} TB"
249
+    elif file_size >= 1000 ** 3:  # Gigabyte
250
+        return f"{round(file_size / (1000 ** 3))} GB"
251
+    elif file_size >= 1000 ** 2:  # Megabyte
252
+        return f"{round(file_size / (1000 ** 2))} MB"
253
+    elif file_size >= 1000:  # Kilobyte
254
+        return f"{round(file_size / 1000)} kB"
255
+    else:  # Byte
256
+        return f"{file_size} bytes"
257
+
258
+
259
+def regular_copy(src, dst, console, task, progress):
260
+    operation_cancelled = False
261
+    try:
262
+        with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
263
+            while True:
264
+                buf = fsrc.read(1024*1024)
265
+                if not buf or operation_cancelled:
266
+                    break
267
+                fdst.write(buf)
268
+                progress.update(task, advance=len(buf))
269
+                progress.refresh()
270
+
271
+    except KeyboardInterrupt:
272
+        operation_cancelled = True
273
+        progress.stop()
274
+        return "c"
275
+
276
+
277
+def verbose_copy(src, dst, console, current, total_files):
278
+    operation_cancelled = False
279
+    file_size = os.path.getsize(src)
280
+
281
+    with Progress(
282
+        BarColumn(bar_width=50),
283
+        "[progress.percentage]{task.percentage:>3.0f}%",
284
+        TimeRemainingColumn(),
285
+        "[#ea2a6f][[/#ea2a6f]",
286
+        FileSizeColumn(),
287
+        "[#ea2a6f]/[/#ea2a6f]",
288
+        TextColumn(f"[bold cyan]{format_file_size(file_size)}[/bold cyan]"),
289
+        "[#ea2a6f]][/#ea2a6f]",
290
+        f"({current} of {total_files})",
291
+        console=console,
292
+        auto_refresh=False
293
+    ) as progress:
294
+        task = progress.add_task("", total=file_size, file_size=format_file_size(file_size))
295
+
296
+        try:
297
+            with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
298
+                while not progress.finished:
299
+                    buf = fsrc.read(1024*1024)
300
+                    if not buf or operation_cancelled:
301
+                        break
302
+                    fdst.write(buf)
303
+                    progress.update(task, advance=len(buf))
304
+                    progress.refresh()
305
+        except KeyboardInterrupt:
306
+            operation_cancelled = True
307
+            progress.stop()
308
+            return "c"
309
+
310
+
311
+def hlp():
312
+    print("""
313
+usage: ptrack [-h] [-v] [-c] [-m]
314
+
315
+A simple CLI utility for asthetically tracking progress when copying or moving files.
316
+
317
+options:
318
+  -h, --help     show this help message and exit
319
+  -v, --verbose  verbose output
320
+  -c, --copy     copy files (You can use `ptc` instead of `ptrack -c`)
321
+  -m, --move     move files (You can use `ptm` instead of `ptrack -m`)
322
+""")
323
diff --git a/dist/ptrack-0.1.4-py3-none-any.whl b/dist/ptrack-0.1.4-py3-none-any.whl
324
new file mode 100644
325
index 0000000..43fa218
326
Binary files /dev/null and b/dist/ptrack-0.1.4-py3-none-any.whl differ
327
diff --git a/dist/ptrack-0.1.4.tar.gz b/dist/ptrack-0.1.4.tar.gz
328
new file mode 100644
329
index 0000000..5363d37
330
Binary files /dev/null and b/dist/ptrack-0.1.4.tar.gz differ
331
diff --git a/ptrack.egg-info/PKG-INFO b/ptrack.egg-info/PKG-INFO
332
new file mode 100644
333
index 0000000..f873109
334
--- /dev/null
335
+++ b/ptrack.egg-info/PKG-INFO
336
@@ -0,0 +1,7 @@
337
+Metadata-Version: 2.1
338
+Name: ptrack
339
+Version: 0.1.4
340
+Summary: A simple CLI utility for asthetically tracking progress when copying or moving files.
341
+Author: Connor Etherington
342
+Author-email: [email protected]
343
+License-File: LICENSE
344
diff --git a/ptrack.egg-info/SOURCES.txt b/ptrack.egg-info/SOURCES.txt
345
new file mode 100644
346
index 0000000..086a784
347
--- /dev/null
348
+++ b/ptrack.egg-info/SOURCES.txt
349
@@ -0,0 +1,12 @@
350
+LICENSE
351
+README.md
352
+setup.py
353
+ptrack/__init__.py
354
+ptrack/main.py
355
+ptrack/methods.py
356
+ptrack.egg-info/PKG-INFO
357
+ptrack.egg-info/SOURCES.txt
358
+ptrack.egg-info/dependency_links.txt
359
+ptrack.egg-info/entry_points.txt
360
+ptrack.egg-info/requires.txt
361
+ptrack.egg-info/top_level.txt
362
diff --git a/ptrack.egg-info/dependency_links.txt b/ptrack.egg-info/dependency_links.txt
363
new file mode 100644
364
index 0000000..8b13789
365
--- /dev/null
366
+++ b/ptrack.egg-info/dependency_links.txt
367
@@ -0,0 +1 @@
368
+
369
diff --git a/ptrack.egg-info/entry_points.txt b/ptrack.egg-info/entry_points.txt
370
new file mode 100644
371
index 0000000..32a28e4
372
--- /dev/null
373
+++ b/ptrack.egg-info/entry_points.txt
374
@@ -0,0 +1,4 @@
375
+[console_scripts]
376
+ptc = ptrack.main:copy
377
+ptm = ptrack.main:move
378
+ptrack = ptrack.main:main
379
diff --git a/ptrack.egg-info/requires.txt b/ptrack.egg-info/requires.txt
380
new file mode 100644
381
index 0000000..382c1b3
382
--- /dev/null
383
+++ b/ptrack.egg-info/requires.txt
384
@@ -0,0 +1,3 @@
385
+rich
386
+argparse
387
+argcomplete
388
diff --git a/ptrack.egg-info/top_level.txt b/ptrack.egg-info/top_level.txt
389
new file mode 100644
390
index 0000000..c003217
391
--- /dev/null
392
+++ b/ptrack.egg-info/top_level.txt
393
@@ -0,0 +1 @@
394
+ptrack
395
diff --git a/ptrack/__init__.py b/ptrack/__init__.py
396
index 8104dff..57693c9 100644
397
--- a/ptrack/__init__.py
398
+++ b/ptrack/__init__.py
399
@@ -1,12 +1,12 @@
400
 import argparse
401
 import argcomplete
402
-version = '0.1.2'
403
+version="0.1.4"
404
 
405
 parser = argparse.ArgumentParser(description='A simple CLI utility for asthetically tracking progress when copying or moving files.')
406
 parser.add_argument('-v', '--verbose', action='store_true', help='verbose output')
407
 parser.add_argument('-c', '--copy', action='store_true', help='copy files (You can use `ptc` instead of `ptrack -c`)')
408
 parser.add_argument('-m', '--move', action='store_true', help='move files (You can use `ptm` instead of `ptrack -m`)')
409
-parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + version)
410
+parser.add_argument('-V', '--version', action='version', version='%(prog)s' + version)
411
 
412
 argcomplete.autocomplete(parser)
413
 args, unknown = parser.parse_known_args()
414
diff --git a/recipe/meta.yaml b/recipe/meta.yaml
415
index a42a955..ce63995 100644
416
--- a/recipe/meta.yaml
417
+++ b/recipe/meta.yaml
418
@@ -1,6 +1,6 @@
419
 package:
420
   name: ptrack
421
-  version: 0.1.2
422
+  version: 0.1.4
423
 
424
 source:
425
   path: ..
426
diff --git a/setup.py b/setup.py
427
index b67d259..9447900 100644
428
--- a/setup.py
429
+++ b/setup.py
430
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
431
 
432
 setup(
433
     name='ptrack',
434
-    version='0.1.2',
435
+    version="0.1.4",
436
     description='A simple CLI utility for asthetically tracking progress when copying or moving files.',
437
     author='Connor Etherington',
438
     author_email='[email protected]',