summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Molenaar <sean@seanmolenaar.eu>2020-09-29 13:54:17 +0200
committerBenjamin Brahmer <info@b-brahmer.de>2020-09-29 14:56:07 +0200
commit35b53ecd404a74edea3c6866e451c4819bdc9ea8 (patch)
treedac46834d8fa7ec0122243f94604c3d2215b4d22
parentd6d169be15913404f99b86c39a03bc71942c9f77 (diff)
OPML export command and fixes
Signed-off-by: Sean Molenaar <sean@seanmolenaar.eu>
-rw-r--r--.github/workflows/integration-tests.yml3
-rw-r--r--CHANGELOG.md21
-rw-r--r--appinfo/info.xml5
-rw-r--r--composer.json3
-rw-r--r--composer.lock5
-rw-r--r--lib/Command/Config/OpmlExport.php50
-rw-r--r--lib/Command/ShowFeed.php11
-rw-r--r--lib/Config/FetcherConfig.php4
-rw-r--r--lib/Controller/AdminController.php11
-rw-r--r--lib/Controller/ApiController.php1
-rw-r--r--lib/Controller/EntityApiSerializer.php2
-rw-r--r--lib/Controller/ExportController.php48
-rw-r--r--lib/Controller/FeedApiController.php31
-rw-r--r--lib/Controller/FeedController.php57
-rw-r--r--lib/Controller/FolderApiController.php23
-rw-r--r--lib/Controller/FolderController.php37
-rw-r--r--lib/Controller/ItemApiController.php47
-rw-r--r--lib/Controller/ItemController.php22
-rw-r--r--lib/Controller/JSONHttpErrorTrait.php2
-rw-r--r--lib/Controller/PageController.php6
-rw-r--r--lib/Controller/UserApiController.php5
-rw-r--r--lib/Controller/UtilityApiController.php2
-rw-r--r--lib/Db/EntityJSONSerializer.php10
-rw-r--r--lib/Db/Feed.php38
-rw-r--r--lib/Db/FeedMapperV2.php2
-rw-r--r--lib/Db/Folder.php20
-rw-r--r--lib/Db/FolderMapperV2.php2
-rw-r--r--lib/Db/Item.php84
-rw-r--r--lib/Db/ItemMapperV2.php10
-rw-r--r--lib/Db/NewsMapperV2.php3
-rw-r--r--lib/Explore/RecommendedSites.php2
-rw-r--r--lib/Fetcher/Fetcher.php4
-rw-r--r--lib/Fetcher/FetcherException.php2
-rw-r--r--lib/Fetcher/YoutubeFetcher.php2
-rw-r--r--lib/Http/TextDownloadResponse.php51
-rw-r--r--lib/Http/TextResponse.php49
-rw-r--r--lib/Service/Exceptions/ServiceConflictException.php2
-rw-r--r--lib/Service/Exceptions/ServiceException.php2
-rw-r--r--lib/Service/Exceptions/ServiceNotFoundException.php2
-rw-r--r--lib/Service/Exceptions/ServiceValidationException.php2
-rw-r--r--lib/Service/FeedService.php2
-rw-r--r--lib/Service/FeedServiceV2.php2
-rw-r--r--lib/Service/FolderService.php2
-rw-r--r--lib/Service/FolderServiceV2.php2
-rw-r--r--lib/Service/ItemService.php2
-rw-r--r--lib/Service/ItemServiceV2.php10
-rw-r--r--lib/Service/OpmlService.php69
-rw-r--r--lib/Service/Service.php7
-rw-r--r--lib/Service/UpdaterService.php8
-rw-r--r--lib/Settings/AdminSection.php (renamed from lib/Settings/Section.php)2
-rw-r--r--lib/Utility/OPMLExporter.php5
-rw-r--r--tests/Unit/Controller/ExportControllerTest.php71
-rw-r--r--tests/Unit/Controller/FolderApiControllerTest.php2
-rw-r--r--tests/Unit/Controller/FolderControllerTest.php4
-rw-r--r--tests/Unit/Controller/ItemApiControllerTest.php4
-rw-r--r--tests/Unit/Controller/ItemControllerTest.php16
-rw-r--r--tests/Unit/Controller/JSONHttpErrorTest.php14
-rw-r--r--tests/Unit/Controller/PageControllerTest.php2
-rw-r--r--tests/Unit/Http/TextDownloadResponseTest.php38
-rw-r--r--tests/Unit/Http/TextResponseTest.php51
-rw-r--r--tests/Unit/Service/ServiceTest.php2
61 files changed, 506 insertions, 492 deletions
diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml
index 77d35d2a1..171c6d43b 100644
--- a/.github/workflows/integration-tests.yml
+++ b/.github/workflows/integration-tests.yml
@@ -104,9 +104,10 @@ jobs:
./occ news:generate-explore --votes 100 "https://nextcloud.com/blog/feed/"
./occ news:folder:add 'admin' 'Something'
./occ news:folder:list 'admin' | grep 'Something'
- ./occ news:folder:delete 'admin' $(./occ news:folder:list 'admin' | grep 'Something' -1 | head -1 | grep -oE '[0-9]*')
./occ news:feed:add 'admin' "https://nextcloud.com/blog/feed/"
./occ news:feed:list 'admin' | grep 'nextcloud\.com'
+ ./occ news:opml:export 'admin' | grep 'nextcloud\.com'
+ ./occ news:folder:delete 'admin' $(./occ news:folder:list 'admin' | grep 'Something' -1 | head -1 | grep -oE '[0-9]*')
./occ news:feed:delete 'admin' $(./occ news:feed:list 'admin' | grep 'nextcloud\.com' -1 | head -1 | grep -oE '[0-9]*')
- name: Prep PHP tests
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee244d80b..f48f0c469 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file.
## Unreleased
+- Drop support before nextcloud 20
+- Move to modern SQL syntax
+- Add management commands
+```shell script
+./occ news:opml:export <userID>
+
+./occ news:folder:add <userID> <name>
+./occ news:folder:list <userID>
+./occ news:folder:delete <userID>
+
+./occ news:feed:add <userID> <URL>
+./occ news:feed:list <userID>
+./occ news:feed:delete <userID>
+```
+
## 14.2.2
### Changed
@@ -99,7 +114,7 @@ All notable changes to this project will be documented in this file.
## 14.1.2
## Changed
-- Updated js packages
+- Updated js packages
### Fixed
- Signature was missing
@@ -163,7 +178,7 @@ All notable changes to this project will be documented in this file.
### Fixed
- Fixed some feeds with a empty body #474
- Restored full text by default for some feeds #479
-- Some smaller adjustments for the design #463 #464
+- Some smaller adjustments for the design #463 #464
## 13.1.4
@@ -187,7 +202,7 @@ All notable changes to this project will be documented in this file.
- Highlight in compact mode #109
- Prevent raw angluar templates from flashing on page load #429
- HTML elements where not rendered #428
-- Provide UserAgent to prevent HTTP 403 errors #428
+- Provide UserAgent to prevent HTTP 403 errors #428
## 13.1.1
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 86c848d65..9297fa5e8 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -65,11 +65,12 @@ Before you update to a new version, [check the changelog](https://github.com/nex
<command>OCA\News\Command\Config\FeedAdd</command>
<command>OCA\News\Command\Config\FeedDelete</command>
<command>OCA\News\Command\Config\FeedDelete</command>
+ <command>OCA\News\Command\Config\OpmlExport</command>
</commands>
<settings>
- <admin>OCA\News\Settings\Admin</admin>
- <admin-section>OCA\News\Settings\Section</admin-section>
+ <admin>OCA\News\Settings\AdminSettings</admin>
+ <admin-section>OCA\News\Settings\AdminSection</admin-section>
</settings>
<navigations>
diff --git a/composer.json b/composer.json
index a5cbc622e..a5a00775f 100644
--- a/composer.json
+++ b/composer.json
@@ -51,7 +51,8 @@
"ext-json": "*",
"ext-simplexml": "*",
"ext-libxml": "*",
- "ext-dom": "*"
+ "ext-dom": "*",
+ "ext-curl": "*"
},
"require-dev": {
"phpunit/phpunit": "9.2.*",
diff --git a/composer.lock b/composer.lock
index f305f3294..5078effa1 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "e553641d7a0ca7ff73af7bdbc2c47617",
+ "content-hash": "63f7665291caac91a887b6eb20a03db7",
"packages": [
{
"name": "andreskrey/readability.php",
@@ -2298,7 +2298,8 @@
"ext-json": "*",
"ext-simplexml": "*",
"ext-libxml": "*",
- "ext-dom": "*"
+ "ext-dom": "*",
+ "ext-curl": "*"
},
"platform-dev": [],
"plugin-api-version": "1.1.0"
diff --git a/lib/Command/Config/OpmlExport.php b/lib/Command/Config/OpmlExport.php
new file mode 100644
index 000000000..1642e8505
--- /dev/null
+++ b/lib/Command/Config/OpmlExport.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace OCA\News\Command\Config;
+
+use OCA\News\Service\OpmlService;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class OpmlExport extends Command
+{
+ /**
+ * @var OpmlService service for the data.
+ */
+ protected $opmlService;
+
+ public function __construct(OpmlService $opmlService)
+ {
+ parent::__construct(null);
+
+ $this->opmlService = $opmlService;
+ }
+
+ /**
+ * Configure command
+ */
+ protected function configure()
+ {
+ $this->setName('news:opml:export')
+ ->setDescription('Print OPML file')
+ ->addArgument('userID', InputArgument::REQUIRED, 'User data to export');
+ }
+
+ /**
+ * Execute command
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ *
+ * @return int|void
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $user = $input->getArgument('userID');
+
+ $output->write($this->opmlService->export($user));
+ return 0;
+ }
+}
diff --git a/lib/Command/ShowFeed.php b/lib/Command/ShowFeed.php
index 1218279e6..8aace3528 100644
--- a/lib/Command/ShowFeed.php
+++ b/lib/Command/ShowFeed.php
@@ -50,6 +50,9 @@ class ShowFeed extends Command
$this->feedFetcher = $feedFetcher;
}
+ /**
+ * Configure the command
+ */
protected function configure()
{
$this->setName('news:show-feed')
@@ -60,6 +63,14 @@ class ShowFeed extends Command
->addOption('full-text', 'f', InputOption::VALUE_NONE, 'Usa a scraper to get full text');
}
+ /**
+ * Execute the command
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ *
+ * @return int
+ */
protected function execute(InputInterface $input, OutputInterface $output): int
{
$url = $input->getArgument('feed');
diff --git a/lib/Config/FetcherConfig.php b/lib/Config/FetcherConfig.php
index 4966f5b40..3e75d854a 100644
--- a/lib/Config/FetcherConfig.php
+++ b/lib/Config/FetcherConfig.php
@@ -98,9 +98,9 @@ class FetcherConfig
/**
* Configure a guzzle client
*
- * @return ClientInterface Legacy client to guzzle.
+ * @return ClientInterface Client to guzzle.
*/
- public function getClient()
+ public function getClient(): ClientInterface
{
$config = [
'timeout' => $this->client_timeout,
diff --git a/lib/Controller/AdminController.php b/lib/Controller/AdminController.php
index addc53591..e3551a2a1 100644
--- a/lib/Controller/AdminController.php
+++ b/lib/Controller/AdminController.php
@@ -67,12 +67,17 @@ class AdminController extends Controller
*
* @return TemplateResponse
*/
- public function index()
+ public function index(): TemplateResponse
{
return new TemplateResponse($this->appName, 'admin', $this->getData(), 'blank');
}
- private function getData()
+ /**
+ * Get admin data.
+ *
+ * @return array
+ */
+ private function getData(): array
{
$data = [];
@@ -108,7 +113,7 @@ class AdminController extends Controller
bool $useCronUpdates,
string $exploreUrl,
int $updateInterval
- ) {
+ ): array {
$this->config->setAppValue($this->appName, 'autoPurgeMinimumInterval', $autoPurgeMinimumInterval);
$this->config->setAppValue($this->appName, 'autoPurgeCount', $autoPurgeCount);
$this->config->setAppValue($this->appName, 'maxRedirects', $maxRedirects);
diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php
index 68caf9236..544b2c23b 100644
--- a/lib/Controller/ApiController.php
+++ b/lib/Controller/ApiController.php
@@ -16,6 +16,7 @@
namespace OCA\News\Controller;
use \OCP\IRequest;
+use OCP\IUser;
use \OCP\IUserSession;
use \OCP\AppFramework\ApiController as BaseApiController;
diff --git a/lib/Controller/EntityApiSerializer.php b/lib/Controller/EntityApiSerializer.php
index c7fdb84e5..daa0f20e5 100644
--- a/lib/Controller/EntityApiSerializer.php
+++ b/lib/Controller/EntityApiSerializer.php
@@ -57,7 +57,7 @@ class EntityApiSerializer
}
- private function convert($entities)
+ private function convert(array $entities)
{
$converted = [];
diff --git a/lib/Controller/ExportController.php b/lib/Controller/ExportController.php
index 16bdfbd4e..78f200934 100644
--- a/lib/Controller/ExportController.php
+++ b/lib/Controller/ExportController.php
@@ -13,39 +13,37 @@
namespace OCA\News\Controller;
+use OCA\News\Service\FeedServiceV2;
+use OCA\News\Service\FolderServiceV2;
+use OCA\News\Service\ItemServiceV2;
+use OCA\News\Service\OpmlService;
+use OCP\AppFramework\Http\DataDownloadResponse;
use \OCP\IRequest;
use \OCP\AppFramework\Controller;
-use \OCP\AppFramework\Http;
use \OCP\AppFramework\Http\JSONResponse;
-use \OCA\News\Http\TextDownloadResponse;
-use \OCA\News\Service\FolderService;
-use \OCA\News\Service\FeedService;
-use \OCA\News\Service\ItemService;
-use \OCA\News\Utility\OPMLExporter;
-
class ExportController extends Controller
{
- private $opmlExporter;
+ private $opmlService;
private $folderService;
private $feedService;
private $itemService;
private $userId;
public function __construct(
- $appName,
+ string $appName,
IRequest $request,
- FolderService $folderService,
- FeedService $feedService,
- ItemService $itemService,
- OPMLExporter $opmlExporter,
- $UserId
+ FolderServiceV2 $folderService,
+ FeedServiceV2 $feedService,
+ ItemServiceV2 $itemService,
+ OpmlService $opmlService,
+ string $UserId
) {
parent::__construct($appName, $request);
$this->feedService = $feedService;
$this->folderService = $folderService;
- $this->opmlExporter = $opmlExporter;
+ $this->opmlService = $opmlService;
$this->itemService = $itemService;
$this->userId = $UserId;
}
@@ -55,15 +53,15 @@ class ExportController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
- public function opml()
+ public function opml(): DataDownloadResponse
{
- $feeds = $this->feedService->findAll($this->userId);
- $folders = $this->folderService->findAll($this->userId);
- $opml = $this->opmlExporter->build($folders, $feeds)->saveXML();
$date = date('Y-m-d');
- $name = "subscriptions-" . $date . ".opml";
- $mimeType = 'text/xml';
- return new TextDownloadResponse($opml, $name, $mimeType);
+
+ return new DataDownloadResponse(
+ $this->opmlService->export($this->userId),
+ "subscriptions-${date}.opml",
+ 'text/xml'
+ );
}
@@ -71,10 +69,10 @@ class ExportController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
- public function articles()
+ public function articles(): JSONResponse
{
- $feeds = $this->feedService->findAll($this->userId);
- $items = $this->itemService->getUnreadOrStarred($this->userId);
+ $feeds = $this->feedService->findAllForUser($this->userId);
+ $items = $this->itemService->findAllForUser($this->userId, ['unread' => true, 'starred' => true]);
// build assoc array for fast access
$feedsDict = [];
diff --git a/lib/Controller/FeedApiController.php b/lib/Controller/FeedApiController.php
index c0b4f1a56..cb3d5e645 100644
--- a/lib/Controller/FeedApiController.php
+++ b/lib/Controller/FeedApiController.php
@@ -18,6 +18,7 @@ namespace OCA\News\Controller;
use OCA\News\Service\Exceptions\ServiceConflictException;
use OCA\News\Service\Exceptions\ServiceNotFoundException;
use OCA\News\Utility\PsrLogger;
+use OCP\AppFramework\Http\JSONResponse;
use \OCP\IRequest;
use \OCP\ILogger;
use \OCP\IUserSession;
@@ -52,7 +53,7 @@ class FeedApiController extends ApiController
private $serializer;
public function __construct(
- $appName,
+ string $appName,
IRequest $request,
IUserSession $userSession,
FeedService $feedService,
@@ -72,7 +73,7 @@ class FeedApiController extends ApiController
* @NoCSRFRequired
* @CORS
*/
- public function index()
+ public function index(): array
{
$result = [
@@ -100,9 +101,10 @@ class FeedApiController extends ApiController
*
* @param string $url
* @param int $folderId
- * @return array|mixed|\OCP\AppFramework\Http\JSONResponse
+ *
+ * @return array|mixed|JSONResponse
*/
- public function create($url, $folderId = 0)
+ public function create(string $url, int $folderId = 0)
{
try {
$this->feedService->purgeDeleted($this->getUserId(), false);
@@ -133,9 +135,10 @@ class FeedApiController extends ApiController
* @CORS
*
* @param int $feedId
- * @return array|\OCP\AppFramework\Http\JSONResponse
+ *
+ * @return array|JSONResponse
*/
- public function delete($feedId)
+ public function delete(int $feedId)
{
try {
$this->feedService->delete($feedId, $this->getUserId());
@@ -155,7 +158,7 @@ class FeedApiController extends ApiController
* @param int $feedId
* @param int $newestItemId
*/
- public function read($feedId, $newestItemId)
+ public function read(int $feedId, int $newestItemId): void
{
$this->itemService->readFeed($feedId, $newestItemId, $this->getUserId());
}
@@ -168,9 +171,10 @@ class FeedApiController extends ApiController
*
* @param int $feedId
* @param int $folderId
- * @return array|\OCP\AppFramework\Http\JSONResponse
+ *
+ * @return array|JSONResponse
*/
- public function move($feedId, $folderId)
+ public function move(int $feedId, int $folderId)
{
try {
$this->feedService->patch(
@@ -193,9 +197,10 @@ class FeedApiController extends ApiController
*
* @param int $feedId
* @param string $feedTitle
- * @return array|\OCP\AppFramework\Http\JSONResponse
+ *
+ * @return array|JSONResponse
*/
- public function rename($feedId, $feedTitle)
+ public function rename(int $feedId, string $feedTitle)
{
try {
$this->feedService->patch(
@@ -215,7 +220,7 @@ class FeedApiController extends ApiController
* @NoCSRFRequired
* @CORS
*/
- public function fromAllUsers()
+ public function fromAllUsers(): array
{
$feeds = $this->feedService->findAllFromAllUsers();
$result = ['feeds' => []];
@@ -237,7 +242,7 @@ class FeedApiController extends ApiController
* @param string $userId
* @param int $feedId
*/
- public function update($userId, $feedId)
+ public function update(string $userId, int $feedId): void
{
try {
$this->feedService->update($userId, $feedId);
diff --git a/lib/Controller/FeedController.php b/lib/Controller/FeedController.php
index d0c25d55b..c09096bd9 100644
--- a/lib/Controller/FeedController.php
+++ b/lib/Controller/FeedController.php
@@ -15,6 +15,7 @@ namespace OCA\News\Controller;
use OCA\News\Service\Exceptions\ServiceConflictException;
use OCA\News\Service\Exceptions\ServiceNotFoundException;
+use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCP\IConfi