diff --git a/backend.php b/backend.php index ef6caf0b..9c0b5c8b 100644 --- a/backend.php +++ b/backend.php @@ -475,7 +475,13 @@ } } } - + + print " + + +
+ Add feed
"; + $result = pg_query("SELECT id,title,feed_url,substring(last_updated,1,16) as last_updated FROM @@ -578,5 +584,164 @@ } + if ($op == "pref-filters") { + + $subop = $_GET["subop"]; + + if ($subop == "editSave") { +/* $feed_title = pg_escape_string($_GET["t"]); + $feed_link = pg_escape_string($_GET["l"]); + $feed_id = $_GET["id"]; + + $result = pg_query("UPDATE ttrss_feeds SET + title = '$feed_title', feed_url = '$feed_link' WHERE id = '$feed_id'"); */ + + } + + if ($subop == "remove") { + + if (!WEB_DEMO_MODE) { + + $ids = split(",", $_GET["ids"]); + + foreach ($ids as $id) { + pg_query("DELETE FROM ttrss_filters WHERE id = '$id'"); + + } + } + } + + if ($subop == "add") { + +/* if (!WEB_DEMO_MODE) { + + $feed_link = pg_escape_string($_GET["link"]); + + $result = pg_query( + "INSERT INTO ttrss_feeds (feed_url,title) VALUES ('$feed_link', '')"); + + $result = pg_query( + "SELECT id FROM ttrss_feeds WHERE feed_url = '$feed_link'"); + + $feed_id = pg_fetch_result($result, 0, "id"); + + if ($feed_id) { + update_rss_feed($link, $feed_link, $feed_id); + } + } */ + } + + $result = pg_query("SELECT description + FROM ttrss_filter_types ORDER BY description"); + + $filter_types = array(); + + while ($line = pg_fetch_assoc($result)) { + array_push($filter_types, $line["description"]); + } + + print " + + +
Expr: "; + print_select("fadd_match", "", $filter_types); + + print" + Add filter
"; + + $result = pg_query("SELECT + id,regexp,description, + (SELECT name FROM ttrss_filter_types WHERE + id = filter_type) as filter_type_name, + (SELECT description FROM ttrss_filter_types + WHERE id = filter_type) as filter_type_descr + FROM + ttrss_filters ORDER by id"); + + print "

"; + + print " + + "; + + $lnum = 0; + + while ($line = pg_fetch_assoc($result)) { + + $class = ($lnum % 2) ? "even" : "odd"; + + $filter_id = $line["id"]; + $edit_filter_id = $_GET["id"]; + + if ($subop == "edit" && $filter_id != $edit_filter_id) { + $class .= "Grayed"; + } + + print ""; + + if (!$edit_filter_id || $subop != "edit") { + + print ""; + + print ""; + + print ""; + + print ""; + + } else if ($filter_id != $edit_filter_id) { + + print ""; + + print ""; + print ""; + print ""; + + } else { + + print ""; + + print ""; + + print ""; + + print ""; + + } + + + print ""; + + ++$lnum; + } + + print "
SelectFilter ExpressionDescriptionMatch
" . + $line["regexp"] . "" . + $line["description"] . "".$line["filter_type_descr"]."".$line["regexp"]."".$line["description"]."".$line["filter_type_descr"].""; + print_select("iedit_match", $line["filter_type_descr"], $filter_types); + print "
"; + + print "

"; + + if ($subop == "edit") { + print "Edit feed:  + Cancel  + Save"; + + } else { + + print " + Selection:  + Edit  + Remove "; + } + } + pg_close($link); ?> diff --git a/functions.php b/functions.php index 9df33518..1337b30f 100644 --- a/functions.php +++ b/functions.php @@ -277,5 +277,17 @@ } + function print_select($id, $default, $values) { + print ""; + } ?> diff --git a/prefs.js b/prefs.js index e9a0e49d..a498bb2e 100644 --- a/prefs.js +++ b/prefs.js @@ -6,6 +6,8 @@ var xmlhttp = false; var active_feed = false; +var active_filter = false; +var active_pane = false; /*@cc_on @*/ /*@if (@_jscript_version >= 5) @@ -26,9 +28,8 @@ if (!xmlhttp && typeof XMLHttpRequest!='undefined') { xmlhttp = new XMLHttpRequest(); } - function feedlist_callback() { - var container = document.getElementById('feeds'); + var container = document.getElementById('feedConfPane'); if (xmlhttp.readyState == 4) { container.innerHTML=xmlhttp.responseText; @@ -47,6 +48,27 @@ function feedlist_callback() { } } +function filterlist_callback() { + var container = document.getElementById('filterConfPane'); + if (xmlhttp.readyState == 4) { + container.innerHTML=xmlhttp.responseText; + + if (active_filter) { + var row = document.getElementById("FILRR-" + active_filter); + if (row) { + if (!row.className.match("Selected")) { + row.className = row.className + "Selected"; + } + } + var checkbox = document.getElementById("FICHK-" + active_filter); + + if (checkbox) { + checkbox.checked = true; + } + } + } +} + function notify_callback() { var container = document.getElementById('notify'); if (xmlhttp.readyState == 4) { @@ -62,7 +84,7 @@ function updateFeedList() { return } - document.getElementById("feeds").innerHTML = "Loading feeds, please wait..."; + document.getElementById("feedConfPane").innerHTML = "Loading feeds, please wait..."; xmlhttp.open("GET", "backend.php?op=pref-feeds", true); xmlhttp.onreadystatechange=feedlist_callback; @@ -109,6 +131,22 @@ function addFeed() { } +function editFilter(id) { + + if (!xmlhttp_ready(xmlhttp)) { + printLockingError(); + return + } + + active_filter = id; + + xmlhttp.open("GET", "backend.php?op=pref-filters&subop=edit&id=" + + param_escape(id), true); + xmlhttp.onreadystatechange=filterlist_callback; + xmlhttp.send(null); + +} + function editFeed(feed) { // notify("Editing feed..."); @@ -127,6 +165,22 @@ function editFeed(feed) { } +function getSelectedFilters() { + + var content = document.getElementById("prefFilterList"); + + var sel_rows = new Array(); + + for (i = 0; i < content.rows.length; i++) { + if (content.rows[i].className.match("Selected")) { + var row_id = content.rows[i].id.replace("FILRR-", ""); + sel_rows.push(row_id); + } + } + + return sel_rows; +} + function getSelectedFeeds() { var content = document.getElementById("prefFeedList"); @@ -269,6 +323,96 @@ function feedEditSave() { } +function filterEditCancel() { + + if (!xmlhttp_ready(xmlhttp)) { + printLockingError(); + return + } + + active_filter = false; + + notify("Operation cancelled."); + + xmlhttp.open("GET", "backend.php?op=pref-filters", true); + xmlhttp.onreadystatechange=filterlist_callback; + xmlhttp.send(null); + +} + +function filterEditSave() { + + var filter = active_filter; + + if (!xmlhttp_ready(xmlhttp)) { + printLockingError(); + return + } + + var regexp = document.getElementById("iedit_regexp").value; + var descr = document.getElementById("iedit_descr").value; + var match = document.getElementById("iedit_match").value; + +// notify("Saving filter " + filter + ": " + regexp + ", " + descr + ", " + match); + + if (regexp.length == 0) { + notify("Filter expression cannot be blank."); + return; + } + + active_filter = false; + + xmlhttp.open("GET", "backend.php?op=pref-filters&subop=editSave&id=" + + filter + "&r=" + param_escape(regexp) + "&d=" + param_escape(descr) + + "&m=" + param_escape(match), true); + + xmlhttp.onreadystatechange=filterlist_callback; + xmlhttp.send(null); + +} + +function removeSelectedFilters() { + + if (!xmlhttp_ready(xmlhttp)) { + printLockingError(); + return + } + + var sel_rows = getSelectedFilters(); + + if (sel_rows.length > 0) { + + notify("Removing selected filters..."); + + xmlhttp.open("GET", "backend.php?op=pref-filters&subop=remove&ids="+ + param_escape(sel_rows.toString()), true); + xmlhttp.onreadystatechange=filterlist_callback; + xmlhttp.send(null); + + } else { + notify("Please select some filters first."); + } +} + + +function editSelectedFilter() { + var rows = getSelectedFilters(); + + if (rows.length == 0) { + notify("No filters are selected."); + return; + } + + if (rows.length > 1) { + notify("Please select one filter."); + return; + } + + editFilter(rows[0]); + +} + + function editSelectedFeed() { var rows = getSelectedFeeds(); @@ -309,6 +453,42 @@ function validateOpmlImport() { } } +function updateFilterList() { + + if (!xmlhttp_ready(xmlhttp)) { + printLockingError(); + return + } + + document.getElementById("filterConfPane").innerHTML = "Loading filters, please wait..."; + + xmlhttp.open("GET", "backend.php?op=pref-filters", true); + xmlhttp.onreadystatechange=filterlist_callback; + xmlhttp.send(null); + +} + +function expandPane(id) { + + var container; + +/* if (active_pane) { + container = document.getElementById(active_pane); + container.innerHTML = "Click to expand..."; + } */ + + container = document.getElementById(id); + + if (id == "feedConfPane") { + updateFeedList(); + } else if (id == "filterConfPane") { + updateFilterList(); + } + + active_pane = id; +} + function init() { // IE kludge @@ -320,7 +500,7 @@ function init() { return; } - updateFeedList(); +// updateFeedList(); document.onkeydown = hotkey_handler; notify(""); diff --git a/prefs.php b/prefs.php index 1d47d539..5a3afb1f 100644 --- a/prefs.php +++ b/prefs.php @@ -28,28 +28,32 @@ +

Feed Configuration

-
 
+
+ Click to expand >> +
- - - -
- Add feed
- -
 
- -
- -

Import OPML

+

OPML Import

+
+
File:  
+ +
+ +

Content filtering

+ +
+ Click to expand >> +
+ diff --git a/tt-rss.css b/tt-rss.css index a714ca5c..3ecb8970 100644 --- a/tt-rss.css +++ b/tt-rss.css @@ -240,7 +240,7 @@ table.prefAddFeed { } -table.prefFeedList tr.title td { +table.prefFeedList tr.title td, table.prefFilterList tr.title td { font-weight : bold; border-width : 0px 0px 1px 0px; border-color : #f0f0f0; @@ -377,9 +377,13 @@ img.feedIcon { border : 1px solid #c0c0c0; } -#iedit_title, #iedit_link { +#iedit_title, #iedit_link, #iedit_regexp, #iedit_descr { width : 100%; padding-left : 2px; } +div.expPane { + margin : 15px; +} + diff --git a/ttrss_schema.sql b/ttrss_schema.sql index 364087f1..79a58677 100644 --- a/ttrss_schema.sql +++ b/ttrss_schema.sql @@ -41,4 +41,21 @@ create table ttrss_entries (id serial not null primary key, no_orig_date boolean not null default false, comments varchar(250) not null default '', unread boolean not null default true); - + +drop table ttrss_filters; +drop table ttrss_filter_types; + +create table ttrss_filter_types (id integer primary key, + name varchar(120) unique not null, + description varchar(250) not null unique); + +insert into ttrss_filter_types (id,name,description) values (1, 'title', 'Title'); +insert into ttrss_filter_types (id,name,description) values (2, 'content', 'Content'); +insert into ttrss_filter_types (id,name,description) values (3, 'both', + 'Title and Content'); + +create table ttrss_filters (id serial primary key, + filter_type integer not null references ttrss_filter_types(id), + regexp varchar(250) not null, + description varchar(250) not null default ''); +