RSS Feed working #14
7 changed files with 114 additions and 17 deletions
2
go.mod
2
go.mod
|
@ -1,3 +1,5 @@
|
||||||
module okoyono.de/buchdesmonats
|
module okoyono.de/buchdesmonats
|
||||||
|
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
|
require github.com/a-h/gemini v0.0.61
|
||||||
|
|
2
go.sum
Normal file
2
go.sum
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
github.com/a-h/gemini v0.0.61 h1:WSV9f5T6Vut9gIATUhqAh9KfsA4/kqcUIbTiDbsn1JY=
|
||||||
|
github.com/a-h/gemini v0.0.61/go.mod h1:p9wvIRDc2s3Lnbkw7CgNzDNgJHPuXDwh3dOF7w0NT8s=
|
74
src/bdm.go
74
src/bdm.go
|
@ -2,18 +2,23 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
//"html/template"
|
||||||
|
xmltpl "text/template"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
ISBN string
|
ISBN string
|
||||||
|
Author string
|
||||||
|
Title string
|
||||||
Filename string
|
Filename string
|
||||||
|
Date string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Item) ImageURL() string {
|
func (i Item) ImageURL() string {
|
||||||
|
@ -67,27 +72,61 @@ func getItems(filename string) []Item {
|
||||||
log.Fatal("Can not download the file. Network problem?")
|
log.Fatal("Can not download the file. Network problem?")
|
||||||
}
|
}
|
||||||
|
|
||||||
re := regexp.MustCompile(`[0-9]{13}`)
|
currentYear := ""
|
||||||
matches := re.FindAllString(string(content), -1)
|
currentMonth := 0
|
||||||
|
re := regexp.MustCompile(`^[^[]+ \[(?P<author>[^"]+)"(?P<title>[^"]+)"\]\([^=]+=(?P<isbn>[0-9]+).*$`)
|
||||||
|
yearRe := regexp.MustCompile(`^## (?P<year>20[0-9]{2})$`)
|
||||||
|
|
||||||
for _, isbn := range matches {
|
var yearBucket []Item
|
||||||
items = append(items, Item{ISBN: isbn, Filename: filename})
|
for _, line := range strings.Split(string(content), "\n") {
|
||||||
|
// Do we find a year?
|
||||||
|
yearMatches := yearRe.FindStringSubmatch(line)
|
||||||
|
if len(yearMatches) > 0 {
|
||||||
|
currentYear = yearMatches[1]
|
||||||
|
currentMonth = 0
|
||||||
|
|
||||||
|
// Add the bucket in reverse order
|
||||||
|
for i := len(yearBucket)-1; i >= 0; i-- {
|
||||||
|
items = append(items, yearBucket[i])
|
||||||
|
}
|
||||||
|
yearBucket = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
matches := re.FindStringSubmatch(line)
|
||||||
|
if len(matches) == 4 {
|
||||||
|
currentMonth++
|
||||||
|
|
||||||
|
yearBucket = append(yearBucket, Item{
|
||||||
|
Author: strings.Trim(matches[1], " "),
|
||||||
|
Title: strings.Trim(matches[2], " "),
|
||||||
|
ISBN: matches[3],
|
||||||
|
Date: fmt.Sprintf("01-%02d-%s", currentMonth, currentYear),
|
||||||
|
Filename: filename,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Output all items:")
|
||||||
|
for _, i := range items {
|
||||||
|
log.Printf("%v", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHTML(filename string, w http.ResponseWriter) {
|
func getTemplate(sourceFile string, templateFilename string, w http.ResponseWriter) {
|
||||||
// Get all items from the git repo
|
// Get all items from the git repo
|
||||||
items := getItems(filename)
|
items := getItems(sourceFile)
|
||||||
|
|
||||||
// Generate the restulting HTML
|
// Generate the restulting HTML
|
||||||
t, err := template.ParseFiles("templates/" + filename + ".html")
|
t, err := xmltpl.ParseFiles("templates/" + templateFilename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = t.Execute(w, items)
|
err = t.Execute(w, map[string]interface{}{
|
||||||
|
"Items": items,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -115,6 +154,7 @@ func main() {
|
||||||
err := item.downloadCover()
|
err := item.downloadCover()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Printf("%v", err)
|
||||||
fmt.Printf("ERROR: File %s not found\n", item.ImageURL())
|
fmt.Printf("ERROR: File %s not found\n", item.ImageURL())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,15 +162,25 @@ func main() {
|
||||||
|
|
||||||
http.HandleFunc("/book", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/book", func(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Print("/book")
|
log.Print("/book")
|
||||||
getHTML("BOOK.mkd", w)
|
getTemplate("BOOK.mkd", "book.html", w)
|
||||||
})
|
})
|
||||||
http.HandleFunc("/comic", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/comic", func(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Print("/comic")
|
log.Print("/comic")
|
||||||
getHTML("COMIC.mkd", w)
|
getTemplate("COMIC.mkd", "comic.html", w)
|
||||||
|
})
|
||||||
|
http.HandleFunc("/book.xml", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Print("/book.xml")
|
||||||
|
w.Header().Add("Content-Type", "Application/rss+xml")
|
||||||
|
getTemplate("BOOK.mkd", "book.xml", w)
|
||||||
|
})
|
||||||
|
http.HandleFunc("/comic.xml", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Print("/comic.xml")
|
||||||
|
w.Header().Add("Content-Type", "Application/rss+xml")
|
||||||
|
getTemplate("COMIC.mkd", "comic.xml", w)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Spawn the webserver (blocking)
|
// Spawn the webserver (blocking)
|
||||||
log.Print("Spawn webserver on port :9783 and waiting for requests ...")
|
log.Print("Spawn webserver on port :9783 and waiting for requests ... ...")
|
||||||
err := http.ListenAndServe(":9783", nil)
|
err := http.ListenAndServe(":9783", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -11,19 +11,19 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Buch des Monats</h1>
|
<h1>Buch des Monats</h1>
|
||||||
<p>Handverlesen und für gut befunden seit 2010
|
<p>Handerlesen und für gut befunden seit 2010
|
||||||
von <a href="https://social.okoyono.de/@mezzo" rel="author">Michael
|
von <a href="https://social.okoyono.de/@mezzo" rel="author">Michael
|
||||||
Reutter</a>. Jeden Monat ein neues Buch aus seiner Sammlung zu den
|
Reutter</a>. Jeden Monat ein neues Buch aus seiner Sammlung zu den
|
||||||
Themengebieten Netzkultur, Geektum, Computerspiele und Cyberpunk. Diese
|
Themengebieten Netzkultur, Geektum, Computerspiele und Cyberpunk. Diese
|
||||||
Bücherliste ist mittlerweile Anlaufstelle für so manchen Leser der nach
|
Bücherliste ist mittlerweile Anlaufstelle für so manchen Leser der nach
|
||||||
neuem Stoff sucht. Die Buchlinks gehen zu <a href="https://mojoreads.com/">mojoreads</a>, <a href="https://git.okoyono.de/mezzo/buch_des_monats">der
|
neuem Stoff sucht. Die Buchlinks gehen zu <a href="https://mojoreads.com/">mojoreads</a>, <a href="https://git.okoyono.de/mezzo/buch_des_monats">der
|
||||||
Code</a> ist von <a href="https://aaron-fischer.net/">Aaron Fischer</a>.
|
Code</a> von <a href="https://aaron-fischer.net/">Aaron Fischer</a>.
|
||||||
Ein <a href="https://okoyono.de/">økoyono</a> Projekt.</p>
|
Ein <a href="https://okoyono.de/">økoyono</a> Projekt.</p>
|
||||||
|
|
||||||
<div id="covers">
|
<div id="covers">
|
||||||
{{ range . }}
|
{{ range . }}
|
||||||
<div class="cover-item">
|
<div class="cover-item">
|
||||||
<a href="https://mojoreads.de/book/?isbn={{ .ISBN }}&ref=mezzo&aff=mr" target="_blank" ><img src="/covers/{{ .ISBN }}.jpg" alt="Mojoreads cover" title="zu Mojoreads" /></a>
|
<a target="_blank" href="https://mojoreads.de/book/?isbn={{ .ISBN }}&ref=mezzo&aff=mr"><img src="/covers/{{ .ISBN }}.jpg" alt="{{ .Author | html }} - {{ .Title | html }}" title="zu Mojoreads" /></a>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
21
templates/book.xml
Normal file
21
templates/book.xml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
|
||||||
|
<title>okoyono.de -- Buch des Monats</title>
|
||||||
|
<link href="https://buchdesmonats.okoyono.de/"/>
|
||||||
|
<updated>{{ (index .Items 0).Date }}T00:00:00Z</updated>
|
||||||
|
<author>
|
||||||
|
<name>Michael Reutter</name>
|
||||||
|
</author>
|
||||||
|
<id>urn:uuid:{{ (index .Items 0).ISBN }}</id>
|
||||||
|
|
||||||
|
{{ range .Items }}
|
||||||
|
<entry>
|
||||||
|
<title>{{ .Author | html }} - "{{ .Title | html }}"</title>
|
||||||
|
<link href="https://mojoreads.de/book/?isbn={{ .ISBN }}&ref=mezzo&aff=mr"/>
|
||||||
|
<id>urn:uuid:{{ .ISBN }}</id>
|
||||||
|
<updated>{{ .Date }}T00:00:00Z</updated>
|
||||||
|
<summary>{{ .Author | html }} - "{{ .Title | html }}"</summary>
|
||||||
|
</entry>
|
||||||
|
{{ end }}
|
||||||
|
</feed>
|
|
@ -16,9 +16,9 @@
|
||||||
Code</a> ist von <a href="https://aaron-fischer.net/">Aaron Fischer</a>. Ein <a href="https://okoyono.de/">økoyono</a> Projekt. (Eine Seite mit Buchempfehlungen findet Ihr <a href="https://buchdesmonats.okoyono.de">hier</a>)</p>
|
Code</a> ist von <a href="https://aaron-fischer.net/">Aaron Fischer</a>. Ein <a href="https://okoyono.de/">økoyono</a> Projekt. (Eine Seite mit Buchempfehlungen findet Ihr <a href="https://buchdesmonats.okoyono.de">hier</a>)</p>
|
||||||
|
|
||||||
<div id="covers">
|
<div id="covers">
|
||||||
{{ range . }}
|
{{ range .Items }}
|
||||||
<div class="cover-item">
|
<div class="cover-item">
|
||||||
<a href="https://mojoreads.de/book/?isbn={{ .ISBN }}&ref=mezzo&aff=mr" target="_blank"><img src="/covers/{{ .ISBN }}.jpg" alt="Mojoreads cover" title="zu Mojoreads" /></a>
|
<a target="_blank" href="https://mojoreads.de/book/?isbn={{ .ISBN }}&ref=mezzo&aff=mr"><img src="/covers/{{ .ISBN }}.jpg" alt="{{ .Author | html }} - {{ .Title | html }}" title="zu Mojoreads" /></a>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
22
templates/comic.xml
Normal file
22
templates/comic.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
|
||||||
|
<title>okoyono.de -- Comic des Monats</title>
|
||||||
|
<link href="https://comicdesmonats.okoyono.de/"/>
|
||||||
|
<updated>{{ (index .Items 0).Date }}T00:00:00Z</updated>
|
||||||
|
<author>
|
||||||
|
<name>Michael Reutter</name>
|
||||||
|
</author>
|
||||||
|
<id>urn:uuid:{{ (index .Items 0).ISBN }}</id>
|
||||||
|
|
||||||
|
{{ range .Items }}
|
||||||
|
<entry>
|
||||||
|
<title>{{ .Author | html }} - "{{ .Title | html }}"</title>
|
||||||
|
<link href="https://mojoreads.de/book/?isbn={{ .ISBN }}&ref=mezzo&aff=mr"/>
|
||||||
|
<id>urn:uuid:{{ .ISBN }}</id>
|
||||||
|
<updated>{{ .Date }}T00:00:00Z</updated>
|
||||||
|
<summary>{{ .Author | html }} - "{{ .Title | html }}"</summary>
|
||||||
|
</entry>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
</feed>
|
Loading…
Reference in a new issue