ptrack


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


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]',