Added devision by semester
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
|||||||
.venv
|
.venv
|
||||||
out
|
out
|
||||||
prod
|
prod
|
||||||
|
cache
|
||||||
node_modules
|
node_modules
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|
||||||
|
|||||||
11
src/build.py
11
src/build.py
@@ -19,7 +19,7 @@ def build(trigger_list: list[str] | None = None):
|
|||||||
# Clear output directory
|
# Clear output directory
|
||||||
shutil.rmtree(settings.paths.output, ignore_errors=True)
|
shutil.rmtree(settings.paths.output, ignore_errors=True)
|
||||||
shutil.copytree(settings.paths.static, settings.paths.output)
|
shutil.copytree(settings.paths.static, settings.paths.output)
|
||||||
inv: list[CSItem] = prepare_cheatsheets(inv_raw, settings.paths.output)
|
inv, cats, no_cat = prepare_cheatsheets(inv_raw)
|
||||||
|
|
||||||
if not os.path.exists(settings.paths.prod):
|
if not os.path.exists(settings.paths.prod):
|
||||||
os.mkdir(settings.paths.prod)
|
os.mkdir(settings.paths.prod)
|
||||||
@@ -38,8 +38,15 @@ def build(trigger_list: list[str] | None = None):
|
|||||||
|
|
||||||
thisYear = datetime.datetime.now().year
|
thisYear = datetime.datetime.now().year
|
||||||
|
|
||||||
|
print(cats)
|
||||||
|
|
||||||
with open(f"{settings.paths.output}/index.html", "w", encoding="utf-8") as f:
|
with open(f"{settings.paths.output}/index.html", "w", encoding="utf-8") as f:
|
||||||
f.write(index.render(items=inv, thisYear=thisYear))
|
f.write(index.render(cats=list(
|
||||||
|
sorted(
|
||||||
|
map(lambda c: (c[0], list(c[1].items())), cats.items()),
|
||||||
|
key=lambda x: x[0]
|
||||||
|
)
|
||||||
|
), no_cat=no_cat, thisYear=thisYear))
|
||||||
|
|
||||||
with open(f"{settings.paths.output}/impressum.html", "w", encoding="utf-8") as f:
|
with open(f"{settings.paths.output}/impressum.html", "w", encoding="utf-8") as f:
|
||||||
f.write(env.get_template("impressum.html.j2").render(thisYear=thisYear))
|
f.write(env.get_template("impressum.html.j2").render(thisYear=thisYear))
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class PathsConfig(BaseSettings):
|
|||||||
static: str = Field(default="static", description="Static files directory")
|
static: str = Field(default="static", description="Static files directory")
|
||||||
output: str = Field(default="out", description="Output directory")
|
output: str = Field(default="out", description="Output directory")
|
||||||
prod: str = Field(default="prod", description="Production directory")
|
prod: str = Field(default="prod", description="Production directory")
|
||||||
|
cache: str = Field(default="cache", description="Cache directory")
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
|
import re
|
||||||
|
|
||||||
from sources import CSInventoryConfig, CSItem, CheatsheetSourceType
|
from sources import CSInventoryConfig, CSItem, CheatsheetSourceType
|
||||||
from sources.plain import process_plain_url
|
from sources.plain import process_plain_url
|
||||||
@@ -23,7 +24,7 @@ def load_cheatsheet_inventory(file: str) -> CSInventoryConfig:
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def prepare_cheatsheets(config: CSInventoryConfig, outdir: str) -> list[CSItem]:
|
def prepare_cheatsheets(config: CSInventoryConfig) -> list[CSItem]:
|
||||||
res: list[CSItem] = []
|
res: list[CSItem] = []
|
||||||
|
|
||||||
logger = get_worker_thread_logger()
|
logger = get_worker_thread_logger()
|
||||||
@@ -34,13 +35,13 @@ def prepare_cheatsheets(config: CSInventoryConfig, outdir: str) -> list[CSItem]:
|
|||||||
try:
|
try:
|
||||||
match item.source.type:
|
match item.source.type:
|
||||||
case CheatsheetSourceType.GITEA_SOURCE:
|
case CheatsheetSourceType.GITEA_SOURCE:
|
||||||
new_items += process_gitea(item, outdir)
|
new_items += process_gitea(item)
|
||||||
|
|
||||||
case CheatsheetSourceType.PLAIN_URL:
|
case CheatsheetSourceType.PLAIN_URL:
|
||||||
new_items.append(process_plain_url(item, outdir))
|
new_items.append(process_plain_url(item))
|
||||||
|
|
||||||
case CheatsheetSourceType.CODEBERG_SOURCE:
|
case CheatsheetSourceType.CODEBERG_SOURCE:
|
||||||
new_items += process_codeberg(item, outdir)
|
new_items += process_codeberg(item)
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
logger.warning("Unknown Source Type: %s", item.source.type)
|
logger.warning("Unknown Source Type: %s", item.source.type)
|
||||||
@@ -54,7 +55,29 @@ def prepare_cheatsheets(config: CSInventoryConfig, outdir: str) -> list[CSItem]:
|
|||||||
new_item: CSItem = new_item
|
new_item: CSItem = new_item
|
||||||
logger.debug(f"-> {new_item.title} ({new_item.url})")
|
logger.debug(f"-> {new_item.title} ({new_item.url})")
|
||||||
res.append(new_item)
|
res.append(new_item)
|
||||||
|
|
||||||
|
no_cat: list[CSItem] = []
|
||||||
|
cats: dict[int, dict[str, list[CSItem]]] = {}
|
||||||
|
|
||||||
return res
|
for item in res:
|
||||||
|
m = re.match(r"[sS][eE][mM]([eE][sS][tT][eE][rR])?(\d+)-(.*)", item.title.strip())
|
||||||
|
if m:
|
||||||
|
semester = int(m.group(2))
|
||||||
|
module = str(m.group(3)).lower().strip() \
|
||||||
|
.replace("_", " ").replace("-", " ").title()
|
||||||
|
|
||||||
|
if semester not in cats:
|
||||||
|
cats[semester] = {}
|
||||||
|
|
||||||
|
if module not in cats[semester]:
|
||||||
|
cats[semester][module] = []
|
||||||
|
|
||||||
|
item.semester = semester
|
||||||
|
item.module = module
|
||||||
|
cats[semester][module].append(item)
|
||||||
|
else:
|
||||||
|
no_cat.append(item)
|
||||||
|
|
||||||
|
return res, cats, no_cat
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,4 +59,6 @@ class CSItem(BaseModel):
|
|||||||
id: str
|
id: str
|
||||||
git_repo: str
|
git_repo: str
|
||||||
git_repo_type: str
|
git_repo_type: str
|
||||||
|
semester: int | None = 0
|
||||||
|
module: str | None = ""
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from pathlib import Path
|
|||||||
from logger import get_worker_thread_logger
|
from logger import get_worker_thread_logger
|
||||||
|
|
||||||
|
|
||||||
def process_codeberg(item: CSInventoryItem, outdir: str) -> list[CSItem] | None:
|
def process_codeberg(item: CSInventoryItem) -> list[CSItem] | None:
|
||||||
logger = get_worker_thread_logger()
|
logger = get_worker_thread_logger()
|
||||||
logger.info(f"Processing Gitea cheatsheet: {item.source.owner}/{item.source.repo}@{item.source.tag}")
|
logger.info(f"Processing Gitea cheatsheet: {item.source.owner}/{item.source.repo}@{item.source.tag}")
|
||||||
source: CSSourceGitea = item.source
|
source: CSSourceGitea = item.source
|
||||||
@@ -29,7 +29,7 @@ def process_codeberg(item: CSInventoryItem, outdir: str) -> list[CSItem] | None:
|
|||||||
for fetch_url, real_url in assets_urls:
|
for fetch_url, real_url in assets_urls:
|
||||||
|
|
||||||
if item.cache:
|
if item.cache:
|
||||||
cache_url = cache_cheatsheet(fetch_url, outdir)
|
cache_url = cache_cheatsheet(fetch_url)
|
||||||
if cache_url:
|
if cache_url:
|
||||||
real_url = cache_url
|
real_url = cache_url
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from pathlib import Path
|
|||||||
from logger import get_worker_thread_logger
|
from logger import get_worker_thread_logger
|
||||||
|
|
||||||
|
|
||||||
def process_gitea(item: CSInventoryItem, outdir: str) -> list[CSItem] | None:
|
def process_gitea(item: CSInventoryItem) -> list[CSItem] | None:
|
||||||
logger = get_worker_thread_logger()
|
logger = get_worker_thread_logger()
|
||||||
logger.info(f"Processing Gitea cheatsheet: {item.source.owner}/{item.source.repo}@{item.source.tag}")
|
logger.info(f"Processing Gitea cheatsheet: {item.source.owner}/{item.source.repo}@{item.source.tag}")
|
||||||
source: CSSourceGitea = item.source
|
source: CSSourceGitea = item.source
|
||||||
@@ -28,7 +28,7 @@ def process_gitea(item: CSInventoryItem, outdir: str) -> list[CSItem] | None:
|
|||||||
for fetch_url, real_url in assets_urls:
|
for fetch_url, real_url in assets_urls:
|
||||||
|
|
||||||
if item.cache:
|
if item.cache:
|
||||||
cache_url = cache_cheatsheet(fetch_url, outdir)
|
cache_url = cache_cheatsheet(fetch_url)
|
||||||
if cache_url:
|
if cache_url:
|
||||||
real_url = cache_url
|
real_url = cache_url
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
from sources import CSInventoryItem, CSSourcePlainURL, CSItem
|
from sources import CSInventoryItem, CSSourcePlainURL, CSItem
|
||||||
from sources.util import cache_cheatsheet, get_datestring
|
from sources.util import cache_cheatsheet, get_datestring
|
||||||
|
from config import get_settings
|
||||||
|
|
||||||
async def process_plain_url(item: CSInventoryItem, outdir: str) -> CSItem | None:
|
async def process_plain_url(item: CSInventoryItem) -> CSItem | None:
|
||||||
source: CSSourcePlainURL = item.source
|
source: CSSourcePlainURL = item.source
|
||||||
res_url = source.url
|
res_url = source.url
|
||||||
|
|
||||||
if item.cache:
|
if item.cache:
|
||||||
cache_url = await cache_cheatsheet(source.url, outdir)
|
cache_url = await cache_cheatsheet(source.url)
|
||||||
if cache_url:
|
if cache_url:
|
||||||
res_url = cache_url
|
res_url = cache_url
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ import os
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from logger import get_worker_thread_logger
|
from logger import get_worker_thread_logger
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
from config import get_settings
|
||||||
|
|
||||||
def get_datestring() -> str:
|
def get_datestring() -> str:
|
||||||
return datetime.datetime.now().strftime("%d.%m.%y")
|
return datetime.datetime.now().strftime("%d.%m.%y (%H:%M:%S)")
|
||||||
|
|
||||||
|
def cache_cheatsheet(url) -> str | None:
|
||||||
def cache_cheatsheet(url, outdir: str) -> str | None:
|
settings = get_settings()
|
||||||
logger = get_worker_thread_logger()
|
logger = get_worker_thread_logger()
|
||||||
logger.info(f"Caching cheatsheet from {url}")
|
logger.info(f"Caching cheatsheet from {url}")
|
||||||
|
|
||||||
@@ -27,14 +28,22 @@ def cache_cheatsheet(url, outdir: str) -> str | None:
|
|||||||
|
|
||||||
url_base_name = Path(urlparse(url).path).stem
|
url_base_name = Path(urlparse(url).path).stem
|
||||||
|
|
||||||
filesname = os.path.join("cache", f"{url_base_name}.pdf")
|
filesname = os.path.join(f"{url_base_name}.pdf")
|
||||||
|
|
||||||
if not os.path.exists(os.path.join(outdir, "cache")):
|
if not os.path.exists(os.path.join(settings.paths.cache)):
|
||||||
os.mkdir(os.path.join(outdir, "cache"))
|
os.mkdir(os.path.join(settings.paths.cache))
|
||||||
|
|
||||||
with open(os.path.join(outdir, filesname), "wb") as f:
|
|
||||||
|
if not os.path.exists(os.path.join(settings.paths.output, "cache")):
|
||||||
|
os.mkdir(os.path.join(settings.paths.output, "cache"))
|
||||||
|
|
||||||
|
|
||||||
|
with open(os.path.join(settings.paths.output, "cache", filesname), "wb") as f:
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
|
with open(os.path.join(settings.paths.cache, filesname), "wb") as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
logger.info(f"Saved file to {filesname}")
|
logger.info(f"Saved file to {filesname}")
|
||||||
|
|
||||||
return filesname
|
return os.path.join("cache", filesname)
|
||||||
|
|||||||
@@ -47,8 +47,7 @@ nav.navbar a:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Main content area padding */
|
/* Main content area padding */
|
||||||
body > h1,
|
body > h1, body > h2, body > h3, body > table, body > p {
|
||||||
body > table {
|
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
@@ -61,17 +60,30 @@ h1 {
|
|||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #444;
|
||||||
|
font-size: 1.2em;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 20px;
|
||||||
|
border-top: 1px solid #999;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
color: #333;
|
color: #333;
|
||||||
text-align: center;
|
text-align: start;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
margin-bottom: 5px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
width: calc(100% - 40px);
|
width: calc(100% - 40px);
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin-top: 20px;
|
margin-top: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,11 +96,35 @@ th, td {
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background-color: #c0c0c0;
|
background-color: #c0c0c0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(1), tr > :nth-child(1) {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(2), tr > :nth-child(2) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(3), tr > :nth-child(3) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(4), tr > :nth-child(4) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(5), tr > :nth-child(5) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
tbody tr:hover {
|
tbody tr:hover {
|
||||||
background-color: #e8e8ff;
|
background-color: #e8e8ff;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["../../styles/main.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAKA;EACI;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;;AAGJ;AACA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;AACA;AAAA;EAEI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;;;AAGJ;AACA;EACI;EACA;EACA;EACA;EACA;EACA","file":"main.css"}
|
{"version":3,"sourceRoot":"","sources":["../../styles/main.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAKA;EACI;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;;AAGJ;AACA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;AACA;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;AACA;EACI;EACA;EACA;EACA;EACA;EACA","file":"main.css"}
|
||||||
@@ -50,8 +50,7 @@ nav.navbar a:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Main content area padding */
|
/* Main content area padding */
|
||||||
body > h1,
|
body > h1, body > h2, body > h3, body > table, body > p {
|
||||||
body > table {
|
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
@@ -64,17 +63,30 @@ h1 {
|
|||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #444;
|
||||||
|
font-size: 1.2em;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 20px;
|
||||||
|
border-top: 1px solid #999;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
color: #333;
|
color: #333;
|
||||||
text-align: center;
|
text-align: start;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
margin-bottom: 5px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
width: calc(100% - 40px);
|
width: calc(100% - 40px);
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin-top: 20px;
|
margin-top: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,11 +99,35 @@ th, td {
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background-color: #c0c0c0;
|
background-color: #c0c0c0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(1), tr > :nth-child(1) {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(2), tr > :nth-child(2) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(3), tr > :nth-child(3) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(4), tr > :nth-child(4) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr > :nth-child(5), tr > :nth-child(5) {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
tbody tr:hover {
|
tbody tr:hover {
|
||||||
background-color: #e8e8ff;
|
background-color: #e8e8ff;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
{% include "navbar.j2" %}
|
{% include "navbar.j2" %}
|
||||||
|
|
||||||
<h1>typst4ei</h1>
|
<h1>typst4ei</h1>
|
||||||
<h3>Eine Sammlung von Formelsammlung für/von EI Stundenten der TUM</h3>
|
<p>Eine Sammlung von Formelsammlung für/von EI Stundenten der TUM</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Disclaimer: Die Richtigkeit des Materials kann nicht garantiert werden.
|
Disclaimer: Die Richtigkeit des Materials kann nicht garantiert werden.
|
||||||
@@ -19,44 +19,96 @@
|
|||||||
Aber Feedback und Korrekturen sind immer willkommen!
|
Aber Feedback und Korrekturen sind immer willkommen!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Title</th>
|
|
||||||
<th>Repo</th>
|
|
||||||
<th>Upload Date</th>
|
|
||||||
<th>Git commit</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for item in items %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="{{ item.url }}">{{ item.title }}</a>
|
|
||||||
|
|
||||||
{% if item.author %}
|
|
||||||
<br>by {{ item.author }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% if item.git_repo %}
|
|
||||||
<a href="{{ item.git_repo }}">{{ item.git_repo_type }}</a>
|
|
||||||
{% else %}
|
|
||||||
N/A
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ item.date }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% if item.git_repo %}
|
|
||||||
{{ item.commit }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
{% for item in cats %}
|
||||||
|
<h2>{{ item[0] }}. Semester</h2>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Autor</th>
|
||||||
|
<th>Repo</th>
|
||||||
|
<th>Upload Date</th>
|
||||||
|
<th>Git commit</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for module in item[1] %}
|
||||||
|
{% for item in module[1] %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{ item.url }}">{{ module[0] }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if item.author %}
|
||||||
|
{{ item.author }}
|
||||||
|
{% else %}
|
||||||
|
N/A
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if item.git_repo %}
|
||||||
|
<a href="{{ item.git_repo }}">{{ item.git_repo_type }}</a>
|
||||||
|
{% else %}
|
||||||
|
N/A
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ item.date }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if item.git_repo %}
|
||||||
|
{{ item.commit }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endfor%}
|
||||||
|
|
||||||
|
{% if no_cat %}
|
||||||
|
<h2>Verschiedenes</h2>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Repo</th>
|
||||||
|
<th>Upload Date</th>
|
||||||
|
<th>Git commit</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in no_cat %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{ item.url }}">{{ item.title }}</a>
|
||||||
|
|
||||||
|
{% if item.author %}
|
||||||
|
<br>by {{ item.author }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if item.git_repo %}
|
||||||
|
<a href="{{ item.git_repo }}">{{ item.git_repo_type }}</a>
|
||||||
|
{% else %}
|
||||||
|
N/A
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ item.date }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if item.git_repo %}
|
||||||
|
{{ item.commit }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user