Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
33 check-ins
|
2026-09-21
| ||
| 05:22 |
Add a configurable dedup cache TTL via xmpp.cache_ttl_secs.
Sent-entry deduplication was hardcoded to a 24h TTL (SEEN_TTL_SECS), so an entry still present in a feed after a day would be re-posted to the MUC. Add an optional [xmpp] cache_ttl_secs key that controls how long keys are kept in the SQLite dedup cache, defaulting to 86400 so existing deployments keep the current behavior. purge_old() now takes the TTL from the config, and --verbose diagnostics render it in readable units through a new format_ttl() helper. Tests cover config parsing with and without the key, format_ttl cases, and test_purge_old now exercises purge_old() directly instead of duplicating its SQL. Document the option in README.md, config.example.toml, and AGENTS.md; AGENTS.md also gains a Repository and Tickets section describing the fossil checkout and its ticket workflow, which was previously undocumented. Version bumped 0.7.0 to 0.8.0 (new config option). Ticket da9cde75f6e23dbf95451bc45028243c11e438b2. leaf check-in: da2a3798e0 user: andrew tags: master, trunk | |
|
2026-09-13
| ||
| 01:49 | Add --version flag and an end-to-end test proving per-feed muc routing. A deployed instance was reported sending a feed with a muc override to the global room instead, but the current code was not at fault: the deployed binary predated the 0.5.0 per-feed muc feature, and serde silently ignores the unrecognized muc config key, so old binaries accept the config without any error and route every feed to the global xmpp.muc. To make stale deployed binaries identifiable, add a --version/-V flag that prints the binary version before any config or network work. To prove room routing works and keep it from regressing, add an integration test that serves an RSS document over a local HTTP socket, runs the real poll_feeds against two feeds (one with a muc override, one without), and asserts each feed's entries carry the correct room. Document the new flag in README.md and AGENTS.md, pull in tokio net/io-util as dev-dependencies for the test server, and bump version to 0.7.0 (new CLI flag). check-in: 23821db47e user: andrew tags: master, trunk | |
|
2026-09-11
| ||
| 05:53 | Send the 'Nothing new to report.' heartbeat to every configured room. The heartbeat previously always went to the global xmpp.muc, so rooms selected via per-feed muc overrides never received liveness signals between alert deliveries. Collect the distinct set of rooms from the feed configs (per-feed muc or global fallback) and send one heartbeat per room via the new distinct_rooms helper, falling back to the global room when no feeds are configured. Also document the per-feed muc override with examples in README.md and config.example.toml, and cover the new helper with unit tests. Bump version to 0.6.0. check-in: 7e6576e00b user: andrew tags: master, trunk | |
| 05:16 | Route feed alerts to different XMPP rooms via optional per-feed muc setting. Each [[feeds]] entry can now set muc to override the global xmpp.muc, so one instance can post different feeds to different MUC rooms. Alerts are grouped by room and sent over one connection per room; feeds without muc behave as before. Bump version to 0.5.0. check-in: 83ff37c646 user: andrew tags: master, trunk | |
|
2026-08-02
| ||
| 06:09 |
Detect HTML responses and repair malformed XML entities in feeds
Feed URLs that return HTML pages instead of RSS/Atom XML now produce a clear error message instead of cryptic XML parser errors. A fallback entity repair step also fixes bare ampersands and invalid entity references in feeds that have minor XML well-formedness issues. check-in: 427a4acede user: sourcehut@lewman.us tags: master, trunk | |
|
2026-07-26
| ||
| 02:33 |
Allow DTDs in XML feeds to fix NOAA feed parsing errors
roxmltree 0.21 rejects documents with <!DOCTYPE> by default, which caused NOAA NDBC feeds (and other DTD-bearing RSS feeds) to fail with "XML with DTD detected". Parse with allow_dtd: true and keep external entity resolution disabled. Extract feed parsing into parse_feed_entries for testability and add a unit test covering a DTD-bearing NOAA RSS document so this does not regress. Bump patch version to 0.4.1. check-in: 95d197adde user: sourcehut@lewman.us tags: master, trunk | |
|
2026-07-25
| ||
| 03:41 |
Detect new NOAA station observations by hashing the full message
NOAA station RSS feeds keep the same and <guid> while only the observation data in <description> changes. The previous ID-based cache key caused every observation update to be skipped as "already seen". Compute the cache key from a StableHasher hash of the formatted MUC message instead, so any change in the observation content produces a new key and gets posted.Bump version to 0.4.0. check-in: 98d761edb3 user: sourcehut@lewman.us tags: master, trunk | |
| 02:37 |
Fix duplicated text in NOAA RSS feed messages
The text extraction helper was collecting each XML text string twice — once from the element node and once from the text node itself. This caused NOAA station observation values (and cache keys) to appear duplicated in MUC output. Filter descendants to text nodes only, add regression tests, and bump version to 0.3.1. check-in: 8edc3e8ddb user: sourcehut@lewman.us tags: master, trunk | |
| 02:13 |
Add NOAA station RSS support with full observation data in MUC messages
Previously only the feed title and link were posted. The new "noaa-rss" format strips the HTML <description>, decodes entities, and sends a multi-line message with timestamp, wind, pressure, water temp, and station link. Also corrected the README cache_file default. check-in: 6e99afd760 user: sourcehut@lewman.us tags: master, trunk | |
|
2026-07-13
| ||
| 05:03 |
Fix process hang on XMPP disconnect by force-exiting after work completes
The tokio runtime hangs indefinitely during shutdown because the XMPP crate's background TCP read tasks never terminate, leaving processes stuck after disconnect. Call std::process::exit(0) at every exit path following an XMPP connection to bypass the hung runtime cleanup. check-in: 4b403663c7 user: sourcehut@lewman.us tags: master, trunk | |
|
2026-07-12
| ||
| 23:19 |
Add full non-UTF-8 feed encoding support via encoding_rs
Previously, resp.text() only handled UTF-8, causing garbled text or parse failures for feeds in legacy encodings like GB2312 (Chinese), Big5 (Taiwanese), or Shift_JIS (Japanese). Fetch raw bytes instead, detect encoding from the XML prolog or Content-Type charset header, and decode using encoding_rs with UTF-8 fallback. Bump version to 0.2.5. check-in: ca8cf4ad25 user: sourcehut@lewman.us tags: master, trunk | |
| 23:05 |
Fix panic when debug-logging messages with multi-byte UTF-8 characters
Byte-slicing at a fixed index could split a multi-byte character (e.g. curly quotes), causing a panic. Use char-boundary-safe truncation instead. Bump version to 0.2.4. check-in: 2057bd6679 user: sourcehut@lewman.us tags: master, trunk | |
| 17:23 |
Fix unsafe patterns and improve error handling
- .gitignore: add config.toml, seen_alerts.db, and seen_alerts.db.tmp to prevent committing live credentials and runtime data - Replace unwrap() on reqwest client builder with graceful error handling - Add HTTP status code check before reading feed body responses - Log body read and XML parse errors instead of silently swallowing them - Error on --config flag without a path argument instead of silently falling through to default config search - Fix RSS messages using empty link text when guid/title is the fallback ID - Bump version to 0.2.3 check-in: 121f508ca3 user: sourcehut@lewman.us tags: master, trunk | |
| 17:17 |
Bump version to 0.2.2
Document versioning policy in AGENTS.md and fix stale dedup flow description to reflect that entries are cached before sending. check-in: d39e66e759 user: sourcehut@lewman.us tags: master, trunk | |
| 17:17 |
Bump version to 0.2.1
0.2.0: SQLite dedup cache, --verbose, --cache-info flags 0.2.1: Fix duplicate posts, disconnect hang, no-alert MUC message check-in: 2fd809a402 user: sourcehut@lewman.us tags: master, trunk | |
| 17:12 |
Fix duplicate posts, hanging disconnect, and silent no-alert runs
Mark feed entries as seen in SQLite BEFORE sending to the MUC instead of after, so a failed XMPP delivery no longer causes every entry to be reposted on the next run. Add a 10-second timeout on disconnect to prevent the process from hanging indefinitely when the XMPP server doesn't respond to the shutdown handshake. Send "Nothing new to report." to the MUC when there are no new alerts, so the bot's presence is visible even on idle runs. check-in: b2d47d801f user: sourcehut@lewman.us tags: master, trunk | |
| 16:31 |
Downgrade rusqlite to 0.39 for stable Rust compatibility
rusqlite 0.40 pulls libsqlite3-sys 0.38 which uses the unstable cfg_select! macro, breaking builds on platforms with older Rust toolchains like OpenBSD. rusqlite 0.39 (libsqlite3-sys 0.37) is the latest version that works on stable Rust. check-in: 5b9eb4c57b user: sourcehut@lewman.us tags: master, trunk | |
| 16:28 |
Replace TOML dedup cache with SQLite to fix duplicate posts
The TOML cache silently reset to empty on parse failures or write errors, causing every feed entry to be reposted on each run. SQLite provides atomic transactions, efficient key lookups, and SQL-based TTL purging. Uses rusqlite with the bundled feature so SQLite is compiled from source with no system library dependency. Dedup flow: poll feeds, check each entry against the SQLite DB, send new alerts to MUC, insert keys only on successful delivery, purge entries older than 24 hours. Failed sends leave keys uninserted so they retry on the next run. Adds --verbose for per-feed dedup stats and --cache-info to dump the SQLite cache contents. Includes 4 unit tests covering dedup, multi- feed, TTL purge, and idempotency. check-in: 9ff8280e96 user: sourcehut@lewman.us tags: master, trunk | |
| 03:44 | update crates to latest releases check-in: 3ae41f9116 user: sourcehut@lewman.us tags: master, trunk | |
|
2026-07-11
| ||
| 21:49 |
Fix Atom feed dedup and improve seen-cache reliability
Atom entries were never matched because the code looked for <id> as an XML attribute instead of a child element, so every Atom entry was silently skipped. RSS dedup now prefers <guid> over <link> or , which is the element explicitly designed for this purpose. Cache keys are now namespaced by feed URL to prevent cross-feed ID collisions when two feeds share the same link URL or title.check-in: 61b5b8d30b user: sourcehut@lewman.us tags: master, trunk | |
| 20:40 |
Add per-feed custom emoji via config.toml
Each feed now supports an optional emoji field to customize the prefix shown in posted messages. Defaults to the warning emoji when not specified. check-in: 2a244bd46f user: sourcehut@lewman.us tags: master, trunk | |
| 19:35 |
Include item URL in posted feed messages
Messages now read "⚠️ Feed: Title URL" instead of just the feed name and title, for both RSS (link text) and Atom (link href attribute). check-in: 3f17ba745e user: sourcehut@lewman.us tags: master, trunk | |
| 19:06 |
Send all feed alerts in a single XMPP connection
Previously each alert opened its own XMPP connection, joined the MUC, sent one message, and disconnected. Now all alerts are collected and sent through one connection with a 500ms gap between messages. Also fixes the disconnect panic by removing the timeout wrapper that could drop the shutdown future mid-teardown. check-in: 0115effbe0 user: sourcehut@lewman.us tags: master, trunk | |
| 17:41 |
Force HTTP/1.1 to prevent panic on platforms without http2 feature
TLS ALPN negotiation could select HTTP/2, causing hyper-util to panic on platforms where reqwest's http2 feature isn't enabled. check-in: 44607352f8 user: sourcehut@lewman.us tags: master, trunk | |
| 05:06 | add the spdx license id check-in: a251a0dd31 user: sourcehut@lewman.us tags: master, trunk | |
| 05:03 | make it a legal copyright for nonsense reasons check-in: dcffce99cc user: sourcehut@lewman.us tags: master, trunk | |
| 05:02 | as moparisthebest points out, we need a license check-in: e3a363e417 user: sourcehut@lewman.us tags: master, trunk | |
|
2026-07-07
| ||
| 05:34 |
Switch dedup cache to TOML with timestamps and fix save-before-send bug
Replace the append-only plaintext cache with a TOML-serialized HashMap that records when each entry was first seen. Entries older than 24 hours are pruned on load, keeping the cache file bounded. The cache is now written only after successful XMPP delivery — failed sends remove the ID so it retries on the next run. check-in: a7e1309884 user: sourcehut@lewman.us tags: master, trunk | |
|
2026-07-05
| ||
| 17:14 | Stop ignoring config.toml check-in: 02800fa9e6 user: sourcehut@lewman.us tags: master, trunk | |
| 17:10 |
Document strict build requirements and fix stale dependency versions
Add a "Strict Build Requirements" section instructing agents to verify all changes with `RUSTFLAGS="-D warnings"` for both cargo build and clippy, treating warnings as hard errors and prohibiting #[allow(...)] suppression. Also correct outdated dependency versions (roxmltree 0.10 → 0.21, toml 0.8 → 1) and the tokio features description to match Cargo.toml. check-in: a565521e23 user: sourcehut@lewman.us tags: master, trunk | |
|
2026-07-04
| ||
| 17:48 |
Poll feeds concurrently instead of sequentially
Use tokio::task::JoinSet to fetch all feeds in parallel, so a slow feed no longer blocks the rest. Deduplication against the seen-cache is now done centrally after all tasks complete. check-in: e8d73d1088 user: sourcehut@lewman.us tags: master, trunk | |
| 05:46 |
Switch to native-tls, update dependencies, and protect config secrets
- Switch TLS from rustls/aws-lc-rs to native-tls (system OpenSSL), removing the rustls dependency and crypto provider initialization - Update reqwest 0.12→0.13, roxmltree 0.10→0.21, toml 0.8→1 - Trim tokio features from "full" to only rt-multi-thread, time, macros - Rename config.toml to config.example.toml and gitignore config.toml to prevent credential leaks - Update README.md and AGENTS.md to reflect all changes check-in: 3d8fbb6a3c user: sourcehut@lewman.us tags: master, trunk | |
| 05:31 |
Initial commit: RSS/Atom feed to XMPP MUC bot
A CLI tool that polls RSS/Atom feeds for new entries and posts them to an XMPP MUC room. Designed to run periodically via cron. Includes config template with USGS earthquake and NWS weather feeds. check-in: 68f534d32d user: sourcehut@lewman.us tags: master, trunk | |