summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernhard Posselt <nukeawhale@gmail.com>2013-04-12 14:53:02 +0200
committerBernhard Posselt <nukeawhale@gmail.com>2013-04-12 14:53:02 +0200
commita069add71e642f37c6309c3bd7af74761acef929 (patch)
tree59b3326de202dd5a8bb5e29ae1a626794fb6b349
parente8767f75116ff7ef2b7a349480151c9f66bbade0 (diff)
implement export, needs proper unittests though, fix 31
-rw-r--r--bl/feedbl.php2
-rw-r--r--controller/exportcontroller.php21
-rw-r--r--controller/feedcontroller.php2
-rw-r--r--css/feeds.css2
-rw-r--r--css/settings.css7
-rw-r--r--dependencyinjection/dicontainer.php10
-rw-r--r--js/app/controllers/controllers.coffee8
-rw-r--r--js/app/controllers/settingscontroller.coffee15
-rw-r--r--js/app/services/opmlparser.coffee2
-rw-r--r--js/public/app.js35
-rw-r--r--templates/main.php13
-rw-r--r--templates/part.settings.php52
-rw-r--r--tests/unit/bl/FeedBlTest.php4
-rw-r--r--tests/unit/controller/ExportControllerTest.php45
-rw-r--r--tests/unit/controller/FeedControllerTest.php2
-rw-r--r--utility/opmlexporter.php120
16 files changed, 190 insertions, 150 deletions
diff --git a/bl/feedbl.php b/bl/feedbl.php
index b70d95342..97deaeff0 100644
--- a/bl/feedbl.php
+++ b/bl/feedbl.php
@@ -49,7 +49,7 @@ class FeedBl extends Bl {
}
- public function findAllFromUser($userId){
+ public function findAll($userId){
return $this->mapper->findAllFromUser($userId);
}
diff --git a/controller/exportcontroller.php b/controller/exportcontroller.php
index 013626938..960748d3e 100644
--- a/controller/exportcontroller.php
+++ b/controller/exportcontroller.php
@@ -28,23 +28,38 @@ namespace OCA\News\Controller;
use \OCA\AppFramework\Controller\Controller;
use \OCA\AppFramework\Core\API;
use \OCA\AppFramework\Http\Request;
+use \OCA\AppFramework\Http\TextDownloadResponse;
+use \OCA\News\Bl\FeedBl;
+use \OCA\News\Bl\FolderBl;
+use \OCA\News\Utility\OPMLExporter;
class ExportController extends Controller {
+ private $opmlExporter;
+ private $folderBl;
+ private $feedBl;
- public function __construct(API $api, Request $request){
+ public function __construct(API $api, Request $request, FeedBl $feedBl,
+ FolderBl $folderBl, OPMLExporter $opmlExporter){
parent::__construct($api, $request);
+ $this->feedBl = $feedBl;
+ $this->folderBl = $folderBl;
+ $this->opmlExporter = $opmlExporter;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
- * @Ajax
+ * @CSRFExemption
*/
public function opml(){
- // TODO
+ $user = $this->api->getUserId();
+ $feeds = $this->feedBl->findAll($user);
+ $folders = $this->folderBl->findAll($user);
+ $opml = $this->opmlExporter->build($folders, $feeds)->saveXML();
+ return new TextDownloadResponse($opml, 'subscriptions.opml', 'text/xml');
}
diff --git a/controller/feedcontroller.php b/controller/feedcontroller.php
index c542ea1d8..5e2a91f24 100644
--- a/controller/feedcontroller.php
+++ b/controller/feedcontroller.php
@@ -55,7 +55,7 @@ class FeedController extends Controller {
*/
public function feeds(){
$userId = $this->api->getUserId();
- $result = $this->feedBl->findAllFromUser($userId);
+ $result = $this->feedBl->findAll($userId);
$params = array(
'feeds' => $result
diff --git a/css/feeds.css b/css/feeds.css
index f2667b326..d8b8481ce 100644
--- a/css/feeds.css
+++ b/css/feeds.css
@@ -96,7 +96,7 @@ button.action:hover {
}
.mark-read-icon {
- background-image: url('%appswebroot%/news/img/mark_read.svg') !important;
+ background-image: url('%appswebroot%/news/img/mark_read.svg');
}
.rss-icon {
diff --git a/css/settings.css b/css/settings.css
index 972659a3a..8adec8885 100644
--- a/css/settings.css
+++ b/css/settings.css
@@ -9,13 +9,6 @@
background-color: transparent !important;
}
-.opml-icon {
- background-image: url('%appswebroot%/news/img/opml-icon.svg');
- background-repeat: no-repeat;
- background-position: 5px center;
- padding-left: 28px;
- padding-right: 10px;
-}
#app-settings-content {
padding-bottom: 25px;
diff --git a/dependencyinjection/dicontainer.php b/dependencyinjection/dicontainer.php
index e26e57f4d..c2d4b44e4 100644
--- a/dependencyinjection/dicontainer.php
+++ b/dependencyinjection/dicontainer.php
@@ -46,6 +46,7 @@ use OCA\News\Db\StatusFlag;
use OCA\News\Utility\Fetcher;
use OCA\News\Utility\FeedFetcher;
use OCA\News\Utility\TwitterFetcher;
+use OCA\News\Utility\OPMLExporter;
require_once __DIR__ . '/../3rdparty/SimplePie/autoloader.php';
@@ -90,8 +91,8 @@ class DIContainer extends BaseContainer {
});
$this['ExportController'] = $this->share(function($c){
- return new ExportController($c['API'], $c['Request'],
- $c['FolderBl'], $c['FeedBl']);
+ return new ExportController($c['API'], $c['Request'], $c['FeedBl'],
+ $c['FolderBl'], $c['OPMLExporter']);
});
$this['UserSettingsController'] = $this->share(function($c){
@@ -161,6 +162,11 @@ class DIContainer extends BaseContainer {
return new StatusFlag();
});
+ $this['OPMLExporter'] = $this->share(function($c){
+ return new OPMLExporter();
+ });
+
+
}
}
diff --git a/js/app/controllers/controllers.coffee b/js/app/controllers/controllers.coffee
index 02d5f5e6c..8a73549cf 100644
--- a/js/app/controllers/controllers.coffee
+++ b/js/app/controllers/controllers.coffee
@@ -20,14 +20,6 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
###
-angular.module('News').controller 'SettingsController',
-['$scope', '_SettingsController',
-($scope, _SettingsController)->
-
- return new _SettingsController($scope)
-]
-
-
angular.module('News').controller 'FeedController',
['$scope', '_FeedController', 'Persistence', 'FolderBl', 'FeedBl',
'SubscriptionsBl', 'StarredBl', 'unreadCountFormatter',
diff --git a/js/app/controllers/settingscontroller.coffee b/js/app/controllers/settingscontroller.coffee
index ec94b843c..07cf7360a 100644
--- a/js/app/controllers/settingscontroller.coffee
+++ b/js/app/controllers/settingscontroller.coffee
@@ -21,15 +21,12 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
###
-angular.module('News').factory '_SettingsController', ->
+angular.module('News').controller 'SettingsController',
+['$scope', 'FeedBl', ($scope, FeedBl) ->
- class SettingsController
+ $scope.import = (fileContent) ->
+ console.log fileContent
- constructor: (@$scope) ->
+ $scope.feedBl = FeedBl
- @$scope.import = (fileContent) =>
- console.log 'hi'
- console.log fileContent
-
-
- return SettingsController \ No newline at end of file
+] \ No newline at end of file
diff --git a/js/app/services/opmlparser.coffee b/js/app/services/opmlparser.coffee
index 5154e423c..9586cbaf2 100644
--- a/js/app/services/opmlparser.coffee
+++ b/js/app/services/opmlparser.coffee
@@ -66,7 +66,7 @@ angular.module('News').factory '_OPMLParser', ->
_recursivelyParse: ($xml, structure) ->
for outline in $xml.children('outline')
$outline = $(outline)
- if angular.isDefined($outline.attr('type'))
+ if angular.isDefined($outline.attr('xmlUrl'))
feed = new Feed($outline.attr('text'), $outline.attr('xmlUrl'))
structure.add(feed)
else
diff --git a/js/public/app.js b/js/public/app.js
index e11c2e976..741188cb4 100644
--- a/js/public/app.js
+++ b/js/public/app.js
@@ -217,12 +217,6 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
(function() {
- angular.module('News').controller('SettingsController', [
- '$scope', '_SettingsController', function($scope, _SettingsController) {
- return new _SettingsController($scope);
- }
- ]);
-
angular.module('News').controller('FeedController', [
'$scope', '_FeedController', 'Persistence', 'FolderBl', 'FeedBl', 'SubscriptionsBl', 'StarredBl', 'unreadCountFormatter', function($scope, _FeedController, Persistence, FolderBl, FeedBl, SubscriptionsBl, StarredBl, unreadCountFormatter) {
return new _FeedController($scope, Persistence, FolderBl, FeedBl, SubscriptionsBl, StarredBl, unreadCountFormatter);
@@ -460,25 +454,14 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
(function() {
- angular.module('News').factory('_SettingsController', function() {
- var SettingsController;
-
- SettingsController = (function() {
- function SettingsController($scope) {
- var _this = this;
-
- this.$scope = $scope;
- this.$scope["import"] = function(fileContent) {
- console.log('hi');
- return console.log(fileContent);
- };
- }
-
- return SettingsController;
-
- })();
- return SettingsController;
- });
+ angular.module('News').controller('SettingsController', [
+ '$scope', 'FeedBl', function($scope, FeedBl) {
+ $scope["import"] = function(fileContent) {
+ return console.log(fileContent);
+ };
+ return $scope.feedBl = FeedBl;
+ }
+ ]);
}).call(this);
@@ -1966,7 +1949,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
outline = _ref[_i];
$outline = $(outline);
- if (angular.isDefined($outline.attr('type'))) {
+ if (angular.isDefined($outline.attr('xmlUrl'))) {
feed = new Feed($outline.attr('text'), $outline.attr('xmlUrl'));
_results.push(structure.add(feed));
} else {
diff --git a/templates/main.php b/templates/main.php
index f70ade37f..e6c964c74 100644
--- a/templates/main.php
+++ b/templates/main.php
@@ -30,18 +30,7 @@
</ul>
<div id="app-settings" ng-controller="SettingsController">
- <div id="app-settings-header">
- <button name="app settings"
- class="settings-button"
- oc-click-slide-toggle="{
- selector: '#app-settings-content',
- hideOnFocusLost: true,
- cssClass: 'opened'
- }"></button>
- </div>
- <div id="app-settings-content">
- <?php print_unescaped($this->inc('part.settings')) ?>
- </div>
+ <?php print_unescaped($this->inc('part.settings')) ?>
</div>
</div>
diff --git a/templates/part.settings.php b/templates/part.settings.php
index 436a575eb..263e4b3a8 100644
--- a/templates/part.settings.php
+++ b/templates/part.settings.php
@@ -1,20 +1,32 @@
-<fieldset class="personalblock">
- <legend><strong><?php p($l->t('Import / Export OPML')); ?></strong></legend>
- <input type="file" id="opml-upload" name="import"
- oc-read-file="import($fileContent)"/>
- <button title="<?php p($l->t('Import')); ?>"
- oc-forward-click="{selector:'#opml-upload'}"
- class="opml-icon">
- <?php p($l->t('Import')); ?>
- </button>
- <button ng-disabled="feeds.length==0" title="<?php p($l->t('Export')); ?>"
- ng-click="export()"
- class="opml-icon">
- <?php p($l->t('Export')); ?>
- </button>
-</fieldset>
-<fieldset class="personalblock">
- <legend><strong><?php p($l->t('Subscribelet')); ?></strong></legend>
- <p><?php print_unescaped($this->inc('part.subscribelet'));?>
- </p>
-</fieldset>
+<div id="app-settings-header">
+<button name="app settings"
+ class="settings-button"
+ oc-click-slide-toggle="{
+ selector: '#app-settings-content',
+ hideOnFocusLost: true,
+ cssClass: 'opened'
+ }"></button>
+</div>
+
+<div id="app-settings-content">
+ <fieldset class="personalblock">
+ <legend><strong><?php p($l->t('Import / Export OPML')); ?></strong></legend>
+ <input type="file" id="opml-upload" name="import"
+ oc-read-file="import($fileContent)"/>
+ <button title="<?php p($l->t('Import')); ?>"
+ oc-forward-click="{selector:'#opml-upload'}">
+ <?php p($l->t('Import')); ?>
+ </button>
+ <a title="<?php p($l->t('Export')); ?>" class="button"
+ href="<?php p(\OCP\Util::linkToRoute('news_export_opml')); ?>"
+ target="_blank"
+ ng-show="feedBl.getNumberOfFeeds() > 0">
+ <?php p($l->t('Export')); ?>
+ </a>
+ </fieldset>
+ <fieldset class="personalblock">
+ <legend><strong><?php p($l->t('Subscribelet')); ?></strong></legend>
+ <p><?php print_unescaped($this->inc('part.subscribelet'));?>
+ </p>
+ </fieldset>
+</div> \ No newline at end of file
diff --git a/tests/unit/bl/FeedBlTest.php b/tests/unit/bl/FeedBlTest.php
index 0fadf2c24..a5ce1c624 100644
--- a/tests/unit/bl/FeedBlTest.php
+++ b/tests/unit/bl/FeedBlTest.php
@@ -64,13 +64,13 @@ class FeedBlTest extends \OCA\AppFramework\Utility\TestUtility {
}
- public function testFindAllFromUser(){
+ public function testFindAll(){
$this->mapper->expects($this->once())
->method('findAllFromUser')
->with($this->equalTo($this->user))
->will($this->returnValue($this->response));
- $result = $this->bl->findAllFromUser($this->user);
+ $result = $this->bl->findAll($this->user);
$this->assertEquals($this->response, $result);
}
diff --git a/tests/unit/controller/ExportControllerTest.php b/tests/unit/controller/ExportControllerTest.php
index 913b091c6..b835e585a 100644
--- a/tests/unit/controller/ExportControllerTest.php
+++ b/tests/unit/controller/ExportControllerTest.php
@@ -26,11 +26,12 @@
namespace OCA\News\Controller;
use \OCA\AppFramework\Http\Request;
-use \OCA\AppFramework\Http\JSONResponse;
+use \OCA\AppFramework\Http\TextDownloadResponse;
use \OCA\AppFramework\Utility\ControllerTestUtility;
use \OCA\AppFramework\Db\DoesNotExistException;
use \OCA\AppFramework\Db\MultipleObjectsReturnedException;
+use \OCA\News\Utility\OPMLExporter;
require_once(__DIR__ . "/../../classloader.php");
@@ -40,22 +41,58 @@ class ExportControllerTest extends ControllerTestUtility {
private $api;
private $request;
private $controller;
-
+ private $user;
+ private $feedBl;
+ private $folderBl;
+ private $opmlExporter;
/**
* Gets run before each test
*/
public function setUp(){
$this->api = $this->getAPIMock();
+ $this->feedBl = $this->getMockBuilder('\OCA\News\Bl\FeedBl')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->folderBl = $this->getMockBuilder('\OCA\News\Bl\FolderBl')
+ ->disableOriginalConstructor()
+ ->getMock();
$this->request = new Request();
- $this->controller = new ExportController($this->api, $this->request);
+ $this->opmlExporter = new OPMLExporter();
+ $this->controller = new ExportController($this->api, $this->request,
+ $this->feedBl, $this->folderBl, $this->opmlExporter);
+ $this->user = 'john';
}
public function testOpmlAnnotations(){
- $annotations = array('IsAdminExemption', 'IsSubAdminExemption', 'Ajax');
+ $annotations = array('IsAdminExemption', 'IsSubAdminExemption',
+ 'CSRFExemption');
$this->assertAnnotations($this->controller, 'opml', $annotations);
}
+ public function testOpmlExportNoFeeds(){
+ $this->api->expects($this->once())
+ ->method('getUserId')
+ ->will($this->returnValue($this->user));
+ $this->feedBl->expects($this->once())
+ ->method('findAll')
+ ->with($this->equalTo($this->user))
+ ->will($this->returnValue(array()));
+ $this->folderBl->expects($this->once())
+ ->method('findAll')
+ ->with($this->equalTo($this->user))
+ ->will($this->returnValue(array()));
+
+ $return = $this->controller->opml();
+ $this->assertTrue($return instanceof TextDownloadResponse);
+
+ // TODO: check if its empty xml structure
+ }
+
+
+ // TODO more tests for this
+
+
} \ No newline at end of file
diff --git a/tests/unit/controller/FeedControllerTest.php b/tests/unit/controller/FeedControllerTest.php
index e3dc60a28..e7c7c29e3 100644
--- a/tests/unit/controller/FeedControllerTest.php
+++ b/tests/unit/controller/FeedControllerTest.php
@@ -122,7 +122,7 @@ class FeedControllerTest extends ControllerTestUtility {
->method('getUserId')
->will($this->returnValue($this->user));
$this->bl->expects($this->once())
- ->method('findAllFromUser')
+ ->method('findAll')
->with($this->equalTo($this->user))
->will($this->returnValue($result['feeds']));
diff --git a/utility/opmlexporter.php b/utility/opmlexporter.php
index d9d404ff1..630b2aba8 100644
--- a/utility/opmlexporter.php
+++ b/utility/opmlexporter.php
@@ -1,82 +1,98 @@
<?php
/**
-* ownCloud - News app
+* ownCloud - News
*
* @author Alessandro Cosentino
-* Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
+* @author Bernhard Posselt
+* @copyright 2012 Alessandro Cosentino cosenal@gmail.com
+* @copyright 2012 Bernhard Posselt nukeawhale@gmail.com
*
-* This file is licensed under the Affero General Public License version 3 or later.
-* See the COPYING-README file
+* 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;
+namespace OCA\News\Utility;
/**
* Exports the OPML
*/
class OPMLExporter {
- private $api;
- private $trans;
-
- public function __construct($api){
- $this->api = $api;
- $this->trans = $api->getTrans();
- }
-
-
/**
* Generates the OPML for the active user
* @return the OPML as string
*/
- public function buildOPML($feeds){
- $dom = new \DomDocument('1.0', 'UTF-8');
- $dom->formatOutput = true;
-
- $opml_el = $dom->createElement('opml');
- $opml_el->setAttribute('version', '2.0');
-
- $head_el = $dom->createElement('head');
+ public function build($folders, $feeds){
+ $document = new \DomDocument('1.0', 'UTF-8');
+ $document->formatOutput = true;
+
+ $root = $document->createElement('opml');
+ $root->setAttribute('version', '2.0');
+
+ // head
+ $head = $document->createElement('head');
+
+ $title = $document->createElement('title', 'Subscriptions');
+ $head->appendChild( $title );
+
+ $root->appendChild($head);
+
+ // body
+ $body = $document->createElement('body');
+
+ // feeds with folders
+ foreach($folders as $folder) {
+ $folderOutline = $document->createElement('outline');
+ $folderOutline->setAttribute('title', $folder->getName());
+ $folderOutline->setAttribute('text', $folder->getName());
+
+ // feeds in folders
+ foreach ($feeds as $feed) {
+ if ($feed->getFolderId() === $folder->getId()) {
+ $feedOutline = $this->createFeedOutline($feed, $document);
+ $folderOutline->appendChild($feedOutline);
+ }
+ }
- $title = $this->api->getUserId() . ' ' .
- $this->trans->t('subscriptions in ownCloud - News');
- $title_el = $dom->createElement('title', $title);
+ $body->appendChild($folderOutline);
+ }
- $head_el->appendChild( $title_el );
- $opml_el->appendChild( $head_el );
- $body_el = $dom->createElement('body');
+ // feeds without folders
+ foreach ($feeds as $feed) {
+ if ($feed->getFolderId() === 0) {
+ $feedOutline = $this->createFeedOutline($feed, $document);
+ $body->appendChild($feedOutline);
+ }
+ }
- $this->feedsToXML($feeds, $body_el, $dom);
+ $root->appendChild($body);
- $opml_el->appendChild( $body_el );
- $dom->appendChild( $opml_el );
+ $document->appendChild($root);
- return $dom->saveXML();
+ return $document;
}
- /**
- * Creates the OPML content recursively
- */
- protected function feedsToXML($data, $xml_el, $dom) {
-
- foreach($data as $collection) {
- $outline_el = $dom->createElement('outline');
- if ($collection instanceOf Folder) {
- $outline_el->setAttribute('title', $collection->getName());
- $outline_el->setAttribute('text', $collection->getName());
- $this->feedsToXML($collection->getChildren(), $outline_el, $dom);
- }
- elseif ($collection instanceOf Feed) {
- $outline_el->setAttribute('title', $collection->getTitle());
- $outline_el->setAttribute('text', $collection->getTitle());
- $outline_el->setAttribute('type', 'rss');
- $outline_el->setAttribute('xmlUrl', $collection->getUrl());
- }
- $xml_el->appendChild( $outline_el );
- }
+ protected function createFeedOutline($feed, $document) {
+ $feedOutline = $document->createElement('outline');
+ $feedOutline->setAttribute('title', $feed->getTitle());
+ $feedOutline->setAttribute('text', $feed->getTitle());
+ $feedOutline->setAttribute('type', 'rss');
+ $feedOutline->setAttribute('xmlUrl', $feed->getUrl());
+ $feedOutline->setAttribute('htmlUrl', $feed->getLink());
+ return $feedOutline;
}