Skip to content

Instantly share code, notes, and snippets.

@jjkavalam
Last active January 10, 2024 08:15
Show Gist options
  • Save jjkavalam/8646e5a141c93a695185ca2c793b9738 to your computer and use it in GitHub Desktop.
Save jjkavalam/8646e5a141c93a695185ca2c793b9738 to your computer and use it in GitHub Desktop.
TiddlyWiki Saver Server (Simple)
// From a directory that contains your TiddlyWiki file (or download https://tiddlywiki.com/empty.html if you don't have one)
// `go run main.go`
// Navigate to the printed URL and open your wiki file
// Enjoy your changes getting saved !
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
)
func main() {
var root string
if len(os.Args) != 1 {
root = os.Args[1]
} else {
root = "."
}
fmt.Println(root)
fileServerHandler := http.FileServer(http.Dir(root))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
fileServerHandler.ServeHTTP(w, r)
case "PUT":
handlePut(w, r, root)
case "OPTIONS":
handleOptions(w, r)
default:
w.WriteHeader(200)
}
})
server := &http.Server{
Addr: "127.0.0.1:8000",
Handler: http.DefaultServeMux,
}
go func() {
if err := server.ListenAndServe(); err != nil {
fmt.Println(err)
}
}()
fmt.Println("TiddlyWiki Backup Server is running at http://127.0.0.1:8000/")
fmt.Println("Press Ctrl+C to shutdown...")
select {}
}
func handlePut(w http.ResponseWriter, r *http.Request, root string) {
filePath := filepath.Join(root, r.URL.Path)
writeErr := func(err error) {
log.Printf("error: %s", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
src, err := os.Open(filePath)
if err != nil {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
defer src.Close()
body, err := io.ReadAll(r.Body)
if err != nil {
writeErr(err)
return
}
if err := os.WriteFile(filePath, body, os.ModePerm); err != nil {
writeErr(err)
return
}
w.WriteHeader(http.StatusOK)
fmt.Print(".")
}
func handleOptions(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Allow", "GET,HEAD,OPTIONS,PUT")
// TiddlyWiki looks for a 'dav' header, and ignores any value
w.Header().Set("dav", "anything")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment