mirror of https://gitlab.com/octtspacc/staticoso
Some internal refactoring
This commit is contained in:
parent
22918f0342
commit
91450570f4
|
@ -40,6 +40,7 @@ Needed for Gemtext output support:
|
||||||
|
|
||||||
## Features roadmap
|
## Features roadmap
|
||||||
|
|
||||||
|
- [ ] Multithreading
|
||||||
- [ ] Overriding internal HTML snippets for template-specific ones
|
- [ ] Overriding internal HTML snippets for template-specific ones
|
||||||
- [ ] Static syntax highlighing for code blocks in any page
|
- [ ] Static syntax highlighing for code blocks in any page
|
||||||
- [x] File name used as a title for pages without one
|
- [x] File name used as a title for pages without one
|
||||||
|
|
138
Source/Build.py
138
Source/Build.py
|
@ -30,7 +30,7 @@ from Modules.Site import *
|
||||||
from Modules.Sitemap import *
|
from Modules.Sitemap import *
|
||||||
from Modules.Utils import *
|
from Modules.Utils import *
|
||||||
|
|
||||||
def ResetOutputDir(OutDir):
|
def ResetOutDir(OutDir):
|
||||||
for e in (OutDir, f"{OutDir}.gmi"):
|
for e in (OutDir, f"{OutDir}.gmi"):
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(e)
|
shutil.rmtree(e)
|
||||||
|
@ -69,7 +69,7 @@ def GetConfMenu(Entries, MarkdownExts):
|
||||||
Menu[int(i)] = e
|
Menu[int(i)] = e
|
||||||
return Menu
|
return Menu
|
||||||
|
|
||||||
def CheckSafeOutputDir(OutDir):
|
def CheckSafeOutDir(OutDir):
|
||||||
InDir = os.path.realpath(os.getcwd())
|
InDir = os.path.realpath(os.getcwd())
|
||||||
OutDir = os.path.realpath(OutDir)
|
OutDir = os.path.realpath(OutDir)
|
||||||
OutFolder = OutDir.split('/')[-1]
|
OutFolder = OutDir.split('/')[-1]
|
||||||
|
@ -103,6 +103,7 @@ def GetModifiedFiles(OutDir):
|
||||||
return Mod
|
return Mod
|
||||||
|
|
||||||
def Main(Args, FeedEntries):
|
def Main(Args, FeedEntries):
|
||||||
|
Flags = {}
|
||||||
HavePages, HavePosts = False, False
|
HavePages, HavePosts = False, False
|
||||||
SiteConf = LoadConfFile('Site.ini')
|
SiteConf = LoadConfFile('Site.ini')
|
||||||
|
|
||||||
|
@ -110,51 +111,51 @@ def Main(Args, FeedEntries):
|
||||||
# os.chdir(Args.InputDir)
|
# os.chdir(Args.InputDir)
|
||||||
# print(f"[I] Current directory: {Args.InputDir}")
|
# print(f"[I] Current directory: {Args.InputDir}")
|
||||||
|
|
||||||
SiteName = OptionChoose('', Args.SiteName, ReadConf(SiteConf, 'Site', 'Name'))
|
SiteName = Flags['SiteName'] = OptionChoose('', Args.SiteName, ReadConf(SiteConf, 'Site', 'Name'))
|
||||||
if SiteName:
|
if SiteName:
|
||||||
print(f"[I] Compiling: {SiteName}")
|
print(f"[I] Compiling: {SiteName}")
|
||||||
|
|
||||||
OutputDir = OptionChoose('public', Args.OutputDir, ReadConf(SiteConf, 'Site', 'OutputDir'))
|
OutDir = Flags['OutDir'] = OptionChoose('public', Args.OutputDir, ReadConf(SiteConf, 'Site', 'OutputDir'))
|
||||||
OutputDir = OutputDir.removesuffix('/')
|
OutDir = Flags['OutDir'] = OutDir.removesuffix('/')
|
||||||
CheckSafeOutputDir(OutputDir)
|
CheckSafeOutDir(OutDir)
|
||||||
print(f"[I] Outputting to: {OutputDir}/")
|
print(f"[I] Outputting to: {OutDir}/")
|
||||||
|
|
||||||
DiffBuild = Args.DiffBuild
|
DiffBuild = Args.DiffBuild
|
||||||
|
|
||||||
BlogName = OptionChoose('', Args.BlogName, ReadConf(SiteConf, 'Site', 'BlogName'))
|
BlogName = Flags['BlogName'] = OptionChoose('', Args.BlogName, ReadConf(SiteConf, 'Site', 'BlogName'))
|
||||||
SiteTagline = OptionChoose('', Args.SiteTagline, ReadConf(SiteConf, 'Site', 'Tagline'))
|
SiteTagline = Flags['SiteTagline'] = OptionChoose('', Args.SiteTagline, ReadConf(SiteConf, 'Site', 'Tagline'))
|
||||||
SiteTemplate = OptionChoose('Default.html', Args.SiteTemplate, ReadConf(SiteConf, 'Site', 'Template'))
|
SiteTemplate = Flags['SiteTemplate'] = OptionChoose('Default.html', Args.SiteTemplate, ReadConf(SiteConf, 'Site', 'Template'))
|
||||||
SiteDomain = OptionChoose('', Args.SiteDomain, ReadConf(SiteConf, 'Site', 'Domain'))
|
SiteDomain = Flags['SiteDomain'] = OptionChoose('', Args.SiteDomain, ReadConf(SiteConf, 'Site', 'Domain'))
|
||||||
SiteRoot = OptionChoose('/', Args.SiteRoot, ReadConf(SiteConf, 'Site', 'Root'))
|
SiteRoot = Flags['SiteRoot'] = OptionChoose('/', Args.SiteRoot, ReadConf(SiteConf, 'Site', 'Root'))
|
||||||
SiteLang = OptionChoose('en', Args.SiteLang, ReadConf(SiteConf, 'Site', 'Lang'))
|
SiteLang = Flags['SiteLang'] = OptionChoose('en', Args.SiteLang, ReadConf(SiteConf, 'Site', 'Lang'))
|
||||||
|
|
||||||
Sorting = literal_eval(OptionChoose('{}', Args.Sorting, ReadConf(SiteConf, 'Site', 'Sorting')))
|
Sorting = Flags['Sorting'] = literal_eval(OptionChoose('{}', Args.Sorting, ReadConf(SiteConf, 'Site', 'Sorting')))
|
||||||
DynamicParts = literal_eval(OptionChoose('{}', Args.DynamicParts, ReadConf(SiteConf, 'Site', 'DynamicParts')))
|
DynamicParts = Flags['DynamicParts'] = literal_eval(OptionChoose('{}', Args.DynamicParts, ReadConf(SiteConf, 'Site', 'DynamicParts')))
|
||||||
NoScripts = StringBoolChoose(False, Args.NoScripts, ReadConf(SiteConf, 'Site', 'NoScripts'))
|
NoScripts = Flags['NoScripts'] = StringBoolChoose(False, Args.NoScripts, ReadConf(SiteConf, 'Site', 'NoScripts'))
|
||||||
|
|
||||||
ActivityPubTypeFilter = OptionChoose('Post', Args.ActivityPubTypeFilter, ReadConf(SiteConf, 'ActivityPub', 'TypeFilter'))
|
ActivityPubTypeFilter = Flags['ActivityPubTypeFilter'] = OptionChoose('Post', Args.ActivityPubTypeFilter, ReadConf(SiteConf, 'ActivityPub', 'TypeFilter'))
|
||||||
ActivityPubHoursLimit = OptionChoose(168, Args.ActivityPubHoursLimit, ReadConf(SiteConf, 'ActivityPub', 'HoursLimit'))
|
ActivityPubHoursLimit = Flags['ActivityPubHoursLimit'] = OptionChoose(168, Args.ActivityPubHoursLimit, ReadConf(SiteConf, 'ActivityPub', 'HoursLimit'))
|
||||||
|
|
||||||
MastodonURL = OptionChoose('', Args.MastodonURL, ReadConf(SiteConf, 'Mastodon', 'URL'))
|
MastodonURL = Flags['MastodonURL'] = OptionChoose('', Args.MastodonURL, ReadConf(SiteConf, 'Mastodon', 'URL'))
|
||||||
MastodonToken = OptionChoose('', Args.MastodonToken, ReadConf(SiteConf, 'Mastodon', 'Token'))
|
MastodonToken = Flags['MastodonToken'] = OptionChoose('', Args.MastodonToken, ReadConf(SiteConf, 'Mastodon', 'Token'))
|
||||||
|
|
||||||
MarkdownExts = literal_eval(OptionChoose(str(MarkdownExtsDefault), Args.MarkdownExts, ReadConf(SiteConf, 'Markdown', 'Exts')))
|
MarkdownExts = Flags['MarkdownExts'] = literal_eval(OptionChoose(str(MarkdownExtsDefault), Args.MarkdownExts, ReadConf(SiteConf, 'Markdown', 'Exts')))
|
||||||
SitemapOutput = StringBoolChoose(True, Args.SitemapOutput, ReadConf(SiteConf, 'Sitemap', 'Output'))
|
SitemapOutput = Flags['SitemapOutput'] = StringBoolChoose(True, Args.SitemapOutput, ReadConf(SiteConf, 'Sitemap', 'Output'))
|
||||||
|
|
||||||
Minify = StringBoolChoose(False, Args.Minify, ReadConf(SiteConf, 'Minify', 'Minify'))
|
Minify = Flags['Minify'] = StringBoolChoose(False, Args.Minify, ReadConf(SiteConf, 'Minify', 'Minify'))
|
||||||
MinifyKeepComments = StringBoolChoose(False, Args.MinifyKeepComments, ReadConf(SiteConf, 'Minify', 'KeepComments'))
|
MinifyKeepComments = Flags['MinifyKeepComments'] = StringBoolChoose(False, Args.MinifyKeepComments, ReadConf(SiteConf, 'Minify', 'KeepComments'))
|
||||||
|
|
||||||
ImgAltToTitle = StringBoolChoose(True, Args.ImgAltToTitle, ReadConf(SiteConf, 'Site', 'ImgAltToTitle'))
|
ImgAltToTitle = Flags['ImgAltToTitle'] = StringBoolChoose(True, Args.ImgAltToTitle, ReadConf(SiteConf, 'Site', 'ImgAltToTitle'))
|
||||||
ImgTitleToAlt = StringBoolChoose(False, Args.ImgTitleToAlt, ReadConf(SiteConf, 'Site', 'ImgTitleToAlt'))
|
ImgTitleToAlt = Flags['ImgTitleToAlt'] = StringBoolChoose(False, Args.ImgTitleToAlt, ReadConf(SiteConf, 'Site', 'ImgTitleToAlt'))
|
||||||
|
|
||||||
CategoriesAutomatic = StringBoolChoose(False, Args.CategoriesAutomatic, ReadConf(SiteConf, 'Categories', 'Automatic'))
|
CategoriesAutomatic = Flags['CategoriesAutomatic'] = StringBoolChoose(False, Args.CategoriesAutomatic, ReadConf(SiteConf, 'Categories', 'Automatic'))
|
||||||
CategoriesUncategorized = OptionChoose('Uncategorized', Args.CategoriesUncategorized, ReadConf(SiteConf, 'Categories', 'Uncategorized'))
|
CategoriesUncategorized = Flags['CategoriesUncategorized'] = OptionChoose('Uncategorized', Args.CategoriesUncategorized, ReadConf(SiteConf, 'Categories', 'Uncategorized'))
|
||||||
|
|
||||||
GemtextOutput = StringBoolChoose(False, Args.GemtextOutput, ReadConf(SiteConf, 'Gemtext', 'Output'))
|
GemtextOutput = Flags['GemtextOutput'] = StringBoolChoose(False, Args.GemtextOutput, ReadConf(SiteConf, 'Gemtext', 'Output'))
|
||||||
GemtextHeader = Args.GemtextHeader if Args.GemtextHeader else ReadConf(SiteConf, 'Gemtext', 'Header') if ReadConf(SiteConf, 'Gemtext', 'Header') else f"# {SiteName}\n\n" if SiteName else ''
|
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 = OptionChoose('Blog', Args.FeedCategoryFilter, ReadConf(SiteConf, 'Feed', 'CategoryFilter'))
|
FeedCategoryFilter = Flags['FeedCategoryFilter'] = OptionChoose('Blog', Args.FeedCategoryFilter, ReadConf(SiteConf, 'Feed', 'CategoryFilter'))
|
||||||
FeedEntries = int(FeedEntries) if (FeedEntries or FeedEntries == 0) and FeedEntries != 'Default' else int(ReadConf(SiteConf, 'Feed', 'Entries')) if ReadConf(SiteConf, 'Feed', 'Entries') else 10
|
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
|
||||||
|
|
||||||
MenuEntries = ReadConf(SiteConf, 'Menu')
|
MenuEntries = ReadConf(SiteConf, 'Menu')
|
||||||
if MenuEntries:
|
if MenuEntries:
|
||||||
|
@ -162,27 +163,27 @@ def Main(Args, FeedEntries):
|
||||||
else:
|
else:
|
||||||
ConfMenu = []
|
ConfMenu = []
|
||||||
|
|
||||||
SiteDomain = SiteDomain.removesuffix('/')
|
SiteDomain = Flags['SiteDomain'] = SiteDomain.removesuffix('/')
|
||||||
Locale = LoadLocale(SiteLang)
|
Locale = LoadLocale(SiteLang)
|
||||||
|
|
||||||
if DiffBuild:
|
if DiffBuild:
|
||||||
print("[I] Build mode: Differential")
|
print("[I] Build mode: Differential")
|
||||||
LimitFiles = GetModifiedFiles(OutputDir)
|
LimitFiles = GetModifiedFiles(OutDir)
|
||||||
else:
|
else:
|
||||||
print("[I] Build mode: Clean")
|
print("[I] Build mode: Clean")
|
||||||
ResetOutputDir(OutputDir)
|
ResetOutDir(OutDir)
|
||||||
LimitFiles = False
|
LimitFiles = False
|
||||||
|
|
||||||
if os.path.isdir('Pages'):
|
if os.path.isdir('Pages'):
|
||||||
HavePages = True
|
HavePages = True
|
||||||
shutil.copytree('Pages', OutputDir, dirs_exist_ok=True)
|
shutil.copytree('Pages', OutDir, dirs_exist_ok=True)
|
||||||
if GemtextOutput:
|
if Flags['GemtextOutput']:
|
||||||
shutil.copytree('Pages', f"{OutputDir}.gmi", ignore=IgnoreFiles, dirs_exist_ok=True)
|
shutil.copytree('Pages', f"{OutDir}.gmi", ignore=IgnoreFiles, dirs_exist_ok=True)
|
||||||
if os.path.isdir('Posts'):
|
if os.path.isdir('Posts'):
|
||||||
HavePosts = True
|
HavePosts = True
|
||||||
shutil.copytree('Posts', f"{OutputDir}/Posts", dirs_exist_ok=True)
|
shutil.copytree('Posts', f"{OutDir}/Posts", dirs_exist_ok=True)
|
||||||
if GemtextOutput:
|
if Flags['GemtextOutput']:
|
||||||
shutil.copytree('Posts', f"{OutputDir}.gmi/Posts", ignore=IgnoreFiles, dirs_exist_ok=True)
|
shutil.copytree('Posts', f"{OutDir}.gmi/Posts", ignore=IgnoreFiles, dirs_exist_ok=True)
|
||||||
|
|
||||||
if not (HavePages or HavePosts):
|
if not (HavePages or HavePosts):
|
||||||
print("[E] No Pages or posts found. Nothing to do, exiting!")
|
print("[E] No Pages or posts found. Nothing to do, exiting!")
|
||||||
|
@ -190,7 +191,8 @@ def Main(Args, FeedEntries):
|
||||||
|
|
||||||
print("[I] Generating HTML")
|
print("[I] Generating HTML")
|
||||||
Pages = MakeSite(
|
Pages = MakeSite(
|
||||||
OutputDir=OutputDir,
|
Flags=Flags,
|
||||||
|
OutputDir=OutDir,
|
||||||
LimitFiles=LimitFiles,
|
LimitFiles=LimitFiles,
|
||||||
TemplatesText=LoadFromDir('Templates', ['*.htm', '*.html']),
|
TemplatesText=LoadFromDir('Templates', ['*.htm', '*.html']),
|
||||||
StaticPartsText=LoadFromDir('StaticParts', ['*.htm', '*.html']),
|
StaticPartsText=LoadFromDir('StaticParts', ['*.htm', '*.html']),
|
||||||
|
@ -207,53 +209,28 @@ def Main(Args, FeedEntries):
|
||||||
FolderRoots=literal_eval(Args.FolderRoots) if Args.FolderRoots else {},
|
FolderRoots=literal_eval(Args.FolderRoots) if Args.FolderRoots else {},
|
||||||
SiteLang=SiteLang,
|
SiteLang=SiteLang,
|
||||||
Locale=Locale,
|
Locale=Locale,
|
||||||
Minify=Minify,
|
|
||||||
MinifyKeepComments=MinifyKeepComments,
|
|
||||||
NoScripts=NoScripts,
|
|
||||||
ImgAltToTitle=ImgAltToTitle, ImgTitleToAlt=ImgTitleToAlt,
|
|
||||||
Sorting=SetSorting(Sorting),
|
Sorting=SetSorting(Sorting),
|
||||||
MarkdownExts=MarkdownExts,
|
MarkdownExts=MarkdownExts)
|
||||||
AutoCategories=CategoriesAutomatic,
|
|
||||||
CategoryUncategorized=CategoriesUncategorized)
|
|
||||||
|
|
||||||
if FeedEntries != 0:
|
if FeedEntries != 0:
|
||||||
print("[I] Generating Feeds")
|
print("[I] Generating Feeds")
|
||||||
for FeedType in (True, False):
|
for FeedType in (True, False):
|
||||||
MakeFeed(
|
MakeFeed(Flags, Pages, FeedType)
|
||||||
OutputDir=OutputDir,
|
|
||||||
CategoryFilter=FeedCategoryFilter,
|
|
||||||
Pages=Pages,
|
|
||||||
SiteName=SiteName,
|
|
||||||
SiteTagline=SiteTagline,
|
|
||||||
SiteDomain=SiteDomain,
|
|
||||||
MaxEntries=FeedEntries,
|
|
||||||
Lang=SiteLang,
|
|
||||||
FullSite=FeedType,
|
|
||||||
Minify=Minify)
|
|
||||||
|
|
||||||
if ActivityPub and MastodonURL and MastodonToken and SiteDomain:
|
if ActivityPub and MastodonURL and MastodonToken and SiteDomain:
|
||||||
print("[I] Mastodon Stuff")
|
print("[I] Mastodon Stuff")
|
||||||
MastodonPosts = MastodonShare(
|
MastodonPosts = MastodonShare(Flags, Pages, Locale)
|
||||||
InstanceURL=MastodonURL,
|
|
||||||
Token=MastodonToken,
|
|
||||||
Pages=Pages,
|
|
||||||
SiteDomain=SiteDomain,
|
|
||||||
SiteLang=SiteLang,
|
|
||||||
Locale=Locale,
|
|
||||||
TypeFilter=ActivityPubTypeFilter,
|
|
||||||
CategoryFilter=FeedCategoryFilter,
|
|
||||||
HoursLimit=ActivityPubHoursLimit)
|
|
||||||
else:
|
else:
|
||||||
MastodonPosts = []
|
MastodonPosts = []
|
||||||
|
|
||||||
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
|
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
|
||||||
if IsLightRun(File, LimitFiles):
|
if IsLightRun(File, LimitFiles):
|
||||||
continue
|
continue
|
||||||
File = f"{OutputDir}/{StripExt(File)}.html"
|
File = f"{OutDir}/{StripExt(File)}.html"
|
||||||
Content = ReadFile(File)
|
Content = ReadFile(File)
|
||||||
Post = ''
|
Post = ''
|
||||||
for p in MastodonPosts:
|
for p in MastodonPosts:
|
||||||
if p['Link'] == SiteDomain + '/' + File[len(f"{OutputDir}/"):]:
|
if p['Link'] == SiteDomain + '/' + File[len(f"{OutDir}/"):]:
|
||||||
Post = '<br><h3>{StrComments}</h3><a href="{URL}" rel="noopener" target="_blank">{StrOpen} ↗️</a>'.format(
|
Post = '<br><h3>{StrComments}</h3><a href="{URL}" rel="noopener" target="_blank">{StrOpen} ↗️</a>'.format(
|
||||||
StrComments=Locale['Comments'],
|
StrComments=Locale['Comments'],
|
||||||
StrOpen=Locale['OpenInNewTab'],
|
StrOpen=Locale['OpenInNewTab'],
|
||||||
|
@ -262,22 +239,25 @@ def Main(Args, FeedEntries):
|
||||||
Content = ReplWithEsc(Content, '[staticoso:Comments]', Post)
|
Content = ReplWithEsc(Content, '[staticoso:Comments]', Post)
|
||||||
WriteFile(File, Content)
|
WriteFile(File, Content)
|
||||||
|
|
||||||
if GemtextOutput:
|
if Flags['GemtextOutput']:
|
||||||
print("[I] Generating Gemtext")
|
print("[I] Generating Gemtext")
|
||||||
GemtextCompileList(OutputDir, Pages, LimitFiles, GemtextHeader)
|
GemtextCompileList(Flags, Pages, LimitFiles)
|
||||||
|
|
||||||
print("[I] Cleaning Temporary Files")
|
print("[I] Cleaning Temporary Files")
|
||||||
DelTmp(OutputDir)
|
DelTmp(OutDir)
|
||||||
|
|
||||||
if SitemapOutput:
|
if Flags['SitemapOutput']:
|
||||||
print("[I] Generating Sitemap")
|
print("[I] Generating Sitemap")
|
||||||
MakeSitemap(OutputDir, Pages, SiteDomain)
|
MakeSitemap(Flags, Pages)
|
||||||
|
|
||||||
print("[I] Copying Assets")
|
print("[I] Copying Assets")
|
||||||
os.system(f"cp -R Assets/* {OutputDir}/")
|
os.system(f"cp -R Assets/* {OutDir}/")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
StartTime = time.time()
|
||||||
|
|
||||||
Parser = argparse.ArgumentParser()
|
Parser = argparse.ArgumentParser()
|
||||||
|
Parser.add_argument('--Logging', type=str) # Levels: Debug, Verbose, Info, Warning, Error.
|
||||||
Parser.add_argument('--DiffBuild', type=str)
|
Parser.add_argument('--DiffBuild', type=str)
|
||||||
Parser.add_argument('--OutputDir', type=str)
|
Parser.add_argument('--OutputDir', type=str)
|
||||||
#Parser.add_argument('--InputDir', type=str)
|
#Parser.add_argument('--InputDir', type=str)
|
||||||
|
@ -321,4 +301,4 @@ if __name__ == '__main__':
|
||||||
Main(
|
Main(
|
||||||
Args=Args,
|
Args=Args,
|
||||||
FeedEntries=FeedEntries)
|
FeedEntries=FeedEntries)
|
||||||
print(f"[I] ✅ Done! ({round(time.process_time(),3)}s)")
|
print(f"[I] ✅ Done! ({round(time.process_time(),3)} / {round(time.time()-StartTime,3)} s)")
|
||||||
|
|
|
@ -51,8 +51,11 @@ def MastodonGetAllLinkPosts(Session, Domain=None):
|
||||||
Posts += [Post]
|
Posts += [Post]
|
||||||
return Posts
|
return Posts
|
||||||
|
|
||||||
def MastodonShare(InstanceURL, Token, TypeFilter, CategoryFilter, HoursLimit, Pages, SiteDomain, SiteLang, Locale):
|
def MastodonShare(Flags, Pages, Locale):
|
||||||
SaidPosting = False
|
SaidPosting = False
|
||||||
|
SiteDomain, SiteLang = Flags['SiteDomain'], Flags['SiteLang']
|
||||||
|
InstanceURL, Token = Flags['MastodonURL'], Flags['MastodonToken']
|
||||||
|
TypeFilter, HoursLimit, CategoryFilter = Flags['ActivityPubTypeFilter'], Flags['ActivityPubHoursLimit'], Flags['FeedCategoryFilter']
|
||||||
Session = MastodonGetSession(InstanceURL, Token)
|
Session = MastodonGetSession(InstanceURL, Token)
|
||||||
Posts = MastodonGetAllLinkPosts(Session, SiteDomain)
|
Posts = MastodonGetAllLinkPosts(Session, SiteDomain)
|
||||||
Pages.sort()
|
Pages.sort()
|
||||||
|
|
|
@ -12,13 +12,13 @@ from ast import literal_eval
|
||||||
|
|
||||||
def LoadConfFile(File):
|
def LoadConfFile(File):
|
||||||
Conf = configparser.ConfigParser()
|
Conf = configparser.ConfigParser()
|
||||||
Conf.optionxform = lambda option: option
|
Conf.optionxform = str
|
||||||
Conf.read(File)
|
Conf.read(File)
|
||||||
return Conf
|
return Conf
|
||||||
|
|
||||||
def LoadConfStr(Str):
|
def LoadConfStr(Str):
|
||||||
Conf = configparser.ConfigParser()
|
Conf = configparser.ConfigParser()
|
||||||
Conf.optionxform = lambda option: option
|
Conf.optionxform = str
|
||||||
Conf.read_string(Str)
|
Conf.read_string(Str)
|
||||||
return Conf
|
return Conf
|
||||||
|
|
||||||
|
|
|
@ -12,16 +12,19 @@
|
||||||
from Libs.feedgen.feed import FeedGenerator
|
from Libs.feedgen.feed import FeedGenerator
|
||||||
from Modules.Utils import *
|
from Modules.Utils import *
|
||||||
|
|
||||||
def MakeFeed(OutputDir, CategoryFilter, Pages, SiteName, SiteTagline, SiteDomain, MaxEntries, Lang, FullSite=False, Minify=False):
|
def MakeFeed(Flags, Pages, FullSite=False):
|
||||||
|
CategoryFilter = Flags['FeedCategoryFilter']
|
||||||
|
MaxEntries = Flags['FeedEntries']
|
||||||
|
|
||||||
Feed = FeedGenerator()
|
Feed = FeedGenerator()
|
||||||
Link = SiteDomain if SiteDomain else ' '
|
Link = Flags['SiteDomain'] if Flags['SiteDomain'] else ' '
|
||||||
Feed.id(Link)
|
Feed.id(Link)
|
||||||
Feed.title(SiteName if SiteName else 'Untitled Site')
|
Feed.title(Flags['SiteName'] if Flags['SiteName'] else 'Untitled Site')
|
||||||
Feed.link(href=Link, rel='alternate')
|
Feed.link(href=Link, rel='alternate')
|
||||||
Feed.description(SiteTagline if SiteTagline else ' ')
|
Feed.description(Flags['SiteTagline'] if Flags['SiteTagline'] else ' ')
|
||||||
if SiteDomain:
|
if Flags['SiteDomain']:
|
||||||
Feed.logo(SiteDomain + '/favicon.png')
|
Feed.logo(Flags['SiteDomain'] + '/favicon.png')
|
||||||
Feed.language(Lang)
|
Feed.language(Flags['SiteLang'])
|
||||||
|
|
||||||
DoPages = []
|
DoPages = []
|
||||||
for e in Pages:
|
for e in Pages:
|
||||||
|
@ -35,8 +38,8 @@ def MakeFeed(OutputDir, CategoryFilter, Pages, SiteName, SiteTagline, SiteDomain
|
||||||
Entry = Feed.add_entry()
|
Entry = Feed.add_entry()
|
||||||
FileName = File.split('/')[-1]
|
FileName = File.split('/')[-1]
|
||||||
File = f"{StripExt(File)}.html"
|
File = f"{StripExt(File)}.html"
|
||||||
Content = ReadFile(f"{OutputDir}/{File}")
|
Content = ReadFile(f"{Flags['OutDir']}/{File}")
|
||||||
Link = SiteDomain + '/' + File if SiteDomain else ' '
|
Link = Flags['SiteDomain'] + '/' + File if Flags['SiteDomain'] else ' '
|
||||||
CreatedOn = GetFullDate(Meta['CreatedOn'])
|
CreatedOn = GetFullDate(Meta['CreatedOn'])
|
||||||
EditedOn = GetFullDate(Meta['EditedOn'])
|
EditedOn = GetFullDate(Meta['EditedOn'])
|
||||||
Entry.id(Link)
|
Entry.id(Link)
|
||||||
|
@ -51,8 +54,8 @@ def MakeFeed(OutputDir, CategoryFilter, Pages, SiteName, SiteTagline, SiteDomain
|
||||||
EditedOn = EditedOn if EditedOn else CreatedOn if CreatedOn and not EditedOn else '1970-01-01T00:00+00:00'
|
EditedOn = EditedOn if EditedOn else CreatedOn if CreatedOn and not EditedOn else '1970-01-01T00:00+00:00'
|
||||||
Entry.updated(EditedOn)
|
Entry.updated(EditedOn)
|
||||||
|
|
||||||
if not os.path.exists(f"{OutputDir}/feed"):
|
if not os.path.exists(f"{Flags['OutDir']}/feed"):
|
||||||
os.mkdir(f"{OutputDir}/feed")
|
os.mkdir(f"{Flags['OutDir']}/feed")
|
||||||
FeedType = 'site.' if FullSite else ''
|
FeedType = 'site.' if FullSite else ''
|
||||||
Feed.atom_file(f"{OutputDir}/feed/{FeedType}atom.xml", pretty=(not Minify))
|
Feed.atom_file(f"{Flags['OutDir']}/feed/{FeedType}atom.xml", pretty=(not Flags['Minify']))
|
||||||
Feed.rss_file(f"{OutputDir}/feed/{FeedType}rss.xml", pretty=(not Minify))
|
Feed.rss_file(f"{Flags['OutDir']}/feed/{FeedType}rss.xml", pretty=(not Flags['Minify']))
|
||||||
|
|
|
@ -22,13 +22,13 @@ def FixGemlogDateLine(Line):
|
||||||
Line = Words[0] + '\n' + Words[1][1:] + ' ' + ' '.join(Words[2:])
|
Line = Words[0] + '\n' + Words[1][1:] + ' ' + ' '.join(Words[2:])
|
||||||
return Line
|
return Line
|
||||||
|
|
||||||
def GemtextCompileList(OutputDir, Pages, LimitFiles, Header=''):
|
def GemtextCompileList(Flags, Pages, LimitFiles):
|
||||||
Cmd = ''
|
Cmd = ''
|
||||||
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
|
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
|
||||||
if IsLightRun(File, LimitFiles):
|
if IsLightRun(File, LimitFiles):
|
||||||
continue
|
continue
|
||||||
Src = f"{OutputDir}.gmi/{StripExt(File)}.html.tmp"
|
Src = f"{Flags['OutDir']}.gmi/{StripExt(File)}.html.tmp"
|
||||||
Dst = f"{OutputDir}.gmi/{StripExt(File)}.gmi"
|
Dst = f"{Flags['OutDir']}.gmi/{StripExt(File)}.gmi"
|
||||||
SlimHTML = StripAttrs(SlimHTML)
|
SlimHTML = StripAttrs(SlimHTML)
|
||||||
for i in ('ol', 'ul', 'li'):
|
for i in ('ol', 'ul', 'li'):
|
||||||
for j in ('<'+i+'>', '</'+i+'>'):
|
for j in ('<'+i+'>', '</'+i+'>'):
|
||||||
|
@ -40,12 +40,12 @@ def GemtextCompileList(OutputDir, Pages, LimitFiles, Header=''):
|
||||||
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
|
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
|
||||||
if IsLightRun(File, LimitFiles):
|
if IsLightRun(File, LimitFiles):
|
||||||
continue
|
continue
|
||||||
Dst = f"{OutputDir}.gmi/{StripExt(File)}.gmi"
|
Dst = f"{Flags['OutDir']}.gmi/{StripExt(File)}.gmi"
|
||||||
Gemtext = ''
|
Gemtext = ''
|
||||||
for Line in ReadFile(Dst).splitlines():
|
for Line in ReadFile(Dst).splitlines():
|
||||||
Line = FixGemlogDateLine(Line)
|
Line = FixGemlogDateLine(Line)
|
||||||
Gemtext += Line + '\n'
|
Gemtext += Line + '\n'
|
||||||
WriteFile(Dst, Header + Gemtext)
|
WriteFile(Dst, Flags['GemtextHeader'] + Gemtext)
|
||||||
|
|
||||||
def FindEarliest(Str, Items):
|
def FindEarliest(Str, Items):
|
||||||
Pos, Item = 0, ''
|
Pos, Item = 0, ''
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
| ================================= """
|
| ================================= """
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from multiprocessing import Pool
|
||||||
from Libs.bs4 import BeautifulSoup
|
from Libs.bs4 import BeautifulSoup
|
||||||
from Modules.Config import *
|
from Modules.Config import *
|
||||||
from Modules.HTML import *
|
from Modules.HTML import *
|
||||||
|
@ -389,8 +390,12 @@ def PatchHTML(File, HTML, StaticPartsText, DynamicParts, DynamicPartsText, HTMLP
|
||||||
|
|
||||||
return HTML, ContentHTML, Description, Image
|
return HTML, ContentHTML, Description, Image
|
||||||
|
|
||||||
def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts, DynamicPartsText, ConfMenu, GlobalMacros, SiteName, BlogName, SiteTagline, SiteTemplate, SiteDomain, SiteRoot, FolderRoots, SiteLang, Locale, Minify, MinifyKeepComments, NoScripts, ImgAltToTitle, ImgTitleToAlt, Sorting, MarkdownExts, AutoCategories, CategoryUncategorized):
|
def MakeSite(Flags, OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts, DynamicPartsText, ConfMenu, GlobalMacros, SiteName, BlogName, SiteTagline, SiteTemplate, SiteDomain, SiteRoot, FolderRoots, SiteLang, Locale, Sorting, MarkdownExts):
|
||||||
PagesPaths, PostsPaths, Pages, MadePages, Categories = [], [], [], [], {}
|
PagesPaths, PostsPaths, Pages, MadePages, Categories = [], [], [], [], {}
|
||||||
|
AutoCategories, CategoryUncategorized = Flags['CategoriesAutomatic'], Flags['CategoriesUncategorized']
|
||||||
|
ImgAltToTitle, ImgTitleToAlt = Flags['ImgAltToTitle'], Flags['ImgTitleToAlt']
|
||||||
|
MinifyKeepComments = Flags['MinifyKeepComments']
|
||||||
|
|
||||||
for Ext in FileExtensions['Pages']:
|
for Ext in FileExtensions['Pages']:
|
||||||
for File in Path('Pages').rglob(f"*.{Ext}"):
|
for File in Path('Pages').rglob(f"*.{Ext}"):
|
||||||
PagesPaths += [FileToStr(File, 'Pages/')]
|
PagesPaths += [FileToStr(File, 'Pages/')]
|
||||||
|
@ -458,9 +463,10 @@ def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts
|
||||||
|
|
||||||
print("[I] Writing Pages")
|
print("[I] Writing Pages")
|
||||||
for File, Content, Titles, Meta in Pages:
|
for File, Content, Titles, Meta in Pages:
|
||||||
|
#print(f'-> {File}')
|
||||||
LightRun = False if LimitFiles == False or File in LimitFiles else True
|
LightRun = False if LimitFiles == False or File in LimitFiles else True
|
||||||
|
|
||||||
PagePath = f"{OutputDir}/{StripExt(File)}.html"
|
PagePath = f"{OutputDir}/{StripExt(File)}.html"
|
||||||
|
|
||||||
if File.lower().endswith(FileExtensions['Markdown']):
|
if File.lower().endswith(FileExtensions['Markdown']):
|
||||||
Content = markdown(PagePostprocessor('md', Content, Meta), extensions=MarkdownExts)
|
Content = markdown(PagePostprocessor('md', Content, Meta), extensions=MarkdownExts)
|
||||||
elif File.lower().endswith(('.pug')):
|
elif File.lower().endswith(('.pug')):
|
||||||
|
@ -505,11 +511,11 @@ def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts
|
||||||
Locale=Locale,
|
Locale=Locale,
|
||||||
LightRun=LightRun)
|
LightRun=LightRun)
|
||||||
|
|
||||||
if Minify:
|
if Flags['Minify']:
|
||||||
if not LightRun:
|
if not LightRun:
|
||||||
HTML = DoMinifyHTML(HTML, MinifyKeepComments)
|
HTML = DoMinifyHTML(HTML, MinifyKeepComments)
|
||||||
ContentHTML = DoMinifyHTML(ContentHTML, MinifyKeepComments)
|
ContentHTML = DoMinifyHTML(ContentHTML, MinifyKeepComments)
|
||||||
if NoScripts:
|
if Flags['NoScripts']:
|
||||||
if not LightRun:
|
if not LightRun:
|
||||||
HTML = StripTags(HTML, ['script'])
|
HTML = StripTags(HTML, ['script'])
|
||||||
ContentHTML = StripTags(ContentHTML, ['script'])
|
ContentHTML = StripTags(ContentHTML, ['script'])
|
||||||
|
@ -522,7 +528,6 @@ def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts
|
||||||
SlimHTML = None
|
SlimHTML = None
|
||||||
else:
|
else:
|
||||||
SlimHTML = HTMLPagesList + ContentHTML
|
SlimHTML = HTMLPagesList + ContentHTML
|
||||||
|
|
||||||
if not LightRun:
|
if not LightRun:
|
||||||
WriteFile(PagePath, HTML)
|
WriteFile(PagePath, HTML)
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
from urllib.parse import quote as URLEncode
|
from urllib.parse import quote as URLEncode
|
||||||
from Modules.Utils import *
|
from Modules.Utils import *
|
||||||
|
|
||||||
def MakeSitemap(OutputDir, Pages, SiteDomain=''):
|
def MakeSitemap(Flags, Pages):
|
||||||
Map = ''
|
Map = ''
|
||||||
Domain = SiteDomain + '/' if SiteDomain else ''
|
Domain = Flags['SiteDomain'] + '/' if Flags['SiteDomain'] else ''
|
||||||
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
|
for File, Content, Titles, Meta, ContentHTML, SlimHTML, Description, Image in Pages:
|
||||||
File = f"{StripExt(File)}.html"
|
File = f"{StripExt(File)}.html"
|
||||||
Map += Domain + URLEncode(File) + '\n'
|
Map += Domain + URLEncode(File) + '\n'
|
||||||
WriteFile(f"{OutputDir}/sitemap.txt", Map)
|
WriteFile(f"{Flags['OutDir']}/sitemap.txt", Map)
|
||||||
|
|
1
TODO
1
TODO
|
@ -1,3 +1,4 @@
|
||||||
|
- Posts in draft state (will not be compiled)
|
||||||
- Check if external tools (pug-cli, html2gmi) are installed
|
- Check if external tools (pug-cli, html2gmi) are installed
|
||||||
- Fix and optimize differential building
|
- Fix and optimize differential building
|
||||||
- Static code syntax highlighing
|
- Static code syntax highlighing
|
||||||
|
|
Loading…
Reference in New Issue