blog

Categories     Timeline     RSS

Desk lamp

desk lamp

All of the components are not that great for their original purpose. But in combination they work well as an adjustable desk lamp for different moods.

Ledergravur Part 2

Die Weihnachtsgeschenke sind ausgepackt, hier die Auflösung, was ich auf das Leder graviert hab: Hnefatafl. Ein Wikingerspiel mit massiv asymmetrischer Spielweise. Die Spielsteine sind koreanische Go-Linsen mit 20.5mm Durchmesser. Jedes Quadrat ist 25mm groß, das gesamte Grid also 275mm x 275mm. Der Umkreis hat einen Durchmesser von 400mm. Es werden 24 schwarze Steine und 12+1 weiße benötigt. Die Parameter zur Gravur findet ihr im vorherigen Post. Enjoy.

Fog

fog 1

fog 2

Minimal three tier Golang app

with TypeScript frontend, REST, a .txt as “data store”, no external dependencies, all compiling to a single binary. The overwhelming result:

It alive

But it represents a starting point for a three tier application. Any real world example would use an actual database and maybe a better routing scheme. You need Go, tsc (npm install -g typescript), Make and a browser. Compile and start with make, then open http://localhost:8000 and hit the button.

$ cat Makefile
all: hello.js hello

hello.js: hello.ts
        which tsc || sudo npm install -g typescript
        tsc hello.ts

hello:
        go run hello.go


$ cat hello.ts
interface Answer {
    Current: Number
}

async function getCurrent() {
    let answer = await fetch("/current")
      .then(res => res.json())
      .then(res => res as Answer);
    let counter = document.getElementById('current');
    if (counter != null)
      counter.innerText = answer.Current.toString();
}


$ cat go.mod
module hello

go 1.16


$ cat hello.go
package main

import (
	_ "embed"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

//go:embed hello.js
var js string

var html string = `
<html>
<head><title></title>
<script>` + js + `
</script>
</head>
<body>
<h1 id="current"></h1>
<button onclick="getCurrent()">Load Current</button>
</body>
</html>
`

const storefile = "myfancydatastore.txt"

type Answer struct {
	Current int
}

func readFromStore() Answer {
	b, err := ioutil.ReadFile(storefile)
	if err != nil {
		// do something
	}
	var a Answer
	err = json.Unmarshal(b, &a)
	if err != nil {
		// do something
	}
	return a
}

func writeToStore(a Answer) {
	b, err := json.Marshal(a)
	if err != nil {
		// do something
	}
	ioutil.WriteFile(storefile, b, 0644)
}

func serveIndex(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		w.Header().Set("content-type", "text/html; charset=utf-8")
		w.Write([]byte(html))
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		w.Header().Set("content-type", "application/json")
		a := readFromStore()
		b, err := json.Marshal(a)
		if err != nil {
			// do something
		}
		w.Write(b)
		a.Current = a.Current + 1
		writeToStore(a)
	}
}

func main() {
	writeToStore(Answer{Current: 0})
	mux := http.NewServeMux()
	mux.HandleFunc("/", serveIndex)
	mux.HandleFunc("/current", handler)
	fmt.Println("Starting server on localhost:8000")
	http.ListenAndServe("localhost:8000", mux)
}

Watch hedgedoc notes

I pushed hedgedoc-watcher to git.fireandbrimst.one, which allows watching hedgedoc notes with an RSS reader.

< Older

Newer >