2022-06-26 00:06:34 +02:00
|
|
|
""" ================================= |
|
|
|
|
| This file is part of |
|
|
|
|
| staticoso |
|
|
|
|
| Just a simple Static Site Generator |
|
|
|
|
| |
|
|
|
|
| Licensed under the AGPLv3 license |
|
|
|
|
| Copyright (C) 2022, OctoSpacc |
|
|
|
|
| ================================= """
|
|
|
|
|
|
|
|
import json
|
|
|
|
import os
|
|
|
|
from datetime import datetime
|
2022-07-08 16:45:17 +02:00
|
|
|
from pathlib import Path
|
2022-06-26 00:06:34 +02:00
|
|
|
|
2022-08-23 22:26:21 +02:00
|
|
|
ReservedPaths = ('Site.ini', 'Assets', 'Pages', 'Posts', 'Templates', 'StaticParts', 'DynamicParts')
|
2022-07-14 20:38:45 +02:00
|
|
|
FileExtensions = {
|
2022-08-14 17:35:58 +02:00
|
|
|
'Pages': ('htm', 'html', 'markdown', 'md', 'pug', 'txt'),
|
|
|
|
'HTML': ('.htm', '.html'),
|
|
|
|
'Markdown': ('.markdown', '.md'),
|
|
|
|
'Tmp': ('htm', 'markdown', 'md', 'pug', 'txt')}
|
2022-07-14 20:38:45 +02:00
|
|
|
|
2022-06-26 00:06:34 +02:00
|
|
|
def ReadFile(p):
|
|
|
|
try:
|
|
|
|
with open(p, 'r') as f:
|
|
|
|
return f.read()
|
|
|
|
except Exception:
|
2022-08-24 15:04:13 +02:00
|
|
|
print(f"[E] Error reading file {p}")
|
2022-06-26 00:06:34 +02:00
|
|
|
return None
|
|
|
|
|
|
|
|
def WriteFile(p, c):
|
|
|
|
try:
|
|
|
|
with open(p, 'w') as f:
|
|
|
|
f.write(c)
|
|
|
|
return True
|
|
|
|
except Exception:
|
2022-08-24 15:04:13 +02:00
|
|
|
print(f"[E] Error writing file {p}")
|
2022-06-26 00:06:34 +02:00
|
|
|
return False
|
|
|
|
|
|
|
|
def FileToStr(File, Truncate=''):
|
|
|
|
return str(File)[len(Truncate):]
|
|
|
|
|
2022-06-29 23:56:20 +02:00
|
|
|
# https://stackoverflow.com/a/15664273
|
|
|
|
def IgnoreFiles(Dir, Files):
|
|
|
|
return [f for f in Files if os.path.isfile(os.path.join(Dir, f))]
|
|
|
|
|
2022-08-14 17:35:58 +02:00
|
|
|
def LoadFromDir(Dir, Matchs):
|
2022-07-08 16:45:17 +02:00
|
|
|
Contents = {}
|
2022-08-14 17:35:58 +02:00
|
|
|
if type(Matchs) != list:
|
|
|
|
Matchs = [Matchs]
|
|
|
|
for Match in Matchs:
|
|
|
|
for File in Path(Dir).rglob(Match):
|
|
|
|
File = str(File)[len(Dir)+1:]
|
2022-08-24 15:04:13 +02:00
|
|
|
Contents.update({File: ReadFile(f"{Dir}/{File}")})
|
2022-07-08 16:45:17 +02:00
|
|
|
return Contents
|
|
|
|
|
2022-06-26 00:06:34 +02:00
|
|
|
def StripExt(Path):
|
|
|
|
return ".".join(Path.split('.')[:-1])
|
|
|
|
|
|
|
|
def UndupeStr(Str, Known, Split):
|
|
|
|
while Str in Known:
|
2022-07-08 15:50:40 +02:00
|
|
|
Sections = Str.split(Split)
|
2022-06-26 00:06:34 +02:00
|
|
|
try:
|
|
|
|
Sections[-1] = str(int(Sections[-1]) + 1)
|
|
|
|
except ValueError:
|
|
|
|
Sections[-1] = Sections[-1] + str(Split) + '2'
|
|
|
|
Str = Split.join(Sections)
|
|
|
|
return Str
|
|
|
|
|
|
|
|
def DashifyStr(s, Limit=32):
|
2022-08-24 15:04:13 +02:00
|
|
|
Str = ''
|
|
|
|
for c in s[:Limit].replace('\n','-').replace('\t','-').replace(' ','-'):
|
2022-06-26 00:06:34 +02:00
|
|
|
if c.lower() in '0123456789qwfpbjluyarstgmneiozxcdvkh-':
|
|
|
|
Str += c
|
|
|
|
return '-' + Str
|
|
|
|
|
2022-07-14 20:38:45 +02:00
|
|
|
def GetPathLevels(Path, AsNum=False, Add=0, Sub=0):
|
|
|
|
n = Path.count('/') + Add - Sub
|
|
|
|
return n if AsNum else '../' * n
|
|
|
|
|
2022-07-11 22:56:42 +02:00
|
|
|
# https://stackoverflow.com/a/34445090
|
|
|
|
def FindAllIndex(Str, Sub):
|
|
|
|
i = Str.find(Sub)
|
|
|
|
while i != -1:
|
|
|
|
yield i
|
|
|
|
i = Str.find(Sub, i+1)
|
|
|
|
|
2022-08-29 17:50:14 +02:00
|
|
|
# Replace substrings in a string, except when an escape char is prepended
|
2022-07-12 00:22:49 +02:00
|
|
|
def ReplWithEsc(Str, Find, Repl, Esc='\\'):
|
|
|
|
New = ''
|
|
|
|
Sects = Str.split(Find)
|
|
|
|
for i,e in enumerate(Sects):
|
|
|
|
if i == 0:
|
|
|
|
New += e
|
|
|
|
elif i > 0:
|
|
|
|
if Sects[i-1].endswith(Esc*2):
|
|
|
|
New = New[:-1]
|
|
|
|
New += Repl + e
|
|
|
|
elif Sects[i-1].endswith(Esc):
|
2022-08-26 19:53:47 +02:00
|
|
|
New = New[:-1]
|
2022-07-12 00:22:49 +02:00
|
|
|
New += Find + e
|
|
|
|
else:
|
|
|
|
New += Repl + e
|
|
|
|
return New
|
|
|
|
|
2022-08-29 17:50:14 +02:00
|
|
|
def DictReplWithEsc(Str, Dict, Esc='\\'):
|
|
|
|
for Item in Dict:
|
|
|
|
Str = ReplWithEsc(Str, Item, Dict[Item], Esc='\\')
|
|
|
|
return Str
|
|
|
|
|
2022-08-13 20:00:03 +02:00
|
|
|
def NumsFromFileName(Path):
|
|
|
|
Name = Path.split('/')[-1]
|
|
|
|
Split = len(Name)
|
|
|
|
for i,e in enumerate(Name):
|
|
|
|
if e.lower() in 'qwfpbjluyarstgmneiozxcdvkh':
|
|
|
|
return Name[:i]
|
|
|
|
return Path
|
|
|
|
|
2022-07-14 20:38:45 +02:00
|
|
|
def RevSort(List):
|
|
|
|
List.sort()
|
|
|
|
List.reverse()
|
|
|
|
return List
|
|
|
|
|
2022-08-13 20:30:44 +02:00
|
|
|
def FileNameDateSort(Old): # TODO: Test this for files not starting with date, and dated folders
|
2022-08-13 20:00:03 +02:00
|
|
|
New = []
|
2022-08-27 16:50:50 +02:00
|
|
|
if Old:
|
|
|
|
Old.sort()
|
|
|
|
New.insert(0, Old[0])
|
|
|
|
for i,e in enumerate(Old):
|
|
|
|
if i == 0:
|
|
|
|
continue
|
|
|
|
Done = False
|
|
|
|
for j,f in enumerate(New):
|
|
|
|
if NumsFromFileName(e) != e and NumsFromFileName(f) != f and NumsFromFileName(e) < NumsFromFileName(f):
|
|
|
|
New.insert(j, e)
|
|
|
|
Done = True
|
|
|
|
break
|
|
|
|
if not Done:
|
|
|
|
New += [e]
|
2022-08-13 20:00:03 +02:00
|
|
|
return New
|
|
|
|
|
2022-07-29 18:12:13 +02:00
|
|
|
def FirstRealItem(List):
|
|
|
|
return next(e for e in List if e)
|
|
|
|
|
2022-06-26 00:06:34 +02:00
|
|
|
def GetFullDate(Date):
|
|
|
|
if not Date:
|
|
|
|
return None
|
|
|
|
return datetime.strftime(datetime.strptime(Date, '%Y-%m-%d'), '%Y-%m-%dT%H:%M+00:00')
|
|
|
|
|
|
|
|
def LoadLocale(Lang):
|
|
|
|
Lang = Lang + '.json'
|
|
|
|
Folder = os.path.dirname(os.path.abspath(__file__)) + '/../../Locale/'
|
|
|
|
File = ReadFile(Folder + Lang)
|
|
|
|
if File:
|
|
|
|
return json.loads(File)
|
|
|
|
else:
|
|
|
|
return json.loads(ReadFile(Folder + 'en.json'))
|
2022-08-29 20:28:12 +02:00
|
|
|
|
|
|
|
def IsLightRun(File, LimitFiles):
|
|
|
|
return False if LimitFiles == False or File in LimitFiles else True
|