From f13079477a08ef32a90223707d66c76268105107 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Wed, 6 Aug 2025 15:15:45 +0100 Subject: [PATCH] appview/ingester: ingest sh.tangled.string from the firehose Change-Id: potvrpwlpwslknmymowyuyursnprxlry Signed-off-by: oppiliappan --- appview/ingester.go | 56 ++++++++++++ appview/middleware/middleware.go | 12 +-- .../templates/strings/fragments/form.html | 89 +++++++++++++++++++ appview/pages/templates/strings/put.html | 17 ++++ appview/state/router.go | 3 - appview/state/state.go | 1 + knotserver/file.go | 8 -- 7 files changed, 165 insertions(+), 21 deletions(-) create mode 100644 appview/pages/templates/strings/fragments/form.html create mode 100644 appview/pages/templates/strings/put.html diff --git a/appview/ingester.go b/appview/ingester.go index 7a3c22a..adc2179 100644 --- a/appview/ingester.go +++ b/appview/ingester.go @@ -64,6 +64,8 @@ func (i *Ingester) Ingest() processFunc { err = i.ingestSpindleMember(e) case tangled.SpindleNSID: err = i.ingestSpindle(e) + case tangled.StringNSID: + err = i.ingestString(e) } l = i.Logger.With("nsid", e.Commit.Collection) } @@ -549,3 +551,57 @@ func (i *Ingester) ingestSpindle(e *models.Event) error { return nil } + +func (i *Ingester) ingestString(e *models.Event) error { + did := e.Did + rkey := e.Commit.RKey + + var err error + + l := i.Logger.With("handler", "ingestString", "nsid", e.Commit.Collection, "did", did, "rkey", rkey) + l.Info("ingesting record") + + ddb, ok := i.Db.Execer.(*db.DB) + if !ok { + return fmt.Errorf("failed to index string record, invalid db cast") + } + + switch e.Commit.Operation { + case models.CommitOperationCreate, models.CommitOperationUpdate: + raw := json.RawMessage(e.Commit.Record) + record := tangled.String{} + err = json.Unmarshal(raw, &record) + if err != nil { + l.Error("invalid record", "err", err) + return err + } + + string := db.StringFromRecord(did, rkey, record) + + if err = string.Validate(); err != nil { + l.Error("invalid record", "err", err) + return err + } + + if err = db.AddString(ddb, string); err != nil { + l.Error("failed to add string", "err", err) + return err + } + + return nil + + case models.CommitOperationDelete: + if err := db.DeleteString( + ddb, + db.FilterEq("did", did), + db.FilterEq("rkey", rkey), + ); err != nil { + l.Error("failed to delete", "err", err) + return fmt.Errorf("failed to delete string record: %w", err) + } + + return nil + } + + return nil +} diff --git a/appview/middleware/middleware.go b/appview/middleware/middleware.go index e427eb2..2d63282 100644 --- a/appview/middleware/middleware.go +++ b/appview/middleware/middleware.go @@ -167,16 +167,6 @@ func (mw Middleware) RepoPermissionMiddleware(requiredPerm string) middlewareFun } } -func StripLeadingAt(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - path := req.URL.EscapedPath() - if strings.HasPrefix(path, "/@") { - req.URL.RawPath = "/" + strings.TrimPrefix(path, "/@") - } - next.ServeHTTP(w, req) - }) -} - func (mw Middleware) ResolveIdent() middlewareFunc { excluded := []string{"favicon.ico"} @@ -188,6 +178,8 @@ func (mw Middleware) ResolveIdent() middlewareFunc { return } + didOrHandle = strings.TrimPrefix(didOrHandle, "@") + id, err := mw.idResolver.ResolveIdent(req.Context(), didOrHandle) if err != nil { // invalid did or handle diff --git a/appview/pages/templates/strings/fragments/form.html b/appview/pages/templates/strings/fragments/form.html new file mode 100644 index 0000000..2badb23 --- /dev/null +++ b/appview/pages/templates/strings/fragments/form.html @@ -0,0 +1,89 @@ +{{ define "strings/fragments/form" }} +
+
+ + +
+ +
+
+ 0 lines + + 0 bytes +
+
+ {{ if eq .Action "edit" }} + + {{ i "x" "size-4" }} + + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} + + {{ end }} + +
+
+ +
+
+{{ end }} diff --git a/appview/pages/templates/strings/put.html b/appview/pages/templates/strings/put.html new file mode 100644 index 0000000..a086715 --- /dev/null +++ b/appview/pages/templates/strings/put.html @@ -0,0 +1,17 @@ +{{ define "title" }}publish a new string{{ end }} + +{{ define "topbar" }} + {{ template "layouts/topbar" $ }} +{{ end }} + +{{ define "content" }} +
+ {{ if eq .Action "new" }} +

Create a new string

+

Store and share code snippets with ease.

+ {{ else }} +

Edit string

+ {{ end }} +
+ {{ template "strings/fragments/form" . }} +{{ end }} diff --git a/appview/state/router.go b/appview/state/router.go index 490aeaf..af9ff99 100644 --- a/appview/state/router.go +++ b/appview/state/router.go @@ -68,9 +68,6 @@ func (s *State) Router() http.Handler { func (s *State) UserRouter(mw *middleware.Middleware) http.Handler { r := chi.NewRouter() - // strip @ from user - r.Use(middleware.StripLeadingAt) - r.With(mw.ResolveIdent()).Route("/{user}", func(r chi.Router) { r.Get("/", s.Profile) diff --git a/appview/state/state.go b/appview/state/state.go index 4696c2c..484fcfa 100644 --- a/appview/state/state.go +++ b/appview/state/state.go @@ -93,6 +93,7 @@ func Make(ctx context.Context, config *config.Config) (*State, error) { tangled.ActorProfileNSID, tangled.SpindleMemberNSID, tangled.SpindleNSID, + tangled.StringNSID, }, nil, slog.Default(), diff --git a/knotserver/file.go b/knotserver/file.go index 8a5c029..5da5171 100644 --- a/knotserver/file.go +++ b/knotserver/file.go @@ -10,13 +10,6 @@ import ( "tangled.sh/tangled.sh/core/types" ) -func (h *Handle) listFiles(files []types.NiceTree, data map[string]any, w http.ResponseWriter) { - data["files"] = files - - writeJSON(w, data) - return -} - func countLines(r io.Reader) (int, error) { buf := make([]byte, 32*1024) bufLen := 0 @@ -52,5 +45,4 @@ func (h *Handle) showFile(resp types.RepoBlobResponse, w http.ResponseWriter, l resp.Lines = lc writeJSON(w, resp) - return } -- 2.43.0