kopia lustrzana https://github.com/nextcloud/social
Merge pull request #25 from nextcloud-gmbh/leftjoin-cacheactor
left join cache, and returns data in timelinepull/26/head
commit
334ad6c7f0
|
@ -32,7 +32,7 @@ return [
|
|||
|
||||
['name' => 'Local#newPost', 'url' => '/api/v1/post', 'verb' => 'POST'],
|
||||
['name' => 'Local#timeline', 'url' => '/api/v1/timeline', 'verb' => 'GET'],
|
||||
['name' => 'Local#direct', 'url' => '/api/v1/direct', 'verb' => 'PUT']
|
||||
['name' => 'Local#direct', 'url' => '/api/v1/direct', 'verb' => 'PUT'],
|
||||
['name' => 'Local#accountSearch', 'url' => '/api/v1/accounts/search', 'verb' => 'GET'],
|
||||
['name' => 'Local#actorInfo', 'url' => '/api/v1/actor/info', 'verb' => 'GET']
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace OCA\Social\Db;
|
|||
|
||||
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Model\ActivityPub\Person;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
|
@ -224,7 +226,8 @@ class CoreRequestBuilder {
|
|||
|
||||
/**
|
||||
* @param IQueryBuilder $qb
|
||||
* @param string $recipient
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
*/
|
||||
protected function limitPaginate(IQueryBuilder &$qb, int $since = 0, int $limit = 5) {
|
||||
if ($since > 0) {
|
||||
|
@ -232,7 +235,12 @@ class CoreRequestBuilder {
|
|||
$dt = new \DateTime();
|
||||
$dt->setTimestamp($since);
|
||||
// TODO: Pagination should use published date, once we can properly query the db for that
|
||||
$qb->andWhere($expr->lt('creation', $qb->createNamedParameter($dt, IQueryBuilder::PARAM_DATE), IQueryBuilder::PARAM_DATE));
|
||||
$qb->andWhere(
|
||||
$expr->lt(
|
||||
'creation', $qb->createNamedParameter($dt, IQueryBuilder::PARAM_DATE),
|
||||
IQueryBuilder::PARAM_DATE
|
||||
)
|
||||
);
|
||||
}
|
||||
$qb->setMaxResults($limit);
|
||||
$qb->orderBy('creation', 'desc');
|
||||
|
@ -273,30 +281,66 @@ class CoreRequestBuilder {
|
|||
$qb->andWhere($expr->like($field, $qb->createNamedParameter($value)));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Left Join service to get info about the serviceId
|
||||
// *
|
||||
// * @param IQueryBuilder $qb
|
||||
// */
|
||||
// public function leftJoinService(IQueryBuilder &$qb) {
|
||||
//
|
||||
// if ($qb->getType() !== QueryBuilder::SELECT) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// $expr = $qb->expr();
|
||||
// $pf = $this->defaultSelectAlias;
|
||||
//
|
||||
|
||||
/**
|
||||
* @param IQueryBuilder $qb
|
||||
* @param string $fieldActorId
|
||||
*/
|
||||
protected function leftJoinCacheActors(IQueryBuilder &$qb, string $fieldActorId) {
|
||||
|
||||
if ($qb->getType() !== QueryBuilder::SELECT) {
|
||||
return;
|
||||
}
|
||||
|
||||
$expr = $qb->expr();
|
||||
$pf = $this->defaultSelectAlias;
|
||||
|
||||
// /** @noinspection PhpMethodParametersCountMismatchInspection */
|
||||
// $qb->selectAlias('s.address', 'service_address')
|
||||
// ->selectAlias('s.status', 'service_status')
|
||||
// ->selectAlias('s.config', 'service_config')
|
||||
// ->selectAlias('s.type', 'service_type')
|
||||
// ->leftJoin(
|
||||
// $this->defaultSelectAlias, CoreRequestBuilder::TABLE_SERVICES, 's',
|
||||
// $expr->eq($pf . '.service_id', 's.id')
|
||||
// );
|
||||
// }
|
||||
$qb->selectAlias('ca.id', 'cacheactor_id')
|
||||
->selectAlias('ca.account', 'cacheactor_account')
|
||||
->selectAlias('ca.following', 'cacheactor_following')
|
||||
->selectAlias('ca.followers', 'cacheactor_followers')
|
||||
->selectAlias('ca.inbox', 'cacheactor_inbox')
|
||||
->selectAlias('ca.shared_inbox', 'cacheactor_shared_inbox')
|
||||
->selectAlias('ca.outbox', 'cacheactor_outbox')
|
||||
->selectAlias('ca.featured', 'cacheactor_featured')
|
||||
->selectAlias('ca.url', 'cacheactor_url')
|
||||
->selectAlias('ca.preferred_username', 'cacheactor_preferred_username')
|
||||
->selectAlias('ca.name', 'cacheactor_name')
|
||||
->selectAlias('ca.summary', 'cacheactor_summary')
|
||||
->selectAlias('ca.public_key', 'cacheactor_public_key')
|
||||
->selectAlias('ca.creation', 'cacheactor_creation')
|
||||
->leftJoin(
|
||||
$this->defaultSelectAlias, CoreRequestBuilder::TABLE_CACHE_ACTORS, 'ca',
|
||||
$expr->eq($pf . '.' . $fieldActorId, 'ca.id')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Person
|
||||
* @throws InvalidResourceException
|
||||
*/
|
||||
protected function parseCacheActorsLeftJoin(array $data): Person {
|
||||
$new = [];
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
if (substr($k, 0, 11) === 'cacheactor_') {
|
||||
$new[substr($k, 11)] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
$actor = new Person();
|
||||
$actor->import($new);
|
||||
|
||||
if ($actor->getType() !== 'Person') {
|
||||
throw new InvalidResourceException();
|
||||
}
|
||||
|
||||
return $actor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -99,14 +99,16 @@ class NotesRequest extends NotesRequestBuilder {
|
|||
|
||||
|
||||
/**
|
||||
* @param string $actorId
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPublicNotes($since = 0, $limit = 5): array {
|
||||
public function getPublicNotes(int $since = 0, int $limit = 5): array {
|
||||
$qb = $this->getNotesSelectSql();
|
||||
$this->limitToRecipient($qb, ActivityService::TO_PUBLIC);
|
||||
$this->limitPaginate($qb, $since, $limit);
|
||||
$this->leftJoinCacheActors($qb, 'attributed_to');
|
||||
|
||||
$notes = [];
|
||||
$cursor = $qb->execute();
|
||||
|
@ -126,6 +128,7 @@ class NotesRequest extends NotesRequestBuilder {
|
|||
public function getNotesForActorId(string $actorId): array {
|
||||
$qb = $this->getNotesSelectSql();
|
||||
$this->limitToRecipient($qb, $actorId);
|
||||
$this->leftJoinCacheActors($qb, 'attributed_to');
|
||||
|
||||
$notes = [];
|
||||
$cursor = $qb->execute();
|
||||
|
|
|
@ -31,8 +31,8 @@ namespace OCA\Social\Db;
|
|||
|
||||
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Model\ActivityPub\Note;
|
||||
use OCA\Social\Model\Post;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
|
||||
class NotesRequestBuilder extends CoreRequestBuilder {
|
||||
|
@ -118,32 +118,15 @@ class NotesRequestBuilder extends CoreRequestBuilder {
|
|||
->setAttributedTo($data['attributed_to'])
|
||||
->setInReplyTo($data['in_reply_to']);
|
||||
|
||||
try {
|
||||
$actor = $this->parseCacheActorsLeftJoin($data);
|
||||
$note->setCompleteDetails(true);
|
||||
$note->setActor($actor);
|
||||
} catch (InvalidResourceException $e) {
|
||||
}
|
||||
|
||||
return $note;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Post
|
||||
*/
|
||||
protected function parsePostsSelectSql($userId, $data): Note {
|
||||
$post = new Post($userId);
|
||||
|
||||
$post->setContent($data['content']);
|
||||
|
||||
// $note->setId($data['id'])
|
||||
// ->setTo($data['to'])
|
||||
// ->setToArray(json_decode($data['to_array'], true))
|
||||
// ->setCc(json_decode($data['cc'], true))
|
||||
// ->setBcc(json_decode($data['bcc']));
|
||||
// $note->setContent($data['content'])
|
||||
// ->setPublished($data['published'])
|
||||
// ->setAttributedTo($data['attributed_to'])
|
||||
// ->setInReplyTo($data['in_reply_to']);
|
||||
|
||||
return $post;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ abstract class ACore implements JsonSerializable {
|
|||
/** @var ICoreService */
|
||||
private $saveAs;
|
||||
|
||||
/** @var bool */
|
||||
private $completeDetails = false;
|
||||
|
||||
/**
|
||||
* Core constructor.
|
||||
|
@ -685,6 +687,25 @@ abstract class ACore implements JsonSerializable {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isCompleteDetails(): bool {
|
||||
return $this->completeDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $completeDetails
|
||||
*
|
||||
* @return ACore
|
||||
*/
|
||||
public function setCompleteDetails(bool $completeDetails): ACore {
|
||||
$this->completeDetails = $completeDetails;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
|
@ -727,6 +748,9 @@ abstract class ACore implements JsonSerializable {
|
|||
'actor', $this->getActor()
|
||||
->getId()
|
||||
);
|
||||
if ($this->isCompleteDetails()) {
|
||||
$this->addEntryItem('actor_info', $this->getActor());
|
||||
}
|
||||
} else {
|
||||
$this->addEntry('actor', $this->getActorId());
|
||||
}
|
||||
|
|
|
@ -353,6 +353,10 @@ class Person extends ACore implements JsonSerializable {
|
|||
->setSharedInbox($this->get('shared_inbox', $data, ''))
|
||||
->setFeatured($this->get('featured', $data, ''))
|
||||
->setCreation($this->getInt('creation', $data, 0));
|
||||
|
||||
if ($this->getPreferredUsername() === '') {
|
||||
$this->setType('Invalid');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -371,6 +375,7 @@ class Person extends ACore implements JsonSerializable {
|
|||
'name' => $this->getName(),
|
||||
'inbox' => $this->getInbox(),
|
||||
'outbox' => $this->getOutbox(),
|
||||
'account' => $this->getAccount(),
|
||||
'following' => $this->getFollowing(),
|
||||
'followers' => $this->getFollowers(),
|
||||
'endpoints' =>
|
||||
|
|
|
@ -236,17 +236,9 @@ class NoteService implements ICoreService {
|
|||
*
|
||||
* @return Note[]
|
||||
*/
|
||||
public function getTimeline($since = 0, $limit = 5): array {
|
||||
$notes = $this->notesRequest->getPublicNotes($since, $limit);
|
||||
$result = [];
|
||||
/** @var Note $note */
|
||||
foreach ($notes as $note) {
|
||||
$actor = $this->actorService->getActorById($note->getAttributedTo());
|
||||
$noteEnhanced = $note->jsonSerialize();
|
||||
$noteEnhanced['actor'] = $actor->jsonSerialize();
|
||||
$result[] = $noteEnhanced;
|
||||
}
|
||||
return $result;
|
||||
public function getTimeline(int $since = 0, int $limit = 5): array {
|
||||
return $this->notesRequest->getPublicNotes($since, $limit);
|
||||
// return $result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -175,6 +175,5 @@ class PersonService implements ICoreService {
|
|||
$this->cacheActorsRequest->save($person);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue