Notification and Migration

Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
nickvergessen-patch-1
Maxence Lange 2020-06-25 01:48:36 -01:00
rodzic ad633a712c
commit 856518cdae
19 zmienionych plików z 450 dodań i 28 usunięć

Wyświetl plik

@ -33,3 +33,9 @@ namespace OCA\Social\AppInfo;
require_once __DIR__ . '/autoload.php';
/** @var Application $app */
$app = \OC::$server->query(Application::class);
$app->checkUpgradeStatus();

Wyświetl plik

@ -32,7 +32,7 @@
<repository type="git">https://github.com/nextcloud/social.git</repository>
<screenshot>https://raw.githubusercontent.com/nextcloud/social/master/img/screenshot.png</screenshot>
<dependencies>
<nextcloud min-version="15" max-version="19"/>
<nextcloud min-version="17" max-version="19"/>
<database>pgsql</database>
<database>sqlite</database>
<database>mysql</database>

Wyświetl plik

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="32"
height="32"
viewBox="0 0 32 32"
id="svg4"
sodipodi:docname="social.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1046"
id="namedview6"
showgrid="false"
inkscape:zoom="7.375"
inkscape:cx="-35.79661"
inkscape:cy="16"
inkscape:window-x="0"
inkscape:window-y="34"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M 16,29 13.97,27.152 C 6.76,20.614 2,16.288 2,11.01 2,6.684 5.388,3.31 9.7,3.31 c 2.436,0 4.774,1.134 6.3,2.912 1.526,-1.778 3.864,-2.912 6.3,-2.912 4.312,0 7.7,3.374 7.7,7.7 0,5.278 -4.76,9.604 -11.97,16.142 z"
id="path2"
inkscape:connector-curvature="0"
style="fill:#000000;stroke-width:1.39999998" />
</svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.7 KiB

Wyświetl plik

@ -31,15 +31,36 @@ declare(strict_types=1);
namespace OCA\Social\AppInfo;
use OC\DB\SchemaWrapper;
use OCA\Social\Notification\Notifier;
use OCA\Social\Service\ConfigService;
use OCA\Social\Service\UpdateService;
use OCP\AppFramework\App;
use OCP\AppFramework\IAppContainer;
use OCP\AppFramework\QueryException;
/**
* Class Application
*
* @package OCA\Social\AppInfo
*/
class Application extends App {
const APP_NAME = 'social';
/** @var ConfigService */
private $configService;
/** @var UpdateService */
private $updateService;
/** @var IAppContainer */
private $container;
/**
* Application constructor.
*
@ -47,6 +68,41 @@ class Application extends App {
*/
public function __construct(array $params = []) {
parent::__construct(self::APP_NAME, $params);
$this->container = $this->getContainer();
$manager = $this->container->getServer()
->getNotificationManager();
$manager->registerNotifierService(Notifier::class);
}
/**
*
*/
public function checkUpgradeStatus() {
$upgradeChecked = $this->container->getServer()
->getConfig()
->getAppValue(Application::APP_NAME, 'update_checked', '');
if ($upgradeChecked === '0.3') {
return;
}
try {
$this->configService = $this->container->query(ConfigService::class);
$this->updateService = $this->container->query(UpdateService::class);
} catch (QueryException $e) {
return;
}
$server = $this->container->getServer();
$schema = new SchemaWrapper($server->getDatabaseConnection());
if ($schema->hasTable('social_a2_stream')) {
$this->updateService->checkUpdateStatus();
}
$this->configService->setAppValue('update_checked', '0.3');
}
}

Wyświetl plik

@ -88,6 +88,7 @@ class ActionsRequestBuilder extends CoreRequestBuilder {
->from(self::TABLE_ACTIONS, 'a');
$this->defaultSelectAlias = 'a';
$qb->setDefaultSelectAlias('a');
return $qb;
}
@ -104,6 +105,7 @@ class ActionsRequestBuilder extends CoreRequestBuilder {
->from(self::TABLE_ACTIONS, 'a');
$this->defaultSelectAlias = 'a';
$qb->setDefaultSelectAlias('a');
return $qb;
}

Wyświetl plik

