mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2025-12-19 14:35:35 +00:00
Compare commits
11 Commits
browserste
...
mailto-err
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0df9a4b7ce | ||
|
|
ec20ab9854 | ||
|
|
3094918e11 | ||
|
|
0d92be348a | ||
|
|
3ac0c9346c | ||
|
|
b6d8db4c67 | ||
|
|
436a66d465 | ||
|
|
764514e5eb | ||
|
|
ad3ffb6ccb | ||
|
|
e051b29bf2 | ||
|
|
126852b778 |
72
.github/workflows/pypi-release.yml
vendored
Normal file
72
.github/workflows/pypi-release.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
name: Publish Python 🐍distribution 📦 to PyPI and TestPyPI
|
||||||
|
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build distribution 📦
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: "3.x"
|
||||||
|
- name: Install pypa/build
|
||||||
|
run: >-
|
||||||
|
python3 -m
|
||||||
|
pip install
|
||||||
|
build
|
||||||
|
--user
|
||||||
|
- name: Build a binary wheel and a source tarball
|
||||||
|
run: python3 -m build
|
||||||
|
- name: Store the distribution packages
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: python-package-distributions
|
||||||
|
path: dist/
|
||||||
|
|
||||||
|
|
||||||
|
test-pypi-package:
|
||||||
|
name: Test the built 📦 package works basically.
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- build
|
||||||
|
steps:
|
||||||
|
- name: Download all the dists
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: python-package-distributions
|
||||||
|
path: dist/
|
||||||
|
- name: Test that the basic pip built package runs without error
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
pip3 install dist/changedetection.io*.whl
|
||||||
|
changedetection.io -d /tmp -p 10000 &
|
||||||
|
sleep 3
|
||||||
|
curl http://127.0.0.1:10000/static/styles/pure-min.css >/dev/null
|
||||||
|
curl http://127.0.0.1:10000/ >/dev/null
|
||||||
|
killall changedetection.io
|
||||||
|
|
||||||
|
|
||||||
|
publish-to-pypi:
|
||||||
|
name: >-
|
||||||
|
Publish Python 🐍 distribution 📦 to PyPI
|
||||||
|
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
|
||||||
|
needs:
|
||||||
|
- test-pypi-package
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment:
|
||||||
|
name: release
|
||||||
|
url: https://pypi.org/p/changedetection.io
|
||||||
|
permissions:
|
||||||
|
id-token: write # IMPORTANT: mandatory for trusted publishing
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download all the dists
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: python-package-distributions
|
||||||
|
path: dist/
|
||||||
|
- name: Publish distribution 📦 to PyPI
|
||||||
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
36
.github/workflows/test-pip-build.yml
vendored
36
.github/workflows/test-pip-build.yml
vendored
@@ -1,36 +0,0 @@
|
|||||||
name: ChangeDetection.io PIP package test
|
|
||||||
|
|
||||||
# Triggers the workflow on push or pull request events
|
|
||||||
|
|
||||||
# This line doesnt work, even tho it is the documented one
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
# Changes to requirements.txt packages and Dockerfile may or may not always be compatible with arm etc, so worth testing
|
|
||||||
# @todo: some kind of path filter for requirements.txt and Dockerfile
|
|
||||||
jobs:
|
|
||||||
test-pip-build-basics:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Python 3.11
|
|
||||||
uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: 3.11
|
|
||||||
|
|
||||||
|
|
||||||
- name: Test that the basic pip built package runs without error
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
mkdir dist
|
|
||||||
pip3 install wheel
|
|
||||||
python3 setup.py bdist_wheel
|
|
||||||
pip3 install -r requirements.txt
|
|
||||||
rm ./changedetection.py
|
|
||||||
rm -rf changedetectio
|
|
||||||
|
|
||||||
pip3 install dist/changedetection.io*.whl
|
|
||||||
changedetection.io -d /tmp -p 10000 &
|
|
||||||
sleep 3
|
|
||||||
curl http://127.0.0.1:10000/static/styles/pure-min.css >/dev/null
|
|
||||||
killall -9 changedetection.io
|
|
||||||
@@ -10,6 +10,8 @@ prune changedetectionio/static/package-lock.json
|
|||||||
prune changedetectionio/static/styles/node_modules
|
prune changedetectionio/static/styles/node_modules
|
||||||
prune changedetectionio/static/styles/package-lock.json
|
prune changedetectionio/static/styles/package-lock.json
|
||||||
include changedetection.py
|
include changedetection.py
|
||||||
|
include requirements.txt
|
||||||
|
include README-pip.md
|
||||||
global-exclude *.pyc
|
global-exclude *.pyc
|
||||||
global-exclude node_modules
|
global-exclude node_modules
|
||||||
global-exclude venv
|
global-exclude venv
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ _Live your data-life pro-actively._
|
|||||||
- Nothing to install, access via browser login after signup.
|
- Nothing to install, access via browser login after signup.
|
||||||
- Super fast, no registration needed setup.
|
- Super fast, no registration needed setup.
|
||||||
- Get started watching and receiving website change notifications straight away.
|
- Get started watching and receiving website change notifications straight away.
|
||||||
|
- See our [tutorials and how-to page for more inspiration](https://changedetection.io/tutorials)
|
||||||
|
|
||||||
### Target specific parts of the webpage using the Visual Selector tool.
|
### Target specific parts of the webpage using the Visual Selector tool.
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ Please :star: star :star: this project and help it grow! https://github.com/dgtl
|
|||||||
With Docker composer, just clone this repository and..
|
With Docker composer, just clone this repository and..
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker-compose up -d
|
$ docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Docker standalone
|
Docker standalone
|
||||||
@@ -137,10 +137,10 @@ docker rm $(docker ps -a -f name=changedetection.io -q)
|
|||||||
docker run -d --restart always -p "127.0.0.1:5000:5000" -v datastore-volume:/datastore --name changedetection.io dgtlmoon/changedetection.io
|
docker run -d --restart always -p "127.0.0.1:5000:5000" -v datastore-volume:/datastore --name changedetection.io dgtlmoon/changedetection.io
|
||||||
```
|
```
|
||||||
|
|
||||||
### docker-compose
|
### docker compose
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose pull && docker-compose up -d
|
docker compose pull && docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
See the wiki for more information https://github.com/dgtlmoon/changedetection.io/wiki
|
See the wiki for more information https://github.com/dgtlmoon/changedetection.io/wiki
|
||||||
|
|||||||
21
app.json
21
app.json
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "ChangeDetection.io",
|
|
||||||
"description": "The best and simplest self-hosted open source website change detection monitoring and notification service.",
|
|
||||||
"keywords": [
|
|
||||||
"changedetection",
|
|
||||||
"website monitoring"
|
|
||||||
],
|
|
||||||
"repository": "https://github.com/dgtlmoon/changedetection.io",
|
|
||||||
"success_url": "/",
|
|
||||||
"scripts": {
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
},
|
|
||||||
"formation": {
|
|
||||||
"web": {
|
|
||||||
"quantity": 1,
|
|
||||||
"size": "free"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"image": "heroku/python"
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Read more https://github.com/dgtlmoon/changedetection.io/wiki
|
# Read more https://github.com/dgtlmoon/changedetection.io/wiki
|
||||||
|
|
||||||
__version__ = '0.45.9'
|
__version__ = '0.45.11'
|
||||||
|
|
||||||
from distutils.util import strtobool
|
from distutils.util import strtobool
|
||||||
from json.decoder import JSONDecodeError
|
from json.decoder import JSONDecodeError
|
||||||
|
|||||||
@@ -1592,6 +1592,15 @@ def notification_runner():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from changedetectionio import notification
|
from changedetectionio import notification
|
||||||
|
# Fallback to system config if not set
|
||||||
|
if not n_object.get('notification_body') and datastore.data['settings']['application'].get('notification_body'):
|
||||||
|
n_object['notification_body'] = datastore.data['settings']['application'].get('notification_body')
|
||||||
|
|
||||||
|
if not n_object.get('notification_title') and datastore.data['settings']['application'].get('notification_title'):
|
||||||
|
n_object['notification_title'] = datastore.data['settings']['application'].get('notification_title')
|
||||||
|
|
||||||
|
if not n_object.get('notification_format') and datastore.data['settings']['application'].get('notification_format'):
|
||||||
|
n_object['notification_title'] = datastore.data['settings']['application'].get('notification_format')
|
||||||
|
|
||||||
sent_obj = notification.process_notification(n_object, datastore)
|
sent_obj = notification.process_notification(n_object, datastore)
|
||||||
|
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ def process_notification(n_object, datastore):
|
|||||||
|
|
||||||
# Get the notification body from datastore
|
# Get the notification body from datastore
|
||||||
jinja2_env = Environment(loader=BaseLoader)
|
jinja2_env = Environment(loader=BaseLoader)
|
||||||
n_body = jinja2_env.from_string(n_object.get('notification_body', default_notification_body)).render(**notification_parameters)
|
n_body = jinja2_env.from_string(n_object.get('notification_body', '')).render(**notification_parameters)
|
||||||
n_title = jinja2_env.from_string(n_object.get('notification_title', default_notification_title)).render(**notification_parameters)
|
n_title = jinja2_env.from_string(n_object.get('notification_title', '')).render(**notification_parameters)
|
||||||
n_format = valid_notification_formats.get(
|
n_format = valid_notification_formats.get(
|
||||||
n_object.get('notification_format', default_notification_format),
|
n_object.get('notification_format', default_notification_format),
|
||||||
valid_notification_formats[default_notification_format],
|
valid_notification_formats[default_notification_format],
|
||||||
@@ -187,8 +187,8 @@ def process_notification(n_object, datastore):
|
|||||||
if not 'format=' in url and (n_format == 'Text' or n_format == 'Markdown'):
|
if not 'format=' in url and (n_format == 'Text' or n_format == 'Markdown'):
|
||||||
prefix = '?' if not '?' in url else '&'
|
prefix = '?' if not '?' in url else '&'
|
||||||
# Apprise format is lowercase text https://github.com/caronc/apprise/issues/633
|
# Apprise format is lowercase text https://github.com/caronc/apprise/issues/633
|
||||||
n_format = n_format.tolower()
|
n_format = n_format.lower()
|
||||||
url = "{}{}format={}".format(url, prefix, n_format)
|
url = f"{url}{prefix}format={n_format}"
|
||||||
# If n_format == HTML, then apprise email should default to text/html and we should be sending HTML only
|
# If n_format == HTML, then apprise email should default to text/html and we should be sending HTML only
|
||||||
|
|
||||||
apobj.add(url)
|
apobj.add(url)
|
||||||
|
|||||||
@@ -188,9 +188,9 @@ class update_worker(threading.Thread):
|
|||||||
return
|
return
|
||||||
threshold = self.datastore.data['settings']['application'].get('filter_failure_notification_threshold_attempts')
|
threshold = self.datastore.data['settings']['application'].get('filter_failure_notification_threshold_attempts')
|
||||||
n_object = {'notification_title': "Changedetection.io - Alert - Browser step at position {} could not be run".format(step_n+1),
|
n_object = {'notification_title': "Changedetection.io - Alert - Browser step at position {} could not be run".format(step_n+1),
|
||||||
'notification_body': "Your configured browser step at position {} for {{watch['url']}} "
|
'notification_body': "Your configured browser step at position {} for {{{{watch_url}}}} "
|
||||||
"did not appear on the page after {} attempts, did the page change layout? "
|
"did not appear on the page after {} attempts, did the page change layout? "
|
||||||
"Does it need a delay added?\n\nLink: {{base_url}}/edit/{{watch_uuid}}\n\n"
|
"Does it need a delay added?\n\nLink: {{{{base_url}}}}/edit/{{{{watch_uuid}}}}\n\n"
|
||||||
"Thanks - Your omniscient changedetection.io installation :)\n".format(step_n+1, threshold),
|
"Thanks - Your omniscient changedetection.io installation :)\n".format(step_n+1, threshold),
|
||||||
'notification_format': 'text'}
|
'notification_format': 'text'}
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
run:
|
|
||||||
changedetection: python3 ./changedetection.py -C -d ./datastore -p $PORT
|
|
||||||
4
setup.py
4
setup.py
@@ -27,7 +27,7 @@ install_requires = open('requirements.txt').readlines()
|
|||||||
setup(
|
setup(
|
||||||
name='changedetection.io',
|
name='changedetection.io',
|
||||||
version=find_version("changedetectionio", "__init__.py"),
|
version=find_version("changedetectionio", "__init__.py"),
|
||||||
description='Website change detection and monitoring service',
|
description='Website change detection and monitoring service, detect changes to web pages and send alerts/notifications.',
|
||||||
long_description=open('README-pip.md').read(),
|
long_description=open('README-pip.md').read(),
|
||||||
long_description_content_type='text/markdown',
|
long_description_content_type='text/markdown',
|
||||||
keywords='website change monitor for changes notification change detection '
|
keywords='website change monitor for changes notification change detection '
|
||||||
@@ -41,7 +41,7 @@ setup(
|
|||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
install_requires=install_requires,
|
install_requires=install_requires,
|
||||||
license="Apache License 2.0",
|
license="Apache License 2.0",
|
||||||
python_requires=">= 3.7",
|
python_requires=">= 3.10",
|
||||||
classifiers=['Intended Audience :: Customer Service',
|
classifiers=['Intended Audience :: Customer Service',
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
'Intended Audience :: Education',
|
'Intended Audience :: Education',
|
||||||
|
|||||||
Reference in New Issue
Block a user