Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ gleam add webls
```

```gleam
import gleam/time/timestamp
import webls/sitemap
import webls/rss
import webls/robots

pub fn sitemap() -> String {
sitemap.sitemap("https://gleam.run/sitemap.xml")
|> sitemap.with_sitemap_last_modified(birl.now())
|> sitemap.with_sitemap_last_modified(timestamp.system_time())
|> sitemap.with_sitemap_items([
sitemap.item("https://gleam.run")
|> sitemap.with_item_frequency(sitemap.Monthly)
Expand All @@ -37,7 +38,7 @@ pub fn rss() -> String {
|> rss.with_channel_items([
rss.item("Gleam 1.0", "Gleam 1.0 is here!")
|> rss.with_item_link("https://gleam.run/blog/gleam-1.0")
|> rss.with_item_pub_date(birl.now())
|> rss.with_item_pub_date(timestamp.system_time())
|> rss.with_item_guid(#("gleam 1.0", Some(False))),
rss.item("Gleam 0.10", "Gleam 0.10 is here!")
|> rss.with_item_link("https://gleam.run/blog/gleam-0.10")
Expand Down
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ repository = { type = "github", user = "versecafe", repo = "webls" }

[dependencies]
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
birl = ">= 1.7.1 and < 2.0.0"
gleam_time = ">= 1.6.0 and < 2.0.0"

[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
11 changes: 4 additions & 7 deletions manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@
# You typically do not need to edit this file

packages = [
{ name = "birl", version = "1.8.0", build_tools = ["gleam"], requirements = ["gleam_regexp", "gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "2AC7BA26F998E3DFADDB657148BD5DDFE966958AD4D6D6957DD0D22E5B56C400" },
{ name = "gleam_regexp", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "9C215C6CA84A5B35BB934A9B61A9A306EC743153BE2B0425A0D032E477B062A9" },
{ name = "gleam_stdlib", version = "0.62.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "0080706D3A5A9A36C40C68481D1D231D243AF602E6D2A2BE67BA8F8F4DFF45EC" },
{ name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" },
{ name = "gleeunit", version = "1.6.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "FDC68A8C492B1E9B429249062CD9BAC9B5538C6FBF584817205D0998C42E1DAC" },
{ name = "ranger", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_yielder"], otp_app = "ranger", source = "hex", outer_checksum = "C8988E8F8CDBD3E7F4D8F2E663EF76490390899C2B2885A6432E942495B3E854" },
{ name = "gleam_stdlib", version = "0.68.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "F7FAEBD8EF260664E86A46C8DBA23508D1D11BB3BCC6EE1B89B3BC3E5C83FF1E" },
{ name = "gleam_time", version = "1.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_time", source = "hex", outer_checksum = "0DF3834D20193F0A38D0EB21F0A78D48F2EC276C285969131B86DF8D4EF9E762" },
{ name = "gleeunit", version = "1.9.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "DA9553CE58B67924B3C631F96FE3370C49EB6D6DC6B384EC4862CC4AAA718F3C" },
]

[requirements]
birl = { version = ">= 1.7.1 and < 2.0.0" }
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
gleam_time = { version = ">= 1.6.0 and < 2.0.0" }
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
29 changes: 16 additions & 13 deletions src/webls/atom.gleam
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import birl.{type Time}
import gleam/int
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/result
import gleam/time/calendar
import gleam/time/timestamp.{type Timestamp}

// Stringify ------------------------------------------------------------------

Expand All @@ -21,7 +22,7 @@ fn atom_feed_to_string(feed: AtomFeed) -> String {
<> text_to_string(feed.title)
<> "</title>\n"
<> "<updated>"
<> birl.to_iso8601(feed.updated)
<> timestamp.to_rfc3339(feed.updated, calendar.utc_offset)
<> "</updated>\n"
<> list.map(feed.authors, person_to_string)
|> list.reduce(fn(acc, author) { acc <> author })
Expand Down Expand Up @@ -70,7 +71,7 @@ fn atom_entry_to_string(entry: AtomEntry) -> String {
<> text_to_string(entry.title)
<> "</title>\n"
<> "<updated>"
<> birl.to_iso8601(entry.updated)
<> timestamp.to_rfc3339(entry.updated, calendar.utc_offset)
<> "</updated>\n"
<> list.map(entry.authors, person_to_string)
|> list.reduce(fn(acc, author) { acc <> author })
Expand All @@ -95,7 +96,9 @@ fn atom_entry_to_string(entry: AtomEntry) -> String {
|> result.unwrap("")
<> case entry.published {
Some(published) ->
"<published>" <> birl.to_iso8601(published) <> "</published>\n"
"<published>"
<> timestamp.to_rfc3339(published, calendar.utc_offset)
<> "</published>\n"
None -> ""
}
<> case entry.rights {
Expand Down Expand Up @@ -189,7 +192,7 @@ fn source_to_string(source: Source) -> String {
<> source.title
<> "</title>\n"
<> "<updated>"
<> birl.to_iso8601(source.updated)
<> timestamp.to_rfc3339(source.updated, calendar.utc_offset)
<> "</updated>\n"
<> "</source>\n"
}
Expand Down Expand Up @@ -271,7 +274,7 @@ pub fn with_person_uri(person: Person, uri: String) -> Person {
Person(..person, uri: Some(uri))
}

pub fn feed(id: String, title: Text, updated: Time) -> AtomFeed {
pub fn feed(id: String, title: Text, updated: Timestamp) -> AtomFeed {
AtomFeed(
id: id,
title: title,
Expand All @@ -289,7 +292,7 @@ pub fn feed(id: String, title: Text, updated: Time) -> AtomFeed {
)
}

pub fn entry(id: String, title: Text, updated: Time) -> AtomEntry {
pub fn entry(id: String, title: Text, updated: Timestamp) -> AtomEntry {
AtomEntry(
id: id,
title: title,
Expand All @@ -314,7 +317,7 @@ pub fn with_entry_title(entry: AtomEntry, title: Text) -> AtomEntry {
AtomEntry(..entry, title: title)
}

pub fn with_entry_updated(entry: AtomEntry, updated: Time) -> AtomEntry {
pub fn with_entry_updated(entry: AtomEntry, updated: Timestamp) -> AtomEntry {
AtomEntry(..entry, updated: updated)
}

Expand Down Expand Up @@ -351,7 +354,7 @@ pub fn with_entry_contributors(
)
}

pub fn with_entry_published(entry: AtomEntry, published: Time) -> AtomEntry {
pub fn with_entry_published(entry: AtomEntry, published: Timestamp) -> AtomEntry {
AtomEntry(..entry, published: Some(published))
}

Expand Down Expand Up @@ -434,7 +437,7 @@ pub type AtomFeed {
AtomFeed(
id: String,
title: Text,
updated: Time,
updated: Timestamp,
authors: List(Person),
link: Option(Link),
categories: List(Category),
Expand Down Expand Up @@ -475,14 +478,14 @@ pub type AtomEntry {
AtomEntry(
id: String,
title: Text,
updated: Time,
updated: Timestamp,
authors: List(Person),
content: Option(Text),
link: Option(Link),
summary: Option(Text),
categories: List(Category),
contributors: List(Person),
published: Option(Time),
published: Option(Timestamp),
rights: Option(Text),
source: Option(Source),
)
Expand All @@ -495,5 +498,5 @@ pub type Text {
}

pub type Source {
Source(id: String, title: String, updated: Time)
Source(id: String, title: String, updated: Timestamp)
}
56 changes: 43 additions & 13 deletions src/webls/rss.gleam
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import birl.{type Time}
import gleam/int
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/result
import gleam/time/calendar
import gleam/time/timestamp.{type Timestamp}

// Stringify ------------------------------------------------------------------

Expand Down Expand Up @@ -55,13 +56,15 @@ fn rss_channel_to_string(channel: RssChannel) -> String {
}
<> case channel.pub_date {
Some(pub_date) ->
"<pubDate>" <> pub_date |> birl.to_iso8601 <> "</pubDate>\n"
"<pubDate>"
<> pub_date |> timestamp.to_rfc3339(calendar.utc_offset)
<> "</pubDate>\n"
_ -> ""
}
<> case channel.last_build_date {
Some(last_build_date) ->
"<lastBuildDate>"
<> last_build_date |> birl.to_iso8601
<> last_build_date |> timestamp.to_rfc3339(calendar.utc_offset)
<> "</lastBuildDate>\n"
_ -> ""
}
Expand Down Expand Up @@ -158,7 +161,7 @@ fn rss_channel_to_string(channel: RssChannel) -> String {
True -> {
"<skipDays>"
<> list.map(channel.skip_days, fn(day) {
"<day>" <> day |> birl.weekday_to_string <> "</day>"
"<day>" <> day |> weekday_to_string <> "</day>"
})
|> list.reduce(fn(acc, day) { acc <> "\n" <> day })
|> result.unwrap("")
Expand Down Expand Up @@ -196,7 +199,9 @@ fn rss_item_to_string(item: RssItem) -> String {
}
<> case item.pub_date {
Some(pub_date) ->
"<pubDate>" <> pub_date |> birl.to_iso8601 <> "</pubDate>\n"
"<pubDate>"
<> pub_date |> timestamp.to_rfc3339(calendar.utc_offset)
<> "</pubDate>\n"
_ -> ""
}
<> item.categories
Expand Down Expand Up @@ -234,6 +239,18 @@ fn rss_item_to_string(item: RssItem) -> String {
<> "</item>"
}

fn weekday_to_string(weekday: Weekday) -> String {
case weekday {
Monday -> "Monday"
Tuesday -> "Tuesday"
Wednesday -> "Wednesday"
Thursday -> "Thursday"
Friday -> "Friday"
Saturday -> "Saturday"
Sunday -> "Sunday"
}
}

// Builder Pattern -------------------------------------------------------------

/// Creates a base RSS channel
Expand Down Expand Up @@ -294,14 +311,17 @@ pub fn with_channel_web_master(
}

/// Sets the publication date of the RSS channel
pub fn with_channel_pub_date(channel: RssChannel, pub_date: Time) -> RssChannel {
pub fn with_channel_pub_date(
channel: RssChannel,
pub_date: Timestamp,
) -> RssChannel {
RssChannel(..channel, pub_date: Some(pub_date))
}

/// Sets the last build date of the RSS channel
pub fn with_channel_last_build_date(
channel: RssChannel,
last_build_date: Time,
last_build_date: Timestamp,
) -> RssChannel {
RssChannel(..channel, last_build_date: Some(last_build_date))
}
Expand Down Expand Up @@ -378,7 +398,7 @@ pub fn with_channel_skip_hours(
/// Sets a list of days to skip in the RSS channel
pub fn with_channel_skip_days(
channel: RssChannel,
skip_days: List(birl.Weekday),
skip_days: List(Weekday),
) -> RssChannel {
RssChannel(..channel, skip_days: skip_days)
}
Expand Down Expand Up @@ -443,7 +463,7 @@ pub fn with_item_guid(item: RssItem, guid: #(String, Option(Bool))) -> RssItem {
}

/// Sets the publication date of the RSS item
pub fn with_item_pub_date(item: RssItem, pub_date: Time) -> RssItem {
pub fn with_item_pub_date(item: RssItem, pub_date: Timestamp) -> RssItem {
RssItem(..item, pub_date: Some(pub_date))
}

Expand Down Expand Up @@ -472,9 +492,9 @@ pub type RssChannel {
/// The web master’s email address
web_master: Option(String),
/// The publication date of the RSS channel
pub_date: Option(Time),
pub_date: Option(Timestamp),
/// The last build date of the RSS channel
last_build_date: Option(Time),
last_build_date: Option(Timestamp),
/// A list of categories for the RSS channel
categories: List(String),
/// The generator program of the RSS channel, feel free to shout webls out!
Expand All @@ -492,7 +512,7 @@ pub type RssChannel {
/// A list of hours in GMT which content aggregation should be skipped
skip_hours: List(Int),
/// A list of days to skip in the RSS channel
skip_days: List(birl.Weekday),
skip_days: List(Weekday),
/// A list of items in the RSS channel
items: List(RssItem),
)
Expand Down Expand Up @@ -574,7 +594,7 @@ pub type RssItem {
/// The RSS channel the item came from
source: Option(String),
/// The publication date of the RSS item
pub_date: Option(Time),
pub_date: Option(Timestamp),
/// A list of categories for the RSS item
categories: List(String),
/// An optional enclosure resource for the RSS item
Expand All @@ -583,3 +603,13 @@ pub type RssItem {
guid: Option(#(String, Option(Bool))),
)
}

pub type Weekday {
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
}
19 changes: 13 additions & 6 deletions src/webls/sitemap.gleam
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import birl.{type Time}
import gleam/float
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/result
import gleam/time/calendar
import gleam/time/timestamp.{type Timestamp}

// Stringify ------------------------------------------------------------------

Expand All @@ -25,7 +26,10 @@ fn sitemap_item_to_string(item: SitemapItem) -> String {
<> item.loc
<> "</loc>\n"
<> case item.last_modified {
Some(date) -> "<lastmod>" <> date |> birl.to_iso8601 <> "</lastmod>\n"
Some(date) ->
"<lastmod>"
<> date |> timestamp.to_rfc3339(calendar.utc_offset)
<> "</lastmod>\n"
_ -> ""
}
<> case item.change_frequency {
Expand Down Expand Up @@ -73,7 +77,7 @@ pub fn with_sitemap_item(sitemap: Sitemap, item: SitemapItem) -> Sitemap {
/// Add a last modified time to the sitemap
pub fn with_sitemap_last_modified(
sitemap: Sitemap,
last_modified: Time,
last_modified: Timestamp,
) -> Sitemap {
Sitemap(..sitemap, last_modified: Some(last_modified))
}
Expand Down Expand Up @@ -102,7 +106,10 @@ pub fn with_item_priority(item: SitemapItem, priority: Float) -> SitemapItem {
}

/// Add a last modified time to the sitemap item
pub fn with_item_last_modified(item: SitemapItem, modified: Time) -> SitemapItem {
pub fn with_item_last_modified(
item: SitemapItem,
modified: Timestamp,
) -> SitemapItem {
SitemapItem(..item, last_modified: Some(modified))
}

Expand All @@ -114,7 +121,7 @@ pub type Sitemap {
/// The url location of the sitemap
url: String,
/// The time of last modification of the sitemap
last_modified: Option(Time),
last_modified: Option(Timestamp),
/// The list of items contained within the sitemap
items: List(SitemapItem),
)
Expand All @@ -126,7 +133,7 @@ pub type SitemapItem {
/// The location/url of the page
loc: String,
/// The time of last modification of the page
last_modified: Option(Time),
last_modified: Option(Timestamp),
/// How frequently the page is likely to continue to change
change_frequency: Option(ChangeFrequency),
/// The priority of the page compared to others within the sitemap
Expand Down
Loading
Loading