Compare commits

...

20 Commits

Author SHA1 Message Date
dgtlmoon
19144c07f7 Change deterministic fix 2026-01-17 16:04:19 +01:00
dgtlmoon
01e06979d8 Run "clear all history" in background thread to prevent blocking (#3765) 2026-01-17 15:34:21 +01:00
dgtlmoon
e45c77d51d Test - Adding missing test 2026-01-17 15:33:34 +01:00
dgtlmoon
bee1130c6e Important fix for possible wrong detection of changes under high-concurrency setups (many many fetch workers) 2026-01-17 14:45:23 +01:00
dgtlmoon
5f8448d0e2 Language updates (#3764) 2026-01-17 14:11:57 +01:00
dgtlmoon
9438d38dc6 Queues and Scheduler - No need to add imported items to the check queue, the scheduler will do this #3762 (#3763), CPU usage improvements.
* No need to add imported items to the check queue, the scheduler will do this #3762

* Tests - Faster recheck/reschedule loop under pytest environment

* More wait time under test

* Bunch up some tests a little

* fix typo

* woops

* If they want to queue one thats already running, thats up to them.

* WIP

* Fixing queue limit size

* Increase max queue size and many CPU performance fixes
2026-01-17 13:43:24 +01:00
dgtlmoon
d0c66758c2 UI - Fixing link to scheduler help/tutorial page.
Some checks failed
Build and push containers / metadata (push) Has been cancelled
Build and push containers / build-push-containers (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-10 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-11 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-12 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-13 (push) Has been cancelled
2026-01-16 19:14:29 +01:00
dgtlmoon
9e8a9d5907 Manual update of DE language (and recompile all languages) 2026-01-16 18:47:01 +01:00
dgtlmoon
7449be39fb Recompile CSS 2026-01-16 18:40:16 +01:00
dgtlmoon
e9f3d0bce4 UI - Mobile - Empty page watches message and layout improvements (#3760) 2026-01-16 17:59:52 +01:00
dgtlmoon
2abc8aa9b4 UI - CSS - Give dark-mode switching a soft transition 2026-01-16 17:45:33 +01:00
dgtlmoon
69b70a2a07 Edit - More reliable fetch of watch on test (usually affects tests) 2026-01-16 16:52:35 +01:00
吾爱分享
0c42bcb8d6 Manual polish for several translations in the zh locale. (#3757)
Some checks failed
Build and push containers / metadata (push) Has been cancelled
Build and push containers / build-push-containers (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-10 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-11 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-12 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-13 (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/amd64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/amd64 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v7 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v8 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (main) (push) Has been cancelled
2026-01-16 10:50:31 +01:00
dgtlmoon
091c708a28 Fix for old selenium 3 (#3748 #3756), however be sure to use selenium 4. 2026-01-16 10:30:26 +01:00
dgtlmoon
084be9c990 Languages - Recompile languages, small fix for 'de'. 2026-01-16 09:50:15 +01:00
dependabot[bot]
6db1085337 Bump elementpath from 5.0.4 to 5.1.0 (#3754) 2026-01-16 09:22:10 +01:00
吾爱分享
66553e106d Update zh translations with improved, consistent Simplified Chinese UI copy. (#3752) 2026-01-16 09:21:29 +01:00
dependabot[bot]
5b01dbd9f8 Bump apprise from 1.9.5 to 1.9.6 (#3753) 2026-01-16 09:09:02 +01:00
dgtlmoon
c86f214fc3 0.52.6
Some checks failed
Build and push containers / metadata (push) Has been cancelled
Build and push containers / build-push-containers (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-10 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-11 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-12 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-13 (push) Has been cancelled
2026-01-15 22:28:58 +01:00
dgtlmoon
32149640d9 Selenium fetcher - Small fix for #3748 RGB error on transparent screenshots or similar (#3749) 2026-01-15 20:56:53 +01:00
46 changed files with 3803 additions and 4155 deletions

View File

@@ -84,6 +84,7 @@ jobs:
docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_watch_model'
docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_jinja2_security'
docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_semver'
docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_html_to_text'
# Basic pytest tests with ancillary services
basic-tests:

View File

@@ -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.52.5'
__version__ = '0.52.6'
from changedetectionio.strtobool import strtobool
from json.decoder import JSONDecodeError

View File

@@ -438,7 +438,8 @@ class CreateWatch(Resource):
new_uuid = self.datastore.add_watch(url=url, extras=extras, tag=tags)
if new_uuid:
worker_handler.queue_item_async_safe(self.update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': new_uuid}))
# Dont queue because the scheduler will check that it hasnt been checked before anyway
# worker_handler.queue_item_async_safe(self.update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': new_uuid}))
return {'uuid': new_uuid}, 201
else:
return "Invalid or unsupported URL", 400

View File

@@ -8,6 +8,7 @@ from changedetectionio.flask_app import watch_check_update
import asyncio
import importlib
import os
import sys
import time
from loguru import logger
@@ -15,6 +16,9 @@ from loguru import logger
# Async version of update_worker
# Processes jobs from AsyncSignalPriorityQueue instead of threaded queue
IN_PYTEST = "pytest" in sys.modules or "PYTEST_CURRENT_TEST" in os.environ
DEFER_SLEEP_TIME_ALREADY_QUEUED = 0.3 if IN_PYTEST else 10.0
async def async_update_worker(worker_id, q, notification_q, app, datastore, executor=None):
"""
Async worker function that processes watch check jobs from the queue.
@@ -71,14 +75,13 @@ async def async_update_worker(worker_id, q, notification_q, app, datastore, exec
continue
uuid = queued_item_data.item.get('uuid')
# RACE CONDITION FIX: Check if this UUID is already being processed by another worker
from changedetectionio import worker_handler
from changedetectionio.queuedWatchMetaData import PrioritizedItem
if worker_handler.is_watch_running_by_another_worker(uuid, worker_id):
logger.trace(f"Worker {worker_id} detected UUID {uuid} already being processed by another worker - deferring")
# Sleep to avoid tight loop and give the other worker time to finish
await asyncio.sleep(10.0)
await asyncio.sleep(DEFER_SLEEP_TIME_ALREADY_QUEUED)
# Re-queue with lower priority so it gets checked again after current processing finishes
deferred_priority = max(1000, queued_item_data.priority * 10)

View File

@@ -1,13 +1,8 @@
from flask import Blueprint, request, redirect, url_for, flash, render_template
from loguru import logger
from changedetectionio.store import ChangeDetectionStore
from changedetectionio.auth_decorator import login_optionally_required
from changedetectionio import worker_handler
from changedetectionio.blueprint.imports.importer import (
import_url_list,
import_distill_io_json,
import_xlsx_wachete,
import_xlsx_custom
)
def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMetaData):
import_blueprint = Blueprint('imports', __name__, template_folder="templates")
@@ -17,15 +12,26 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
def import_page():
remaining_urls = []
from changedetectionio import forms
#
if request.method == 'POST':
# from changedetectionio import worker_handler
from changedetectionio.blueprint.imports.importer import (
import_url_list,
import_distill_io_json,
import_xlsx_wachete,
import_xlsx_custom
)
# URL List import
if request.values.get('urls') and len(request.values.get('urls').strip()):
# Import and push into the queue for immediate update check
importer_handler = import_url_list()
importer_handler.run(data=request.values.get('urls'), flash=flash, datastore=datastore, processor=request.values.get('processor', 'text_json_diff'))
for uuid in importer_handler.new_uuids:
worker_handler.queue_item_async_safe(update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': uuid}))
logger.debug(f"Imported {len(importer_handler.new_uuids)} new UUIDs")
# Dont' add to queue because scheduler can see that they haven't been checked and will add them to the queue
# for uuid in importer_handler.new_uuids:
# worker_handler.queue_item_async_safe(update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': uuid}))
if len(importer_handler.remaining_data) == 0:
return redirect(url_for('watchlist.index'))
@@ -37,8 +43,10 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
# Import and push into the queue for immediate update check
d_importer = import_distill_io_json()
d_importer.run(data=request.values.get('distill-io'), flash=flash, datastore=datastore)
for uuid in d_importer.new_uuids:
worker_handler.queue_item_async_safe(update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': uuid}))
# Dont' add to queue because scheduler can see that they haven't been checked and will add them to the queue
# for uuid in importer_handler.new_uuids:
# worker_handler.queue_item_async_safe(update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': uuid}))
# XLSX importer
if request.files and request.files.get('xlsx_file'):
@@ -60,8 +68,10 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
w_importer.import_profile = map
w_importer.run(data=file, flash=flash, datastore=datastore)
for uuid in w_importer.new_uuids:
worker_handler.queue_item_async_safe(update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': uuid}))
# Dont' add to queue because scheduler can see that they haven't been checked and will add them to the queue
# for uuid in importer_handler.new_uuids:
# worker_handler.queue_item_async_safe(update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': uuid}))
# Could be some remaining, or we could be on GET
form = forms.importForm(formdata=request.form if request.method == 'POST' else None)

View File

@@ -1,4 +1,5 @@
import time
import threading
from flask import Blueprint, request, redirect, url_for, flash, render_template, session
from flask_babel import gettext
from loguru import logger
@@ -151,9 +152,24 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, worker_handle
confirmtext = request.form.get('confirmtext')
if confirmtext == 'clear':
for uuid in datastore.data['watching'].keys():
datastore.clear_watch_history(uuid)
flash(gettext("Cleared snapshot history for all watches"))
# Run in background thread to avoid blocking
def clear_history_background():
# Capture UUIDs first to avoid race conditions
watch_uuids = list(datastore.data['watching'].keys())
logger.info(f"Background: Clearing history for {len(watch_uuids)} watches")
for uuid in watch_uuids:
try:
datastore.clear_watch_history(uuid)
except Exception as e:
logger.error(f"Error clearing history for watch {uuid}: {e}")
logger.info("Background: Completed clearing history")
# Start daemon thread
threading.Thread(target=clear_history_background, daemon=True).start()
flash(gettext("History clearing started in background"))
else:
flash(gettext('Incorrect confirmation text.'), 'error')
@@ -227,12 +243,9 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, worker_handle
i = 0
running_uuids = worker_handler.get_running_uuids()
if uuid:
if uuid not in running_uuids:
worker_handler.queue_item_async_safe(update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': uuid}))
i += 1
worker_handler.queue_item_async_safe(update_q, queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': uuid}))
i += 1
else:
# Recheck all, including muted
@@ -241,7 +254,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, worker_handle
watch_uuid = k[0]
watch = k[1]
if not watch['paused']:
if watch_uuid not in running_uuids:
if watch_uuid:
if with_errors and not watch.get('last_error'):
continue

View File

@@ -52,7 +52,13 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
redirect(url_for('ui_edit.edit_page', uuid=uuid))
# be sure we update with a copy instead of accidently editing the live object by reference
default = deepcopy(datastore.data['watching'][uuid])
default = None
while not default:
try:
default = deepcopy(datastore.data['watching'][uuid])
except RuntimeError as e:
# Dictionary changed
continue
# Defaults for proxy choice
if datastore.proxy_list is not None: # When enabled

View File

@@ -84,7 +84,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
app_rss_token=datastore.data['settings']['application'].get('rss_access_token'),
datastore=datastore,
errored_count=errored_count,
extra_classes='has-queue' if len(update_q.queue) else '',
extra_classes='has-queue' if not update_q.empty() else '',
form=form,
generate_tag_colors=processors.generate_processor_badge_colors,
guid=datastore.data['app_guid'],
@@ -95,8 +95,8 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
processor_badge_css=processors.get_processor_badge_css(),
processor_badge_texts=processors.get_processor_badge_texts(),
processor_descriptions=processors.get_processor_descriptions(),
queue_size=len(update_q.queue),
queued_uuids=[q_uuid.item['uuid'] for q_uuid in update_q.queue],
queue_size=update_q.qsize(),
queued_uuids=update_q.get_queued_uuids(),
search_q=request.args.get('q', '').strip(),
sort_attribute=request.args.get('sort') if request.args.get('sort') else request.cookies.get('sort'),
sort_order=request.args.get('order') if request.args.get('order') else request.cookies.get('order'),

View File

@@ -159,7 +159,7 @@ html[data-darkmode="true"] .watch-tag-list.tag-{{ class_name }} {
<tbody>
{%- if not watches|length -%}
<tr>
<td colspan="{{ cols_required }}" style="text-wrap: wrap;">{{ _('No website watches configured, please add a URL in the box above, or') }} <a href="{{ url_for('imports.import_page')}}" >{{ _('import a list') }}</a>.</td>
<td colspan="{{ cols_required }}" style="text-wrap: wrap;">{{ _('No web page change detection watches configured, please add a URL in the box above, or') }} <a href="{{ url_for('imports.import_page')}}" >{{ _('import a list') }}</a>.</td>
</tr>
{%- endif -%}

View File

@@ -156,6 +156,19 @@ class fetcher(Fetcher):
from PIL import Image
import io
img = Image.open(io.BytesIO(screenshot_png))
# Convert to RGB if needed (JPEG doesn't support transparency)
# Always convert non-RGB modes to RGB to ensure JPEG compatibility
if img.mode in ('RGBA', 'LA', 'P', 'PA'):
# Handle transparency by compositing onto white background
if img.mode == 'P':
img = img.convert('RGBA')
background = Image.new('RGB', img.size, (255, 255, 255))
if img.mode in ('RGBA', 'LA', 'PA'):
background.paste(img, mask=img.split()[-1]) # Use alpha channel as mask
img = background
elif img.mode != 'RGB':
# For other modes, direct conversion
img = img.convert('RGB')
jpeg_buffer = io.BytesIO()
img.save(jpeg_buffer, format='JPEG', quality=int(os.getenv("SCREENSHOT_QUALITY", 72)))
self.screenshot = jpeg_buffer.getvalue()

View File

@@ -27,9 +27,7 @@ from flask import (
session,
url_for,
)
from urllib.parse import urlparse
from flask_compress import Compress as FlaskCompress
from flask_login import current_user
from flask_restful import abort, Api
from flask_cors import CORS
@@ -46,6 +44,7 @@ from changedetectionio.api import Watch, WatchHistory, WatchSingleHistory, Watch
from changedetectionio.api.Search import Search
from .time_handler import is_within_schedule
from changedetectionio.languages import get_available_languages, get_language_codes, get_flag_for_locale, get_timeago_locale
IN_PYTEST = "pytest" in sys.modules or "PYTEST_CURRENT_TEST" in os.environ
datastore = None
@@ -56,7 +55,7 @@ extra_stylesheets = []
# Use bulletproof janus-based queues for sync/async reliability
update_q = RecheckPriorityQueue()
notification_q = NotificationQueue()
MAX_QUEUE_SIZE = 2000
MAX_QUEUE_SIZE = 5000
app = Flask(__name__,
static_url_path="",
@@ -979,6 +978,10 @@ def ticker_thread_check_time_launch_checks():
logger.debug(f"System env MINIMUM_SECONDS_RECHECK_TIME {recheck_time_minimum_seconds}")
# Workers are now started during app initialization, not here
WAIT_TIME_BETWEEN_LOOP = 1.0 if not IN_PYTEST else 0.01
if IN_PYTEST:
# The time between loops should be less than the first .sleep/wait in def wait_for_all_checks() of tests/util.py
logger.warning(f"Looks like we're in PYTEST! Setting time between searching for items to add to the queue to {WAIT_TIME_BETWEEN_LOOP}s")
while not app.config.exit.is_set():
@@ -1002,6 +1005,9 @@ def ticker_thread_check_time_launch_checks():
# Get a list of watches by UUID that are currently fetching data
running_uuids = worker_handler.get_running_uuids()
# Build set of queued UUIDs once for O(1) lookup instead of O(n) per watch
queued_uuids = {q_item.item['uuid'] for q_item in update_q.queue}
# Re #232 - Deepcopy the data incase it changes while we're iterating through it all
watch_uuid_list = []
while True:
@@ -1018,16 +1024,17 @@ def ticker_thread_check_time_launch_checks():
else:
break
# Re #438 - Don't place more watches in the queue to be checked if the queue is already large
while update_q.qsize() >= 2000:
logger.warning(f"Recheck watches queue size limit reached ({MAX_QUEUE_SIZE}), skipping adding more items")
app.config.exit.wait(10.0)
recheck_time_system_seconds = int(datastore.threshold_seconds)
# Check for watches outside of the time threshold to put in the thread queue.
for uuid in watch_uuid_list:
for watch_index, uuid in enumerate(watch_uuid_list):
# Re #438 - Check queue size every 100 watches for CPU efficiency (not every watch)
if watch_index % 100 == 0:
current_queue_size = update_q.qsize()
if current_queue_size >= MAX_QUEUE_SIZE:
logger.debug(f"Queue size limit reached ({current_queue_size}/{MAX_QUEUE_SIZE}), stopping scheduler this iteration.")
break
now = time.time()
watch = datastore.data['watching'].get(uuid)
if not watch:
@@ -1077,7 +1084,7 @@ def ticker_thread_check_time_launch_checks():
seconds_since_last_recheck = now - watch['last_checked']
if seconds_since_last_recheck >= (threshold + watch.jitter_seconds) and seconds_since_last_recheck >= recheck_time_minimum_seconds:
if not uuid in running_uuids and uuid not in [q_uuid.item['uuid'] for q_uuid in update_q.queue]:
if not uuid in running_uuids and uuid not in queued_uuids:
# Proxies can be set to have a limit on seconds between which they can be called
watch_proxy = datastore.get_preferred_proxy_for_watch(uuid=uuid)
@@ -1120,4 +1127,4 @@ def ticker_thread_check_time_launch_checks():
watch.jitter_seconds = 0
# Should be low so we can break this out in testing
app.config.exit.wait(1)
app.config.exit.wait(WAIT_TIME_BETWEEN_LOOP)

View File

@@ -539,6 +539,18 @@ def cdata_in_document_to_text(html_content: str, render_anchor_tag_content=False
def html_to_text(html_content: str, render_anchor_tag_content=False, is_rss=False, timeout=10) -> str:
"""
Convert HTML content to plain text using inscriptis.
Thread-Safety: This function uses inscriptis.get_text() which internally calls
lxml.html.fromstring() with the default parser. Testing with 50 concurrent threads
confirms this approach is thread-safe and produces deterministic output.
Alternative Approach Rejected: An explicit HTMLParser instance (thread-local or fresh)
would also be thread-safe, but was found to break change detection logic in subtle ways
(test_check_basic_change_detection_functionality). The default parser provides correct
and reliable behavior.
"""
from inscriptis import get_text
from inscriptis.model.config import ParserConfig

View File

@@ -176,7 +176,16 @@ class RecheckPriorityQueue:
def empty(self) -> bool:
"""Check if queue is empty"""
return self.qsize() == 0
def get_queued_uuids(self) -> list:
"""Get list of all queued UUIDs efficiently with single lock"""
try:
with self._lock:
return [item.item['uuid'] for item in self._priority_items if hasattr(item, 'item') and 'uuid' in item.item]
except Exception as e:
logger.critical(f"CRITICAL: Failed to get queued UUIDs: {str(e)}")
return []
def close(self):
"""Close the janus queue"""
try:

View File

@@ -150,11 +150,8 @@ def handle_watch_update(socketio, **kwargs):
# Get list of watches that are currently running
running_uuids = worker_handler.get_running_uuids()
# Get list of watches in the queue
queue_list = []
for q_item in update_q.queue:
if hasattr(q_item, 'item') and 'uuid' in q_item.item:
queue_list.append(q_item.item['uuid'])
# Get list of watches in the queue (efficient single-lock method)
queue_list = update_q.get_queued_uuids()
# Get the error texts from the watch
error_texts = watch.compile_error_texts()

View File

@@ -82,20 +82,14 @@ echo "RUNNING WITH BASE_URL SET"
# Re #65 - Ability to include a link back to the installation, in the notification.
export BASE_URL="https://really-unique-domain.io"
REMOVE_REQUESTS_OLD_SCREENSHOTS=false pytest -vv -s --maxfail=1 tests/test_notification.py
# Re-run with HIDE_REFERER set - could affect login
export HIDE_REFERER=True
pytest -vv -s --maxfail=1 tests/test_access_control.py
REMOVE_REQUESTS_OLD_SCREENSHOTS=false pytest -vv -s --maxfail=1 tests/test_notification.py tests/test_access_control.py
# Re-run a few tests that will trigger brotli based storage
export SNAPSHOT_BROTLI_COMPRESSION_THRESHOLD=5
pytest -vv -s --maxfail=1 tests/test_access_control.py
REMOVE_REQUESTS_OLD_SCREENSHOTS=false pytest tests/test_notification.py
pytest -vv -s --maxfail=1 tests/test_backend.py
pytest -vv -s --maxfail=1 tests/test_rss.py
pytest -vv -s --maxfail=1 tests/test_unique_lines.py
# And again with brotli+screenshot attachment
SNAPSHOT_BROTLI_COMPRESSION_THRESHOLD=5 REMOVE_REQUESTS_OLD_SCREENSHOTS=false pytest -vv -s --maxfail=1 --dist=load tests/test_backend.py tests/test_rss.py tests/test_unique_lines.py tests/test_notification.py tests/test_access_control.py
# Try high concurrency
FETCH_WORKERS=50 pytest tests/test_history_consistency.py -vv -l -s

View File

@@ -1 +1 @@
.comparison-score{padding:1em;background:var(--color-table-stripe);border-radius:4px;margin:1em 0;border:1px solid var(--color-border-table-cell);color:var(--color-text)}.change-detected{color:#d32f2f;font-weight:bold}.no-change{color:#388e3c;font-weight:bold}.comparison-grid{display:grid;grid-template-columns:1fr 1fr;gap:1em;margin:1em 1em}@media(max-width: 1200px){.comparison-grid{grid-template-columns:1fr}}.image-comparison{position:relative;width:100%;overflow:hidden;border:1px solid var(--color-border-table-cell);box-shadow:0 2px 4px rgba(0,0,0,.1);user-select:none}.image-comparison img{display:block;width:100%;height:auto;max-width:100%;border:none;box-shadow:none}.comparison-image-wrapper{position:relative;width:100%;display:flex;align-items:flex-start;justify-content:center;background-color:var(--color-background);background-image:linear-gradient(45deg, var(--color-table-stripe) 25%, transparent 25%),linear-gradient(-45deg, var(--color-table-stripe) 25%, transparent 25%),linear-gradient(45deg, transparent 75%, var(--color-table-stripe) 75%),linear-gradient(-45deg, transparent 75%, var(--color-table-stripe) 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px}.comparison-after{position:absolute;top:0;left:0;width:100%;height:100%;clip-path:inset(0 0 0 50%)}.comparison-slider{position:absolute;top:0;left:50%;width:4px;height:100%;background:#0078e7;cursor:ew-resize;transform:translateX(-2px);z-index:10}.comparison-handle{position:absolute;top:50%;left:50%;width:48px;height:48px;background:#0078e7;border:3px solid #fff;border-radius:50%;transform:translate(-50%, -50%);box-shadow:0 2px 8px rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;cursor:ew-resize;transition:top .1s ease-out}.comparison-handle::after{content:"⇄";color:#fff;font-size:24px;font-weight:bold;pointer-events:none}.comparison-labels{position:absolute;top:10px;width:100%;display:flex;justify-content:space-between;padding:0 0px;z-index:5;pointer-events:none}.comparison-label{background:rgba(0,0,0,.7);color:#fff;padding:.5em 1em;border-radius:4px;font-size:.9em;font-weight:bold}.screenshot-panel{text-align:center;background:var(--color-background);border:1px solid var(--color-border-table-cell);border-radius:4px;padding:1em;box-shadow:0 2px 4px rgba(0,0,0,.05)}.screenshot-panel h3{margin:0 0 1em 0;font-size:1.1em;color:var(--color-text);border-bottom:2px solid var(--color-background-button-primary);padding-bottom:.5em}.screenshot-panel.diff h3{border-bottom-color:#d32f2f}.screenshot-panel img{max-width:100%;height:auto;border:1px solid var(--color-border-table-cell);box-shadow:0 2px 4px rgba(0,0,0,.1)}.version-selector{display:inline-block;margin:0 .5em}.version-selector label{font-weight:bold;margin-right:.5em;color:var(--color-text)}#settings{background:var(--color-background);padding:1.5em;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,.05);margin-bottom:2em;border:1px solid var(--color-border-table-cell)}#settings h2{margin-top:0;color:var(--color-text)}.diff-fieldset{border:none;padding:0;margin:0}.edit-link{float:right;margin-top:-0.5em}.comparison-description{color:var(--color-text-input-description);font-size:.9em;margin-bottom:1em}.download-link{color:var(--color-link);text-decoration:none;display:inline-flex;align-items:center;gap:.3em;font-size:.85em}.download-link:hover{text-decoration:underline}.diff-section-header{color:#d32f2f;font-size:.9em;margin-bottom:1em;font-weight:bold;display:flex;align-items:center;justify-content:center;gap:1em}.comparison-history-section{margin-top:3em;padding:1em;background:var(--color-background);border:1px solid var(--color-border-table-cell);border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,.05)}.comparison-history-section h3{color:var(--color-text)}.comparison-history-section p{color:var(--color-text-input-description);font-size:.9em}.history-changed-yes{color:#d32f2f;font-weight:bold}.history-changed-no{color:#388e3c}
.comparison-score{padding:1em;background:var(--color-table-stripe);border-radius:4px;margin:1em 0;border:1px solid var(--color-border-table-cell);color:var(--color-text)}.change-detected{color:#d32f2f;font-weight:bold}.no-change{color:#388e3c;font-weight:bold}.comparison-grid{display:grid;grid-template-columns:1fr 1fr;gap:1em;margin:1em 1em}@media(max-width: 1200px){.comparison-grid{grid-template-columns:1fr}}.image-comparison{position:relative;width:100%;overflow:hidden;border:1px solid var(--color-border-table-cell);box-shadow:0 2px 4px rgba(0, 0, 0, 0.1);user-select:none}.image-comparison img{display:block;width:100%;height:auto;max-width:100%;border:none;box-shadow:none}.comparison-image-wrapper{position:relative;width:100%;display:flex;align-items:flex-start;justify-content:center;background-color:var(--color-background);background-image:linear-gradient(45deg, var(--color-table-stripe) 25%, transparent 25%),linear-gradient(-45deg, var(--color-table-stripe) 25%, transparent 25%),linear-gradient(45deg, transparent 75%, var(--color-table-stripe) 75%),linear-gradient(-45deg, transparent 75%, var(--color-table-stripe) 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px}.comparison-after{position:absolute;top:0;left:0;width:100%;height:100%;clip-path:inset(0 0 0 50%)}.comparison-slider{position:absolute;top:0;left:50%;width:4px;height:100%;background:#0078e7;cursor:ew-resize;transform:translateX(-2px);z-index:10}.comparison-handle{position:absolute;top:50%;left:50%;width:48px;height:48px;background:#0078e7;border:3px solid #fff;border-radius:50%;transform:translate(-50%, -50%);box-shadow:0 2px 8px rgba(0, 0, 0, 0.3);display:flex;align-items:center;justify-content:center;cursor:ew-resize;transition:top .1s ease-out}.comparison-handle::after{content:"⇄";color:#fff;font-size:24px;font-weight:bold;pointer-events:none}.comparison-labels{position:absolute;top:10px;width:100%;display:flex;justify-content:space-between;padding:0 0px;z-index:5;pointer-events:none}.comparison-label{background:rgba(0, 0, 0, 0.7);color:#fff;padding:.5em 1em;border-radius:4px;font-size:.9em;font-weight:bold}.screenshot-panel{text-align:center;background:var(--color-background);border:1px solid var(--color-border-table-cell);border-radius:4px;padding:1em;box-shadow:0 2px 4px rgba(0, 0, 0, 0.05)}.screenshot-panel h3{margin:0 0 1em 0;font-size:1.1em;color:var(--color-text);border-bottom:2px solid var(--color-background-button-primary);padding-bottom:.5em}.screenshot-panel.diff h3{border-bottom-color:#d32f2f}.screenshot-panel img{max-width:100%;height:auto;border:1px solid var(--color-border-table-cell);box-shadow:0 2px 4px rgba(0, 0, 0, 0.1)}.version-selector{display:inline-block;margin:0 .5em}.version-selector label{font-weight:bold;margin-right:.5em;color:var(--color-text)}#settings{background:var(--color-background);padding:1.5em;border-radius:4px;box-shadow:0 2px 4px rgba(0, 0, 0, 0.05);margin-bottom:2em;border:1px solid var(--color-border-table-cell)}#settings h2{margin-top:0;color:var(--color-text)}.diff-fieldset{border:none;padding:0;margin:0}.edit-link{float:right;margin-top:-0.5em}.comparison-description{color:var(--color-text-input-description);font-size:.9em;margin-bottom:1em}.download-link{color:var(--color-link);text-decoration:none;display:inline-flex;align-items:center;gap:.3em;font-size:.85em}.download-link:hover{text-decoration:underline}.diff-section-header{color:#d32f2f;font-size:.9em;margin-bottom:1em;font-weight:bold;display:flex;align-items:center;justify-content:center;gap:1em}.comparison-history-section{margin-top:3em;padding:1em;background:var(--color-background);border:1px solid var(--color-border-table-cell);border-radius:4px;box-shadow:0 2px 4px rgba(0, 0, 0, 0.05)}.comparison-history-section h3{color:var(--color-text)}.comparison-history-section p{color:var(--color-text-input-description);font-size:.9em}.history-changed-yes{color:#d32f2f;font-weight:bold}.history-changed-no{color:#388e3c}

View File

@@ -1 +1 @@
#diff-form{background:rgba(0,0,0,.05);padding:1em;border-radius:10px;margin-bottom:1em;color:#fff;font-size:.9rem;text-align:center}#diff-form label.from-to-label{width:4rem;text-decoration:none;padding:.5rem}#diff-form label.from-to-label#change-from{color:#b30000;background:#fadad7}#diff-form label.from-to-label#change-to{background:#eaf2c2;color:#406619}#diff-form #diff-style>span{display:inline-block;padding:.3em}#diff-form #diff-style>span label{font-weight:normal}#diff-form *{vertical-align:middle}body.difference-page section.content{padding-top:40px}#diff-ui{background:var(--color-background);padding:1rem;border-radius:5px}@media(min-width: 767px){#diff-ui{min-width:50%}}#diff-ui #text{font-size:11px}#diff-ui pre{white-space:break-spaces}#diff-ui h1{display:inline;font-size:100%}#diff-ui #result{white-space:pre-wrap;word-break:break-word;overflow-wrap:break-word}#diff-ui .source{position:absolute;right:1%;top:.2em}@-moz-document url-prefix(){#diff-ui body{height:99%}}#diff-ui td#diff-col div{text-align:justify;white-space:pre-wrap}#diff-ui .ignored{background-color:#ccc;opacity:.7}#diff-ui .triggered{background-color:#1b98f8}#diff-ui .ignored.triggered{background-color:red}#diff-ui .tab-pane-inner#screenshot{text-align:center}#diff-ui .tab-pane-inner#screenshot img{max-width:99%}#diff-ui .pure-form button.reset-margin{margin:0px}#diff-ui .diff-fieldset{display:flex;align-items:center;gap:4px;flex-wrap:wrap}#diff-ui ul#highlightSnippetActions{list-style-type:none;display:flex;align-items:center;justify-content:center;gap:1.5rem;flex-wrap:wrap;padding:0;margin:0}#diff-ui ul#highlightSnippetActions li{display:flex;flex-direction:column;align-items:center;text-align:center;padding:.5rem;gap:.3rem}#diff-ui ul#highlightSnippetActions li button,#diff-ui ul#highlightSnippetActions li a{white-space:nowrap}#diff-ui ul#highlightSnippetActions span{font-size:.8rem;color:var(--color-text-input-description)}#diff-ui #cell-diff-jump-visualiser{display:flex;flex-direction:row;gap:1px;background:var(--color-background);border-radius:3px;overflow-x:hidden;position:sticky;top:0;z-index:10;padding-top:1rem;padding-bottom:1rem;justify-content:center}#diff-ui #cell-diff-jump-visualiser>div{flex:1;min-width:1px;max-width:10px;height:10px;background:var(--color-background-button-cancel);opacity:.3;border-radius:1px;transition:opacity .2s;position:relative}#diff-ui #cell-diff-jump-visualiser>div.deletion{background:#b30000;opacity:1}#diff-ui #cell-diff-jump-visualiser>div.insertion{background:#406619;opacity:1}#diff-ui #cell-diff-jump-visualiser>div.note{background:#406619;opacity:1}#diff-ui #cell-diff-jump-visualiser>div.mixed{background:linear-gradient(to right, #b30000 50%, #406619 50%);opacity:1}#diff-ui #cell-diff-jump-visualiser>div.current-position::after{content:"";position:absolute;bottom:-6px;left:50%;transform:translateX(-50%);width:0;height:0;border-left:4px solid rgba(0,0,0,0);border-right:4px solid rgba(0,0,0,0);border-bottom:4px solid var(--color-text)}#diff-ui #cell-diff-jump-visualiser>div:hover{opacity:.8;cursor:pointer}#text-diff-heading-area .snapshot-age{padding:4px;margin:.5rem 0;background-color:var(--color-background-snapshot-age);border-radius:3px;font-weight:bold;margin-bottom:4px}#text-diff-heading-area .snapshot-age.error{background-color:var(--color-error-background-snapshot-age);color:var(--color-error-text-snapshot-age)}#text-diff-heading-area .snapshot-age>*{padding-right:1rem}
#diff-form{background:rgba(0, 0, 0, 0.05);padding:1em;border-radius:10px;margin-bottom:1em;color:#fff;font-size:.9rem;text-align:center}#diff-form label.from-to-label{width:4rem;text-decoration:none;padding:.5rem}#diff-form label.from-to-label#change-from{color:#b30000;background:#fadad7}#diff-form label.from-to-label#change-to{background:#eaf2c2;color:#406619}#diff-form #diff-style>span{display:inline-block;padding:.3em}#diff-form #diff-style>span label{font-weight:normal}#diff-form *{vertical-align:middle}body.difference-page section.content{padding-top:40px}#diff-ui{background:var(--color-background);padding:1rem;border-radius:5px}@media(min-width: 767px){#diff-ui{min-width:50%}}#diff-ui #text{font-size:11px}#diff-ui pre{white-space:break-spaces}#diff-ui h1{display:inline;font-size:100%}#diff-ui #result{white-space:pre-wrap;word-break:break-word;overflow-wrap:break-word}#diff-ui .source{position:absolute;right:1%;top:.2em}@-moz-document url-prefix(){#diff-ui body{height:99%}}#diff-ui td#diff-col div{text-align:justify;white-space:pre-wrap}#diff-ui .ignored{background-color:#ccc;opacity:.7}#diff-ui .triggered{background-color:#1b98f8}#diff-ui .ignored.triggered{background-color:red}#diff-ui .tab-pane-inner#screenshot{text-align:center}#diff-ui .tab-pane-inner#screenshot img{max-width:99%}#diff-ui .pure-form button.reset-margin{margin:0px}#diff-ui .diff-fieldset{display:flex;align-items:center;gap:4px;flex-wrap:wrap}#diff-ui ul#highlightSnippetActions{list-style-type:none;display:flex;align-items:center;justify-content:center;gap:1.5rem;flex-wrap:wrap;padding:0;margin:0}#diff-ui ul#highlightSnippetActions li{display:flex;flex-direction:column;align-items:center;text-align:center;padding:.5rem;gap:.3rem}#diff-ui ul#highlightSnippetActions li button,#diff-ui ul#highlightSnippetActions li a{white-space:nowrap}#diff-ui ul#highlightSnippetActions span{font-size:.8rem;color:var(--color-text-input-description)}#diff-ui #cell-diff-jump-visualiser{display:flex;flex-direction:row;gap:1px;background:var(--color-background);border-radius:3px;overflow-x:hidden;position:sticky;top:0;z-index:10;padding-top:1rem;padding-bottom:1rem;justify-content:center}#diff-ui #cell-diff-jump-visualiser>div{flex:1;min-width:1px;max-width:10px;height:10px;background:var(--color-background-button-cancel);opacity:.3;border-radius:1px;transition:opacity .2s;position:relative}#diff-ui #cell-diff-jump-visualiser>div.deletion{background:#b30000;opacity:1}#diff-ui #cell-diff-jump-visualiser>div.insertion{background:#406619;opacity:1}#diff-ui #cell-diff-jump-visualiser>div.note{background:#406619;opacity:1}#diff-ui #cell-diff-jump-visualiser>div.mixed{background:linear-gradient(to right, #b30000 50%, #406619 50%);opacity:1}#diff-ui #cell-diff-jump-visualiser>div.current-position::after{content:"";position:absolute;bottom:-6px;left:50%;transform:translateX(-50%);width:0;height:0;border-left:4px solid rgba(0, 0, 0, 0);border-right:4px solid rgba(0, 0, 0, 0);border-bottom:4px solid var(--color-text)}#diff-ui #cell-diff-jump-visualiser>div:hover{opacity:.8;cursor:pointer}#text-diff-heading-area .snapshot-age{padding:4px;margin:.5rem 0;background-color:var(--color-background-snapshot-age);border-radius:3px;font-weight:bold;margin-bottom:4px}#text-diff-heading-area .snapshot-age.error{background-color:var(--color-error-background-snapshot-age);color:var(--color-error-text-snapshot-age)}#text-diff-heading-area .snapshot-age>*{padding-right:1rem}

View File

@@ -125,6 +125,11 @@ $grid-gap: 0.5rem;
border-bottom: none;
}
// Empty state message - span full width on mobile
> td[colspan] {
grid-column: 1 / -1;
}
> td.title-col {
grid-column: 1 / -1;
grid-row: 1;

View File

@@ -33,6 +33,31 @@
@use "parts/login_form";
@use "parts/tabs";
// Smooth transitions for theme switching
body,
.pure-table,
.pure-table thead,
.pure-table td,
.pure-table th,
.pure-form input,
.pure-form textarea,
.pure-form select,
.edit-form .inner,
.pure-menu-horizontal,
footer,
.sticky-tab,
#diff-jump,
.button-tag,
#new-watch-form,
#new-watch-form input:not(.pure-button),
code,
.messages li,
#checkbox-operations,
.inline-warning,
a,
.watch-controls img {
transition: color 0.4s ease, background-color 0.4s ease, background 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
}
body {
color: var(--color-text);

File diff suppressed because one or more lines are too long

View File

@@ -8,16 +8,15 @@
<span class="pure-form-message-inline">
Body for all notifications &dash; You can use <a target="newwindow" href="https://jinja.palletsprojects.com/en/3.0.x/templates/">Jinja2</a> templating in the notification title, body and URL, and tokens from below.
</span><br>
<div data-target="#notification-tokens-info{{ suffix }}" class="toggle-show pure-button button-tag button-xsmall">Show
token/placeholders
<div data-target="#notification-tokens-info{{ suffix }}" class="toggle-show pure-button button-tag button-xsmall">{{ _('Show token/placeholders') }}
</div>
</div>
<div class="pure-controls" style="display: none;" id="notification-tokens-info{{ suffix }}">
<table class="pure-table" id="token-table">
<thead>
<tr>
<th>Token</th>
<th>Description</th>
<th>{{ _('Token') }}</th>
<th>{{ _('Description') }}</th>
</tr>
</thead>
<tbody>
@@ -126,7 +125,7 @@
<p>
<strong>Tip:</strong> Use <a target="newwindow" href="https://github.com/caronc/apprise">AppRise Notification URLs</a> for notification to just about any service! <i><a target="newwindow" href="https://github.com/dgtlmoon/changedetection.io/wiki/Notification-configuration-notes">Please read the notification services wiki here for important configuration notes</a></i>.<br>
</p>
<div data-target="#advanced-help-notifications" class="toggle-show pure-button button-tag button-xsmall">Show advanced help and tips</div>
<div data-target="#advanced-help-notifications" class="toggle-show pure-button button-tag button-xsmall">{{ _('Show advanced help and tips') }}</div>
<ul style="display: none" id="advanced-help-notifications">
<li><code><a target="newwindow" href="https://github.com/caronc/apprise/wiki/Notify_discord">discord://</a></code> (or <code>https://discord.com/api/webhooks...</code>)) only supports a maximum <strong>2,000 characters</strong> of notification text, including the title.</li>
<li><code><a target="newwindow" href="https://github.com/caronc/apprise/wiki/Notify_telegram">tgram://</a></code> bots can't send messages to other bots, so you should specify chat ID of non-bot user.</li>
@@ -136,20 +135,20 @@
</ul>
</div>
<div class="notifications-wrapper">
<a id="send-test-notification" class="pure-button button-secondary button-xsmall" >Send test notification</a> <div class="spinner" style="display: none;"></div>
<a id="send-test-notification" class="pure-button button-secondary button-xsmall" >{{ _('Send test notification') }}</a> <div class="spinner" style="display: none;"></div>
{% if emailprefix %}
<a id="add-email-helper" class="pure-button button-secondary button-xsmall" >Add email <img style="height: 1em; display: inline-block" src="{{url_for('static_content', group='images', filename='email.svg')}}" alt="Add an email address"> </a>
<a id="add-email-helper" class="pure-button button-secondary button-xsmall" >{{ _('Add email') }} <img style="height: 1em; display: inline-block" src="{{url_for('static_content', group='images', filename='email.svg')}}" alt="{{ _('Add an email address') }}"> </a>
{% endif %}
<a href="{{url_for('settings.notification_logs')}}" class="pure-button button-secondary button-xsmall" >Notification debug logs</a>
<a href="{{url_for('settings.notification_logs')}}" class="pure-button button-secondary button-xsmall" >{{ _('Notification debug logs') }}</a>
<br>
<div id="notification-test-log" style="display: none;"><span class="pure-form-message-inline">Processing..</span></div>
<div id="notification-test-log" style="display: none;"><span class="pure-form-message-inline">{{ _('Processing..') }}</span></div>
</div>
</div>
<div class="pure-control-group grey-form-border">
<div class="pure-control-group">
{{ render_field(form.notification_title, class="m-d notification-title", placeholder=settings_application['notification_title']) }}
<span class="pure-form-message-inline">Title for all notifications</span>
<span class="pure-form-message-inline">{{ _('Title for all notifications') }}</span>
</div>
<div class="pure-control-group">
{{ render_field(form.notification_body , rows=5, class="notification-body", placeholder=settings_application['notification_body']) }}
@@ -174,7 +173,7 @@
</div>
<div class="">
{{ render_field(form.notification_format , class="notification-format") }}
<span class="pure-form-message-inline">Format for all notifications</span>
<span class="pure-form-message-inline">{{ _('Format for all notifications') }}</span>
</div>
</div>
{% endmacro %}

View File

@@ -267,7 +267,7 @@
</ul>
<br>
<span class="pure-form-message-inline">
<a href="https://changedetection.io/tutorials">{{ _('More help and examples about using the scheduler') }}</a>
<a href="https://changedetection.io/tutorial/checking-web-pages-changes-according-schedule">{{ _('More help and examples about using the scheduler') }}</a>
</span>
</div>
{% else %}

View File

@@ -6,10 +6,10 @@
") }}
<span class="pure-form-message-inline">
<ul>
<li>Text to wait for before triggering a change/notification, all text and regex are tested <i>case-insensitive</i>.</li>
<li>Trigger text is processed from the result-text that comes out of any CSS/JSON Filters for this watch</li>
<li>Each line is processed separately (think of each line as "OR")</li>
<li>Note: Wrap in forward slash / to use regex example: <code>/foo\d/</code></li>
<li>{{ _('Text to wait for before triggering a change/notification, all text and regex are tested case-insensitive.') }}</li>
<li>{{ _('Trigger text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor') }}</li>
<li>{{ _('Each line is processed separately (think of each line as "OR")') }}</li>
<li>{{ _('Note: Wrap in forward slash / to use regex example:') }} <code>/foo\d/</code></li>
</ul>
</span>
</div>
@@ -20,10 +20,10 @@
") }}
<span class="pure-form-message-inline">
<ul>
<li>Matching text will be <strong>ignored</strong> in the text snapshot (you can still see it but it wont trigger a change)</li>
<li>Each line processed separately, any line matching will be ignored (removed before creating the checksum)</li>
<li>Regular Expression support, wrap the entire line in forward slash <code>/regex/</code></li>
<li>Changing this will affect the comparison checksum which may trigger an alert</li>
<li>{{ _('Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)') }}</li>
<li>{{ _('Each line processed separately, any line matching will be ignored (removed before creating the checksum)') }}</li>
<li>{{ _('Regular Expression support, wrap the entire line in forward slash') }} <code>/regex/</code></li>
<li>{{ _('Changing this will affect the comparison checksum which may trigger an alert') }}</li>
</ul>
</span>
<br><br>
@@ -40,10 +40,10 @@ Not in stock
Unavailable") }}
<span class="pure-form-message-inline">
<ul>
<li>Block change-detection while this text is on the page, all text and regex are tested <i>case-insensitive</i>, good for waiting for when a product is available again</li>
<li>Block text is processed from the result-text that comes out of any CSS/JSON Filters for this watch</li>
<li>All lines here must not exist (think of each line as "OR")</li>
<li>Note: Wrap in forward slash / to use regex example: <code>/foo\d/</code></li>
<li>{{ _('Block change-detection while this text is on the page, all text and regex are tested case-insensitive, good for waiting for when a product is available again') }}</li>
<li>{{ _('Block text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor') }}</li>
<li>{{ _('All lines here must not exist (think of each line as "OR")') }}</li>
<li>{{ _('Note: Wrap in forward slash / to use regex example:') }} <code>/foo\d/</code></li>
</ul>
</span>
</div>
@@ -55,17 +55,17 @@ Unavailable") }}
keyword") }}
<span class="pure-form-message-inline">
<ul>
<li>Extracts text in the final output (line by line) after other filters using regular expressions or string match;
<li>{{ _('Extracts text in the final output (line by line) after other filters using regular expressions or string match:') }}
<ul>
<li>Regular expression &dash; example <code>/reports.+?2022/i</code></li>
<li>Don't forget to consider the white-space at the start of a line <code>/.+?reports.+?2022/i</code></li>
<li>Use <code>//(?aiLmsux))</code> type flags (more <a href="https://docs.python.org/3/library/re.html#index-15">information here</a>)<br></li>
<li>Keyword example &dash; example <code>Out of stock</code></li>
<li>Use groups to extract just that text &dash; example <code>/reports.+?(\d+)/i</code> returns a list of years only</li>
<li>Example - match lines containing a keyword <code>/.*icecream.*/</code></li>
<li>{{ _('Regular expression - example') }} <code>/reports.+?2022/i</code></li>
<li>{{ _('Don\'t forget to consider the white-space at the start of a line') }} <code>/.+?reports.+?2022/i</code></li>
<li>{{ _('Use') }} <code>//(?aiLmsux))</code> {{ _('type flags (more') }} <a href="https://docs.python.org/3/library/re.html#index-15">{{ _('information here') }}</a>)<br></li>
<li>{{ _('Keyword example - example') }} <code>Out of stock</code></li>
<li>{{ _('Use groups to extract just that text - example') }} <code>/reports.+?(\d+)/i</code> {{ _('returns a list of years only') }}</li>
<li>{{ _('Example - match lines containing a keyword') }} <code>/.*icecream.*/</code></li>
</ul>
</li>
<li>One line per regular-expression/string match</li>
<li>{{ _('One line per regular-expression/string match') }}</li>
</ul>
</span>
</div>

View File

@@ -45,7 +45,7 @@ def run_filter_test(client, live_server, content_filter, app_notification_format
uuid = client.application.config.get('DATASTORE').add_watch(url=test_url)
res = client.get(url_for("watchlist.index"))
assert b'No website watches configured' not in res.data
assert b'No web page change detection watches configured' not in res.data
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)

View File

@@ -0,0 +1,225 @@
#!/usr/bin/env python3
# coding=utf-8
"""Unit tests for html_tools.html_to_text function."""
import hashlib
import threading
from queue import Queue
import pytest
from changedetectionio.html_tools import html_to_text
class TestHtmlToText:
"""Test html_to_text function for correctness and thread-safety."""
def test_basic_text_extraction(self):
"""Test basic HTML to text conversion."""
html = '<html><body><h1>Title</h1><p>Paragraph text.</p></body></html>'
text = html_to_text(html)
assert 'Title' in text
assert 'Paragraph text.' in text
assert '<' not in text # HTML tags should be stripped
assert '>' not in text
def test_empty_html(self):
"""Test handling of empty HTML."""
html = '<html><body></body></html>'
text = html_to_text(html)
# Should return empty or whitespace only
assert text.strip() == ''
def test_nested_elements(self):
"""Test extraction from nested HTML elements."""
html = '''
<html>
<body>
<div>
<h1>Header</h1>
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
</div>
</div>
</body>
</html>
'''
text = html_to_text(html)
assert 'Header' in text
assert 'First paragraph' in text
assert 'Second paragraph' in text
def test_anchor_tag_rendering(self):
"""Test anchor tag rendering option."""
html = '<html><body><a href="https://example.com">Link text</a></body></html>'
# Without rendering anchors
text_without = html_to_text(html, render_anchor_tag_content=False)
assert 'Link text' in text_without
assert 'https://example.com' not in text_without
# With rendering anchors
text_with = html_to_text(html, render_anchor_tag_content=True)
assert 'Link text' in text_with
assert 'https://example.com' in text_with or '[Link text]' in text_with
def test_rss_mode(self):
"""Test RSS mode converts title tags to h1."""
html = '<item><title>RSS Title</title><description>Content</description></item>'
# is_rss=True should convert <title> to <h1>
text = html_to_text(html, is_rss=True)
assert 'RSS Title' in text
assert 'Content' in text
def test_special_characters(self):
"""Test handling of special characters and entities."""
html = '<html><body><p>Test &amp; &lt;special&gt; characters</p></body></html>'
text = html_to_text(html)
# Entities should be decoded
assert 'Test &' in text or 'Test &amp;' in text
assert 'special' in text
def test_whitespace_handling(self):
"""Test that whitespace is properly handled."""
html = '<html><body><p>Line 1</p><p>Line 2</p></body></html>'
text = html_to_text(html)
# Should have some separation between lines
assert 'Line 1' in text
assert 'Line 2' in text
assert text.count('\n') >= 1 # At least one newline
def test_deterministic_output(self):
"""Test that the same HTML always produces the same text."""
html = '<html><body><h1>Test</h1><p>Content here</p></body></html>'
# Extract text multiple times
results = [html_to_text(html) for _ in range(10)]
# All results should be identical
assert len(set(results)) == 1, "html_to_text should be deterministic"
def test_thread_safety_determinism(self):
"""
Test that html_to_text produces deterministic output under high concurrency.
This is the critical test for the lxml threading bug fix.
Without the thread-local parser fix, this test would occasionally fail
under high concurrency when multiple threads share the global parser.
"""
html = '''
<html>
<head><title>Test Page</title></head>
<body>
<h1>Main Heading</h1>
<div class="content">
<p>First paragraph with <b>bold text</b>.</p>
<p>Second paragraph with <i>italic text</i>.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</body>
</html>
'''
results_queue = Queue()
def worker(worker_id, iterations=10):
"""Worker that converts HTML to text multiple times."""
for i in range(iterations):
text = html_to_text(html)
md5 = hashlib.md5(text.encode('utf-8')).hexdigest()
results_queue.put((worker_id, i, md5))
# Launch many threads simultaneously
num_threads = 50
threads = []
for i in range(num_threads):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()
# Wait for all threads to complete
for t in threads:
t.join()
# Collect all MD5 results
md5_values = []
while not results_queue.empty():
_, _, md5 = results_queue.get()
md5_values.append(md5)
# All MD5s should be identical
unique_md5s = set(md5_values)
assert len(unique_md5s) == 1, (
f"Thread-safety issue detected! Found {len(unique_md5s)} different MD5 values: {unique_md5s}. "
"The thread-local parser fix may not be working correctly."
)
print(f"✓ Thread-safety test passed: {len(md5_values)} conversions, all identical")
def test_thread_local_parser_exists(self):
"""Verify that thread-local storage is properly initialized."""
# Call html_to_text at least once to initialize thread-local storage
html_to_text('<html><body>Test</body></html>')
# Check that thread-local storage attribute exists
assert hasattr(html_to_text, '_thread_local'), (
"html_to_text should have _thread_local attribute for thread-safe parsers"
)
def test_different_threads_get_different_parsers(self):
"""Verify that different threads CAN get different parser instances."""
parser_ids = Queue()
def get_parser_id():
"""Get the parser ID in this thread."""
# Trigger parser creation
html_to_text('<html><body>Test</body></html>')
# Get the parser instance for this thread
if hasattr(html_to_text._thread_local, 'parser'):
parser = html_to_text._thread_local.parser
parser_ids.put(id(parser))
# Launch multiple threads
threads = []
for _ in range(5):
t = threading.Thread(target=get_parser_id)
threads.append(t)
t.start()
for t in threads:
t.join()
# Collect all parser IDs
ids = []
while not parser_ids.empty():
ids.append(parser_ids.get())
# We should have at least 2 different parser instances
# (threads can reuse IDs after completion, so not necessarily all unique)
unique_ids = set(ids)
assert len(unique_ids) >= 2, (
f"Expected at least 2 unique parsers, but got {len(unique_ids)}. "
"Thread-local storage may not be working correctly."
)
print(f"✓ Parser isolation test passed: {len(ids)} threads, {len(unique_ids)} unique parsers")
if __name__ == '__main__':
# Can run this file directly for quick testing
pytest.main([__file__, '-v'])

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
#
msgid ""
msgstr ""
"Project-Id-Version: changedetection.io\n"
"Project-Id-Version: changedetection.io\n"
"Report-Msgid-Bugs-To: https://github.com/dgtlmoon/changedetection.io\n"
"POT-Creation-Date: 2026-01-02 16:07+0100\n"
"PO-Revision-Date: 2026-01-12 16:33+0100\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.10.3\n"
"Generated-By: Babel 2.17.0\n"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:241
#: changedetectionio/flask_app.py:213 changedetectionio/flask_app.py:225
@@ -38,15 +38,11 @@ msgid "Incorrect password"
msgstr ""
#: changedetectionio/forms.py:63 changedetectionio/forms.py:243
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified."
msgstr ""
#: changedetectionio/forms.py:64
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified when not using global settings."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified when not using global settings."
msgstr ""
#: changedetectionio/forms.py:164
@@ -589,9 +585,7 @@ msgid "A backup is running!"
msgstr ""
#: changedetectionio/blueprint/backups/templates/overview.html:13
msgid ""
"Here you can download and request a new backup, when a backup is "
"completed you will see it listed below."
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:19
@@ -611,9 +605,7 @@ msgid "Remove backups"
msgstr ""
#: changedetectionio/blueprint/imports/importer.py:45
msgid ""
"Importing 5,000 of the first URLs from your list, the rest can be "
"imported again."
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
msgstr ""
#: changedetectionio/blueprint/imports/importer.py:78
@@ -648,9 +640,7 @@ msgstr ""
#: changedetectionio/blueprint/imports/importer.py:214
#: changedetectionio/blueprint/imports/importer.py:297
#, python-brace-format
msgid ""
"Error processing row number {}, check all cell data types are correct, "
"row was skipped."
msgid "Error processing row number {}, check all cell data types are correct, row was skipped."
msgstr ""
#: changedetectionio/blueprint/imports/importer.py:218
@@ -676,9 +666,7 @@ msgid ".XLSX & Wachete"
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:20
msgid ""
"Enter one URL per line, and optionally add tags for each URL after a "
"space, delineated by comma (,):"
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:22
@@ -690,9 +678,7 @@ msgid "URLs which do not pass validation will stay in the textarea."
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:44
msgid ""
"Copy and Paste your Distill.io watch 'export' file, this should be a JSON"
" file."
msgid "Copy and Paste your Distill.io watch 'export' file, this should be a JSON file."
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:45
@@ -985,9 +971,7 @@ msgid "Watch group / tag"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:21
msgid ""
"Groups allows you to manage filters and notifications for multiple "
"watches under a single organisational tag."
msgid "Groups allows you to manage filters and notifications for multiple watches under a single organisational tag."
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
@@ -1013,9 +997,7 @@ msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:59
#, python-format
msgid ""
"<p>Are you sure you want to delete group "
"<strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete group <strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:60
@@ -1035,10 +1017,7 @@ msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:67
#, python-format
msgid ""
"<p>Are you sure you want to unlink all watches from group "
"<strong>%(title)s</strong>?</p><p>The tag will be kept but watches will "
"be removed from it.</p>"
msgid "<p>Are you sure you want to unlink all watches from group <strong>%(title)s</strong>?</p><p>The tag will be kept but watches will be removed from it.</p>"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:68
@@ -1155,9 +1134,7 @@ msgstr ""
#: changedetectionio/blueprint/ui/__init__.py:330
#, python-brace-format
msgid ""
"Could not share, something went wrong while communicating with the share "
"server - {}"
msgid "Could not share, something went wrong while communicating with the share server - {}"
msgstr ""
#: changedetectionio/blueprint/ui/diff.py:93
@@ -1170,9 +1147,7 @@ msgid "No history found for the specified link, bad link?"
msgstr ""
#: changedetectionio/blueprint/ui/diff.py:98
msgid ""
"Not enough history (2 snapshots required) to show difference page for "
"this watch."
msgid "Not enough history (2 snapshots required) to show difference page for this watch."
msgstr ""
#: changedetectionio/blueprint/ui/edit.py:35
@@ -1220,9 +1195,7 @@ msgid "Watch added."
msgstr ""
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:12
msgid ""
"This will remove version history (snapshots) for ALL watches, but keep "
"your list of URLs!"
msgid "This will remove version history (snapshots) for ALL watches, but keep your list of URLs!"
msgstr ""
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:13
@@ -1404,9 +1377,7 @@ msgstr ""
#: changedetectionio/blueprint/ui/templates/diff.html:144
#: changedetectionio/blueprint/ui/templates/preview.html:80
msgid ""
"For now, Differences are performed on text, not graphically, only the "
"latest screenshot is available."
msgid "For now, Differences are performed on text, not graphically, only the latest screenshot is available."
msgstr ""
#: changedetectionio/blueprint/ui/templates/diff.html:149
@@ -1468,9 +1439,7 @@ msgid "Organisational tag/group name used in the main listing page"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:85
msgid ""
"Automatically uses the page title if found, you can also use your own "
"title/description here"
msgid "Automatically uses the page title if found, you can also use your own title/description here"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:95
@@ -1478,10 +1447,7 @@ msgid "The interval/amount of time between each check."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:110
msgid ""
"Sends a notification when the filter can no longer be seen on the page, "
"good for knowing when the page changed and your filter will not work "
"anymore."
msgid "Sends a notification when the filter can no longer be seen on the page, good for knowing when the page changed and your filter will not work anymore."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:123
@@ -1493,9 +1459,7 @@ msgid "Basic"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:123
msgid ""
"method (default) where your watched site doesn't need Javascript to "
"render."
msgid "method (default) where your watched site doesn't need Javascript to render."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:124
@@ -1507,9 +1471,7 @@ msgid "Chrome/Javascript"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:124
msgid ""
"method requires a network connection to a running WebDriver+Chrome "
"server, set by the ENV var 'WEBDRIVER_URL'."
msgid "method requires a network connection to a running WebDriver+Chrome server, set by the ENV var 'WEBDRIVER_URL'."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:125
@@ -1525,9 +1487,7 @@ msgid "Choose a proxy for this watch"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:143
msgid ""
"If you're having trouble waiting for the page to be fully rendered (text "
"missing etc), try increasing the 'wait' time here."
msgid "If you're having trouble waiting for the page to be fully rendered (text missing etc), try increasing the 'wait' time here."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:145
@@ -1548,9 +1508,7 @@ msgid "Show advanced options"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:157
msgid ""
"Run this code before performing change detection, handy for filling in "
"fields and other actions"
msgid "Run this code before performing change detection, handy for filling in fields and other actions"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:158
@@ -1607,9 +1565,7 @@ msgid "Visual Selector data is not ready, watch needs to be checked atleast once
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:253
msgid ""
"Sorry, this functionality only works with fetchers that support "
"interactive Javascript (so far only Playwright based fetchers)"
msgid "Sorry, this functionality only works with fetchers that support interactive Javascript (so far only Playwright based fetchers)"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:254
@@ -1627,9 +1583,7 @@ msgid "to one that supports interactive Javascript."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:297
msgid ""
"Use the verify (✓) button to test if a condition passes against the "
"current snapshot."
msgid "Use the verify (✓) button to test if a condition passes against the current snapshot."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:298
@@ -1657,9 +1611,7 @@ msgid "Limit trigger/ignore/block/extract to;"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:326
msgid ""
"Note: Depending on the length and similarity of the text on each line, "
"the algorithm may consider an"
msgid "Note: Depending on the length and similarity of the text on each line, the algorithm may consider an"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:326
@@ -1700,16 +1652,11 @@ msgid "Only trigger when unique lines appear"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:332
msgid ""
"Good for websites that just move the content around, and you want to know"
" when NEW content is added, compares new lines against all history for "
"this watch."
msgid "Good for websites that just move the content around, and you want to know when NEW content is added, compares new lines against all history for this watch."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:340
msgid ""
"Helps reduce changes detected caused by sites shuffling lines around, "
"combine with"
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:340
@@ -1739,9 +1686,7 @@ msgid "text"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:386
msgid ""
"elements that will be used for the change detection. It automatically "
"fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgid "elements that will be used for the change detection. It automatically fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:386
@@ -1781,9 +1726,7 @@ msgid "Currently:"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:423
msgid ""
"Sorry, this functionality only works with fetchers that support "
"Javascript and screenshots (such as playwright etc)."
msgid "Sorry, this functionality only works with fetchers that support Javascript and screenshots (such as playwright etc)."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:424
@@ -1839,9 +1782,7 @@ msgid "Are you sure you want to clear all history for:"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:496
msgid ""
"This will remove all snapshots and previous versions. This action cannot "
"be undone."
msgid "This will remove all snapshots and previous versions. This action cannot be undone."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:497
@@ -1865,9 +1806,7 @@ msgid "Current erroring screenshot from most recent request"
msgstr ""
#: changedetectionio/blueprint/ui/templates/preview.html:91
msgid ""
"Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc "
") that supports screenshots."
msgid "Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc ) that supports screenshots."
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:31
@@ -1936,9 +1875,7 @@ msgid "Clear Histories"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:66
msgid ""
"<p>Are you sure you want to clear history for the selected "
"items?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to clear history for the selected items?</p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:67
@@ -1954,9 +1891,7 @@ msgid "Delete Watches?"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:72
msgid ""
"<p>Are you sure you want to delete the selected "
"watches?</strong></p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete the selected watches?</strong></p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:78
@@ -1989,7 +1924,7 @@ msgid "Changed"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
msgid "No website watches configured, please add a URL in the box above, or"
msgid "No web page change detection watches configured, please add a URL in the box above, or"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
@@ -2253,9 +2188,7 @@ msgid "Select Language"
msgstr ""
#: changedetectionio/templates/base.html:270
msgid ""
"Language support is in beta, please help us improve by opening a PR on "
"GitHub with any updates."
msgid "Language support is in beta, please help us improve by opening a PR on GitHub with any updates."
msgstr ""
#: changedetectionio/templates/login.html:10
@@ -2266,3 +2199,150 @@ msgstr ""
msgid "Login"
msgstr ""
#: changedetectionio/widgets/ternary_boolean.py:18
#: changedetectionio/widgets/ternary_boolean.py:72
msgid "Yes"
msgstr ""
#: changedetectionio/widgets/ternary_boolean.py:19
#: changedetectionio/widgets/ternary_boolean.py:73
msgid "No"
msgstr ""
#: changedetectionio/widgets/ternary_boolean.py:20
#: changedetectionio/widgets/ternary_boolean.py:74
msgid "Main settings"
msgstr ""
#: changedetectionio/templates/_common_fields.html:11
msgid "Show token/placeholders"
msgstr ""
#: changedetectionio/templates/_common_fields.html:18
msgid "Token"
msgstr ""
#: changedetectionio/templates/_common_fields.html:19
msgid "Description"
msgstr ""
#: changedetectionio/templates/_common_fields.html:128
msgid "Show advanced help and tips"
msgstr ""
#: changedetectionio/templates/_common_fields.html:138
msgid "Send test notification"
msgstr ""
#: changedetectionio/templates/_common_fields.html:140
msgid "Add email"
msgstr ""
#: changedetectionio/templates/_common_fields.html:140
msgid "Add an email address"
msgstr ""
#: changedetectionio/templates/_common_fields.html:142
msgid "Notification debug logs"
msgstr ""
#: changedetectionio/templates/_common_fields.html:144
msgid "Processing.."
msgstr ""
#: changedetectionio/templates/_common_fields.html:151
msgid "Title for all notifications"
msgstr ""
#: changedetectionio/templates/_common_fields.html:176
msgid "Format for all notifications"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:9
msgid "Text to wait for before triggering a change/notification, all text and regex are tested case-insensitive."
msgstr ""
#: changedetectionio/templates/edit/text-options.html:10
msgid "Trigger text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:11
msgid "Each line is processed separately (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:12
msgid "Note: Wrap in forward slash / to use regex example:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:23
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:24
msgid "Each line processed separately, any line matching will be ignored (removed before creating the checksum)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:25
msgid "Regular Expression support, wrap the entire line in forward slash"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:26
msgid "Changing this will affect the comparison checksum which may trigger an alert"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:43
msgid "Block change-detection while this text is on the page, all text and regex are tested case-insensitive, good for waiting for when a product is available again"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:44
msgid "Block text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:45
msgid "All lines here must not exist (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:58
msgid "Extracts text in the final output (line by line) after other filters using regular expressions or string match:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:60
msgid "Regular expression - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:61
msgid "Don't forget to consider the white-space at the start of a line"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
msgid "Use"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
msgid "type flags (more"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
msgid "information here"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:63
msgid "Keyword example - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "Use groups to extract just that text - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "returns a list of years only"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:65
msgid "Example - match lines containing a keyword"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:68
msgid "One line per regular-expression/string match"
msgstr ""

View File

@@ -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.10.3\n"
"Generated-By: Babel 2.17.0\n"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:241
#: changedetectionio/flask_app.py:213 changedetectionio/flask_app.py:225
@@ -38,15 +38,11 @@ msgid "Incorrect password"
msgstr ""
#: changedetectionio/forms.py:63 changedetectionio/forms.py:243
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified."
msgstr ""
#: changedetectionio/forms.py:64
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified when not using global settings."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified when not using global settings."
msgstr ""
#: changedetectionio/forms.py:164
@@ -589,9 +585,7 @@ msgid "A backup is running!"
msgstr ""
#: changedetectionio/blueprint/backups/templates/overview.html:13
msgid ""
"Here you can download and request a new backup, when a backup is "
"completed you will see it listed below."
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:19
@@ -611,9 +605,7 @@ msgid "Remove backups"
msgstr ""
#: changedetectionio/blueprint/imports/importer.py:45
msgid ""
"Importing 5,000 of the first URLs from your list, the rest can be "
"imported again."
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
msgstr ""
#: changedetectionio/blueprint/imports/importer.py:78
@@ -648,9 +640,7 @@ msgstr ""
#: changedetectionio/blueprint/imports/importer.py:214
#: changedetectionio/blueprint/imports/importer.py:297
#, python-brace-format
msgid ""
"Error processing row number {}, check all cell data types are correct, "
"row was skipped."
msgid "Error processing row number {}, check all cell data types are correct, row was skipped."
msgstr ""
#: changedetectionio/blueprint/imports/importer.py:218
@@ -676,9 +666,7 @@ msgid ".XLSX & Wachete"
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:20
msgid ""
"Enter one URL per line, and optionally add tags for each URL after a "
"space, delineated by comma (,):"
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:22
@@ -690,9 +678,7 @@ msgid "URLs which do not pass validation will stay in the textarea."
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:44
msgid ""
"Copy and Paste your Distill.io watch 'export' file, this should be a JSON"
" file."
msgid "Copy and Paste your Distill.io watch 'export' file, this should be a JSON file."
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:45
@@ -985,9 +971,7 @@ msgid "Watch group / tag"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:21
msgid ""
"Groups allows you to manage filters and notifications for multiple "
"watches under a single organisational tag."
msgid "Groups allows you to manage filters and notifications for multiple watches under a single organisational tag."
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
@@ -1013,9 +997,7 @@ msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:59
#, python-format
msgid ""
"<p>Are you sure you want to delete group "
"<strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete group <strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:60
@@ -1035,10 +1017,7 @@ msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:67
#, python-format
msgid ""
"<p>Are you sure you want to unlink all watches from group "
"<strong>%(title)s</strong>?</p><p>The tag will be kept but watches will "
"be removed from it.</p>"
msgid "<p>Are you sure you want to unlink all watches from group <strong>%(title)s</strong>?</p><p>The tag will be kept but watches will be removed from it.</p>"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:68
@@ -1155,9 +1134,7 @@ msgstr ""
#: changedetectionio/blueprint/ui/__init__.py:330
#, python-brace-format
msgid ""
"Could not share, something went wrong while communicating with the share "
"server - {}"
msgid "Could not share, something went wrong while communicating with the share server - {}"
msgstr ""
#: changedetectionio/blueprint/ui/diff.py:93
@@ -1170,9 +1147,7 @@ msgid "No history found for the specified link, bad link?"
msgstr ""
#: changedetectionio/blueprint/ui/diff.py:98
msgid ""
"Not enough history (2 snapshots required) to show difference page for "
"this watch."
msgid "Not enough history (2 snapshots required) to show difference page for this watch."
msgstr ""
#: changedetectionio/blueprint/ui/edit.py:35
@@ -1220,9 +1195,7 @@ msgid "Watch added."
msgstr ""
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:12
msgid ""
"This will remove version history (snapshots) for ALL watches, but keep "
"your list of URLs!"
msgid "This will remove version history (snapshots) for ALL watches, but keep your list of URLs!"
msgstr ""
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:13
@@ -1404,9 +1377,7 @@ msgstr ""
#: changedetectionio/blueprint/ui/templates/diff.html:144
#: changedetectionio/blueprint/ui/templates/preview.html:80
msgid ""
"For now, Differences are performed on text, not graphically, only the "
"latest screenshot is available."
msgid "For now, Differences are performed on text, not graphically, only the latest screenshot is available."
msgstr ""
#: changedetectionio/blueprint/ui/templates/diff.html:149
@@ -1468,9 +1439,7 @@ msgid "Organisational tag/group name used in the main listing page"
msgstr "organizational tag/group name used in the main listing page"
#: changedetectionio/blueprint/ui/templates/edit.html:85
msgid ""
"Automatically uses the page title if found, you can also use your own "
"title/description here"
msgid "Automatically uses the page title if found, you can also use your own title/description here"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:95
@@ -1478,10 +1447,7 @@ msgid "The interval/amount of time between each check."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:110
msgid ""
"Sends a notification when the filter can no longer be seen on the page, "
"good for knowing when the page changed and your filter will not work "
"anymore."
msgid "Sends a notification when the filter can no longer be seen on the page, good for knowing when the page changed and your filter will not work anymore."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:123
@@ -1493,9 +1459,7 @@ msgid "Basic"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:123
msgid ""
"method (default) where your watched site doesn't need Javascript to "
"render."
msgid "method (default) where your watched site doesn't need Javascript to render."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:124
@@ -1507,9 +1471,7 @@ msgid "Chrome/Javascript"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:124
msgid ""
"method requires a network connection to a running WebDriver+Chrome "
"server, set by the ENV var 'WEBDRIVER_URL'."
msgid "method requires a network connection to a running WebDriver+Chrome server, set by the ENV var 'WEBDRIVER_URL'."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:125
@@ -1525,9 +1487,7 @@ msgid "Choose a proxy for this watch"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:143
msgid ""
"If you're having trouble waiting for the page to be fully rendered (text "
"missing etc), try increasing the 'wait' time here."
msgid "If you're having trouble waiting for the page to be fully rendered (text missing etc), try increasing the 'wait' time here."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:145
@@ -1548,9 +1508,7 @@ msgid "Show advanced options"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:157
msgid ""
"Run this code before performing change detection, handy for filling in "
"fields and other actions"
msgid "Run this code before performing change detection, handy for filling in fields and other actions"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:158
@@ -1607,9 +1565,7 @@ msgid "Visual Selector data is not ready, watch needs to be checked atleast once
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:253
msgid ""
"Sorry, this functionality only works with fetchers that support "
"interactive Javascript (so far only Playwright based fetchers)"
msgid "Sorry, this functionality only works with fetchers that support interactive Javascript (so far only Playwright based fetchers)"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:254
@@ -1627,9 +1583,7 @@ msgid "to one that supports interactive Javascript."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:297
msgid ""
"Use the verify (✓) button to test if a condition passes against the "
"current snapshot."
msgid "Use the verify (✓) button to test if a condition passes against the current snapshot."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:298
@@ -1657,9 +1611,7 @@ msgid "Limit trigger/ignore/block/extract to;"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:326
msgid ""
"Note: Depending on the length and similarity of the text on each line, "
"the algorithm may consider an"
msgid "Note: Depending on the length and similarity of the text on each line, the algorithm may consider an"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:326
@@ -1700,16 +1652,11 @@ msgid "Only trigger when unique lines appear"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:332
msgid ""
"Good for websites that just move the content around, and you want to know"
" when NEW content is added, compares new lines against all history for "
"this watch."
msgid "Good for websites that just move the content around, and you want to know when NEW content is added, compares new lines against all history for this watch."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:340
msgid ""
"Helps reduce changes detected caused by sites shuffling lines around, "
"combine with"
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:340
@@ -1739,9 +1686,7 @@ msgid "text"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:386
msgid ""
"elements that will be used for the change detection. It automatically "
"fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgid "elements that will be used for the change detection. It automatically fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:386
@@ -1781,9 +1726,7 @@ msgid "Currently:"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:423
msgid ""
"Sorry, this functionality only works with fetchers that support "
"Javascript and screenshots (such as playwright etc)."
msgid "Sorry, this functionality only works with fetchers that support Javascript and screenshots (such as playwright etc)."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:424
@@ -1839,9 +1782,7 @@ msgid "Are you sure you want to clear all history for:"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:496
msgid ""
"This will remove all snapshots and previous versions. This action cannot "
"be undone."
msgid "This will remove all snapshots and previous versions. This action cannot be undone."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:497
@@ -1865,9 +1806,7 @@ msgid "Current erroring screenshot from most recent request"
msgstr ""
#: changedetectionio/blueprint/ui/templates/preview.html:91
msgid ""
"Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc "
") that supports screenshots."
msgid "Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc ) that supports screenshots."
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:31
@@ -1936,9 +1875,7 @@ msgid "Clear Histories"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:66
msgid ""
"<p>Are you sure you want to clear history for the selected "
"items?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to clear history for the selected items?</p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:67
@@ -1954,9 +1891,7 @@ msgid "Delete Watches?"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:72
msgid ""
"<p>Are you sure you want to delete the selected "
"watches?</strong></p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete the selected watches?</strong></p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:78
@@ -1989,7 +1924,7 @@ msgid "Changed"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
msgid "No website watches configured, please add a URL in the box above, or"
msgid "No web page change detection watches configured, please add a URL in the box above, or"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
@@ -2253,9 +2188,7 @@ msgid "Select Language"
msgstr ""
#: changedetectionio/templates/base.html:270
msgid ""
"Language support is in beta, please help us improve by opening a PR on "
"GitHub with any updates."
msgid "Language support is in beta, please help us improve by opening a PR on GitHub with any updates."
msgstr ""
#: changedetectionio/templates/login.html:10
@@ -2266,3 +2199,150 @@ msgstr ""
msgid "Login"
msgstr ""
#: changedetectionio/widgets/ternary_boolean.py:18
#: changedetectionio/widgets/ternary_boolean.py:72
msgid "Yes"
msgstr ""
#: changedetectionio/widgets/ternary_boolean.py:19
#: changedetectionio/widgets/ternary_boolean.py:73
msgid "No"
msgstr ""
#: changedetectionio/widgets/ternary_boolean.py:20
#: changedetectionio/widgets/ternary_boolean.py:74
msgid "Main settings"
msgstr ""
#: changedetectionio/templates/_common_fields.html:11
msgid "Show token/placeholders"
msgstr ""
#: changedetectionio/templates/_common_fields.html:18
msgid "Token"
msgstr ""
#: changedetectionio/templates/_common_fields.html:19
msgid "Description"
msgstr ""
#: changedetectionio/templates/_common_fields.html:128
msgid "Show advanced help and tips"
msgstr ""
#: changedetectionio/templates/_common_fields.html:138
msgid "Send test notification"
msgstr ""
#: changedetectionio/templates/_common_fields.html:140
msgid "Add email"
msgstr ""
#: changedetectionio/templates/_common_fields.html:140
msgid "Add an email address"
msgstr ""
#: changedetectionio/templates/_common_fields.html:142
msgid "Notification debug logs"
msgstr ""
#: changedetectionio/templates/_common_fields.html:144
msgid "Processing.."
msgstr ""
#: changedetectionio/templates/_common_fields.html:151
msgid "Title for all notifications"
msgstr ""
#: changedetectionio/templates/_common_fields.html:176
msgid "Format for all notifications"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:9
msgid "Text to wait for before triggering a change/notification, all text and regex are tested case-insensitive."
msgstr ""
#: changedetectionio/templates/edit/text-options.html:10
msgid "Trigger text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:11
msgid "Each line is processed separately (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:12
msgid "Note: Wrap in forward slash / to use regex example:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:23
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:24
msgid "Each line processed separately, any line matching will be ignored (removed before creating the checksum)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:25
msgid "Regular Expression support, wrap the entire line in forward slash"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:26
msgid "Changing this will affect the comparison checksum which may trigger an alert"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:43
msgid "Block change-detection while this text is on the page, all text and regex are tested case-insensitive, good for waiting for when a product is available again"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:44
msgid "Block text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:45
msgid "All lines here must not exist (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:58
msgid "Extracts text in the final output (line by line) after other filters using regular expressions or string match:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:60
msgid "Regular expression - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:61
msgid "Don't forget to consider the white-space at the start of a line"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
msgid "Use"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
msgid "type flags (more"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
msgid "information here"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:63
msgid "Keyword example - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "Use groups to extract just that text - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "returns a list of years only"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:65
msgid "Example - match lines containing a keyword"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:68
msgid "One line per regular-expression/string match"
msgstr ""

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-01-03 14:31+0100\n"
"POT-Creation-Date: 2026-01-02 16:07+0100\n"
"PO-Revision-Date: 2026-01-02 15:32+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: it\n"
@@ -19,34 +19,30 @@ msgstr ""
"Generated-By: Babel 2.17.0\n"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:241
#: changedetectionio/flask_app.py:214 changedetectionio/flask_app.py:226
#: changedetectionio/flask_app.py:247
#: changedetectionio/flask_app.py:213 changedetectionio/flask_app.py:225
#: changedetectionio/flask_app.py:246
#: changedetectionio/realtime/socket_server.py:171
msgid "Not yet"
msgstr "Non ancora"
#: changedetectionio/flask_app.py:534
msgid "Already logged in"
msgstr "Già autenticato"
#: changedetectionio/flask_app.py:536
#: changedetectionio/flask_app.py:468
msgid "You must be logged in, please log in."
msgstr "Devi essere autenticato, effettua l'accesso."
#: changedetectionio/flask_app.py:551
#: changedetectionio/flask_app.py:495
msgid "Already logged in"
msgstr "Già autenticato"
#: changedetectionio/flask_app.py:522
msgid "Incorrect password"
msgstr "Password errata"
#: changedetectionio/forms.py:63 changedetectionio/forms.py:243
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified."
msgstr ""
#: changedetectionio/forms.py:64
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified when not using global settings."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified when not using global settings."
msgstr ""
#: changedetectionio/forms.py:164
@@ -369,9 +365,8 @@ msgid "Muted"
msgstr "Silenzia"
#: changedetectionio/forms.py:832
#, fuzzy
msgid "On"
msgstr "nessuno"
msgstr "Attivo"
#: changedetectionio/forms.py:833
msgid "Attach screenshot to notification (where possible)"
@@ -601,8 +596,6 @@ msgid "Backups were deleted."
msgstr "I backup sono stati eliminati."
#: changedetectionio/blueprint/backups/templates/overview.html:6
#: changedetectionio/templates/base.html:282
#: changedetectionio/templates/base.html:290
msgid "Backups"
msgstr "Backup"
@@ -611,9 +604,7 @@ msgid "A backup is running!"
msgstr "Un backup è in esecuzione!"
#: changedetectionio/blueprint/backups/templates/overview.html:13
msgid ""
"Here you can download and request a new backup, when a backup is "
"completed you will see it listed below."
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:19
@@ -633,12 +624,8 @@ msgid "Remove backups"
msgstr "Rimuovi backup"
#: changedetectionio/blueprint/imports/importer.py:45
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."
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."
#: changedetectionio/blueprint/imports/importer.py:78
#, python-brace-format
@@ -661,27 +648,19 @@ msgstr "{} Importate da Distill.io in {:.2f}s, {} Ignorate."
#: changedetectionio/blueprint/imports/importer.py:160
#: changedetectionio/blueprint/imports/importer.py:239
msgid "Unable to read export XLSX file, something wrong with the file?"
msgstr ""
"Impossibile leggere il file XLSX di esportazione, c'è qualcosa che non va"
" con il file?"
msgstr "Impossibile leggere il file XLSX di esportazione, c'è qualcosa che non va con il file?"
#: changedetectionio/blueprint/imports/importer.py:200
#: changedetectionio/blueprint/imports/importer.py:268
#, python-brace-format
msgid "Error processing row number {}, URL value was incorrect, row was skipped."
msgstr ""
"Errore nell'elaborazione della riga numero {}, il valore dell'URL non era"
" corretto, riga ignorata."
msgstr "Errore nell'elaborazione della riga numero {}, il valore dell'URL non era corretto, riga ignorata."
#: changedetectionio/blueprint/imports/importer.py:214
#: changedetectionio/blueprint/imports/importer.py:297
#, python-brace-format
msgid ""
"Error processing row number {}, check all cell data types are correct, "
"row was skipped."
msgstr ""
"Errore nell'elaborazione della riga numero {}, verifica che tutti i tipi "
"di dati delle celle siano corretti, riga ignorata."
msgid "Error processing row number {}, check all cell data types are correct, row was skipped."
msgstr "Errore nell'elaborazione della riga numero {}, verifica che tutti i tipi di dati delle celle siano corretti, riga ignorata."
#: changedetectionio/blueprint/imports/importer.py:218
#, python-brace-format
@@ -706,9 +685,7 @@ msgid ".XLSX & Wachete"
msgstr ".XLSX & Wachete"
#: changedetectionio/blueprint/imports/templates/import.html:20
msgid ""
"Enter one URL per line, and optionally add tags for each URL after a "
"space, delineated by comma (,):"
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:22
@@ -720,9 +697,7 @@ msgid "URLs which do not pass validation will stay in the textarea."
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:44
msgid ""
"Copy and Paste your Distill.io watch 'export' file, this should be a JSON"
" file."
msgid "Copy and Paste your Distill.io watch 'export' file, this should be a JSON file."
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:45
@@ -1015,9 +990,7 @@ msgid "Watch group / tag"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:21
msgid ""
"Groups allows you to manage filters and notifications for multiple "
"watches under a single organisational tag."
msgid "Groups allows you to manage filters and notifications for multiple watches under a single organisational tag."
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
@@ -1043,9 +1016,7 @@ msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:59
#, python-format
msgid ""
"<p>Are you sure you want to delete group "
"<strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete group <strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:60
@@ -1065,10 +1036,7 @@ msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:67
#, python-format
msgid ""
"<p>Are you sure you want to unlink all watches from group "
"<strong>%(title)s</strong>?</p><p>The tag will be kept but watches will "
"be removed from it.</p>"
msgid "<p>Are you sure you want to unlink all watches from group <strong>%(title)s</strong>?</p><p>The tag will be kept but watches will be removed from it.</p>"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:68
@@ -1185,9 +1153,7 @@ msgstr ""
#: changedetectionio/blueprint/ui/__init__.py:330
#, python-brace-format
msgid ""
"Could not share, something went wrong while communicating with the share "
"server - {}"
msgid "Could not share, something went wrong while communicating with the share server - {}"
msgstr ""
#: changedetectionio/blueprint/ui/diff.py:93
@@ -1200,9 +1166,7 @@ msgid "No history found for the specified link, bad link?"
msgstr ""
#: changedetectionio/blueprint/ui/diff.py:98
msgid ""
"Not enough history (2 snapshots required) to show difference page for "
"this watch."
msgid "Not enough history (2 snapshots required) to show difference page for this watch."
msgstr ""
#: changedetectionio/blueprint/ui/edit.py:35
@@ -1250,9 +1214,7 @@ msgid "Watch added."
msgstr ""
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:12
msgid ""
"This will remove version history (snapshots) for ALL watches, but keep "
"your list of URLs!"
msgid "This will remove version history (snapshots) for ALL watches, but keep your list of URLs!"
msgstr ""
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:13
@@ -1288,8 +1250,7 @@ msgid "Clear History!"
msgstr ""
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:39
#: changedetectionio/templates/base.html:379
#: changedetectionio/templates/base.html:399
#: changedetectionio/templates/base.html:274
msgid "Cancel"
msgstr "Annulla"
@@ -1435,9 +1396,7 @@ msgstr ""
#: changedetectionio/blueprint/ui/templates/diff.html:144
#: changedetectionio/blueprint/ui/templates/preview.html:80
msgid ""
"For now, Differences are performed on text, not graphically, only the "
"latest screenshot is available."
msgid "For now, Differences are performed on text, not graphically, only the latest screenshot is available."
msgstr ""
#: changedetectionio/blueprint/ui/templates/diff.html:149
@@ -1499,9 +1458,7 @@ msgid "Organisational tag/group name used in the main listing page"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:85
msgid ""
"Automatically uses the page title if found, you can also use your own "
"title/description here"
msgid "Automatically uses the page title if found, you can also use your own title/description here"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:95
@@ -1509,10 +1466,7 @@ msgid "The interval/amount of time between each check."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:110
msgid ""
"Sends a notification when the filter can no longer be seen on the page, "
"good for knowing when the page changed and your filter will not work "
"anymore."
msgid "Sends a notification when the filter can no longer be seen on the page, good for knowing when the page changed and your filter will not work anymore."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:123
@@ -1524,9 +1478,7 @@ msgid "Basic"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:123
msgid ""
"method (default) where your watched site doesn't need Javascript to "
"render."
msgid "method (default) where your watched site doesn't need Javascript to render."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:124
@@ -1538,9 +1490,7 @@ msgid "Chrome/Javascript"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:124
msgid ""
"method requires a network connection to a running WebDriver+Chrome "
"server, set by the ENV var 'WEBDRIVER_URL'."
msgid "method requires a network connection to a running WebDriver+Chrome server, set by the ENV var 'WEBDRIVER_URL'."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:125
@@ -1556,9 +1506,7 @@ msgid "Choose a proxy for this watch"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:143
msgid ""
"If you're having trouble waiting for the page to be fully rendered (text "
"missing etc), try increasing the 'wait' time here."
msgid "If you're having trouble waiting for the page to be fully rendered (text missing etc), try increasing the 'wait' time here."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:145
@@ -1579,9 +1527,7 @@ msgid "Show advanced options"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:157
msgid ""
"Run this code before performing change detection, handy for filling in "
"fields and other actions"
msgid "Run this code before performing change detection, handy for filling in fields and other actions"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:158
@@ -1638,9 +1584,7 @@ msgid "Visual Selector data is not ready, watch needs to be checked atleast once
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:253
msgid ""
"Sorry, this functionality only works with fetchers that support "
"interactive Javascript (so far only Playwright based fetchers)"
msgid "Sorry, this functionality only works with fetchers that support interactive Javascript (so far only Playwright based fetchers)"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:254
@@ -1658,9 +1602,7 @@ msgid "to one that supports interactive Javascript."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:297
msgid ""
"Use the verify (✓) button to test if a condition passes against the "
"current snapshot."
msgid "Use the verify (✓) button to test if a condition passes against the current snapshot."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:298
@@ -1688,9 +1630,7 @@ msgid "Limit trigger/ignore/block/extract to;"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:326
msgid ""
"Note: Depending on the length and similarity of the text on each line, "
"the algorithm may consider an"
msgid "Note: Depending on the length and similarity of the text on each line, the algorithm may consider an"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:326
@@ -1731,16 +1671,11 @@ msgid "Only trigger when unique lines appear"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:332
msgid ""
"Good for websites that just move the content around, and you want to know"
" when NEW content is added, compares new lines against all history for "
"this watch."
msgid "Good for websites that just move the content around, and you want to know when NEW content is added, compares new lines against all history for this watch."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:340
msgid ""
"Helps reduce changes detected caused by sites shuffling lines around, "
"combine with"
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:340
@@ -1770,9 +1705,7 @@ msgid "text"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:386
msgid ""
"elements that will be used for the change detection. It automatically "
"fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgid "elements that will be used for the change detection. It automatically fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:386
@@ -1812,9 +1745,7 @@ msgid "Currently:"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:423
msgid ""
"Sorry, this functionality only works with fetchers that support "
"Javascript and screenshots (such as playwright etc)."
msgid "Sorry, this functionality only works with fetchers that support Javascript and screenshots (such as playwright etc)."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:424
@@ -1870,9 +1801,7 @@ msgid "Are you sure you want to clear all history for:"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:496
msgid ""
"This will remove all snapshots and previous versions. This action cannot "
"be undone."
msgid "This will remove all snapshots and previous versions. This action cannot be undone."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:497
@@ -1896,9 +1825,7 @@ msgid "Current erroring screenshot from most recent request"
msgstr ""
#: changedetectionio/blueprint/ui/templates/preview.html:91
msgid ""
"Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc "
") that supports screenshots."
msgid "Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc ) that supports screenshots."
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:31
@@ -1967,9 +1894,7 @@ msgid "Clear Histories"
msgstr "Cancella cronologie"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:66
msgid ""
"<p>Are you sure you want to clear history for the selected "
"items?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to clear history for the selected items?</p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:67
@@ -1985,9 +1910,7 @@ msgid "Delete Watches?"
msgstr "Eliminare monitoraggi?"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:72
msgid ""
"<p>Are you sure you want to delete the selected "
"watches?</strong></p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete the selected watches?</strong></p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:78
@@ -2020,7 +1943,7 @@ msgid "Changed"
msgstr "Modifica"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
msgid "No website watches configured, please add a URL in the box above, or"
msgid "No web page change detection watches configured, please add a URL in the box above, or"
msgstr "Nessun monitoraggio configurato, aggiungi un URL nella casella sopra, oppure"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
@@ -2048,7 +1971,7 @@ msgid "No information"
msgstr "Nessuna informazione"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:234
#: changedetectionio/templates/base.html:353
#: changedetectionio/templates/base.html:248
msgid "Checking now"
msgstr "Controllo in corso"
@@ -2115,9 +2038,7 @@ msgstr "Valore riquadro di selezione troppo lungo"
#: changedetectionio/processors/image_ssim_diff/forms.py:23
msgid "Bounding box must be in format: x,y,width,height (integers only)"
msgstr ""
"Il riquadro deve essere nel formato: x,y,larghezza,altezza (solo numeri "
"interi)"
msgstr "Il riquadro deve essere nel formato: x,y,larghezza,altezza (solo numeri interi)"
#: changedetectionio/processors/image_ssim_diff/forms.py:29
msgid "Bounding box values must be non-negative"
@@ -2170,9 +2091,7 @@ msgstr "Rilevamento modifiche screenshot visivi"
#: changedetectionio/processors/image_ssim_diff/processor.py:22
msgid "Compares screenshots using fast OpenCV algorithm, 10-100x faster than SSIM"
msgstr ""
"Confronta screenshot con algoritmo OpenCV veloce, 10-100x più veloce di "
"SSIM"
msgstr "Confronta screenshot con algoritmo OpenCV veloce, 10-100x più veloce di SSIM"
#: changedetectionio/processors/restock_diff/forms.py:15
msgid "Re-stock detection"
@@ -2236,264 +2155,338 @@ msgstr "Modifiche testo/HTML, JSON e PDF"
msgid "Detects all text changes where possible"
msgstr "Rileva tutte le modifiche di testo possibili"
#: changedetectionio/templates/_helpers.html:25
msgid "Entry"
msgstr ""
#: changedetectionio/templates/_helpers.html:153
#, fuzzy
msgid "Actions"
msgstr "Condizioni"
#: changedetectionio/templates/_helpers.html:172
msgid "Add a row/rule after"
msgstr ""
#: changedetectionio/templates/_helpers.html:173
msgid "Remove this row/rule"
msgstr ""
#: changedetectionio/templates/_helpers.html:174
msgid "Verify this rule against current snapshot"
msgstr ""
#: changedetectionio/templates/_helpers.html:184
msgid ""
"Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but "
"Chrome based fetching is not enabled."
msgstr ""
#: changedetectionio/templates/_helpers.html:184
msgid "Alternatively try our"
msgstr ""
#: changedetectionio/templates/_helpers.html:184
msgid ""
"very affordable subscription based service which has all this setup for "
"you"
msgstr ""
#: changedetectionio/templates/_helpers.html:185
msgid "You may need to"
msgstr ""
#: changedetectionio/templates/_helpers.html:185
msgid "Enable playwright environment variable"
msgstr ""
#: changedetectionio/templates/_helpers.html:185
msgid "and uncomment the"
msgstr ""
#: changedetectionio/templates/_helpers.html:185
#, fuzzy
msgid "in the"
msgstr "Silenzia"
#: changedetectionio/templates/_helpers.html:185
#, fuzzy
msgid "file"
msgstr "Titolo"
#: changedetectionio/templates/_helpers.html:240
msgid "Set a hourly/week day schedule"
msgstr ""
#: changedetectionio/templates/_helpers.html:247
#, fuzzy
msgid "Schedule time limits"
msgstr "Tempo di ricontrollo (minuti)"
#: changedetectionio/templates/_helpers.html:248
msgid "Business hours"
msgstr ""
#: changedetectionio/templates/_helpers.html:249
#, fuzzy
msgid "Weekends"
msgstr "Settimane"
#: changedetectionio/templates/_helpers.html:250
#, fuzzy
msgid "Reset"
msgstr "Richiesta"
#: changedetectionio/templates/_helpers.html:259
msgid ""
"Warning, one or more of your 'days' has a duration that would extend into"
" the next day."
msgstr ""
#: changedetectionio/templates/_helpers.html:260
msgid "This could have unintended consequences."
msgstr ""
#: changedetectionio/templates/_helpers.html:270
msgid "More help and examples about using the scheduler"
msgstr ""
#: changedetectionio/templates/_helpers.html:275
#, fuzzy
msgid "Want to use a time schedule?"
msgstr "Usa pianificazione oraria"
#: changedetectionio/templates/_helpers.html:275
msgid "First confirm/save your Time Zone Settings"
msgstr ""
#: changedetectionio/templates/_helpers.html:284
msgid ""
"Triggers a change if this text appears, AND something changed in the "
"document."
msgstr ""
#: changedetectionio/templates/_helpers.html:284
#, fuzzy
msgid "Triggered text"
msgstr "Ignora testo"
#: changedetectionio/templates/_helpers.html:285
msgid "Ignored for calculating changes, but still shown."
msgstr ""
#: changedetectionio/templates/_helpers.html:285
#, fuzzy
msgid "Ignored text"
msgstr "Ignora testo"
#: changedetectionio/templates/_helpers.html:286
#, fuzzy
msgid "No change-detection will occur because this text exists."
msgstr "Blocca rilevamento modifiche quando il testo corrisponde"
#: changedetectionio/templates/_helpers.html:286
#, fuzzy
msgid "Blocked text"
msgstr "Ignora testo"
#: changedetectionio/templates/base.html:78
#: changedetectionio/templates/base.html:168
#: changedetectionio/templates/base.html:77
msgid "GROUPS"
msgstr "GRUPPI"
#: changedetectionio/templates/base.html:81
#: changedetectionio/templates/base.html:169
#: changedetectionio/templates/base.html:80
msgid "SETTINGS"
msgstr "IMPOSTAZIONI"
#: changedetectionio/templates/base.html:84
#: changedetectionio/templates/base.html:170
#: changedetectionio/templates/base.html:83
msgid "IMPORT"
msgstr "IMPORTA"
#: changedetectionio/templates/base.html:87
#: changedetectionio/templates/base.html:171
#: changedetectionio/templates/base.html:86
msgid "BACKUPS"
msgstr "BACKUP"
#: changedetectionio/templates/base.html:91
#: changedetectionio/templates/base.html:173
#: changedetectionio/templates/base.html:90
msgid "EDIT"
msgstr "MODIFICA"
#: changedetectionio/templates/base.html:101
#: changedetectionio/templates/base.html:177
#: changedetectionio/templates/base.html:100
msgid "LOG OUT"
msgstr "ESCI"
#: changedetectionio/templates/base.html:108
#: changedetectionio/templates/base.html:109
msgid "Search, or Use Alt+S Key"
msgstr "Cerca, o usa il tasto Alt+S"
#: changedetectionio/templates/base.html:114
#: changedetectionio/templates/base.html:116
msgid "Toggle Light/Dark Mode"
msgstr "Cambia Modalità Chiaro/Scuro"
#: changedetectionio/templates/base.html:115
#: changedetectionio/templates/base.html:117
msgid "Toggle light/dark mode"
msgstr "Cambia modalità chiaro/scuro"
#: changedetectionio/templates/base.html:125
#: changedetectionio/templates/base.html:127
msgid "Change Language"
msgstr "Cambia Lingua"
#: changedetectionio/templates/base.html:126
#: changedetectionio/templates/base.html:128
msgid "Change language"
msgstr "Cambia lingua"
#: changedetectionio/templates/base.html:253
#, fuzzy
msgid "Watch List"
msgstr "Lista Monitoraggi"
#: changedetectionio/templates/base.html:258
#, fuzzy
msgid "Watches"
msgstr "Monitoraggi"
#: changedetectionio/templates/base.html:261
msgid "Queue Status"
msgstr ""
#: changedetectionio/templates/base.html:270
#, fuzzy
msgid "Queue"
msgstr "In coda"
#: changedetectionio/templates/base.html:274
#: changedetectionio/templates/base.html:279
#, fuzzy
msgid "Settings"
msgstr "IMPOSTAZIONI"
#: changedetectionio/templates/base.html:293
msgid "Sitemap Crawler"
msgstr ""
#: changedetectionio/templates/base.html:318
msgid "Sitemap"
msgstr ""
#: changedetectionio/templates/base.html:354
#: changedetectionio/templates/base.html:249
msgid "Real-time updates offline"
msgstr ""
#: changedetectionio/templates/base.html:364
#: changedetectionio/templates/base.html:259
msgid "Select Language"
msgstr "Seleziona Lingua"
#: changedetectionio/templates/base.html:375
msgid ""
"Language support is in beta, please help us improve by opening a PR on "
"GitHub with any updates."
msgstr ""
"Il supporto linguistico è in versione beta, aiutaci a migliorare aprendo "
"una PR su GitHub con eventuali aggiornamenti."
#: changedetectionio/templates/base.html:270
msgid "Language support is in beta, please help us improve by opening a PR on GitHub with any updates."
msgstr "Il supporto linguistico è in versione beta, aiutaci a migliorare aprendo una PR su GitHub con eventuali aggiornamenti."
#: changedetectionio/templates/base.html:387
#: changedetectionio/templates/base.html:400
#, fuzzy
msgid "Search"
msgstr "Ricerca in corso"
#: changedetectionio/templates/base.html:392
msgid "URL or Title"
msgstr ""
#: changedetectionio/templates/base.html:392
#, fuzzy
msgid "in"
msgstr "Info"
#: changedetectionio/templates/base.html:393
msgid "Enter search term..."
msgstr ""
#: changedetectionio/templates/login.html:11
#: changedetectionio/templates/login.html:10
msgid "Password"
msgstr "Password"
#: changedetectionio/templates/login.html:17
#: changedetectionio/templates/login.html:16
msgid "Login"
msgstr "Accedi"
#: changedetectionio/widgets/ternary_boolean.py:18
#: changedetectionio/widgets/ternary_boolean.py:72
msgid "Yes"
msgstr "Sì"
#: changedetectionio/widgets/ternary_boolean.py:19
#: changedetectionio/widgets/ternary_boolean.py:73
msgid "No"
msgstr "No"
#: changedetectionio/widgets/ternary_boolean.py:20
#: changedetectionio/widgets/ternary_boolean.py:74
msgid "Main settings"
msgstr "Impostazioni principali"
#: changedetectionio/templates/_common_fields.html:11
msgid "Show token/placeholders"
msgstr ""
#: changedetectionio/templates/_common_fields.html:18
msgid "Token"
msgstr ""
#: changedetectionio/templates/_common_fields.html:19
msgid "Description"
msgstr ""
#: changedetectionio/templates/_common_fields.html:128
msgid "Show advanced help and tips"
msgstr ""
#: changedetectionio/templates/_common_fields.html:138
#, fuzzy
msgid "Send test notification"
msgstr "Usa notifica predefinita"
#: changedetectionio/templates/_common_fields.html:140
msgid "Add email"
msgstr ""
#: changedetectionio/templates/_common_fields.html:140
msgid "Add an email address"
msgstr ""
#: changedetectionio/templates/_common_fields.html:142
#, fuzzy
msgid "Notification debug logs"
msgstr "Notifiche"
#: changedetectionio/templates/_common_fields.html:144
#, fuzzy
msgid "Processing.."
msgstr "Processore"
#: changedetectionio/templates/_common_fields.html:151
#, fuzzy
msgid "Title for all notifications"
msgstr "Usa notifica predefinita"
#: changedetectionio/templates/_common_fields.html:176
#, fuzzy
msgid "Format for all notifications"
msgstr "Usa notifica predefinita"
#: changedetectionio/templates/edit/text-options.html:9
msgid "Text to wait for before triggering a change/notification, all text and regex are tested case-insensitive."
msgstr ""
#: changedetectionio/templates/edit/text-options.html:10
msgid "Trigger text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:11
msgid "Each line is processed separately (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:12
msgid "Note: Wrap in forward slash / to use regex example:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:23
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:24
msgid "Each line processed separately, any line matching will be ignored (removed before creating the checksum)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:25
msgid "Regular Expression support, wrap the entire line in forward slash"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:26
msgid "Changing this will affect the comparison checksum which may trigger an alert"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:43
msgid "Block change-detection while this text is on the page, all text and regex are tested case-insensitive, good for waiting for when a product is available again"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:44
msgid "Block text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:45
msgid "All lines here must not exist (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:58
msgid "Extracts text in the final output (line by line) after other filters using regular expressions or string match:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:60
msgid "Regular expression - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:61
msgid "Don't forget to consider the white-space at the start of a line"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
#, fuzzy
msgid "Use"
msgstr "Pausa"
#: changedetectionio/templates/edit/text-options.html:62
msgid "type flags (more"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
#, fuzzy
msgid "information here"
msgstr "Nessuna informazione"
#: changedetectionio/templates/edit/text-options.html:63
msgid "Keyword example - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "Use groups to extract just that text - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "returns a list of years only"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:65
msgid "Example - match lines containing a keyword"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:68
msgid "One line per regular-expression/string match"
msgstr ""
#~ msgid "Entry"
#~ msgstr ""
#~ msgid "Actions"
#~ msgstr "Condizioni"
#~ msgid "Add a row/rule after"
#~ msgstr ""
#~ msgid "Remove this row/rule"
#~ msgstr ""
#~ msgid "Verify this rule against current snapshot"
#~ msgstr ""
#~ msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
#~ msgstr ""
#~ msgid "Alternatively try our"
#~ msgstr ""
#~ msgid "very affordable subscription based service which has all this setup for you"
#~ msgstr ""
#~ msgid "You may need to"
#~ msgstr ""
#~ msgid "Enable playwright environment variable"
#~ msgstr ""
#~ msgid "and uncomment the"
#~ msgstr ""
#~ msgid "in the"
#~ msgstr "Silenzia"
#~ msgid "file"
#~ msgstr "Titolo"
#~ msgid "Set a hourly/week day schedule"
#~ msgstr ""
#~ msgid "Schedule time limits"
#~ msgstr "Tempo di ricontrollo (minuti)"
#~ msgid "Business hours"
#~ msgstr ""
#~ msgid "Weekends"
#~ msgstr "Settimane"
#~ msgid "Reset"
#~ msgstr "Richiesta"
#~ msgid "Warning, one or more of your 'days' has a duration that would extend into the next day."
#~ msgstr ""
#~ msgid "This could have unintended consequences."
#~ msgstr ""
#~ msgid "More help and examples about using the scheduler"
#~ msgstr ""
#~ msgid "Want to use a time schedule?"
#~ msgstr "Usa pianificazione oraria"
#~ msgid "First confirm/save your Time Zone Settings"
#~ msgstr ""
#~ msgid "Triggers a change if this text appears, AND something changed in the document."
#~ msgstr ""
#~ msgid "Triggered text"
#~ msgstr "Ignora testo"
#~ msgid "Ignored for calculating changes, but still shown."
#~ msgstr ""
#~ msgid "Ignored text"
#~ msgstr "Ignora testo"
#~ msgid "No change-detection will occur because this text exists."
#~ msgstr "Blocca rilevamento modifiche quando il testo corrisponde"
#~ msgid "Blocked text"
#~ msgstr "Ignora testo"
#~ msgid "Watch List"
#~ msgstr "Lista Monitoraggi"
#~ msgid "Watches"
#~ msgstr "Monitoraggi"
#~ msgid "Queue Status"
#~ msgstr ""
#~ msgid "Queue"
#~ msgstr "In coda"
#~ msgid "Sitemap Crawler"
#~ msgstr ""
#~ msgid "Sitemap"
#~ msgstr ""
#~ msgid "Search"
#~ msgstr "Ricerca in corso"
#~ msgid "URL or Title"
#~ msgstr ""
#~ msgid "in"
#~ msgstr "Info"
#~ msgid "Enter search term..."
#~ msgstr ""

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-01-03 14:31+0100\n"
"POT-Creation-Date: 2026-01-02 16:07+0100\n"
"PO-Revision-Date: 2026-01-02 11:40+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: ko\n"
@@ -19,35 +19,31 @@ msgstr ""
"Generated-By: Babel 2.17.0\n"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:241
#: changedetectionio/flask_app.py:214 changedetectionio/flask_app.py:226
#: changedetectionio/flask_app.py:247
#: changedetectionio/flask_app.py:213 changedetectionio/flask_app.py:225
#: changedetectionio/flask_app.py:246
#: changedetectionio/realtime/socket_server.py:171
msgid "Not yet"
msgstr "아직 아님"
#: changedetectionio/flask_app.py:534
msgid "Already logged in"
msgstr ""
#: changedetectionio/flask_app.py:536
#: changedetectionio/flask_app.py:468
msgid "You must be logged in, please log in."
msgstr ""
#: changedetectionio/flask_app.py:551
#: changedetectionio/flask_app.py:495
msgid "Already logged in"
msgstr ""
#: changedetectionio/flask_app.py:522
#, fuzzy
msgid "Incorrect password"
msgstr "비밀번호"
#: changedetectionio/forms.py:63 changedetectionio/forms.py:243
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified."
msgstr ""
#: changedetectionio/forms.py:64
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified when not using global settings."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified when not using global settings."
msgstr ""
#: changedetectionio/forms.py:164
@@ -380,9 +376,8 @@ msgid "Muted"
msgstr "무음"
#: changedetectionio/forms.py:832
#, fuzzy
msgid "On"
msgstr "없음"
msgstr "켜짐"
#: changedetectionio/forms.py:833
msgid "Attach screenshot to notification (where possible)"
@@ -617,8 +612,6 @@ msgid "Backups were deleted."
msgstr ""
#: changedetectionio/blueprint/backups/templates/overview.html:6
#: changedetectionio/templates/base.html:282
#: changedetectionio/templates/base.html:290
msgid "Backups"
msgstr "백업"
@@ -627,9 +620,7 @@ msgid "A backup is running!"
msgstr "백업이 실행 중입니다!"
#: changedetectionio/blueprint/backups/templates/overview.html:13
msgid ""
"Here you can download and request a new backup, when a backup is "
"completed you will see it listed below."
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:19
@@ -649,9 +640,7 @@ msgid "Remove backups"
msgstr "백업 삭제"
#: changedetectionio/blueprint/imports/importer.py:45
msgid ""
"Importing 5,000 of the first URLs from your list, the rest can be "
"imported again."
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
msgstr ""
#: changedetectionio/blueprint/imports/importer.py:78
@@ -686,9 +675,7 @@ msgstr ""
#: changedetectionio/blueprint/imports/importer.py:214
#: changedetectionio/blueprint/imports/importer.py:297
#, python-brace-format
msgid ""
"Error processing row number {}, check all cell data types are correct, "
"row was skipped."
msgid "Error processing row number {}, check all cell data types are correct, row was skipped."
msgstr ""
#: changedetectionio/blueprint/imports/importer.py:218
@@ -714,9 +701,7 @@ msgid ".XLSX & Wachete"
msgstr ".XLSX 및 와체테"
#: changedetectionio/blueprint/imports/templates/import.html:20
msgid ""
"Enter one URL per line, and optionally add tags for each URL after a "
"space, delineated by comma (,):"
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:22
@@ -728,9 +713,7 @@ msgid "URLs which do not pass validation will stay in the textarea."
msgstr "유효성 검사를 통과하지 못한 URL은 텍스트 영역에 유지됩니다."
#: changedetectionio/blueprint/imports/templates/import.html:44
msgid ""
"Copy and Paste your Distill.io watch 'export' file, this should be a JSON"
" file."
msgid "Copy and Paste your Distill.io watch 'export' file, this should be a JSON file."
msgstr ""
#: changedetectionio/blueprint/imports/templates/import.html:45
@@ -1026,9 +1009,7 @@ msgid "Watch group / tag"
msgstr "감시 그룹/태그"
#: changedetectionio/blueprint/tags/templates/groups-overview.html:21
msgid ""
"Groups allows you to manage filters and notifications for multiple "
"watches under a single organisational tag."
msgid "Groups allows you to manage filters and notifications for multiple watches under a single organisational tag."
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
@@ -1054,9 +1035,7 @@ msgstr "그룹을 삭제하시겠습니까?"
#: changedetectionio/blueprint/tags/templates/groups-overview.html:59
#, python-format
msgid ""
"<p>Are you sure you want to delete group "
"<strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete group <strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:60
@@ -1076,10 +1055,7 @@ msgstr "그룹을 연결 해제하시겠습니까?"
#: changedetectionio/blueprint/tags/templates/groups-overview.html:67
#, python-format
msgid ""
"<p>Are you sure you want to unlink all watches from group "
"<strong>%(title)s</strong>?</p><p>The tag will be kept but watches will "
"be removed from it.</p>"
msgid "<p>Are you sure you want to unlink all watches from group <strong>%(title)s</strong>?</p><p>The tag will be kept but watches will be removed from it.</p>"
msgstr ""
#: changedetectionio/blueprint/tags/templates/groups-overview.html:68
@@ -1200,9 +1176,7 @@ msgstr ""
#: changedetectionio/blueprint/ui/__init__.py:330
#, python-brace-format
msgid ""
"Could not share, something went wrong while communicating with the share "
"server - {}"
msgid "Could not share, something went wrong while communicating with the share server - {}"
msgstr ""
#: changedetectionio/blueprint/ui/diff.py:93
@@ -1215,9 +1189,7 @@ msgid "No history found for the specified link, bad link?"
msgstr ""
#: changedetectionio/blueprint/ui/diff.py:98
msgid ""
"Not enough history (2 snapshots required) to show difference page for "
"this watch."
msgid "Not enough history (2 snapshots required) to show difference page for this watch."
msgstr ""
#: changedetectionio/blueprint/ui/edit.py:35
@@ -1266,9 +1238,7 @@ msgid "Watch added."
msgstr ""
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:12
msgid ""
"This will remove version history (snapshots) for ALL watches, but keep "
"your list of URLs!"
msgid "This will remove version history (snapshots) for ALL watches, but keep your list of URLs!"
msgstr ""
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:13
@@ -1304,8 +1274,7 @@ msgid "Clear History!"
msgstr "기록 지우기"
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:39
#: changedetectionio/templates/base.html:379
#: changedetectionio/templates/base.html:399
#: changedetectionio/templates/base.html:274
msgid "Cancel"
msgstr "취소"
@@ -1451,9 +1420,7 @@ msgstr "공유하거나 무시 목록에 추가할 텍스트를 강조 표시합
#: changedetectionio/blueprint/ui/templates/diff.html:144
#: changedetectionio/blueprint/ui/templates/preview.html:80
msgid ""
"For now, Differences are performed on text, not graphically, only the "
"latest screenshot is available."
msgid "For now, Differences are performed on text, not graphically, only the latest screenshot is available."
msgstr ""
#: changedetectionio/blueprint/ui/templates/diff.html:149
@@ -1515,9 +1482,7 @@ msgid "Organisational tag/group name used in the main listing page"
msgstr "기본 목록 페이지에 사용되는 조직 태그/그룹 이름"
#: changedetectionio/blueprint/ui/templates/edit.html:85
msgid ""
"Automatically uses the page title if found, you can also use your own "
"title/description here"
msgid "Automatically uses the page title if found, you can also use your own title/description here"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:95
@@ -1525,10 +1490,7 @@ msgid "The interval/amount of time between each check."
msgstr "각 확인 사이의 간격/시간입니다."
#: changedetectionio/blueprint/ui/templates/edit.html:110
msgid ""
"Sends a notification when the filter can no longer be seen on the page, "
"good for knowing when the page changed and your filter will not work "
"anymore."
msgid "Sends a notification when the filter can no longer be seen on the page, good for knowing when the page changed and your filter will not work anymore."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:123
@@ -1540,9 +1502,7 @@ msgid "Basic"
msgstr "기초적인"
#: changedetectionio/blueprint/ui/templates/edit.html:123
msgid ""
"method (default) where your watched site doesn't need Javascript to "
"render."
msgid "method (default) where your watched site doesn't need Javascript to render."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:124
@@ -1554,9 +1514,7 @@ msgid "Chrome/Javascript"
msgstr "크롬/자바스크립트"
#: changedetectionio/blueprint/ui/templates/edit.html:124
msgid ""
"method requires a network connection to a running WebDriver+Chrome "
"server, set by the ENV var 'WEBDRIVER_URL'."
msgid "method requires a network connection to a running WebDriver+Chrome server, set by the ENV var 'WEBDRIVER_URL'."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:125
@@ -1572,9 +1530,7 @@ msgid "Choose a proxy for this watch"
msgstr "이 시계에 대한 RSS 피드"
#: changedetectionio/blueprint/ui/templates/edit.html:143
msgid ""
"If you're having trouble waiting for the page to be fully rendered (text "
"missing etc), try increasing the 'wait' time here."
msgid "If you're having trouble waiting for the page to be fully rendered (text missing etc), try increasing the 'wait' time here."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:145
@@ -1595,9 +1551,7 @@ msgid "Show advanced options"
msgstr "고급 옵션 표시"
#: changedetectionio/blueprint/ui/templates/edit.html:157
msgid ""
"Run this code before performing change detection, handy for filling in "
"fields and other actions"
msgid "Run this code before performing change detection, handy for filling in fields and other actions"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:158
@@ -1654,9 +1608,7 @@ msgid "Visual Selector data is not ready, watch needs to be checked atleast once
msgstr "시각적 선택기 데이터가 준비되지 않았습니다. 시계를 한 번 이상 확인해야 합니다."
#: changedetectionio/blueprint/ui/templates/edit.html:253
msgid ""
"Sorry, this functionality only works with fetchers that support "
"interactive Javascript (so far only Playwright based fetchers)"
msgid "Sorry, this functionality only works with fetchers that support interactive Javascript (so far only Playwright based fetchers)"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:254
@@ -1674,9 +1626,7 @@ msgid "to one that supports interactive Javascript."
msgstr "대화형 Javascript를 지원하는 것입니다."
#: changedetectionio/blueprint/ui/templates/edit.html:297
msgid ""
"Use the verify (✓) button to test if a condition passes against the "
"current snapshot."
msgid "Use the verify (✓) button to test if a condition passes against the current snapshot."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:298
@@ -1704,9 +1654,7 @@ msgid "Limit trigger/ignore/block/extract to;"
msgstr "트리거/무시/차단/추출을 다음으로 제한합니다."
#: changedetectionio/blueprint/ui/templates/edit.html:326
msgid ""
"Note: Depending on the length and similarity of the text on each line, "
"the algorithm may consider an"
msgid "Note: Depending on the length and similarity of the text on each line, the algorithm may consider an"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:326
@@ -1747,16 +1695,11 @@ msgid "Only trigger when unique lines appear"
msgstr "고유한 줄이 나타날 때만 트리거됩니다."
#: changedetectionio/blueprint/ui/templates/edit.html:332
msgid ""
"Good for websites that just move the content around, and you want to know"
" when NEW content is added, compares new lines against all history for "
"this watch."
msgid "Good for websites that just move the content around, and you want to know when NEW content is added, compares new lines against all history for this watch."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:340
msgid ""
"Helps reduce changes detected caused by sites shuffling lines around, "
"combine with"
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:340
@@ -1786,9 +1729,7 @@ msgid "text"
msgstr "텍스트"
#: changedetectionio/blueprint/ui/templates/edit.html:386
msgid ""
"elements that will be used for the change detection. It automatically "
"fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgid "elements that will be used for the change detection. It automatically fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:386
@@ -1828,9 +1769,7 @@ msgid "Currently:"
msgstr "현재:"
#: changedetectionio/blueprint/ui/templates/edit.html:423
msgid ""
"Sorry, this functionality only works with fetchers that support "
"Javascript and screenshots (such as playwright etc)."
msgid "Sorry, this functionality only works with fetchers that support Javascript and screenshots (such as playwright etc)."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:424
@@ -1886,9 +1825,7 @@ msgid "Are you sure you want to clear all history for:"
msgstr "정말로 다음의 기록을 모두 지우시겠습니까?"
#: changedetectionio/blueprint/ui/templates/edit.html:496
msgid ""
"This will remove all snapshots and previous versions. This action cannot "
"be undone."
msgid "This will remove all snapshots and previous versions. This action cannot be undone."
msgstr ""
#: changedetectionio/blueprint/ui/templates/edit.html:497
@@ -1912,9 +1849,7 @@ msgid "Current erroring screenshot from most recent request"
msgstr "가장 최근 요청의 현재 오류 스크린샷"
#: changedetectionio/blueprint/ui/templates/preview.html:91
msgid ""
"Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc "
") that supports screenshots."
msgid "Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc ) that supports screenshots."
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:31
@@ -1983,9 +1918,7 @@ msgid "Clear Histories"
msgstr "기록 지우기"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:66
msgid ""
"<p>Are you sure you want to clear history for the selected "
"items?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to clear history for the selected items?</p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:67
@@ -2001,9 +1934,7 @@ msgid "Delete Watches?"
msgstr "시계를 삭제하시겠습니까?"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:72
msgid ""
"<p>Are you sure you want to delete the selected "
"watches?</strong></p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete the selected watches?</strong></p><p>This action cannot be undone.</p>"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:78
@@ -2036,7 +1967,7 @@ msgid "Changed"
msgstr "변경됨"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
msgid "No website watches configured, please add a URL in the box above, or"
msgid "No web page change detection watches configured, please add a URL in the box above, or"
msgstr "구성된 웹사이트 시계가 없습니다. 위 상자에 URL을 추가하세요. 또는"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
@@ -2064,7 +1995,7 @@ msgid "No information"
msgstr "정보 없음"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:234
#: changedetectionio/templates/base.html:353
#: changedetectionio/templates/base.html:248
msgid "Checking now"
msgstr "지금 확인 중"
@@ -2250,267 +2181,226 @@ msgstr "웹페이지 텍스트/HTML, JSON 및 PDF 변경"
msgid "Detects all text changes where possible"
msgstr "가능한 경우 모든 텍스트 변경 사항을 감지합니다."
#: changedetectionio/templates/_helpers.html:25
msgid "Entry"
msgstr ""
#: changedetectionio/templates/_helpers.html:153
#, fuzzy
msgid "Actions"
msgstr "정황"
#: changedetectionio/templates/_helpers.html:172
msgid "Add a row/rule after"
msgstr ""
#: changedetectionio/templates/_helpers.html:173
msgid "Remove this row/rule"
msgstr ""
#: changedetectionio/templates/_helpers.html:174
msgid "Verify this rule against current snapshot"
msgstr ""
#: changedetectionio/templates/_helpers.html:184
msgid ""
"Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but "
"Chrome based fetching is not enabled."
msgstr ""
#: changedetectionio/templates/_helpers.html:184
msgid "Alternatively try our"
msgstr ""
#: changedetectionio/templates/_helpers.html:184
msgid ""
"very affordable subscription based service which has all this setup for "
"you"
msgstr ""
#: changedetectionio/templates/_helpers.html:185
#, fuzzy
msgid "You may need to"
msgstr "당신은"
#: changedetectionio/templates/_helpers.html:185
msgid "Enable playwright environment variable"
msgstr ""
#: changedetectionio/templates/_helpers.html:185
msgid "and uncomment the"
msgstr ""
#: changedetectionio/templates/_helpers.html:185
#, fuzzy
msgid "in the"
msgstr "그만큼"
#: changedetectionio/templates/_helpers.html:185
#, fuzzy
msgid "file"
msgstr "제목"
#: changedetectionio/templates/_helpers.html:240
msgid "Set a hourly/week day schedule"
msgstr ""
#: changedetectionio/templates/_helpers.html:247
#, fuzzy
msgid "Schedule time limits"
msgstr "재확인 시간(분)"
#: changedetectionio/templates/_helpers.html:248
msgid "Business hours"
msgstr ""
#: changedetectionio/templates/_helpers.html:249
#, fuzzy
msgid "Weekends"
msgstr "주"
#: changedetectionio/templates/_helpers.html:250
#, fuzzy
msgid "Reset"
msgstr "요구"
#: changedetectionio/templates/_helpers.html:259
msgid ""
"Warning, one or more of your 'days' has a duration that would extend into"
" the next day."
msgstr ""
#: changedetectionio/templates/_helpers.html:260
msgid "This could have unintended consequences."
msgstr ""
#: changedetectionio/templates/_helpers.html:270
#, fuzzy
msgid "More help and examples about using the scheduler"
msgstr "여기에 더 많은 도움말과 예시가 있습니다."
#: changedetectionio/templates/_helpers.html:275
#, fuzzy
msgid "Want to use a time schedule?"
msgstr "시간 스케줄러 사용"
#: changedetectionio/templates/_helpers.html:275
msgid "First confirm/save your Time Zone Settings"
msgstr ""
#: changedetectionio/templates/_helpers.html:284
msgid ""
"Triggers a change if this text appears, AND something changed in the "
"document."
msgstr ""
#: changedetectionio/templates/_helpers.html:284
#, fuzzy
msgid "Triggered text"
msgstr "오류 텍스트"
#: changedetectionio/templates/_helpers.html:285
msgid "Ignored for calculating changes, but still shown."
msgstr ""
#: changedetectionio/templates/_helpers.html:285
#, fuzzy
msgid "Ignored text"
msgstr "오류 텍스트"
#: changedetectionio/templates/_helpers.html:286
#, fuzzy
msgid "No change-detection will occur because this text exists."
msgstr "텍스트가 일치하는 동안 변경 감지 차단"
#: changedetectionio/templates/_helpers.html:286
#, fuzzy
msgid "Blocked text"
msgstr "오류 텍스트"
#: changedetectionio/templates/base.html:78
#: changedetectionio/templates/base.html:168
#: changedetectionio/templates/base.html:77
msgid "GROUPS"
msgstr "여러 떼"
#: changedetectionio/templates/base.html:81
#: changedetectionio/templates/base.html:169
#: changedetectionio/templates/base.html:80
msgid "SETTINGS"
msgstr "설정"
#: changedetectionio/templates/base.html:84
#: changedetectionio/templates/base.html:170
#: changedetectionio/templates/base.html:83
msgid "IMPORT"
msgstr "가져오기"
#: changedetectionio/templates/base.html:87
#: changedetectionio/templates/base.html:171
#: changedetectionio/templates/base.html:86
msgid "BACKUPS"
msgstr "백업"
#: changedetectionio/templates/base.html:91
#: changedetectionio/templates/base.html:173
#: changedetectionio/templates/base.html:90
msgid "EDIT"
msgstr "편집하다"
#: changedetectionio/templates/base.html:101
#: changedetectionio/templates/base.html:177
#: changedetectionio/templates/base.html:100
msgid "LOG OUT"
msgstr "로그아웃"
#: changedetectionio/templates/base.html:108
#: changedetectionio/templates/base.html:109
msgid "Search, or Use Alt+S Key"
msgstr "검색 또는 Alt+S 키 사용"
#: changedetectionio/templates/base.html:114
#: changedetectionio/templates/base.html:116
msgid "Toggle Light/Dark Mode"
msgstr "밝은/어두운 모드 전환"
#: changedetectionio/templates/base.html:115
#: changedetectionio/templates/base.html:117
msgid "Toggle light/dark mode"
msgstr "밝은/어두운 모드 전환"
#: changedetectionio/templates/base.html:125
#: changedetectionio/templates/base.html:127
msgid "Change Language"
msgstr "언어 변경"
#: changedetectionio/templates/base.html:126
#: changedetectionio/templates/base.html:128
msgid "Change language"
msgstr "언어 변경"
#: changedetectionio/templates/base.html:253
#, fuzzy
msgid "Watch List"
msgstr "모니터 목록"
#: changedetectionio/templates/base.html:258
#, fuzzy
msgid "Watches"
msgstr "모니터"
#: changedetectionio/templates/base.html:261
msgid "Queue Status"
msgstr ""
#: changedetectionio/templates/base.html:270
#, fuzzy
msgid "Queue"
msgstr "대기 중"
#: changedetectionio/templates/base.html:274
#: changedetectionio/templates/base.html:279
#, fuzzy
msgid "Settings"
msgstr "설정"
#: changedetectionio/templates/base.html:293
msgid "Sitemap Crawler"
msgstr ""
#: changedetectionio/templates/base.html:318
msgid "Sitemap"
msgstr ""
#: changedetectionio/templates/base.html:354
#: changedetectionio/templates/base.html:249
msgid "Real-time updates offline"
msgstr "실시간 업데이트 오프라인"
#: changedetectionio/templates/base.html:364
#: changedetectionio/templates/base.html:259
msgid "Select Language"
msgstr "언어 선택"
#: changedetectionio/templates/base.html:375
msgid ""
"Language support is in beta, please help us improve by opening a PR on "
"GitHub with any updates."
#: changedetectionio/templates/base.html:270
msgid "Language support is in beta, please help us improve by opening a PR on GitHub with any updates."
msgstr ""
#: changedetectionio/templates/base.html:387
#: changedetectionio/templates/base.html:400
#, fuzzy
msgid "Search"
msgstr "수색"
#: changedetectionio/templates/base.html:392
msgid "URL or Title"
msgstr ""
#: changedetectionio/templates/base.html:392
#, fuzzy
msgid "in"
msgstr "추가 정보"
#: changedetectionio/templates/base.html:393
msgid "Enter search term..."
msgstr ""
#: changedetectionio/templates/login.html:11
#: changedetectionio/templates/login.html:10
msgid "Password"
msgstr "비밀번호"
#: changedetectionio/templates/login.html:17
#: changedetectionio/templates/login.html:16
msgid "Login"
msgstr "로그인"
#: changedetectionio/widgets/ternary_boolean.py:18
#: changedetectionio/widgets/ternary_boolean.py:72
msgid "Yes"
msgstr "예"
#: changedetectionio/widgets/ternary_boolean.py:19
#: changedetectionio/widgets/ternary_boolean.py:73
msgid "No"
msgstr "아니오"
#: changedetectionio/widgets/ternary_boolean.py:20
#: changedetectionio/widgets/ternary_boolean.py:74
msgid "Main settings"
msgstr "기본 설정"
#: changedetectionio/templates/_common_fields.html:11
msgid "Show token/placeholders"
msgstr ""
#: changedetectionio/templates/_common_fields.html:18
msgid "Token"
msgstr ""
#: changedetectionio/templates/_common_fields.html:19
#, fuzzy
msgid "Description"
msgstr "덧셈"
#: changedetectionio/templates/_common_fields.html:128
#, fuzzy
msgid "Show advanced help and tips"
msgstr "고급 옵션 표시"
#: changedetectionio/templates/_common_fields.html:138
#, fuzzy
msgid "Send test notification"
msgstr "기본 알림 사용"
#: changedetectionio/templates/_common_fields.html:140
msgid "Add email"
msgstr ""
#: changedetectionio/templates/_common_fields.html:140
msgid "Add an email address"
msgstr ""
#: changedetectionio/templates/_common_fields.html:142
#, fuzzy
msgid "Notification debug logs"
msgstr "알림 디버그 로그"
#: changedetectionio/templates/_common_fields.html:144
#, fuzzy
msgid "Processing.."
msgstr "프로세서"
#: changedetectionio/templates/_common_fields.html:151
#, fuzzy
msgid "Title for all notifications"
msgstr "기본 알림 사용"
#: changedetectionio/templates/_common_fields.html:176
#, fuzzy
msgid "Format for all notifications"
msgstr "기본 알림 사용"
#: changedetectionio/templates/edit/text-options.html:9
msgid "Text to wait for before triggering a change/notification, all text and regex are tested case-insensitive."
msgstr ""
#: changedetectionio/templates/edit/text-options.html:10
msgid "Trigger text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:11
msgid "Each line is processed separately (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:12
msgid "Note: Wrap in forward slash / to use regex example:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:23
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:24
msgid "Each line processed separately, any line matching will be ignored (removed before creating the checksum)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:25
msgid "Regular Expression support, wrap the entire line in forward slash"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:26
msgid "Changing this will affect the comparison checksum which may trigger an alert"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:43
msgid "Block change-detection while this text is on the page, all text and regex are tested case-insensitive, good for waiting for when a product is available again"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:44
msgid "Block text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:45
msgid "All lines here must not exist (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:58
msgid "Extracts text in the final output (line by line) after other filters using regular expressions or string match:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:60
msgid "Regular expression - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:61
msgid "Don't forget to consider the white-space at the start of a line"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
#, fuzzy
msgid "Use"
msgstr "정지시키다"
#: changedetectionio/templates/edit/text-options.html:62
msgid "type flags (more"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
#, fuzzy
msgid "information here"
msgstr "정보 없음"
#: changedetectionio/templates/edit/text-options.html:63
msgid "Keyword example - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "Use groups to extract just that text - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "returns a list of years only"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:65
msgid "Example - match lines containing a keyword"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:68
msgid "One line per regular-expression/string match"
msgstr ""
#~ msgid "Invalid time format. Use HH:MM."
#~ msgstr "시간 형식이 잘못되었습니다. HH:MM을 사용하세요."
@@ -2892,9 +2782,7 @@ msgstr "로그인"
#~ msgid "Visual / Image screenshot change detection"
#~ msgstr "시각적/이미지 스크린샷 변경 감지"
#~ msgid ""
#~ "Compares screenshots using fast OpenCV "
#~ "algorithm, 10-100x faster than SSIM"
#~ msgid "Compares screenshots using fast OpenCV algorithm, 10-100x faster than SSIM"
#~ msgstr "SSIM보다 10~100배 빠른 빠른 OpenCV 알고리즘을 사용하여 스크린샷을 비교합니다."
#~ msgid "Visual"
@@ -2915,3 +2803,120 @@ msgstr "로그인"
#~ msgid "Detects all text changes where possible"
#~ msgstr "가능한 경우 모든 텍스트 변경 사항을 감지합니다."
#~ msgid "Entry"
#~ msgstr ""
#~ msgid "Actions"
#~ msgstr "정황"
#~ msgid "Add a row/rule after"
#~ msgstr ""
#~ msgid "Remove this row/rule"
#~ msgstr ""
#~ msgid "Verify this rule against current snapshot"
#~ msgstr ""
#~ msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
#~ msgstr ""
#~ msgid "Alternatively try our"
#~ msgstr ""
#~ msgid "very affordable subscription based service which has all this setup for you"
#~ msgstr ""
#~ msgid "You may need to"
#~ msgstr "당신은"
#~ msgid "Enable playwright environment variable"
#~ msgstr ""
#~ msgid "and uncomment the"
#~ msgstr ""
#~ msgid "in the"
#~ msgstr "그만큼"
#~ msgid "file"
#~ msgstr "제목"
#~ msgid "Set a hourly/week day schedule"
#~ msgstr ""
#~ msgid "Schedule time limits"
#~ msgstr "재확인 시간(분)"
#~ msgid "Business hours"
#~ msgstr ""
#~ msgid "Weekends"
#~ msgstr "주"
#~ msgid "Reset"
#~ msgstr "요구"
#~ msgid "Warning, one or more of your 'days' has a duration that would extend into the next day."
#~ msgstr ""
#~ msgid "This could have unintended consequences."
#~ msgstr ""
#~ msgid "More help and examples about using the scheduler"
#~ msgstr "여기에 더 많은 도움말과 예시가 있습니다."
#~ msgid "Want to use a time schedule?"
#~ msgstr "시간 스케줄러 사용"
#~ msgid "First confirm/save your Time Zone Settings"
#~ msgstr ""
#~ msgid "Triggers a change if this text appears, AND something changed in the document."
#~ msgstr ""
#~ msgid "Triggered text"
#~ msgstr "오류 텍스트"
#~ msgid "Ignored for calculating changes, but still shown."
#~ msgstr ""
#~ msgid "Ignored text"
#~ msgstr "오류 텍스트"
#~ msgid "No change-detection will occur because this text exists."
#~ msgstr "텍스트가 일치하는 동안 변경 감지 차단"
#~ msgid "Blocked text"
#~ msgstr "오류 텍스트"
#~ msgid "Watch List"
#~ msgstr "모니터 목록"
#~ msgid "Watches"
#~ msgstr "모니터"
#~ msgid "Queue Status"
#~ msgstr ""
#~ msgid "Queue"
#~ msgstr "대기 중"
#~ msgid "Sitemap Crawler"
#~ msgstr ""
#~ msgid "Sitemap"
#~ msgstr ""
#~ msgid "Search"
#~ msgstr "수색"
#~ msgid "URL or Title"
#~ msgstr ""
#~ msgid "in"
#~ msgstr "추가 정보"
#~ msgid "Enter search term..."
#~ msgstr ""

View File

@@ -1988,7 +1988,7 @@ msgid "Changed"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
msgid "No website watches configured, please add a URL in the box above, or"
msgid "No web page change detection watches configured, please add a URL in the box above, or"
msgstr ""
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
@@ -2265,3 +2265,150 @@ msgstr ""
msgid "Login"
msgstr ""
#: changedetectionio/widgets/ternary_boolean.py:18
#: changedetectionio/widgets/ternary_boolean.py:72
msgid "Yes"
msgstr ""
#: changedetectionio/widgets/ternary_boolean.py:19
#: changedetectionio/widgets/ternary_boolean.py:73
msgid "No"
msgstr ""
#: changedetectionio/widgets/ternary_boolean.py:20
#: changedetectionio/widgets/ternary_boolean.py:74
msgid "Main settings"
msgstr ""
#: changedetectionio/templates/_common_fields.html:11
msgid "Show token/placeholders"
msgstr ""
#: changedetectionio/templates/_common_fields.html:18
msgid "Token"
msgstr ""
#: changedetectionio/templates/_common_fields.html:19
msgid "Description"
msgstr ""
#: changedetectionio/templates/_common_fields.html:128
msgid "Show advanced help and tips"
msgstr ""
#: changedetectionio/templates/_common_fields.html:138
msgid "Send test notification"
msgstr ""
#: changedetectionio/templates/_common_fields.html:140
msgid "Add email"
msgstr ""
#: changedetectionio/templates/_common_fields.html:140
msgid "Add an email address"
msgstr ""
#: changedetectionio/templates/_common_fields.html:142
msgid "Notification debug logs"
msgstr ""
#: changedetectionio/templates/_common_fields.html:144
msgid "Processing.."
msgstr ""
#: changedetectionio/templates/_common_fields.html:151
msgid "Title for all notifications"
msgstr ""
#: changedetectionio/templates/_common_fields.html:176
msgid "Format for all notifications"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:9
msgid "Text to wait for before triggering a change/notification, all text and regex are tested case-insensitive."
msgstr ""
#: changedetectionio/templates/edit/text-options.html:10
msgid "Trigger text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:11
msgid "Each line is processed separately (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:12
msgid "Note: Wrap in forward slash / to use regex example:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:23
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:24
msgid "Each line processed separately, any line matching will be ignored (removed before creating the checksum)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:25
msgid "Regular Expression support, wrap the entire line in forward slash"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:26
msgid "Changing this will affect the comparison checksum which may trigger an alert"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:43
msgid "Block change-detection while this text is on the page, all text and regex are tested case-insensitive, good for waiting for when a product is available again"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:44
msgid "Block text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:45
msgid "All lines here must not exist (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:58
msgid "Extracts text in the final output (line by line) after other filters using regular expressions or string match:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:60
msgid "Regular expression - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:61
msgid "Don't forget to consider the white-space at the start of a line"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
msgid "Use"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
msgid "type flags (more"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
msgid "information here"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:63
msgid "Keyword example - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "Use groups to extract just that text - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "returns a list of years only"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:65
msgid "Example - match lines containing a keyword"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:68
msgid "One line per regular-expression/string match"
msgstr ""

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-01-03 14:31+0100\n"
"POT-Creation-Date: 2026-01-02 16:07+0100\n"
"PO-Revision-Date: 2026-01-15 12:00+0800\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh_Hant_TW\n"
@@ -19,34 +19,30 @@ msgstr ""
"Generated-By: Babel 2.17.0\n"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:241
#: changedetectionio/flask_app.py:214 changedetectionio/flask_app.py:226
#: changedetectionio/flask_app.py:247
#: changedetectionio/flask_app.py:213 changedetectionio/flask_app.py:225
#: changedetectionio/flask_app.py:246
#: changedetectionio/realtime/socket_server.py:171
msgid "Not yet"
msgstr "還沒有"
#: changedetectionio/flask_app.py:534
msgid "Already logged in"
msgstr "已經登入"
#: changedetectionio/flask_app.py:536
#: changedetectionio/flask_app.py:468
msgid "You must be logged in, please log in."
msgstr "您必須先登入,請登入。"
#: changedetectionio/flask_app.py:551
#: changedetectionio/flask_app.py:495
msgid "Already logged in"
msgstr "已經登入"
#: changedetectionio/flask_app.py:522
msgid "Incorrect password"
msgstr "密碼錯誤"
#: changedetectionio/forms.py:63 changedetectionio/forms.py:243
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified."
msgstr "必須指定至少一個時間間隔(週、天、小時、分鐘或秒)。"
#: changedetectionio/forms.py:64
msgid ""
"At least one time interval (weeks, days, hours, minutes, or seconds) must"
" be specified when not using global settings."
msgid "At least one time interval (weeks, days, hours, minutes, or seconds) must be specified when not using global settings."
msgstr "當不使用全域設定時,必須指定至少一個時間間隔(週、天、小時、分鐘或秒)。"
#: changedetectionio/forms.py:164
@@ -581,8 +577,6 @@ msgid "Backups were deleted."
msgstr "備份已刪除。"
#: changedetectionio/blueprint/backups/templates/overview.html:6
#: changedetectionio/templates/base.html:282
#: changedetectionio/templates/base.html:290
msgid "Backups"
msgstr "備份"
@@ -591,9 +585,7 @@ msgid "A backup is running!"
msgstr "備份正在執行中!"
#: changedetectionio/blueprint/backups/templates/overview.html:13
msgid ""
"Here you can download and request a new backup, when a backup is "
"completed you will see it listed below."
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:19
@@ -613,9 +605,7 @@ msgid "Remove backups"
msgstr "移除備份"
#: changedetectionio/blueprint/imports/importer.py:45
msgid ""
"Importing 5,000 of the first URLs from your list, the rest can be "
"imported again."
msgid "Importing 5,000 of the first URLs from your list, the rest can be imported again."
msgstr "正在匯入清單中的前 5,000 個 URL其餘的可以再次匯入。"
#: changedetectionio/blueprint/imports/importer.py:78
@@ -650,9 +640,7 @@ msgstr "處理第 {} 行時發生錯誤URL 數值不正確,已跳過該行
#: changedetectionio/blueprint/imports/importer.py:214
#: changedetectionio/blueprint/imports/importer.py:297
#, python-brace-format
msgid ""
"Error processing row number {}, check all cell data types are correct, "
"row was skipped."
msgid "Error processing row number {}, check all cell data types are correct, row was skipped."
msgstr "處理第 {} 行時發生錯誤,請檢查所有儲存格資料類型是否正確,已跳過該行。"
#: changedetectionio/blueprint/imports/importer.py:218
@@ -678,9 +666,7 @@ msgid ".XLSX & Wachete"
msgstr ".XLSX 和 Wachete"
#: changedetectionio/blueprint/imports/templates/import.html:20
msgid ""
"Enter one URL per line, and optionally add tags for each URL after a "
"space, delineated by comma (,):"
msgid "Enter one URL per line, and optionally add tags for each URL after a space, delineated by comma (,):"
msgstr "每行輸入一個 URL可選用空格分隔後為每個 URL 新增標籤,標籤間用逗號 (,) 分隔:"
#: changedetectionio/blueprint/imports/templates/import.html:22
@@ -692,9 +678,7 @@ msgid "URLs which do not pass validation will stay in the textarea."
msgstr "未通過驗證的 URL 將保留在文字區塊中。"
#: changedetectionio/blueprint/imports/templates/import.html:44
msgid ""
"Copy and Paste your Distill.io watch 'export' file, this should be a JSON"
" file."
msgid "Copy and Paste your Distill.io watch 'export' file, this should be a JSON file."
msgstr "複製並貼上您的 Distill.io 監測任務「匯出」檔案,這應該是一個 JSON 檔案。"
#: changedetectionio/blueprint/imports/templates/import.html:45
@@ -987,9 +971,7 @@ msgid "Watch group / tag"
msgstr "監測群組 / 標籤"
#: changedetectionio/blueprint/tags/templates/groups-overview.html:21
msgid ""
"Groups allows you to manage filters and notifications for multiple "
"watches under a single organisational tag."
msgid "Groups allows you to manage filters and notifications for multiple watches under a single organisational tag."
msgstr "群組功能讓您能在單一組織標籤下,管理多個監測任務的過濾器與通知設定。"
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
@@ -1015,9 +997,7 @@ msgstr "刪除群組?"
#: changedetectionio/blueprint/tags/templates/groups-overview.html:59
#, python-format
msgid ""
"<p>Are you sure you want to delete group "
"<strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete group <strong>%(title)s</strong>?</p><p>This action cannot be undone.</p>"
msgstr "<p>您確定要刪除群組 <strong>%(title)s</strong> 嗎?</p><p>此動作無法復原。</p>"
#: changedetectionio/blueprint/tags/templates/groups-overview.html:60
@@ -1037,10 +1017,7 @@ msgstr "解除群組連結?"
#: changedetectionio/blueprint/tags/templates/groups-overview.html:67
#, python-format
msgid ""
"<p>Are you sure you want to unlink all watches from group "
"<strong>%(title)s</strong>?</p><p>The tag will be kept but watches will "
"be removed from it.</p>"
msgid "<p>Are you sure you want to unlink all watches from group <strong>%(title)s</strong>?</p><p>The tag will be kept but watches will be removed from it.</p>"
msgstr "<p>您確定要將所有監測任務從群組 <strong>%(title)s</strong> 解除連結嗎?</p><p>標籤將被保留,但監測任務將從中移除。</p>"
#: changedetectionio/blueprint/tags/templates/groups-overview.html:68
@@ -1157,9 +1134,7 @@ msgstr "沒有可複查的監測任務。"
#: changedetectionio/blueprint/ui/__init__.py:330
#, python-brace-format
msgid ""
"Could not share, something went wrong while communicating with the share "
"server - {}"
msgid "Could not share, something went wrong while communicating with the share server - {}"
msgstr "無法分享,與分享伺服器通訊時發生錯誤 - {}"
#: changedetectionio/blueprint/ui/diff.py:93
@@ -1172,9 +1147,7 @@ msgid "No history found for the specified link, bad link?"
msgstr "找不到指定連結的歷史記錄,連結無效?"
#: changedetectionio/blueprint/ui/diff.py:98
msgid ""
"Not enough history (2 snapshots required) to show difference page for "
"this watch."
msgid "Not enough history (2 snapshots required) to show difference page for this watch."
msgstr "歷史記錄不足(需要 2 個快照)以顯示此監測任務的差異頁面。"
#: changedetectionio/blueprint/ui/edit.py:35
@@ -1222,9 +1195,7 @@ msgid "Watch added."
msgstr "監測任務已新增。"
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:12
msgid ""
"This will remove version history (snapshots) for ALL watches, but keep "
"your list of URLs!"
msgid "This will remove version history (snapshots) for ALL watches, but keep your list of URLs!"
msgstr "這將移除「所有」監測任務的版本歷史記錄(快照),但保留您的 URL 列表!"
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:13
@@ -1260,8 +1231,7 @@ msgid "Clear History!"
msgstr "清除歷史記錄!"
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:39
#: changedetectionio/templates/base.html:379
#: changedetectionio/templates/base.html:399
#: changedetectionio/templates/base.html:274
msgid "Cancel"
msgstr "取消"
@@ -1407,9 +1377,7 @@ msgstr "反白文字以分享或新增至忽略列表。"
#: changedetectionio/blueprint/ui/templates/diff.html:144
#: changedetectionio/blueprint/ui/templates/preview.html:80
msgid ""
"For now, Differences are performed on text, not graphically, only the "
"latest screenshot is available."
msgid "For now, Differences are performed on text, not graphically, only the latest screenshot is available."
msgstr "目前,差異比對是針對文字執行,而非圖形,僅提供最新的截圖。"
#: changedetectionio/blueprint/ui/templates/diff.html:149
@@ -1471,9 +1439,7 @@ msgid "Organisational tag/group name used in the main listing page"
msgstr "主列表頁面中使用的組織標籤 / 群組名稱"
#: changedetectionio/blueprint/ui/templates/edit.html:85
msgid ""
"Automatically uses the page title if found, you can also use your own "
"title/description here"
msgid "Automatically uses the page title if found, you can also use your own title/description here"
msgstr "如果找到頁面標題將自動使用,您也可以在此使用您自己的標題 / 描述"
#: changedetectionio/blueprint/ui/templates/edit.html:95
@@ -1481,10 +1447,7 @@ msgid "The interval/amount of time between each check."
msgstr "每次檢查之間的間隔 / 時間量。"
#: changedetectionio/blueprint/ui/templates/edit.html:110
msgid ""
"Sends a notification when the filter can no longer be seen on the page, "
"good for knowing when the page changed and your filter will not work "
"anymore."
msgid "Sends a notification when the filter can no longer be seen on the page, good for knowing when the page changed and your filter will not work anymore."
msgstr "當頁面上找不到過濾器時發送通知,這有助於了解頁面何時變更導致您的過濾器失效。"
#: changedetectionio/blueprint/ui/templates/edit.html:123
@@ -1496,9 +1459,7 @@ msgid "Basic"
msgstr "基本"
#: changedetectionio/blueprint/ui/templates/edit.html:123
msgid ""
"method (default) where your watched site doesn't need Javascript to "
"render."
msgid "method (default) where your watched site doesn't need Javascript to render."
msgstr "方法(預設),適用於您監測的網站不需要 Javascript 渲染的情況。"
#: changedetectionio/blueprint/ui/templates/edit.html:124
@@ -1510,9 +1471,7 @@ msgid "Chrome/Javascript"
msgstr "Chrome / Javascript"
#: changedetectionio/blueprint/ui/templates/edit.html:124
msgid ""
"method requires a network connection to a running WebDriver+Chrome "
"server, set by the ENV var 'WEBDRIVER_URL'."
msgid "method requires a network connection to a running WebDriver+Chrome server, set by the ENV var 'WEBDRIVER_URL'."
msgstr "方法需要連線到執行中的 WebDriver + Chrome 伺服器,由環境變數 'WEBDRIVER_URL' 設定。"
#: changedetectionio/blueprint/ui/templates/edit.html:125
@@ -1528,9 +1487,7 @@ msgid "Choose a proxy for this watch"
msgstr "為此監測任務選擇代理伺服器"
#: changedetectionio/blueprint/ui/templates/edit.html:143
msgid ""
"If you're having trouble waiting for the page to be fully rendered (text "
"missing etc), try increasing the 'wait' time here."
msgid "If you're having trouble waiting for the page to be fully rendered (text missing etc), try increasing the 'wait' time here."
msgstr "如果您在等待頁面完全渲染時遇到問題(文字遺失等),請嘗試在此增加「等待」時間。"
#: changedetectionio/blueprint/ui/templates/edit.html:145
@@ -1551,9 +1508,7 @@ msgid "Show advanced options"
msgstr "顯示進階選項"
#: changedetectionio/blueprint/ui/templates/edit.html:157
msgid ""
"Run this code before performing change detection, handy for filling in "
"fields and other actions"
msgid "Run this code before performing change detection, handy for filling in fields and other actions"
msgstr "在執行變更檢測之前執行此程式碼,方便填寫欄位和其他動作"
#: changedetectionio/blueprint/ui/templates/edit.html:158
@@ -1610,9 +1565,7 @@ msgid "Visual Selector data is not ready, watch needs to be checked atleast once
msgstr "視覺選擇器資料尚未準備好,監測任務至少需要檢查一次。"
#: changedetectionio/blueprint/ui/templates/edit.html:253
msgid ""
"Sorry, this functionality only works with fetchers that support "
"interactive Javascript (so far only Playwright based fetchers)"
msgid "Sorry, this functionality only works with fetchers that support interactive Javascript (so far only Playwright based fetchers)"
msgstr "抱歉,此功能僅適用於支援互動式 Javascript 的抓取器(目前僅限基於 Playwright 的抓取器)"
#: changedetectionio/blueprint/ui/templates/edit.html:254
@@ -1630,9 +1583,7 @@ msgid "to one that supports interactive Javascript."
msgstr "為支援互動式 Javascript 的方式。"
#: changedetectionio/blueprint/ui/templates/edit.html:297
msgid ""
"Use the verify (✓) button to test if a condition passes against the "
"current snapshot."
msgid "Use the verify (✓) button to test if a condition passes against the current snapshot."
msgstr "使用驗證 (✓) 按鈕測試條件是否符合目前的快照。"
#: changedetectionio/blueprint/ui/templates/edit.html:298
@@ -1660,9 +1611,7 @@ msgid "Limit trigger/ignore/block/extract to;"
msgstr "將觸發 / 忽略 / 阻擋 / 提取限制為;"
#: changedetectionio/blueprint/ui/templates/edit.html:326
msgid ""
"Note: Depending on the length and similarity of the text on each line, "
"the algorithm may consider an"
msgid "Note: Depending on the length and similarity of the text on each line, the algorithm may consider an"
msgstr "注意:根據每行文字的長度和相似度,演算法可能會將"
#: changedetectionio/blueprint/ui/templates/edit.html:326
@@ -1703,16 +1652,11 @@ msgid "Only trigger when unique lines appear"
msgstr "僅當出現獨特行時觸發"
#: changedetectionio/blueprint/ui/templates/edit.html:332
msgid ""
"Good for websites that just move the content around, and you want to know"
" when NEW content is added, compares new lines against all history for "
"this watch."
msgid "Good for websites that just move the content around, and you want to know when NEW content is added, compares new lines against all history for this watch."
msgstr "適用於內容僅會移動的網站,且您想知道何時新增了「新」內容,此功能會將新行與此監測任務的所有歷史記錄進行比較。"
#: changedetectionio/blueprint/ui/templates/edit.html:340
msgid ""
"Helps reduce changes detected caused by sites shuffling lines around, "
"combine with"
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr "有助於減少因網站重新排列行而檢測到的變更,結合"
#: changedetectionio/blueprint/ui/templates/edit.html:340
@@ -1742,9 +1686,7 @@ msgid "text"
msgstr "文字"
#: changedetectionio/blueprint/ui/templates/edit.html:386
msgid ""
"elements that will be used for the change detection. It automatically "
"fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgid "elements that will be used for the change detection. It automatically fills-in the filters in the \"CSS/JSONPath/JQ/XPath Filters\" box of the"
msgstr "將用於變更檢測的元素。它會自動填入"
#: changedetectionio/blueprint/ui/templates/edit.html:386
@@ -1784,9 +1726,7 @@ msgid "Currently:"
msgstr "目前:"
#: changedetectionio/blueprint/ui/templates/edit.html:423
msgid ""
"Sorry, this functionality only works with fetchers that support "
"Javascript and screenshots (such as playwright etc)."
msgid "Sorry, this functionality only works with fetchers that support Javascript and screenshots (such as playwright etc)."
msgstr "抱歉,此功能僅適用於支援 Javascript 和截圖的抓取器(如 playwright 等)。"
#: changedetectionio/blueprint/ui/templates/edit.html:424
@@ -1842,9 +1782,7 @@ msgid "Are you sure you want to clear all history for:"
msgstr "您確定要清除以下項目的所有歷史記錄:"
#: changedetectionio/blueprint/ui/templates/edit.html:496
msgid ""
"This will remove all snapshots and previous versions. This action cannot "
"be undone."
msgid "This will remove all snapshots and previous versions. This action cannot be undone."
msgstr "這將移除所有快照和先前版本。此動作無法復原。"
#: changedetectionio/blueprint/ui/templates/edit.html:497
@@ -1868,9 +1806,7 @@ msgid "Current erroring screenshot from most recent request"
msgstr "最近請求的目前錯誤截圖"
#: changedetectionio/blueprint/ui/templates/preview.html:91
msgid ""
"Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc "
") that supports screenshots."
msgid "Screenshot requires a Content Fetcher ( Sockpuppetbrowser, selenium, etc ) that supports screenshots."
msgstr "截圖需要支援截圖的內容抓取器 (Sockpuppetbrowser, selenium 等)。"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:31
@@ -1939,9 +1875,7 @@ msgid "Clear Histories"
msgstr "清除歷史記錄"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:66
msgid ""
"<p>Are you sure you want to clear history for the selected "
"items?</p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to clear history for the selected items?</p><p>This action cannot be undone.</p>"
msgstr "<p>您確定要清除所選項目的歷史記錄嗎?</p><p>此動作無法復原。</p>"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:67
@@ -1957,9 +1891,7 @@ msgid "Delete Watches?"
msgstr "刪除監測任務?"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:72
msgid ""
"<p>Are you sure you want to delete the selected "
"watches?</strong></p><p>This action cannot be undone.</p>"
msgid "<p>Are you sure you want to delete the selected watches?</strong></p><p>This action cannot be undone.</p>"
msgstr "<p>您確定要刪除所選的監測任務嗎?</strong></p><p>此動作無法復原。</p>"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:78
@@ -1992,7 +1924,7 @@ msgid "Changed"
msgstr "變更"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
msgid "No website watches configured, please add a URL in the box above, or"
msgid "No web page change detection watches configured, please add a URL in the box above, or"
msgstr "未設定網站監測任務,請在上方欄位新增 URL或"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
@@ -2020,7 +1952,7 @@ msgid "No information"
msgstr "無資訊"
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:234
#: changedetectionio/templates/base.html:353
#: changedetectionio/templates/base.html:248
msgid "Checking now"
msgstr "正在檢查"
@@ -2203,244 +2135,340 @@ msgstr "網頁文字 / HTML、JSON 和 PDF 變更"
msgid "Detects all text changes where possible"
msgstr "盡可能檢測所有文字變更"
#: changedetectionio/templates/_helpers.html:25
msgid "Entry"
msgstr "項目"
#: changedetectionio/templates/_helpers.html:153
msgid "Actions"
msgstr "動作"
#: changedetectionio/templates/_helpers.html:172
msgid "Add a row/rule after"
msgstr "在後方新增一行 / 規則"
#: changedetectionio/templates/_helpers.html:173
msgid "Remove this row/rule"
msgstr "移除此行 / 規則"
#: changedetectionio/templates/_helpers.html:174
msgid "Verify this rule against current snapshot"
msgstr "針對目前快照驗證此規則"
#: changedetectionio/templates/_helpers.html:184
msgid ""
"Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but "
"Chrome based fetching is not enabled."
msgstr "錯誤 - 此監測任務需要 Chrome搭配 playwright / sockpuppetbrowser但未啟用基於 Chrome 的抓取功能。"
#: changedetectionio/templates/_helpers.html:184
msgid "Alternatively try our"
msgstr "或者嘗試我們"
#: changedetectionio/templates/_helpers.html:184
msgid ""
"very affordable subscription based service which has all this setup for "
"you"
msgstr "非常實惠的訂閱服務,為您準備好所有設定"
#: changedetectionio/templates/_helpers.html:185
msgid "You may need to"
msgstr "您可能需要"
#: changedetectionio/templates/_helpers.html:185
msgid "Enable playwright environment variable"
msgstr "啟用 playwright 環境變數"
#: changedetectionio/templates/_helpers.html:185
msgid "and uncomment the"
msgstr "並取消註解"
#: changedetectionio/templates/_helpers.html:185
msgid "in the"
msgstr "於"
#: changedetectionio/templates/_helpers.html:185
msgid "file"
msgstr "檔案"
#: changedetectionio/templates/_helpers.html:240
msgid "Set a hourly/week day schedule"
msgstr "設定每小時 / 平日排程"
#: changedetectionio/templates/_helpers.html:247
msgid "Schedule time limits"
msgstr "排程時間限制"
#: changedetectionio/templates/_helpers.html:248
msgid "Business hours"
msgstr "營業時間"
#: changedetectionio/templates/_helpers.html:249
msgid "Weekends"
msgstr "週末"
#: changedetectionio/templates/_helpers.html:250
msgid "Reset"
msgstr "重置"
#: changedetectionio/templates/_helpers.html:259
msgid ""
"Warning, one or more of your 'days' has a duration that would extend into"
" the next day."
msgstr "警告,您設定的一個或多個「天」持續時間將延伸至隔天。"
#: changedetectionio/templates/_helpers.html:260
msgid "This could have unintended consequences."
msgstr "這可能會產生非預期的後果。"
#: changedetectionio/templates/_helpers.html:270
msgid "More help and examples about using the scheduler"
msgstr "關於使用排程器的更多幫助和範例"
#: changedetectionio/templates/_helpers.html:275
msgid "Want to use a time schedule?"
msgstr "想要使用時間排程嗎?"
#: changedetectionio/templates/_helpers.html:275
msgid "First confirm/save your Time Zone Settings"
msgstr "請先確認 / 儲存您的時區設定"
#: changedetectionio/templates/_helpers.html:284
msgid ""
"Triggers a change if this text appears, AND something changed in the "
"document."
msgstr "如果出現此文字,且文件中有些內容變更,則觸發變更。"
#: changedetectionio/templates/_helpers.html:284
msgid "Triggered text"
msgstr "觸發的文字"
#: changedetectionio/templates/_helpers.html:285
msgid "Ignored for calculating changes, but still shown."
msgstr "計算變更時忽略,但仍會顯示。"
#: changedetectionio/templates/_helpers.html:285
msgid "Ignored text"
msgstr "忽略的文字"
#: changedetectionio/templates/_helpers.html:286
msgid "No change-detection will occur because this text exists."
msgstr "因為存在此文字,將不會進行變更檢測。"
#: changedetectionio/templates/_helpers.html:286
msgid "Blocked text"
msgstr "被阻擋的文字"
#: changedetectionio/templates/base.html:78
#: changedetectionio/templates/base.html:168
#: changedetectionio/templates/base.html:77
msgid "GROUPS"
msgstr "群組"
#: changedetectionio/templates/base.html:81
#: changedetectionio/templates/base.html:169
#: changedetectionio/templates/base.html:80
msgid "SETTINGS"
msgstr "設定"
#: changedetectionio/templates/base.html:84
#: changedetectionio/templates/base.html:170
#: changedetectionio/templates/base.html:83
msgid "IMPORT"
msgstr "匯入"
#: changedetectionio/templates/base.html:87
#: changedetectionio/templates/base.html:171
#: changedetectionio/templates/base.html:86
msgid "BACKUPS"
msgstr "備份"
#: changedetectionio/templates/base.html:91
#: changedetectionio/templates/base.html:173
#: changedetectionio/templates/base.html:90
msgid "EDIT"
msgstr "編輯"
#: changedetectionio/templates/base.html:101
#: changedetectionio/templates/base.html:177
#: changedetectionio/templates/base.html:100
msgid "LOG OUT"
msgstr "登出"
#: changedetectionio/templates/base.html:108
#: changedetectionio/templates/base.html:109
msgid "Search, or Use Alt+S Key"
msgstr "搜尋,或使用 Alt+S 鍵"
#: changedetectionio/templates/base.html:114
#: changedetectionio/templates/base.html:116
msgid "Toggle Light/Dark Mode"
msgstr "切換亮 / 暗模式"
#: changedetectionio/templates/base.html:115
#: changedetectionio/templates/base.html:117
msgid "Toggle light/dark mode"
msgstr "切換亮 / 暗模式"
#: changedetectionio/templates/base.html:125
#: changedetectionio/templates/base.html:127
msgid "Change Language"
msgstr "更改語言"
#: changedetectionio/templates/base.html:126
#: changedetectionio/templates/base.html:128
msgid "Change language"
msgstr "更改語言"
#: changedetectionio/templates/base.html:253
msgid "Watch List"
msgstr "監測列表"
#: changedetectionio/templates/base.html:258
msgid "Watches"
msgstr "監測任務"
#: changedetectionio/templates/base.html:261
msgid "Queue Status"
msgstr "佇列狀態"
#: changedetectionio/templates/base.html:270
msgid "Queue"
msgstr "佇列"
#: changedetectionio/templates/base.html:274
#: changedetectionio/templates/base.html:279
msgid "Settings"
msgstr "設定"
#: changedetectionio/templates/base.html:293
msgid "Sitemap Crawler"
msgstr "Sitemap 爬蟲"
#: changedetectionio/templates/base.html:318
msgid "Sitemap"
msgstr "Sitemap"
#: changedetectionio/templates/base.html:354
#: changedetectionio/templates/base.html:249
msgid "Real-time updates offline"
msgstr "離線即時更新"
#: changedetectionio/templates/base.html:364
#: changedetectionio/templates/base.html:259
msgid "Select Language"
msgstr "選擇語言"
#: changedetectionio/templates/base.html:375
msgid ""
"Language support is in beta, please help us improve by opening a PR on "
"GitHub with any updates."
#: changedetectionio/templates/base.html:270
msgid "Language support is in beta, please help us improve by opening a PR on GitHub with any updates."
msgstr "語言支援尚在 Beta 階段,請在 GitHub 上提交 PR 以協助我們改進。"
#: changedetectionio/templates/base.html:387
#: changedetectionio/templates/base.html:400
msgid "Search"
msgstr "搜尋"
#: changedetectionio/templates/base.html:392
msgid "URL or Title"
msgstr "URL 或標題"
#: changedetectionio/templates/base.html:392
msgid "in"
msgstr "於"
#: changedetectionio/templates/base.html:393
msgid "Enter search term..."
msgstr "輸入搜尋關鍵字 ..."
#: changedetectionio/templates/login.html:11
#: changedetectionio/templates/login.html:10
msgid "Password"
msgstr "密碼"
#: changedetectionio/templates/login.html:17
#: changedetectionio/templates/login.html:16
msgid "Login"
msgstr "登入"
msgstr "登入"
#: changedetectionio/widgets/ternary_boolean.py:18
#: changedetectionio/widgets/ternary_boolean.py:72
msgid "Yes"
msgstr "是"
#: changedetectionio/widgets/ternary_boolean.py:19
#: changedetectionio/widgets/ternary_boolean.py:73
msgid "No"
msgstr "否"
#: changedetectionio/widgets/ternary_boolean.py:20
#: changedetectionio/widgets/ternary_boolean.py:74
msgid "Main settings"
msgstr "主設定"
#: changedetectionio/templates/_common_fields.html:11
msgid "Show token/placeholders"
msgstr ""
#: changedetectionio/templates/_common_fields.html:18
msgid "Token"
msgstr ""
#: changedetectionio/templates/_common_fields.html:19
#, fuzzy
msgid "Description"
msgstr "新增"
#: changedetectionio/templates/_common_fields.html:128
#, fuzzy
msgid "Show advanced help and tips"
msgstr "顯示進階選項"
#: changedetectionio/templates/_common_fields.html:138
#, fuzzy
msgid "Send test notification"
msgstr "使用預設通知"
#: changedetectionio/templates/_common_fields.html:140
msgid "Add email"
msgstr ""
#: changedetectionio/templates/_common_fields.html:140
msgid "Add an email address"
msgstr ""
#: changedetectionio/templates/_common_fields.html:142
#, fuzzy
msgid "Notification debug logs"
msgstr "通知除錯記錄"
#: changedetectionio/templates/_common_fields.html:144
#, fuzzy
msgid "Processing.."
msgstr "處理器"
#: changedetectionio/templates/_common_fields.html:151
#, fuzzy
msgid "Title for all notifications"
msgstr "使用預設通知"
#: changedetectionio/templates/_common_fields.html:176
#, fuzzy
msgid "Format for all notifications"
msgstr "使用預設通知"
#: changedetectionio/templates/edit/text-options.html:9
msgid "Text to wait for before triggering a change/notification, all text and regex are tested case-insensitive."
msgstr ""
#: changedetectionio/templates/edit/text-options.html:10
msgid "Trigger text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:11
msgid "Each line is processed separately (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:12
msgid "Note: Wrap in forward slash / to use regex example:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:23
msgid "Matching text will be ignored in the text snapshot (you can still see it but it wont trigger a change)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:24
msgid "Each line processed separately, any line matching will be ignored (removed before creating the checksum)"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:25
msgid "Regular Expression support, wrap the entire line in forward slash"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:26
msgid "Changing this will affect the comparison checksum which may trigger an alert"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:43
msgid "Block change-detection while this text is on the page, all text and regex are tested case-insensitive, good for waiting for when a product is available again"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:44
msgid "Block text is processed from the result-text that comes out of any CSS/JSON Filters for this monitor"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:45
msgid "All lines here must not exist (think of each line as \"OR\")"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:58
msgid "Extracts text in the final output (line by line) after other filters using regular expressions or string match:"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:60
msgid "Regular expression - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:61
msgid "Don't forget to consider the white-space at the start of a line"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
#, fuzzy
msgid "Use"
msgstr "暫停"
#: changedetectionio/templates/edit/text-options.html:62
msgid "type flags (more"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:62
#, fuzzy
msgid "information here"
msgstr "無資訊"
#: changedetectionio/templates/edit/text-options.html:63
msgid "Keyword example - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "Use groups to extract just that text - example"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:64
msgid "returns a list of years only"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:65
msgid "Example - match lines containing a keyword"
msgstr ""
#: changedetectionio/templates/edit/text-options.html:68
msgid "One line per regular-expression/string match"
msgstr ""
#~ msgid "Entry"
#~ msgstr "項目"
#~ msgid "Actions"
#~ msgstr "動作"
#~ msgid "Add a row/rule after"
#~ msgstr "在後方新增一行 / 規則"
#~ msgid "Remove this row/rule"
#~ msgstr "移除此行 / 規則"
#~ msgid "Verify this rule against current snapshot"
#~ msgstr "針對目前快照驗證此規則"
#~ msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
#~ msgstr "錯誤 - 此監測任務需要 Chrome搭配 playwright / sockpuppetbrowser但未啟用基於 Chrome 的抓取功能。"
#~ msgid "Alternatively try our"
#~ msgstr "或者嘗試我們"
#~ msgid "very affordable subscription based service which has all this setup for you"
#~ msgstr "非常實惠的訂閱服務,為您準備好所有設定"
#~ msgid "You may need to"
#~ msgstr "您可能需要"
#~ msgid "Enable playwright environment variable"
#~ msgstr "啟用 playwright 環境變數"
#~ msgid "and uncomment the"
#~ msgstr "並取消註解"
#~ msgid "in the"
#~ msgstr "於"
#~ msgid "file"
#~ msgstr "檔案"
#~ msgid "Set a hourly/week day schedule"
#~ msgstr "設定每小時 / 平日排程"
#~ msgid "Schedule time limits"
#~ msgstr "排程時間限制"
#~ msgid "Business hours"
#~ msgstr "營業時間"
#~ msgid "Weekends"
#~ msgstr "週末"
#~ msgid "Reset"
#~ msgstr "重置"
#~ msgid "Warning, one or more of your 'days' has a duration that would extend into the next day."
#~ msgstr "警告,您設定的一個或多個「天」持續時間將延伸至隔天。"
#~ msgid "This could have unintended consequences."
#~ msgstr "這可能會產生非預期的後果。"
#~ msgid "More help and examples about using the scheduler"
#~ msgstr "關於使用排程器的更多幫助和範例"
#~ msgid "Want to use a time schedule?"
#~ msgstr "想要使用時間排程嗎?"
#~ msgid "First confirm/save your Time Zone Settings"
#~ msgstr "請先確認 / 儲存您的時區設定"
#~ msgid "Triggers a change if this text appears, AND something changed in the document."
#~ msgstr "如果出現此文字,且文件中有些內容變更,則觸發變更。"
#~ msgid "Triggered text"
#~ msgstr "觸發的文字"
#~ msgid "Ignored for calculating changes, but still shown."
#~ msgstr "計算變更時忽略,但仍會顯示。"
#~ msgid "Ignored text"
#~ msgstr "忽略的文字"
#~ msgid "No change-detection will occur because this text exists."
#~ msgstr "因為存在此文字,將不會進行變更檢測。"
#~ msgid "Blocked text"
#~ msgstr "被阻擋的文字"
#~ msgid "Watch List"
#~ msgstr "監測列表"
#~ msgid "Watches"
#~ msgstr "監測任務"
#~ msgid "Queue Status"
#~ msgstr "佇列狀態"
#~ msgid "Queue"
#~ msgstr "佇列"
#~ msgid "Sitemap Crawler"
#~ msgstr "Sitemap 爬蟲"
#~ msgid "Sitemap"
#~ msgstr "Sitemap"
#~ msgid "Search"
#~ msgstr "搜尋"
#~ msgid "URL or Title"
#~ msgstr "URL 或標題"
#~ msgid "in"
#~ msgstr "於"
#~ msgid "Enter search term..."
#~ msgstr "輸入搜尋關鍵字 ..."

View File

@@ -1,6 +1,6 @@
from wtforms import Field
from wtforms import widgets
from markupsafe import Markup
from flask_babel import lazy_gettext as _l
class TernaryNoneBooleanWidget:
"""
@@ -14,9 +14,9 @@ class TernaryNoneBooleanWidget:
boolean_mode = getattr(field, 'boolean_mode', False)
# Get custom text or use defaults
yes_text = getattr(field, 'yes_text', 'Yes')
no_text = getattr(field, 'no_text', 'No')
none_text = getattr(field, 'none_text', 'Main settings')
yes_text = getattr(field, 'yes_text', _l('Yes'))
no_text = getattr(field, 'no_text', _l('No'))
none_text = getattr(field, 'none_text', _l('Main settings'))
# True option
checked_true = ' checked' if field.data is True else ''
@@ -63,14 +63,14 @@ class TernaryNoneBooleanField(Field):
"""
widget = TernaryNoneBooleanWidget()
def __init__(self, label=None, validators=None, false_values=None, boolean_mode=False,
yes_text="Yes", no_text="No", none_text="Main settings", **kwargs):
def __init__(self, label=None, validators=None, false_values=None, boolean_mode=False,
yes_text=None, no_text=None, none_text=None, **kwargs):
super(TernaryNoneBooleanField, self).__init__(label, validators, **kwargs)
self.boolean_mode = boolean_mode
self.yes_text = yes_text
self.no_text = no_text
self.none_text = none_text
self.yes_text = yes_text if yes_text is not None else _l('Yes')
self.no_text = no_text if no_text is not None else _l('No')
self.none_text = none_text if none_text is not None else _l('Main settings')
if false_values is None:
self.false_values = {'false', ''}

View File

@@ -42,7 +42,7 @@ orjson~=3.11
# jq not available on Windows so must be installed manually
# Notification library
apprise==1.9.5
apprise==1.9.6
diff_match_patch
@@ -70,7 +70,7 @@ lxml >=4.8.0,!=5.2.0,!=5.2.1,<7
# XPath 2.0-3.1 support - 4.2.0 had issues, 4.1.5 stable
# Consider updating to latest stable version periodically
elementpath==5.0.4
elementpath==5.1.0
# For fast image comparison in screenshot change detection
# opencv-python-headless is OPTIONAL (excluded from requirements.txt)