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