mirror of
https://github.com/Horizontal42/f1-telemetry.git
synced 2026-11-11 00:42:03 +03:00
rename: recurse subdirs, move already-renamed files to correct folder
When races_dir is set: - os.walk scans all subdirectories of the source - already-renamed files (both tokens present) are also moved if not in the right races/<track>/<session>/ folder - files already in the correct place are skipped with 'already in place' GUI remembers last rename source folder separately from other modes.
This commit is contained in:
parent
818bda26cb
commit
351e9cdf69
3 changed files with 83 additions and 23 deletions
|
|
@ -196,9 +196,11 @@ class _App:
|
|||
self._log_queue.put(None)
|
||||
|
||||
def _on_rename(self) -> None:
|
||||
d = filedialog.askdirectory(title='Select folder to rename', initialdir=_RACES_DIR)
|
||||
init = self._last_dir.get('rename', os.path.expanduser('~'))
|
||||
d = filedialog.askdirectory(title='Select folder with CSV files', initialdir=init)
|
||||
if not d:
|
||||
return
|
||||
self._last_dir['rename'] = d
|
||||
self._set_busy(True)
|
||||
threading.Thread(target=self._worker_rename, args=(d,), daemon=True).start()
|
||||
|
||||
|
|
@ -209,7 +211,8 @@ class _App:
|
|||
self._push('No CSV files found')
|
||||
for r in results:
|
||||
if r.status == 'renamed':
|
||||
self._push(f'renamed: {r.old} -> {r.new}')
|
||||
new_display = os.path.relpath(r.new, _RACES_DIR) if r.new and r.new.startswith(_RACES_DIR) else r.new
|
||||
self._push(f'renamed: {r.old} -> {new_display}')
|
||||
elif r.status == 'skipped':
|
||||
self._push(f'skipped: {r.old} ({r.detail})')
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -115,9 +115,15 @@ def rename_unprocessed(targets: list[str], races_dir: str | None = None) -> list
|
|||
for t in targets:
|
||||
t = os.path.abspath(t)
|
||||
if os.path.isdir(t):
|
||||
for name in os.listdir(t):
|
||||
if name.lower().endswith('.csv'):
|
||||
paths.append(os.path.join(t, name))
|
||||
if races_dir is not None:
|
||||
for root, _, files in os.walk(t):
|
||||
for fname in sorted(files):
|
||||
if fname.lower().endswith('.csv'):
|
||||
paths.append(os.path.join(root, fname))
|
||||
else:
|
||||
for fname in os.listdir(t):
|
||||
if fname.lower().endswith('.csv'):
|
||||
paths.append(os.path.join(t, fname))
|
||||
else:
|
||||
paths.append(t)
|
||||
|
||||
|
|
@ -131,9 +137,22 @@ def rename_unprocessed(targets: list[str], races_dir: str | None = None) -> list
|
|||
results.append(RenameResult(name, None, 'error', 'not a CSV file'))
|
||||
continue
|
||||
stem = os.path.splitext(name)[0]
|
||||
|
||||
if races_dir is None:
|
||||
if _is_processed(stem):
|
||||
results.append(RenameResult(name, None, 'skipped', 'already processed'))
|
||||
continue
|
||||
try:
|
||||
lap, session_type, _ = read_metadata(p)
|
||||
except Exception as e:
|
||||
results.append(RenameResult(name, None, 'error', str(e)))
|
||||
continue
|
||||
if not session_type:
|
||||
results.append(RenameResult(name, None, 'error', 'session type not found in CSV'))
|
||||
continue
|
||||
new_name = insert_tokens(name, session_type, lap)
|
||||
dest = os.path.join(os.path.dirname(p), new_name)
|
||||
else:
|
||||
try:
|
||||
lap, session_type, track_name = read_metadata(p)
|
||||
except Exception as e:
|
||||
|
|
@ -142,14 +161,15 @@ def rename_unprocessed(targets: list[str], races_dir: str | None = None) -> list
|
|||
if not session_type:
|
||||
results.append(RenameResult(name, None, 'error', 'session type not found in CSV'))
|
||||
continue
|
||||
new_name = insert_tokens(name, session_type, lap)
|
||||
if races_dir is not None:
|
||||
new_name = name if _is_processed(stem) else insert_tokens(name, session_type, lap)
|
||||
dest_dir = os.path.join(races_dir, _safe_dirname(track_name), _session_folder(session_type))
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
else:
|
||||
dest_dir = os.path.dirname(p)
|
||||
dest = os.path.join(dest_dir, new_name)
|
||||
if os.path.exists(dest):
|
||||
if os.path.abspath(p) == os.path.abspath(dest):
|
||||
results.append(RenameResult(name, None, 'skipped', 'already in place'))
|
||||
continue
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
|
||||
if os.path.exists(dest) and os.path.abspath(dest) != os.path.abspath(p):
|
||||
results.append(RenameResult(name, dest, 'error', 'target exists'))
|
||||
continue
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -139,3 +139,40 @@ def test_rename_unprocessed_moves_to_races_dir(tmp_path, sample_path):
|
|||
assert r.new.startswith(races_dir)
|
||||
assert 'Practice' in r.new
|
||||
assert not os.path.exists(src)
|
||||
|
||||
|
||||
def test_rename_unprocessed_moves_already_renamed(tmp_path, sample_path):
|
||||
"""Already-renamed file in wrong folder gets moved to correct folder."""
|
||||
src = str(tmp_path / "zandvoort_P1_L7_74.074_ferrari.csv")
|
||||
shutil.copy(sample_path, src)
|
||||
races_dir = str(tmp_path / 'races')
|
||||
results = rename_unprocessed([src], races_dir=races_dir)
|
||||
assert len(results) == 1
|
||||
r = results[0]
|
||||
assert r.status == 'renamed'
|
||||
assert 'Practice' in r.new
|
||||
assert os.path.exists(r.new)
|
||||
assert not os.path.exists(src)
|
||||
|
||||
|
||||
def test_rename_unprocessed_skips_already_in_place(tmp_path, sample_path):
|
||||
"""File already in correct folder is skipped on second run."""
|
||||
src = str(tmp_path / "zandvoort_74.074_ferrari.csv")
|
||||
shutil.copy(sample_path, src)
|
||||
races_dir = str(tmp_path / 'races')
|
||||
rename_unprocessed([src], races_dir=races_dir)
|
||||
results = rename_unprocessed([races_dir], races_dir=races_dir)
|
||||
assert all(r.status == 'skipped' for r in results)
|
||||
|
||||
|
||||
def test_rename_unprocessed_walks_subdirs(tmp_path, sample_path):
|
||||
"""With races_dir, scans subdirectories recursively."""
|
||||
sub = tmp_path / 'sub' / 'nested'
|
||||
sub.mkdir(parents=True)
|
||||
src = str(sub / "zandvoort_74.074_ferrari.csv")
|
||||
shutil.copy(sample_path, src)
|
||||
races_dir = str(tmp_path / 'races')
|
||||
results = rename_unprocessed([str(tmp_path)], races_dir=races_dir)
|
||||
assert len(results) == 1
|
||||
assert results[0].status == 'renamed'
|
||||
assert 'Practice' in results[0].new
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue