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