summaryrefslogtreecommitdiff
path: root/src/pyssg
diff options
context:
space:
mode:
Diffstat (limited to 'src/pyssg')
-rw-r--r--src/pyssg/builder.py45
-rw-r--r--src/pyssg/configuration.py90
-rw-r--r--src/pyssg/pyssg.py57
3 files changed, 152 insertions, 40 deletions
diff --git a/src/pyssg/builder.py b/src/pyssg/builder.py
index b8acf08..8472b20 100644
--- a/src/pyssg/builder.py
+++ b/src/pyssg/builder.py
@@ -2,6 +2,7 @@ import os
import shutil
from copy import deepcopy
+from .configuration import Configuration
from .template import Template
from .database import Database
from .parser import MDParser
@@ -9,37 +10,19 @@ from .page import Page
from .discovery import get_file_list, get_dir_structure
class HTMLBuilder:
- def __init__(self, src: str,
- dst: str,
- base_url: str,
+ def __init__(self, config: Configuration,
template: Template,
- db: Database,
- dformat: str=None,
- l_dformat: str=None,
- lsep_dformat: str=None):
- self.src: str = src
- self.dst: str = dst
- self.base_url: str = base_url
+ db: Database):
+ self.src: str = config.src
+ self.dst: str = config.dst
+ self.base_url: str = config.base_url
+ self.dformat: str = config.dformat
+ self.l_dformat: str = config.l_dformat
+ self.lsep_dformat: str = config.lsep_dformat
+ self.force: bool = config.force
+
self.template: Template = template
self.db: Database = db
- self.dformat: str = None
- self.l_dformat: str = None
- self.lsep_dformat: str = None
-
- if dformat is not None:
- self.dformat = dformat
- else:
- self.dformat = "%a, %d %b, %Y @ %H:%M %Z"
-
- if l_dformat is not None:
- self.l_dformat = l_dformat
- else:
- self.l_dformat = "%b %d"
-
- if lsep_dformat is not None:
- self.lsep_dformat = lsep_dformat
- else:
- self.lsep_dformat = "%B %Y"
self.dirs: list[str] = None
self.md_files: list[str] = None
@@ -61,7 +44,11 @@ class HTMLBuilder:
self.__create_article_index(parser.all_tags, parser.all_pages)
# create each category of html pages
- self.__create_articles(parser.updated_pages)
+ # check if all pages should be created
+ if self.force:
+ self.__create_articles(parser.all_pages)
+ else:
+ self.__create_articles(parser.updated_pages)
self.__create_tags(parser.all_tags, parser.all_pages)
diff --git a/src/pyssg/configuration.py b/src/pyssg/configuration.py
new file mode 100644
index 0000000..3f7acfe
--- /dev/null
+++ b/src/pyssg/configuration.py
@@ -0,0 +1,90 @@
+import os
+
+
+class Configuration:
+ def __init__(self, path: str):
+ self.path: str = path
+ self.src: str = None
+ self.dst: str = None
+ self.base_url: str = None
+ self.dformat: str = None
+ self.l_dformat: str = None
+ self.lsep_dformat: str = None
+ self.force: bool = None
+
+
+ def read(self):
+ try:
+ lines: list[str] = None
+ with open(self.path, 'r') as f:
+ lines = f.readlines()
+
+ opts: dict[str, Union[str, bool]] = dict()
+ for l in lines:
+ kv: list[str] = l.split('=', 1)
+ if len(kv) != 2:
+ raise Exception('wrong config syntax')
+
+ k: str = kv[0].strip()
+ k_temp: str = kv[0].strip()
+ # check if value should be a boolean true
+ v: Union[str, bool] = k_temp\
+ if k_temp.lower() not in ['true', '1', 'yes']\
+ else True
+
+ opts[k] = v
+
+ try:
+ self.src = opts['SRC_PATH']
+ except KeyError: pass
+
+ try:
+ self.dst = opts['SRC_PATH']
+ except KeyError: pass
+
+ try:
+ self.base_url = opts['BASE_URL']
+ except KeyError: pass
+
+ try:
+ self.dformat = opts['DATE_FORMAT']
+ except KeyError: pass
+
+ try:
+ self.l_dformat = opts['LIST_DATE_FORMAT']
+ except KeyError: pass
+
+ try:
+ self.lsep_dformat = opts['LIST_SEP_DATE_FORMAT']
+ except KeyError: pass
+
+ try:
+ # if the parser above didn't read a boolean true, then take it
+ # as a false anyways
+ self.force = opts['FORCE'] if opts['FORCE'] is True else False
+ except KeyError: pass
+
+ except OSError: pass
+
+
+ def fill_missing(self, opts: dict[str, Union[str, bool]]) -> None:
+ if self.src is None:
+ self.src = opts['src']
+
+ if self.dst is None:
+ self.dst = opts['dst']
+
+ if self.base_url is None:
+ self.base_url = opts['url']
+
+ if self.dformat is None:
+ self.dformat = opts['date-format']
+
+ if self.l_dformat is None:
+ self.l_dformat = opts['list-date-format']
+
+ if self.lsep_dformat is None:
+ self.lsep_dformat = opts['list-sep-date-format']
+
+ if self.force is None:
+ self.force = opts['force']
diff --git a/src/pyssg/pyssg.py b/src/pyssg/pyssg.py
index 3cda0bc..2f46c18 100644
--- a/src/pyssg/pyssg.py
+++ b/src/pyssg/pyssg.py
@@ -1,6 +1,7 @@
import os
from argparse import ArgumentParser, Namespace
+from .configuration import Configuration
from .database import Database
from .template import Template
from .builder import HTMLBuilder
@@ -9,7 +10,16 @@ from .builder import HTMLBuilder
def get_options() -> Namespace:
parser = ArgumentParser(prog='pyssg',
description='''Static Site Generator that reads
- Markdown files and creates HTML files.''')
+ Markdown files and creates HTML files.\nIf
+ [-c]onfig file is provided (or exists in default
+ location) all other options are ignored.\nFor
+ datetime formats see:
+ https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes''')
+ parser.add_argument('-c', '--config',
+ default='$XDG_CONFIG_HOME/pyssg/pyssgrc',
+ type=str,
+ help='''config file (path) to read from; defaults to
+ '$XDG_CONFIG_HOME/pyssg/pyssgrc' ''')
parser.add_argument('-s', '--src',
default='src',
type=str,
@@ -24,6 +34,24 @@ def get_options() -> Namespace:
default='',
type=str,
help='''base url without trailing slash''')
+ parser.add_argument('--date-format',
+ default='%a, %b %d, %Y @ %H:%M %Z',
+ type=str,
+ help='''date format used inside pages (for creation and
+ modification times, for example); defaults to '%a, %b
+ %d, %Y @ %H:%M %Z' ('Tue, Mar 16, 2021 @ 02:46 UTC',
+ for example)''')
+ parser.add_argument('--list-date-format',
+ default='%b %d',
+ type=str,
+ help='''date format used for page entries in a list;
+ defaults to '%b %d' ('Mar 16', for example)''')
+ parser.add_argument('--list-sep-date-format',
+ default='%B %Y',
+ type=str,
+ help='''date format used for the separator between page
+ entries in a list; defaults to '%B %Y' ('March 2021',
+ for example)''')
parser.add_argument('-i', '--init',
action='store_true',
help='''initializes the dir structure, templates,
@@ -32,38 +60,45 @@ def get_options() -> Namespace:
action='store_true',
help='''generates all html files and passes over
existing (handmade) ones''')
+ parser.add_argument('-f', '--force',
+ action='store_true',
+ help='''force building all pages and not only the
+ updated ones''')
return parser.parse_args()
def main() -> None:
- opts: dict[str] = vars(get_options())
- src: str = opts['src']
- dst: str = opts['dst']
- base_url: str = opts['url']
+ opts: dict[str, Union[str, bool]] = vars(get_options())
+ conf_path: str = opts['config']
+ conf_path = os.path.expandvars(conf_path)
+
+ config: Configuration = Configuration(conf_path)
+ config.read()
+ config.fill_missing(opts)
if opts['init']:
try:
- os.mkdir(src)
- os.makedirs(os.path.join(dst, 'tag'))
+ os.mkdir(config.src)
+ os.makedirs(os.path.join(config.dst, 'tag'))
except FileExistsError:
pass
# write default templates
- template: Template = Template(src)
+ template: Template = Template(config.src)
template.write()
return
if opts['build']:
# start the db
- db: Database = Database(os.path.join(src, '.files'))
+ db: Database = Database(os.path.join(config.src, '.files'))
db.read()
# read templates
- template: Template = Template(src)
+ template: Template = Template(config.src)
template.read()
- builder: HTMLBuilder = HTMLBuilder(src, dst, base_url, template, db)
+ builder: HTMLBuilder = HTMLBuilder(config, template, db)
builder.build()
db.write()