1
0
mirror of https://github.com/chylex/Nextcloud-News.git synced 2025-05-09 07:34:05 +02:00

Fix repair step and test it

Signed-off-by: Sean Molenaar <sean@seanmolenaar.eu>
This commit is contained in:
Sean Molenaar 2020-09-28 21:07:24 +02:00 committed by Benjamin Brahmer
parent d00d1ab2a2
commit bc01761221
28 changed files with 323 additions and 693 deletions

View File

@ -99,6 +99,8 @@ jobs:
- name: Functional tests - name: Functional tests
run: | run: |
cd ../server cd ../server
./occ migrations:migrate news
./occ maintenance:repair
./occ news:generate-explore --votes 100 "https://nextcloud.com/blog/feed/" ./occ news:generate-explore --votes 100 "https://nextcloud.com/blog/feed/"
./occ news:folder:add 'admin' 'Something' ./occ news:folder:add 'admin' 'Something'
./occ news:folder:list 'admin' | grep 'Something' ./occ news:folder:list 'admin' | grep 'Something'

View File

@ -1,20 +0,0 @@
<?php
/**
* Nextcloud - News
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Alessandro Cosentino <cosenal@gmail.com>
* @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright 2012 Alessandro Cosentino
* @copyright 2012-2014 Bernhard Posselt
*/
namespace OCA\News\AppInfo;
use OCA\News\Hooks\User;
require_once __DIR__ . '/../vendor/autoload.php';
\OCP\Util::connectHook('OC_User', 'pre_deleteUser', User::class, 'deleteUser');

View File

