Merge pull request #10964 from annando/api

The API is now using the router
This commit is contained in:
Hypolite Petovan 2021-11-08 05:36:13 -05:00 committed by GitHub
commit e5f878c767
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 656 additions and 536 deletions

View file

@ -61,6 +61,7 @@ use Friendica\Security\OAuth;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images; use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Proxy;
use Friendica\Util\Strings; use Friendica\Util\Strings;
use Friendica\Util\XML; use Friendica\Util\XML;
@ -614,10 +615,10 @@ function api_get_user(App $a, $contact_id = null)
'screen_name' => (($contact['nick']) ? $contact['nick'] : $contact['name']), 'screen_name' => (($contact['nick']) ? $contact['nick'] : $contact['name']),
'location' => ($contact["location"] != "") ? $contact["location"] : ContactSelector::networkToName($contact['network'], $contact['url'], $contact['protocol']), 'location' => ($contact["location"] != "") ? $contact["location"] : ContactSelector::networkToName($contact['network'], $contact['url'], $contact['protocol']),
'description' => BBCode::toPlaintext($contact["about"] ?? ''), 'description' => BBCode::toPlaintext($contact["about"] ?? ''),
'profile_image_url' => $contact["micro"], 'profile_image_url' => Contact::getAvatarUrlForUrl($contact['url'], api_user(), Proxy::SIZE_MICRO),
'profile_image_url_https' => $contact["micro"], 'profile_image_url_https' => Contact::getAvatarUrlForUrl($contact['url'], api_user(), Proxy::SIZE_MICRO),
'profile_image_url_profile_size' => $contact["thumb"], 'profile_image_url_profile_size' => Contact::getAvatarUrlForUrl($contact['url'], api_user(), Proxy::SIZE_THUMB),
'profile_image_url_large' => $contact["photo"], 'profile_image_url_large' => Contact::getAvatarUrlForUrl($contact['url'], api_user(), Proxy::SIZE_SMALL),
'url' => $contact["url"], 'url' => $contact["url"],
'protected' => false, 'protected' => false,
'followers_count' => 0, 'followers_count' => 0,
@ -688,10 +689,10 @@ function api_get_user(App $a, $contact_id = null)
'screen_name' => (($uinfo[0]['nick']) ? $uinfo[0]['nick'] : $uinfo[0]['name']), 'screen_name' => (($uinfo[0]['nick']) ? $uinfo[0]['nick'] : $uinfo[0]['name']),
'location' => $location, 'location' => $location,
'description' => BBCode::toPlaintext($description ?? ''), 'description' => BBCode::toPlaintext($description ?? ''),
'profile_image_url' => $uinfo[0]['micro'], 'profile_image_url' => Contact::getAvatarUrlForUrl($uinfo[0]['url'], api_user(), Proxy::SIZE_MICRO),
'profile_image_url_https' => $uinfo[0]['micro'], 'profile_image_url_https' => Contact::getAvatarUrlForUrl($uinfo[0]['url'], api_user(), Proxy::SIZE_MICRO),
'profile_image_url_profile_size' => $uinfo[0]["thumb"], 'profile_image_url_profile_size' => Contact::getAvatarUrlForUrl($uinfo[0]['url'], api_user(), Proxy::SIZE_THUMB),
'profile_image_url_large' => $uinfo[0]["photo"], 'profile_image_url_large' => Contact::getAvatarUrlForUrl($uinfo[0]['url'], api_user(), Proxy::SIZE_SMALL),
'url' => $uinfo[0]['url'], 'url' => $uinfo[0]['url'],
'protected' => false, 'protected' => false,
'followers_count' => intval($countfollowers), 'followers_count' => intval($countfollowers),
@ -1983,7 +1984,7 @@ function api_conversation_show($type)
// try to fetch the item for the local user - or the public item, if there is no local one // try to fetch the item for the local user - or the public item, if there is no local one
$item = Post::selectFirst(['parent-uri-id'], ['id' => $id]); $item = Post::selectFirst(['parent-uri-id'], ['id' => $id]);
if (!DBA::isResult($item)) { if (!DBA::isResult($item)) {
throw new BadRequestException("There is no status with this id."); throw new BadRequestException("There is no status with the id $id.");
} }
$parent = Post::selectFirst(['id'], ['uri-id' => $item['parent-uri-id'], 'uid' => [0, api_user()]], ['order' => ['uid' => true]]); $parent = Post::selectFirst(['id'], ['uri-id' => $item['parent-uri-id'], 'uid' => [0, api_user()]], ['order' => ['uid' => true]]);

View file

@ -19,21 +19,31 @@
* *
*/ */
use Friendica\App; namespace Friendica\Module\Api\Friendica;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\BaseApi;
require_once __DIR__ . '/../include/api.php'; /**
* api/friendica
function api_post(App $a) *
* @package Friendica\Module\Api\Friendica
*/
class Index extends BaseApi
{ {
if (!$a->isLoggedIn()) { public static function post(array $parameters = [])
notice(DI::l10n()->t('Permission denied.')); {
return; self::checkAllowedScope(self::SCOPE_WRITE);
}
public static function delete(array $parameters = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
}
public static function rawContent(array $parameters = [])
{
echo api_call(DI::app());
exit();
} }
} }
function api_content(App $a)
{
echo api_call($a);
exit();
}

View file

