From 4cbe14801bc8d40075f2ba81f0d915338f70648a Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Mon, 22 Jun 2026 17:43:17 +0100 Subject: [PATCH 1/8] Add RAML entry for /cyclops/sets/{altName}/sets --- ramls/cyclops.raml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ramls/cyclops.raml b/ramls/cyclops.raml index ba6d93f..0260d3a 100644 --- a/ramls/cyclops.raml +++ b/ramls/cyclops.raml @@ -207,6 +207,16 @@ documentation: responses: 204: description: No content is returned. + /sets: + description: "Sets of objects (books, films, etc.) within this project" + get: + description: "Return a list of the names of all known sets in this project" + responses: + 200: + body: + application/json: + type: !include sets-schema.json + example: !include examples/show-sets-example.json /funds: description: "Funds that can be associated with a project or assigned to a spectre" get: From 256d8e4459568c3b9e956f925262d4c275ce9375 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Mon, 22 Jun 2026 17:44:26 +0100 Subject: [PATCH 2/8] Add MD entry for /cyclops/sets/{altName}/sets --- descriptors/ModuleDescriptor-template.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index 225e931..63d7b96 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -161,6 +161,15 @@ "cyclops.projects.put" ] }, + { + "methods": [ + "GET" + ], + "pathPattern": "/cyclops/projects/{id}/sets", + "permissionsRequired": [ + "cyclops.sets.read" + ] + }, { "methods": [ "GET" From 8587f1e17402ff6d0e1778f1b64daba5c1a94fb3 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Mon, 22 Jun 2026 17:47:18 +0100 Subject: [PATCH 3/8] Tweak description in RAML --- ramls/cyclops.raml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ramls/cyclops.raml b/ramls/cyclops.raml index 0260d3a..95a2ef1 100644 --- a/ramls/cyclops.raml +++ b/ramls/cyclops.raml @@ -208,7 +208,7 @@ documentation: 204: description: No content is returned. /sets: - description: "Sets of objects (books, films, etc.) within this project" + description: "Sets of objects (books, films, etc.) in this project" get: description: "Return a list of the names of all known sets in this project" responses: From 2ec1c4e753c1485df68ec87ca4da8c9ec8b99be8 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Mon, 22 Jun 2026 17:59:10 +0100 Subject: [PATCH 4/8] Implement /cyclops/sets/{setName}/sets --- cyclops/handlers.go | 18 ++++++++++++++++++ cyclops/server.go | 3 +++ 2 files changed, 21 insertions(+) diff --git a/cyclops/handlers.go b/cyclops/handlers.go index 64fd9ca..54cecd1 100644 --- a/cyclops/handlers.go +++ b/cyclops/handlers.go @@ -655,6 +655,24 @@ func (server *ModCyclopsServer) handleUpdateProject(w http.ResponseWriter, req * return nil } +func (server *ModCyclopsServer) handleShowSetsInProject(w http.ResponseWriter, req *http.Request, caption string) error { + projectId := chi.URLParam(req, "projectId") + command := "show sets in project " + projectId + ";" + server.Log("command", command) + resp, err := server.sendToCCMS(caption+" "+projectId, command) + if err != nil { + return fmt.Errorf("could not fetch show-sets response: %w", err) + } + + result := readResults(resp)[0] + sets := make([]any, 0) + for val := range result.Data() { + sets = append(sets, val.Values()[0]) + } + setList := SetList{Sets: sets} + return server.respondWithJSON(w, setList, caption) +} + // ----------------------------------------------------------------------------- type FundList struct { diff --git a/cyclops/server.go b/cyclops/server.go index e0adbd1..bd7c732 100644 --- a/cyclops/server.go +++ b/cyclops/server.go @@ -114,6 +114,9 @@ func MakeModCyclopsServer(logger *catlogger.Logger, ccmsClient CCMSClient, root r.Put("/cyclops/projects/{projectId}", func(w http.ResponseWriter, req *http.Request) { server.runWithErrorHandling(w, req, server.handleUpdateProject, "update project") }) + r.Get("/cyclops/projects/{projectId}/sets", func(w http.ResponseWriter, req *http.Request) { + server.runWithErrorHandling(w, req, server.handleShowSetsInProject, "show sets for project") + }) r.Get("/cyclops/funds", func(w http.ResponseWriter, req *http.Request) { server.runWithErrorHandling(w, req, server.handleShowFunds, "show funds") }) From bdb682637cc9bfcb0122fe1ef18f138506978f90 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Mon, 22 Jun 2026 17:59:55 +0100 Subject: [PATCH 5/8] Add HTML invocation for /cyclops/sets/{altName}/sets --- htdocs/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/index.html b/htdocs/index.html index 9d69a41..c2e3e54 100644 --- a/htdocs/index.html +++ b/htdocs/index.html @@ -66,6 +66,7 @@ origins: [{ id: 'lehigh', name: 'LeHigh' }, { id: 'nyu', name: 'New York U.' }], destinations: [{ id: 'clockss', name: 'CLOCKSS' }], })">modify project "literature of North Korea" +
  • list of sets in project "literature of North Korea"
    • list of sets
    • From 894ea7037383df2ad56684400f4395a0f2d2ec44 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Mon, 22 Jun 2026 18:05:52 +0100 Subject: [PATCH 6/8] Tweak caption for handleShowSetsInProject --- cyclops/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cyclops/server.go b/cyclops/server.go index bd7c732..5a1f83e 100644 --- a/cyclops/server.go +++ b/cyclops/server.go @@ -115,7 +115,7 @@ func MakeModCyclopsServer(logger *catlogger.Logger, ccmsClient CCMSClient, root server.runWithErrorHandling(w, req, server.handleUpdateProject, "update project") }) r.Get("/cyclops/projects/{projectId}/sets", func(w http.ResponseWriter, req *http.Request) { - server.runWithErrorHandling(w, req, server.handleShowSetsInProject, "show sets for project") + server.runWithErrorHandling(w, req, server.handleShowSetsInProject, "show sets in project") }) r.Get("/cyclops/funds", func(w http.ResponseWriter, req *http.Request) { server.runWithErrorHandling(w, req, server.handleShowFunds, "show funds") From ca8e98e6e683cfbf0d9b8ec5c2f12e963d3ff0f1 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Mon, 22 Jun 2026 18:18:16 +0100 Subject: [PATCH 7/8] Add unit-test for handleShowSetsInProject --- cyclops/handlers_test.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cyclops/handlers_test.go b/cyclops/handlers_test.go index 02c1ccd..7599069 100644 --- a/cyclops/handlers_test.go +++ b/cyclops/handlers_test.go @@ -277,6 +277,29 @@ func TestHandleShowSets(t *testing.T) { } } +func TestHandleShowSetsInProject(t *testing.T) { + fake := &fakeCCMS{resp: listResponse("mike.object", "mike.endangered")} + server := newTestServer(fake) + + rr := httptest.NewRecorder() + err := server.handleShowSetsInProject(rr, jsonRequest("", map[string]string{"projectId": "mike"}), "show sets in project") + if err != nil { + t.Fatalf("handleShowSets returned error: %v", err) + } + + assertEqual(t, "command sent to CCMS", fake.lastCmd, "show sets in project mike;") + + var got SetList + err = json.Unmarshal(rr.Body.Bytes(), &got) + if err != nil { + t.Fatalf("could not decode response body %q: %v", rr.Body.String(), err) + } + want := SetList{Sets: []any{"mike.object", "mike.endangered"}} + if !reflect.DeepEqual(got, want) { + t.Errorf("translated response:\n got %+v\nwant %+v", got, want) + } +} + func TestHandleShowFunds(t *testing.T) { fake := &fakeCCMS{resp: listResponse("general", "endowment")} server := newTestServer(fake) From 804cca096976daeab925a90ef05810d96cb39594 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Mon, 22 Jun 2026 18:19:28 +0100 Subject: [PATCH 8/8] Sample commands in HTML use set `korea_lit` --- htdocs/index.html | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/index.html b/htdocs/index.html index c2e3e54..5e1386f 100644 --- a/htdocs/index.html +++ b/htdocs/index.html @@ -18,7 +18,7 @@ @@ -70,15 +70,15 @@
    See also: the interactive form