diff options
Diffstat (limited to 'lib/Controller')
-rw-r--r-- | lib/Controller/AdminController.php | 88 | ||||
-rw-r--r-- | lib/Controller/ApiController.php | 37 | ||||
-rw-r--r-- | lib/Controller/EntityApiSerializer.php | 68 | ||||
-rw-r--r-- | lib/Controller/ExportController.php | 91 | ||||
-rw-r--r-- | lib/Controller/FeedApiController.php | 224 | ||||
-rw-r--r-- | lib/Controller/FeedController.php | 301 | ||||
-rw-r--r-- | lib/Controller/FolderApiController.php | 139 | ||||
-rw-r--r-- | lib/Controller/FolderController.php | 176 | ||||
-rw-r--r-- | lib/Controller/ItemApiController.php | 245 | ||||
-rw-r--r-- | lib/Controller/ItemController.php | 218 | ||||
-rw-r--r-- | lib/Controller/JSONHttpError.php | 31 | ||||
-rw-r--r-- | lib/Controller/PageController.php | 224 | ||||
-rw-r--r-- | lib/Controller/UserApiController.php | 72 | ||||
-rw-r--r-- | lib/Controller/UtilityApiController.php | 83 |
14 files changed, 1997 insertions, 0 deletions
diff --git a/lib/Controller/AdminController.php b/lib/Controller/AdminController.php new file mode 100644 index 000000000..a673566de --- /dev/null +++ b/lib/Controller/AdminController.php @@ -0,0 +1,88 @@ +<?php +/** + * ownCloud - 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 Alessandro Cosentino 2012 + * @copyright Bernhard Posselt 2012, 2014 + */ + +namespace OCA\News\Controller; + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IRequest; +use OCP\AppFramework\Controller; + +use OCA\News\Config\Config; +use OCA\News\Service\itemService; + +class AdminController extends Controller { + + private $config; + private $configPath; + private $itemService; + + public function __construct($AppName, IRequest $request, Config $config, + ItemService $itemService, $configFile){ + parent::__construct($AppName, $request); + $this->config = $config; + $this->configPath = $configFile; + $this->itemService = $itemService; + } + + // There are no checks for the index method since the output is rendered + // in admin/admin.php + public function index() { + $data = [ + 'autoPurgeMinimumInterval' => + $this->config->getAutoPurgeMinimumInterval(), + 'autoPurgeCount' => $this->config->getAutoPurgeCount(), + 'maxRedirects' => $this->config->getMaxRedirects(), + 'feedFetcherTimeout' => $this->config->getFeedFetcherTimeout(), + 'useCronUpdates' => $this->config->getUseCronUpdates(), + 'maxSize' => $this->config->getMaxSize(), + 'exploreUrl' => $this->config->getExploreUrl(), + ]; + return new TemplateResponse($this->appName, 'admin', $data, 'blank'); + } + + + /** + * @param int $autoPurgeMinimumInterval + * @param int $autoPurgeCount + * @param int $maxRedirects + * @param int $feedFetcherTimeout + * @param int $maxSize + * @param bool $useCronUpdates + * @param string $exploreUrl + * @return array with the updated values + */ + public function update($autoPurgeMinimumInterval, $autoPurgeCount, + $maxRedirects, $feedFetcherTimeout, $maxSize, + $useCronUpdates, $exploreUrl) { + $this->config->setAutoPurgeMinimumInterval($autoPurgeMinimumInterval); + $this->config->setAutoPurgeCount($autoPurgeCount); + $this->config->setMaxRedirects($maxRedirects); + $this->config->setMaxSize($maxSize); + $this->config->setFeedFetcherTimeout($feedFetcherTimeout); + $this->config->setUseCronUpdates($useCronUpdates); + $this->config->setExploreUrl($exploreUrl); + $this->config->write($this->configPath); + + return [ + 'autoPurgeMinimumInterval' => + $this->config->getAutoPurgeMinimumInterval(), + 'autoPurgeCount' => $this->config->getAutoPurgeCount(), + 'maxRedirects' => $this->config->getMaxRedirects(), + 'maxSize' => $this->config->getMaxSize(), + 'feedFetcherTimeout' => $this->config->getFeedFetcherTimeout(), + 'useCronUpdates' => $this->config->getUseCronUpdates(), + 'exploreUrl' => $this->config->getExploreUrl(), + ]; + } + +} diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php new file mode 100644 index 000000000..f3b77b379 --- /dev/null +++ b/lib/Controller/ApiController.php @@ -0,0 +1,37 @@ +<?php +/** + * ownCloud - 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 Alessandro Cosentino 2012 + * @copyright Bernhard Posselt 2012, 2014 + */ + +namespace OCA\News\Controller; + +use OCP\IRequest; +use OCP\AppFramework\ApiController as BaseApiController; + +class ApiController extends BaseApiController { + + public function __construct($appName, + IRequest $request){ + parent::__construct($appName, $request); + } + + /** + * @PublicPage + * @NoCSRFRequired + * @CORS + */ + public function index() { + return [ + 'apiLevels' => ['v1-2'] + ]; + } + +} diff --git a/lib/Controller/EntityApiSerializer.php b/lib/Controller/EntityApiSerializer.php new file mode 100644 index 000000000..073ad5c39 --- /dev/null +++ b/lib/Controller/EntityApiSerializer.php @@ -0,0 +1,68 @@ +<?php +/** + * ownCloud - News + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Bernhard Posselt <dev@bernhard-posselt.com> + * @copyright Bernhard Posselt 2014 + */ + +namespace OCA\News\Controller; + +use \OCA\News\Db\IAPI; + + +class EntityApiSerializer { + + private $level; + + public function __construct($level) { + $this->level = $level; + } + + + /** + * Call toAPI() method on all entities. Works on + * + * @param mixed $data : + * * Entity + * * Entity[] + * * array('level' => Entity[]) + * * Response + * @return array|mixed + */ + public function serialize($data) { + + if($data instanceof IAPI) { + return [$this->level => [$data->toAPI()]]; + } + + if(is_array($data) && array_key_exists($this->level, $data)) { + $data[$this->level] = $this->convert($data[$this->level]); + } elseif(is_array($data)) { + $data = [$this->level => $this->convert($data)]; + } + + return $data; + } + + + private function convert($entities) { + $converted = []; + + foreach($entities as $entity) { + if($entity instanceof IAPI) { + $converted[] = $entity->toAPI(); + + // break if it contains anything else than entities + } else { + return $entities; + } + } + + return $converted; + } + +}
\ No newline at end of file diff --git a/lib/Controller/ExportController.php b/lib/Controller/ExportController.php new file mode 100644 index 000000000..bc9fc0ff1 --- /dev/null +++ b/lib/Controller/ExportController.php @@ -0,0 +1,91 @@ +<?php +/** + * ownCloud - 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 Alessandro Cosentino 2012 + * @copyright Bernhard Posselt 2012, 2014 + */ + +namespace OCA\News\Controller; + +use \OCP\IRequest; +use \OCP\AppFramework\Controller; +use \OCP\AppFramework\Http; +use \OCP\AppFramework\Http\JSONResponse; + +use \OCA\News\Http\TextDownloadResponse; +use \OCA\News\Service\FolderService; +use \OCA\News\Service\FeedService; +use \OCA\News\Service\ItemService; +use \OCA\News\Utility\OPMLExporter; + +class ExportController extends Controller { + + private $opmlExporter; + private $folderService; + private $feedService; + private $itemService; + private $userId; + + public function __construct($AppName, + IRequest $request, + FolderService $folderService, + FeedService $feedService, + ItemService $itemService, + OPMLExporter $opmlExporter, + $UserId){ + parent::__construct($AppName, $request); + $this->feedService = $feedService; + $this->folderService = $folderService; + $this->opmlExporter = $opmlExporter; + $this->itemService = $itemService; + $this->userId = $UserId; + } + + + /** + * @NoAdminRequired + * @NoCSRFRequired + */ + public function opml(){ + $feeds = $this->feedService->findAll($this->userId); + $folders = $this->folderService->findAll($this->userId); + $opml = $this->opmlExporter->build($folders, $feeds)->saveXML(); + $name = 'subscriptions.opml'; + $mimeType = 'text/xml'; + return new TextDownloadResponse($opml, $name, $mimeType); + } + + + /** + * @NoAdminRequired + * @NoCSRFRequired + */ + public function articles(){ + $feeds = $this->feedService->findAll($this->userId); + $items = $this->itemService->getUnreadOrStarred($this->userId); + + // build assoc array for fast access + $feedsDict = []; + foreach($feeds as $feed) { + $feedsDict['feed' . $feed->getId()] = $feed; + } + + $articles = []; + foreach($items as $item) { + $articles[] = $item->toExport($feedsDict); + } + + $response = new JSONResponse($articles); + $response->addHeader('Content-Disposition', + 'attachment; filename="articles.json"'); + return $response; + } + + +}
\ No newline at end of file diff --git a/lib/Controller/FeedApiController.php b/lib/Controller/FeedApiController.php new file mode 100644 index 000000000..9713db8cf --- /dev/null +++ b/lib/Controller/FeedApiController.php @@ -0,0 +1,224 @@ +<?php +/** + * ownCloud - 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 Alessandro Cosentino 2012 + * @copyright Bernhard Posselt 2012, 2014 + */ + +namespace OCA\News\Controller; + +use \OCP\IRequest; +use \OCP\ILogger; +use \OCP\AppFramework\ApiController; +use \OCP\AppFramework\Http; + +use \OCA\News\Service\FeedService; +use \OCA\News\Service\ItemService; +use \OCA\News\Service\ServiceNotFoundException; +use \OCA\News\Service\ServiceConflictException; + + +class FeedApiController extends ApiController { + + use JSONHttpError; + + private $itemService; + private $feedService; + private $userId; + private $logger; + private $loggerParams; + private $serializer; + + public function __construct($AppName, + IRequest $request, + FeedService $feedService, + ItemService $itemService, + ILogger $logger, + $UserId, + $LoggerParameters){ + parent::__construct($AppName, $request); + $this->feedService = $feedService; + $this->itemService = $itemService; + $this->userId = $UserId; + $this->logger = $logger; + $this->loggerParams = $LoggerParameters; + $this->serializer = new EntityApiSerializer('feeds'); + } + + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @CORS + */ + public function index() { + + $result = [ + 'starredCount' => $this->itemService->starredCount($this->userId), + 'feeds' => $this->feedService->findAll($this->userId) + ]; + + + try { + $result['newestItemId'] = + $this->itemService->getNewestItemId($this->userId); + + // in case there are no items, ignore + } catch(ServiceNotFoundException $ex) {} + + return $this->serializer->serialize($result); + } + + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @CORS + * + * @param string $url + * @param int $folderId + * @return array|mixed|\OCP\AppFramework\Http\JSONResponse + */ + public function create($url, $folderId=0) { + try { + $this->feedService->purgeDeleted($this->userId, false); + + $feed = $this->feedService->create($url, $folderId, $this->userId); + $result = ['feeds' => [$feed]]; + + try { + $result['newestItemId'] = + $this->itemService->getNewestItemId($this->userId); + + // in case there are no items, ignore + } catch(ServiceNotFoundException $ex) {} + + return $this->serializer->serialize($result); + + } catch(ServiceConflictException $ex) { + return $this->error($ex, Http::STATUS_CONFLICT); + } catch(ServiceNotFoundException $ex) { + return $this->error($ex, Http::STATUS_NOT_FOUND); + } + } + + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @CORS + * + * @param int $feedId + * @return array|\OCP\AppFramework\Http\JSONResponse + */ + public function delete($feedId) { + try { + $this->feedService->delete($feedId, $this->userId); + } catch(ServiceNotFoundException $ex) { + return $this->error($ex, Http::STATUS_NOT_FOUND); + } + + return []; + } + + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @CORS + * + * @param int $feedId + * @param int $newestItemId + */ + public function read($feedId, $newestItemId) { + $this->itemService->readFeed($feedId, $newestItemId, $this->userId); + } + + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @CORS + * + * @param int $feedId + * @param int $folderId + * @return array|\OCP\AppFramework\Http\JSONResponse + */ + public function move($feedId, $folderId) { + try { + $this->feedService->patch( + $feedId, $this->userId, ['folderId' => $folderId] + ); + } catch(ServiceNotFoundException $ex) { + return $this->error($ex, Http::STATUS_NOT_FOUND); + } + + return []; + } + + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @CORS + * + * @param int $feedId + * @param string $feedTitle + * @return array|\OCP\AppFramework\Http\JSONResponse + */ + public function rename($feedId, $feedTitle) { + try { + $this->feedService->patch( + $feedId, $this->userId, ['title' => $feedTitle] + ); + } catch(ServiceNotFoundException $ex) { + return $this->error($ex, Http::STATUS_NOT_FOUND); + } + + return []; + } + + + /** + * @NoCSRFRequired + * @CORS + */ + public function fromAllUsers() { + $feeds = $this->feedService->findAllFromAllUsers(); + $result = ['feeds' => []]; + + foreach ($feeds as $feed) { + $result['feeds'][] = [ + 'id' => $feed->getId(), + 'userId' => $feed->getUserId() + ]; + } + + return $result; + } + + + /** + * @NoCSRFRequired + * + * @param string $userId + * @param int $feedId + */ + public function update($userId, $feedId) { + try { + $this->feedService->update($feedId, $userId); + // ignore update failure + } catch(\Exception $ex) { + $this->logger->debug('Could not update feed ' . $ex->getMessage(), + $this->loggerParams); + } + } + + +} diff --git a/lib/Controller/FeedController.php b/lib/Controller/FeedController.php new file mode 100644 index 000000000..2b95794a3 --- /dev/null +++ b/lib/Controller/FeedController.php @@ -0,0 +1,301 @@ +<?php +/** + * ownCloud - 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 Alessandro Cosentino 2012 + * @copyright Bernhard Posselt 2012, 2014 + */ + +namespace OCA\News\Controller; + +use OCP\IRequest; +use OCP\IConfig; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; + +use OCA\News\Service\ItemService; +use OCA\News\Service\FeedService; +use OCA\News\Service\FolderService; +use OCA\News\Service\ServiceNotFoundException; +use OCA\News\Service\ServiceConflictException; +use OCA\News\Db\FeedType; + + +class FeedController extends Controller { + + use JSONHttpError; + + private $feedService; + private $folderService; + private $itemService; + private $userId; + private $settings; + + public function __construct($AppName, + IRequest $request, + FolderService $folderService, + FeedService $feedService, + ItemService $itemService, + IConfig $settings, + $UserId){ + parent::__construct($AppName, $request); + $this->feedService = $feedService; + $this->folderService = $folderService; + $this->itemService = $itemService; + $this->userId = $UserId; + $this->settings = $settings; + } + + + /** + * @NoAdminRequired + */ + public function index(){ + + // this method is also used to update the interface + // because of this we also pass the starred count and the newest + // item id which will be used for marking feeds read + $params = [ + 'feeds' => $this->feedService->findAll($this->userId), + 'starred' => $this->itemService->starredCount($this->userId) + ]; + + try { + $params['newestItemId'] = + $this->itemService->getNewestItemId($this->userId); + + // An exception occurs if there is a newest item. If there is none, + // simply ignore it and do not add the newestItemId + } catch (ServiceNotFoundException $ex) {} + + return $params; + } + + + /** + * @NoAdminRequired + */ + public function active(){ + $feedId = (int) $this->settings->getUserValue($this->userId, + $this->appName,'lastViewedFeedId'); + $feedType = $this->settings->getUserValue($this->userId, $this->appName, + 'lastViewedFeedType'); + + // cast from null to int is 0 + if($feedType !== null){ + $feedType = (int) $feedType; + } + + // check if feed or folder exists + try { + if($feedType === FeedType::FOLDER){ + $this->folderService->find($feedId, $this->userId); + + } elseif ($feedType === FeedType::FEED){ + $this->feedService->find($feedId, $this->userId); + + // if its the first launch, those values will be null + } elseif($feedType === null){ + throw new ServiceNotFoundException(''); + } + + } catch (ServiceNotFoundException $ex){ + $feedId = 0; + $feedType = FeedType::SUBSCRIPTIONS; + } + + return [ + 'activeFeed' => [ + 'id' => $feedId, + 'type' => $feedType + ] + ]; + } + + + /** + * @NoAdminRequired + * + * @param string $url + * @param int $parentFolderId + * @param string $title + * @param string $user + * @param string $password + * @return array|\OCP\AppFramework\Http\JSONResponse + */ + public function create($url, $parentFolderId, $title=null, + $user=null, $password=null){ + try { + // we need to purge deleted feeds if a feed is created to + // prevent already exists exceptions + $this->feedService->purgeDeleted($this->userId, false); + + $feed = $this->feedService->create($url, $parentFolderId, + $this->userId, $title, + $user, $password); + $params = ['feeds' => [$feed]]; + + try { + $params['newestItemId'] = + $this->itemService->getNewestItemId($this->userId); + + // An exception occurs if there is a newest item. If there is none, + // simply ignore it and do not add the newestItemId + } catch (ServiceNotFoundException $ex) {} + + return $params; + + } catch(ServiceConflictException $ex) { + return $this->error($ex, Http::STATUS_CONFLICT); + } catch(ServiceNotFoundException $ex) { + return $this->error($ex, Http::STATUS_UNPROCESSABLE_ENTITY); + } + + } + + + /** + * @NoAdminRequired + * + * @param int $feedId + * @return array|\OCP\AppFramework\Http\JSONResponse + */ + public function delete($feedId){ + try { + $this->feedService->markDeleted($feedId, $this->userId); + } catch(ServiceNotFoundException $ex) { + return $this->error($ex, Http::STATUS_NOT_FOUND); + } + + return []; + } + + + /** + * @NoAdminRequired + * + * @param int $feedId + * @return array|\OCP\AppFramework\Http\JSONResponse + */ + public function update($feedId){ + try { + $feed = $this->feedService->update($feedId, $this->userId); + + return [ + 'feeds' => [ + // only pass unread count to not accidentally readd + // the feed again + [ + 'id' => $feed->getId(), + 'unreadCount' => $feed->getUnreadCount() + ] + ] + ]; + + } catch(ServiceNotFoundException $ex) { + return $this->error($ex, Http::STATUS_NOT_FOUND); + } + + } + + + /** + * @NoAdminRequired + * + * @param array $json + * @return array + */ + public function import($json) { + $feed = $this->feedService->importArticles($json, $this->userId); + + $params = [ + 'starred' => $this->itemService->starredCount($this->userId) + ]; + + if($feed) { + $params['feeds'] = [$feed]; + } + + return $params; + } + + + /** + * @NoAdminRequired + * + * @param int $feedId + * @param int $highestItemId + * @return array + */ + public function read($feedId, $highestItemId){ + $this->itemService->readFeed($feedId, $highestItemId, $this->userId); + + return [ + 'feeds' => [ + [ + 'id' => $feedId, + 'unreadCount' => 0 + ] + ] + ]; + } + + + /** + * @NoAdminRequired + * + * @param int $feedId + * @return array|\OCP\AppFramework\Http\JSONResponse + */ + public function restore($feedId){ + try { + $this->feedService->unmarkDeleted($feedId, $this->userId); + } catch(ServiceNotFoundException $ex) { + return $this->error($ex, Http::STATUS_NOT_FOUND); + } + + return []; + } + + /** + * @NoAdminRequired + * + * @param int $feedId + * @param bool $pinned + * @param bool $fullTextEnabled + * @param int $updateMode + * @param int $ordering + * @param int $folderId + * @param string $title + */ + public function patch($feedId, $pinned=null, $fullTextEnabled=null, + $updateMode=null, $ordering=null, $title=null, + $folderId=null) { + $attributes = [ + 'pinned' => $pinned, + 'fullTextEnabled' => $fullTextEnabled, + 'updateMode' => $updateMode, + 'ordering' => $ordering, + 'title' => $title, + 'folderId' => $folderId + ]; + + $diff = array_filter($attributes, function ($value) { + return $value !== null; + }); + + try { + $this->feedService->patch($feedId, $this->userId, $diff); + } catch(ServiceNotFoundException $ex) { + return $this->error($ex, Http::STATUS_NOT_FOUND); + } + + return []; + } + +} diff --git a/lib/Controller/FolderApiController.php b/lib/Controller/FolderApiController.php new file mode 100644 index 000000000..53693e84f --- /dev/null +++ b/lib/Controller/FolderApiController.php @@ -0,0 +1,139 @@ +<?php +/** + * ownCloud - 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 Alessandro Cosentino 2012 + * @copyright Bernhard Posselt 2012, 2014 + */ + +namespace OCA\News\Controller; + +use \OCP\IRequest; +use \OCP\AppFramework\ApiController; +use \OCP\AppFramework\Http; + +use \OCA\News\Service\FolderService; +use \OCA\News\Service\ItemService; +use \OCA\News\Service\ServiceNotFoundException; +use \OCA\News\Service\ServiceConflictException; +use \OCA\News\Service\ServiceValidationException; + + +class FolderApiController extends ApiController { + + use JSONHttpError; + + private $folderService; + private $itemService; + private $userId; + |