Created
January 10, 2025 09:32
-
-
Save jagaudin/8d2786cb6a655ddea21ce462d79c8400 to your computer and use it in GitHub Desktop.
Script to collect latest drawings from a Momentum project folder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
''' | |
This script collects latest drawings from an Momentum project folder | |
and puts them into a `Current documents` folder. If that folder already | |
exists, its content is attemptingly moved to a `SS` subfolder. | |
This script should be located in the `Document issues` folder of a | |
project. | |
''' | |
from collections import defaultdict | |
from pathlib import Path | |
from shutil import copy2, move, SameFileError | |
digit = '[0123456789]' | |
file_ext = 'pdf' | |
# Pattern is designed to look into dated folders (starting with 6 digits) | |
# and look for filenames that start with a project number (4 digits), contain | |
# the sequence '-MOM-' and end with the extension specified. | |
pattern = digit * 6 + '*/' + digit * 4 + '-MOM-*.' + file_ext | |
# Length of revision code | |
n_char = 3 | |
# Admissible revision prefixes with their order as values | |
prefix = { | |
'P': '0', | |
'C': '1', | |
} | |
# Destination folder name | |
dest = 'Current documents' | |
def get_rev_code(path): | |
''' | |
Returns the segment of the filename after the last '-' in upper case. | |
''' | |
return path.stem.rsplit('-', maxsplit=1)[-1].upper() | |
def is_rev_code_valid(rev_code): | |
''' | |
Checks if a revision code is valid, i.e. it is the correct length and | |
starts with one of the `prefix` keys followed by digits only. | |
''' | |
rev_code = str(rev_code) | |
if ( | |
len(rev_code) == n_char | |
and rev_code.startswith(tuple(prefix.keys())) | |
and rev_code[1:n_char].isdecimal() | |
): | |
return True | |
return False | |
def rev_code_rank(path): | |
''' | |
Returns a translating string reflecting the order of revisions based | |
on the prefixes' order. | |
The first letter gets substitued for a numerical character that reflects | |
the prefix order. | |
''' | |
rev_code = get_rev_code(path) | |
return rev_code.translate(str.maketrans(prefix)) | |
# Get path to current working directory, the 'Issues' folder of a project. | |
p = Path.cwd() | |
valid, invalid = defaultdict(list), [] | |
# Create a destination and 'ss' folder if necessary. | |
dest_path = p / dest | |
ss_path = dest_path / 'ss' | |
ss_path.mkdir(parents=True, exist_ok=True) | |
# Move files present in the dest folder to 'ss' if possible. | |
for f in dest_path.glob('*.' + file_ext): | |
try: | |
move(f, ss_path) | |
except: | |
continue | |
# Group files matching pattern by their name and list all revisions, | |
# list invalid files too. | |
for f in p.rglob(pattern): | |
title = f.stem.split(maxsplit=1)[0][:-n_char] | |
if title.endswith('-') and is_rev_code_valid(get_rev_code(f)): | |
valid[title].append(f) | |
else: | |
invalid.append(f) | |
# With valid files, find the latest issue and copy it to the dest folder. | |
while valid: | |
title, revs = valid.popitem() | |
latest = max(revs, key=rev_code_rank) | |
try: | |
copy2(latest, dest_path / latest.name) | |
except SameFileError: | |
pass | |
# Print the list of invalid files. | |
print(*(f for f in invalid), sep='\n') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment