From 12462ce2b2c3ac2ac5770ae0276a3bb4ee8019d1 Mon Sep 17 00:00:00 2001 From: Jonas Heinrich <onny@project-insanity.org> Date: Mon, 15 Mar 2021 11:21:12 +0100 Subject: [PATCH] beginning to implement export podcast subscriptions --- appinfo/routes.php | 1 + l10n/de.js | 80 +++++++++++++------------- l10n/de.json | 80 +++++++++++++------------- lib/Controller/ExportController.php | 79 +++++++++++++++++++++++++ lib/ExportResponse.php | 56 ++++++++++++++++++ src/components/ItemGrid.vue | 26 +++++++++ src/views/Library.vue | 14 ++++- translationfiles/templates/podcast.pot | 2 +- 8 files changed, 254 insertions(+), 84 deletions(-) create mode 100644 lib/Controller/ExportController.php create mode 100644 lib/ExportResponse.php diff --git a/appinfo/routes.php b/appinfo/routes.php index 63e76b9..d001648 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -25,6 +25,7 @@ return [ 'resources' => [ 'show' => ['url' => '/api/shows'], 'episode' => ['url' => '/api/episodes'], + 'export' => ['url' => '/export'], ], 'routes' => [ diff --git a/l10n/de.js b/l10n/de.js index 57532f8..0ec5301 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -1,47 +1,45 @@ OC.L10N.register( "podcast", { - "Radio stations" : "Radio Stationen", - "Radio" : "Radio", - "Radio listening app" : "Online Radiosender hören", - "Listening to your favorite radio stations in Nextcloud" : "Höre deine Lieblings-Radiosender direkt in Nextcloud", - "Error fetching favorite stations" : "Favorisierte Stationen konnten nicht geladen werden", - "No favorites added yet!" : "Noch keine favorisierte Stationen vorhanden", - "Failed to fetch favorite radio stations" : "Favorisierte Stationen konnten nicht geladen werden", - "No favorites yet" : "Noch keine Favoriten", - "No recent stations yet" : "Noch keine zuletzt gespielten Stationen", - "No search results" : "Keine Suchergebnisse", - "Stations you mark as favorite will show up here" : "Radio Stationen die favorisiert wurden werden hier angezeigt", - "Stations you recently played will show up here" : "Radio Stationen die vor kurzem gespielt wurden, werden hier angezeigt", - "No stations were found matching your search term" : "Keine Stationen unter diesen Suchbegriff gefunden", - "No stations here" : "Keine Stationen verfügbar", - "Could not remove station from favorites" : "Radio station konnte nicht von den Favoriten entfernt werden", - "Could not favor station" : "Station konnte nicht favorisiert werden", - "Lost connection to radio station, retrying ..." : "Verbindung zur Radio Station unterbrochen, versuche wiederzuverbinden ...", - "Unable to count play on remote API" : "Wiedergabe konnte nicht gezählt werden von der entfernten API", - "Could not add station to recent list" : "Radio Station konnte nicht in die zuletzt gespielt Liste aufgenommen werden", - "Countries" : "Länder", - "States" : "Staaten", - "Languages" : "Sprachen", - "Tags" : "Stichwörter", - "Could not fetch stations from remote API" : "Radio Stationen konnten nicht von der API geladen werden", - "Unable to load favorites" : "Favoriten konnten nicht geladen werden", - "Top" : "Beliebteste", - "Recent" : "Zuletzt gehört", - "New" : "Neu", - "Favorites" : "Favoriten", - "Categories" : "Kategorien", - "Search" : "Suche", - "Stream URL" : "Stream URL", - "Copy link to clipboard" : "Adresse in die Zwischenablage kopieren", - "Homepage" : "Webseite", - "Country & Language" : "Land und Sprache", - "Codec & Bitrate" : "Codec & Bitrate", - "Link copied to clipboard" : "Adresse in die Zwischenablage kopiert", - "Error while copying link to clipboard" : "Fehler beim Speichern in die Zwischenablage", + "Podcast episodes" : "Podcast Episoden", + "Podcast" : "Podcast", + "🔊 Browse, manage and listen to podcasts" : "🔊 Browse, manage and listen to podcasts", + "**🔊 Browse, listen and subscribe to podcasts**\n\nFull featured podcatcher which uses the community index fyyd.de as a source.\n\n- 🔠Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- â Support episode chapters\n- 👂 Smoth audio playback and transitions" : "**🔊 Browse, listen and subscribe to podcasts**\n\nFull featured podcatcher which uses the community index fyyd.de as a source.\n\n- 🔠Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- â Support episode chapters\n- 👂 Smoth audio playback and transitions", + "Hide" : "Verstecken", + "Show" : "Anzeigen", + "episodes" : "Episoden", + "Error fetching favorite episodes" : "Fehler beim Laden der favorisierten Episoden", + "No episodes added yet!" : "Keine Episoden bis jetzt hinzugefügt!", + "Failed to fetch favorite podcast episodes" : "Fehler beim Laden der Podcast Episoden", + "Show all" : "Zeige alle", + "by" : "von", + "Show more" : "Zeige mehr", + "Show less" : "Zeige weniger", + "Unsubscribe" : "Abbestellen", + "Subscribe" : "Abonnieren", + "Listening" : "Aktuell höhrend", + "Library" : "Bibliothek", + "Browse" : "Durchsuchen", + "Search" : "Suchen", "Name" : "Name", - "Add to favorites" : "Zu den Favoriten hinzufügen", - "Remove from favorites" : "Von den Favoriten entfernen", - "Details" : "Weitere Informationen" + "Duration" : "Länge", + "Date" : "Datum", + "Go to episode" : "Gehe zu Episode", + "Go to show" : "Gehe zu Sendung", + "Download" : "Herunterladen", + "Share" : "Teilen", + "Remove from queue" : "Von Wiedergabeliste entfernen", + "Resume" : "Fortsetzen", + "Pause" : "Pausieren", + "Play" : "Abspielen", + "Hot podcasts" : "Zurzeit beliebte Podcasts", + "New podcasts" : "Neue Podcasts", + "Podcasts in" : "Podcasts in", + "Publication date" : "Veröffentlicht", + "Episode chapters" : "Kapitel", + "Pause episode" : "Episode pausieren", + "Resume episode" : "Episode fortsetzen", + "Play episode" : "Episode abspielen", + "Currently listening" : "Zuletzt gehört" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/de.json b/l10n/de.json index ab8a13d..36c8308 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -1,45 +1,43 @@ { "translations": { - "Radio stations" : "Radio Stationen", - "Radio" : "Radio", - "Radio listening app" : "Online Radiosender hören", - "Listening to your favorite radio stations in Nextcloud" : "Höre deine Lieblings-Radiosender direkt in Nextcloud", - "Error fetching favorite stations" : "Favorisierte Stationen konnten nicht geladen werden", - "No favorites added yet!" : "Noch keine favorisierte Stationen vorhanden", - "Failed to fetch favorite radio stations" : "Favorisierte Stationen konnten nicht geladen werden", - "No favorites yet" : "Noch keine Favoriten", - "No recent stations yet" : "Noch keine zuletzt gespielten Stationen", - "No search results" : "Keine Suchergebnisse", - "Stations you mark as favorite will show up here" : "Radio Stationen die favorisiert wurden werden hier angezeigt", - "Stations you recently played will show up here" : "Radio Stationen die vor kurzem gespielt wurden, werden hier angezeigt", - "No stations were found matching your search term" : "Keine Stationen unter diesen Suchbegriff gefunden", - "No stations here" : "Keine Stationen verfügbar", - "Could not remove station from favorites" : "Radio station konnte nicht von den Favoriten entfernt werden", - "Could not favor station" : "Station konnte nicht favorisiert werden", - "Lost connection to radio station, retrying ..." : "Verbindung zur Radio Station unterbrochen, versuche wiederzuverbinden ...", - "Unable to count play on remote API" : "Wiedergabe konnte nicht gezählt werden von der entfernten API", - "Could not add station to recent list" : "Radio Station konnte nicht in die zuletzt gespielt Liste aufgenommen werden", - "Countries" : "Länder", - "States" : "Staaten", - "Languages" : "Sprachen", - "Tags" : "Stichwörter", - "Could not fetch stations from remote API" : "Radio Stationen konnten nicht von der API geladen werden", - "Unable to load favorites" : "Favoriten konnten nicht geladen werden", - "Top" : "Beliebteste", - "Recent" : "Zuletzt gehört", - "New" : "Neu", - "Favorites" : "Favoriten", - "Categories" : "Kategorien", - "Search" : "Suche", - "Stream URL" : "Stream URL", - "Copy link to clipboard" : "Adresse in die Zwischenablage kopieren", - "Homepage" : "Webseite", - "Country & Language" : "Land und Sprache", - "Codec & Bitrate" : "Codec & Bitrate", - "Link copied to clipboard" : "Adresse in die Zwischenablage kopiert", - "Error while copying link to clipboard" : "Fehler beim Speichern in die Zwischenablage", + "Podcast episodes" : "Podcast Episoden", + "Podcast" : "Podcast", + "🔊 Browse, manage and listen to podcasts" : "🔊 Browse, manage and listen to podcasts", + "**🔊 Browse, listen and subscribe to podcasts**\n\nFull featured podcatcher which uses the community index fyyd.de as a source.\n\n- 🔠Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- â Support episode chapters\n- 👂 Smoth audio playback and transitions" : "**🔊 Browse, listen and subscribe to podcasts**\n\nFull featured podcatcher which uses the community index fyyd.de as a source.\n\n- 🔠Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- â Support episode chapters\n- 👂 Smoth audio playback and transitions", + "Hide" : "Verstecken", + "Show" : "Anzeigen", + "episodes" : "Episoden", + "Error fetching favorite episodes" : "Fehler beim Laden der favorisierten Episoden", + "No episodes added yet!" : "Keine Episoden bis jetzt hinzugefügt!", + "Failed to fetch favorite podcast episodes" : "Fehler beim Laden der Podcast Episoden", + "Show all" : "Zeige alle", + "by" : "von", + "Show more" : "Zeige mehr", + "Show less" : "Zeige weniger", + "Unsubscribe" : "Abbestellen", + "Subscribe" : "Abonnieren", + "Listening" : "Aktuell höhrend", + "Library" : "Bibliothek", + "Browse" : "Durchsuchen", + "Search" : "Suchen", "Name" : "Name", - "Add to favorites" : "Zu den Favoriten hinzufügen", - "Remove from favorites" : "Von den Favoriten entfernen", - "Details" : "Weitere Informationen" + "Duration" : "Länge", + "Date" : "Datum", + "Go to episode" : "Gehe zu Episode", + "Go to show" : "Gehe zu Sendung", + "Download" : "Herunterladen", + "Share" : "Teilen", + "Remove from queue" : "Von Wiedergabeliste entfernen", + "Resume" : "Fortsetzen", + "Pause" : "Pausieren", + "Play" : "Abspielen", + "Hot podcasts" : "Zurzeit beliebte Podcasts", + "New podcasts" : "Neue Podcasts", + "Podcasts in" : "Podcasts in", + "Publication date" : "Veröffentlicht", + "Episode chapters" : "Kapitel", + "Pause episode" : "Episode pausieren", + "Resume episode" : "Episode fortsetzen", + "Play episode" : "Episode abspielen", + "Currently listening" : "Zuletzt gehört" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/lib/Controller/ExportController.php b/lib/Controller/ExportController.php new file mode 100644 index 0000000..11712d9 --- /dev/null +++ b/lib/Controller/ExportController.php @@ -0,0 +1,79 @@ +<?php + +/** + * Podcast App + * + * @author Jonas Heinrich + * @copyright 2021 Jonas Heinrich <onny@project-insanity.org> + * + * 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\Podcast\Controller; + +use OC; +use OCA\Podcast\ExportResponse; +use OCA\Podcast\AppInfo\Application; +use OCA\Podcast\Service\ShowService; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\DataResponse; +use OCP\IRequest; +use SimpleXMLElement; +use DOMDocument; + +class ExportController extends Controller { + /** @var ShowService */ + private $service; + + /** @var string */ + private $userId; + + use Errors; + + public function __construct(IRequest $request, + ShowService $service, + $userId) { + parent::__construct(Application::APP_ID, $request); + $this->service = $service; + $this->userId = $userId; + } + + /** + * @NoAdminRequired + */ + public function index() { + + $xml = new SimpleXMLElement('<?xml version="1.0"?><opml version="1.0"></opml>'); + $xml->addAttribute('encoding', 'UTF-8'); + $trackList = $xml->addChild('body'); + foreach($this->service->findAll($this->userId) as $show) { + $track = $trackList->addChild('outline'); + $track->addAttribute('type', 'rss'); + $track->addAttribute('text', $show->getTitle()); + $track->addAttribute('title', $show->getTitle()); + $track->addAttribute('xmlUrl', 'FIXME'); + $track->addAttribute('htmlUrl', 'FIXME'); + } + + $dom = new DOMDocument("1.0"); + $dom->preserveWhiteSpace = false; + $dom->formatOutput = true; + $dom->loadXML($xml->asXML()); + + return new ExportResponse($dom->saveXML()); + + } + +} diff --git a/lib/ExportResponse.php b/lib/ExportResponse.php new file mode 100644 index 0000000..a6b2bd8 --- /dev/null +++ b/lib/ExportResponse.php @@ -0,0 +1,56 @@ +<?php + +/** + * Podcast App + * + * @author Jonas Heinrich + * @copyright 2021 Jonas Heinrich <onny@project-insanity.org> + * + * 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\Podcast; + +use OC; +use OC\HintException; +use OCP\AppFramework\Http\Response; + +class ExportResponse extends Response { + private $returnstring; + + public function __construct($returnstring) { + parent::__construct(); + + $user = OC::$server->getUserSession()->getUser(); + if (is_null($user)) { + throw new HintException('User not logged in'); + } + + $userName = $user->getDisplayName(); + $productName = OC::$server->getThemingDefaults()->getName(); + $dateTime = OC::$server->getDateTimeFormatter(); + + $export_name = '"' . $productName . ' Podcast Subscriptions (' . $userName . ') (' . $dateTime->formatDate(time()) . ').opml"'; + $this->addHeader("Cache-Control", "private"); + $this->addHeader("Content-Type", " application/xml"); + $this->addHeader("Content-Length", strlen($returnstring)); + $this->addHeader("Content-Disposition", "attachment; filename=" . $export_name); + $this->returnstring = $returnstring; + } + + public function render() { + return $this->returnstring; + } +} diff --git a/src/components/ItemGrid.vue b/src/components/ItemGrid.vue index f053a18..170eed4 100644 --- a/src/components/ItemGrid.vue +++ b/src/components/ItemGrid.vue @@ -23,6 +23,20 @@ <div class="podcastSection"> <div class="podcastSectionHeader"> <h1>{{ title }}</h1> + <Actions v-show="showMenu"> + <ActionButton + icon="icon-add" + :close-after-click="true" + @click="showModal()"> + Add podcast feed + </ActionButton> + <ActionButton + icon="icon-download" + :close-after-click="true" + @click="$emit('doExport')"> + Export subscriptions + </ActionButton> + </Actions> </div> <div class="grid"> <div @@ -49,8 +63,16 @@ </template> <script> + +import Actions from '@nextcloud/vue/dist/Components/Actions' +import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' + export default { name: 'ItemGrid', + components: { + Actions, + ActionButton, + }, props: { title: { type: String, @@ -60,6 +82,10 @@ export default { type: Array, default() { return [] }, }, + showMenu: { + type: Boolean, + default: false, + }, }, } </script> diff --git a/src/views/Library.vue b/src/views/Library.vue index 7059fe0..17d3f97 100644 --- a/src/views/Library.vue +++ b/src/views/Library.vue @@ -23,7 +23,9 @@ <div class="mainContent"> <ItemGrid :title="t('podcast', 'Library')" - :podcasts="podcasts" /> + :show-menu="true" + :podcasts="podcasts" + @doExport="doExport" /> </div> </template> @@ -31,6 +33,7 @@ import ItemGrid from '../components/ItemGrid' import { mapGetters } from 'vuex' import { setBrowserTitle } from '../utils/misc.js' +import { getRequestToken } from '@nextcloud/auth' export default { name: 'Library', @@ -51,6 +54,15 @@ export default { mounted() { setBrowserTitle(t('podcast', 'Library')) }, + methods: { + + doExport() { + window.location + = 'export?requesttoken=' + + encodeURIComponent(getRequestToken()) + }, + + }, } </script> diff --git a/translationfiles/templates/podcast.pot b/translationfiles/templates/podcast.pot index 0649c79..04da818 100644 --- a/translationfiles/templates/podcast.pot +++ b/translationfiles/templates/podcast.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Nextcloud 3.14159\n" "Report-Msgid-Bugs-To: translations\\@example.com\n" -"POT-Creation-Date: 2021-03-14 13:20+0100\n" +"POT-Creation-Date: 2021-03-14 13:43+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" -- GitLab