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