flacopyus 0.4.2__tar.gz → 0.4.3__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.
Files changed (32) hide show
  1. {flacopyus-0.4.2/flacopyus.egg-info → flacopyus-0.4.3}/PKG-INFO +1 -1
  2. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/__init__.py +1 -1
  3. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/main.py +103 -67
  4. {flacopyus-0.4.2 → flacopyus-0.4.3/flacopyus.egg-info}/PKG-INFO +1 -1
  5. {flacopyus-0.4.2 → flacopyus-0.4.3}/LICENSE +0 -0
  6. {flacopyus-0.4.2 → flacopyus-0.4.3}/MANIFEST.in +0 -0
  7. {flacopyus-0.4.2 → flacopyus-0.4.3}/README.md +0 -0
  8. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/__main__.py +0 -0
  9. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/args.py +0 -0
  10. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/assets.py +0 -0
  11. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/audio/drum-loop.flac +0 -0
  12. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/audio/system-shutdown.wav +0 -0
  13. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/bin/LICENSE +0 -0
  14. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/bin/opusenc.exe +0 -0
  15. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/cli.py +0 -0
  16. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/filesys.py +0 -0
  17. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/funs.py +0 -0
  18. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/opus.py +0 -0
  19. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/py.typed +0 -0
  20. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/pyinstaller/hook-flacopyus.py +0 -0
  21. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/spr.py +0 -0
  22. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/stdio.py +0 -0
  23. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus/test.py +0 -0
  24. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus.egg-info/SOURCES.txt +0 -0
  25. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus.egg-info/dependency_links.txt +0 -0
  26. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus.egg-info/entry_points.txt +0 -0
  27. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus.egg-info/requires.txt +0 -0
  28. {flacopyus-0.4.2 → flacopyus-0.4.3}/flacopyus.egg-info/top_level.txt +0 -0
  29. {flacopyus-0.4.2 → flacopyus-0.4.3}/images/FlacopyusFlow.png +0 -0
  30. {flacopyus-0.4.2 → flacopyus-0.4.3}/images/FlacopyusStill.png +0 -0
  31. {flacopyus-0.4.2 → flacopyus-0.4.3}/pyproject.toml +0 -0
  32. {flacopyus-0.4.2 → flacopyus-0.4.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flacopyus
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: CLI tool to mirror your FLAC audio library to a portable lossy Opus version
5
5
  Maintainer-email: curegit <contact@curegit.jp>
6
6
  License-Expression: GPL-3.0-or-later
@@ -1,4 +1,4 @@
1
- __version__ = "0.4.2"
1
+ __version__ = "0.4.3"
2
2
 
3
3
 
4
4
  def pyinstaller_hooks_dir():
@@ -36,6 +36,8 @@ def main(
36
36
  prefer_external: bool = False,
37
37
  verbose: bool = False,
38
38
  ) -> int:
39
+ summery_message: str = ""
40
+
39
41
  progress_display = progress_bar(error_console)
40
42
  with progress_display:
41
43
  with get_opusenc(opusenc_executable=opusenc_executable, prefer_external=prefer_external, verbose=verbose) as opusenc_binary:
@@ -214,7 +216,8 @@ def main(
214
216
  # 42 is heuristic
215
217
  if i % 42 == 0:
216
218
  progress_display.update(task, total=len(pending), refresh=True)
217
- progress_display.update(task, total=len(pending), refresh=True)
219
+ total_traversed_count = len(pending)
220
+ progress_display.update(task, total=total_traversed_count, refresh=True)
218
221
  # Finish remaining tasks
219
222
  with lock_for_encoding:
220
223
  task_e = progress_display.add_task("Encoding", total=len(for_encoding))
@@ -229,6 +232,7 @@ def main(
229
232
  done_encoding_count += 1
230
233
  progress_display.update(task, advance=len(done), refresh=True)
231
234
  progress_display.update(task_e, completed=done_encoding_count, total=len(for_encoding), refresh=True)
235
+ summery_message += f"{done_encoding_count} files encoded, {total_traversed_count - done_encoding_count} files already up-to-date"
232
236
  except KeyboardInterrupt, Exception:
233
237
  # Exit quickly when interrupted/failed
234
238
  executor.shutdown(cancel_futures=True)
@@ -242,11 +246,15 @@ def main(
242
246
  sync_disk(d_fp)
243
247
 
244
248
  def copy_task(s: Path, d: Path, /):
249
+ is_for_copying = False
245
250
  if d.is_symlink():
246
251
  remove_symlink_from_dest(d)
247
252
  if d.is_dir():
248
253
  remove_folder_from_dest(d)
249
254
  if not d.exists():
255
+ is_for_copying = True
256
+ with lock_for_copying:
257
+ for_copying.append(s)
250
258
  copyfile_fsync(s, d)
251
259
  copy_mtime(s, d)
252
260
  if verbose:
@@ -262,6 +270,9 @@ def main(
262
270
  if not updated_checksum:
263
271
  updated = False
264
272
  if not updated:
273
+ is_for_copying = True
274
+ with lock_for_copying:
275
+ for_copying.append(s)
265
276
  copyfile_fsync(s, d)
266
277
  copy_mtime(mtime_sec_or_ns, d)
267
278
  if verbose:
@@ -270,7 +281,7 @@ def main(
270
281
  fix_case_file(d)
271
282
  with lock_delete_flags:
272
283
  would_delete_flags[d] = False
273
- return True
284
+ return is_for_copying
274
285
 
275
286
  def make_copy_map(pool, pending, /):
276
287
  def copy_map(s, d):
@@ -280,73 +291,98 @@ def main(
280
291
  return copy_map
281
292
 
282
293
  pending_cp: list[tuple[Path, Future[bool]]] = []
283
- with ThreadPoolExecutor(max_workers=copying_concurrency) as executor_cp:
284
- try:
285
- for _ in itreemap(
286
- make_copy_map(executor_cp, pending_cp),
287
- src,
288
- dest=dest,
289
- extmap=copy_exts,
290
- mkdir=True,
291
- mkdir_empty=False,
292
- follow_symlinks=True,
293
- include_broken_symlinks=False,
294
- error_broken_symlinks=False,
295
- progress=False,
296
- ):
297
- pass
298
- task_c = progress_display.add_task("Copying", total=len(pending_cp))
294
+ for_copying: list[Path] = []
295
+ lock_for_copying = RLock()
296
+ if copy_exts:
297
+ with ThreadPoolExecutor(max_workers=copying_concurrency) as executor_cp:
298
+ task_c = progress_display.add_task("Traversing (copy)", total=len(pending_cp))
299
+ try:
300
+ for i, _ in enumerate(
301
+ itreemap(
302
+ make_copy_map(executor_cp, pending_cp),
303
+ src,
304
+ dest=dest,
305
+ extmap=copy_exts,
306
+ mkdir=True,
307
+ mkdir_empty=False,
308
+ fix_case=fix_case,
309
+ follow_symlinks=True,
310
+ include_broken_symlinks=False,
311
+ error_broken_symlinks=False,
312
+ progress=False,
313
+ )
314
+ ):
315
+ # 42 is heuristic
316
+ if i % 42 == 0:
317
+ progress_display.update(task_c, total=len(pending_cp), refresh=True)
318
+ progress_display.update(task_c, total=len(pending_cp), refresh=True)
319
+ # Finish remaining tasks
320
+ with lock_for_copying:
321
+ task_cp = progress_display.add_task("Copying", total=len(for_copying))
322
+ done_copying_count = 0
323
+ done_checking_count = 0
324
+ while pending_cp:
325
+ time.sleep(poll)
326
+ done, pending_cp = filter_split(lambda x: x[1].done(), pending_cp)
327
+ for _, fu in done:
328
+ # Unwrap first for collecting exceptions
329
+ really_copied = fu.result()
330
+ if really_copied:
331
+ done_copying_count += 1
332
+ done_checking_count += len(done)
333
+ progress_display.update(task_c, advance=len(done), refresh=True)
334
+ progress_display.update(task_cp, completed=done_copying_count, total=len(for_copying), refresh=True)
335
+ summery_message += f"\n{len(for_copying)} files copied, {done_checking_count - done_copying_count} files already up-to-date"
336
+ except KeyboardInterrupt, Exception:
337
+ # Exit quickly when interrupted/failed
338
+ executor_cp.shutdown(cancel_futures=True)
339
+ raise
299
340
 
300
- while pending_cp:
301
- time.sleep(poll)
302
- done, pending_cp = filter_split(lambda x: x[1].done(), pending_cp)
303
- for d, fu in done:
304
- # Unwrap for collecting exceptions
305
- fu.result()
306
- progress_display.update(task_c, advance=len(done), refresh=True)
307
- except KeyboardInterrupt, Exception:
308
- # Exit quickly when interrupted/failed
309
- executor_cp.shutdown(cancel_futures=True)
310
- raise
341
+ # Deletion phase
342
+ done_deletion_count = 0
343
+ for p, would_be_deleted in would_delete_flags.items():
344
+ if would_be_deleted:
345
+ p.unlink()
346
+ done_deletion_count += 1
347
+ if verbose:
348
+ reprint(f"{p} (Deleted)")
349
+ if delete:
350
+ summery_message += f"\n{done_deletion_count} files deleted"
311
351
 
312
- # Deletion phase
313
- for p, would_be_deleted in would_delete_flags.items():
314
- if would_be_deleted:
315
- p.unlink()
316
- if verbose:
317
- reprint(f"{p} (Deleted)")
352
+ # Directory deletion phase
353
+ del_dir = delete_dir or purge_dir
354
+ try_del: set[Path] = set()
355
+ if del_dir:
356
+ found_emp: bool | None = None
357
+ while found_emp is not False:
358
+ found_emp = False
359
+ for d, s, is_empty in itreemap(
360
+ lambda d, s: not any(d.iterdir()),
361
+ dest,
362
+ src,
363
+ file=False,
364
+ directory=True,
365
+ mkdir=False,
366
+ follow_symlinks=True,
367
+ include_broken_symlinks=False,
368
+ error_broken_symlinks=False,
369
+ progress=False,
370
+ ):
371
+ if is_empty:
372
+ if d.is_symlink():
373
+ if d not in try_del:
374
+ found_emp = True
375
+ try_del.add(d)
376
+ d.unlink()
377
+ break
378
+ if purge_dir or not s.exists() or not s.is_dir():
379
+ if d not in try_del:
380
+ found_emp = True
381
+ try_del.add(d)
382
+ d.rmdir()
383
+ break
318
384
 
319
- # Directory deletion phase
320
- del_dir = delete_dir or purge_dir
321
- try_del: set[Path] = set()
322
- if del_dir:
323
- found_emp: bool | None = None
324
- while found_emp is not False:
325
- found_emp = False
326
- for d, s, is_empty in itreemap(
327
- lambda d, s: not any(d.iterdir()),
328
- dest,
329
- src,
330
- file=False,
331
- directory=True,
332
- mkdir=False,
333
- follow_symlinks=True,
334
- include_broken_symlinks=False,
335
- error_broken_symlinks=False,
336
- progress=False,
337
- ):
338
- if is_empty:
339
- if d.is_symlink():
340
- if d not in try_del:
341
- found_emp = True
342
- try_del.add(d)
343
- d.unlink()
344
- break
345
- if purge_dir or not s.exists() or not s.is_dir():
346
- if d not in try_del:
347
- found_emp = True
348
- try_del.add(d)
349
- d.rmdir()
350
- break
385
+ if summery_message:
386
+ reprint(summery_message)
351
387
 
352
388
  return 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flacopyus
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: CLI tool to mirror your FLAC audio library to a portable lossy Opus version
5
5
  Maintainer-email: curegit <contact@curegit.jp>
6
6
  License-Expression: GPL-3.0-or-later
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
File without changes
File without changes
File without changes
File without changes