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.3 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
sitemap.append(SITEMAP_HREF + "list/" + slug)
142
sitemap.append(SITEMAP_HREF + "list")
143
return Lists
144
145
def RenderPosts():
146
global PostList
147
for post in PostList:
148
Revised = post["updated"] if "updated" in post else False
149
RenderedHTML = RenderTemplate("blog-post.html",
150
Revised=Revised,
151
Title=post["title"],
152
PostDate=post["date"],
153
Content=post["content"],
154
PostPath=post["pathname"],
155
PlaintextPath=post["plaintext"])
156
print("Building blog-posts/%s to %s/blog/%s" % (post["origin"], BUILD_DIRECTORY, post["pathname"]))
157
with open(BUILD_DIRECTORY + "/blog/" + post["pathname"], "w", encoding="utf-8") as PostHTMLFile:
158
PostHTMLFile.write(RenderedHTML)
159
print("Copying blog-posts/%s to %s/blog/%s" % (post["origin"], BUILD_DIRECTORY, post["plaintext"]))
160
with open(BUILD_DIRECTORY + "/blog/" + post["plaintext"], "w", encoding="utf-8") as PostHTMLFile:
161
PostHTMLFile.write(post["raw-content"])
162
sitemap.append(SITEMAP_HREF + "blog/" + post["pathname"])
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
global PostList
173
CreatedJSON = {
174
"version": "https://jsonfeed.org/version/1",
175
"title": "Steve0Greatness' Blog",
176
"home_page_url": "https://steve0greatness.github.io",
177
"feed_url": "https://steve0greatness.github.io/blog/feed.rss",
178
"language": "en-US",
179
"favicon": "https://steve0greatness.github.io/favicon.ico",
180
"description": "A blog by a human being.",
181
"authors": [
182
{
183
"name": "Steve0Greatness",
184
"url": "https://steve0greatness.github.io"
185
}
186
],
187
"items": []
188
}
189
for post in PostList:
190
CreatedJSON["items"].append({
191
"id": "https://steve0greatness.github.io/blog/" + post["pathname"],
192
"title": "JSON Feed version 1.1",
193
"icon": "https://steve0greatness.github.io/favicon.ico",
194
"content_html": post["content"],
195
"date_published": post["atom-post-time"],
196
"date_modified": post["atom-update-time"],
197
"url": "https://steve0greatness.github.io/blog/" + post["pathname"]
198
})
199
with open(BUILD_DIRECTORY + "/blog/feed.json", "w") as JSONFeedFile:
200
DumpJSON(CreatedJSON, JSONFeedFile)
201
202
def RenderLists():
203
Lists = GetLists()
204
CreateDirectory(BUILD_DIRECTORY + "/list/")
205
ListIndex = "<ul>"
206
for List in Lists:
207
FileLocation = "/list/" + List["filename"].replace(".yml", ".html")
208
Title = List["title"]
209
print("%s -> %s" % ("lists/" + List["filename"], BUILD_DIRECTORY + FileLocation))
210
with open(BUILD_DIRECTORY + FileLocation, "w") as file:
211
file.write(RenderTemplate("list.html", Content=List["content"], Title=Title, Location=FileLocation))
212
ListIndex += "<li><a href=\"%s\">%s</a></li>" % (FileLocation, Title)
213
ListIndex += "</ul>"
214
print("Building list index")
215
with open(BUILD_DIRECTORY + "/list/index.html", "w") as file:
216
file.write(RenderTemplate("list-index.html", Content=ListIndex))
217
218
def main():
219
global PostList
220
PostList = GetBlogList()
221
print("Wiping directory")
222
WipeFinalDir()
223
print("Creating blog holder")
224
CreateDirectory(BUILD_DIRECTORY + "/blog")
225
print("Rendering posts")
226
RenderPosts()
227
CreateJSONFeed()
228
print("Copying static directory")
229
CopyDirectory("static", BUILD_DIRECTORY)
230
print("Creating lists")
231
RenderLists()
232
233
print("Building pages")
234
for file, path in PAGES.items():
235
AllowSitemap = file not in DISALLOWED_SITEMAP
236
RenderPage(file, path, AllowSitemap, 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()