A mirror of my website's source code.

By using this site, you agree to have cookies stored on your device, strictly for functional purposes, such as storing your session and preferences.

Dismiss

 build.py

View raw Download
text/x-script.python • 9.39 kiB
Python script, ASCII text executable
        
            
1
from Renderers import RenderTemplate, RenderMarkdown
2
from sys import argv
3
from shutil import rmtree as DeleteDirectory
4
from os import mkdir as CreateDirectory, listdir as ListDirectory, unlink as DeleteFile
5
from os.path import isfile as IsFile, exists as PathExists
6
from distutils.dir_util import copy_tree as CopyDirectory
7
from datetime import datetime
8
from json import dump as DumpJSON
9
from yaml import safe_load as LoadYML
10
from re import sub as RegReplace
11
12
GITHUB_BUILD_DIR = "docs" # Separate because this site is built with an action that won't work if they aren't
13
LOCAL_BUILD_DIR = "build"
14
15
BUILD_DIRECTORY = GITHUB_BUILD_DIR if len(argv) > 1 and argv[1] == "gh-pages-deploy" else LOCAL_BUILD_DIR
16
17
PAGES = {
18
"index.html": "index.html",
19
"blog-list.html": "blog/index.html",
20
"blog-feed.rss": "blog/feed.rss",
21
"blog-feed.atom": "blog/feed.atom",
22
"404.html": "404.html",
23
}
24
25
DISALLOWED_SITEMAP = {
26
"404.html",
27
"blog-feed.rss",
28
"blog-feed.atom",
29
"blog-list.html",
30
"index.html",
31
}
32
33
REDIRECTS = {
34
"link-tree.html": "list/link-tree.html", # Old location -> new location
35
}
36
37
SITEMAP_HREF = "https://steve0greatness.github.io/"
38
sitemap = [
39
SITEMAP_HREF + "blog/",
40
SITEMAP_HREF,
41
]
42
43
def WipeFinalDir():
44
if not PathExists(BUILD_DIRECTORY):
45
print("Directory didn't existing, creating it...")
46
CreateDirectory(BUILD_DIRECTORY)
47
return
48
print("Directory exists, wiping it...")
49
for item in ListDirectory(BUILD_DIRECTORY):
50
path = BUILD_DIRECTORY + "/" + item
51
if IsFile(path):
52
DeleteFile(path)
53
continue
54
DeleteDirectory(path)
55
56
def PostDateToDateObj(Date):
57
return datetime.strptime(Date, "%Y %b %d")
58
59
def PostSortHelper(Post):
60
return PostDateToDateObj(Post["date"])
61
62
def GetBlogList():
63
print("Grabbing post list")
64
PostSlugs = ListDirectory("blog-posts")
65
Posts = []
66
for slug in PostSlugs:
67
print("Grabbing post list blog-posts/%s" % (slug))
68
with open("blog-posts/" + slug, encoding="utf-8") as MDFile:
69
RawMD = MDFile.read()
70
PostHTML = RenderMarkdown(RawMD)
71
Item = PostHTML.metadata
72
Item["content"] = PostHTML
73
Item["raw-content"] = RawMD
74
Item["rss-content"] = PostHTML.replace("&", "&amp;").replace(">", "&gt;").replace("<", "&lt;")
75
Item["atom-content"] = RegReplace("</(?=.*)", "</xhtml:", RegReplace("<(?=[^\/].*)", "<xhtml:", PostHTML))
76
Item["rss-post-time"] = PostDateToDateObj(Item["date"]).strftime("%a, %d %b %Y") + " 00:00:00 GMT"
77
Item["atom-post-time"] = PostDateToDateObj(Item["date"]).strftime("%Y-%m-%d") + "T00:00:00Z"
78
Item["atom-update-time"] = Item["atom-post-time"]
79
if "updated" in Item:
80
Item["atom-update-time"] = PostDateToDateObj(Item["updated"]).strftime("%Y-%m-%d") + "T00:00:00Z"
81
Item["pathname"] = slug.replace(".md", ".html")
82
Item["plaintext"] = slug.replace(".md", ".txt")
83
Item["origin"] = slug
84
Posts.append(Item)
85
PostsByDate = sorted(Posts, key=PostSortHelper, reverse=True)
86
return PostsByDate
87
88
PostList = []
89
90
91
def ListParseCategory(Obj, depth):
92
html = "<h%d id=\"%s\">%s</h%d>" % (2+depth, Obj["id"], Obj["title"], 2+depth)
93
if "paragraph" in Obj:
94
html += "<p>%s</p>" % Obj["paragraph"]
95
listType = "ul"
96
if "list-type" in Obj and Obj["list-type"] == "ordered":
97
listType = "ol"
98
html += "<%s>" % listType
99
for item in Obj["list"]:
100
html += "<li>" + LIST_PARSER_DICT[item["type"]](item, depth + 1) + "</li>"
101
html += "</%s>" % listType
102
return html
103
104
def ListParseLink(Obj, depth):
105
html = "<a href=\"%s\">" % Obj["href"]
106
text = Obj["text"]
107
if "text-type" in Obj and Obj["text-type"] == "text/markdown":
108
text = RenderMarkdown(text).replace("<p>", "").replace("</p>", "")
109
html += text + "</a>"
110
if "comment" in Obj:
111
html += "(%s)" % Obj["comment"]
112
return html
113
114
def ListParseText(Obj, depth):
115
text = Obj["text"]
116
# if "text-type" in Obj and Obj["text-type"] == "text/markdown":
117
# print(RenderMarkdown(text))
118
# text = RenderMarkdown(text) # this doesn't work???
119
if "comment" in Obj:
120
text += "(%s)" % Obj["comment"]
121
return text
122
123
LIST_PARSER_DICT = {
124
"category": ListParseCategory,
125
"link": ListParseLink,
126
"text": ListParseText,
127
}
128
129
def GetLists():
130
ListSlugs = ListDirectory("lists")
131
Lists = []
132
for slug in ListSlugs:
133
List = {
134
"title": "",
135
"content": "",
136
"filename": slug
137
}
138
with open("lists/" + slug) as ListYML:
139
ListDict = LoadYML(ListYML.read())
140
List["title"] = ListDict["title"]
141
if "paragraph" in ListDict:
142
List["content"] += "<p>%s</p>" % ListDict["paragraph"]
143
for item in ListDict["list"]:
144
List["content"] += LIST_PARSER_DICT[item["type"]](item, 0)
145
Lists.append(List)
146
sitemap.append(SITEMAP_HREF + "list/" + slug)
147
sitemap.append(SITEMAP_HREF + "list/")
148
return Lists
149
150
def RenderPosts():
151
global PostList
152
for post in PostList:
153
Revised = post["updated"] if "updated" in post else False
154
RenderedHTML = RenderTemplate("blog-post.html",
155
Revised=Revised,
156
Title=post["title"],
157
PostDate=post["date"],
158
Content=post["content"],
159
PostPath=post["pathname"],
160
PlaintextPath=post["plaintext"])
161
print("Building blog-posts/%s to %s/blog/%s" % (post["origin"], BUILD_DIRECTORY, post["pathname"]))
162
with open(BUILD_DIRECTORY + "/blog/" + post["pathname"], "w", encoding="utf-8") as PostHTMLFile:
163
PostHTMLFile.write(RenderedHTML)
164
print("Copying blog-posts/%s to %s/blog/%s" % (post["origin"], BUILD_DIRECTORY, post["plaintext"]))
165
with open(BUILD_DIRECTORY + "/blog/" + post["plaintext"], "w", encoding="utf-8") as PostHTMLFile:
166
PostHTMLFile.write(post["raw-content"])
167
sitemap.append(SITEMAP_HREF + "blog/" + post["pathname"])
168
169
def RenderPage(PageInput: str, ContentDest: str, AllowSitemap: bool = True, **kwargs):
170
print("Building views/%s to %s/%s" % (PageInput, BUILD_DIRECTORY, ContentDest))
171
if AllowSitemap:
172
sitemap.append(SITEMAP_HREF + ContentDest)
173
with open(BUILD_DIRECTORY + "/" + ContentDest, "w", encoding="utf-8") as DestLocation:
174
DestLocation.write(RenderTemplate(PageInput, **kwargs))
175
176
def CreateJSONFeed():
177
global PostList
178
CreatedJSON = {
179
"version": "https://jsonfeed.org/version/1",
180
"title": "Steve0Greatness' Blog",
181
"home_page_url": "https://steve0greatness.github.io",
182
"feed_url": "https://steve0greatness.github.io/blog/feed.rss",
183
"language": "en-US",
184
"favicon": "https://steve0greatness.github.io/favicon.ico",
185
"description": "A blog by a human being.",
186
"authors": [
187
{
188
"name": "Steve0Greatness",
189
"url": "https://steve0greatness.github.io"
190
}
191
],
192
"items": []
193
}
194
for post in PostList:
195
CreatedJSON["items"].append({
196
"id": "https://steve0greatness.github.io/blog/" + post["pathname"],
197
"title": "JSON Feed version 1.1",
198
"icon": "https://steve0greatness.github.io/favicon.ico",
199
"content_html": post["content"],
200
"date_published": post["atom-post-time"],
201
"date_modified": post["atom-update-time"],
202
"url": "https://steve0greatness.github.io/blog/" + post["pathname"]
203
})
204
with open(BUILD_DIRECTORY + "/blog/feed.json", "w") as JSONFeedFile:
205
DumpJSON(CreatedJSON, JSONFeedFile)
206
207
def RenderLists():
208
Lists = GetLists()
209
CreateDirectory(BUILD_DIRECTORY + "/list/")
210
ListIndex = "<ul>"
211
for List in Lists:
212
FileLocation = "/list/" + List["filename"].replace(".yml", ".html")
213
Title = List["title"]
214
print("%s -> %s" % ("lists/" + List["filename"], BUILD_DIRECTORY + FileLocation))
215
with open(BUILD_DIRECTORY + FileLocation, "w") as file:
216
file.write(RenderTemplate("list.html", Content=List["content"], Title=Title, Location=FileLocation))
217
ListIndex += "<li><a href=\"%s\">%s</a></li>" % (FileLocation, Title)
218
ListIndex += "</ul>"
219
print("Building list index")
220
with open(BUILD_DIRECTORY + "/list/index.html", "w") as file:
221
file.write(RenderTemplate("list-index.html", Content=ListIndex))
222
223
def main():
224
global PostList
225
PostList = GetBlogList()
226
print("Wiping directory")
227
WipeFinalDir()
228
print("Creating blog holder")
229
CreateDirectory(BUILD_DIRECTORY + "/blog")
230
print("Rendering posts")
231
RenderPosts()
232
CreateJSONFeed()
233
print("Copying static directory")
234
CopyDirectory("static", BUILD_DIRECTORY)
235
print("Creating lists")
236
RenderLists()
237
238
print("Building pages")
239
for file, path in PAGES.items():
240
AllowSitemap = file not in DISALLOWED_SITEMAP
241
RenderPage(file, path, AllowSitemap, PostList=PostList)
242
243
print("Building redirects")
244
for OldLocation, NewLocation in REDIRECTS.items():
245
RenderPage("redirect.html", OldLocation, False, redirect=NewLocation, old=OldLocation)
246
247
with open(BUILD_DIRECTORY + "/sitemap.txt", "w") as SitemapFile:
248
SitemapFile.write("\n".join(sitemap))
249
250
if __name__ == "__main__":
251
main()