Podcast endpoints (#3140)

* Add: `AudioTrack.yaml`

* Fix: audiotrack example

* Initial: podcast schemas and endpoints

* Update schemas

* Add: podcasts tag

* Update bundled spec
This commit is contained in:
Nicholas W 2024-07-11 14:29:35 -07:00 committed by GitHub
parent acaf1ac196
commit c5e60d30e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 1810 additions and 0 deletions

View File

@ -0,0 +1,355 @@
paths:
/api/podcasts:
post:
summary: Create a new podcast
operationId: createPodcast
tags:
- Podcasts
requestBody:
required: true
content:
application/json:
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/Podcast'
responses:
200:
description: Successfully created a podcast
content:
application/json:
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/Podcast'
400:
description: Bad request
403:
description: Forbidden
404:
description: Not found
/api/podcasts/feed:
post:
summary: Get podcast feed
operationId: getPodcastFeed
tags:
- Podcasts
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
rssFeed:
type: string
description: The RSS feed URL of the podcast
responses:
200:
description: Successfully retrieved podcast feed
content:
application/json:
schema:
type: object
properties:
podcast:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/Podcast'
400:
description: Bad request
403:
description: Forbidden
404:
description: Not found
/api/podcasts/opml:
post:
summary: Get feeds from OPML text
operationId: getFeedsFromOPMLText
tags:
- Podcasts
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
opmlText:
type: string
description: The OPML text containing podcast feeds
responses:
200:
description: Successfully retrieved feeds from OPML text
content:
application/json:
schema:
type: array
items:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/Podcast'
400:
description: Bad request
403:
description: Forbidden
/api/podcasts/{id}/checknew:
parameters:
- name: id
in: path
description: Podcast ID
required: true
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
get:
summary: Check and download new episodes
operationId: checkNewEpisodes
tags:
- Podcasts
parameters:
- name: limit
in: query
description: Maximum number of episodes to download
required: false
schema:
type: integer
responses:
200:
description: Successfully checked and downloaded new episodes
content:
application/json:
schema:
type: object
properties:
episodes:
type: array
items:
$ref: '../objects/entities/PodcastEpisode.yaml#/components/schemas/PodcastEpisode'
403:
description: Forbidden
404:
description: Not found
500:
description: Server error
/api/podcasts/{id}/clear-queue:
parameters:
- name: id
in: path
description: Podcast ID
required: true
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
get:
summary: Clear episode download queue
operationId: clearEpisodeDownloadQueue
tags:
- Podcasts
responses:
200:
description: Successfully cleared download queue
403:
description: Forbidden
/api/podcasts/{id}/downloads:
parameters:
- name: id
in: path
description: Podcast ID
required: true
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
get:
summary: Get episode downloads
operationId: getEpisodeDownloads
tags:
- Podcasts
responses:
200:
description: Successfully retrieved episode downloads
content:
application/json:
schema:
type: object
properties:
downloads:
type: array
items:
$ref: '../objects/entities/PodcastEpisode.yaml#/components/schemas/PodcastEpisode'
404:
description: Not found
/api/podcasts/{id}/search-episode:
parameters:
- name: id
in: path
description: Podcast ID
required: true
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
get:
summary: Find episode by title
operationId: findEpisode
tags:
- Podcasts
parameters:
- name: title
in: query
description: Title of the episode to search for
required: true
schema:
type: string
responses:
200:
description: Successfully found episodes
content:
application/json:
schema:
type: object
properties:
episodes:
type: array
items:
$ref: '../objects/entities/PodcastEpisode.yaml#/components/schemas/PodcastEpisode'
404:
description: Not found
500:
description: Server error
/api/podcasts/{id}/download-episodes:
parameters:
- name: id
in: path
description: Podcast ID
required: true
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
post:
summary: Download podcast episodes
operationId: downloadEpisodes
tags:
- Podcasts
requestBody:
required: true
content:
application/json:
schema:
type: array
items:
type: string
responses:
200:
description: Successfully started episode download
400:
description: Bad request
403:
description: Forbidden
/api/podcasts/{id}/match-episodes:
parameters:
- name: id
in: path
description: Podcast ID
required: true
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
post:
summary: Quick match podcast episodes
operationId: quickMatchEpisodes
tags:
- Podcasts
parameters:
- name: override
in: query
description: Override existing details if set to 1
required: false
schema:
type: string
responses:
200:
description: Successfully matched episodes
content:
application/json:
schema:
type: object
properties:
numEpisodesUpdated:
type: integer
403:
description: Forbidden
/api/podcasts/{id}/episode/{episodeId}:
parameters:
- name: id
in: path
description: Podcast ID
required: true
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
- name: episodeId
in: path
description: Episode ID
required: true
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
patch:
summary: Update a podcast episode
operationId: updateEpisode
tags:
- Podcasts
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
200:
description: Successfully updated episode
content:
application/json:
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/Podcast'
404:
description: Not found
get:
summary: Get a specific podcast episode
operationId: getEpisode
tags:
- Podcasts
responses:
200:
description: Successfully retrieved episode
content:
application/json:
schema:
$ref: '../objects/entities/PodcastEpisode.yaml#/components/schemas/PodcastEpisode'
404:
description: Not found
delete:
summary: Remove a podcast episode
operationId: removeEpisode
tags:
- Podcasts
parameters:
- name: hard
in: query
description: Hard delete the episode if set to 1
required: false
schema:
type: string
responses:
200:
description: Successfully removed episode
content:
application/json:
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/Podcast'
404:
description: Not found
500:
description: Server error

View File

@ -0,0 +1,74 @@
components:
schemas:
PodcastEpisode:
type: object
description: A single episode of a podcast.
properties:
libraryItemId:
$ref: '../LibraryItem.yaml#/components/schemas/libraryItemId'
podcastId:
$ref: '../mediaTypes/Podcast.yaml#/components/schemas/podcastId'
id:
$ref: '../mediaTypes/Podcast.yaml#/components/schemas/podcastId'
oldEpisodeId:
$ref: '../mediaTypes/Podcast.yaml#/components/schemas/oldPodcastId'
index:
type: integer
description: The index of the episode within the podcast.
nullable: true
season:
type: string
description: The season number of the episode.
nullable: true
episode:
type: string
description: The episode number within the season.
nullable: true
episodeType:
type: string
description: The type of episode (e.g., full, trailer).
nullable: true
title:
type: string
description: The title of the episode.
nullable: true
subtitle:
type: string
description: The subtitle of the episode.
nullable: true
description:
type: string
description: The description of the episode.
nullable: true
enclosure:
type: object
description: The enclosure object containing additional episode data.
nullable: true
additionalProperties: true
guid:
type: string
description: The globally unique identifier for the episode.
nullable: true
pubDate:
type: string
description: The publication date of the episode.
nullable: true
chapters:
type: array
description: The chapters within the episode.
items:
type: object
audioFile:
$ref: '../files/AudioFile.yaml#/components/schemas/audioFile'
publishedAt:
$ref: '../../schemas.yaml#/components/schemas/createdAt'
addedAt:
$ref: '../../schemas.yaml#/components/schemas/addedAt'
updatedAt:
$ref: '../../schemas.yaml#/components/schemas/updatedAt'
audioTrack:
$ref: '../files/AudioTrack.yaml#/components/schemas/AudioTrack'
duration:
$ref: '../../schemas.yaml#/components/schemas/durationSec'
size:
$ref: '../../schemas.yaml#/components/schemas/size'

View File

@ -0,0 +1,45 @@
components:
schemas:
AudioTrack:
type: object
description: Represents an audio track with various properties.
properties:
index:
type: integer
nullable: true
description: The index of the audio track.
example: null
startOffset:
type: number
format: float
nullable: true
description: The start offset of the audio track in seconds.
example: null
duration:
type: number
format: float
nullable: true
description: The duration of the audio track in seconds.
example: null
title:
type: string
nullable: true
description: The title of the audio track.
example: null
contentUrl:
type: string
nullable: true
description: The URL where the audio track content is located.
example: '`/api/items/${itemId}/file/${audioFile.ino}`'
mimeType:
type: string
nullable: true
description: The MIME type of the audio track.
example: null
codec:
type: string
nullable: true
description: The codec used for the audio track.
example: aac
metadata:
$ref: '../metadata/FileMetadata.yaml#/components/schemas/fileMetadata'

View File

@ -0,0 +1,74 @@
components:
schemas:
podcastId:
type: string
description: The ID of podcasts and podcast episodes after 2.3.0.
format: uuid
example: e4bb1afb-4a4f-4dd6-8be0-e615d233185b
oldPodcastId:
description: The ID of podcasts on server version 2.2.23 and before.
type: string
nullable: true
format: 'pod_[a-z0-9]{18}'
example: pod_o78uaoeuh78h6aoeif
Podcast:
type: object
description: A podcast containing multiple episodes.
properties:
id:
$ref: '#/components/schemas/podcastId'
libraryItemId:
$ref: '../LibraryItem.yaml#/components/schemas/libraryItemId'
metadata:
$ref: '../metadata/PodcastMetadata.yaml#/components/schemas/PodcastMetadata'
coverPath:
type: string
description: The file path to the podcast's cover image.
nullable: true
tags:
type: array
description: The tags associated with the podcast.
items:
type: string
episodes:
type: array
description: The episodes of the podcast.
items:
$ref: '../entities/PodcastEpisode.yaml#/components/schemas/PodcastEpisode'
autoDownloadEpisodes:
type: boolean
description: Whether episodes are automatically downloaded.
autoDownloadSchedule:
type: string
description: The schedule for automatic episode downloads, in cron format.
nullable: true
lastEpisodeCheck:
type: integer
description: The timestamp of the last episode check.
maxEpisodesToKeep:
type: integer
description: The maximum number of episodes to keep.
maxNewEpisodesToDownload:
type: integer
description: The maximum number of new episodes to download when automatically downloading epsiodes.
lastCoverSearch:
type: integer
description: The timestamp of the last cover search.
nullable: true
lastCoverSearchQuery:
type: string
description: The query used for the last cover search.
nullable: true
size:
type: integer
description: The total size of all episodes in bytes.
duration:
type: integer
description: The total duration of all episodes in seconds.
numTracks:
type: integer
description: The number of tracks (episodes) in the podcast.
latestEpisodePublished:
type: integer
description: The timestamp of the most recently published episode.

View File

@ -0,0 +1,59 @@
components:
schemas:
PodcastMetadata:
type: object
description: Metadata for a podcast.
properties:
title:
type: string
description: The title of the podcast.
nullable: true
author:
type: string
description: The author of the podcast.
nullable: true
description:
type: string
description: The description of the podcast.
nullable: true
releaseDate:
type: string
format: date-time
description: The release date of the podcast.
nullable: true
genres:
type: array
description: The genres of the podcast.
items:
type: string
feedUrl:
type: string
description: The URL of the podcast feed.
nullable: true
imageUrl:
type: string
description: The URL of the podcast's image.
nullable: true
itunesPageUrl:
type: string
description: The URL of the podcast's iTunes page.
nullable: true
itunesId:
type: string
description: The iTunes ID of the podcast.
nullable: true
itunesArtistId:
type: string
description: The iTunes artist ID of the podcast.
nullable: true
explicit:
type: boolean
description: Whether the podcast contains explicit content.
language:
type: string
description: The language of the podcast.
nullable: true
type:
type: string
description: The type of podcast (e.g., episodic, serial).
nullable: true

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,26 @@ paths:
$ref: './controllers/NotificationController.yaml#/paths/~1api~1notifications~1{id}'
/api/notifications/{id}/test:
$ref: './controllers/NotificationController.yaml#/paths/~1api~1notifications~1{id}~1test'
/api/podcasts:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts'
/api/podcasts/feed:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts~1feed'
/api/podcasts/opml:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts~1opml'
/api/podcasts/{id}/checknew:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts~1{id}~1checknew'
/api/podcasts/{id}/clear-queue:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts~1{id}~1clear-queue'
/api/podcasts/{id}/downloads:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts~1{id}~1downloads'
/api/podcasts/{id}/search-episode:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts~1{id}~1search-episode'
/api/podcasts/{id}/download-episodes:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts~1{id}~1download-episodes'
/api/podcasts/{id}/match-episodes:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts~1{id}~1match-episodes'
/api/podcasts/{id}/episode/{episodeId}:
$ref: './controllers/PodcastController.yaml#/paths/~1api~1podcasts~1{id}~1episode~1{episodeId}'
/api/series/{id}:
$ref: './controllers/SeriesController.yaml#/paths/~1api~1series~1{id}'
tags:
@ -66,3 +86,5 @@ tags:
description: Email endpoints
- name: Notification
description: Notifications endpoints
- name: Podcasts
description: Podcast endpoints

View File

@ -20,6 +20,10 @@ components:
description: The total length (in seconds) of the item or file.
type: number
example: 33854.905
duration:
description: The total length of the item or file.
type: string
example: '01:23:45'
tags:
description: Tags applied to items.
type: array