@ -45,19 +45,17 @@
"ezyang/htmlpurifier": "^4.13.0", "ezyang/htmlpurifier": "^4.13.0",
"pear/net_url2": "2.2.2", "pear/net_url2": "2.2.2",
"riimu/kit-pathjoin": "1.2.0", "riimu/kit-pathjoin": "1.2.0",
"debril/feed-io": "^v4.7.8", "debril/feed-io": "^v4.7.9",
"arthurhoaro/favicon": "^1.2", "arthurhoaro/favicon": "^1.3",
"andreskrey/readability.php": "^2.1",
"ext-json": "*", "ext-json": "*",
"ext-simplexml": "*", "ext-simplexml": "*",
"ext-libxml": "*", "ext-libxml": "*",
"andreskrey/readability.php": "^2.1",
"ext-dom": "*" "ext-dom": "*"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "9.2.6", "phpunit/phpunit": "9.2.*",
"squizlabs/php_codesniffer": "^3.5.6", "squizlabs/php_codesniffer": "^3.5.6",
"guzzlehttp/guzzle": "^6.3",
"symfony/service-contracts": "2.2.0",
"phpstan/phpstan": "^0.12.43" "phpstan/phpstan": "^0.12.43"
}, },
"replace": { "replace": {

375
composer.lock generated
View File

@ -4,7 +4,7 @@
"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#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "0f4161d1df33ea0b72224da925f2f6b5", "content-hash": "e553641d7a0ca7ff73af7bdbc2c47617",
"packages": [ "packages": [
{ {
"name": "andreskrey/readability.php", "name": "andreskrey/readability.php",
@ -763,28 +763,28 @@
}, },
{ {
"name": "phpspec/prophecy", "name": "phpspec/prophecy",
"version": "1.11.1", "version": "1.12.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpspec/prophecy.git", "url": "https://github.com/phpspec/prophecy.git",
"reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d",
"reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"doctrine/instantiator": "^1.2", "doctrine/instantiator": "^1.2",
"php": "^7.2", "php": "^7.2 || ~8.0, <8.1",
"phpdocumentor/reflection-docblock": "^5.0", "phpdocumentor/reflection-docblock": "^5.2",
"sebastian/comparator": "^3.0 || ^4.0", "sebastian/comparator": "^3.0 || ^4.0",
"sebastian/recursion-context": "^3.0 || ^4.0" "sebastian/recursion-context": "^3.0 || ^4.0"
}, },
"require-dev": { "require-dev": {
"phpspec/phpspec": "^6.0", "phpspec/phpspec": "^6.0",
"phpunit/phpunit": "^8.0" "phpunit/phpunit": "^8.0 || ^9.0 <9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -822,20 +822,20 @@
"spy", "spy",
"stub" "stub"
], ],
"time": "2020-07-08T12:44:21+00:00" "time": "2020-09-29T09:10:42+00:00"
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "0.12.45", "version": "0.12.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "90c67259212ed891ee86604a9368ef7d7bead3a4" "reference": "9419738e20f0c49757be05d22969c1c44c1dff3b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/90c67259212ed891ee86604a9368ef7d7bead3a4", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9419738e20f0c49757be05d22969c1c44c1dff3b",
"reference": "90c67259212ed891ee86604a9368ef7d7bead3a4", "reference": "9419738e20f0c49757be05d22969c1c44c1dff3b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -878,7 +878,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-09-26T19:19:00+00:00" "time": "2020-09-28T09:48:55+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
@ -952,23 +952,23 @@
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
"version": "3.0.4", "version": "3.0.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "25fefc5b19835ca653877fe081644a3f8c1d915e" "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/25fefc5b19835ca653877fe081644a3f8c1d915e", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8",
"reference": "25fefc5b19835ca653877fe081644a3f8c1d915e", "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1004,28 +1004,28 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-07-11T05:18:21+00:00" "time": "2020-09-28T05:57:25+00:00"
}, },
{ {
"name": "phpunit/php-invoker", "name": "phpunit/php-invoker",
"version": "3.1.0", "version": "3.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-invoker.git", "url": "https://github.com/sebastianbergmann/php-invoker.git",
"reference": "7a85b66acc48cacffdf87dadd3694e7123674298" "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/7a85b66acc48cacffdf87dadd3694e7123674298", "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
"reference": "7a85b66acc48cacffdf87dadd3694e7123674298", "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"ext-pcntl": "*", "ext-pcntl": "*",
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"suggest": { "suggest": {
"ext-pcntl": "*" "ext-pcntl": "*"
@ -1063,27 +1063,27 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-08-06T07:04:15+00:00" "time": "2020-09-28T05:58:55+00:00"
}, },
{ {
"name": "phpunit/php-text-template", "name": "phpunit/php-text-template",
"version": "2.0.2", "version": "2.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git", "url": "https://github.com/sebastianbergmann/php-text-template.git",
"reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324" "reference": "18c887016e60e52477e54534956d7b47bc52cd84"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/18c887016e60e52477e54534956d7b47bc52cd84",
"reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", "reference": "18c887016e60e52477e54534956d7b47bc52cd84",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1118,27 +1118,27 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T11:55:37+00:00" "time": "2020-09-28T06:03:05+00:00"
}, },
{ {
"name": "phpunit/php-timer", "name": "phpunit/php-timer",
"version": "5.0.1", "version": "5.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git", "url": "https://github.com/sebastianbergmann/php-timer.git",
"reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7" "reference": "c9ff14f493699e2f6adee9fd06a0245b276643b7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/cc49734779cbb302bf51a44297dab8c4bbf941e7", "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/c9ff14f493699e2f6adee9fd06a0245b276643b7",
"reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7", "reference": "c9ff14f493699e2f6adee9fd06a0245b276643b7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.2" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1173,7 +1173,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T11:58:13+00:00" "time": "2020-09-28T06:00:25+00:00"
}, },
{ {
"name": "phpunit/php-token-stream", "name": "phpunit/php-token-stream",
@ -1329,74 +1329,25 @@
], ],
"time": "2020-07-13T17:55:55+00:00" "time": "2020-07-13T17:55:55+00:00"
}, },
{
"name": "psr/container",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"time": "2017-02-14T16:28:37+00:00"
},
{ {
"name": "sebastian/code-unit", "name": "sebastian/code-unit",
"version": "1.0.5", "version": "1.0.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/code-unit.git", "url": "https://github.com/sebastianbergmann/code-unit.git",
"reference": "c1e2df332c905079980b119c4db103117e5e5c90" "reference": "d3a241b6028ff9d8e97d2b6ebd4090d01f92fad8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/c1e2df332c905079980b119c4db103117e5e5c90", "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/d3a241b6028ff9d8e97d2b6ebd4090d01f92fad8",
"reference": "c1e2df332c905079980b119c4db103117e5e5c90", "reference": "d3a241b6028ff9d8e97d2b6ebd4090d01f92fad8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1428,27 +1379,27 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:50:45+00:00" "time": "2020-09-28T05:28:46+00:00"
}, },
{ {
"name": "sebastian/code-unit-reverse-lookup", "name": "sebastian/code-unit-reverse-lookup",
"version": "2.0.2", "version": "2.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
"reference": "ee51f9bb0c6d8a43337055db3120829fa14da819" "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ee51f9bb0c6d8a43337055db3120829fa14da819", "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
"reference": "ee51f9bb0c6d8a43337055db3120829fa14da819", "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1479,29 +1430,29 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:04:00+00:00" "time": "2020-09-28T05:30:19+00:00"
}, },
{ {
"name": "sebastian/comparator", "name": "sebastian/comparator",
"version": "4.0.3", "version": "4.0.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git", "url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f" "reference": "e717aabeafe4eac045d3e947dad3207118664c72"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e717aabeafe4eac045d3e947dad3207118664c72",
"reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", "reference": "e717aabeafe4eac045d3e947dad3207118664c72",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0", "php": ">=7.3",
"sebastian/diff": "^4.0", "sebastian/diff": "^4.0",
"sebastian/exporter": "^4.0" "sebastian/exporter": "^4.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1549,27 +1500,27 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:05:46+00:00" "time": "2020-09-28T05:31:46+00:00"
}, },
{ {
"name": "sebastian/diff", "name": "sebastian/diff",
"version": "4.0.2", "version": "4.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/diff.git", "url": "https://github.com/sebastianbergmann/diff.git",
"reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113" "reference": "ffc949a1a2aae270ea064453d7535b82e4c32092"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ffc949a1a2aae270ea064453d7535b82e4c32092",
"reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", "reference": "ffc949a1a2aae270ea064453d7535b82e4c32092",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0", "phpunit/phpunit": "^9.3",
"symfony/process": "^4.2 || ^5" "symfony/process": "^4.2 || ^5"
}, },
"type": "library", "type": "library",
@ -1611,27 +1562,27 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-30T04:46:02+00:00" "time": "2020-09-28T05:32:55+00:00"
}, },
{ {
"name": "sebastian/environment", "name": "sebastian/environment",
"version": "5.1.2", "version": "5.1.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/environment.git", "url": "https://github.com/sebastianbergmann/environment.git",
"reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2" "reference": "388b6ced16caa751030f6a69e588299fa09200ac"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac",
"reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", "reference": "388b6ced16caa751030f6a69e588299fa09200ac",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"suggest": { "suggest": {
"ext-posix": "*" "ext-posix": "*"
@ -1639,7 +1590,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "5.0-dev" "dev-master": "5.1-dev"
} }
}, },
"autoload": { "autoload": {
@ -1670,29 +1621,29 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:07:24+00:00" "time": "2020-09-28T05:52:38+00:00"
}, },
{ {
"name": "sebastian/exporter", "name": "sebastian/exporter",
"version": "4.0.2", "version": "4.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git", "url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "571d721db4aec847a0e59690b954af33ebf9f023" "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/571d721db4aec847a0e59690b954af33ebf9f023", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65",
"reference": "571d721db4aec847a0e59690b954af33ebf9f023", "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0", "php": ">=7.3",
"sebastian/recursion-context": "^4.0" "sebastian/recursion-context": "^4.0"
}, },
"require-dev": { "require-dev": {
"ext-mbstring": "*", "ext-mbstring": "*",
"phpunit/phpunit": "^9.2" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1743,7 +1694,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:08:55+00:00" "time": "2020-09-28T05:24:23+00:00"
}, },
{ {
"name": "sebastian/global-state", "name": "sebastian/global-state",
@ -1801,25 +1752,25 @@
}, },
{ {
"name": "sebastian/object-enumerator", "name": "sebastian/object-enumerator",
"version": "4.0.2", "version": "4.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git", "url": "https://github.com/sebastianbergmann/object-enumerator.git",
"reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8" "reference": "f6f5957013d84725427d361507e13513702888a4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/074fed2d0a6d08e1677dd8ce9d32aecb384917b8", "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f6f5957013d84725427d361507e13513702888a4",
"reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8", "reference": "f6f5957013d84725427d361507e13513702888a4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0", "php": ">=7.3",
"sebastian/object-reflector": "^2.0", "sebastian/object-reflector": "^2.0",
"sebastian/recursion-context": "^4.0" "sebastian/recursion-context": "^4.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1850,27 +1801,27 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:11:32+00:00" "time": "2020-09-28T05:55:06+00:00"
}, },
{ {
"name": "sebastian/object-reflector", "name": "sebastian/object-reflector",
"version": "2.0.2", "version": "2.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/object-reflector.git", "url": "https://github.com/sebastianbergmann/object-reflector.git",
"reference": "127a46f6b057441b201253526f81d5406d6c7840" "reference": "d9d0ab3b12acb1768bc1e0a89b23c90d2043cbe5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/127a46f6b057441b201253526f81d5406d6c7840", "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/d9d0ab3b12acb1768bc1e0a89b23c90d2043cbe5",
"reference": "127a46f6b057441b201253526f81d5406d6c7840", "reference": "d9d0ab3b12acb1768bc1e0a89b23c90d2043cbe5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1901,27 +1852,27 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:12:55+00:00" "time": "2020-09-28T05:56:16+00:00"
}, },
{ {
"name": "sebastian/recursion-context", "name": "sebastian/recursion-context",
"version": "4.0.2", "version": "4.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git", "url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63" "reference": "ed8c9cd355089134bc9cba421b5cfdd58f0eaef7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/062231bf61d2b9448c4fa5a7643b5e1829c11d63", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/ed8c9cd355089134bc9cba421b5cfdd58f0eaef7",
"reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63", "reference": "ed8c9cd355089134bc9cba421b5cfdd58f0eaef7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -1960,24 +1911,24 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:14:17+00:00" "time": "2020-09-28T05:17:32+00:00"
}, },
{ {
"name": "sebastian/resource-operations", "name": "sebastian/resource-operations",
"version": "3.0.2", "version": "3.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/resource-operations.git", "url": "https://github.com/sebastianbergmann/resource-operations.git",
"reference": "0653718a5a629b065e91f774595267f8dc32e213" "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0653718a5a629b065e91f774595267f8dc32e213", "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
"reference": "0653718a5a629b065e91f774595267f8dc32e213", "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.0"
@ -2011,27 +1962,27 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:16:22+00:00" "time": "2020-09-28T06:45:17+00:00"
}, },
{ {
"name": "sebastian/type", "name": "sebastian/type",
"version": "2.2.1", "version": "2.2.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/type.git", "url": "https://github.com/sebastianbergmann/type.git",
"reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a" "reference": "e494dcaeb89d1458c9ccd8c819745245a1669aea"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/86991e2b33446cd96e648c18bcdb1e95afb2c05a", "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/e494dcaeb89d1458c9ccd8c819745245a1669aea",
"reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a", "reference": "e494dcaeb89d1458c9ccd8c819745245a1669aea",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.2" "phpunit/phpunit": "^9.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -2063,24 +2014,24 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-07-05T08:31:53+00:00" "time": "2020-09-28T06:01:38+00:00"
}, },
{ {
"name": "sebastian/version", "name": "sebastian/version",
"version": "3.0.1", "version": "3.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/version.git", "url": "https://github.com/sebastianbergmann/version.git",
"reference": "626586115d0ed31cb71483be55beb759b5af5a3c" "reference": "c6c1022351a901512170118436c764e473f6de8c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/626586115d0ed31cb71483be55beb759b5af5a3c", "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
"reference": "626586115d0ed31cb71483be55beb759b5af5a3c", "reference": "c6c1022351a901512170118436c764e473f6de8c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3 || ^8.0" "php": ">=7.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -2112,7 +2063,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-06-26T12:18:43+00:00" "time": "2020-09-28T06:39:44+00:00"
}, },
{ {
"name": "squizlabs/php_codesniffer", "name": "squizlabs/php_codesniffer",
@ -2241,82 +2192,6 @@
], ],
"time": "2020-07-14T12:35:20+00:00" "time": "2020-07-14T12:35:20+00:00"
}, },
{
"name": "symfony/service-contracts",
"version": "v2.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1",
"reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"psr/container": "^1.0"
},
"suggest": {
"symfony/service-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
"Symfony\\Contracts\\Service\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Generic abstractions related to writing services",
"homepage": "https://symfony.com",
"keywords": [
"abstractions",
"contracts",
"decoupling",
"interfaces",
"interoperability",
"standards"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-09-07T11:33:47+00:00"
},
{ {
"name": "theseer/tokenizer", "name": "theseer/tokenizer",
"version": "1.2.0", "version": "1.2.0",

View File

@ -18,19 +18,13 @@ use HTMLPurifier;
use HTMLPurifier_Config; use HTMLPurifier_Config;
use Favicon\Favicon; use Favicon\Favicon;
use OC\Encryption\Update;
use OCA\News\Config\LegacyConfig; use OCA\News\Config\LegacyConfig;
use OCA\News\Config\FetcherConfig; use OCA\News\Config\FetcherConfig;
use OCA\News\Db\FolderMapper; use OCA\News\Hooks\UserDeleteHook;
use OCA\News\Service\FeedService;
use OCA\News\Service\FolderService;
use OCA\News\Service\ItemService;
use OCA\News\Utility\PsrLogger;
use OCA\News\Utility\Updater; use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\IContainer; use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\IConfig; use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\ILogger;
use OCP\ITempManager; use OCP\ITempManager;
use OCP\AppFramework\App; use OCP\AppFramework\App;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
@ -42,7 +36,8 @@ use OCA\News\Db\ItemMapper;
use OCA\News\Fetcher\FeedFetcher; use OCA\News\Fetcher\FeedFetcher;
use OCA\News\Fetcher\Fetcher; use OCA\News\Fetcher\Fetcher;
use OCA\News\Fetcher\YoutubeFetcher; use OCA\News\Fetcher\YoutubeFetcher;
use OCA\News\Scraper\Scraper; use OCP\User\Events\BeforeUserDeletedEvent;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
/** /**
@ -50,7 +45,7 @@ use Psr\Log\LoggerInterface;
* *
* @package OCA\News\AppInfo * @package OCA\News\AppInfo
*/ */
class Application extends App class Application extends App implements IBootstrap
{ {
/** /**
@ -71,64 +66,38 @@ class Application extends App
'updateInterval' => 3600, 'updateInterval' => 3600,
]; ];
/**
* Application constructor.
*
* @param array $urlParams Parameters
*/
public function __construct(array $urlParams = []) public function __construct(array $urlParams = [])
{ {
parent::__construct(self::NAME, $urlParams); parent::__construct(self::NAME, $urlParams);
}
$container = $this->getContainer(); public function register(IRegistrationContext $context): void
{
@include_once __DIR__ . '/../../vendor/autoload.php';
// files $context->registerService(Fetcher::class, function (ContainerInterface $container): Fetcher {
$container->registerService('checksums', function () { $fetcher = new Fetcher();
return file_get_contents(__DIR__ . '/checksum.json');
}); // register fetchers in order, the most generic fetcher should be
$container->registerService('info', function () { // the last one
return file_get_contents(__DIR__ . '/../../appinfo/info.xml'); $fetcher->registerFetcher($container->get(YoutubeFetcher::class));
$fetcher->registerFetcher($container->get(FeedFetcher::class));
return $fetcher;
}); });
$context->registerEventListener(BeforeUserDeletedEvent::class, UserDeleteHook::class);
// parameters // parameters
$container->registerParameter('exploreDir', __DIR__ . '/../Explore/feeds'); $context->registerParameter('exploreDir', __DIR__ . '/../Explore/feeds');
$container->registerParameter('configFile', 'config.ini'); $context->registerParameter('configFile', 'config.ini');
// factories // factories
$container->registerService(ItemMapper::class, function (IContainer $c): ItemMapper { $context->registerService(ItemMapper::class, function (ContainerInterface $c): ItemMapper {
return $c->query(MapperFactory::class)->build(); return $c->get(MapperFactory::class)->build();
}); });
/** $context->registerService(HTMLPurifier::class, function (ContainerInterface $c): HTMLPurifier {
* Core $directory = $c->get(ITempManager::class)->getTempBaseDir() . '/news/cache/purifier';
*/
$container->registerService('LoggerParameters', function (IContainer $c): array {
return ['app' => $c->query('AppName')];
});
$container->registerService('ConfigView', function (IContainer $c): ?Node {
/** @var IRootFolder $fs */
$fs = $c->query(IRootFolder::class);
$path = 'news/config';
if ($fs->nodeExists($path)) {
return $fs->get($path);
} else {
return null;
}
});
$container->registerService(LegacyConfig::class, function (IContainer $c): LegacyConfig {
$config = new LegacyConfig(
$c->query('ConfigView'),
$c->query(LoggerInterface::class),
$c->query('LoggerParameters')
);
$config->read($c->query('configFile'), false);
return $config;
});
$container->registerService(HTMLPurifier::class, function (IContainer $c): HTMLPurifier {
$directory = $c->query(IConfig::class)->getSystemValue('datadirectory') . '/news/cache/purifier';
if (!is_dir($directory)) { if (!is_dir($directory)) {
mkdir($directory, 0770, true); mkdir($directory, 0770, true);
@ -164,47 +133,42 @@ class Application extends App
return new HTMLPurifier($config); return new HTMLPurifier($config);
}); });
/** $context->registerService(FeedIo::class, function (ContainerInterface $c): FeedIo {
* Fetchers $config = $c->get(FetcherConfig::class);
*/ return new FeedIo($config->getClient(), $c->get(LoggerInterface::class));
$container->registerService(FetcherConfig::class, function (IContainer $c): FetcherConfig {
$fConfig = new FetcherConfig();
$fConfig->setConfig($c->query(IConfig::class))
->setProxy($c->query(IConfig::class));
return $fConfig;
}); });
$container->registerService(FeedIo::class, function (IContainer $c): FeedIo { $context->registerService(Favicon::class, function (ContainerInterface $c): Favicon {
$config = $c->query(FetcherConfig::class);
return new FeedIo($config->getClient(), $c->query(LoggerInterface::class));
});
$container->registerService(Favicon::class, function (IContainer $c): Favicon {
$favicon = new Favicon(); $favicon = new Favicon();
$tempManager = $c->query(ITempManager::class); $favicon->cache(['dir' => $c->get(ITempManager::class)->getTempBaseDir()]);
$settings = ['dir' => $tempManager->getTempBaseDir()];
$favicon->cache($settings);
return $favicon; return $favicon;
}); });
$container->registerService(Fetcher::class, function (IContainer $c): Fetcher { //TODO: Remove code after 15.1
$fetcher = new Fetcher(); $context->registerService('ConfigView', function (ContainerInterface $c): ?Node {
/** @var IRootFolder $fs */
// register fetchers in order, the most generic fetcher should be $fs = $c->get(IRootFolder::class);
// the last one $path = 'news/config';
$fetcher->registerFetcher($c->query(YoutubeFetcher::class)); if ($fs->nodeExists($path)) {
$fetcher->registerFetcher($c->query(FeedFetcher::class)); return $fs->get($path);
return $fetcher; } else {
return null;
}
}); });
/** //TODO: Remove code after 15.1
* Scrapers $context->registerService(LegacyConfig::class, function (ContainerInterface $c): LegacyConfig {
*/ $config = new LegacyConfig(
$container->registerService(Scraper::class, function (IContainer $c): Scraper { $c->get('ConfigView'),
return new Scraper( $c->get(LoggerInterface::class)
$c->query(LoggerInterface::class)
); );
$config->read($c->get('configFile'), false);
return $config;
}); });
} }
public function boot(IBootContext $context): void
{
//NO-OP
}
} }

