| @@ -18,5 +18,5 @@ jobs: | |||||
| - name: Run pre-commit hooks | - name: Run pre-commit hooks | ||||
| uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd | uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd | ||||
| - name: Run translation checks | |||||
| - name: Run tests | |||||
| run: uv run python -m pytest | run: uv run python -m pytest | ||||
| @@ -33,8 +33,6 @@ build-backend = "setuptools.build_meta" | |||||
| pythonVersion = "3.13" | pythonVersion = "3.13" | ||||
| venvPath = "." | venvPath = "." | ||||
| venv = ".venv" | venv = ".venv" | ||||
| # toolforge_i18n doesn't define __all__, so pyright flags its public API as private | |||||
| reportPrivateImportUsage = false | |||||
| [tool.ruff] | [tool.ruff] | ||||
| target-version = "py313" | target-version = "py313" | ||||
| @@ -3,9 +3,10 @@ import logging | |||||
| import os | import os | ||||
| from logging.handlers import TimedRotatingFileHandler | from logging.handlers import TimedRotatingFileHandler | ||||
| import toolforge_i18n | |||||
| from earwigbot.bot import Bot | |||||
| from flask import Flask, request | from flask import Flask, request | ||||
| from flask.sessions import SecureCookieSessionInterface, SessionMixin | from flask.sessions import SecureCookieSessionInterface, SessionMixin | ||||
| from toolforge_i18n import ToolforgeI18n, set_user_agent | |||||
| class CopyviosSessionInterface(SecureCookieSessionInterface): | class CopyviosSessionInterface(SecureCookieSessionInterface): | ||||
| @@ -35,14 +36,14 @@ app.config["SESSION_COOKIE_SECURE"] = True | |||||
| app.config["SESSION_COOKIE_SAMESITE"] = "Lax" | app.config["SESSION_COOKIE_SAMESITE"] = "Lax" | ||||
| app.config["PERMANENT_SESSION_LIFETIME"] = datetime.timedelta(days=365) | app.config["PERMANENT_SESSION_LIFETIME"] = datetime.timedelta(days=365) | ||||
| set_user_agent( | |||||
| "Copyvios/1.0 (https://github.com/earwig/copyvios; wikipedia.earwig@gmail.com)" | |||||
| ) | |||||
| i18n = ToolforgeI18n(app) | |||||
| app.jinja_options["trim_blocks"] = True | app.jinja_options["trim_blocks"] = True | ||||
| app.jinja_options["lstrip_blocks"] = True | app.jinja_options["lstrip_blocks"] = True | ||||
| hand = TimedRotatingFileHandler("logs/app.log", when="midnight", backupCount=7) | hand = TimedRotatingFileHandler("logs/app.log", when="midnight", backupCount=7) | ||||
| hand.setLevel(logging.DEBUG) | hand.setLevel(logging.DEBUG) | ||||
| app.logger.addHandler(hand) | app.logger.addHandler(hand) | ||||
| bot = Bot(".earwigbot", 100) | |||||
| toolforge_i18n.set_user_agent(bot.config.wiki["userAgent"]) # pyright: ignore[reportPrivateImportUsage] | |||||
| i18n = toolforge_i18n.ToolforgeI18n(app) # pyright: ignore[reportPrivateImportUsage] | |||||
| @@ -9,6 +9,8 @@ import sqlalchemy | |||||
| import sqlalchemy.event | import sqlalchemy.event | ||||
| from earwigbot.bot import Bot | from earwigbot.bot import Bot | ||||
| from . import bot | |||||
| @dataclass(frozen=True, order=True) | @dataclass(frozen=True, order=True) | ||||
| class Lang: | class Lang: | ||||
| @@ -62,8 +64,6 @@ def _get_engine(bot: Bot) -> sqlalchemy.Engine: | |||||
| def _make_cache() -> AppCache: | def _make_cache() -> AppCache: | ||||
| bot = Bot(".earwigbot", 100) | |||||
| oauth_config = bot.config.wiki.get("copyvios", {}).get("oauth", {}) | oauth_config = bot.config.wiki.get("copyvios", {}).get("oauth", {}) | ||||
| if oauth_config.get("consumer_token") is None: | if oauth_config.get("consumer_token") is None: | ||||
| raise ValueError( | raise ValueError( | ||||
| @@ -8,6 +8,7 @@ import urllib.parse | |||||
| from datetime import UTC, datetime, timedelta | from datetime import UTC, datetime, timedelta | ||||
| from enum import Enum | from enum import Enum | ||||
| import toolforge_i18n | |||||
| from earwigbot import exceptions | from earwigbot import exceptions | ||||
| from earwigbot.wiki import Page, Site | from earwigbot.wiki import Page, Site | ||||
| from earwigbot.wiki.copyvios import CopyvioChecker, workers | from earwigbot.wiki.copyvios import CopyvioChecker, workers | ||||
| @@ -16,7 +17,6 @@ from earwigbot.wiki.copyvios.result import CopyvioCheckResult, CopyvioSource | |||||
| from earwigbot.wiki.copyvios.workers import CopyvioWorkspace | from earwigbot.wiki.copyvios.workers import CopyvioWorkspace | ||||
| from flask import current_app, g, session | from flask import current_app, g, session | ||||
| from sqlalchemy import PoolProxiedConnection | from sqlalchemy import PoolProxiedConnection | ||||
| from toolforge_i18n._flask import message as _i18n_message | |||||
| from .cache import cache | from .cache import cache | ||||
| from .misc import get_sql_error, sql_dialect | from .misc import get_sql_error, sql_dialect | ||||
| @@ -54,12 +54,12 @@ class CopyvioCheckError(Exception): | |||||
| def do_check(query: CheckQuery) -> CopyvioCheckResult | None: | def do_check(query: CheckQuery) -> CopyvioCheckResult | None: | ||||
| if query.submitted: | if query.submitted: | ||||
| is_logged_in = _get_username() is not None | is_logged_in = _get_username() is not None | ||||
| bypass = current_app.config.get("COPYVIOS_BYPASS_LOGIN", False) | |||||
| config_bypass = current_app.config.get("COPYVIOS_BYPASS_LOGIN", False) | |||||
| if ( | if ( | ||||
| query.use_engine | query.use_engine | ||||
| and not is_logged_in | and not is_logged_in | ||||
| and not isinstance(query, APIQuery) | and not isinstance(query, APIQuery) | ||||
| and not bypass | |||||
| and not config_bypass | |||||
| ): | ): | ||||
| raise CopyvioCheckError(ErrorCode.NOT_LOGGED_IN) | raise CopyvioCheckError(ErrorCode.NOT_LOGGED_IN) | ||||
| @@ -309,10 +309,10 @@ def _format_date(cache_time: datetime) -> str: | |||||
| diff = datetime.now(UTC) - cache_time | diff = datetime.now(UTC) - cache_time | ||||
| total_seconds = diff.days * 86400 + diff.seconds | total_seconds = diff.days * 86400 + diff.seconds | ||||
| if total_seconds >= 3600: | if total_seconds >= 3600: | ||||
| return _i18n_message("ago-hours", num=int(total_seconds / 3600)) | |||||
| return toolforge_i18n.message("ago-hours", num=int(total_seconds / 3600)) # pyright: ignore[reportPrivateImportUsage] | |||||
| if total_seconds >= 60: | if total_seconds >= 60: | ||||
| return _i18n_message("ago-minutes", num=int(total_seconds / 60)) | |||||
| return str(_i18n_message("ago-seconds", num=total_seconds)) | |||||
| return toolforge_i18n.message("ago-minutes", num=int(total_seconds / 60)) # pyright: ignore[reportPrivateImportUsage] | |||||
| return str(toolforge_i18n.message("ago-seconds", num=total_seconds)) # pyright: ignore[reportPrivateImportUsage] | |||||
| def _cache_result( | def _cache_result( | ||||
| @@ -1,4 +1,6 @@ | |||||
| from toolforge_i18n import TranslationsConfig | |||||
| from toolforge_i18n import ( | |||||
| TranslationsConfig, # pyright: ignore[reportPrivateImportUsage] | |||||
| ) | |||||
| config = TranslationsConfig( | config = TranslationsConfig( | ||||
| variables={ | variables={ | ||||