Skip to content

Instantly share code, notes, and snippets.

@dimonf
Last active July 23, 2020 15:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dimonf/17cf00ebc40475ea8bb8690023066440 to your computer and use it in GitHub Desktop.
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
#!/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