@ -21,6 +21,7 @@
namespace Friendica\Module\Api\Mastodon\Timelines; namespace Friendica\Module\Api\Mastodon\Timelines;
use Friendica\Core\Logger;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBA; use Friendica\Database\DBA;
@ -100,7 +101,11 @@ class PublicTimeline extends BaseApi
$statuses = []; $statuses = [];
while ($item = Post::fetch($items)) { while ($item = Post::fetch($items)) {
self::setBoundaries($item['uri-id']); self::setBoundaries($item['uri-id']);
try {
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid); $statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
} catch (\Throwable $th) {
Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]);
}
} }
DBA::close($items); DBA::close($items);

View file

@ -40,6 +40,118 @@ $profileRoutes = [
'/media' => [Module\Profile\Media::class, [R::GET]], '/media' => [Module\Profile\Media::class, [R::GET]],
]; ];
$apiRoutes = [
'/account' => [
'/verify_credentials[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/rate_limit_status[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/update_profile[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/update_profile_image[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
],
'/blocks/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/conversation/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/direct_messages' => [
'/all[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/conversation[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE, R::POST]],
'/new[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/sent[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
],
'/direct_messages[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET, R::POST]],
'/externalprofile/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/favorites/create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/favorites/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE, R::POST]],
'/favorites[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/followers/ids[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\FollowersIds::class, [R::GET ]],
'/followers/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\FollowersList::class, [R::GET ]],
'/friends/ids[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\FriendsIds::class, [R::GET ]],
'/friends/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\FriendsList::class, [R::GET ]],
'/friendships/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/friendships/incoming[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/friendica' => [
'/activity/attendmaybe[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/activity/attendno[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/activity/attendyes[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/activity/dislike[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/activity/like[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/activity/unattendmaybe[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/activity/unattendno[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/activity/unattendyes[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/activity/undislike[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/activity/unlike[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/notification/seen[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/notification[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/direct_messages_setseen[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/direct_messages_search[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/events[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Events\Index::class, [R::GET ]],
'/group_show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/group_create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/group_delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE ]],
'/group_update[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/profile/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Profile\Show::class, [R::GET ]],
'/photoalbum/delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE ]],
'/photoalbum/update[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/photos/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/photo/create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/photo/delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE ]],
'/photo/update[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/photo[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
],
'/gnusocial/config[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/gnusocial/version[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/help/test[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/lists' => [
'/create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE, R::POST]],
'/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/ownerships[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/statuses[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/subscriptions[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/update[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
],
'/media/upload[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/media/metadata/create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/saved_searches/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/search/tweets[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/search[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/statusnet/config[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/statusnet/conversation[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/statusnet/conversation/{id:\d+}[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/statusnet/version[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/statuses' => [
'/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE, R::POST]],
'/followers[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/friends[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/friends_timeline[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/home_timeline[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/mediap[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/mentions[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/mentions_timeline[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/networkpublic_timeline[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/public_timeline[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/replies[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/retweet[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/show/{id:\d+}[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/update[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/update_with_media[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]],
'/user_timeline[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
],
'/users' => [
'/lookup[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/search[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
'/show/{id:\d+}[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]],
],
];
return [ return [
'/' => [Module\Home::class, [R::GET]], '/' => [Module\Home::class, [R::GET]],
@ -58,6 +170,8 @@ return [
], ],
'/api' => [ '/api' => [
'' => $apiRoutes,
'/1.1' => $apiRoutes,
'/v1' => [ '/v1' => [
'/accounts' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], // not supported '/accounts' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], // not supported
'/accounts/{id:\d+}' => [Module\Api\Mastodon\Accounts::class, [R::GET ]], '/accounts/{id:\d+}' => [Module\Api\Mastodon\Accounts::class, [R::GET ]],
@ -160,14 +274,6 @@ return [
'/v{version:\d+}' => [ '/v{version:\d+}' => [
'/search' => [Module\Api\Mastodon\Search::class, [R::GET ]], '/search' => [Module\Api\Mastodon\Search::class, [R::GET ]],
], ],
'/friendica' => [
'/profile/show' => [Module\Api\Friendica\Profile\Show::class, [R::GET ]],
'/events' => [Module\Api\Friendica\Events\Index::class, [R::GET ]],
],
'/followers/ids' => [Module\Api\Twitter\FollowersIds::class, [R::GET ]],
'/followers/list' => [Module\Api\Twitter\FollowersList::class, [R::GET ]],
'/friends/ids' => [Module\Api\Twitter\FriendsIds::class, [R::GET ]],
'/friends/list' => [Module\Api\Twitter\FriendsList::class, [R::GET ]],
'/meta' => [Module\Api\Mastodon\Unimplemented::class, [R::POST ]], // not supported '/meta' => [Module\Api\Mastodon\Unimplemented::class, [R::POST ]], // not supported
'/oembed' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], '/oembed' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]],
'/proofs' => [Module\Api\Mastodon\Proofs::class, [R::GET ]], // Dummy, not supported '/proofs' => [Module\Api\Mastodon\Proofs::class, [R::GET ]], // Dummy, not supported

View file

@ -144,10 +144,8 @@ class ModuleTest extends DatabaseTest
], ],
'legacy' => [ 'legacy' => [
'assert' => LegacyModule::class, 'assert' => LegacyModule::class,
// API is one of the last modules to switch from legacy to new BaseModule 'name' => 'display',
// so this should be a stable test case until we completely switch ;-) 'command' => 'display/test/it',
'name' => 'api',
'command' => 'api/test/it',
'privAdd' => false, 'privAdd' => false,
], ],
'new' => [ 'new' => [

File diff suppressed because it is too large Load diff