A Liferea RSS/Atom feed reader plugin that hides articles matching configurable filter patterns. Supports both global filters and per-feed filters with real-time and periodic scanning.
- Liferea 1.15.x (GTK3 /
Liferea-3.0GIR) - Python 3.x with GObject Introspection
- Global patterns — apply to every feed
- Feed-specific patterns — scoped to named feeds via
[Feed Name]sections - Case-insensitive regex matching — regex patterns are matched against article titles
- Real-time filtering — new articles are filtered immediately via
row-insertedsignal - Periodic re-scan — catches late-arriving items every 2 seconds
- Automatic feed tracking — detects feed selection changes to apply correct patterns
- Clean deactivation — all signals and timeouts are disconnected on plugin disable
cp src/filter.plugin $HOME/.local/share/liferea/plugins/
cp src/liferea-plugin-filter.py $HOME/.local/share/liferea/plugins/
lifereaThen enable the plugin in Liferea: Edit → Plugins → Liferea Filter Articles.
Create the configuration directory and file:
mkdir -p ~/.config/liferea-plugin-filter
touch ~/.config/liferea-plugin-filter/patterns.txtConfiguration can be hot reloaded in Liferea by disable / enable plugin.
# Lines starting with # are comments
# Empty lines are skipped
# --- Global patterns (apply to all feeds) ---
breaking news
press release
# --- Feed-specific patterns ---
[The Example]
jesusphone review
[The Second]
kernel patch- Patterns are regex substrings
- Matching is case-insensitive
- Feed names must match exactly as they appear in Liferea's feed list (Pango markup is stripped automatically)
Plugin output appears in the terminal when Liferea is started from the command line. Each message is prefixed with an ISO 8601 timestamp:
[2025-01-15T10:23:45.123456+00:00] liferea-plugin-filter: Plugin activated
[2025-01-15T10:23:45.123456+00:00] Global regex patterns (2): ['breaking news', 'press release']
[2025-01-15T10:23:45.123456+00:00] Feed-specific regex for "The Example" (1): ['jesusphone review']
[2025-01-15T10:23:45.123456+00:00] Connected to feed selection changes, current feed: "The Example"
[2025-01-15T10:23:45.123456+00:00] Filter active - scanning every 2000ms
[2025-01-15T10:23:47.123456+00:00] REMOVED: JesusPhone X review: ...
[2025-01-15T10:23:49.123456+00:00] REMOVED (live): breaking news: ...
| Component | Role |
|---|---|
do_activate() -> None |
Entry point — loads patterns, schedules on_ui_ready() via GLib.idle_add |
do_deactivate() -> None |
Cleans up: removes timeout source, disconnects model and feed-list signals |
_on_ui_ready() -> bool |
Finds the itemlist TreeView, sets up model signals, connects feed selection tracker, runs initial filter, starts periodic scan |
_find_itemlist_treeview() -> Gtk.TreeView | None |
Traverses widget hierarchy (normalViewItems / wideViewItems) to locate the article TreeView |
_setup_model(model: Gtk.TreeModel) -> None |
Connects row-inserted signal on the current model; disconnects old model if it changed |
_on_feed_selection_changed(selection: Gtk.TreeSelection) -> None |
Callback on feed selection change — updates current_feed_name so correct patterns apply |
_on_row_inserted(model: Gtk.TreeModel, path: Gtk.TreePath, iterator: Gtk.TreeIter) -> None |
Real-time callback — immediately removes newly inserted rows that match filters |
_periodic_scan() -> bool |
Runs every 2 s — detects model changes (feed switches) and re-filters to catch late arrivals |
_load_filter_patterns() -> tuple[list[re.Pattern], dict[str, list[re.Pattern]]] |
Reads patterns.txt, compiles regex patterns, returns global + feed-specific lists |
_get_active_patterns() -> list[re.Pattern] |
Combines global patterns with feed-specific patterns for the currently selected feed |
_filter_items(model: Gtk.TreeModel) -> int |
Two-pass scan: collects matching iterators, then removes them from the model |
_item_matches_filter(model: Gtk.TreeModel, iterator: Gtk.TreeIter) -> tuple[bool, str] |
Checks an article title (column 2) against all active patterns; returns (matched, title) |
_get_selected_feed_name() -> str | None |
Reads the selected feed from the feedlist TreeView, strips Pango markup |
_log(msg: str) -> None |
Logs the message to stdout |
_to_str(val: Any) -> str |
Safely converts a model column value to a string, guarding against None and GObject repr noise |