Rework a bunch of scripts into a single website script

This commit is contained in:
Eryn Wells 2024-11-18 14:59:43 -08:00
parent f83c6ebbe5
commit a9f52aad98
12 changed files with 275 additions and 92 deletions

86
scripts/convert_page.py Executable file
View file

@ -0,0 +1,86 @@
#!/usr/bin/env python3
# Eryn Wells <eryn@erynwells.me>
'''
Convert a Hugo content page from a single page to a bundle and vice versa.
'''
import argparse
import os.path
def parse_args(argv, *a, **kw):
parser = argparse.ArgumentParser(*a, **kw)
parser.add_argument('page_path', metavar='PATH', help='Path to page or bundle to convert')
args = parser.parse_args(argv)
return args
def path_is_page(path):
if not os.path.isfile(path):
return False
_, extension = os.path.splitext(path)
if extension not in ['.md']:
return False
return True
def path_is_page_bundle(path):
if not os.path.isdir(path):
return False
contents = os.listdir(path)
if 'index.md' not in contents:
return False
return True
def can_convert_page_bundle_to_page(path):
contents = os.listdir(path)
if len(contents) != 1:
return False
if 'index.md' not in contents:
return False
return True
def convert_page_to_bundle(path) -> bool:
dirname = os.path.dirname(path)
name, extension = os.path.splitext(path)
bundle_path = os.path.join(dirname, name)
index_path = os.path.join(dirname, 'index' + extension)
try:
print(f'Creating {bundle_path} ... ', end='')
os.mkdir(bundle_path)
print('OK')
except FileExistsError as e:
print(f'\nCannot create {bundle_path}: directory already exists')
return False
try:
print(f'Moving {path} -> {index_path} ... ', end='')
os.rename(path, index_path)
print('OK')
except:
print(f'\nCannot move page file to new index path {index_path}')
return True
def main(argv):
args = parse_args(argv[1:], prog=argv[0])
page_path = args.page_path
if path_is_page(page_path):
print(f'{page_path} is a page')
convert_page_to_bundle(page_path)
elif path_is_page_bundle(page_path):
print(f'{page_path} is a page bundle')
if not can_convert_page_bundle_to_page(page_path):
print(f'Cannot convert bundle {page_path} to page')
if __name__ == '__main__':
import sys
result = main(sys.argv)
sys.exit(0 if not result else result)

View file

@ -0,0 +1,12 @@
# Eryn Wells <eryn@erynwells.me>
import datetime
import os.path as osp
from typing import Optional
from . import paths
def post_path(name, *, year: Optional[int] = None):
if not year:
year = datetime.date.today().year
return osp.join(paths.content_path(), 'blog', str(year), name)

View file

@ -0,0 +1 @@
from .command import Command

View file

@ -0,0 +1,24 @@
# Eryn Wells <eryn@erynwells.me>
import argparse
import re
class Command:
def __init__(self) -> None:
pass
@property
def name(self) -> str:
class_name = self.__class__.__name__
if class_name.endswith('Command'):
trimmed_class_name = class_name.removesuffix('Command')
hyphenated_name = re.sub(r'\B([A-Z])', r'-\1', trimmed_class_name)
return hyphenated_name.lower()
return class_name.lower()
@property
def help(self) -> str:
return ''
def add_arguments(self, _: argparse.ArgumentParser):
raise NotImplementedError()

View file

@ -0,0 +1,88 @@
#!/usr/bin/env python3.12
# Eryn Wells <eryn@erynwells.me>
import argparse
import datetime
import os
import subprocess
import sys
from typing import Optional
from . import blog
from .dates import next_sunday_noon
from .scripting import Command
class WeeknotesCommand(Command):
@staticmethod
def weeknotes_filename(year: str, week: str) -> str:
return f'weeknotes-{year}w{week}.md'
@staticmethod
def weeknotes_path(*, week_number: Optional[int] = None):
if week_number:
year = datetime.datetime.now().year
week_number_str = str(week_number)
else:
next_sunday = next_sunday_noon()
year = next_sunday.year
week_number_str = next_sunday.strftime('%V')
return blog.post_path(WeeknotesCommand.weeknotes_filename(
str(year),
week_number_str
))
@property
def help(self) -> str:
return 'Work with weeknotes posts'
def add_arguments(self, parser: argparse.ArgumentParser):
commands = parser.add_subparsers(title='Weeknotes', required=True)
convert_command = commands.add_parser(
'convert',
help='Convert a post from a single file to a page bundle and vice versa'
)
convert_command.set_defaults(handler=self.handle_convert_command)
edit_command = commands.add_parser(
'edit',
help="Edit the current week's weeknotes post"
)
edit_command.add_argument(
'--editor', '-e',
default=os.environ.get('EDITOR', 'nvim'),
)
edit_command.add_argument('--week', '-w')
edit_command.set_defaults(handler=self.handle_edit_command)
show_command = commands.add_parser(
'show',
aliases=['print'],
help="Print a path to the current week's weeknotes post",
)
show_command.add_argument('--week', '-w')
show_command.add_argument('--date', action='store_true')
show_command.set_defaults(handler=self.handle_show_command)
def handle_convert_command(self, _: argparse.Namespace):
raise NotImplementedError()
def handle_edit_command(self, args: argparse.Namespace):
path = WeeknotesCommand.weeknotes_path(week_number=args.week)
subprocess.run(
f'{args.editor} "{path}"',
stdin=sys.stdin,
stdout=sys.stdout,
stderr=sys.stderr,
env=os.environ,
shell=True,
)
def handle_show_command(self, args: argparse.Namespace):
if args.date:
if args.week:
raise NotImplementedError('Cannot print date with specified week number')
print(next_sunday_noon().isoformat())
else:
print(WeeknotesCommand.weeknotes_path(week_number=args.week))

