diff options
Diffstat (limited to 'p/api')
| -rw-r--r-- | p/api/fever.php | 43 | ||||
| -rw-r--r-- | p/api/greader.php | 172 |
2 files changed, 186 insertions, 29 deletions
diff --git a/p/api/fever.php b/p/api/fever.php index 55baa6d16..dd54a372b 100644 --- a/p/api/fever.php +++ b/p/api/fever.php @@ -3,6 +3,7 @@ * Fever API for FreshRSS * Version 0.1 * Author: Kevin Papst / https://github.com/kevinpapst + * Documentation: https://feedafever.com/api * * Inspired by: * TinyTinyRSS Fever API plugin @dasmurphy @@ -29,6 +30,36 @@ register_shutdown_function('session_destroy'); Minz_Session::init('FreshRSS'); // ================================================================================================ +// <Debug> +$ORIGINAL_INPUT = file_get_contents('php://input', false, null, 0, 1048576); + +function debugInfo() { + if (function_exists('getallheaders')) { + $ALL_HEADERS = getallheaders(); + } else { //nginx http://php.net/getallheaders#84262 + $ALL_HEADERS = array(); + foreach ($_SERVER as $name => $value) { + if (substr($name, 0, 5) === 'HTTP_') { + $ALL_HEADERS[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; + } + } + } + global $ORIGINAL_INPUT; + return print_r( + array( + 'date' => date('c'), + 'headers' => $ALL_HEADERS, + '_SERVER' => $_SERVER, + '_GET' => $_GET, + '_POST' => $_POST, + '_COOKIE' => $_COOKIE, + 'INPUT' => $ORIGINAL_INPUT + ), true); +} + +//Minz_Log::debug('----------------------------------------------------------------', API_LOG); +//Minz_Log::debug(debugInfo(), API_LOG); +// </Debug> class FeverDAO extends Minz_ModelPdo { @@ -63,7 +94,7 @@ class FeverDAO extends Minz_ModelPdo $sql = 'SELECT id, guid, title, author, ' . ($entryDAO->isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content') - . ', link, date, is_read, is_favorite, id_feed, tags ' + . ', link, date, is_read, is_favorite, id_feed ' . 'FROM `' . $this->prefix . 'entry` WHERE'; if (!empty($entry_ids)) { @@ -311,7 +342,7 @@ class FeverAPI { $groups = array(); - $categoryDAO = new FreshRSS_CategoryDAO(); + $categoryDAO = FreshRSS_Factory::createCategoryDao(); $categories = $categoryDAO->listCategories(false, false); /** @var FreshRSS_Category $category */ @@ -456,7 +487,7 @@ class FeverAPI } if (isset($_REQUEST['group_ids'])) { - $categoryDAO = new FreshRSS_CategoryDAO(); + $categoryDAO = FreshRSS_Factory::createCategoryDao(); $group_ids = explode(',', $_REQUEST['group_ids']); foreach ($group_ids as $id) { /** @var FreshRSS_Category $category */ @@ -495,17 +526,17 @@ class FeverAPI // Load list of extensions and enable the "system" ones. Minz_ExtensionManager::init(); - foreach($entries as $item) { + foreach ($entries as $item) { /** @var FreshRSS_Entry $entry */ $entry = Minz_ExtensionManager::callHook('entry_before_display', $item); - if (is_null($entry)) { + if ($entry == null) { continue; } $items[] = array( 'id' => $entry->id(), 'feed_id' => $entry->feed(false), 'title' => $entry->title(), - 'author' => $entry->author(), + 'author' => $entry->authors(true), 'html' => $entry->content(), 'url' => $entry->link(), 'is_saved' => $entry->isFavorite() ? 1 : 0, diff --git a/p/api/greader.php b/p/api/greader.php index 4affc2826..c6701096c 100644 --- a/p/api/greader.php +++ b/p/api/greader.php @@ -18,6 +18,7 @@ Server-side API compatible with Google Reader API layer 2 * https://github.com/ericmann/gReader-Library/blob/master/greader.class.php * https://github.com/devongovett/reader * https://github.com/theoldreader/api +* https://www.inoreader.com/developers/ */ require(__DIR__ . '/../../constants.php'); @@ -41,6 +42,12 @@ if (PHP_INT_SIZE < 8) { //32-bit } } +if (version_compare(PHP_VERSION, '5.4.0') >= 0) { + define('JSON_OPTIONS', JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); +} else { + define('JSON_OPTIONS', 0); +} + function headerVariable($headerName, $varName) { $header = ''; $upName = 'HTTP_' . strtoupper($headerName); @@ -233,7 +240,7 @@ function userInfo() { //https://github.com/theoldreader/api#user-info 'userName' => $user, 'userProfileId' => $user, 'userEmail' => FreshRSS_Context::$user_conf->mail_login, - ))); + ), JSON_OPTIONS)); } function tagList() { @@ -253,10 +260,24 @@ function tagList() { $tags[] = array( 'id' => 'user/-/label/' . $cName, //'sortid' => $cName, + 'type' => 'folder', //Inoreader ); } - echo json_encode(array('tags' => $tags)), "\n"; + unset($res); + + $tagDAO = FreshRSS_Factory::createTagDao(); + $labels = $tagDAO->listTags(true); + foreach ($labels as $label) { + $tags[] = array( + 'id' => 'user/-/label/' . $label->name(), + //'sortid' => $cName, + 'type' => 'tag', //Inoreader + 'unread_count' => $label->nbUnread(), //Inoreader + ); + } + + echo json_encode(array('tags' => $tags), JSON_OPTIONS), "\n"; exit(); } @@ -292,7 +313,7 @@ function subscriptionList() { ); } - echo json_encode(array('subscriptions' => $subscriptions)), "\n"; + echo json_encode(array('subscriptions' => $subscriptions), JSON_OPTIONS), "\n"; exit(); } @@ -309,7 +330,7 @@ function subscriptionEdit($streamNames, $titles, $action, $add = '', $remove = ' $addCatId = 0; $categoryDAO = null; if ($add != '' || $remove != '') { - $categoryDAO = new FreshRSS_CategoryDAO(); + $categoryDAO = FreshRSS_Factory::createCategoryDao(); } $c_name = ''; if ($add != '' && strpos($add, 'user/') === 0) { //user/-/label/Example ; user/username/label/Example @@ -390,13 +411,13 @@ function quickadd($url) { exit(json_encode(array( 'numResults' => 1, 'streamId' => $feed->id(), - ))); + ), JSON_OPTIONS)); } catch (Exception $e) { Minz_Log::error('quickadd error: ' . $e->getMessage(), API_LOG); die(json_encode(array( 'numResults' => 0, 'error' => $e->getMessage(), - ))); + ), JSON_OPTIONS)); } } @@ -406,7 +427,7 @@ function unreadCount() { //http://blog.martindoms.com/2009/10/16/using-the-googl $totalUnreads = 0; $totalLastUpdate = 0; - $categoryDAO = new FreshRSS_CategoryDAO(); + $categoryDAO = FreshRSS_Factory::createCategoryDao(); foreach ($categoryDAO->listCategories(true, true) as $cat) { $catLastUpdate = 0; foreach ($cat->feeds() as $feed) { @@ -431,6 +452,14 @@ function unreadCount() { //http://blog.martindoms.com/2009/10/16/using-the-googl } } + $tagDAO = FreshRSS_Factory::createTagDao(); + foreach ($tagDAO->listTags(true) as $label) { + $unreadcounts[] = array( + 'id' => 'user/-/label/' . $label->name(), + 'count' => $label->nbUnread(), + ); + } + $unreadcounts[] = array( 'id' => 'user/-/state/com.google/reading-list', 'count' => $totalUnreads, @@ -440,13 +469,21 @@ function unreadCount() { //http://blog.martindoms.com/2009/10/16/using-the-googl echo json_encode(array( 'max' => $totalUnreads, 'unreadcounts' => $unreadcounts, - )), "\n"; + ), JSON_OPTIONS), "\n"; exit(); } function entriesToArray($entries) { + if (empty($entries)) { + return array(); + } $feedDAO = FreshRSS_Factory::createFeedDao(); $arrayFeedCategoryNames = $feedDAO->arrayFeedCategoryNames(); + $tagDAO = FreshRSS_Factory::createTagDao(); + $entryIdsTagNames = $tagDAO->getEntryIdsTagNames($entries); + if ($entryIdsTagNames == false) { + $entryIdsTagNames = array(); + } $items = array(); foreach ($entries as $entry) { @@ -478,8 +515,9 @@ function entriesToArray($entries) { //'htmlUrl' => $line['f_website'], ), ); - if ($entry->author() != '') { - $item['author'] = $entry->author(); + $author = $entry->authors(true); + if ($author != '') { + $item['author'] = $author; } if ($entry->isRead()) { $item['categories'][] = 'user/-/state/com.google/read'; @@ -487,6 +525,10 @@ function entriesToArray($entries) { if ($entry->isFavorite()) { $item['categories'][] = 'user/-/state/com.google/starred'; } + $tagNames = isset($entryIdsTagNames['e_' . $entry->id()]) ? $entryIdsTagNames['e_' . $entry->id()] : array(); + foreach ($tagNames as $tagName) { + $item['categories'][] = 'user/-/label/' . $tagName; + } $items[] = $item; } return $items; @@ -508,10 +550,22 @@ function streamContents($path, $include_target, $start_time, $count, $order, $ex $type = 'f'; break; case 'label': - $type = 'c'; - $categoryDAO = new FreshRSS_CategoryDAO(); + $categoryDAO = FreshRSS_Factory::createCategoryDao(); $cat = $categoryDAO->searchByName($include_target); - $include_target = $cat == null ? -1 : $cat->id(); + if ($cat != null) { + $type = 'c'; + $include_target = $cat->id(); + } else { + $tagDAO = FreshRSS_Factory::createTagDao(); + $tag = $tagDAO->searchByName($include_target); + if ($tag != null) { + $type = 't'; + $include_target = $tag->id(); + } else { + $type = 'A'; + $include_target = -1; + } + } break; default: $type = 'A'; @@ -556,7 +610,7 @@ function streamContents($path, $include_target, $start_time, $count, $order, $ex } } - echo json_encode($response), "\n"; + echo json_encode($response, JSON_OPTIONS), "\n"; exit(); } @@ -576,9 +630,22 @@ function streamContentsItemsIds($streamId, $start_time, $count, $order, $exclude } elseif (strpos($streamId, 'user/-/label/') === 0) { $type = 'c'; $c_name = substr($streamId, 13); - $categoryDAO = new FreshRSS_CategoryDAO(); + $categoryDAO = FreshRSS_Factory::createCategoryDao(); $cat = $categoryDAO->searchByName($c_name); - $id = $cat == null ? -1 : $cat->id(); + if ($cat != null) { + $type = 'c'; + $id = $cat->id(); + } else { + $tagDAO = FreshRSS_Factory::createTagDao(); + $tag = $tagDAO->searchByName($c_name); + if ($tag != null) { + $type = 't'; + $id = $tag->id(); + } else { + $type = 'A'; + $id = -1; + } + } } switch ($exclude_target) { @@ -622,7 +689,7 @@ function streamContentsItemsIds($streamId, $start_time, $count, $order, $exclude } } - echo json_encode($response), "\n"; + echo json_encode($response, JSON_OPTIONS), "\n"; exit(); } @@ -644,7 +711,7 @@ function streamContentsItems($e_ids, $order) { 'items' => $items, ); - echo json_encode($response), "\n"; + echo json_encode($response, JSON_OPTIONS), "\n"; exit(); } @@ -654,6 +721,7 @@ function editTag($e_ids, $a, $r) { } $entryDAO = FreshRSS_Factory::createEntryDao(); + $tagDAO = FreshRSS_Factory::createTagDao(); switch ($a) { case 'user/-/state/com.google/read': @@ -668,6 +736,30 @@ function editTag($e_ids, $a, $r) { break; case 'user/-/state/com.google/broadcast': break;*/ + default: + $tagName = ''; + if (strpos($a, 'user/-/label/') === 0) { + $tagName = substr($a, 13); + } else { + $user = Minz_Session::param('currentUser', '_'); + $prefix = 'user/' . $user . '/label/'; + if (strpos($a, $prefix) === 0) { + $tagName = substr($a, strlen($prefix)); + } + } + if ($tagName != '') { + $tag = $tagDAO->searchByName($tagName); + if ($tag == null) { + $tagDAO->addTag(array('name' => $tagName)); + $tag = $tagDAO->searchByName($tagName); + } + if ($tag != null) { + foreach ($e_ids as $e_id) { + $tagDAO->tagEntry($tag->id(), $e_id, true); + } + } + } + break; } switch ($r) { case 'user/-/state/com.google/read': @@ -676,6 +768,17 @@ function editTag($e_ids, $a, $r) { case 'user/-/state/com.google/starred': $entryDAO->markFavorite($e_ids, false); break; + default: + if (strpos($r, 'user/-/label/') === 0) { + $tagName = substr($r, 13); + $tag = $tagDAO->searchByName($tagName); + if ($tag != null) { + foreach ($e_ids as $e_id) { + $tagDAO->tagEntry($tag->id(), $e_id, false); + } + } + } + break; } exit('OK'); @@ -685,12 +788,20 @@ function renameTag($s, $dest) { if ($s != '' && strpos($s, 'user/-/label/') === 0 && $dest != '' && strpos($dest, 'user/-/label/') === 0) { $s = substr($s, 13); - $categoryDAO = new FreshRSS_CategoryDAO(); + $dest = substr($dest, 13); + + $categoryDAO = FreshRSS_Factory::createCategoryDao(); $cat = $categoryDAO->searchByName($s); if ($cat != null) { - $dest = substr($dest, 13); $categoryDAO->updateCategory($cat->id(), array('name' => $dest)); exit('OK'); + } else { + $tagDAO = FreshRSS_Factory::createTagDao(); + $tag = $tagDAO->searchByName($s); + if ($tag != null) { + $tagDAO->updateTag($tag->id(), array('name' => $dest)); + exit('OK'); + } } } badRequest(); @@ -699,7 +810,7 @@ function renameTag($s, $dest) { function disableTag($s) { if ($s != '' && strpos($s, 'user/-/label/') === 0) { $s = substr($s, 13); - $categoryDAO = new FreshRSS_CategoryDAO(); + $categoryDAO = FreshRSS_Factory::createCategoryDao(); $cat = $categoryDAO->searchByName($s); if ($cat != null) { $feedDAO = FreshRSS_Factory::createFeedDao(); @@ -708,6 +819,13 @@ function disableTag($s) { $categoryDAO->deleteCategory($cat->id()); } exit('OK'); + } else { + $tagDAO = FreshRSS_Factory::createTagDao(); + $tag = $tagDAO->searchByName($s); + if ($tag != null) { + $tagDAO->deleteTag($tag->id()); + exit('OK'); + } } } badRequest(); @@ -720,9 +838,17 @@ function markAllAsRead($streamId, $olderThanId) { $entryDAO->markReadFeed($f_id, $olderThanId); } elseif (strpos($streamId, 'user/-/label/') === 0) { $c_name = substr($streamId, 13); - $categoryDAO = new FreshRSS_CategoryDAO(); + $categoryDAO = FreshRSS_Factory::createCategoryDao(); $cat = $categoryDAO->searchByName($c_name); - $entryDAO->markReadCat($cat === null ? -1 : $cat->id(), $olderThanId); + if ($cat != null) { + $entryDAO->markReadCat($cat->id(), $olderThanId); + } else { + $tagDAO = FreshRSS_Factory::createTagDao(); + $tag = $tagDAO->searchByName($c_name); + if ($tag != null) { + $entryDAO->markReadTag($tag->id(), $olderThanId); + } + } } elseif ($streamId === 'user/-/state/com.google/reading-list') { $entryDAO->markReadEntries($olderThanId, false, -1); } |
