mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-02-24 07:06:21 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9048af6e8 | ||
|
|
2f7315e29c | ||
|
|
bf3f8eae45 | ||
|
|
fe7aa38c65 | ||
|
|
a385c89abf | ||
|
|
98f884bbff | ||
|
|
35499d1171 | ||
|
|
599aed75d1 | ||
|
|
6df75a5af9 | ||
|
|
f71c4b9865 | ||
|
|
82d5d7999c | ||
|
|
7a51f1e4bf | ||
|
|
91dee697f9 |
@@ -715,7 +715,7 @@ jobs:
|
||||
pip install 'pyOpenSSL>=23.2.0'
|
||||
|
||||
echo "=== Running version 0.49.1 to create datastore ==="
|
||||
python3 ./changedetection.py -C -d /tmp/data &
|
||||
ALLOW_IANA_RESTRICTED_ADDRESSES=true python3 ./changedetection.py -C -d /tmp/data &
|
||||
APP_PID=$!
|
||||
|
||||
# Wait for app to be ready
|
||||
@@ -763,7 +763,7 @@ jobs:
|
||||
pip install -r requirements.txt
|
||||
|
||||
echo "=== Running current version (commit ${{ github.sha }}) with old datastore (testing mode) ==="
|
||||
TESTING_SHUTDOWN_AFTER_DATASTORE_LOAD=1 python3 ./changedetection.py -d /tmp/data > /tmp/upgrade-test.log 2>&1
|
||||
ALLOW_IANA_RESTRICTED_ADDRESSES=true TESTING_SHUTDOWN_AFTER_DATASTORE_LOAD=1 python3 ./changedetection.py -d /tmp/data > /tmp/upgrade-test.log 2>&1
|
||||
|
||||
echo "=== Upgrade test output ==="
|
||||
cat /tmp/upgrade-test.log
|
||||
@@ -771,7 +771,7 @@ jobs:
|
||||
|
||||
# Now start the current version normally to verify the tag survived
|
||||
echo "=== Starting current version to verify tag exists after upgrade ==="
|
||||
timeout 20 python3 ./changedetection.py -d /tmp/data > /tmp/ui-test.log 2>&1 &
|
||||
ALLOW_IANA_RESTRICTED_ADDRESSES=true timeout 20 python3 ./changedetection.py -d /tmp/data > /tmp/ui-test.log 2>&1 &
|
||||
APP_PID=$!
|
||||
|
||||
# Wait for app to be ready and fetch UI
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Read more https://github.com/dgtlmoon/changedetection.io/wiki
|
||||
# Semver means never use .01, or 00. Should be .1.
|
||||
__version__ = '0.53.5'
|
||||
__version__ = '0.54.1'
|
||||
|
||||
from changedetectionio.strtobool import strtobool
|
||||
from json.decoder import JSONDecodeError
|
||||
|
||||
@@ -17,7 +17,7 @@ class Tag(Resource):
|
||||
self.update_q = kwargs['update_q']
|
||||
|
||||
# Get information about a single tag
|
||||
# curl http://localhost:5000/api/v1/tag/<string:uuid>
|
||||
# curl http://localhost:5000/api/v1/tag/<uuid_str:uuid>
|
||||
@auth.check_token
|
||||
@validate_openapi_request('getTag')
|
||||
def get(self, uuid):
|
||||
|
||||
@@ -57,7 +57,7 @@ class Watch(Resource):
|
||||
self.update_q = kwargs['update_q']
|
||||
|
||||
# Get information about a single watch, excluding the history list (can be large)
|
||||
# curl http://localhost:5000/api/v1/watch/<string:uuid>
|
||||
# curl http://localhost:5000/api/v1/watch/<uuid_str:uuid>
|
||||
# @todo - version2 - ?muted and ?paused should be able to be called together, return the watch struct not "OK"
|
||||
# ?recheck=true
|
||||
@auth.check_token
|
||||
@@ -217,7 +217,7 @@ class WatchHistory(Resource):
|
||||
self.datastore = kwargs['datastore']
|
||||
|
||||
# Get a list of available history for a watch by UUID
|
||||
# curl http://localhost:5000/api/v1/watch/<string:uuid>/history
|
||||
# curl http://localhost:5000/api/v1/watch/<uuid_str:uuid>/history
|
||||
@auth.check_token
|
||||
@validate_openapi_request('getWatchHistory')
|
||||
def get(self, uuid):
|
||||
|
||||
@@ -94,13 +94,13 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
return results
|
||||
|
||||
@login_required
|
||||
@check_proxies_blueprint.route("/<string:uuid>/status", methods=['GET'])
|
||||
@check_proxies_blueprint.route("/<uuid_str:uuid>/status", methods=['GET'])
|
||||
def get_recheck_status(uuid):
|
||||
results = _recalc_check_status(uuid=uuid)
|
||||
return results
|
||||
|
||||
@login_required
|
||||
@check_proxies_blueprint.route("/<string:uuid>/start", methods=['GET'])
|
||||
@check_proxies_blueprint.route("/<uuid_str:uuid>/start", methods=['GET'])
|
||||
def start_check(uuid):
|
||||
|
||||
if not datastore.proxy_list:
|
||||
|
||||
@@ -15,7 +15,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q: PriorityQueue
|
||||
price_data_follower_blueprint = Blueprint('price_data_follower', __name__)
|
||||
|
||||
@login_required
|
||||
@price_data_follower_blueprint.route("/<string:uuid>/accept", methods=['GET'])
|
||||
@price_data_follower_blueprint.route("/<uuid_str:uuid>/accept", methods=['GET'])
|
||||
def accept(uuid):
|
||||
datastore.data['watching'][uuid]['track_ldjson_price_data'] = PRICE_DATA_TRACK_ACCEPT
|
||||
datastore.data['watching'][uuid]['processor'] = 'restock_diff'
|
||||
@@ -25,7 +25,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q: PriorityQueue
|
||||
return redirect(url_for("watchlist.index"))
|
||||
|
||||
@login_required
|
||||
@price_data_follower_blueprint.route("/<string:uuid>/reject", methods=['GET'])
|
||||
@price_data_follower_blueprint.route("/<uuid_str:uuid>/reject", methods=['GET'])
|
||||
def reject(uuid):
|
||||
datastore.data['watching'][uuid]['track_ldjson_price_data'] = PRICE_DATA_TRACK_REJECT
|
||||
datastore.data['watching'][uuid].commit()
|
||||
|
||||
@@ -9,11 +9,12 @@ def construct_single_watch_routes(rss_blueprint, datastore):
|
||||
datastore: The ChangeDetectionStore instance
|
||||
"""
|
||||
|
||||
@rss_blueprint.route("/watch/<string:uuid>", methods=['GET'])
|
||||
@rss_blueprint.route("/watch/<uuid_str:uuid>", methods=['GET'])
|
||||
def rss_single_watch(uuid):
|
||||
import time
|
||||
|
||||
from flask import make_response, request
|
||||
from flask import make_response, request, Response
|
||||
from flask_babel import lazy_gettext as _l
|
||||
from feedgen.feed import FeedGenerator
|
||||
from loguru import logger
|
||||
|
||||
@@ -42,12 +43,12 @@ def construct_single_watch_routes(rss_blueprint, datastore):
|
||||
# Get the watch by UUID
|
||||
watch = datastore.data['watching'].get(uuid)
|
||||
if not watch:
|
||||
return f"Watch with UUID {uuid} not found", 404
|
||||
return Response(_l("Watch with UUID %(uuid)s not found", uuid=uuid), status=404, mimetype='text/plain')
|
||||
|
||||
# Check if watch has at least 2 history snapshots
|
||||
dates = list(watch.history.keys())
|
||||
if len(dates) < 2:
|
||||
return f"Watch {uuid} does not have enough history snapshots to show changes (need at least 2)", 400
|
||||
return Response(_l("Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)", uuid=uuid), status=400, mimetype='text/plain')
|
||||
|
||||
# Get the number of diffs to include (default: 5)
|
||||
rss_diff_length = datastore.data['settings']['application'].get('rss_diff_length', 5)
|
||||
|
||||
@@ -54,7 +54,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
|
||||
return redirect(url_for('tags.tags_overview_page'))
|
||||
|
||||
@tags_blueprint.route("/mute/<string:uuid>", methods=['GET'])
|
||||
@tags_blueprint.route("/mute/<uuid_str:uuid>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def mute(uuid):
|
||||
tag = datastore.data['settings']['application']['tags'].get(uuid)
|
||||
@@ -63,7 +63,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
tag.commit()
|
||||
return redirect(url_for('tags.tags_overview_page'))
|
||||
|
||||
@tags_blueprint.route("/delete/<string:uuid>", methods=['GET'])
|
||||
@tags_blueprint.route("/delete/<uuid_str:uuid>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def delete(uuid):
|
||||
# Delete the tag from settings immediately
|
||||
@@ -90,7 +90,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
flash(gettext("Tag deleted, removing from watches in background"))
|
||||
return redirect(url_for('tags.tags_overview_page'))
|
||||
|
||||
@tags_blueprint.route("/unlink/<string:uuid>", methods=['GET'])
|
||||
@tags_blueprint.route("/unlink/<uuid_str:uuid>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def unlink(uuid):
|
||||
# Unlink tag from all watches in background thread to avoid blocking
|
||||
@@ -141,7 +141,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
flash(gettext("All tags deleted, clearing from watches in background"))
|
||||
return redirect(url_for('tags.tags_overview_page'))
|
||||
|
||||
@tags_blueprint.route("/edit/<string:uuid>", methods=['GET'])
|
||||
@tags_blueprint.route("/edit/<uuid_str:uuid>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def form_tag_edit(uuid):
|
||||
from changedetectionio.blueprint.tags.form import group_restock_settings_form
|
||||
@@ -203,7 +203,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
return output
|
||||
|
||||
|
||||
@tags_blueprint.route("/edit/<string:uuid>", methods=['POST'])
|
||||
@tags_blueprint.route("/edit/<uuid_str:uuid>", methods=['POST'])
|
||||
@login_optionally_required
|
||||
def form_tag_edit_submit(uuid):
|
||||
from changedetectionio.blueprint.tags.form import group_restock_settings_form
|
||||
|
||||
@@ -141,7 +141,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, worker_pool,
|
||||
# Import the login decorator
|
||||
from changedetectionio.auth_decorator import login_optionally_required
|
||||
|
||||
@ui_blueprint.route("/clear_history/<string:uuid>", methods=['GET'])
|
||||
@ui_blueprint.route("/clear_history/<uuid_str:uuid>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def clear_watch_history(uuid):
|
||||
try:
|
||||
@@ -366,7 +366,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, worker_pool,
|
||||
return redirect(url_for('watchlist.index'))
|
||||
|
||||
|
||||
@ui_blueprint.route("/share-url/<string:uuid>", methods=['GET'])
|
||||
@ui_blueprint.route("/share-url/<uuid_str:uuid>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def form_share_put_watch(uuid):
|
||||
"""Given a watch UUID, upload the info and return a share-link
|
||||
|
||||
@@ -66,7 +66,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
|
||||
return Markup(result)
|
||||
|
||||
@diff_blueprint.route("/diff/<string:uuid>", methods=['GET'])
|
||||
@diff_blueprint.route("/diff/<uuid_str:uuid>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def diff_history_page(uuid):
|
||||
"""
|
||||
@@ -128,7 +128,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
redirect=redirect
|
||||
)
|
||||
|
||||
@diff_blueprint.route("/diff/<string:uuid>/extract", methods=['GET'])
|
||||
@diff_blueprint.route("/diff/<uuid_str:uuid>/extract", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def diff_history_page_extract_GET(uuid):
|
||||
"""
|
||||
@@ -182,7 +182,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
redirect=redirect
|
||||
)
|
||||
|
||||
@diff_blueprint.route("/diff/<string:uuid>/extract", methods=['POST'])
|
||||
@diff_blueprint.route("/diff/<uuid_str:uuid>/extract", methods=['POST'])
|
||||
@login_optionally_required
|
||||
def diff_history_page_extract_POST(uuid):
|
||||
"""
|
||||
@@ -238,7 +238,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
redirect=redirect
|
||||
)
|
||||
|
||||
@diff_blueprint.route("/diff/<string:uuid>/processor-asset/<string:asset_name>", methods=['GET'])
|
||||
@diff_blueprint.route("/diff/<uuid_str:uuid>/processor-asset/<string:asset_name>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def processor_asset(uuid, asset_name):
|
||||
"""
|
||||
|
||||
@@ -20,7 +20,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
|
||||
if tag_uuid in watch.get('tags', []) and (tag.get('include_filters') or tag.get('subtractive_selectors')):
|
||||
return True
|
||||
|
||||
@edit_blueprint.route("/edit/<string:uuid>", methods=['GET', 'POST'])
|
||||
@edit_blueprint.route("/edit/<uuid_str:uuid>", methods=['GET', 'POST'])
|
||||
@login_optionally_required
|
||||
# https://stackoverflow.com/questions/42984453/wtforms-populate-form-with-data-if-data-exists
|
||||
# https://wtforms.readthedocs.io/en/3.0.x/forms/#wtforms.form.Form.populate_obj ?
|
||||
@@ -327,7 +327,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
|
||||
|
||||
return output
|
||||
|
||||
@edit_blueprint.route("/edit/<string:uuid>/get-html", methods=['GET'])
|
||||
@edit_blueprint.route("/edit/<uuid_str:uuid>/get-html", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def watch_get_latest_html(uuid):
|
||||
from io import BytesIO
|
||||
@@ -354,7 +354,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
|
||||
# Return a 500 error
|
||||
abort(500)
|
||||
|
||||
@edit_blueprint.route("/edit/<string:uuid>/get-data-package", methods=['GET'])
|
||||
@edit_blueprint.route("/edit/<uuid_str:uuid>/get-data-package", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def watch_get_data_package(uuid):
|
||||
"""Download all data for a single watch as a zip file"""
|
||||
@@ -405,7 +405,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
|
||||
mimetype='application/zip')
|
||||
|
||||
# Ajax callback
|
||||
@edit_blueprint.route("/edit/<string:uuid>/preview-rendered", methods=['POST'])
|
||||
@edit_blueprint.route("/edit/<uuid_str:uuid>/preview-rendered", methods=['POST'])
|
||||
@login_optionally_required
|
||||
def watch_get_preview_rendered(uuid):
|
||||
'''For when viewing the "preview" of the rendered text from inside of Edit'''
|
||||
|
||||
@@ -10,7 +10,7 @@ from changedetectionio import html_tools
|
||||
def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
preview_blueprint = Blueprint('ui_preview', __name__, template_folder="../ui/templates")
|
||||
|
||||
@preview_blueprint.route("/preview/<string:uuid>", methods=['GET'])
|
||||
@preview_blueprint.route("/preview/<uuid_str:uuid>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def preview_page(uuid):
|
||||
"""
|
||||
@@ -125,7 +125,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||
|
||||
return output
|
||||
|
||||
@preview_blueprint.route("/preview/<string:uuid>/processor-asset/<string:asset_name>", methods=['GET'])
|
||||
@preview_blueprint.route("/preview/<uuid_str:uuid>/processor-asset/<string:asset_name>", methods=['GET'])
|
||||
@login_optionally_required
|
||||
def processor_asset(uuid, asset_name):
|
||||
"""
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from loguru import logger
|
||||
from urllib.parse import urljoin, urlparse
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
@@ -7,6 +8,7 @@ import asyncio
|
||||
from changedetectionio import strtobool
|
||||
from changedetectionio.content_fetchers.exceptions import BrowserStepsInUnsupportedFetcher, EmptyReply, Non200ErrorCodeReceived
|
||||
from changedetectionio.content_fetchers.base import Fetcher
|
||||
from changedetectionio.validate_url import is_private_hostname
|
||||
|
||||
|
||||
# "html_requests" is listed as the default fetcher in store.py!
|
||||
@@ -79,14 +81,48 @@ class fetcher(Fetcher):
|
||||
if strtobool(os.getenv('ALLOW_FILE_URI', 'false')) and url.startswith('file://'):
|
||||
from requests_file import FileAdapter
|
||||
session.mount('file://', FileAdapter())
|
||||
|
||||
allow_iana_restricted = strtobool(os.getenv('ALLOW_IANA_RESTRICTED_ADDRESSES', 'false'))
|
||||
|
||||
try:
|
||||
# Fresh DNS check at fetch time — catches DNS rebinding regardless of add-time cache.
|
||||
if not allow_iana_restricted:
|
||||
parsed_initial = urlparse(url)
|
||||
if parsed_initial.hostname and is_private_hostname(parsed_initial.hostname):
|
||||
raise Exception(f"Fetch blocked: '{url}' resolves to a private/reserved IP address. "
|
||||
f"Set ALLOW_IANA_RESTRICTED_ADDRESSES=true to allow.")
|
||||
|
||||
r = session.request(method=request_method,
|
||||
data=request_body.encode('utf-8') if type(request_body) is str else request_body,
|
||||
url=url,
|
||||
headers=request_headers,
|
||||
timeout=timeout,
|
||||
proxies=proxies,
|
||||
verify=False)
|
||||
verify=False,
|
||||
allow_redirects=False)
|
||||
|
||||
# Manually follow redirects so each hop's resolved IP can be validated,
|
||||
# preventing SSRF via an open redirect on a public host.
|
||||
current_url = url
|
||||
for _ in range(10):
|
||||
if not r.is_redirect:
|
||||
break
|
||||
location = r.headers.get('Location', '')
|
||||
redirect_url = urljoin(current_url, location)
|
||||
if not allow_iana_restricted:
|
||||
parsed_redirect = urlparse(redirect_url)
|
||||
if parsed_redirect.hostname and is_private_hostname(parsed_redirect.hostname):
|
||||
raise Exception(f"Redirect blocked: '{redirect_url}' resolves to a private/reserved IP address.")
|
||||
current_url = redirect_url
|
||||
r = session.request('GET', redirect_url,
|
||||
headers=request_headers,
|
||||
timeout=timeout,
|
||||
proxies=proxies,
|
||||
verify=False,
|
||||
allow_redirects=False)
|
||||
else:
|
||||
raise Exception("Too many redirects")
|
||||
|
||||
except Exception as e:
|
||||
msg = str(e)
|
||||
if proxies and 'SOCKSHTTPSConnectionPool' in msg:
|
||||
|
||||
@@ -27,7 +27,6 @@ from flask import (
|
||||
session,
|
||||
url_for,
|
||||
)
|
||||
from flask_compress import Compress as FlaskCompress
|
||||
from flask_restful import abort, Api
|
||||
from flask_cors import CORS
|
||||
|
||||
@@ -69,19 +68,43 @@ socketio_server = None
|
||||
|
||||
# Enable CORS, especially useful for the Chrome extension to operate from anywhere
|
||||
CORS(app)
|
||||
from werkzeug.routing import BaseConverter, ValidationError
|
||||
from uuid import UUID
|
||||
|
||||
class StrictUUIDConverter(BaseConverter):
|
||||
# Special sentinel values allowed in addition to strict UUIDs
|
||||
_ALLOWED_SENTINELS = frozenset({'first'})
|
||||
|
||||
def to_python(self, value: str) -> str:
|
||||
if value in self._ALLOWED_SENTINELS:
|
||||
return value
|
||||
try:
|
||||
u = UUID(value)
|
||||
except ValueError as e:
|
||||
raise ValidationError() from e
|
||||
# Reject non-standard formats (braces, URNs, no-hyphens)
|
||||
if str(u) != value.lower():
|
||||
raise ValidationError()
|
||||
return str(u)
|
||||
|
||||
def to_url(self, value) -> str:
|
||||
return str(value)
|
||||
|
||||
# app setup (once)
|
||||
app.url_map.converters["uuid_str"] = StrictUUIDConverter
|
||||
|
||||
# Flask-Compress handles HTTP compression, Socket.IO compression disabled to prevent memory leak.
|
||||
# There's also a bug between flask compress and socketio that causes some kind of slow memory leak
|
||||
# It's better to use compression on your reverse proxy (nginx etc) instead.
|
||||
if strtobool(os.getenv("FLASK_ENABLE_COMPRESSION")):
|
||||
from flask_compress import Compress as FlaskCompress
|
||||
app.config['COMPRESS_MIN_SIZE'] = 2096
|
||||
app.config['COMPRESS_MIMETYPES'] = ['text/html', 'text/css', 'text/javascript', 'application/json', 'application/javascript', 'image/svg+xml']
|
||||
# Use gzip only - smaller memory footprint than zstd/brotli (4-8KB vs 200-500KB contexts)
|
||||
app.config['COMPRESS_ALGORITHM'] = ['gzip']
|
||||
compress = FlaskCompress()
|
||||
compress.init_app(app)
|
||||
|
||||
compress = FlaskCompress()
|
||||
|
||||
compress.init_app(app)
|
||||
app.config['TEMPLATES_AUTO_RELOAD'] = False
|
||||
|
||||
|
||||
@@ -534,22 +557,22 @@ def changedetection_app(config=None, datastore_o=None):
|
||||
|
||||
|
||||
watch_api.add_resource(WatchHistoryDiff,
|
||||
'/api/v1/watch/<string:uuid>/difference/<string:from_timestamp>/<string:to_timestamp>',
|
||||
'/api/v1/watch/<uuid_str:uuid>/difference/<string:from_timestamp>/<string:to_timestamp>',
|
||||
resource_class_kwargs={'datastore': datastore})
|
||||
watch_api.add_resource(WatchSingleHistory,
|
||||
'/api/v1/watch/<string:uuid>/history/<string:timestamp>',
|
||||
'/api/v1/watch/<uuid_str:uuid>/history/<string:timestamp>',
|
||||
resource_class_kwargs={'datastore': datastore, 'update_q': update_q})
|
||||
watch_api.add_resource(WatchFavicon,
|
||||
'/api/v1/watch/<string:uuid>/favicon',
|
||||
'/api/v1/watch/<uuid_str:uuid>/favicon',
|
||||
resource_class_kwargs={'datastore': datastore})
|
||||
watch_api.add_resource(WatchHistory,
|
||||
'/api/v1/watch/<string:uuid>/history',
|
||||
'/api/v1/watch/<uuid_str:uuid>/history',
|
||||
resource_class_kwargs={'datastore': datastore})
|
||||
|
||||
watch_api.add_resource(CreateWatch, '/api/v1/watch',
|
||||
resource_class_kwargs={'datastore': datastore, 'update_q': update_q})
|
||||
|
||||
watch_api.add_resource(Watch, '/api/v1/watch/<string:uuid>',
|
||||
watch_api.add_resource(Watch, '/api/v1/watch/<uuid_str:uuid>',
|
||||
resource_class_kwargs={'datastore': datastore, 'update_q': update_q})
|
||||
|
||||
watch_api.add_resource(SystemInfo, '/api/v1/systeminfo',
|
||||
@@ -562,7 +585,7 @@ def changedetection_app(config=None, datastore_o=None):
|
||||
watch_api.add_resource(Tags, '/api/v1/tags',
|
||||
resource_class_kwargs={'datastore': datastore})
|
||||
|
||||
watch_api.add_resource(Tag, '/api/v1/tag', '/api/v1/tag/<string:uuid>',
|
||||
watch_api.add_resource(Tag, '/api/v1/tag', '/api/v1/tag/<uuid_str:uuid>',
|
||||
resource_class_kwargs={'datastore': datastore, 'update_q': update_q})
|
||||
|
||||
watch_api.add_resource(Search, '/api/v1/search',
|
||||
|
||||
@@ -36,7 +36,7 @@ def _task(watch, update_handler):
|
||||
|
||||
|
||||
def prepare_filter_prevew(datastore, watch_uuid, form_data):
|
||||
'''Used by @app.route("/edit/<string:uuid>/preview-rendered", methods=['POST'])'''
|
||||
'''Used by @app.route("/edit/<uuid_str:uuid>/preview-rendered", methods=['POST'])'''
|
||||
from changedetectionio import forms, html_tools
|
||||
from changedetectionio.model.Watch import model as watch_model
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
@@ -198,26 +198,11 @@ def handle_watch_update(socketio, **kwargs):
|
||||
except Exception as e:
|
||||
logger.error(f"Socket.IO error in handle_watch_update: {str(e)}")
|
||||
|
||||
|
||||
def _patch_flask_request_context_session():
|
||||
"""Flask 3.1 removed the session setter from RequestContext, but Flask-SocketIO 5.6.0
|
||||
still assigns to it directly (ctx.session = ...). Restore a setter that writes the
|
||||
private _session attribute so the two libraries work together.
|
||||
"""
|
||||
from flask.ctx import RequestContext
|
||||
if getattr(RequestContext.session, 'fset', None) is not None:
|
||||
return # Already has a setter (future Flask version restored it)
|
||||
original_prop = RequestContext.session
|
||||
RequestContext.session = original_prop.setter(lambda self, value: setattr(self, '_session', value))
|
||||
|
||||
|
||||
def init_socketio(app, datastore):
|
||||
"""Initialize SocketIO with the main Flask app"""
|
||||
import platform
|
||||
import sys
|
||||
|
||||
_patch_flask_request_context_session()
|
||||
|
||||
# Platform-specific async_mode selection for better stability
|
||||
system = platform.system().lower()
|
||||
python_version = sys.version_info
|
||||
|
||||
@@ -44,12 +44,12 @@ data_sanity_test () {
|
||||
cd ..
|
||||
TMPDIR=$(mktemp -d)
|
||||
PORT_N=$((5000 + RANDOM % (6501 - 5000)))
|
||||
./changedetection.py -p $PORT_N -d $TMPDIR -u "https://localhost?test-url-is-sanity=1" &
|
||||
ALLOW_IANA_RESTRICTED_ADDRESSES=true ./changedetection.py -p $PORT_N -d $TMPDIR -u "https://localhost?test-url-is-sanity=1" &
|
||||
PID=$!
|
||||
sleep 5
|
||||
kill $PID
|
||||
sleep 2
|
||||
./changedetection.py -p $PORT_N -d $TMPDIR &
|
||||
ALLOW_IANA_RESTRICTED_ADDRESSES=true ./changedetection.py -p $PORT_N -d $TMPDIR &
|
||||
PID=$!
|
||||
sleep 5
|
||||
# On a restart the URL should still be there
|
||||
|
||||
@@ -728,8 +728,11 @@ class ChangeDetectionStore(DatastoreUpdatesMixin, FileSavingDataStore):
|
||||
return False
|
||||
|
||||
if not is_safe_valid_url(url):
|
||||
flash(gettext('Watch protocol is not permitted or invalid URL format'), 'error')
|
||||
|
||||
from flask import has_request_context
|
||||
if has_request_context():
|
||||
flash(gettext('Watch protocol is not permitted or invalid URL format'), 'error')
|
||||
else:
|
||||
logger.error(f"add_watch: URL '{url}' is not permitted or invalid, skipping.")
|
||||
return None
|
||||
|
||||
# Check PAGE_WATCH_LIMIT if set
|
||||
|
||||
@@ -13,6 +13,10 @@ import sys
|
||||
# When test server is slow/unresponsive, workers fail fast instead of holding UUIDs for 45s
|
||||
# This prevents exponential priority growth from repeated deferrals (priority × 10 each defer)
|
||||
os.environ['DEFAULT_SETTINGS_REQUESTS_TIMEOUT'] = '5'
|
||||
# Test server runs on localhost (127.0.0.1) which is a private IP.
|
||||
# Allow it globally so all existing tests keep working; test_ssrf_protection
|
||||
# uses monkeypatch to temporarily override this for its own assertions.
|
||||
os.environ['ALLOW_IANA_RESTRICTED_ADDRESSES'] = 'true'
|
||||
|
||||
from changedetectionio.flask_app import init_app_secret, changedetection_app
|
||||
from changedetectionio.tests.util import live_server_setup, new_live_server_setup
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from flask import url_for
|
||||
|
||||
@@ -579,3 +580,131 @@ def test_static_directory_traversal(client, live_server, measure_memory_usage, d
|
||||
# Should get 403 (not authenticated) or 404 (file not found), not a path traversal
|
||||
assert res.status_code in [403, 404]
|
||||
|
||||
|
||||
def test_ssrf_private_ip_blocked(client, live_server, monkeypatch, measure_memory_usage, datastore_path):
|
||||
"""
|
||||
SSRF protection: IANA-reserved/private IP addresses must be blocked by default.
|
||||
|
||||
Covers:
|
||||
1. is_private_hostname() correctly classifies all reserved ranges
|
||||
2. is_safe_valid_url() rejects private-IP URLs at add-time (env var off)
|
||||
3. is_safe_valid_url() allows private-IP URLs when ALLOW_IANA_RESTRICTED_ADDRESSES=true
|
||||
4. UI form rejects private-IP URLs and shows the standard error message
|
||||
5. Requests fetcher blocks fetch-time DNS rebinding (fresh check on every fetch)
|
||||
6. Requests fetcher blocks redirects that lead to a private IP (open-redirect bypass)
|
||||
|
||||
conftest.py sets ALLOW_IANA_RESTRICTED_ADDRESSES=true globally so the test
|
||||
server (localhost) keeps working for all other tests. monkeypatch temporarily
|
||||
overrides it to 'false' here, and is automatically restored after the test.
|
||||
"""
|
||||
from unittest.mock import patch, MagicMock
|
||||
from changedetectionio.validate_url import is_safe_valid_url, is_private_hostname
|
||||
|
||||
monkeypatch.setenv('ALLOW_IANA_RESTRICTED_ADDRESSES', 'false')
|
||||
# Clear any URL results cached while the env var was 'true'
|
||||
is_safe_valid_url.cache_clear()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 1. is_private_hostname() — unit tests across all reserved ranges
|
||||
# ------------------------------------------------------------------
|
||||
private_hosts = [
|
||||
'127.0.0.1', # loopback
|
||||
'10.0.0.1', # RFC 1918
|
||||
'172.16.0.1', # RFC 1918
|
||||
'192.168.1.1', # RFC 1918
|
||||
'169.254.169.254', # link-local / AWS metadata endpoint
|
||||
'::1', # IPv6 loopback
|
||||
'fc00::1', # IPv6 unique local
|
||||
'fe80::1', # IPv6 link-local
|
||||
]
|
||||
for host in private_hosts:
|
||||
assert is_private_hostname(host), f"{host} should be identified as private/reserved"
|
||||
|
||||
for host in ['8.8.8.8', '1.1.1.1']:
|
||||
assert not is_private_hostname(host), f"{host} should be identified as public"
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 2. is_safe_valid_url() blocks private-IP URLs (env var off)
|
||||
# ------------------------------------------------------------------
|
||||
blocked_urls = [
|
||||
'http://127.0.0.1/',
|
||||
'http://10.0.0.1/',
|
||||
'http://172.16.0.1/',
|
||||
'http://192.168.1.1/',
|
||||
'http://169.254.169.254/',
|
||||
'http://169.254.169.254/latest/meta-data/iam/security-credentials/',
|
||||
'http://[::1]/',
|
||||
'http://[fc00::1]/',
|
||||
'http://[fe80::1]/',
|
||||
]
|
||||
for url in blocked_urls:
|
||||
assert not is_safe_valid_url(url), f"{url} should be blocked by is_safe_valid_url"
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 3. ALLOW_IANA_RESTRICTED_ADDRESSES=true bypasses the block
|
||||
# ------------------------------------------------------------------
|
||||
monkeypatch.setenv('ALLOW_IANA_RESTRICTED_ADDRESSES', 'true')
|
||||
is_safe_valid_url.cache_clear()
|
||||
assert is_safe_valid_url('http://127.0.0.1/'), \
|
||||
"Private IP should be allowed when ALLOW_IANA_RESTRICTED_ADDRESSES=true"
|
||||
|
||||
# Restore the block for the remaining assertions
|
||||
monkeypatch.setenv('ALLOW_IANA_RESTRICTED_ADDRESSES', 'false')
|
||||
is_safe_valid_url.cache_clear()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 4. UI form rejects private-IP URLs
|
||||
# ------------------------------------------------------------------
|
||||
for url in ['http://127.0.0.1/', 'http://169.254.169.254/latest/meta-data/']:
|
||||
res = client.post(
|
||||
url_for('ui.ui_views.form_quick_watch_add'),
|
||||
data={'url': url, 'tags': ''},
|
||||
follow_redirects=True
|
||||
)
|
||||
assert b'Watch protocol is not permitted or invalid URL format' in res.data, \
|
||||
f"UI should reject {url}"
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 5. Fetch-time DNS-rebinding check in the requests fetcher
|
||||
# Simulates: URL passed add-time validation with a public IP, but
|
||||
# by fetch time DNS has been rebound to a private IP.
|
||||
# ------------------------------------------------------------------
|
||||
from changedetectionio.content_fetchers.requests import fetcher as RequestsFetcher
|
||||
|
||||
f = RequestsFetcher()
|
||||
|
||||
with patch('changedetectionio.content_fetchers.requests.is_private_hostname', return_value=True):
|
||||
with pytest.raises(Exception, match='private/reserved'):
|
||||
f._run_sync(
|
||||
url='http://example.com/',
|
||||
timeout=5,
|
||||
request_headers={},
|
||||
request_body=None,
|
||||
request_method='GET',
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 6. Redirect-to-private-IP blocked (open-redirect SSRF bypass)
|
||||
# Public host returns a 302 pointing at an IANA-reserved address.
|
||||
# ------------------------------------------------------------------
|
||||
mock_redirect = MagicMock()
|
||||
mock_redirect.is_redirect = True
|
||||
mock_redirect.status_code = 302
|
||||
mock_redirect.headers = {'Location': 'http://169.254.169.254/latest/meta-data/'}
|
||||
|
||||
def _private_only_for_redirect(hostname):
|
||||
# Initial host is "public"; the redirect target is private
|
||||
return hostname in {'169.254.169.254', '10.0.0.1', '172.16.0.1',
|
||||
'192.168.0.1', '127.0.0.1', '::1'}
|
||||
|
||||
with patch('changedetectionio.content_fetchers.requests.is_private_hostname',
|
||||
side_effect=_private_only_for_redirect):
|
||||
with patch('requests.Session.request', return_value=mock_redirect):
|
||||
with pytest.raises(Exception, match='Redirect blocked'):
|
||||
f._run_sync(
|
||||
url='http://example.com/',
|
||||
timeout=5,
|
||||
request_headers={},
|
||||
request_body=None,
|
||||
request_method='GET',
|
||||
)
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: 2026-01-02 11:40+0100\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: cs\n"
|
||||
@@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -34,34 +34,116 @@ msgstr ""
|
||||
msgid "Backups were deleted."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "Backups"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr "A backup is running!"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr "Mb"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr "No backups found."
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr "Vytvořit zálohu"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr "Odstranit zálohy"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr ""
|
||||
@@ -120,6 +202,14 @@ msgstr "Distill.io"
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ".XLSX a Wachete"
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr ""
|
||||
@@ -206,6 +296,16 @@ msgstr "Znovu zkontrolovat čas (minuty)"
|
||||
msgid "Import"
|
||||
msgstr "IMPORTOVAT"
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr ""
|
||||
@@ -291,6 +391,10 @@ msgstr "API"
|
||||
msgid "RSS"
|
||||
msgstr "RSS"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "Backups"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr "Čas a datum"
|
||||
@@ -307,10 +411,6 @@ msgstr "Info"
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr "Výchozí čas opětovné kontroly pro všechny monitory, aktuální systémové minimum je"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr "sekundy"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr "Více informací"
|
||||
@@ -666,6 +766,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr "Verze Pythonu:"
|
||||
@@ -919,10 +1023,6 @@ msgstr ""
|
||||
msgid "Incorrect confirmation text."
|
||||
msgstr "Žádné informace"
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
@@ -1527,6 +1627,10 @@ msgstr "Odpověď typu serveru"
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr "Stáhněte si nejnovější HTML snímek"
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr "Smazat monitory?"
|
||||
@@ -1784,6 +1888,66 @@ msgstr "v '%(title)s'"
|
||||
msgid "Not yet"
|
||||
msgstr "Ještě ne"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr "sekundy"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr ""
|
||||
@@ -2878,6 +3042,18 @@ msgstr ""
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr ""
|
||||
@@ -3091,3 +3267,6 @@ msgstr "Hlavní nastavení"
|
||||
#~ msgid "Tip: You can also add 'shared' watches."
|
||||
#~ msgstr "Tip: Můžete také přidat „sdílené“ monitory."
|
||||
|
||||
#~ msgid "Marking watches as viewed in background..."
|
||||
#~ msgstr ""
|
||||
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: 2026-01-14 03:57+0100\n"
|
||||
"Last-Translator: \n"
|
||||
"Language: de\n"
|
||||
@@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -34,36 +34,118 @@ msgstr "Backup läuft im Hintergrund, bitte in ein paar Minuten erneut versuchen
|
||||
msgid "Backups were deleted."
|
||||
msgstr "Backups wurden gelöscht."
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "Backups"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr "Ein Backup läuft!"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr ""
|
||||
"Hier können Sie ein neues Backup herunterladen und anfordern. Sobald ein Backup abgeschlossen ist, wird es unten "
|
||||
"aufgelistet."
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr "Mb"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr "Keine Backups gefunden."
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr "Backup erstellen"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr "Backups entfernen"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr "Es werden 5.000 der ersten URLs aus Ihrer Liste importiert, der Rest kann erneut importiert werden."
|
||||
@@ -122,6 +204,14 @@ msgstr "Distill.io"
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ".XLSX & Wachete"
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr ""
|
||||
@@ -210,6 +300,16 @@ msgstr "Nachprüfzeit (Minuten)"
|
||||
msgid "Import"
|
||||
msgstr "IMPORT"
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr "Passwortschutz entfernt."
|
||||
@@ -295,6 +395,10 @@ msgstr "API"
|
||||
msgid "RSS"
|
||||
msgstr "RSS"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "Backups"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr "Uhrzeit und Datum"
|
||||
@@ -311,10 +415,6 @@ msgstr "Info"
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr "Standardmäßige Überprüfungszeit für alle Observationen, derzeitiges Systemminimum ist"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr "Sekunden"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr "Weitere Informationen"
|
||||
@@ -676,6 +776,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr "Python-Version:"
|
||||
@@ -935,10 +1039,6 @@ msgstr ""
|
||||
msgid "Incorrect confirmation text."
|
||||
msgstr "Falscher Bestätigungstext"
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
@@ -1565,6 +1665,10 @@ msgstr "Antwort vom Servertyp"
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr "Laden Sie den neuesten HTML-Snapshot herunter"
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr "Überwachung löschen?"
|
||||
@@ -1826,6 +1930,66 @@ msgstr "in '%(title)s'"
|
||||
msgid "Not yet"
|
||||
msgstr "Noch nicht"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr "Sekunden"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr "Bereits angemeldet"
|
||||
@@ -2927,6 +3091,18 @@ msgstr ""
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr ""
|
||||
@@ -3206,3 +3382,6 @@ msgstr "Haupteinstellungen"
|
||||
#~ msgid "Tip: You can also add 'shared' watches."
|
||||
#~ msgstr "Tipp: Sie können auch „gemeinsame“ Überwachungen hinzufügen."
|
||||
|
||||
#~ msgid "Marking watches as viewed in background..."
|
||||
#~ msgstr ""
|
||||
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: changedetection.io\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/dgtlmoon/changedetection.io\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: 2026-01-12 16:33+0100\n"
|
||||
"Last-Translator: British English Translation Team\n"
|
||||
"Language: en_GB\n"
|
||||
@@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -34,34 +34,116 @@ msgstr ""
|
||||
msgid "Backups were deleted."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr ""
|
||||
@@ -120,6 +202,14 @@ msgstr ""
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr ""
|
||||
@@ -204,6 +294,16 @@ msgstr ""
|
||||
msgid "Import"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr ""
|
||||
@@ -289,6 +389,10 @@ msgstr ""
|
||||
msgid "RSS"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr ""
|
||||
@@ -305,10 +409,6 @@ msgstr ""
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr ""
|
||||
@@ -662,6 +762,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr ""
|
||||
@@ -915,10 +1019,6 @@ msgstr ""
|
||||
msgid "Incorrect confirmation text."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
@@ -1523,6 +1623,10 @@ msgstr ""
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr ""
|
||||
@@ -1780,6 +1884,66 @@ msgstr ""
|
||||
msgid "Not yet"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr ""
|
||||
@@ -2874,6 +3038,18 @@ msgstr ""
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr ""
|
||||
@@ -3036,3 +3212,6 @@ msgstr ""
|
||||
#~ msgid "Tip: You can also add 'shared' watches."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Marking watches as viewed in background..."
|
||||
#~ msgstr ""
|
||||
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/dgtlmoon/changedetection.io\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: 2026-01-12 16:37+0100\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: en_US\n"
|
||||
@@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -34,34 +34,116 @@ msgstr ""
|
||||
msgid "Backups were deleted."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr ""
|
||||
@@ -120,6 +202,14 @@ msgstr ""
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr ""
|
||||
@@ -204,6 +294,16 @@ msgstr ""
|
||||
msgid "Import"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr ""
|
||||
@@ -289,6 +389,10 @@ msgstr ""
|
||||
msgid "RSS"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr ""
|
||||
@@ -305,10 +409,6 @@ msgstr ""
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr ""
|
||||
@@ -662,6 +762,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr ""
|
||||
@@ -915,10 +1019,6 @@ msgstr ""
|
||||
msgid "Incorrect confirmation text."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
@@ -1523,6 +1623,10 @@ msgstr ""
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr ""
|
||||
@@ -1780,6 +1884,66 @@ msgstr ""
|
||||
msgid "Not yet"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr ""
|
||||
@@ -2874,6 +3038,18 @@ msgstr ""
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr ""
|
||||
@@ -3036,3 +3212,6 @@ msgstr ""
|
||||
#~ msgid "Tip: You can also add 'shared' watches."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Marking watches as viewed in background..."
|
||||
#~ msgstr ""
|
||||
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: 2026-01-02 11:40+0100\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: fr\n"
|
||||
@@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -34,34 +34,116 @@ msgstr "Sauvegarde en cours de création en arrière-plan, revenez dans quelques
|
||||
msgid "Backups were deleted."
|
||||
msgstr "Les sauvegardes ont été supprimées."
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "SAUVEGARDES"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr "Une sauvegarde est en cours !"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr "Mo"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr "Aucune sauvegarde trouvée."
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr "Créer sauvegarde"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr "Supprimer sauvegardes"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr "Importation de 5 000 des premières URL de votre liste, le reste peut être importé à nouveau."
|
||||
@@ -122,6 +204,14 @@ msgstr "Distill.io"
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ".XLSX et Wachete"
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr ""
|
||||
@@ -206,6 +296,16 @@ msgstr "Temps de revérification (minutes)"
|
||||
msgid "Import"
|
||||
msgstr "IMPORTER"
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr ""
|
||||
@@ -291,6 +391,10 @@ msgstr "API"
|
||||
msgid "RSS"
|
||||
msgstr "RSS"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "SAUVEGARDES"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr "Heure et date"
|
||||
@@ -307,10 +411,6 @@ msgstr "Info"
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr "Heure de revérification par défaut pour tous les moniteurs, le minimum actuel du système est"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr "secondes"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr "Plus d'informations"
|
||||
@@ -666,6 +766,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr "Version Python :"
|
||||
@@ -919,10 +1023,6 @@ msgstr ""
|
||||
msgid "Incorrect confirmation text."
|
||||
msgstr "Aucune information"
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
@@ -1529,6 +1629,10 @@ msgstr "Réponse du type de serveur"
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr "Télécharger le dernier instantané HTML"
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr "Supprimer les montres ?"
|
||||
@@ -1786,6 +1890,66 @@ msgstr "dans '%(title)s'"
|
||||
msgid "Not yet"
|
||||
msgstr "Pas encore"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr "secondes"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr "Déjà connecté"
|
||||
@@ -2886,6 +3050,18 @@ msgstr ""
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr ""
|
||||
@@ -3099,3 +3275,6 @@ msgstr "Paramètres principaux"
|
||||
#~ msgid "Tip: You can also add 'shared' watches."
|
||||
#~ msgstr "Astuce : Vous pouvez également ajouter des montres « partagées »."
|
||||
|
||||
#~ msgid "Marking watches as viewed in background..."
|
||||
#~ msgstr ""
|
||||
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: 2026-01-02 15:32+0100\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: it\n"
|
||||
@@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -34,34 +34,116 @@ msgstr "Backup in creazione in background, riprova tra qualche minuto."
|
||||
msgid "Backups were deleted."
|
||||
msgstr "I backup sono stati eliminati."
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "Backup"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr "Un backup è in esecuzione!"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr "MB"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr "Nessun backup trovato."
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr "Crea backup"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr "Rimuovi backup"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr "Importazione delle prime 5.000 URL dalla tua lista, il resto può essere importato di nuovo."
|
||||
@@ -122,6 +204,14 @@ msgstr "Distill.io"
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ".XLSX & Wachete"
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr ""
|
||||
@@ -206,6 +296,16 @@ msgstr "Tempo di ricontrollo (minuti)"
|
||||
msgid "Import"
|
||||
msgstr "Importa"
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr ""
|
||||
@@ -291,6 +391,10 @@ msgstr "API"
|
||||
msgid "RSS"
|
||||
msgstr "RSS"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "Backup"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr "Data e ora"
|
||||
@@ -307,10 +411,6 @@ msgstr "Info"
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr "secondi"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr ""
|
||||
@@ -664,6 +764,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr ""
|
||||
@@ -917,10 +1021,6 @@ msgstr ""
|
||||
msgid "Incorrect confirmation text."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
@@ -1525,6 +1625,10 @@ msgstr ""
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr ""
|
||||
@@ -1782,6 +1886,66 @@ msgstr ""
|
||||
msgid "Not yet"
|
||||
msgstr "Non ancora"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr "secondi"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr "Già autenticato"
|
||||
@@ -2876,6 +3040,18 @@ msgstr ""
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr ""
|
||||
@@ -3071,3 +3247,6 @@ msgstr "Impostazioni principali"
|
||||
#~ msgid "Tip: You can also add 'shared' watches."
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Marking watches as viewed in background..."
|
||||
#~ msgstr ""
|
||||
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: 2026-01-02 11:40+0100\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: ko\n"
|
||||
@@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -34,34 +34,116 @@ msgstr ""
|
||||
msgid "Backups were deleted."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "백업"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr "백업이 실행 중입니다!"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr "MB"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr "백업을 찾을 수 없습니다."
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr "백업 생성"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr "백업 삭제"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr ""
|
||||
@@ -120,6 +202,14 @@ msgstr "Distill.io"
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ".XLSX 및 와체테"
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr ""
|
||||
@@ -204,6 +294,16 @@ msgstr "재확인 시간(분)"
|
||||
msgid "Import"
|
||||
msgstr "수입"
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr ""
|
||||
@@ -289,6 +389,10 @@ msgstr "API"
|
||||
msgid "RSS"
|
||||
msgstr "RSS"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "백업"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr "시간 및 날짜"
|
||||
@@ -305,10 +409,6 @@ msgstr "정보"
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr "모든 시계의 기본 재확인 시간, 현재 시스템 최소값은 다음과 같습니다."
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr "초"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr "추가 정보"
|
||||
@@ -662,6 +762,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr "파이썬 버전:"
|
||||
@@ -915,10 +1019,6 @@ msgstr ""
|
||||
msgid "Incorrect confirmation text."
|
||||
msgstr "잘못된 확인 텍스트."
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
@@ -1523,6 +1623,10 @@ msgstr "서버 유형 응답"
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr "최신 HTML 스냅샷 다운로드"
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr "시계를 삭제하시겠습니까?"
|
||||
@@ -1780,6 +1884,66 @@ msgstr "'%(title)s'에서"
|
||||
msgid "Not yet"
|
||||
msgstr "아직 아님"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr "초"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr ""
|
||||
@@ -2874,6 +3038,18 @@ msgstr ""
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr ""
|
||||
@@ -3192,3 +3368,6 @@ msgstr "기본 설정"
|
||||
#~ msgid "Tip: You can also add 'shared' watches."
|
||||
#~ msgstr "팁: '공유' 시계를 추가할 수도 있습니다."
|
||||
|
||||
#~ msgid "Marking watches as viewed in background..."
|
||||
#~ msgstr ""
|
||||
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: changedetection.io 0.52.9\n"
|
||||
"Project-Id-Version: changedetection.io 0.53.6\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -33,40 +33,121 @@ msgstr ""
|
||||
msgid "Backups were deleted."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
#, python-brace-format
|
||||
msgid "{} Imported from list in {:.2f}s, {} Skipped."
|
||||
msgstr ""
|
||||
|
||||
@@ -79,7 +160,6 @@ msgid "JSON structure looks invalid, was it broken?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
#, python-brace-format
|
||||
msgid "{} Imported from Distill.io in {:.2f}s, {} Skipped."
|
||||
msgstr ""
|
||||
|
||||
@@ -88,22 +168,18 @@ msgid "Unable to read export XLSX file, something wrong with the file?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
#, python-brace-format
|
||||
msgid "Error processing row number {}, URL value was incorrect, row was skipped."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
#, python-brace-format
|
||||
msgid "Error processing row number {}, check all cell data types are correct, row was skipped."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
#, python-brace-format
|
||||
msgid "{} imported from Wachete .xlsx in {:.2f}s"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
#, python-brace-format
|
||||
msgid "{} imported from custom .xlsx in {:.2f}s"
|
||||
msgstr ""
|
||||
|
||||
@@ -119,6 +195,14 @@ msgstr ""
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr ""
|
||||
@@ -203,17 +287,25 @@ msgstr ""
|
||||
msgid "Import"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "Warning: Worker count ({}) is close to or exceeds available CPU cores ({})"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "Worker count adjusted: {}"
|
||||
msgstr ""
|
||||
|
||||
@@ -222,7 +314,6 @@ msgid "Dynamic worker adjustment not supported for sync workers"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "Error adjusting workers: {}"
|
||||
msgstr ""
|
||||
|
||||
@@ -288,6 +379,10 @@ msgstr ""
|
||||
msgid "RSS"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr ""
|
||||
@@ -304,10 +399,6 @@ msgstr ""
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr ""
|
||||
@@ -661,6 +752,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr ""
|
||||
@@ -682,7 +777,6 @@ msgid "Clear Snapshot History"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/tags/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The tag \"{}\" already exists"
|
||||
msgstr ""
|
||||
|
||||
@@ -843,57 +937,46 @@ msgid "RSS Feed for this watch"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches deleted"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches paused"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches unpaused"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches updated"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches muted"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches un-muted"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches queued for rechecking"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches errors cleared"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches cleared/reset."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches set to use default notification settings"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "{} watches were tagged"
|
||||
msgstr ""
|
||||
|
||||
@@ -902,7 +985,6 @@ msgid "Watch not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "Cleared snapshot history for watch {}"
|
||||
msgstr ""
|
||||
|
||||
@@ -915,11 +997,6 @@ msgid "Incorrect confirmation text."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
msgstr ""
|
||||
|
||||
@@ -940,12 +1017,10 @@ msgid "Queued 1 watch for rechecking."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "Queued {} watches for rechecking ({} already queued or running)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "Queued {} watches for rechecking."
|
||||
msgstr ""
|
||||
|
||||
@@ -954,7 +1029,6 @@ msgid "Queueing watches for rechecking in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "Could not share, something went wrong while communicating with the share server - {}"
|
||||
msgstr ""
|
||||
|
||||
@@ -975,22 +1049,18 @@ msgid "No watches to edit"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/edit.py
|
||||
#, python-brace-format
|
||||
msgid "No watch with the UUID {} found."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/edit.py
|
||||
#, python-brace-format
|
||||
msgid "Switched to mode - {}."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/edit.py
|
||||
#, python-brace-format
|
||||
msgid "Could not load '{}' processor, processor plugin might be missing. Please select a different processor."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/edit.py
|
||||
#, python-brace-format
|
||||
msgid "Could not load '{}' processor, processor plugin might be missing."
|
||||
msgstr ""
|
||||
|
||||
@@ -1522,6 +1592,10 @@ msgstr ""
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr ""
|
||||
@@ -1571,7 +1645,6 @@ msgid "Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/views.py
|
||||
#, python-brace-format
|
||||
msgid "Warning, URL {} already exists"
|
||||
msgstr ""
|
||||
|
||||
@@ -1584,7 +1657,6 @@ msgid "Watch added."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/watchlist/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "displaying <b>{start} - {end}</b> {record_name} in total <b>{total}</b>"
|
||||
msgstr ""
|
||||
|
||||
@@ -1779,6 +1851,66 @@ msgstr ""
|
||||
msgid "Not yet"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr ""
|
||||
@@ -2325,12 +2457,10 @@ msgid "Not enough history to compare. Need at least 2 snapshots."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/processors/image_ssim_diff/difference.py
|
||||
#, python-brace-format
|
||||
msgid "Failed to load screenshots: {}"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/processors/image_ssim_diff/difference.py
|
||||
#, python-brace-format
|
||||
msgid "Failed to calculate diff: {}"
|
||||
msgstr ""
|
||||
|
||||
@@ -2456,7 +2586,6 @@ msgid "Detects all text changes where possible"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/store/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "Error fetching metadata for {}"
|
||||
msgstr ""
|
||||
|
||||
@@ -2465,7 +2594,6 @@ msgid "Watch protocol is not permitted or invalid URL format"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/store/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "Watch limit reached ({}/{} watches). Cannot add more watches."
|
||||
msgstr ""
|
||||
|
||||
@@ -2873,6 +3001,18 @@ msgstr ""
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: 2026-01-18 21:31+0800\n"
|
||||
"Last-Translator: 吾爱分享 <admin@wuaishare.cn>\n"
|
||||
"Language: zh\n"
|
||||
@@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -34,34 +34,116 @@ msgstr "备份正在后台生成,请几分钟后再查看。"
|
||||
msgid "Backups were deleted."
|
||||
msgstr "备份已删除。"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "备份"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr "备份正在运行!"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr "在此可下载并请求新的备份,备份完成后会在下方列表中显示。"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr "MB"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr "未找到备份。"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr "创建备份"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr "删除备份"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr "仅导入列表前 5,000 个 URL,其余可稍后继续导入。"
|
||||
@@ -120,6 +202,14 @@ msgstr "Distill.io"
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ".XLSX 与 Wachete"
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr "每行输入一个 URL,可在 URL 后用空格追加标签,标签以逗号 (,) 分隔:"
|
||||
@@ -204,6 +294,16 @@ msgstr "复检间隔(分钟)"
|
||||
msgid "Import"
|
||||
msgstr "导入"
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr "已移除密码保护。"
|
||||
@@ -289,6 +389,10 @@ msgstr "API"
|
||||
msgid "RSS"
|
||||
msgstr "RSS"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "备份"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr "时间与日期"
|
||||
@@ -305,10 +409,6 @@ msgstr "信息"
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr "所有监控项的默认复检间隔,当前系统最小值为"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr "秒"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr "更多信息"
|
||||
@@ -662,6 +762,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr "带认证的 SOCKS5 代理仅支持“明文请求”抓取器,其他抓取器请改为白名单 IP"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr "Python 版本:"
|
||||
@@ -915,10 +1019,6 @@ msgstr "历史清理已在后台开始"
|
||||
msgid "Incorrect confirmation text."
|
||||
msgstr "确认文本不正确。"
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr "正在后台将监控项标记为已读..."
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
@@ -1523,6 +1623,10 @@ msgstr "服务器类型响应"
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr "下载最新的 HTML 快照"
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr "删除监控项?"
|
||||
@@ -1780,6 +1884,66 @@ msgstr "(“%(title)s”中)"
|
||||
msgid "Not yet"
|
||||
msgstr "尚未"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr "秒"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr "已登录"
|
||||
@@ -2874,6 +3038,18 @@ msgstr "每行单独处理(可理解为每行都是“或”)"
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr "注意:使用正则时请用斜杠 / 包裹,例如:"
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr "匹配的文本会在文本快照中被忽略(仍可见但不会触发变更)"
|
||||
@@ -3021,3 +3197,6 @@ msgstr "主设置"
|
||||
#~ msgid "Tip: You can also add 'shared' watches."
|
||||
#~ msgstr "提示:你也可以添加“共享”的监控项。"
|
||||
|
||||
#~ msgid "Marking watches as viewed in background..."
|
||||
#~ msgstr "正在后台将监控项标记为已读..."
|
||||
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-02-05 17:47+0100\n"
|
||||
"POT-Creation-Date: 2026-02-23 03:54+0100\n"
|
||||
"PO-Revision-Date: 2026-01-15 12:00+0800\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: zh_Hant_TW\n"
|
||||
@@ -16,7 +16,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.17.0\n"
|
||||
"Generated-By: Babel 2.16.0\n"
|
||||
|
||||
#: changedetectionio/blueprint/backups/__init__.py
|
||||
msgid "A backup is already running, check back in a few minutes"
|
||||
@@ -34,34 +34,116 @@ msgstr "正在背景建立備份,請稍後再回來查看。"
|
||||
msgid "Backups were deleted."
|
||||
msgstr "備份已刪除。"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "備份"
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Backup zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Must be a .zip backup file!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include groups"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing groups of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Include watches"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Replace existing watches of the same UUID"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore backup"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "A restore is already running, check back in a few minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "No file uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "File must be a .zip backup file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Invalid or corrupted zip file"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/restore.py
|
||||
msgid "Restore started in background, check back in a few minutes."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "A backup is running!"
|
||||
msgstr "備份正在執行中!"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Here you can download and request a new backup, when a backup is completed you will see it listed below."
|
||||
msgstr "您可以在此下載並請求建立新備份,備份完成後將顯示於下方。"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Mb"
|
||||
msgstr "MB"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "No backups found."
|
||||
msgstr "找不到備份。"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Create backup"
|
||||
msgstr "建立備份"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/overview.html
|
||||
#: changedetectionio/blueprint/backups/templates/backup_create.html
|
||||
msgid "Remove backups"
|
||||
msgstr "移除備份"
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "A restore is running!"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Restore a backup. Must be a .zip backup file created on/after v0.53.1 (new database layout)."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Note: This does not override the main application settings, only watches and groups."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all groups found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing groups of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Include all watches found in backup?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/backups/templates/backup_restore.html
|
||||
msgid "Replace any existing watches of the same UUID?"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/importer.py
|
||||
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
|
||||
msgstr "正在匯入清單中的前 5,000 個 URL,其餘的可以再次匯入。"
|
||||
@@ -120,6 +202,14 @@ msgstr "Distill.io"
|
||||
msgid ".XLSX & Wachete"
|
||||
msgstr ".XLSX 和 Wachete"
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Restoring changedetection.io backups is in the"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "backups section"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/imports/templates/import.html
|
||||
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
|
||||
msgstr "每行輸入一個 URL,可選用空格分隔後為每個 URL 新增標籤,標籤間用逗號 (,) 分隔:"
|
||||
@@ -204,6 +294,16 @@ msgstr "複查時間(分鐘)"
|
||||
msgid "Import"
|
||||
msgstr "匯入"
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch with UUID %(uuid)s not found"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/rss/single_watch.py
|
||||
#, python-format
|
||||
msgid "Watch %(uuid)s does not have enough history snapshots to show changes (need at least 2)"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/__init__.py
|
||||
msgid "Password protection removed."
|
||||
msgstr "密碼保護已移除。"
|
||||
@@ -289,6 +389,10 @@ msgstr "API"
|
||||
msgid "RSS"
|
||||
msgstr "RSS"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Backups"
|
||||
msgstr "備份"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Time & Date"
|
||||
msgstr "時間與日期"
|
||||
@@ -305,10 +409,6 @@ msgstr "資訊"
|
||||
msgid "Default recheck time for all watches, current system minimum is"
|
||||
msgstr "所有監測任務的預設複查時間,目前系統最小值為"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "seconds"
|
||||
msgstr "秒"
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "more info"
|
||||
msgstr "更多資訊"
|
||||
@@ -662,6 +762,10 @@ msgid ""
|
||||
"whitelist the IP access instead"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Uptime:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html
|
||||
msgid "Python version:"
|
||||
msgstr "Python 版本:"
|
||||
@@ -915,10 +1019,6 @@ msgstr ""
|
||||
msgid "Incorrect confirmation text."
|
||||
msgstr "確認文字不正確。"
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
msgid "Marking watches as viewed in background..."
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/__init__.py
|
||||
#, python-brace-format
|
||||
msgid "The watch by UUID {} does not exist."
|
||||
@@ -1523,6 +1623,10 @@ msgstr "伺服器類型回應"
|
||||
msgid "Download latest HTML snapshot"
|
||||
msgstr "下載最新 HTML 快照"
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Download watch data package"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/ui/templates/edit.html
|
||||
msgid "Delete Watch?"
|
||||
msgstr "刪除監測任務?"
|
||||
@@ -1780,6 +1884,66 @@ msgstr "於 '%(title)s'"
|
||||
msgid "Not yet"
|
||||
msgstr "還沒有"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "0 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "year"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "years"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "month"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "months"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "week"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "day"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hour"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minute"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "second"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/blueprint/settings/templates/settings.html changedetectionio/flask_app.py
|
||||
msgid "seconds"
|
||||
msgstr "秒"
|
||||
|
||||
#: changedetectionio/flask_app.py
|
||||
msgid "Already logged in"
|
||||
msgstr "已經登入"
|
||||
@@ -2874,6 +3038,18 @@ msgstr ""
|
||||
msgid "Note: Wrap in forward slash / to use regex example:"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "You can also use"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "conditions"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "\"Page text\" - with Contains, Starts With, Not Contains and many more"
|
||||
msgstr ""
|
||||
|
||||
#: changedetectionio/templates/edit/text-options.html
|
||||
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
|
||||
msgstr ""
|
||||
@@ -3150,3 +3326,6 @@ msgstr "主設定"
|
||||
#~ msgid "Tip: You can also add 'shared' watches."
|
||||
#~ msgstr "提示:您也可以新增「共享」監測任務。"
|
||||
|
||||
#~ msgid "Marking watches as viewed in background..."
|
||||
#~ msgstr ""
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import ipaddress
|
||||
import socket
|
||||
from functools import lru_cache
|
||||
from loguru import logger
|
||||
from urllib.parse import urlparse, urlunparse, parse_qsl, urlencode
|
||||
@@ -56,6 +58,23 @@ def normalize_url_encoding(url):
|
||||
return url
|
||||
|
||||
|
||||
def is_private_hostname(hostname):
|
||||
"""Return True if hostname resolves to an IANA-restricted (private/reserved) IP address.
|
||||
|
||||
Fails closed: unresolvable hostnames return True (block them).
|
||||
Never cached — callers that need fresh DNS resolution (e.g. at fetch time) can call
|
||||
this directly without going through the lru_cached is_safe_valid_url().
|
||||
"""
|
||||
try:
|
||||
for info in socket.getaddrinfo(hostname, None):
|
||||
ip = ipaddress.ip_address(info[4][0])
|
||||
if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:
|
||||
return True
|
||||
except socket.gaierror:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@lru_cache(maxsize=10000)
|
||||
def is_safe_valid_url(test_url):
|
||||
from changedetectionio import strtobool
|
||||
@@ -119,4 +138,12 @@ def is_safe_valid_url(test_url):
|
||||
logger.warning(f'URL f"{test_url}" failed validation, aborting.')
|
||||
return False
|
||||
|
||||
# Block IANA-restricted (private/reserved) IP addresses unless explicitly allowed.
|
||||
# This is an add-time check; fetch-time re-validation in requests.py handles DNS rebinding.
|
||||
if not strtobool(os.getenv('ALLOW_IANA_RESTRICTED_ADDRESSES', 'false')):
|
||||
parsed = urlparse(test_url)
|
||||
if parsed.hostname and is_private_hostname(parsed.hostname):
|
||||
logger.warning(f'URL "{test_url}" resolves to a private/reserved IP address, aborting.')
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@@ -1,27 +1,21 @@
|
||||
# eventlet>=0.38.0 # Removed - replaced with threading mode for better Python 3.12+ compatibility
|
||||
feedgen~=1.0
|
||||
feedparser~=6.0 # For parsing RSS/Atom feeds
|
||||
flask-compress
|
||||
# 0.6.3 included compatibility fix for werkzeug 3.x (2.x had deprecation of url handlers)
|
||||
flask-login>=0.6.3
|
||||
flask-paginate
|
||||
flask_restful
|
||||
flask_cors # For the Chrome extension to operate
|
||||
# janus # No longer needed - using pure threading.Queue for multi-loop support
|
||||
flask_wtf~=1.2
|
||||
# Flask 3.1 removed the session setter on RequestContext; the patch in
|
||||
# changedetectionio/realtime/socket_server.py restores it so Flask-SocketIO works.
|
||||
# Require >=3.1 so the patch is always needed; <4 guards against unknown breaking changes.
|
||||
flask-socketio>=5.6.1,<6 # Re #3910
|
||||
flask>=3.1,<4
|
||||
# Flask-SocketIO 5.x still does ctx.session = ... directly; the patch above handles it.
|
||||
# >=5.5.0 ensures the threading async_mode we rely on is available.
|
||||
flask-socketio>=5.5.0,<6
|
||||
python-socketio>=5.11.0,<6
|
||||
python-engineio>=4.9.0,<5
|
||||
flask_cors # For the Chrome extension to operate
|
||||
flask_restful
|
||||
flask_wtf~=1.2
|
||||
inscriptis~=2.2
|
||||
python-engineio>=4.9.0,<5
|
||||
python-socketio>=5.11.0,<6
|
||||
pytz
|
||||
timeago~=1.0
|
||||
validators~=0.35
|
||||
werkzeug==3.1.6
|
||||
|
||||
|
||||
# Set these versions together to avoid a RequestsDependencyWarning
|
||||
# >= 2.26 also adds Brotli support if brotli is installed
|
||||
@@ -103,12 +97,8 @@ pytest ~=9.0
|
||||
pytest-flask ~=1.3
|
||||
pytest-mock ~=3.15
|
||||
|
||||
# Anything 4.0 and up but not 5.0
|
||||
jsonschema ~= 4.26
|
||||
|
||||
# OpenAPI validation support
|
||||
openapi-core[flask] >= 0.19.0
|
||||
|
||||
openapi-core[flask] ~= 0.22
|
||||
|
||||
loguru
|
||||
|
||||
@@ -130,8 +120,7 @@ greenlet >= 3.0.3
|
||||
# Default SOCKETIO_MODE=threading is recommended for better compatibility
|
||||
gevent
|
||||
|
||||
# Previously pinned for flask_expects_json (removed 2026-02). Unpinning for now.
|
||||
referencing
|
||||
referencing # Don't pin — jsonschema-path (required by openapi-core>=0.18) caps referencing<0.37.0, so pinning 0.37.0 forces openapi-core back to 0.17.2. Revisit once jsonschema-path>=0.3.5 relaxes the cap.
|
||||
|
||||
# For conditions
|
||||
panzi-json-logic
|
||||
|
||||
Reference in New Issue
Block a user