Last active
January 15, 2022 17:53
-
-
Save introt/b7f36474d7699bdaa2607879753ef421 to your computer and use it in GitHub Desktop.
Add event summaries to ISO 8601 -like filenames from an ICS calendar
This file contains 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 python3 | |
""" | |
timely_rename.py | |
Prepend ISO 8601 -like filenames | |
with event summaries from an ICS calendar | |
(c) 2021 introt | |
License: Apache 2.0 | |
""" | |
import re | |
from os import rename | |
from ics import Calendar | |
# needs 0.8.0-dev or later: https://github.com/ics-py/ics-py | |
from datetime import datetime as dt | |
# eg. 2021-11-19-Note-08-15.xopp -> ['2021', '11', '19', '08', '15'] | |
date_pat = re.compile(r'(\d{4})-(\d{2})-(\d{2}).*?(\d{2}).(\d{2})') | |
def get_timely_name(filename, calendar): | |
try: | |
g = date_pat.match(filename).groups() | |
candidates = calendar.timeline.at(dt(int(g[0]), int(g[1]), int(g[2]), int(g[3]), int(g[4]))) | |
name = None | |
for c in candidates: | |
if not name: | |
name = c.summary | |
else: | |
print("WARNING: multiple events: choosing", name, "over", c.summary) | |
return "{}-{}".format(name, filename).replace(' ', '_').replace('/', '-') | |
except Exception: | |
# return unchanged filename | |
return filename | |
def timely_rename(file, verbose=True, dry_run=True): | |
new = get_timely_name(file, c) | |
if verbose or dry_run: | |
print('"{}" -> "{}"'.format(file, new)) | |
if not dry_run: | |
rename(file, new) | |
if __name__ == '__main__': | |
import argparse | |
parser = argparse.ArgumentParser(description='Prepend ISO 8601 -like filenames with event summaries from an ICS calendar') | |
parser.add_argument('files', metavar='FILE', type=str, nargs='+', help='file(s) to rename') | |
parser.add_argument('--calendar', metavar='ICSFILE', type=str, nargs=1, help='ics filename/path') | |
parser.add_argument('--dry_run', help='print new filenames without renaming', action='store_true') | |
parser.add_argument('--verbose', help='print old and new filenames (implied by --dry-run)', action='store_true') | |
args=parser.parse_args() | |
c = Calendar(''.join(open(args.calendar[0], 'r').readlines())) | |
for file in args.files: | |
timely_rename(file, verbose=args.verbose, dry_run=args.dry_run) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This has been an exercise in dealing with both feature creep and perfectionism - there are so many things that could be done better or made configurable, but here's a MVP for y'all to play with.
Feel free to fork! Below are some features I'd add if I had the time: