mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-23 05:34:55 +00:00
Largely complete article querying
Tests to come
This commit is contained in:
parent
a43f8797c5
commit
0e7abfa8f9
1 changed files with 98 additions and 12 deletions
|
@ -109,7 +109,12 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
'keeplist_rules' => "keep_rule",
|
'keeplist_rules' => "keep_rule",
|
||||||
'blocklist_rules' => "block_rule",
|
'blocklist_rules' => "block_rule",
|
||||||
];
|
];
|
||||||
protected const ARTICLE_COLUMNS = ["id", "url", "title", "author", "fingerprint", "subscription", "published_date", "modified_date", "starred", "unread", "content", "media_url", "media_type"];
|
protected const ARTICLE_COLUMNS = [
|
||||||
|
"id", "url", "title", "author", "fingerprint", "subscription",
|
||||||
|
"published_date", "modified_date",
|
||||||
|
"starred", "unread",
|
||||||
|
"content", "media_url", "media_type"
|
||||||
|
];
|
||||||
protected const CALLS = [ // handler method Admin Path Body Query Required fields
|
protected const CALLS = [ // handler method Admin Path Body Query Required fields
|
||||||
'/categories' => [
|
'/categories' => [
|
||||||
'GET' => ["getCategories", false, false, false, false, []],
|
'GET' => ["getCategories", false, false, false, false, []],
|
||||||
|
@ -640,7 +645,8 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
$meta = Arsse::$user->propertiesGet(Arsse::$user->id, false);
|
$meta = Arsse::$user->propertiesGet(Arsse::$user->id, false);
|
||||||
return [
|
return [
|
||||||
'num' => $meta['num'],
|
'num' => $meta['num'],
|
||||||
'root' => $meta['root_folder_name'] ?? Arsse::$lang->msg("API.Miniflux.DefaultCategoryName")
|
'root' => $meta['root_folder_name'] ?? Arsse::$lang->msg("API.Miniflux.DefaultCategoryName"),
|
||||||
|
'tz' => new \DateTimeZone($meta['tz'] ?? "UTC"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -892,8 +898,8 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getEntries(array $query): ResponseInterface {
|
protected function computeContext(array $query, Context $c = null): Context {
|
||||||
$c = (new Context)
|
$c = ($c ?? new Context)
|
||||||
->limit($query['limit'])
|
->limit($query['limit'])
|
||||||
->offset($query['offset'])
|
->offset($query['offset'])
|
||||||
->starred($query['starred'])
|
->starred($query['starred'])
|
||||||
|
@ -924,25 +930,105 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
} elseif ($status === ["unread"]) {
|
} elseif ($status === ["unread"]) {
|
||||||
$c->hidden(false)->unread(true);
|
$c->hidden(false)->unread(true);
|
||||||
}
|
}
|
||||||
|
return $c;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function computeOrder(array $query): array {
|
||||||
$desc = $query['direction'] === "desc" ? " desc" : "";
|
$desc = $query['direction'] === "desc" ? " desc" : "";
|
||||||
if ($query['order'] === "id") {
|
if ($query['order'] === "id") {
|
||||||
$order = ["id".$desc];
|
return ["id".$desc];
|
||||||
} elseif ($query['order'] === "status") {
|
} elseif ($query['order'] === "status") {
|
||||||
if (!$desc) {
|
if (!$desc) {
|
||||||
$order = ["hidden", "unread desc"];
|
return ["hidden", "unread desc"];
|
||||||
} else {
|
} else {
|
||||||
$order = ["hidden desc", "unread"];
|
return ["hidden desc", "unread"];
|
||||||
}
|
}
|
||||||
} elseif ($query['order'] === "published_at") {
|
} elseif ($query['order'] === "published_at") {
|
||||||
$order = ["modified_date".$desc];
|
return ["modified_date".$desc];
|
||||||
} elseif ($query['order'] === "category_title") {
|
} elseif ($query['order'] === "category_title") {
|
||||||
$order = ["top_folder_name".$desc];
|
return ["top_folder_name".$desc];
|
||||||
} elseif ($query['order'] === "catgory_id") {
|
} elseif ($query['order'] === "catgory_id") {
|
||||||
$order = ["top_folder".$desc];
|
return ["top_folder".$desc];
|
||||||
} else {
|
} else {
|
||||||
$order = [];
|
return [];
|
||||||
}
|
}
|
||||||
$articles = Arsse::$db->articleList(Arsse::$user->id, $c, self::ARTICLE_COLUMNS, $order);
|
}
|
||||||
|
|
||||||
|
protected function transformEntry(array $entry, int $uid, \DateTimeZone $tz): array {
|
||||||
|
if ($entry['hidden']) {
|
||||||
|
$status = "removed";
|
||||||
|
} elseif ($entry['unread']) {
|
||||||
|
$status = "unread";
|
||||||
|
} else {
|
||||||
|
$status = "read";
|
||||||
|
}
|
||||||
|
if ($entry['media_url']) {
|
||||||
|
$enclosures = [
|
||||||
|
[
|
||||||
|
'id' => $entry['id'], // NOTE: We don't have IDs for enclosures, but we also only have one enclosure per entry, so we can just re-use the same ID
|
||||||
|
'user_id' => $uid,
|
||||||
|
'entry_id' => $entry['id'],
|
||||||
|
'url' => $entry['media_url'],
|
||||||
|
'mime_type' => $entry['media_type'] ?: "application/octet-stream",
|
||||||
|
'size' => 0,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$enclosures = null;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'id' => (int) $entry['id'],
|
||||||
|
'user_id' => $uid,
|
||||||
|
'feed_id' => (int) $entry['subscription'],
|
||||||
|
'status' => $status,
|
||||||
|
'hash' => $entry['fingerprint'],
|
||||||
|
'title' => $entry['title'],
|
||||||
|
'url' => $entry['url'],
|
||||||
|
'comments_url' => "",
|
||||||
|
'published_at' => Date::transform(Date::normalize($entry['published_date'], "sql")->setTimezone($tz), "iso8601"),
|
||||||
|
'created_at' => Date::transform(Date::normalize($entry['modified_date'], "sql")->setTimezone($tz), "iso8601m"),
|
||||||
|
'content' => $entry['content'],
|
||||||
|
'author' => (string) $entry['author'],
|
||||||
|
'share_code' => "",
|
||||||
|
'starred' => (bool) $entry['starred'],
|
||||||
|
'reading_time' => 0,
|
||||||
|
'enclosures' => $enclosures,
|
||||||
|
'feed' => null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getEntries(array $query): ResponseInterface {
|
||||||
|
$c = $this->computeContext($query);
|
||||||
|
$order = $this->computeOrder($query);
|
||||||
|
$tr = Arsse::$db->begin();
|
||||||
|
$meta = $this->userMeta(Arsse::$user->id);
|
||||||
|
// compile the list of entries
|
||||||
|
try {
|
||||||
|
$entries = Arsse::$db->articleList(Arsse::$user->id, $c, self::ARTICLE_COLUMNS, $order);
|
||||||
|
} catch (ExceptionInput $e) {
|
||||||
|
return new ErrorResponse("MissingCategory", 400);
|
||||||
|
}
|
||||||
|
$out = [];
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$out[] = $this->transformEntry($entry, $meta['num'], $meta['tz']);
|
||||||
|
}
|
||||||
|
// next compile a map of feeds to add to the entries
|
||||||
|
$feeds = [];
|
||||||
|
foreach (Arsse::$db->subscriptionList(Arsse::$user->id) as $r) {
|
||||||
|
$feeds[(int) $r['id']] = $this->transformFeed($r, $meta['num'], $meta['root']);
|
||||||
|
}
|
||||||
|
// add the feed objects to each entry
|
||||||
|
// NOTE: If ever we implement multiple enclosure, this would be the right place to add them
|
||||||
|
for ($a = 0; $a < sizeof($out); $a++) {
|
||||||
|
$out[$a]['feed'] = $feeds[$out[$a]['feed_id']];
|
||||||
|
}
|
||||||
|
// finally compute the total number of entries match the query, if the query hs a limit or offset
|
||||||
|
if ($c->limit || $c->offset) {
|
||||||
|
$count = Arsse::$db->articleCount(Arsse::$user->id, $c);
|
||||||
|
} else {
|
||||||
|
$count = sizeof($out);
|
||||||
|
}
|
||||||
|
return new Response(['total' => $count, 'entries' => $out]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function tokenGenerate(string $user, string $label): string {
|
public static function tokenGenerate(string $user, string $label): string {
|
||||||
|
|
Loading…
Reference in a new issue