Browse Source

Add searching to TTRSS handler

microsub
J. King 5 years ago
parent
commit
3b8461b1ca
  1. 6
      CHANGELOG
  2. 8
      README.md
  3. 13
      lib/REST/TinyTinyRSS/API.php
  4. 5
      tests/cases/REST/TinyTinyRSS/TestAPI.php

6
CHANGELOG

@ -1,3 +1,9 @@
Version 0.7.0 (2019-??-??)
==========================
New features:
- Support for basic freeform searching in Tiny Tiny RSS
Version 0.6.1 (2019-01-23)
==========================

8
README.md

@ -130,7 +130,6 @@ We are not aware of any other extensions to the TTRSS protocol. If you know of a
- The `getPref` operation is not implemented; it returns `UNKNOWN_METHOD`
- The `shareToPublished` operation is not implemented; it returns `UNKNOWN_METHOD`
- Setting an article's "published" flag with the `updateArticle` operation is not implemented and will gracefully fail
- The `search` parameter of the `getHeadlines` operation is not implemented; the operation will proceed as if no search string were specified
- The `sanitize`, `force_update`, and `has_sandbox` parameters of the `getHeadlines` operation are ignored
- String `feed_id` values for the `getCompactHeadlines` operation are not supported and will yield an `INCORRECT_USAGE` error
- Articles are limited to a single attachment rather than multiple attachments
@ -141,6 +140,13 @@ We are not aware of any other extensions to the TTRSS protocol. If you know of a
- Feed, category, and label names are normally unrestricted; The Arsse rejects empty strings, as well as strings composed solely of whitespace
- Discovering multiple feeds during `subscribeToFeed` processing normally produces an error; The Arsse instead chooses the first feed it finds
- Providing the `setArticleLabel` operation with an invalid label normally silently fails; The Arsse returns an `INVALID_USAGE` error instead
- Processing of the `search` parameter of the `getHeadlines` operation differs in the following ways:
- Values other than `"true"` or `"false"` for the `unread`, `star`, and `pub` special keywords treat the entire token as a search term rather than as `"false"`
- Limits are placed on the number of search terms: ten each for `title`, `author`, and `note`, and twenty for content searching; exceeding the limits will yield a non-standard `TOO_MANY_SEARCH_TERMS` error
- Invalid dates are ignored rather than assumed to be `"1970-01-01"`
- Only a single negative date is allowed (this is a known bug rather than intentional)
- Dates are always relative to UTC
- Full-text search is not yet employed with any database, including PostgreSQL
- Article hashes are normally SHA1; The Arsse uses SHA256 hashes
- Article attachments normally have unique IDs; The Arsse always gives attachments an ID of `"0"`
- The default sort order of the `getHeadlines` operation normally uses custom sorting for "special" feeds; The Arsse's default sort order is equivalent to `feed_dates` for all feeds

13
lib/REST/TinyTinyRSS/API.php

@ -49,7 +49,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
'sid' => ValueInfo::T_STRING, // session ID
'seq' => ValueInfo::T_INT, // request number from client
'user' => ValueInfo::T_STRING | ValueInfo::M_STRICT, // user name for `login`
'password' => ValueInfo::T_STRING | ValueInfo::M_STRICT, // password for `login` and `subscribeToFeed`
'password' => ValueInfo::T_STRING | ValueInfo::M_STRICT, // password for `login` or remote password for `subscribeToFeed`
'include_empty' => ValueInfo::T_BOOL | ValueInfo::M_DROP, // whether to include empty items in `getFeedTree` and `getCategories`
'unread_only' => ValueInfo::T_BOOL | ValueInfo::M_DROP, // whether to exclude items without unread articles in `getCategories` and `getFeeds`
'enable_nested' => ValueInfo::T_BOOL | ValueInfo::M_DROP, // whether to NOT show subcategories in `getCategories
@ -76,7 +76,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
'since_id' => ValueInfo::T_INT, // cut-off article ID for `getHeadlines` and `getCompactHeadlines; returns only higher article IDs when specified
'order_by' => ValueInfo::T_STRING, // sort order for `getHeadlines`
'include_header' => ValueInfo::T_BOOL | ValueInfo::M_DROP, // whether to attach a header to the results of `getHeadlines`
'search' => ValueInfo::T_STRING, // search string for `getHeadlines` (not yet implemented)
'search' => ValueInfo::T_STRING, // search string for `getHeadlines`
'field' => ValueInfo::T_INT, // which state to change in `updateArticle`
'mode' => ValueInfo::T_INT, // whether to set, clear, or toggle the selected state in `updateArticle`
'data' => ValueInfo::T_STRING, // note text in `updateArticle` if setting a note
@ -1478,7 +1478,14 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
default:
throw new \JKingWeb\Arsse\Exception("constantUnknown", $viewMode); // @codeCoverageIgnore
}
// TODO: implement searching
// handle the search string, if any
if (isset($data['search'])) {
$c = Search::parse($data['search'], $c);
if (!$c) {
// the search string inherently returns an empty result, either directly or interacting with other input
return new ResultEmpty;
}
}
// handle sorting
switch ($data['order_by']) {
case "date_reverse":

5
tests/cases/REST/TinyTinyRSS/TestAPI.php

@ -1809,6 +1809,8 @@ LONG_STRING;
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'view_mode' => "published"],
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -6, 'view_mode' => "unread"],
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112],
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'view_mode' => "unread", 'search' => "unread:false"],
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'search' => "pub:true"],
];
$in2 = [
// simple context tests
@ -1833,6 +1835,7 @@ LONG_STRING;
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'is_cat' => true, 'include_nested' => true],
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'order_by' => "feed_dates"],
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'order_by' => "date_reverse"],
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'search' => "interesting"],
];
$in3 = [
// time-based context tests
@ -1868,6 +1871,7 @@ LONG_STRING;
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folderShallow(42), $this->anything())->thenReturn($this->generateHeadlines(14));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->folder(42), $this->anything())->thenReturn($this->generateHeadlines(15));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->reverse(false), $this->anything())->thenReturn($this->generateHeadlines(16));
Phake::when(Arsse::$db)->articleList($this->anything(), (clone $c)->subscription(42)->searchTerms(["interesting"]), $this->anything())->thenReturn($this->generateHeadlines(17));
$out2 = [
$this->respErr("INCORRECT_USAGE"),
$this->outputHeadlines(11),
@ -1890,6 +1894,7 @@ LONG_STRING;
$this->outputHeadlines(15),
$this->outputHeadlines(11), // defaulting sorting is not fully implemented
$this->outputHeadlines(16),
$this->outputHeadlines(17),
];
$out3 = [
$this->outputHeadlines(1001),

Loading…
Cancel
Save