~m15o/the-neon-kiosk

d24c4f34c9214aca1bdc678f6188e111a6fd3fa1 — m15o 2 years ago ac2e4f7 master
Add HTML blogs
8 files changed, 162 insertions(+), 29 deletions(-)

M .gitignore
M about.html
M go.mod
M go.sum
M join.html
M main.go
A tpl-blog.html
M tpl.html
M .gitignore => .gitignore +3 -1
@@ 1,4 1,6 @@
kiosk
.idea
input
output.html
\ No newline at end of file
index.html
blogs
blogs.html
\ No newline at end of file

M about.html => about.html +5 -6
@@ 11,14 11,13 @@
        <h1>About</h1>
        <p>
            The Neon Kiosk is a virtual Kiosk located somewhere on <a href="https://nightfall.city/main-street/">Main Street, Nightfall City</a>.
            The kiosk distributes <a href="https://journal.miso.town">HTML Journals</a>. A journal is any HTML page that
            follows the little markup described on the HTML Journal site. The journal can be hosted anywhere! It can be
            The kiosk distributes <a href="https://journal.miso.town">HTML Journals</a> and <a href="https://blog.miso.town">HTML Blogs</a>. A journal is any HTML page that
            follows the little markup described on the HTML Journal site. A blog is any HTML page that lists posts using a little markup described on the HTML Blog site. Journals and blogs can be hosted anywhere! It can be
            on Neocities, <a href="https://ichi.city">ichi</a> or even on your personal machine. It will work as long as
            it is reachable over the web. Journals don't need to have their own dedicated page either: they can simply
            be updates on your homepage, that would work too.
            it is reachable over the web.
        </p>
        <p>
            The Kiosk simply scans all the journals once a day and produces a static file. If you'd like to host your own
            The Kiosk simply scans all the sites once a day and produces a static file. If you'd like to host your own
            Kiosk, you are more than welcome to do so! Actually, this would be incredibly awesome! You can find the <a href="https://git.sr.ht/~m15o/the-neon-kiosk/tree">source
            right here</a>.
        </p>


@@ 30,7 29,7 @@
            If you have any question, feel free to send them at m15o at posteo dot net.
        </p>
        <p>
            <a href="join.html">Submit your journal</a><br>
            <a href="join.html">Submit your site</a><br>
            <a href="/">Go back</a>
        </p>
    </article>

M go.mod => go.mod +7 -2
@@ 2,8 2,13 @@ module git.sr.ht/~m15o/kiosk

go 1.18

require git.sr.ht/~m15o/htmlj v0.0.0-20220709084050-c36dda5901f7
require (
	git.sr.ht/~m15o/htmlb v0.0.0-20220714142247-6b03ade78118
	git.sr.ht/~m15o/htmlj v0.0.0-20220709084050-c36dda5901f7
)

require golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect
require golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect

replace git.sr.ht/~m15o/htmlj => ../htmlj

replace git.sr.ht/~m15o/htmlb => ../htmlb

M go.sum => go.sum +2 -6
@@ 1,6 1,2 @@
git.sr.ht/~m15o/htmlj v0.0.0-20220618164623-e5391f9c1902 h1:6L/JfNa//bebnbncDL0XD/ozUt1JEQ7wHnp2zqJnZZE=
git.sr.ht/~m15o/htmlj v0.0.0-20220618164623-e5391f9c1902/go.mod h1:Js769MMC92wojjogmjepyFRfYwCR018xUg2worv6RaE=
git.sr.ht/~m15o/htmlj v0.0.0-20220705092447-a88c4782be51 h1:hjw3vDA3nRYeYHGzjsvIlfkPXQY0HsqkeVR5VDONqAQ=
git.sr.ht/~m15o/htmlj v0.0.0-20220705092447-a88c4782be51/go.mod h1:Js769MMC92wojjogmjepyFRfYwCR018xUg2worv6RaE=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=

