changedetectionio/blueprint/watchlist/templates/watch-overview.html
{%- extends 'base.html' -%} {%- block content -%} {%- set tips = [_("Changedetection.io can monitor more than just web-pages! See our plugins!") ~ ' ' ~ _('More info') ~ '', _("You can also add 'shared' watches.") ~ ' ' ~ _('More info') ~ '' ] -%} {%- from '_helpers.html' import render_simple_field, render_field, render_nolabel_field, sort_by_title -%}
{{ _('Add a new web page change detection watch') }} {{ render_nolabel_field(form.url, placeholder="https://...", required=true) }} {{ render_nolabel_field(form.watch_submit_button, title=_("Watch this URL!") ) }} {{ render_nolabel_field(form.edit_and_watch_submit_button, title=_("Edit first then Watch") ) }} {% if llm_configured %}
{% endif %} {{ render_field(form.tags, value=active_tag.title if active_tag_uuid else '', placeholder=_("Watch group / tag"), class="transparent-field") }}
{{ render_simple_field(form.processor) }} Tip: {{ tips | random | safe }} {% if llm_configured %} {% endif %}
{{ _('Pause') }}{{ _('UnPause') }}{{ _('Mute') }}{{ _('UnMute') }}{{ _('Recheck') }}{{ _('Tag') }}{{ _('Mark viewed') }}{{ _('Use default notification') }}{{ _('Clear errors') }}{{ _('Clear/reset history') }}{{ _('Delete') }}
{%- if watches|length >= pagination.per_page -%}{{ pagination.info }}{%- endif -%}
{{ _('Queued size') }}: {{ queue_size }}
{%- if search_q -%} {{ _('Searching') }} " {{search_q}}" {%- endif -%} {{ _('All') }} {%- for uuid, tag in tags -%} {%- if tag != "" -%} {{ tag.title }} {%- endif -%} {%- endfor -%} {%- set sort_order = sort_order or 'asc' -%} {%- set sort_attribute = sort_attribute or 'last_changed' -%} {%- set pagination_page = request.args.get('page', 0) -%} {%- set cols_required = 6 -%} {%- set any_has_restock_price_processor = datastore.any_watches_have_processor_by_name("restock_diff") -%} {%- if any_has_restock_price_processor -%} {%- set cols_required = cols_required + 1 -%} {%- endif -%} {%- set ui_settings = datastore.data['settings']['application']['ui'] -%} {%- set wrapper_classes = ['has-unread-changes' if unread_changes_count else '', 'has-error' if errored_count else '',] -%} {%- set table_classes = ['favicon-enabled' if 'favicons_enabled' not in ui_settings or ui_settings['favicons_enabled'] else 'favicon-not-enabled', ] -%}
| {%- set link_order = "desc" if sort_order == 'asc' else "asc" -%} {%- set arrow_span = "" -%} # | {{ _('Website') }} | {%- if any_has_restock_price_processor -%} {{ _('Restock & Price') }} | {%- endif -%} {{ _('Last Checked') }}{{ _('Checked') }} | {{ _('Last Changed') }}{{ _('Changed') }} | ||
|---|---|---|---|---|---|---|
| {%- if not watches | length -%} | {{ _('No web page change detection watches configured, please add a URL in the box above, or') }} {{ _('import a list') }}. | ||||
| {%- endif -%} {%- for watch in (watches | sort(attribute=sort_attribute, reverse=sort_order == 'asc')) | pagination_slice(skip=pagination.skip) -%} {%- set checking_now = is_checking_now(watch) -%} {%- set history_n = watch.history_n -%} {%- set favicon = watch.get_favicon_filename() -%} {%- set error_texts = watch.compile_error_texts(has_proxies=has_proxies) -%} {%- set system_use_url_watchlist = datastore.data['settings']['application']['ui'].get('use_page_title_in_list') -%} {# Class settings mirrored in changedetectionio/static/js/realtime.js for the frontend #} {%- set row_classes = [loop.cycle('pure-table-odd', 'pure-table-even'), 'processor-' ~ watch['processor'], 'has-error' if error_texts | length > 2 else '', 'paused' if watch.paused is defined and watch.paused != False else '', 'unviewed' if watch.has_unviewed else '', 'has-restock-info' if watch.has_restock_info else 'no-restock-info', 'has-favicon' if favicon else '', 'in-stock' if watch.has_restock_info and watch['restock']['in_stock'] else '', 'not-in-stock' if watch.has_restock_info and not watch['restock']['in_stock'] else '', 'queued' if watch.uuid in queued_uuids else '', 'checking-now' if checking_now else '', 'notification_muted' if watch.notification_muted else '', 'single-history' if history_n == 1 else '', 'multiple-history' if history_n >= 2 else '', 'use-html-title' if system_use_url_watchlist else 'no-html-title', ] -%} | |||
| {{ loop.index+pagination.skip }} | ||||||
| {% if 'favicons_enabled' not in ui_settings or ui_settings['favicons_enabled'] %} | ||||||
| {# Intersection Observer lazy loading: store real URL in data-src, load only when visible in viewport #} | ||||||
| {% endif %} | ||||||
| {%- if watch['processor'] and watch['processor'] in processor_badge_texts -%} {{ processor_badge_texts[watch['processor']] }} {%- endif -%} {% if system_use_url_watchlist or watch.get('use_page_title_in_list') %} {{ watch.label }} {% else %} {{ watch.get('title') or watch.link }} {% endif %} | ||||||
| {{ error_texts | safe }} | |||||
| {%- if watch['processor'] == 'text_json_diff' -%} {%- if watch['has_ldjson_price_data'] and not watch['track_ldjson_price_data'] -%} | ||||||
| Switch to Restock & Price watch mode? Yes No | ||||||
| {%- endif -%} {%- endif -%} {%- for watch_tag_uuid, watch_tag in datastore.get_all_tags_for_watch(watch['uuid']).items() -%} {{ watch_tag.title }} {%- endfor -%} |
{%- set effective_fetcher = watch.get_fetch_backend if watch.get_fetch_backend != "system" else system_default_fetcher -%} {%- if effective_fetcher and ("html_webdriver" in effective_fetcher or "html_" in effective_fetcher or "extra_browser_" in effective_fetcher) -%} {{ effective_fetcher|fetcher_status_icons }} {%- endif -%} {%- if watch.is_pdf -%} {%- endif -%} {%- if watch.has_browser_steps -%} {%- endif -%}
|{%- if any_has_restock_price_processor -%} {%- if watch['processor'] == 'restock_diff' -%} {%- if watch.has_restock_info -%} {%- if watch['restock']['in_stock']-%} {{ _('In stock') }} {%- else-%} {{ _('Not in stock') }} {%- endif -%} {%- endif -%} {%- if watch.get('restock') and watch['restock'].get('price') -%} {%- set restock = watch['restock'] -%} {%- set price = restock.get('price') -%} {%- set cur = restock.get('currency','') -%} {%- if price is not none and (price|string)|regex_search('\d') -%} {# @todo: make parse_currency/parse_decimal aware of the locale of the actual web page and use that instead changedetectionio/processors/restock_diff/__init__.py #} {%- if price is number -%}{# It's a number so we can convert it to their locale' #} {{ price|format_number_locale }} {{ cur }} {%- else -%}{# It's totally fine if it arrives as something else, the website might be something weird in this field #} {{ price }} {{ cur }} {%- endif -%} {%- endif -%} {%- elif not watch.has_restock_info -%} {{ _('No information') }} {%- endif -%} {%- endif -%} |{%- endif -%} {#last_checked becomes fetch-start-time#}
{{ _('Checking now') }}
{{watch|format_last_checked_time|safe}} | {%- if watch.history_n >=2 and watch.last_changed >0 -%} {{watch.last_changed|format_timestamp_timeago}} {%- else -%} {{ _('Not yet') }} {%- endif -%} |
{%- set target_attr = ' target="' ~ watch.uuid ~ '"' if datastore.data['settings']['application']['ui'].get('open_diff_in_new_tab') else '' -%} {{ _('Queued') }}{{ _('Recheck') }}{{ _('Edit') }}{{ _('History') }}✨ {{ _('Summary') }}{{ _('Preview') }}
|
{%- endfor -%}
{{ pagination.links }}
{%- endblock -%}