Spaces:
Paused
Paused
| {% extends 'base.html' %} | |
| {% block content %} | |
| {% from '_helpers.html' import render_field, render_checkbox_field, render_button, render_time_schedule_form %} | |
| {% from '_common_fields.html' import render_common_settings_form %} | |
| <script> | |
| </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="#timedate">Time & Date</a></li> | |
| <li class="tab"><a href="#proxies">CAPTCHA & Proxies</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 --> | |
| <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.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.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"> | |
| {% 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 view watch diff page when password is enabled (Good for sharing the diff page) | |
| </span> | |
| </div> | |
| <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.pager_size) }} | |
| <span class="pure-form-message-inline">Number of items per page in the watch overview list, 0 to disable.</span> | |
| </div> | |
| <div class="pure-control-group"> | |
| {{ render_field(form.application.form.rss_content_format) }} | |
| <span class="pure-form-message-inline">Love RSS? Does your reader support HTML? Set it here</span> | |
| </div> | |
| <div class="pure-control-group"> | |
| {{ render_checkbox_field(form.application.form.extract_title_as_title) }} | |
| <span class="pure-form-message-inline">Note: This will automatically apply to all existing watches.</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 class="pure-control-group 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> | |
| {% endif %} | |
| </fieldset> | |
| </div> | |
| <div class="tab-pane-inner" id="notifications"> | |
| <fieldset> | |
| <div class="field-group"> | |
| {{ render_common_settings_form(form.application.form, emailprefix, settings_application, extra_notification_token_placeholder_info) }} | |
| </div> | |
| </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 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> | |
| </div> | |
| <div class="tab-pane-inner" id="api"> | |
| <h4>API Access</h4> | |
| <p>Drive your changedetection.io via API, More about <a href="https://github.com/dgtlmoon/changedetection.io/wiki/API-Reference">API access 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') }}" alt="Chrome"> | |
| Chrome Webstore | |
| </a> | |
| </p> | |
| </div> | |
| </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> | |
| <p> | |
| {{ render_field(form.application.form.timezone) }} | |
| <datalist id="timezones" style="display: none;"> | |
| {% for tz_name in available_timezones %} | |
| <option value="{{ tz_name }}">{{ tz_name }}</option> | |
| {% endfor %} | |
| </datalist> | |
| </p> | |
| </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> | |
| <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. | |
| <div class="pure-control-group" id="extra-proxies-setting"> | |
| {{ render_field(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_field(form.requests.form.extra_browsers) }} | |
| </div> | |
| </div> | |
| <div id="actions"> | |
| <div class="pure-control-group"> | |
| {{ render_button(form.save_button) }} | |
| <a href="{{url_for('watchlist.index')}}" class="pure-button button-small button-cancel">Back</a> | |
| <a href="{{url_for('ui.clear_all_history')}}" class="pure-button button-small button-error">Clear Snapshot History</a> | |
| </div> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| {% endblock %} | |