From 374f31210238b537715faf5f74bd7f4f4a073202 Mon Sep 17 00:00:00 2001
From: Maxence Lange
Date: Tue, 4 Dec 2018 22:46:04 -0100
Subject: logging in/out request
Signed-off-by: Maxence Lange
---
lib/Controller/ActivityPubController.php | 4 ++--
lib/Service/CurlService.php | 8 ++++++++
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/lib/Controller/ActivityPubController.php b/lib/Controller/ActivityPubController.php
index b4cc6de5..391bd942 100644
--- a/lib/Controller/ActivityPubController.php
+++ b/lib/Controller/ActivityPubController.php
@@ -170,7 +170,7 @@ class ActivityPubController extends Controller {
try {
$body = file_get_contents('php://input');
- $this->miscService->log('Shared Inbox: ' . $body, 0);
+ $this->miscService->log('[<<] shared-inbox: ' . $body, 1);
$origin = $this->activityService->checkRequest($this->request);
@@ -205,7 +205,7 @@ class ActivityPubController extends Controller {
try {
$body = file_get_contents('php://input');
- $this->miscService->log('Inbox: ' . $body, 0);
+ $this->miscService->log('[<<] inbox: ' . $body, 1);
$origin = $this->activityService->checkRequest($this->request);
diff --git a/lib/Service/CurlService.php b/lib/Service/CurlService.php
index f24f3983..0286748f 100644
--- a/lib/Service/CurlService.php
+++ b/lib/Service/CurlService.php
@@ -76,6 +76,7 @@ class CurlService {
* @throws Request410Exception
*/
public function request(Request $request): array {
+
$curl = $this->initRequest($request);
$this->initRequestPost($curl, $request);
@@ -105,10 +106,17 @@ class CurlService {
$ret['_path'] = $request->getUrl();
$ret['_code'] = $code;
+ $this->miscService->log(
+ '[>>] request: ' . json_encode($request) . ' - result: ' . json_encode($ret), 1
+ );
+
return $ret;
}
+ /**
+ * @param Request $request
+ */
public function assignUserAgent(Request $request) {
$request->setUserAgent(
self::USER_AGENT . ' ' . $this->configService->getAppValue('installed_version')
--
cgit v1.2.3
From 1248d3fc8089cbb582a1a651cfb84bbf764ac210 Mon Sep 17 00:00:00 2001
From: Maxence Lange
Date: Tue, 4 Dec 2018 22:49:17 -0100
Subject: limit on Accepted followers
Signed-off-by: Maxence Lange
---
lib/Db/CoreRequestBuilder.php | 37 +++++++++++++++++++++++++++++++------
lib/Db/FollowsRequest.php | 3 +++
lib/Db/FollowsRequestBuilder.php | 4 +++-
lib/Db/NotesRequest.php | 32 ++++++++++++++++++++++----------
lib/Model/ActivityPub/Follow.php | 28 ++++++++++++++++++++++++++++
5 files changed, 87 insertions(+), 17 deletions(-)
diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php
index 9db10b90..b6e0780e 100644
--- a/lib/Db/CoreRequestBuilder.php
+++ b/lib/Db/CoreRequestBuilder.php
@@ -218,10 +218,10 @@ class CoreRequestBuilder {
*
* @param IQueryBuilder $qb
* @param bool $accepted
+ * @param string $alias
*/
- protected function limitToAccepted(IQueryBuilder &$qb, bool $accepted) {
- $this->limitToDBField($qb, 'accepted', ($accepted) ? '1' : '0');
-
+ protected function limitToAccepted(IQueryBuilder &$qb, bool $accepted, string $alias = '') {
+ $this->limitToDBField($qb, 'accepted', ($accepted) ? '1' : '0', true, $alias);
}
@@ -458,13 +458,37 @@ class CoreRequestBuilder {
* @param IQueryBuilder $qb
* @param string $field
* @param int $value
+ * @param string $alias
+ */
+ protected function limitToDBFieldInt(
+ IQueryBuilder &$qb, string $field, int $value, string $alias = ''
+ ) {
+ $expr = $this->exprLimitToDBFieldInt($qb, $field, $value, $alias);
+ $qb->andWhere($expr);
+ }
+
+
+ /**
+ * @param IQueryBuilder $qb
+ * @param string $field
+ * @param int $value
+ * @param string $alias
+ *
+ * @return string
*/
- protected function limitToDBFieldInt(IQueryBuilder &$qb, string $field, int $value) {
+ protected function exprLimitToDBFieldInt(
+ IQueryBuilder &$qb, string $field, int $value, string $alias = ''
+ ): string {
$expr = $qb->expr();
- $pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->defaultSelectAlias . '.' : '';
+
+ $pf = '';
+ if ($qb->getType() === QueryBuilder::SELECT) {
+ $pf = (($alias === '') ? $this->defaultSelectAlias : $alias) . '.';
+ }
$field = $pf . $field;
- $qb->andWhere($expr->eq($field, $qb->createNamedParameter($value)));
+
+ return $expr->eq($field, $qb->createNamedParameter($value));
}
@@ -688,6 +712,7 @@ class CoreRequestBuilder {
}
$andX = $expr->andX();
+ $andX->add($this->exprLimitToDBFieldInt($qb, 'accepted', 1, $prefix . '_f'));
if ($asFollower === true) {
$andX->add(
$expr->eq(
diff --git a/lib/Db/FollowsRequest.php b/lib/Db/FollowsRequest.php
index 4861b878..708f2513 100644
--- a/lib/Db/FollowsRequest.php
+++ b/lib/Db/FollowsRequest.php
@@ -152,6 +152,7 @@ class FollowsRequest extends FollowsRequestBuilder {
public function getByFollowId(string $followId): array {
$qb = $this->getFollowsSelectSql();
$this->limitToFollowId($qb, $followId);
+ $this->limitToAccepted($qb, true);
$this->leftJoinCacheActors($qb, 'actor_id');
$follows = [];
@@ -173,6 +174,7 @@ class FollowsRequest extends FollowsRequestBuilder {
public function getFollowersByActorId(string $actorId): array {
$qb = $this->getFollowsSelectSql();
$this->limitToOBjectId($qb, $actorId);
+ $this->limitToAccepted($qb, true);
$this->leftJoinCacheActors($qb, 'actor_id');
$this->leftJoinDetails($qb, 'id', 'ca');
$qb->orderBy('creation', 'desc');
@@ -196,6 +198,7 @@ class FollowsRequest extends FollowsRequestBuilder {
public function getFollowingByActorId(string $actorId): array {
$qb = $this->getFollowsSelectSql();
$this->limitToActorId($qb, $actorId);
+ $this->limitToAccepted($qb, true);
$this->leftJoinCacheActors($qb, 'object_id');
$this->leftJoinDetails($qb, 'id', 'ca');
$qb->orderBy('creation', 'desc');
diff --git a/lib/Db/FollowsRequestBuilder.php b/lib/Db/FollowsRequestBuilder.php
index 25c0686a..01e08442 100644
--- a/lib/Db/FollowsRequestBuilder.php
+++ b/lib/Db/FollowsRequestBuilder.php
@@ -83,7 +83,9 @@ class FollowsRequestBuilder extends CoreRequestBuilder {
$qb = $this->dbConnection->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
- $qb->select('f.id', 'f.type', 'f.actor_id', 'f.object_id', 'f.follow_id', 'f.creation')
+ $qb->select(
+ 'f.id', 'f.type', 'f.actor_id', 'f.object_id', 'f.follow_id', 'f.accepted', 'f.creation'
+ )
->from(self::TABLE_SERVER_FOLLOWS, 'f');
$this->defaultSelectAlias = 'f';
diff --git a/lib/Db/NotesRequest.php b/lib/Db/NotesRequest.php
index 36e3e930..cc3fd342 100644
--- a/lib/Db/NotesRequest.php
+++ b/lib/Db/NotesRequest.php
@@ -156,17 +156,22 @@ class NotesRequest extends NotesRequestBuilder {
/**
+ * Should returns:
+ * * Own posts,
+ * * Followed accounts
+ *
* @param string $actorId
* @param int $since
* @param int $limit
*
* @return array
*/
- public function getHomeNotesForActorId(string $actorId, int $since = 0, int $limit = 5): array {
+ public function getStreamHome(string $actorId, int $since = 0, int $limit = 5): array {
$qb = $this->getNotesSelectSql();
$this->rightJoinFollowing($qb);
$this->limitToActorId($qb, $actorId, 'f');
+ $this->limitToAccepted($qb, true, 'f');
$qb->orWhere($this->exprLimitToDBField($qb, 'attributed_to', $actorId));
$this->limitPaginate($qb, $since, $limit);
@@ -184,19 +189,20 @@ class NotesRequest extends NotesRequestBuilder {
/**
+ * Should returns:
+ * * Private message.
+ * - group messages.
+
+ * @param string $actorId
* @param int $since
* @param int $limit
- * @param bool $localOnly
*
* @return array
*/
- public function getPublicNotes(int $since = 0, int $limit = 5, bool $localOnly = true): array {
+ public function getStreamDirect(string $actorId, int $since = 0, int $limit = 5): array {
$qb = $this->getNotesSelectSql();
- $this->limitToRecipient($qb, ActivityService::TO_PUBLIC);
+ $this->limitToRecipient($qb, $actorId, true);
$this->limitPaginate($qb, $since, $limit);
- if ($localOnly) {
- $this->limitToLocal($qb, true);
- }
$this->leftJoinCacheActors($qb, 'attributed_to');
$notes = [];
@@ -211,17 +217,23 @@ class NotesRequest extends NotesRequestBuilder {
/**
- * @param string $actorId
+ * Should returns:
+ * - All local public/federated posts
+ *
* @param int $since
* @param int $limit
+ * @param bool $localOnly
*
* @return array
*/
- public function getDirectNotesForActorId(string $actorId, int $since = 0, int $limit = 5
+ public function getStreamTimeline(int $since = 0, int $limit = 5, bool $localOnly = true
): array {
$qb = $this->getNotesSelectSql();
- $this->limitToRecipient($qb, $actorId, true);
+ $this->limitToRecipient($qb, ActivityService::TO_PUBLIC);
$this->limitPaginate($qb, $since, $limit);
+ if ($localOnly) {
+ $this->limitToLocal($qb, true);
+ }
$this->leftJoinCacheActors($qb, 'attributed_to');
$notes = [];
diff --git a/lib/Model/ActivityPub/Follow.php b/lib/Model/ActivityPub/Follow.php
index 26546265..e6e22738 100644
--- a/lib/Model/ActivityPub/Follow.php
+++ b/lib/Model/ActivityPub/Follow.php
@@ -32,6 +32,7 @@ namespace OCA\Social\Model\ActivityPub;
use JsonSerializable;
+use OCA\Social\Exceptions\InvalidResourceEntryException;
/**
@@ -48,6 +49,9 @@ class Follow extends ACore implements JsonSerializable {
/** @var string */
private $followId = '';
+ /** @var bool */
+ private $accepted = false;
+
/**
* Follow constructor.
@@ -80,8 +84,29 @@ class Follow extends ACore implements JsonSerializable {
}
+ /**
+ * @return bool
+ */
+ public function isAccepted(): bool {
+ return $this->accepted;
+ }
+
+ /**
+ * @param bool $accepted
+ *
+ * @return Follow
+ */
+ public function setAccepted(bool $accepted): Follow {
+ $this->accepted = $accepted;
+
+ return $this;
+ }
+
+
/**
* @param array $data
+ *
+ * @throws InvalidResourceEntryException
*/
public function import(array $data) {
parent::import($data);
@@ -94,6 +119,7 @@ class Follow extends ACore implements JsonSerializable {
public function importFromDatabase(array $data) {
parent::importFromDatabase($data);
+ $this->setAccepted(($this->getInt('accepted', $data, 0) === 1) ? true : false);
$this->setFollowId($this->get('follow_id', $data, ''));
}
@@ -105,6 +131,8 @@ class Follow extends ACore implements JsonSerializable {
return array_merge(
parent::jsonSerialize(),
[
+ 'follow_id' => $this->getFollowId(),
+ 'accepted' => $this->isAccepted()
]
);
}
--
cgit v1.2.3
From 89848f8510ca1bd61951ae86585e03d6a6924500 Mon Sep 17 00:00:00 2001
From: Maxence Lange
Date: Tue, 4 Dec 2018 22:49:52 -0100
Subject: allow 200 and 202 as a valid status
Signed-off-by: Maxence Lange
---
lib/Service/ActivityService.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/Service/ActivityService.php b/lib/Service/ActivityService.php
index 6dd75def..8e094e56 100644
--- a/lib/Service/ActivityService.php
+++ b/lib/Service/ActivityService.php
@@ -296,7 +296,8 @@ class ActivityService {
}
try {
- if ($this->getint('_code', $result, 500) === 202) {
+ $accepted = [200, 202];
+ if (in_array($this->getint('_code', $result, 500), $accepted)) {
$this->queueService->endRequest($queue, true);
} else {
$this->queueService->endRequest($queue, false);
--
cgit v1.2.3
From 2a47f895ad602183ff83aa8549103f8261983a85 Mon Sep 17 00:00:00 2001
From: Maxence Lange
Date: Tue, 4 Dec 2018 22:50:36 -0100
Subject: issue with some headers
Signed-off-by: Maxence Lange
---
lib/Controller/ActivityPubController.php | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/Controller/ActivityPubController.php b/lib/Controller/ActivityPubController.php
index 391bd942..ce92a2e5 100644
--- a/lib/Controller/ActivityPubController.php
+++ b/lib/Controller/ActivityPubController.php
@@ -323,6 +323,16 @@ class ActivityPubController extends Controller {
// uncomment this line to display the result that would be return to an ActivityPub service (TEST)
// return true;
+ // TODO - cleaner to being able to parse:
+ // - 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
+ // - 'application/activity+json, application/ld+json'
+ $accept = explode(',', $this->request->getHeader('Accept'));
+ $accept = array_map('trim', $accept);
+
+ if (in_array('application/ld+json', $accept)) {
+ return true;
+ }
+
if ($this->request->getHeader('Accept')
=== 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"') {
return true;
--
cgit v1.2.3
From 1b222bf4699a41a6fcfb8fb7e8abc1d107fbdd3b Mon Sep 17 00:00:00 2001
From: Maxence Lange
Date: Tue, 4 Dec 2018 22:51:27 -0100
Subject: renaming
Signed-off-by: Maxence Lange
---
lib/Controller/LocalController.php | 88 +++++++++++++++++++++++----------
lib/Service/ActivityPub/NoteService.php | 59 ++++++++++++++++++----
2 files changed, 110 insertions(+), 37 deletions(-)
diff --git a/lib/Controller/LocalController.php b/lib/Controller/LocalController.php
index a1c564b4..2e31350a 100644
--- a/lib/Controller/LocalController.php
+++ b/lib/Controller/LocalController.php
@@ -33,12 +33,11 @@ namespace OCA\Social\Controller;
use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse;
use daita\MySmallPhpTools\Traits\TArrayTools;
use Exception;
-use OC\User\NoUserException;
use OCA\Social\AppInfo\Application;
-use OCA\Social\Exceptions\AccountAlreadyExistsException;
-use OCA\Social\Exceptions\ActorDoesNotExistException;
+use OCA\Social\Exceptions\AccountDoesNotExistException;
use OCA\Social\Exceptions\InvalidResourceException;
use OCA\Social\Model\ActivityPub\ACore;
+use OCA\Social\Model\ActivityPub\Person;
use OCA\Social\Model\Post;
use OCA\Social\Service\ActivityPub\DocumentService;
use OCA\Social\Service\ActivityPub\FollowService;
@@ -51,7 +50,6 @@ use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\FileDisplayResponse;
-use OCP\AppFramework\Http\NotFoundResponse;
use OCP\AppFramework\Http\Response;
use OCP\IRequest;
@@ -93,6 +91,10 @@ class LocalController extends Controller {
private $miscService;
+ /** @var Person */
+ private $viewer;
+
+
/**
* LocalController constructor.
*
@@ -204,10 +206,36 @@ class LocalController extends Controller {
* @return DataResponse
*/
public function streamHome($since = 0, int $limit = 5): DataResponse {
+ try {
+ $this->initViewer(true);
+ $posts = $this->noteService->getStreamHome($this->viewer->getId(), $since, $limit);
+
+ return $this->success($posts);
+ } catch (Exception $e) {
+ return $this->fail($e);
+ }
+ }
+
+ /**
+ * // TODO: Delete the NoCSRF check
+ *
+ * @NoCSRFRequired
+ * @NoAdminRequired
+ * @NoSubAdminRequired
+ *
+ * @param string $username
+ * @param int $since
+ * @param int $limit
+ *
+ * @return DataResponse
+ */
+ public function streamAccount(string $username, $since = 0, int $limit = 5): DataResponse {
try {
- $actor = $this->actorService->getActorFromUserId($this->userId);
- $posts = $this->noteService->getHomeNotesForActor($actor, $since, $limit);
+ $this->initViewer();
+
+ $account = $this->actorService->getActor($username);
+ $posts = $this->noteService->getStreamAccount($account->getId(), $since, $limit);
return $this->success($posts);
} catch (Exception $e) {
@@ -229,10 +257,9 @@ class LocalController extends Controller {
* @return DataResponse
*/
public function streamDirect(int $since = 0, int $limit = 5): DataResponse {
-
try {
- $actor = $this->actorService->getActorFromUserId($this->userId);
- $posts = $this->noteService->getDirectNotesForActor($actor, $since, $limit);
+ $this->initViewer();
+ $posts = $this->noteService->getStreamDirect($this->viewer->getId(), $since, $limit);
return $this->success($posts);
} catch (Exception $e) {
@@ -257,7 +284,7 @@ class LocalController extends Controller {
*/
public function streamTimeline(int $since = 0, int $limit = 5): DataResponse {
try {
- $posts = $this->noteService->getLocalTimeline($since, $limit);
+ $posts = $this->noteService->getStreamLocalTimeline($since, $limit);
return $this->success($posts);
} catch (Exception $e) {
@@ -281,7 +308,7 @@ class LocalController extends Controller {
*/
public function streamFederated(int $since = 0, int $limit = 5): DataResponse {
try {
- $posts = $this->noteService->getFederatedTimeline($since, $limit);
+ $posts = $this->noteService->getStreamGlobalTimeline($since, $limit);
return $this->success($posts);
} catch (Exception $e) {
@@ -368,9 +395,9 @@ class LocalController extends Controller {
* @return DataResponse
*/
public function currentFollowers(): DataResponse {
- $this->initViewer();
-
try {
+ $this->initViewer();
+
$actor = $this->actorService->getActorFromUserId($this->userId);
$followers = $this->followService->getFollowers($actor);
@@ -389,9 +416,9 @@ class LocalController extends Controller {
* @return DataResponse
*/
public function currentFollowing(): DataResponse {
- $this->initViewer();
-
try {
+ $this->initViewer();
+
$actor = $this->actorService->getActorFromUserId($this->userId);
$followers = $this->followService->getFollowing($actor);
@@ -415,9 +442,8 @@ class LocalController extends Controller {
* @return DataResponse
*/
public function accountInfo(string $username): DataResponse {
- $this->initViewer();
-
try {
+ $this->initViewer();
$actor = $this->actorService->getActor($username);
$actor = $this->personService->getFromLocalAccount($actor->getPreferredUsername());
@@ -462,9 +488,10 @@ class LocalController extends Controller {
* @return DataResponse
*/
public function accountFollowing(string $username): DataResponse {
- $this->initViewer();
try {
+ $this->initViewer();
+
$actor = $this->actorService->getActor($username);
$following = $this->followService->getFollowing($actor);
@@ -488,9 +515,9 @@ class LocalController extends Controller {
* @return DataResponse
*/
public function globalAccountInfo(string $account): DataResponse {
- $this->initViewer();
-
try {
+ $this->initViewer();
+
$actor = $this->personService->getFromAccount($account);
return $this->success(['account' => $actor]);
@@ -513,9 +540,8 @@ class LocalController extends Controller {
* @return DataResponse
*/
public function globalActorInfo(string $id): DataResponse {
- $this->initViewer();
-
try {
+ $this->initViewer();
$actor = $this->personService->getFromId($id);
return $this->success(['actor' => $actor]);
@@ -617,14 +643,22 @@ class LocalController extends Controller {
/**
- * @throws Exception
+ *
+ * @param bool $exception
+ *
+ * @throws AccountDoesNotExistException
*/
- private function initViewer() {
+ private function initViewer(bool $exception = false) {
try {
- $viewer = $this->actorService->getActorFromUserId($this->userId, true);
- $this->followService->setViewerId($viewer->getId());
- $this->personService->setViewerId($viewer->getId());
+ $this->viewer = $this->actorService->getActorFromUserId($this->userId, true);
+
+ $this->followService->setViewerId($this->viewer->getId());
+ $this->personService->setViewerId($this->viewer->getId());
+ $this->noteService->setViewerId($this->viewer->getId());
} catch (Exception $e) {
+ if ($exception) {
+ throw new AccountDoesNotExistException();
+ }
}
}
diff --git a/lib/Service/ActivityPub/NoteService.php b/lib/Service/ActivityPub/NoteService.php
index cd49e906..f99dd13a 100644
--- a/lib/Service/ActivityPub/NoteService.php
+++ b/lib/Service/ActivityPub/NoteService.php
@@ -82,6 +82,10 @@ class NoteService implements ICoreService {
private $miscService;
+ /** @var string */
+ private $viewerId = '';
+
+
/**
* NoteService constructor.
*
@@ -108,6 +112,19 @@ class NoteService implements ICoreService {
}
+ /**
+ * @param string $viewerId
+ */
+ public function setViewerId(string $viewerId) {
+ $this->viewerId = $viewerId;
+ $this->notesRequest->setViewerId($viewerId);
+ }
+
+ public function getViewerId(): string {
+ return $this->viewerId;
+ }
+
+
/**
* @param string $userId
* @param string $content
@@ -333,28 +350,50 @@ class NoteService implements ICoreService {
/**
- * @param Person $actor
+ * @param string $actorId
*
* @param int $since
* @param int $limit
*
* @return Note[]
*/
- public function getHomeNotesForActor(Person $actor, int $since = 0, int $limit = 5): array {
- return $this->notesRequest->getHomeNotesForActorId($actor->getId(), $since, $limit);
+ public function getStreamHome(string $actorId, int $since = 0, int $limit = 5): array {
+ return $this->notesRequest->getStreamHome($actorId, $since, $limit);
}
/**
- * @param Person $actor
+ * @param string $actorId
+ * @param int $since
+ * @param int $limit
+ *
+ * @return Note[]
+ */
+ public function getStreamAccount(string $actorId, int $since = 0, int $limit = 5): array {
+ return $this->notesRequest->getStreamHome($actorId, $since, $limit);
+ }
+
+
+ /**
+ * @param string $actorId
+ * @param int $since
+ * @param int $limit
*
+ * @return Note[]
+ */
+ public function getStreamDirect(string $actorId, int $since = 0, int $limit = 5): array {
+ return $this->notesRequest->getStreamDirect($actorId, $since, $limit);
+ }
+
+
+ /**
* @param int $since
* @param int $limit
*
* @return Note[]
*/
- public function getDirectNotesForActor(Person $actor, int $since = 0, int $limit = 5): array {
- return $this->notesRequest->getDirectNotesForActorId($actor->getId(), $since, $limit);
+ public function getStreamLocalTimeline(int $since = 0, int $limit = 5): array {
+ return $this->notesRequest->getStreamTimeline($since, $limit, true);
}
@@ -364,8 +403,8 @@ class NoteService implements ICoreService {
*
* @return Note[]
*/
- public function getLocalTimeline(int $since = 0, int $limit = 5): array {
- return $this->notesRequest->getPublicNotes($since, $limit, true);
+ public function getStreamInternalTimeline(int $since = 0, int $limit = 5): array {
+ // TODO - admin should be able to provide a list of 'friendly/internal' instance of ActivityPub
}
@@ -375,8 +414,8 @@ class NoteService implements ICoreService {
*
* @return Note[]
*/
- public function getFederatedTimeline(int $since = 0, int $limit = 5): array {
- return $this->notesRequest->getPublicNotes($since, $limit, false);
+ public function getStreamGlobalTimeline(int $since = 0, int $limit = 5): array {
+ return $this->notesRequest->getStreamTimeline($since, $limit, false);
}
}
--
cgit v1.2.3
From aa3d417edbf05d75248527e4a41c0d25e4ccb70b Mon Sep 17 00:00:00 2001
From: Maxence Lange
Date: Tue, 4 Dec 2018 22:52:02 -0100
Subject: non case sensitive allowed ids
Signed-off-by: Maxence Lange
---
lib/Db/NotesRequestBuilder.php | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/lib/Db/NotesRequestBuilder.php b/lib/Db/NotesRequestBuilder.php
index 79be40e6..9b68a4d9 100644
--- a/lib/Db/NotesRequestBuilder.php
+++ b/lib/Db/NotesRequestBuilder.php
@@ -80,7 +80,8 @@ class NotesRequestBuilder extends CoreRequestBuilder {
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
- 'sn.id', 'sn.type', 'sn.to', 'sn.to_array', 'sn.cc', 'sn.bcc', 'sn.content', 'sn.summary',
+ 'sn.id', 'sn.type', 'sn.to', 'sn.to_array', 'sn.cc', 'sn.bcc', 'sn.content',
+ 'sn.summary',
'sn.published', 'sn.published_time', 'sn.attributed_to', 'sn.in_reply_to', 'sn.source',
'sn.local', 'sn.instances', 'sn.creation'
)
@@ -134,28 +135,28 @@ class NotesRequestBuilder extends CoreRequestBuilder {
$pf = $this->defaultSelectAlias . '.';
$orX = $expr->orX();
- $orX->add($expr->eq($pf . 'to', 'f.follow_id'));
+ $orX->add($expr->eq($func->lower($pf . 'to'), $func->lower('f.follow_id')));
$orX->add(
$expr->like(
- $pf . 'to_array', $func->concat(
+ $func->lower($pf . 'to_array'), $func->concat(
$qb->createNamedParameter('%"'),
- $func->concat('f.follow_id', $qb->createNamedParameter('"%'))
+ $func->concat($func->lower('f.follow_id'), $qb->createNamedParameter('"%'))
)
)
);
$orX->add(
$expr->like(
- $pf . 'cc', $func->concat(
+ $func->lower($pf . 'cc'), $func->concat(
$qb->createNamedParameter('%"'),
- $func->concat('f.follow_id', $qb->createNamedParameter('"%'))
+ $func->concat($func->lower('f.follow_id'), $qb->createNamedParameter('"%'))
)
)
);
$orX->add(
$expr->like(
- $pf . 'bcc', $func->concat(
+ $func->lower($pf . 'bcc'), $func->concat(
$qb->createNamedParameter('%"'),
- $func->concat('f.follow_id', $qb->createNamedParameter('"%'))
+ $func->concat($func->lower('f.follow_id'), $qb->createNamedParameter('"%'))
)
)
);
--
cgit v1.2.3
From 6af499a81781a65e6e6f5a20f3e616b8ada480d1 Mon Sep 17 00:00:00 2001
From: Maxence Lange
Date: Tue, 4 Dec 2018 22:52:47 -0100
Subject: fill followId and confirm local followers
Signed-off-by: Maxence Lange
---
lib/Service/ActivityPub/FollowService.php | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/lib/Service/ActivityPub/FollowService.php b/lib/Service/ActivityPub/FollowService.php
index 7e1c35f8..e243c271 100644
--- a/lib/Service/ActivityPub/FollowService.php
+++ b/lib/Service/ActivityPub/FollowService.php
@@ -129,11 +129,14 @@ class FollowService implements ICoreService {
$follow->generateUniqueId();
$follow->setActorId($actor->getId());
$follow->setObjectId($remoteActor->getId());
+ $follow->setFollowId($remoteActor->getFollowers());
try {
$this->followsRequest->getByPersons($actor->getId(), $remoteActor->getId());
} catch (FollowDoesNotExistException $e) {
$this->followsRequest->save($follow);
+ // TODO - Remove this auto-accepted.
+// $this->followsRequest->accepted($follow);
$follow->addInstancePath(
new InstancePath(
@@ -258,7 +261,14 @@ class FollowService implements ICoreService {
$follow->checkOrigin($follow->getActorId());
try {
- $this->followsRequest->getByPersons($follow->getActorId(), $follow->getObjectId());
+ $knownFollow = $this->followsRequest->getByPersons(
+ $follow->getActorId(), $follow->getObjectId()
+ );
+ // in case of local follower.
+ // TODO - remove when following a local account does not need curl request anymore
+ if ($knownFollow->getId() === $follow->getId() && !$knownFollow->isAccepted()) {
+ $this->confirmFollowRequest($follow);
+ }
} catch (FollowDoesNotExistException $e) {
$actor = $this->personService->getFromId($follow->getObjectId());
if ($actor->isLocal()) {
--
cgit v1.2.3
From 61a28c21711332edca0642ca153f6854ed33591c Mon Sep 17 00:00:00 2001
From: Maxence Lange
Date: Tue, 4 Dec 2018 23:01:07 -0100
Subject: get public messages from an account
Signed-off-by: Maxence Lange
---
appinfo/routes.php | 1 +
lib/Db/NotesRequest.php | 32 ++++++++++++++++++++++++++++++--
lib/Service/ActivityPub/NoteService.php | 2 +-
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/appinfo/routes.php b/appinfo/routes.php
index 7fc4b1fb..6a595a4e 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -68,6 +68,7 @@ return [
['name' => 'Local#streamTimeline', 'url' => '/api/v1/stream/timeline', 'verb' => 'GET'],
['name' => 'Local#streamFederated', 'url' => '/api/v1/stream/federated', 'verb' => 'GET'],
['name' => 'Local#streamDirect', 'url' => '/api/v1/stream/direct', 'verb' => 'GET'],
+ ['name' => 'Local#streamAccount', 'url' => '/api/v1/account/{username}/stream', 'verb' => 'GET'],
['name' => 'Local#postCreate', 'url' => '/api/v1/post', 'verb' => 'POST'],
['name' => 'Local#postDelete', 'url' => '/api/v1/post', 'verb' => 'DELETE'],
diff --git a/lib/Db/NotesRequest.php b/lib/Db/NotesRequest.php
index cc3fd342..ec9aca9f 100644
--- a/lib/Db/NotesRequest.php
+++ b/lib/Db/NotesRequest.php
@@ -189,10 +189,38 @@ class NotesRequest extends NotesRequestBuilder {
/**
- * Should returns:
+ * Should returns:
+ * * public message from actorId.
+ * - to followers-only if follower is logged.
+ *
+ * @param string $actorId
+ * @param int $since
+ * @param int $limit
+ *
+ * @return array
+ */
+ public function getStreamAccount(string $actorId, int $since = 0, int $limit = 5): array {
+ $qb = $this->getNotesSelectSql();
+ $this->limitToRecipient($qb, ActivityService::TO_PUBLIC);
+ $this->limitPaginate($qb, $since, $limit);
+ $this->limitToAttributedTo($qb, $actorId);
+
+ $notes = [];
+ $cursor = $qb->execute();
+ while ($data = $cursor->fetch()) {
+ $notes[] = $this->parseNotesSelectSql($data);
+ }
+ $cursor->closeCursor();
+
+ return $notes;
+ }
+
+
+ /**
+ * Should returns:
* * Private message.
* - group messages.
-
+ *
* @param string $actorId
* @param int $since
* @param int $limit
diff --git a/lib/Service/ActivityPub/NoteService.php b/lib/Service/ActivityPub/NoteService.php
index f99dd13a..8bddea7b 100644
--- a/lib/Service/ActivityPub/NoteService.php
+++ b/lib/Service/ActivityPub/NoteService.php
@@ -370,7 +370,7 @@ class NoteService implements ICoreService {
* @return Note[]
*/
public function getStreamAccount(string $actorId, int $since = 0, int $limit = 5): array {
- return $this->notesRequest->getStreamHome($actorId, $since, $limit);
+ return $this->notesRequest->getStreamAccount($actorId, $since, $limit);
}
--
cgit v1.2.3
From 9d71a7b50c710f12051dba04e05c3dc366798bd1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julius=20H=C3=A4rtl?=
Date: Wed, 5 Dec 2018 10:49:44 +0100
Subject: Fix following and actor_info for account stream
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Julius Härtl
---
lib/Db/NotesRequest.php | 1 +
lib/Service/ActivityPub/FollowService.php | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/Db/NotesRequest.php b/lib/Db/NotesRequest.php
index ec9aca9f..b4de9316 100644
--- a/lib/Db/NotesRequest.php
+++ b/lib/Db/NotesRequest.php
@@ -204,6 +204,7 @@ class NotesRequest extends NotesRequestBuilder {
$this->limitToRecipient($qb, ActivityService::TO_PUBLIC);
$this->limitPaginate($qb, $since, $limit);
$this->limitToAttributedTo($qb, $actorId);
+ $this->leftJoinCacheActors($qb, 'attributed_to');
$notes = [];
$cursor = $qb->execute();
diff --git a/lib/Service/ActivityPub/FollowService.php b/lib/Service/ActivityPub/FollowService.php
index e243c271..4e9942af 100644
--- a/lib/Service/ActivityPub/FollowService.php
+++ b/lib/Service/ActivityPub/FollowService.php
@@ -136,7 +136,7 @@ class FollowService implements ICoreService {
} catch (FollowDoesNotExistException $e) {
$this->followsRequest->save($follow);
// TODO - Remove this auto-accepted.
-// $this->followsRequest->accepted($follow);
+ $this->followsRequest->accepted($follow);
$follow->addInstancePath(
new InstancePath(
--
cgit v1.2.3
From c3bd113694ef1e50f811684f8a71e9132ed10733 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julius=20H=C3=A4rtl?=
Date: Wed, 5 Dec 2018 10:50:37 +0100
Subject: Add public stream to profile page
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Julius Härtl
---
src/components/Composer.vue | 4 +-
src/components/TimelineEntry.vue | 7 ++-
src/components/TimelineList.vue | 122 +++++++++++++++++++++++++++++++++++++++
src/store/timeline.js | 26 +++++++--
src/views/ProfileTimeline.vue | 20 +++----
src/views/Timeline.vue | 117 ++-----------------------------------
6 files changed, 164 insertions(+), 132 deletions(-)
create mode 100644 src/components/TimelineList.vue
diff --git a/src/components/Composer.vue b/src/components/Composer.vue
index 1bdb78b6..de440406 100644
--- a/src/components/Composer.vue
+++ b/src/components/Composer.vue
@@ -499,9 +499,7 @@ export default {
this.$store.dispatch('post', this.getPostData()).then((response) => {
this.post = ''
this.$refs.composerInput.innerText = this.post
- this.$store.dispatch('refreshTimeline', {
- account: this.currentUser.uid
- })
+ this.$store.dispatch('refreshTimeline')
})
},
remoteSearch(text) {
diff --git a/src/components/TimelineEntry.vue b/src/components/TimelineEntry.vue
index 7fa30b32..ba90f88d 100644
--- a/src/components/TimelineEntry.vue
+++ b/src/components/TimelineEntry.vue
@@ -7,15 +7,20 @@
+ {{ item.account_info }}
+
diff --git a/src/components/TimelineList.vue b/src/components/TimelineList.vue
new file mode 100644
index 00000000..458ec3af
--- /dev/null
+++ b/src/components/TimelineList.vue
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
diff --git a/src/store/timeline.js b/src/store/timeline.js
index cadbd990..c31fb245 100644
--- a/src/store/timeline.js
+++ b/src/store/timeline.js
@@ -26,7 +26,8 @@ import Vue from 'vue'
const state = {
timeline: {},
since: Math.floor(Date.now() / 1000) + 1,
- type: 'home'
+ type: 'home',
+ account: ''
}
const mutations = {
addToTimeline(state, data) {
@@ -41,6 +42,9 @@ const mutations = {
},
setTimelineType(state, type) {
state.type = type
+ },
+ setAccount(state, account) {
+ state.account = account
}
}
const getters = {
@@ -54,6 +58,12 @@ const actions = {
changeTimelineType(context, type) {
context.commit('resetTimeline')
context.commit('setTimelineType', type)
+ context.commit('setAccount', '')
+ },
+ changeTimelineTypeAccount(context, account) {
+ context.commit('resetTimeline')
+ context.commit('setTimelineType', 'account')
+ context.commit('setAccount', account)
},
post(context, post) {
return axios.post(OC.generateUrl('apps/social/api/v1/post'), { data: post }).then((response) => {
@@ -64,14 +74,20 @@ const actions = {
console.error('Failed to create a post', error)
})
},
- refreshTimeline(context, account) {
- return this.dispatch('fetchTimeline', { account: account, sinceTimestamp: Math.floor(Date.now() / 1000) + 1 })
+ refreshTimeline(context) {
+ return this.dispatch('fetchTimeline', { sinceTimestamp: Math.floor(Date.now() / 1000) + 1 })
},
- fetchTimeline(context, { account, sinceTimestamp }) {
+ fetchTimeline(context, { sinceTimestamp }) {
if (typeof sinceTimestamp === 'undefined') {
sinceTimestamp = state.since - 1
}
- return axios.get(OC.generateUrl(`apps/social/api/v1/stream/${state.type}?limit=5&since=` + sinceTimestamp)).then((response) => {
+ let url
+ if (state.type === 'account') {
+ url = OC.generateUrl(`apps/social/api/v1/account/${state.account}/stream?limit=25&since=` + sinceTimestamp)
+ } else {
+ url = OC.generateUrl(`apps/social/api/v1/stream/${state.type}?limit=25&since=` + sinceTimestamp)
+ }
+ return axios.get(url).then((response) => {
if (response.status === -1) {
throw response.message
}
diff --git a/src/views/ProfileTimeline.vue b/src/views/ProfileTimeline.vue
index eb50a136..043dda4a 100644
--- a/src/views/ProfileTimeline.vue
+++ b/src/views/ProfileTimeline.vue
@@ -21,30 +21,26 @@
-->
-
-
-
+
diff --git a/src/views/Timeline.vue b/src/views/Timeline.vue
index 81b9fdea..4a6e986f 100644
--- a/src/views/Timeline.vue
+++ b/src/views/Timeline.vue
@@ -10,17 +10,8 @@
-
+
+
@@ -88,6 +79,7 @@ import TimelineEntry from './../components/TimelineEntry'
import Composer from './../components/Composer'
import CurrentUserMixin from './../mixins/currentUserMixin'
import EmptyContent from './../components/EmptyContent'
+import TimelineList from './../components/TimelineList'
export default {
name: 'Timeline',
@@ -98,104 +90,24 @@ export default {
Multiselect,
Composer,
InfiniteLoading,
- EmptyContent
+ EmptyContent,
+ TimelineList
},
mixins: [CurrentUserMixin],
data: function() {
return {
- infoHidden: false,
- state: [],
- emptyContent: {
- default: {
- image: 'img/undraw/posts.svg',
- title: t('social', 'No posts found'),
- description: t('social', 'Posts from people you follow will show up here')
- },
- direct: {
- image: 'img/undraw/direct.svg',
- title: t('social', 'No direct messages found'),
- description: t('social', 'Posts directed to you will show up here')
- },
- timeline: {
- image: 'img/undraw/local.svg',
- title: t('social', 'No local posts found'),
- description: t('social', 'Posts from other people on this instance will show up here')
- },
- federated: {
- image: 'img/undraw/global.svg',
- title: t('social', 'No global posts found'),
- description: t('social', 'Posts from federated instances will show up here')
- }
- }
+ infoHidden: false
}
},
computed: {
- emptyContentData() {
- if (typeof this.emptyContent[this.$route.params.type] !== 'undefined') {
- return this.emptyContent[this.$route.params.type]
- }
- return this.emptyContent.default
- },
type: function() {
if (this.$route.params.type) {
return this.$route.params.type
}
return 'home'
},
- url: function() {
- return OC.linkTo('social', 'img/nextcloud.png')
- },
- timeline: function() {
- return this.$store.getters.getTimeline
- },
showInfo() {
return this.$store.getters.getServerData.firstrun && !this.infoHidden
- },
- menu: function() {
- let defaultCategories = [
- {
- id: 'social-timeline',
- classes: [],
- href: '#',
- icon: 'icon-category-monitoring',
- text: t('social', 'Timeline')
- },
- {
- id: 'social-account',
- classes: [],
- href: '#',
- icon: 'icon-category-user',
- text: t('social', 'Profile')
- },
- {
- id: 'social-friends',
- classes: [],
- href: '#',
- icon: 'icon-category-social',
- text: t('social', 'Friends')
- },
- {
- id: 'social-favorites',
- classes: [],
- href: '#',
- icon: 'icon-favorite',
- text: t('social', 'Favorites')
- },
- {
- id: 'social-direct-messages',
- classes: [],
- href: '#',
- icon: 'icon-comment',
- utils: {
- counter: 3
- },
- text: t('social', 'Direct messages')
- }
- ]
- return {
- items: defaultCategories,
- loading: false
- }
}
},
beforeMount: function() {
@@ -204,23 +116,6 @@ export default {
methods: {
hideInfo() {
this.infoHidden = true
- },
- infiniteHandler($state) {
- this.$store.dispatch('fetchTimeline', {
- account: this.currentUser.uid
- }).then((response) => {
- if (response.status === -1) {
- OC.Notification.showTemporary('Failed to load more timeline entries')
- console.error('Failed to load more timeline entries', response)
- $state.complete()
- return
- }
- response.result.length > 0 ? $state.loaded() : $state.complete()
- }).catch((error) => {
- OC.Notification.showTemporary('Failed to load more timeline entries')
- console.error('Failed to load more timeline entries', error)
- $state.complete()
- })
}
}
}
--
cgit v1.2.3