Skip to content

Instantly share code, notes, and snippets.

@jagaudin
Created January 10, 2025 09:32
Show Gist options
  • Save jagaudin/8d2786cb6a655ddea21ce462d79c8400 to your computer and use it in GitHub Desktop.
Save jagaudin/8d2786cb6a655ddea21ce462d79c8400 to your computer and use it in GitHub Desktop.
Script to collect latest drawings from a Momentum project folder
#!/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