mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2025-12-18 05:55:45 +00:00
Compare commits
1 Commits
API-condit
...
3337-extra
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6572efecc |
5
.github/test/Dockerfile-alpine
vendored
5
.github/test/Dockerfile-alpine
vendored
@@ -2,7 +2,7 @@
|
|||||||
# Test that we can still build on Alpine (musl modified libc https://musl.libc.org/)
|
# Test that we can still build on Alpine (musl modified libc https://musl.libc.org/)
|
||||||
# Some packages wont install via pypi because they dont have a wheel available under this architecture.
|
# Some packages wont install via pypi because they dont have a wheel available under this architecture.
|
||||||
|
|
||||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.22
|
FROM ghcr.io/linuxserver/baseimage-alpine:3.21
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
COPY requirements.txt /requirements.txt
|
COPY requirements.txt /requirements.txt
|
||||||
@@ -24,13 +24,12 @@ RUN \
|
|||||||
apk add --update --no-cache \
|
apk add --update --no-cache \
|
||||||
libjpeg \
|
libjpeg \
|
||||||
libxslt \
|
libxslt \
|
||||||
file \
|
|
||||||
nodejs \
|
nodejs \
|
||||||
poppler-utils \
|
poppler-utils \
|
||||||
python3 && \
|
python3 && \
|
||||||
echo "**** pip3 install test of changedetection.io ****" && \
|
echo "**** pip3 install test of changedetection.io ****" && \
|
||||||
python3 -m venv /lsiopy && \
|
python3 -m venv /lsiopy && \
|
||||||
pip install -U pip wheel setuptools && \
|
pip install -U pip wheel setuptools && \
|
||||||
pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.22/ -r /requirements.txt && \
|
pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.21/ -r /requirements.txt && \
|
||||||
apk del --purge \
|
apk del --purge \
|
||||||
build-dependencies
|
build-dependencies
|
||||||
|
|||||||
@@ -84,9 +84,6 @@ COPY changedetection.py /app/changedetection.py
|
|||||||
ARG LOGGER_LEVEL=''
|
ARG LOGGER_LEVEL=''
|
||||||
ENV LOGGER_LEVEL="$LOGGER_LEVEL"
|
ENV LOGGER_LEVEL="$LOGGER_LEVEL"
|
||||||
|
|
||||||
# Default
|
|
||||||
ENV LC_ALL=en_US.UTF-8
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
CMD ["python", "./changedetection.py", "-d", "/datastore"]
|
CMD ["python", "./changedetection.py", "-d", "/datastore"]
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Read more https://github.com/dgtlmoon/changedetection.io/wiki
|
# Read more https://github.com/dgtlmoon/changedetection.io/wiki
|
||||||
|
|
||||||
__version__ = '0.50.8'
|
__version__ = '0.50.7'
|
||||||
|
|
||||||
from changedetectionio.strtobool import strtobool
|
from changedetectionio.strtobool import strtobool
|
||||||
from json.decoder import JSONDecodeError
|
from json.decoder import JSONDecodeError
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import uuid
|
|||||||
|
|
||||||
from changedetectionio import strtobool
|
from changedetectionio import strtobool
|
||||||
default_notification_format_for_watch = 'System default'
|
default_notification_format_for_watch = 'System default'
|
||||||
CONDITIONS_MATCH_LOGIC_DEFAULT = 'ALL'
|
|
||||||
|
|
||||||
class watch_base(dict):
|
class watch_base(dict):
|
||||||
|
|
||||||
@@ -16,8 +15,6 @@ class watch_base(dict):
|
|||||||
'body': None,
|
'body': None,
|
||||||
'browser_steps': [],
|
'browser_steps': [],
|
||||||
'browser_steps_last_error_step': None,
|
'browser_steps_last_error_step': None,
|
||||||
'conditions' : {},
|
|
||||||
'conditions_match_logic': CONDITIONS_MATCH_LOGIC_DEFAULT,
|
|
||||||
'check_count': 0,
|
'check_count': 0,
|
||||||
'check_unique_lines': False, # On change-detected, compare against all history if its something new
|
'check_unique_lines': False, # On change-detected, compare against all history if its something new
|
||||||
'consecutive_filter_failures': 0, # Every time the CSS/xPath filter cannot be located, reset when all is fine.
|
'consecutive_filter_failures': 0, # Every time the CSS/xPath filter cannot be located, reset when all is fine.
|
||||||
|
|||||||
@@ -6,19 +6,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.favicon-enabled {
|
||||||
tr {
|
tr {
|
||||||
/* make the icons and the text inline-ish */
|
/* make the icons and the text inline-ish */
|
||||||
td.inline.title-col {
|
td.inline.title-col {
|
||||||
.flex-wrapper {
|
.flex-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
td,
|
td,
|
||||||
th {
|
th {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -292,7 +292,9 @@ def test_access_denied(client, live_server, measure_memory_usage):
|
|||||||
|
|
||||||
def test_api_watch_PUT_update(client, live_server, measure_memory_usage):
|
def test_api_watch_PUT_update(client, live_server, measure_memory_usage):
|
||||||
|
|
||||||
|
|
||||||
api_key = live_server.app.config['DATASTORE'].data['settings']['application'].get('api_access_token')
|
api_key = live_server.app.config['DATASTORE'].data['settings']['application'].get('api_access_token')
|
||||||
|
|
||||||
# Create a watch
|
# Create a watch
|
||||||
set_original_response()
|
set_original_response()
|
||||||
test_url = url_for('test_endpoint', _external=True)
|
test_url = url_for('test_endpoint', _external=True)
|
||||||
@@ -300,27 +302,14 @@ def test_api_watch_PUT_update(client, live_server, measure_memory_usage):
|
|||||||
# Create new
|
# Create new
|
||||||
res = client.post(
|
res = client.post(
|
||||||
url_for("createwatch"),
|
url_for("createwatch"),
|
||||||
data=json.dumps({"url": test_url,
|
data=json.dumps({"url": test_url, 'tag': "One, Two", "title": "My test URL", 'headers': {'cookie': 'yum'} }),
|
||||||
'tag': "One, Two",
|
|
||||||
"title": "My test URL",
|
|
||||||
'headers': {'cookie': 'yum'},
|
|
||||||
"conditions": [
|
|
||||||
{
|
|
||||||
"field": "page_filtered_text",
|
|
||||||
"operator": "contains_regex",
|
|
||||||
"value": "." # contains anything
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"conditions_match_logic": "ALL"
|
|
||||||
}
|
|
||||||
),
|
|
||||||
headers={'content-type': 'application/json', 'x-api-key': api_key},
|
headers={'content-type': 'application/json', 'x-api-key': api_key},
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
)
|
)
|
||||||
|
|
||||||
assert res.status_code == 201
|
assert res.status_code == 201
|
||||||
|
|
||||||
wait_for_all_checks(client)
|
|
||||||
# Get a listing, it will be the first one
|
# Get a listing, it will be the first one
|
||||||
res = client.get(
|
res = client.get(
|
||||||
url_for("createwatch"),
|
url_for("createwatch"),
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import time
|
|||||||
|
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
from .util import live_server_setup, wait_for_all_checks
|
from .util import live_server_setup, wait_for_all_checks
|
||||||
from ..model import CONDITIONS_MATCH_LOGIC_DEFAULT
|
|
||||||
|
|
||||||
|
|
||||||
def set_original_response(number="50"):
|
def set_original_response(number="50"):
|
||||||
test_return_data = f"""<html>
|
test_return_data = f"""<html>
|
||||||
@@ -78,7 +76,7 @@ def test_conditions_with_text_and_number(client, live_server):
|
|||||||
"fetch_backend": "html_requests",
|
"fetch_backend": "html_requests",
|
||||||
"include_filters": ".number-container",
|
"include_filters": ".number-container",
|
||||||
"title": "Number AND Text Condition Test",
|
"title": "Number AND Text Condition Test",
|
||||||
"conditions_match_logic": CONDITIONS_MATCH_LOGIC_DEFAULT, # ALL = AND logic
|
"conditions_match_logic": "ALL", # ALL = AND logic
|
||||||
"conditions-0-operator": "in",
|
"conditions-0-operator": "in",
|
||||||
"conditions-0-field": "page_filtered_text",
|
"conditions-0-field": "page_filtered_text",
|
||||||
"conditions-0-value": "5",
|
"conditions-0-value": "5",
|
||||||
@@ -285,7 +283,7 @@ def test_lev_conditions_plugin(client, live_server, measure_memory_usage):
|
|||||||
data={
|
data={
|
||||||
"url": test_url,
|
"url": test_url,
|
||||||
"fetch_backend": "html_requests",
|
"fetch_backend": "html_requests",
|
||||||
"conditions_match_logic": CONDITIONS_MATCH_LOGIC_DEFAULT, # ALL = AND logic
|
"conditions_match_logic": "ALL", # ALL = AND logic
|
||||||
"conditions-0-field": "levenshtein_ratio",
|
"conditions-0-field": "levenshtein_ratio",
|
||||||
"conditions-0-operator": "<",
|
"conditions-0-operator": "<",
|
||||||
"conditions-0-value": "0.8" # needs to be more of a diff to trigger a change
|
"conditions-0-value": "0.8" # needs to be more of a diff to trigger a change
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
from changedetectionio.conditions import execute_ruleset_against_all_plugins
|
from changedetectionio.conditions import execute_ruleset_against_all_plugins
|
||||||
from changedetectionio.model import CONDITIONS_MATCH_LOGIC_DEFAULT
|
|
||||||
from changedetectionio.store import ChangeDetectionStore
|
from changedetectionio.store import ChangeDetectionStore
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
@@ -60,7 +59,7 @@ class TestTriggerConditions(unittest.TestCase):
|
|||||||
|
|
||||||
self.store.data['watching'][self.watch_uuid].update(
|
self.store.data['watching'][self.watch_uuid].update(
|
||||||
{
|
{
|
||||||
"conditions_match_logic": CONDITIONS_MATCH_LOGIC_DEFAULT,
|
"conditions_match_logic": "ALL",
|
||||||
"conditions": [
|
"conditions": [
|
||||||
{"operator": ">=", "field": "extracted_number", "value": "10"},
|
{"operator": ">=", "field": "extracted_number", "value": "10"},
|
||||||
{"operator": "<=", "field": "extracted_number", "value": "5000"},
|
{"operator": "<=", "field": "extracted_number", "value": "5000"},
|
||||||
|
|||||||
@@ -66,9 +66,6 @@ services:
|
|||||||
# A valid timezone name to run as (for scheduling watch checking) see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
# A valid timezone name to run as (for scheduling watch checking) see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||||
# - TZ=America/Los_Angeles
|
# - TZ=America/Los_Angeles
|
||||||
#
|
#
|
||||||
# Text processing locale, en_US.UTF-8 used by default unless defined as something else here, UTF-8 should cover 99.99% of cases.
|
|
||||||
# - LC_ALL=en_US.UTF-8
|
|
||||||
#
|
|
||||||
# Maximum height of screenshots, default is 16000 px, screenshots will be clipped to this if exceeded.
|
# Maximum height of screenshots, default is 16000 px, screenshots will be clipped to this if exceeded.
|
||||||
# RAM usage will be higher if you increase this.
|
# RAM usage will be higher if you increase this.
|
||||||
# - SCREENSHOT_MAX_HEIGHT=16000
|
# - SCREENSHOT_MAX_HEIGHT=16000
|
||||||
|
|||||||
Reference in New Issue
Block a user