136 lines
2.4 KiB
Go
136 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"html/template"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"regexp"
|
|
"time"
|
|
|
|
"github.com/jinzhu/now"
|
|
"p83.nl/go/ekster/pkg/microsub"
|
|
"willnorris.com/go/microformats"
|
|
|
|
"p83.nl/go/ekster/pkg/jf2"
|
|
)
|
|
|
|
func init() {
|
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
|
}
|
|
func main() {
|
|
u, err := url.Parse(os.Args[1])
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
filename := os.Args[2]
|
|
|
|
re, err := regexp.Compile(`<span class="next-entry"></span>`)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
f, err := openAndCreate(filename)
|
|
|
|
data, err := ioutil.ReadAll(f)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
f.Close()
|
|
|
|
var buf bytes.Buffer
|
|
items, err := getEntriesForFeed(u)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
items = filterEntriesAfter(items, now.With(time.Now()).Monday())
|
|
|
|
err = outputEntries(items, &buf)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
output := re.ReplaceAll(data, buf.Bytes())
|
|
err = ioutil.WriteFile(filename, output, 0666)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func openAndCreate(filename string) (io.ReadCloser, error) {
|
|
f, err := os.Open(filename)
|
|
if err != nil && !os.IsExist(err) {
|
|
t, err := template.ParseFiles("templates/full.html")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
f, err = os.Create(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = t.Execute(f, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = f.Close()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
f, err = os.Open(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
return f, nil
|
|
}
|
|
|
|
func outputEntries(items []microsub.Item, w io.Writer) error {
|
|
t, err := template.ParseFiles("templates/weekly.html")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
err = t.Execute(w, items)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getEntriesForFeed(u *url.URL) ([]microsub.Item, error) {
|
|
resp, err := http.Get(u.String())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != 200 {
|
|
return nil, fmt.Errorf("status is not 200, but %d", resp.StatusCode)
|
|
}
|
|
|
|
md := microformats.Parse(resp.Body, u)
|
|
items := jf2.SimplifyMicroformatDataItems(md)
|
|
return items, nil
|
|
}
|
|
|
|
func filterEntriesAfter(items []microsub.Item, from time.Time) []microsub.Item {
|
|
var result []microsub.Item
|
|
for _, item := range items {
|
|
published, err := time.Parse(time.RFC3339, item.Published)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if published.After(from) {
|
|
result = append(result, item)
|
|
}
|
|
}
|
|
return result
|
|
}
|