@ -70,10 +70,10 @@ class ActorsRequestBuilder extends CoreRequestBuilder {
/**
* Base of the Sql Select request for Shares
*
* @return IQueryBuilder
* @return SocialQueryBuilder
*/
protected function getActorsSelectSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
protected function getActorsSelectSql(): SocialQueryBuilder {
$qb = $this->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
@ -83,6 +83,7 @@ class ActorsRequestBuilder extends CoreRequestBuilder {
->from(self::TABLE_ACTORS, 'a');
$this->defaultSelectAlias = 'a';
$qb->setDefaultSelectAlias('a');
return $qb;
}

Wyświetl plik

@ -90,7 +90,8 @@ class CacheActorsRequestBuilder extends CoreRequestBuilder {
/** @deprecated */
$this->defaultSelectAlias = 'ca';
$qb->setDefaultSelectAlias('ca');
return $qb;
}

Wyświetl plik

@ -69,10 +69,10 @@ class CacheDocumentsRequestBuilder extends CoreRequestBuilder {
/**
* Base of the Sql Select request for Shares
*
* @return IQueryBuilder
* @return SocialQueryBuilder
*/
protected function getCacheDocumentsSelectSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
protected function getCacheDocumentsSelectSql(): SocialQueryBuilder {
$qb = $this->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
@ -82,6 +82,7 @@ class CacheDocumentsRequestBuilder extends CoreRequestBuilder {
->from(self::TABLE_CACHE_DOCUMENTS, 'cd');
$this->defaultSelectAlias = 'cd';
$qb->setDefaultSelectAlias('cd');
return $qb;
}

Wyświetl plik

@ -167,7 +167,7 @@ class FollowsRequest extends FollowsRequestBuilder {
*/
public function countFollowers(string $actorId): int {
$qb = $this->countFollowsSelectSql();
$qb->limitToObjectId($actorId);
$qb->limitToObjectIdPrim($qb->prim($actorId));
$qb->limitToType(Follow::TYPE);
$qb->limitToAccepted(true);
@ -186,7 +186,7 @@ class FollowsRequest extends FollowsRequestBuilder {
*/
public function countFollowing(string $actorId): int {
$qb = $this->countFollowsSelectSql();
$qb->limitToActorId($actorId);
$qb->limitToActorIdPrim($qb->prim($actorId));
$qb->limitToType(Follow::TYPE);
$qb->limitToAccepted(true);

Wyświetl plik

@ -77,10 +77,10 @@ class FollowsRequestBuilder extends CoreRequestBuilder {
/**
* Base of the Sql Select request for Shares
*
* @return IQueryBuilder
* @return SocialQueryBuilder
*/
protected function getFollowsSelectSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
protected function getFollowsSelectSql(): SocialQueryBuilder {
$qb = $this->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
@ -89,6 +89,7 @@ class FollowsRequestBuilder extends CoreRequestBuilder {
->from(self::TABLE_FOLLOWS, 'f');
$this->defaultSelectAlias = 'f';
$qb->setDefaultSelectAlias('f');
return $qb;
}
@ -104,6 +105,7 @@ class FollowsRequestBuilder extends CoreRequestBuilder {
$qb->selectAlias($qb->createFunction('COUNT(*)'), 'count')
->from(self::TABLE_FOLLOWS, 'f');
$qb->setDefaultSelectAlias('f');
$this->defaultSelectAlias = 'f';
return $qb;

Wyświetl plik

@ -75,16 +75,17 @@ class HashtagsRequestBuilder extends CoreRequestBuilder {
/**
* Base of the Sql Select request for Shares
*
* @return IQueryBuilder
* @return SocialQueryBuilder
*/
protected function getHashtagsSelectSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
protected function getHashtagsSelectSql(): SocialQueryBuilder {
$qb = $this->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select('h.hashtag', 'h.trend')
->from(self::TABLE_HASHTAGS, 'h');
$this->defaultSelectAlias = 'h';
$qb->setDefaultSelectAlias('h');
return $qb;
}

Wyświetl plik

@ -72,7 +72,7 @@ class RequestQueueRequestBuilder extends CoreRequestBuilder {
* @return IQueryBuilder
*/
protected function getRequestQueueSelectSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
$qb = $this->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
@ -82,6 +82,7 @@ class RequestQueueRequestBuilder extends CoreRequestBuilder {
->from(self::TABLE_REQUEST_QUEUE, 'rq');
$this->defaultSelectAlias = 'rq';
$qb->setDefaultSelectAlias('rq');
return $qb;
}

Wyświetl plik

@ -75,16 +75,17 @@ class StreamActionsRequestBuilder extends CoreRequestBuilder {
/**
* Base of the Sql Select request for Shares
*
* @return IQueryBuilder
* @return SocialQueryBuilder
*/
protected function getStreamActionSelectSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
protected function getStreamActionSelectSql(): SocialQueryBuilder {
$qb = $this->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select('sa.id', 'sa.actor_id', 'sa.stream_id', 'sa.values')
->from(self::TABLE_STREAM_ACTIONS, 'sa');
$this->defaultSelectAlias = 'sa';
$qb->setDefaultSelectAlias('sa');
return $qb;
}

Wyświetl plik

@ -74,9 +74,9 @@ class StreamDestRequestBuilder extends CoreRequestBuilder {
/**
* Base of the Sql Select request for Shares
*
* @return IQueryBuilder
* @return SocialQueryBuilder
*/
protected function getStreamDestSelectSql(): IQueryBuilder {
protected function getStreamDestSelectSql(): SocialQueryBuilder {
$qb = $this->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
@ -84,6 +84,7 @@ class StreamDestRequestBuilder extends CoreRequestBuilder {
->from(self::TABLE_STREAM_DEST, 'sd');
$this->defaultSelectAlias = 'sd';
$qb->setDefaultSelectAlias('sd');
return $qb;
}
@ -105,14 +106,15 @@ class StreamDestRequestBuilder extends CoreRequestBuilder {
/**
* Base of the Sql Select request for Shares
*
* @return IQueryBuilder
* @return SocialQueryBuilder
*/
protected function countStreamDestSelectSql(): IQueryBuilder {
protected function countStreamDestSelectSql(): SocialQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->selectAlias($qb->createFunction('COUNT(*)'), 'count')
->from(self::TABLE_STREAM_DEST, 'sd');
$this->defaultSelectAlias = 'sd';
$qb->setDefaultSelectAlias('sd');
return $qb;
}

Wyświetl plik

@ -91,7 +91,7 @@ class StreamQueueRequest extends StreamQueueRequestBuilder {
*/
public function getFromToken(string $token): array {
$qb = $this->getStreamQueueSelectSql();
$this->limitToToken($qb, $token);
$qb->limitToToken($token);
$queue = [];
$cursor = $qb->execute();

Wyświetl plik

@ -69,10 +69,10 @@ class StreamQueueRequestBuilder extends CoreRequestBuilder {
/**
* Base of the Sql Select request for Shares
*
* @return IQueryBuilder
* @return SocialQueryBuilder
*/
protected function getStreamQueueSelectSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
protected function getStreamQueueSelectSql(): SocialQueryBuilder {
$qb = $this->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
@ -81,6 +81,7 @@ class StreamQueueRequestBuilder extends CoreRequestBuilder {
->from(self::TABLE_STREAM_QUEUE, 'qs');
$this->defaultSelectAlias = 'qs';
$qb->setDefaultSelectAlias('qs');
return $qb;
}

Wyświetl plik

@ -84,6 +84,7 @@ class StreamTagsRequestBuilder extends CoreRequestBuilder {
->from(self::TABLE_STREAM_TAGS, 'st');
$this->defaultSelectAlias = 'st';
$qb->setDefaultSelectAlias('st');
return $qb;
}

Wyświetl plik

@ -0,0 +1,150 @@
<?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\Notification;
use InvalidArgumentException;
use OC;
use OCA\Social\AppInfo\Application;
use OCP\Contacts\IManager;
use OCP\Federation\ICloudIdManager;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\L10N\IFactory;
use OCP\Notification\INotification;
use OCP\Notification\INotifier;
/**
* Class Notifier
*
* @package OCA\Social\Notification
*/
class Notifier implements INotifier {
/** @var IL10N */
private $l10n;
/** @var IFactory */
protected $factory;
/** @var IManager */
protected $contactsManager;
/** @var IURLGenerator */
protected $url;
/** @var ICloudIdManager */
protected $cloudIdManager;
public function __construct(
IL10N $l10n, IFactory $factory, IManager $contactsManager, IURLGenerator $url,
ICloudIdManager $cloudIdManager
) {
$this->l10n = $l10n;
$this->factory = $factory;
$this->contactsManager = $contactsManager;
$this->url = $url;
$this->cloudIdManager = $cloudIdManager;
}
/**
* Identifier of the notifier, only use [a-z0-9_]
*
* @return string
* @since 17.0.0
*/
public function getID(): string {
return Application::APP_NAME;
}
/**
* Human readable name describing the notifier
*
* @return string
* @since 17.0.0
*/
public function getName(): string {
return $this->l10n->t('Social');
}
/**
* @param INotification $notification
* @param string $languageCode The code of the language that should be used to prepare the notification
*
* @return INotification
* @throws InvalidArgumentException
*/
public function prepare(INotification $notification, string $languageCode): INotification {
if ($notification->getApp() !== Application::APP_NAME) {
throw new InvalidArgumentException();
}
$l10n = OC::$server->getL10N(Application::APP_NAME, $languageCode);
$notification->setIcon(
$this->url->getAbsoluteURL($this->url->imagePath('social', 'social_dark.svg'))
);
$params = $notification->getSubjectParameters();
switch ($notification->getSubject()) {
case 'update_alpha3':
$notification->setParsedSubject('The Social App have been updated to alpha3.');
$notification->setParsedMessage(
$l10n->t(
'Please note that the data from alpha2 can only be migrated manually.
A detailed documentation to guide you during this process is available using the button below.',
$params
)
);
break;
default:
throw new InvalidArgumentException();
}
foreach ($notification->getActions() as $action) {
switch ($action->getLabel()) {
case 'help':
$action->setParsedLabel((string)$l10n->t('Help'))
->setPrimary(true);
break;
}
$notification->addParsedAction($action);
}
return $notification;
}
}

Wyświetl plik

@ -0,0 +1,141 @@
<?php
/**
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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\Service;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IGroupManager;
use OCP\IUserManager;
use OCP\Notification\IManager as INotificationManager;
use OCP\Notification\INotification;
/**
* Class UpdateService
*
* @package OCA\Social\Service
*/
class UpdateService {
/** @var IUserManager */
private $userManager;
/** @var IGroupManager */
private $groupManager;
/** @var ITimeFactory */
private $time;
/** @var INotificationManager */
private $notificationManager;
/** @var string */
private $updateId = 'alpha3';
/**
* UpdateService constructor.
*
* @param IUserManager $userManager
* @param IGroupManager $groupManager
* @param ITimeFactory $time
* @param INotificationManager $notificationManager
*/
public function __construct(
IUserManager $userManager, IGroupManager $groupManager, ITimeFactory $time,
INotificationManager $notificationManager
) {
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->time = $time;
$this->notificationManager = $notificationManager;
}
public function checkUpdateStatus() {
$notifications = $this->generateNotifications(true, 'update_alpha3', []);
foreach ($notifications as $notif) {
$help = $notif->createAction();
$help->setLabel('help')
->setLink('https://help.nextcloud.com/t/social-alpha3-how-to-upgrade/85535', 'WEB');
$notif->addAction($help);
$this->notificationManager->notify($notif);
}
}
/**
* @param bool $adminOnly
* @param string $subject
* @param array $data
*
* @return INotification[]
*/
public function generateNotifications(bool $adminOnly, string $subject, array $data): array {
$notifications = [];
$users = $this->userManager->search('');
if ($adminOnly) {
$admin = [];
foreach ($users as $user) {
if ($this->groupManager->isAdmin($user->getUID())) {
$admin[] = $user;
}
}
$users = $admin;
}
foreach ($users as $user) {
$notifications[] = $this->createNotification($user->getUID(), $subject, $data);
}
return $notifications;
}
/**
* @param string $userId
* @param string $subject
* @param array $data
*
* @return INotification
*/
public function createNotification(string $userId, string $subject, array $data): INotification {
$now = $this->time->getDateTime();
$notification = $this->notificationManager->createNotification();
$notification->setApp('social')
->setDateTime($now)
->setUser($userId)
->setObject('update', 'update_' . $this->updateId)
->setSubject($subject, $data);
return $notification;
}
}