Skip to content

Commit

Permalink
Playlist API v2: Playlist event attribute deprecation (#437)
Browse files Browse the repository at this point in the history
  • Loading branch information
RocketMan committed Apr 8, 2024
1 parent 56a0158 commit 9b43aff
Show file tree
Hide file tree
Showing 6 changed files with 413 additions and 423 deletions.
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 <jmason@ibinx.com>
* @copyright Copyright (C) 1997-2023 Jim Mason <jmason@ibinx.com>
* @copyright Copyright (C) 1997-2024 Jim Mason <jmason@ibinx.com>
* @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

0 comments on commit 9b43aff

Please sign in to comment.