From cea67fe245158dad24728a8d4539a6d156661118 Mon Sep 17 00:00:00 2001 From: octospacc Date: Wed, 19 Oct 2022 11:27:51 +0200 Subject: [PATCH] Internal improvements --- Source/Build.py | 52 +++++++++++++++++++------------------- Source/Modules/Config.py | 21 +++++++++++++++ Source/Modules/Elements.py | 8 +++--- Source/Modules/Logging.py | 13 +++++----- Source/Modules/Site.py | 10 +++++--- TODO | 13 +++++----- 6 files changed, 71 insertions(+), 46 deletions(-) diff --git a/Source/Build.py b/Source/Build.py index 93c6470..fb8281f 100755 --- a/Source/Build.py +++ b/Source/Build.py @@ -108,17 +108,17 @@ def Main(Args, FeedEntries): HavePages, HavePosts = False, False SiteConf = LoadConfFile('Site.ini') - ConfigLogging(OptionChoose(None, Args.Logging, ReadConf(SiteConf, 'Main', 'Logging'))) + ConfigLogging(DefConfOptChoose('Logging', Args.Logging, ReadConf(SiteConf, 'Main', 'Logging'))) #if Args.InputDir: # os.chdir(Args.InputDir) # print(f"[I] Current directory: {Args.InputDir}") - SiteName = Flags['SiteName'] = OptionChoose('', Args.SiteName, ReadConf(SiteConf, 'Site', 'Name')) + SiteName = Flags['SiteName'] = OptChoose('', Args.SiteName, ReadConf(SiteConf, 'Site', 'Name')) if SiteName: logging.info(f"Compiling: {SiteName}") - OutDir = Flags['OutDir'] = OptionChoose('public', Args.OutputDir, ReadConf(SiteConf, 'Site', 'OutputDir')) + OutDir = Flags['OutDir'] = DefConfOptChoose('OutDir', Args.OutputDir, ReadConf(SiteConf, 'Site', 'OutputDir')) OutDir = Flags['OutDir'] = OutDir.removesuffix('/') CheckSafeOutDir(OutDir) logging.info(f"Outputting to: {OutDir}/") @@ -126,43 +126,43 @@ def Main(Args, FeedEntries): Threads = Args.Threads if Args.Threads else 0 DiffBuild = Args.DiffBuild if Args.DiffBuild else False - BlogName = Flags['BlogName'] = OptionChoose('', Args.BlogName, ReadConf(SiteConf, 'Site', 'BlogName')) - SiteTagline = Flags['SiteTagline'] = OptionChoose('', Args.SiteTagline, ReadConf(SiteConf, 'Site', 'Tagline')) - SiteTemplate = Flags['SiteTemplate'] = OptionChoose('Default.html', Args.SiteTemplate, ReadConf(SiteConf, 'Site', 'Template')) - SiteDomain = Flags['SiteDomain'] = OptionChoose('', Args.SiteDomain, ReadConf(SiteConf, 'Site', 'Domain')) - SiteRoot = Flags['SiteRoot'] = OptionChoose('/', Args.SiteRoot, ReadConf(SiteConf, 'Site', 'Root')) - SiteLang = Flags['SiteLang'] = OptionChoose('en', Args.SiteLang, ReadConf(SiteConf, 'Site', 'Lang')) + BlogName = Flags['BlogName'] = OptChoose('', Args.BlogName, ReadConf(SiteConf, 'Site', 'BlogName')) + SiteTagline = Flags['SiteTagline'] = OptChoose('', Args.SiteTagline, ReadConf(SiteConf, 'Site', 'Tagline')) + SiteTemplate = Flags['SiteTemplate'] = DefConfOptChoose('SiteTemplate', Args.SiteTemplate, ReadConf(SiteConf, 'Site', 'Template')) + SiteDomain = Flags['SiteDomain'] = OptChoose('', Args.SiteDomain, ReadConf(SiteConf, 'Site', 'Domain')) + SiteRoot = Flags['SiteRoot'] = OptChoose('/', Args.SiteRoot, ReadConf(SiteConf, 'Site', 'Root')) + SiteLang = Flags['SiteLang'] = DefConfOptChoose('SiteLang', Args.SiteLang, ReadConf(SiteConf, 'Site', 'Lang')) - Sorting = Flags['Sorting'] = literal_eval(OptionChoose('{}', Args.Sorting, ReadConf(SiteConf, 'Site', 'Sorting'))) + Sorting = Flags['Sorting'] = literal_eval(OptChoose('{}', Args.Sorting, ReadConf(SiteConf, 'Site', 'Sorting'))) Sorting = Flags['Sorting'] = SetSorting(Sorting) - NoScripts = Flags['NoScripts'] = StringBoolChoose(False, Args.NoScripts, ReadConf(SiteConf, 'Site', 'NoScripts')) + NoScripts = Flags['NoScripts'] = StrBoolChoose(False, Args.NoScripts, ReadConf(SiteConf, 'Site', 'NoScripts')) FolderRoots = Flags['FolderRoots'] = literal_eval(Args.FolderRoots) if Args.FolderRoots else {} - ActivityPubTypeFilter = Flags['ActivityPubTypeFilter'] = OptionChoose('Post', Args.ActivityPubTypeFilter, ReadConf(SiteConf, 'ActivityPub', 'TypeFilter')) - ActivityPubHoursLimit = Flags['ActivityPubHoursLimit'] = OptionChoose(168, Args.ActivityPubHoursLimit, ReadConf(SiteConf, 'ActivityPub', 'HoursLimit')) + ActivityPubTypeFilter = Flags['ActivityPubTypeFilter'] = DefConfOptChoose('ActivityPubTypeFilter', Args.ActivityPubTypeFilter, ReadConf(SiteConf, 'ActivityPub', 'TypeFilter')) + ActivityPubHoursLimit = Flags['ActivityPubHoursLimit'] = DefConfOptChoose('ActivityPubHoursLimit', Args.ActivityPubHoursLimit, ReadConf(SiteConf, 'ActivityPub', 'HoursLimit')) - MastodonURL = Flags['MastodonURL'] = OptionChoose('', Args.MastodonURL, ReadConf(SiteConf, 'Mastodon', 'URL')) - MastodonToken = Flags['MastodonToken'] = OptionChoose('', Args.MastodonToken, ReadConf(SiteConf, 'Mastodon', 'Token')) + MastodonURL = Flags['MastodonURL'] = OptChoose('', Args.MastodonURL, ReadConf(SiteConf, 'Mastodon', 'URL')) + MastodonToken = Flags['MastodonToken'] = OptChoose('', Args.MastodonToken, ReadConf(SiteConf, 'Mastodon', 'Token')) MarkdownExts = Flags['MarkdownExts'] = literal_eval(OptionChoose(str(MarkdownExtsDefault), Args.MarkdownExts, ReadConf(SiteConf, 'Markdown', 'Exts'))) - SitemapOutput = Flags['SitemapOutput'] = StringBoolChoose(True, Args.SitemapOutput, ReadConf(SiteConf, 'Sitemap', 'Output')) + SitemapOutput = Flags['SitemapOutput'] = StrBoolChoose(True, Args.SitemapOutput, ReadConf(SiteConf, 'Sitemap', 'Output')) - Minify = Flags['Minify'] = StringBoolChoose(False, Args.Minify, ReadConf(SiteConf, 'Minify', 'Minify')) - MinifyKeepComments = Flags['MinifyKeepComments'] = StringBoolChoose(False, Args.MinifyKeepComments, ReadConf(SiteConf, 'Minify', 'KeepComments')) + Minify = Flags['Minify'] = StrBoolChoose(False, Args.Minify, ReadConf(SiteConf, 'Minify', 'Minify')) + MinifyKeepComments = Flags['MinifyKeepComments'] = StrBoolChoose(False, Args.MinifyKeepComments, ReadConf(SiteConf, 'Minify', 'KeepComments')) - ImgAltToTitle = Flags['ImgAltToTitle'] = StringBoolChoose(True, Args.ImgAltToTitle, ReadConf(SiteConf, 'Site', 'ImgAltToTitle')) - ImgTitleToAlt = Flags['ImgTitleToAlt'] = StringBoolChoose(False, Args.ImgTitleToAlt, ReadConf(SiteConf, 'Site', 'ImgTitleToAlt')) - HTMLFixPre = Flags['HTMLFixPre'] = StringBoolChoose(False, Args.HTMLFixPre, ReadConf(SiteConf, 'Site', 'HTMLFixPre')) + ImgAltToTitle = Flags['ImgAltToTitle'] = StrBoolChoose(True, Args.ImgAltToTitle, ReadConf(SiteConf, 'Site', 'ImgAltToTitle')) + ImgTitleToAlt = Flags['ImgTitleToAlt'] = StrBoolChoose(False, Args.ImgTitleToAlt, ReadConf(SiteConf, 'Site', 'ImgTitleToAlt')) + HTMLFixPre = Flags['HTMLFixPre'] = StrBoolChoose(False, Args.HTMLFixPre, ReadConf(SiteConf, 'Site', 'HTMLFixPre')) - CategoriesAutomatic = Flags['CategoriesAutomatic'] = StringBoolChoose(False, Args.CategoriesAutomatic, ReadConf(SiteConf, 'Categories', 'Automatic')) - CategoriesUncategorized = Flags['CategoriesUncategorized'] = OptionChoose('Uncategorized', Args.CategoriesUncategorized, ReadConf(SiteConf, 'Categories', 'Uncategorized')) + CategoriesAutomatic = Flags['CategoriesAutomatic'] = StrBoolChoose(False, Args.CategoriesAutomatic, ReadConf(SiteConf, 'Categories', 'Automatic')) + CategoriesUncategorized = Flags['CategoriesUncategorized'] = DefConfOptChoose('CategoriesUncategorized', Args.CategoriesUncategorized, ReadConf(SiteConf, 'Categories', 'Uncategorized')) - GemtextOutput = Flags['GemtextOutput'] = StringBoolChoose(False, Args.GemtextOutput, ReadConf(SiteConf, 'Gemtext', 'Output')) + GemtextOutput = Flags['GemtextOutput'] = StrBoolChoose(False, Args.GemtextOutput, ReadConf(SiteConf, 'Gemtext', 'Output')) GemtextHeader = Flags['GemtextHeader'] = Args.GemtextHeader if Args.GemtextHeader else ReadConf(SiteConf, 'Gemtext', 'Header') if ReadConf(SiteConf, 'Gemtext', 'Header') else f"# {SiteName}\n\n" if SiteName else '' - FeedCategoryFilter = Flags['FeedCategoryFilter'] = OptionChoose('Blog', Args.FeedCategoryFilter, ReadConf(SiteConf, 'Feed', 'CategoryFilter')) - FeedEntries = Flags['FeedEntries'] = int(FeedEntries) if (FeedEntries or FeedEntries == 0) and FeedEntries != 'Default' else int(ReadConf(SiteConf, 'Feed', 'Entries')) if ReadConf(SiteConf, 'Feed', 'Entries') else 10 + FeedCategoryFilter = Flags['FeedCategoryFilter'] = DefConfOptChoose('FeedCategoryFilter', Args.FeedCategoryFilter, ReadConf(SiteConf, 'Feed', 'CategoryFilter')) + FeedEntries = Flags['FeedEntries'] = int(FeedEntries) if (FeedEntries or FeedEntries == 0) and FeedEntries != 'Default' else int(ReadConf(SiteConf, 'Feed', 'Entries')) if ReadConf(SiteConf, 'Feed', 'Entries') else DefConf['FeedEntries'] DynamicParts = Flags['DynamicParts'] = literal_eval(OptionChoose('{}', Args.DynamicParts, ReadConf(SiteConf, 'Site', 'DynamicParts'))) DynamicPartsText = Snippets['DynamicParts'] = LoadFromDir('DynamicParts', ['*.htm', '*.html']) diff --git a/Source/Modules/Config.py b/Source/Modules/Config.py index 3305615..1dcbbed 100644 --- a/Source/Modules/Config.py +++ b/Source/Modules/Config.py @@ -10,6 +10,18 @@ import configparser from ast import literal_eval +DefConf = { + 'Logging': 20, + 'OutDir': 'public', + 'SiteLang': 'en', + 'SiteTemplate': 'Default.html', + 'ActivityPubTypeFilter': 'Post', + 'ActivityPubHoursLimit': 168, + 'CategoriesUncategorized': 'Uncategorized', + 'FeedCategoryFilter': 'Blog', + 'FeedEntries': 10 +} + def LoadConfFile(File): Conf = configparser.ConfigParser() Conf.optionxform = str @@ -37,8 +49,15 @@ def EvalOpt(Opt): else: return None +# TODO: Cleaning + def OptionChoose(Default, Primary, Secondary, Tertiary=None): return Primary if Primary != None else Secondary if Secondary != None else Tertiary if Tertiary != None else Default +def OptChoose(Default, Primary, Secondary, Tertiary=None): + return OptionChoose(Default, Primary, Secondary, Tertiary=None) + +def DefConfOptChoose(Key, Primary, Secondary): + return OptChoose(DefConf[Key], Primary, Secondary) def StringBoolChoose(Default, Primary, Secondary): Var = Default @@ -51,3 +70,5 @@ def StringBoolChoose(Default, Primary, Secondary): elif Check in ('False', 'None'): Var = False return Var +def StrBoolChoose(Default, Primary, Secondary): + return StringBoolChoose(Default, Primary, Secondary) diff --git a/Source/Modules/Elements.py b/Source/Modules/Elements.py index 71c8bf7..9042d23 100644 --- a/Source/Modules/Elements.py +++ b/Source/Modules/Elements.py @@ -76,11 +76,11 @@ def GetImage(Meta, BodyImage, Prefer='MetaImage'): def MakeContentHeader(Meta, Locale, Categories=''): Header = '' - for i in ['CreatedOn', 'EditedOn']: - if Meta[i]: - Header += f'{Locale[i]}: {Meta[i]}
' + for e in ['CreatedOn', 'EditedOn']: + if Meta[e]: + Header += f'{Locale[e]}: {Meta[e]}
' if Categories: - Header += f"{Locale['Categories']}:{Categories.removesuffix(' ')}
" + Header += f'{Locale["Categories"]}:{Categories.removesuffix(" ")}
' return f'

