mirror of
https://github.com/friendica/friendica
synced 2025-04-23 09:10:10 +00:00
Merge branch 'friendica:develop' into bug-noLocalPosts
This commit is contained in:
commit
7676aa7908
64 changed files with 1931 additions and 1271 deletions
|
@ -69,6 +69,8 @@ class Statuses extends BaseApi
|
|||
|
||||
if ($request['pinned']) {
|
||||
$condition = ['author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED], 'type' => Post\Collection::FEATURED];
|
||||
} elseif ($request['only_media']) {
|
||||
$condition = ['author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED], 'type' => [Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]];
|
||||
} elseif (!$uid) {
|
||||
$condition = ['author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED],
|
||||
'uid' => 0, 'network' => Protocol::FEDERATED];
|
||||
|
@ -76,16 +78,11 @@ class Statuses extends BaseApi
|
|||
$condition = ["`author-id` = ? AND (`uid` = 0 OR (`uid` = ? AND NOT `global`))", $id, $uid];
|
||||
}
|
||||
|
||||
if (!$request['pinned']) {
|
||||
if (!$request['pinned'] && !$request['only_media']) {
|
||||
$condition = DBA::mergeConditions($condition, ["(`gravity` IN (?, ?) OR (`gravity` = ? AND `vid` = ?))",
|
||||
Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE)]);
|
||||
}
|
||||
|
||||
if ($request['only_media']) {
|
||||
$condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
|
||||
Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]);
|
||||
}
|
||||
|
||||
if (!empty($request['max_id'])) {
|
||||
$condition = DBA::mergeConditions($condition, ["`uri-id` < ?", $request['max_id']]);
|
||||
}
|
||||
|
@ -99,12 +96,16 @@ class Statuses extends BaseApi
|
|||
$params['order'] = ['uri-id'];
|
||||
}
|
||||
|
||||
if ($request['exclude_replies']) {
|
||||
if (($request['pinned'] || $request['only_media']) && $request['exclude_replies']) {
|
||||
$condition = DBA::mergeConditions($condition, ['gravity' => Item::GRAVITY_PARENT]);
|
||||
}
|
||||
|
||||
if ($request['pinned']) {
|
||||
$items = DBA::select('collection-view', ['uri-id'], $condition, $params);
|
||||
} elseif ($request['only_media']) {
|
||||
$items = DBA::select('media-view', ['uri-id'], $condition, $params);
|
||||
} elseif ($request['exclude_replies']) {
|
||||
$items = Post::selectThreadForUser($uid, ['uri-id'], $condition, $params);
|
||||
} else {
|
||||
$items = Post::selectForUser($uid, ['uri-id'], $condition, $params);
|
||||
}
|
||||
|
|
82
src/Module/Api/Mastodon/FollowedTags.php
Normal file
82
src/Module/Api/Mastodon/FollowedTags.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon;
|
||||
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/followed_tags/
|
||||
*/
|
||||
class FollowedTags extends BaseApi
|
||||
{
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$request = $this->getRequest([
|
||||
'max_id' => 0,
|
||||
'since_id' => 0,
|
||||
'min_id' => 0,
|
||||
'limit' => 100, // Maximum number of results to return. Defaults to 100. Paginate using the HTTP Link header.
|
||||
], $request);
|
||||
|
||||
$params = ['order' => ['id' => true], 'limit' => $request['limit']];
|
||||
|
||||
$condition = ["`uid` = ? AND `term` LIKE ?", $uid, '#%'];
|
||||
|
||||
if (!empty($request['max_id'])) {
|
||||
$condition = DBA::mergeConditions($condition, ["`id` < ?", $request['max_id']]);
|
||||
}
|
||||
|
||||
if (!empty($request['since_id'])) {
|
||||
$condition = DBA::mergeConditions($condition, ["`id` > ?", $request['since_id']]);
|
||||
}
|
||||
|
||||
if (!empty($request['min_id'])) {
|
||||
$condition = DBA::mergeConditions($condition, ["`id` > ?", $request['min_id']]);
|
||||
|
||||
$params['order'] = ['id'];
|
||||
}
|
||||
|
||||
$return = [];
|
||||
|
||||
$saved_searches = DBA::select('search', ['id', 'term'], $condition);
|
||||
while ($saved_search = DBA::fetch($saved_searches)) {
|
||||
self::setBoundaries($saved_search['id']);
|
||||
|
||||
$hashtag = new \Friendica\Object\Api\Mastodon\Tag($this->baseUrl, ['name' => ltrim($saved_search['term'], '#')], [], true);
|
||||
$return[] = $hashtag->toArray();
|
||||
}
|
||||
|
||||
DBA::close($saved_searches);
|
||||
|
||||
if (!empty($request['min_id'])) {
|
||||
$return = array_reverse($return);
|
||||
}
|
||||
|
||||
self::setLinkHeader();
|
||||
System::jsonExit($return);
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ use Friendica\Core\System;
|
|||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
@ -67,10 +68,24 @@ class Search extends BaseApi
|
|||
|
||||
if (empty($request['type']) || ($request['type'] == 'accounts')) {
|
||||
$result['accounts'] = self::searchAccounts($uid, $request['q'], $request['resolve'], $limit, $request['offset'], $request['following']);
|
||||
|
||||
if (!is_array($result['accounts'])) {
|
||||
// Curbing the search if we got an exact result
|
||||
$request['type'] = 'accounts';
|
||||
$result['accounts'] = [$result['accounts']];
|
||||
}
|
||||
}
|
||||
|
||||
if ((empty($request['type']) || ($request['type'] == 'statuses')) && (strpos($request['q'], '@') == false)) {
|
||||
$result['statuses'] = self::searchStatuses($uid, $request['q'], $request['account_id'], $request['max_id'], $request['min_id'], $limit, $request['offset']);
|
||||
|
||||
if (!is_array($result['statuses'])) {
|
||||
// Curbing the search if we got an exact result
|
||||
$request['type'] = 'statuses';
|
||||
$result['statuses'] = [$result['statuses']];
|
||||
}
|
||||
}
|
||||
|
||||
if ((empty($request['type']) || ($request['type'] == 'hashtags')) && (strpos($request['q'], '@') == false)) {
|
||||
$result['hashtags'] = self::searchHashtags($request['q'], $request['exclude_unreviewed'], $limit, $request['offset'], $this->parameters['version']);
|
||||
}
|
||||
|
@ -78,31 +93,59 @@ class Search extends BaseApi
|
|||
System::jsonExit($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uid
|
||||
* @param string $q
|
||||
* @param bool $resolve
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @param bool $following
|
||||
* @return array|\Friendica\Object\Api\Mastodon\Account Object if result is absolute (exact account match), list if not
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \Friendica\Network\HTTPException\NotFoundException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function searchAccounts(int $uid, string $q, bool $resolve, int $limit, int $offset, bool $following)
|
||||
{
|
||||
$accounts = [];
|
||||
|
||||
if ((strrpos($q, '@') > 0) || Network::isValidHttpUrl($q)) {
|
||||
$id = Contact::getIdForURL($q, 0, $resolve ? null : false);
|
||||
|
||||
if (!empty($id)) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($id, $uid);
|
||||
}
|
||||
if (
|
||||
(strrpos($q, '@') > 0 || Network::isValidHttpUrl($q))
|
||||
&& $id = Contact::getIdForURL($q, 0, $resolve ? null : false)
|
||||
) {
|
||||
return DI::mstdnAccount()->createFromContactId($id, $uid);
|
||||
}
|
||||
|
||||
if (empty($accounts)) {
|
||||
$contacts = Contact::searchByName($q, '', $following ? $uid : 0, $limit, $offset);
|
||||
foreach ($contacts as $contact) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($contact['id'], $uid);
|
||||
}
|
||||
DBA::close($contacts);
|
||||
$accounts = [];
|
||||
foreach (Contact::searchByName($q, '', $following ? $uid : 0, $limit, $offset) as $contact) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($contact['id'], $uid);
|
||||
}
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uid
|
||||
* @param string $q
|
||||
* @param string $account_id
|
||||
* @param int $max_id
|
||||
* @param int $min_id
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @return array|\Friendica\Object\Api\Mastodon\Status Object is result is absolute (exact post match), list if not
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \Friendica\Network\HTTPException\NotFoundException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function searchStatuses(int $uid, string $q, string $account_id, int $max_id, int $min_id, int $limit, int $offset)
|
||||
{
|
||||
if (Network::isValidHttpUrl($q)) {
|
||||
$q = Network::convertToIdn($q);
|
||||
// If the user-specific search failed, we search and probe a public post
|
||||
$item_id = Item::fetchByLink($q, $uid) ?: Item::fetchByLink($q);
|
||||
if ($item_id && $item = Post::selectFirst(['uri-id'], ['id' => $item_id])) {
|
||||
return DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
|
||||
}
|
||||
}
|
||||
|
||||
$params = ['order' => ['uri-id' => true], 'limit' => [$offset, $limit]];
|
||||
|
||||
if (substr($q, 0, 1) == '#') {
|
||||
|
@ -148,7 +191,7 @@ class Search extends BaseApi
|
|||
return $statuses;
|
||||
}
|
||||
|
||||
private static function searchHashtags(string $q, bool $exclude_unreviewed, int $limit, int $offset, int $version)
|
||||
private static function searchHashtags(string $q, bool $exclude_unreviewed, int $limit, int $offset, int $version): array
|
||||
{
|
||||
$q = ltrim($q, '#');
|
||||
|
||||
|
|
52
src/Module/Api/Mastodon/Tags.php
Normal file
52
src/Module/Api/Mastodon/Tags.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon;
|
||||
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/tags/
|
||||
*/
|
||||
class Tags extends BaseApi
|
||||
{
|
||||
/**
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
self::checkAllowedScope(self::SCOPE_READ);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($this->parameters['hashtag'])) {
|
||||
DI::mstdnError()->UnprocessableEntity();
|
||||
}
|
||||
|
||||
$tag = ltrim($this->parameters['hashtag'], '#');
|
||||
$following = DBA::exists('search', ['uid' => $uid, 'term' => '#' . $tag]);
|
||||
|
||||
$hashtag = new \Friendica\Object\Api\Mastodon\Tag($this->baseUrl, ['name' => $tag], [], $following);
|
||||
System::jsonExit($hashtag->toArray());
|
||||
}
|
||||
}
|
51
src/Module/Api/Mastodon/Tags/Follow.php
Normal file
51
src/Module/Api/Mastodon/Tags/Follow.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon\Tags;
|
||||
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/tags/#follow
|
||||
*/
|
||||
class Follow extends BaseApi
|
||||
{
|
||||
protected function post(array $request = [])
|
||||
{
|
||||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($this->parameters['hashtag'])) {
|
||||
DI::mstdnError()->UnprocessableEntity();
|
||||
}
|
||||
|
||||
$fields = ['uid' => $uid, 'term' => '#' . ltrim($this->parameters['hashtag'], '#')];
|
||||
if (!DBA::exists('search', $fields)) {
|
||||
DBA::insert('search', $fields);
|
||||
}
|
||||
|
||||
$hashtag = new \Friendica\Object\Api\Mastodon\Tag($this->baseUrl, ['name' => ltrim($this->parameters['hashtag'])], [], true);
|
||||
System::jsonExit($hashtag->toArray());
|
||||
}
|
||||
}
|
50
src/Module/Api/Mastodon/Tags/Unfollow.php
Normal file
50
src/Module/Api/Mastodon/Tags/Unfollow.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon\Tags;
|
||||
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/tags/#unfollow
|
||||
*/
|
||||
class Unfollow extends BaseApi
|
||||
{
|
||||
protected function post(array $request = [])
|
||||
{
|
||||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
if (empty($this->parameters['hashtag'])) {
|
||||
DI::mstdnError()->UnprocessableEntity();
|
||||
}
|
||||
|
||||
$term = ['uid' => $uid, 'term' => '#' . ltrim($this->parameters['hashtag'], '#')];
|
||||
|
||||
DBA::delete('search', $term);
|
||||
|
||||
$hashtag = new \Friendica\Object\Api\Mastodon\Tag($this->baseUrl, ['name' => ltrim($this->parameters['hashtag'])], [], false);
|
||||
System::jsonExit($hashtag->toArray());
|
||||
}
|
||||
}
|
60
src/Module/Api/Mastodon/Trends/Links.php
Normal file
60
src/Module/Api/Mastodon/Trends/Links.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon\Trends;
|
||||
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Module\BaseApi;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/trends/#links
|
||||
*/
|
||||
class Links extends BaseApi
|
||||
{
|
||||
/**
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
$request = $this->getRequest([
|
||||
'limit' => 10, // Maximum number of results to return. Defaults to 10.
|
||||
], $request);
|
||||
|
||||
$condition = ["EXISTS(SELECT `id` FROM `post-media` WHERE `post-media`.`uri-id` = `post-thread-view`.`uri-id` AND `type` = ? AND NOT `name` IS NULL AND NOT `description` IS NULL) AND NOT `private` AND `commented` > ? AND `created` > ?",
|
||||
Post\Media::HTML, DateTimeFormat::utc('now -1 day'), DateTimeFormat::utc('now -1 week')];
|
||||
$condition = DBA::mergeConditions($condition, ['network' => Protocol::FEDERATED]);
|
||||
|
||||
$trending = [];
|
||||
$statuses = Post::selectPostThread(['uri-id', 'total-comments', 'total-actors'], $condition, ['limit' => $request['limit'], 'order' => ['total-actors' => true]]);
|
||||
while ($status = Post::fetch($statuses)) {
|
||||
$history = [['day' => (string)time(), 'uses' => (string)$status['total-comments'], 'accounts' => (string)$status['total-actors']]];
|
||||
$trending[] = DI::mstdnCard()->createFromUriId($status['uri-id'], $history)->toArray();
|
||||
}
|
||||
DBA::close($statuses);
|
||||
|
||||
System::jsonExit($trending);
|
||||
}
|
||||
}
|
60
src/Module/Api/Mastodon/Trends/Statuses.php
Normal file
60
src/Module/Api/Mastodon/Trends/Statuses.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon\Trends;
|
||||
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Module\BaseApi;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/trends/#statuses
|
||||
*/
|
||||
class Statuses extends BaseApi
|
||||
{
|
||||
/**
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
$request = $this->getRequest([
|
||||
'limit' => 10, // Maximum number of results to return. Defaults to 10.
|
||||
], $request);
|
||||
|
||||
$condition = ["NOT `private` AND `commented` > ? AND `created` > ?", DateTimeFormat::utc('now -1 day'), DateTimeFormat::utc('now -1 week')];
|
||||
$condition = DBA::mergeConditions($condition, ['network' => Protocol::FEDERATED]);
|
||||
|
||||
$trending = [];
|
||||
$statuses = Post::selectPostThread(['uri-id'], $condition, ['limit' => $request['limit'], 'order' => ['total-actors' => true]]);
|
||||
while ($status = Post::fetch($statuses)) {
|
||||
$trending[] = DI::mstdnStatus()->createFromUriId($status['uri-id'], $uid);
|
||||
}
|
||||
DBA::close($statuses);
|
||||
|
||||
System::jsonExit($trending);
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Api\Mastodon;
|
||||
namespace Friendica\Module\Api\Mastodon\Trends;
|
||||
|
||||
use Friendica\Core\System;
|
||||
use Friendica\DI;
|
||||
|
@ -29,7 +29,7 @@ use Friendica\Module\BaseApi;
|
|||
/**
|
||||
* @see https://docs.joinmastodon.org/methods/instance/trends/
|
||||
*/
|
||||
class Trends extends BaseApi
|
||||
class Tags extends BaseApi
|
||||
{
|
||||
/**
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
|
@ -37,7 +37,6 @@ class Attach extends BaseModule
|
|||
*/
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
$a = DI::app();
|
||||
if (empty($this->parameters['item'])) {
|
||||
throw new \Friendica\Network\HTTPException\BadRequestException();
|
||||
}
|
||||
|
|
100
src/Module/Media/Attachment/Browser.php
Normal file
100
src/Module/Media/Attachment/Browser.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Media\Attachment;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Model\Attach;
|
||||
use Friendica\Module\Response;
|
||||
use Friendica\Network\HTTPException\UnauthorizedException;
|
||||
use Friendica\Util\Profiler;
|
||||
use Friendica\Util\Strings;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Browser for Attachments
|
||||
*/
|
||||
class Browser extends BaseModule
|
||||
{
|
||||
/** @var IHandleUserSessions */
|
||||
protected $session;
|
||||
/** @var App */
|
||||
protected $app;
|
||||
|
||||
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IHandleUserSessions $session, App $app, array $server, array $parameters = [])
|
||||
{
|
||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||
|
||||
$this->session = $session;
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
protected function content(array $request = []): string
|
||||
{
|
||||
if (!$this->session->getLocalUserId()) {
|
||||
throw new UnauthorizedException($this->t('You need to be logged in to access this page.'));
|
||||
}
|
||||
|
||||
// Needed to match the correct template in a module that uses a different theme than the user/site/default
|
||||
$theme = Strings::sanitizeFilePathItem($request['theme'] ?? '');
|
||||
if ($theme && is_file("view/theme/$theme/config.php")) {
|
||||
$this->app->setCurrentTheme($theme);
|
||||
}
|
||||
|
||||
$files = Attach::selectToArray(['id', 'filename', 'filetype'], ['uid' => $this->session->getLocalUserId()]);
|
||||
|
||||
$fileArray = array_map([$this, 'map_files'], $files);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('media/browser.tpl');
|
||||
$output = Renderer::replaceMacros($tpl, [
|
||||
'$type' => 'attachment',
|
||||
'$path' => ['' => $this->t('Files')],
|
||||
'$folders' => false,
|
||||
'$files' => $fileArray,
|
||||
'$cancel' => $this->t('Cancel'),
|
||||
'$nickname' => $this->app->getLoggedInUserNickname(),
|
||||
'$upload' => $this->t('Upload'),
|
||||
]);
|
||||
|
||||
if (empty($request['mode'])) {
|
||||
System::httpExit($output);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function map_files(array $record): array
|
||||
{
|
||||
list($m1, $m2) = explode('/', $record['filetype']);
|
||||
$filetype = file_exists(sprintf('images/icons/%s.png', $m1) ? $m1 : 'text');
|
||||
|
||||
return [
|
||||
sprintf('%s/attach/%s', $this->baseUrl, $record['id']),
|
||||
$record['filename'],
|
||||
sprintf('%s/images/icon/16/%s.png', $this->baseUrl, $filetype),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Profile\Attachment;
|
||||
namespace Friendica\Module\Media\Attachment;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
|
@ -73,30 +73,12 @@ class Upload extends \Friendica\BaseModule
|
|||
$this->response->setType(Response::TYPE_JSON, 'application/json');
|
||||
}
|
||||
|
||||
$nick = $this->parameters['nickname'];
|
||||
$owner = User::getOwnerDataByNick($nick);
|
||||
$owner = User::getOwnerDataById($this->userSession->getLocalUserId());
|
||||
if (!$owner) {
|
||||
$this->logger->warning('owner is not a valid record:', ['owner' => $owner, 'nick' => $nick]);
|
||||
$this->logger->warning('Owner not found.', ['uid' => $this->userSession->getLocalUserId()]);
|
||||
return $this->return(401, $this->t('Invalid request.'));
|
||||
}
|
||||
|
||||
$can_post = false;
|
||||
$contact_id = 0;
|
||||
$page_owner_uid = $owner['uid'];
|
||||
$community_page = $owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY;
|
||||
|
||||
if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $page_owner_uid) {
|
||||
$can_post = true;
|
||||
} elseif ($community_page && !empty($this->userSession->getRemoteContactID($page_owner_uid))) {
|
||||
$contact_id = $this->userSession->getRemoteContactID($page_owner_uid);
|
||||
$can_post = $this->database->exists('contact', ['blocked' => false, 'pending' => false, 'id' => $contact_id, 'uid' => $page_owner_uid]);
|
||||
}
|
||||
|
||||
if (!$can_post) {
|
||||
$this->logger->warning('User does not have required permissions', ['contact_id' => $contact_id, 'page_owner_uid' => $page_owner_uid]);
|
||||
return $this->return(403, $this->t('Permission denied.'), true);
|
||||
}
|
||||
|
||||
if (empty($_FILES['userfile'])) {
|
||||
$this->logger->warning('No file uploaded (empty userfile)');
|
||||
return $this->return(401, $this->t('Invalid request.'), true);
|
||||
|
@ -126,7 +108,7 @@ class Upload extends \Friendica\BaseModule
|
|||
return $this->return(401, $msg);
|
||||
}
|
||||
|
||||
$newid = Attach::storeFile($tempFileName, $page_owner_uid, $fileName, '<' . $owner['id'] . '>');
|
||||
$newid = Attach::storeFile($tempFileName, $owner['uid'], $fileName, '<' . $owner['id'] . '>');
|
||||
|
||||
@unlink($tempFileName);
|
||||
|
125
src/Module/Media/Photo/Browser.php
Normal file
125
src/Module/Media/Photo/Browser.php
Normal file
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Media\Photo;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Module\Response;
|
||||
use Friendica\Network\HTTPException\UnauthorizedException;
|
||||
use Friendica\Util\Images;
|
||||
use Friendica\Util\Profiler;
|
||||
use Friendica\Util\Strings;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Browser for Photos
|
||||
*/
|
||||
class Browser extends BaseModule
|
||||
{
|
||||
/** @var IHandleUserSessions */
|
||||
protected $session;
|
||||
/** @var App */
|
||||
protected $app;
|
||||
|
||||
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IHandleUserSessions $session, App $app, array $server, array $parameters = [])
|
||||
{
|
||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||
|
||||
$this->session = $session;
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
protected function content(array $request = []): string
|
||||
{
|
||||
if (!$this->session->getLocalUserId()) {
|
||||
throw new UnauthorizedException($this->t('You need to be logged in to access this page.'));
|
||||
}
|
||||
|
||||
// Needed to match the correct template in a module that uses a different theme than the user/site/default
|
||||
$theme = Strings::sanitizeFilePathItem($request['theme'] ?? '');
|
||||
if ($theme && is_file("view/theme/$theme/config.php")) {
|
||||
$this->app->setCurrentTheme($theme);
|
||||
}
|
||||
|
||||
$album = $this->parameters['album'] ?? null;
|
||||
|
||||
$photos = Photo::getBrowsablePhotosForUser($this->session->getLocalUserId(), $album);
|
||||
$albums = $album ? false : Photo::getBrowsableAlbumsForUser($this->session->getLocalUserId());
|
||||
|
||||
$path = [
|
||||
'' => $this->t('Photos'),
|
||||
];
|
||||
if (!empty($album)) {
|
||||
$path[$album] = $album;
|
||||
}
|
||||
|
||||
$photosArray = array_map([$this, 'map_files'], $photos);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('media/browser.tpl');
|
||||
$output = Renderer::replaceMacros($tpl, [
|
||||
'$type' => 'photo',
|
||||
'$path' => $path,
|
||||
'$folders' => $albums,
|
||||
'$files' => $photosArray,
|
||||
'$cancel' => $this->t('Cancel'),
|
||||
'$nickname' => $this->app->getLoggedInUserNickname(),
|
||||
'$upload' => $this->t('Upload'),
|
||||
]);
|
||||
|
||||
if (empty($request['mode'])) {
|
||||
System::httpExit($output);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function map_files(array $record): array
|
||||
{
|
||||
$types = Images::supportedTypes();
|
||||
$ext = $types[$record['type']];
|
||||
$filename_e = $record['filename'];
|
||||
|
||||
// Take the largest picture that is smaller or equal 640 pixels
|
||||
$photo = Photo::selectFirst(
|
||||
['scale'],
|
||||
[
|
||||
"`resource-id` = ? AND `height` <= ? AND `width` <= ?",
|
||||
$record['resource-id'],
|
||||
640,
|
||||
640
|
||||
],
|
||||
['order' => ['scale']]);
|
||||
$scale = $photo['scale'] ?? $record['loq'];
|
||||
|
||||
return [
|
||||
sprintf('%s/photos/%s/image/%s', $this->baseUrl, $this->app->getLoggedInUserNickname(), $record['resource-id']),
|
||||
$filename_e,
|
||||
sprintf('%s/photo/%s-%s.%s', $this->baseUrl, $record['resource-id'], $scale, $ext),
|
||||
$record['desc'],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Profile\Photos;
|
||||
namespace Friendica\Module\Media\Photo;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
|
@ -76,36 +76,11 @@ class Upload extends \Friendica\BaseModule
|
|||
|
||||
$album = trim($request['album'] ?? '');
|
||||
|
||||
if (empty($_FILES['media'])) {
|
||||
$user = $this->database->selectFirst('owner-view', ['id', 'uid', 'nickname', 'page-flags'], ['nickname' => $this->parameters['nickname'], 'blocked' => false]);
|
||||
} else {
|
||||
$user = $this->database->selectFirst('owner-view', ['id', 'uid', 'nickname', 'page-flags'], ['uid' => BaseApi::getCurrentUserID() ?: null, 'blocked' => false]);
|
||||
}
|
||||
$owner = User::getOwnerDataById($this->userSession->getLocalUserId());
|
||||
|
||||
if (!$this->database->isResult($user)) {
|
||||
$this->logger->warning('User is not valid', ['nickname' => $this->parameters['nickname'], 'user' => $user]);
|
||||
return $this->return(404, $this->t('User not found.'));
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup permissions structures
|
||||
*/
|
||||
$can_post = false;
|
||||
$visitor = 0;
|
||||
$contact_id = 0;
|
||||
$page_owner_uid = $user['uid'];
|
||||
|
||||
if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $page_owner_uid) {
|
||||
$can_post = true;
|
||||
} elseif ($user['page-flags'] == User::PAGE_FLAGS_COMMUNITY && !$this->userSession->getRemoteContactID($page_owner_uid)) {
|
||||
$contact_id = $this->userSession->getRemoteContactID($page_owner_uid);
|
||||
$can_post = $this->database->exists('contact', ['blocked' => false, 'pending' => false, 'id' => $contact_id, 'uid' => $page_owner_uid]);
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
|
||||
if (!$can_post) {
|
||||
$this->logger->warning('No permission to upload files', ['contact_id' => $contact_id, 'page_owner_uid' => $page_owner_uid]);
|
||||
return $this->return(403, $this->t('Permission denied.'), true);
|
||||
if (!$owner) {
|
||||
$this->logger->warning('Owner not found.', ['uid' => $this->userSession->getLocalUserId()]);
|
||||
return $this->return(401, $this->t('Invalid request.'));
|
||||
}
|
||||
|
||||
if (empty($_FILES['userfile']) && empty($_FILES['media'])) {
|
||||
|
@ -223,9 +198,9 @@ class Upload extends \Friendica\BaseModule
|
|||
$album = $this->t('Wall Photos');
|
||||
}
|
||||
|
||||
$allow_cid = '<' . $user['id'] . '>';
|
||||
$allow_cid = '<' . $owner['id'] . '>';
|
||||
|
||||
$result = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 0, Photo::DEFAULT, $allow_cid);
|
||||
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 0, Photo::DEFAULT, $allow_cid);
|
||||
if (!$result) {
|
||||
$this->logger->warning('Photo::store() failed', ['result' => $result]);
|
||||
return $this->return(401, $this->t('Image upload failed.'));
|
||||
|
@ -233,7 +208,7 @@ class Upload extends \Friendica\BaseModule
|
|||
|
||||
if ($width > 640 || $height > 640) {
|
||||
$image->scaleDown(640);
|
||||
$result = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 1, Photo::DEFAULT, $allow_cid);
|
||||
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 1, Photo::DEFAULT, $allow_cid);
|
||||
if ($result) {
|
||||
$smallest = 1;
|
||||
}
|
||||
|
@ -241,14 +216,14 @@ class Upload extends \Friendica\BaseModule
|
|||
|
||||
if ($width > 320 || $height > 320) {
|
||||
$image->scaleDown(320);
|
||||
$result = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 2, Photo::DEFAULT, $allow_cid);
|
||||
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 2, Photo::DEFAULT, $allow_cid);
|
||||
if ($result && ($smallest == 0)) {
|
||||
$smallest = 2;
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->info('upload done');
|
||||
return $this->return(200, "\n\n" . '[url=' . $this->baseUrl . '/photos/' . $user['nickname'] . '/image/' . $resource_id . '][img]' . $this->baseUrl . "/photo/$resource_id-$smallest." . $image->getExt() . "[/img][/url]\n\n");
|
||||
return $this->return(200, "\n\n" . '[url=' . $this->baseUrl . '/photos/' . $owner['nickname'] . '/image/' . $resource_id . '][img]' . $this->baseUrl . "/photo/$resource_id-$smallest." . $image->getExt() . "[/img][/url]\n\n");
|
||||
}
|
||||
|
||||
/**
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Profile\Photos;
|
||||
namespace Friendica\Module\Profile;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Content\Pager;
|
||||
|
@ -40,7 +40,7 @@ use Friendica\Util\Images;
|
|||
use Friendica\Util\Profiler;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Index extends \Friendica\Module\BaseProfile
|
||||
class Photos extends \Friendica\Module\BaseProfile
|
||||
{
|
||||
/** @var IHandleUserSessions */
|
||||
private $session;
|
Loading…
Add table
Add a link
Reference in a new issue