Rework a bunch of scripts into a single website script
This commit is contained in:
		
							parent
							
								
									f83c6ebbe5
								
							
						
					
					
						commit
						a9f52aad98
					
				
					 12 changed files with 275 additions and 92 deletions
				
			
		
							
								
								
									
										0
									
								
								scripts/erynwells_me/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								scripts/erynwells_me/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										12
									
								
								scripts/erynwells_me/blog.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								scripts/erynwells_me/blog.py
									
										
									
									
									
										Normal 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)
 | 
			
		||||
							
								
								
									
										33
									
								
								scripts/erynwells_me/dates.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								scripts/erynwells_me/dates.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
#!/usr/bin/env python3
 | 
			
		||||
# Eryn Wells <eryn@erynwells.me>
 | 
			
		||||
 | 
			
		||||
import datetime
 | 
			
		||||
from typing import Optional
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def next_sunday_noon(from_date: Optional[datetime.date] = None) -> datetime.datetime:
 | 
			
		||||
    '''
 | 
			
		||||
    Return a `datetime` for noon on the upcoming Sunday. Use today if no
 | 
			
		||||
    `from_date` is given.
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    today = from_date or datetime.date.today()
 | 
			
		||||
 | 
			
		||||
    current_weekday = today.weekday()
 | 
			
		||||
    if current_weekday == 6:
 | 
			
		||||
        days_to_next_sunday = 6
 | 
			
		||||
    else:
 | 
			
		||||
        days_to_next_sunday = 6 - current_weekday
 | 
			
		||||
 | 
			
		||||
    delta = datetime.timedelta(days=days_to_next_sunday)
 | 
			
		||||
 | 
			
		||||
    noon = datetime.time(hour=12)
 | 
			
		||||
 | 
			
		||||
    timezone = datetime.datetime.now().astimezone().tzinfo
 | 
			
		||||
    next_sunday_noon = datetime.datetime.combine(
 | 
			
		||||
        today + delta,
 | 
			
		||||
        noon,
 | 
			
		||||
        tzinfo=timezone
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    return next_sunday_noon
 | 
			
		||||
							
								
								
									
										12
									
								
								scripts/erynwells_me/metadata.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								scripts/erynwells_me/metadata.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
#!/usr/bin/env python3
 | 
			
		||||
# Eryn Wells <eryn@erynwells.me>
 | 
			
		||||
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def slugify(s: str) -> str:
 | 
			
		||||
    '''Process a string into something suitable to be a page slug.'''
 | 
			
		||||
    s = s.strip().lower()
 | 
			
		||||
    s = re.sub(r'\s+', '-', s)
 | 
			
		||||
    s = re.sub(r'[‘’“”"\'()]', '', s)
 | 
			
		||||
    return s
 | 
			
		||||
							
								
								
									
										19
									
								
								scripts/erynwells_me/paths.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								scripts/erynwells_me/paths.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
#!/usr/bin/env python3
 | 
			
		||||
# Eryn Wells <eryn@erynwells.me>
 | 
			
		||||
 | 
			
		||||
import os.path as osp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def content_path() -> str:
 | 
			
		||||
    '''Return the path to the content directory.'''
 | 
			
		||||
    path = osp.abspath(osp.join(osp.dirname(__file__), '..', '..', 'content'))
 | 
			
		||||
    assert osp.isdir(path)
 | 
			
		||||
    return path
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def blog_path() -> str:
 | 
			
		||||
    return osp.join(content_path(), 'blog')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def photos_path() -> str:
 | 
			
		||||
    return osp.join(content_path(), 'photos')
 | 
			
		||||
							
								
								
									
										1
									
								
								scripts/erynwells_me/scripting/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								scripts/erynwells_me/scripting/__init__.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
from .command import Command
 | 
			
		||||
							
								
								
									
										24
									
								
								scripts/erynwells_me/scripting/command.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								scripts/erynwells_me/scripting/command.py
									
										
									
									
									
										Normal 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()
 | 
			
		||||
							
								
								
									
										88
									
								
								scripts/erynwells_me/weeknotes.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								scripts/erynwells_me/weeknotes.py
									
										
									
									
									
										Normal 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))
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue