Compare commits

..

1 Commits

Author SHA1 Message Date
dgtlmoon
d4a85976e6 Previous error that is no longer valid was not being cleared 2023-07-11 08:59:23 +02:00
12 changed files with 41 additions and 78 deletions

View File

@@ -62,7 +62,7 @@ jobs:
with: with:
context: ./ context: ./
file: ./Dockerfile file: ./Dockerfile
platforms: linux/arm/v6,linux/arm/v7,linux/amd64,linux/arm64, platforms: linux/arm/v7,linux/arm/v6,linux/amd64,linux/arm64,
cache-from: type=local,src=/tmp/.buildx-cache cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache

View File

@@ -36,8 +36,6 @@ jobs:
run: | run: |
# Build a changedetection.io container and start testing inside # Build a changedetection.io container and start testing inside
docker build . -t test-changedetectionio docker build . -t test-changedetectionio
# Debug info
docker run test-changedetectionio bash -c 'pip list'
- name: Spin up ancillary SMTP+Echo message test server - name: Spin up ancillary SMTP+Echo message test server
run: | run: |
@@ -46,6 +44,7 @@ jobs:
- name: Test built container with pytest - name: Test built container with pytest
run: | run: |
# Unit tests # Unit tests
docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_notification_diff' docker run test-changedetectionio bash -c 'python3 -m unittest changedetectionio.tests.unit.test_notification_diff'

View File

@@ -38,7 +38,7 @@ from flask_paginate import Pagination, get_page_parameter
from changedetectionio import html_tools from changedetectionio import html_tools
from changedetectionio.api import api_v1 from changedetectionio.api import api_v1
__version__ = '0.44.1' __version__ = '0.43.2'
datastore = None datastore = None

View File

@@ -1,6 +1,3 @@
import os
from distutils.util import strtobool
from flask_expects_json import expects_json from flask_expects_json import expects_json
from changedetectionio import queuedWatchMetaData from changedetectionio import queuedWatchMetaData
from flask_restful import abort, Resource from flask_restful import abort, Resource
@@ -36,7 +33,7 @@ class Watch(Resource):
@auth.check_token @auth.check_token
def get(self, uuid): def get(self, uuid):
""" """
@api {get} /api/v1/watch/:uuid Single watch - get data, recheck, pause, mute. @api {get} /api/v1/watch/:uuid Get a single watch data
@apiDescription Retrieve watch information and set muted/paused status @apiDescription Retrieve watch information and set muted/paused status
@apiExample {curl} Example usage: @apiExample {curl} Example usage:
curl http://localhost:4000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091 -H"x-api-key:813031b16330fe25e3780cf0325daa45" curl http://localhost:4000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091 -H"x-api-key:813031b16330fe25e3780cf0325daa45"
@@ -212,9 +209,7 @@ class CreateWatch(Resource):
json_data = request.get_json() json_data = request.get_json()
url = json_data['url'].strip() url = json_data['url'].strip()
# If hosts that only contain alphanumerics are allowed ("localhost" for example) if not validators.url(json_data['url'].strip()):
allow_simplehost = not strtobool(os.getenv('BLOCK_SIMPLEHOSTS', 'False'))
if not validators.url(url, simple_host=allow_simplehost):
return "Invalid or unsupported URL", 400 return "Invalid or unsupported URL", 400
if json_data.get('proxy'): if json_data.get('proxy'):

View File

@@ -46,18 +46,12 @@ def construct_blueprint(datastore: ChangeDetectionStore):
except content_fetcher.Non200ErrorCodeReceived as e: except content_fetcher.Non200ErrorCodeReceived as e:
if e.status_code == 404: if e.status_code == 404:
status.update({'status': 'OK', 'length': len(contents), 'text': f"OK but 404 (page not found)"}) status.update({'status': 'OK', 'length': len(contents), 'text': f"OK but 404 (page not found)"})
elif e.status_code == 403 or e.status_code == 401: elif e.status_code == 403:
status.update({'status': 'ERROR', 'length': len(contents), 'text': f"{e.status_code} - Access denied"}) status.update({'status': 'ERROR', 'length': len(contents), 'text': f"403 - Access denied"})
else: else:
status.update({'status': 'ERROR', 'length': len(contents), 'text': f"Status code: {e.status_code}"}) status.update({'status': 'ERROR', 'length': len(contents), 'text': f"Status code: {e.status_code}"})
except text_json_diff.FilterNotFoundInResponse:
status.update({'status': 'OK', 'length': len(contents), 'text': f"OK but CSS/xPath filter not found (page changed layout?)"})
except content_fetcher.EmptyReply as e: except content_fetcher.EmptyReply as e:
if e.status_code == 403 or e.status_code == 401: status.update({'status': 'ERROR OTHER', 'length': len(contents) if contents else 0, 'text': "Empty reply, needs chrome?"})
status.update({'status': 'ERROR OTHER', 'length': len(contents), 'text': f"Got empty reply with code {e.status_code} - Access denied"})
else:
status.update({'status': 'ERROR OTHER', 'length': len(contents) if contents else 0, 'text': f"Empty reply with code {e.status_code}, needs chrome?"})
except Exception as e: except Exception as e:
status.update({'status': 'ERROR OTHER', 'length': len(contents) if contents else 0, 'text': 'Error: '+str(e)}) status.update({'status': 'ERROR OTHER', 'length': len(contents) if contents else 0, 'text': 'Error: '+str(e)})
else: else:
@@ -98,13 +92,8 @@ def construct_blueprint(datastore: ChangeDetectionStore):
if not datastore.proxy_list: if not datastore.proxy_list:
return return
if checks_in_progress.get(uuid): # @todo - Cancel any existing runs
state = _recalc_check_status(uuid=uuid) checks_in_progress[uuid] = {}
for proxy_key, v in state.items():
if v.get('status') == 'RUNNING':
return state
else:
checks_in_progress[uuid] = {}
for k, v in datastore.proxy_list.items(): for k, v in datastore.proxy_list.items():
if not checks_in_progress[uuid].get(k): if not checks_in_progress[uuid].get(k):

View File

@@ -201,8 +201,7 @@ class Fetcher():
dest = os.path.join(self.browser_steps_screenshot_path, 'step_*.jpeg') dest = os.path.join(self.browser_steps_screenshot_path, 'step_*.jpeg')
files = glob.glob(dest) files = glob.glob(dest)
for f in files: for f in files:
if os.path.isfile(f): os.unlink(f)
os.unlink(f)
# Maybe for the future, each fetcher provides its own diff output, could be used for text, image # Maybe for the future, each fetcher provides its own diff output, could be used for text, image

View File

@@ -1,6 +1,5 @@
import os import os
import re import re
from distutils.util import strtobool
from wtforms import ( from wtforms import (
BooleanField, BooleanField,
@@ -258,10 +257,9 @@ class validateURL(object):
def __call__(self, form, field): def __call__(self, form, field):
import validators import validators
# If hosts that only contain alphanumerics are allowed ("localhost" for example)
allow_simplehost = not strtobool(os.getenv('BLOCK_SIMPLEHOSTS', 'False'))
try: try:
validators.url(field.data.strip(), simple_host=allow_simplehost) validators.url(field.data.strip())
except validators.ValidationFailure: except validators.ValidationFailure:
message = field.gettext('\'%s\' is not a valid URL.' % (field.data.strip())) message = field.gettext('\'%s\' is not a valid URL.' % (field.data.strip()))
raise ValidationError(message) raise ValidationError(message)

View File

@@ -12,7 +12,7 @@ $(function () {
function set_proxy_check_status(proxy_key, state) { function set_proxy_check_status(proxy_key, state) {
// select input by value name // select input by value name
const proxy_li = $('input[value="' + proxy_key + '" ]').parent(); const proxy_li = $("input[value=" + proxy_key + "]").parent();
if (state['status'] === 'RUNNING') { if (state['status'] === 'RUNNING') {
$('.proxy-status', proxy_li).html('<span class="spinner"></span>'); $('.proxy-status', proxy_li).html('<span class="spinner"></span>');
} }

View File

@@ -1,25 +0,0 @@
#toggle-light-mode {
width: 3rem;
/* default */
.icon-dark {
display: none;
}
}
html[data-darkmode="true"] {
#toggle-light-mode {
.icon-light {
display: none;
}
.icon-dark {
display: block;
}
}
}

View File

@@ -8,7 +8,6 @@
@import "parts/_pagination"; @import "parts/_pagination";
@import "parts/_spinners"; @import "parts/_spinners";
@import "parts/_variables"; @import "parts/_variables";
@import "parts/_darkmode";
body { body {
color: var(--color-text); color: var(--color-text);
@@ -55,6 +54,22 @@ a.github-link {
} }
} }
#toggle-light-mode {
width: 3rem;
.icon-dark {
display: none;
}
&.dark {
.icon-light {
display: none;
}
.icon-dark {
display: block;
}
}
}
#toggle-search { #toggle-search {
width: 2rem; width: 2rem;

View File

@@ -316,18 +316,6 @@ html[data-darkmode="true"] {
html[data-darkmode="true"] .watch-table .unviewed.error { html[data-darkmode="true"] .watch-table .unviewed.error {
color: var(--color-watch-table-error); } color: var(--color-watch-table-error); }
#toggle-light-mode {
width: 3rem;
/* default */ }
#toggle-light-mode .icon-dark {
display: none; }
html[data-darkmode="true"] #toggle-light-mode .icon-light {
display: none; }
html[data-darkmode="true"] #toggle-light-mode .icon-dark {
display: block; }
body { body {
color: var(--color-text); color: var(--color-text);
background: var(--color-background-page); } background: var(--color-background-page); }
@@ -362,6 +350,15 @@ a.github-link {
a.github-link:hover { a.github-link:hover {
color: var(--color-icon-github-hover); } color: var(--color-icon-github-hover); }
#toggle-light-mode {
width: 3rem; }
#toggle-light-mode .icon-dark {
display: none; }
#toggle-light-mode.dark .icon-light {
display: none; }
#toggle-light-mode.dark .icon-dark {
display: block; }
#toggle-search { #toggle-search {
width: 2rem; } width: 2rem; }

View File

@@ -10,8 +10,7 @@ flask~=2.0
inscriptis~=2.2 inscriptis~=2.2
pytz pytz
timeago~=1.0 timeago~=1.0
validators~=0.21 validators
# Set these versions together to avoid a RequestsDependencyWarning # Set these versions together to avoid a RequestsDependencyWarning
# >= 2.26 also adds Brotli support if brotli is installed # >= 2.26 also adds Brotli support if brotli is installed
@@ -33,7 +32,7 @@ dnspython<2.3.0
# jq not available on Windows so must be installed manually # jq not available on Windows so must be installed manually
# Notification library # Notification library
apprise~=1.4.5 apprise~=1.3.0
# apprise mqtt https://github.com/dgtlmoon/changedetection.io/issues/315 # apprise mqtt https://github.com/dgtlmoon/changedetection.io/issues/315
paho-mqtt paho-mqtt
@@ -72,6 +71,3 @@ pillow
# Include pytest, so if theres a support issue we can ask them to run these tests on their setup # Include pytest, so if theres a support issue we can ask them to run these tests on their setup
pytest ~=7.2 pytest ~=7.2
pytest-flask ~=1.2 pytest-flask ~=1.2
# Pin jsonschema version to prevent build errors on armv6 while rpds-py wheels aren't available (1708)
jsonschema==4.17.3