Web ad-hoc items
This commit is contained in:
parent
bc19b0a70f
commit
f5e9a0faec
@ -103,7 +103,7 @@ Parity features
|
|||||||
* [ ] set a working directory for item actions
|
* [ ] set a working directory for item actions
|
||||||
* [ ] crontab integration
|
* [ ] crontab integration
|
||||||
* [ ] source batching
|
* [ ] source batching
|
||||||
* [ ] add item from web
|
* [x] add item from web
|
||||||
* [ ] Nix build
|
* [ ] Nix build
|
||||||
* [ ] NixOS module
|
* [ ] NixOS module
|
||||||
* [ ] NixOS vm demo
|
* [ ] NixOS vm demo
|
||||||
|
@ -42,4 +42,36 @@
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
</details>
|
</details>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<details open>
|
||||||
|
<summary><span class="feed-controls">Add item</span></summary>
|
||||||
|
<form action="/item" method="post">
|
||||||
|
<p>
|
||||||
|
<input type="text" name="title" class="wide" placeholder="Title">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input type="url" name="link" class="wide" placeholder="Link">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<textarea name="body" class="wide" placeholder="Body"></textarea>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="ttl">TTL:</label>
|
||||||
|
<input type="datetime-local" name="ttl">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="ttd">TTD:</label>
|
||||||
|
<input type="datetime-local" name="ttd">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="tts">TTS:</label>
|
||||||
|
<input type="datetime-local" name="tts">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input type="submit" value="Add">
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</details>
|
||||||
|
</article>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -133,7 +133,6 @@ var item = load("itemPage.html", "item.html")
|
|||||||
|
|
||||||
type ItemData struct {
|
type ItemData struct {
|
||||||
Item core.Item
|
Item core.Item
|
||||||
Open bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Item(writer io.Writer, data ItemData) {
|
func Item(writer io.Writer, data ItemData) {
|
||||||
|
@ -71,6 +71,7 @@ summary:focus {
|
|||||||
.wide {
|
.wide {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.fade > * {
|
.fade > * {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
{{ define "title" }}{{ if .Item.Title }}{{ .Item.Title }}{{ else }}{{ .Item.Source }}/{{ .Item.Id }}{{ end }} - Intake [{{ .Item.Source }}]{{ end }}
|
{{ define "title" }}{{ if .Item.Title }}{{ .Item.Title }}{{ else }}{{ .Item.Source }}/{{ .Item.Id }}{{ end }} - Intake [{{ .Item.Source }}]{{ end }}
|
||||||
|
|
||||||
{{ define "content" -}}
|
{{ define "content" -}}
|
||||||
|
<article class="center">
|
||||||
|
<span class="feed-controls">
|
||||||
|
<a href="/">Home</a>
|
||||||
|
</span>
|
||||||
|
</article>
|
||||||
|
|
||||||
{{ template "item" .Item }}
|
{{ template "item" .Item }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
70
web/item.go
70
web/item.go
@ -1,6 +1,8 @@
|
|||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -135,3 +137,71 @@ func (env *Env) massDeactivate(writer http.ResponseWriter, req *http.Request) {
|
|||||||
writer.Header()["HX-Refresh"] = []string{"true"}
|
writer.Header()["HX-Refresh"] = []string{"true"}
|
||||||
http.Error(writer, "ok", http.StatusNoContent)
|
http.Error(writer, "ok", http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (env *Env) addItem(writer http.ResponseWriter, req *http.Request) {
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
log.Printf("error parsing form data: %v", err)
|
||||||
|
http.Error(writer, "", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
exists, err := core.SourceExists(env.db, "default")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(writer, fmt.Sprintf("error: failed to check for source: %v", err), 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
if err := core.AddSource(env.db, "default"); err != nil {
|
||||||
|
http.Error(writer, fmt.Sprintf("error: failed to add source: %v", err), 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes := make([]byte, 16)
|
||||||
|
if _, err := rand.Read(bytes); err != nil {
|
||||||
|
http.Error(writer, fmt.Sprintf("error: failed to generate id: %v", err), 500)
|
||||||
|
}
|
||||||
|
id := hex.EncodeToString(bytes)
|
||||||
|
|
||||||
|
title := req.PostForm.Get("title")
|
||||||
|
link := req.PostForm.Get("link")
|
||||||
|
body := req.PostForm.Get("body")
|
||||||
|
|
||||||
|
item := core.Item{
|
||||||
|
Source: "default",
|
||||||
|
Id: id,
|
||||||
|
Title: title,
|
||||||
|
Link: link,
|
||||||
|
Body: body,
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
if ttl := req.PostForm.Get("ttl"); ttl != "" {
|
||||||
|
ttl, _ := time.Parse("2006-01-02T15:04", ttl)
|
||||||
|
item.Ttl = int(ttl.Unix() - now)
|
||||||
|
}
|
||||||
|
if ttd := req.PostForm.Get("ttd"); ttd != "" {
|
||||||
|
ttd, _ := time.Parse("2006-01-02T15:04", ttd)
|
||||||
|
item.Ttd = int(ttd.Unix() - now)
|
||||||
|
}
|
||||||
|
if tts := req.PostForm.Get("tts"); tts != "" {
|
||||||
|
tts, _ := time.Parse("2006-01-02T15:04", tts)
|
||||||
|
item.Tts = int(tts.Unix() - now)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := core.AddItems(env.db, []core.Item{item}); err != nil {
|
||||||
|
http.Error(writer, fmt.Sprintf("error: failed to add item: %s", err), 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
item, err = core.GetItem(env.db, "default", id)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(writer, err.Error(), 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := html.ItemData{
|
||||||
|
Item: item,
|
||||||
|
}
|
||||||
|
html.Item(writer, data)
|
||||||
|
}
|
||||||
|
@ -42,6 +42,7 @@ func RunServer(db core.DB, addr string, port string) {
|
|||||||
handleFunc("GET /source/{source}", env.getSource, env.authed, logged)
|
handleFunc("GET /source/{source}", env.getSource, env.authed, logged)
|
||||||
handleFunc("POST /source/{source}/fetch", env.fetchSource, env.authed, logged)
|
handleFunc("POST /source/{source}/fetch", env.fetchSource, env.authed, logged)
|
||||||
handleFunc("GET /channel/{channel}", env.getChannel, env.authed, logged)
|
handleFunc("GET /channel/{channel}", env.getChannel, env.authed, logged)
|
||||||
|
handleFunc("POST /item", env.addItem, env.authed, logged)
|
||||||
handleFunc("GET /item/{source}/{id}", env.getItem, env.authed, logged)
|
handleFunc("GET /item/{source}/{id}", env.getItem, env.authed, logged)
|
||||||
handleFunc("DELETE /item/{source}/{id}", env.deleteItem, env.authed, logged)
|
handleFunc("DELETE /item/{source}/{id}", env.deleteItem, env.authed, logged)
|
||||||
handleFunc("POST /item/{source}/{id}/action/{action}", env.doAction, env.authed, logged)
|
handleFunc("POST /item/{source}/{id}/action/{action}", env.doAction, env.authed, logged)
|
||||||
|
Loading…
Reference in New Issue
Block a user