Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playlist API v2: Playlist event attribute deprecation #437

Merged
merged 2 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 112 additions & 53 deletions api/Playlists.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Zookeeper Online
*
* @author Jim Mason <[email protected]>
* @copyright Copyright (C) 1997-2023 Jim Mason <[email protected]>
* @copyright Copyright (C) 1997-2024 Jim Mason <[email protected]>
* @link https://zookeeper.ibinx.com/
* @license GPL-3.0
*
Expand Down Expand Up @@ -121,6 +121,60 @@ private static function paginate(RequestInterface $request, $type, $key, &$offse
return [$size, $result];
}

private static function fetchEvents($playlist, $aflags) {
$relations = new ResourceCollection();

Engine::api(IPlaylist::class)->getTracksWithObserver($playlist,
(new PlaylistObserver())->onComment(function($entry) use($relations) {
$e = new JsonResource("event", $entry->getId());
$a = $e->attributes();
$a->set("type", "comment");
$a->set("comment", $entry->getComment());
$a->set("created", $entry->getCreatedTime());
$relations->set($e);
})->onLogEvent(function($entry) use($relations) {
$e = new JsonResource("event", $entry->getId());
$a = $e->attributes();
$a->set("type", "logEvent");
$a->set("event", $entry->getLogEventType());
$a->set("code", $entry->getLogEventCode());
$a->set("created", $entry->getCreatedTime());
$relations->set($e);
})->onSetSeparator(function($entry) use($relations) {
$e = new JsonResource("event", $entry->getId());
$a = $e->attributes();
$a->set("type", "break");
$a->set("created", $entry->getCreatedTime());
$relations->set($e);
})->onSpin(function($entry) use($relations, $aflags) {
$e = new JsonResource("event", $entry->getId());
$a = $e->attributes();
$a->set("type", "spin");
$attrs = $entry->asArray();
unset($attrs["tag"]);
unset($attrs["id"]);
$a->merge($attrs);
$a->set("created", $entry->getCreatedTime());

$tag = $entry->getTag();
if($tag) {
$a->set("artist", PlaylistEntry::swapNames($entry->getArtist()));
if($aflags && sizeof($albums = Engine::api(ILibrary::class)->search(ILibrary::ALBUM_KEY, 0, 1, $tag)))
$res = Albums::fromArray($albums, $aflags)[0];
else
$res = new JsonResource("album", $tag);

$relation = new Relationship("album", $res);
$relation->links()->set(new Link("related", Engine::getBaseUrl()."album/$tag"));
$e->relationships()->set($relation);
}

$relations->set($e);
}));

return $relations;
}

