mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-05-01 07:10:34 +00:00
278da3fa9b
Build and push containers / metadata (push) Has been cancelled
Build and push containers / build-push-containers (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-10 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-11 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-12 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-13 (push) Has been cancelled
422 lines
29 KiB
HTML
422 lines
29 KiB
HTML
{% extends 'base.html' %}
|
||
|
||
{% block content %}
|
||
{% from '_helpers.html' import render_field, render_checkbox_field, render_button, render_time_schedule_form, render_ternary_field, render_fieldlist_with_inline_errors %}
|
||
{% from '_common_fields.html' import render_common_settings_form, show_token_placeholders %}
|
||
<script>
|
||
const notification_base_url="{{url_for('ui.ui_notification.ajax_callback_send_notification_test', mode="global-settings")}}";
|
||
{% if emailprefix %}
|
||
const email_notification_prefix=JSON.parse('{{emailprefix|tojson}}');
|
||
{% endif %}
|
||
</script>
|
||
<script src="{{url_for('static_content', group='js', filename='tabs.js')}}" defer></script>
|
||
<script src="{{url_for('static_content', group='js', filename='plugins.js')}}" defer></script>
|
||
<script src="{{url_for('static_content', group='js', filename='notifications.js')}}" defer></script>
|
||
<script src="{{url_for('static_content', group='js', filename='vis.js')}}" defer></script>
|
||
<script src="{{url_for('static_content', group='js', filename='global-settings.js')}}" defer></script>
|
||
<script src="{{url_for('static_content', group='js', filename='scheduler.js')}}" defer></script>
|
||
<div class="edit-form">
|
||
<div class="tabs collapsable">
|
||
<ul>
|
||
<li class="tab" id=""><a href="#general">{{ _('General') }}</a></li>
|
||
<li class="tab"><a href="#notifications">{{ _('Notifications') }}</a></li>
|
||
<li class="tab"><a href="#fetching">{{ _('Fetching') }}</a></li>
|
||
<li class="tab"><a href="#filters">{{ _('Global Filters') }}</a></li>
|
||
<li class="tab"><a href="#ui-options">{{ _('UI Options') }}</a></li>
|
||
<li class="tab"><a href="#api">{{ _('API') }}</a></li>
|
||
<li class="tab"><a href="#rss">{{ _('RSS') }}</a></li>
|
||
<li class="tab"><a href="{{ url_for('backups.index') }}">{{ _('Backups') }}</a></li>
|
||
<li class="tab"><a href="#timedate">{{ _('Time & Date') }}</a></li>
|
||
<li class="tab"><a href="#proxies">{{ _('CAPTCHA & Proxies') }}</a></li>
|
||
{% if plugin_tabs %}
|
||
{% for tab in plugin_tabs %}
|
||
<li class="tab"><a href="#plugin-{{ tab.plugin_id }}">{{ tab.tab_label }}</a></li>
|
||
{% endfor %}
|
||
{% endif %}
|
||
<li class="tab"><a href="#info">{{ _('Info') }}</a></li>
|
||
</ul>
|
||
</div>
|
||
<div class="box-wrap inner">
|
||
<form class="pure-form pure-form-stacked settings" action="{{url_for('settings.settings_page')}}" method="POST">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" >
|
||
<div class="tab-pane-inner" id="general">
|
||
<fieldset>
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.requests.form.time_between_check, class="time-check-widget") }}
|
||
|
||
<span class="pure-form-message-inline">{{ _('Default recheck time for all watches, current system minimum is') }} <i>{{min_system_recheck_seconds}}</i> {{ _('seconds') }} (<a href="https://github.com/dgtlmoon/changedetection.io/wiki/Misc-system-settings#enviroment-variables">{{ _('more info') }}</a>).</span>
|
||
<div id="time-between-check-schedule">
|
||
<!-- Start Time and End Time {{ timezone_default_config }} -->
|
||
<div id="limit-between-time">
|
||
{{ render_time_schedule_form(form.requests, available_timezones, timezone_default_config) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.application.form.filter_failure_notification_threshold_attempts, class="filter_failure_notification_threshold_attempts") }}
|
||
<span class="pure-form-message-inline">{{ _('After this many consecutive times that the CSS/xPath filter is missing, send a notification') }}
|
||
<br>
|
||
{{ _('Set to') }} <strong>0</strong> {{ _('to disable') }}
|
||
</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.application.form.history_snapshot_max_length, class="history_snapshot_max_length") }}
|
||
<span class="pure-form-message-inline">{{ _('Limit collection of history snapshots for each watch to this number of history items.') }}
|
||
<br>
|
||
{{ _('Set to empty to disable / no limit') }}
|
||
</span>
|
||
</div>
|
||
|
||
<div class="pure-control-group">
|
||
{% if not hide_remove_pass %}
|
||
{% if current_user.is_authenticated %}
|
||
{{ render_button(form.application.form.removepassword_button) }}
|
||
{% else %}
|
||
{{ render_field(form.application.form.password) }}
|
||
<span class="pure-form-message-inline">{{ _('Password protection for your changedetection.io application.') }}</span>
|
||
{% endif %}
|
||
{% else %}
|
||
<span class="pure-form-message-inline">{{ _('Password is locked.') }}</span>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<div class="pure-control-group">
|
||
{{ render_checkbox_field(form.application.form.shared_diff_access, class="shared_diff_access") }}
|
||
<span class="pure-form-message-inline">{{ _('Allow access to the watch change history page when password is enabled (Good for sharing the diff page)') }}</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_checkbox_field(form.application.form.empty_pages_are_a_change) }}
|
||
<span class="pure-form-message-inline">{{ _('When a request returns no content, or the HTML does not contain any text, is this considered a change?') }}</span>
|
||
</div>
|
||
{% if form.requests.proxy %}
|
||
<div>
|
||
<br>
|
||
<div class="inline-radio">
|
||
{{ render_field(form.requests.form.proxy, class="fetch-backend-proxy") }}
|
||
<span class="pure-form-message-inline">{{ _('Choose a default proxy for all watches') }}</span>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
</fieldset>
|
||
</div>
|
||
|
||
<div class="tab-pane-inner" id="notifications">
|
||
<fieldset>
|
||
{{ render_common_settings_form(form.application.form, emailprefix, settings_application, extra_notification_token_placeholder_info) }}
|
||
</fieldset>
|
||
<div class="pure-control-group" id="notification-base-url">
|
||
{{ render_field(form.application.form.base_url, class="m-d") }}
|
||
<span class="pure-form-message-inline">
|
||
{{ _('Base URL used for the') }} <code>{{ '{{ base_url }}' }}</code> {{ _('token in notification links.') }}<br>
|
||
{{ _('Default value is the system environment variable') }} '<code>BASE_URL</code>' - <a href="https://github.com/dgtlmoon/changedetection.io/wiki/Configurable-BASE_URL-setting">{{ _('read more here') }}</a>.
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-pane-inner" id="fetching">
|
||
<div class="pure-control-group inline-radio">
|
||
{{ render_field(form.application.form.fetch_backend, class="fetch-backend") }}
|
||
<span class="pure-form-message-inline">
|
||
<p>{{ _('Use the') }} <strong>{{ _('Basic') }}</strong> {{ _('method (default) where your watched sites don\'t need Javascript to render.') }}</p>
|
||
<p>{{ _('The') }} <strong>{{ _('Chrome/Javascript') }}</strong> {{ _('method requires a network connection to a running WebDriver+Chrome server, set by the ENV var') }} 'WEBDRIVER_URL'. </p>
|
||
</span>
|
||
</div>
|
||
<fieldset class="pure-group" id="webdriver-override-options" data-visible-for="application-fetch_backend=html_webdriver">
|
||
<div class="pure-form-message-inline">
|
||
<strong>{{ _('If you\'re having trouble waiting for the page to be fully rendered (text missing etc), try increasing the \'wait\' time here.') }}</strong>
|
||
<br>
|
||
{{ _('This will wait') }} <i>n</i> {{ _('seconds before extracting the text.') }}
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.application.form.webdriver_delay) }}
|
||
</div>
|
||
</fieldset>
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.requests.form.workers) }}
|
||
{% set worker_info = get_worker_status_info() %}
|
||
<span class="pure-form-message-inline">{{ _('Number of concurrent workers to process watches. More workers = faster processing but higher memory usage.') }}<br>
|
||
{{ _('Currently running:') }} <strong>{{ worker_info.count }}</strong> {{ _('operational') }} {{ worker_info.type }} {{ _('workers') }}{% if worker_info.active_workers > 0 %} ({{ worker_info.active_workers }} {{ _('actively processing') }}){% endif %}.</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.requests.form.jitter_seconds, class="jitter_seconds") }}
|
||
<span class="pure-form-message-inline">{{ _('Example - 3 seconds random jitter could trigger up to 3 seconds earlier or up to 3 seconds later') }}</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ 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.') }}</span><br>
|
||
</div>
|
||
<div class="pure-control-group inline-radio">
|
||
{{ render_field(form.requests.form.default_ua) }}
|
||
<span class="pure-form-message-inline">
|
||
{{ _('Applied to all requests.') }}<br><br>
|
||
{{ _('Note: Simply changing the User-Agent often does not defeat anti-robot technologies, it\'s important to consider') }} <a href="https://changedetection.io/tutorial/what-are-main-types-anti-robot-mechanisms">{{ _('all of the ways that the browser is detected') }}</a>.
|
||
</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
<br>
|
||
{{ _('Tip:') }} <a href="https://github.com/dgtlmoon/changedetection.io/wiki/Proxy-configuration#brightdata-proxy-support">{{ _('Connect using Bright Data and Oxylabs Proxies, find out more here.') }}</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-pane-inner" id="filters">
|
||
|
||
<fieldset class="pure-group">
|
||
{{ render_checkbox_field(form.application.form.ignore_whitespace) }}
|
||
<span class="pure-form-message-inline">{{ _('Ignore whitespace, tabs and new-lines/line-feeds when considering if a change was detected.') }}<br>
|
||
<i>{{ _('Note:') }}</i> {{ _('Changing this will change the status of your existing watches, possibly trigger alerts etc.') }}
|
||
</span>
|
||
</fieldset>
|
||
<fieldset class="pure-group">
|
||
{{ render_checkbox_field(form.application.form.render_anchor_tag_content) }}
|
||
<span class="pure-form-message-inline">{{ _('Render anchor tag content, default disabled, when enabled renders links as') }} <code>(link text)[https://somesite.com]</code>
|
||
<br>
|
||
<i>{{ _('Note:') }}</i> {{ _('Changing this could affect the content of your existing watches, possibly trigger alerts etc.') }}
|
||
</span>
|
||
</fieldset>
|
||
<fieldset class="pure-group">
|
||
{{ render_field(form.application.form.global_subtractive_selectors, rows=5, placeholder="header
|
||
footer
|
||
nav
|
||
.stockticker
|
||
//*[contains(text(), 'Advertisement')]") }}
|
||
<span class="pure-form-message-inline">
|
||
<ul>
|
||
<li> {{ _('Remove HTML element(s) by CSS and XPath selectors before text conversion.') }} </li>
|
||
<li> {{ _('Don\'t paste HTML here, use only CSS and XPath selectors') }} </li>
|
||
<li> {{ _('Add multiple elements, CSS or XPath selectors per line to ignore multiple parts of the HTML.') }} </li>
|
||
</ul>
|
||
</span>
|
||
</fieldset>
|
||
<fieldset class="pure-group">
|
||
{{ render_field(form.application.form.global_ignore_text, rows=5, placeholder="Some text to ignore in a line
|
||
/some.regex\d{2}/ for case-INsensitive regex
|
||
") }}
|
||
<span class="pure-form-message-inline">{{ _('Note: This is applied globally in addition to the per-watch rules.') }}</span><br>
|
||
<span class="pure-form-message-inline">
|
||
<ul>
|
||
<li>{{ _('Matching text will be') }} <strong>{{ _('ignored') }}</strong> {{ _('in the text snapshot (you can still see it but it wont trigger a change)') }}</li>
|
||
<li>{{ _('Note: This is applied globally in addition to the per-watch rules.') }}</li>
|
||
<li>{{ _('Each line processed separately, any line matching will be ignored (removed before creating the checksum)') }}</li>
|
||
<li>{{ _('Regular Expression support, wrap the entire line in forward slash') }} <code>/regex/</code></li>
|
||
<li>{{ _('Changing this will affect the comparison checksum which may trigger an alert') }}</li>
|
||
</ul>
|
||
</span>
|
||
</fieldset>
|
||
<fieldset class="pure-group">
|
||
{{ render_checkbox_field(form.application.form.strip_ignored_lines) }}
|
||
<span class="pure-form-message-inline">{{ _('Remove any text that appears in the "Ignore text" from the output (otherwise its just ignored for change-detection)') }}<br>
|
||
<i>{{ _('Note:') }}</i> {{ _('Changing this will change the status of your existing watches, possibly trigger alerts etc.') }}
|
||
</span>
|
||
</fieldset>
|
||
</div>
|
||
|
||
<div class="tab-pane-inner" id="api">
|
||
<h4>{{ _('API Access') }}</h4>
|
||
<p>{{ _('Drive your changedetection.io via API, More about') }} <a href="https://changedetection.io/docs/api_v1/index.html">{{ _('API access and examples here') }}</a>.</p>
|
||
|
||
<div class="pure-control-group">
|
||
{{ render_checkbox_field(form.application.form.api_access_token_enabled) }}
|
||
<div class="pure-form-message-inline">{{ _('Restrict API access limit by using') }} <code>x-api-key</code> {{ _('header - required for the Chrome Extension to work') }}</div><br>
|
||
<div class="pure-form-message-inline"><br>{{ _('API Key') }} <span id="api-key">{{api_key}}</span>
|
||
<span style="display:none;" id="api-key-copy" >{{ _('copy') }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
<a href="{{url_for('settings.settings_reset_api_key')}}" class="pure-button button-small button-cancel">{{ _('Regenerate API key') }}</a>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
<h4>{{ _('Chrome Extension') }}</h4>
|
||
<p>{{ _('Easily add any web-page to your changedetection.io installation from within Chrome.') }}</p>
|
||
<strong>{{ _('Step 1') }}</strong> {{ _('Install the extension,') }} <strong>{{ _('Step 2') }}</strong> {{ _('Navigate to this page,') }}
|
||
<strong>{{ _('Step 3') }}</strong> {{ _('Open the extension from the toolbar and click') }} "<i>{{ _('Sync API Access') }}</i>"
|
||
<p>
|
||
<a id="chrome-extension-link"
|
||
title="{{ _('Try our new Chrome Extension!') }}"
|
||
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') }}" >
|
||
{{ _('Chrome Webstore') }}
|
||
</a>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="tab-pane-inner" id="rss">
|
||
<div class="pure-control-group">
|
||
{{ render_checkbox_field(form.application.form.rss_hide_muted_watches) }}
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.application.form.rss_diff_length) }}
|
||
<span class="pure-form-message-inline">{{ _('Maximum number of history snapshots to include in the watch specific RSS feed.') }}</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_checkbox_field(form.application.form.rss_reader_mode) }}
|
||
<span class="pure-form-message-inline">{{ _('For watching other RSS feeds - When watching RSS/Atom feeds, convert them into clean text for better change detection.') }}</span>
|
||
</div>
|
||
<div class="pure-control-group grey-form-border">
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.application.form.rss_content_format) }}
|
||
<span class="pure-form-message-inline">{{ _('Does your reader support HTML? Set it here') }}</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.application.form.rss_template_type) }}
|
||
<span class="pure-form-message-inline">{{ _('\'System default\' for the same template for all items, or re-use your "Notification Body" as the template.') }}</span>
|
||
</div>
|
||
<div>
|
||
{{ render_field(form.application.form.rss_template_override) }}
|
||
{{ show_token_placeholders(extra_notification_token_placeholder_info=extra_notification_token_placeholder_info, suffix="-rss") }}
|
||
</div>
|
||
</div>
|
||
<br>
|
||
|
||
|
||
</div>
|
||
<div class="tab-pane-inner" id="timedate">
|
||
<div class="pure-control-group">
|
||
{{ _('Ensure the settings below are correct, they are used to manage the time schedule for checking your web page watches.') }}
|
||
</div>
|
||
<div class="pure-control-group">
|
||
<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>
|
||
<div>
|
||
{{ render_field(form.application.form.scheduler_timezone_default) }}
|
||
<datalist id="timezones" style="display: none;">
|
||
{%- for timezone in available_timezones -%}<option value="{{ timezone }}">{{ timezone }}</option>{%- endfor -%}
|
||
</datalist>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="tab-pane-inner" id="ui-options">
|
||
<div class="pure-control-group">
|
||
{{ render_checkbox_field(form.application.form.ui.form.open_diff_in_new_tab, class="open_diff_in_new_tab") }}
|
||
<span class="pure-form-message-inline">{{ _('Enable this setting to open the diff page in a new tab. If disabled, the diff page will open in the current tab.') }}</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_checkbox_field(form.application.form.ui.form.socket_io_enabled, class="socket_io_enabled") }}
|
||
<span class="pure-form-message-inline">{{ _('Realtime UI Updates Enabled - (Restart required if this is changed)') }}</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_checkbox_field(form.application.form.ui.form.favicons_enabled, class="") }}
|
||
<span class="pure-form-message-inline">{{ _('Enable or Disable Favicons next to the watch list') }}</span>
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_checkbox_field(form.application.form.ui.use_page_title_in_list) }}
|
||
</div>
|
||
<div class="pure-control-group">
|
||
{{ render_field(form.application.form.pager_size) }}
|
||
<span class="pure-form-message-inline">{{ _('Number of items per page in the watch overview list, 0 to disable.') }}</span>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="tab-pane-inner" id="proxies">
|
||
<div id="recommended-proxy">
|
||
<div>
|
||
<img style="height: 2em;" src="{{url_for('static_content', group='images', filename='brightdata.svg')}}" alt="BrightData Proxy Provider">
|
||
<p>BrightData offer world-class proxy services, "Data Center" proxies are a very affordable way to proxy your requests, whilst <strong><a href="https://brightdata.grsm.io/n0r16zf7eivq">WebUnlocker</a></strong> can help solve most CAPTCHAs.</p>
|
||
<p>
|
||
BrightData offer many <a href="https://brightdata.com/proxy-types" target="new">many different types of proxies</a>, it is worth reading about what is best for your use-case.
|
||
</p>
|
||
|
||
<p>
|
||
When you have <a href="https://brightdata.grsm.io/n0r16zf7eivq">registered</a>, enabled the required services, visit the <A href="https://brightdata.com/cp/api_example?">API example page</A>, then select <strong>Python</strong>, set the country you wish to use, then copy+paste the access Proxy URL into the "Extra Proxies" boxes below.<br>
|
||
</p>
|
||
<p>
|
||
The Proxy URL with BrightData should start with <code>http://brd-customer...</code>
|
||
</p>
|
||
<p>When you sign up using <a href="https://brightdata.grsm.io/n0r16zf7eivq">https://brightdata.grsm.io/n0r16zf7eivq</a> BrightData will match any first deposit up to $150</p>
|
||
</div>
|
||
<div>
|
||
<img style="height: 2em;"
|
||
src="{{url_for('static_content', group='images', filename='oxylabs.svg')}}"
|
||
alt="Oxylabs Proxy Provider">
|
||
<p>
|
||
Collect public data at scale with industry-leading web scraping solutions and the world’s
|
||
largest ethical proxy network.
|
||
</p>
|
||
<p>
|
||
Oxylabs also provide a <a href="https://oxylabs.io/products/web-unblocker"><strong>WebUnlocker</strong></a>
|
||
proxy that bypasses sophisticated anti-bot systems, so you don’t have to.<br>
|
||
</p>
|
||
<p>
|
||
Serve over <a href="https://oxylabs.io/location-proxy">195 countries</a>, providing <a
|
||
href="https://oxylabs.io/products/residential-proxy-pool">Residential</a>, <a
|
||
href="https://oxylabs.io/products/mobile-proxies">Mobile</a> and <a
|
||
href="https://oxylabs.io/products/rotating-isp-proxies">ISP proxies</a> and much more.
|
||
</p>
|
||
<p>
|
||
Use the promo code <strong>boost35</strong> with this link <a href="https://oxylabs.go2cloud.org/SH2d">https://oxylabs.go2cloud.org/SH2d</a> for 35% off Residential, Mobile proxies, Web Unblocker, and Scraper APIs. Built-in proxies enable you to access data from all around the world and help overcome anti-bot solutions.
|
||
|
||
</p>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<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">
|
||
{{ render_fieldlist_with_inline_errors(form.requests.form.extra_proxies) }}
|
||
<span class="pure-form-message-inline">{{ _('"Name" will be used for selecting the proxy in the Watch Edit settings') }}</span><br>
|
||
<span class="pure-form-message-inline">{{ _('SOCKS5 proxies with authentication are only supported with \'plain requests\' fetcher, for other fetchers you should whitelist the IP access instead') }}</span>
|
||
</div>
|
||
<div class="pure-control-group" id="extra-browsers-setting">
|
||
<p>
|
||
<span class="pure-form-message-inline"><i>Extra Browsers</i> can be attached to further defeat CAPTCHA's on websites that are particularly hard to scrape.</span><br>
|
||
<span class="pure-form-message-inline">Simply paste the connection address into the box, <a href="https://changedetection.io/tutorial/using-bright-datas-scraping-browser-pass-captchas-and-other-protection-when-monitoring">More instructions and examples here</a> </span>
|
||
</p>
|
||
{{ render_fieldlist_with_inline_errors(form.requests.form.extra_browsers) }}
|
||
</div>
|
||
</div>
|
||
{% if plugin_tabs %}
|
||
{% for tab in plugin_tabs %}
|
||
<div class="tab-pane-inner" id="plugin-{{ tab.plugin_id }}">
|
||
{% set plugin_form = plugin_forms[tab.plugin_id] %}
|
||
{% if tab.template_path %}
|
||
{# Plugin provides custom template - include it directly (no separate form) #}
|
||
{% include tab.template_path with context %}
|
||
{% else %}
|
||
{# Default form rendering - fields only, no submit button #}
|
||
<fieldset>
|
||
{% for field in plugin_form %}
|
||
{% if field.type != 'CSRFToken' and field.type != 'SubmitField' %}
|
||
<div class="pure-control-group">
|
||
{% if field.type == 'BooleanField' %}
|
||
{{ render_checkbox_field(field) }}
|
||
{% else %}
|
||
{{ render_field(field) }}
|
||
{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</fieldset>
|
||
{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
{% endif %}
|
||
<div class="tab-pane-inner" id="info">
|
||
<p><strong>{{ _('Uptime:') }}</strong> {{ uptime_seconds|format_duration }}</p>
|
||
<p><strong>{{ _('Python version:') }}</strong> {{ python_version }}</p>
|
||
<p><strong>{{ _('Plugins active:') }}</strong></p>
|
||
{% if active_plugins %}
|
||
<ul>
|
||
{% for plugin in active_plugins %}
|
||
<li><strong>{{ plugin.name }}</strong> - {{ plugin.description }}</li>
|
||
{% endfor %}
|
||
</ul>
|
||
{% else %}
|
||
<p>{{ _('No plugins active') }}</p>
|
||
{% endif %}
|
||
</div>
|
||
<div id="actions">
|
||
<div class="pure-control-group">
|
||
{{ render_button(form.save_button) }}
|
||
<a href="{{url_for('watchlist.index')}}" class="pure-button button-cancel">{{ _('Back') }}</a>
|
||
<a href="{{url_for('ui.clear_all_history')}}" class="pure-button button-error">{{ _('Clear Snapshot History') }}</a>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
{% endblock %}
|