kopia lustrzana https://github.com/nextcloud/social
Merge pull request #730 from nextcloud/feature/noid/disply-single-note
display single notepull/758/head
commit
34f8b1d8cc
|
|
@ -60,7 +60,7 @@ return [
|
|||
['name' => 'OStatus#followRemote', 'url' => '/api/v1/ostatus/followRemote/{local}', 'verb' => 'GET'],
|
||||
['name' => 'OStatus#getLink', 'url' => '/api/v1/ostatus/link/{local}/{account}', 'verb' => 'GET'],
|
||||
|
||||
['name' => 'SocialPub#displayPost', 'url' => '/@{username}/{postId}', 'verb' => 'GET'],
|
||||
['name' => 'ActivityPub#displayPost', 'url' => '/@{username}/{token}', 'verb' => 'GET'],
|
||||
|
||||
['name' => 'Local#streamHome', 'url' => '/api/v1/stream/home', 'verb' => 'GET'],
|
||||
['name' => 'Local#streamNotifications', 'url' => '/api/v1/stream/notifications', 'verb' => 'GET'],
|
||||
|
|
@ -71,7 +71,8 @@ return [
|
|||
['name' => 'Local#streamLiked', 'url' => '/api/v1/stream/liked', 'verb' => 'GET'],
|
||||
['name' => 'Local#streamAccount', 'url' => '/api/v1/account/{username}/stream', 'verb' => 'GET'],
|
||||
|
||||
['name' => 'Local#postData', 'url' => '/local/v1/post', 'verb' => 'GET'],
|
||||
['name' => 'Local#postGet', 'url' => '/local/v1/post', 'verb' => 'GET'],
|
||||
['name' => 'Local#postReplies', 'url' => '/local/v1/post/replies', 'verb' => 'GET'],
|
||||
|
||||
['name' => 'Local#postCreate', 'url' => '/api/v1/post', 'verb' => 'POST'],
|
||||
['name' => 'Local#postDelete', 'url' => '/api/v1/post', 'verb' => 'DELETE'],
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "f5575fb747924736058725f236d7fdae",
|
||||
"content-hash": "f93a783c86bad53b0b8486db3fc61380",
|
||||
"packages": [
|
||||
{
|
||||
"name": "daita/my-small-php-tools",
|
||||
|
|
@ -12,12 +12,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/daita/my-small-php-tools.git",
|
||||
"reference": "bea3a148a427d446511c23b1512686fa03835754"
|
||||
"reference": "ffc91a81c84ec679379b4b8a0a34434f3697c6e7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/bea3a148a427d446511c23b1512686fa03835754",
|
||||
"reference": "bea3a148a427d446511c23b1512686fa03835754",
|
||||
"url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/ffc91a81c84ec679379b4b8a0a34434f3697c6e7",
|
||||
"reference": "ffc91a81c84ec679379b4b8a0a34434f3697c6e7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
}
|
||||
],
|
||||
"description": "My small PHP Tools",
|
||||
"time": "2019-08-20T20:23:09+00:00"
|
||||
"time": "2019-09-15T08:55:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendica/json-ld",
|
||||
|
|
@ -448,26 +448,26 @@
|
|||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-docblock",
|
||||
"version": "4.3.1",
|
||||
"version": "4.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||
"reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c"
|
||||
"reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c",
|
||||
"reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e",
|
||||
"reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0",
|
||||
"phpdocumentor/reflection-common": "^1.0.0",
|
||||
"phpdocumentor/type-resolver": "^0.4.0",
|
||||
"phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0",
|
||||
"phpdocumentor/type-resolver": "~0.4 || ^1.0.0",
|
||||
"webmozart/assert": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/instantiator": "~1.0.5",
|
||||
"doctrine/instantiator": "^1.0.5",
|
||||
"mockery/mockery": "^1.0",
|
||||
"phpunit/phpunit": "^6.4"
|
||||
},
|
||||
|
|
@ -495,29 +495,29 @@
|
|||
}
|
||||
],
|
||||
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
||||
"time": "2019-04-30T17:48:53+00:00"
|
||||
"time": "2019-09-12T14:27:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/type-resolver",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||
"reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
|
||||
"reference": "cf842904952e64e703800d094cdf34e715a8a3ae"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
|
||||
"reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/cf842904952e64e703800d094cdf34e715a8a3ae",
|
||||
"reference": "cf842904952e64e703800d094cdf34e715a8a3ae",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5 || ^7.0",
|
||||
"php": "^7.0",
|
||||
"phpdocumentor/reflection-common": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9.4",
|
||||
"phpunit/phpunit": "^5.2||^4.8.24"
|
||||
"mockery/mockery": "^1.0",
|
||||
"phpunit/phpunit": "^6.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
|
@ -527,9 +527,7 @@
|
|||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpDocumentor\\Reflection\\": [
|
||||
"src/"
|
||||
]
|
||||
"phpDocumentor\\Reflection\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
|
|
@ -542,7 +540,7 @@
|
|||
"email": "me@mikevanriel.com"
|
||||
}
|
||||
],
|
||||
"time": "2017-07-14T14:27:02+00:00"
|
||||
"time": "2017-12-30T13:23:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
|
|
@ -1213,16 +1211,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
"version": "3.1.1",
|
||||
"version": "3.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/exporter.git",
|
||||
"reference": "06a9a5947f47b3029d76118eb5c22802e5869687"
|
||||
"reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/06a9a5947f47b3029d76118eb5c22802e5869687",
|
||||
"reference": "06a9a5947f47b3029d76118eb5c22802e5869687",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e",
|
||||
"reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1276,7 +1274,7 @@
|
|||
"export",
|
||||
"exporter"
|
||||
],
|
||||
"time": "2019-08-11T12:43:14+00:00"
|
||||
"time": "2019-09-14T09:02:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
|
|
@ -1659,16 +1657,16 @@
|
|||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/assert.git",
|
||||
"reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
|
||||
"reference": "88e6d84706d09a236046d686bbea96f07b3a34f4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
|
||||
"reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4",
|
||||
"reference": "88e6d84706d09a236046d686bbea96f07b3a34f4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1676,8 +1674,7 @@
|
|||
"symfony/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.6",
|
||||
"sebastian/version": "^1.0.1"
|
||||
"phpunit/phpunit": "^4.8.36 || ^7.5.13"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
|
@ -1706,7 +1703,7 @@
|
|||
"check",
|
||||
"validate"
|
||||
],
|
||||
"time": "2018-12-25T11:19:39+00:00"
|
||||
"time": "2019-08-24T08:43:50+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
|
|
|||
|
|
@ -38,14 +38,18 @@ use OC\AppFramework\Http;
|
|||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Exceptions\ItemUnknownException;
|
||||
use OCA\Social\Exceptions\SignatureIsGoneException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\StreamNotFoundException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Service\CacheActorService;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\FediverseService;
|
||||
use OCA\Social\Service\FollowService;
|
||||
use OCA\Social\Service\ImportService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCA\Social\Service\SignatureService;
|
||||
use OCA\Social\Service\StreamQueueService;
|
||||
use OCA\Social\Service\StreamService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IRequest;
|
||||
|
|
@ -80,6 +84,12 @@ class ActivityPubController extends Controller {
|
|||
/** @var FollowService */
|
||||
private $followService;
|
||||
|
||||
/** @var StreamService */
|
||||
private $streamService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
||||
|
|
@ -95,13 +105,16 @@ class ActivityPubController extends Controller {
|
|||
* @param StreamQueueService $streamQueueService
|
||||
* @param ImportService $importService
|
||||
* @param FollowService $followService
|
||||
* @param StreamService $streamService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IRequest $request, SocialPubController $socialPubController,
|
||||
FediverseService $fediverseService, CacheActorService $cacheActorService,
|
||||
SignatureService $signatureService, StreamQueueService $streamQueueService,
|
||||
ImportService $importService, FollowService $followService, MiscService $miscService
|
||||
ImportService $importService, FollowService $followService, StreamService $streamService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
parent::__construct(Application::APP_NAME, $request);
|
||||
|
||||
|
|
@ -112,6 +125,8 @@ class ActivityPubController extends Controller {
|
|||
$this->streamQueueService = $streamQueueService;
|
||||
$this->importService = $importService;
|
||||
$this->followService = $followService;
|
||||
$this->streamService = $streamService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
|
@ -131,6 +146,7 @@ class ActivityPubController extends Controller {
|
|||
*
|
||||
* @return Response
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function actor(string $username): Response {
|
||||
if (!$this->checkSourceActivityStreams()) {
|
||||
|
|
@ -162,6 +178,7 @@ class ActivityPubController extends Controller {
|
|||
*
|
||||
* @return Response
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function actorAlias(string $username): Response {
|
||||
return $this->actor($username);
|
||||
|
|
@ -227,7 +244,7 @@ class ActivityPubController extends Controller {
|
|||
$this->miscService->log('[<<] inbox: ' . $body, 1);
|
||||
|
||||
$requestTime = 0;
|
||||
$origin = $this->signatureService->checkRequest($this->request, $body,$requestTime);
|
||||
$origin = $this->signatureService->checkRequest($this->request, $body, $requestTime);
|
||||
$this->fediverseService->authorized($origin);
|
||||
|
||||
// TODO - check the recipient <-> username
|
||||
|
|
@ -281,9 +298,9 @@ class ActivityPubController extends Controller {
|
|||
*
|
||||
* @return Response
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function followers(string $username): Response {
|
||||
|
||||
if (!$this->checkSourceActivityStreams()) {
|
||||
return $this->socialPubController->followers($username);
|
||||
}
|
||||
|
|
@ -311,6 +328,7 @@ class ActivityPubController extends Controller {
|
|||
*
|
||||
* @return Response
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function following(string $username): Response {
|
||||
if (!$this->checkSourceActivityStreams()) {
|
||||
|
|
@ -328,16 +346,24 @@ class ActivityPubController extends Controller {
|
|||
* @PublicPage
|
||||
*
|
||||
* @param string $username
|
||||
* @param $postId
|
||||
* @param string $token
|
||||
*
|
||||
* @return Response
|
||||
* @throws SocialAppConfigException
|
||||
* @throws StreamNotFoundException
|
||||
*/
|
||||
public function displayPost($username, $postId) {
|
||||
public function displayPost(string $username, string $token): Response {
|
||||
if (!$this->checkSourceActivityStreams()) {
|
||||
return $this->socialPubController->displayPost($username, $postId);
|
||||
return $this->socialPubController->displayPost($username, $token);
|
||||
}
|
||||
|
||||
return $this->success([$username, $postId]);
|
||||
// TODO - check viewer rights !
|
||||
$postId = $this->configService->getSocialUrl() . '@' . $username . '/' . $token;
|
||||
$stream = $this->streamService->getStreamById($postId, false);
|
||||
|
||||
$stream->setCompleteDetails(false);
|
||||
|
||||
return $this->directSuccess($stream);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ declare(strict_types=1);
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace OCA\Social\Controller;
|
||||
|
||||
|
||||
|
|
@ -130,10 +131,10 @@ class LocalController extends Controller {
|
|||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IRequest $request, $userId, AccountService $accountService,
|
||||
CacheActorService $cacheActorService, HashtagService $hashtagService,
|
||||
FollowService $followService,
|
||||
PostService $postService, StreamService $streamService, SearchService $searchService,
|
||||
IRequest $request, $userId, AccountService $accountService, CacheActorService $cacheActorService,
|
||||
HashtagService $hashtagService,
|
||||
FollowService $followService, PostService $postService, StreamService $streamService,
|
||||
SearchService $searchService,
|
||||
BoostService $boostService, LikeService $likeService, DocumentService $documentService,
|
||||
MiscService $miscService
|
||||
) {
|
||||
|
|
@ -194,16 +195,42 @@ class LocalController extends Controller {
|
|||
* get info about a post (limited to viewer rights).
|
||||
*
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return DataResponse
|
||||
*/
|
||||
public function postData(string $id): DataResponse {
|
||||
public function postGet(string $id): DataResponse {
|
||||
try {
|
||||
$this->initViewer(true);
|
||||
|
||||
return $this->directSuccess($this->streamService->getStreamById($id, true));
|
||||
$stream = $this->streamService->getStreamById($id, true);
|
||||
|
||||
return $this->directSuccess($stream);
|
||||
} catch (Exception $e) {
|
||||
return $this->fail($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get replies about a post (limited to viewer rights).
|
||||
*
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @param string $id
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return DataResponse
|
||||
*/
|
||||
public function postReplies(string $id, int $since = 0, int $limit = 5): DataResponse {
|
||||
try {
|
||||
$this->initViewer(true);
|
||||
|
||||
return $this->success($this->streamService->getRepliesByParentId($id, $since, $limit, true));
|
||||
} catch (Exception $e) {
|
||||
return $this->fail($e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ use OCP\IL10N;
|
|||
use OCP\IRequest;
|
||||
use OCP\IURLGenerator;
|
||||
|
||||
|
||||
/**
|
||||
* Class NavigationController
|
||||
*
|
||||
* @package OCA\Social\Controller
|
||||
*/
|
||||
class NavigationController extends Controller {
|
||||
|
||||
|
||||
|
|
@ -88,6 +94,7 @@ class NavigationController extends Controller {
|
|||
/** @var CheckService */
|
||||
private $checkService;
|
||||
|
||||
|
||||
/**
|
||||
* NavigationController constructor.
|
||||
*
|
||||
|
|
@ -261,6 +268,7 @@ class NavigationController extends Controller {
|
|||
*
|
||||
* @return TemplateResponse
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function timeline(string $path = ''): TemplateResponse {
|
||||
return $this->navigate();
|
||||
|
|
@ -276,6 +284,7 @@ class NavigationController extends Controller {
|
|||
*
|
||||
* @return TemplateResponse
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function account(string $path = ''): TemplateResponse {
|
||||
return $this->navigate();
|
||||
|
|
|
|||
|
|
@ -31,14 +31,15 @@ namespace OCA\Social\Controller;
|
|||
|
||||
|
||||
use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse;
|
||||
|
||||
use Exception;
|
||||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Exceptions\CacheActorDoesNotExistException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\StreamNotFoundException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Service\AccountService;
|
||||
use OCA\Social\Service\CacheActorService;
|
||||
use OCA\Social\Service\FollowService;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\StreamService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
|
|
@ -47,28 +48,35 @@ use OCP\AppFramework\Http\TemplateResponse;
|
|||
use OCP\IL10N;
|
||||
use OCP\IRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Class SocialPubController
|
||||
*
|
||||
* @package OCA\Social\Controller
|
||||
*/
|
||||
class SocialPubController extends Controller {
|
||||
|
||||
|
||||
use TNCDataResponse;
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $userId;
|
||||
|
||||
/** @var IL10N */
|
||||
private $l10n;
|
||||
|
||||
/** @var AccountService */
|
||||
private $accountService;
|
||||
/** @var NavigationController */
|
||||
private $navigationController;
|
||||
|
||||
/** @var CacheActorService */
|
||||
private $cacheActorService;
|
||||
|
||||
/** @var FollowService */
|
||||
private $followService;
|
||||
/** @var StreamService */
|
||||
private $streamService;
|
||||
|
||||
/** @var NavigationController */
|
||||
private $navigationController;
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -77,36 +85,39 @@ class SocialPubController extends Controller {
|
|||
* @param $userId
|
||||
* @param IRequest $request
|
||||
* @param IL10N $l10n
|
||||
* @param CacheActorService $cacheActorService
|
||||
* @param NavigationController $navigationController
|
||||
* @param CacheActorService $cacheActorService
|
||||
* @param StreamService $streamService
|
||||
* @param ConfigService $configService
|
||||
*/
|
||||
public function __construct(
|
||||
$userId,
|
||||
IRequest $request,
|
||||
IL10N $l10n,
|
||||
CacheActorService $cacheActorService,
|
||||
NavigationController $navigationController
|
||||
$userId, IRequest $request, IL10N $l10n, NavigationController $navigationController,
|
||||
CacheActorService $cacheActorService, StreamService $streamService, ConfigService $configService
|
||||
) {
|
||||
parent::__construct(Application::APP_NAME, $request);
|
||||
|
||||
$this->userId = $userId;
|
||||
$this->l10n = $l10n;
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->navigationController = $navigationController;
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->streamService = $streamService;
|
||||
$this->configService = $configService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $username
|
||||
*
|
||||
* @return Response
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
private function renderPage($username): Response {
|
||||
if ($this->userId) {
|
||||
return $this->navigationController->navigate('');
|
||||
}
|
||||
$data = [
|
||||
'serverData' => [
|
||||
'serverData' => [
|
||||
'public' => true,
|
||||
],
|
||||
'application' => 'Social'
|
||||
|
|
@ -141,6 +152,7 @@ class SocialPubController extends Controller {
|
|||
*
|
||||
* @return Response
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function actor(string $username): Response {
|
||||
return $this->renderPage($username);
|
||||
|
|
@ -158,6 +170,7 @@ class SocialPubController extends Controller {
|
|||
*
|
||||
* @return TemplateResponse
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function followers(string $username): Response {
|
||||
return $this->renderPage($username);
|
||||
|
|
@ -175,6 +188,7 @@ class SocialPubController extends Controller {
|
|||
*
|
||||
* @return TemplateResponse
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function following(string $username): Response {
|
||||
return $this->renderPage($username);
|
||||
|
|
@ -182,19 +196,34 @@ class SocialPubController extends Controller {
|
|||
|
||||
|
||||
/**
|
||||
* Should return post, do nothing.
|
||||
* Display the navigation page of the Social app.
|
||||
*
|
||||
* @NoCSRFRequired
|
||||
* @PublicPage
|
||||
*
|
||||
* @param string $username
|
||||
* @param $postId
|
||||
* @param string $token
|
||||
*
|
||||
* @return Response
|
||||
* @return TemplateResponse
|
||||
* @throws StreamNotFoundException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function displayPost(string $username, int $postId) {
|
||||
return $this->success([$username, $postId]);
|
||||
public function displayPost(string $username, string $token): TemplateResponse {
|
||||
// TODO - check viewer rights !
|
||||
$postId = $this->configService->getSocialUrl() . '@' . $username . '/' . $token;
|
||||
$stream = $this->streamService->getStreamById($postId, false);
|
||||
$data = [
|
||||
'id' => $postId,
|
||||
'item' => $stream,
|
||||
'serverData' => [
|
||||
'public' => true,
|
||||
],
|
||||
'application' => 'Social'
|
||||
];
|
||||
|
||||
return new TemplateResponse(Application::APP_NAME, 'stream', $data);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,20 +43,6 @@ use OCP\IDBConnection;
|
|||
class ActorsRequest extends ActorsRequestBuilder {
|
||||
|
||||
|
||||
/**
|
||||
* ActorsRequest constructor.
|
||||
*
|
||||
* @param IDBConnection $connection
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IDBConnection $connection, ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
parent::__construct($connection, $configService, $miscService);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create a new Person in the database.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -35,29 +35,13 @@ use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
|||
use Exception;
|
||||
use OCA\Social\Exceptions\CacheActorDoesNotExistException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
class CacheActorsRequest extends CacheActorsRequestBuilder {
|
||||
|
||||
|
||||
const CACHE_TTL = 60 * 24; // 1d
|
||||
|
||||
/**
|
||||
* CacheActorsRequest constructor.
|
||||
*
|
||||
* @param IDBConnection $connection
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IDBConnection $connection, ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
parent::__construct($connection, $configService, $miscService);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* insert cache about an Actor in database.
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ use DateInterval;
|
|||
use DateTime;
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
use Exception;
|
||||
use OC;
|
||||
use OC\DB\SchemaWrapper;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Exceptions\DateTimeException;
|
||||
|
|
@ -48,6 +49,7 @@ use OCA\Social\Service\ConfigService;
|
|||
use OCA\Social\Service\MiscService;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\ILogger;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -88,6 +90,8 @@ class CoreRequestBuilder {
|
|||
self::TABLE_STREAM_ACTIONS
|
||||
];
|
||||
|
||||
protected $logger;
|
||||
|
||||
/** @var IDBConnection */
|
||||
protected $dbConnection;
|
||||
|
||||
|
|
@ -98,29 +102,53 @@ class CoreRequestBuilder {
|
|||
protected $miscService;
|
||||
|
||||
|
||||
/** @var string */
|
||||
protected $defaultSelectAlias;
|
||||
|
||||
/** @var Person */
|
||||
protected $viewer = null;
|
||||
|
||||
/** @var string */
|
||||
protected $defaultSelectAlias;
|
||||
|
||||
|
||||
/**
|
||||
* CoreRequestBuilder constructor.
|
||||
*
|
||||
* @param IDBConnection $connection
|
||||
* @param ILogger $logger
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IDBConnection $connection, ConfigService $configService, MiscService $miscService
|
||||
IDBConnection $connection, ILogger $logger, ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
$this->dbConnection = $connection;
|
||||
$this->logger = $logger;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return SocialQueryBuilder
|
||||
*/
|
||||
public function getQueryBuilder(): SocialQueryBuilder {
|
||||
$qb = new SocialQueryBuilder(
|
||||
$this->dbConnection,
|
||||
OC::$server->getSystemConfig(),
|
||||
$this->logger
|
||||
);
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return IDBConnection
|
||||
*/
|
||||
public function getConnection(): IDBConnection {
|
||||
return $this->dbConnection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $viewer
|
||||
*/
|
||||
|
|
@ -198,6 +226,17 @@ class CoreRequestBuilder {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the Id (string)
|
||||
*
|
||||
* @param IQueryBuilder $qb
|
||||
* @param string $id
|
||||
*/
|
||||
protected function limitToInReplyTo(IQueryBuilder &$qb, string $id) {
|
||||
$this->limitToDBField($qb, 'in_reply_to', $id, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the StreamId
|
||||
*
|
||||
|
|
@ -257,7 +296,7 @@ class CoreRequestBuilder {
|
|||
* @param string $username
|
||||
*/
|
||||
protected function searchInPreferredUsername(IQueryBuilder &$qb, string $username) {
|
||||
$dbConn = $this->dbConnection;
|
||||
$dbConn = $this->getConnection();
|
||||
$this->searchInDBField(
|
||||
$qb, 'preferred_username', $dbConn->escapeLikeParameter($username) . '%'
|
||||
);
|
||||
|
|
@ -314,7 +353,7 @@ class CoreRequestBuilder {
|
|||
* @param bool $all
|
||||
*/
|
||||
protected function searchInHashtag(IQueryBuilder &$qb, string $hashtag, bool $all = false) {
|
||||
$dbConn = $this->dbConnection;
|
||||
$dbConn = $this->getConnection();
|
||||
$this->searchInDBField(
|
||||
$qb, 'hashtag', (($all) ? '%' : '') . $dbConn->escapeLikeParameter($hashtag) . '%'
|
||||
);
|
||||
|
|
@ -385,7 +424,7 @@ class CoreRequestBuilder {
|
|||
* @param string $account
|
||||
*/
|
||||
protected function searchInAccount(IQueryBuilder &$qb, string $account) {
|
||||
$dbConn = $this->dbConnection;
|
||||
$dbConn = $this->getConnection();
|
||||
$this->searchInDBField($qb, 'account', $dbConn->escapeLikeParameter($account) . '%');
|
||||
}
|
||||
|
||||
|
|
@ -493,13 +532,17 @@ class CoreRequestBuilder {
|
|||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws DateTimeException
|
||||
*/
|
||||
protected function limitPaginate(IQueryBuilder &$qb, int $since = 0, int $limit = 5) {
|
||||
if ($since > 0) {
|
||||
$dTime = new DateTime();
|
||||
$dTime->setTimestamp($since);
|
||||
$this->limitToDBFieldDateTime($qb, 'published_time', $dTime);
|
||||
try {
|
||||
if ($since > 0) {
|
||||
$dTime = new DateTime();
|
||||
$dTime->setTimestamp($since);
|
||||
$this->limitToDBFieldDateTime($qb, 'published_time', $dTime);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new DateTimeException();
|
||||
}
|
||||
|
||||
$qb->setMaxResults($limit);
|
||||
|
|
@ -507,6 +550,8 @@ class CoreRequestBuilder {
|
|||
$qb->orderBy($pf . '.published_time', 'desc');
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
/**
|
||||
* @param IQueryBuilder $qb
|
||||
|
|
@ -1160,9 +1205,7 @@ class CoreRequestBuilder {
|
|||
* @param string $fieldActorId
|
||||
* @param string $pf
|
||||
*/
|
||||
protected function leftJoinDetails(
|
||||
IQueryBuilder $qb, string $fieldActorId = 'id', string $pf = ''
|
||||
) {
|
||||
protected function leftJoinDetails(IQueryBuilder $qb, string $fieldActorId = 'id', string $pf = '') {
|
||||
$this->leftJoinFollowAsViewer($qb, $fieldActorId, true, 'as_follower', $pf);
|
||||
$this->leftJoinFollowAsViewer($qb, $fieldActorId, false, 'as_followed', $pf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,343 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace OCA\Social\Db;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Db\ExtendedQueryBuilder;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
|
||||
|
||||
/**
|
||||
* Class SocialQueryBuilder
|
||||
*
|
||||
* @package OCA\Push\Db
|
||||
*/
|
||||
class SocialQueryBuilder extends ExtendedQueryBuilder {
|
||||
|
||||
|
||||
/** @var Person */
|
||||
private $viewer = null;
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasViewer(): bool {
|
||||
return ($this->viewer !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Person $viewer
|
||||
*/
|
||||
public function setViewer(Person $viewer): void {
|
||||
$this->viewer = $viewer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Person
|
||||
*/
|
||||
public function getViewer(): Person {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
public function generatePrimaryKey(string $id) {
|
||||
$this->setValue('id_prim', $this->createNamedParameter(hash('sha512', $id)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the Type
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return SocialQueryBuilder
|
||||
*/
|
||||
public function limitToType(string $type): self {
|
||||
$this->limitToDBField('type', $type, false);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the ActivityId
|
||||
*
|
||||
* @param string $activityId
|
||||
*/
|
||||
protected function limitToActivityId(string $activityId) {
|
||||
$this->limitToDBField('activity_id', $activityId, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the Id (string)
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
protected function limitToInReplyTo(string $id) {
|
||||
$this->limitToDBField('in_reply_to', $id, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the sub-type
|
||||
*
|
||||
* @param string $subType
|
||||
*/
|
||||
protected function limitToSubType(string $subType) {
|
||||
$this->limitToDBField('subtype', $subType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*/
|
||||
protected function filterType(string $type) {
|
||||
$this->filterDBField('type', $type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the Preferred Username
|
||||
*
|
||||
* @param string $username
|
||||
*/
|
||||
protected function limitToPreferredUsername(string $username) {
|
||||
$this->limitToDBField('preferred_username', $username, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* search using username
|
||||
*
|
||||
* @param string $username
|
||||
*/
|
||||
protected function searchInPreferredUsername(string $username) {
|
||||
$dbConn = $this->getConnection();
|
||||
$this->searchInDBField('preferred_username', $dbConn->escapeLikeParameter($username) . '%');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the ActorId
|
||||
*/
|
||||
protected function limitToPublic() {
|
||||
$this->limitToDBFieldInt('public', 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the token
|
||||
*
|
||||
* @param string $token
|
||||
*/
|
||||
protected function limitToToken(string $token) {
|
||||
$this->limitToDBField('token', $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the results to a given number
|
||||
*
|
||||
* @param int $limit
|
||||
*/
|
||||
protected function limitResults(int $limit) {
|
||||
$this->setMaxResults($limit);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the ActorId
|
||||
*
|
||||
* @param string $hashtag
|
||||
*/
|
||||
protected function limitToHashtag(string $hashtag) {
|
||||
$this->limitToDBField('hashtag', $hashtag, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the ActorId
|
||||
*
|
||||
* @param string $hashtag
|
||||
* @param bool $all
|
||||
*/
|
||||
protected function searchInHashtag(string $hashtag, bool $all = false) {
|
||||
$dbConn = $this->getConnection();
|
||||
$this->searchInDBField('hashtag', (($all) ? '%' : '') . $dbConn->escapeLikeParameter($hashtag) . '%');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the ActorId
|
||||
*
|
||||
* @param string $actorId
|
||||
* @param string $alias
|
||||
*/
|
||||
protected function limitToActorId(string $actorId, string $alias = '') {
|
||||
$this->limitToDBField('actor_id', $actorId, false, $alias);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the FollowId
|
||||
*
|
||||
* @param string $followId
|
||||
*/
|
||||
protected function limitToFollowId(string $followId) {
|
||||
$this->limitToDBField('follow_id', $followId, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the FollowId
|
||||
*
|
||||
* @param bool $accepted
|
||||
* @param string $alias
|
||||
*/
|
||||
protected function limitToAccepted(bool $accepted, string $alias = '') {
|
||||
$this->limitToDBField('accepted', ($accepted) ? '1' : '0', true, $alias);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the ServiceId
|
||||
*
|
||||
* @param string $objectId
|
||||
*/
|
||||
protected function limitToObjectId(string $objectId) {
|
||||
$this->limitToDBField('object_id', $objectId, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the account
|
||||
*
|
||||
* @param string $account
|
||||
*/
|
||||
protected function limitToAccount(string $account) {
|
||||
$this->limitToDBField('account', $account, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the account
|
||||
*
|
||||
* @param string $account
|
||||
*/
|
||||
protected function searchInAccount(string $account) {
|
||||
$dbConn = $this->getConnection();
|
||||
$this->searchInDBField('account', $dbConn->escapeLikeParameter($account) . '%');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the creation
|
||||
*
|
||||
* @param int $delay
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function limitToCaching(int $delay = 0) {
|
||||
$date = new DateTime('now');
|
||||
$date->sub(new DateInterval('PT' . $delay . 'M'));
|
||||
|
||||
$this->limitToDBFieldDateTime('caching', $date, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the url
|
||||
*
|
||||
* @param string $url
|
||||
*/
|
||||
protected function limitToUrl(string $url) {
|
||||
$this->limitToDBField('url', $url);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the url
|
||||
*
|
||||
* @param string $actorId
|
||||
*/
|
||||
protected function limitToAttributedTo(string $actorId) {
|
||||
$this->limitToDBField('attributed_to', $actorId, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the status
|
||||
*
|
||||
* @param int $status
|
||||
*/
|
||||
protected function limitToStatus(int $status) {
|
||||
$this->limitToDBFieldInt('status', $status);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the instance
|
||||
*
|
||||
* @param string $address
|
||||
*/
|
||||
protected function limitToAddress(string $address) {
|
||||
$this->limitToDBField('address', $address);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the instance
|
||||
*
|
||||
* @param bool $local
|
||||
*/
|
||||
protected function limitToLocal(bool $local) {
|
||||
$this->limitToDBField('local', ($local) ? '1' : '0');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limit the request to the parent_id
|
||||
*
|
||||
* @param string $parentId
|
||||
*/
|
||||
protected function limitToParentId(string $parentId) {
|
||||
$this->limitToDBField('parent_id', $parentId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -51,6 +51,7 @@ use OCA\Social\Service\ConfigService;
|
|||
use OCA\Social\Service\MiscService;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\ILogger;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -69,15 +70,16 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
* StreamRequest constructor.
|
||||
*
|
||||
* @param IDBConnection $connection
|
||||
* @param ILogger $logger
|
||||
* @param StreamDestRequest $streamDestRequest
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IDBConnection $connection, StreamDestRequest $streamDestRequest, ConfigService $configService,
|
||||
MiscService $miscService
|
||||
IDBConnection $connection, ILogger $logger, StreamDestRequest $streamDestRequest,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
parent::__construct($connection, $configService, $miscService);
|
||||
parent::__construct($connection, $logger, $configService, $miscService);
|
||||
|
||||
$this->streamDestRequest = $streamDestRequest;
|
||||
}
|
||||
|
|
@ -171,7 +173,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
* @param Document $document
|
||||
* @param array $attachments
|
||||
*
|
||||
* @return array
|
||||
* @return Document[]
|
||||
*/
|
||||
private function updateAttachmentInList(Document $document, array $attachments): array {
|
||||
$new = [];
|
||||
|
|
@ -216,17 +218,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$this->limitToType($qb, $type);
|
||||
}
|
||||
|
||||
$streams = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
try {
|
||||
$streams[] = $this->parseStreamSelectSql($data);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $streams;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -236,6 +228,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
*
|
||||
* @return Stream
|
||||
* @throws StreamNotFoundException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function getStreamById(string $id, bool $asViewer = false): Stream {
|
||||
if ($id === '') {
|
||||
|
|
@ -251,23 +244,46 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$this->leftJoinStreamAction($qb);
|
||||
}
|
||||
|
||||
$cursor = $qb->execute();
|
||||
$data = $cursor->fetch();
|
||||
$cursor->closeCursor();
|
||||
|
||||
if ($data === false) {
|
||||
try {
|
||||
return $this->getStreamFromRequest($qb);
|
||||
} catch (ItemUnknownException $e) {
|
||||
throw new StreamNotFoundException('Malformed Stream');
|
||||
} catch (StreamNotFoundException $e) {
|
||||
throw new StreamNotFoundException(
|
||||
'Stream (ById) not found - ' . $id . ' (asViewer: ' . $asViewer . ')'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$stream = $this->parseStreamSelectSql($data);
|
||||
} catch (Exception $e) {
|
||||
throw new StreamNotFoundException('Malformed Stream');
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
* @param bool $asViewer
|
||||
*
|
||||
* @return Stream[]
|
||||
* @throws StreamNotFoundException
|
||||
* @throws DateTimeException
|
||||
*/
|
||||
public function getRepliesByParentId(string $id, int $since = 0, int $limit = 5, bool $asViewer = false
|
||||
): array {
|
||||
if ($id === '') {
|
||||
throw new StreamNotFoundException();
|
||||
};
|
||||
|
||||
$qb = $this->getStreamSelectSql();
|
||||
$this->limitToInReplyTo($qb, $id);
|
||||
$this->limitPaginate($qb, $since, $limit);
|
||||
$this->leftJoinCacheActors($qb, 'attributed_to');
|
||||
|
||||
if ($asViewer) {
|
||||
$this->limitToViewer($qb);
|
||||
$this->leftJoinStreamAction($qb);
|
||||
}
|
||||
|
||||
return $stream;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -286,15 +302,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$qb = $this->getStreamSelectSql();
|
||||
$this->limitToActivityId($qb, $id);
|
||||
|
||||
$cursor = $qb->execute();
|
||||
$data = $cursor->fetch();
|
||||
$cursor->closeCursor();
|
||||
|
||||
if ($data === false) {
|
||||
throw new StreamNotFoundException('Stream (ByActivityId) not found - ' . $id);
|
||||
}
|
||||
|
||||
return $this->parseStreamSelectSql($data);
|
||||
return $this->getStreamFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -319,17 +327,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$this->limitToType($qb, $type);
|
||||
$this->limitToSubType($qb, $subType);
|
||||
|
||||
$cursor = $qb->execute();
|
||||
$data = $cursor->fetch();
|
||||
$cursor->closeCursor();
|
||||
|
||||
if ($data === false) {
|
||||
throw new StreamNotFoundException(
|
||||
'StreamByObjectId not found - ' . $type . ' - ' . $objectId
|
||||
);
|
||||
}
|
||||
|
||||
return $this->parseStreamSelectSql($data);
|
||||
return $this->getStreamFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -362,7 +360,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
* @param int $limit
|
||||
*
|
||||
* @return Stream[]
|
||||
* @throws Exception
|
||||
* @throws DateTimeException
|
||||
*/
|
||||
public function getTimelineHome(Person $actor, int $since = 0, int $limit = 5): array {
|
||||
$qb = $this->getStreamSelectSql();
|
||||
|
|
@ -379,17 +377,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$this->leftJoinStreamAction($qb);
|
||||
$this->filterDuplicate($qb);
|
||||
|
||||
$streams = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
try {
|
||||
$streams[] = $this->parseStreamSelectSql($data);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $streams;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -405,8 +393,8 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @return Stream[]
|
||||
* @throws DateTimeException
|
||||
*/
|
||||
public function getTimelineNotifications(Person $actor, int $since = 0, int $limit = 5): array {
|
||||
$qb = $this->getStreamSelectSql();
|
||||
|
|
@ -418,17 +406,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$this->leftJoinCacheActors($qb, 'attributed_to');
|
||||
$this->leftJoinStreamAction($qb);
|
||||
|
||||
$streams = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
try {
|
||||
$streams[] = $this->parseStreamSelectSql($data);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $streams;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -441,8 +419,8 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @return Stream[]
|
||||
* @throws DateTimeException
|
||||
*/
|
||||
public function getTimelineAccount(string $actorId, int $since = 0, int $limit = 5): array {
|
||||
$qb = $this->getStreamSelectSql();
|
||||
|
|
@ -454,17 +432,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$this->leftJoinCacheActors($qb, 'attributed_to');
|
||||
$this->leftJoinStreamAction($qb);
|
||||
|
||||
$streams = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
try {
|
||||
$streams[] = $this->parseStreamSelectSql($data);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $streams;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -477,8 +445,8 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @return Stream[]
|
||||
* @throws DateTimeException
|
||||
*/
|
||||
public function getTimelineDirect(Person $actor, int $since = 0, int $limit = 5): array {
|
||||
$qb = $this->getStreamSelectSql();
|
||||
|
|
@ -492,17 +460,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
|
||||
$this->leftJoinCacheActors($qb, 'attributed_to');
|
||||
|
||||
$streams = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
try {
|
||||
$streams[] = $this->parseStreamSelectSql($data);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $streams;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -514,8 +472,8 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
* @param int $limit
|
||||
* @param bool $localOnly
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @return Stream[]
|
||||
* @throws DateTimeException
|
||||
*/
|
||||
public function getTimelineGlobal(int $since = 0, int $limit = 5, bool $localOnly = true
|
||||
): array {
|
||||
|
|
@ -531,17 +489,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
// TODO: to: = real public, cc: = unlisted !?
|
||||
$this->limitToRecipient($qb, ACore::CONTEXT_PUBLIC, true, ['to']);
|
||||
|
||||
$streams = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
try {
|
||||
$streams[] = $this->parseStreamSelectSql($data);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $streams;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -553,8 +501,8 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
* @param int $limit
|
||||
* @param bool $localOnly
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @return Stream[]
|
||||
* @throws DateTimeException
|
||||
*/
|
||||
public function getTimelineLiked(int $since = 0, int $limit = 5, bool $localOnly = true): array {
|
||||
$qb = $this->getStreamSelectSql();
|
||||
|
|
@ -567,17 +515,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$this->leftJoinActions($qb, Like::TYPE);
|
||||
$this->filterDBField($qb, 'id', '', false, 'a');
|
||||
|
||||
$streams = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
try {
|
||||
$streams[] = $this->parseStreamSelectSql($data);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $streams;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -592,8 +530,8 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @return Stream[]
|
||||
* @throws DateTimeException
|
||||
*/
|
||||
public function getTimelineTag(Person $actor, string $hashtag, int $since = 0, int $limit = 5
|
||||
): array {
|
||||
|
|
@ -612,14 +550,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$this->leftJoinCacheActors($qb, 'attributed_to');
|
||||
$this->leftJoinStreamAction($qb);
|
||||
|
||||
$streams = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
$streams[] = $this->parseStreamSelectSql($data);
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $streams;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -628,8 +559,6 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
*
|
||||
* @return Stream[]
|
||||
* @throws DateTimeException
|
||||
* @throws ItemUnknownException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function getNoteSince(int $since): array {
|
||||
$qb = $this->getStreamSelectSql();
|
||||
|
|
@ -637,14 +566,7 @@ class StreamRequest extends StreamRequestBuilder {
|
|||
$this->limitToType($qb, Note::TYPE);
|
||||
$this->leftJoinStreamAction($qb);
|
||||
|
||||
$streams = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
$streams[] = $this->parseStreamSelectSql($data, Note::TYPE);
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $streams;
|
||||
return $this->getStreamsFromRequest($qb);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,14 @@ namespace OCA\Social\Db;
|
|||
|
||||
|
||||
use daita\MySmallPhpTools\Exceptions\CacheItemNotFoundException;
|
||||
use daita\MySmallPhpTools\Exceptions\RowNotFoundException;
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Exceptions\ItemUnknownException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\StreamNotFoundException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Announce;
|
||||
|
|
@ -60,11 +62,11 @@ class StreamRequestBuilder extends CoreRequestBuilder {
|
|||
/**
|
||||
* Base of the Sql Insert request
|
||||
*
|
||||
* @return IQueryBuilder
|
||||
* @return SocialQueryBuilder
|
||||
*/
|
||||
protected function getStreamInsertSql(): IQueryBuilder {
|
||||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
$qb->insert(self::TABLE_STREAM);
|
||||
protected function getStreamInsertSql(): SocialQueryBuilder {
|
||||
$qb = $this->getQueryBuilder();
|
||||
$qb->insert(self::TABLE_STREAMS);
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
|
@ -73,11 +75,11 @@ class StreamRequestBuilder extends CoreRequestBuilder {
|
|||
/**
|
||||
* Base of the Sql Update request
|
||||
*
|
||||
* @return IQueryBuilder
|
||||
* @return SocialQueryBuilder
|
||||
*/
|
||||
protected function getStreamUpdateSql(): IQueryBuilder {
|
||||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
$qb->update(self::TABLE_STREAM);
|
||||
protected function getStreamUpdateSql(): SocialQueryBuilder {
|
||||
$qb = $this->getQueryBuilder();
|
||||
$qb->update(self::TABLE_STREAMS);
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
|
@ -86,10 +88,10 @@ class StreamRequestBuilder extends CoreRequestBuilder {
|
|||
/**
|
||||
* Base of the Sql Select request for Shares
|
||||
*
|
||||
* @return IQueryBuilder
|
||||
* @return SocialQueryBuilder
|
||||
*/
|
||||
protected function getStreamSelectSql(): IQueryBuilder {
|
||||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
protected function getStreamSelectSql(): SocialQueryBuilder {
|
||||
$qb = $this->getQueryBuilder();
|
||||
|
||||
/** @noinspection PhpMethodParametersCountMismatchInspection */
|
||||
$qb->selectDistinct('s.id')
|
||||
|
|
@ -110,10 +112,10 @@ class StreamRequestBuilder extends CoreRequestBuilder {
|
|||
/**
|
||||
* Base of the Sql Select request for Shares
|
||||
*
|
||||
* @return IQueryBuilder
|
||||
* @return SocialQueryBuilder
|
||||
*/
|
||||
protected function countNotesSelectSql(): IQueryBuilder {
|
||||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
protected function countNotesSelectSql(): SocialQueryBuilder {
|
||||
$qb = $this->getQueryBuilder();
|
||||
$qb->selectAlias($qb->createFunction('COUNT(*)'), 'count')
|
||||
->from(self::TABLE_STREAM, 's');
|
||||
|
||||
|
|
@ -126,11 +128,11 @@ class StreamRequestBuilder extends CoreRequestBuilder {
|
|||
/**
|
||||
* Base of the Sql Delete request
|
||||
*
|
||||
* @return IQueryBuilder
|
||||
* @return SocialQueryBuilder
|
||||
*/
|
||||
protected function getStreamDeleteSql(): IQueryBuilder {
|
||||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
$qb->delete(self::TABLE_STREAM);
|
||||
protected function getStreamDeleteSql(): SocialQueryBuilder {
|
||||
$qb = $this->getQueryBuilder();
|
||||
$qb->delete(self::TABLE_STREAMS);
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
|
@ -321,9 +323,8 @@ class StreamRequestBuilder extends CoreRequestBuilder {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function exprValueWithinJsonFormat(IQueryBuilder $qb, string $field, string $value
|
||||
): string {
|
||||
$dbConn = $this->dbConnection;
|
||||
protected function exprValueWithinJsonFormat(IQueryBuilder $qb, string $field, string $value): string {
|
||||
$dbConn = $this->getConnection();
|
||||
$expr = $qb->expr();
|
||||
|
||||
return $expr->iLike(
|
||||
|
|
@ -340,9 +341,8 @@ class StreamRequestBuilder extends CoreRequestBuilder {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function exprValueNotWithinJsonFormat(IQueryBuilder $qb, string $field, string $value
|
||||
): string {
|
||||
$dbConn = $this->dbConnection;
|
||||
protected function exprValueNotWithinJsonFormat(IQueryBuilder $qb, string $field, string $value): string {
|
||||
$dbConn = $this->getConnection();
|
||||
$expr = $qb->expr();
|
||||
$func = $qb->func();
|
||||
|
||||
|
|
@ -447,6 +447,37 @@ class StreamRequestBuilder extends CoreRequestBuilder {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param SocialQueryBuilder $qb
|
||||
*
|
||||
* @return Stream
|
||||
* @throws StreamNotFoundException
|
||||
*/
|
||||
protected function getStreamFromRequest(SocialQueryBuilder $qb): Stream {
|
||||
/** @var Stream $result */
|
||||
try {
|
||||
$result = $qb->getRow([$this, 'parseStreamSelectSql']);
|
||||
} catch (RowNotFoundException $e) {
|
||||
throw new StreamNotFoundException($e->getMessage());
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param SocialQueryBuilder $qb
|
||||
*
|
||||
* @return Stream[]
|
||||
*/
|
||||
public function getStreamsFromRequest(SocialQueryBuilder $qb): array {
|
||||
/** @var Stream[] $result */
|
||||
$result = $qb->getRows([$this, 'parseStreamSelectSql']);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param string $as
|
||||
|
|
@ -455,7 +486,7 @@ class StreamRequestBuilder extends CoreRequestBuilder {
|
|||
* @throws ItemUnknownException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
protected function parseStreamSelectSql(array $data, string $as = Stream::TYPE): Stream {
|
||||
public function parseStreamSelectSql(array $data, string $as = Stream::TYPE): Stream {
|
||||
if ($as === Stream::TYPE) {
|
||||
$as = $this->get('type', $data, Stream::TYPE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ declare(strict_types=1);
|
|||
namespace OCA\Social\Model\ActivityPub;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\IQueryRow;
|
||||
use daita\MySmallPhpTools\Model\Cache;
|
||||
use daita\MySmallPhpTools\Model\CacheItem;
|
||||
use DateTime;
|
||||
|
|
@ -39,7 +40,12 @@ use OCA\Social\Model\StreamAction;
|
|||
use OCA\Social\Traits\TDetails;
|
||||
|
||||
|
||||
class Stream extends ACore implements JsonSerializable {
|
||||
/**
|
||||
* Class Stream
|
||||
*
|
||||
* @package OCA\Social\Model\ActivityPub
|
||||
*/
|
||||
class Stream extends ACore implements IQueryRow, JsonSerializable {
|
||||
|
||||
|
||||
use TDetails;
|
||||
|
|
@ -396,8 +402,7 @@ class Stream extends ACore implements JsonSerializable {
|
|||
[
|
||||
'content' => $this->getContent(),
|
||||
'attributedTo' => ($this->getAttributedTo() !== '') ? $this->getUrlSocial()
|
||||
. $this->getAttributedTo(
|
||||
) : '',
|
||||
. $this->getAttributedTo() : '',
|
||||
'inReplyTo' => $this->getInReplyTo(),
|
||||
'sensitive' => $this->isSensitive(),
|
||||
'conversation' => $this->getConversation()
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ use OCA\Social\Db\FollowsRequest;
|
|||
use OCA\Social\Db\StreamRequest;
|
||||
use OCA\Social\Exceptions\AccountAlreadyExistsException;
|
||||
use OCA\Social\Exceptions\ActorDoesNotExistException;
|
||||
use OCA\Social\Exceptions\ItemAlreadyExistsException;
|
||||
use OCA\Social\Exceptions\ItemUnknownException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
|
|
@ -161,6 +162,7 @@ class AccountService {
|
|||
* @throws NoUserException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
* @throws ItemAlreadyExistsException
|
||||
*/
|
||||
public function getActorFromUserId(string $userId, bool $create = false): Person {
|
||||
$this->miscService->confirmUserId($userId);
|
||||
|
|
@ -192,6 +194,7 @@ class AccountService {
|
|||
* @param string $username
|
||||
*
|
||||
* @throws AccountAlreadyExistsException
|
||||
* @throws ItemAlreadyExistsException
|
||||
* @throws NoUserException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
|
|
@ -238,6 +241,7 @@ class AccountService {
|
|||
*
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
* @throws ItemAlreadyExistsException
|
||||
*/
|
||||
public function cacheLocalActorByUsername(string $username) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ class FediverseService {
|
|||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function authorized(string $address): bool {
|
||||
if ($address === '') {
|
||||
throw new UnauthorizedFediverseException('Empty Origin');
|
||||
}
|
||||
|
||||
if ($this->getAccessType() ===
|
||||
$this->configService->accessTypeList['BLACKLIST']
|
||||
&& !$this->isListed($address)) {
|
||||
|
|
|
|||
|
|
@ -262,6 +262,8 @@ class SignatureService {
|
|||
throw new SignatureIsGoneException();
|
||||
} catch (SignatureException $e) {
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ use OCA\Social\Db\StreamRequest;
|
|||
use OCA\Social\Exceptions\InvalidOriginException;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Exceptions\ItemUnknownException;
|
||||
use OCA\Social\Exceptions\StreamNotFoundException;
|
||||
use OCA\Social\Exceptions\RedundancyLimitException;
|
||||
use OCA\Social\Exceptions\RequestContentException;
|
||||
use OCA\Social\Exceptions\RequestNetworkException;
|
||||
|
|
@ -44,6 +43,7 @@ use OCA\Social\Exceptions\RequestResultNotJsonException;
|
|||
use OCA\Social\Exceptions\RequestResultSizeException;
|
||||
use OCA\Social\Exceptions\RequestServerException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\StreamNotFoundException;
|
||||
use OCA\Social\Exceptions\UnauthorizedFediverseException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
|
|
@ -383,12 +383,27 @@ class StreamService {
|
|||
*
|
||||
* @return Stream
|
||||
* @throws StreamNotFoundException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function getStreamById(string $id, bool $asViewer = false): Stream {
|
||||
return $this->streamRequest->getStreamById($id, $asViewer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
* @param bool $asViewer
|
||||
*
|
||||
* @return Stream[]
|
||||
* @throws StreamNotFoundException
|
||||
*/
|
||||
public function getRepliesByParentId(string $id, int $since = 0, int $limit = 5, bool $asViewer = false): array {
|
||||
return $this->streamRequest->getRepliesByParentId($id, $since, $limit, $asViewer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
* @param int $since
|
||||
|
|
|
|||
Plik diff jest za duży
Load Diff
|
|
@ -31,6 +31,8 @@
|
|||
"linkifyjs": "^2.1.8",
|
||||
"nextcloud-axios": "^0.2.1",
|
||||
"nextcloud-vue": "^0.12.3",
|
||||
"nextcloud-logger": "0.0.6",
|
||||
"nextcloud-auth": "0.0.3",
|
||||
"tributejs": "^3.7.3",
|
||||
"twemoji": "^12.0.1",
|
||||
"uuid": "^3.3.3",
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ export default {
|
|||
// importing server data into the store
|
||||
const serverDataElmt = document.getElementById('serverData')
|
||||
if (serverDataElmt !== null) {
|
||||
this.$store.commit('setServerData', JSON.parse(document.getElementById('serverData').dataset.server))
|
||||
this.$store.commit('setServerData', JSON.parse(serverDataElmt.dataset.server))
|
||||
}
|
||||
|
||||
if (!this.serverData.public) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="timeline-entry">
|
||||
<div class="timeline-entry" @click="getSinglePostTimeline">
|
||||
<div v-if="item.type === 'SocialAppNotification'">
|
||||
{{ actionSummary }}
|
||||
</div>
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Logger from '../logger'
|
||||
import TimelinePost from './TimelinePost.vue'
|
||||
|
||||
export default {
|
||||
|
|
@ -94,6 +95,35 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
getSinglePostTimeline(e) {
|
||||
|
||||
// Do not call the single-post view when clicking on a link, a post attachment miniature or the post's author
|
||||
if (e.target.tagName === 'A' || e.target.tagName === 'IMG' || e.target.className.startsWith('post-author')) {
|
||||
Logger.debug('will not call single-post', { event: e })
|
||||
return
|
||||
}
|
||||
|
||||
// Display internal or external post
|
||||
if (!this.item.local) {
|
||||
if (this.item.type === 'Note') {
|
||||
window.open(this.item.id)
|
||||
} else if (this.item.type === 'Announce') {
|
||||
window.open(this.item.object)
|
||||
} else {
|
||||
Logger.warn("Don't know what to do with posts of type " + this.item.type, { post: this.item })
|
||||
}
|
||||
} else {
|
||||
this.$router.push({ name: 'single-post',
|
||||
params: {
|
||||
account: this.item.actor_info.preferredUsername,
|
||||
id: this.item.id,
|
||||
localId: this.item.id.split('/')[this.item.id.split('/').length - 1],
|
||||
type: 'single-post'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
userDisplayName(actorInfo) {
|
||||
return actorInfo.name !== '' ? actorInfo.name : actorInfo.preferredUsername
|
||||
}
|
||||
|
|
@ -105,6 +135,9 @@ export default {
|
|||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.timeline-entry:hover {
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.container-icon-boost {
|
||||
display: inline-block;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { getLoggerBuilder } from 'nextcloud-logger'
|
||||
import { getCurrentUser } from 'nextcloud-auth'
|
||||
|
||||
export default getLoggerBuilder()
|
||||
.setApp('social')
|
||||
.setUid(getCurrentUser().uid)
|
||||
.build()
|
||||
|
|
@ -26,6 +26,7 @@ import Router from 'vue-router'
|
|||
|
||||
// Dynamic loading
|
||||
const Timeline = () => import('./views/Timeline')
|
||||
const TimelineSinglePost = () => import('./views/TimelineSinglePost')
|
||||
const Profile = () => import(/* webpackChunkName: "profile" */'./views/Profile')
|
||||
const ProfileTimeline = () => import(/* webpackChunkName: "profile" */'./views/ProfileTimeline')
|
||||
const ProfileFollowers = () => import(/* webpackChunkName: "profile" */'./views/ProfileFollowers')
|
||||
|
|
@ -57,6 +58,14 @@ export default new Router({
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/:index(index.php/)?apps/social/@:account/:localId',
|
||||
components: {
|
||||
default: TimelineSinglePost
|
||||
},
|
||||
props: true,
|
||||
name: 'single-post'
|
||||
},
|
||||
{
|
||||
path: '/:index(index.php/)?apps/social/@:account',
|
||||
components: {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import Logger from '../logger'
|
||||
import axios from 'nextcloud-axios'
|
||||
import Vue from 'vue'
|
||||
|
||||
|
|
@ -92,6 +93,15 @@ const getters = {
|
|||
return Object.values(state.timeline).sort(function(a, b) {
|
||||
return b.publishedTime - a.publishedTime
|
||||
})
|
||||
},
|
||||
getPostFromTimeline(state) {
|
||||
return (postId) => {
|
||||
if (typeof state.timeline[postId] !== 'undefined') {
|
||||
return state.timeline[postId]
|
||||
} else {
|
||||
Logger.warn('Could not find post in timeline', { postId: postId })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const actions = {
|
||||
|
|
@ -181,22 +191,47 @@ const actions = {
|
|||
return this.dispatch('fetchTimeline', { sinceTimestamp: Math.floor(Date.now() / 1000) + 1 })
|
||||
},
|
||||
fetchTimeline(context, { sinceTimestamp }) {
|
||||
|
||||
if (typeof sinceTimestamp === 'undefined') {
|
||||
sinceTimestamp = state.since - 1
|
||||
}
|
||||
let url
|
||||
|
||||
// Compute URl to get the data
|
||||
let url = ''
|
||||
if (state.type === 'account') {
|
||||
url = OC.generateUrl(`apps/social/api/v1/account/${state.account}/stream?limit=25&since=` + sinceTimestamp)
|
||||
} else if (state.type === 'tags') {
|
||||
url = OC.generateUrl(`apps/social/api/v1/stream/tag/${state.params.tag}?limit=25&since=` + sinceTimestamp)
|
||||
} else if (state.type === 'single-post') {
|
||||
url = OC.generateUrl(`apps/social/local/v1/post/replies?id=${state.params.id}&limit=5&since=` + sinceTimestamp)
|
||||
} else {
|
||||
url = OC.generateUrl(`apps/social/api/v1/stream/${state.type}?limit=25&since=` + sinceTimestamp)
|
||||
}
|
||||
|
||||
// Get the data and add them to the timeline
|
||||
return axios.get(url).then((response) => {
|
||||
|
||||
if (response.status === -1) {
|
||||
throw response.message
|
||||
}
|
||||
context.commit('addToTimeline', response.data.result)
|
||||
|
||||
let result = []
|
||||
|
||||
// Also load replies when displaying a single post timeline
|
||||
if (state.type === 'single-post') {
|
||||
result.push(response.data)
|
||||
// axios.get(OC.generateUrl(``)).then((response) => {
|
||||
// if (response.status !== -1) {
|
||||
// result.concat(response.data.result)
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
result = response.data.result
|
||||
}
|
||||
|
||||
// Add results to timeline
|
||||
context.commit('addToTimeline', result)
|
||||
|
||||
return response.data
|
||||
})
|
||||
},
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<composer v-if="type !== 'notifications'" />
|
||||
<composer v-if="type !== 'notifications' && type !== 'single-post'" />
|
||||
<h2 v-if="type === 'tags'">
|
||||
#{{ this.$route.params.tag }}
|
||||
</h2>
|
||||
|
|
@ -117,6 +117,8 @@ export default {
|
|||
params() {
|
||||
if (this.$route.name === 'tags') {
|
||||
return { tag: this.$route.params.tag }
|
||||
} else if (this.$route.name === 'single-post') {
|
||||
return this.$route.params
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<div class="social__wrapper">
|
||||
<timeline-entry :item="mainPost" />
|
||||
<timeline-list :type="$route.params.type" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.social__timeline {
|
||||
max-width: 600px;
|
||||
margin: 15px auto;
|
||||
}
|
||||
|
||||
#app-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import Logger from '../logger'
|
||||
import TimelineEntry from './../components/TimelineEntry.vue'
|
||||
import TimelineList from './../components/TimelineList.vue'
|
||||
|
||||
export default {
|
||||
name: 'TimelineSinglePost',
|
||||
components: {
|
||||
TimelineEntry,
|
||||
TimelineList
|
||||
},
|
||||
mixins: [
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
mainPost: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
beforeMount: function() {
|
||||
|
||||
// Get data of post clicked on
|
||||
if (typeof this.$route.params.id === 'undefined') {
|
||||
Logger.debug('displaying the single post timeline for a non logged-in user')
|
||||
this.mainPost = JSON.parse(document.getElementById('postData').dataset.server)
|
||||
} else {
|
||||
this.mainPost = this.$store.getters.getPostFromTimeline(this.$route.params.id)
|
||||
}
|
||||
|
||||
// Set params for the TimelineList component
|
||||
let params = {
|
||||
account: window.location.href.split('/')[window.location.href.split('/').length - 2].substr(1),
|
||||
id: window.location.href,
|
||||
localId: window.location.href.split('/')[window.location.href.split('/').length - 1],
|
||||
type: 'single-post'
|
||||
}
|
||||
|
||||
this.$store.dispatch('changeTimelineType', {
|
||||
type: 'single-post',
|
||||
params: params
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
script('social', 'social');
|
||||
style('social', 'style');
|
||||
?>
|
||||
<span id="postData" data-server="<?php p(json_encode($_['item']));?>"></span>
|
||||
<span id="serverData" data-server="<?php p(json_encode($_['serverData']));?>"></span>
|
||||
<div id="vue-content"></div>
|
||||
Ładowanie…
Reference in New Issue