Initial homepage and category page generation scripts
This commit is contained in:
parent
bf16180810
commit
bec8a07195
13 changed files with 174 additions and 28 deletions
|
@ -3,3 +3,7 @@
|
|||
Simple leaderboard site template updated via Python scripts!
|
||||
|
||||
Designed for use within speedrunning communities.
|
||||
|
||||
## About
|
||||
|
||||
paceboard is a template-based static site generator for speedrunning leaderboards. Python scripts are used to add runs and categories, and all info is stored in `csv` files.
|
|
@ -26,3 +26,7 @@ h1, h2 {
|
|||
font-family: "Lexend", "Arial", Arial, sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.categoryLink {
|
||||
display: block;
|
||||
}
|
|
@ -1 +1 @@
|
|||
tk_category_name,tk_category_dashname,tk_category_description,tk_category_rules
|
||||
tk_category_dashname,tk_category_name,tk_category_description,tk_category_rules
|
||||
|
|
|
|
@ -1 +1 @@
|
|||
id,date,game,category,runner,verifier,link,comment
|
||||
tk_run_id,tk_run_date,tk_run_game,tk_run_category,tk_run_runner,tk_run_verifier,tk_run_link,tk_run_description
|
||||
|
|
|
|
@ -0,0 +1,30 @@
|
|||
### Script for adding a new category. Handles adding data to config.csv.
|
||||
|
||||
from utils import csv as util_csv
|
||||
|
||||
divider = "----------"
|
||||
|
||||
print(
|
||||
f"\nWe'll ask for the name, description, and rules of the new category.\n\n{divider}\n"
|
||||
)
|
||||
|
||||
# tk_category_name, tk_category_dashname, tk_category_description, tk_category_rules
|
||||
|
||||
tk_category_name = input("Name: ")
|
||||
tk_category_description = input("Description: ")
|
||||
tk_category_rules = input("Rules: ")
|
||||
|
||||
tk_category_dashname = tk_category_name.replace(" ", "_")
|
||||
|
||||
categoryDict = {
|
||||
"tk_category_name": tk_category_name,
|
||||
"tk_category_dashname": tk_category_dashname,
|
||||
"tk_category_description": tk_category_description,
|
||||
"tk_category_rules": tk_category_rules,
|
||||
}
|
||||
|
||||
util_csv.dictWriter("../csv/config.csv", categoryDict, "a")
|
||||
|
||||
print(
|
||||
f"\n{divider}\n\nAdded category! If you made a mistake, you can manually edit csv/categories.csv (and csv/runs.csv if you've added any runs to the borked category). \n"
|
||||
)
|
|
@ -4,8 +4,13 @@ from utils.gen import index as gen_index
|
|||
from utils.gen import categories as gen_categories
|
||||
from utils.gen import runs as gen_runs
|
||||
|
||||
print("Generating homepage...")
|
||||
gen_index.generate("../templates", "..", "index.html")
|
||||
gen_categories.generate()
|
||||
gen_runs.generate()
|
||||
|
||||
print("Generating leaderboard pages for each category...")
|
||||
gen_categories.generate("../templates", "../categories", "category.html")
|
||||
|
||||
# print("Generating details pages for each run...")
|
||||
# gen_runs.generate("../templates", "runs", "runs.html")
|
||||
|
||||
print("Done generating site!")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
### Initial configuration script for paceboard. Handles adding properties to config.csv.
|
||||
### Initial configuration script for paceboard. Handles adding data to config.csv.
|
||||
|
||||
from utils import csv as util_csv
|
||||
|
||||
|
@ -20,7 +20,7 @@ configDict = {
|
|||
"tk_logo_alt": tk_logo_alt,
|
||||
}
|
||||
|
||||
util_csv.dictWriterSingleDict("../csv/config.csv", configDict)
|
||||
util_csv.dictWriter("../csv/config.csv", configDict)
|
||||
|
||||
print(
|
||||
f"\n{divider}\n\nPerfect! You can always overwrite the info above by running this script again.\nHere's an overview of how to use paceboard:\n\n- Add a category using scripts/add-category.py\n- Add a run using scripts/add-run.py\n- Use scripts/generate.py to update the site with the info you've added.\n- All categories, runs, and configuration details are stored in csv/\n- Replace the logo saved as assets/img/logo.png\n- For the adventurous, you can restyle your site's pages by editing files within templates/ and css/\n\nRemember to run scripts/generate.py to initialize your site.\nThat's all for now! <3\n"
|
||||
|
|
|
@ -23,22 +23,29 @@ def readerWithFunction(filepath, function, arg=None):
|
|||
return value
|
||||
|
||||
|
||||
def dictWriterSingleDict(filepath, dict):
|
||||
def dictWriter(filepath, dict, flag="w"):
|
||||
"""Completely rewrite a csv using the values in a single dictionary.
|
||||
|
||||
filepath -- the path of the csv, whether or not it exists
|
||||
dict -- the dictionary to pull all values from
|
||||
flag -- flag for open() (default "w")
|
||||
"w" will also activate writeheader()
|
||||
"""
|
||||
with open(filepath, "w", newline="") as file:
|
||||
with open(filepath, flag, newline="") as file:
|
||||
|
||||
dictWriter = csv.DictWriter(file, fieldnames=dict.keys(), delimiter=",")
|
||||
if flag == "w":
|
||||
dictWriter.writeheader()
|
||||
dictWriter.writerow(dict)
|
||||
file.close()
|
||||
|
||||
|
||||
def dictReaderFirstRow(filepath):
|
||||
"""Get a dictionary of the first (non-header) row of values in a csv
|
||||
|
||||
filepath -- the path of the csv, whether or not it exists
|
||||
"""
|
||||
with open(filepath, newline="") as file:
|
||||
print(os.path.abspath(filepath))
|
||||
dict = {}
|
||||
dictReader = csv.DictReader(file)
|
||||
for row in dictReader:
|
||||
|
@ -50,6 +57,20 @@ def dictReaderFirstRow(filepath):
|
|||
return dict
|
||||
|
||||
|
||||
def dictReaderMultiRow(filepath, idName):
|
||||
"""Get a dictionary of dictionaries of the (non-header) row of values in a csv
|
||||
|
||||
filepath -- the path of the csv, whether or not it exists
|
||||
"""
|
||||
with open(filepath, newline="") as file:
|
||||
dict = {}
|
||||
dictReader = csv.DictReader(file)
|
||||
for row in dictReader:
|
||||
dict[row[idName]] = row
|
||||
file.close()
|
||||
return dict
|
||||
|
||||
|
||||
def getIndexOfField(filepath, field):
|
||||
"""Get the index (column number) of a field in a csv.
|
||||
|
||||
|
|
|
@ -1,5 +1,39 @@
|
|||
### Generation helper for category pages
|
||||
|
||||
from .. import file as util_file
|
||||
from .. import csv as util_csv
|
||||
import shutil
|
||||
import os
|
||||
|
||||
def generate():
|
||||
print("- categories.py -")
|
||||
|
||||
def generate(templatedir, destinationdir, templateFilename):
|
||||
"""Main generation function for category page generation helper.
|
||||
|
||||
templatedir -- the relative path of the template html file's directory
|
||||
destinationpath -- the directory where category paths should be generated
|
||||
filename -- the filename of the category template (always category.html)
|
||||
"""
|
||||
|
||||
idName = "tk_category_dashname"
|
||||
categories = util_csv.dictReaderMultiRow("../csv/categories.csv", idName)
|
||||
config = util_csv.dictReaderFirstRow("../csv/config.csv")
|
||||
|
||||
for category in categories:
|
||||
|
||||
path = f"{destinationdir}/{categories[category][idName]}"
|
||||
currentDir = os.getcwd()
|
||||
|
||||
os.makedirs(path, exist_ok=True)
|
||||
|
||||
shutil.copy(
|
||||
f"{currentDir}/{templatedir}/{templateFilename}",
|
||||
f"{currentDir}/{path}/index.html",
|
||||
)
|
||||
|
||||
for key in categories[category]:
|
||||
util_file.replaceTextInFile(
|
||||
f"{path}/index.html", key, categories[category][key]
|
||||
)
|
||||
|
||||
for key in config.keys():
|
||||
util_file.replaceTextInFile(f"{path}/index.html", key, config[key])
|
||||
|
|
|
@ -5,18 +5,30 @@ from .. import csv as util_csv
|
|||
import shutil
|
||||
|
||||
|
||||
def generate(templatedir, destinationdir, filename):
|
||||
def generate(templatedir, destinationdir, templateFilename):
|
||||
"""Main generation function for index.html generation helper.
|
||||
|
||||
templatedir -- the relative path of the template html file's directory
|
||||
destinationpath -- the directory where index.html should be generated
|
||||
filename -- the filename of the index page (always index.html)
|
||||
filename -- the filename of the index template (always index.html)
|
||||
"""
|
||||
print("- index.py -")
|
||||
|
||||
shutil.copy(f"{templatedir}/{filename}", destinationdir)
|
||||
shutil.copy(f"{templatedir}/{templateFilename}", destinationdir)
|
||||
|
||||
idName = "tk_category_dashname"
|
||||
categories = util_csv.dictReaderMultiRow("../csv/categories.csv", idName)
|
||||
config = util_csv.dictReaderFirstRow("../csv/config.csv")
|
||||
|
||||
for key in config.keys():
|
||||
util_file.replaceTextInFile(f"{destinationdir}/{filename}", key, config[key])
|
||||
util_file.replaceTextInFile(f"{destinationdir}/index.html", key, config[key])
|
||||
|
||||
tk_category_dashname = "tk_category_dashname"
|
||||
tk_category_name = "tk_category_name"
|
||||
for category in categories:
|
||||
|
||||
util_file.replaceTextInFile(
|
||||
f"{destinationdir}/index.html",
|
||||
"lk_categories",
|
||||
f'<a class="categoryLink" href="categories/{categories[category][tk_category_dashname]}">{categories[category][tk_category_name]}</a>lk_categories',
|
||||
)
|
||||
util_file.replaceTextInFile(f"{destinationdir}/index.html", "lk_categories", "")
|
||||
|
|
|
@ -1,5 +1,41 @@
|
|||
### Generation helper for run pages
|
||||
|
||||
from .. import file as util_file
|
||||
from .. import csv as util_csv
|
||||
import shutil
|
||||
import os
|
||||
|
||||
def generate():
|
||||
print("- runs.py -")
|
||||
|
||||
def generate(templatedir, destinationdir, templateFilename):
|
||||
"""Main generation function for category page generation helper.
|
||||
|
||||
templatedir -- the relative path of the template html file's directory
|
||||
destinationpath -- the directory where run paths should be generated
|
||||
filename -- the filename of the run template (always run.html)
|
||||
"""
|
||||
|
||||
# TODO fix everything
|
||||
|
||||
idName = "tk_category_dashname"
|
||||
categories = util_csv.dictReaderMultiRow("../csv/categories.csv", idName)
|
||||
config = util_csv.dictReaderFirstRow("../csv/config.csv")
|
||||
|
||||
for category in categories:
|
||||
|
||||
path = f"{destinationdir}/{categories[category][idName]}"
|
||||
currentDir = os.getcwd()
|
||||
|
||||
os.makedirs(path, exist_ok=True)
|
||||
|
||||
shutil.copy(
|
||||
f"{currentDir}/{templatedir}/{templateFilename}",
|
||||
f"{currentDir}/{path}/index.html",
|
||||
)
|
||||
|
||||
for key in categories[category]:
|
||||
util_file.replaceTextInFile(
|
||||
f"{path}/index.html", key, categories[category][key]
|
||||
)
|
||||
|
||||
for key in config.keys():
|
||||
util_file.replaceTextInFile(f"{path}/index.html", key, config[key])
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>tk_title - tk_category_name</title>
|
||||
<title>tk_game_name - tk_category_name</title>
|
||||
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link rel="icon" href="assets/img/logo.png">
|
||||
<link rel="stylesheet" href="../../css/style.css">
|
||||
<link rel="icon" href="../../assets/img/logo.png">
|
||||
|
||||
<meta property="og:title" content="tk_game - tk_category_name" />
|
||||
<meta property="og:title" content="tk_game_name - tk_category_name" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:description" content="tk_category_description" />
|
||||
<meta property="og:url" content="tk_url/tk_category_dashname.html" />
|
||||
<meta property="og:url" content="tk_url/tk_category_dashname/index.html" />
|
||||
<meta property="og:image:secure_url" content="https://tk_url/assets/img/logo.png" />
|
||||
<meta property="og:image:alt" content="tk_logo_alt" />
|
||||
|
||||
|
@ -22,11 +22,11 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<h1>tk_game - tk_category_name</h1>
|
||||
<h1>tk_game_name - tk_category_name</h1>
|
||||
<p>tk_category_description</p>
|
||||
|
||||
<h2>Leaderboard</h2>
|
||||
<!-- lk_categories -->
|
||||
<!-- lk_leaderboard -->
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -26,7 +26,7 @@
|
|||
<p>tk_game_description</p>
|
||||
|
||||
<h2>Categories</h2>
|
||||
<!-- lk_categories -->
|
||||
lk_categories
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in a new issue