From 0594dddcacd7a88cd1dd6221006450751323a4d5 Mon Sep 17 00:00:00 2001 From: rimu <3310831+rimu@users.noreply.github.com> Date: Wed, 7 Feb 2024 18:33:25 +1300 Subject: [PATCH] smarter theme engine - derive list of themes from directory structure, not hard coded list --- app/admin/forms.py | 4 +--- app/admin/routes.py | 3 ++- app/main/routes.py | 7 ++++--- app/user/forms.py | 4 +--- app/user/routes.py | 3 ++- app/utils.py | 12 ++++++++++++ 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/app/admin/forms.py b/app/admin/forms.py index ed9a9c8f..f92a68f4 100644 --- a/app/admin/forms.py +++ b/app/admin/forms.py @@ -29,9 +29,7 @@ class SiteMiscForm(FlaskForm): registration_mode = SelectField(_l('Registration mode'), choices=types, default=1, coerce=str) application_question = TextAreaField(_l('Question to ask people applying for an account')) log_activitypub_json = BooleanField(_l('Log ActivityPub JSON for debugging')) - themes = [('', _l('PieFed')), - ('high_contrast', _l('High contrast'))] - default_theme = SelectField(_l('Default theme'), choices=themes, coerce=str) + default_theme = SelectField(_l('Default theme'), coerce=str) submit = SubmitField(_l('Save')) diff --git a/app/admin/routes.py b/app/admin/routes.py index 4d8c19f3..f4297102 100644 --- a/app/admin/routes.py +++ b/app/admin/routes.py @@ -17,7 +17,7 @@ from app.community.util import save_icon_file, save_banner_file from app.models import AllowedInstances, BannedInstances, ActivityPubLog, utcnow, Site, Community, CommunityMember, \ User, Instance, File, Report, Topic, UserRegistration from app.utils import render_template, permission_required, set_setting, get_setting, gibberish, markdown_to_html, \ - moderating_communities, joined_communities, finalize_user_setup + moderating_communities, joined_communities, finalize_user_setup, theme_list from app.admin import bp @@ -68,6 +68,7 @@ def admin_misc(): site = Site.query.get(1) if site is None: site = Site() + form.default_theme.choices = theme_list() if form.validate_on_submit(): site.enable_downvotes = form.enable_downvotes.data site.allow_local_image_posts = form.allow_local_image_posts.data diff --git a/app/main/routes.py b/app/main/routes.py index 6a2d82d2..6c5df246 100644 --- a/app/main/routes.py +++ b/app/main/routes.py @@ -18,7 +18,7 @@ from sqlalchemy import select, desc, text from sqlalchemy_searchable import search from app.utils import render_template, get_setting, gibberish, request_etag_matches, return_304, blocked_domains, \ ap_datetime, ip_address, retrieve_block_list, shorten_string, markdown_to_text, user_filters_home, \ - joined_communities, moderating_communities, parse_page + joined_communities, moderating_communities, parse_page, theme_list from app.models import Community, CommunityMember, Post, Site, User, utcnow, Domain, Topic from PIL import Image import pytesseract @@ -249,8 +249,9 @@ def keyboard_shortcuts(): @bp.route('/test') def test(): - x = parse_page('https://slate.com/technology/2024/02/quora-what-happened-ai-decline.html') - return str(x) + themes = theme_list() + + return str(themes) return current_app.config['SERVER_NAME'] diff --git a/app/user/forms.py b/app/user/forms.py index 15849655..beac7266 100644 --- a/app/user/forms.py +++ b/app/user/forms.py @@ -45,9 +45,7 @@ class SettingsForm(FlaskForm): ('active', _l('Active')), ] default_sort = SelectField(_l('By default, sort posts by'), choices=sorts, validators=[DataRequired()], coerce=str) - themes = [('', _l('PieFed')), - ('high_contrast', _l('High contrast'))] - theme = SelectField(_l('Theme'), choices=themes, coerce=str) + theme = SelectField(_l('Theme'), coerce=str) submit = SubmitField(_l('Save settings')) diff --git a/app/user/routes.py b/app/user/routes.py index 6efe3441..a01da016 100644 --- a/app/user/routes.py +++ b/app/user/routes.py @@ -17,7 +17,7 @@ from app.user.forms import ProfileForm, SettingsForm, DeleteAccountForm, ReportU from app.user.utils import purge_user_then_delete from app.utils import get_setting, render_template, markdown_to_html, user_access, markdown_to_text, shorten_string, \ is_image_url, ensure_directory_exists, gibberish, file_get_contents, community_membership, user_filters_home, \ - user_filters_posts, user_filters_replies, moderating_communities, joined_communities + user_filters_posts, user_filters_replies, moderating_communities, joined_communities, theme_list from sqlalchemy import desc, or_, text import os @@ -152,6 +152,7 @@ def change_settings(): if user is None: abort(404) form = SettingsForm() + form.theme.choices = theme_list() if form.validate_on_submit(): current_user.newsletter = form.newsletter.data current_user.ignore_bots = form.ignore_bots.data diff --git a/app/utils.py b/app/utils.py index 4e3eb6d6..89b1d64d 100644 --- a/app/utils.py +++ b/app/utils.py @@ -675,6 +675,7 @@ def parse_page(page_url, tags_to_search = KNOWN_OPENGRAPH_TAGS, fallback_tags = def current_theme(): + """ The theme the current user has set, falling back to the site default if none specified or user is not logged in """ if current_user.is_authenticated: if current_user.theme is not None and current_user.theme != '': return current_user.theme @@ -682,3 +683,14 @@ def current_theme(): return g.site.default_theme if g.site.default_theme is not None else '' else: return g.site.default_theme if g.site.default_theme is not None else '' + + +def theme_list(): + """ All the themes available, by looking in the templates/themes directory """ + result = [('', 'PieFed')] + for root, dirs, files in os.walk('app/templates/themes'): + for dir in dirs: + if os.path.exists(f'app/templates/themes/{dir}/{dir}.json'): + theme_settings = json.loads(file_get_contents(f'app/templates/themes/{dir}/{dir}.json')) + result.append((dir, theme_settings['name'])) + return result