Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • petre/nextcloud-app-podcast
  • onny/nextcloud-app-podcast
2 results
Show changes
Commits on Source (41)
......@@ -18,3 +18,4 @@ js/
build/
coverage/
utils/docker-ci
translationfiles/de/podcast.mo
......@@ -15,7 +15,8 @@ compiling:
script:
- apt update
- DEBIAN_FRONTEND="noninteractive" apt install -y gettext php php-simplexml
- npm install
- npm install -g pnpm
- pnpm install
- make build-js
- make translations
artifacts:
......@@ -42,12 +43,12 @@ testing:
packaging:
stage: packaging
image: ubuntu:rolling
script:
- apt update
- DEBIAN_FRONTEND="noninteractive" apt install -y wget sudo gettext php php-simplexml
- wget http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u12_amd64.deb
- wget https://github.com/ChristophWurst/krankerl/releases/download/v0.12.3/krankerl_0.12.3_amd64.deb
- sudo dpkg -i libssl1.0.0_1.0.1t-1+deb8u12_amd64.deb krankerl_0.12.3_amd64.deb
- DEBIAN_FRONTEND="noninteractive" apt install -y wget sudo gettext php php-simplexml nodejs pnpm git
- wget https://github.com/ChristophWurst/krankerl/releases/download/v0.13.0/krankerl_0.13.0_amd64.deb
- sudo dpkg -i krankerl_0.13.0_amd64.deb
- krankerl package
artifacts:
paths:
......
......@@ -6,6 +6,7 @@
/.gitlab-ci.yml
/.l10nignore
/.nextcloudignore
/tsconfig.json
/node_modules
/.npmignore
/babel.config.js
......
## 0.4.0 - 2021-XX
Please note that this is still a preview release. It should demonstrate basic
functionality and the user interface. Some main features of a podcatcher are not
yet implemented.
### Known issues
- There is no background job yet to fetch and display new episodes
[#114](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/114) @onny
### Changed
- Update pnpm modules
[#235](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/235) @onny
- Switch from npm to pnpm
[#234](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/234) @onny
- Add support for Nextcloud 22
[#229](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/229) @onny
- Switch donation address from Bitcoin to Mobilecoin
[#237](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/237) @onny
## 0.3.1 - 2021-03
Please note that this is still a preview release. It should demonstrate basic
functionality and the user interface. Some main features of a podcatcher are not
yet implemented.
### Known issues
- There is no background job yet to fetch and display new episodes
[#114](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/114) @onny
### Added
- Export podcast subscriptions as OPML
[#104](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/104) @onny
- German translation
[#183](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/183) @onny
- Make player metadata, title and show name as links
[#167](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/167) @onny
- Add pagination to listening and library view
[#195](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/195) @onny
- Show newest podcasts and episodes in library view
[#214](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/214) @onny
### Fixed
- Listening view: Only show episods with playtime
[#213](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/213) @onny
- Library view: Show list of newest episodes (which are present in the database)
[#213](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/213) @onny
- Episodes playback state is only saved and used in "Listening" view
[#159](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/159) @onny
- Fix issues with database migration on Mysql backends
[#176](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/176) @onny
### Changed
- Update npm modules
[#181](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/181) @onny
- CI: Update krankerl
[#179](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/179) @onny
- Api use getRequestToken
[#180](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/180) @onny
- Less mixed content: query fyyd api on server side
[#194](https://git.project-insanity.org/onny/nextcloud-app-podcast/-/issues/194) @onny
## 0.2 - 2021-02
Please note that this is still a preview release. It should demonstrate basic
......
......@@ -7,44 +7,44 @@ all: dev-setup lint build-js-production test
dev-setup: clean clean-dev npm-init
npm-init:
npm ci
pnpm ci
npm-update:
npm update
pnpm update
# Building
build-js:
npm run dev
pnpm run dev
build-js-production:
npm run build
pnpm run build
watch-js:
npm run watch
pnpm run watch
# Testing
test:
npm run test
pnpm run test
test-watch:
npm run test:watch
pnpm run test:watch
test-coverage:
npm run test:coverage
pnpm run test:coverage
# Linting
lint:
npm run lint
pnpm run lint
lint-fix:
npm run lint:fix
pnpm run lint:fix
# Style linting
stylelint:
npm run stylelint
pnpm run stylelint
stylelint-fix:
npm run stylelint:fix
pnpm run stylelint:fix
# Cleaning
clean:
......
......@@ -11,6 +11,7 @@ uses the directory [fyyd.de](https://fyyd.de) as a source.
- [ ] Check newly released episodes
- [x] Support for chapters in episodes
- [x] Support for links and timecodes in episode notes
- [ ] Import and export subscriptions
- [x] Mobile friendly interface
- [x] Unified search integration
- [ ] Dashboard integration
......@@ -47,7 +48,8 @@ have to submit it first there.
Can be easily tested using Docker:
```
docker run -v /tmp/nextcloud-app-podcast:/opt/nextcloud/apps/podcast -d --name nextcloud-app-podcast -p 80:80 rootlogin/nextcloud:20.0.6
docker build https://git.project-insanity.org/onny/docker-nextcloud.git nextcloud
docker run -v /tmp/nextcloud-app-podcast:/opt/nextcloud/apps/podcast -d --name nextcloud-app-podcast -p 80:80 nextcloud
```
First part of -v is the path to the cloned and compiled or downloaded Nextcloud Podcast app. Debug running container it with:
```
......@@ -89,7 +91,7 @@ make translations
```
Use the source file ``translationfiles/template/podcast.pot`` to create
translations. For example, contribute translations via
[Transifex](https://www.transifex.com/project-insanityorg/podcast-2/dashboard/).
[Transifex](https://www.transifex.com/project-insanityorg/podcast-1/dashboard/).
Put the translated language file into the corresponding template folder. For
example the German language file should be placed at
......@@ -108,9 +110,9 @@ You can report bugs in the public gitlab repository [here](https://git.project-i
For now only German translations are provided, so please submit your translations if possible :) It's really easy, just `git clone` this repo and copy the translation files in `l10n` according to your locale. Merge requests go to [this podcast repository](https://git.project-insanity.org/onny/nextcloud-app-podcast).
### Donation
If you like this app and want to support my work, you can donate to this Bitcoin address:
If you like this app and want to support my work, you can donate to this [MobileCoin](https://mobilecoin.com) address:
```
19mpmuNczGDgdxaBLBn3REEpQLPPcJHZB6
v2Z6pvq2zWLmQeP1ywxe9G4k3wQqbxrNvLk8zF1XVJjkvyd3dVjJmyHysyG1hHehiPPyKFkgoPHHBRGnDp4CzpJUxd2g5vWcTvfHukMy7iQaVEgkeErWkQnzey3ArnAPMhMB6DJYkqYQ2DjYNAwqFBvrS3rjiBEgo9aM6LEUuJmeckai9UTaKA9g9sH8k5TwKUMmmLx35Y3gn8zGMVsWxc8e2UuLRho9Gwvs4eiMmV634QkKLASxtYq24SbzxPdc9p
```
## Credits
......
......@@ -6,8 +6,7 @@
<summary>🔊 Browse, manage and listen to podcasts</summary>
<description>**🔊 Browse, listen and subscribe to podcasts**
Full featured podcatcher which uses the community index fyyd.de as a
source.
Full featured podcatcher which uses the community index fyyd.de as a source.
- 🔍 Browse and subscribe huge collection of podcasts
- 🔊 Listen to episodes directly in Nextcloud
......@@ -15,7 +14,7 @@
- 👂 Smoth audio playback and transitions
</description>
<version>0.2.0</version>
<version>0.4.0</version>
<licence>agpl</licence>
<author mail="onny@project-insanity.org" >Jonas Heinrich</author>
<namespace>Podcast</namespace>
......@@ -27,7 +26,7 @@
<screenshot small-thumbnail="https://git.project-insanity.org/onny/nextcloud-app-podcast/raw/master/dist/screenshot-thumbnail3.jpg">https://git.project-insanity.org/onny/nextcloud-app-podcast/raw/master/dist/screenshot3.png</screenshot>
<dependencies>
<php min-version="7.4" max-version="8" />
<nextcloud min-version="20" max-version="21"/>
<nextcloud min-version="20" max-version="22"/>
</dependencies>
<navigations>
<navigation>
......
......@@ -25,6 +25,7 @@ return [
'resources' => [
'show' => ['url' => '/api/shows'],
'episode' => ['url' => '/api/episodes'],
'export' => ['url' => '/export'],
],
'routes' => [
......
......@@ -19,6 +19,6 @@
*
*/
@include icon-black-white('recent', 'podcast', 1);
@include icon-black-white('header', 'podcast', 1);
@include icon-black-white('podcast', 'podcast', 1);
@include icon-black-white('podcast-trans', 'podcast', 1);
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="header.svg"
id="svg44"
version="1.1"
viewBox="0 0 24 24"
height="24"
width="24">
<metadata
id="metadata50">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs48" />
<sodipodi:namedview
inkscape:current-layer="svg44"
inkscape:window-maximized="1"
inkscape:window-y="0"
inkscape:window-x="0"
inkscape:cy="3.1647928"
inkscape:cx="23.500195"
inkscape:zoom="5.6882691"
showgrid="false"
id="namedview46"
inkscape:window-height="872"
inkscape:window-width="1436"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<g
style="fill:#000000"
id="g42"
fill-rule="evenodd"
fill="#ffffff">
<path
style="fill:#000000"
id="path40"
d="M13 2v20h-2V2zM6 6v12H4V6zM20 6v12h-2V6z" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0">
<rect style="color:#000000" fill-opacity="0" height="97.986" width="163.31" y="-32.993" x="-62.897"/>
<path style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m8 0c-4.4064 0-8 3.5936-8 8 0 4.406 3.5936 8 8 8 4.406 0 8-3.594 8-8 0-4.4064-3.594-8-8-8zm0 2c3.326 0 6 2.6744 6 6 0 3.326-2.674 6-6 6-3.3256 0-6-2.674-6-6 0-3.3256 2.6744-6 6-6zm-0.4414 0.9316c-0.334 0.0075-0.6014 0.2793-0.6035 0.6133l-0.8516 4.4414v0.0117c-0.1821 0.7569 0.3361 1.002 0.916 1.3536l0.0059 0.0019 2.9976 1.5785c0.653 0.502 1.407-0.476 0.754-0.9789l-1.777-1.9453v-0.0078l-0.8086-4.4492c0.0011-0.3478-0.2851-0.6279-0.6328-0.6192z"/>
</svg>
OC.L10N.register(
"radio",
"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);");
{ "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
......@@ -67,8 +67,6 @@ class Application extends App implements IBootstrap {
public function registerCsp() {
$manager = $this->getContainer()->getServer()->getContentSecurityPolicyManager();
$policy = new ContentSecurityPolicy();
$policy->addAllowedConnectDomain('https://de1.api.radio-browser.info');
$policy->addAllowedConnectDomain('https://api.fyyd.de');
$policy->addAllowedImageDomain('*');
$policy->addAllowedMediaDomain('*');
$manager->addDefaultPolicy($policy);
......
......@@ -25,14 +25,25 @@ namespace OCA\Podcast\Controller;
use OCA\Podcast\AppInfo\Application;
use OCA\Podcast\Service\EpisodeService;
use OCA\Podcast\Service\FyydApiService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest;
use OCP\ILogger;
use OCP\Http\Client\IClientService;
class EpisodeController extends Controller {
/** @var ILogger */
private $logger;
/** @var EpisodesService */
private $service;
/** @var FyydApiService */
private $fyydapi;
/** @var string */
private $userId;
......@@ -40,17 +51,69 @@ class EpisodeController extends Controller {
public function __construct(IRequest $request,
EpisodeService $service,
FyydApiService $fyydapi,
ILogger $logger,
$userId) {
parent::__construct(Application::APP_ID, $request);
$this->service = $service;
$this->fyydapi = $fyydapi;
$this->logger = $logger;
$this->userId = $userId;
}
/**
* @NoAdminRequired
*/
public function index(): DataResponse {
return new DataResponse($this->service->findAll($this->userId));
public function index(int $episode_id = null, int $podcast_id = null,
int $count = 20, int $page = 0, string $sortBy = null): DataResponse {
$data = $this->service->findAll($this->userId, $sortBy);
if ($episode_id) {
$list = $this->fyydapi->queryEpisode($episode_id);
foreach($data as $localEpisode) {
if ($localEpisode->getId() === $list['data']['id']) {
$list['data']['lastplayed'] = $localEpisode->getLastplayed();
$list['data']['playtime'] = $localEpisode->getPlaytime();
}
}
return new DataResponse($list);
} else if ($podcast_id) {
$list = $this->fyydapi->queryEpisodes($podcast_id, $count, $page);
foreach($list['data']['episodes'] as $key=>$fyydEpisode) {
foreach($data as $localEpisode) {
if ($localEpisode->getId() === $fyydEpisode['id']) {
$list['data']['episodes'][$key]['lastplayed'] = $localEpisode->getLastplayed();
$list['data']['episodes'][$key]['playtime'] = $localEpisode->getPlaytime();
}
}
}
return new DataResponse($list);
}
$data = array_slice($data, $page * $count, $count);
if (count($data) === $count) {
$nextPage = $page + 1;
} else {
$nextPage = null;
};
$response = [
"meta" => [
"paging" => [
"next_page" => $nextPage,
],
],
"data" => [
"episodes" => $data,
],
];
return new DataResponse($response);
}
/**
......@@ -65,27 +128,27 @@ class EpisodeController extends Controller {
/**
* @NoAdminRequired
*/
public function create(int $id, string $imgurl, string $title,
public function create(int $id, string $imgURL, string $title,
string $pubdate, int $duration, int $playtime, int $lastplayed,
string $enclosure, string $description, int $podcastid
string $enclosure, string $description, int $podcast_id
): DataResponse {
return new DataResponse($this->service->create($id, $imgurl, $title,
return new DataResponse($this->service->create($id, $imgURL, $title,
$pubdate, $duration, $playtime, $lastplayed, $enclosure, $description,
$podcastid, $this->userId));
$podcast_id, $this->userId));
}
/**
* @NoAdminRequired
*/
public function update(int $id, string $imgurl, string $title,
public function update(int $id, string $imgURL, string $title,
string $pubdate, int $duration, int $playtime, int $lastplayed,
string $enclosure, string $description, int $podcastid
string $enclosure, string $description, int $podcast_id
): DataResponse {
return $this->handleNotFound(function () use ($id, $imgurl, $title,
return $this->handleNotFound(function () use ($id, $imgURL, $title,
$pubdate, $duration, $playtime, $lastplayed, $enclosure, $description,
$podcastid) {
return $this->service->update($id, $imgurl, $title, $pubdate, $duration,
$playtime, $lastplayed, $enclosure, $description, $podcastid,
$podcast_id) {
return $this->service->update($id, $imgURL, $title, $pubdate, $duration,
$playtime, $lastplayed, $enclosure, $description, $podcast_id,
$this->userId);
});
}
......
<?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>');
$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', $show->getFeedurl());
$track->addAttribute('htmlUrl', $show->getHomepage());
}
$dom = new DOMDocument("1.0");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());
return new ExportResponse($dom->saveXML());
}
}
......@@ -25,6 +25,7 @@ namespace OCA\Podcast\Controller;
use OCA\Podcast\AppInfo\Application;
use OCA\Podcast\Service\ShowService;
use OCA\Podcast\Service\FyydApiService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest;
......@@ -33,6 +34,9 @@ class ShowController extends Controller {
/** @var ShowsService */
private $service;
/** @var FyydApiService */
private $fyydapi;
/** @var string */
private $userId;
......@@ -40,17 +44,55 @@ class ShowController extends Controller {
public function __construct(IRequest $request,
ShowService $service,
FyydApiService $fyydapi,
$userId) {
parent::__construct(Application::APP_ID, $request);
$this->service = $service;
$this->fyydapi = $fyydapi;
$this->userId = $userId;
}
/**
* @NoAdminRequired
*/
public function index(): DataResponse {
return new DataResponse($this->service->findAll($this->userId));
public function index(int $podcast_id = null, string $category = null,
int $count = 20, int $page = 0): DataResponse {
$data = $this->service->findAll($this->userId);
if ($category) {
$list = $this->fyydapi->queryCategory($category, $count, $page);
return new DataResponse($list);
} else if ($podcast_id) {
$list = $this->fyydapi->queryPodcast($podcast_id);
foreach($data as $localEpisode) {
if ($localEpisode->getId() === $list['data']['id']) {
$list['data']['dateadded'] = intval($localEpisode->getDateadded());
}
}
return new DataResponse($list);
}
$data = array_slice($data, $page * $count, $count);
if (count($data) === $count) {
$nextPage = $page + 1;
} else {
$nextPage = null;
};
$response = [
"meta" => [
"paging" => [
"next_page" => $nextPage,
],
],
"data" => $data,
];
return new DataResponse($response);
}
/**
......@@ -65,21 +107,23 @@ class ShowController extends Controller {
/**
* @NoAdminRequired
*/
public function create(int $id, string $imgurl, string $author,
string $title, string $lastpub, int $dateadded): DataResponse {
return new DataResponse($this->service->create($id, $imgurl, $author,
$title, $lastpub, $dateadded, $this->userId));
public function create(int $id, string $smallImageURL, string $author,
string $title, string $lastpub, int $dateadded, string $homepage,
string $feedurl): DataResponse {
return new DataResponse($this->service->create($id, $smallImageURL, $author,
$title, $lastpub, $dateadded, $homepage, $feedurl, $this->userId));
}
/**
* @NoAdminRequired
*/
public function update(int $id, string $imgurl, string $author,
string $title, string $lastpub, int $dateadded): DataResponse {
return $this->handleNotFound(function () use ($id, $imgurl, $author,
$title, $lastpub, $dateadded) {
return $this->service->update($id, $imgurl, $author, $title, $lastpub,
$dateadded, $this->userId);
public function update(int $id, string $smallImageURL, string $author,
string $title, string $lastpub, int $dateadded, string $homepage,
string $feedurl): DataResponse {
return $this->handleNotFound(function () use ($id, $smallImageURL, $author,
$title, $lastpub, $dateadded, $homepage, $feedurl) {
return $this->service->update($id, $smallImageURL, $author, $title, $lastpub,
$dateadded, $homepage, $feedurl, $this->userId);
});
}
......
......@@ -42,7 +42,7 @@ class Episode extends Entity implements JsonSerializable {
public function jsonSerialize(): array {
return [
'id' => $this->id,
'imgurl' => $this->imgurl,
'imgURL' => $this->imgurl,
'title' => $this->title,
'pubdate' => $this->pubdate,
'duration' => $this->duration,
......@@ -50,7 +50,7 @@ class Episode extends Entity implements JsonSerializable {
'lastplayed' => $this->lastplayed,
'enclosure' => $this->enclosure,
'description' => $this->description,
'podcastid' => $this->podcastid,
'podcast_id' => $this->podcastid,
];
}
}
......@@ -55,13 +55,29 @@ class EpisodeMapper extends QBMapper {
* @param string $userId
* @return array
*/
public function findAll(string $userId): array {
public function findAll(string $userId, string $sortBy = null): array {
if ($sortBy) {
if ($sortBy === 'pubdate') {
$sortBy = 'pubdate';
} else {
$sortBy = 'lastplayed';
}
} else {
$sortBy = 'lastplayed';
};
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from('episodes')
->orderBy('lastplayed', 'DESC')
->orderBy($sortBy, 'DESC')
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
/* For listening view, query only episodes which were already
listened */
if ($sortBy === 'lastplayed') {
$qb->andWhere($qb->expr()->gt('playtime',$qb->createNamedParameter(0)));
};
return $this->findEntities($qb);
}
}
......@@ -33,16 +33,20 @@ class Show extends Entity implements JsonSerializable {
protected $title;
protected $lastpub;
protected $dateadded;
protected $homepage;
protected $feedurl;
protected $userId;
public function jsonSerialize(): array {
return [
'id' => $this->id,
'imgurl' => $this->imgurl,
'smallImageURL' => $this->imgurl,
'author' => $this->author,
'title' => $this->title,
'lastpub' => $this->lastpub,
'dateadded' => $this->dateadded,
'homepage' => $this->homepage,
'feedurl' => $this->feedurl,
];
}
}