M join.html => join.html +4 -4
@@ 8,10 8,10 @@
<body>
<main>
    <article>
        <h1>Submit your journal</h1>
        <h1>Submit your site</h1>
        <p>
            Do you write a journal? Would you like it to be available in this kiosk? Great! You are in the right place.
            To be added, your journal needs to follow the <a href="https://journal.miso.town">HTML Journal</a> format. Feel free to send the link over:
            Do you write a journal or a blog? Would you like it to be available in this kiosk? Great! You are in the right place.
            For a journal to be added, it needs to follow the <a href="https://journal.miso.town">HTML Journal</a> format. For a blog, it needs to follow the <a href="https://blog.miso.town">HTML Blog</a> format. Feel free to send the link over:
        </p>
        <form method="POST" action="https://riku.miso.town/submit?user_id=1&label=kiosk">
            <table>


@@ 29,7 29,7 @@
                </tr>
            </table>
        </form>
        <p>Don't have a journal yet? Create one on <a href="https://ichi.city">ichi</a>! Need help? Send me a message at m15o at posteo dot net.</p>
        <p>Don't have a journal or a blog yet? Create one on <a href="https://ichi.city">ichi</a>! Need help? Send me a message at m15o at posteo dot net.</p>
        <p><a href="/">Go back</a></p>
    </article>
</main>

