summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernhard Posselt <nukeawhale@gmail.com>2013-09-11 20:31:58 +0200
committerBernhard Posselt <nukeawhale@gmail.com>2013-09-12 01:00:32 +0200
commit00c6e040deec9c3998ab679dcb84fc46ae72d2ac (patch)
tree88a7ba6ab686b8a57d051f268e467773c8573059
parent8ca8695fbe55599b1212de332853ebb85442b226 (diff)
removed google importer on the serverside, add importer for articles
-rw-r--r--appinfo/routes.php4
-rw-r--r--businesslayer/feedbusinesslayer.php71
-rw-r--r--controller/feedcontroller.php13
-rw-r--r--db/feed.php1
-rw-r--r--db/item.php35
-rw-r--r--dependencyinjection/dicontainer.php2
-rw-r--r--templates/part.settings.php3
-rw-r--r--tests/unit/businesslayer/FeedBusinessLayerTest.php69
-rw-r--r--tests/unit/controller/FeedControllerTest.php35
-rw-r--r--tests/unit/db/FeedTest.php7
-rw-r--r--tests/unit/db/ItemTest.php38
-rw-r--r--tests/unit/utility/ImportParserTest.php191
-rw-r--r--utility/feedfetcher.php2
-rw-r--r--utility/importparser.php97
14 files changed, 200 insertions, 368 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php
index 90c5f2378..7f287d18c 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -140,10 +140,10 @@ $this->create('news_feeds_read', '/feeds/{feedId}/read')->post()->action(
}
);
-$this->create('news_feeds_import_googlereader', '/feeds/import/googlereader')
+$this->create('news_feeds_import_articles', '/feeds/import/articles')
->post()->action(
function($params){
- App::main('FeedController', 'importGoogleReader', $params,
+ App::main('FeedController', 'importArticles', $params,
new DIContainer());
}
);
diff --git a/businesslayer/feedbusinesslayer.php b/businesslayer/feedbusinesslayer.php
index 034209add..cc7324251 100644
--- a/businesslayer/feedbusinesslayer.php
+++ b/businesslayer/feedbusinesslayer.php
@@ -30,11 +30,11 @@ use \OCA\AppFramework\Utility\TimeFactory;
use \OCA\AppFramework\Core\API;
use \OCA\News\Db\Feed;
+use \OCA\News\Db\Item;
use \OCA\News\Db\FeedMapper;
use \OCA\News\Db\ItemMapper;
use \OCA\News\Utility\Fetcher;
use \OCA\News\Utility\FetcherException;
-use \OCA\News\Utility\ImportParser;
use \OCA\News\Utility\ArticleEnhancer\Enhancer;
@@ -44,14 +44,12 @@ class FeedBusinessLayer extends BusinessLayer {
private $itemMapper;
private $api;
private $timeFactory;
- private $importParser;
private $autoPurgeMinimumInterval;
private $enhancer;
public function __construct(FeedMapper $feedMapper, Fetcher $feedFetcher,
ItemMapper $itemMapper, API $api,
TimeFactory $timeFactory,
- ImportParser $importParser,
$autoPurgeMinimumInterval,
Enhancer $enhancer){
parent::__construct($feedMapper);
@@ -59,7 +57,6 @@ class FeedBusinessLayer extends BusinessLayer {
$this->itemMapper = $itemMapper;
$this->api = $api;
$this->timeFactory = $timeFactory;
- $this->importParser = $importParser;
$this->autoPurgeMinimumInterval = $autoPurgeMinimumInterval;
$this->enhancer = $enhancer;
}
@@ -226,41 +223,61 @@ class FeedBusinessLayer extends BusinessLayer {
/**
- * Imports the google reader json
+ * Import articles
* @param array $json the array with json
* @param string userId the username
- * @return Feed the created feed
+ * @return Feed if one had to be created for nonexistent feeds
*/
- public function importGoogleReaderJSON($json, $userId) {
- $url = 'http://owncloud/googlereader';
+ public function importArticles($json, $userId) {
+ $url = 'http://owncloud/nofeed';
$urlHash = md5($url);
- try {
- $feed = $this->mapper->findByUrlHash($urlHash, $userId);
- } catch(DoesNotExistException $ex) {
- $feed = new Feed();
- $feed->setUserId($userId);
- $feed->setUrlHash($urlHash);
- $feed->setUrl($url);
- $feed->setTitle('Google Reader');
- $feed->setAdded($this->timeFactory->getTime());
- $feed->setFolderId(0);
- $feed->setPreventUpdate(true);
- $feed = $this->mapper->insert($feed);
+ // build assoc array for fast access
+ $feeds = $this->findAll($userId);
+ $feedsDict = array();
+ foreach($feeds as $feed) {
+ $feedsDict[$feed->getLink()] = $feed;
}
- foreach($this->importParser->parse($json) as $item) {
- $item->setFeedId($feed->getId());
+ // loop over all items and get the corresponding feed
+ // if the feed does not exist, create a seperate feed for them
+ foreach ($json as $entry) {
+ $item = Item::fromImport($entry);
+ $item->setLastModified($this->timeFactory->getTime());
+ $feedLink = $entry['feedLink']; // this is not set on the item yet
+
+ if(array_key_exists($feedLink, $feedsDict)) {
+ $feed = $feedsDict[$feedLink];
+ $item->setFeedId($feed->getId());
+ } elseif(array_key_exists($url, $feedsDict)) {
+ $feed = $feedsDict[$url];
+ $item->setFeedId($feed->getId());
+ } else {
+ $feed = new Feed();
+ $feed->setUserId($userId);
+ $feed->setLink($url);
+ $feed->setUrl($url);
+ $feed->setTitle($this->api->getTrans()->t('Articles without feed'));
+ $feed->setAdded($this->timeFactory->getTime());
+ $feed->setFolderId(0);
+ $feed->setPreventUpdate(true);
+ $feed = $this->mapper->insert($item);
+
+ $item->setFeedId($feed->getId());
+ $feedsDict[$feed->getLink()] = $feed;
+ }
+
try {
- $this->itemMapper->findByGuidHash(
- $item->getGuidHash(), $item->getFeedId(), $userId);
- } catch(DoesNotExistException $ex) {
+ $this->itemMapper->findByGuidHash($item->getGuidHash(),
+ $feed->getId(), $userId);
+ } catch(DoesNotExistException $ex){
$this->itemMapper->insert($item);
}
}
- return $this->mapper->findByUrlHash($urlHash, $userId);
-
+ if($feed) {
+ return $this->mapper->findByUrlHash($urlHash, $userId);
+ }
}
diff --git a/controller/feedcontroller.php b/controller/feedcontroller.php
index 69b713914..762859627 100644
--- a/controller/feedcontroller.php
+++ b/controller/feedcontroller.php
@@ -227,18 +227,21 @@ class FeedController extends Controller {
* @IsSubAdminExemption
* @Ajax
*/
- public function importGoogleReader() {
+ public function importArticles() {
$json = $this->params('json');
$userId = $this->api->getUserId();
- $feed = $this->feedBusinessLayer->importGoogleReaderJSON($json, $userId);
+ $feed = $this->feedBusinessLayer->importArticles($json, $userId);
+
+ $params = array();
+ if($feed) {
+ $params['feeds'] = array($feed);
+ }
- $params = array(
- 'feeds' => array($feed)
- );
return $this->renderJSON($params);
}
+
/**
* @IsAdminExemption
* @IsSubAdminExemption
diff --git a/db/feed.php b/db/feed.php
index caf0127d6..e84e4489d 100644
--- a/db/feed.php
+++ b/db/feed.php
@@ -78,6 +78,7 @@ class Feed extends Entity implements IAPI {
$url = trim($url);
if(strpos($url, 'http') === 0) {
parent::setLink($url);
+ $this->setUrlHash(md5($url));
}
}
diff --git a/db/item.php b/db/item.php
index c83da572d..5c0472eaf 100644
--- a/db/item.php
+++ b/db/item.php
@@ -40,7 +40,7 @@ class Item extends Entity implements IAPI {
public $enclosureMime;
public $enclosureLink;
public $feedId;
- public $status;
+ public $status = 0;
public $lastModified;
@@ -126,6 +126,32 @@ class Item extends Entity implements IAPI {
}
+ public static function fromImport($import) {
+ $item = new static();
+ $item->setGuid($import['guid']);
+ $item->setUrl($import['url']);
+ $item->setTitle($import['title']);
+ $item->setAuthor($import['author']);
+ $item->setPubDate($import['pubDate']);
+ $item->setBody($import['body']);
+ $item->setEnclosureMime($import['enclosureMime']);
+ $item->setEnclosureLink($import['enclosureLink']);
+ if($import['unread']) {
+ $item->setUnread();
+ } else {
+ $item->setRead();
+ }
+ if($import['starred']) {
+ $item->setStarred();
+ } else {
+ $item->setUnstarred();
+ }
+
+ $item->setFeedId(null);
+ return $item;
+ }
+
+
public function setAuthor($name) {
parent::setAuthor(strip_tags($name));
}
@@ -143,5 +169,12 @@ class Item extends Entity implements IAPI {
}
}
+
+ public function setGuid($guid) {
+ parent::setGuid($guid);
+ $this->setGuidHash(md5($guid));
+ }
+
+
}
diff --git a/dependencyinjection/dicontainer.php b/dependencyinjection/dicontainer.php
index 77e7b4aa6..d73870fb3 100644
--- a/dependencyinjection/dicontainer.php
+++ b/dependencyinjection/dicontainer.php
@@ -57,7 +57,6 @@ use \OCA\News\Utility\Fetcher;
use \OCA\News\Utility\FeedFetcher;
use \OCA\News\Utility\TwitterFetcher;
use \OCA\News\Utility\OPMLExporter;
-use \OCA\News\Utility\ImportParser;
use \OCA\News\Utility\Updater;
use \OCA\News\Utility\SimplePieFileFactory;
@@ -193,7 +192,6 @@ class DIContainer extends BaseContainer {
$c['ItemMapper'],
$c['API'],
$c['TimeFactory'],
- $c['ImportParser'],
$c['autoPurgeMinimumInterval'],
$c['Enhancer']);
});
diff --git a/templates/part.settings.php b/templates/part.settings.php
index 4769ab9cc..0e622b778 100644
--- a/templates/part.settings.php
+++ b/templates/part.settings.php
@@ -43,7 +43,8 @@
<fieldset class="personalblock">
<legend><strong><?php p($l->t('Unread/Starred Articles')); ?></strong></legend>
<input type="file" id="google-upload" name="importgoogle"
- oc-read-file="importGoogleReader($fileContent)"/>
+ accept="application/json"
+ oc-read-file="importGoogleReader($fileContent)"/>
<button title="<?php p($l->t('Import')); ?>"
class="upload-icon svg"
oc-forward-click="{selector:'#google-upload'}">
diff --git a/tests/unit/businesslayer/FeedBusinessLayerTest.php b/tests/unit/businesslayer/FeedBusinessLayerTest.php
index 220b1c980..23bb98c55 100644
--- a/tests/unit/businesslayer/FeedBusinessLayerTest.php
+++ b/tests/unit/businesslayer/FeedBusinessLayerTest.php
@@ -34,7 +34,6 @@ use \OCA\News\Db\Feed;
use \OCA\News\Db\Item;
use \OCA\News\Utility\Fetcher;
use \OCA\News\Utility\FetcherException;
-use \OCA\News\Utility\ImportParser;
class FeedBusinessLayerTest extends \OCA\AppFramework\Utility\TestUtility {
@@ -70,15 +69,12 @@ class FeedBusinessLayerTest extends \OCA\AppFramework\Utility\TestUtility {
$this->itemMapper = $this->getMockBuilder('\OCA\News\Db\ItemMapper')
->disableOriginalConstructor()
->getMock();
- $this->importParser = $this->getMockBuilder('\OCA\News\Utility\ImportParser')
- ->disableOriginalConstructor()
- ->getMock();
$this->enhancer = $this->getMockBuilder('\OCA\News\Utility\ArticleEnhancer\Enhancer')
->disableOriginalConstructor()
->getMock();
$this->feedBusinessLayer = new FeedBusinessLayer($this->feedMapper,
$this->fetcher, $this->itemMapper, $this->api,
- $timeFactory, $this->importParser, $this->autoPurgeMinimumInterval,
+ $timeFactory, $this->autoPurgeMinimumInterval,
$this->enhancer);
$this->user = 'jack';
$response = 'hi';
@@ -423,51 +419,58 @@ class FeedBusinessLayerTest extends \OCA\AppFramework\Utility\TestUtility {
}
- public function testImportGoogleReaderJSON(){
- $url = 'http://owncloud/googlereader';
- $urlHash = md5($url);
+ public function testImportArticles(){
+ $url = 'http://owncloud/nofeed';
$feed = new Feed();
$feed->setId(3);
$feed->setUserId($this->user);
- $feed->setUrlHash($urlHash);
$feed->setUrl($url);
- $feed->setTitle('Google Reader');
+ $feed->setLink($url);
+ $feed->setTitle('Articles without feed');
$feed->setAdded($this->time);
$feed->setFolderId(0);
$feed->setPreventUpdate(true);
- $items = array(new Item());
+ $feeds = array($feed);
+
+ $item = new Item();
+ $item->setFeedId(3);
+ $item->setAuthor('john');
+ $item->setGuid('s');
+ $item->setTitle('hey');
+ $item->setPubDate(333);
+ $item->setBody('come over');
+ $item->setEnclosureMime('mime');
+ $item->setEnclosureLink('lin');
+ $item->setUnread();
+ $item->setUnstarred();
+ $item->setLastModified($this->time);
+
+ $json = $item->toExport(array('feed3' => $feed));
+
+ $items = array($json);
+
+ $this->feedMapper->expects($this->once())
+ ->method('findAllFromUser')
+ ->with($this->equalTo($this->user))
+ ->will($this->returnValue($feeds));
- $this->feedMapper->expects($this->at(0))
- ->method('findByUrlHash')
- ->with($this->equalTo($urlHash),
- $this->equalTo($this->user))
- ->will($this->throwException(new DoesNotExistException('hi')));
- $this->feedMapper->expects($this->at(1))
- ->method('insert')
- ->will($this->returnValue($feed));
- $this->feedMapper->expects($this->at(2))
- ->method('findByUrlHash')
- ->with($this->equalTo($urlHash),
- $this->equalTo($this->user))
- ->will($this->returnValue($feed));
- $this->importParser->expects($this->once())
- ->method('parse')
- ->will($this->returnValue($items));
$this->itemMapper->expects($this->once())
- ->method('findByGuidHash');
- $this->itemMapper->expects($this->never())
- ->method('insert');
+ ->method('findByGuidHash')
+ ->will($this->throwException(new DoesNotExistException('yo')));
+ $this->itemMapper->expects($this->once())
+ ->method('insert')
+ ->with($this->equalTo($item));
- $result = $this->feedBusinessLayer->importGoogleReaderJSON(array(), $this->user);
+ $result = $this->feedBusinessLayer->importArticles($items, $this->user);
- $this->assertEquals($feed, $result);
+ $this->assertEquals(null, $result);
}
- public function testImportGoogleReaderJSONFeedExists(){
+ public function atestImportGoogleReaderJSONFeedExists(){
$url = 'http://owncloud/googlereader';
$urlHash = md5($url);
diff --git a/tests/unit/controller/FeedControllerTest.php b/tests/unit/controller/FeedControllerTest.php
index efbf90ea3..e3204517b 100644
--- a/tests/unit/controller/FeedControllerTest.php
+++ b/tests/unit/controller/FeedControllerTest.php
@@ -126,8 +126,8 @@ class FeedControllerTest extends ControllerTestUtility {
}
- public function testImportGoogleReaderAnnotations(){
- $this->assertFeedControllerAnnotations('importGoogleReader');
+ public function testImportArticlesAnnotations(){
+ $this->assertFeedControllerAnnotations('importArticles');
}
public function testReadAnnotations(){
@@ -543,7 +543,7 @@ class FeedControllerTest extends ControllerTestUtility {
}
- public function testImportGoogleReader() {
+ public function testImportArticles() {
$feed = new Feed();
$post = array(
@@ -558,12 +558,37 @@ class FeedControllerTest extends ControllerTestUtility {
->method('getUserId')
->will($this->returnValue($this->user));
$this->feedBusinessLayer->expects($this->once())
- ->method('importGoogleReaderJSON')
+ ->method('importArticles')
->with($this->equalTo($post['json']),
$this->equalTo($this->user))
->will($this->returnValue($feed));
- $response = $this->controller->importGoogleReader();
+ $response = $this->controller->importArticles();
+
+ $this->assertEquals($expected, $response->getParams());
+ $this->assertTrue($response instanceof JSONResponse);
+ }
+
+
+ public function testImportArticlesCreatesNoAdditionalFeed() {
+ $feed = new Feed();
+
+ $post = array(
+ 'json' => 'the json'
+ );
+ $expected = array();
+ $this->controller = $this->getPostController($post);
+
+ $this->api->expects($this->once())
+ ->method('getUserId')
+ ->will($this->returnValue($this->user));
+ $this->feedBusinessLayer->expects($this->once())
+ ->method('importArticles')
+ ->with($this->equalTo($post['json']),
+ $this->equalTo($this->user))
+ ->will($this->returnValue(null));
+
+ $response = $this->controller->importArticles();
$this->assertEquals($expected, $response->getParams());
$this->assertTrue($response instanceof JSONResponse);
diff --git a/tests/unit/db/FeedTest.php b/tests/unit/db/FeedTest.php
index b4192db1a..da9326dd4 100644
--- a/tests/unit/db/FeedTest.php
+++ b/tests/unit/db/FeedTest.php
@@ -62,6 +62,13 @@ class FeedTest extends \PHPUnit_Framework_TestCase {
}
+ public function testSetLinkUpdatesHash() {
+ $feed = new Feed();
+ $feed->setLink('http://test');
+ $this->assertEquals(md5('http://test'), $feed->getUrlHash());
+ }
+
+
public function testSetXSSLink() {
$feed = new Feed();
$feed->setLink('javascript:alert()');
diff --git a/tests/unit/db/ItemTest.php b/tests/unit/db/ItemTest.php
index 511badeeb..b4360f273 100644
--- a/tests/unit/db/ItemTest.php
+++ b/tests/unit/db/ItemTest.php
@@ -117,7 +117,7 @@ class ItemTest extends \PHPUnit_Framework_TestCase {
$item->setEnclosureLink('enclink');
$item->setFeedId(1);
$item->setStatus(0);
- $item->setUnread();
+ $item->setRead();
$item->setStarred();
$item->setLastModified(321);
@@ -136,13 +136,39 @@ class ItemTest extends \PHPUnit_Framework_TestCase {
'body' => 'body',
'enclosureMime' => 'audio/ogg',
'enclosureLink' => 'enclink',
- 'unread' => true,
+ 'unread' => false,
'starred' => true,
'feedLink' => 'http://test'
), $item->toExport($feeds));
}
+ public function testFromImport() {
+ $item = new Item();
+ $item->setGuid('guid');
+ $item->setUrl('https://google');
+ $item->setTitle('title');
+ $item->setAuthor('author');
+ $item->setPubDate(123);
+ $item->setBody('body');
+ $item->setEnclosureMime('audio/ogg');
+ $item->setEnclosureLink('enclink');
+ $item->setFeedId(1);
+ $item->setUnread();
+ $item->setStarred();
+
+ $feed = new Feed();
+ $feed->setLink('http://test');
+ $feeds = array(
+ "feed1" => $feed
+ );
+
+ $compareWith = Item::fromImport($item->toExport($feeds));
+ $item->setFeedId(null);
+ $this->assertEquals($item, $compareWith);
+ }
+
+
public function testSetAuthor(){
$item = new Item();
$item->setAuthor('<a>my link</li>');
@@ -172,4 +198,12 @@ class ItemTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals('magnet://link.com', $item->getUrl());
}
+
+ public function testSetGuidUpdatesHash() {
+ $feed = new Item();
+ $feed->setGuid('http://test');
+ $this->assertEquals(md5('http://test'), $feed->getGuidHash());
+ }
+
+
} \ No newline at end of file
diff --git a/tests/unit/utility/ImportParserTest.php b/tests/unit/utility/ImportParserTest.php
deleted file mode 100644
index 82328139f..000000000
--- a/tests/unit/utility/ImportParserTest.php
+++ /dev/null
@@ -1,191 +0,0 @@
-<?php
-
-/**
-* ownCloud - News
-*
-* @author Alessandro Cosentino
-* @author Bernhard Posselt
-* @copyright 2012 Alessandro Cosentino cosenal@gmail.com
-* @copyright 2012 Bernhard Posselt dev@bernhard-posselt.com
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-namespace OCA\News\Utility;
-
-use \OCA\News\Db\Item;
-
-require_once(__DIR__ . "/../../classloader.php");
-
-
-class ImportParserTest extends \OCA\AppFramework\Utility\TestUtility {
-
- private $parser;
- private $time;
- private $in;
- private $purifier;
-
- protected function setUp(){
- $this->time = 222;
- $this->purifier = $this->getMock('purifier', array('purify'));
- $timeFactory = $this->getMockBuilder(
- '\OCA\AppFramework\Utility\TimeFactory')
- ->disableOriginalConstructor()
- ->getMock();
- $timeFactory->expects($this->any())
- ->method('getTime')
- ->will($this->returnValue($this->time));
-
- $this->parser = new ImportParser($timeFactory, $this->purifier);
- $this->in = array(
- 'items' => array(
- array(
- 'id' => "tag:google.com,2005:reader/item/f9fd1dd3c19262e1",
- 'title' => "[HorribleSubs] Mushibugyo - 01 [720p].mkv",
- "published" => 1365415485,
- "alternate" => array( array(
- "href" => "http://www.nyaa.eu/?page=view&tid=421561",
- "type" => "text/html"
- )),
- "summary" => array(
- "content" => "1596 seeder(s), 775 leecher(s), 8005 download(s) - 316.7 MiB - Trusted"
- )
- )
- )
- );
- }
-
-
- public function testImportParserReturnsEmptyArrayIfNoInput(){
- $result = $this->parser->parse(array());
-
- $this->assertEquals($result, array());
- }
-
-
- public function testParsesItems() {
- $body = $this->in['items'][0]['summary']['content'];
- $this->purifier->expects($this->once())
- ->method('purify')
- ->with($this->equalTo($body))
- ->will($this->returnValue($body));
-
- $result = $this->parser->parse($this->in);
-
- $out = new Item();
- $out->setTitle($this->in['items'][0]['title']);
- $out->setPubDate($this->in['items'][0]['published']);
- $out->setBody($body);
- $out->setUrl($this->in['items'][0]['alternate'][0]['href']);
- $out->setGuid($this->in['items'][0]['id']);
- $out->setGuidHash(md5($this->in['items'][0]['id']));
- $out->setStatus(0);
- $out->setUnread();
- $out->setStarred();
-
- $this->assertEquals(array($out), $result);
- }
-
-
- public function testParsesItemsNoSummary() {
- $this->in['items'][0]['content']['content'] = 'hi';
- $body = $this->in['items'][0]['content']['content'];
-
- $this->purifier->expects($this->once())
- ->method('purify')
- ->with($this->equalTo($body))
- ->will($this->retur