* Add PostgreSQL back end (#30)
* Upgrade password storage (#32)
* Change podcast/episode storage for SQLite (#29)
* Move date/time handling to NodaTime (#31)
This commit was merged in pull request #33.
This commit is contained in:
2022-08-21 18:56:18 -04:00
committed by GitHub
parent 1ec664ad24
commit 5f3daa1de9
45 changed files with 3820 additions and 1306 deletions

View File

@@ -1,6 +1,7 @@
namespace MyWebLog
open System
open NodaTime
/// Support functions for domain definition
[<AutoOpen>]
@@ -12,6 +13,29 @@ module private Helpers =
Convert.ToBase64String(Guid.NewGuid().ToByteArray ()).Replace('/', '_').Replace('+', '-').Substring (0, 22)
/// Functions to support NodaTime manipulation
module Noda =
/// The clock to use when getting "now" (will make mutable for testing)
let clock : IClock = SystemClock.Instance
/// The Unix epoch
let epoch = Instant.FromUnixTimeSeconds 0L
/// Truncate an instant to remove fractional seconds
let toSecondsPrecision (value : Instant) =
Instant.FromUnixTimeSeconds (value.ToUnixTimeSeconds ())
/// The current Instant, with fractional seconds truncated
let now () =
toSecondsPrecision (clock.GetCurrentInstant ())
/// Convert a date/time to an Instant with whole seconds
let fromDateTime (dt : DateTime) =
toSecondsPrecision (Instant.FromDateTimeUtc (DateTime (dt.Ticks, DateTimeKind.Utc)))
/// A user's access level
type AccessLevel =
/// The user may create and publish posts and edit the ones they have created
@@ -137,6 +161,8 @@ module ExplicitRating =
| x -> raise (invalidArg "rating" $"{x} is not a valid explicit rating")
open NodaTime.Text
/// A podcast episode
type Episode =
{ /// The URL to the media file for the episode (may be permalink)
@@ -146,7 +172,7 @@ type Episode =
Length : int64
/// The duration of the episode
Duration : TimeSpan option
Duration : Duration option
/// The media type of the file (overrides podcast default if present)
MediaType : string option
@@ -214,6 +240,10 @@ module Episode =
EpisodeNumber = None
EpisodeDescription = None
}
/// Format a duration for an episode
let formatDuration ep =
ep.Duration |> Option.map (DurationPattern.CreateWithInvariantCulture("H:mm:ss").Format)
open Markdig
@@ -269,12 +299,11 @@ module MetaItem =
let empty =
{ Name = ""; Value = "" }
/// A revision of a page or post
[<CLIMutable; NoComparison; NoEquality>]
type Revision =
{ /// When this revision was saved
AsOf : DateTime
AsOf : Instant
/// The text of the revision
Text : MarkupText
@@ -285,7 +314,7 @@ module Revision =
/// An empty revision
let empty =
{ AsOf = DateTime.UtcNow
{ AsOf = Noda.epoch
Text = Html ""
}