/podcast/{overzicht,stream,download} toegevoegd
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', true);
|
||||
|
||||
@@ -37,9 +39,13 @@ QUERY;
|
||||
/**
|
||||
* Lijst van alle nieuwsberichten
|
||||
*/
|
||||
public function list(int $count = 15, int $page = 1) {
|
||||
if((int)$count <= 0) { $count = 15; }
|
||||
if((int)$page <= 0) { $page = 1; }
|
||||
public function list(Request $request) {
|
||||
$count = (int)$request->get('aantal', 15);
|
||||
$page = (int)$request->get('pagina', 1);
|
||||
if($count <= 0 || $page <= 0) {
|
||||
return abort(400);
|
||||
}
|
||||
|
||||
$start = ($page - 1) * $count;
|
||||
$newsItems = app('db')->select(self::$BASE_SQL
|
||||
. ' ORDER BY `published` DESC'
|
||||
|
||||
133
api/app/Http/Controllers/PodcastController.php
Normal file
133
api/app/Http/Controllers/PodcastController.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', true);
|
||||
|
||||
class PodcastController extends Controller
|
||||
{
|
||||
// TODO: Include program
|
||||
private static $BASE_SQL = <<<QUERY
|
||||
SELECT `podcast`.`id`, `podcast`.`soundfilename`,
|
||||
`podcast_meta`.`creationdt` AS `created`, `podcast_meta`.`title`, `podcast_meta`.`content`, `podcast_meta`.`program`,
|
||||
`programs`.`longname` AS `program_name`, `programs`.`description` AS `program_description`
|
||||
FROM `podcast`
|
||||
INNER JOIN `podcast_meta` ON `podcast`.`id` = `podcast_meta`.`podcast`
|
||||
LEFT JOIN `programs` ON `podcast_meta`.`program` = `programs`.`id`
|
||||
WHERE `podcast_meta`.`active` = 1 AND `podcast_meta`.`title` <> '' AND `podcast_meta`.`content` <> ''
|
||||
QUERY;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Lijst van alle podcasts
|
||||
*/
|
||||
public function list(Request $request) {
|
||||
$count = (int)$request->get('aantal', 15);
|
||||
$page = (int)$request->get('pagina', 1);
|
||||
if($count <= 0 || $page <= 0) {
|
||||
return abort(400);
|
||||
}
|
||||
|
||||
$start = ($page - 1) * $count;
|
||||
$podcasts = app('db')->select(self::$BASE_SQL
|
||||
. ' ORDER BY `podcast_meta`.`creationdt` DESC, `podcast_meta`.`id` DESC'
|
||||
. ' LIMIT ' . (int)$start . ', ' . (int)$count);
|
||||
|
||||
$result = array();
|
||||
foreach($podcasts as $podcast) {
|
||||
$result[] = new \Model\Podcast($podcast);
|
||||
}
|
||||
|
||||
return response()->json(['page' => $page, 'count' => $count, 'podcasts' => $result]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download specifieke podcast
|
||||
*/
|
||||
public function download(Request $request, int $id) {
|
||||
$queryResult = app('db')->select(self::$BASE_SQL
|
||||
. ' AND `podcast`.`id` = :id '
|
||||
. ' LIMIT 0, 1',
|
||||
['id' => $id]);
|
||||
|
||||
if(count($queryResult) == 0) { return abort(404); }
|
||||
|
||||
$podcast = new \Model\Podcast($queryResult[0]);
|
||||
if(!$podcast->isValidAuth($request->get('auth'))) {
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
return response()->download($podcast->getSoundfile(),
|
||||
'6FM Gemist - ' . $podcast->title . '.mp3');
|
||||
}
|
||||
|
||||
public function stream(Request $request, int $id) {
|
||||
$queryResult = app('db')->select(self::$BASE_SQL
|
||||
. ' AND `podcast`.`id` = :id '
|
||||
. ' LIMIT 0, 1',
|
||||
['id' => $id]);
|
||||
|
||||
if(count($queryResult) == 0) { return abort(404); }
|
||||
|
||||
$podcast = new \Model\Podcast($queryResult[0]);
|
||||
if(!$podcast->isValidAuth($request->get('auth'))) {
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
$filename = $podcast->getSoundfile();
|
||||
$file = fopen($filename, "rb");
|
||||
$size = filesize($filename);
|
||||
$content = fread($file, $size);
|
||||
fclose($file);
|
||||
|
||||
self::streamFile($request, 'audio/mpeg', $content, $size);
|
||||
}
|
||||
|
||||
// Provide a streaming file with support for scrubbing
|
||||
// Source: https://gist.github.com/widnyana/cd2bdda07dc02e9fce71
|
||||
private static function streamFile(Request $r, $contentType, $stream, $fullsize ) {
|
||||
$size = $fullsize;
|
||||
$response_code = 200;
|
||||
$headers = array("Content-type" => $contentType);
|
||||
|
||||
// Check for request for part of the stream
|
||||
$range = $r->header('Range');
|
||||
if($range != null) {
|
||||
$eqPos = strpos($range, "=");
|
||||
$toPos = strpos($range, "-");
|
||||
$unit = substr($range, 0, $eqPos);
|
||||
$start = intval(substr($range, $eqPos+1, $toPos));
|
||||
$success = fseek($stream, $start);
|
||||
if($success == 0) {
|
||||
$size = $fullsize - $start;
|
||||
$response_code = 206;
|
||||
$headers["Accept-Ranges"] = $unit;
|
||||
$headers["Content-Range"] = $unit . " " . $start . "-" . ($fullsize-1) . "/" . $fullsize;
|
||||
}
|
||||
}
|
||||
|
||||
$headers["Content-Length"] = $size;
|
||||
$response = new StreamedResponse(
|
||||
function () use ($stream) {
|
||||
$out = fopen('php://output', 'w');
|
||||
fputs($out, $stream);
|
||||
fclose($out);
|
||||
}, 200, $headers);
|
||||
$response->send();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,216 +1,170 @@
|
||||
swagger: "2.0"
|
||||
swagger: '2.0'
|
||||
info:
|
||||
description: "Dit is de publieke alleen-lezen interface van 6FM RES (Radio Extranet Systeem)."
|
||||
version: "1.0.0"
|
||||
title: "6FM RES"
|
||||
# termsOfService: "http://swagger.io/terms/"
|
||||
description: 'Dit is de publieke alleen-lezen interface van 6FM RES (Radio Extranet Systeem).'
|
||||
version: '1.0.0'
|
||||
title: '6FM RES'
|
||||
# termsOfService: 'http://swagger.io/terms/'
|
||||
contact:
|
||||
email: "mischa.spelt@6fm.nl"
|
||||
email: 'mischa.spelt@6fm.nl'
|
||||
#license:
|
||||
# name: "Apache 2.0"
|
||||
# url: "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
host: "api.6fm.nl"
|
||||
basePath: "/"
|
||||
# name: 'Apache 2.0'
|
||||
# url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
|
||||
host: 'api.6fm.nl'
|
||||
basePath: '/'
|
||||
tags:
|
||||
- name: "nieuws"
|
||||
description: "Nieuwsberichten"
|
||||
- name: "agenda"
|
||||
description: "Regioagenda-items"
|
||||
- name: 'nieuws'
|
||||
description: 'Nieuwsberichten'
|
||||
- name: 'agenda'
|
||||
description: 'Regioagenda-items'
|
||||
- name: 'podcast'
|
||||
description: 'Podcasts'
|
||||
#externalDocs:
|
||||
# description: "Find out more"
|
||||
# url: "http://swagger.io"
|
||||
#- name: "store"
|
||||
#description: "Access to Petstore orders"
|
||||
#- name: "user"
|
||||
#description: "Operations about user"
|
||||
# description: 'Find out more'
|
||||
# url: 'http://swagger.io'
|
||||
#- name: 'store'
|
||||
#description: 'Access to Petstore orders'
|
||||
#- name: 'user'
|
||||
#description: 'Operations about user'
|
||||
#externalDocs:
|
||||
# description: "Find out more about our store"
|
||||
# url: "http://swagger.io"
|
||||
# description: 'Find out more about our store'
|
||||
# url: 'http://swagger.io'
|
||||
schemes:
|
||||
- "http"
|
||||
- 'http'
|
||||
paths:
|
||||
'/nieuws/overzicht':
|
||||
get:
|
||||
tags:
|
||||
- "nieuws"
|
||||
summary: "Overzicht van nieuwsberichten"
|
||||
description: "Geeft een overzicht van de 15 meest recente nieuwsberichten. Equivalent aan /nieuws/overzicht/15/1."
|
||||
- 'nieuws'
|
||||
summary: 'Overzicht van nieuwsberichten'
|
||||
description: 'Geeft een overzicht van {aantal} recente nieuwsberichten, de meest recente {pagina} pagina''s overslaand. Met andere woorden, geeft de nieuwsberichten ({pagina} - 1) * {aantal} + 1 tot en met {pagina} * {aantal} terug, waarbij 1 het meest recent toegevoegde bericht is. '
|
||||
produces:
|
||||
- "application/json"
|
||||
responses:
|
||||
200:
|
||||
description: "Success"
|
||||
schema:
|
||||
type: "object"
|
||||
properties:
|
||||
page:
|
||||
type: "integer"
|
||||
count:
|
||||
type: "integer"
|
||||
news:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/NewsItem"
|
||||
'/nieuws/overzicht/{aantal}':
|
||||
get:
|
||||
tags:
|
||||
- "nieuws"
|
||||
summary: "Overzicht van nieuwsberichten"
|
||||
description: "Geeft een overzicht van de {aantal} meest recente nieuwsberichten. Equivalent aan /nieuws/overzicht/{aantal}/1."
|
||||
produces:
|
||||
- "application/json"
|
||||
- 'application/json'
|
||||
parameters:
|
||||
- name: aantal
|
||||
in: path
|
||||
description: "Het aantal nieuwsberichten per resultaatpagina."
|
||||
required: true
|
||||
default: 15
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: "Success"
|
||||
schema:
|
||||
type: "object"
|
||||
properties:
|
||||
page:
|
||||
type: "integer"
|
||||
count:
|
||||
type: "integer"
|
||||
news:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/NewsItem"
|
||||
'/nieuws/overzicht/{aantal}/{pagina}':
|
||||
get:
|
||||
tags:
|
||||
- "nieuws"
|
||||
summary: "Overzicht van nieuwsberichten"
|
||||
description: "Geeft een overzicht van {aantal} recente nieuwsberichten, de meest recente {pagina} pagina's overslaand"
|
||||
produces:
|
||||
- "application/json"
|
||||
parameters:
|
||||
- name: aantal
|
||||
in: path
|
||||
description: "Het aantal nieuwsberichten per resultaatpagina."
|
||||
required: true
|
||||
in: query
|
||||
description: 'Het aantal nieuwsberichten per resultaatpagina.'
|
||||
required: false
|
||||
default: 15
|
||||
type: string
|
||||
- name: pagina
|
||||
in: path
|
||||
description: "Het paginanummer."
|
||||
required: true
|
||||
in: query
|
||||
description: 'Het paginanummer.'
|
||||
required: false
|
||||
default: 1
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: "Success"
|
||||
description: 'Success'
|
||||
schema:
|
||||
type: "object"
|
||||
type: 'object'
|
||||
properties:
|
||||
page:
|
||||
type: "integer"
|
||||
type: integer
|
||||
count:
|
||||
type: "integer"
|
||||
type: integer
|
||||
news:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/NewsItem"
|
||||
$ref: '#/definitions/NewsItem'
|
||||
400:
|
||||
description: 'Parameter ''aantal'' of ''pagina'' heeft geen geldige waarde.'
|
||||
|
||||
'/nieuws/bericht/{id}':
|
||||
get:
|
||||
tags:
|
||||
- "nieuws"
|
||||
summary: "Details van een specifiek nieuwsbericht"
|
||||
description: "Geeft de details van een specifiek nieuwsbericht"
|
||||
- 'nieuws'
|
||||
summary: 'Details van een specifiek nieuwsbericht'
|
||||
description: 'Geeft de details van een specifiek nieuwsbericht'
|
||||
produces:
|
||||
- "application/json"
|
||||
- 'application/json'
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: "Het unieke ID van het nieuwsbericht"
|
||||
description: 'Het unieke ID van het nieuwsbericht'
|
||||
required: true
|
||||
type: "integer"
|
||||
type: integer
|
||||
responses:
|
||||
200:
|
||||
description: "Success"
|
||||
description: 'Success'
|
||||
schema:
|
||||
$ref: '#/definitions/NewsItem'
|
||||
404:
|
||||
description: "ID is ongeldig"
|
||||
description: 'ID is ongeldig'
|
||||
|
||||
'/agenda/overzicht[/week]':
|
||||
get:
|
||||
tags:
|
||||
- "agenda"
|
||||
summary: "Overzicht van alle agendaberichten in de komende 7 dagen"
|
||||
description: "Geeft een overzicht van alle agendaberichten in de komende week"
|
||||
- 'agenda'
|
||||
summary: 'Overzicht van alle agendaberichten in de komende 7 dagen'
|
||||
description: 'Geeft een overzicht van alle agendaberichten in de komende week'
|
||||
produces:
|
||||
- "application/json"
|
||||
- 'application/json'
|
||||
responses:
|
||||
200:
|
||||
description: "Success"
|
||||
description: 'Success'
|
||||
schema:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/AgendaItem'
|
||||
|
||||
'/agenda/overzicht/maand':
|
||||
get:
|
||||
tags:
|
||||
- "agenda"
|
||||
summary: "Overzicht van alle agendaberichten in de komende 30 dagen"
|
||||
description: "Geeft een overzicht van alle agendaberichten in de komende maand"
|
||||
- 'agenda'
|
||||
summary: 'Overzicht van alle agendaberichten in de komende 30 dagen'
|
||||
description: 'Geeft een overzicht van alle agendaberichten in de komende maand'
|
||||
produces:
|
||||
- "application/json"
|
||||
- 'application/json'
|
||||
responses:
|
||||
200:
|
||||
description: "Success"
|
||||
description: 'Success'
|
||||
schema:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/AgendaItem'
|
||||
|
||||
'/agenda/overzicht/alles':
|
||||
get:
|
||||
tags:
|
||||
- "agenda"
|
||||
summary: "Overzicht van alle agendaberichten in de toekomst"
|
||||
description: "Geeft een overzicht van alle agendaberichten in de toekomst"
|
||||
- 'agenda'
|
||||
summary: 'Overzicht van alle agendaberichten in de toekomst'
|
||||
description: 'Geeft een overzicht van alle agendaberichten in de toekomst'
|
||||
produces:
|
||||
- "application/json"
|
||||
- 'application/json'
|
||||
responses:
|
||||
200:
|
||||
description: "Success"
|
||||
description: 'Success'
|
||||
schema:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/AgendaItem'
|
||||
|
||||
'/agenda/kalender':
|
||||
get:
|
||||
tags:
|
||||
- "agenda"
|
||||
summary: "Haalt de agenda op in kalender-formaat voor de huidige maand"
|
||||
description: "Geeft alle agendaitems voor de huidige kalendermaand gegroepeerd op dag van de maand."
|
||||
- 'agenda'
|
||||
summary: 'Haalt de agenda op in kalender-formaat voor de huidige maand'
|
||||
description: 'Geeft alle agendaitems voor de huidige kalendermaand gegroepeerd op dag van de maand.'
|
||||
produces:
|
||||
- "application/json"
|
||||
- 'application/json'
|
||||
responses:
|
||||
200:
|
||||
description: "Success"
|
||||
description: 'Success'
|
||||
schema:
|
||||
type: "object"
|
||||
type: 'object'
|
||||
properties:
|
||||
items:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/AgendaItem'
|
||||
days:
|
||||
type: "object"
|
||||
description: "Eigenschapnamen zijn datum binnen gegeven maand in yyyy-mm-dd formaat"
|
||||
type: 'object'
|
||||
description: 'Eigenschapnamen zijn datum binnen gegeven maand in yyyy-mm-dd formaat'
|
||||
additionalProperties:
|
||||
type: 'array'
|
||||
description: "ID's van agenda-items op deze datum"
|
||||
type: array
|
||||
description: 'ID''s van agenda-items op deze datum'
|
||||
items:
|
||||
type: 'integer'
|
||||
type: integer
|
||||
example:
|
||||
'2017-01-20': [ 40234, 48398 ]
|
||||
'2017-01-21': [ 40234, 47239 ]
|
||||
@@ -219,42 +173,42 @@ paths:
|
||||
'/agenda/kalender/{jaar}/{maand}':
|
||||
get:
|
||||
tags:
|
||||
- "agenda"
|
||||
summary: "Haalt de agenda op in kalender-formaat voor de gegeven maand"
|
||||
description: "Geeft alle agendaitems voor de gegeven kalendermaand gegroepeerd op dag van de maand."
|
||||
- 'agenda'
|
||||
summary: 'Haalt de agenda op in kalender-formaat voor de gegeven maand'
|
||||
description: 'Geeft alle agendaitems voor de gegeven kalendermaand gegroepeerd op dag van de maand.'
|
||||
produces:
|
||||
- "application/json"
|
||||
- 'application/json'
|
||||
parameters:
|
||||
- name: jaar
|
||||
in: path
|
||||
description: "Het jaartal"
|
||||
description: 'Het jaartal'
|
||||
required: true
|
||||
type: "integer"
|
||||
type: integer
|
||||
- name: maand
|
||||
in: path
|
||||
description: "De maand van het jaar (1 - 12)"
|
||||
description: 'De maand van het jaar (1 - 12)'
|
||||
required: true
|
||||
type: "integer"
|
||||
type: integer
|
||||
responses:
|
||||
400:
|
||||
description: "Maand of jaartal ongeldig. Maand moet 1, 2, ..., 12 zijn."
|
||||
description: 'Maand of jaartal ongeldig. Maand moet 1, 2, ..., 12 zijn.'
|
||||
200:
|
||||
description: "Success"
|
||||
description: 'Success'
|
||||
schema:
|
||||
type: "object"
|
||||
type: 'object'
|
||||
properties:
|
||||
items:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/AgendaItem'
|
||||
days:
|
||||
type: "object"
|
||||
description: "Eigenschapnamen zijn datum binnen gegeven maand in yyyy-mm-dd formaat"
|
||||
type: 'object'
|
||||
description: 'Eigenschapnamen zijn datum binnen gegeven maand in yyyy-mm-dd formaat'
|
||||
additionalProperties:
|
||||
type: 'array'
|
||||
description: "ID's van agenda-items op deze datum"
|
||||
type: array
|
||||
description: 'ID''s van agenda-items op deze datum'
|
||||
items:
|
||||
type: 'integer'
|
||||
type: integer
|
||||
example:
|
||||
'2017-01-20': [ 40234, 48398 ]
|
||||
'2017-01-21': [ 40234, 47239 ]
|
||||
@@ -263,129 +217,265 @@ paths:
|
||||
'/agenda/details/{id}':
|
||||
get:
|
||||
tags:
|
||||
- "agenda"
|
||||
summary: "Details van een specifiek agendaitem"
|
||||
description: "Geeft de details van een specifiek agendaitem"
|
||||
- 'agenda'
|
||||
summary: 'Details van een specifiek agendaitem'
|
||||
description: 'Geeft de details van een specifiek agendaitem'
|
||||
produces:
|
||||
- "application/json"
|
||||
- 'application/json'
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: "Het unieke ID van het agendabericht"
|
||||
description: 'Het unieke ID van het agendabericht'
|
||||
required: true
|
||||
type: "integer"
|
||||
type: integer
|
||||
responses:
|
||||
200:
|
||||
description: "Success"
|
||||
description: 'Success'
|
||||
schema:
|
||||
$ref: '#/definitions/AgendaItem'
|
||||
404:
|
||||
description: "ID is ongeldig"
|
||||
description: 'ID is ongeldig'
|
||||
|
||||
'/podcast/overzicht':
|
||||
get:
|
||||
tags:
|
||||
- 'podcast'
|
||||
summary: 'Overzicht van meest recente podcasts'
|
||||
description: 'Geeft een overzicht van {aantal} recente podcasts, de meest recente {pagina} pagina''s overslaand. Met andere woorden, geeft de podcasts ({pagina} - 1) * {aantal} + 1 tot en met {pagina} * {aantal} terug, waarbij 1 de meest recent toegevoegde podcast is. '
|
||||
parameters:
|
||||
- name: aantal
|
||||
in: query
|
||||
description: 'Het aantal podcasts per resultaatpagina.'
|
||||
required: false
|
||||
default: 15
|
||||
type: string
|
||||
- name: pagina
|
||||
in: query
|
||||
description: 'Het paginanummer.'
|
||||
required: false
|
||||
default: 1
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: 'Success'
|
||||
schema:
|
||||
type: 'object'
|
||||
properties:
|
||||
page:
|
||||
type: integer
|
||||
count:
|
||||
type: integer
|
||||
podcasts:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Podcast'
|
||||
400:
|
||||
description: 'Parameter ''aantal'' of ''pagina'' heeft geen geldige waarde.'
|
||||
|
||||
'/podcast/download/{id}/{title}':
|
||||
get:
|
||||
tags:
|
||||
- 'podcast'
|
||||
summary: 'Download een specifieke podcast'
|
||||
description: 'Geeft een MP3-bestand terug waarvan de headers de browser forceren het bestand te downloaden.'
|
||||
produces:
|
||||
- 'audio/mpeg'
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: 'Het unieke ID van de podcast'
|
||||
required: true
|
||||
type: integer
|
||||
- name: title
|
||||
in: path
|
||||
description: 'De titel van de podcast'
|
||||
required: true
|
||||
type: string
|
||||
- name: auth
|
||||
in: query
|
||||
description: 'De authorisatiecode voor het downloaden van de podcast. Deze verandert per gebruikerssessie. (Dit is onder andere nodig om te voorkomen dat uitzendingen ouder dan twee weken kunnen worden gedownload door de URL aan te passen.) Deze sleutel is beschikbaar via de ''url'' eigenschap van de podcast.'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
404:
|
||||
description: 'Podcast ID of authorisatiesleutel is ongeldig'
|
||||
|
||||
'/podcast/stream/{id}/{title}':
|
||||
get:
|
||||
tags:
|
||||
- 'podcast'
|
||||
summary: 'Stream een specifieke podcast'
|
||||
description: 'Geeft een MP3-bestand terug voor live streaming'
|
||||
produces:
|
||||
- 'audio/mpeg'
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: 'Het unieke ID van de podcast'
|
||||
required: true
|
||||
type: integer
|
||||
- name: title
|
||||
in: path
|
||||
description: 'De titel van de podcast'
|
||||
required: true
|
||||
type: string
|
||||
- name: auth
|
||||
in: query
|
||||
description: 'De authorisatiecode voor het streamen van de podcast. Deze verandert per gebruikerssessie. (Dit is onder andere nodig om te voorkomen dat uitzendingen ouder dan twee weken kunnen worden gestreamd door de URL aan te passen.) Deze sleutel is beschikbaar via de ''url'' eigenschap van de podcast.'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
404:
|
||||
description: 'Podcast ID of authorisatiesleutel is ongeldig'
|
||||
|
||||
|
||||
#securityDefinitions:
|
||||
#petstore_auth:
|
||||
# type: "oauth2"
|
||||
# authorizationUrl: "http://petstore.swagger.io/oauth/dialog"
|
||||
# flow: "implicit"
|
||||
# type: 'oauth2'
|
||||
# authorizationUrl: 'http://petstore.swagger.io/oauth/dialog'
|
||||
# flow: 'implicit'
|
||||
# scopes:
|
||||
# write:pets: "modify pets in your account"
|
||||
# read:pets: "read your pets"
|
||||
# write:pets: 'modify pets in your account'
|
||||
# read:pets: 'read your pets'
|
||||
#api_key:
|
||||
# type: "apiKey"
|
||||
# name: "api_key"
|
||||
# in: "header"
|
||||
# type: 'apiKey'
|
||||
# name: 'api_key'
|
||||
# in: 'header'
|
||||
definitions:
|
||||
DateTime:
|
||||
type: "object"
|
||||
type: 'object'
|
||||
properties:
|
||||
date:
|
||||
type: "string"
|
||||
format: "yyyy-mm-dd hh:mm:ss.zzzzzz"
|
||||
example: "2017-07-12 15:23:59.000000"
|
||||
type: string
|
||||
format: 'yyyy-mm-dd hh:mm:ss.zzzzzz'
|
||||
example: '2017-07-12 15:23:59.000000'
|
||||
timezone_type:
|
||||
type: "integer"
|
||||
type: integer
|
||||
example: 4
|
||||
timezone:
|
||||
type: "string"
|
||||
example: "Europe/Amsterdam"
|
||||
type: string
|
||||
example: 'Europe/Amsterdam'
|
||||
NewsSource:
|
||||
type: "object"
|
||||
type: 'object'
|
||||
properties:
|
||||
title:
|
||||
type: "string"
|
||||
type: string
|
||||
url:
|
||||
type: "string"
|
||||
type: string
|
||||
show:
|
||||
type: "boolean"
|
||||
type: 'boolean'
|
||||
NewsImage:
|
||||
type: "object"
|
||||
type: 'object'
|
||||
properties:
|
||||
id:
|
||||
type: "integer"
|
||||
type: integer
|
||||
title:
|
||||
type: "string"
|
||||
type: string
|
||||
url:
|
||||
type: "string"
|
||||
type: string
|
||||
|
||||
NewsItem:
|
||||
type: "object"
|
||||
type: 'object'
|
||||
properties:
|
||||
id:
|
||||
type: "integer"
|
||||
type: integer
|
||||
title:
|
||||
type: "string"
|
||||
type: string
|
||||
content:
|
||||
type: "string"
|
||||
type: string
|
||||
published:
|
||||
$ref: "#/definitions/DateTime"
|
||||
$ref: '#/definitions/DateTime'
|
||||
edited:
|
||||
$ref: "#/definitions/DateTime"
|
||||
$ref: '#/definitions/DateTime'
|
||||
keywords:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
type: "string"
|
||||
type: string
|
||||
source:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/NewsSource"
|
||||
$ref: '#/definitions/NewsSource'
|
||||
theme:
|
||||
type: "string"
|
||||
type: string
|
||||
region:
|
||||
type: "string"
|
||||
type: string
|
||||
podcast:
|
||||
type: "string"
|
||||
type: string
|
||||
images:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/NewsImage"
|
||||
$ref: '#/definitions/NewsImage'
|
||||
video:
|
||||
type: "string"
|
||||
type: string
|
||||
url:
|
||||
type: "string"
|
||||
type: string
|
||||
|
||||
AgendaItem:
|
||||
type: "object"
|
||||
type: 'object'
|
||||
properties:
|
||||
id:
|
||||
type: "integer"
|
||||
type: integer
|
||||
title:
|
||||
type: "string"
|
||||
type: string
|
||||
region:
|
||||
type: "string"
|
||||
type: string
|
||||
content:
|
||||
type: "string"
|
||||
type: string
|
||||
starts:
|
||||
$ref: "#/definitions/DateTime"
|
||||
$ref: '#/definitions/DateTime'
|
||||
ends:
|
||||
$ref: "#/definitions/DateTime"
|
||||
$ref: '#/definitions/DateTime'
|
||||
images:
|
||||
type: "array"
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/NewsImage"
|
||||
$ref: '#/definitions/NewsImage'
|
||||
url:
|
||||
type: "string"
|
||||
type: string
|
||||
|
||||
Podcast:
|
||||
type: 'object'
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
title:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
created:
|
||||
$ref: '#/definitions/DateTime'
|
||||
program:
|
||||
$ref: '#/definitions/Program'
|
||||
description: 'Alleen de {name}, {description} en {id} van het programma worden ingevuld, {hosts}, {schedule} en {podcasts} zijn leeg. Gebruik GET /programma om meer informatie hierover te krijgen.'
|
||||
url:
|
||||
type: string
|
||||
description: 'Link om de podcast als MP3 te streamen of te downloaden. Voeg hiervoor /podcast/stream/ of /podcast/download/ toe voor de url, bijvoorbeeld: /podcast/stream/213723/6fm-podcast-titel-slug?auth=15ff823563323fe3342812937b4013984218'
|
||||
|
||||
Program:
|
||||
type: 'object'
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
hosts:
|
||||
type: array
|
||||
items:
|
||||
type: string # Voor nu
|
||||
description: 'NOT IMPLEMENTED YET!'
|
||||
required: false
|
||||
schedule:
|
||||
type: array
|
||||
description: 'NOT IMPLEMENTED YET!'
|
||||
required: false
|
||||
podcasts:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Podcast'
|
||||
description: 'Podcasts in deze lijst hebben geen {programma} ingevuld.'
|
||||
required: false
|
||||
|
||||
#externalDocs:
|
||||
# description: "Find out more about Swagger"
|
||||
# url: "http://swagger.io"
|
||||
# description: 'Find out more about Swagger'
|
||||
# url: 'http://swagger.io'
|
||||
|
||||
@@ -16,8 +16,6 @@ $app->get('/', function () use ($app) {
|
||||
});
|
||||
|
||||
$app->get('nieuws/overzicht', 'NewsController@list' );
|
||||
$app->get('nieuws/overzicht/{count:\d+}', 'NewsController@list' );
|
||||
$app->get('nieuws/overzicht/{count:\d+}/{page:\d+}', 'NewsController@list' );
|
||||
$app->get('nieuws/bericht/{id:\d+}', 'NewsController@item' );
|
||||
|
||||
$app->get('agenda/overzicht[/week]', 'AgendaController@listWeek' );
|
||||
@@ -25,3 +23,15 @@ $app->get('agenda/overzicht/maand', 'AgendaController@listMonth' );
|
||||
$app->get('agenda/overzicht/alles', 'AgendaController@list' );
|
||||
$app->get('agenda/kalender[/{year:\d\d\d\d}/{month:\d\d?}]', 'AgendaController@calendar' );
|
||||
$app->get('agenda/details/{id:\d+}', 'AgendaController@item' );
|
||||
|
||||
$app->get('podcast/overzicht', 'PodcastController@list' );
|
||||
// podcast/programma/1234[?aantal=&pagina=]
|
||||
$app->get('podcast/download/{id:\d+}/[{title}]', 'PodcastController@download' );
|
||||
$app->get('podcast/stream/{id:\d+}/[{title}]', 'PodcastController@stream' );
|
||||
|
||||
// programma/nustraks
|
||||
// programma/schema
|
||||
// programma/details/{id:\d+}
|
||||
|
||||
// live/onair
|
||||
// live/stream
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,7 +46,7 @@ class Model {
|
||||
$text = str_replace($search, $replace, $text);
|
||||
|
||||
// Verwijder alle woorden van 3 letters, behalve BEL (BEL-combinatie etc)
|
||||
$text = preg_replace('/\b(?!bel)([a-z]{1,3})\b/u', '', $text);
|
||||
$text = preg_replace('/\b(?!bel|fm)([a-z]{1,3})\b/u', '', $text);
|
||||
|
||||
// Vervang alles dat niet een woord-karakter is (letter, cijfer), een streepje of spatie
|
||||
$text = preg_replace('/[^\w_\-\s]/', '', $text);
|
||||
|
||||
46
common/classes/Podcast.php
Normal file
46
common/classes/Podcast.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Model;
|
||||
|
||||
require "Program.php";
|
||||
|
||||
class Podcast extends Model {
|
||||
public $id;
|
||||
public $title;
|
||||
public $content;
|
||||
protected $soundfilename;
|
||||
public $created;
|
||||
public $program;
|
||||
public $url;
|
||||
public $download;
|
||||
private $key;
|
||||
|
||||
public function __construct($data) {
|
||||
parent::__construct($data);
|
||||
parent::ConvertToDateTime($this->created);
|
||||
|
||||
$this->key = sha1($this->id . ':' . session_id() . ':' . $this->soundfilename);
|
||||
$this->url = $this->id . '/' . parent::url_slug($this->title) . '?auth=' . $this->key;
|
||||
|
||||
if($this->program != 0) {
|
||||
$this->program = new \Model\Program(['id' => $this->program, 'name' => $data->program_name, 'description' => $data->program_description]);
|
||||
}
|
||||
}
|
||||
|
||||
public function isValidAuth($key) {
|
||||
return ($key == $this->key);
|
||||
}
|
||||
|
||||
public function getSoundfile() {
|
||||
return '/tmp/podcast.mp3';
|
||||
}
|
||||
|
||||
public function excerpt() {
|
||||
$hasImages = count($this->images) > 0;
|
||||
$maxLength = $hasImages ? 200 : 500;
|
||||
return '<p class="news-excerpt ' . ($hasImages ? 'short' : 'long') . '">' .
|
||||
substr($this->content, 0, $maxLength) .
|
||||
(strlen($this->content) > $maxLength ? '...' : '') .
|
||||
'</p>';
|
||||
}
|
||||
}
|
||||
18
common/classes/Program.php
Normal file
18
common/classes/Program.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Model;
|
||||
|
||||
class Program extends Model {
|
||||
public $id;
|
||||
public $name;
|
||||
public $description;
|
||||
|
||||
// TODO: Implementeren
|
||||
public $hosts;
|
||||
public $schedule;
|
||||
public $podcasts;
|
||||
|
||||
public function __construct($data) {
|
||||
parent::__construct($data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user