Skip to content

Commit

Permalink
add inveniordm delete draft record cli command
Browse files Browse the repository at this point in the history
  • Loading branch information
mfenner committed Feb 22, 2025
1 parent a441b03 commit b396bf3
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 2 deletions.
74 changes: 74 additions & 0 deletions cmd/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
Copyright © 2025 Front Matter <[email protected]>
*/
package cmd

import (
"bytes"
"encoding/json"
"fmt"
"time"

"github.com/front-matter/commonmeta/commonmeta"
"github.com/front-matter/commonmeta/inveniordm"
"github.com/front-matter/commonmeta/utils"
"github.com/spf13/cobra"
"golang.org/x/time/rate"
)

// deleteCmd represents the decode command
var deleteCmd = &cobra.Command{
Use: "delete",
Short: "Deletes a InvenioRDM record.",
Long: `Deletes a InvenioRDM record by id.
Example usage:
commonmeta delete fh8y2-aef76`,
Run: func(cmd *cobra.Command, args []string) {
host, _ := cmd.Flags().GetString("host")
token, _ := cmd.Flags().GetString("token")

var record commonmeta.APIResponse

if len(args) == 0 {
fmt.Println("Please provide an input")
return
}
input := args[0]
rid, ok := utils.ValidateRID(input)
if !ok {
fmt.Println("Please provide a valid input")
return
}
if host == "" || token == "" {
fmt.Println("Please provide an inveniordm host and token")
return
}
rl := rate.NewLimiter(rate.Every(60*time.Second), 900) // 900 request every 60 seconds
client := inveniordm.NewClient(rl, host)
record.ID = rid
record, err := inveniordm.DeleteDraftRecord(record, client, token)
if err != nil {
cmd.PrintErr(err)
}

var output []byte
var out bytes.Buffer
output, err = json.Marshal(record)
if err != nil {
cmd.PrintErr(err)
}

json.Indent(&out, output, "", " ")
cmd.Println(out.String())

if err != nil {
cmd.PrintErr(err)
}
},
}

func init() {
rootCmd.AddCommand(deleteCmd)
}
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "commonmeta",
Version: "v0.6.64",
Version: "v0.6.65",
Short: "Convert scholarly metadata from one format to another",
Long: `Convert scholarly metadata between formats. Currently
supported input formats are Crossref and DataCite DOIs, currently
Expand Down
2 changes: 2 additions & 0 deletions inveniordm/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ var CommunityTranslations = map[string]string{
"papers": "researchblogging",
"urheberrecht": "copyright",
"veranstaltungshinweise": "events",
"asapbio": "preprints",
"biorxiv": "preprints",
}

// Fetch fetches InvenioRDM metadata and returns Commonmeta metadata.
Expand Down
22 changes: 22 additions & 0 deletions inveniordm/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,28 @@ func PublishDraftRecord(record commonmeta.APIResponse, client *InvenioRDMClient,
return record, nil
}

// DeleteDraftRecord publishes a draft record in InvenioRDM.
func DeleteDraftRecord(record commonmeta.APIResponse, client *InvenioRDMClient, apiKey string) (commonmeta.APIResponse, error) {
requestURL := fmt.Sprintf("https://%s/api/records/%s/draft", client.Host, record.ID)
req, _ := http.NewRequest(http.MethodDelete, requestURL, nil)
req.Header = http.Header{
"Content-Type": {"application/json"},
"Authorization": {"Bearer " + apiKey},
}
resp, err := client.Do(req)
if err != nil {
return record, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode != 204 {
fmt.Println(string(body), record)
return record, err
}
record.Status = "deleted"
return record, nil
}

// CreateCommunity creates a community in InvenioRDM.
func CreateCommunity(community string, client *InvenioRDMClient, apiKey string) (string, error) {
type Response struct {
Expand Down
20 changes: 19 additions & 1 deletion utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ func GetROR(ror string) (ROR, error) {
}

// ValidateID validates an identifier and returns the type
// Can be DOI, UUID, ISSN, ORCID, ROR, URL
// Can be DOI, UUID, ISSN, ORCID, ROR, URL, RID
func ValidateID(id string) (string, string) {
doi, ok := doiutils.ValidateDOI(id)
if ok {
Expand All @@ -516,6 +516,10 @@ func ValidateID(id string) (string, string) {
if ok {
return uuid, "UUID"
}
rid, ok := ValidateRID(id)
if ok {
return rid, "RID"
}
orcid, ok := ValidateORCID(id)
if ok {
return orcid, "ORCID"
Expand Down Expand Up @@ -568,6 +572,16 @@ func ValidateUUID(uuid string) (string, bool) {
return r.FindString(uuid), true
}

// ValidateRID validates a RID
// RID is the unique identifier used by the InvenioRDM platform
func ValidateRID(rid string) (string, bool) {
r := regexp.MustCompile("^[0-9a-z]{5}-[0-9a-z]{3}[0-9]{2}$")
if !r.MatchString(rid) {
return "", false
}
return r.FindString(rid), true
}

func CamelCaseToWords(str string) string {
var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])")
Expand Down Expand Up @@ -642,6 +656,10 @@ func DecodeID(id string) (int64, error) {
// ROR ID is a 9-character string that starts with 0
// and is a base32-encoded number with a mod 97-1
number, err = crockford.Decode(identifier, true)
} else if identifierType == "RID" {
// RID is a 10-character string with a hyphen after five digits.
// It is a base32-encoded numbers with checksum.
number, err = crockford.Decode(identifier, true)
} else if identifierType == "ORCID" {
str := identifier
identifier = strings.ReplaceAll(identifier, "-", "")
Expand Down
8 changes: 8 additions & 0 deletions utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,13 @@ func ExampleValidateUUID() {
// 2491b2d5-7daf-486b-b78b-e5aab48064c1
}

func ExampleValidateRID() {
s, _ := utils.ValidateRID("nryd8-14284")
fmt.Println(s)
// Output:
// nryd8-14284
}

func TestSanitize(t *testing.T) {
t.Parallel()
type testCase struct {
Expand Down Expand Up @@ -382,6 +389,7 @@ func TestValidateID(t *testing.T) {
{input: "https://doi.org/10.7554/eLife.01567", want: "DOI"},
{input: "10.1101/097196", want: "DOI"},
{input: "2491b2d5-7daf-486b-b78b-e5aab48064c1", want: "UUID"},
{input: "nryd8-14284", want: "RID"},
{input: "https://ror.org/0342dzm54", want: "ROR"},
{input: "https://orcid.org/0000-0002-1825-0097", want: "ORCID"},
{input: "https://datadryad.org/stash/dataset/doi:10.5061/dryad.8515", want: "URL"},
Expand Down

0 comments on commit b396bf3

Please sign in to comment.