summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--composer.json15
-rw-r--r--composer.lock325
-rw-r--r--js/package-lock.json668
-rw-r--r--lib/AppInfo/Application.php113
-rw-r--r--lib/Config/Config.php4
-rw-r--r--lib/Config/FetcherConfig.php118
-rw-r--r--lib/Config/LegacyGuzzleClient.php65
-rw-r--r--lib/Config/LegacyGuzzleResponse.php86
-rw-r--r--lib/Db/Item.php14
-rw-r--r--lib/Fetcher/FeedFetcher.php377
-rw-r--r--lib/Fetcher/Fetcher.php45
-rw-r--r--lib/Fetcher/IFeedFetcher.php17
-rw-r--r--lib/Fetcher/YoutubeFetcher.php25
-rw-r--r--lib/PostProcessor/LWNProcessor.php117
-rw-r--r--lib/Service/FeedService.php47
-rw-r--r--lib/Utility/PicoFeedClientFactory.php42
-rw-r--r--lib/Utility/PicoFeedFaviconFactory.php40
-rw-r--r--lib/Utility/PsrLogger.php97
-rw-r--r--tests/Unit/Config/ConfigTest.php2
-rw-r--r--tests/Unit/Fetcher/FeedFetcherTest.php650
-rw-r--r--tests/Unit/Service/FeedServiceTest.php11
22 files changed, 1605 insertions, 1277 deletions
diff --git a/Makefile b/Makefile
index d716d09da..e9aa3c1e2 100644
--- a/Makefile
+++ b/Makefile
@@ -41,10 +41,10 @@
app_name:=$(notdir $(CURDIR))
build_tools_directory:=$(CURDIR)/build/tools
-source_build_directory:=$(CURDIR)/build/source/news
+source_build_directory:=$(CURDIR)/build/source/$(app_name)
source_artifact_directory:=$(CURDIR)/build/artifacts/source
source_package_name:=$(source_artifact_directory)/$(app_name)
-appstore_build_directory:=$(CURDIR)/build/appstore/news
+appstore_build_directory:=$(CURDIR)/build/appstore/$(app_name)
appstore_artifact_directory:=$(CURDIR)/build/artifacts/appstore
appstore_package_name:=$(appstore_artifact_directory)/$(app_name)
npm:=$(shell which npm 2> /dev/null)
diff --git a/composer.json b/composer.json
index 4a03b86a2..de3b7a028 100644
--- a/composer.json
+++ b/composer.json
@@ -11,6 +11,12 @@
"role": "Developer"
},
{
+ "name": "Sean Molenaar",
+ "email": "sean@seanmolenaar.eu",
+ "homepage": "https://seanmolenaar.eu",
+ "role": "Developer"
+ },
+ {
"name": "Alessandro Cosentino",
"homepage": "http://algorithmsforthekitchen.com/",
"email": "cosenal@gmail.com",
@@ -33,11 +39,16 @@
"ezyang/htmlpurifier": "4.10.0",
"pear/net_url2": "2.2.2",
"riimu/kit-pathjoin": "1.2.0",
- "nicolus/picofeed": "0.1.35"
+ "debril/feed-io": "^3.0",
+ "arthurhoaro/favicon": "^1.2"
},
"require-dev": {
"phpunit/phpunit": "^6.5",
- "squizlabs/php_codesniffer": "^3.3"
+ "squizlabs/php_codesniffer": "^3.3",
+ "guzzlehttp/guzzle": "~6.3"
+ },
+ "replace": {
+ "guzzlehttp/guzzle": "*"
},
"autoload": {
"psr-4": {
diff --git a/composer.lock b/composer.lock
index 2c814bcd0..e981b11f9 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,93 +4,93 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "f4a0d96b7e83ec4d9d232412b9e61566",
+ "content-hash": "1630b553e70e8245b11922394d4d9f59",
"packages": [
{
- "name": "ezyang/htmlpurifier",
- "version": "v4.10.0",
+ "name": "arthurhoaro/favicon",
+ "version": "v1.2.2",
"source": {
"type": "git",
- "url": "https://github.com/ezyang/htmlpurifier.git",
- "reference": "d85d39da4576a6934b72480be6978fb10c860021"
+ "url": "https://github.com/ArthurHoaro/favicon.git",
+ "reference": "50fd2a0f984db13948a69ab120451e03e41979fa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d85d39da4576a6934b72480be6978fb10c860021",
- "reference": "d85d39da4576a6934b72480be6978fb10c860021",
+ "url": "https://api.github.com/repos/ArthurHoaro/favicon/zipball/50fd2a0f984db13948a69ab120451e03e41979fa",
+ "reference": "50fd2a0f984db13948a69ab120451e03e41979fa",
"shasum": ""
},
"require": {
- "php": ">=5.2"
+ "php": ">=5.3.3"
},
"require-dev": {
- "simpletest/simpletest": "^1.1"
+ "phpunit/phpunit": "~4.8",
+ "weew/helpers-filesystem": "~1.0"
},
"type": "library",
"autoload": {
- "psr-0": {
- "HTMLPurifier": "library/"
- },
- "files": [
- "library/HTMLPurifier.composer.php"
- ]
+ "psr-4": {
+ "Favicon\\": "src/Favicon/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "LGPL"
+ "Apache-2.0"
],
"authors": [
{
- "name": "Edward Z. Yang",
- "email": "admin@htmlpurifier.org",
- "homepage": "http://ezyang.com"
+ "name": "Chris Shiflett",
+ "homepage": "http://shiflett.org/"
+ },
+ {
+ "name": "Arthur Hoaro",
+ "homepage": "http://hoa.ro"
}
],
- "description": "Standards compliant HTML filter written in PHP",
- "homepage": "http://htmlpurifier.org/",
+ "description": "PHP Library used to discover favicon from given URL",
+ "homepage": "https://github.com/ArthurHoaro/favicon",
"keywords": [
- "html"
+ "favicon",
+ "finder",
+ "icon"
],
- "time": "2018-02-23T01:58:20+00:00"
+ "time": "2018-09-08T09:37:54+00:00"
},
{
- "name": "nicolus/picofeed",
- "version": "v0.1.35",
+ "name": "debril/feed-io",
+ "version": "v3.1.1",
"source": {
"type": "git",
- "url": "https://github.com/nicolus/picoFeed.git",
- "reference": "3a27b47de31eedec075c719f961783c5db7a7b08"
+ "url": "https://github.com/alexdebril/feed-io.git",
+ "reference": "a79a09a915540b5475b12c82effb3dd43c2b2a0b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nicolus/picoFeed/zipball/3a27b47de31eedec075c719f961783c5db7a7b08",
- "reference": "3a27b47de31eedec075c719f961783c5db7a7b08",
+ "url": "https://api.github.com/repos/alexdebril/feed-io/zipball/a79a09a915540b5475b12c82effb3dd43c2b2a0b",
+ "reference": "a79a09a915540b5475b12c82effb3dd43c2b2a0b",
"shasum": ""
},
"require": {
- "ext-dom": "*",
- "ext-iconv": "*",
- "ext-libxml": "*",
- "ext-simplexml": "*",
- "ext-xml": "*",
- "php": ">=5.3.0",
- "zendframework/zendxml": "^1.0"
+ "guzzlehttp/guzzle": "~6.2",
+ "php": ">=5.6.0",
+ "psr/log": "~1.0"
},
"require-dev": {
- "phpdocumentor/reflection-docblock": "2.0.4",
- "phpunit/phpunit": "4.8.26",
- "symfony/yaml": "2.8.7"
+ "friendsofphp/php-cs-fixer": "^2.4",
+ "monolog/monolog": "1.*",
+ "phpunit/phpunit": "~5.6.0"
},
"suggest": {
- "ext-curl": "PicoFeed will use cURL if present"
+ "monolog/monolog": "Allows to handle logs",
+ "symfony/console": "Allows to use the command line interface"
},
"bin": [
- "picofeed"
+ "bin/feedio"
],
"type": "library",
"autoload": {
- "psr-0": {
- "PicoFeed": "lib/"
+ "psr-4": {
+ "FeedIo\\": "src/FeedIo"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -99,12 +99,69 @@
],
"authors": [
{
- "name": "Frédéric Guillot"
+ "name": "Alexandre Debril",
+ "email": "alex.debril@gmail.com"
}
],
- "description": "Modern library to handle RSS/Atom feeds",
- "homepage": "https://github.com/miniflux/picoFeed",
- "time": "2017-06-20T22:54:47+00:00"
+ "description": "PHP library built to consume and serve JSONFeed / RSS / Atom feeds",
+ "homepage": "https://feed-io.net",
+ "keywords": [
+ "atom",
+ "cli",
+ "client",
+ "feed",
+ "jsonfeed",
+ "news",
+ "rss"
+ ],
+ "time": "2018-06-18T12:31:47+00:00"
+ },
+ {
+ "name": "ezyang/htmlpurifier",
+ "version": "v4.10.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ezyang/htmlpurifier.git",
+ "reference": "d85d39da4576a6934b72480be6978fb10c860021"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d85d39da4576a6934b72480be6978fb10c860021",
+ "reference": "d85d39da4576a6934b72480be6978fb10c860021",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2"
+ },
+ "require-dev": {
+ "simpletest/simpletest": "^1.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "HTMLPurifier": "library/"
+ },
+ "files": [
+ "library/HTMLPurifier.composer.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL"
+ ],
+ "authors": [
+ {
+ "name": "Edward Z. Yang",
+ "email": "admin@htmlpurifier.org",
+ "homepage": "http://ezyang.com"
+ }
+ ],
+ "description": "Standards compliant HTML filter written in PHP",
+ "homepage": "http://htmlpurifier.org/",
+ "keywords": [
+ "html"
+ ],
+ "time": "2018-02-23T01:58:20+00:00"
},
{
"name": "pear/net_url2",
@@ -171,6 +228,53 @@
"time": "2017-08-25T06:16:11+00:00"
},
{
+ "name": "psr/log",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2018-11-20T15:27:04+00:00"
+ },
+ {
"name": "riimu/kit-pathjoin",
"version": "v1.2.0",
"source": {
@@ -219,52 +323,6 @@
"system"
],
"time": "2017-07-09T14:41:04+00:00"
- },
- {
- "name": "zendframework/zendxml",
- "version": "1.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/zendframework/ZendXml.git",
- "reference": "267db6a2c431a08a8f8ff0f1f4c302a5ba6f5b99"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/zendframework/ZendXml/zipball/267db6a2c431a08a8f8ff0f1f4c302a5ba6f5b99",
- "reference": "267db6a2c431a08a8f8ff0f1f4c302a5ba6f5b99",
- "shasum": ""
- },
- "require": {
- "php": "^5.6 || ^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4",
- "zendframework/zend-coding-standard": "~1.0.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1.x-dev",
- "dev-develop": "1.2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "ZendXml\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "description": "Utility library for XML usage, best practices, and security in PHP",
- "keywords": [
- "ZendFramework",
- "security",
- "xml",
- "zf"
- ],
- "time": "2018-04-30T15:11:04+00:00"
}
],
"packages-dev": [
@@ -1640,16 +1698,16 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "3.3.2",
+ "version": "3.4.0",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e"
+ "reference": "379deb987e26c7cd103a7b387aea178baec96e48"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6ad28354c04b364c3c71a34e4a18b629cc3b231e",
- "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/379deb987e26c7cd103a7b387aea178baec96e48",
+ "reference": "379deb987e26c7cd103a7b387aea178baec96e48",
"shasum": ""
},
"require": {
@@ -1687,7 +1745,65 @@
"phpcs",
"standards"
],
- "time": "2018-09-23T23:08:17+00:00"
+ "time": "2018-12-19T23:57:18+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.10.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ },
+ {
+ "name": "Gert de Pagter",
+ "email": "backendtea@gmail.com"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "time": "2018-08-06T14:22:27+00:00"
},
{
"name": "theseer/tokenizer",
@@ -1731,20 +1847,21 @@
},
{
"name": "webmozart/assert",
- "version": "1.3.0",
+ "version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
- "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
+ "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
- "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
+ "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0"
+ "php": "^5.3.3 || ^7.0",
+ "symfony/polyfill-ctype": "^1.8"
},
"require-dev": {
"phpunit/phpunit": "^4.6",
@@ -1777,7 +1894,7 @@
"check",
"validate"
],
- "time": "2018-01-29T19:49:41+00:00"
+ "time": "2018-12-25T11:19:39+00:00"
}
],
"aliases": [],
diff --git a/js/package-lock.json b/js/package-lock.json
index 97204fc9b..eb3d2e289 100644
--- a/js/package-lock.json
+++ b/js/package-lock.json
@@ -31,7 +31,7 @@
},
"acorn": {
"version": "2.6.4",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.6.4.tgz",
+ "resolved": "http://registry.npmjs.org/acorn/-/acorn-2.6.4.tgz",
"integrity": "sha1-6x9FtKQ/ox0DcBpexG87Umc+kO4=",
"dev": true
},
@@ -89,7 +89,8 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"angular": {
"version": "1.7.5",
@@ -351,7 +352,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"assign-symbols": {
"version": "1.0.0",
@@ -361,7 +363,7 @@
},
"async": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/async/-/async-1.0.0.tgz",
"integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=",
"dev": true
},
@@ -379,9 +381,9 @@
"optional": true
},
"atob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
- "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
"dev": true
},
"aws-sign2": {
@@ -392,9 +394,9 @@
"optional": true
},
"aws4": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
- "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"dev": true,
"optional": true
},
@@ -503,9 +505,9 @@
}
},
"binary-extensions": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
- "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz",
+ "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==",
"dev": true
},
"blob": {
@@ -515,9 +517,9 @@
"dev": true
},
"bluebird": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz",
+ "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==",
"dev": true
},
"body-parser": {
@@ -548,9 +550,9 @@
}
},
"bowser": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.3.tgz",
- "integrity": "sha512-/gp96UlcFw5DbV2KQPCqTqi0Mb9gZRyDAHiDsGEH+4B/KOQjeoE5lM1PxlVX8DQDvfEfitmC1rW2Oy8fk/XBDg==",
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz",
+ "integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==",
"dev": true
},
"brace-expansion": {
@@ -592,6 +594,28 @@
}
}
},
+ "buffer-alloc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+ "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+ "dev": true,
+ "requires": {
+ "buffer-alloc-unsafe": "^1.1.0",
+ "buffer-fill": "^1.0.0"
+ }
+ },
+ "buffer-alloc-unsafe": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+ "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
+ "dev": true
+ },
+ "buffer-fill": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+ "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
+ "dev": true
+ },
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@@ -616,7 +640,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -710,7 +734,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@@ -800,9 +824,9 @@
},
"dependencies": {
"glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@@ -872,7 +896,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -920,12 +944,12 @@
}
},
"color-convert": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
- "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
- "color-name": "^1.1.1"
+ "color-name": "1.1.3"
}
},
"color-name": {
@@ -956,22 +980,30 @@
},
"dependencies": {
"lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
},
"combined-stream": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
- "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
+ "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
"dev": true,
+ "optional": true,
"requires": {
"delayed-stream": "~1.0.0"
}
},
+ "commander": {
+ "version": "2.17.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+ "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
+ "dev": true,
+ "optional": true
+ },
"component-bind": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
@@ -1018,7 +1050,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"optional": true,
@@ -1090,7 +1122,7 @@
},
"convert-source-map": {
"version": "1.1.3",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
+ "resolved": "http://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
"integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=",
"dev": true
},
@@ -1129,25 +1161,22 @@
"dev": true
},
"css": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/css/-/css-2.2.3.tgz",
- "integrity": "sha512-0W171WccAjQGGTKLhw4m2nnl0zPHUlTO/I8td4XzJgIB8Hg3ZZx71qT4G4eX8OVsSiaAKiUMy73E3nsbPlg2DQ==",
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+ "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
"dev": true,
"requires": {
- "inherits": "^2.0.1",
- "source-map": "^0.1.38",
- "source-map-resolve": "^0.5.1",
+ "inherits": "^2.0.3",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.5.2",
"urix": "^0.1.0"
},
"dependencies": {
"source-map": {
- "version": "0.1.43",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
- "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
- "dev": true,
- "requires": {
- "amdefine": ">=0.0.4"
- }
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
}
}
},
@@ -1302,7 +1331,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"depd": {
"version": "1.1.2",
@@ -1334,9 +1364,9 @@
"dev": true
},
"detect-node": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz",
- "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
+ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
"dev": true
},
"di": {
@@ -1491,7 +1521,7 @@
"dependencies": {
"debug": {
"version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
"dev": true,
"requires": {
@@ -1528,7 +1558,7 @@
"dependencies": {
"debug": {
"version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
"dev": true,
"requires": {
@@ -1570,18 +1600,18 @@
"dev": true
},
"error-ex": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
- "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
"requires": {
"is-arrayish": "^0.2.1"
}
},
"es5-ext": {
- "version": "0.10.45",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz",
- "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==",
+ "version": "0.10.46",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz",
+ "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==",
"dev": true,
"requires": {
"es6-iterator": "~2.0.3",
@@ -1601,9 +1631,9 @@
}
},
"es6-promise": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
- "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz",
+ "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==",
"dev": true,
"optional": true
},
@@ -1847,9 +1877,9 @@
}
},
"extend": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
- "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true
},
"extend-shallow": {
@@ -1955,7 +1985,8 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"eyes": {
"version": "0.1.8",
@@ -2129,12 +2160,12 @@
"dev": true
},
"follow-redirects": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz",
- "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==",
+ "version": "1.5.8",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz",
+ "integrity": "sha512-sy1mXPmv7kLAMKW/8XofG7o9T+6gAjzdZK4AJF6ryqQYUa/hnzgiypoeUecZ53x7XiqKNEpNqLtS97MshW2nxg==",
"dev": true,
"requires": {
- "debug": "^3.1.0"
+ "debug": "=3.1.0"
},
"dependencies": {
"debug": {
@@ -2180,6 +2211,18 @@
"asynckit": "^0.4.0",
"combined-stream": "1.0.6",
"mime-types": "^2.1.12"
+ },
+ "dependencies": {
+ "combined-stream": {
+ "version": "1.0.6",
+ "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ }
}
},
"fragment-cache": {
@@ -2268,12 +2311,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2288,17 +2333,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -2415,7 +2463,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -2427,6 +2476,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -2441,6 +2491,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -2448,12 +2499,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -2472,6 +2525,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -2552,7 +2606,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -2564,6 +2619,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -2685,6 +2741,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -2802,6 +2859,17 @@
"inherits": "2",
"minimatch": "^2.0.1",
"once": "^1.3.0"
+ },
+ "dependencies": {
+ "minimatch": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
+ "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.0.0"
+ }
+ }
}
},
"glob-base": {
@@ -2871,9 +2939,18 @@
"unique-stream": "^1.0.0"
},
"dependencies": {
+ "minimatch": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
+ "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.0.0"
+ }
+ },
"readable-stream": {
"version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"dev": true,
"requires": {
@@ -3066,9 +3143,9 @@
},
"dependencies": {
"clone": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
- "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
"dev": true
},
"clone-stats": {
@@ -3084,9 +3161,9 @@
"dev": true
},
"vinyl": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz",
- "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+ "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
"dev": true,
"requires": {
"clone": "^2.1.1",
@@ -3113,9 +3190,9 @@
},
"dependencies": {
"lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
},
"minimatch": {
@@ -3193,7 +3270,7 @@
},
"lodash": {
"version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
"dev": true
},
@@ -3204,9 +3281,9 @@
"dev": true
},
"supports-color": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
@@ -3300,15 +3377,15 @@
}
},
"lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
},
"supports-color": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
@@ -3392,9 +3469,9 @@
},
"dependencies": {
"lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
@@ -3435,30 +3512,47 @@
}
},
"handlebars": {
- "version": "4.0.11",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz",
- "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=",
+ "version": "4.0.12",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz",
+ "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==",
"dev": true,
"requires": {
- "async": "^1.4.0",
+ "async": "^2.5.0",
"optimist": "^0.6.1",
- "source-map": "^0.4.4",
- "uglify-js": "^2.6"
+ "source-map": "^0.6.1",
+ "uglify-js": "^3.1.4"
},
"dependencies": {
"async": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.10"
+ }
+ },
+ "lodash": {
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
},
"source-map": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "3.4.9",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
+ "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
"dev": true,
+ "optional": true,
"requires": {
- "amdefine": ">=0.0.4"
+ "commander": "~2.17.1",
+ "source-map": "~0.6.1"
}
}
}
@@ -3471,13 +3565,13 @@
"optional": true
},
"har-validator": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
- "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz",
+ "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
"dev": true,
"optional": true,
"requires": {
- "ajv": "^5.1.0",
+ "ajv": "^5.3.0",
"har-schema": "^2.0.0"
}
},
@@ -3585,9 +3679,9 @@
}
},
"hosted-git-info": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz",
- "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==",
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
"dev": true
},
"htmlparser2": {
@@ -3605,7 +3699,7 @@
},
"http-errors": {
"version": "1.6.3",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"dev": true,
"requires": {
@@ -3755,7 +3849,7 @@
},
"is-builtin-module": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
"dev": true,
"requires": {
@@ -3875,23 +3969,6 @@
}
}
},
- "is-odd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
- "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
- "dev": true,
- "requires": {
- "is-number": "^4.0.0"
- },
- "dependencies": {
- "is-number": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
- "dev": true
- }
- }
- },
"is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -3970,10 +4047,13 @@
"dev": true
},
"isbinaryfile": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz",
- "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=",
- "dev": true
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz",
+ "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==",
+ "dev": true,
+ "requires": {
+ "buffer-alloc": "^1.2.0"
+ }
},
"isemail": {
"version": "1.2.0",
@@ -4071,7 +4151,7 @@
},
"joi": {
"version": "6.10.1",
- "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz",
+ "resolved": "http://registry.npmjs.org/joi/-/joi-6.10.1.tgz",
"integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=",
"dev": true,
"requires": {
@@ -4098,9 +4178,9 @@
},
"dependencies": {
"esprima": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
- "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
}
}
@@ -4132,9 +4212,9 @@
},
"dependencies": {
"lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
},
"minimatch": {
@@ -4183,7 +4263,7 @@
},
"jsonfile": {
"version": "2.4.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
"dev": true,
"optional": true,
@@ -4249,15 +4329,15 @@
},
"dependencies": {
"colors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.0.tgz",
- "integrity": "sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz",
+ "integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ==",
"dev": true
},
"glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@@ -4276,7 +4356,7 @@
},
"lodash": {
"version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
"dev": true
},
@@ -4325,9 +4405,9 @@
}
},
"lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
},
"minimatch": {
@@ -4434,7 +4514,7 @@
},
"load-json-file": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"dev": true,
"requires": {
@@ -4464,7 +4544,7 @@
},
"lodash": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz",
+ "resolved": "http://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz",
"integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=",
"dev": true
},
@@ -4478,9 +4558,9 @@
},
"dependencies": {
"lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
@@ -4648,7 +4728,7 @@
},
"log4js": {
"version": "0.6.38",
- "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz",
+ "resolved": "http://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz",
"integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=",
"dev": true,
"requires": {
@@ -4658,7 +4738,7 @@
"dependencies": {
"readable-stream": {
"version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"dev": true,
"requires": {
@@ -4693,9 +4773,9 @@
"dev": true
},
"make-error": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz",
- "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==",
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
+ "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==",
"dev": true
},
"make-error-cause": {
@@ -4955,18 +5035,18 @@
"dev": true
},
"mime-db": {
- "version": "1.33.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
- "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+ "version": "1.36.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
+ "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==",
"dev": true
},
"mime-types": {
- "version": "2.1.18",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
- "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "version": "2.1.20",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
+ "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
"dev": true,
"requires": {
- "mime-db": "~1.33.0"
+ "mime-db": "~1.36.0"
}
},
"minimatch": {
@@ -4980,7 +5060,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -5007,7 +5087,7 @@
},
"mkdirp": {
"version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
@@ -5016,7 +5096,7 @@
"dependencies": {
"minimist": {
"version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
}
@@ -5042,22 +5122,22 @@
}
},
"mute-stdout": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.0.tgz",
- "integrity": "sha1-WzLqB+tDyd7WEwQ0z5JvRrKn/U0=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
+ "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==",
"dev": true
},
"nan": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
- "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
+ "version": "2.11.1",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
+ "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==",
"dev": true,
"optional": true
},
"nanomatch": {
- "version": "1.2.9",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
- "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
"dev": true,
"requires": {
"arr-diff": "^4.0.0",
@@ -5065,7 +5145,6 @@
"define-property": "^2.0.2",
"extend-shallow": "^3.0.2",
"fragment-cache": "^0.2.1",
- "is-odd": "^2.0.0",
"is-windows": "^1.0.2",
"kind-of": "^6.0.2",
"object.pick": "^1.3.0",
@@ -5075,9 +5154,9 @@
}
},
"natives": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.4.tgz",
- "integrity": "sha512-Q29yeg9aFKwhLVdkTAejM/HvYG0Y1Am1+HUkFQGn5k2j8GS+v60TVmZh6nujpEAj/qql+wGUrlryO8bF+b1jEg==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.5.tgz",
+ "integrity": "sha512-1pJ+02gl2KJgCPFtpZGtuD4lGSJnIZvvFHCQTOeDRMSXjfu2GmYWuhI8NFMA4W2I5NNFRbfy/YCiVt4CgNpP8A==",
"dev": true
},
"negotiator": {
@@ -5125,9 +5204,9 @@
},
"dependencies": {
"semver": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
- "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
+ "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==",
"dev": true
}
}
@@ -5184,9 +5263,9 @@
"dev": true
},
"oauth-sign": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
- "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
"dev": true,
"optional": true
},
@@ -5324,7 +5403,7 @@
"dependencies": {
"minimist": {
"version": "0.0.10",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
"dev": true
}
@@ -5398,7 +5477,7 @@
},
"os-locale": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
"dev": true,
"requires": {
@@ -5528,9 +5607,9 @@
"dev": true
},
"path-parse": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
- "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
"path-root": {
@@ -5678,7 +5757,7 @@
},
"kind-of": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
"integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
"dev": true
}
@@ -5727,6 +5806,13 @@
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
"dev": true
},
+ "psl": {
+ "version": "1.1.29",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
+ "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==",
+ "dev": true,
+ "optional": true
+ },
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
@@ -5753,7 +5839,7 @@
},
"chalk": {
"version": "0.4.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz",
"integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=",
"dev": true,
"requires": {
@@ -5764,7 +5850,7 @@
},
"strip-ansi": {
"version": "0.1.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz",
+ "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz",
"integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=",
"dev": true
}
@@ -5783,9 +5869,9 @@
"dev": true
},
"randomatic": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz",
- "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz",
+ "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==",
"dev": true,
"requires": {
"is-number": "^4.0.0",
@@ -5863,7 +5949,7 @@
},
"readable-stream": {
"version": "1.1.14",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"dev": true,
"requires": {
@@ -5874,15 +5960,14 @@
}
},
"readdirp": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
- "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
"dev": true,
"requires": {
- "graceful-fs": "^4.1.2",
- "minimatch": "^3.0.2",
- "readable-stream": "^2.0.2",
- "set-immediate-shim": "^1.0.1"
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
},
"dependencies": {
"graceful-fs": {
@@ -5897,18 +5982,9 @@
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "dev": true,
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -5977,9 +6053,9 @@
"dev": true
},
"repeat-element": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
- "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
"dev": true
},
"repeat-string": {
@@ -6004,32 +6080,32 @@
"dev": true
},
"request": {
- "version": "2.87.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
- "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"dev": true,
"optional": true,
"requires": {
"aws-sign2": "~0.7.0",
- "aws4": "^1.6.0",
+ "aws4": "^1.8.0",
"caseless": "~0.12.0",
- "combined-stream": "~1.0.5",
- "extend": "~3.0.1",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
"forever-agent": "~0.6.1",
- "form-data": "~2.3.1",
- "har-validator": "~5.0.3",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.17",
- "oauth-sign": "~0.8.2",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
- "qs": "~6.5.1",
- "safe-buffer": "^5.1.1",
- "tough-cookie": "~2.3.3",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
- "uuid": "^3.1.0"
+ "uuid": "^3.3.2"
}
},
"request-progress": {
@@ -6049,9 +6125,9 @@
"dev": true
},
"resolve": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
- "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
+ "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
"dev": true,
"requires": {
"path-parse": "^1.0.5"
@@ -6098,9 +6174,9 @@
},
"dependencies": {
"glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@@ -6164,12 +6240,6 @@
"integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=",
"dev": true
},
- "set-immediate-shim": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
- "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
- "dev": true
- },
"set-value": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
@@ -6211,9 +6281,9 @@
},
"dependencies": {
"glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@@ -6389,7 +6459,7 @@
"dependencies": {
"debug": {
"version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
"dev": true,
"requires": {
@@ -6422,7 +6492,7 @@
"dependencies": {
"debug": {
"version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
"dev": true,
"requires": {
@@ -6458,7 +6528,7 @@
"dependencies": {
"debug": {
"version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
"dev": true,
"requires": {
@@ -6493,7 +6563,7 @@
},
"debug": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
"integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
"dev": true,
"requires": {
@@ -6540,9 +6610,9 @@
"dev": true
},
"spdx-correct": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
- "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.1.tgz",
+ "integrity": "sha512-hxSPZbRZvSDuOvADntOElzJpenIR7wXJkuoUcUtS0erbgt2fgeaoPIYretfKpslMhfFDY4k0MZ2F5CUzhBsSvQ==",
"dev": true,
"requires": {
"spdx-expression-parse": "^3.0.0",
@@ -6550,9 +6620,9 @@
}
},
"spdx-exceptions": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
- "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+ "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
"dev": true
},
"spdx-expression-parse": {
@@ -6566,9 +6636,9 @@
}
},
"spdx-license-ids": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
- "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz",
+ "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==",
"dev": true
},
"split": {
@@ -6690,7 +6760,7 @@
},
"strip-ansi": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
@@ -6747,7 +6817,7 @@
},
"through": {
"version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true,
"optional": true
@@ -6770,7 +6840,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -6876,12 +6946,13 @@
}
},
"tough-cookie": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
- "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"dev": true,
"optional": true,
"requires": {
+ "psl": "^1.1.24",
"punycode": "^1.4.1"
}
},
@@ -6982,7 +7053,7 @@
},
"yargs": {
"version": "3.10.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
"integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
"dev": true,
"requires": {
@@ -7131,13 +7202,10 @@
"dev": true
},
"use": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz",
- "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.2"
- }
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true
},
"user-home": {
"version": "1.1.1",
@@ -7196,9 +7264,9 @@
}
},
"validate-npm-package-license": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
- "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
"dev": true,
"requires": {
"spdx-correct": "^3.0.0",
@@ -7252,7 +7320,7 @@
},
"readable-stream": {
"version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"dev": true,
"requires": {
@@ -7325,9 +7393,9 @@
"dev": true
},
"winston": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.2.tgz",
- "integrity": "sha512-4S/Ad4ZfSNl8OccCLxnJmNISWcm2joa6Q0YGDxlxMzH0fgSwWsjMt+SmlNwCqdpaPg3ev1HKkMBsIiXeSUwpbA==",
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.4.tgz",
+ "integrity": "sha512-NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q==",
"dev": true,
"requires": {
"async": "~1.0.0",
@@ -7346,7 +7414,7 @@
},
"wrap-ansi": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"dev": true,
"requires": {
@@ -7412,7 +7480,7 @@
},
"yargs": {
"version": "3.32.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
+ "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
"integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
"dev": true,
"requires": {
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index d88bbbaec..b2773a224 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -13,27 +13,46 @@
namespace OCA\News\AppInfo;
+use Closure;
+use FeedIo\FeedIo;
use HTMLPurifier;
use HTMLPurifier_Config;
+
+use OCA\News\Config\FetcherConfig;
+use OCA\News\Utility\PsrLogger;
+use OCP\BackgroundJob\IJobList;
+
+use OCP\IContainer;
+use OCP\INavigationManager;
+use OCP\IURLGenerator;
+use OCP\IConfig;
+use OCP\AppFramework\App;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+
+
+use OCA\News\Config\AppConfig;
use OCA\News\Config\Config;
-use OCA\News\Db\ItemMapper;
use OCA\News\Db\MapperFactory;
+use OCA\News\Db\ItemMapper;
use OCA\News\Fetcher\FeedFetcher;
use OCA\News\Fetcher\Fetcher;
use OCA\News\Fetcher\YoutubeFetcher;
use OCA\News\Utility\ProxyConfigParser;
-use OCP\AppFramework\App;
-use OCP\Files\IRootFolder;
-use OCP\Files\Node;
-use OCP\IConfig;
-use OCP\IContainer;
-use OCP\ILogger;
-use PicoFeed\Config\Config as PicoFeedConfig;
-use PicoFeed\Reader\Reader as PicoFeedReader;
+/**
+ * Class Application
+ *
+ * @package OCA\News\AppInfo
+ */
class Application extends App
{
+ /**
+ * Application constructor.
+ *
+ * @param array $urlParams Parameters
+ */
public function __construct(array $urlParams = [])
{
parent::__construct('news', $urlParams);
@@ -57,6 +76,21 @@ class Application extends App
return $c->query(MapperFactory::class)->build();
});
+
+ /**
+ * App config parser.
+ */
+ $container->registerService(AppConfig::class, function (IContainer $c) {
+ $config = new AppConfig(
+ $c->query(INavigationManager::class),
+ $c->query(IURLGenerator::class),
+ $c->query(IJobList::class)
+ );
+
+ $config->loadConfig($c->query('info'));
+ return $config;
+ });
+
/**
* Core
*/
@@ -79,10 +113,21 @@ class Application extends App
}
});
+ /**
+ * Logger base
+ */
+ $container->registerService(PsrLogger::class, function (IContainer $c) {
+ return new PsrLogger(
+ $c->query('ServerContainer')->getLogger(),
+ $c->query('AppName')
+ );
+ });
+
+
$container->registerService(Config::class, function (IContainer $c): Config {
$config = new Config(
$c->query('ConfigView'),
- $c->query(ILogger::class),
+ $c->query(PsrLogger::class),
$c->query('LoggerParameters')
);
$config->read($c->query('configFile'), true);
@@ -115,55 +160,33 @@ class Application extends App
/**
* Fetchers
*/
- $container->registerService(PicoFeedConfig::class, function (IContainer $c): PicoFeedConfig {
+ $container->registerService(FetcherConfig::class, function (IContainer $c) {
// FIXME: move this into a separate class for testing?
$config = $c->query(Config::class);
- $proxy = $c->query(ProxyConfigParser::class);
-
- $userAgent = 'NextCloud-News/1.0';
-
- $pico = new PicoFeedConfig();
- $pico->setClientUserAgent($userAgent)
- ->setClientTimeout($config->getFeedFetcherTimeout())
- ->setMaxRedirections($config->getMaxRedirects())
- ->setMaxBodySize($config->getMaxSize())
- ->setParserHashAlgo('md5');
-
- // proxy settings
- $proxySettings = $proxy->parse();
- $host = $proxySettings['host'];
- $port = $proxySettings['port'];
- $user = $proxySettings['user'];
- $password = $proxySettings['password'];
-
- if ($host) {
- $pico->setProxyHostname($host);
-
- if ($port) {
- $pico->setProxyPort($port);
- }
- }
+ $proxy = $c->query(ProxyConfigParser::class);
- if ($user) {
- $pico->setProxyUsername($user)
- ->setProxyPassword($password);
- }
+ $fConfig = new FetcherConfig();
+ $fConfig->setClientTimeout($config->getFeedFetcherTimeout());
+ $fConfig->setProxy($proxy);
- return $pico;
+ return $fConfig;
});
- $container->registerService(PicoFeedReader::class, function (IContainer $c): PicoFeedReader {
- return new PicoFeedReader($c->query(PicoFeedConfig::class));
+ $container->registerService(FeedIo::class, function (IContainer $c) {
+ $config = $c->query(FetcherConfig::class);
+ return new FeedIo($config->getClient(), $c->query(PsrLogger::class));
});
- $container->registerService(Fetcher::class, function (IContainer $c): Fetcher {
+ /**
+ * @noinspection PhpParamsInspection
+ */
+ $container->registerService(Fetcher::class, function (IContainer $c) {
$fetcher = new Fetcher();
// register fetchers in order, the most generic fetcher should be
// the last one
$fetcher->registerFetcher($c->query(YoutubeFetcher::class));
$fetcher->registerFetcher($c->query(FeedFetcher::class));
-
return $fetcher;
});
}
diff --git a/lib/Config/Config.php b/lib/Config/Config.php
index 7c5cee74a..dea1f5814 100644
--- a/lib/Config/Config.php
+++ b/lib/Config/Config.php
@@ -13,7 +13,7 @@
namespace OCA\News\Config;
-use OCP\ILogger;
+use OCA\News\Utility\PsrLogger;
use OCP\Files\Folder;
class Config
@@ -35,7 +35,7 @@ class Config
public function __construct(
Folder $fileSystem,
- ILogger $logger,
+ PsrLogger $logger,
$LoggerParameters
) {
$this->fileSystem = $fileSystem;
diff --git a/lib/Config/FetcherConfig.php b/lib/Config/FetcherConfig.php
new file mode 100644
index 000000000..55603c47c
--- /dev/null
+++ b/lib/Config/FetcherConfig.php
@@ -0,0 +1,118 @@
+<?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;
+
+use FeedIo\Adapter\ClientInterface;
+use \GuzzleHttp\Client;
+use \FeedIo\Adapter\Guzzle\Client as FeedIoClient;
+
+/**
+ * Class FetcherConfig
+ *
+ * @package OCA\News\Config
+ */
+class FetcherConfig
+{
+ protected $client_timeout;
+ protected $proxy;
+
+ /**
+ * Configure a guzzle client
+ *
+ * @return ClientInterface Legacy client to guzzle.
+ */
+ public function getClient()
+ {
+ if (!class_exists('GuzzleHttp\Collection')) {
+ $config = [
+ 'timeout' => $this->getClientTimeout(),
+ ];
+
+ if (!empty($this->proxy)) {
+ $config['proxy'] = $this->proxy;
+ }
+
+ $guzzle = new Client();
+ $client = new FeedIoClient($guzzle);
+
+ return $client;
+ }
+
+ $config = [
+ 'request.options' => [
+ 'timeout' => $this->getClientTimeout(),
+ ],
+ ];
+
+ if (!empty($this->proxy)) {
+ $config['request.options']['proxy'] = $this->proxy;
+ }
+
+ $guzzle = new Client($config);
+ return new LegacyGuzzleClient($guzzle);
+ }
+
+ /**
+ * Set a timeout for the client
+ *
+ * @param int $timeout The timeout
+ *
+ * @return self
+ */
+ public function setClientTimeout($timeout)
+ {
+ $this->client_timeout = $timeout;
+
+ return $this;
+ }
+
+ /**
+ * Get the client timeout.
+ *
+ * @return mixed
+ */
+ public function getClientTimeout()
+ {
+ return $this->client_timeout;
+ }
+
+ /**
+ * Set the proxy
+ *
+ * @param \OCA\News\Utility\ProxyConfigParser $proxy The proxy to set.
+ *
+ * @return self
+ */
+ public function setProxy($proxy)
+ {
+ // proxy settings
+ $proxySettings = $proxy->parse();
+ $host = $proxySettings['host'];
+ $port = $proxySettings['port'];
+ $user = $proxySettings['user'];
+ $password = $proxySettings['password'];
+
+ $proxy_string = 'https://';
+ if (!empty($user)) {
+ $proxy_string .= $user . ':' . $password . '@';
+ }
+ $proxy_string .= $host;
+ if (!empty($port)) {
+ $proxy_string .= ':' . $port;
+ }
+ $this->proxy = $proxy_string;
+
+ return $this;
+ }
+}
diff --git a/lib/Config/LegacyGuzzleClient.php b/lib/Config/LegacyGuzzleClient.php
new file mode 100644
index 000000000..bc1364c30
--- /dev/null
+++ b/lib/Config/LegacyGuzzleClient.php
@@ -0,0 +1,65 @@
+<?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\Config;
+
+use FeedIo\Adapter\ClientInterface as FeedIoClientInterface;
+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($url, \DateTime $modifiedSince)
+ {
+ try {
+ $options = [
+ 'headers' => [
+ 'User-Agent' => 'NextCloud-News/1.0',
+ 'If-Modified-Since' => $modifiedSince->format(\DateTime::RFC2822)
+ ]
+ ];
+
+ 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());
+ }
+ }
+ }
+}
diff --git a/lib/Config/LegacyGuzzleResponse.php b/lib/Config/LegacyGuzzleResponse.php
new file mode 100644
index 000000000..d9f6102ee
--- /dev/null
+++ b/lib/Config/LegacyGuzzleResponse.php
@@ -0,0 +1,86 @@
+<?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\Config;
+
+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()
+ {
+ return $this->response->getStatusCode() !== 304 && $this->response->getBody()->getSize() > 0;
+ }
+
+ /**
+ * @return \Psr\Http\Message\StreamInterface
+ */
+ public function getBody()
+ {
+ return $this->response->getBody();
+ }
+
+ /**
+ * @return \DateTime|null
+ */
+ public function getLastModified()
+ {
+ if ($this->response->hasHeader(static::HTTP_LAST_MODIFIED)) {
+ $lastModified = \DateTime::createFromFormat(
+ \DateTime::RFC2822,
+ $this->getHeader(static::HTTP_LAST_MODIFIED)
+ );
+
+ return false === $lastModified ? null : $lastModified;
+ }
+
+ return;
+ }
+
+ /**
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return $this->response->getHeaders();
+ }
+
+ /**
+ * @param string $name
+ * @return string[]
+ */
+ public function getHeader($name)
+ {
+ return $this->response->getHeader($name);
+ }
+}
diff --git a/lib/Db/Item.php b/lib/Db/Item.php
index 1a8d284a2..3a17dd2cb 100644
--- a/lib/Db/Item.php
+++ b/lib/Db/Item.php
@@ -491,4 +491,18 @@ class Item extends Entity implements IAPI, \JsonSerializable
$this->getEnclosureLink()
);
}
+
+ /**
+ * Check if a given mimetype is supported
+ *
+ * @param string $mime mimetype to check
+ *
+ * @return boolean
+ */
+ public function isSupportedMime($mime)
+ {
+ return (
+ stripos($mime, 'audio/') !== false ||
+ stripos($mime, 'video/') !== false);
+ }
}
diff --git a/lib/Fetcher/FeedFetcher.php b/lib/Fetcher/FeedFetcher.php
index 65a4b5526..ae338ca09 100644
--- a/lib/Fetcher/FeedFetcher.php
+++ b/lib/Fetcher/FeedFetcher.php
@@ -13,29 +13,17 @@
namespace OCA\News\Fetcher;
-use Exception;
-
-use OCA\News\PostProcessor\LWNProcessor;
+use DateTime;
+use Favicon\Favicon;
+use FeedIo\Feed\ItemInterface;
+use FeedIo\FeedInterface;
+use FeedIo\FeedIo;
use OCP\Http\Client\IClientService;
-use PicoFeed\Parser\MalFormedXmlException;
-use PicoFeed\Reader\Reader;
-use PicoFeed\Parser\Parser;
-use PicoFeed\Reader\SubscriptionNotFoundException;
-use PicoFeed\Reader\UnsupportedFeedFormatException;
-use PicoFeed\Client\InvalidCertificateException;
-use PicoFeed\Client\InvalidUrlException;
-use PicoFeed\Client\MaxRedirectException;
-use PicoFeed\Client\MaxSizeException;
-use PicoFeed\Client\TimeoutException;
-use PicoFeed\Client\ForbiddenException;
-use PicoFeed\Client\UnauthorizedException;
use OCP\IL10N;
use OCA\News\Db\Item;
use OCA\News\Db\Feed;
-use OCA\News\Utility\PicoFeedFaviconFactory;
-use OCA\News\Utility\PicoFeedReaderFactory;
use OCA\News\Utility\Time;
class FeedFetcher implements IFeedFetcher
@@ -48,22 +36,26 @@ class FeedFetcher implements IFeedFetcher
private $clientService;
public function __construct(
- Reader $reader,
- PicoFeedFaviconFactory $faviconFactory,
+ FeedIo $fetcher,
+ Favicon $favicon,
IL10N $l10n,
Time $time,
IClientService $clientService
) {
- $this->faviconFactory = $faviconFactory;
- $this->reader = $reader;
- $this->time = $time;
- $this->l10n = $l10n;
- $this->clientService = $clientService;
+ $this->faviconFactory = $favicon;
+ $this->reader = $fetcher;
+ $this->time = $time;
+ $this->l10n = $l10n;
+ $this->clientService = $clientService;
}
/**
- * This fetcher handles all the remaining urls therefore always returns true
+ * This fetcher handles all the remaining urls therefore always returns true.
+ *
+ * @param string $url The URL to check
+ *
+ * @return bool
*/
public function canHandle($url)
{
@@ -74,176 +66,55 @@ class FeedFetcher implements IFeedFetcher
/**
* Fetch a feed from remote
*
- * @param string $url remote url of the feed
- * @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.
- * If lastModified matches the http header from the feed no results are fetched
- * @param string $etag an etag from an http header.
- * If lastModified matches the http header from the feed no results are fetched
- * @param bool $fullTextEnabled if true tells the fetcher to enhance the articles by fetching more content
- * @param string $basicAuthUser if given, basic auth is set for this feed
- * @param string $basicAuthPassword if given, basic auth is set for this feed. Ignored if user is empty
+ * @param string $url Remote url of the feed
+ * @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. If lastModified matches
+ * the header from the feed no results are fetched
+ * @param string $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 null or an empty string.
*
- * @throws FetcherException if it fails
* @return array an array containing the new feed and its items, first
* element being the Feed and second element being an array of Items
*/
- public function fetch(
- $url,
- $getFavicon = true,
- $lastModified = null,
- $etag = null,
- $fullTextEnabled = false,
- $basicAuthUser = null,
- $basicAuthPassword = null
- ) {
- try {
- if ($basicAuthUser !== null && trim($basicAuthUser) !== '') {
- $resource = $this->reader->discover(
- $url,
- $lastModified,
- $etag,
- $basicAuthUser,
- $basicAuthPassword
- );
- } else {
- $resource = $this->reader->discover($url, $lastModified, $etag);
- }
-
- if (!$resource->isModified()) {
- return [null, null];
- }
-
- $location = $resource->getUrl();
- $etag = $resource->getEtag();
- $content = $resource->getContent();
- $encoding = $resource->getEncoding();
- $lastModified = $resource->getLastModified();
-
- $parser = $this->reader->getParser($location, $content, $encoding);
-
- if ($fullTextEnabled) {
- $parser->enableContentGrabber();
- $parser->getItemPostProcessor()->register(
- new LWNProcessor(
- $basicAuthUser,
- $basicAuthPassword,
- $this->clientService
- )
- );
- }
-
- $parsedFeed = $parser->execute();
-
- $feed = $this->buildFeed(
- $parsedFeed,
- $url,
- $getFavicon,
- $lastModified,
- $etag,
- $location
- );
-
- $items = [];
- foreach ($parsedFeed->getItems() as $item) {
- $items[] = $this->buildItem($item, $parsedFeed);
- }
-
- return [$feed, $items];
- } catch (Exception $ex) {
- $this->handleError($ex, $url);
- }
- }
-
-
- private function handleError(Exception $ex, $url)
+ public function fetch($url, $getFavicon = true, $lastModified = null, $user = null, $password = null)
{
- $msg = $ex->getMessage();
+ if ($user !== null && trim($user) !== '') {
+ $url = explode('://', $url);
+ $url = $url[0] . '://' . $user . ':' . $password . '@' . $url[1];
+ }
+ $resource = $this->reader->readSince($url, new DateTime($lastModified));
- if ($ex instanceof MalFormedXmlException) {
- $msg = $this->l10n->t('Feed contains invalid XML');
- } elseif ($ex instanceof SubscriptionNotFoundException) {
- $msg = $this->l10n->t(
- 'Feed not found: Either the website ' .
- 'does not provide a feed or blocks access. To rule out ' .
- 'blocking, try to download the feed on your server\'s ' .
- 'command line using curl: curl ' . $url
- );
- } elseif ($ex instanceof UnsupportedFeedFormatException) {
- $msg = $this->l10n->t('Detected feed format is not supported');
- } elseif ($ex instanceof InvalidCertificateException) {
- $msg = $this->buildCurlSslErrorMessage($ex->getCode());
- } elseif ($ex instanceof InvalidUrlException) {
- $msg = $this->l10n->t('Website not found');
- } elseif ($ex instanceof MaxRedirectException) {
- $msg = $this->l10n->t('More redirects than allowed, aborting');
- } elseif ($ex instanceof MaxSizeException) {
- $msg = $this->l10n->t('Bigger than maximum allowed size');
- } elseif ($ex instanceof TimeoutException) {
- $msg = $this->l10n->t('Request timed out');
- } elseif ($ex instanceof UnauthorizedException) {
- $msg = $this->l10n->t(
- 'Required credentials for feed were ' .
- 'either missing or incorrect'
- );
- } elseif ($ex instanceof ForbiddenException) {
- $msg = $this->l10n->t('Forbidden to access feed');
+ if (!$resource->getResponse()->isModified()) {
+ return [null, null];
}
- throw new FetcherException($msg);
- }
+ $location = $resource->getUrl();
+ $parsedFeed = $resource->getFeed();
+ $feed = $this->buildFeed(
+ $parsedFeed,
+ $url,
+ $getFavicon,
+ $location
+ );
- private function buildCurlSslErrorMessage($errorCode)
- {
- switch ($errorCode) {
- case 35: // CURLE_SSL_CONNECT_ERROR
- return $this->l10n->t(
- 'Certificate error: A problem occurred ' .
- 'somewhere in the SSL/TLS handshake. Could be ' .
- 'certificates (file formats, paths, permissions), ' .
- 'passwords, and others.'
- );
- case 51: // CURLE_PEER_FAILED_VERIFICATION
- return $this->l10n->t(
- 'Certificate error: The remote server\'s SSL ' .
- 'certificate or SSH md5 fingerprint was deemed not OK.'
- );
- case 58: // CURLE_SSL_CERTPROBLEM
- return $this->l10n->t(
- 'Certificate error: Problem with the local client ' .
- 'certificate.'
- );
- case 59: // CURLE_SSL_CIPHER
- return $this->l10n->t(
- 'Certificate error: Couldn\'t use specified cipher.'
- );
- case 60: // CURLE_SSL_CACERT
- return $this->l10n->t(
- 'Certificate error: Peer certificate cannot be ' .
- 'authenticated with known CA certificates.'
- );
- case 64: // CURLE_USE_SSL_FAILED
- return $this->l10n->t(
- 'Certificate error: Requested FTP SSL level failed.'
- );
- case 66: // CURLE_SSL_ENGINE_INITFAILED
- return $this->l10n->t(
- 'Certificate error: Initiating the SSL engine failed.'
- );
- case 77: // CURLE_SSL_CACERT_BADFILE
- return $this->l10n->t(
- 'Certificate error: Problem with reading the SSL CA ' .
- 'cert (path? access rights?)'
- );
- case 83: // CURLE_SSL_ISSUER_ERROR
- return $this->l10n->t(
- 'Certificate error: Issuer check failed'
- );
- default:
- return $this->l10n->t('Unknown SSL certificate error!');
+ $items = [];
+ foreach ($parsedFeed as $item) {
+ $items[] = $this->buildItem($item, $parsedFeed);
}
+
+ return [$feed, $items];
}
+ /**
+ * Decode the string twice
+ *
+ * @param string $string String to decode
+ *
+ * @return string
+ */
private function decodeTwice($string)
{
return html_entity_decode(
@@ -257,37 +128,73 @@ class FeedFetcher implements IFeedFetcher
);
}
-
- protected function determineRtl($parsedItem, $parsedFeed)
+ /**
+ * Check if a feed is RTL or not
+ *
+ * @param FeedInterface $parsedFeed The feed that was parsed
+ *
+ * @return bool
+ */
+ protected function determineRtl($parsedFeed)
{
- $itemLang = $parsedItem->getLanguage();
- $feedLang = $parsedFeed->getLanguage();
-
- if ($itemLang) {
- return Parser::isLanguageRTL($itemLang);
- } else {
- return Parser::isLanguageRTL($feedLang);
+ $language = $parsedFeed->getLanguage();
+
+ $language = strtolower($language);
+ $rtl_languages = array(
+ 'ar', // Arabic (ar-**)
+ 'fa', // Farsi (fa-**)
+ 'ur', // Urdu (ur-**)
+ 'ps', // Pashtu (ps-**)
+ 'syr', // Syriac (syr-**)
+ 'dv', // Divehi (dv-**)
+ 'he', // Hebrew (he-**)
+ 'yi', // Yiddish (yi-**)
+ );
+ foreach ($rtl_languages as $prefix) {
+ if (strpos($language, $prefix) === 0) {
+ return true;
+ }
}
+ return false;
}
-
+ /**
+ * Build an item based on a feed.
+ *
+ * @param ItemInterface $parsedItem The item to use
+ * @param FeedInterface $parsedFeed The feed to use
+ *
+ * @return Item
+ */
protected function buildItem($parsedItem, $parsedFeed)
{
$item = new Item();
$item->setUnread(true);
- $item->setUrl($parsedItem->getUrl());
- $item->setGuid($parsedItem->getId());
+ $item->setUrl($parsedItem->getLink());
+ $item->setGuid($parsedItem->getPublicId());
$item->setGuidHash($item->getGuid());
- $item->setPubDate($parsedItem->getPublishedDate()->getTimestamp());
- $item->setUpdatedDate($parsedItem->getUpdatedDate()->getTimestamp());
- $item->setRtl($this->determineRtl($parsedItem, $parsedFeed));
+
+ $pubDT = $parsedItem->getLastModified();
+ if ($parsedItem->getValue('pubDate') !== null) {
+ $pubDT = new DateTime($parsedItem->getValue('pubDate'));
+ } elseif ($parsedItem->getValue('published') !== null) {
+ $pubDT = new DateTime($parsedItem->getValue('published'));
+ }
+
+ $item->setPubDate(
+ $pubDT->getTimestamp()
+ );
+ $item->setLastModified(
+ $parsedItem->getLastModified()->getTimestamp()
+ );
+ $item->setRtl($this->determineRtl($parsedFeed));
// unescape content because angularjs helps against XSS
$item->setTitle($this->decodeTwice($parsedItem->getTitle()));
$item->setAuthor($this->decodeTwice($parsedItem->getAuthor()));
// purification is done in the service layer
- $body = $parsedItem->getContent();
+ $body = $parsedItem->getDescription();
$body = mb_convert_encoding(
$body,
'HTML-ENTITIES',
@@ -295,14 +202,14 @@ class FeedFetcher implements IFeedFetcher
);
$item->setBody($body);
- $enclosureUrl = $parsedItem->getEnclosureUrl();
- if ($enclosureUrl) {
- $enclosureType = $parsedItem->getEnclosureType();
- if (stripos($enclosureType, 'audio/') !== false
- || stripos($enclosureType, 'video/') !== false
- ) {
- $item->setEnclosureMime($enclosureType);
- $item->setEnclosureLink($enclosureUrl);
+ if ($parsedItem->hasMedia()) {
+ // TODO: Fix multiple media support
+ foreach ($parsedItem->getMedias() as $media) {
+ if (!$item->isSupportedMime($media->getType())) {
+ continue;
+ }
+ $item->setEnclosureMime($media->getType());
+ $item->setEnclosureLink($media->getUrl());
}
}
@@ -311,39 +218,35 @@ class FeedFetcher implements IFeedFetcher
return $item;
}
-
- protected function buildFeed(
- $parsedFeed,
- $url,
- $getFavicon,
- $modified,
- $etag,
- $location
- ) {
- $feed = new Feed();
-
- $link = $parsedFeed->getSiteUrl();
-
- if (!$link) {
- $link = $location;
- }
+ /**
+ * Build a feed based on provided info
+ *
+ * @param FeedInterface $feed Feed to build from
+ * @param string $url URL to use
+ * @param bool $getFavicon To get the favicon
+ * @param string $location String base URL
+ *
+ * @return Feed
+ */
+ protected function buildFeed($feed, $url, $getFavicon, $location)
+ {
+ $newFeed = new Feed();
// unescape content because angularjs helps against XSS
- $title = strip_tags($this->decodeTwice($parsedFeed->getTitle()));
- $feed->setTitle($title);
- $feed->setUrl($url); // the url used to add the feed
- $feed->setLocation($location); // the url where the feed was found
- $feed->setLink($link); // <link> attribute in the feed
- $feed->setHttpLastModified($modified);
- $feed->setHttpEtag($etag);
- $feed->setAdded($this->time->getTime());
-
- if ($getFavicon) {
- $faviconFetcher = $this->faviconFactory->build();
- $favicon = $faviconFetcher->find($feed->getLink());
- $feed->setFaviconLink($favicon);
+ $title = strip_tags($this->decodeTwice($feed->getTitle()));
+ $newFeed->setTitle($title);
+ $newFeed->setUrl($url); // the url used to add the feed
+ $newFeed->setLocation($location); // the url where the feed was found
+ $newFeed->setLink($feed->getLink()); // <link> attribute in the feed
+ $newFeed->setLastModified($feed->getLastModified()->getTimestamp());
+ $newFeed->setAdded($this->time->getTime());
+
+ if (!$getFavicon) {
+ return $newFeed;
}
+ $favicon = $this->faviconFactory->get($url);
+ $newFeed->setFaviconLink($favicon);
- return $feed;
+ return $newFeed;
}
}
diff --git a/lib/Fetcher/Fetcher.php b/lib/Fetcher/Fetcher.php
index e78da0265..23f5b57f7 100644
--- a/lib/Fetcher/Fetcher.php
+++ b/lib/Fetcher/Fetcher.php
@@ -16,6 +16,10 @@ namespace OCA\News\Fetcher;
class Fetcher
{
+ /**
+ * List of fetchers.
+ * @var IFeedFetcher[]
+ */
private $fetchers;
public function __construct()
@@ -39,39 +43,28 @@ class Fetcher
*
* @param string $url remote url of the feed
* @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 $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
- * @param string $etag an etag from an http header.
- * If lastModified matches the http header from the feed no results are fetched
- * @param bool $fullTextEnabled if true tells the fetcher to enhance the articles by fetching more content
- * @param string $basicAuthUser if given, basic auth is set for this feed
- * @param string $basicAuthPassword if given, basic auth is set for this feed. Ignored if user is empty
+ * @param string $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
*
- * @throws FetcherException if simple pie fails
+ * @throws FetcherException if FeedIO fails
* @return array an array containing the new feed and its items, first
* element being the Feed and second element being an array of Items
*/
- public function fetch(
- $url,
- $getFavicon = true,
- $lastModified = null,
- $etag = null,
- $fullTextEnabled = false,
- $basicAuthUser = null,
- $basicAuthPassword = null
- ) {
+ public function fetch($url, $getFavicon = true, $lastModified = null, $user = null, $password = null)
+ {
foreach ($this->fetchers as $fetcher) {
- if ($fetcher->canHandle($url)) {
- return $fetcher->fetch(
- $url,
- $getFavicon,
- $lastModified,
- $etag,
- $fullTextEnabled,
- $basicAuthUser,
- $basicAuthPassword
- );
+ if (!$fetcher->canHandle($url)) {
+ continue;
}
+ return $fetcher->fetch(
+ $url,
+ $getFavicon,
+ $lastModified,
+ $user,
+ $password
+ );
}
return [null, []];
diff --git a/lib/Fetcher/IFeedFetcher.php b/lib/Fetcher/IFeedFetcher.php
index c96bd315b..d5994a076 100644
--- a/lib/Fetcher/IFeedFetcher.php
+++ b/lib/Fetcher/IFeedFetcher.php
@@ -23,25 +23,14 @@ interface IFeedFetcher
* @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.
* If lastModified matches the http header from the feed no results are fetched
- * @param string $etag an etag from an http header.
- * If lastModified matches the http header from the feed no results are fetched
- * @param bool $fullTextEnabled if true tells the fetcher to enhance the articles by fetching more content
- * @param string $basicAuthUser if given, basic auth is set for this feed
- * @param string $basicAuthPassword if given, basic auth is set for this feed. Ignored if user is empty
+ * @param string $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
*
* @throws FetcherException if the fetcher encounters a problem
* @return array an array containing the new feed and its items, first
* element being the Feed and second element being an array of Items
*/
- public function fetch(
- $url,
- $getFavicon = true,
- $lastModified = null,
- $etag = null,
- $fullTextEnabled = false,
- $basicAuthUser = null,
- $basicAuthPassword = null
- );
+ public function fetch($url, $getFavicon = true, $lastModified = null, $user = null, $password = null);
/**
* Can a fetcher handle a feed.
diff --git a/lib/Fetcher/YoutubeFetcher.php b/lib/Fetcher/YoutubeFetcher.php
index a47b8fdb8..9ccce4463 100644
--- a/lib/Fetcher/YoutubeFetcher.php
+++ b/lib/Fetcher/YoutubeFetcher.php
@@ -52,35 +52,24 @@ class YoutubeFetcher implements IFeedFetcher
* @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.
* If lastModified matches the http header from the feed no results are fetched
- * @param string $etag an etag from an http header.
- * If lastModified matches the http header from the feed no results are fetched
- * @param bool $fullTextEnabled if true tells the fetcher to enhance the articles by fetching more content
- * @param string $basicAuthUser if given, basic auth is set for this feed
- * @param string $basicAuthPassword if given, basic auth is set for this feed. Ignored if user is empty
+ * @param string $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
*
* @throws FetcherException if it fails
* @return array an array containing the new feed and its items, first
* element being the Feed and second element being an array of Items
*/
- public function fetch(
- $url,
- $getFavicon = true,
- $lastModified = null,
- $etag = null,
- $fullTextEnabled = false,
- $basicAuthUser = null,
- $basicAuthPassword = null
- ) {
+ public function fetch($url, $getFavicon = true, $lastModified = null, $user = null, $password = null
+ )
+ {
$transformedUrl = $this->buildUrl($url);
$result = $this->feedFetcher->fetch(
$transformedUrl,
$getFavicon,
$lastModified,
- $etag,
- $fullTextEnabled,
- $basicAuthUser,
- $basicAuthPassword
+ $user,
+ $password
);
// reset feed url so we know the correct added url for the feed
diff --git a/lib/PostProcessor/LWNProcessor.php b/lib/PostProcessor/LWNProcessor.php
deleted file mode 100644
index 1028df100..000000000
--- a/lib/PostProcessor/LWNProcessor.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * Nextcloud - News
- *
- * This file is licensed under the Affero General Public License version 3 or
- * later. See the COPYING file.
- *
- * @author Robin Appelman <robin@icewind.nl>
- */
-
-namespace OCA\News\PostProcessor;
-
-use GuzzleHttp\Cookie\CookieJar;
-use OCP\Http\Client\IClientService;
-use PicoFeed\Parser\Feed;
-use PicoFeed\Parser\Item;
-use PicoFeed\Processor\ItemProcessorInterface;
-use PicoFeed\Scraper\RuleParser;
-
-class LWNProcessor implements ItemProcessorInterface
-{
- private $user;
-
- private $password;
-
- private $clientService;
-
- private $cookieJar;
-
- /**
- * @param $user
- * @param $password
- */
- public function __construct($user, $password, IClientService $clientService)
- {
- $this->user = $user;
- $this->password = $password;
- $this->clientService = $clientService;
- $this->cookieJar = new CookieJar();
- }
-
- private function login()
- {
- if ($this->cookieJar->count() > 0) {
- return true;
- }
- if (!$this->user || !$this->password) {
- return false;
- }
-
- $client = $this->clientService->newClient();
- $response = $client->post(
- 'https://lwn.net/login',
- [
- 'cookies' => $this->cookieJar,
- 'body' => [
- 'Username' => $this->user,
- 'Password' => $this->password,
- 'target' => '/'
- ]
- ]
- );
- return ($response->getStatusCode() === 200 && $this->cookieJar->count() > 0);
- }
-
- private function getBody($url)
- {
- $client = $this->clientService->newClient();
- $response = $client->get(
- $url,
- [
- 'cookies' => $this->cookieJar
- ]
- );
- $parser = new RuleParser(
- $response->getBody(),
- [
- 'body' => array(
- '//div[@class="ArticleText"]',
- ),
- 'strip' => array(
- '//div[@class="FeatureByline"]'
- )
- ]
- );
- $articleBody = $parser->execute();
- // make all links absolute
- return str_replace('href="/', 'href="https://lwn.net/', $articleBody);
- }
-
- private function canHandle($url)
- {
- $regex = '%(?:https?://|//)?(?:www.)?lwn.net%';
-
- return (bool)preg_match($regex, $url);
- }
-
- /**
- * Execute Item Processor
- *
- * @access public
- * @param Feed $feed
- * @param Item $item
- * @return bool
- */
- public function execute(Feed $feed, Item $item)
- {
- if ($this->canHandle($item->getUrl())) {
- $loggedIn = $this->login();
-
- $item->setUrl(str_replace('/rss', '', $item->getUrl()));
- if ($loggedIn) {
- $item->setContent($this->getBody($item->getUrl()));
- }
- }
- }
-}
diff --git a/lib/Service/FeedService.php b/lib/Service/FeedService.php
index 2ccbb014b..fade77df8 100644
--- a/lib/Service/FeedService.php
+++ b/lib/Service/FeedService.php
@@ -58,8 +58,8 @@ class FeedService extends Service
$this->logger = $logger;
$this->l10n = $l10n;
$this->timeFactory = $timeFactory;
- $this->autoPurgeMinimumInterval =
- $config->getAutoPurgeMinimumInterval();
+ $this->autoPurgeMinimumInterval = $config->getAutoPurgeMinimumInterval(
+ );
$this->purifier = $purifier;
$this->feedMapper = $feedMapper;
$this->loggerParams = $LoggerParameters;
@@ -69,6 +69,7 @@ class FeedService extends Service
* Finds all feeds of a user
*
* @param string $userId the name of the user
+ *
* @return Feed[]
*/
public function findAll($userId)
@@ -96,9 +97,10 @@ class FeedService extends Service
* folder
* @param string $userId for which user the feed should be created
* @param string $title if given, this is used for the opml feed title
- * @param string $basicAuthUser if given, basic auth is set for this feed
- * @param string $basicAuthPassword if given, basic auth is set for this
+ * @param string $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 null or an empty string
+ *
* @throws ServiceConflictException if the feed exists already
* @throws ServiceNotFoundException if the url points to an invalid feed
* @return Feed the newly created feed
@@ -108,23 +110,21 @@ class FeedService extends Service
$folderId,
$userId,
$title = null,
- $basicAuthUser = null,
- $basicAuthPassword = null
+ $user = null,
+ $password = null
) {
// first try if the feed exists already
try {
/**
- * @var Feed $feed
+ * @var Feed $feed
* @var Item[] $items
*/
list($feed, $items) = $this->feedFetcher->fetch(
$feedUrl,
true,
null,
- null,
- false,
- $basicAuthUser,
- $basicAuthPassword
+ $user,
+ $password
);
// try again if feed exists depending on the reported link
@@ -140,8 +140,8 @@ class FeedService extends Service
// insert feed
$itemCount = count($items);
- $feed->setBasicAuthUser($basicAuthUser);
- $feed->setBasicAuthPassword($basicAuthPassword);
+ $feed->setBasicAuthUser($user);
+ $feed->setBasicAuthPassword($password);
$feed->setFolderId($folderId);
$feed->setUserId($userId);
$feed->setArticlesPerUpdate($itemCount);
@@ -213,6 +213,7 @@ class FeedService extends Service
* @param int $feedId the id of the feed that should be updated
* @param string $userId the id of the user
* @param bool $forceUpdate update even if the article exists already
+ *
* @throws ServiceNotFoundException if the feed does not exist
* @return Feed the updated feed entity
*/
@@ -237,8 +238,6 @@ class FeedService extends Service
$location,
false,
$existingFeed->getHttpLastModified(),
- $existingFeed->getHttpEtag(),
- $existingFeed->getFullTextEnabled(),
$existingFeed->getBasicAuthUser(),
$existingFeed->getBasicAuthPassword()
);
@@ -332,6 +331,7 @@ class FeedService extends Service
*
* @param array $json the array with json
* @param string $userId the username
+ *
* @return Feed if one had to be created for nonexistent feeds
*/
public function importArticles($json, $userId)
@@ -406,6 +406,7 @@ class FeedService extends Service
*
* @param int $feedId the id of the feed that should be deleted
* @param string $userId the name of the user for security reasons
+ *
* @throws ServiceNotFoundException when feed does not exist
*/
public function markDeleted($feedId, $userId)
@@ -421,6 +422,7 @@ class FeedService extends Service
*
* @param int $feedId the id of the feed that should be restored
* @param string $userId the name of the user for security reasons
+ *
* @throws ServiceNotFoundException when feed does not exist
*/
public function unmarkDeleted($feedId, $userId)
@@ -471,13 +473,14 @@ class FeedService extends Service
* @param $feedId
* @param $userId
* @param $diff an array containing the fields to update, e.g.:
- * [
- * 'ordering' => 1,
- * 'fullTextEnabled' => true,
- * 'pinned' => true,
- * 'updateMode' => 0,
- * 'title' => 'title'
- * ]
+ * [
+ * 'ordering' => 1,
+ * 'fullTextEnabled' => true,
+ * 'pinned' => true,
+ * 'updateMode' => 0,
+ * 'title' => 'title'
+ * ]
+ *
* @throws ServiceNotFoundException if feed does not exist
*/
public function patch($feedId, $userId, $diff = [])
diff --git a/lib/Utility/PicoFeedClientFactory.php b/lib/Utility/PicoFeedClientFactory.php
deleted file mode 100644
index 046224919..000000000
--- a/lib/Utility/PicoFeedClientFactory.php
+++ /dev/null
@@ -1,42 +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\Utility;
-
-use \PicoFeed\Config\Config;
-use \PicoFeed\Client\Client;
-
-class PicoFeedClientFactory
-{
-
- private $config;
-
- public function __construct(Config $config)
- {
- $this->config = $config;
- }
-
-
- /**
- * Returns a new instance of an PicoFeed Http client
- *
- * @return \PicoFeed\Client instance
- */
- public function build()
- {
- $client = Client::getInstance();
- $client->setConfig($this->config);
- return $client;
- }
-}
diff --git a/lib/Utility/PicoFeedFaviconFactory.php b/lib/Utility/PicoFeedFaviconFactory.php
deleted file mode 100644
index 09a1b76c8..000000000
--- a/lib/Utility/PicoFeedFaviconFactory.php
+++ /dev/null
@@ -1,40 +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\Utility;
-
-use \PicoFeed\Config\Config;
-use \PicoFeed\Reader\Favicon;
-
-class PicoFeedFaviconFactory
-{
-
- private $config;
-
- public function __construct(Config $config)
- {
- $this->config = $config;
- }
-
-
- /**
- * Returns a new instance of an PicoFeed Http client
- *
- * @return \PicoFeed\Favicon instance
- */
- public function build()
- {
- return new Favicon($this->config);
- }
-}
diff --git a/lib/Utility/PsrLogger.php b/lib/Utility/PsrLogger.php
new file mode 100644
index 000000000..5d9a2529b
--- /dev/null
+++ b/lib/Utility/PsrLogger.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Nextcloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Sean Molenaar <sean@seanmolenaar.eu>
+ * @copyright 2018 Sean Molenaar
+ */
+
+namespace OCA\News\Utility;
+
+use \OCP\ILogger;
+
+/**
+ * This is a wrapper to make OC\Log conform to Psr\Log\LoggerInterface
+ *
+ * @package OCA\News\Utility
+ */
+class PsrLogger implements \Psr\Log\LoggerInterface
+{
+ private $logger;
+ private $appName;
+
+ /**
+ * PsrLogger constructor.
+ *
+ * @param ILogger $logger The logger
+ * @param string $appName Name of the app
+ */
+ public function __construct(ILogger $logger, $appName)
+ {
+ $this->logger = $logger;
+ $this->appName = $appName;
+ }
+
+ public function logException($exception, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->logException($exception, $context);
+ }
+
+ public function emergency($message, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->emergency($message, $context);
+ }
+
+ public function alert($message, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->alert($message, $context);
+ }
+
+ public function critical($message, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->critical($message, $context);
+ }
+
+ public function error($message, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->error($message, $context);
+ }
+
+ public function warning($message, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->warning($message, $context);
+ }
+
+ public function notice($message, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->notice($message, $context);
+ }
+
+ public function info($message, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->info($message, $context);
+ }
+
+ public function debug($message, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->debug($message, $context);
+ }
+
+ public function log($level, $message, array $context = [])
+ {
+ $context['app'] = $this->appName;
+ $this->logger->log($level, $message, $context);
+ }
+}
diff --git a/tests/Unit/Config/ConfigTest.php b/tests/Unit/Config/ConfigTest.php
index 992453cca..1d1bd0ed6 100644
--- a/tests/Unit/Config/ConfigTest.php
+++ b/tests/Unit/Config/ConfigTest.php
@@ -29,7 +29,7 @@ class ConfigTest extends TestCase
public function setUp()
{
- $this->logger = $this->getMockBuilder(ILogger::class)
+ $this->logger = $this->getMockBuilder('OCA\News\Utility\PsrLogger')
->disableOriginalConstructor()
->getMock();
$this->fileSystem = $this->getMockBuilder(Folder::class)->getMock();
diff --git a/tests/Unit/Fetcher/FeedFetcherTest.php b/tests/Unit/Fetcher/FeedFetcherTest.php
index 36eaefa1e..f6ef47602 100644
--- a/tests/Unit/Fetcher/FeedFetcherTest.php
+++ b/tests/Unit/Fetcher/FeedFetcherTest.php
@@ -13,13 +13,15 @@
namespace OCA\News\Tests\Unit\Fetcher;
-use \OCA\News\Db\Item;
+use FeedIo\Feed\Item\MediaInterface;
use \OCA\News\Db\Feed;
+use \OCA\News\Db\Item;
use OCA\News\Fetcher\FeedFetcher;
use OCA\News\Utility\PicoFeedFaviconFactory;
use OCA\News\Utility\Time;
use OCP\Http\Client\IClientService;
use OCP\IL10N;
+
use PHPUnit\Framework\TestCase;
use PicoFeed\Client\Client;
use PicoFeed\Parser\Parser;
@@ -27,403 +29,453 @@ use PicoFeed\Processor\ItemPostProcessor;
use PicoFeed\Reader\Favicon;
use PicoFeed\Reader\Reader;
-
+/**
+ * Class FeedFetcherTest
+ *
+ * @package OCA\News\Tests\Unit\Fetcher
+ */
class FeedFetcherTest extends TestCase
{
-
- private $fetcher;
- private $parser;
- private $reader;
- private $client;
- private $faviconFetcher;
- private $parsedFeed;
- private $faviconFactory;
- private $l10n;
- private $url;
- private $time;
- private $item;
- private $content;
- private $encoding;
+ /**
+ * The class to test
+ *
+ * @var FeedFetcher
+ */
+ private $_fetcher;
+
+ /**
+ * Feed reader
+ *
+ * @var \FeedIo\FeedIo
+ */
+ private $_reader;
+
+ /**
+ * Feed reader result
+ *
+ * @var \FeedIo\Reader\Result
+ */
+ private $_result;
+
+ /**
+ * Feed reader result object
+ *
+ * @var \FeedIo\Adapter\ResponseInterface
+ */
+ private $_response;
+
+ private $_favicon;
+ private $_l10n;
+ private $_url;
+ private $_time;
+ private $_item_mock;
+ private $_feed_mock;
+ private $_encoding;
// items
- private $permalink;
- private $title;
- private $guid;
- private $pub;
- private $updated;
- private $body;
- private $author;
- private $enclosureLink;
- private $rtl;
- private $language;
+ private $_permalink;
+ private $_title;
+ private $_guid;
+ private $_pub;
+ private $_updated;
+ private $_body;
+ private $_author;
+ private $_enclosure;
+ private $_rtl;
+ private $_language;
// feed
- private $feedTitle;
- private $feedLink;
- private $feedImage;
- private $webFavicon;
- private $modified;
- private $etag;
- private $location;
- private $feedLanguage;
+ private $_feed_title;
+ private $_feed_link;
+ private $_feed_image;
+ private $_web_favicon;
+ private $_modified;
+ private $_location;
protected function setUp()
{
- $this->l10n = $this->getMockBuilder(IL10N::class)
+ $this->_l10n = $this->getMockBuilder(\OCP\IL10N::class)
->disableOriginalConstructor()
->getMock();
- $this->reader = $this->getMockBuilder(Reader::class)
+ $this->_reader = $this->getMockBuilder(\FeedIo\FeedIo::class)
->disableOriginalConstructor()
->getMock();
- $this->parser = $this->getMockBuilder(Parser::class)
+ $this->_favicon = $this->getMockBuilder(\Favicon\Favicon::class)
->disableOriginalConstructor()
->getMock();
- $this->client = $this->getMockBuilder(Client::class)
+ $this->_result = $this->getMockBuilder(\FeedIo\Reader\Result::class)
->disableOriginalConstructor()
->getMock();
- $this->parsedFeed = $this->getMockBuilder(\PicoFeed\Parser\Feed::class)
+ $this->_response = $this->getMockBuilder(\FeedIo\Adapter\ResponseInterface::class)
->disableOriginalConstructor()
->getMock();
- $this->item = $this->getMockBuilder(\PicoFeed\Parser\Item::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->faviconFetcher = $this->getMockBuilder(Favicon::class)
+
+ $this->_item_mock = $this->getMockBuilder(\FeedIo\Feed\ItemInterface::class)
->disableOriginalConstructor()
->getMock();
- $this->faviconFactory = $this->getMockBuilder(PicoFeedFaviconFactory::class)
+
+ $this->_feed_mock = $this->getMockBuilder(\FeedIo\FeedInterface::class)
->disableOriginalConstructor()
->getMock();
- $this->time = 2323;
- $timeFactory = $this->getMockBuilder(Time::class)
+ $this->_time = 2323;
+ $timeFactory = $this->getMockBuilder(\OCA\News\Utility\Time::class)
->disableOriginalConstructor()
->getMock();
$timeFactory->expects($this->any())
->method('getTime')
- ->will($this->returnValue($this->time));
- $postProcessor = $this->getMockBuilder(ItemPostProcessor::class)
+ ->will($this->returnValue($this->_time));
+ $clientService = $this->getMockBuilder(IClientService::class)
->getMock();
- $this->parser->expects($this->any())
- ->method('getItemPostProcessor')
- ->will($this->returnValue($postProcessor));
- $clientService = $this->getMockBuilder(IClientService::class)
- ->getMock();
- $this->fetcher = new FeedFetcher(
- $this->reader,
- $this->faviconFactory,
- $this->l10n,
+ $this->_fetcher = new FeedFetcher(
+ $this->_reader,
+ $this->_favicon,
+ $this->_l10n,
$timeFactory,
$clientService
);
- $this->url = 'http://tests';
-
- $this->permalink = 'http://permalink';
- $this->title = 'my&amp;lt;&apos; title';
- $this->guid = 'hey guid here';
- $this->body = 'let the bodies hit the floor <a href="test">test</a>';
- $this->body2 = 'let the bodies hit the floor ' .
- '<a target="_blank" href="test">test</a>';
- $this->pub = 23111;
- $this->updated = 23444;
- $this->author = '&lt;boogieman';
- $this->enclosureLink = 'http://enclosure.you';
-
- $this->feedTitle = '&lt;a&gt;&amp;its a&lt;/a&gt; title';
- $this->feedLink = 'http://goatse';
- $this->feedImage = '/an/image';
- $this->webFavicon = 'http://anon.google.com';
- $this->authorMail = 'doe@joes.com';
- $this->modified = 3;
- $this->etag = 'yo';
- $this->content = 'some content';
- $this->encoding = 'UTF-8';
- $this->language = 'de-DE';
- $this->feedLanguage = 'de-DE';
+ $this->_url = 'http://tests';
+
+ $this->_permalink = 'http://permalink';
+ $this->_title = 'my&amp;lt;&apos; title';
+ $this->_guid = 'hey guid here';
+ $this->_body = 'let the bodies hit the floor <a href="test">test</a>';
+ $this->_pub = 23111;
+ $this->_updated = 23444;
+ $this->_author = '&lt;boogieman';
+ $this->_enclosure = 'http://enclosure.you';
+
+ $this->_feed_title = '&lt;a&gt;&amp;its a&lt;/a&gt; title';
+ $this->_feed_link = 'http://tests';
+ $this->_feed_image = '/an/image';
+ $this->_web_favicon = 'http://anon.google.com';
+ $this->_modified = $this->getMockBuilder('\DateTime')->getMock();
+ $this->_modified->expects($this->any())
+ ->method('getTimestamp')
+ ->will($this->returnValue(3));
+ $this->_encoding = 'UTF-8';
+ $this->_language = 'de-DE';
+ $this->_rtl = false;
}
-
public function testCanHandle()
{
$url = 'google.de';
- $this->assertTrue($this->fetcher->canHandle($url));
+ $this->assertTrue($this->_fetcher->canHandle($url));
}
- private function setUpReader($url='', $modified=true, $noParser=false)
+ public function testNoFetchIfNotModified()
{
- $this->reader->expects($this->once())
- ->method('discover')
- ->with($this->equalTo($url))
- ->will($this->returnValue($this->client));
- $this->client->expects($this->once())
- ->method('isModified')
- ->will($this->returnValue($modified));
+ $this->_setUpReader($this->_url, false);;
+ $result = $this->_fetcher->fetch($this->_url, false);
+ $this->assertSame([null, null], $result);
+ }
- if (!$modified) {
- $this->reader->expects($this->never())
- ->method('getParser');
- } else {
- $this->client->expects($this->once())
- ->method('getLastModified')
- ->will($this->returnValue($this->modified));
- $this->client->expects($this->once())
- ->method('getEtag')
- ->will($this->returnValue($this->etag));
- $this->client->expects($this->once())
- ->method('getUrl')
- ->will($this->returnValue($this->location));
- $this->client->expects($this->once())
- ->method('getContent')
- ->will($this->returnValue($this->content));
- $this->client->expects($this->once())
- ->method('getEncoding')
- ->will($this->returnValue($this->encoding));
-
- if ($noParser) {
- $this->reader->expects($this->once())
- ->method('getParser')
- ->will(
- $this->throwException(
- new \PicoFeed\Reader\SubscriptionNotFoundException()
- )
- );
- } else {
- $this->reader->expects($this->once())
- ->method('getParser')
- ->with(
- $this->equalTo($this->location),
- $this->equalTo($this->content),
- $this->equalTo($this->encoding)
- )
- ->will($this->returnValue($this->parser));
- }
-
- $this->parser->expects($this->once())
- ->method('execute')
- ->will($this->returnValue($this->parsedFeed));
- }
+ public function testFetch()
+ {
+ $this->_setUpReader($this->_url);
+ $item = $this->_createItem();
+ $feed = $this->_createFeed();
+ $this->_mockIterator($this->_feed_mock, [$this->_item_mock]);
+ $result = $this->_fetcher->fetch($this->_url, false);
+ $this->assertEquals([$feed, [$item]], $result);
}
- private function expectFeed($method, $return, $count = 1)
+ public function testAudioEnclosure()
{
- $this->parsedFeed->expects($this->exactly($count))
- ->method($method)
- ->will($this->returnValue($return));
- }
+ $this->_setUpReader($this->_url);
+ $item = $this->_createItem('audio/ogg');
+ $feed = $this->_createFeed();
+ $this->_mockIterator($this->_feed_mock, [$this->_item_mock]);
+ $result = $this->_fetcher->fetch($this->_url, false);
- private function expectItem($method, $return, $count = 1)
- {
- $this->item->expects($this->exactly($count))
- ->method($method)
- ->will($this->returnValue($return));
+ $this->assertEquals([$feed, [$item]], $result);
}
- private function createItem($enclosureType=null)
+ public function testVideoEnclosure()
{
- $this->expectItem('getUrl', $this->permalink);
- $this->expectItem('getTitle', $this->title);
- $this->expectItem('getId', $this->guid);
- $this->expectItem('getContent', $this->body);
+ $this->_setUpReader($this->_url);
+ $item = $this->_createItem('video/ogg');
+ $feed = $this->_createFeed();
+ $this->_mockIterator($this->_feed_mock, [$this->_item_mock]);
+ $result = $this->_fetcher->fetch($this->_url, false);
- $item = new Item();
+ $this->assertEquals([$feed, [$item]], $result);
+ }
- date_default_timezone_set('America/Los_Angeles');
+ public function testFavicon()
+ {
+ $this->_setUpReader($this->_url);
- $pubdate = \Datetime::createFromFormat('U', $this->pub);
- $this->expectItem('getPublishedDate', $pubdate);
- $item->setPubDate($this->pub);
+ $feed = $this->_createFeed('de-DE', true);
+ $item = $this->_createItem();
+ $this->_mockIterator($this->_feed_mock, [$this->_item_mock]);
+ $result = $this->_fetcher->fetch($this->_url, true);
- $update = \Datetime::createFromFormat('U', $this->updated);
- $this->expectItem('getUpdatedDate', $update);
- $item->setUpdatedDate($this->updated);
+ $this->assertEquals([$feed, [$item]], $result);
+ }
- $item->setStatus(0);
- $item->setUnread(true);
- $item->setUrl($this->permalink);
- $item->setTitle('my<\' title');
- $item->setGuid($this->guid);
- $item->setGuidHash($this->guid);
- $item->setBody($this->body);
- $item->setRtl(false);
+ public function testNoFavicon()
+ {
+ $this->_setUpReader($this->_url);
- $this->expectItem('getAuthor', $this->author);
- $item->setAuthor(html_entity_decode($this->author));
+ $feed = $this->_createFeed(false);
- if($enclosureType === 'audio/ogg' || $enclosureType === 'video/ogg') {
- $this->expectItem('getEnclosureUrl', $this->enclosureLink);
- $this->expectItem('getEnclosureType', $enclosureType);
+ $this->_favicon->expects($this->never())
+ ->method('get');
- $item->setEnclosureMime($enclosureType);
- $item->setEnclosureLink($this->enclosureLink);
- }
- $item->generateSearchIndex();
+ $item = $this->_createItem();
+ $this->_mockIterator($this->_feed_mock, [$this->_item_mock]);
+ $result = $this->_fetcher->fetch($this->_url, false);
- return $item;
+ $this->assertEquals([$feed, [$item]], $result);
}
+ public function testRtl()
+ {
+ $this->_setUpReader($this->_url);
+ $this->_createFeed('he-IL');
+ $this->_createItem();
+ $this->_mockIterator($this->_feed_mock, [$this->_item_mock]);
+ list($feed, $items) = $this->_fetcher->fetch(
+ $this->_url, false
+ );
+ $this->assertTrue($items[0]->getRtl());
+ }
- private function createFeed($hasFavicon=false)
+ public function testRssPubDate()
{
- $this->expectFeed('getTitle', $this->feedTitle);
- $this->expectFeed('getSiteUrl', $this->feedLink);
+ $this->_setUpReader($this->_url);
+ $this->_createFeed('he-IL');
+ $this->_createItem();
- $feed = new Feed();
- $feed->setTitle('&its a title');
- $feed->setUrl($this->url);
- $feed->setLink($this->feedLink);
- $feed->setAdded($this->time);
- $feed->setHttpLastModified($this->modified);
- $feed->setHttpEtag($this->etag);
- $feed->setLocation($this->location);
-
- if($hasFavicon) {
- $this->faviconFactory->expects($this->once())
- ->method('build')
- ->will($this->returnValue($this->faviconFetcher));
- $this->faviconFetcher->expects($this->once())
- ->method('find')
- ->with($this->equalTo($this->feedLink))
- ->will($this->returnValue($this->webFavicon));
- $feed->setFaviconLink($this->webFavicon);
- }
+ $this->_item_mock->expects($this->exactly(2))
+ ->method('getValue')
+ ->will($this->returnValueMap([
+ ['pubDate', '2018-03-27T19:50:29Z'],
+ ['published', NULL],
+ ]));
- return $feed;
- }
- public function testNoFetchIfNotModified()
- {
- $this->setUpReader($this->url, false);;
- $result = $this->fetcher->fetch($this->url, false);
+ $this->_mockIterator($this->_feed_mock, [$this->_item_mock]);
+ list($feed, $items) = $this->_fetcher->fetch($this->_url, false);
+ $this->assertSame($items[0]->getPubDate(), 1522180229);
}
- public function testFetch()
+ public function testAtomPubDate()
{
- $this->setUpReader($this->url);
- $item = $this->createItem();
- $feed = $this->createFeed();
- $this->expectFeed('getItems', [$this->item]);
- $result = $this->fetcher->fetch($this->url, false);
-
- $this->assertEquals([$feed, [$item]], $result);
- }
+ $this->_setUpReader($this->_url);
+ $this->_createFeed('he-IL');
+ $this->_createItem();
+ $this->_item_mock->expects($this->exactly(3))
+ ->method('getValue')
+ ->will($this->returnValueMap([
+ ['pubDate', NULL],
+ ['published', '2018-02-27T19:50:29Z'],
+ ]));
- public function testAudioEnclosure()
- {
- $this->setUpReader($this->url);
- $item = $this->createItem('audio/ogg');
- $feed = $this->createFeed();
- $this->expectFeed('getItems', [$this->item]);
- $result = $this->fetcher->fetch($this->url, false);
- $this->assertEquals([$feed, [$item]], $result);
+ $this->_mockIterator($this->_feed_mock, [$this->_item_mock]);
+ list($feed, $items) = $this->_fetcher->fetch($this->_url, false);
+ $this->assertSame($items[0]->getPubDate(), 1519761029);
}
-
- public function testVideoEnclosure()
+ /**
+ * Mock an iteration option on an existing mock
+ *
+ * @param object $iteratorMock The mock to enhance
+ * @param array $items The items to make available
+ *
+ * @return mixed
+ */
+ private function _mockIterator($iteratorMock, array $items)
{
- $this->setUpReader($this->url);
- $item = $this->createItem('video/ogg');
- $feed = $this->createFeed();
- $this->expectFeed('getItems', [$this->item]);
- $result = $this->fetcher->fetch($this->url, false);
-
- $this->assertEquals([$feed, [$item]], $result);
+ $iteratorData = new \stdClass();
+ $iteratorData->array = $items;
+ $iteratorData->position = 0;
+
+ $iteratorMock->expects($this->any())
+ ->method('rewind')
+ ->will(
+ $this->returnCallback(
+ function () use ($iteratorData) {
+ $iteratorData->position = 0;
+ }
+ )
+ );
+
+ $iteratorMock->expects($this->any())
+ ->method('current')
+ ->will(
+ $this->returnCallback(
+ function () use ($iteratorData) {
+ return $iteratorData->array[$iteratorData->position];
+ }
+ )
+ );
+
+ $iteratorMock->expects($this->any())
+ ->method('key')
+ ->will(
+ $this->returnCallback(
+ function () use ($iteratorData) {
+ return $iteratorData->position;
+ }
+ )
+ );
+
+ $iteratorMock->expects($this->any())
+ ->method('next')
+ ->will(
+ $this->returnCallback(
+ function () use ($iteratorData) {
+ $iteratorData->position++;
+ }
+ )
+ );
+
+ $iteratorMock->expects($this->any())
+ ->method('valid')
+ ->will(
+ $this->returnCallback(
+ function () use ($iteratorData) {
+ return isset($iteratorData->array[$iteratorData->position]);
+ }
+ )
+ );
+
+ $iteratorMock->expects($this->any())
+ ->method('count')
+ ->will(
+ $this->returnCallback(
+ function () use ($iteratorData) {
+ return sizeof($iteratorData->array);
+ }
+ )
+ );
+
+ return $iteratorMock;
}
-
-
- public function testFavicon()
+ private function _setUpReader($url='', $modified=true)
{
- $this->setUpReader($this->url);
+ $this->_reader->expects($this->once())
+ ->method('readSince')
+ ->with($this->equalTo($url))
+ ->will($this->returnValue($this->_result));
+ $this->_result->expects($this->once())
+ ->method('getResponse')
+ ->will($this->returnValue($this->_response));
+ $this->_response->expects($this->once())
+ ->method('isModified')
+ ->will($this->returnValue($modified));
- $feed = $this->createFeed(true);
- $item = $this->createItem();
- $this->expectFeed('getItems', [$this->item]);
- $result = $this->fetcher->fetch($this->url);
+ if (!$modified) {
+ $this->_result->expects($this->never())
+ ->method('getUrl');
+ } else {
+ $this->_result->expects($this->once())
+ ->method('getUrl')
+ ->will($this->returnValue($this->_location));
+ $this->_result->expects($this->once())
+ ->method('getFeed')
+ ->will($this->returnValue($this->_feed_mock));
+ }
- $this->assertEquals([$feed, [$item]], $result);
}
- public function testFullText()
+ private function _expectFeed($method, $return, $count = 1)
{
- $this->setUpReader($this->url);
-
- $feed = $this->createFeed();
- $item = $this->createItem();
- $this->parser->expects($this->once())
- ->method('enableContentGrabber');
- $this->expectFeed('getItems', [$this->item]);
- $this->fetcher->fetch($this->url, false, null, null, true);
+ $this->_feed_mock->expects($this->exactly($count))
+ ->method($method)
+ ->will($this->returnValue($return));
}
+ private function _expectItem($method, $return, $count = 1)
+ {
+ $this->_item_mock->expects($this->exactly($count))
+ ->method($method)
+ ->will($this->returnValue($return));
+ }
- public function testNoFavicon()
+
+ private function _createItem($enclosureType=null)
{
- $this->setUpReader($this->url);
+ $this->_expectItem('getLink', $this->_permalink);
+ $this->_expectItem('getTitle', $this->_title);
+ $this->_expectItem('getPublicId', $this->_guid);
+ $this->_expectItem('getDescription', $this->_body);
+ $this->_expectItem('getLastModified', $this->_modified, 2);
+ $this->_expectItem('getAuthor', $this->_author);
- $feed = $this->createFeed(false);
+ $item = new Item();
- $this->faviconFetcher->expects($this->never())
- ->method('find');
+ $item->setStatus(0);
+ $item->setUnread(true);
+ $item->setUrl($this->_permalink);
+ $item->setTitle('my<\' title');
+ $item->setGuid($this->_guid);
+ $item->setGuidHash($this->_guid);
+ $item->setBody($this->_body);
+ $item->setRtl(false);
+ $item->setLastModified(3);
+ $item->setPubDate(3);
+ $item->setAuthor(html_entity_decode($this->_author));
+
+ if ($enclosureType === 'audio/ogg' || $enclosureType === 'video/ogg') {
+ $media = $this->getMockbuilder(MediaInterface::class)->getMock();
+ $media->expects($this->once())
+ ->method('getType')
+ ->will($this->returnValue('sounds'));
+ $media2 = $this->getMockbuilder(MediaInterface::class)->getMock();
+ $media2->expects($this->exactly(2))
+ ->method('getType')
+ ->will($this->returnValue($enclosureType));
+ $media2->expects($this->once())
+ ->method('getUrl')
+ ->will($this->returnValue($this->_enclosure));
+ $this->_expectItem('hasMedia', true);
+ $this->_expectItem('getMedias', [$media, $media2]);
- $item = $this->createItem();
- $this->expectFeed('getItems', [$this->item]);
- $result = $this->fetcher->fetch($this->url, false);
+ $item->setEnclosureMime($enclosureType);
+ $item->setEnclosureLink($this->_enclosure);
+ }
+ $item->generateSearchIndex();
- $this->assertEquals([$feed, [$item]], $result);
+ return $item;
}
- public function testRtl()
+ private function _createFeed($lang='de-DE', $favicon=false)
{
- $this->setUpReader($this->url);
- $this->expectFeed('getLanguage', 'he-IL');
- $this->expectItem('getLanguage', '');
- $feed = $this->createFeed();
- $item = $this->createItem(null);
- $this->expectFeed('getItems', [$this->item]);
- list($feed, $items) = $this->fetcher->fetch(
- $this->url, false, null,
- null, true
- );
- $this->assertTrue($items[0]->getRtl());
- }
+ $this->_expectFeed('getTitle', $this->_feed_title);
+ $this->_expectFeed('getLink', $this->_feed_link);
+ $this->_expectFeed('getLastModified', $this->_modified);
+ $this->_expectFeed('getLanguage', $lang);
+ $feed = new Feed();
- public function testRtlItemPrecedence()
- {
- $this->setUpReader($this->url);
- $this->expectFeed('getLanguage', 'de-DE');
- $this->expectItem('getLanguage', 'he-IL');
-
- $feed = $this->createFeed();
- $item = $this->createItem(null);
- $this->expectFeed('getItems', [$this->item]);
- list($feed, $items) = $this->fetcher->fetch(
- $this->url, false, null,
- null, true
- );
- $this->assertTrue($items[0]->getRtl());
- }
+ $feed->setTitle('&its a title');
+ $feed->setLink($this->_feed_link);
+ $feed->setUrl($this->_url);
+ $feed->setLastModified(3);
+ $feed->setAdded($this->_time);
+ if ($favicon) {
+ $feed->setFaviconLink('http://anon.google.com');
+ $this->_favicon->expects($this->exactly(1))
+ ->method('get')
+ ->with($this->equalTo($this->_feed_link))
+ ->will($this->returnValue($this->_web_favicon));
+ } else {
+ $this->_favicon->expects($this->never())
+ ->method('get');
+ }
- public function testNegativeRtlItemPrecedence()
- {
- $this->setUpReader($this->url);
- $this->expectFeed('getLanguage', 'he-IL');
- $this->expectItem('getLanguage', 'de-DE');
-
- $feed = $this->createFeed();
- $item = $this->createItem(null);
- $this->expectFeed('getItems', [$this->item]);
- list($feed, $items) = $this->fetcher->fetch(
- $this->url, false, null,
- null, true
- );
- $this->assertFalse($items[0]->getRtl());
+ return $feed;
}
-
}
diff --git a/tests/Unit/Service/FeedServiceTest.php b/tests/Unit/Service/FeedServiceTest.php
index 8cdc50c88..9b0c50b20 100644
--- a/tests/Unit/Service/FeedServiceTest.php
+++ b/tests/Unit/Service/FeedServiceTest.php
@@ -311,7 +311,8 @@ class FeedServiceTest extends TestCase
$this->equalTo('http://test'),
$this->equalTo(false),
$this->equalTo(3),
- $this->equalTo(4)
+ $this->equalTo(''),
+ $this->equalTo('')
)
->will($this->returnValue($fetchReturn));
$this->feedMapper->expects($this->at(1))
@@ -377,7 +378,8 @@ class FeedServiceTest extends TestCase
$this->equalTo('http://test'),
$this->equalTo(false),
$this->equalTo(3),
- $this->equalTo(4)
+ $this->equalTo(''),
+ $this->equalTo('')
)
->will($this->returnValue($fetchReturn));
$this->feedMapper->expects($this->at(1))
@@ -635,7 +637,6 @@ class FeedServiceTest extends TestCase
$feed = new Feed();
$feed->setId(3);
$feed->setUrl('https://goo.com');
- $feed->setHttpEtag('abc');
$feed->setHttpLastModified(123);
$feed->setFullTextEnabled(true);
@@ -654,9 +655,7 @@ class FeedServiceTest extends TestCase
->with(
$this->equalTo($feed->getUrl()),
$this->equalTo(false),
- $this->equalTo($feed->getHttpLastModified()),
- $this->equalTo($feed->getHttpEtag()),
- $this->equalTo($feed->getFullTextEnabled())
+ $this->equalTo($feed->getHttpLastModified())
)
->will($this->throwException($ex));