mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-06-12 03:42:11 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c87e62e10 | |||
| 5b151c68e2 | |||
| e51ff34c89 | |||
| ba4ed9cf27 | |||
| 33b7f1684d | |||
| 3d14df6a11 | |||
| 08ce1e28ce | |||
| e4118a1620 | |||
| 64d0c09b08 | |||
| 008e5eb024 | |||
| e6553065fd | |||
| de996a4566 | |||
| 4784ae4cd0 |
@@ -183,6 +183,9 @@ docker compose pull && docker compose up -d
|
|||||||
|
|
||||||
See the wiki for more information https://github.com/dgtlmoon/changedetection.io/wiki
|
See the wiki for more information https://github.com/dgtlmoon/changedetection.io/wiki
|
||||||
|
|
||||||
|
## Different browser viewport sizes (mobile, desktop etc)
|
||||||
|
|
||||||
|
If you are using the recommended `sockpuppetbrowser` (which is in the docker-compose.yml as a setting to be uncommented) you can easily set different viewport sizes for your web page change detection, [see more information here about setting up different viewport sizes](https://github.com/dgtlmoon/sockpuppetbrowser?tab=readme-ov-file#setting-viewport-size).
|
||||||
|
|
||||||
## Filters
|
## Filters
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Read more https://github.com/dgtlmoon/changedetection.io/wiki
|
# Read more https://github.com/dgtlmoon/changedetection.io/wiki
|
||||||
# Semver means never use .01, or 00. Should be .1.
|
# Semver means never use .01, or 00. Should be .1.
|
||||||
__version__ = '0.51.4'
|
__version__ = '0.52.1'
|
||||||
|
|
||||||
from changedetectionio.strtobool import strtobool
|
from changedetectionio.strtobool import strtobool
|
||||||
from json.decoder import JSONDecodeError
|
from json.decoder import JSONDecodeError
|
||||||
|
|||||||
@@ -64,8 +64,17 @@ class Watch(Resource):
|
|||||||
@validate_openapi_request('getWatch')
|
@validate_openapi_request('getWatch')
|
||||||
def get(self, uuid):
|
def get(self, uuid):
|
||||||
"""Get information about a single watch, recheck, pause, or mute."""
|
"""Get information about a single watch, recheck, pause, or mute."""
|
||||||
|
import time
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
watch = deepcopy(self.datastore.data['watching'].get(uuid))
|
watch = None
|
||||||
|
for _ in range(20):
|
||||||
|
try:
|
||||||
|
watch = deepcopy(self.datastore.data['watching'].get(uuid))
|
||||||
|
break
|
||||||
|
except RuntimeError:
|
||||||
|
# Incase dict changed, try again
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
if not watch:
|
if not watch:
|
||||||
abort(404, message='No watch exists with the UUID of {}'.format(uuid))
|
abort(404, message='No watch exists with the UUID of {}'.format(uuid))
|
||||||
|
|
||||||
@@ -302,18 +311,28 @@ class WatchHistoryDiff(Resource):
|
|||||||
from_version_file_contents = watch.get_history_snapshot(from_timestamp)
|
from_version_file_contents = watch.get_history_snapshot(from_timestamp)
|
||||||
to_version_file_contents = watch.get_history_snapshot(to_timestamp)
|
to_version_file_contents = watch.get_history_snapshot(to_timestamp)
|
||||||
|
|
||||||
# Get diff preferences (using defaults similar to the existing code)
|
# Get diff preferences from query parameters (matching UI preferences in DIFF_PREFERENCES_CONFIG)
|
||||||
diff_prefs = {
|
# Support both 'type' (UI parameter) and 'word_diff' (API parameter) for backward compatibility
|
||||||
'diff_ignoreWhitespace': False,
|
diff_type = request.args.get('type', 'diffLines')
|
||||||
'diff_changesOnly': True
|
if diff_type == 'diffWords':
|
||||||
}
|
word_diff = True
|
||||||
|
|
||||||
# Generate the diff
|
# Get boolean diff preferences with defaults from DIFF_PREFERENCES_CONFIG
|
||||||
|
changes_only = strtobool(request.args.get('changesOnly', 'true'))
|
||||||
|
ignore_whitespace = strtobool(request.args.get('ignoreWhitespace', 'false'))
|
||||||
|
include_removed = strtobool(request.args.get('removed', 'true'))
|
||||||
|
include_added = strtobool(request.args.get('added', 'true'))
|
||||||
|
include_replaced = strtobool(request.args.get('replaced', 'true'))
|
||||||
|
|
||||||
|
# Generate the diff with all preferences
|
||||||
content = diff.render_diff(
|
content = diff.render_diff(
|
||||||
previous_version_file_contents=from_version_file_contents,
|
previous_version_file_contents=from_version_file_contents,
|
||||||
newest_version_file_contents=to_version_file_contents,
|
newest_version_file_contents=to_version_file_contents,
|
||||||
ignore_junk=diff_prefs.get('diff_ignoreWhitespace'),
|
ignore_junk=ignore_whitespace,
|
||||||
include_equal=not diff_prefs.get('diff_changesOnly'),
|
include_equal=changes_only,
|
||||||
|
include_removed=include_removed,
|
||||||
|
include_added=include_added,
|
||||||
|
include_replaced=include_replaced,
|
||||||
word_diff=word_diff,
|
word_diff=word_diff,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -47,9 +47,6 @@ def construct_single_watch_routes(rss_blueprint, datastore):
|
|||||||
if len(dates) < 2:
|
if len(dates) < 2:
|
||||||
return f"Watch {uuid} does not have enough history snapshots to show changes (need at least 2)", 400
|
return f"Watch {uuid} does not have enough history snapshots to show changes (need at least 2)", 400
|
||||||
|
|
||||||
# Add uuid to watch for proper functioning
|
|
||||||
watch['uuid'] = uuid
|
|
||||||
|
|
||||||
# Get the number of diffs to include (default: 5)
|
# Get the number of diffs to include (default: 5)
|
||||||
rss_diff_length = datastore.data['settings']['application'].get('rss_diff_length', 5)
|
rss_diff_length = datastore.data['settings']['application'].get('rss_diff_length', 5)
|
||||||
|
|
||||||
@@ -101,7 +98,7 @@ def construct_single_watch_routes(rss_blueprint, datastore):
|
|||||||
date_index_from, date_index_to)
|
date_index_from, date_index_to)
|
||||||
|
|
||||||
# Create and populate feed entry
|
# Create and populate feed entry
|
||||||
guid = f"{watch['uuid']}/{timestamp_to}"
|
guid = f"{uuid}/{timestamp_to}"
|
||||||
fe = fg.add_entry()
|
fe = fg.add_entry()
|
||||||
title_suffix = f"Change @ {res['original_context']['change_datetime']}"
|
title_suffix = f"Change @ {res['original_context']['change_datetime']}"
|
||||||
populate_feed_entry(fe, watch, res.get('body', ''), guid, timestamp_to,
|
populate_feed_entry(fe, watch, res.get('body', ''), guid, timestamp_to,
|
||||||
|
|||||||
@@ -63,11 +63,8 @@ def construct_tag_routes(rss_blueprint, datastore):
|
|||||||
|
|
||||||
# Only include unviewed watches
|
# Only include unviewed watches
|
||||||
if not watch.viewed:
|
if not watch.viewed:
|
||||||
# Add uuid to watch for proper functioning
|
# Include a link to the diff page (use uuid from loop, don't modify watch dict)
|
||||||
watch['uuid'] = uuid
|
diff_link = {'href': url_for('ui.ui_diff.diff_history_page', uuid=uuid, _external=True)}
|
||||||
|
|
||||||
# Include a link to the diff page
|
|
||||||
diff_link = {'href': url_for('ui.ui_diff.diff_history_page', uuid=watch['uuid'], _external=True)}
|
|
||||||
|
|
||||||
# Get watch label
|
# Get watch label
|
||||||
watch_label = get_watch_label(datastore, watch)
|
watch_label = get_watch_label(datastore, watch)
|
||||||
|
|||||||
@@ -85,9 +85,7 @@
|
|||||||
|
|
||||||
<div class="tab-pane-inner" id="notifications">
|
<div class="tab-pane-inner" id="notifications">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="field-group">
|
{{ render_common_settings_form(form.application.form, emailprefix, settings_application, extra_notification_token_placeholder_info) }}
|
||||||
{{ render_common_settings_form(form.application.form, emailprefix, settings_application, extra_notification_token_placeholder_info) }}
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<div class="pure-control-group" id="notification-base-url">
|
<div class="pure-control-group" id="notification-base-url">
|
||||||
{{ render_field(form.application.form.base_url, class="m-d") }}
|
{{ render_field(form.application.form.base_url, class="m-d") }}
|
||||||
@@ -128,7 +126,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
{{ render_field(form.requests.form.timeout) }}
|
{{ render_field(form.requests.form.timeout) }}
|
||||||
<span class="pure-form-message-inline">For regular plain requests (not chrome based), maximum number of seconds until timeout, 1-999.<br>
|
<span class="pure-form-message-inline">For regular plain requests (not chrome based), maximum number of seconds until timeout, 1-999.</span><br>
|
||||||
</div>
|
</div>
|
||||||
<div class="pure-control-group inline-radio">
|
<div class="pure-control-group inline-radio">
|
||||||
{{ render_field(form.requests.form.default_ua) }}
|
{{ render_field(form.requests.form.default_ua) }}
|
||||||
@@ -219,7 +217,7 @@ nav
|
|||||||
<a id="chrome-extension-link"
|
<a id="chrome-extension-link"
|
||||||
title="Try our new Chrome Extension!"
|
title="Try our new Chrome Extension!"
|
||||||
href="https://chromewebstore.google.com/detail/changedetectionio-website/kefcfmgmlhmankjmnbijimhofdjekbop">
|
href="https://chromewebstore.google.com/detail/changedetectionio-website/kefcfmgmlhmankjmnbijimhofdjekbop">
|
||||||
<img alt="Chrome store icon" src="{{ url_for('static_content', group='images', filename='google-chrome-icon.png') }}" alt="Chrome">
|
<img alt="Chrome store icon" src="{{ url_for('static_content', group='images', filename='google-chrome-icon.png') }}" >
|
||||||
Chrome Webstore
|
Chrome Webstore
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -260,14 +258,14 @@ nav
|
|||||||
Ensure the settings below are correct, they are used to manage the time schedule for checking your web page watches.
|
Ensure the settings below are correct, they are used to manage the time schedule for checking your web page watches.
|
||||||
</div>
|
</div>
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
<p><strong>UTC Time & Date from Server:</strong> <span id="utc-time" >{{ utc_time }}</span></p>
|
<p><strong>UTC Time & Date from Server:</strong> <span id="utc-time" >{{ utc_time }}</span></p>
|
||||||
<p><strong>Local Time & Date in Browser:</strong> <span class="local-time" data-utc="{{ utc_time }}"></span></p>
|
<p><strong>Local Time & Date in Browser:</strong> <span class="local-time" data-utc="{{ utc_time }}"></span></p>
|
||||||
<p>
|
<div>
|
||||||
{{ render_field(form.application.form.scheduler_timezone_default) }}
|
{{ render_field(form.application.form.scheduler_timezone_default) }}
|
||||||
<datalist id="timezones" style="display: none;">
|
<datalist id="timezones" style="display: none;">
|
||||||
{%- for timezone in available_timezones -%}<option value="{{ timezone }}">{{ timezone }}</option>{%- endfor -%}
|
{%- for timezone in available_timezones -%}<option value="{{ timezone }}">{{ timezone }}</option>{%- endfor -%}
|
||||||
</datalist>
|
</datalist>
|
||||||
</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane-inner" id="ui-options">
|
<div class="tab-pane-inner" id="ui-options">
|
||||||
@@ -336,7 +334,7 @@ nav
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p><strong>Tip</strong>: "Residential" and "Mobile" proxy type can be more successfull than "Data Center" for blocked websites.
|
<p><strong>Tip</strong>: "Residential" and "Mobile" proxy type can be more successfull than "Data Center" for blocked websites.</p>
|
||||||
|
|
||||||
<div class="pure-control-group" id="extra-proxies-setting">
|
<div class="pure-control-group" id="extra-proxies-setting">
|
||||||
{{ render_fieldlist_with_inline_errors(form.requests.form.extra_proxies) }}
|
{{ render_fieldlist_with_inline_errors(form.requests.form.extra_proxies) }}
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
|||||||
sent_obj = process_notification(n_object, datastore)
|
sent_obj = process_notification(n_object, datastore)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
e_str = str(e)
|
e_str = str(e)
|
||||||
# Remove this text which is not important and floods the container
|
# Remove this text which is not important and floods the container
|
||||||
e_str = e_str.replace(
|
e_str = e_str.replace(
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="diff-jump">
|
<div id="diff-jump" style="display:none;"><!-- disabled for now -->
|
||||||
<a id="jump-next-diff" title="{{ _('Jump to next difference') }}">{{ _('Jump') }}</a>
|
<a id="jump-next-diff" title="{{ _('Jump to next difference') }}">{{ _('Jump') }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe
|
|||||||
datastore=datastore,
|
datastore=datastore,
|
||||||
errored_count=errored_count,
|
errored_count=errored_count,
|
||||||
form=form,
|
form=form,
|
||||||
|
generate_tag_colors=processors.generate_processor_badge_colors,
|
||||||
guid=datastore.data['app_guid'],
|
guid=datastore.data['app_guid'],
|
||||||
has_proxies=datastore.proxy_list,
|
has_proxies=datastore.proxy_list,
|
||||||
hosted_sticky=os.getenv("SALTED_PASS", False) == False,
|
hosted_sticky=os.getenv("SALTED_PASS", False) == False,
|
||||||
|
|||||||
@@ -22,6 +22,33 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
/* Auto-generated processor badge colors */
|
/* Auto-generated processor badge colors */
|
||||||
{{ processor_badge_css|safe }}
|
{{ processor_badge_css|safe }}
|
||||||
|
|
||||||
|
/* Auto-generated tag colors */
|
||||||
|
{%- for uuid, tag in tags -%}
|
||||||
|
{%- if tag and tag.title -%}
|
||||||
|
{%- set class_name = tag.title|sanitize_tag_class -%}
|
||||||
|
{%- set colors = generate_tag_colors(tag.title) -%}
|
||||||
|
.button-tag.tag-{{ class_name }} {
|
||||||
|
background-color: {{ colors['light']['bg'] }};
|
||||||
|
color: {{ colors['light']['color'] }};
|
||||||
|
}
|
||||||
|
|
||||||
|
.watch-tag-list.tag-{{ class_name }} {
|
||||||
|
background-color: {{ colors['light']['bg'] }};
|
||||||
|
color: {{ colors['light']['color'] }};
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-darkmode="true"] .button-tag.tag-{{ class_name }} {
|
||||||
|
background-color: {{ colors['dark']['bg'] }};
|
||||||
|
color: {{ colors['dark']['color'] }};
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-darkmode="true"] .watch-tag-list.tag-{{ class_name }} {
|
||||||
|
background-color: {{ colors['dark']['bg'] }};
|
||||||
|
color: {{ colors['dark']['color'] }};
|
||||||
|
}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
</style>
|
</style>
|
||||||
<div class="box" id="form-quick-watch-add">
|
<div class="box" id="form-quick-watch-add">
|
||||||
|
|
||||||
@@ -82,7 +109,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
<!-- tag list -->
|
<!-- tag list -->
|
||||||
{%- for uuid, tag in tags -%}
|
{%- for uuid, tag in tags -%}
|
||||||
{%- if tag != "" -%}
|
{%- if tag != "" -%}
|
||||||
<a href="{{url_for('watchlist.index', tag=uuid) }}" class="pure-button button-tag {{'active' if active_tag_uuid == uuid }}">{{ tag.title }}</a>
|
<a href="{{url_for('watchlist.index', tag=uuid) }}" class="pure-button button-tag tag-{{ tag.title|sanitize_tag_class }} {{'active' if active_tag_uuid == uuid }}">{{ tag.title }}</a>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
</div>
|
</div>
|
||||||
@@ -169,7 +196,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
<div class="flex-wrapper">
|
<div class="flex-wrapper">
|
||||||
{% if 'favicons_enabled' not in ui_settings or ui_settings['favicons_enabled'] %}
|
{% if 'favicons_enabled' not in ui_settings or ui_settings['favicons_enabled'] %}
|
||||||
<div>{# A page might have hundreds of these images, set IMG options for lazy loading, don't set SRC if we dont have it so it doesnt fetch the placeholder' #}
|
<div>{# A page might have hundreds of these images, set IMG options for lazy loading, don't set SRC if we dont have it so it doesnt fetch the placeholder' #}
|
||||||
<img alt="Favicon thumbnail" class="favicon" loading="lazy" decoding="async" fetchpriority="low" {% if favicon %} src="{{url_for('static_content', group='favicon', filename=watch.uuid)}}" {% else %} src='data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="7.087" height="7.087" viewBox="0 0 7.087 7.087"%3E%3Ccircle cx="3.543" cy="3.543" r="3.279" stroke="%23e1e1e1" stroke-width="0.45" fill="none" opacity="0.74"/%3E%3C/svg%3E' {% endif %} />
|
<img alt="Favicon thumbnail" class="favicon" loading="lazy" decoding="async" fetchpriority="low" {% if favicon %} src="{{url_for('static_content', group='favicon', filename=watch.uuid)}}" {% else %} src='data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="7.087" height="7.087" viewBox="0 0 7.087 7.087"%3E%3Ccircle cx="3.543" cy="3.543" r="3.279" stroke="%23e1e1e1" stroke-width="0.45" fill="none" opacity="0.74"/%3E%3C/svg%3E' {% endif %} >
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div>
|
<div>
|
||||||
@@ -191,7 +218,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
<span class="processor-badge processor-badge-{{ watch['processor'] }}" title="{{ processor_descriptions.get(watch['processor'], watch['processor']) }}">{{ processor_badge_texts[watch['processor']] }}</span>
|
<span class="processor-badge processor-badge-{{ watch['processor'] }}" title="{{ processor_descriptions.get(watch['processor'], watch['processor']) }}">{{ processor_badge_texts[watch['processor']] }}</span>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- for watch_tag_uuid, watch_tag in datastore.get_all_tags_for_watch(watch['uuid']).items() -%}
|
{%- for watch_tag_uuid, watch_tag in datastore.get_all_tags_for_watch(watch['uuid']).items() -%}
|
||||||
<span class="watch-tag-list">{{ watch_tag.title }}</span>
|
<span class="watch-tag-list tag-{{ watch_tag.title|sanitize_tag_class }}">{{ watch_tag.title }}</span>
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
</div>
|
</div>
|
||||||
<div class="status-icons">
|
<div class="status-icons">
|
||||||
|
|||||||
@@ -297,6 +297,25 @@ def _jinja2_filter_fetcher_status_icons(fetcher_name):
|
|||||||
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@app.template_filter('sanitize_tag_class')
|
||||||
|
def _jinja2_filter_sanitize_tag_class(tag_title):
|
||||||
|
"""Sanitize a tag title to create a valid CSS class name.
|
||||||
|
Removes all non-alphanumeric characters and converts to lowercase.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tag_title: The tag title string
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: A sanitized string suitable for use as a CSS class name
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
# Remove all non-alphanumeric characters and convert to lowercase
|
||||||
|
sanitized = re.sub(r'[^a-zA-Z0-9]', '', tag_title).lower()
|
||||||
|
# Ensure it starts with a letter (CSS requirement)
|
||||||
|
if sanitized and not sanitized[0].isalpha():
|
||||||
|
sanitized = 'tag' + sanitized
|
||||||
|
return sanitized if sanitized else 'tag'
|
||||||
|
|
||||||
# Import login_optionally_required from auth_decorator
|
# Import login_optionally_required from auth_decorator
|
||||||
from changedetectionio.auth_decorator import login_optionally_required
|
from changedetectionio.auth_decorator import login_optionally_required
|
||||||
|
|
||||||
@@ -895,7 +914,7 @@ def notification_runner():
|
|||||||
# At the moment only one thread runs (single runner)
|
# At the moment only one thread runs (single runner)
|
||||||
n_object = notification_q.get(block=False)
|
n_object = notification_q.get(block=False)
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
time.sleep(1)
|
app.config.exit.wait(1)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
@@ -932,7 +951,7 @@ def notification_runner():
|
|||||||
app.config['watch_check_update_SIGNAL'].send(app_context=app, watch_uuid=n_object.get('uuid'))
|
app.config['watch_check_update_SIGNAL'].send(app_context=app, watch_uuid=n_object.get('uuid'))
|
||||||
|
|
||||||
# Process notifications
|
# Process notifications
|
||||||
notification_debug_log+= ["{} - SENDING - {}".format(now.strftime("%Y/%m/%d %H:%M:%S,000"), json.dumps(sent_obj))]
|
notification_debug_log+= ["{} - SENDING - {}".format(now.strftime("%c"), json.dumps(sent_obj))]
|
||||||
# Trim the log length
|
# Trim the log length
|
||||||
notification_debug_log = notification_debug_log[-100:]
|
notification_debug_log = notification_debug_log[-100:]
|
||||||
|
|
||||||
@@ -990,7 +1009,7 @@ def ticker_thread_check_time_launch_checks():
|
|||||||
# Re #438 - Don't place more watches in the queue to be checked if the queue is already large
|
# Re #438 - Don't place more watches in the queue to be checked if the queue is already large
|
||||||
while update_q.qsize() >= 2000:
|
while update_q.qsize() >= 2000:
|
||||||
logger.warning(f"Recheck watches queue size limit reached ({MAX_QUEUE_SIZE}), skipping adding more items")
|
logger.warning(f"Recheck watches queue size limit reached ({MAX_QUEUE_SIZE}), skipping adding more items")
|
||||||
time.sleep(3)
|
app.config.exit.wait(10.0)
|
||||||
|
|
||||||
|
|
||||||
recheck_time_system_seconds = int(datastore.threshold_seconds)
|
recheck_time_system_seconds = int(datastore.threshold_seconds)
|
||||||
@@ -1088,8 +1107,5 @@ def ticker_thread_check_time_launch_checks():
|
|||||||
# Reset for next time
|
# Reset for next time
|
||||||
watch.jitter_seconds = 0
|
watch.jitter_seconds = 0
|
||||||
|
|
||||||
# Wait before checking the list again - saves CPU
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# Should be low so we can break this out in testing
|
# Should be low so we can break this out in testing
|
||||||
app.config.exit.wait(1)
|
app.config.exit.wait(1)
|
||||||
|
|||||||
@@ -781,8 +781,8 @@ class SingleBrowserStep(Form):
|
|||||||
|
|
||||||
class processor_text_json_diff_form(commonSettingsForm):
|
class processor_text_json_diff_form(commonSettingsForm):
|
||||||
|
|
||||||
url = fields.URLField('URL', validators=[validateURL()])
|
url = fields.URLField('Web Page URL', validators=[validateURL()])
|
||||||
tags = StringTagUUID('Group tag', [validators.Optional()], default='')
|
tags = StringTagUUID('Group Tag', [validators.Optional()], default='')
|
||||||
|
|
||||||
time_between_check = EnhancedFormField(
|
time_between_check = EnhancedFormField(
|
||||||
TimeBetweenCheckForm,
|
TimeBetweenCheckForm,
|
||||||
|
|||||||
@@ -34,13 +34,16 @@ def get_timeago_locale(flask_locale):
|
|||||||
'no': 'nb_NO', # Norwegian Bokmål
|
'no': 'nb_NO', # Norwegian Bokmål
|
||||||
'hi': 'in_HI', # Hindi
|
'hi': 'in_HI', # Hindi
|
||||||
'cs': 'en', # Czech not supported by timeago, fallback to English
|
'cs': 'en', # Czech not supported by timeago, fallback to English
|
||||||
|
'en_GB': 'en', # British English - timeago uses 'en'
|
||||||
|
'en_US': 'en', # American English - timeago uses 'en'
|
||||||
}
|
}
|
||||||
return locale_map.get(flask_locale, flask_locale)
|
return locale_map.get(flask_locale, flask_locale)
|
||||||
|
|
||||||
# Language metadata: flag icon CSS class and native name
|
# Language metadata: flag icon CSS class and native name
|
||||||
# Using flag-icons library: https://flagicons.lipis.dev/
|
# Using flag-icons library: https://flagicons.lipis.dev/
|
||||||
LANGUAGE_DATA = {
|
LANGUAGE_DATA = {
|
||||||
'en': {'flag': 'fi fi-gb fis', 'name': 'English'},
|
'en_GB': {'flag': 'fi fi-gb fis', 'name': 'English (UK)'},
|
||||||
|
'en_US': {'flag': 'fi fi-us fis', 'name': 'English (US)'},
|
||||||
'de': {'flag': 'fi fi-de fis', 'name': 'Deutsch'},
|
'de': {'flag': 'fi fi-de fis', 'name': 'Deutsch'},
|
||||||
'fr': {'flag': 'fi fi-fr fis', 'name': 'Français'},
|
'fr': {'flag': 'fi fi-fr fis', 'name': 'Français'},
|
||||||
'ko': {'flag': 'fi fi-kr fis', 'name': '한국어'},
|
'ko': {'flag': 'fi fi-kr fis', 'name': '한국어'},
|
||||||
@@ -71,10 +74,7 @@ def get_available_languages():
|
|||||||
"""
|
"""
|
||||||
translations_dir = Path(__file__).parent / 'translations'
|
translations_dir = Path(__file__).parent / 'translations'
|
||||||
|
|
||||||
# Always include English as base language
|
available = {}
|
||||||
available = {
|
|
||||||
'en': LANGUAGE_DATA['en']
|
|
||||||
}
|
|
||||||
|
|
||||||
# Scan for translation directories
|
# Scan for translation directories
|
||||||
if translations_dir.exists():
|
if translations_dir.exists():
|
||||||
@@ -85,6 +85,10 @@ def get_available_languages():
|
|||||||
if po_file.exists():
|
if po_file.exists():
|
||||||
available[lang_dir.name] = LANGUAGE_DATA[lang_dir.name]
|
available[lang_dir.name] = LANGUAGE_DATA[lang_dir.name]
|
||||||
|
|
||||||
|
# If no English variants found, fall back to adding en_GB as default
|
||||||
|
if 'en_GB' not in available and 'en_US' not in available:
|
||||||
|
available['en_GB'] = LANGUAGE_DATA['en_GB']
|
||||||
|
|
||||||
return available
|
return available
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,17 +3,17 @@
|
|||||||
* Allows users to select their preferred language
|
* Allows users to select their preferred language
|
||||||
*/
|
*/
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
$(document).ready(function() {
|
||||||
const languageButton = document.getElementById('language-selector');
|
const $languageButton = $('.language-selector');
|
||||||
const languageModal = document.getElementById('language-modal');
|
const $languageModal = $('#language-modal');
|
||||||
const closeButton = document.getElementById('close-language-modal');
|
const $closeButton = $('#close-language-modal');
|
||||||
|
|
||||||
if (!languageButton || !languageModal) {
|
if (!$languageButton.length || !$languageModal.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open modal when language button is clicked
|
// Open modal when language button is clicked
|
||||||
languageButton.addEventListener('click', function(e) {
|
$languageButton.on('click', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// Update all language links to include current hash in the redirect parameter
|
// Update all language links to include current hash in the redirect parameter
|
||||||
@@ -21,51 +21,53 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
const currentHash = window.location.hash;
|
const currentHash = window.location.hash;
|
||||||
|
|
||||||
if (currentHash) {
|
if (currentHash) {
|
||||||
const languageOptions = languageModal.querySelectorAll('.language-option');
|
const $languageOptions = $languageModal.find('.language-option');
|
||||||
languageOptions.forEach(function(option) {
|
$languageOptions.each(function() {
|
||||||
const url = new URL(option.href, window.location.origin);
|
const $option = $(this);
|
||||||
|
const url = new URL($option.attr('href'), window.location.origin);
|
||||||
// Update the redirect parameter to include the hash
|
// Update the redirect parameter to include the hash
|
||||||
const redirectPath = currentPath + currentHash;
|
const redirectPath = currentPath + currentHash;
|
||||||
url.searchParams.set('redirect', redirectPath);
|
url.searchParams.set('redirect', redirectPath);
|
||||||
option.setAttribute('href', url.pathname + url.search + url.hash);
|
$option.attr('href', url.pathname + url.search + url.hash);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
languageModal.showModal();
|
$languageModal[0].showModal();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Close modal when cancel button is clicked
|
// Close modal when cancel button is clicked
|
||||||
if (closeButton) {
|
if ($closeButton.length) {
|
||||||
closeButton.addEventListener('click', function() {
|
$closeButton.on('click', function() {
|
||||||
languageModal.close();
|
$languageModal[0].close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close modal when clicking outside (on backdrop)
|
// Close modal when clicking outside (on backdrop)
|
||||||
languageModal.addEventListener('click', function(e) {
|
$languageModal.on('click', function(e) {
|
||||||
const rect = languageModal.getBoundingClientRect();
|
const rect = this.getBoundingClientRect();
|
||||||
if (
|
if (
|
||||||
e.clientY < rect.top ||
|
e.clientY < rect.top ||
|
||||||
e.clientY > rect.bottom ||
|
e.clientY > rect.bottom ||
|
||||||
e.clientX < rect.left ||
|
e.clientX < rect.left ||
|
||||||
e.clientX > rect.right
|
e.clientX > rect.right
|
||||||
) {
|
) {
|
||||||
languageModal.close();
|
$languageModal[0].close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Close modal on Escape key
|
// Close modal on Escape key
|
||||||
languageModal.addEventListener('cancel', function(e) {
|
$languageModal.on('cancel', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
languageModal.close();
|
$languageModal[0].close();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Highlight current language
|
// Highlight current language
|
||||||
const currentLocale = document.documentElement.lang || 'en';
|
const currentLocale = $('html').attr('lang') || 'en';
|
||||||
const languageOptions = languageModal.querySelectorAll('.language-option');
|
const $languageOptions = $languageModal.find('.language-option');
|
||||||
languageOptions.forEach(function(option) {
|
$languageOptions.each(function() {
|
||||||
if (option.dataset.locale === currentLocale) {
|
const $option = $(this);
|
||||||
option.classList.add('active');
|
if ($option.attr('data-locale') === currentLocale) {
|
||||||
|
$option.addClass('active');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -120,7 +120,8 @@ $(document).ready(function () {
|
|||||||
console.log(`${data.event_timestamp} - Queue size update: ${data.q_length}`);
|
console.log(`${data.event_timestamp} - Queue size update: ${data.q_length}`);
|
||||||
|
|
||||||
// Update queue bubble in action sidebar
|
// Update queue bubble in action sidebar
|
||||||
if (queueBubble) {
|
//if (queueBubble) {
|
||||||
|
if (0) {
|
||||||
const count = parseInt(data.q_length) || 0;
|
const count = parseInt(data.q_length) || 0;
|
||||||
const oldCount = parseInt(queueBubble.getAttribute('data-count')) || 0;
|
const oldCount = parseInt(queueBubble.getAttribute('data-count')) || 0;
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,12 @@
|
|||||||
* Toggles theme between light and dark mode.
|
* Toggles theme between light and dark mode.
|
||||||
*/
|
*/
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
const button = document.getElementById("toggle-light-mode");
|
|
||||||
|
|
||||||
button.onclick = () => {
|
$(".toggle-light-mode").on("click", function () {
|
||||||
const htmlElement = document.getElementsByTagName("html");
|
const isDark = $("html").attr("data-darkmode") === "true";
|
||||||
const isDarkMode = htmlElement[0].dataset.darkmode === "true";
|
$("html").attr("data-darkmode", !isDark);
|
||||||
htmlElement[0].dataset.darkmode = !isDarkMode;
|
setCookieValue(!isDark);
|
||||||
setCookieValue(!isDarkMode);
|
});
|
||||||
};
|
|
||||||
|
|
||||||
const setCookieValue = (value) => {
|
const setCookieValue = (value) => {
|
||||||
document.cookie = `css_dark_mode=${value};max-age=31536000;path=/`
|
document.cookie = `css_dark_mode=${value};max-age=31536000;path=/`
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* SCSS variables (compile-time)
|
||||||
|
* These can be used in media queries and other places where CSS custom properties don't work
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Breakpoints
|
||||||
|
$desktop-wide-breakpoint: 980px;
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
z-index: 10;
|
z-index: 0;
|
||||||
|
|
||||||
@media only screen and (max-width: 900px) {
|
@media only screen and (max-width: 900px) {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
padding: 1rem 0.5rem;
|
padding: 0;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
|
|
||||||
#toggle-light-mode {
|
.toggle-light-mode {
|
||||||
/* width: 3rem;*/
|
|
||||||
/* default */
|
/* default */
|
||||||
.icon-dark {
|
.icon-dark {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-darkmode="true"] {
|
html[data-darkmode="true"] {
|
||||||
#toggle-light-mode {
|
.toggle-light-mode {
|
||||||
.icon-light {
|
.icon-light {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// Hamburger Menu for Mobile Navigation
|
// Hamburger Menu for Mobile Navigation
|
||||||
|
@use "../settings" as *;
|
||||||
|
|
||||||
.hamburger-menu {
|
.hamburger-menu {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -9,7 +10,7 @@
|
|||||||
z-index: 10001;
|
z-index: 10001;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@media only screen and (max-width: 768px) {
|
@media only screen and (max-width: $desktop-wide-breakpoint) {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -97,7 +98,7 @@
|
|||||||
li {
|
li {
|
||||||
border-bottom: 1px solid var(--color-border-table-cell);
|
border-bottom: 1px solid var(--color-border-table-cell);
|
||||||
|
|
||||||
a {
|
>* {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
@@ -135,9 +136,9 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide regular menu items on mobile
|
// Hide regular menu items on mobile (but not in mobile drawer)
|
||||||
@media only screen and (max-width: 768px) {
|
@media only screen and (max-width: $desktop-wide-breakpoint) {
|
||||||
.menu-collapsible {
|
#top-right-menu .menu-collapsible {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +152,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Desktop - hide mobile menu elements
|
// Desktop - hide mobile menu elements
|
||||||
@media only screen and (min-width: 769px) {
|
@media only screen and (min-width: 1025px) {
|
||||||
.hamburger-menu,
|
.hamburger-menu,
|
||||||
.mobile-menu-drawer,
|
.mobile-menu-drawer,
|
||||||
.mobile-menu-overlay {
|
.mobile-menu-overlay {
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#language-selector-flag {
|
||||||
|
display: inline-block;
|
||||||
|
width: 1.2em;
|
||||||
|
height: 1.2em;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 0.6;
|
||||||
|
&:hover {
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Language Selector Modal Styles
|
||||||
|
.language-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-option {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--color-text);
|
||||||
|
border: 1px solid transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-background-menu-link-hover);
|
||||||
|
border-color: var(--color-border-table-cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: var(--color-link);
|
||||||
|
color: var(--color-text-button);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flag {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-name {
|
||||||
|
flex-grow: 1;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#language-modal {
|
||||||
|
.language-list {
|
||||||
|
.lang-option {
|
||||||
|
display: inline-block;
|
||||||
|
width: 1.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -20,23 +20,8 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||||
|
|
||||||
// Subtle accent line at top
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 4px;
|
|
||||||
background: linear-gradient(
|
|
||||||
90deg,
|
|
||||||
var(--color-link) 0%,
|
|
||||||
var(--color-menu-accent) 100%
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 15px 50px rgba(0, 0, 0, 0.12),
|
0 15px 50px rgba(0, 0, 0, 0.12),
|
||||||
0 5px 15px rgba(0, 0, 0, 0.06);
|
0 5px 15px rgba(0, 0, 0, 0.06);
|
||||||
@@ -108,7 +93,6 @@
|
|||||||
box-shadow: 0 2px 8px rgba(27, 152, 248, 0.2);
|
box-shadow: 0 2px 8px rgba(27, 152, 248, 0.2);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(27, 152, 248, 0.3);
|
box-shadow: 0 4px 12px rgba(27, 152, 248, 0.3);
|
||||||
background: #0066cc;
|
background: #0066cc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,3 +31,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#cdio-logo {
|
||||||
|
padding-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#inline-menu-extras-group {
|
||||||
|
>* {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
body.wrapped-tabs {
|
||||||
|
.tabs {
|
||||||
|
ul {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(var(--tab-width, 180px), 1fr));
|
||||||
|
grid-auto-flow: row;
|
||||||
|
grid-auto-columns: unset;
|
||||||
|
gap: 0;
|
||||||
|
column-gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
ul {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
display: grid;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
grid-auto-columns: max-content;
|
||||||
|
gap: 5px;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
white-space: nowrap;
|
||||||
|
color: var(--color-text-tab);
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
background-color: var(--color-background-tab);
|
||||||
|
|
||||||
|
&:not(.active) {
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-background-tab-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active,
|
||||||
|
:target {
|
||||||
|
background-color: var(--color-background);
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--color-text-tab-active);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
padding: 0.7em;
|
||||||
|
color: var(--color-text-tab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
* -- BASE STYLES --
|
* -- BASE STYLES --
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@use "settings" as *;
|
||||||
@use "parts/variables";
|
@use "parts/variables";
|
||||||
@use "parts/arrows";
|
@use "parts/arrows";
|
||||||
@use "parts/browser-steps";
|
@use "parts/browser-steps";
|
||||||
@@ -23,12 +24,14 @@
|
|||||||
@use "parts/widgets";
|
@use "parts/widgets";
|
||||||
@use "parts/diff_image";
|
@use "parts/diff_image";
|
||||||
@use "parts/modal";
|
@use "parts/modal";
|
||||||
|
@use "parts/language";
|
||||||
@use "parts/action_sidebar";
|
@use "parts/action_sidebar";
|
||||||
@use "parts/hamburger_menu";
|
@use "parts/hamburger_menu";
|
||||||
@use "parts/search_modal";
|
@use "parts/search_modal";
|
||||||
@use "parts/notification_bubble";
|
@use "parts/notification_bubble";
|
||||||
@use "parts/toast";
|
@use "parts/toast";
|
||||||
@use "parts/login_form";
|
@use "parts/login_form";
|
||||||
|
@use "parts/tabs";
|
||||||
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -157,7 +160,13 @@ body.spinner-active {
|
|||||||
}
|
}
|
||||||
|
|
||||||
section.content {
|
section.content {
|
||||||
padding-top: 100px;
|
@media only screen and (max-width: $desktop-wide-breakpoint) {
|
||||||
|
padding-top: 80px;
|
||||||
|
}
|
||||||
|
@media only screen and (min-width: $desktop-wide-breakpoint) {
|
||||||
|
padding-top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -175,13 +184,13 @@ code {
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
|
line-height: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Processor type badges - colors auto-generated from processor names */
|
/* Processor type badges - colors auto-generated from processor names */
|
||||||
.processor-badge {
|
.processor-badge {
|
||||||
@extend .inline-tag;
|
@extend .inline-tag;
|
||||||
font-size: 0.85em;
|
font-weight: 900;
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.watch-tag-list {
|
.watch-tag-list {
|
||||||
@@ -514,6 +523,9 @@ footer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sticky-tab {
|
.sticky-tab {
|
||||||
|
@media only screen and (max-width: $desktop-wide-breakpoint) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 60px;
|
top: 60px;
|
||||||
font-size: 65%;
|
font-size: 65%;
|
||||||
@@ -658,7 +670,7 @@ footer {
|
|||||||
|
|
||||||
|
|
||||||
@media only screen and (max-width: 760px),
|
@media only screen and (max-width: 760px),
|
||||||
(min-device-width: 768px) and (max-device-width: 1024px) {
|
(min-device-width: 768px) and (max-device-width: $desktop-wide-breakpoint) {
|
||||||
.edit-form {
|
.edit-form {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -670,30 +682,10 @@ footer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@media only screen and (max-width: 760px),
|
@media only screen and (max-width: 760px), (min-device-width: 768px) and (max-device-width: $desktop-wide-breakpoint) {
|
||||||
(min-device-width: 768px) and (max-device-width: 800px) {
|
|
||||||
|
|
||||||
div.sticky-tab#hosted-sticky {
|
|
||||||
top: 60px;
|
|
||||||
left: 0px;
|
|
||||||
right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
section.content {
|
|
||||||
padding-top: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the tabs easier to hit, they will be all nice and horizontal
|
|
||||||
div.tabs.collapsable ul li {
|
|
||||||
display: block;
|
|
||||||
border-radius: 0px;
|
|
||||||
margin-right: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type='text'] {
|
input[type='text'] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pure-table {
|
.pure-table {
|
||||||
@@ -769,45 +761,6 @@ textarea::placeholder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.tabs {
|
|
||||||
ul {
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin-right: 1px;
|
|
||||||
display: inline-block;
|
|
||||||
color: var(--color-text-tab);
|
|
||||||
border-top-left-radius: 5px;
|
|
||||||
border-top-right-radius: 5px;
|
|
||||||
background-color: var(--color-background-tab);
|
|
||||||
|
|
||||||
&:not(.active) {
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--color-background-tab-hover);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active,
|
|
||||||
:target {
|
|
||||||
background-color: var(--color-background);
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--color-text-tab-active);
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
display: block;
|
|
||||||
padding: 0.7em;
|
|
||||||
color: var(--color-text-tab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$form-edge-padding: 20px;
|
$form-edge-padding: 20px;
|
||||||
|
|
||||||
.pure-form-stacked {
|
.pure-form-stacked {
|
||||||
@@ -1144,44 +1097,4 @@ ul#highlightSnippetActions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Language Selector Modal Styles
|
|
||||||
.language-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 0.5rem;
|
|
||||||
padding: 0.5rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-option {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 1rem;
|
|
||||||
padding: 0.25rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: background-color 0.2s ease;
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--color-text);
|
|
||||||
border: 1px solid transparent;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--color-background-menu-link-hover);
|
|
||||||
border-color: var(--color-border-table-cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background-color: var(--color-link);
|
|
||||||
color: var(--color-text-button);
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flag {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.language-name {
|
|
||||||
flex-grow: 1;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -145,6 +145,7 @@
|
|||||||
<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>
|
</div>
|
||||||
|
|
||||||
<div class="pure-control-group grey-form-border">
|
<div class="pure-control-group grey-form-border">
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
{{ render_field(form.notification_title, class="m-d notification-title", placeholder=settings_application['notification_title']) }}
|
{{ render_field(form.notification_title, class="m-d notification-title", placeholder=settings_application['notification_title']) }}
|
||||||
@@ -169,6 +170,7 @@
|
|||||||
</span></li>
|
</span></li>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="">
|
<div class="">
|
||||||
{{ render_field(form.notification_format , class="notification-format") }}
|
{{ render_field(form.notification_format , class="notification-format") }}
|
||||||
|
|||||||
@@ -53,10 +53,10 @@
|
|||||||
<div class="home-menu pure-menu pure-menu-horizontal" id="nav-menu">
|
<div class="home-menu pure-menu pure-menu-horizontal" id="nav-menu">
|
||||||
|
|
||||||
{% if has_password and not current_user.is_authenticated %}
|
{% if has_password and not current_user.is_authenticated %}
|
||||||
<a class="pure-menu-heading" href="https://changedetection.io" rel="noopener">
|
<a id="cdio-logo" class="pure-menu-heading" href="https://changedetection.io" rel="noopener">
|
||||||
<strong>Change</strong>Detection.io</a>
|
<strong>Change</strong>Detection.io</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="pure-menu-heading" href="{{url_for('watchlist.index')}}">
|
<a id="cdio-logo" class="pure-menu-heading" href="{{url_for('watchlist.index')}}">
|
||||||
<strong>Change</strong>Detection.io</a>
|
<strong>Change</strong>Detection.io</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if current_diff_url and is_safe_valid_url(current_diff_url) %}
|
{% if current_diff_url and is_safe_valid_url(current_diff_url) %}
|
||||||
@@ -72,61 +72,19 @@
|
|||||||
|
|
||||||
<ul class="pure-menu-list" id="top-right-menu">
|
<ul class="pure-menu-list" id="top-right-menu">
|
||||||
<!-- Collapsible menu items (hidden on mobile, shown in drawer) -->
|
<!-- Collapsible menu items (hidden on mobile, shown in drawer) -->
|
||||||
|
{% include "menu.html" %}
|
||||||
|
|
||||||
{% if current_user.is_authenticated or not has_password %}
|
{% if current_user.is_authenticated or not has_password %}
|
||||||
{% if not current_diff_url %}
|
{% if not current_diff_url %}
|
||||||
<li class="pure-menu-item menu-collapsible {% if request.endpoint.startswith('tags.') %}active{% endif %}">
|
<li class="pure-menu-item menu-collapsible">
|
||||||
<a href="{{ url_for('tags.tags_overview_page')}}" class="pure-menu-link">{{ _('GROUPS') }}</a>
|
<button class="toggle-button" id="open-search-modal" type="button" title="{{ _('Search, or Use Alt+S Key') }}">
|
||||||
</li>
|
{% include "svgs/search-icon.svg" %}
|
||||||
<li class="pure-menu-item menu-collapsible {% if request.endpoint.startswith('settings.') %}active{% endif %}">
|
</button>
|
||||||
<a href="{{ url_for('settings.settings_page')}}" class="pure-menu-link">{{ _('SETTINGS') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="pure-menu-item menu-collapsible {% if request.endpoint.startswith('imports.') %}active{% endif %}">
|
|
||||||
<a href="{{ url_for('imports.import_page')}}" class="pure-menu-link">{{ _('IMPORT') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="pure-menu-item menu-collapsible {% if request.endpoint.startswith('backups.') %}active{% endif %}">
|
|
||||||
<a href="{{ url_for('backups.index')}}" class="pure-menu-link">{{ _('BACKUPS') }}</a>
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
<li class="pure-menu-item menu-collapsible">
|
|
||||||
<a href="{{ url_for('ui.ui_edit.edit_page', uuid=uuid, next='diff') }}" class="pure-menu-link">{{ _('EDIT') }}</a>
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
|
||||||
<li class="pure-menu-item menu-collapsible">
|
|
||||||
<a class="pure-menu-link" href="https://changedetection.io">Website Change Detection and Notification.</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% if current_user.is_authenticated %}
|
|
||||||
<li class="pure-menu-item menu-collapsible">
|
|
||||||
<a href="{{url_for('logout', redirect=request.path)}}" class="pure-menu-link">{{ _('LOG OUT') }}</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- Always visible items -->
|
|
||||||
{% if current_user.is_authenticated or not has_password %}
|
|
||||||
<li class="pure-menu-item">
|
|
||||||
<button class="toggle-button" id="open-search-modal" type="button" title="{{ _('Search, or Use Alt+S Key') }}">
|
|
||||||
{% include "svgs/search-icon.svg" %}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
<li class="pure-menu-item">
|
|
||||||
<button class="toggle-button" id ="toggle-light-mode" type="button" title="{{ _('Toggle Light/Dark Mode') }}">
|
|
||||||
<span class="visually-hidden">{{ _('Toggle light/dark mode') }}</span>
|
|
||||||
<span class="icon-light">
|
|
||||||
{% include "svgs/light-mode-toggle-icon.svg" %}
|
|
||||||
</span>
|
|
||||||
<span class="icon-dark">
|
|
||||||
{% include "svgs/dark-mode-toggle-icon.svg" %}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li class="pure-menu-item">
|
|
||||||
<button class="toggle-button" id="language-selector" type="button" title="{{ _('Change Language') }}">
|
|
||||||
<span class="visually-hidden">{{ _('Change language') }}</span>
|
|
||||||
<span class="{{ get_flag_for_locale(get_locale()) }}" style="display: inline-block; width: 1.2em; height: 1.2em; vertical-align: middle; border-radius: 50%; overflow: hidden;"></span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li class="pure-menu-item" id="heart-us">
|
<li class="pure-menu-item" id="heart-us">
|
||||||
<svg
|
<svg
|
||||||
fill="#ff0000"
|
fill="#ff0000"
|
||||||
@@ -136,16 +94,9 @@
|
|||||||
id="svg-heart"
|
id="svg-heart"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
<path id="heartpath" d="M 5.338316,0.50302766 C 0.71136983,0.50647126 -3.9576371,7.2707777 8.5004254,15.503028 23.833425,5.3700277 13.220206,-2.5384409 8.6762066,1.6475589 c -0.060791,0.054322 -0.11943,0.1110064 -0.1757812,0.1699219 -0.057,-0.059 -0.1157813,-0.116875 -0.1757812,-0.171875 C 7.4724566,0.86129334 6.4060729,0.50223298 5.338316,0.50302766 Z"
|
<path id="heartpath" d="M 5.338316,0.50302766 C 0.71136983,0.50647126 -3.9576371,7.2707777 8.5004254,15.503028 23.833425,5.3700277 13.220206,-2.5384409 8.6762066,1.6475589 c -0.060791,0.054322 -0.11943,0.1110064 -0.1757812,0.1699219 -0.057,-0.059 -0.1157813,-0.116875 -0.1757812,-0.171875 C 7.4724566,0.86129334 6.4060729,0.50223298 5.338316,0.50302766 Z" style="fill:var(--color-background);fill-opacity:1;stroke:#ff0000;stroke-opacity:1" />
|
||||||
style="fill:var(--color-background);fill-opacity:1;stroke:#ff0000;stroke-opacity:1" />
|
|
||||||
</svg>
|
</svg>
|
||||||
</li>
|
</li>
|
||||||
<li class="pure-menu-item">
|
|
||||||
<a class="github-link" href="https://github.com/dgtlmoon/changedetection.io">
|
|
||||||
{% include "svgs/github.svg" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<!-- Hamburger menu button (mobile only) -->
|
<!-- Hamburger menu button (mobile only) -->
|
||||||
<li class="pure-menu-item">
|
<li class="pure-menu-item">
|
||||||
<button class="hamburger-menu" id="hamburger-toggle" aria-label="Toggle menu">
|
<button class="hamburger-menu" id="hamburger-toggle" aria-label="Toggle menu">
|
||||||
@@ -163,27 +114,17 @@
|
|||||||
<div class="mobile-menu-overlay" id="mobile-menu-overlay"></div>
|
<div class="mobile-menu-overlay" id="mobile-menu-overlay"></div>
|
||||||
<div class="mobile-menu-drawer" id="mobile-menu-drawer">
|
<div class="mobile-menu-drawer" id="mobile-menu-drawer">
|
||||||
<ul class="mobile-menu-items">
|
<ul class="mobile-menu-items">
|
||||||
{% if current_user.is_authenticated or not has_password %}
|
{% include "menu.html" %}
|
||||||
{% if not current_diff_url %}
|
<li class="pure-menu-item menu-collapsible">
|
||||||
<li><a href="{{ url_for('tags.tags_overview_page')}}">{{ _('GROUPS') }}</a></li>
|
{%- if right_sticky -%}<div>{{ right_sticky }}</div>{%- endif -%}
|
||||||
<li><a href="{{ url_for('settings.settings_page')}}">{{ _('SETTINGS') }}</a></li>
|
<a href="https://changedetection.io/?ref={{ guid }}">Let us host your instance!</a><br>
|
||||||
<li><a href="{{ url_for('imports.import_page')}}">{{ _('IMPORT') }}</a></li>
|
</li>
|
||||||
<li><a href="{{ url_for('backups.index')}}">{{ _('BACKUPS') }}</a></li>
|
|
||||||
{% else %}
|
|
||||||
<li><a href="{{ url_for('ui.ui_edit.edit_page', uuid=uuid, next='diff') }}">{{ _('EDIT') }}</a></li>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% if current_user.is_authenticated %}
|
|
||||||
<li><a href="{{url_for('logout', redirect=request.path)}}">{{ _('LOG OUT') }}</a></li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="pure-menu-horizontal-spinner"></div>
|
<div id="pure-menu-horizontal-spinner"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% if hosted_sticky %}
|
{% if hosted_sticky %}
|
||||||
<div class="sticky-tab" id="hosted-sticky">
|
<div class="sticky-tab" id="hosted-sticky">
|
||||||
<a href="https://changedetection.io/?ref={{guid}}">Let us host your instance!</a>
|
<a href="https://changedetection.io/?ref={{guid}}">Let us host your instance!</a>
|
||||||
@@ -248,6 +189,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
|
{#
|
||||||
{% if current_user.is_authenticated or not has_password %}
|
{% if current_user.is_authenticated or not has_password %}
|
||||||
<aside class="action-sidebar">
|
<aside class="action-sidebar">
|
||||||
<a href="{{ url_for('watchlist.index') }}" class="action-sidebar-item {% if request.endpoint.startswith('watchlist.') or request.endpoint.startswith('ui.') %}active{% endif %}" title="{{ _('Watch List') }}">
|
<a href="{{ url_for('watchlist.index') }}" class="action-sidebar-item {% if request.endpoint.startswith('watchlist.') or request.endpoint.startswith('ui.') %}active{% endif %}" title="{{ _('Watch List') }}">
|
||||||
@@ -257,7 +199,6 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<span class="action-label">{{ _('Watches') }}</span>
|
<span class="action-label">{{ _('Watches') }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('queue_status') }}" class="action-sidebar-item {% if request.endpoint == 'queue_status' %}active{% endif %}" id="queue-action-item" title="{{ _('Queue Status') }}">
|
<a href="{{ url_for('queue_status') }}" class="action-sidebar-item {% if request.endpoint == 'queue_status' %}active{% endif %}" id="queue-action-item" title="{{ _('Queue Status') }}">
|
||||||
<svg class="action-icon" viewBox="0 0 24 24">
|
<svg class="action-icon" viewBox="0 0 24 24">
|
||||||
<line x1="8" y1="6" x2="21" y2="6"/>
|
<line x1="8" y1="6" x2="21" y2="6"/>
|
||||||
@@ -270,56 +211,9 @@
|
|||||||
<span class="action-label">{{ _('Queue') }}</span>
|
<span class="action-label">{{ _('Queue') }}</span>
|
||||||
<span class="notification-bubble blue-bubble" id="queue-bubble" data-count="0"></span>
|
<span class="notification-bubble blue-bubble" id="queue-bubble" data-count="0"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('settings.settings_page') }}" class="action-sidebar-item {% if request.endpoint.startswith('settings.') %}active{% endif %}" title="{{ _('Settings') }}">
|
|
||||||
<svg class="action-icon" viewBox="0 0 24 24">
|
|
||||||
<circle cx="12" cy="12" r="3"/>
|
|
||||||
<path d="M12 1v6m0 6v10M3.5 3.5l4.2 4.2m5.6 5.6l4.2 4.2M1 12h6m6 0h10M3.5 20.5l4.2-4.2m5.6-5.6l4.2-4.2"/>
|
|
||||||
</svg>
|
|
||||||
<span class="action-label">{{ _('Settings') }}</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="{{ url_for('backups.index') }}" class="action-sidebar-item {% if request.endpoint.startswith('backups.') %}active{% endif %}" title="{{ _('Backups') }}">
|
|
||||||
<svg class="action-icon" viewBox="0 0 24 24">
|
|
||||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
||||||
<polyline points="14 2 14 8 20 8"/>
|
|
||||||
<line x1="16" y1="13" x2="8" y2="13"/>
|
|
||||||
<line x1="16" y1="17" x2="8" y2="17"/>
|
|
||||||
<polyline points="10 9 9 9 8 9"/>
|
|
||||||
</svg>
|
|
||||||
<span class="action-label">{{ _('Backups') }}</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="#" class="action-sidebar-item" title="{{ _('Sitemap Crawler') }}">
|
|
||||||
<svg class="action-icon" viewBox="0 0 24 24">
|
|
||||||
<!-- Spider web with map nodes -->
|
|
||||||
<circle cx="12" cy="12" r="2"/>
|
|
||||||
<!-- Radial web lines -->
|
|
||||||
<line x1="12" y1="12" x2="12" y2="4"/>
|
|
||||||
<line x1="12" y1="12" x2="19" y2="7"/>
|
|
||||||
<line x1="12" y1="12" x2="20" y2="12"/>
|
|
||||||
<line x1="12" y1="12" x2="19" y2="17"/>
|
|
||||||
<line x1="12" y1="12" x2="12" y2="20"/>
|
|
||||||
<line x1="12" y1="12" x2="5" y2="17"/>
|
|
||||||
<line x1="12" y1="12" x2="4" y2="12"/>
|
|
||||||
<line x1="12" y1="12" x2="5" y2="7"/>
|
|
||||||
<!-- Outer web ring -->
|
|
||||||
<circle cx="12" cy="12" r="8" fill="none"/>
|
|
||||||
<!-- Map nodes on web -->
|
|
||||||
<circle cx="12" cy="4" r="1.5"/>
|
|
||||||
<circle cx="19" cy="7" r="1.5"/>
|
|
||||||
<circle cx="20" cy="12" r="1.5"/>
|
|
||||||
<circle cx="19" cy="17" r="1.5"/>
|
|
||||||
<circle cx="12" cy="20" r="1.5"/>
|
|
||||||
<circle cx="5" cy="17" r="1.5"/>
|
|
||||||
<circle cx="4" cy="12" r="1.5"/>
|
|
||||||
<circle cx="5" cy="7" r="1.5"/>
|
|
||||||
</svg>
|
|
||||||
<span class="action-label">{{ _('Sitemap') }}</span>
|
|
||||||
</a>
|
|
||||||
</aside>
|
</aside>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
#}
|
||||||
<div class="content-main">
|
<div class="content-main">
|
||||||
<header>
|
<header>
|
||||||
{% block header %}{% endblock %}
|
{% block header %}{% endblock %}
|
||||||
@@ -367,7 +261,7 @@
|
|||||||
<div class="language-list">
|
<div class="language-list">
|
||||||
{% for locale, lang_data in available_languages.items()|sort %}
|
{% for locale, lang_data in available_languages.items()|sort %}
|
||||||
<a href="{{ url_for('set_language', locale=locale, redirect=request.path) }}" class="language-option" data-locale="{{ locale }}">
|
<a href="{{ url_for('set_language', locale=locale, redirect=request.path) }}" class="language-option" data-locale="{{ locale }}">
|
||||||
<span class="{{ lang_data.flag }}" style="display: inline-block; width: 1.5em; height: 1.5em; vertical-align: middle; margin-right: 0.5em; border-radius: 50%; overflow: hidden;"></span> <span class="language-name">{{ lang_data.name }}</span>
|
<span class="lang-option {{ lang_data.flag }}"></span> <span class="language-name">{{ lang_data.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
@@ -402,6 +296,77 @@
|
|||||||
</dialog>
|
</dialog>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
/* AUTOMATIC TAB COLUMN-IZER FOR WHEN TABS WRAP */
|
||||||
|
// Exit early if no tabs on page
|
||||||
|
if (!document.querySelector('.tab')) return;
|
||||||
|
|
||||||
|
const cache = new Map();
|
||||||
|
|
||||||
|
function checkWrapping(ul) {
|
||||||
|
const tabs = ul.querySelectorAll('.tab');
|
||||||
|
if (tabs.length < 2) return false;
|
||||||
|
|
||||||
|
// Init cache on first run
|
||||||
|
if (!cache.has(ul)) {
|
||||||
|
ul.style.setProperty('--tab-width', '');
|
||||||
|
void ul.offsetHeight;
|
||||||
|
let max = 0;
|
||||||
|
tabs.forEach(t => max = Math.max(max, t.offsetWidth));
|
||||||
|
cache.set(ul, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temporarily use flex wrap to check if wrapping occurs
|
||||||
|
ul.style.display = 'flex';
|
||||||
|
ul.style.flexWrap = 'wrap';
|
||||||
|
void ul.offsetHeight;
|
||||||
|
|
||||||
|
const top = tabs[0].offsetTop;
|
||||||
|
const wrapped = Array.from(tabs).some((t, i) => i > 0 && t.offsetTop !== top);
|
||||||
|
|
||||||
|
// Reset display to use CSS grid
|
||||||
|
ul.style.display = '';
|
||||||
|
ul.style.flexWrap = '';
|
||||||
|
|
||||||
|
// Set CSS variable for wrapped mode
|
||||||
|
if (wrapped) {
|
||||||
|
ul.style.setProperty('--tab-width', `${cache.get(ul) + 10}px`);
|
||||||
|
} else {
|
||||||
|
ul.style.setProperty('--tab-width', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
let any = false;
|
||||||
|
document.querySelectorAll('ul').forEach(ul => {
|
||||||
|
if (ul.querySelector('.tab') && checkWrapping(ul)) any = true;
|
||||||
|
});
|
||||||
|
document.body.classList.toggle('wrapped-tabs', any);
|
||||||
|
}
|
||||||
|
|
||||||
|
check();
|
||||||
|
let timer;
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = setTimeout(check, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Re-check wrapping when tabs are switched via anchors
|
||||||
|
window.addEventListener('hashchange', () => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
// Use requestAnimationFrame + setTimeout to ensure DOM has settled
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
timer = setTimeout(check, 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<script src="{{url_for('static_content', group='js', filename='language-selector.js')}}" defer></script>
|
<script src="{{url_for('static_content', group='js', filename='language-selector.js')}}" defer></script>
|
||||||
<script src="{{url_for('static_content', group='js', filename='search-modal.js')}}" defer></script>
|
<script src="{{url_for('static_content', group='js', filename='search-modal.js')}}" defer></script>
|
||||||
<script src="{{url_for('static_content', group='js', filename='toast.js')}}"></script>
|
<script src="{{url_for('static_content', group='js', filename='toast.js')}}"></script>
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
{# Menu items template - used for both desktop and mobile menus #}
|
||||||
|
{# CSS media queries handle which version displays - no need for conditional classes #}
|
||||||
|
|
||||||
|
|
||||||
|
{% if current_user.is_authenticated or not has_password %}
|
||||||
|
{% if not current_diff_url %}
|
||||||
|
<li class="pure-menu-item menu-collapsible {% if request.endpoint.startswith('tags.') %}active{% endif %}">
|
||||||
|
<a href="{{ url_for('tags.tags_overview_page') }}" class="pure-menu-link">{{ _('GROUPS') }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="pure-menu-item menu-collapsible {% if request.endpoint.startswith('settings.') %}active{% endif %}">
|
||||||
|
<a href="{{ url_for('settings.settings_page') }}" class="pure-menu-link">{{ _('SETTINGS') }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="pure-menu-item menu-collapsible {% if request.endpoint.startswith('imports.') %}active{% endif %}">
|
||||||
|
<a href="{{ url_for('imports.import_page') }}" class="pure-menu-link">{{ _('IMPORT') }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="pure-menu-item menu-collapsible {% if request.endpoint.startswith('backups.') %}active{% endif %}">
|
||||||
|
<a href="{{ url_for('backups.index') }}" class="pure-menu-link">{{ _('BACKUPS') }}</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="pure-menu-item menu-collapsible">
|
||||||
|
<a href="{{ url_for('ui.ui_edit.edit_page', uuid=uuid, next='diff') }}"
|
||||||
|
class="pure-menu-link">{{ _('EDIT') }}</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{%- if current_user.is_authenticated -%}
|
||||||
|
<li class="pure-menu-item menu-collapsible">
|
||||||
|
<a href="{{ url_for('logout', redirect=request.path) }}" class="pure-menu-link">{{ _('LOG OUT') }}</a>
|
||||||
|
</li>
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<li class="pure-menu-item menu-collapsible">
|
||||||
|
<a class="pure-menu-link" href="https://changedetection.io">Website Change Detection and Notification.</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
<li class="pure-menu-item menu-collapsible" id="inline-menu-extras-group">
|
||||||
|
<button class="toggle-button toggle-light-mode " type="button" title="{{ _('Toggle Light/Dark Mode') }}">
|
||||||
|
<span class="visually-hidden">{{ _('Toggle light/dark mode') }}</span>
|
||||||
|
<span class="icon-light">
|
||||||
|
{% include "svgs/light-mode-toggle-icon.svg" %}
|
||||||
|
</span>
|
||||||
|
<span class="icon-dark">
|
||||||
|
{% include "svgs/dark-mode-toggle-icon.svg" %}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="toggle-button language-selector" type="button" title="{{ _('Change Language') }}">
|
||||||
|
<span class="visually-hidden">{{ _('Change language') }}</span>
|
||||||
|
<span class="{{ get_flag_for_locale(get_locale()) }}" id="language-selector-flag"></span>
|
||||||
|
</button>
|
||||||
|
<a class="github-link" href="https://github.com/dgtlmoon/changedetection.io">
|
||||||
|
{% include "svgs/github.svg" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
@@ -165,18 +165,83 @@ def test_api_simple(client, live_server, measure_memory_usage, datastore_path):
|
|||||||
assert b'<div id' in res.data
|
assert b'<div id' in res.data
|
||||||
|
|
||||||
|
|
||||||
# Fetch the difference between two versions
|
# Fetch the difference between two versions (default text format)
|
||||||
res = client.get(
|
res = client.get(
|
||||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest'),
|
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest'),
|
||||||
headers={'x-api-key': api_key},
|
headers={'x-api-key': api_key},
|
||||||
)
|
)
|
||||||
assert b'(changed) Which is across' in res.data
|
assert b'(changed) Which is across' in res.data
|
||||||
|
|
||||||
|
# Test htmlcolor format
|
||||||
res = client.get(
|
res = client.get(
|
||||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?format=htmlcolor',
|
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?format=htmlcolor',
|
||||||
headers={'x-api-key': api_key},
|
headers={'x-api-key': api_key},
|
||||||
)
|
)
|
||||||
assert b'aria-label="Changed text" title="Changed text">Which is across multiple lines' in res.data
|
assert b'aria-label="Changed text" title="Changed text">Which is across multiple lines' in res.data
|
||||||
|
|
||||||
|
# Test html format
|
||||||
|
res = client.get(
|
||||||
|
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?format=html',
|
||||||
|
headers={'x-api-key': api_key},
|
||||||
|
)
|
||||||
|
assert res.status_code == 200
|
||||||
|
assert b'<br>' in res.data
|
||||||
|
|
||||||
|
# Test markdown format
|
||||||
|
res = client.get(
|
||||||
|
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?format=markdown',
|
||||||
|
headers={'x-api-key': api_key},
|
||||||
|
)
|
||||||
|
assert res.status_code == 200
|
||||||
|
|
||||||
|
# Test new diff preference parameters
|
||||||
|
# Test removed=false (should hide removed content)
|
||||||
|
res = client.get(
|
||||||
|
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?removed=false',
|
||||||
|
headers={'x-api-key': api_key},
|
||||||
|
)
|
||||||
|
# Should not contain removed content indicator
|
||||||
|
assert b'(removed)' not in res.data
|
||||||
|
# Should still contain added content
|
||||||
|
assert b'(added)' in res.data or b'which has this one new line' in res.data
|
||||||
|
|
||||||
|
# Test added=false (should hide added content)
|
||||||
|
# Note: The test data has replacements, not pure additions, so we test differently
|
||||||
|
res = client.get(
|
||||||
|
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?added=false&replaced=false',
|
||||||
|
headers={'x-api-key': api_key},
|
||||||
|
)
|
||||||
|
# With both added and replaced disabled, should have minimal content
|
||||||
|
# Should not contain added indicators
|
||||||
|
assert b'(added)' not in res.data
|
||||||
|
|
||||||
|
# Test replaced=false (should hide replaced/changed content)
|
||||||
|
res = client.get(
|
||||||
|
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?replaced=false',
|
||||||
|
headers={'x-api-key': api_key},
|
||||||
|
)
|
||||||
|
# Should not contain changed content indicator
|
||||||
|
assert b'(changed)' not in res.data
|
||||||
|
|
||||||
|
# Test type=diffWords for word-level diff
|
||||||
|
res = client.get(
|
||||||
|
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?type=diffWords&format=htmlcolor',
|
||||||
|
headers={'x-api-key': api_key},
|
||||||
|
)
|
||||||
|
# Should contain HTML formatted diff
|
||||||
|
assert res.status_code == 200
|
||||||
|
assert len(res.data) > 0
|
||||||
|
|
||||||
|
# Test combined parameters: show only additions with word diff
|
||||||
|
res = client.get(
|
||||||
|
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?removed=false&replaced=false&type=diffWords',
|
||||||
|
headers={'x-api-key': api_key},
|
||||||
|
)
|
||||||
|
assert res.status_code == 200
|
||||||
|
# Should not contain removed or changed markers
|
||||||
|
assert b'(removed)' not in res.data
|
||||||
|
assert b'(changed)' not in res.data
|
||||||
|
|
||||||
|
|
||||||
# Fetch the whole watch
|
# Fetch the whole watch
|
||||||
res = client.get(
|
res = client.get(
|
||||||
|
|||||||
@@ -25,12 +25,13 @@ def test_content_filter_live_preview(client, live_server, measure_memory_usage,
|
|||||||
|
|
||||||
test_url = url_for('test_endpoint', _external=True)
|
test_url = url_for('test_endpoint', _external=True)
|
||||||
|
|
||||||
res = client.post(
|
|
||||||
url_for("ui.ui_views.form_quick_watch_add"),
|
uuid = client.application.config.get('DATASTORE').add_watch(url=test_url)
|
||||||
data={"url": test_url, "tags": ''},
|
res = client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||||
follow_redirects=True
|
assert b'Queued 1 watch for rechecking.' in res.data
|
||||||
)
|
|
||||||
uuid = next(iter(live_server.app.config['DATASTORE'].data['watching']))
|
wait_for_all_checks(client)
|
||||||
|
|
||||||
res = client.post(
|
res = client.post(
|
||||||
url_for("ui.ui_edit.edit_page", uuid=uuid),
|
url_for("ui.ui_edit.edit_page", uuid=uuid),
|
||||||
data={
|
data={
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import re
|
|||||||
from flask import url_for
|
from flask import url_for
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from .util import set_original_response, set_modified_response, set_more_modified_response, live_server_setup, wait_for_all_checks
|
from .util import set_original_response, set_modified_response, set_more_modified_response, live_server_setup, wait_for_all_checks, wait_for_notification_endpoint_output
|
||||||
from . util import extract_UUID_from_client
|
from . util import extract_UUID_from_client
|
||||||
import logging
|
import logging
|
||||||
import base64
|
import base64
|
||||||
@@ -83,7 +83,9 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore
|
|||||||
|
|
||||||
|
|
||||||
uuid = next(iter(live_server.app.config['DATASTORE'].data['watching']))
|
uuid = next(iter(live_server.app.config['DATASTORE'].data['watching']))
|
||||||
with open(os.path.join(datastore_path, str(uuid), 'last-screenshot.png'), 'wb') as f:
|
screenshot_dir = os.path.join(datastore_path, str(uuid))
|
||||||
|
os.makedirs(screenshot_dir, exist_ok=True)
|
||||||
|
with open(os.path.join(screenshot_dir, 'last-screenshot.png'), 'wb') as f:
|
||||||
f.write(base64.b64decode(testimage_png))
|
f.write(base64.b64decode(testimage_png))
|
||||||
|
|
||||||
# Goto the edit page, add our ignore text
|
# Goto the edit page, add our ignore text
|
||||||
@@ -142,7 +144,7 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore
|
|||||||
# Trigger a check
|
# Trigger a check
|
||||||
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||||
wait_for_all_checks(client)
|
wait_for_all_checks(client)
|
||||||
time.sleep(6)
|
wait_for_notification_endpoint_output(datastore_path=datastore_path)
|
||||||
|
|
||||||
# Check no errors were recorded
|
# Check no errors were recorded
|
||||||
res = client.get(url_for("watchlist.index"))
|
res = client.get(url_for("watchlist.index"))
|
||||||
@@ -199,7 +201,7 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore
|
|||||||
set_more_modified_response(datastore_path=datastore_path)
|
set_more_modified_response(datastore_path=datastore_path)
|
||||||
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||||
wait_for_all_checks(client)
|
wait_for_all_checks(client)
|
||||||
time.sleep(6)
|
wait_for_notification_endpoint_output(datastore_path=datastore_path)
|
||||||
# Verify what was sent as a notification, this file should exist
|
# Verify what was sent as a notification, this file should exist
|
||||||
with open(os.path.join(datastore_path, "notification.txt"), "r") as f:
|
with open(os.path.join(datastore_path, "notification.txt"), "r") as f:
|
||||||
notification_submission = f.read()
|
notification_submission = f.read()
|
||||||
@@ -240,7 +242,8 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore
|
|||||||
)
|
)
|
||||||
assert b"Updated watch." in res.data
|
assert b"Updated watch." in res.data
|
||||||
|
|
||||||
time.sleep(2)
|
wait_for_all_checks(client)
|
||||||
|
wait_for_notification_endpoint_output(datastore_path=datastore_path)
|
||||||
|
|
||||||
# Verify what was sent as a notification, this file should exist
|
# Verify what was sent as a notification, this file should exist
|
||||||
with open(os.path.join(datastore_path, "notification.txt"), "r") as f:
|
with open(os.path.join(datastore_path, "notification.txt"), "r") as f:
|
||||||
@@ -325,7 +328,7 @@ def test_notification_custom_endpoint_and_jinja2(client, live_server, measure_me
|
|||||||
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||||
wait_for_all_checks(client)
|
wait_for_all_checks(client)
|
||||||
|
|
||||||
time.sleep(2) # plus extra delay for notifications to fire
|
wait_for_notification_endpoint_output(datastore_path=datastore_path)
|
||||||
|
|
||||||
|
|
||||||
# Check no errors were recorded, because we asked for 204 which is slightly uncommon but is still OK
|
# Check no errors were recorded, because we asked for 204 which is slightly uncommon but is still OK
|
||||||
@@ -443,7 +446,7 @@ def test_global_send_test_notification(client, live_server, measure_memory_usage
|
|||||||
assert res.status_code != 500
|
assert res.status_code != 500
|
||||||
|
|
||||||
# Give apprise time to fire
|
# Give apprise time to fire
|
||||||
time.sleep(4)
|
wait_for_notification_endpoint_output(datastore_path=datastore_path)
|
||||||
|
|
||||||
with open(os.path.join(datastore_path, "notification.txt"), 'r') as f:
|
with open(os.path.join(datastore_path, "notification.txt"), 'r') as f:
|
||||||
x = f.read()
|
x = f.read()
|
||||||
@@ -500,7 +503,7 @@ def test_single_send_test_notification_on_watch(client, live_server, measure_mem
|
|||||||
|
|
||||||
test_notification_url = url_for('test_notification_endpoint', _external=True).replace('http://', 'post://')+"?xxx={{ watch_url }}&+custom-header=123"
|
test_notification_url = url_for('test_notification_endpoint', _external=True).replace('http://', 'post://')+"?xxx={{ watch_url }}&+custom-header=123"
|
||||||
# 1995 UTF-8 content should be encoded
|
# 1995 UTF-8 content should be encoded
|
||||||
test_body = 'change detection is cool 网站监测 内容更新了 - {{diff_full}}'
|
test_body = 'change detection is cool 网站监测 内容更新了 - {{diff_full}}\n\nCurrent snapshot: {{current_snapshot}}'
|
||||||
######### Test global/system settings
|
######### Test global/system settings
|
||||||
res = client.post(
|
res = client.post(
|
||||||
url_for("ui.ui_notification.ajax_callback_send_notification_test")+f"/{uuid}",
|
url_for("ui.ui_notification.ajax_callback_send_notification_test")+f"/{uuid}",
|
||||||
@@ -525,7 +528,8 @@ def test_single_send_test_notification_on_watch(client, live_server, measure_mem
|
|||||||
assert 'title="Changed into">Example text:' not in x
|
assert 'title="Changed into">Example text:' not in x
|
||||||
assert 'span' not in x
|
assert 'span' not in x
|
||||||
assert 'Example text:' in x
|
assert 'Example text:' in x
|
||||||
|
#3720 current_snapshot check, was working but lets test it exactly.
|
||||||
|
assert 'Current snapshot: Example text: example test' in x
|
||||||
os.unlink(os.path.join(datastore_path, "notification.txt"))
|
os.unlink(os.path.join(datastore_path, "notification.txt"))
|
||||||
|
|
||||||
def _test_color_notifications(client, notification_body_token, datastore_path):
|
def _test_color_notifications(client, notification_body_token, datastore_path):
|
||||||
@@ -572,7 +576,7 @@ def _test_color_notifications(client, notification_body_token, datastore_path):
|
|||||||
assert b'Queued 1 watch for rechecking.' in res.data
|
assert b'Queued 1 watch for rechecking.' in res.data
|
||||||
|
|
||||||
wait_for_all_checks(client)
|
wait_for_all_checks(client)
|
||||||
time.sleep(2)
|
wait_for_notification_endpoint_output(datastore_path=datastore_path)
|
||||||
|
|
||||||
with open(os.path.join(datastore_path, "notification.txt"), 'r') as f:
|
with open(os.path.join(datastore_path, "notification.txt"), 'r') as f:
|
||||||
x = f.read()
|
x = f.read()
|
||||||
|
|||||||
Binary file not shown.
@@ -170,7 +170,7 @@ msgstr "Neplatná hodnota."
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:732
|
#: changedetectionio/forms.py:732
|
||||||
msgid "Watch"
|
msgid "Watch"
|
||||||
msgstr "# monitory"
|
msgstr "Monitorovat"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
||||||
msgid "Processor"
|
msgid "Processor"
|
||||||
@@ -178,7 +178,7 @@ msgstr "Procesor"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:734
|
#: changedetectionio/forms.py:734
|
||||||
msgid "Edit > Watch"
|
msgid "Edit > Watch"
|
||||||
msgstr "Nejprve upravte a poté sledujte"
|
msgstr "Upravit > Monitorovat"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
||||||
msgid "Fetch Method"
|
msgid "Fetch Method"
|
||||||
@@ -344,7 +344,7 @@ msgstr "Odeslat upozornění, když filtr již na stránce nelze najít"
|
|||||||
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Žádné informace"
|
msgstr "Oznámení"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
msgid "Muted"
|
msgid "Muted"
|
||||||
@@ -396,7 +396,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Zrušit ztlumení"
|
msgstr "Název"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:921
|
#: changedetectionio/forms.py:921
|
||||||
msgid "Proxy URL"
|
msgid "Proxy URL"
|
||||||
@@ -420,7 +420,7 @@ msgstr "Požadavky na prostý text"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:946
|
#: changedetectionio/forms.py:946
|
||||||
msgid "Chrome requests"
|
msgid "Chrome requests"
|
||||||
msgstr "Žádost"
|
msgstr "Chrome požadavky"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:952
|
#: changedetectionio/forms.py:952
|
||||||
msgid "Default proxy"
|
msgid "Default proxy"
|
||||||
@@ -476,7 +476,7 @@ msgstr "Kontrola zabezpečení přístupového tokenu API povolena"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:989
|
#: changedetectionio/forms.py:989
|
||||||
msgid "Notification base URL override"
|
msgid "Notification base URL override"
|
||||||
msgstr "Počet upozornění na upozornění"
|
msgstr "Základní URL pro upozornění"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:993
|
#: changedetectionio/forms.py:993
|
||||||
msgid "Treat empty pages as a change?"
|
msgid "Treat empty pages as a change?"
|
||||||
@@ -608,11 +608,11 @@ msgstr "No backups found."
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
||||||
msgid "Create backup"
|
msgid "Create backup"
|
||||||
msgstr "Create backup"
|
msgstr "Vytvořit zálohu"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
||||||
msgid "Remove backups"
|
msgid "Remove backups"
|
||||||
msgstr "Remove backups"
|
msgstr "Odstranit zálohy"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/imports/importer.py:45
|
#: changedetectionio/blueprint/imports/importer.py:45
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -823,7 +823,7 @@ msgstr "Generál"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
||||||
msgid "Fetching"
|
msgid "Fetching"
|
||||||
msgstr "Hledání"
|
msgstr "Načítání"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
||||||
msgid "Global Filters"
|
msgid "Global Filters"
|
||||||
@@ -851,7 +851,7 @@ msgstr "CAPTCHA a proxy"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "Více informací"
|
msgstr "Info"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
||||||
msgid "Default recheck time for all watches, current system minimum is"
|
msgid "Default recheck time for all watches, current system minimum is"
|
||||||
@@ -1004,7 +1004,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
||||||
msgid "# Watches"
|
msgid "# Watches"
|
||||||
msgstr "# monitory"
|
msgstr "# monitorů"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
||||||
msgid "Tag / Label name"
|
msgid "Tag / Label name"
|
||||||
@@ -1251,7 +1251,7 @@ msgstr "nejprve odkaz."
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
||||||
msgid "Confirmation text"
|
msgid "Confirmation text"
|
||||||
msgstr "Žádné informace"
|
msgstr "Potvrzovací text"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
||||||
msgid "Type in the word"
|
msgid "Type in the word"
|
||||||
@@ -1456,7 +1456,7 @@ msgstr "Podmínky"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr "NASTAVENÍ"
|
msgstr "Statistiky"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
||||||
@@ -1895,11 +1895,11 @@ msgstr "Přidejte nové monitory zjišťování změn webové stránky"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
||||||
msgid "Watch this URL!"
|
msgid "Watch this URL!"
|
||||||
msgstr "Sledujte tuto adresu URL!"
|
msgstr "Monitorovat tuto URL!"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
||||||
msgid "Edit first then Watch"
|
msgid "Edit first then Watch"
|
||||||
msgstr "Nejprve upravte a poté sledujte"
|
msgstr "Upravit a monitorovat"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
||||||
msgid "Create a shareable link"
|
msgid "Create a shareable link"
|
||||||
@@ -2011,9 +2011,7 @@ msgstr "Změněno"
|
|||||||
msgid "No website watches configured, please add a URL in the box above, or"
|
msgid "No website watches configured, please add a URL in the box above, or"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nejsou nakonfigurována žádná sledování webových stránek, do výše "
|
"Nejsou nakonfigurována žádná sledování webových stránek, do výše "
|
||||||
"uvedeného pole přidejte adresu URL neboNejsou nakonfigurována žádná "
|
"uvedeného pole přidejte adresu URL nebo"
|
||||||
"sledování webových stránek, do výše uvedeného pole přidejte adresu URL "
|
|
||||||
"nebo"
|
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
|
||||||
msgid "import a list"
|
msgid "import a list"
|
||||||
@@ -2050,7 +2048,7 @@ msgstr "Ve frontě"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:250
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:250
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr "Dějiny"
|
msgstr "Historie"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:251
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:251
|
||||||
msgid "Preview"
|
msgid "Preview"
|
||||||
@@ -2401,11 +2399,11 @@ msgstr "Změnit jazyk"
|
|||||||
|
|
||||||
#: changedetectionio/templates/base.html:253
|
#: changedetectionio/templates/base.html:253
|
||||||
msgid "Watch List"
|
msgid "Watch List"
|
||||||
msgstr "# monitory"
|
msgstr "Seznam monitorů"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:258
|
#: changedetectionio/templates/base.html:258
|
||||||
msgid "Watches"
|
msgid "Watches"
|
||||||
msgstr "# monitory"
|
msgstr "Monitory"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:261
|
#: changedetectionio/templates/base.html:261
|
||||||
msgid "Queue Status"
|
msgid "Queue Status"
|
||||||
|
|||||||
Binary file not shown.
@@ -172,7 +172,7 @@ msgstr "Ungültiger Wert."
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:732
|
#: changedetectionio/forms.py:732
|
||||||
msgid "Watch"
|
msgid "Watch"
|
||||||
msgstr "Watch"
|
msgstr "Monitor"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
||||||
msgid "Processor"
|
msgid "Processor"
|
||||||
@@ -180,7 +180,7 @@ msgstr "Prozessor"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:734
|
#: changedetectionio/forms.py:734
|
||||||
msgid "Edit > Watch"
|
msgid "Edit > Watch"
|
||||||
msgstr "Edit > Watch"
|
msgstr "Bearbeiten > Monitor"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
||||||
msgid "Fetch Method"
|
msgid "Fetch Method"
|
||||||
@@ -337,7 +337,7 @@ msgstr "Speichern"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:829
|
#: changedetectionio/forms.py:829
|
||||||
msgid "Proxy"
|
msgid "Proxy"
|
||||||
msgstr "Stellvertreter"
|
msgstr "Proxy"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:831
|
#: changedetectionio/forms.py:831
|
||||||
msgid "Send a notification when the filter can no longer be found on the page"
|
msgid "Send a notification when the filter can no longer be found on the page"
|
||||||
@@ -350,7 +350,7 @@ msgstr ""
|
|||||||
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Keine Informationen"
|
msgstr "Benachrichtigungen"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
msgid "Muted"
|
msgid "Muted"
|
||||||
@@ -404,7 +404,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Stummschaltung aufheben"
|
msgstr "Name"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:921
|
#: changedetectionio/forms.py:921
|
||||||
msgid "Proxy URL"
|
msgid "Proxy URL"
|
||||||
@@ -428,7 +428,7 @@ msgstr "Klartextanfragen"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:946
|
#: changedetectionio/forms.py:946
|
||||||
msgid "Chrome requests"
|
msgid "Chrome requests"
|
||||||
msgstr "Anfrage"
|
msgstr "Chrome Requests"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:952
|
#: changedetectionio/forms.py:952
|
||||||
msgid "Default proxy"
|
msgid "Default proxy"
|
||||||
@@ -484,7 +484,7 @@ msgstr "Sicherheitsüberprüfung des API-Zugriffstokens aktiviert"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:989
|
#: changedetectionio/forms.py:989
|
||||||
msgid "Notification base URL override"
|
msgid "Notification base URL override"
|
||||||
msgstr "Anzahl der Benachrichtigungsalarme"
|
msgstr "Basis-URL für Benachrichtigungen"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:993
|
#: changedetectionio/forms.py:993
|
||||||
msgid "Treat empty pages as a change?"
|
msgid "Treat empty pages as a change?"
|
||||||
@@ -620,11 +620,11 @@ msgstr "Keine Backups gefunden."
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
||||||
msgid "Create backup"
|
msgid "Create backup"
|
||||||
msgstr "BACKUPS"
|
msgstr "Backup erstellen"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
||||||
msgid "Remove backups"
|
msgid "Remove backups"
|
||||||
msgstr "BACKUPS"
|
msgstr "Backups entfernen"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/imports/importer.py:45
|
#: changedetectionio/blueprint/imports/importer.py:45
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -815,7 +815,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/__init__.py:126
|
#: changedetectionio/blueprint/settings/__init__.py:126
|
||||||
msgid "Settings updated."
|
msgid "Settings updated."
|
||||||
msgstr "EINSTELLUNGEN"
|
msgstr "Einstellungen aktualisiert."
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/__init__.py:129
|
#: changedetectionio/blueprint/settings/__init__.py:129
|
||||||
#: changedetectionio/blueprint/ui/edit.py:283
|
#: changedetectionio/blueprint/ui/edit.py:283
|
||||||
@@ -839,7 +839,7 @@ msgstr "Allgemein"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
||||||
msgid "Fetching"
|
msgid "Fetching"
|
||||||
msgstr "Suchen"
|
msgstr "Abrufen"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
||||||
msgid "Global Filters"
|
msgid "Global Filters"
|
||||||
@@ -867,7 +867,7 @@ msgstr "CAPTCHA & Proxys"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "Weitere Informationen"
|
msgstr "Info"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
||||||
msgid "Default recheck time for all watches, current system minimum is"
|
msgid "Default recheck time for all watches, current system minimum is"
|
||||||
@@ -897,7 +897,7 @@ msgstr "Keine Plugins aktiv"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:405
|
#: changedetectionio/blueprint/settings/templates/settings.html:405
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "BACKUPS"
|
msgstr "Zurück"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:406
|
#: changedetectionio/blueprint/settings/templates/settings.html:406
|
||||||
msgid "Clear Snapshot History"
|
msgid "Clear Snapshot History"
|
||||||
@@ -942,7 +942,7 @@ msgstr "Filter und Trigger"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/edit-tag.html:50
|
#: changedetectionio/blueprint/tags/templates/edit-tag.html:50
|
||||||
msgid "These settings are"
|
msgid "These settings are"
|
||||||
msgstr "EINSTELLUNGEN"
|
msgstr "Diese Einstellungen sind"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/edit-tag.html:50
|
#: changedetectionio/blueprint/tags/templates/edit-tag.html:50
|
||||||
msgid "added"
|
msgid "added"
|
||||||
@@ -1271,7 +1271,7 @@ msgstr "Link zuerst."
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
||||||
msgid "Confirmation text"
|
msgid "Confirmation text"
|
||||||
msgstr "Keine Informationen"
|
msgstr "Bestätigungstext"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
||||||
msgid "Type in the word"
|
msgid "Type in the word"
|
||||||
@@ -1420,7 +1420,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/diff.html:127
|
#: changedetectionio/blueprint/ui/templates/diff.html:127
|
||||||
msgid "from settings."
|
msgid "from settings."
|
||||||
msgstr "EINSTELLUNGEN"
|
msgstr "aus den Einstellungen."
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/diff.html:133
|
#: changedetectionio/blueprint/ui/templates/diff.html:133
|
||||||
msgid "Goto single snapshot"
|
msgid "Goto single snapshot"
|
||||||
@@ -1478,7 +1478,7 @@ msgstr "Bedingungen"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr "EINSTELLUNGEN"
|
msgstr "Statistiken"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
||||||
@@ -1931,11 +1931,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
||||||
msgid "Watch this URL!"
|
msgid "Watch this URL!"
|
||||||
msgstr "Sehen Sie sich diese URL an!"
|
msgstr "Diese URL überwachen!"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
||||||
msgid "Edit first then Watch"
|
msgid "Edit first then Watch"
|
||||||
msgstr "Zuerst bearbeiten, dann ansehen"
|
msgstr "Bearbeiten > Überwachen"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
||||||
msgid "Create a shareable link"
|
msgid "Create a shareable link"
|
||||||
@@ -2396,7 +2396,7 @@ msgstr "EINSTELLUNGEN"
|
|||||||
#: changedetectionio/templates/base.html:84
|
#: changedetectionio/templates/base.html:84
|
||||||
#: changedetectionio/templates/base.html:170
|
#: changedetectionio/templates/base.html:170
|
||||||
msgid "IMPORT"
|
msgid "IMPORT"
|
||||||
msgstr "IMPORT"
|
msgstr "IMPORTIEREN"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:87
|
#: changedetectionio/templates/base.html:87
|
||||||
#: changedetectionio/templates/base.html:171
|
#: changedetectionio/templates/base.html:171
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -181,7 +181,7 @@ msgstr "Processeur"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:734
|
#: changedetectionio/forms.py:734
|
||||||
msgid "Edit > Watch"
|
msgid "Edit > Watch"
|
||||||
msgstr "Modifiez d'abord, puis regardez"
|
msgstr "Modifier > Surveiller"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
||||||
msgid "Fetch Method"
|
msgid "Fetch Method"
|
||||||
@@ -342,7 +342,7 @@ msgstr "Sauvegarder"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:829
|
#: changedetectionio/forms.py:829
|
||||||
msgid "Proxy"
|
msgid "Proxy"
|
||||||
msgstr "Procuration"
|
msgstr "Proxy"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:831
|
#: changedetectionio/forms.py:831
|
||||||
msgid "Send a notification when the filter can no longer be found on the page"
|
msgid "Send a notification when the filter can no longer be found on the page"
|
||||||
@@ -353,7 +353,7 @@ msgstr "Envoyer une notification lorsque le filtre n'est plus trouvé sur la pag
|
|||||||
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Aucune information"
|
msgstr "Notifications"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
msgid "Muted"
|
msgid "Muted"
|
||||||
@@ -405,7 +405,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Réactiver le son"
|
msgstr "Nom"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:921
|
#: changedetectionio/forms.py:921
|
||||||
msgid "Proxy URL"
|
msgid "Proxy URL"
|
||||||
@@ -429,7 +429,7 @@ msgstr "Requêtes en texte brut"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:946
|
#: changedetectionio/forms.py:946
|
||||||
msgid "Chrome requests"
|
msgid "Chrome requests"
|
||||||
msgstr "Demande"
|
msgstr "Requêtes Chrome"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:952
|
#: changedetectionio/forms.py:952
|
||||||
msgid "Default proxy"
|
msgid "Default proxy"
|
||||||
@@ -485,7 +485,7 @@ msgstr "Contrôle de sécurité du jeton d'accès à l'API activé"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:989
|
#: changedetectionio/forms.py:989
|
||||||
msgid "Notification base URL override"
|
msgid "Notification base URL override"
|
||||||
msgstr "Nombre d'alertes de notification"
|
msgstr "URL de base pour les notifications"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:993
|
#: changedetectionio/forms.py:993
|
||||||
msgid "Treat empty pages as a change?"
|
msgid "Treat empty pages as a change?"
|
||||||
@@ -621,11 +621,11 @@ msgstr "Aucune sauvegarde trouvée."
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
||||||
msgid "Create backup"
|
msgid "Create backup"
|
||||||
msgstr "SAUVEGARDES"
|
msgstr "Créer sauvegarde"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
||||||
msgid "Remove backups"
|
msgid "Remove backups"
|
||||||
msgstr "SAUVEGARDES"
|
msgstr "Supprimer sauvegardes"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/imports/importer.py:45
|
#: changedetectionio/blueprint/imports/importer.py:45
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -844,7 +844,7 @@ msgstr "Général"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
||||||
msgid "Fetching"
|
msgid "Fetching"
|
||||||
msgstr "Recherche"
|
msgstr "Récupération"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
||||||
msgid "Global Filters"
|
msgid "Global Filters"
|
||||||
@@ -872,7 +872,7 @@ msgstr "CAPTCHA et procurations"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "Plus d'informations"
|
msgstr "Info"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
||||||
msgid "Default recheck time for all watches, current system minimum is"
|
msgid "Default recheck time for all watches, current system minimum is"
|
||||||
@@ -902,7 +902,7 @@ msgstr "Aucun plugin actif"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:405
|
#: changedetectionio/blueprint/settings/templates/settings.html:405
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "SAUVEGARDES"
|
msgstr "Retour"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:406
|
#: changedetectionio/blueprint/settings/templates/settings.html:406
|
||||||
msgid "Clear Snapshot History"
|
msgid "Clear Snapshot History"
|
||||||
@@ -1276,7 +1276,7 @@ msgstr "lien d'abord."
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
||||||
msgid "Confirmation text"
|
msgid "Confirmation text"
|
||||||
msgstr "Aucune information"
|
msgstr "Texte de confirmation"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
||||||
msgid "Type in the word"
|
msgid "Type in the word"
|
||||||
@@ -1483,7 +1483,7 @@ msgstr "Conditions"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr "PARAMÈTRES"
|
msgstr "Statistiques"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
||||||
@@ -1942,7 +1942,7 @@ msgstr "Surveillez cette URL !"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
||||||
msgid "Edit first then Watch"
|
msgid "Edit first then Watch"
|
||||||
msgstr "Modifiez d'abord, puis regardez"
|
msgstr "Modifier > Surveiller"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
||||||
msgid "Create a shareable link"
|
msgid "Create a shareable link"
|
||||||
@@ -2054,8 +2054,7 @@ msgstr "Modifié"
|
|||||||
msgid "No website watches configured, please add a URL in the box above, or"
|
msgid "No website watches configured, please add a URL in the box above, or"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Aucune surveillance de site Web configurée, veuillez ajouter une URL dans"
|
"Aucune surveillance de site Web configurée, veuillez ajouter une URL dans"
|
||||||
" la case ci-dessus, ouAucune surveillance de site Web configurée, "
|
" la case ci-dessus, ou"
|
||||||
"veuillez ajouter une URL dans la case ci-dessus, ou"
|
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
|
||||||
msgid "import a list"
|
msgid "import a list"
|
||||||
@@ -2092,7 +2091,7 @@ msgstr "En file d'attente"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:250
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:250
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr "Histoire"
|
msgstr "Historique"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:251
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:251
|
||||||
msgid "Preview"
|
msgid "Preview"
|
||||||
|
|||||||
Binary file not shown.
@@ -175,16 +175,15 @@ msgstr "Valore non valido."
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:732
|
#: changedetectionio/forms.py:732
|
||||||
msgid "Watch"
|
msgid "Watch"
|
||||||
msgstr "Osserva"
|
msgstr "Monitora"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
||||||
msgid "Processor"
|
msgid "Processor"
|
||||||
msgstr "Processore"
|
msgstr "Processore"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:734
|
#: changedetectionio/forms.py:734
|
||||||
#, fuzzy
|
|
||||||
msgid "Edit > Watch"
|
msgid "Edit > Watch"
|
||||||
msgstr "Modifica prima poi Monitora"
|
msgstr "Modifica > Monitora"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
||||||
msgid "Fetch Method"
|
msgid "Fetch Method"
|
||||||
@@ -415,9 +414,8 @@ msgid "Invalid template syntax in \"%(header)s\" header: %(error)s"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
||||||
#, fuzzy
|
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Riattiva audio"
|
msgstr "Nome"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:921
|
#: changedetectionio/forms.py:921
|
||||||
msgid "Proxy URL"
|
msgid "Proxy URL"
|
||||||
@@ -440,9 +438,8 @@ msgid "Plaintext requests"
|
|||||||
msgstr "Richieste in chiaro"
|
msgstr "Richieste in chiaro"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:946
|
#: changedetectionio/forms.py:946
|
||||||
#, fuzzy
|
|
||||||
msgid "Chrome requests"
|
msgid "Chrome requests"
|
||||||
msgstr "Richiesta"
|
msgstr "Richieste Chrome"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:952
|
#: changedetectionio/forms.py:952
|
||||||
msgid "Default proxy"
|
msgid "Default proxy"
|
||||||
@@ -497,9 +494,8 @@ msgid "API access token security check enabled"
|
|||||||
msgstr "Controllo sicurezza token API attivo"
|
msgstr "Controllo sicurezza token API attivo"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:989
|
#: changedetectionio/forms.py:989
|
||||||
#, fuzzy
|
|
||||||
msgid "Notification base URL override"
|
msgid "Notification base URL override"
|
||||||
msgstr "Notifiche"
|
msgstr "URL base notifiche"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:993
|
#: changedetectionio/forms.py:993
|
||||||
msgid "Treat empty pages as a change?"
|
msgid "Treat empty pages as a change?"
|
||||||
@@ -1026,7 +1022,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
||||||
msgid "# Watches"
|
msgid "# Watches"
|
||||||
msgstr ""
|
msgstr "# Monitoraggi"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
||||||
msgid "Tag / Label name"
|
msgid "Tag / Label name"
|
||||||
@@ -1273,7 +1269,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
||||||
msgid "Confirmation text"
|
msgid "Confirmation text"
|
||||||
msgstr ""
|
msgstr "Testo di conferma"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
||||||
msgid "Type in the word"
|
msgid "Type in the word"
|
||||||
@@ -1915,7 +1911,7 @@ msgstr "Monitora questo URL!"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
||||||
msgid "Edit first then Watch"
|
msgid "Edit first then Watch"
|
||||||
msgstr "Modifica prima poi Monitora"
|
msgstr "Modifica > Monitora"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
||||||
msgid "Create a shareable link"
|
msgid "Create a shareable link"
|
||||||
@@ -2025,7 +2021,7 @@ msgstr "Modifica"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
|
||||||
msgid "No website watches configured, please add a URL in the box above, or"
|
msgid "No website watches configured, please add a URL in the box above, or"
|
||||||
msgstr ""
|
msgstr "Nessun monitoraggio configurato, aggiungi un URL nella casella sopra, oppure"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:130
|
||||||
msgid "import a list"
|
msgid "import a list"
|
||||||
@@ -2428,12 +2424,12 @@ msgstr "Cambia lingua"
|
|||||||
#: changedetectionio/templates/base.html:253
|
#: changedetectionio/templates/base.html:253
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Watch List"
|
msgid "Watch List"
|
||||||
msgstr "Osserva"
|
msgstr "Lista Monitoraggi"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:258
|
#: changedetectionio/templates/base.html:258
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Watches"
|
msgid "Watches"
|
||||||
msgstr "Osserva"
|
msgstr "Monitoraggi"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:261
|
#: changedetectionio/templates/base.html:261
|
||||||
msgid "Queue Status"
|
msgid "Queue Status"
|
||||||
|
|||||||
Binary file not shown.
@@ -176,18 +176,16 @@ msgid "Invalid value."
|
|||||||
msgstr "값이 잘못되었습니다."
|
msgstr "값이 잘못되었습니다."
|
||||||
|
|
||||||
#: changedetectionio/forms.py:732
|
#: changedetectionio/forms.py:732
|
||||||
#, fuzzy
|
|
||||||
msgid "Watch"
|
msgid "Watch"
|
||||||
msgstr "# 시계"
|
msgstr "모니터"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
||||||
msgid "Processor"
|
msgid "Processor"
|
||||||
msgstr "프로세서"
|
msgstr "프로세서"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:734
|
#: changedetectionio/forms.py:734
|
||||||
#, fuzzy
|
|
||||||
msgid "Edit > Watch"
|
msgid "Edit > Watch"
|
||||||
msgstr "먼저 편집한 다음 보기"
|
msgstr "편집 > 모니터"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -363,7 +361,7 @@ msgstr "구하다"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:829
|
#: changedetectionio/forms.py:829
|
||||||
msgid "Proxy"
|
msgid "Proxy"
|
||||||
msgstr "대리"
|
msgstr "프록시"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:831
|
#: changedetectionio/forms.py:831
|
||||||
msgid "Send a notification when the filter can no longer be found on the page"
|
msgid "Send a notification when the filter can no longer be found on the page"
|
||||||
@@ -374,7 +372,7 @@ msgstr "페이지에서 필터를 더 이상 찾을 수 없으면 알림 보내
|
|||||||
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "정보 없음"
|
msgstr "알림"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -427,9 +425,8 @@ msgid "Invalid template syntax in \"%(header)s\" header: %(error)s"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
||||||
#, fuzzy
|
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "음소거 해제"
|
msgstr "이름"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:921
|
#: changedetectionio/forms.py:921
|
||||||
msgid "Proxy URL"
|
msgid "Proxy URL"
|
||||||
@@ -452,9 +449,8 @@ msgid "Plaintext requests"
|
|||||||
msgstr "일반 텍스트 요청"
|
msgstr "일반 텍스트 요청"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:946
|
#: changedetectionio/forms.py:946
|
||||||
#, fuzzy
|
|
||||||
msgid "Chrome requests"
|
msgid "Chrome requests"
|
||||||
msgstr "요구"
|
msgstr "Chrome 요청"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:952
|
#: changedetectionio/forms.py:952
|
||||||
msgid "Default proxy"
|
msgid "Default proxy"
|
||||||
@@ -511,9 +507,8 @@ msgid "API access token security check enabled"
|
|||||||
msgstr "API 액세스 토큰 보안 확인이 활성화되었습니다."
|
msgstr "API 액세스 토큰 보안 확인이 활성화되었습니다."
|
||||||
|
|
||||||
#: changedetectionio/forms.py:989
|
#: changedetectionio/forms.py:989
|
||||||
#, fuzzy
|
|
||||||
msgid "Notification base URL override"
|
msgid "Notification base URL override"
|
||||||
msgstr "알림 경고 수"
|
msgstr "알림 기본 URL"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:993
|
#: changedetectionio/forms.py:993
|
||||||
msgid "Treat empty pages as a change?"
|
msgid "Treat empty pages as a change?"
|
||||||
@@ -647,11 +642,11 @@ msgstr "백업을 찾을 수 없습니다."
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
||||||
msgid "Create backup"
|
msgid "Create backup"
|
||||||
msgstr "백업"
|
msgstr "백업 생성"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
||||||
msgid "Remove backups"
|
msgid "Remove backups"
|
||||||
msgstr "백업"
|
msgstr "백업 삭제"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/imports/importer.py:45
|
#: changedetectionio/blueprint/imports/importer.py:45
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -859,7 +854,7 @@ msgstr "일반적인"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
||||||
msgid "Fetching"
|
msgid "Fetching"
|
||||||
msgstr "수색"
|
msgstr "가져오기"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
||||||
msgid "Global Filters"
|
msgid "Global Filters"
|
||||||
@@ -887,7 +882,7 @@ msgstr "보안 문자 및 프록시"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "추가 정보"
|
msgstr "정보"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
||||||
msgid "Default recheck time for all watches, current system minimum is"
|
msgid "Default recheck time for all watches, current system minimum is"
|
||||||
@@ -915,7 +910,7 @@ msgstr "활성화된 플러그인이 없습니다."
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:405
|
#: changedetectionio/blueprint/settings/templates/settings.html:405
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "백업"
|
msgstr "뒤로"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:406
|
#: changedetectionio/blueprint/settings/templates/settings.html:406
|
||||||
msgid "Clear Snapshot History"
|
msgid "Clear Snapshot History"
|
||||||
@@ -1038,7 +1033,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
||||||
msgid "# Watches"
|
msgid "# Watches"
|
||||||
msgstr "# 시계"
|
msgstr "# 모니터"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
||||||
msgid "Tag / Label name"
|
msgid "Tag / Label name"
|
||||||
@@ -1290,7 +1285,7 @@ msgstr "먼저 링크하세요."
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
||||||
msgid "Confirmation text"
|
msgid "Confirmation text"
|
||||||
msgstr "정보 없음"
|
msgstr "확인 텍스트"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
||||||
msgid "Type in the word"
|
msgid "Type in the word"
|
||||||
@@ -1493,7 +1488,7 @@ msgstr "정황"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr "설정"
|
msgstr "통계"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
||||||
@@ -1928,11 +1923,11 @@ msgstr "새로운 웹 페이지 변경 감지 감시 추가"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
||||||
msgid "Watch this URL!"
|
msgid "Watch this URL!"
|
||||||
msgstr "이 URL을 시청하세요!"
|
msgstr "이 URL 모니터!"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
||||||
msgid "Edit first then Watch"
|
msgid "Edit first then Watch"
|
||||||
msgstr "먼저 편집한 다음 보기"
|
msgstr "편집 후 모니터"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
||||||
msgid "Create a shareable link"
|
msgid "Create a shareable link"
|
||||||
@@ -2079,7 +2074,7 @@ msgstr "대기 중"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:250
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:250
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr "역사"
|
msgstr "기록"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:251
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:251
|
||||||
msgid "Preview"
|
msgid "Preview"
|
||||||
@@ -2405,7 +2400,7 @@ msgstr "설정"
|
|||||||
#: changedetectionio/templates/base.html:84
|
#: changedetectionio/templates/base.html:84
|
||||||
#: changedetectionio/templates/base.html:170
|
#: changedetectionio/templates/base.html:170
|
||||||
msgid "IMPORT"
|
msgid "IMPORT"
|
||||||
msgstr "수입"
|
msgstr "가져오기"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:87
|
#: changedetectionio/templates/base.html:87
|
||||||
#: changedetectionio/templates/base.html:171
|
#: changedetectionio/templates/base.html:171
|
||||||
@@ -2445,12 +2440,12 @@ msgstr "언어 변경"
|
|||||||
#: changedetectionio/templates/base.html:253
|
#: changedetectionio/templates/base.html:253
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Watch List"
|
msgid "Watch List"
|
||||||
msgstr "# 시계"
|
msgstr "모니터 목록"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:258
|
#: changedetectionio/templates/base.html:258
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Watches"
|
msgid "Watches"
|
||||||
msgstr "# 시계"
|
msgstr "모니터"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:261
|
#: changedetectionio/templates/base.html:261
|
||||||
msgid "Queue Status"
|
msgid "Queue Status"
|
||||||
|
|||||||
Binary file not shown.
@@ -176,9 +176,8 @@ msgid "Invalid value."
|
|||||||
msgstr "无效值。"
|
msgstr "无效值。"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:732
|
#: changedetectionio/forms.py:732
|
||||||
#, fuzzy
|
|
||||||
msgid "Watch"
|
msgid "Watch"
|
||||||
msgstr "# 手表"
|
msgstr "监控"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
||||||
msgid "Processor"
|
msgid "Processor"
|
||||||
@@ -187,7 +186,7 @@ msgstr "处理器"
|
|||||||
#: changedetectionio/forms.py:734
|
#: changedetectionio/forms.py:734
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Edit > Watch"
|
msgid "Edit > Watch"
|
||||||
msgstr "先编辑后观看"
|
msgstr "编辑 > 监控"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -363,7 +362,7 @@ msgstr "节省"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:829
|
#: changedetectionio/forms.py:829
|
||||||
msgid "Proxy"
|
msgid "Proxy"
|
||||||
msgstr "代理人"
|
msgstr "代理"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:831
|
#: changedetectionio/forms.py:831
|
||||||
msgid "Send a notification when the filter can no longer be found on the page"
|
msgid "Send a notification when the filter can no longer be found on the page"
|
||||||
@@ -374,7 +373,7 @@ msgstr "当页面上找不到过滤器时发送通知"
|
|||||||
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
#: changedetectionio/blueprint/ui/templates/edit.html:59
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "暂无信息"
|
msgstr "通知"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:832
|
#: changedetectionio/forms.py:832
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -427,9 +426,8 @@ msgid "Invalid template syntax in \"%(header)s\" header: %(error)s"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
||||||
#, fuzzy
|
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "取消静音"
|
msgstr "名称"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:921
|
#: changedetectionio/forms.py:921
|
||||||
msgid "Proxy URL"
|
msgid "Proxy URL"
|
||||||
@@ -452,9 +450,8 @@ msgid "Plaintext requests"
|
|||||||
msgstr "明文请求"
|
msgstr "明文请求"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:946
|
#: changedetectionio/forms.py:946
|
||||||
#, fuzzy
|
|
||||||
msgid "Chrome requests"
|
msgid "Chrome requests"
|
||||||
msgstr "要求"
|
msgstr "Chrome请求"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:952
|
#: changedetectionio/forms.py:952
|
||||||
msgid "Default proxy"
|
msgid "Default proxy"
|
||||||
@@ -511,9 +508,8 @@ msgid "API access token security check enabled"
|
|||||||
msgstr "已启用 API 访问令牌安全检查"
|
msgstr "已启用 API 访问令牌安全检查"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:989
|
#: changedetectionio/forms.py:989
|
||||||
#, fuzzy
|
|
||||||
msgid "Notification base URL override"
|
msgid "Notification base URL override"
|
||||||
msgstr "通知警报计数"
|
msgstr "通知基础URL"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:993
|
#: changedetectionio/forms.py:993
|
||||||
msgid "Treat empty pages as a change?"
|
msgid "Treat empty pages as a change?"
|
||||||
@@ -647,11 +643,11 @@ msgstr "未找到备份。"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
#: changedetectionio/blueprint/backups/templates/overview.html:28
|
||||||
msgid "Create backup"
|
msgid "Create backup"
|
||||||
msgstr "备份"
|
msgstr "创建备份"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
#: changedetectionio/blueprint/backups/templates/overview.html:30
|
||||||
msgid "Remove backups"
|
msgid "Remove backups"
|
||||||
msgstr "备份"
|
msgstr "删除备份"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/imports/importer.py:45
|
#: changedetectionio/blueprint/imports/importer.py:45
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -859,7 +855,7 @@ msgstr "一般的"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
#: changedetectionio/blueprint/settings/templates/settings.html:23
|
||||||
msgid "Fetching"
|
msgid "Fetching"
|
||||||
msgstr "搜寻中"
|
msgstr "获取"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
#: changedetectionio/blueprint/settings/templates/settings.html:24
|
||||||
msgid "Global Filters"
|
msgid "Global Filters"
|
||||||
@@ -887,7 +883,7 @@ msgstr "验证码和代理"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
#: changedetectionio/blueprint/settings/templates/settings.html:35
|
||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "更多信息"
|
msgstr "信息"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
#: changedetectionio/blueprint/settings/templates/settings.html:46
|
||||||
msgid "Default recheck time for all watches, current system minimum is"
|
msgid "Default recheck time for all watches, current system minimum is"
|
||||||
@@ -915,7 +911,7 @@ msgstr "没有激活的插件"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:405
|
#: changedetectionio/blueprint/settings/templates/settings.html:405
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "备份"
|
msgstr "返回"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/settings/templates/settings.html:406
|
#: changedetectionio/blueprint/settings/templates/settings.html:406
|
||||||
msgid "Clear Snapshot History"
|
msgid "Clear Snapshot History"
|
||||||
@@ -1038,7 +1034,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
||||||
msgid "# Watches"
|
msgid "# Watches"
|
||||||
msgstr "# 手表"
|
msgstr "# 监控项"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
||||||
msgid "Tag / Label name"
|
msgid "Tag / Label name"
|
||||||
@@ -1290,7 +1286,7 @@ msgstr "先链接。"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:17
|
||||||
msgid "Confirmation text"
|
msgid "Confirmation text"
|
||||||
msgstr "暂无信息"
|
msgstr "确认文本"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
#: changedetectionio/blueprint/ui/templates/clear_all_history.html:27
|
||||||
msgid "Type in the word"
|
msgid "Type in the word"
|
||||||
@@ -1493,7 +1489,7 @@ msgstr "状况"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
#: changedetectionio/blueprint/ui/templates/edit.html:60
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr "设置"
|
msgstr "统计"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
#: changedetectionio/blueprint/ui/templates/edit.html:73
|
||||||
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
#: changedetectionio/blueprint/ui/templates/edit.html:313
|
||||||
@@ -1928,11 +1924,11 @@ msgstr "添加新的网页更改检测监视"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
||||||
msgid "Watch this URL!"
|
msgid "Watch this URL!"
|
||||||
msgstr "关注这个网址!"
|
msgstr "监控此URL!"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
||||||
msgid "Edit first then Watch"
|
msgid "Edit first then Watch"
|
||||||
msgstr "先编辑后观看"
|
msgstr "编辑后监控"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
||||||
msgid "Create a shareable link"
|
msgid "Create a shareable link"
|
||||||
@@ -2405,7 +2401,7 @@ msgstr "设置"
|
|||||||
#: changedetectionio/templates/base.html:84
|
#: changedetectionio/templates/base.html:84
|
||||||
#: changedetectionio/templates/base.html:170
|
#: changedetectionio/templates/base.html:170
|
||||||
msgid "IMPORT"
|
msgid "IMPORT"
|
||||||
msgstr "进口"
|
msgstr "导入"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:87
|
#: changedetectionio/templates/base.html:87
|
||||||
#: changedetectionio/templates/base.html:171
|
#: changedetectionio/templates/base.html:171
|
||||||
@@ -2445,12 +2441,12 @@ msgstr "更改语言"
|
|||||||
#: changedetectionio/templates/base.html:253
|
#: changedetectionio/templates/base.html:253
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Watch List"
|
msgid "Watch List"
|
||||||
msgstr "# 手表"
|
msgstr "监控列表"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:258
|
#: changedetectionio/templates/base.html:258
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Watches"
|
msgid "Watches"
|
||||||
msgstr "# 手表"
|
msgstr "监控项"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:261
|
#: changedetectionio/templates/base.html:261
|
||||||
msgid "Queue Status"
|
msgid "Queue Status"
|
||||||
|
|||||||
Binary file not shown.
@@ -176,18 +176,16 @@ msgid "Invalid value."
|
|||||||
msgstr "無效值。"
|
msgstr "無效值。"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:732
|
#: changedetectionio/forms.py:732
|
||||||
#, fuzzy
|
|
||||||
msgid "Watch"
|
msgid "Watch"
|
||||||
msgstr "# 手錶"
|
msgstr "監控"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
#: changedetectionio/forms.py:733 changedetectionio/forms.py:766
|
||||||
msgid "Processor"
|
msgid "Processor"
|
||||||
msgstr "處理器"
|
msgstr "處理器"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:734
|
#: changedetectionio/forms.py:734
|
||||||
#, fuzzy
|
|
||||||
msgid "Edit > Watch"
|
msgid "Edit > Watch"
|
||||||
msgstr "先編輯後觀看"
|
msgstr "編輯 > 監控"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
#: changedetectionio/forms.py:747 changedetectionio/forms.py:994
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -363,7 +361,7 @@ msgstr "節省"
|
|||||||
|
|
||||||
#: changedetectionio/forms.py:829
|
#: changedetectionio/forms.py:829
|
||||||
msgid "Proxy"
|
msgid "Proxy"
|
||||||
msgstr "代理人"
|
msgstr "代理"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:831
|
#: changedetectionio/forms.py:831
|
||||||
msgid "Send a notification when the filter can no longer be found on the page"
|
msgid "Send a notification when the filter can no longer be found on the page"
|
||||||
@@ -427,9 +425,8 @@ msgid "Invalid template syntax in \"%(header)s\" header: %(error)s"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
#: changedetectionio/forms.py:920 changedetectionio/forms.py:932
|
||||||
#, fuzzy
|
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "取消靜音"
|
msgstr "名稱"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:921
|
#: changedetectionio/forms.py:921
|
||||||
msgid "Proxy URL"
|
msgid "Proxy URL"
|
||||||
@@ -452,9 +449,8 @@ msgid "Plaintext requests"
|
|||||||
msgstr "明文請求"
|
msgstr "明文請求"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:946
|
#: changedetectionio/forms.py:946
|
||||||
#, fuzzy
|
|
||||||
msgid "Chrome requests"
|
msgid "Chrome requests"
|
||||||
msgstr "要求"
|
msgstr "Chrome請求"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:952
|
#: changedetectionio/forms.py:952
|
||||||
msgid "Default proxy"
|
msgid "Default proxy"
|
||||||
@@ -511,9 +507,8 @@ msgid "API access token security check enabled"
|
|||||||
msgstr "已啟用 API 訪問令牌安全檢查"
|
msgstr "已啟用 API 訪問令牌安全檢查"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:989
|
#: changedetectionio/forms.py:989
|
||||||
#, fuzzy
|
|
||||||
msgid "Notification base URL override"
|
msgid "Notification base URL override"
|
||||||
msgstr "通知警報計數"
|
msgstr "通知基礎URL"
|
||||||
|
|
||||||
#: changedetectionio/forms.py:993
|
#: changedetectionio/forms.py:993
|
||||||
msgid "Treat empty pages as a change?"
|
msgid "Treat empty pages as a change?"
|
||||||
@@ -1038,7 +1033,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:31
|
||||||
msgid "# Watches"
|
msgid "# Watches"
|
||||||
msgstr "# 手錶"
|
msgstr "# 監控項"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
#: changedetectionio/blueprint/tags/templates/groups-overview.html:32
|
||||||
msgid "Tag / Label name"
|
msgid "Tag / Label name"
|
||||||
@@ -1928,11 +1923,11 @@ msgstr "添加新的網頁更改檢測監視"
|
|||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:34
|
||||||
msgid "Watch this URL!"
|
msgid "Watch this URL!"
|
||||||
msgstr "關注這個網址!"
|
msgstr "監控此URL!"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:35
|
||||||
msgid "Edit first then Watch"
|
msgid "Edit first then Watch"
|
||||||
msgstr "先編輯後觀看"
|
msgstr "編輯後監控"
|
||||||
|
|
||||||
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
#: changedetectionio/blueprint/watchlist/templates/watch-overview.html:45
|
||||||
msgid "Create a shareable link"
|
msgid "Create a shareable link"
|
||||||
@@ -2405,7 +2400,7 @@ msgstr "設定"
|
|||||||
#: changedetectionio/templates/base.html:84
|
#: changedetectionio/templates/base.html:84
|
||||||
#: changedetectionio/templates/base.html:170
|
#: changedetectionio/templates/base.html:170
|
||||||
msgid "IMPORT"
|
msgid "IMPORT"
|
||||||
msgstr "進口"
|
msgstr "導入"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:87
|
#: changedetectionio/templates/base.html:87
|
||||||
#: changedetectionio/templates/base.html:171
|
#: changedetectionio/templates/base.html:171
|
||||||
@@ -2445,12 +2440,12 @@ msgstr "更改語言"
|
|||||||
#: changedetectionio/templates/base.html:253
|
#: changedetectionio/templates/base.html:253
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Watch List"
|
msgid "Watch List"
|
||||||
msgstr "# 手錶"
|
msgstr "監控列表"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:258
|
#: changedetectionio/templates/base.html:258
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Watches"
|
msgid "Watches"
|
||||||
msgstr "# 手錶"
|
msgstr "監控項"
|
||||||
|
|
||||||
#: changedetectionio/templates/base.html:261
|
#: changedetectionio/templates/base.html:261
|
||||||
msgid "Queue Status"
|
msgid "Queue Status"
|
||||||
|
|||||||
+86
-4
@@ -28,7 +28,7 @@ info:
|
|||||||
|
|
||||||
For example: `x-api-key: YOUR_API_KEY`
|
For example: `x-api-key: YOUR_API_KEY`
|
||||||
|
|
||||||
version: 0.1.3
|
version: 0.1.4
|
||||||
contact:
|
contact:
|
||||||
name: ChangeDetection.io
|
name: ChangeDetection.io
|
||||||
url: https://github.com/dgtlmoon/changedetection.io
|
url: https://github.com/dgtlmoon/changedetection.io
|
||||||
@@ -761,9 +761,9 @@ paths:
|
|||||||
get:
|
get:
|
||||||
operationId: getWatchHistoryDiff
|
operationId: getWatchHistoryDiff
|
||||||
tags: [Watch History]
|
tags: [Watch History]
|
||||||
summary: Get diff between two snapshots
|
summary: Get the difference between two snapshots
|
||||||
description: |
|
description: |
|
||||||
Generate a formatted diff (comparison) between two historical snapshots of a web page change monitor (watch).
|
Generate a difference (comparison) between two historical snapshots of a web page change monitor (watch).
|
||||||
|
|
||||||
This endpoint compares content between two points in time and returns the differences in your chosen format.
|
This endpoint compares content between two points in time and returns the differences in your chosen format.
|
||||||
Perfect for reviewing what changed between specific versions or comparing recent changes.
|
Perfect for reviewing what changed between specific versions or comparing recent changes.
|
||||||
@@ -798,6 +798,10 @@ paths:
|
|||||||
# Compare two specific timestamps in plain text with word-level diff
|
# Compare two specific timestamps in plain text with word-level diff
|
||||||
curl -X GET "http://localhost:5000/api/v1/watch/095be615-a8ad-4c33-8e9c-c7612fbf6c9f/difference/1640995200/1640998800?format=text&word_diff=true" \
|
curl -X GET "http://localhost:5000/api/v1/watch/095be615-a8ad-4c33-8e9c-c7612fbf6c9f/difference/1640995200/1640998800?format=text&word_diff=true" \
|
||||||
-H "x-api-key: YOUR_API_KEY"
|
-H "x-api-key: YOUR_API_KEY"
|
||||||
|
|
||||||
|
# Show only additions (hide removed/replaced content), ignore whitespace
|
||||||
|
curl -X GET "http://localhost:5000/api/v1/watch/095be615-a8ad-4c33-8e9c-c7612fbf6c9f/difference/previous/latest?format=htmlcolor&removed=false&replaced=false&ignoreWhitespace=true" \
|
||||||
|
-H "x-api-key: YOUR_API_KEY"
|
||||||
- lang: 'Python'
|
- lang: 'Python'
|
||||||
source: |
|
source: |
|
||||||
import requests
|
import requests
|
||||||
@@ -822,6 +826,20 @@ paths:
|
|||||||
params={'format': 'text', 'word_diff': 'true'}
|
params={'format': 'text', 'word_diff': 'true'}
|
||||||
)
|
)
|
||||||
print(response.text)
|
print(response.text)
|
||||||
|
|
||||||
|
# Show only additions, ignore whitespace and use word-level diff
|
||||||
|
response = requests.get(
|
||||||
|
f'http://localhost:5000/api/v1/watch/{uuid}/difference/previous/latest',
|
||||||
|
headers=headers,
|
||||||
|
params={
|
||||||
|
'format': 'htmlcolor',
|
||||||
|
'type': 'diffWords',
|
||||||
|
'removed': 'false',
|
||||||
|
'replaced': 'false',
|
||||||
|
'ignoreWhitespace': 'true'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
print(response.text)
|
||||||
parameters:
|
parameters:
|
||||||
- name: uuid
|
- name: uuid
|
||||||
in: path
|
in: path
|
||||||
@@ -861,9 +879,10 @@ paths:
|
|||||||
- `text` (default): Plain text with (removed) and (added) prefixes
|
- `text` (default): Plain text with (removed) and (added) prefixes
|
||||||
- `html`: Basic HTML format
|
- `html`: Basic HTML format
|
||||||
- `htmlcolor`: Rich HTML with colored backgrounds (red for deletions, green for additions)
|
- `htmlcolor`: Rich HTML with colored backgrounds (red for deletions, green for additions)
|
||||||
|
- `markdown`: Markdown format with HTML rendering
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
enum: [text, html, htmlcolor]
|
enum: [text, html, htmlcolor, markdown]
|
||||||
default: text
|
default: text
|
||||||
- name: word_diff
|
- name: word_diff
|
||||||
in: query
|
in: query
|
||||||
@@ -888,6 +907,69 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||||
default: "false"
|
default: "false"
|
||||||
|
- name: type
|
||||||
|
in: query
|
||||||
|
description: |
|
||||||
|
Diff granularity type:
|
||||||
|
- `diffLines` (default): Line-level comparison, showing which lines changed
|
||||||
|
- `diffWords`: Word-level comparison, showing which words changed within lines
|
||||||
|
|
||||||
|
This parameter is an alternative to `word_diff` for better alignment with the UI.
|
||||||
|
If both are specified, `type=diffWords` will enable word-level diffing.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [diffLines, diffWords]
|
||||||
|
default: diffLines
|
||||||
|
- name: changesOnly
|
||||||
|
in: query
|
||||||
|
description: |
|
||||||
|
When enabled, only show lines/content that changed (no surrounding context).
|
||||||
|
When disabled, include unchanged lines for context around changes.
|
||||||
|
Accepts: true, false, 1, 0, yes, no, on, off
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||||
|
default: "true"
|
||||||
|
- name: ignoreWhitespace
|
||||||
|
in: query
|
||||||
|
description: |
|
||||||
|
When enabled, ignore whitespace-only changes (spaces, tabs, newlines).
|
||||||
|
Useful for focusing on content changes and ignoring formatting differences.
|
||||||
|
Accepts: true, false, 1, 0, yes, no, on, off
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||||
|
default: "false"
|
||||||
|
- name: removed
|
||||||
|
in: query
|
||||||
|
description: |
|
||||||
|
Include removed/deleted content in the diff output.
|
||||||
|
When disabled, content that was deleted will not appear in the diff.
|
||||||
|
Accepts: true, false, 1, 0, yes, no, on, off
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||||
|
default: "true"
|
||||||
|
- name: added
|
||||||
|
in: query
|
||||||
|
description: |
|
||||||
|
Include added/new content in the diff output.
|
||||||
|
When disabled, content that was added will not appear in the diff.
|
||||||
|
Accepts: true, false, 1, 0, yes, no, on, off
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||||
|
default: "true"
|
||||||
|
- name: replaced
|
||||||
|
in: query
|
||||||
|
description: |
|
||||||
|
Include replaced/modified content in the diff output.
|
||||||
|
When disabled, content that was modified (changed from one value to another) will not appear in the diff.
|
||||||
|
Accepts: true, false, 1, 0, yes, no, on, off
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||||
|
default: "true"
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Formatted diff between the two snapshots
|
description: Formatted diff between the two snapshots
|
||||||
|
|||||||
+163
-4
File diff suppressed because one or more lines are too long
+4
-4
@@ -12,8 +12,8 @@ janus # Thread-safe async/sync queue bridge
|
|||||||
flask_wtf~=1.2
|
flask_wtf~=1.2
|
||||||
flask~=3.1
|
flask~=3.1
|
||||||
flask-socketio~=5.6.0
|
flask-socketio~=5.6.0
|
||||||
python-socketio~=5.14.3
|
python-socketio~=5.16.0
|
||||||
python-engineio~=4.12.3
|
python-engineio~=4.13.0
|
||||||
inscriptis~=2.2
|
inscriptis~=2.2
|
||||||
pytz
|
pytz
|
||||||
timeago~=1.0
|
timeago~=1.0
|
||||||
@@ -60,7 +60,7 @@ cryptography==46.0.3
|
|||||||
paho-mqtt!=2.0.*
|
paho-mqtt!=2.0.*
|
||||||
|
|
||||||
# Used for CSS filtering, JSON extraction from HTML
|
# Used for CSS filtering, JSON extraction from HTML
|
||||||
beautifulsoup4>=4.0.0,<=4.14.2
|
beautifulsoup4>=4.0.0,<=4.14.3
|
||||||
|
|
||||||
# XPath filtering, lxml is required by bs4 anyway, but put it here to be safe.
|
# XPath filtering, lxml is required by bs4 anyway, but put it here to be safe.
|
||||||
# #2328 - 5.2.0 and 5.2.1 had extra CPU flag CFLAGS set which was not compatible on older hardware
|
# #2328 - 5.2.0 and 5.2.1 had extra CPU flag CFLAGS set which was not compatible on older hardware
|
||||||
@@ -148,7 +148,7 @@ tzdata
|
|||||||
pluggy ~= 1.6
|
pluggy ~= 1.6
|
||||||
|
|
||||||
# Needed for testing, cross-platform for process and system monitoring
|
# Needed for testing, cross-platform for process and system monitoring
|
||||||
psutil==7.1.0
|
psutil==7.2.1
|
||||||
|
|
||||||
ruff >= 0.11.2
|
ruff >= 0.11.2
|
||||||
pre_commit >= 4.2.0
|
pre_commit >= 4.2.0
|
||||||
|
|||||||
Reference in New Issue
Block a user