View File

@ -1,29 +0,0 @@
<?php
/**
* Nextcloud - News
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Alessandro Cosentino <cosenal@gmail.com>
* @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright 2012 Alessandro Cosentino
* @copyright 2012-2014 Bernhard Posselt
*/
namespace OCA\News\Config;
class DependencyException extends \Exception
{
/**
* Constructor
*
* @param string $msg the error message
*/
public function __construct($msg)
{
parent::__construct($msg);
}
}

View File

@ -59,24 +59,48 @@ class FetcherConfig
'application/atom+xml;q=0.6, application/xml;q=0.4, ' . 'application/atom+xml;q=0.6, application/xml;q=0.4, ' .
'text/xml;q=0.4, */*;q=0.2'; 'text/xml;q=0.4, */*;q=0.2';
/**
* FetcherConfig constructor.
*
* @param IConfig $config
*/
public function __construct(IConfig $config)
{
$this->client_timeout = $config->getAppValue(
Application::NAME,
'feedFetcherTimeout',
Application::DEFAULT_SETTINGS['feedFetcherTimeout']
);
$this->redirects = $config->getAppValue(
Application::NAME,
'maxRedirects',
Application::DEFAULT_SETTINGS['maxRedirects']
);
$proxy = $config->getSystemValue('proxy', null);
if (is_null($proxy)) {
return $this;
}
$url = new \Net_URL2($proxy);
$creds = $config->getSystemValue('proxyuserpwd', null);
if ($creds) {
$auth = explode(':', $creds, 2);
$url->setUserinfo($auth[0], $auth[1]);
}
$this->proxy = $url->getNormalizedURL();
return $this;
}
/** /**
* Configure a guzzle client * Configure a guzzle client
* *
* @return ClientInterface Legacy client to guzzle. * @return ClientInterface Legacy client to guzzle.
*/ */
public function getClient() public function getClient()
{
if (!class_exists('GuzzleHttp\Collection')) {
return new FeedIoClient($this->getConfig());
}
return new LegacyGuzzleClient($this->getOldConfig());
}
/**
* Get configuration for modern guzzle.
* @return Client Guzzle client.
*/
private function getConfig()
{ {
$config = [ $config = [
'timeout' => $this->client_timeout, 'timeout' => $this->client_timeout,
@ -90,81 +114,7 @@ class FetcherConfig
$config['redirect.max'] = $this->redirects; $config['redirect.max'] = $this->redirects;
} }
return new Client($config); $client = new Client($config);
} return new FeedIoClient($client);
/**
* Get configuration for old guzzle.
* @return Client Guzzle client.
*/
private function getOldConfig()
{
$config = [
'request.options' => [
'timeout' => $this->client_timeout,
'headers' => ['User-Agent' => static::DEFAULT_USER_AGENT],
],
];
if (!empty($this->proxy)) {
$config['request.options']['proxy'] = $this->proxy;
}
if (!empty($this->redirects)) {
$config['request.options']['redirect.max'] = $this->redirects;
}
return new Client($config);
}
/**
* Set settings for config.
*
* @param IConfig $config The shared configuration
*
* @return self
*/
public function setConfig(IConfig $config)
{
$this->client_timeout = $config->getAppValue(
Application::NAME,
'feedFetcherTimeout',
Application::DEFAULT_SETTINGS['feedFetcherTimeout']
);
$this->redirects = $config->getAppValue(
Application::NAME,
'maxRedirects',
Application::DEFAULT_SETTINGS['maxRedirects']
);
return $this;
}
/**
* Set the proxy
*
* @param IConfig $config Nextcloud config.
*
* @return self
*/
public function setProxy(IConfig $config)
{
$proxy = $config->getSystemValue('proxy', null);
$creds = $config->getSystemValue('proxyuserpwd', null);
if (is_null($proxy)) {
return $this;
}
$url = new \Net_URL2($proxy);
if ($creds) {
$auth = explode(':', $creds, 2);
$url->setUserinfo($auth[0], $auth[1]);
}
$this->proxy = $url->getNormalizedURL();
return $this;
} }
} }

