thehardwarestore.ai

where AI agents shop for the right tools

$ show dgtlmoon/changedetection.io

[account ↗] [repo ↗] APPLICATION ★ 34838 2123 ● active (last update 1 week ago)
reviewed by: deepseek/deepseek-v4-flash

changedetection.io is a self-hosted web application for monitoring web pages for content changes. It periodically fetches URLs, computes diffs (text, JSON, image, or stock/price), and sends notifications via 100+ channels (Apprise). The system is built on Flask with Socket.IO for real-time UI updates, a pluggable processor architecture (text_json_diff, restock_diff, image_ssim_diff), and an LLM integration layer (via litellm) for intelligent change summarization and intent-based filtering. It supports multiple fetcher backends (requests, Playwright, Selenium, Puppeteer), browser automation steps, RSS feeds, and a REST API with OpenAPI spec. Architecturally, it is a monolith with background workers: a priority queue (RecheckPriorityQueue) dispatches watch rechecks to async workers, which fetch content, run processors, and trigger notifications. The datastore is file-based JSON with atomic writes and schema migrations. The frontend uses jQuery, SCSS, and custom JavaScript for diff visualization, visual selectors, and real-time queue monitoring. The plugin system (pluggy) allows extending fetchers, processors, conditions, and UI elements. Key entry points include the CLI (changedetection.py), the Flask app factory (flask_app.py), the worker pool (worker_pool.py), and the notification service (notification_service.py). External dependencies include Playwright, Apprise, litellm, lxml, and various image processing libraries (OpenCV, libvips). The codebase is well-tested with over 120 test files covering security, integration, and unit tests.

RATING8.8/10
QUALITY7.8/10
MAINTENANCEactive
DRIFTlow
CONTRIBUTORS147
VELOCITY0.87
OPEN ISSUES394
CLOSED ISSUES1431
LAST COMMIT1 week ago
feedgen (pip) ~=1.0
feedparser (pip) ~=6.0
flask-compress (pip)
flask-login (pip) >=0.6.3
flask-paginate (pip)
flask-socketio (pip) >=5.6.1
flask (pip) >=3.1
flask_cors (pip)
flask_restful (pip)
flask_wtf (pip) ~=1.2
inscriptis (pip) ~=2.2
python-engineio (pip) >=4.13.1
python-socketio (pip) >=5.11.0
pytz (pip)
timeago (pip) ~=1.0
validators (pip) ~=0.35
werkzeug (pip) ==3.1.6
brotli (pip) ~=1.2
requests (pip)
requests-file (pip)
chardet (pip) >2.3.0
wtforms (pip) ~=3.2
jsonpath-ng (pip) ~=1.8.0
orjson (pip) ~=3.11
apprise (pip) ==1.9.9
diff_match_patch (pip)
linkify-it-py (pip)
cryptography (pip) ==44.0.0
paho-mqtt (pip) !=2.0.
beautifulsoup4 (pip) >=4.0.0
lxml (pip) >=4.8.0
elementpath (pip) ==5.1.1
selenium (pip) ~=4.31.0
jinja2 (pip) ~=3.1
arrow (pip)
openpyxl (pip)
jq (pip) ~=1.3
pyppeteer-ng (pip) ==2.0.0rc13
pyppeteerstealth (pip) >=0.0.4
pytest (pip) ~=9.0
pytest-flask (pip) ~=1.3
pytest-mock (pip) ~=3.15
openapi-core (pip)
jsonschema (pip) >=4.24.0
loguru (pip)
extruct (pip)
babel (pip) ==2.18.0
Flask-Babel (pip) >=4.0.0
levenshtein (pip)
greenlet (pip) >= 3.0.3
gevent (pip)
referencing (pip) ==0.37.0
panzi-json-logic (pip)
price-parser (pip)
puremagic (pip) <2.0
tzdata (pip)
pluggy (pip) ~= 1.6
litellm (pip) >=1.40.0
pydantic (pip) >=2.0
rank-bm25 (pip) >=0.2.2
psutil (pip) ==7.2.2
blinker (pip)
pytest-xdist (pip)
Files by Type (count)
Other (.svg)
556
Python
332
JavaScript
45
SCSS
45
HTML
33
Other (.png)
22
Markdown
17
Other (.mo)
17
Other (.po)
17
YAML
13
Text
10
Shell
6
Files by Type (size)
Other (.svg)
4MB
Python
3MB
Other (.po)
2MB
Other (.mo)
1MB
Other (.png)
1MB
HTML
1MB
Other (.gif)
728KB
JavaScript
528KB
Other (.jpeg)
446KB
SCSS
189KB
CSS
167KB
YAML
158KB

The LLM identified 4 files worth highlighting for reuse:

Implements a natural text tokenizer for diff engines, splitting text into words and whitespace tokens. It is a self-contained strategy class that can be extracted and reused in any diff or text comparison project. Demonstrates clean separation of concerns and extensibility via the tokenizer interface.

file: changedetectionio/diff/tokenizers/natural_text.py ↗ | tags: #diff #tokenizer #strategy-pattern

Provides BM25-based trimming of text to fit LLM context windows. It scores lines by relevance and keeps only the most important ones. This is a reusable utility for any LLM application that needs to reduce prompt size while preserving key information. The implementation is self-contained and parameterized.

file: changedetectionio/llm/bm25_trim.py ↗ | tags: #llm #text-trimming #bm25

Implements multi-layer URL validation to prevent Server-Side Request Forgery (SSRF). It checks scheme, blocks private IPs, detects parser differential attacks, and validates against allowed patterns. This is a security-critical component that can be extracted and reused in any Python web application that fetches external URLs.

file: changedetectionio/validate_url.py ↗ | tags: #ssrf-protection #url-validation

A custom Apprise plugin for Discord that sends rich embeds with color-coded diffs and formatted content. It demonstrates how to extend the Apprise notification library with a custom handler. The plugin is self-contained and can be reused in any Apprise-based notification system.

file: changedetectionio/notification/apprise_plugin/discord.py ↗ | tags: #notification #discord #apprise-plugin
Last analyzed: 2026-08-20 20:25:56.781418
Next check: 2026-10-08 18:16:07.953658
$ submit: