Working towards differential building

This commit is contained in:
octospacc 2022-08-27 16:50:50 +02:00
parent 9cf3bc3e27
commit 506f251a7b
6 changed files with 82 additions and 42 deletions

View File

@ -19,7 +19,7 @@ try:
from Modules.ActivityPub import * from Modules.ActivityPub import *
ActivityPub = True ActivityPub = True
except: except:
print("[E] Can't load the ActivityPub module. Its use is disabled. Make sure the 'requests' library is installed.") print("[W] ⚠️ Can't load the ActivityPub module. Its use is disabled. Make sure the 'requests' library is installed.")
ActivityPub = False ActivityPub = False
from Modules.Config import * from Modules.Config import *
@ -29,18 +29,18 @@ from Modules.Site import *
from Modules.Sitemap import * from Modules.Sitemap import *
from Modules.Utils import * from Modules.Utils import *
def ResetPublic(OutputDir): def ResetOutputDir(OutDir):
for i in (OutputDir, f"{OutputDir}.gmi"): for e in (OutDir, f"{OutDir}.gmi"):
try: try:
shutil.rmtree(i) shutil.rmtree(e)
except FileNotFoundError: except FileNotFoundError:
pass pass
def DelTmp(OutputDir): def DelTmp(OutDir):
for Ext in FileExtensions['Tmp']: for Ext in FileExtensions['Tmp']:
for File in Path(OutputDir).rglob(f"*.{Ext}"): for File in Path(OutDir).rglob(f"*.{Ext}"):
os.remove(File) os.remove(File)
for Dir in (OutputDir, f"{OutputDir}.gmi"): for Dir in (OutDir, f"{OutDir}.gmi"):
for File in Path(Dir).rglob('*.tmp'): for File in Path(Dir).rglob('*.tmp'):
os.remove(File) os.remove(File)
@ -73,16 +73,48 @@ def CheckSafeOutputDir(OutDir):
OutDir = os.path.realpath(OutDir) OutDir = os.path.realpath(OutDir)
OutFolder = OutDir.split('/')[-1] OutFolder = OutDir.split('/')[-1]
if InDir == OutDir: if InDir == OutDir:
print(f"[E] Output and Input directories ({OutDir}) can't be the same. Exiting.") print(f"[E] Output and Input directories ({OutDir}) can't be the same. Exiting.")
exit(1) exit(1)
elif OutFolder in ReservedPaths and f"{InDir}/{OutFolder}" == OutDir: elif OutFolder in ReservedPaths and f"{InDir}/{OutFolder}" == OutDir:
print(f"[E] Output directory {OutDir} can't be a reserved subdirectory of the Input. Exiting.") print(f"[E] Output directory {OutDir} can't be a reserved subdirectory of the Input. Exiting.")
exit(1) exit(1)
def GetModifiedFiles(OutDir):
All, Mod = [], []
for Path in ('Pages', 'Posts'):
for Root, Dirs, Files in os.walk(Path):
for File in Files:
Src = os.path.join(Root,File)
SrcTime = int(os.path.getmtime(Src))
if Path == 'Pages':
Tmp = '/'.join(Src.split('/')[1:])
elif Path == 'Posts':
Tmp = Src
Obj = f"{OutDir}/{StripExt(Tmp)}.html"
try:
ObjTime = int(os.path.getmtime(Obj))
except FileNotFoundError:
ObjTime = 0
All += [{'Tmp':Tmp, 'SrcTime':SrcTime, 'ObjTime':ObjTime}]
for File in All:
if File['SrcTime'] > File['ObjTime']:
Mod += [File['Tmp']]
#Latest = 0
#for File in Sources:
# if File['t'] > Latest:
# Latest = File['t']
#Meta = ReadFile('staticoso.meta')
return Mod
def Main(Args, FeedEntries): def Main(Args, FeedEntries):
HavePages, HavePosts = False, False HavePages, HavePosts = False, False
SiteConf = LoadConfFile('Site.ini') SiteConf = LoadConfFile('Site.ini')
#if Args.InputDir:
# os.chdir(Args.InputDir)
# print(f"[I] Current directory: {Args.InputDir}")
CleanBuild = Args.CleanBuild
OutputDir = Args.OutputDir if Args.OutputDir else ReadConf(SiteConf, 'Site', 'OutputDir') if ReadConf(SiteConf, 'Site', 'OutputDir') else 'public' OutputDir = Args.OutputDir if Args.OutputDir else ReadConf(SiteConf, 'Site', 'OutputDir') if ReadConf(SiteConf, 'Site', 'OutputDir') else 'public'
OutputDir = OutputDir.removesuffix('/') OutputDir = OutputDir.removesuffix('/')
CheckSafeOutputDir(OutputDir) CheckSafeOutputDir(OutputDir)
@ -120,18 +152,23 @@ def Main(Args, FeedEntries):
else: else:
ConfMenu = [] ConfMenu = []
ResetPublic(OutputDir) if CleanBuild:
print("[I] Building Clean")
ResetOutputDir(OutputDir)
else:
print("[I] Building Differentially")
LimitFiles = GetModifiedFiles(OutputDir)
if os.path.isdir('Pages'): if os.path.isdir('Pages'):
HavePages = True HavePages = True
shutil.copytree('Pages', OutputDir) shutil.copytree('Pages', OutputDir, dirs_exist_ok=True)
if GemtextOut: if GemtextOut:
shutil.copytree('Pages', f"{OutputDir}.gmi", ignore=IgnoreFiles) shutil.copytree('Pages', f"{OutputDir}.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") shutil.copytree('Posts', f"{OutputDir}/Posts", dirs_exist_ok=True)
if GemtextOut: if GemtextOut:
shutil.copytree('Posts', f"{OutputDir}.gmi/Posts", ignore=IgnoreFiles) shutil.copytree('Posts', f"{OutputDir}.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!")
@ -140,6 +177,7 @@ def Main(Args, FeedEntries):
print("[I] Generating HTML") print("[I] Generating HTML")
Pages = MakeSite( Pages = MakeSite(
OutputDir=OutputDir, OutputDir=OutputDir,
LimitFiles=LimitFiles,
TemplatesText=LoadFromDir('Templates', ['*.htm', '*.html']), TemplatesText=LoadFromDir('Templates', ['*.htm', '*.html']),
StaticPartsText=LoadFromDir('StaticParts', ['*.htm', '*.html']), StaticPartsText=LoadFromDir('StaticParts', ['*.htm', '*.html']),
DynamicParts=DynamicParts, DynamicParts=DynamicParts,
@ -220,11 +258,14 @@ def Main(Args, FeedEntries):
print("[I] Copying Assets") print("[I] Copying Assets")
os.system(f"cp -R Assets/* {OutputDir}/") os.system(f"cp -R Assets/* {OutputDir}/")
print("[I] Done!") print("[I] Done!")
if __name__ == '__main__': if __name__ == '__main__':
Parser = argparse.ArgumentParser() Parser = argparse.ArgumentParser()
Parser.add_argument('--CleanBuild', action='store_true')
Parser.add_argument('--OutputDir', type=str) Parser.add_argument('--OutputDir', type=str)
#Parser.add_argument('--InputDir', type=str)
#Parser.add_argument('--InputFiles', type=str, nargs='+')
Parser.add_argument('--Sorting', type=str) Parser.add_argument('--Sorting', type=str)
Parser.add_argument('--SiteLang', type=str) Parser.add_argument('--SiteLang', type=str)
Parser.add_argument('--SiteRoot', type=str) Parser.add_argument('--SiteRoot', type=str)
@ -257,7 +298,7 @@ if __name__ == '__main__':
from Modules.Feed import * from Modules.Feed import *
FeedEntries = Args.FeedEntries if Args.FeedEntries else 'Default' FeedEntries = Args.FeedEntries if Args.FeedEntries else 'Default'
except: except:
print("[W] Can't load the XML libraries. XML Feeds Generation is Disabled. Make sure the 'lxml' library is installed.") print("[W] ⚠️ Can't load the XML libraries. XML Feeds Generation is Disabled. Make sure the 'lxml' library is installed.")
FeedEntries = 0 FeedEntries = 0
Main( Main(

View File

@ -7,7 +7,6 @@
| Copyright (C) 2022, OctoSpacc | | Copyright (C) 2022, OctoSpacc |
| ================================= """ | ================================= """
import io
import configparser import configparser
from ast import literal_eval from ast import literal_eval

View File

@ -12,11 +12,11 @@
import os import os
from Modules.Utils import * from Modules.Utils import *
def PugCompileList(OutputDir, Pages): def PugCompileList(OutputDir, Pages, LimitFiles):
# Pug-cli seems to shit itself with folder paths as input, so we pass ALL the files as arguments # Pug-cli seems to shit itself with folder paths as input, so we pass ALL the files as arguments
Paths = '' Paths = ''
for File, Content, Titles, Meta in Pages: for File, Content, Titles, Meta in Pages:
if File.lower().endswith('.pug'): if File.lower().endswith('.pug') and File in LimitFiles:
Path = f'{OutputDir}/{File}' Path = f'{OutputDir}/{File}'
WriteFile(Path, Content) WriteFile(Path, Content)
Paths += f'"{Path}" ' Paths += f'"{Path}" '

View File

@ -373,7 +373,7 @@ def DoMinifyHTML(HTML):
convert_charrefs=True, convert_charrefs=True,
keep_pre=True) keep_pre=True)
def MakeSite(OutputDir, TemplatesText, StaticPartsText, DynamicParts, DynamicPartsText, ConfMenu, GlobalMacros, SiteName, BlogName, SiteTagline, SiteTemplate, SiteDomain, SiteRoot, FolderRoots, SiteLang, Locale, Minify, NoScripts, ImgAltToTitle, ImgTitleToAlt, Sorting, MarkdownExts, AutoCategories): def MakeSite(OutputDir, LimitFiles, TemplatesText, StaticPartsText, DynamicParts, DynamicPartsText, ConfMenu, GlobalMacros, SiteName, BlogName, SiteTagline, SiteTemplate, SiteDomain, SiteRoot, FolderRoots, SiteLang, Locale, Minify, NoScripts, ImgAltToTitle, ImgTitleToAlt, Sorting, MarkdownExts, AutoCategories):
PagesPaths, PostsPaths, Pages, MadePages, Categories = [], [], [], [], {} PagesPaths, PostsPaths, Pages, MadePages, Categories = [], [], [], [], {}
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}"):
@ -381,14 +381,12 @@ def MakeSite(OutputDir, TemplatesText, StaticPartsText, DynamicParts, DynamicPar
for File in Path('Posts').rglob(f"*.{Ext}"): for File in Path('Posts').rglob(f"*.{Ext}"):
PostsPaths += [FileToStr(File, 'Posts/')] PostsPaths += [FileToStr(File, 'Posts/')]
if PagesPaths: PagesPaths = FileNameDateSort(PagesPaths)
PagesPaths = FileNameDateSort(PagesPaths) if Sorting['Pages'] == 'Inverse':
if Sorting['Pages'] == 'Inverse': PagesPaths.reverse()
PagesPaths.reverse() PostsPaths = FileNameDateSort(PostsPaths)
if PostsPaths: if Sorting['Posts'] == 'Inverse':
PostsPaths = FileNameDateSort(PostsPaths) PostsPaths.reverse()
if Sorting['Posts'] == 'Inverse':
PostsPaths.reverse()
print("[I] Preprocessing Source Pages") print("[I] Preprocessing Source Pages")
for Type in ['Page', 'Post']: for Type in ['Page', 'Post']:
@ -403,7 +401,7 @@ def MakeSite(OutputDir, TemplatesText, StaticPartsText, DynamicParts, DynamicPar
Pages += [[File, Content, Titles, Meta]] Pages += [[File, Content, Titles, Meta]]
for Cat in Meta['Categories']: for Cat in Meta['Categories']:
Categories.update({Cat:''}) Categories.update({Cat:''})
PugCompileList(OutputDir, Pages) PugCompileList(OutputDir, Pages, LimitFiles)
if Categories: if Categories:
print("[I] Generating Category Lists") print("[I] Generating Category Lists")

View File

@ -116,19 +116,20 @@ def RevSort(List):
def FileNameDateSort(Old): # TODO: Test this for files not starting with date, and dated folders def FileNameDateSort(Old): # TODO: Test this for files not starting with date, and dated folders
New = [] New = []
Old.sort() if Old:
New.insert(0, Old[0]) Old.sort()
for i,e in enumerate(Old): New.insert(0, Old[0])
if i == 0: for i,e in enumerate(Old):
continue if i == 0:
Done = False continue
for j,f in enumerate(New): Done = False
if NumsFromFileName(e) != e and NumsFromFileName(f) != f and NumsFromFileName(e) < NumsFromFileName(f): for j,f in enumerate(New):
New.insert(j, e) if NumsFromFileName(e) != e and NumsFromFileName(f) != f and NumsFromFileName(e) < NumsFromFileName(f):
Done = True New.insert(j, e)
break Done = True
if not Done: break
New += [e] if not Done:
New += [e]
return New return New
def FirstRealItem(List): def FirstRealItem(List):

1
TODO
View File

@ -1,3 +1,4 @@
- Check if external tools are installed
- Specify input folder(s) and files (idea is Makefile compatibility too) - Specify input folder(s) and files (idea is Makefile compatibility too)
- Show page size/words/time in meta line - Show page size/words/time in meta line
- Add feed support for diary-like pages - Add feed support for diary-like pages