View File

@ -39,8 +39,7 @@ class LegacyConfig
public function __construct( public function __construct(
?Folder $fileSystem, ?Folder $fileSystem,
LoggerInterface $logger, LoggerInterface $logger
$LoggerParameters
) { ) {
$this->fileSystem = $fileSystem; $this->fileSystem = $fileSystem;
$this->autoPurgeMinimumInterval = 60; $this->autoPurgeMinimumInterval = 60;
@ -51,7 +50,7 @@ class LegacyConfig
$this->useCronUpdates = true; $this->useCronUpdates = true;
$this->logger = $logger; $this->logger = $logger;
$this->exploreUrl = ''; $this->exploreUrl = '';
$this->loggerParams = $LoggerParameters; $this->loggerParams = ['app' => Application::NAME];
$this->updateInterval = 3600; $this->updateInterval = 3600;
} }

View File

@ -29,7 +29,7 @@ use Psr\Log\LoggerInterface;
class FeedApiController extends ApiController class FeedApiController extends ApiController
{ {
use JSONHttpError; use JSONHttpErrorTrait;
/** /**
* @var ItemService * @var ItemService

View File

@ -27,7 +27,7 @@ use OCA\News\Db\FeedType;
class FeedController extends Controller class FeedController extends Controller
{ {
use JSONHttpError; use JSONHttpErrorTrait;
private $feedService; private $feedService;
private $folderService; private $folderService;

View File

@ -27,7 +27,7 @@ use \OCA\News\Service\Exceptions\ServiceValidationException;
class FolderApiController extends ApiController class FolderApiController extends ApiController
{ {
use JSONHttpError; use JSONHttpErrorTrait;
private $folderService; private $folderService;
private $itemService; private $itemService;

View File

@ -26,7 +26,7 @@ use \OCA\News\Service\Exceptions\ServiceValidationException;
class FolderController extends Controller class FolderController extends Controller
{ {
use JSONHttpError; use JSONHttpErrorTrait;
private $folderService; private $folderService;
private $feedService; private $feedService;

View File

@ -24,7 +24,7 @@ use \OCA\News\Service\Exceptions\ServiceNotFoundException;
class ItemApiController extends ApiController class ItemApiController extends ApiController
{ {
use JSONHttpError; use JSONHttpErrorTrait;
private $itemService; private $itemService;
private $serializer; private $serializer;

View File

@ -25,7 +25,7 @@ use \OCA\News\Service\FeedService;
class ItemController extends Controller class ItemController extends Controller
{ {
use JSONHttpError; use JSONHttpErrorTrait;
private $itemService; private $itemService;
private $feedService; private $feedService;

View File

@ -13,10 +13,8 @@ namespace OCA\News\Controller;
use \OCP\AppFramework\Http\JSONResponse; use \OCP\AppFramework\Http\JSONResponse;
trait JSONHttpError trait JSONHttpErrorTrait
{ {
/** /**
* @param \Exception $exception The exception to report * @param \Exception $exception The exception to report
* @param int $code The http error code * @param int $code The http error code

View File

@ -31,7 +31,7 @@ use OCA\News\Db\FeedType;
class PageController extends Controller class PageController extends Controller
{ {
use JSONHttpError; use JSONHttpErrorTrait;
/** /**
* @var IConfig * @var IConfig

View File

@ -22,13 +22,20 @@ class RecommendedSites
* @param string $exploreDir the absolute path to where the recommendation * @param string $exploreDir the absolute path to where the recommendation
* config files lie without a trailing slash * config files lie without a trailing slash
*/ */
public function __construct($exploreDir) public function __construct(string $exploreDir)
{ {
$this->directory = $exploreDir; $this->directory = $exploreDir;
} }
public function forLanguage($languageCode) /**
* @param string $languageCode
*
* @return array
*
* @throws RecommendedSiteNotFoundException
*/
public function forLanguage(string $languageCode)
{ {
$file = $this->directory . '/feeds.' . $languageCode . '.json'; $file = $this->directory . '/feeds.' . $languageCode . '.json';

View File

@ -1,66 +0,0 @@
<?php
/**
* Nextcloud - News
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Sean Molenaar <smillernl@me.com>
* @copyright 2018 Sean Molenaar
*/
namespace OCA\News\Fetcher\Client;
use FeedIo\Adapter\ClientInterface as FeedIoClientInterface;
use FeedIo\Adapter\ResponseInterface;
use FeedIo\Adapter\NotFoundException;
use FeedIo\Adapter\ServerErrorException;
use Guzzle\Service\ClientInterface;
use GuzzleHttp\Exception\BadResponseException;
/**
* Guzzle dependent HTTP client
*/
class LegacyGuzzleClient implements FeedIoClientInterface
{
/**
* @var ClientInterface
*/
protected $guzzleClient;
/**
* @param ClientInterface $guzzleClient
*/
public function __construct(ClientInterface $guzzleClient)
{
$this->guzzleClient = $guzzleClient;
}
/**
* @param string $url
* @param \DateTime $modifiedSince
* @throws \FeedIo\Adapter\NotFoundException
* @throws \FeedIo\Adapter\ServerErrorException
* @return \FeedIo\Adapter\ResponseInterface
*/
public function getResponse(string $url, \DateTime $modifiedSince) : ResponseInterface
{
$modifiedSince->setTimezone(new \DateTimeZone('GMT'));
try {
$options = [
'headers' => [
'If-Modified-Since' => $modifiedSince->format('D, d M Y H:i:s e')
]
];
return new LegacyGuzzleResponse($this->guzzleClient->get($url, $options));
} catch (BadResponseException $e) {
switch ((int) $e->getResponse()->getStatusCode()) {
case 404:
throw new NotFoundException($e->getMessage());
default:
throw new ServerErrorException($e->getMessage());
}
}
}
}

View File

@ -1,86 +0,0 @@
<?php
/**
* Nextcloud - News
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Sean Molenaar <smillernl@me.com>
* @copyright 2018 Sean Molenaar
*/
namespace OCA\News\Fetcher\Client;
use FeedIo\Adapter\ResponseInterface;
use GuzzleHttp\Message\ResponseInterface as GuzzleResponseInterface;
/**
* Guzzle dependent HTTP Response
*/
class LegacyGuzzleResponse implements ResponseInterface
{
const HTTP_LAST_MODIFIED = 'Last-Modified';
/**
* @var \GuzzleHttp\Message\ResponseInterface
*/
protected $response;
/**
* @param \GuzzleHttp\Message\ResponseInterface
*/
public function __construct(GuzzleResponseInterface $psrResponse)
{
$this->response = $psrResponse;
}
/**
* @return boolean
*/
public function isModified() : bool
{
return $this->response->getStatusCode() !== 304 && $this->response->getBody()->getSize() > 0;
}
/**
* @return \Psr\Http\Message\StreamInterface
*/
public function getBody() : ? string
{
return $this->response->getBody();
}
/**
* @return \DateTime|null
*/
public function getLastModified() : ?\DateTime
{
if ($this->response->hasHeader(static::HTTP_LAST_MODIFIED)) {
$lastModified = \DateTime::createFromFormat(
'D, d M Y H:i:s e',
$this->getHeader(static::HTTP_LAST_MODIFIED)
);
return false === $lastModified ? null : $lastModified;
}
return null;
}
/**
* @return array
*/
public function getHeaders() : iterable
{
return $this->response->getHeaders();
}
/**
* @param string $name
* @return string[]
*/
public function getHeader(string $name) : iterable
{
return current($this->response->getHeader($name));
}
}

View File

@ -75,8 +75,14 @@ class FeedFetcher implements IFeedFetcher
* *
* @inheritdoc * @inheritdoc
*/ */
public function fetch(string $url, bool $favicon, $lastModified, bool $fullTextEnabled, $user, $password): array public function fetch(
{ string $url,
bool $favicon,
?string $lastModified,
bool $fullTextEnabled,
?string $user,
?string $password
): array {
$url2 = new Net_URL2($url); $url2 = new Net_URL2($url);
if (!empty($user) && !empty(trim($user))) { if (!empty($user) && !empty(trim($user))) {
$url2->setUserinfo(urlencode($user), urlencode($password)); $url2->setUserinfo(urlencode($user), urlencode($password));
@ -148,7 +154,7 @@ class FeedFetcher implements IFeedFetcher
* *
* @return string * @return string
*/ */
private function decodeTwice($string): string private function decodeTwice(string $string): string
{ {
return html_entity_decode( return html_entity_decode(
html_entity_decode( html_entity_decode(
@ -195,12 +201,12 @@ class FeedFetcher implements IFeedFetcher
* Build an item based on a feed. * Build an item based on a feed.
* *
* @param ItemInterface $parsedItem The item to use * @param ItemInterface $parsedItem The item to use
* @param string $body Text of the item, if not provided use description from $parsedItem * @param string|null $body Text of the item, if not provided use description from $parsedItem
* @param bool $RTL True if the feed is RTL (Right-to-left) * @param bool $RTL True if the feed is RTL (Right-to-left)
* *
* @return Item * @return Item
*/ */
protected function buildItem(ItemInterface $parsedItem, string $body = null, bool $RTL = false): Item protected function buildItem(ItemInterface $parsedItem, ?string $body = null, bool $RTL = false): Item
{ {
$item = new Item(); $item = new Item();
$item->setUnread(true); $item->setUnread(true);
@ -208,18 +214,18 @@ class FeedFetcher implements IFeedFetcher
$item->setGuid($parsedItem->getPublicId()); $item->setGuid($parsedItem->getPublicId());
$item->setGuidHash(md5($item->getGuid())); $item->setGuidHash(md5($item->getGuid()));
$lastmodified = $parsedItem->getLastModified() ?? new DateTime(); $lastModified = $parsedItem->getLastModified() ?? new DateTime();
if ($parsedItem->getValue('pubDate') !== null) { if ($parsedItem->getValue('pubDate') !== null) {
$pubDT = new DateTime($parsedItem->getValue('pubDate')); $pubDT = new DateTime($parsedItem->getValue('pubDate'));
} elseif ($parsedItem->getValue('published') !== null) { } elseif ($parsedItem->getValue('published') !== null) {
$pubDT = new DateTime($parsedItem->getValue('published')); $pubDT = new DateTime($parsedItem->getValue('published'));
} else { } else {
$pubDT = $lastmodified; $pubDT = $lastModified;
} }
$item->setPubDate($pubDT->getTimestamp()); $item->setPubDate($pubDT->getTimestamp());
$item->setLastModified($lastmodified->getTimestamp()); $item->setLastModified($lastModified->getTimestamp());
$item->setRtl($RTL); $item->setRtl($RTL);
// unescape content because angularjs helps against XSS // unescape content because angularjs helps against XSS

View File

@ -43,25 +43,25 @@ class Fetcher
/** /**
* Fetch a feed from remote * Fetch a feed from remote
* *
* @param string $url remote url of the feed * @param string $url remote url of the feed
* @param boolean $getFavicon if the favicon should also be fetched, defaults to true * @param boolean $getFavicon if the favicon should also be fetched, defaults to true
* @param string $lastModified a last modified value from an http header defaults to false. * @param string|null $lastModified a last modified value from an http header defaults to false.
* If lastModified matches the http header from the feed no results are fetched * If lastModified matches the http header from the feed no results are fetched
* @param bool $fullTextEnabled If true use a scraper to download the full article * @param bool $fullTextEnabled If true use a scraper to download the full article
* @param string $user if given, basic auth is set for this feed * @param string|null $user if given, basic auth is set for this feed
* @param string $password if given, basic auth is set for this feed. Ignored if user is empty * @param string|null $password if given, basic auth is set for this feed. Ignored if user is empty
* *
* @throws ReadErrorException if FeedIO fails * @throws ReadErrorException if FeedIO fails
* @return array an array containing the new feed and its items, first * @return array an array containing the new feed and its items, first
* element being the Feed and second element being an array of Items * element being the Feed and second element being an array of Items
*/ */
public function fetch( public function fetch(
$url, string $url,
$getFavicon = true, bool $getFavicon = true,
$lastModified = null, ?string $lastModified = null,
$fullTextEnabled = false, bool $fullTextEnabled = false,
$user = null, ?string $user = null,
$password = null ?string $password = null
) { ) {
foreach ($this->fetchers as $fetcher) { foreach ($this->fetchers as $fetcher) {
if (!$fetcher->canHandle($url)) { if (!$fetcher->canHandle($url)) {

View File

@ -31,9 +31,17 @@ interface IFeedFetcher
* *
* @return array an array containing the new feed and its items, first * @return array an array containing the new feed and its items, first
* element being the Feed and second element being an array of Items * element being the Feed and second element being an array of Items
*
* @throws ReadErrorException if the Feed-IO fetcher encounters a problem * @throws ReadErrorException if the Feed-IO fetcher encounters a problem
*/ */
public function fetch(string $url, bool $favicon, $lastModified, bool $fullTextEnabled, $user, $password): array; public function fetch(
string $url,
bool $favicon,
?string $lastModified,
bool $fullTextEnabled,
?string $user,
?string $password
): array;
/** /**
* Can a fetcher handle a feed. * Can a fetcher handle a feed.

View File

@ -22,7 +22,14 @@ class YoutubeFetcher implements IFeedFetcher
} }
private function buildUrl($url) /**
* Build YouTube URL
*
* @param string $url
*
* @return string
*/
private function buildUrl(string $url)
{ {
$baseRegex = '%(?:https?://|//)?(?:www.)?youtube.com'; $baseRegex = '%(?:https?://|//)?(?:www.)?youtube.com';
$playRegex = $baseRegex . '.*?list=([^&]*)%'; $playRegex = $baseRegex . '.*?list=([^&]*)%';
@ -54,8 +61,14 @@ class YoutubeFetcher implements IFeedFetcher
* *
* @inheritdoc * @inheritdoc
*/ */
public function fetch(string $url, bool $favicon, $lastModified, bool $fullTextEnabled, $user, $password): array public function fetch(
{ string $url,
bool $favicon,
?string $lastModified,
bool $fullTextEnabled,
?string $user,
?string $password
): array {
$transformedUrl = $this->buildUrl($url); $transformedUrl = $this->buildUrl($url);
$result = $this->feedFetcher->fetch( $result = $this->feedFetcher->fetch(

View File

@ -17,20 +17,28 @@ use OCA\News\AppInfo\Application;
use OCA\News\Service\ItemService; use OCA\News\Service\ItemService;
use OCA\News\Service\FeedService; use OCA\News\Service\FeedService;
use OCA\News\Service\FolderService; use OCA\News\Service\FolderService;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\User\Events\BeforeUserDeletedEvent;
class User class UserDeleteHook implements IEventListener
{ {
public static function deleteUser($params) /**
* Handle user deletion
*
* @param BeforeUserDeletedEvent $event
*/
public function handle(Event $event): void
{ {
$userId = $params['uid']; $userId = $event->getUser()->getUID();
$app = new Application(); $app = new Application();
$container = $app->getContainer(); $container = $app->getContainer();
// order is important! // order is important!
$container->query(ItemService::class)->deleteUser($userId); $container->get(ItemService::class)->deleteUser($userId);
$container->query(FeedService::class)->deleteUser($userId); $container->get(FeedService::class)->deleteUser($userId);
$container->query(FolderService::class)->deleteUser($userId); $container->get(FolderService::class)->deleteUser($userId);
} }
} }

View File

@ -52,7 +52,14 @@ class MigrateConfig implements IRepairStep
return; return;
} }
$app_keys = $this->iConfig->getAppKeys(Application::NAME);
foreach ($this->config as $key => $value) { foreach ($this->config as $key => $value) {
if (!isset(Application::DEFAULT_SETTINGS[$key])) {
continue;
}
if (in_array($key, $app_keys)) {
continue;
}
$this->iConfig->setAppValue(Application::NAME, $key, $value); $this->iConfig->setAppValue(Application::NAME, $key, $value);
} }
} }

View File

@ -8,14 +8,9 @@
<whitelist processUncoveredFilesFromWhitelist="true"> <whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./lib/</directory> <directory suffix=".php">./lib/</directory>
<exclude> <exclude>
<file>./lib/Config/DependencyException.php</file> <file>./lib/AppInfo/Application.php</file>
<file>./lib/Explore/feeds/RecommendedSiteNotFoundException.php</file> <file>./lib/Controller/JSONHttpErrorTrait.php</file>
<file>./lib/Explore/feeds/RecommendedSiteNotFoundException.php</file> <file>./lib/**Exception.php</file>
<file>./lib/Fetcher/FetcherException.php</file>
<file>./lib/Service/ServiceConflictException.php</file>
<file>./lib/Service/ServiceException.php</file>
<file>./lib/Service/ServiceNotFoundException.php</file>
<file>./lib/Service/ServiceValidationException.php</file>
</exclude> </exclude>
</whitelist> </whitelist>
</filter> </filter>

View File

@ -30,6 +30,7 @@ use OCA\News\Tests\Integration\Fixtures\FolderFixture;
use OCA\News\Db\FeedMapper; use OCA\News\Db\FeedMapper;
use OCA\News\Db\ItemMapper; use OCA\News\Db\ItemMapper;
use OCA\News\Db\FolderMapper; use OCA\News\Db\FolderMapper;
use Psr\Container\ContainerInterface;
abstract class IntegrationTest extends \Test\TestCase abstract class IntegrationTest extends \Test\TestCase
@ -67,9 +68,9 @@ abstract class IntegrationTest extends \Test\TestCase
$this->setupUser($this->user, $this->userPassword); $this->setupUser($this->user, $this->userPassword);
// set up database layers // set up database layers
$this->itemMapper = $this->container->query(ItemMapper::class); $this->itemMapper = $this->container->get(ItemMapper::class);
$this->feedMapper = $this->container->query(FeedMapper::class); $this->feedMapper = $this->container->get(FeedMapper::class);
$this->folderMapper = $this->container->query(FolderMapper::class); $this->folderMapper = $this->container->get(FolderMapper::class);
} }
protected function findItemByTitle($title) protected function findItemByTitle($title)

View File

@ -13,13 +13,13 @@
namespace OCA\News\Tests\Unit\Controller; namespace OCA\News\Tests\Unit\Controller;
use OCA\News\Controller\JSONHttpError; use OCA\News\Controller\JSONHttpErrorTrait;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class Test class Test
{ {
use JSONHttpError; use JSONHttpErrorTrait;
} }
class JSONHttpErrorTest extends TestCase class JSONHttpErrorTest extends TestCase