diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b40585..96f6c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # What’s New +## 1.1.0 + ++ **Deprecated** several configuration values ~ ++ Removed permanently the remains of extensions. ++ I18n improvements. + ## 1.0.0 + **BREAKING CHANGES AHEAD**! @@ -11,7 +17,7 @@ + Switched to `pyproject.toml`. `requirements.txt` has been sunset. + Switched to the Apache License; the old license text is moved to `LICENSE.0_9` + Added color themes! This is a breaking (but trivial) aesthetic change. Default theme is 'Miku' (aquamarine green). -+ Extensions have been removed. They never had a clear, usable, public API in the first place. ++ Extensions **have been removed**. They never had a clear, usable, public API in the first place. ## 0.9 diff --git a/i18n/salvi.en.json b/i18n/salvi.en.json index 2376fe5..996c8a6 100644 --- a/i18n/salvi.en.json +++ b/i18n/salvi.en.json @@ -9,6 +9,7 @@ "back-to": "Back to", "backlinks": "Backlinks", "backlinks-empty": "No other pages linking here. Is this page orphan?", + "bad-request": "Bad request", "calculate": "Calculate", "calendar": "Calendar", "confirm-password": "Confirm password", @@ -18,6 +19,8 @@ "groups-count": "User group count", "have-read-terms": "I have read {0} and {1}", "homepage": "Homepage", + "in-the-future": "in the future", + "in-the-past": "in the past", "include-tags": "Include tags", "input-tags": "Tags (comma separated)", "jump-to-actions": "Jump to actions", @@ -27,6 +30,7 @@ "latest-uploads": "Latest uploads", "logged-in-as": "Logged in as", "login": "Log in", + "manage-accounts": "Manage accounts", "month": "Month", "n-days-ago": "{0} days ago", "n-hours-ago": "{0} hours ago", @@ -40,6 +44,7 @@ "not-found-text-2": "does not exist.", "not-logged-in": "Not logged in", "note-history": "Page history", + "notes-by-date": "Pages by date", "notes-count": "Number of pages", "notes-count-with-url": "Number of pages with URL set", "notes-month-empty": "None found :(", @@ -62,10 +67,13 @@ "search-results": "Search results for", "search-no-results": "No results for", "show-all": "Show all", + "show-more-years": "Show more years", "sign-up": "Sign up", "tags": "Tags", "terms-of-service": "Terms of Service", "upload-file": "Upload file", + "user-generated-warning": "Any content in this site is user-generated and", + "user-liability-warning": "each user is responsible for what they publish", "username": "Username", "users-count": "Number of users", "welcome": "Welcome to {0}!", diff --git a/i18n/salvi.it.json b/i18n/salvi.it.json index 711625d..6580835 100644 --- a/i18n/salvi.it.json +++ b/i18n/salvi.it.json @@ -9,6 +9,7 @@ "back-to": "Torna a", "backlinks": "Collegamenti in entrata", "backlinks-empty": "Nessuna altra pagina punta qui. Questa pagina è orfana?", + "bad-request": "Richiesta non conforme", "calculate": "Calcola", "calendar": "Calendario", "confirm-password": "Conferma password", diff --git a/salvi/__init__.py b/salvi/__init__.py index f6ada0d..f6c016a 100644 --- a/salvi/__init__.py +++ b/salvi/__init__.py @@ -8,27 +8,21 @@ Pages are stored in SQLite/MySQL databases. Markdown is used for text formatting. ''' -__version__ = '1.0.0' +__version__ = '1.1.0-dev36' from flask import ( - Flask, abort, flash, g, jsonify, make_response, redirect, + Flask, g, make_response, redirect, request, render_template, send_from_directory ) from markupsafe import Markup -from flask_login import LoginManager, login_user, logout_user, current_user, login_required +from flask_login import LoginManager from flask_wtf import CSRFProtect -from flask_sqlalchemy import SQLAlchemy from sqlalchemy import select from suou.configparse import ConfigOptions, ConfigParserConfigSource, ConfigValue from suou.flask import add_context_from_config -from werkzeug.security import generate_password_hash, check_password_hash from werkzeug.routing import BaseConverter -import datetime, hashlib, html, importlib, json, markdown, os, random, \ - re, sys, warnings -from functools import lru_cache, partial -from urllib.parse import quote -import gzip -from getpass import getpass +import html, os +from functools import partial from configparser import ConfigParser import dotenv @@ -40,11 +34,13 @@ dotenv.load_dotenv(os.path.join(APP_BASE_DIR, '.env')) class SiteConfig(ConfigOptions): app_name = ConfigValue(default='Salvi', legacy_src='site.title', public=True) + ## v--- will change to server_name in 2.0.0 domain_name = ConfigValue(public=True) database_url = ConfigValue(legacy_src='database.url', required=True) secret_key = ConfigValue(required=True) default_group = ConfigValue(prefix='salvi_', cast=int, default=1) material_icons_url = ConfigValue(default='https://fonts.googleapis.com/icon?family=Material+Icons', public=True) + # v--- pending deprecation default_items_per_page = ConfigValue(prefix='salvi_', legacy_src='appearance.items_per_page', default=20, cast=int) ... diff --git a/salvi/constants.py b/salvi/constants.py index a5b425b..d37ff4f 100644 --- a/salvi/constants.py +++ b/salvi/constants.py @@ -9,7 +9,7 @@ PING_RE = r'(? 0 - else: - return _BitComparator(self._column, self._flag) - def __set__(self, obj, val): - if obj: - orig = getattr(obj, self._column.name) - if val: - orig |= self._flag - else: - orig &= ~(self._flag) - setattr(obj, self._column.name, orig) - else: - raise NotImplementedError - - # Helper for interactive session management -from suou.sqlalchemy import create_session, declarative_base +from suou.sqlalchemy import create_session, declarative_base, BitSelector CSI = create_session_interactively = partial(create_session, app_config.database_url) @@ -221,11 +170,11 @@ class Page(db.Model): calendar = Column(DateTime, index=True, nullable=True) owner_id = Column(Integer, ForeignKey('user.id'), nullable=True) flags = Column(BigInteger, default=0) - is_redirect = BitSelector(flags, 1) - is_sync = BitSelector(flags, 2) - is_math_enabled = BitSelector(flags, 4) - is_locked = BitSelector(flags, 8) - is_cw = BitSelector(flags, 16) + is_redirect: Mapped[bool] = BitSelector(flags, 1) + is_sync: Mapped[bool] = BitSelector(flags, 2) + is_math_enabled: Mapped[bool] = BitSelector(flags, 4) + is_locked: Mapped[bool] = BitSelector(flags, 8) + is_cw: Mapped[bool] = BitSelector(flags, 16) revisions: Relationship[List[PageRevision]] = relationship("PageRevision", back_populates = 'page') owner: Relationship[User] = relationship('User', back_populates = 'owned_pages') @@ -237,7 +186,7 @@ class Page(db.Model): def latest(self) -> PageRevision: return db.session.execute( - db.select(PageRevision).where(PageRevision.page_id == self.id).order_by(PageRevision.pub_date.desc()).limit(1) + select(PageRevision).where(PageRevision.page_id == self.id).order_by(PageRevision.pub_date.desc()).limit(1) ).scalar() def get_url(self): @@ -247,6 +196,7 @@ class Page(db.Model): def by_url(cls, url: str): return db.session.execute(db.select(Page).where(Page.url == url)).scalar() + @deprecated('usage of inefficient and deprecated remove_tags()') def short_desc(self) -> str: if self.is_cw: return '(Content Warning: we are not allowed to show a description.)' @@ -298,10 +248,6 @@ class Page(db.Model): tags = [x.name for x in self.tags] ) - @not_implemented - def ldjson(): - ... - @deprecated('meta name="keywords" is nowadays ignored by search engines') def seo_keywords(self): kw = [] diff --git a/salvi/renderer.py b/salvi/renderer.py index b286048..4d4df75 100644 --- a/salvi/renderer.py +++ b/salvi/renderer.py @@ -22,7 +22,7 @@ def md_and_toc(text) -> tuple[Markup, Any | None]: try: converter: markdown.Markdown = markdown.Markdown(extensions=extensions, extension_configs=extension_configs) markup = Markup(converter.convert(text)) - toc = converter.toc + toc = Markup(converter.toc) return markup, toc except Exception as e: return error_p('Error during rendering: {0}: {1}') diff --git a/salvi/templates/400.html b/salvi/templates/400.html index 1e02791..dc58259 100644 --- a/salvi/templates/400.html +++ b/salvi/templates/400.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% from "macros/title.html" import title_tag with context %} -{% block title %}{{ title_tag(T('Bad Request'), false) }}{% endblock %} +{% block title %}{{ title_tag(T('bad-request'), false) }}{% endblock %} {% block content %}
diff --git a/salvi/templates/base.html b/salvi/templates/base.html index 9f3deb1..f3539d1 100644 --- a/salvi/templates/base.html +++ b/salvi/templates/base.html @@ -25,7 +25,6 @@ } {% block json_info %}{% endblock %} - {% block ldjson %}{% endblock %}
@@ -63,7 +62,7 @@