saving work

This commit is contained in:
Xuu 2020-10-26 12:39:08 -06:00
parent 1a88e47181
commit db4ac49a49
Signed by: xuu
GPG Key ID: 8B3B0604F164E04F
9 changed files with 93 additions and 221 deletions

View File

@ -120,7 +120,9 @@ func (tr *Runner) Run(key Key, fn Fn, opts ...Option) *qTask {
tr.queue[key.Key()] = task tr.queue[key.Key()] = task
tr.mu.Unlock() tr.mu.Unlock()
log.Debug("Waiting for limiter")
tr.limiter.Take() tr.limiter.Take()
log.Debug("Got tag from limiter")
go func() { go func() {
defer func() { defer func() {
@ -156,7 +158,7 @@ func NewRunner(ctx context.Context, defaultOpts ...Option) *Runner {
ctx: ctx, ctx: ctx,
cancel: cancel, cancel: cancel,
pause: make(chan struct{}), pause: make(chan struct{}),
limiter: ratelimit.New(1), limiter: ratelimit.New(10),
} }
return tr return tr

View File

@ -1,4 +1,4 @@
package routes package readutil
import ( import (
"bytes" "bytes"

View File

@ -13,6 +13,7 @@ import (
"strings" "strings"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"sour.is/x/paste/src/pkg/readutil"
"sour.is/x/toolbox/httpsrv" "sour.is/x/toolbox/httpsrv"
"sour.is/x/toolbox/log" "sour.is/x/toolbox/log"
@ -87,7 +88,7 @@ func (a *Artifact) get(w http.ResponseWriter, r *http.Request) {
defer f.Close() defer f.Close()
if !hasPath { if !hasPath {
pr := NewPreviewReader(f) pr := readutil.NewPreviewReader(f)
mime, err := ReadMIME(pr, name) mime, err := ReadMIME(pr, name)
if err != nil { if err != nil {
@ -165,7 +166,7 @@ func (a *Artifact) get(w http.ResponseWriter, r *http.Request) {
return return
} }
pr := NewPreviewReader(tr) pr := readutil.NewPreviewReader(tr)
mime, err := ReadMIME(pr, hdr.Name) mime, err := ReadMIME(pr, hdr.Name)
if err != nil { if err != nil {
@ -197,7 +198,7 @@ func (a *Artifact) put(w http.ResponseWriter, r *http.Request) {
} }
rdr := io.LimitReader(r.Body, 500*1024*1024) rdr := io.LimitReader(r.Body, 500*1024*1024)
pr := NewPreviewReader(rdr) pr := readutil.NewPreviewReader(rdr)
rdr = pr.Drain() rdr = pr.Drain()
s256 := sha256.New() s256 := sha256.New()

View File

@ -7,11 +7,12 @@ import (
"github.com/andybalholm/brotli" "github.com/andybalholm/brotli"
xz "github.com/remyoudompheng/go-liblzma" xz "github.com/remyoudompheng/go-liblzma"
"sour.is/x/paste/src/pkg/readutil"
"sour.is/x/toolbox/log" "sour.is/x/toolbox/log"
) )
func Decompress(in io.Reader) (io.Reader, error) { func Decompress(in io.Reader) (io.Reader, error) {
rdr := NewPreviewReader(in) rdr := readutil.NewPreviewReader(in)
mime, err := ReadMIMEWithSize(rdr, "", 32768) mime, err := ReadMIMEWithSize(rdr, "", 32768)
if err != nil { if err != nil {
return rdr.Drain(), err return rdr.Drain(), err

View File

@ -97,6 +97,7 @@ func (s *identity) get(w http.ResponseWriter, r *http.Request) {
return return
} }
log.Infos("Scheduling Style", "email", entity.Primary.Address)
q.Run(StyleKey(entity.Primary.Address), func(q promise.Q) { q.Run(StyleKey(entity.Primary.Address), func(q promise.Q) {
ctx := q.Context() ctx := q.Context()
key := q.Key().(StyleKey) key := q.Key().(StyleKey)
@ -108,18 +109,26 @@ func (s *identity) get(w http.ResponseWriter, r *http.Request) {
return return
} }
log.Notice("Resolving Style")
q.Resolve(style) q.Resolve(style)
}) })
go func() {
log.Infos("Scheduling Proofs", "num", len(entity.Proofs))
for i := range entity.Proofs { for i := range entity.Proofs {
q.Run(ProofKey(entity.Proofs[i]), func(q promise.Q) { q.Run(ProofKey(entity.Proofs[i]), func(q promise.Q) {
key := q.Key().(ProofKey) key := q.Key().(ProofKey)
proof := NewProof(string(key)) proof := NewProof(string(key))
proof.Checked = true
proof.Verified = true
log.Notice("Resolving Proof")
q.Resolve(proof) q.Resolve(proof)
}) })
} }
}()
log.Notice("Resolving Entity")
q.Resolve(entity) q.Resolve(entity)
}) })
@ -388,7 +397,7 @@ func (s *identity) getStyle(ctx context.Context, email string) (*Style, error) {
style.Palette = getPalette(fmt.Sprintf("#%x", id[:3])) style.Palette = getPalette(fmt.Sprintf("#%x", id[:3]))
style.Avatar = fmt.Sprintf("https://%s/avatar/%x", avatarHost, id) style.Avatar = fmt.Sprintf("https://%s/avatar/%x", avatarHost, id)
style.Cover = pixl style.Cover = pixl
style.Background = pixl style.Background = "https://lavana.sour.is/bg/52548b3dcb032882675afe1e4bcba0e9"
if styleHost != "" { if styleHost != "" {
style.Cover = fmt.Sprintf("https://%s/cover/%x", styleHost, id) style.Cover = fmt.Sprintf("https://%s/cover/%x", styleHost, id)
@ -402,7 +411,7 @@ func styleSRV(ctx context.Context, email string) (avatar string, style string, e
// Defaults // Defaults
style = "" style = ""
avatar = "cdn.libravatar.org" avatar = "www.gravatar.com"
parts := strings.SplitN(email, "@", 2) parts := strings.SplitN(email, "@", 2)
if _, srv, err := net.DefaultResolver.LookupSRV(ctx, "style-sec", "tcp", parts[1]); err == nil { if _, srv, err := net.DefaultResolver.LookupSRV(ctx, "style-sec", "tcp", parts[1]); err == nil {
@ -503,18 +512,48 @@ func NewProof(uri string) *Proof {
switch u.Scheme { switch u.Scheme {
case "dns": case "dns":
p.Icon = "link" p.Icon = "fas fa-globe"
p.Name = u.Opaque p.Name = u.Opaque
p.Link = fmt.Sprintf("https://%s", u.Hostname()) p.Link = fmt.Sprintf("https://%s", u.Hostname())
case "xmpp":
p.Icon = "fas fa-comments"
p.Name = u.Opaque
case "https": case "https":
p.Icon = "link" p.Icon = "fas fa-atlas"
p.Name = u.Hostname() p.Name = u.Hostname()
p.Link = fmt.Sprintf("https://%s", u.Hostname()) p.Link = fmt.Sprintf("https://%s", u.Hostname())
case "xmpp": switch {
p.Icon = "comments" case strings.HasPrefix(u.Host, "twitter.com"):
p.Name = u.Hostname() p.Icon = "fab fa-twitter"
p.Service = "Twitter"
case strings.HasPrefix(u.Host, "news.ycombinator.com"):
p.Icon = "fab fa-hacker-news"
p.Service = "HackerNews"
case strings.HasPrefix(u.Host, "dev.to"):
p.Icon = "fab fa-dev"
p.Service = "dev.to"
case strings.HasPrefix(u.Host, "reddit.com"), strings.HasPrefix(u.Host, "www.reddit.com"):
p.Icon = "fab fa-reddit"
p.Service = "Reddit"
case strings.HasPrefix(u.Host, "gist.github.com"):
p.Icon = "fab fa-github"
p.Service = "GitHub"
case strings.HasPrefix(u.Host, "lobste.rs"):
p.Icon = "fas fa-list-ul"
p.Service = "Lobsters"
case strings.HasSuffix(u.Host, "/gitlab_proof/"):
p.Icon = "fab fa-gitlab"
p.Service = "GetLab"
case strings.HasSuffix(u.Host, "/gitea_proof/"):
p.Icon = "fas fa-mug-hot"
p.Service = "Gitea"
default:
p.Icon = "fas fa-project-diagram"
p.Service = "fediverse"
}
} }
return p return p
@ -600,6 +639,11 @@ var identityTPL = `
<h1 class="display-8 fg-color-8">{{.Primary.Name}}</h1> <h1 class="display-8 fg-color-8">{{.Primary.Name}}</h1>
<p class="lead fg-color-11"><i class="fas fa-fingerprint"></i> {{.Fingerprint}}</p> <p class="lead fg-color-11"><i class="fas fa-fingerprint"></i> {{.Fingerprint}}</p>
</div> </div>
{{else}}
<div class="col-lg">
<h1 class="display-8 fg-color-8">Loading...</h1>
<p class="lead fg-color-11">Reading key from remote service.</p>
</div>
{{end}} {{end}}
{{end}} {{end}}
</div> </div>
@ -622,10 +666,25 @@ var identityTPL = `
<div class="card"> <div class="card">
<div class="card-header">Proofs</div> <div class="card-header">Proofs</div>
<ul class="list-group list-group-flush"> <ul class="list-group list-group-flush">
{{range .}}<li class="list-group-item"><i class="fas fa-{{.Icon}}"></i> <span class="badge badge-secondary">{{.Service}}</span> {{.Name}}</li>{{end}} {{range .}}
<li class="list-group-item">
<i class="{{.Icon}}"></i>
<span class="badge badge-secondary">{{.Service}}</span>
{{.Name}}
{{if .Checked}}
{{if .Verified}}Verified{{else}}Invalid{{end}}
{{else}}Checking...{{end}}
</li>
{{end}}
</ul> </ul>
</div> </div>
<br/> <br/>
{{else}}
<div class="card">
<div class="card-header">Proofs</div>
<div class="card-body">Loading...</div>
</div>
<br/>
{{end}} {{end}}
</div> </div>

View File

@ -15,6 +15,8 @@ import (
"github.com/h2non/filetype" "github.com/h2non/filetype"
"sour.is/x/toolbox/httpsrv" "sour.is/x/toolbox/httpsrv"
"sour.is/x/toolbox/log" "sour.is/x/toolbox/log"
"sour.is/x/paste/src/pkg/readutil"
) )
func init() { func init() {
@ -81,7 +83,7 @@ func (a *Image) get(w http.ResponseWriter, r *http.Request) {
} }
defer f.Close() defer f.Close()
pr := NewPreviewReader(f) pr := readutil.NewPreviewReader(f)
mime, err := ReadMIME(pr, name) mime, err := ReadMIME(pr, name)
w.Header().Set("Content-Type", mime) w.Header().Set("Content-Type", mime)
@ -105,7 +107,7 @@ func (a *Image) put(w http.ResponseWriter, r *http.Request) {
} }
rdr := io.LimitReader(r.Body, a.maxSize) rdr := io.LimitReader(r.Body, a.maxSize)
pr := NewPreviewReader(rdr) pr := readutil.NewPreviewReader(rdr)
if !isImageOrVideo(pr) { if !isImageOrVideo(pr) {
httpsrv.WriteError(w, http.StatusUnsupportedMediaType, "ERR Not Image") httpsrv.WriteError(w, http.StatusUnsupportedMediaType, "ERR Not Image")
return return

View File

@ -16,6 +16,7 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"sour.is/x/paste/src/pkg/readutil"
"sour.is/x/toolbox/httpsrv" "sour.is/x/toolbox/httpsrv"
"sour.is/x/toolbox/log" "sour.is/x/toolbox/log"
) )
@ -150,7 +151,7 @@ func (p *Paste) getPaste(w http.ResponseWriter, r *http.Request) {
} }
defer f.Close() defer f.Close()
pr := NewPreviewReader(f) pr := readutil.NewPreviewReader(f)
keep := true keep := true
scanner := bufio.NewScanner(pr) scanner := bufio.NewScanner(pr)

View File

@ -1,195 +0,0 @@
package routes
import (
"sour.is/x/httpsrv"
"os"
"golang.org/x/sys/unix"
"log"
"net/http"
"sour.is/x/ident"
"crypto/rand"
"encoding/base64"
"crypto/sha256"
"io/ioutil"
"io"
"bufio"
"github.com/gorilla/mux"
"strings"
"time"
"strconv"
)
var store string
var randBytes int
func init() {
httpsrv.RegisterModule("paste", SetConfig)
httpsrv.IdentRegister("paste", httpsrv.IdentRoutes{
{ "Paste", "GET", "/paste/rng", GetRandom, },
{ "Paste", "GET", "/paste/{id}", GetPaste, },
{ "Paste", "GET", "/paste/get/{id}", GetPaste, },
{ "Paste", "POST", "/paste", PostPaste, },
{ "Paste", "DELETE", "/paste/{id}", DeletePaste, },
{ "Paste", "GET", "/api/rng", GetRandom, },
{ "Paste", "GET", "/api/{id}", GetPaste, },
{ "Paste", "GET", "/api/get/{id}", GetPaste, },
{ "Paste", "POST", "/api", PostPaste, },
{ "Paste", "DELETE", "/api/{id}", DeletePaste, },
})
}
func SetConfig (config map[string]string) {
store = "data/"
if config["store"] != "" {
store = config["store"]
}
if !chkStore(store) {
log.Fatalf("[routes::Paste] Store location [%s] does not exist or is not writable.", store)
}
randBytes = 1024
if config["random"] != "" {
randBytes, _ = strconv.Atoi(config["random"])
}
}
func chkStore(path string) bool {
file, err := os.Stat(path)
if err == nil { return true }
if os.IsNotExist(err) { return false }
if !file.IsDir() { return false }
if unix.Access(path, unix.W_OK & unix.R_OK) != nil { return false }
return true
}
func chkFile(path string) bool {
file, err := os.Stat(path)
if err == nil { return true }
if os.IsNotExist(err) { return false }
if file.IsDir() { return false }
if unix.Access(path, unix.W_OK & unix.R_OK) != nil { return false }
return true
}
func chkGone(path string) bool {
file, err := os.Stat(path)
if err != nil { return true }
if file.Size() == 0 { return true }
return false
}
func GetRandom(w http.ResponseWriter, r *http.Request, i ident.Ident) {
w.WriteHeader(http.StatusOK)
w.Header().Set("content-type","application/octet-stream")
s := make([]byte, randBytes)
rand.Read(s)
w.Write(s)
}
func GetPaste(w http.ResponseWriter, r *http.Request, i ident.Ident) {
vars := mux.Vars(r)
id := vars["id"]
if !chkFile(store + id) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("ERR Not Found"))
return
}
if chkGone(store + id) {
w.WriteHeader(http.StatusGone)
w.Write([]byte("ERR Gone"))
return
}
head, err := os.Open(store + id)
if err != nil {
log.Fatal(err)
}
defer head.Close()
keep := true
scanner := bufio.NewScanner(head)
for scanner.Scan() {
txt := scanner.Text()
log.Println(txt)
if (txt == "") {
break
}
if strings.HasPrefix(txt, "exp:") {
now := time.Now().Unix()
exp, err := strconv.ParseInt(strings.TrimSpace(strings.TrimPrefix(txt, "exp:")), 10, 64)
if err != nil {
log.Print(err)
}
if now > exp {
log.Printf("%d > %d", now, exp)
w.WriteHeader(http.StatusGone)
w.Write([]byte("ERR Gone"))
Delete(store + id)
return
}
}
if strings.HasPrefix(txt, "burn:") {
burn := strings.TrimSpace(strings.TrimPrefix(txt, "burn:"))
if burn == "true" {
keep = false
}
}
}
file, _ := os.Open(store + id)
defer file.Close()
w.WriteHeader(http.StatusOK)
scanner = bufio.NewScanner(file)
for scanner.Scan() {
w.Write(scanner.Bytes())
w.Write([]byte("\n"))
}
if !keep {
Delete(store + id)
}
}
func PostPaste(w http.ResponseWriter, r *http.Request, i ident.Ident) {
body, _ := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))
s256 := sha256.Sum256(body)
id := base64.RawURLEncoding.EncodeToString(s256[12:])
ioutil.WriteFile(store + id, body, 0644)
w.WriteHeader(http.StatusCreated)
w.Write([]byte("OK " + id))
}
func DeletePaste(w http.ResponseWriter, r *http.Request, i ident.Ident) {
vars := mux.Vars(r)
id := vars["id"]
Delete(store + id)
w.WriteHeader(http.StatusNoContent)
w.Write([]byte("OK"))
}
func Delete(path string) {
ioutil.WriteFile(path, []byte(""), 0644)
}

View File

@ -9,6 +9,7 @@ import (
"github.com/andybalholm/brotli" "github.com/andybalholm/brotli"
"github.com/h2non/filetype" "github.com/h2non/filetype"
"github.com/h2non/filetype/types" "github.com/h2non/filetype/types"
"sour.is/x/paste/src/pkg/readutil"
"sour.is/x/toolbox/log" "sour.is/x/toolbox/log"
) )
@ -24,7 +25,7 @@ func init() {
func br(buf []byte) bool { func br(buf []byte) bool {
var r io.Reader = bytes.NewReader(buf) var r io.Reader = bytes.NewReader(buf)
r = NewPreviewReader(r) r = readutil.NewPreviewReader(r)
br := brotli.NewReader(r) br := brotli.NewReader(r)
i, err := br.Read(make([]byte, 1)) i, err := br.Read(make([]byte, 1))
log.Debugs("BR:", "i", i, "err", err) log.Debugs("BR:", "i", i, "err", err)