Skip to content

Commit

Permalink
Event publishing workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
JarrodCTaylor committed Jul 2, 2024
1 parent f706bd6 commit 28f496c
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 0 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/publish-events.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Daily Event Publishing

on:
workflow_dispatch:
# schedule:
# - cron: '0 0 * * *' # Daily at midnight UTC

jobs:
daily-backup:
runs-on: ubuntu-latest

steps:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '8'

- name: Set up Clojure
uses: DeLaGuardo/[email protected]
with:
cli: 'latest'

- name: Install CLI
run: |
curl -L -O https://github.com/clojure/brew-install/releases/latest/download/posix-install.sh
chmod +x posix-install.sh
sudo ./posix-install.sh
clojure
- name: Check out the repository
uses: actions/checkout@v4

- name: Run Event Script
run: |
cd script/eventgen
clojure -X parse/parse-feed :dir '"../../content/events"'
- name: Commit and push event page
run: |
cd content
git config --global user.name clojure-build
git config --global user.email "[email protected]"
git add content/events
git commit -m 'update events'
git push
4 changes: 4 additions & 0 deletions script/eventgen/deps.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{:paths ["src"]
:deps
{org.mnode.ical4j/ical4j {:mvn/version "4.0.0-beta5"}
org.slf4j/slf4j-nop {:mvn/version "1.7.36"}}}
129 changes: 129 additions & 0 deletions script/eventgen/src/parse.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
(ns parse
(:require
[clojure.java.io :as jio]
[clojure.string :as str])
(:import
[java.time LocalDate]
[java.io StringReader]
[net.fortuna.ical4j.model PropertyListAccessor]
[net.fortuna.ical4j.data CalendarBuilder]))

(defn coerce-date
[s]
(try
(str (subs s 0 4) "-" (subs s 4 6) "-" (subs s 6 8))
(catch Throwable _ s)))

(defn extract-props
[^PropertyListAccessor component]
(loop [[p & rp] (.getAll (.getPropertyList component))
m {}]
(if p
(let [prop-name (-> p .getName str/lower-case keyword)
prop-val (cond-> (.getValue p)
(#{:dtstart :dtend} prop-name) (coerce-date))]
(recur rp (cond-> m (not (str/blank? prop-val)) (assoc prop-name prop-val))))
m)))

(defn trim-punc-r
[s]
(let [last (dec (.length s))]
(if (contains? #{\space \tab \newline \formfeed \backspace \return \: \( \- \& \| \,}
(.charAt s last))
(trim-punc-r (subs s 0 last))
s)))

(defn title
[summary limit]
(if (< (count summary) limit)
(trim-punc-r summary)
(let [prefixes (->> [(second (re-matches #"(.[^:]+):.*" summary)) ;; . to skip leading colon
(second (re-matches #"(.[^(]+)\(.*" summary)) ;; . to skip leading (
(second (re-matches #"(.+)\s-.*" summary)) ;; \s as - is commonly in kebab case names
(second (re-matches #"(.+)&ndash.*" summary))
(second (re-matches #"(.+)&mdash.*" summary))]
;(#(do (println %) %))
(remove nil?)
(remove #(>= (count %) limit))
(remove #(< (count %) 15))
(sort-by count))]
(if (pos? (count prefixes))
(trim-punc-r (last prefixes))
(let [chop (subs summary 0 40)
ri (str/last-index-of chop " ")]
(trim-punc-r (subs summary 0 ri)))))))

(defn add-title
[event]
(if-let [summary (:summary event)]
(assoc event :title (title summary 40))
event))

(defn adoc-file
[event]
(let [title (:title event)
year (subs (:dtstart event) 0 4)]
(str year "/"
(-> title
str/lower-case
(str/replace #"[^a-z0-9\-]" (constantly "-"))
(str/replace #"[-]{2,}+" "-")
trim-punc-r)
"-"
(hash (:uid event))
".adoc")))

(defn write-event
[dir {:keys [dtstart dtend title location summary description url] :as event}]
(let [f (jio/file dir (adoc-file event))
contents
(str "= " title "\n"
dtstart "\n"
":jbake-type: event\n"
":jbake-edition: \n" ;; not using
":jbake-link: " url "\n"
":jbake-location: " (or location "unknown") "\n"
":jbake-start: " dtstart "\n"
":jbake-end: " dtend "\n"
"\n"
"== " summary "\n\n"
(str/join "\n" (map #(str % " +") (str/split description #"\r?\n|\r"))) "\n\n")]
(jio/make-parents f)
(spit f contents)))

(defn parse-feed
[{:keys [dir]}]
(let [ics (slurp "https://www.clojurians-zulip.org/feeds/events.ics")
builder (CalendarBuilder.)
cal (.build builder (StringReader. ics))
comps (.getComponents cal)
year (.getYear (LocalDate/now))
events (->> comps
(map extract-props)
(filter #(<= year (parse-long (subs (:dtstart %) 0 4))))
(map add-title))]
(run! #(write-event dir %) events)))

(comment
(def ics (slurp "https://www.clojurians-zulip.org/feeds/events.ics"))
(def builder (CalendarBuilder.))
(def cal (.build builder (StringReader. ics)))
(def comps (.getComponents cal))
(count comps)
(take 50 (map class comps))
(class (first comps))
(def c (first comps))
(class (second (.getProperties c)))
(count (.getComponentList c))
(.getProperty c "dtstart")
(extract-props c)
(set! *print-length* 100)
(let [ds (take 100 (map add-title (map extract-props comps)))]
(run! #(println (adoc-file %)) ds)
#_(run! #(println (:dtstart %) (:dtend %)) ds)
#_(run! #(println (title (:summary %) 40) "\t" %) ds))


(parse-feed {:dir "/Users/alex.miller/code/clojure-site/content/events"})

)

0 comments on commit 28f496c

Please sign in to comment.