26
scripts/upload-asset.py Normal file
View file

@ -0,0 +1,26 @@
#!/usr/bin/env python3
# Eryn Wells <eryn@erynwells.me>
'''
Upload a static asset to a server.
'''
import argparse
import subprocess
def parse_args(argv, *a, **kw):
parser = argparse.ArgumentParser(*a, **kw)
parser.add_argument('file', metavar='FILE', nargs='+')
parser.add_argument('destination', metavar='DEST')
args = parser.parse_args(argv)
return args
def main(argv):
args = parse_args(argv[1:], prog=argv[0])
if __name__ == '__main__':
import sys
result = main(sys.argv)
sys.exit(0 if not result else result)

38
scripts/website Executable file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env python3
# Eryn Wells <eryn@erynwells.me>
'''
A Python interface to my personal website, Erynwells.me.
'''
import argparse
from typing import List
from erynwells_me.scripting import Command
from erynwells_me.weeknotes import WeeknotesCommand
COMMANDS: List[Command] = [
WeeknotesCommand(),
]
def parse_args(commands: List[Command], argv, *a, **kw):
parser = argparse.ArgumentParser(*a, **kw)
subcommands = parser.add_subparsers(title='Subcommands', required=True)
for command in commands:
subcommand_parser = subcommands.add_parser(command.name, help=command.help)
command.add_arguments(subcommand_parser)
args = parser.parse_args(argv)
return args
def main(argv):
args = parse_args(COMMANDS, argv[1:], prog=argv[0])
args.handler(args)
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))

View file

@ -1,92 +0,0 @@
#!/usr/bin/env python3.12
# Eryn Wells <eryn@erynwells.me>
import argparse
import datetime
import os.path
import subprocess
from typing import Optional
from website.dates import next_sunday_noon
from website.paths import content_path
def weeknotes_path(*, week_number: Optional[int] = None):
if week_number:
year = datetime.datetime.now().year
week_number_str = str(week_number)
else:
next_sunday = next_sunday_noon()
year = next_sunday.year
week_number_str = next_sunday.strftime('%V')
weeknotes_filename = f'weeknotes-{year}w{week_number_str}.md'
return os.path.join(content_path(), 'blog', str(year), weeknotes_filename)
def parse_args(argv, *a, **kw):
parser = argparse.ArgumentParser(*a, **kw)
commands = parser.add_subparsers(title='Commands', required=True)
convert_command = commands.add_parser(
'convert',
help='Convert a post from a single file to a page bundle and vice versa'
)
convert_command.set_defaults(handler=handle_convert_command)
edit_command = commands.add_parser(
'edit',
help="Edit the current week's weeknotes post"
)
edit_command.add_argument(
'--editor', '-e',
default=os.environ.get('EDITOR', 'nvim'),
)
edit_command.add_argument('--week', '-w')
edit_command.set_defaults(handler=handle_edit_command)
show_command = commands.add_parser(
'show',
aliases=['print'],
help="Print a path to the current week's weeknotes post",
)
show_command.add_argument('--week', '-w')
show_command.add_argument('--date', action='store_true')
show_command.set_defaults(handler=handle_show_command)
args = parser.parse_args(argv)
return args
def handle_convert_command(args):
raise NotImplementedError()
def handle_edit_command(args):
path = weeknotes_path(week_number=args.week)
subprocess.run(
f'{args.editor} "{path}"',
stdin=sys.stdin,
stdout=sys.stdout,
stderr=sys.stderr,
env=os.environ,
shell=True,
)
def handle_show_command(args):
if args.date:
if args.week:
raise NotImplementedError('Cannot print date with specified week number')
print(next_sunday_noon().isoformat())
else:
print(weeknotes_path(week_number=args.week))
def main(argv):
args = parse_args(argv[1:], prog=argv[0])
args.handler(args)
if __name__ == '__main__':
import sys
result = main(sys.argv)
sys.exit(0 if not result else result)