Preparing parseWebhook to support relative GUIDs. related to #69
This commit is contained in:
@@ -342,7 +342,11 @@ final class Initializer
|
||||
]);
|
||||
}
|
||||
|
||||
return new Response(status: 200, headers: ['X-Status' => 'Entity is unchanged.']);
|
||||
return new Response(status: 200, headers: [
|
||||
'X-Status' => 'Entity is unchanged.',
|
||||
'X-WH-Type' => $request->getAttribute('WH_TYPE', 'not_set'),
|
||||
'X-WH-Event' => $request->getAttribute('WH_EVENT', 'not_set'),
|
||||
]);
|
||||
} catch (HttpException $e) {
|
||||
if (200 === $e->getCode()) {
|
||||
return new Response(status: $e->getCode(), headers: [
|
||||
|
||||
@@ -102,7 +102,7 @@ class EmbyServer extends JellyfinServer
|
||||
throw new HttpException(sprintf('%s: Not allowed event [%s]', afterLast(__CLASS__, '\\'), $event), 200);
|
||||
}
|
||||
|
||||
$date = time();
|
||||
$isTainted = in_array($event, self::WEBHOOK_TAINTED_EVENTS);
|
||||
|
||||
$meta = match ($type) {
|
||||
StateInterface::TYPE_MOVIE => [
|
||||
@@ -145,16 +145,9 @@ class EmbyServer extends JellyfinServer
|
||||
$isWatched = (int)(bool)ag($json, 'Item.Played', ag($json, 'Item.PlayedToCompletion', 0));
|
||||
}
|
||||
|
||||
$guids = ag($json, 'Item.ProviderIds', []);
|
||||
$providersId = ag($json, 'Item.ProviderIds', []);
|
||||
|
||||
if (!$this->hasSupportedIds($guids)) {
|
||||
throw new HttpException(
|
||||
sprintf('%s: No supported GUID was given. [%s]', afterLast(__CLASS__, '\\'), arrayToString($guids)),
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
$guids = $this->getGuids($type, $guids);
|
||||
$guids = $this->getGuids($providersId, $type);
|
||||
|
||||
foreach (Guid::fromArray($guids)->getPointers() as $guid) {
|
||||
$this->cacheData[$guid] = ag($json, 'Item.Id');
|
||||
@@ -162,19 +155,40 @@ class EmbyServer extends JellyfinServer
|
||||
|
||||
$row = [
|
||||
'type' => $type,
|
||||
'updated' => $date,
|
||||
'updated' => time(),
|
||||
'watched' => $isWatched,
|
||||
'meta' => $meta,
|
||||
...$guids
|
||||
];
|
||||
|
||||
if (true === Config::get('webhook.debug') || null !== ag($request->getQueryParams(), 'debug')) {
|
||||
saveWebhookPayload($request, "{$this->name}.{$event}", $json + ['entity' => $row]);
|
||||
$entity = Container::get(StateInterface::class)::fromArray($row)->setIsTainted($isTainted);
|
||||
|
||||
if (!$entity->hasGuids()) {
|
||||
throw new HttpException(
|
||||
sprintf(
|
||||
'%s: No supported GUID was given. [%s]',
|
||||
afterLast(__CLASS__, '\\'),
|
||||
arrayToString(
|
||||
[
|
||||
'guids' => !empty($providersId) ? $providersId : 'None',
|
||||
'rGuids' => $entity->hasRelativeGuids() ? $entity->getRelativeGuids() : 'None',
|
||||
]
|
||||
)
|
||||
), 400
|
||||
);
|
||||
}
|
||||
|
||||
return Container::get(StateInterface::class)::fromArray($row)->setIsTainted(
|
||||
in_array($event, self::WEBHOOK_TAINTED_EVENTS)
|
||||
);
|
||||
if (false === $isTainted && (true === Config::get('webhook.debug') || null !== ag(
|
||||
$request->getQueryParams(),
|
||||
'debug'
|
||||
))) {
|
||||
saveWebhookPayload($this->name . '.' . $event, $request, [
|
||||
'entity' => $entity->getAll(),
|
||||
'payload' => $json,
|
||||
]);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public function push(array $entities, DateTimeInterface|null $after = null): array
|
||||
|
||||
@@ -286,8 +286,6 @@ class JellyfinServer implements ServerInterface
|
||||
|
||||
$isTainted = in_array($event, self::WEBHOOK_TAINTED_EVENTS);
|
||||
|
||||
$date = time();
|
||||
|
||||
$meta = match ($type) {
|
||||
StateInterface::TYPE_MOVIE => [
|
||||
'via' => $this->name,
|
||||
@@ -311,49 +309,65 @@ class JellyfinServer implements ServerInterface
|
||||
default => throw new HttpException(sprintf('%s: Invalid content type.', afterLast(__CLASS__, '\\')), 400),
|
||||
};
|
||||
|
||||
$guids = [];
|
||||
$providersId = [];
|
||||
|
||||
foreach ($json as $key => $val) {
|
||||
if (str_starts_with($key, 'Provider_')) {
|
||||
$guids[self::afterString($key, 'Provider_')] = $val;
|
||||
if (!str_starts_with($key, 'Provider_')) {
|
||||
continue;
|
||||
}
|
||||
$providersId[self::afterString($key, 'Provider_')] = $val;
|
||||
}
|
||||
|
||||
if (!$this->hasSupportedIds($guids)) {
|
||||
throw new HttpException(
|
||||
sprintf('%s: No supported GUID was given. [%s]', afterLast(__CLASS__, '\\'), arrayToString($guids)),
|
||||
400
|
||||
);
|
||||
// We use SeriesName to overcome jellyfin webhook limitation, it does not send series id.
|
||||
if (StateInterface::TYPE_EPISODE === $type && null !== ag($json, 'SeriesName')) {
|
||||
$meta['parent'] = $this->getEpisodeParent(ag($json, 'ItemId'), ag($json, 'SeriesName'));
|
||||
}
|
||||
|
||||
if (false === $isTainted && StateInterface::TYPE_EPISODE === $type) {
|
||||
$meta['parent'] = $this->getParentGUIDs(ag($json, 'ItemId'), ag($json, 'SeriesName'));
|
||||
}
|
||||
|
||||
$guids = $this->getGuids($guids, $type);
|
||||
$guids = $this->getGuids($providersId, $type);
|
||||
|
||||
foreach (Guid::fromArray($guids)->getPointers() as $guid) {
|
||||
$this->cacheData[$guid] = ag($json, 'Item.ItemId');
|
||||
}
|
||||
|
||||
$isWatched = (int)(bool)ag($json, 'Played', ag($json, 'PlayedToCompletion', 0));
|
||||
|
||||
$row = [
|
||||
'type' => $type,
|
||||
'updated' => $date,
|
||||
'watched' => $isWatched,
|
||||
'updated' => time(),
|
||||
'watched' => (int)(bool)ag($json, 'Played', ag($json, 'PlayedToCompletion', 0)),
|
||||
'meta' => $meta,
|
||||
...$guids
|
||||
];
|
||||
|
||||
if (true === Config::get('webhook.debug') || null !== ag($request->getQueryParams(), 'debug')) {
|
||||
saveWebhookPayload($request, "{$this->name}.{$event}", $json + ['entity' => $row]);
|
||||
$entity = Container::get(StateInterface::class)::fromArray($row)->setIsTainted($isTainted);
|
||||
|
||||
if (!$entity->hasGuids()) {
|
||||
throw new HttpException(
|
||||
sprintf(
|
||||
'%s: No supported GUID was given. [%s]',
|
||||
afterLast(__CLASS__, '\\'),
|
||||
arrayToString(
|
||||
[
|
||||
'guids' => !empty($providersId) ? $providersId : 'None',
|
||||
'rGuids' => $entity->hasRelativeGuids() ? $entity->getRelativeGuids() : 'None',
|
||||
]
|
||||
)
|
||||
), 400
|
||||
);
|
||||
}
|
||||
|
||||
return Container::get(StateInterface::class)::fromArray($row)->setIsTainted($isTainted);
|
||||
if (false === $isTainted && (true === Config::get('webhook.debug') || null !== ag(
|
||||
$request->getQueryParams(),
|
||||
'debug'
|
||||
))) {
|
||||
saveWebhookPayload($this->name . '.' . $event, $request, [
|
||||
'entity' => $entity->getAll(),
|
||||
'payload' => $json,
|
||||
]);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
protected function getParentGUIDs(mixed $id, string|null $series): array
|
||||
protected function getEpisodeParent(mixed $id, string|null $series): array
|
||||
{
|
||||
if (null !== $series && array_key_exists($series, $this->cacheShow)) {
|
||||
return $this->cacheShow[$series];
|
||||
|
||||
@@ -366,49 +366,56 @@ class PlexServer implements ServerInterface
|
||||
];
|
||||
}
|
||||
|
||||
$isWatched = (int)(bool)ag($json, 'Metadata.viewCount', 0);
|
||||
|
||||
$date = time();
|
||||
|
||||
if (!$this->hasSupportedIds($json['Metadata']['Guid'] ?? [])) {
|
||||
throw new HttpException(
|
||||
sprintf(
|
||||
'%s: No supported GUID was given. [%s]',
|
||||
afterLast(__CLASS__, '\\'),
|
||||
arrayToString($json['Metadata']['Guid'] ?? [])
|
||||
),
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
$guids = $this->getGuids($json['Metadata']['Guid'] ?? [], $type);
|
||||
|
||||
foreach (Guid::fromArray($guids)->getPointers() as $guid) {
|
||||
$this->cacheData[$guid] = ag($json, 'Metadata.guid');
|
||||
}
|
||||
|
||||
if (false === $isTainted && StateInterface::TYPE_EPISODE === $type) {
|
||||
$meta['parent'] = $this->getParentGUIDs(
|
||||
$json['Metadata']['grandparentRatingKey'] ?? $json['Metadata']['parentRatingKey']
|
||||
);
|
||||
if (StateInterface::TYPE_EPISODE === $type) {
|
||||
$parentId = ag($json, 'Metadata.grandparentRatingKey', fn() => ag($json, 'Metadata.parentRatingKey'));
|
||||
$meta['parent'] = null !== $parentId ? $this->getEpisodeParent($parentId) : [];
|
||||
}
|
||||
|
||||
$row = [
|
||||
'type' => $type,
|
||||
'updated' => $date,
|
||||
'watched' => $isWatched,
|
||||
'updated' => time(),
|
||||
'watched' => (int)(bool)ag($json, 'Metadata.viewCount', 0),
|
||||
'meta' => $meta,
|
||||
...$guids
|
||||
];
|
||||
|
||||
if (true === Config::get('webhook.debug') || null !== ag($request->getQueryParams(), 'debug')) {
|
||||
saveWebhookPayload($request, "{$this->name}.{$event}", $json + ['entity' => $row]);
|
||||
$entity = Container::get(StateInterface::class)::fromArray($row)->setIsTainted($isTainted);
|
||||
|
||||
if (!$entity->hasGuids()) {
|
||||
throw new HttpException(
|
||||
sprintf(
|
||||
'%s: No supported GUID was given. [%s]',
|
||||
afterLast(__CLASS__, '\\'),
|
||||
arrayToString(
|
||||
[
|
||||
'guids' => !empty($json['Metadata']['Guid']) ? $json['Metadata']['Guid'] : 'None',
|
||||
'rGuids' => $entity->hasRelativeGuids() ? $entity->getRelativeGuids() : 'None',
|
||||
]
|
||||
)
|
||||
), 400
|
||||
);
|
||||
}
|
||||
|
||||
return Container::get(StateInterface::class)::fromArray($row)->setIsTainted($isTainted);
|
||||
if (false !== $isTainted && (true === Config::get('webhook.debug') || null !== ag(
|
||||
$request->getQueryParams(),
|
||||
'debug'
|
||||
))) {
|
||||
saveWebhookPayload($this->name . '.' . $event, $request, [
|
||||
'entity' => $entity->getAll(),
|
||||
'payload' => $json,
|
||||
]);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
protected function getParentGUIDs(mixed $id): array
|
||||
protected function getEpisodeParent(int|string $id): array
|
||||
{
|
||||
if (array_key_exists($id, $this->cacheShow)) {
|
||||
return $this->cacheShow[$id];
|
||||
@@ -443,7 +450,6 @@ class PlexServer implements ServerInterface
|
||||
$json['Guid'][] = ['id' => $json['guid']];
|
||||
}
|
||||
|
||||
|
||||
if (!$this->hasSupportedIds($json['Guid'])) {
|
||||
$this->cacheShow[$id] = [];
|
||||
return $this->cacheShow[$id];
|
||||
@@ -1850,8 +1856,10 @@ class PlexServer implements ServerInterface
|
||||
'date' => makeDate($item->originallyAvailableAt ?? 'now')->format('Y-m-d'),
|
||||
];
|
||||
|
||||
if (null !== ($item->grandparentRatingKey ?? null)) {
|
||||
$meta['parent'] = $this->showInfo[$item->grandparentRatingKey] ?? [];
|
||||
$parentId = $item->grandparentRatingKey ?? $item->parentRatingKey ?? null;
|
||||
|
||||
if (null !== $parentId) {
|
||||
$meta['parent'] = $this->showInfo[$parentId] ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ if (!function_exists('fsize')) {
|
||||
}
|
||||
|
||||
if (!function_exists('saveWebhookPayload')) {
|
||||
function saveWebhookPayload(ServerRequestInterface $request, string $name, array $parsed = []): void
|
||||
function saveWebhookPayload(string $name, ServerRequestInterface $request, array $parsed = []): void
|
||||
{
|
||||
$content = [
|
||||
'query' => $request->getQueryParams(),
|
||||
|
||||
Reference in New Issue
Block a user