From: Hypolite Petovan Date: Sun, 5 Jan 2020 22:29:54 +0000 (-0500) Subject: Introduce Mastodon entity factories and API\Entity X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=5a1abb8c7dd467f835937739819f32fb397f6314;p=friendica.git Introduce Mastodon entity factories and API\Entity --- diff --git a/src/Api/BaseEntity.php b/src/Api/BaseEntity.php new file mode 100644 index 0000000000..4bc15943df --- /dev/null +++ b/src/Api/BaseEntity.php @@ -0,0 +1,18 @@ +id = $publicContact['id']; + $this->username = $publicContact['nick']; + $this->acct = + strpos($publicContact['url'], $baseUrl->get() . '/') === 0 ? + $publicContact['nick'] : + $publicContact['addr']; + $this->display_name = $publicContact['name']; + $this->locked = !empty($apcontact['manually-approve']); + $this->created_at = DateTimeFormat::utc($publicContact['created'], DateTimeFormat::ATOM); + $this->followers_count = $apcontact['followers_count'] ?? 0; + $this->following_count = $apcontact['following_count'] ?? 0; + $this->statuses_count = $apcontact['statuses_count'] ?? 0; + $this->note = BBCode::convert($publicContact['about'], false); + $this->url = $publicContact['url']; + $this->avatar = $userContact['avatar'] ?? $publicContact['avatar']; + $this->avatar_static = $userContact['avatar'] ?? $publicContact['avatar']; + // No header picture in Friendica + $this->header = ''; + $this->header_static = ''; + // No custom emojis per account in Friendica + $this->emojis = []; + // No metadata fields in Friendica + $this->fields = []; + $this->bot = ($publicContact['contact-type'] == Contact::TYPE_NEWS); + $this->group = ($publicContact['contact-type'] == Contact::TYPE_COMMUNITY); + $this->discoverable = !$publicContact['unsearchable']; + + $publicContactLastItem = $publicContact['last-item'] ?: DBA::NULL_DATETIME; + $userContactLastItem = $userContact['last-item'] ?? DBA::NULL_DATETIME; + + $lastItem = $userContactLastItem > $publicContactLastItem ? $userContactLastItem : $publicContactLastItem; + $this->last_status_at = $lastItem != DBA::NULL_DATETIME ? DateTimeFormat::utc($lastItem, DateTimeFormat::ATOM) : null; + } +} diff --git a/src/Api/Entity/Mastodon/Emoji.php b/src/Api/Entity/Mastodon/Emoji.php new file mode 100644 index 0000000000..f3dbfa5e7d --- /dev/null +++ b/src/Api/Entity/Mastodon/Emoji.php @@ -0,0 +1,22 @@ +id = $introduction_id; + } +} diff --git a/src/Api/Entity/Mastodon/Instance.php b/src/Api/Entity/Mastodon/Instance.php new file mode 100644 index 0000000000..c3828e2b87 --- /dev/null +++ b/src/Api/Entity/Mastodon/Instance.php @@ -0,0 +1,85 @@ +uri = $baseUrl->get(); + $instance->title = Config::get('config', 'sitename'); + $instance->description = Config::get('config', 'info'); + $instance->email = Config::get('config', 'admin_email'); + $instance->version = FRIENDICA_VERSION; + $instance->urls = []; // Not supported + $instance->stats = Stats::get(); + $instance->thumbnail = $baseUrl->get() . (Config::get('system', 'shortcut_icon') ?? 'images/friendica-32.png'); + $instance->languages = [Config::get('system', 'language')]; + $instance->max_toot_chars = (int)Config::get('config', 'api_import_size', Config::get('config', 'max_import_size')); + $instance->registrations = ($register_policy != Register::CLOSED); + $instance->approval_required = ($register_policy == Register::APPROVE); + $instance->contact_account = []; + + if (!empty(Config::get('config', 'admin_email'))) { + $adminList = explode(',', str_replace(' ', '', Config::get('config', 'admin_email'))); + $administrator = User::getByEmail($adminList[0], ['nickname']); + if (!empty($administrator)) { + $adminContact = DBA::selectFirst('contact', ['id'], ['nick' => $administrator['nickname'], 'self' => true]); + $instance->contact_account = DI::mstdnAccount()->createFromContactId($adminContact['id']); + } + } + + return $instance; + } +} diff --git a/src/Api/Entity/Mastodon/Relationship.php b/src/Api/Entity/Mastodon/Relationship.php new file mode 100644 index 0000000000..44a7d70c40 --- /dev/null +++ b/src/Api/Entity/Mastodon/Relationship.php @@ -0,0 +1,60 @@ +id = $userContactId; + $this->following = in_array($userContact['rel'] ?? 0, [Contact::SHARING, Contact::FRIEND]); + $this->followed_by = in_array($userContact['rel'] ?? 0, [Contact::FOLLOWER, Contact::FRIEND]); + $this->blocking = (bool)$userContact['blocked'] ?? false; + $this->muting = (bool)$userContact['readonly'] ?? false; + $this->muting_notifications = (bool)$userContact['readonly'] ?? false; + $this->requested = (bool)$userContact['pending'] ?? false; + $this->domain_blocking = Network::isUrlBlocked($userContact['url'] ?? ''); + + return $this; + } +} diff --git a/src/Api/Entity/Mastodon/Stats.php b/src/Api/Entity/Mastodon/Stats.php new file mode 100644 index 0000000000..219587830a --- /dev/null +++ b/src/Api/Entity/Mastodon/Stats.php @@ -0,0 +1,39 @@ +user_count = intval(Config::get('nodeinfo', 'total_users')); + $stats->status_count = Config::get('nodeinfo', 'local_posts') + Config::get('nodeinfo', 'local_comments'); + $stats->domain_count = DBA::count('gserver', ["`network` in (?, ?) AND `last_contact` >= `last_failure`", Protocol::DFRN, Protocol::ACTIVITYPUB]); + } + return $stats; + } +} diff --git a/src/Api/Mastodon/Account.php b/src/Api/Mastodon/Account.php deleted file mode 100644 index ade6fc03dc..0000000000 --- a/src/Api/Mastodon/Account.php +++ /dev/null @@ -1,111 +0,0 @@ -id = $publicContact['id']; - $account->username = $publicContact['nick']; - $account->acct = - strpos($publicContact['url'], $baseUrl->get() . '/') === 0 ? - $publicContact['nick'] : - $publicContact['addr']; - $account->display_name = $publicContact['name']; - $account->locked = !empty($apcontact['manually-approve']); - $account->created_at = DateTimeFormat::utc($publicContact['created'], DateTimeFormat::ATOM); - $account->followers_count = $apcontact['followers_count'] ?? 0; - $account->following_count = $apcontact['following_count'] ?? 0; - $account->statuses_count = $apcontact['statuses_count'] ?? 0; - $account->note = BBCode::convert($publicContact['about'], false); - $account->url = $publicContact['url']; - $account->avatar = $userContact['avatar'] ?? $publicContact['avatar']; - $account->avatar_static = $userContact['avatar'] ?? $publicContact['avatar']; - // No header picture in Friendica - $account->header = ''; - $account->header_static = ''; - // No custom emojis per account in Friendica - $account->emojis = []; - // No metadata fields in Friendica - $account->fields = []; - $account->bot = ($publicContact['contact-type'] == Contact::TYPE_NEWS); - $account->group = ($publicContact['contact-type'] == Contact::TYPE_COMMUNITY); - $account->discoverable = !$publicContact['unsearchable']; - - $publicContactLastItem = $publicContact['last-item'] ?: DBA::NULL_DATETIME; - $userContactLastItem = $userContact['last-item'] ?? DBA::NULL_DATETIME; - - $lastItem = $userContactLastItem > $publicContactLastItem ? $userContactLastItem : $publicContactLastItem; - $account->last_status_at = $lastItem != DBA::NULL_DATETIME ? DateTimeFormat::utc($lastItem, DateTimeFormat::ATOM) : null; - - return $account; - } -} diff --git a/src/Api/Mastodon/Emoji.php b/src/Api/Mastodon/Emoji.php deleted file mode 100644 index 0fda2d12cb..0000000000 --- a/src/Api/Mastodon/Emoji.php +++ /dev/null @@ -1,20 +0,0 @@ -uri = $baseUrl->get(); - $instance->title = Config::get('config', 'sitename'); - $instance->description = Config::get('config', 'info'); - $instance->email = Config::get('config', 'admin_email'); - $instance->version = FRIENDICA_VERSION; - $instance->urls = []; // Not supported - $instance->stats = Stats::get(); - $instance->thumbnail = $baseUrl->get() . (Config::get('system', 'shortcut_icon') ?? 'images/friendica-32.png'); - $instance->languages = [Config::get('system', 'language')]; - $instance->max_toot_chars = (int)Config::get('config', 'api_import_size', Config::get('config', 'max_import_size')); - $instance->registrations = ($register_policy != Register::CLOSED); - $instance->approval_required = ($register_policy == Register::APPROVE); - $instance->contact_account = []; - - if (!empty(Config::get('config', 'admin_email'))) { - $adminList = explode(',', str_replace(' ', '', Config::get('config', 'admin_email'))); - $administrator = User::getByEmail($adminList[0], ['nickname']); - if (!empty($administrator)) { - $adminContact = DBA::selectFirst('contact', [], ['nick' => $administrator['nickname'], 'self' => true]); - $apcontact = APContact::getByURL($adminContact['url'], false); - $instance->contact_account = Account::create($baseUrl, $adminContact, $apcontact); - } - } - - return $instance; - } -} diff --git a/src/Api/Mastodon/Relationship.php b/src/Api/Mastodon/Relationship.php deleted file mode 100644 index 18e249ba3e..0000000000 --- a/src/Api/Mastodon/Relationship.php +++ /dev/null @@ -1,59 +0,0 @@ -id = $contact['id']; - $relationship->following = in_array($contact['rel'], [Contact::SHARING, Contact::FRIEND]); - $relationship->followed_by = in_array($contact['rel'], [Contact::FOLLOWER, Contact::FRIEND]); - $relationship->blocking = (bool)$contact['blocked']; - $relationship->muting = (bool)$contact['readonly']; - $relationship->muting_notifications = (bool)$contact['readonly']; - $relationship->requested = (bool)$contact['pending']; - $relationship->domain_blocking = Network::isUrlBlocked($contact['url']); - // Unsupported - $relationship->showing_reblogs = true; - // Unsupported - $relationship->endorsed = false; - - return $relationship; - } -} diff --git a/src/Api/Mastodon/Stats.php b/src/Api/Mastodon/Stats.php deleted file mode 100644 index 895a58e060..0000000000 --- a/src/Api/Mastodon/Stats.php +++ /dev/null @@ -1,38 +0,0 @@ -user_count = intval(Config::get('nodeinfo', 'total_users')); - $stats->status_count = Config::get('nodeinfo', 'local_posts') + Config::get('nodeinfo', 'local_comments'); - $stats->domain_count = DBA::count('gserver', ["`network` in (?, ?) AND `last_contact` >= `last_failure`", Protocol::DFRN, Protocol::ACTIVITYPUB]); - } - return $stats; - } -} diff --git a/src/DI.php b/src/DI.php index 485b1b799d..d82b801e92 100644 --- a/src/DI.php +++ b/src/DI.php @@ -28,6 +28,9 @@ use Psr\Log\LoggerInterface; * @method static Core\Process process() * @method static Core\Session\ISession session() * @method static Database\Database dba() + * @method static Factory\Mastodon\Account mstdnAccount() + * @method static Factory\Mastodon\FollowRequest mstdnFollowRequest() + * @method static Factory\Mastodon\Relationship mstdnRelationship() * @method static Model\User\Cookie cookie() * @method static Model\Notify notify() * @method static Model\Introduction intro() @@ -62,6 +65,9 @@ abstract class DI 'process' => Core\Process::class, 'session' => Core\Session\ISession::class, 'dba' => Database\Database::class, + 'mstdnAccount' => Factory\Mastodon\Account::class, + 'mstdnFollowRequest' => Factory\Mastodon\FollowRequest::class, + 'mstdnRelationship' => Factory\Mastodon\Relationship::class, 'cookie' => Model\User\Cookie::class, 'notify' => Model\Notify::class, 'intro' => Model\Introduction::class, diff --git a/src/Factory/Mastodon/Account.php b/src/Factory/Mastodon/Account.php new file mode 100644 index 0000000000..e38654b295 --- /dev/null +++ b/src/Factory/Mastodon/Account.php @@ -0,0 +1,46 @@ +baseUrl = $baseURL; + } + + /** + * @param int $contactId + * @param int $uid User Id + * @return \Friendica\Api\Entity\Mastodon\Account + * @throws HTTPException\InternalServerErrorException + * @throws \ImagickException + */ + public function createFromContactId(int $contactId, $uid = 0) + { + $cdata = Contact::getPublicAndUserContacID($contactId, $uid); + if (!empty($cdata)) { + $publicContact = Contact::getById($cdata['public']); + $userContact = Contact::getById($cdata['user']); + } else { + $publicContact = Contact::getById($contactId); + $userContact = []; + } + + $apcontact = APContact::getByURL($publicContact['url'], false); + + return new \Friendica\Api\Entity\Mastodon\Account($this->baseUrl, $publicContact, $apcontact, $userContact); + } +} diff --git a/src/Factory/Mastodon/FollowRequest.php b/src/Factory/Mastodon/FollowRequest.php new file mode 100644 index 0000000000..b59bfb8ae8 --- /dev/null +++ b/src/Factory/Mastodon/FollowRequest.php @@ -0,0 +1,47 @@ +baseUrl = $baseURL; + } + + /** + * @param Introduction $Introduction + * @return \Friendica\Api\Entity\Mastodon\FollowRequest + * @throws HTTPException\InternalServerErrorException + * @throws \ImagickException + */ + public function createFromIntroduction(Introduction $Introduction) + { + $cdata = Contact::getPublicAndUserContacID($Introduction->{'contact-id'}, $Introduction->uid); + + if (empty($cdata)) { + $this->logger->warning('Wrong introduction data', ['Introduction' => $Introduction]); + throw new HTTPException\InternalServerErrorException('Wrong introduction data'); + } + + $publicContact = Contact::getById($cdata['public']); + $userContact = Contact::getById($cdata['user']); + + $apcontact = APContact::getByURL($publicContact['url'], false); + + return new \Friendica\Api\Entity\Mastodon\FollowRequest($this->baseUrl, $Introduction->id, $publicContact, $apcontact, $userContact); + } +} diff --git a/src/Factory/Mastodon/Relationship.php b/src/Factory/Mastodon/Relationship.php new file mode 100644 index 0000000000..25c9d4c8ce --- /dev/null +++ b/src/Factory/Mastodon/Relationship.php @@ -0,0 +1,38 @@ +createFromContact(Contact::getById($userContactId)); + } + + /** + * @param array $userContact Full contact row record with uid != 0 + * @return RelationshipEntity + */ + public function createFromContact(array $userContact) + { + return new RelationshipEntity($userContact['id'], $userContact); + } + + /** + * @param int $userContactId Contact row id with uid != 0 + * @return RelationshipEntity + */ + public function createDefaultFromContactId(int $userContactId) + { + return new RelationshipEntity($userContactId); + } +} diff --git a/src/Module/Api/Mastodon/Instance.php b/src/Module/Api/Mastodon/Instance.php index 96d4db3302..cc7639f460 100644 --- a/src/Module/Api/Mastodon/Instance.php +++ b/src/Module/Api/Mastodon/Instance.php @@ -2,7 +2,7 @@ namespace Friendica\Module\Api\Mastodon; -use Friendica\Api\Mastodon\Instance as InstanceEntity; +use Friendica\Api\Entity\Mastodon\Instance as InstanceEntity; use Friendica\Core\System; use Friendica\Module\Base\Api;