From b995948ffb54efa0a5f889977ab57c7259aa1a9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Gr=C3=B8n=C3=A5s?= <44143748+sondregronas@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:57:51 +0200 Subject: [PATCH] Add prettier & ruff formatting, delete requirements.txt --- .gitignore | 5 + Dockerfile | 2 +- README.md | 4 + package.json | 20 +++ piggy/__init__.py | 12 +- piggy/app.py | 71 ++++---- piggy/caching.py | 67 ++++---- piggy/piggybank.py | 52 +++--- piggy/static/css/styles.css | 154 +++++++++--------- piggy/static/css/tailwind.input.css | 2 +- .../assignments/0-assignments_root.html | 59 ++++--- piggy/templates/assignments/1-year_level.html | 57 ++++--- piggy/templates/assignments/2-class_name.html | 57 ++++--- piggy/templates/assignments/3-subject.html | 35 ++-- piggy/templates/assignments/4-topic.html | 44 ++--- piggy/templates/assignments/5-assignment.html | 54 +++--- piggy/templates/example.html | 34 ++-- piggy/templates/index.html | 16 +- piggy/templates/layout.html | 52 +++--- pyproject.toml | 78 +++++++++ requirements.txt | 2 - run.py | 22 +-- 22 files changed, 527 insertions(+), 372 deletions(-) create mode 100644 package.json create mode 100644 pyproject.toml delete mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 1cfb12b..70924e6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.DS_Store .DS_Store? .cache +*.egg-info tailwind.css @@ -12,3 +13,7 @@ turtleconvert/ .idea/ venv/ __pycache__/ + + +node_modules/ +package-lock.json \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 357968d..5560fb7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ WORKDIR /app COPY requirements.txt /app -RUN pip install -U pip && pip install setuptools wheel && pip install -q -r requirements.txt +RUN pip install -U pip && pip install . RUN pip install gunicorn diff --git a/README.md b/README.md index e6d545a..d832fe2 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,8 @@ [![GitHub Pages](https://badgen.net/badge/visit/github%20pages/?icon=chrome)](https://piggy.iktim.no) +Install `pip install .` + +Install dev `pip install .[dev]` + `npm install` + 🚧 Construction in progress. 🚧 \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..26b62b0 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "devDependencies": { + "prettier": "^3.3.3", + "prettier-plugin-jinja-template": "^1.4.1", + "tailwindcss": "^3.4.10" + }, + "prettier": { + "plugins": [ + "prettier-plugin-jinja-template" + ], + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "jinja-template" + } + } + ] + } +} diff --git a/piggy/__init__.py b/piggy/__init__.py index 566f1ae..775e8fc 100644 --- a/piggy/__init__.py +++ b/piggy/__init__.py @@ -2,16 +2,16 @@ from piggy.piggybank import generate_piggymap -PIGGYBANK_FOLDER = Path('piggybank') +PIGGYBANK_FOLDER = Path("piggybank") PIGGYMAP = generate_piggymap(PIGGYBANK_FOLDER) SUPPORTED_LANGUAGES = { - '': {'name': 'Norsk'}, # Default language - 'eng': {'name': 'English'}, - 'ukr': {'name': 'Українська'}, + "": {"name": "Norsk"}, # Default language + "eng": {"name": "English"}, + "ukr": {"name": "Українська"}, } # A prefix for the assignment URLs, to avoid conflicts with other routes -ASSIGNMENT_ROUTE = 'main' +ASSIGNMENT_ROUTE = "main" # Media is on a different prefix to not compete with the assignment routes -MEDIA_ROUTE = 'img' +MEDIA_ROUTE = "img" diff --git a/piggy/app.py b/piggy/app.py index 972f3a3..20e43d3 100644 --- a/piggy/app.py +++ b/piggy/app.py @@ -16,83 +16,82 @@ def create_app(): - app = Flask(__name__, static_folder='static') + app = Flask(__name__, static_folder="static") - assignment_routes = Blueprint(ASSIGNMENT_ROUTE, __name__, url_prefix=f'/{ASSIGNMENT_ROUTE}') - media_routes = Blueprint(MEDIA_ROUTE, __name__, url_prefix=f'/{MEDIA_ROUTE}') + assignment_routes = Blueprint(ASSIGNMENT_ROUTE, __name__, url_prefix=f"/{ASSIGNMENT_ROUTE}") + media_routes = Blueprint(MEDIA_ROUTE, __name__, url_prefix=f"/{MEDIA_ROUTE}") generate_static_files_wrapper() @app.context_processor def context_processor(): """Context variables for all templates in the app.""" - return {'ASSIGNMENT_URL_PREFIX': ASSIGNMENT_ROUTE, - 'MEDIA_URL_PREFIX': MEDIA_ROUTE, - 'piggymap': PIGGYMAP, - 'img_fmt': 'webp'} - - @app.route('/') + return { + "ASSIGNMENT_URL_PREFIX": ASSIGNMENT_ROUTE, + "MEDIA_URL_PREFIX": MEDIA_ROUTE, + "piggymap": PIGGYMAP, + "img_fmt": "webp", + } + + @app.route("/") @lru_cache_wrapper def index(): - html = '

Velkommen til Piggy!

' + html = "

Velkommen til Piggy!

" html += f'\n' return html - @assignment_routes.route(f'/') - @assignment_routes.route(f'/') + @assignment_routes.route("/") + @assignment_routes.route("/") @lru_cache_wrapper - def get_assignment_directory(path=''): + def get_assignment_directory(path=""): """ Render the webpage for a given path. Keeps track of template_type (assignments_root, year_level, class_name, subject, topic) based on the path. Gets the relevant piggymap from the path. (key = child content, value = dict with relevant child data + meta) """ - path = path.strip('/') + path = path.strip("/") template_type = get_template_from_path(path) metadata, segment = get_piggymap_segment_from_path(path, PIGGYMAP) - media_abspath = f'/{MEDIA_ROUTE}/{path}' if path else f'/{MEDIA_ROUTE}' - abspath = f'/{ASSIGNMENT_ROUTE}/{path}' if path else f'/{ASSIGNMENT_ROUTE}' + media_abspath = f"/{MEDIA_ROUTE}/{path}" if path else f"/{MEDIA_ROUTE}" + abspath = f"/{ASSIGNMENT_ROUTE}/{path}" if path else f"/{ASSIGNMENT_ROUTE}" - return render_template(template_type, - meta=metadata, - segment=segment, - path=path, - media_abspath=media_abspath, - abspath=abspath) + return render_template( + template_type, meta=metadata, segment=segment, path=path, media_abspath=media_abspath, abspath=abspath + ) - @assignment_routes.route(f'/////') - def get_assignment(year_level, class_name, subject, topic, assignment, lang=''): + @assignment_routes.route("/////") + def get_assignment(year_level, class_name, subject, topic, assignment, lang=""): """ Render an assignment from the piggymap. Takes precedence over the wildcard route due to specificity. """ # TODO: Simplify path handling (less parameters)? if request: # Caching doesn't work with request context - lang = request.cookies.get('lang', lang) + lang = request.cookies.get("lang", lang) if lang: - assignment = f'translations/{lang}/{assignment}' - path = f'{PIGGYBANK_FOLDER}/{year_level}/{class_name}/{subject}/{topic}' + assignment = f"translations/{lang}/{assignment}" + path = f"{PIGGYBANK_FOLDER}/{year_level}/{class_name}/{subject}/{topic}" - return _render_assignment(Path(f'{path}/{assignment}.md')) + return _render_assignment(Path(f"{path}/{assignment}.md")) - @media_routes.route(f'//media/') - @assignment_routes.route(f'//attachments/') + @media_routes.route("//media/") + @assignment_routes.route("//attachments/") def get_assignment_media_wildcard(wildcard, filename): """ Get a media file from either the media or attachments folder. (only in MEDIA_URL_PREFIX or ASSIGNMENT_URL_PREFIX) """ - if request.path.split('/')[1] == MEDIA_ROUTE: - wildcard = wildcard.replace(MEDIA_ROUTE, '', 1).strip('/') - folder = 'media' + if request.path.split("/")[1] == MEDIA_ROUTE: + wildcard = wildcard.replace(MEDIA_ROUTE, "", 1).strip("/") + folder = "media" else: - folder = 'attachments' + folder = "attachments" try: - return send_file(Path(f'{PIGGYBANK_FOLDER}/{wildcard}/{folder}/{filename}').absolute()) + return send_file(Path(f"{PIGGYBANK_FOLDER}/{wildcard}/{folder}/{filename}").absolute()) except FileNotFoundError: - return send_file('static/img/placeholders/100x100.png') + return send_file("static/img/placeholders/100x100.png") if not app.debug: # Generate a cache of all assignment related pages diff --git a/piggy/caching.py b/piggy/caching.py index b127fd8..80543ce 100644 --- a/piggy/caching.py +++ b/piggy/caching.py @@ -11,29 +11,30 @@ def lru_cache_wrapper(func): - if os.environ.get('USE_CACHE', '1') == '1': + if os.environ.get("USE_CACHE", "1") == "1": return lru_cache()(func) return func -def cache_directory(segment: dict, - directory_fn: Callable[[str], str], - assignment_fn: Callable[[Path], Response], - _path: str = ''): +def cache_directory( + segment: dict, directory_fn: Callable[[str], str], assignment_fn: Callable[[Path], Response], _path: str = "" +): for key, value in segment.items(): - print(f'Caching: {_path}/{key}') - directory_fn(f'{_path}/{key}'.strip('/')) - if _path.count('/') == 3: - for assignment, assignment_data in value.get('data', {}).items(): - assignment_path = f'{_path}/{key}/{assignment}'.strip('/') - assignment_path = Path(f'{PIGGYBANK_FOLDER}/{assignment_path}.md') + print(f"Caching: {_path}/{key}") + directory_fn(f"{_path}/{key}".strip("/")) + if _path.count("/") == 3: + for assignment, assignment_data in value.get("data", {}).items(): + assignment_path = f"{_path}/{key}/{assignment}".strip("/") + assignment_path = Path(f"{PIGGYBANK_FOLDER}/{assignment_path}.md") assignment_fn(assignment_path) - [assignment_fn(Path(f'{assignment_path.parent}/translations/{lang}/{assignment}.md')) - for lang in SUPPORTED_LANGUAGES.keys()] - elif _path.count('/') > 3: + [ + assignment_fn(Path(f"{assignment_path.parent}/translations/{lang}/{assignment}.md")) + for lang in SUPPORTED_LANGUAGES.keys() + ] + elif _path.count("/") > 3: return else: - cache_directory(value.get('data', {}), f'{_path}/{key}') + cache_directory(value.get("data", {}), f"{_path}/{key}") @lru_cache_wrapper @@ -41,29 +42,31 @@ def _render_assignment(p: Path) -> Response: """Render an assignment from a Path object.""" if not p.exists(): # TODO: Raise a custom error - return Response('Error: Assignment not found', status=404) + return Response("Error: Assignment not found", status=404) try: sections = mdfile_to_sections(p) - print('Rendering:', p) + print("Rendering:", p) except ConversionError: # TODO: Raise a custom error - return Response('Error: Could not render assignment', status=500) + return Response("Error: Could not render assignment", status=500) - lang = '' - if p.parents[1].name == 'translations': + lang = "" + if p.parents[1].name == "translations": lang = p.parent.name - current_language = SUPPORTED_LANGUAGES.get(lang, '')['name'] + current_language = SUPPORTED_LANGUAGES.get(lang, "")["name"] match = ASSIGNMENT_FILENAME_REGEX.match(p.name) - render = render_template('assignments/5-assignment.html', - content=sections, - current_language=current_language, - supported_languages=SUPPORTED_LANGUAGES, - path=p, - assignment_name=match.group(1).strip(), - level=match.group(2).strip(), - level_name=match.group(3).strip(), - media_abspath=f'/{MEDIA_ROUTE}/{p.parent}', - abspath=f'/{ASSIGNMENT_ROUTE}/{p}') - return Response(render, mimetype='text/html', status=200) + render = render_template( + "assignments/5-assignment.html", + content=sections, + current_language=current_language, + supported_languages=SUPPORTED_LANGUAGES, + path=p, + assignment_name=match.group(1).strip(), + level=match.group(2).strip(), + level_name=match.group(3).strip(), + media_abspath=f"/{MEDIA_ROUTE}/{p.parent}", + abspath=f"/{ASSIGNMENT_ROUTE}/{p}", + ) + return Response(render, mimetype="text/html", status=200) diff --git a/piggy/piggybank.py b/piggy/piggybank.py index 98d6a01..247d95a 100644 --- a/piggy/piggybank.py +++ b/piggy/piggybank.py @@ -9,26 +9,26 @@ def load_meta_json(path: Path): try: - with open(path, 'r', encoding='utf-8') as f: + with open(path, "r", encoding="utf-8") as f: data = json.load(f) except FileNotFoundError: data = {} - if 'name' not in data: - data['name'] = path.parent.name + if "name" not in data: + data["name"] = path.parent.name return data def get_piggymap_segment_from_path(path: str, piggymap: dict) -> tuple[dict, dict]: """Get the metadata and segment from a path.""" segment = dict(piggymap.copy()) - meta = segment.get('meta', {}) - for path in path.split('/'): + meta = segment.get("meta", {}) + for path in path.split("/"): if not path: continue if path not in segment: return {}, {} - meta = segment.get(path, {}).get('meta', {}) - segment = segment.get(path, {}).get('data', {}) + meta = segment.get(path, {}).get("meta", {}) + segment = segment.get(path, {}).get("data", {}) return meta, segment @@ -37,14 +37,14 @@ def get_template_from_path(path: str) -> str: """Get the directory name from a path.""" # TODO: Use an enum? nest_level_dirname = { - 0: 'assignments/0-assignments_root', - 1: 'assignments/1-year_level', - 2: 'assignments/2-class_name', - 3: 'assignments/3-subject', - 4: 'assignments/4-topic', + 0: "assignments/0-assignments_root", + 1: "assignments/1-year_level", + 2: "assignments/2-class_name", + 3: "assignments/3-subject", + 4: "assignments/4-topic", } - path = path.split('/') - return nest_level_dirname.get(len([x for x in path if x]), 'unknown') + '.html' + path = path.split("/") + return nest_level_dirname.get(len([x for x in path if x]), "unknown") + ".html" def generate_piggymap(path: Path, max_levels: int = 5, _current_level: int = 0): @@ -68,27 +68,27 @@ def generate_piggymap(path: Path, max_levels: int = 5, _current_level: int = 0): return None for item in os.listdir(path): # If the item is a directory, we want to go deeper - if os.path.isdir(f'{path}/{item}'): - new_item = generate_piggymap(Path(f'{path}/{item}'), _current_level=_current_level + 1) + if os.path.isdir(f"{path}/{item}"): + new_item = generate_piggymap(Path(f"{path}/{item}"), _current_level=_current_level + 1) if new_item: - piggymap[item] = {'data': new_item} + piggymap[item] = {"data": new_item} # If the folder contains a 'meta.json' file, we should add that as metadata to the folder - piggymap[item]['meta'] = load_meta_json(Path(f'{path}/{item}/meta.json')) + piggymap[item]["meta"] = load_meta_json(Path(f"{path}/{item}/meta.json")) continue # If the item is a file, we want to check if it's a valid assignment file match = ASSIGNMENT_FILENAME_REGEX.match(item) if not match: continue - assignment_path = Path(f'{path}/{item}') + assignment_path = Path(f"{path}/{item}") sections = mdfile_to_sections(assignment_path) - piggymap[item.replace('.md', '')] = { - 'path': assignment_path, - 'assignment_name': match.group(1).strip(), - 'level': match.group(2).strip(), - 'level_name': match.group(3).strip(), - 'heading': sections['heading'], - 'meta': sections['meta'], + piggymap[item.replace(".md", "")] = { + "path": assignment_path, + "assignment_name": match.group(1).strip(), + "level": match.group(2).strip(), + "level_name": match.group(3).strip(), + "heading": sections["heading"], + "meta": sections["meta"], } return piggymap diff --git a/piggy/static/css/styles.css b/piggy/static/css/styles.css index a538ed8..29657b6 100644 --- a/piggy/static/css/styles.css +++ b/piggy/static/css/styles.css @@ -1,129 +1,131 @@ :root { - /* Temporary piggy colors */ - --snout-main: #e5ebf1; - --snout-card: #b7bcc2; + /* Temporary piggy colors */ + --snout-main: #e5ebf1; + --snout-card: #b7bcc2; - /* Not used for now */ - --snout-button: #5b434b; - --snout-button-hover: #835f6d; + /* Not used for now */ + --snout-button: #5b434b; + --snout-button-hover: #835f6d; } .main-container { - background-color: var(--snout-main); + background-color: var(--snout-main); } .card-container { - background-color: var(--snout-card); - box-shadow: inset 0px 0px 10px 0 #58585855; - transition: transform 0.1s ease, box-shadow 0.1s ease; + background-color: var(--snout-card); + box-shadow: inset 0px 0px 10px 0 #58585855; + transition: + transform 0.1s ease, + box-shadow 0.1s ease; } .card-container:hover { - transform: translateY(2px); - box-shadow: inset 0px 0px 7px 0 rgba(255, 210, 255, 0.3); - cursor: pointer; + transform: translateY(2px); + box-shadow: inset 0px 0px 7px 0 rgba(255, 210, 255, 0.3); + cursor: pointer; } .thumbnail-container { - position: relative; + position: relative; } .thumbnail-text-overlay { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - background: rgba(0, 0, 0, 0.75); - color: white; - padding: 4px 10px 4px 10px; - display: flex; - justify-content: space-between; - border-bottom-left-radius: 0.71rem; - border-bottom-right-radius: 0.71rem; - font-weight: bold; - text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.6); /* Subtle text shadow */ + position: absolute; + bottom: 0; + left: 0; + width: 100%; + background: rgba(0, 0, 0, 0.75); + color: white; + padding: 4px 10px 4px 10px; + display: flex; + justify-content: space-between; + border-bottom-left-radius: 0.71rem; + border-bottom-right-radius: 0.71rem; + font-weight: bold; + text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.6); /* Subtle text shadow */ } .thumbnail-text-overlay-compact { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - color: white; - background: rgba(0, 0, 0, 0.65); - padding: 4px 10px 4px 10px; - display: flex; - justify-content: space-between; - font-weight: bold; - text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.6); /* Subtle text shadow */ - border-radius: 0.165rem; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + color: white; + background: rgba(0, 0, 0, 0.65); + padding: 4px 10px 4px 10px; + display: flex; + justify-content: space-between; + font-weight: bold; + text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.6); /* Subtle text shadow */ + border-radius: 0.165rem; } .tags-container { - max-height: 4.5rem; - overflow: hidden; - position: relative; - display: flex; - flex-wrap: wrap; - justify-content: center; + max-height: 4.5rem; + overflow: hidden; + position: relative; + display: flex; + flex-wrap: wrap; + justify-content: center; } .tags-container.fade::after { - content: ''; - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 2.0rem; - /* This does not quite work, why isn't there a way to infer the color from a constant ;_; */ - /* use sass or something for this in the actual piggy */ - background: linear-gradient(to bottom, #261f2100, #261f21ff); - pointer-events: none; + content: ""; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 2rem; + /* This does not quite work, why isn't there a way to infer the color from a constant ;_; */ + /* use sass or something for this in the actual piggy */ + background: linear-gradient(to bottom, #261f2100, #261f21ff); + pointer-events: none; } .tags-container.expanded { - max-height: none; + max-height: none; } .tags-container.expanded::after { - display: none; + display: none; } .see-more { - display: none; - cursor: pointer; - color: #fff; - background-color: var(--snout-button); - padding: 0.1rem; - border-radius: 2.0rem; - text-align: center; - margin-top: 0.5rem; - transition: background-color 0.1s ease; + display: none; + cursor: pointer; + color: #fff; + background-color: var(--snout-button); + padding: 0.1rem; + border-radius: 2rem; + text-align: center; + margin-top: 0.5rem; + transition: background-color 0.1s ease; } .see-more:hover { - background-color: var(--snout-button-hover); + background-color: var(--snout-button-hover); } .tags-container + .see-more { - display: block; + display: block; } .tag-box { - margin: 2px 2px 2px 2px; - box-shadow: inset 0px 0px 5px 0 #00000033; - text-shadow: 1px 1px 10px #000000aa; + margin: 2px 2px 2px 2px; + box-shadow: inset 0px 0px 5px 0 #00000033; + text-shadow: 1px 1px 10px #000000aa; } .size-text { - font-weight: bold; - font-style: italic; + font-weight: bold; + font-style: italic; } .subject-id { - bottom: 0; + bottom: 0; } .description-container { - bottom: 0; -} \ No newline at end of file + bottom: 0; +} diff --git a/piggy/static/css/tailwind.input.css b/piggy/static/css/tailwind.input.css index bd6213e..b5c61c9 100644 --- a/piggy/static/css/tailwind.input.css +++ b/piggy/static/css/tailwind.input.css @@ -1,3 +1,3 @@ @tailwind base; @tailwind components; -@tailwind utilities; \ No newline at end of file +@tailwind utilities; diff --git a/piggy/templates/assignments/0-assignments_root.html b/piggy/templates/assignments/0-assignments_root.html index f1fc56f..3315122 100644 --- a/piggy/templates/assignments/0-assignments_root.html +++ b/piggy/templates/assignments/0-assignments_root.html @@ -1,36 +1,47 @@ {% extends "layout.html" %} {% block content %} +

+ Oppgavebanken Piggy 🐷 +

-

Oppgavebanken Piggy 🐷

- -
-
- - {% for item, data in segment.items() %} + - +
{% endblock %} diff --git a/piggy/templates/assignments/1-year_level.html b/piggy/templates/assignments/1-year_level.html index 70b78cd..eb6a647 100644 --- a/piggy/templates/assignments/1-year_level.html +++ b/piggy/templates/assignments/1-year_level.html @@ -1,36 +1,45 @@ {% extends "layout.html" %} {% block content %} +

{{ meta.name }}

-

{{ meta.name }}

- -
-
- - {% for item, data in segment.items() %} + - +
{% endblock %} diff --git a/piggy/templates/assignments/2-class_name.html b/piggy/templates/assignments/2-class_name.html index 70b78cd..eb6a647 100644 --- a/piggy/templates/assignments/2-class_name.html +++ b/piggy/templates/assignments/2-class_name.html @@ -1,36 +1,45 @@ {% extends "layout.html" %} {% block content %} +

{{ meta.name }}

-

{{ meta.name }}

- -
-
- - {% for item, data in segment.items() %} + - +
{% endblock %} diff --git a/piggy/templates/assignments/3-subject.html b/piggy/templates/assignments/3-subject.html index f8fb7df..5f427f5 100644 --- a/piggy/templates/assignments/3-subject.html +++ b/piggy/templates/assignments/3-subject.html @@ -1,27 +1,30 @@ {% extends "layout.html" %} {% block content %} +

{{ meta.name }}

+ Header image for {{ meta.name }} +
{{ media_abspath }}/header.png
+

{{ meta.description or 'No description provided' }}

-

{{ meta.name }}

-Header image for {{ meta.name }} -
{{ media_abspath }}/header.png
-

{{ meta.description or 'No description provided' }}

+
-
- -{% for key, val in segment.items() %} + {% for key, val in segment.items() %}

{{ key }} {{ val.meta.title }}

- Header image for {{ key }} + Header image for {{ key }}
{{ media_abspath }}/{{ key }}/media/header.png
-
+
View {{ key }} -
+
{% for meta_key, meta_val in val.get('meta', {}).items() %} - {{ meta_key }}: {{ meta_val }} -
+ {{ meta_key }}: {{ meta_val }} +
{% endfor %} - HELLO THIS IS A TEST FOR TOPICS -{% endfor %} - -{% endblock %} \ No newline at end of file + {% endfor %} +{% endblock %} diff --git a/piggy/templates/assignments/4-topic.html b/piggy/templates/assignments/4-topic.html index 6dd1d23..ec2803d 100644 --- a/piggy/templates/assignments/4-topic.html +++ b/piggy/templates/assignments/4-topic.html @@ -1,30 +1,32 @@

Oppgavebanken

{% for item, data in segment.items() %} - {# Name metadata for child item #} -

{{ data.meta.title }}

+ {# Name metadata for child item #} +

{{ data.meta.title }}

+ {# Header media for child item #} + Header image for {{ item }} +
{{ media_abspath }}/{{ item }}/media/header.png
- {# Header media for child item #} - Header image for {{ item }} -
{{ media_abspath }}/{{ item }}/media/header.png
+
+ {# Link to item, display name #} + View {{ data.meta.title }} +
-
- {# Link to item, display name #} - View {{ data.meta.title }} -
+

All metadata (kun for assignment segmentet)

-

All metadata (kun for assignment segmentet)

+

Data variables

+
  • Path: {{ data.path }}
  • +
  • Assignment name: {{ data.assignment_name }}
  • +
  • Level: {{ data.level }}
  • +
  • Level Name: {{ data.level_name }}
  • +
  • Heading (title i frontmatter): {{ data.heading }}
  • -

    Data variables

    -
  • Path: {{ data.path }}
  • -
  • Assignment name: {{ data.assignment_name }}
  • -
  • Level: {{ data.level }}
  • -
  • Level Name: {{ data.level_name }}
  • -
  • Heading (title i frontmatter): {{ data.heading }}
  • - -

    Meta variables (Frontmatter)

    - {% for meta_key, meta_val in data.meta.items() %} -
  • {{ meta_key }}: {{ meta_val }}
  • - {% endfor %} +

    Meta variables (Frontmatter)

    + {% for meta_key, meta_val in data.meta.items() %} +
  • {{ meta_key }}: {{ meta_val }}
  • + {% endfor %} {% endfor %} diff --git a/piggy/templates/assignments/5-assignment.html b/piggy/templates/assignments/5-assignment.html index 0a10b96..1a29fdb 100644 --- a/piggy/templates/assignments/5-assignment.html +++ b/piggy/templates/assignments/5-assignment.html @@ -1,40 +1,40 @@ - {{ content.head | safe }} + {{ content.head | safe }} - + header { + background-color: #333; + color: white; + padding: 1em; + text-align: center; + } + -
    +

    {{ content.heading }}

    {% if content.meta.difficulty %} - {% if content.meta.difficulty > 50 %} - Difficulty: UMULIG!!! - {% else %} -

    Difficulty: {{ '⭐' * content.meta.difficulty }}

    - {% endif %} + {% if content.meta.difficulty > 50 %} + Difficulty: UMULIG!!! + {% else %} +

    Difficulty: {{ '⭐' * content.meta.difficulty }}

    + {% endif %} {% endif %}
    -
    Current language: {{ current_language }}
    - {% for lang, val in supported_languages.items() %} - {{ val.name }} - {% endfor %} +
    Current language: {{ current_language }}
    + {% for lang, val in supported_languages.items() %} + {{ val.name }} + {% endfor %}
    Home -
    -
    - {{ content.body | safe }} -
    - \ No newline at end of file +
    +
    {{ content.body | safe }}
    + diff --git a/piggy/templates/example.html b/piggy/templates/example.html index e93a56e..8c02e58 100644 --- a/piggy/templates/example.html +++ b/piggy/templates/example.html @@ -1,20 +1,22 @@ {% for item, data in segment.items() %} - {# Name metadata for child item #} -

    {{ data.meta.name }}

    + {# Name metadata for child item #} +

    {{ data.meta.name }}

    + {# Header media for child item #} + Header image for {{ item }} +
    {{ media_abspath }}/{{ item }}/media/header.png
    - {# Header media for child item #} - Header image for {{ item }} -
    {{ media_abspath }}/{{ item }}/media/header.png
    +
    + {# Link to item, display name #} + View {{ data.meta.name }} +
    -
    - {# Link to item, display name #} - View {{ data.meta.name }} -
    - -

    All metadata

    - {% for meta_key, meta_val in data.meta.items() %} - {{ meta_key }}: {{ meta_val }} -
    - {% endfor %} -{% endfor %} \ No newline at end of file +

    All metadata

    + {% for meta_key, meta_val in data.meta.items() %} + {{ meta_key }}: {{ meta_val }} +
    + {% endfor %} +{% endfor %} diff --git a/piggy/templates/index.html b/piggy/templates/index.html index 6c84afe..40cf46f 100644 --- a/piggy/templates/index.html +++ b/piggy/templates/index.html @@ -1,12 +1,12 @@ - + - - - + + + Document - - + +

    Velkommen til piggy!

    - - \ No newline at end of file + + diff --git a/piggy/templates/layout.html b/piggy/templates/layout.html index 3e7794b..55293d7 100644 --- a/piggy/templates/layout.html +++ b/piggy/templates/layout.html @@ -1,30 +1,38 @@ - + - - - + + + Document - - - + + + - - + + - - -{% block content %} -{% endblock %} - - \ No newline at end of file + + + {% block content %} + {% endblock %} + + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..73782dd --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,78 @@ +[project] +name = "piggy" +version = "0.1.0" +description = "" +license = {file = "LICENSE.md"} +readme = "README.md" +dependencies = [ + "flask", + "turtleconverter@git+https://github.com/sondregronas/turtleconverter@main", + "gunicorn", +] + +[build-system] +requires = ["setuptools", "wheel"] + +[tool.setuptools] +py-modules = [] + +[project.optional-dependencies] +dev = [ + "ruff", +] + +[tool.ruff] +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", +] + +line-length = 120 +indent-width = 4 + +# Assume Python 3.12 +target-version = "py312" + +[tool.ruff.lint] +# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. +select = ["E4", "E7", "E9", "F"] +ignore = [] + +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] + +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + +docstring-code-format = false +docstring-code-line-length = "dynamic" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 8a355a7..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -flask -git+https://github.com/sondregronas/turtleconverter@main \ No newline at end of file diff --git a/run.py b/run.py index 72c1801..2820826 100644 --- a/run.py +++ b/run.py @@ -3,25 +3,27 @@ from piggy.app import create_app -TAILWIND_RUN_CMD = ('cd piggy && ' - 'npx tailwindcss -c tailwind.config.js ' - '-i static/css/tailwind.input.css ' - '-o static/css/tailwind.css && ' - 'cd ..') +TAILWIND_RUN_CMD = ( + "cd piggy && " + "npx tailwindcss -c tailwind.config.js " + "-i static/css/tailwind.input.css " + "-o static/css/tailwind.css && " + "cd .." +) subprocess.Popen(TAILWIND_RUN_CMD, shell=True) def checkout_branch(branch): - os.system(f'cd piggybank && git checkout {branch} && cd .. && git submodule update --remote --recursive') + os.system(f"cd piggybank && git checkout {branch} && cd .. && git submodule update --remote --recursive") -if __name__ == '__main__': +if __name__ == "__main__": # checkout_branch('test-data') - os.environ['FLASK_DEBUG'] = '1' - os.environ['USE_CACHE'] = '0' + os.environ["FLASK_DEBUG"] = "1" + os.environ["USE_CACHE"] = "0" app = create_app() app.run(port=5001) else: - checkout_branch('output') + checkout_branch("output") app = create_app()