search in PHP completed

This commit is contained in:
Michel Roux 2023-07-27 23:01:24 +02:00
parent 431cbf0c42
commit 2a4662e85b
6 changed files with 99 additions and 35 deletions

View File

@ -6,11 +6,16 @@ require_once './vendor/autoload.php';
use Nextcloud\CodingStandard\Config;
class MyConfig extends Config {
class MyConfig extends Config
{
public function getRules(): array
{
$rules = parent::getRules();
$rules['@PhpCsFixer'] = true;
$rules['curly_braces_position']['classes_opening_brace'] = 'next_line_unless_newline_at_signature_end';
$rules['phpdoc_separation'] = false;
$rules['phpdoc_to_comment'] = false;
$rules['single_line_comment_style'] = false;
return $rules;
}
}

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
/**
* Create your routes in here. The name is the lowercase name of the controller
* without the controller part, the stuff after the hash is the method.
* e.g. page#index -> OCA\RePod\Controller\PageController->index()
* e.g. page#index -> OCA\RePod\Controller\PageController->index().
*
* The controller class has to be registered in the application.php file since
* it's instantiated in there
@ -14,6 +14,6 @@ return [
'routes' => [
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
['name' => 'top#index', 'url' => '/top/{count}', 'verb' => 'GET'],
['name' => 'search#index', 'url' => '/search/{value}', 'verb' => 'GET']
]
['name' => 'search#index', 'url' => '/search/{value}', 'verb' => 'GET'],
],
];

View File

@ -18,13 +18,16 @@ class Application extends App implements IBootstrap
public const APP_ID = 'repod';
private const GPODDERSYNC_ID = 'gpoddersync';
public function __construct() {
public function __construct()
{
parent::__construct(self::APP_ID);
}
public function boot(IBootContext $context): void {
public function boot(IBootContext $context): void
{
/** @psalm-suppress DeprecatedInterface */
$appContainer = $context->getAppContainer();
/** @var IAppManager $appManager */
$appManager = $appContainer->get(IAppManager::class);
@ -40,10 +43,12 @@ class Application extends App implements IBootstrap
Util::connectHook('\OCP\Config', 'js', $this, 'extendJsConfig');
}
public function register(IRegistrationContext $context): void {
public function register(IRegistrationContext $context): void
{
}
public static function extendJsConfig(array $settings): void {
public static function extendJsConfig(array $settings): void
{
/** @var IAppManager $appManager */
$appManager = Server::get(IAppManager::class);
@ -51,7 +56,7 @@ class Application extends App implements IBootstrap
/** @var array $appConfig */
$appConfig = json_decode((string) $settings['array']['oc_appconfig'], true);
$appConfig['repod'] = [
'gpodder' => $appManager->isEnabledForUser(self::GPODDERSYNC_ID)
'gpodder' => $appManager->isEnabledForUser(self::GPODDERSYNC_ID),
];
$settings['array']['oc_appconfig'] = json_encode($appConfig);
}

View File

@ -14,7 +14,8 @@ use OCP\Util;
class PageController extends Controller
{
public function __construct(IRequest $request, private IConfig $config) {
public function __construct(IRequest $request, private IConfig $config)
{
parent::__construct(Application::APP_ID, $request);
}
@ -22,7 +23,8 @@ class PageController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function index(): TemplateResponse {
public function index(): TemplateResponse
{
Util::addScript(Application::APP_ID, 'repod-main');
$csp = new ContentSecurityPolicy();
@ -36,6 +38,7 @@ class PageController extends Controller
$response = new TemplateResponse(Application::APP_ID, 'main');
$response->setContentSecurityPolicy($csp);
return $response;
}
}

View File

@ -4,52 +4,102 @@ declare(strict_types=1);
namespace OCA\RePod\Controller;
use Exception;
use OCA\RePod\AppInfo\Application;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Http\Client\IClientService;
use OCP\IRequest;
use OCP\IUserSession;
use OCP\L10N\IFactory;
class SearchController extends Controller
{
public function __construct(
IRequest $request,
private IClientService $clientService
private IClientService $clientService,
private IFactory $l10n,
private IUserSession $userSession
) {
parent::__construct(Application::APP_ID, $request);
}
public function index(string $value): JSONResponse {
public function index(string $value): JSONResponse
{
$podcasts = [];
try {
$fyydClient = $this->clientService->newClient();
$fyydReponse = $fyydClient->get("https://api.fyyd.de/0.2/search/podcast", [
$fyydReponse = $fyydClient->get('https://api.fyyd.de/0.2/search/podcast', [
'query' => [
'title' => $value,
'term' => $value
]
'term' => $value,
],
]);
$fyydJson = (array) json_decode((string) $fyydReponse->getBody(), true, flags: JSON_THROW_ON_ERROR);
if (array_key_exists('data', $fyydJson) && is_array($fyydJson['data'])) {
/** @var string[] $fyydFeed */
foreach ($fyydJson['data'] as $fyydFeed) {
$podcasts[] = [
'id' => $fyydFeed['id'],
'title' => $fyydFeed['title'],
'description' => $fyydFeed['description'],
'image' => $fyydFeed['imgURL'],
'url' => $fyydFeed['xmlURL'],
'lang' => $fyydFeed['language'],
'lastpub' => $fyydFeed['lastpub']
];
$lastPub = date_format(new \DateTime($fyydFeed['lastpub']), DATE_ATOM);
if ($lastPub) {
$podcasts[] = [
'provider' => 'fyyd',
'id' => $fyydFeed['id'],
'title' => $fyydFeed['title'],
'author' => $fyydFeed['author'],
'image' => $fyydFeed['imgURL'],
'provider_url' => $fyydFeed['htmlURL'],
'feed_url' => $fyydFeed['xmlURL'],
'last_pub' => $lastPub,
'nb_episodes' => $fyydFeed['episode_count'],
];
}
}
}
} catch (Exception $e) {
} catch (\Exception $e) {
}
try {
$itunesClient = $this->clientService->newClient();
$itunesResponse = $itunesClient->get('https://itunes.apple.com/search', [
'query' => [
'media' => 'podcast',
'term' => $value,
'lang' => $this->l10n->getUserLanguage($this->userSession->getUser()),
],
]);
$itunesJson = (array) json_decode((string) $itunesResponse->getBody(), true, flags: JSON_THROW_ON_ERROR);
if (array_key_exists('data', $itunesJson) && is_array($itunesJson['data'])) {
/** @var string[] $itunesFeed */
foreach ($itunesJson['results'] as $itunesFeed) {
$lastPub = date_format(new \DateTime($itunesFeed['releaseDate']), DATE_ATOM);
if ($lastPub) {
$podcasts[] = [
'id' => $itunesFeed['id'],
'title' => $itunesFeed['trackName'],
'author' => $itunesFeed['artistName'],
'image' => $itunesFeed['artworkUrl600'],
'provider_url' => $itunesFeed['trackViewUrl'],
'feed_url' => $itunesFeed['feedUrl'],
'last_pub' => $lastPub,
'nb_episodes' => $itunesFeed['trackCount'],
];
}
}
}
} catch (\Exception $e) {
}
/**
* string[] $a
* string[] $b.
*/
usort($podcasts, fn (array $a, array $b) => $a['last_pub'] <=> $b['last_pub']);
$podcasts = array_intersect_key($podcasts, array_unique(array_map(fn (array $feed) => $feed['feed_url'], $podcasts)));
return new JSONResponse($podcasts);
}
}

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace OCA\RePod\Controller;
use Exception;
use OCA\RePod\AppInfo\Application;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
@ -29,12 +28,13 @@ class TopController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function index(int $count = 10): JSONResponse {
public function index(int $count = 10): JSONResponse
{
$language = 'en';
try {
$langClient = $this->clientService->newClient();
$langResponse = $langClient->get("https://api.fyyd.de/0.2/feature/podcast/hot/languages");
$langResponse = $langClient->get('https://api.fyyd.de/0.2/feature/podcast/hot/languages');
$langJson = (array) json_decode((string) $langResponse->getBody(), true, flags: JSON_THROW_ON_ERROR);
if (array_key_exists('data', $langJson) && is_array($langJson['data'])) {
$language = $this->l10n->getUserLanguage($this->userSession->getUser());
@ -42,20 +42,21 @@ class TopController extends Controller
$language = count($language) > 1 ? $language[1] : $language[0];
$language = in_array($language, $langJson['data']) ? $language : 'en';
}
} catch (Exception $e) {
} catch (\Exception $e) {
}
try {
$podcastClient = $this->clientService->newClient();
$podcastReponse = $podcastClient->get("https://api.fyyd.de/0.2/feature/podcast/hot", [
$podcastReponse = $podcastClient->get('https://api.fyyd.de/0.2/feature/podcast/hot', [
'query' => [
'count' => $count,
'language' => $language
]
'language' => $language,
],
]);
$podcastJson = (array) json_decode((string) $podcastReponse->getBody(), true, flags: JSON_THROW_ON_ERROR);
return new JSONResponse($podcastJson, $podcastReponse->getStatusCode());
} catch (Exception $e) {
} catch (\Exception $e) {
return new JSONResponse([$e->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR);
}
}