public static function fromRecord($rec, $flags) {
$id = $rec["list"] ?? $rec["id"];
$res = new JsonResource("show", $id);
Expand Down Expand Up @@ -149,6 +203,17 @@ public static function fromRecord($rec, $flags) {
}

if($flags & self::LINKS_EVENTS) {
if(Engine::getApiVer() >= 2) {
$aflags = $flags & self::LINKS_ALBUMS_DETAILS ?
Albums::LINKS_ALL : Albums::LINKS_NONE;

$relations = self::fetchEvents($id, $aflags);
$relation = new Relationship("events", $relations);
$relation->links()->set(new Link("related", Engine::getBaseUrl()."playlist/$id/events"));
$res->relationships()->set($relation);
return $res;
}

$relations = new ResourceCollection();

$events = [];
Expand Down Expand Up @@ -223,9 +288,11 @@ public function fetchResource(RequestInterface $request): ResponseInterface {

$row["list"] = $key;
$flags = self::LINKS_NONE;
if($request->requestsField("show", "events"))
$apiver = Engine::getApiVer();
if($apiver >= 2 || $request->requestsField("show", "events"))
$flags |= self::LINKS_EVENTS | self::LINKS_ALBUMS;
if($request->requestsInclude("albums"))
if($request->requestsInclude("events.album") ||
$apiver < 2 && $request->requestsInclude("albums"))
$flags |= self::LINKS_ALBUMS_DETAILS;
if($request->requestsInclude("origin"))
$flags |= self::LINKS_ORIGIN;
Expand All @@ -234,21 +301,25 @@ public function fetchResource(RequestInterface $request): ResponseInterface {

$document = new Document($resource);
$response = new DocumentResponse($document);
$response->headers()->set('Content-Type', ApiServer::CONTENT_TYPE);
if(Engine::getApiVer() < 2)
$response->headers()->set('Content-Type', ApiServer::CONTENT_TYPE);
return $response;
}

public function fetchResources(RequestInterface $request): ResponseInterface {
$flags = self::LINKS_NONE;
if($request->requestsField("show", "events"))
$apiver = Engine::getApiVer();
if($apiver >= 2 || $request->requestsField("show", "events"))
$flags |= self::LINKS_EVENTS | self::LINKS_ALBUMS;
if($request->requestsInclude("albums"))
if($request->requestsInclude("events.album") ||
$apiver < 2 && $request->requestsInclude("albums"))
$flags |= self::LINKS_ALBUMS_DETAILS;
if($request->requestsInclude("origin"))
$flags |= self::LINKS_ORIGIN;

$response = $this->paginateOffset($request, self::$paginateOps, $flags);
$response->headers()->set('Content-Type', ApiServer::CONTENT_TYPE);
if(Engine::getApiVer() < 2)
$response->headers()->set('Content-Type', ApiServer::CONTENT_TYPE);
return $response;
}

Expand All @@ -272,6 +343,9 @@ public function fetchRelationship(RequestInterface $request): ResponseInterface

switch($request->relationship()) {
case "albums":
if(Engine::getApiVer() >= 2)
throw new NotAllowedException('You are not allowed to fetch the relationship ' . $request->relationship());

$api->getTracksWithObserver($id,
(new PlaylistObserver())->onSpin(function($entry) use($relations, $flags) {
$tag = $entry->getTag();
Expand All @@ -288,51 +362,8 @@ public function fetchRelationship(RequestInterface $request): ResponseInterface
case "events":
if(!$request->requestsInclude("album"))
$flags = Albums::LINKS_NONE;
$api->getTracksWithObserver($id,
(new PlaylistObserver())->onComment(function($entry) use($relations) {
$e = new JsonResource("event", $entry->getId());
$a = $e->attributes();
$a->set("type", "comment");
$a->set("comment", $entry->getComment());
$a->set("created", $entry->getCreatedTime());
$relations->set($e);
})->onLogEvent(function($entry) use($relations) {
$e = new JsonResource("event", $entry->getId());
$a = $e->attributes();
$a->set("type", "logEvent");
$a->set("event", $entry->getLogEventType());
$a->set("code", $entry->getLogEventCode());
$a->set("created", $entry->getCreatedTime());
$relations->set($e);
})->onSetSeparator(function($entry) use($relations) {
$e = new JsonResource("event", $entry->getId());
$a = $e->attributes();
$a->set("type", "break");
$a->set("created", $entry->getCreatedTime());
$relations->set($e);
})->onSpin(function($entry) use($relations, $flags) {
$e = new JsonResource("event", $entry->getId());
$a = $e->attributes();
$a->set("type", "spin");
$attrs = $entry->asArray();
unset($attrs["tag"]);
unset($attrs["id"]);
$a->merge($attrs);
$a->set("created", $entry->getCreatedTime());

$tag = $entry->getTag();
if($tag) {
$a->set("artist", PlaylistEntry::swapNames($entry->getArtist()));
if($flags && sizeof($albums = Engine::api(ILibrary::class)->search(ILibrary::ALBUM_KEY, 0, 1, $tag)))
$res = Albums::fromArray($albums, $flags)[0];
else
$res = new JsonResource("album", $tag);

$e->relationships()->set(new Relationship("album", $res));
}

$relations->set($e);
}));
$relations = self::fetchEvents($id, $flags);
break;
case "origin":
$origin = $list['origin'];
Expand Down Expand Up @@ -360,7 +391,8 @@ public function fetchRelationship(RequestInterface $request): ResponseInterface
}

$response = new DocumentResponse($document);
$response->headers()->set('Content-Type', ApiServer::CONTENT_TYPE);
if(Engine::getApiVer() < 2)
$response->headers()->set('Content-Type', ApiServer::CONTENT_TYPE);
return $response;
}

Expand Down Expand Up @@ -470,7 +502,7 @@ function($matches) use ($list) {

// insert the tracks
$events = $attrs->getOptional("events");
if($events) {
if($events && Engine::getApiVer() < 2) {
$status = '';
$window = $papi->getTimestampWindow($playlist);
foreach($events as $pentry) {
Expand All @@ -490,6 +522,33 @@ function($matches) use ($list) {
}
}

if($show->relationships()->has("events")) {
$window = $papi->getTimestampWindow($playlist);
$included = $request->requestBody()->included();
foreach($show->relationships()->get("events")->related()->all() as $er) {
$event = $included->get("event", $er->id());
$pentry = $event->attributes()->all();
$entry = PlaylistEntry::fromArray($pentry);
$created = $entry->getCreated();
if($created == "auto") {
$autoTimestamp = $papi->isNowWithinShow(
["showdate" => $date, "showtime" => $time]);
$created = $autoTimestamp ? (new \DateTime("now"))->format(IPlaylist::TIME_FORMAT_SQL) : null;
$entry->setCreated($created);
} else if($created) {
try {
$stamp = PlaylistEntry::scrubTimestamp(
new \DateTime($created), $window);
$entry->setCreated($stamp?$stamp->format(IPlaylist::TIME_FORMAT_SQL):null);
} catch(\Exception $e) {
error_log("failed to parse timestamp: $created");
$entry->setCreated(null);
}
}
$success = $papi->insertTrackEntry($playlist, $entry, $status);
}
}

if($playlist) {
if($aid && $papi->isNowWithinShow(
["showdate" => $date, "showtime" => $time]))
Expand Down
4 changes: 2 additions & 2 deletions controllers/Validate.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ public function validatePlaylists() {

$successd = false;
if($this->doTest("duplicate playlist", $success4)) {
$response = $this->client->post('api/v1/playlist', [
$response = $this->client->post('api/v2/playlist', [
RequestOptions::JSON => [
'data' => [
'type' => 'show',
Expand Down Expand Up @@ -340,7 +340,7 @@ public function validatePlaylists() {
$json->data->relationships->origin->data->id == $pid &&
preg_match(IPlaylist::DUPLICATE_REGEX, $json->data->attributes->name) &&
$json->data->attributes->airname == $airname &&
sizeof($json->data->attributes->events) == 3;
sizeof($json->data->relationships->events->data) == 3;
$this->showSuccess($successd1, $response);
}

Expand Down
8 changes: 4 additions & 4 deletions docs/PlaylistEvents.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ airname.
### <a id="show"></a> Create the show:
---
````
POST /api/v1/playlist HTTP/1.1
POST /api/v2/playlist HTTP/1.1
X-APIKEY: eb5e0e0b42a84531af5f257ed61505050494788d
Content-Type: application/vnd.api+json

Expand All @@ -41,7 +41,7 @@ Content-Type: application/vnd.api+json
---
````
HTTP/1.1 201 Created
Location: /api/v1/playlist/628
Location: /api/v2/playlist/628
Content-Length: 0
````
---
Expand All @@ -58,7 +58,7 @@ The value of `Location` is used as the base for the subsequent requests.
### <a id="eventComment"></a> Add a comment:
---
````
POST /api/v1/playlist/628/events HTTP/1.1
POST /api/v2/playlist/628/events HTTP/1.1
X-APIKEY: eb5e0e0b42a84531af5f257ed61505050494788d
Content-Type: application/vnd.api+json

Expand Down Expand Up @@ -96,7 +96,7 @@ section 7.3.
### <a id="eventSpin"></a> Add a spin:
---
````
POST /api/v1/playlist/628/events HTTP/1.1
POST /api/v2/playlist/628/events HTTP/1.1
X-APIKEY: eb5e0e0b42a84531af5f257ed61505050494788d
Content-Type: application/vnd.api+json

Expand Down
Loading
Loading