M main.go => main.go +110 -7
@@ 4,6 4,7 @@ import (
	"bufio"
	_ "embed"
	"fmt"
	"git.sr.ht/~m15o/htmlb"
	"git.sr.ht/~m15o/htmlj"
	"html/template"
	"log"


@@ 19,6 20,9 @@ import (
//go:embed tpl.html
var tpl string

//go:embed tpl-blog.html
var tplBlog string

type Entry struct {
	URL       string
	Author    string


@@ 27,19 31,51 @@ type Entry struct {
	Body      template.HTML
}

type BlogEntry struct {
	URL       string
	Author    string
	Published time.Time
	Title     string
	Href      string
}

func (b BlogEntry) FullPath() string {
	rv, _ := resolveLink(b.URL, b.Href)
	return rv
}

func (b BlogEntry) PublishedStr() string {
	return b.Published.Format("2006-01-02")
}

type Journal struct {
	URL string
	J   *htmlj.Journal
}

func main() {
	if len(os.Args) < 3 {
		fmt.Println("Usage: kiosk INPUT_FILE OUTPUT_FILE")
		return
type Blog struct {
	URL string
	B   *htmlb.Blog
}

func processJournals(input, output string) {
	var urls []string
	f, err := os.Open(input)
	if err != nil {
		log.Fatal(err)
	}

	s := bufio.NewScanner(f)
	for s.Scan() {
		urls = append(urls, s.Text())
	}

	buildJournals(urls, output)
}

func processBlogs(input, output string) {
	var urls []string
	f, err := os.Open(os.Args[1])
	f, err := os.Open(input)
	if err != nil {
		log.Fatal(err)
	}


@@ 49,7 85,17 @@ func main() {
		urls = append(urls, s.Text())
	}

	build(urls, os.Args[2])
	buildBlogs(urls, output)
}

func main() {
	if len(os.Args) < 5 {
		fmt.Println("Usage: kiosk INPUT_JOURNAL_FILE OUTPUT_JOURNAL_FILE INPUT_BLOG_FILE OUTPUT_BLOG_FILE")
		return
	}

	processJournals(os.Args[1], os.Args[2])
	processBlogs(os.Args[3], os.Args[4])
}

var client = http.Client{


@@ 65,6 111,15 @@ func fetchJournal(u string) (*htmlj.Journal, error) {
	return htmlj.Parse(r.Body)
}

func fetchBlog(u string) (*htmlb.Blog, error) {
	r, err := client.Get(u)
	if err != nil {
		return nil, err
	}

	return htmlb.Parse(r.Body)
}

func resolveLink(b, l string) (string, error) {
	u, err := url.Parse(l)
	if err != nil {


@@ 105,7 160,7 @@ func processContent(u, content string) (string, error) {
	return rv, nil
}

func build(urls []string, dst string) {
func buildJournals(urls []string, dst string) {
	var journals []Journal
	for _, u := range urls {
		fmt.Print("Fetching: ", u)


@@ 156,3 211,51 @@ func build(urls []string, dst string) {
	}
	t.Execute(f, entries)
}

func buildBlogs(urls []string, dst string) {
	var blogs []Blog
	for _, u := range urls {
		fmt.Print("Fetching: ", u)
		b, err := fetchBlog(u)
		if err != nil {
			log.Println("Error fetching journal:", err)
			continue
		}
		fmt.Printf(" - %d entries found\n", len(b.Entries))
		blogs = append(blogs, Blog{
			URL: u,
			B:   b,
		})
	}

	var entries []BlogEntry

	lastMonth := time.Now().AddDate(0, -1, 0)

	for _, b := range blogs {
		for _, e := range b.B.Entries {
			if !e.Published.After(lastMonth) {
				continue
			}
			entries = append(entries, BlogEntry{
				URL:       b.URL,
				Author:    b.B.Title,
				Published: e.Published,
				Title:     e.Title,
				Href:      e.Href,
			})
		}
	}

	sort.Slice(entries, func(i, j int) bool {
		return entries[i].Published.After(entries[j].Published)
	})

	t := template.Must(template.New("").Parse(tplBlog))

	f, err := os.Create(dst)
	if err != nil {
		log.Fatal(err)
	}
	t.Execute(f, entries)
}

A tpl-blog.html => tpl-blog.html +27 -0
@@ 0,0 1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>The Neon Kiosk</title>
    <link rel="stylesheet" href="style.css"/>
</head>
<body>
<main>
    <header>
        <h1>The Neon Kiosk</h1>
        <p>Just an ordinary looking virtual kiosk. There are <a href="https://journal.miso.town">journals</a> and <a href="https://blog.miso.town">blogs</a> in it!</a></p>
        <p><a href="/join.html" >Submit your site</a> | <a href="about.html">About</a></p>
    </header>
    <marquee loop="-1" behavior="alternate">Just a funny looking Kiosk! Just a funny looking Kiosk! Just a funny looking Kiosk! Just a funny looking Kiosk! Just a funny looking Kiosk!</marquee>
    <header><p><a href="/">Journals</a> | Blogs</p></header>
    <ul>
    {{ range . }}
        <li><time>{{ .PublishedStr }}</time> - <a href="{{ .URL }}">{{ .Author }}</a> - <a href="{{ .FullPath }}">{{ .Title }}</a></li>
    {{ end }}
    </ul>
</main>
<footer>
    <p><a href="https://journal.miso.town"><img src="https://journal.miso.town/static/banner-htmlj.png"></a> <a href="https://blog.miso.town"><img src="https://blog.miso.town/static/banner-htmlb.png"></a> <a href="https://nightfall.city"><img src="https://nightfall.city/button.png"></a></p>
</footer>
</body>
</html>
\ No newline at end of file

M tpl.html => tpl.html +4 -3
@@ 9,10 9,11 @@
<main>
    <header>
        <h1>The Neon Kiosk</h1>
        <p>Just an ordinary looking virtual kiosk. There are <a href="https://journal.miso.town">journals</a> in it!</a></p>
        <p><a href="/join.html" >Submit your journal</a> | <a href="about.html">About</a> </p>
        <p>Just an ordinary looking virtual kiosk. There are <a href="https://journal.miso.town">journals</a> and <a href="https://blog.miso.town">blogs</a> in it!</a></p>
        <p><a href="/join.html" >Submit your site</a> | <a href="about.html">About</a></p>
    </header>
    <marquee loop="-1" behavior="alternate">Just a funny looking Kiosk! Just a funny looking Kiosk! Just a funny looking Kiosk! Just a funny looking Kiosk! Just a funny looking Kiosk!</marquee>
    <header><p>Journals | <a href="/blogs.html">Blogs</a></p></header>
    {{ range . }}
    <article>
        <h2>{{ .Title }} - <a href="{{ .URL }}">{{ .Author }}</a></h2>


@@ 21,7 22,7 @@
    {{ end }}
</main>
<footer>
    <p><a href="https://journal.miso.town"><img src="https://journal.miso.town/static/banner-htmlj.png"></a> <a href="https://nightfall.city"><img src="https://nightfall.city/button.png"></a></p>
    <p><a href="https://journal.miso.town"><img src="https://journal.miso.town/static/banner-htmlj.png"></a> <a href="https://blog.miso.town"><img src="https://blog.miso.town/static/banner-htmlb.png"></a> <a href="https://nightfall.city"><img src="https://nightfall.city/button.png"></a></p>
</footer>
</body>
</html>
\ No newline at end of file