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
Showing
with 9967 additions and 1547 deletions
......@@ -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,24 +128,28 @@ class EpisodeController extends Controller {
/**
* @NoAdminRequired
*/
public function create(int $id, string $imgurl, string $author,
string $title, string $pubdate, string $duration, string $playtime,
string $lastplayed, string $enclosure): DataResponse {
return new DataResponse($this->service->create($id, $imgurl, $author,
$title, $pubdate, $duration, $playtime, $lastplayed, $enclosure,
$this->userId));
public function create(int $id, string $imgURL, string $title,
string $pubdate, int $duration, int $playtime, int $lastplayed,
string $enclosure, string $description, int $podcast_id
): DataResponse {
return new DataResponse($this->service->create($id, $imgURL, $title,
$pubdate, $duration, $playtime, $lastplayed, $enclosure, $description,
$podcast_id, $this->userId));
}
/**
* @NoAdminRequired
*/
public function update(int $id, string $imgurl, string $author,
string $title, string $pubdate, string $duration, string $playtime,
string $lastplayed, string $enclosure): DataResponse {
return $this->handleNotFound(function () use ($id, $imgurl, $author,
$title, $pubdate, $duration, $playtime, $lastplayed, $enclosure) {
return $this->service->update($id, $imgurl, $author, $title, $pubdate,
$duration, $playtime, $lastplayed, $enclosure, $this->userId);
public function update(int $id, string $imgURL, string $title,
string $pubdate, int $duration, int $playtime, int $lastplayed,
string $enclosure, string $description, int $podcast_id
): DataResponse {
return $this->handleNotFound(function () use ($id, $imgURL, $title,
$pubdate, $duration, $playtime, $lastplayed, $enclosure, $description,
$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): DataResponse {
return new DataResponse($this->service->create($id, $imgurl, $author,
$title, $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): DataResponse {
return $this->handleNotFound(function () use ($id, $imgurl, $author,
$title) {
return $this->service->update($id, $imgurl, $author, $title,
$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);
});
}
......
......@@ -29,26 +29,28 @@ use OCP\AppFramework\Db\Entity;
class Episode extends Entity implements JsonSerializable {
protected $imgurl;
protected $author;
protected $title;
protected $pubdate;
protected $duration;
protected $playtime;
protected $lastplayed;
protected $enclosure;
protected $description;
protected $podcastid;
protected $userId;
public function jsonSerialize(): array {
return [
'id' => $this->id,
'imgurl' => $this->imgurl,
'author' => $this->author,
'imgURL' => $this->imgurl,
'title' => $this->title,
'pubdate' => $this->pubdate,
'duration' => $this->duration,
'playtime' => $this->playtime,
'lastplayed' => $this->lastplayed,
'enclosure' => $this->enclosure,
'description' => $this->description,
'podcast_id' => $this->podcastid,
];
}
}
......@@ -55,12 +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($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);
}
}
......@@ -31,14 +31,22 @@ class Show extends Entity implements JsonSerializable {
protected $imgurl;
protected $author;
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,
];
}
}
......@@ -46,6 +46,7 @@ class ShowMapper extends QBMapper {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from('shows')
->orderBy('dateadded', 'DESC')
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
return $this->findEntity($qb);
......@@ -60,6 +61,7 @@ class ShowMapper extends QBMapper {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from('shows')
->orderBy('lastpub', 'DESC')
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
return $this->findEntities($qb);
}
......
<?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;
}
}
<?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/>.
*
*/
declare(strict_types=1);
namespace OCA\Podcast\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\SimpleMigrationStep;
use OCP\Migration\IOutput;
use Doctrine\DBAL\Types\Type;
class Version000100Date20210201162900 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @return void
*/
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @return ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('shows');
$table->addColumn('lastpub', 'string', [
'notnull' => false,
]);
$table->addColumn('dateadded', 'bigint', [
'notnull' => false,
]);
$table = $schema->getTable('episodes');
$table->addColumn('description', 'string', [
'notnull' => false,
]);
$table->addColumn('podcastid', 'integer', [
'notnull' => true,
]);
if ($table->hasColumn('playtime')) {
$table->dropColumn('playtime');
$table->addColumn('playtime', 'integer');
};
if ($table->hasColumn('duration')) {
$table->dropColumn('duration');
$table->addColumn('duration', 'integer');
};
if ($table->hasColumn('lastplayed')) {
$table->dropColumn('lastplayed');
$table->addColumn('lastplayed', 'bigint');
};
if ($table->hasColumn('author')) {
$table->dropColumn('author');
};
return $schema;
}
}
<?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/>.
*
*/
declare(strict_types=1);
namespace OCA\Podcast\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\SimpleMigrationStep;
use OCP\Migration\IOutput;
use Doctrine\DBAL\Types\Type;
class Version000100Date20210315125200 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @return void
*/
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @return ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('shows');
$table->addColumn('homepage', 'string', [
'notnull' => false,
]);
$table->addColumn('feedurl', 'string', [
'notnull' => false,
]);
$table = $schema->getTable('episodes');
return $schema;
}
}
......@@ -40,8 +40,8 @@ class EpisodeService {
$this->mapper = $mapper;
}
public function findAll(string $userId): array {
return $this->mapper->findAll($userId);
public function findAll(string $userId, string $sortBy = null): array {
return $this->mapper->findAll($userId, $sortBy);
}
private function handleException(Exception $e): void {
......@@ -66,34 +66,36 @@ class EpisodeService {
}
}
public function create($id, $imgurl, $author, $title, $pubdate, $duration,
$playtime, $lastplayed, $enclosure, $userId) {
public function create($id, $imgurl, $title, $pubdate, $duration, $playtime,
$lastplayed, $enclosure, $description, $podcastid, $userId) {
$episode = new Episode();
$episode->setId($id);
$episode->setImgurl($imgurl);
$episode->setAuthor($author);
$episode->setTitle($title);
$episode->setPubdate($pubdate);
$episode->setDuration($duration);
$episode->setPlaytime($playtime);
$episode->setLastplayed($lastplayed);
$episode->setEnclosure($enclosure);
$episode->setDescription($description);
$episode->setPodcastid($podcastid);
$episode->setUserId($userId);
return $this->mapper->insert($episode);
}
public function update($id, $imgurl, $author, $title, $pubdate, $duration,
$playtime, $lastplayed, $enclosure, $userId) {
public function update($id, $imgurl, $title, $pubdate, $duration, $playtime,
$lastplayed, $enclosure, $description, $podcastid, $userId) {
try {
$episode = $this->mapper->find($id, $userId);
$episode->setImgurl($imgurl);
$episode->setAuthor($author);
$episode->setTitle($title);
$episode->setPubdate($pubdate);
$episode->setDuration($duration);
$episode->setPlaytime($playtime);
$episode->setLastplayed($lastplayed);
$episode->setEnclosure($enclosure);
$episode->setDescription($description);
$episode->setPodcastid($podcastid);
return $this->mapper->update($episode);
} catch (Exception $e) {
$this->handleException($e);
......
<?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/>.
*
*/
declare(strict_types=1);
namespace OCA\Podcast\Service;
use OCP\IURLGenerator;
use OCP\Http\Client\IClientService;
use function urlencode;
class FyydApiService {
/** @var IClientService */
private $clientService;
/** @var IURLGenerator */
private $url;
public $baseUrl = "https://api.fyyd.de/0.2";
public function __construct(
IClientService $clientService,
IURLGenerator $url
) {
$this->clientService = $clientService;
$this->url = $url;
}
public function queryEpisodes(int $podcast_id, int $count = 20, int $page = 0) {
$url = $this->baseUrl . "/podcast/episodes";
$options['query'] = [
'podcast_id' => $podcast_id,
'count' => $count,
'page' => $page
];
$client = $this->clientService->newClient();
try {
$response = $client->get($url, $options);
} catch (Exception $e) {
$this->logger->error("Could not search for podcasts: " . $e->getMessage());
throw $e;
}
$body = $response->getBody();
$parsed = json_decode($body, true);
return $parsed;
}
public function queryEpisode(int $episode_id) {
$url = $this->baseUrl . "/episode";
$options['query'] = [
'episode_id' => $episode_id,
];
$client = $this->clientService->newClient();
try {
$response = $client->get($url, $options);
} catch (Exception $e) {
$this->logger->error("Could not search for podcasts: " . $e->getMessage());
throw $e;
}
$body = $response->getBody();
$parsed = json_decode($body, true);
return $parsed;
}
public function queryPodcast(int $podcast_id) {
$url = $this->baseUrl . "/podcast";
$options['query'] = [
'podcast_id' => $podcast_id,
];
$client = $this->clientService->newClient();
try {
$response = $client->get($url, $options);
} catch (Exception $e) {
$this->logger->error("Could not search for podcasts: " . $e->getMessage());
throw $e;
}
$body = $response->getBody();
$parsed = json_decode($body, true);
return $parsed;
}
public function queryCategory(string $category, int $count = 20,
int $page = 0) {
if ($category === 'hot') {
$url = $this->baseUrl . "/feature/podcast/hot";
$options['query'] = [
'count' => $count,
'page' => $page,
];
} else if ($category === 'latest') {
$url = $this->baseUrl . "/podcast/latest";
$options['query'] = [
'count' => $count,
'page' => $page,
];
} else {
$url = $this->baseUrl . "/category";
$options['query'] = [
'count' => $count,
'page' => $page,
'category_id' => $category,
];
}
$client = $this->clientService->newClient();
try {
$response = $client->get($url, $options);
} catch (Exception $e) {
$this->logger->error("Could not search for podcasts: " . $e->getMessage());
throw $e;
}
$body = $response->getBody();
$parsed = json_decode($body, true);
return $parsed;
}
}
......@@ -66,22 +66,32 @@ class ShowService {
}
}
public function create($id, $imgurl, $author, $title, $userId) {
public function create($id, $imgurl, $author, $title, $lastpub, $dateadded,
$homepage, $feedurl, $userId) {
$show = new Show();
$show->setId($id);
$show->setImgurl($imgurl);
$show->setAuthor($author);
$show->setTitle($title);
$show->setLastpub($lastpub);
$show->setDateadded($dateadded);
$show->setHomepage($homepage);
$show->setFeedurl($feedurl);
$show->setUserId($userId);
return $this->mapper->insert($show);
}
public function update($id, $imgurl, $author, $title, $userId) {
public function update($id, $imgurl, $author, $title, $lastpub, $dateadded,
$homepage, $feedurl, $userId) {
try {
$show = $this->mapper->find($id, $userId);
$show->setImgurl($imgurl);
$show->setAuthor($author);
$show->setTitle($title);
$show->setLastpub($lastpub);
$show->setDateadded($dateadded);
$show->setHomepage($homepage);
$show->setFeedurl($feedurl);
return $this->mapper->update($show);
} catch (Exception $e) {
$this->handleException($e);
......
This diff is collapsed.
{
"name": "podcast",
"description": "Listen to your favorite podcast shows in Nextcloud",
"version": "0.0.1",
"version": "0.4.0",
"author": "Jonas Heinrich <onny@project-insanity.org>",
"contributors": [
"Jonas Heinrich <onny@project-insanity.org>"
......@@ -30,26 +30,34 @@
"stylelint:fix": "stylelint src --fix"
},
"dependencies": {
"@nextcloud/axios": "^1.5.0",
"@nextcloud/dialogs": "^3.1.1",
"@babel/eslint-parser": "^7.15.8",
"@nextcloud/auth": "^1.3.0",
"@nextcloud/axios": "^1.7.0",
"@nextcloud/dialogs": "^3.1.2",
"@nextcloud/l10n": "^1.4.1",
"@nextcloud/moment": "^1.1.1",
"@nextcloud/router": "^1.2.0",
"@nextcloud/vue": "^2.9.0",
"@nextcloud/vue-dashboard": "^1.0.1",
"autoprefixer": "^9.8.6",
"howler": "^2.2.1",
"javascript-time-ago": "^2.3.3",
"music-metadata": "^7.5.0",
"postcss-loader": "^4.1.0",
"style-loader": "^2.0.0",
"vue": "^2.6.12",
"vue-content-loader": "^0.2.3",
"@nextcloud/router": "^2.0.0",
"@nextcloud/vue": "^4.2.0",
"@nextcloud/vue-dashboard": "^2.0.1",
"autoprefixer": "^10.3.7",
"eslint-plugin-jsdoc": "^36.1.1",
"eslint-webpack-plugin": "^3.0.1",
"howler": "^2.2.3",
"javascript-time-ago": "^2.3.9",
"linkify-string": "^3.0.3",
"music-metadata": "^7.11.4",
"node-polyfill-webpack-plugin": "^1.1.4",
"postcss-loader": "^6.2.0",
"splitpanes": "^2.3.8",
"style-loader": "^3.3.0",
"vue": "^2.6.14",
"vue-content-loader": "^2.0.0",
"vue-lazyload": "^1.3.3",
"vue-resize-observer": "^1.0.32",
"vue-router": "^3.4.9",
"vue-material-design-icons": "^4.13.0",
"vue-resize-directive": "^1.2.0",
"vue-router": "^3.5.2",
"vue-show-more-text": "^2.0.2",
"vuex": "^3.5.1"
"vuex": "^3.6.2"
},
"browserslist": [
"extends @nextcloud/browserslist-config"
......@@ -58,38 +66,35 @@
"node": ">=10.0.0"
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/core": "^7.15.8",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/preset-env": "^7.12.1",
"@nextcloud/browserslist-config": "^1.0.0",
"@nextcloud/eslint-config": "^2.2.0",
"@nextcloud/eslint-plugin": "^1.5.0",
"@nextcloud/webpack-vue-config": "^1.4.1",
"@vue/test-utils": "^1.1.1",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.1",
"css-loader": "^3.6.0",
"eslint": "^6.8.0",
"eslint-config-standard": "^14.1.1",
"eslint-import-resolver-webpack": "^0.13.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-html": "^6.1.1",
"eslint-plugin-import": "^2.22.1",
"@babel/preset-env": "^7.15.8",
"@nextcloud/browserslist-config": "^2.2.0",
"@nextcloud/eslint-config": "^6.1.0",
"@nextcloud/eslint-plugin": "^2.0.0",
"@nextcloud/webpack-vue-config": "^4.1.0",
"@vue/test-utils": "^1.2.2",
"babel-loader": "^8.2.2",
"css-loader": "^6.4.0",
"eslint": "^8.0.1",
"eslint-config-standard": "^16.0.3",
"eslint-import-resolver-webpack": "^0.13.1",
"eslint-plugin-html": "^6.2.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.1.0",
"eslint-plugin-vue": "^6.2.2",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^7.19.1",
"file-loader": "^6.2.0",
"node-sass": "^4.14.1",
"sass-loader": "^8.0.2",
"stylelint": "^13.8.0",
"stylelint-config-recommended-scss": "^4.2.0",
"stylelint-scss": "^3.18.0",
"stylelint-webpack-plugin": "^2.1.1",
"vue-loader": "^15.9.5",
"vue-template-compiler": "^2.6.12",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-merge": "^5.4.0"
"node-sass": "^6.0.1",
"sass-loader": "^12.2.0",
"stylelint": "^13.13.1",
"stylelint-config-recommended-scss": "^4.3.0",
"stylelint-scss": "^3.21.0",
"stylelint-webpack-plugin": "^3.0.1",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.58.2",
"webpack-cli": "^4.9.0",
"webpack-merge": "^5.8.0"
}
}
This diff is collapsed.
screenshot-thumbnail.jpg

26.8 KiB

screenshot.png

259 KiB

......@@ -26,6 +26,10 @@
<AppContent>
<router-view />
</AppContent>
<Player />
<!-- <div class="floatControl">
Skip intro
</div> -->
</Content>
</template>
......@@ -33,6 +37,7 @@
import Content from '@nextcloud/vue/dist/Components/Content'
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
import Navigation from './components/Navigation'
import Player from './components/Player'
export default {
name: 'App',
......@@ -40,11 +45,11 @@ export default {
Content,
Navigation,
AppContent,
Player,
},
created() {
this.$store.dispatch('loadShows')
this.$store.dispatch('loadEpisodes')
this.$store.dispatch('loadVolume')
this.$store.dispatch('loadEpisodes')
},
}
</script>
......@@ -57,4 +62,35 @@ export default {
}
}
.app-content {
overflow: scroll;
height: calc(100vh - 98px);
}
.app-navigation {
bottom: 80px;
}
.floatControl {
position: fixed;
bottom: 75px;
right: 25px;
height: 45px;
width: 120px;
background: rgba(66, 66, 66, 0.48);
z-index: 8001;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
border: 1px solid #464646;
cursor: pointer;
&:hover {
// background: rgba(161, 161, 161, 0.48);
background: rgba(66, 66, 66, 0.7);
}
}
</style>