{Header}

' def MakeCategoryLine(File, Meta): diff --git a/Source/Modules/Logging.py b/Source/Modules/Logging.py index 61f362e..8c9616c 100644 --- a/Source/Modules/Logging.py +++ b/Source/Modules/Logging.py @@ -9,6 +9,7 @@ import logging import sys +from Modules.Config import * LoggingFormat = '[%(levelname)s] %(message)s' LoggingLevels = { @@ -25,11 +26,11 @@ def SetupLogging(Level): logging.addLevelName(40, 'E') def ConfigLogging(Level): - Num = 20 + Num = DefConf['Logging'] if Level: - if Level.isdecimal(): - Num = int(Level) - else: - if Level.lower() in LoggingLevels: - Num = LoggingLevels['Level']['Num'] + if Level.isdecimal(): + Num = int(Level) + else: + if Level.lower() in LoggingLevels: + Num = LoggingLevels['Level']['Num'] SetupLogging(Num) diff --git a/Source/Modules/Site.py b/Source/Modules/Site.py index 6783ace..bdf9bc0 100644 --- a/Source/Modules/Site.py +++ b/Source/Modules/Site.py @@ -269,6 +269,8 @@ def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLP Title = GetTitle(File.split('/')[-1], Meta, Titles, 'MetaTitle', BlogName) Description = GetDescription(Meta, BodyDescription, 'MetaDescription') Image = GetImage(Meta, BodyImage, 'MetaImage') + ContentHeader = MakeContentHeader(Meta, Locale, MakeCategoryLine(File, Meta)) + TimeNow = datetime.now().strftime('%Y-%m-%d %H:%M') for Line in HTML.splitlines(): Line = Line.lstrip().rstrip() @@ -315,10 +317,10 @@ def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLP '': Meta['Style'], '[staticoso:Page:Content]': Content, '': Content, - '[staticoso:Page:ContentInfo]': MakeContentHeader(Meta, Locale, MakeCategoryLine(File, Meta)), - '': MakeContentHeader(Meta, Locale, MakeCategoryLine(File, Meta)), - '[staticoso:BuildTime]': datetime.now().strftime('%Y-%m-%d %H:%M'), - '': datetime.now().strftime('%Y-%m-%d %H:%M'), + '[staticoso:Page:ContentInfo]': ContentHeader, + '': ContentHeader, + '[staticoso:BuildTime]': TimeNow, + '': TimeNow, '': SiteDomain, '[staticoso:Site:Name]': SiteName, '': SiteName, diff --git a/TODO b/TODO index 8790723..ba945c0 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,5 @@ +- Set categories for all files in a folder and subfolder +- Pages with lists of all posts and all pages (? the folder categories thing might make it redundant?) - Fix title detection: - Don't consider titles in code/comment blocks - Consider titles in lists (title marker preceded by chars) @@ -8,7 +10,7 @@ - Posts in draft state (will not be compiled) / show unlisted status for posts with Index = False - Check if external tools (pug-cli, html2gmi) are installed - Static code syntax highlighing -- Override internal HTML snippets (meta lines, page lists, ...) with config file in Templates/NAME.ini +- Override internal HTML snippets (meta lines, page lists, redirects, ...) with config file in Templates/NAME.ini - Specify input folder(s) - Show page size/words/time in meta line - Add feed support for diary-like pages @@ -18,10 +20,9 @@ - Handle file extensions with any case sensitivity, not just lowercase; currently the bulk of the issue is finding the files on disk - Test sorting by date for files not starting with date, and dated folders - Fix arguments - some are only callable from CLI and not Site.ini - make them coherent with INI categories -- Accept Macros as CLI arguments -- Deprecate FolderRoots (Macros make it redundant) +- Accept Macros as CLI arguments + Deprecate FolderRoots (Macros make it redundant) - Fix ordering menu in Site.ini (not working for inner pages) -- Feed generation without native libraries +- Feed generation optionally without native libraries - JSON feeds - Full XML sitemap - SCSS support @@ -32,6 +33,6 @@ - Exporting the entire site text as JSON for full-text search tools - Automatic guessing of .htm/.html extension for declarations of templates and stuff - Exporting sites to different formats (?) (single-page HTML, PDF, EPUB, ...) -- Disable only ActivityPub feed for a page +- Disable ActivityPub feed for a specific page +- Symlinks and direct copies as option instead of redirect pages - Automatic redirects/symlinks for making pages work without .html suffix -- Override URL for a page / Add custom redirects for it