Last active
July 23, 2020 15:30
-
-
Save dimonf/17cf00ebc40475ea8bb8690023066440 to your computer and use it in GitHub Desktop.
replace "created" date in dokuwiki meta files with the date, derived from the file (page) name
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/python3 | |
'''In dokuwiki metadata is stored in separate files, such as data/meta[/namespace]/[...]/page_name.meta | |
It is critical for blog plugin to have correct "created" timestamp for individual entries (files) | |
as this determines the order the entries appear on summary page. This scirpt helps to 'restore' the | |
"created" timestamp in metafiles in case a metafile created anew by dokuwiki. This migh happen if | |
for some reason meta file were lost or didn't exist at all (e.g. the blog files were imported from | |
other app, such as vimwiki)."created" - is a tagname in dokuwiki meta files. | |
The script searches through meta files in dokuwiki data folder and replaces timestamp with | |
new one, generated from the date of the file, which is encoded in file name prefix of YYYY-DD-MM format. | |
ASSUMPTIONS: | |
- dokuwiki 'blog' plugin is installed; | |
- dokuwiki plugin.blog.dateprefix = %Y:%Y-%m-%d (i.e. filenames have YYYY-DD-MM prefix. Remember, git do | |
not stores ctime!) | |
NOTES: | |
- page (or blog entry) files are not always accompanied by designated meta file. This is the case if files | |
are created outside of dokuwiki php eninge (restorded from backup or imported) | |
- this script will not create new meta files; it will only attempt to amend existing ones. | |
''' | |
import os, re | |
from datetime import datetime | |
import argparse | |
parser = argparse.ArgumentParser(description = 'search through files in dokuwiki data folder and replace timestamp with new one') | |
parser.add_argument('-m','--meta-dir', type=str, dest='meta_dir', required=True, | |
help='root directory for metadata files') | |
parser.add_argument('-n','--dry-run', action='store_const', const=True, dest='dry_run', | |
help='do not modify files') | |
args = parser.parse_args() | |
re_metafile = re.compile(r'.*\.meta$') | |
re_timestamp = re.compile(r'(?<=i:)\d{8,}(?=;)', flags=re.MULTILINE) | |
re_timestamp_created = re.compile(r'(?<="created";i:)\d{8,}(?=;)', flags=re.MULTILINE) | |
def date_from_filename(fl_name): | |
return datetime.strptime(fl_name[:10], '%Y-%m-%d') | |
def inplace_sub_time(fl_meta_path, new_time): | |
with open(fl_meta_path, 'r') as fl_meta: | |
fl_content = fl_meta.read() | |
# | |
fl_content, n_matches = re.subn(rf'("created";i:)\d+',rf'\1{new_time}',fl_content,flags=re.MULTILINE) | |
if not n_matches: | |
return False | |
# | |
with open(fl_meta_path, 'w') as fl_meta: | |
fl_meta.write(fl_content) | |
return True | |
for root,dirs,files in os.walk(args.meta_dir): | |
for fl_name in files: | |
if not re_metafile.match(fl_name): | |
continue | |
try: | |
fl_date = date_from_filename(fl_name) | |
fl_timestamp = str(int(fl_date.timestamp())) | |
except ValueError: | |
continue | |
fl_path = os.path.join(root, fl_name) | |
with open(fl_path, 'r') as fl: | |
fl_data = fl.read() | |
#first attempt to find and replace timestamp for "created" key. | |
# Do not replace the values immediately to avoid unnecessary | |
# re-writing of meta files | |
t_stamps = set(re.findall(re_timestamp_created, fl_data)) | |
if len(t_stamps) > 0: | |
if fl_timestamp in t_stamps: | |
continue | |
fl_data = re.sub(re_timestamp_created, fl_timestamp, fl_data, re.MULTILINE) | |
#in some cases "created" key is absent in metadata file. Try to find | |
# and amend "modified" value then | |
else: | |
t_stamps = set(re.findall(re_timestamp, fl_data)) | |
if len(t_stamps) == 0 or (fl_timestamp in t_stamps): | |
continue | |
fl_data = re.sub(rf'{min(t_stamps)}',fl_timestamp, fl_data, re.MULTILINE) | |
if not args.dry_run: | |
with open(fl_path, 'w') as fl: | |
fl.write(fl_data) | |
print(fl_path + '\n replace timestamp ' + min(t_stamps) + ' with '+fl_timestamp) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment