Reorganize SQLite data files

- Add episode data structure (#9)
- Add fields for chapters (#6) and transcripts (#8)
- Add fields for medium (#3), funding (#7), and GUID (#4)
- Fix RethinkDB restore problems (#10)
- Save custom feeds in SQLite (#11)
This commit is contained in:
2022-06-24 21:56:07 -04:00
parent dfb0ff3b9c
commit 707b67c630
15 changed files with 2484 additions and 1823 deletions

View File

@@ -190,6 +190,9 @@ type Post =
/// The tags for the post
tags : string list
/// Podcast episode information for this post
episode : Episode option
/// Metadata for the post
metadata : MetaItem list
@@ -217,6 +220,7 @@ module Post =
template = None
categoryIds = []
tags = []
episode = None
metadata = []
priorPermalinks = []
revisions = []

View File

@@ -68,6 +68,109 @@ module CommentStatus =
| it -> invalidOp $"{it} is not a valid post status"
/// Valid values for the iTunes explicit rating
type ExplicitRating =
| Yes
| No
| Clean
/// Functions to support iTunes explicit ratings
module ExplicitRating =
/// Convert an explicit rating to a string
let toString : ExplicitRating -> string =
function
| Yes -> "yes"
| No -> "no"
| Clean -> "clean"
/// Parse a string into an explicit rating
let parse : string -> ExplicitRating =
function
| "yes" -> Yes
| "no" -> No
| "clean" -> Clean
| x -> raise (invalidArg "rating" $"{x} is not a valid explicit rating")
/// A podcast episode
type Episode =
{ /// The URL to the media file for the episode (may be permalink)
media : string
/// The length of the media file, in bytes
length : int64
/// The duration of the episode
duration : TimeSpan option
/// The media type of the file (overrides podcast default if present)
mediaType : string option
/// The URL to the image file for this episode (overrides podcast image if present, may be permalink)
imageUrl : string option
/// A subtitle for this episode
subtitle : string option
/// This episode's explicit rating (overrides podcast rating if present)
explicit : ExplicitRating option
/// A link to a chapter file
chapterFile : string option
/// The MIME type for the chapter file
chapterType : string option
/// The URL for the transcript of the episode (may be permalink)
transcriptUrl : string option
/// The MIME type of the transcript
transcriptType : string option
/// The language in which the transcript is written
transcriptLang : string option
/// If true, the transcript will be declared (in the feed) to be a captions file
transcriptCaptions : bool option
/// The season number (for serialized podcasts)
seasonNumber : int option
/// A description of the season
seasonDescription : string option
/// The episode number
episodeNumber : double option
/// A description of the episode
episodeDescription : string option
}
/// Functions to support episodes
module Episode =
/// An empty episode
let empty = {
media = ""
length = 0L
duration = None
mediaType = None
imageUrl = None
subtitle = None
explicit = None
chapterFile = None
chapterType = None
transcriptUrl = None
transcriptType = None
transcriptLang = None
transcriptCaptions = None
seasonNumber = None
seasonDescription = None
episodeNumber = None
episodeDescription = None
}
open Markdig
open Markdown.ColorCode
@@ -171,6 +274,43 @@ module PageId =
let create () = PageId (newId ())
/// PodcastIndex.org podcast:medium allowed values
type PodcastMedium =
| Podcast
| Music
| Video
| Film
| Audiobook
| Newsletter
| Blog
/// Functions to support podcast medium
module PodcastMedium =
/// Convert a podcast medium to a string
let toString =
function
| Podcast -> "podcast"
| Music -> "music"
| Video -> "video"
| Film -> "film"
| Audiobook -> "audiobook"
| Newsletter -> "newsletter"
| Blog -> "blog"
/// Parse a string into a podcast medium
let parse value =
match value with
| "podcast" -> Podcast
| "music" -> Music
| "video" -> Video
| "film" -> Film
| "audiobook" -> Audiobook
| "newsletter" -> Newsletter
| "blog" -> Blog
| it -> invalidOp $"{it} is not a valid podcast medium"
/// Statuses for posts
type PostStatus =
/// The post should not be publicly available
@@ -248,30 +388,6 @@ module CustomFeedSource =
| source -> invalidArg "feedSource" $"{source} is not a valid feed source"
/// Valid values for the iTunes explicit rating
type ExplicitRating =
| Yes
| No
| Clean
/// Functions to support iTunes explicit ratings
module ExplicitRating =
/// Convert an explicit rating to a string
let toString : ExplicitRating -> string =
function
| Yes -> "yes"
| No -> "no"
| Clean -> "clean"
/// Parse a string into an explicit rating
let parse : string -> ExplicitRating =
function
| "yes" -> Yes
| "no" -> No
| "clean" -> Clean
| x -> raise (invalidArg "rating" $"{x} is not a valid explicit rating")
/// Options for a feed that describes a podcast
type PodcastOptions =
{ /// The title of the podcast
@@ -309,6 +425,18 @@ type PodcastOptions =
/// The base URL for relative URL media files for this podcast (optional; defaults to web log base)
mediaBaseUrl : string option
/// A GUID for this podcast
guid : Guid option
/// A URL at which information on supporting the podcast may be found (supports permalinks)
fundingUrl : string option
/// The text to be displayed in the funding item within the feed
fundingText : string option
/// The medium (what the podcast IS, not what it is ABOUT)
medium : PodcastMedium option
}

View File

@@ -300,6 +300,11 @@ type EditCustomFeedModel =
explicit = ExplicitRating.parse this.explicit
defaultMediaType = noneIfBlank this.defaultMediaType
mediaBaseUrl = noneIfBlank this.mediaBaseUrl
// TODO: implement UI to update these
guid = None
fundingUrl = None
fundingText = None
medium = None
}
else
None