diff --git a/Makefile b/Makefile index 90e711f..d35b794 100644 --- a/Makefile +++ b/Makefile @@ -4,4 +4,4 @@ help: ## display this help @awk 'BEGIN{FS = ":.*##"; printf "\033[1m\nUsage\n \033[1;92m make\033[0;36m \033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } ' $(MAKEFILE_LIST) serve: ## Run "intake serve" with live reload - @air -build.cmd "go build -o scratch/intake" -build.bin scratch/intake -build.args_bin serve -build.exclude_dir scratch + @air -build.cmd "go build -o tmp/intake" -build.bin tmp/intake -build.args_bin serve,--db,tmp/db.sqlite diff --git a/cmd/serve.go b/cmd/serve.go index e5cefbd..4a103ae 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -11,10 +11,21 @@ var serveCmd = &cobra.Command{ Long: `Serve the intake web interface. `, Run: func(cmd *cobra.Command, args []string) { - web.RunServer() + serve() }, } +var serveAddr string +var servePort string + func init() { rootCmd.AddCommand(serveCmd) + + serveCmd.Flags().StringVarP(&serveAddr, "addr", "a", "localhost", "Address to bind to") + serveCmd.Flags().StringVarP(&servePort, "port", "p", "8081", "Port to bind to") +} + +func serve() { + db := openAndMigrateDb() + web.RunServer(db, serveAddr, servePort) } diff --git a/web/html/home.html b/web/html/home.html index 881e323..d7c5e7a 100644 --- a/web/html/home.html +++ b/web/html/home.html @@ -1 +1,20 @@ -{{ define "content" }}

Hello {{ . }}

{{ end }} +{{ define "title" }}Intake{{ end }} + +{{ define "content" -}} +
+
+Sources +{{ if .Sources }} + +{{ range .Sources }} + + + +{{ end }} +
{{ .Name }}
+{{ else }} +

No sources found.

+{{ end }} +
+
+{{- end }} diff --git a/web/html/html.go b/web/html/html.go index 62d1904..fd7fd8b 100644 --- a/web/html/html.go +++ b/web/html/html.go @@ -6,6 +6,9 @@ import ( "io" ) +//go:embed intake.css +var Stylesheet []byte + //go:embed *.html var templates embed.FS diff --git a/web/html/intake.css b/web/html/intake.css new file mode 100644 index 0000000..2986bd9 --- /dev/null +++ b/web/html/intake.css @@ -0,0 +1,75 @@ + +main { + max-width: 700px; + margin: 0 auto; +} +article { + border: 1px solid black; border-radius: 6px; + padding: 5px; + margin-bottom: 20px; + word-break: break-word; +} +.item-title { + font-size: 1.4em; +} +.item-button { + font-size: 1em; + float:right; + margin-left: 2px; +} +.item-link { + text-decoration: none; + float:right; + font-size: 1em; + padding: 2px 7px; + border: 1px solid; + border-radius: 2px; +} +.item-info { + color: rgba(0, 0, 0, 0.7); +} +article img { + max-width: 100%; + height: auto; +} +button, summary { + cursor: pointer; +} +summary { + display: block; +} +summary:focus { + outline: 1px dotted gray; +} +.strikethru span, .strikethru p { + text-decoration: line-through; +} +.wide { + width: 100%; + resize: vertical; +} +.fade span, .fade p { + color: rgba(0, 0, 0, 0.2); +} +pre { + white-space: pre-wrap; +} +table.feed-control td { + font-family: monospace; padding: 5px 10px; +} +.intake-sources td { + padding-block: 0.4em; +} +.intake-sources form { + margin: 0 +} +article.center { + text-align: center; +} +article textarea { + width: 100%; + resize: vertical; +} +span.error-message { + color: red; +} diff --git a/web/html/layout.html b/web/html/layout.html index f827cde..57be7b2 100644 --- a/web/html/layout.html +++ b/web/html/layout.html @@ -1,8 +1,13 @@ -Intake + +{{ block "title" . }}Intake{{ end }} + + +
{{ template "content" . }} +
diff --git a/web/main.go b/web/main.go new file mode 100644 index 0000000..95191d1 --- /dev/null +++ b/web/main.go @@ -0,0 +1,34 @@ +package web + +import ( + "log" + "net" + "net/http" + + "github.com/Jaculabilis/intake/core" +) + +type Env struct { + db *core.DB +} + +func logged(handler http.HandlerFunc) http.HandlerFunc { + return func(writer http.ResponseWriter, req *http.Request) { + log.Printf("%s %s", req.Method, req.URL.Path) + handler(writer, req) + } +} + +func handleFunc(pattern string, handler http.HandlerFunc) { + http.HandleFunc(pattern, logged(handler)) +} + +func RunServer(db *core.DB, addr string, port string) { + env := &Env{db} + bind := net.JoinHostPort(addr, port) + + handleFunc("/", env.rootHandler) + handleFunc("/style.css", env.styleHandler) + + log.Fatal(http.ListenAndServe(bind, nil)) +} diff --git a/web/root.go b/web/root.go index c5d5ed1..f54d919 100644 --- a/web/root.go +++ b/web/root.go @@ -1,19 +1,35 @@ package web import ( - "log" "net/http" + "github.com/Jaculabilis/intake/core" "github.com/Jaculabilis/intake/web/html" ) -func rootHandler(writer http.ResponseWriter, req *http.Request) { - log.Printf("%s %s", req.Method, req.URL.Path) - html.Home(writer, "world") +type SourceData struct { + Name string } -func RunServer() { - http.HandleFunc("/", rootHandler) - - log.Fatal(http.ListenAndServe("localhost:8081", nil)) +type HomeData struct { + Sources []SourceData +} + +func (env *Env) rootHandler(writer http.ResponseWriter, req *http.Request) { + names, err := core.GetSources(env.db) + if err != nil { + writer.Write([]byte(err.Error())) + } + + var sources []SourceData + for _, name := range names { + sources = append(sources, SourceData{name}) + } + data := HomeData{sources} + html.Home(writer, data) +} + +func (env *Env) styleHandler(writer http.ResponseWriter, req *http.Request) { + writer.Header()["Cache-Control"] = []string{"public, max-age=86400"} + writer.Write(html.Stylesheet) }