Skip to content

Commit

Permalink
Merge pull request #1135 from research-software-directory/codemeta-ov…
Browse files Browse the repository at this point in the history
…erview

CodeMeta overview page
  • Loading branch information
ewan-escience authored Feb 29, 2024
2 parents 672dc04 + 7aae77c commit 27a7f15
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 35 deletions.
2 changes: 2 additions & 0 deletions codemeta/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ COPY **.go .

RUN go build -v -o /usr/local/bin/app

COPY **.gohtml .

RUN useradd user
USER user

Expand Down
64 changes: 30 additions & 34 deletions codemeta/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
//
// SPDX-License-Identifier: Apache-2.0

// https://research-software-directory.org/api/v1/software?slug=eq.rsd-ng&select=brand_name,concept_doi,short_statement,contributor(family_names,given_names,affiliation,role,orcid),license_for_software(license),repository_url(url)

package main

import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
Expand Down Expand Up @@ -81,15 +79,37 @@ func main() {
postgrestUrl = "http://backend:3500"
}

http.HandleFunc("GET /", func(writer http.ResponseWriter, request *http.Request) {
http.Redirect(writer, request, "/v3/", http.StatusMovedPermanently)
http.HandleFunc("GET /{other}/", func(writer http.ResponseWriter, request *http.Request) {
http.Redirect(writer, request, "/", http.StatusMovedPermanently)
})

http.HandleFunc("GET /v3/", func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusBadRequest)
_, err := writer.Write([]byte("Please provide a slug"))
http.HandleFunc("GET /", func(writer http.ResponseWriter, request *http.Request) {
urlUnformatted := "%v/software?select=slug,brand_name,short_statement&order=brand_name"
url := fmt.Sprintf(urlUnformatted, postgrestUrl)
bodyBytes, err := GetAndReadBody(url)
if err != nil {
log.Print("Couldn't write response: ", err)
log.Print("Unknown error when downloading software overview: ", err)
writer.WriteHeader(http.StatusInternalServerError)
_, err := writer.Write([]byte("Server error"))
if err != nil {
log.Print("Couldn't write response: ", err)
}
return
}

byteBuffer := &bytes.Buffer{}
err = GenerateOverview(bodyBytes, byteBuffer)
if err != nil {
writer.WriteHeader(http.StatusInternalServerError)
_, err := writer.Write([]byte("Unknown error when generating software overview, please provide a slug"))
if err != nil {
log.Print("Couldn't write response: ", err)
}
}

_, err = byteBuffer.WriteTo(writer)
if err != nil {
log.Print("Couldn't write response after generating the overview: ", err)
}
})

Expand Down Expand Up @@ -129,7 +149,7 @@ func main() {
urlUnformatted := "%v/software?slug=eq.%v&select=brand_name,concept_doi,short_statement,contributor(family_names,given_names,affiliation,role,orcid,email_address),keyword(value),license_for_software(license),repository_url(url)"
url := fmt.Sprintf(urlUnformatted, postgrestUrl, slug)

resp, err := http.Get(url)
bytes, err := GetAndReadBody(url)
if err != nil {
log.Print("Unknown error when downloading data for slug "+slug+": ", err)
writer.WriteHeader(http.StatusInternalServerError)
Expand All @@ -140,30 +160,6 @@ func main() {
return
}

var bytes []byte
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
log.Print("Unknown error when closing response body for slug "+slug+": ", err)
writer.WriteHeader(http.StatusInternalServerError)
_, err := writer.Write([]byte("Server error"))
if err != nil {
log.Print("Couldn't write response: ", err)
}
return
}
}(resp.Body)
bytes, err = io.ReadAll(resp.Body)
if err != nil {
log.Print("Unknown error for reading response body for slug "+slug+": ", err)
writer.WriteHeader(http.StatusInternalServerError)
_, err := writer.Write([]byte("Server error"))
if err != nil {
log.Print("Couldn't write response: ", err)
}
return
}

jsonBytes, err := convertRsdToCodeMeta(bytes)
if err != nil {
log.Print("Unknown error for slug "+slug+": ", err)
Expand Down
35 changes: 35 additions & 0 deletions codemeta/overview.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: 2024 Ewan Cahen (Netherlands eScience Center) <[email protected]>
// SPDX-FileCopyrightText: 2024 Netherlands eScience Center
//
// SPDX-License-Identifier: Apache-2.0

package main

import (
"encoding/json"
"html/template"
"io"
)

type SoftwareBasicData struct {
Slug string `json:"slug"`
BrandName string `json:"brand_name"`
ShortStatement string `json:"short_statement"`
}

var tmpl = template.Must(template.ParseFiles("overview.gohtml"))

func GenerateOverview(bytes []byte, writer io.Writer) error {
var software []SoftwareBasicData
err := json.Unmarshal(bytes, &software)
if err != nil {
return err
}

err = tmpl.Execute(writer, software)
if err != nil {
return err
}

return nil
}
24 changes: 24 additions & 0 deletions codemeta/overview.gohtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CodeMeta overview</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/[email protected]/css/pico.min.css">
</head>
<body class="container">
<h1>
CodeMeta overview
</h1>
<section>
This page gives a succinct overview of all software pages that export to CodeMeta.
<mark><strong>Warning</strong>: this feature is still in development, so the generated CodeMeta data might still
change.
</mark>
</section>
<section>{{range .}}
<article>
<header><a href="v3/{{.Slug}}/">{{.BrandName}}</a></header>{{.ShortStatement}}
</article>{{end}}
</section>
</body>
</html>
35 changes: 35 additions & 0 deletions codemeta/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: 2024 Ewan Cahen (Netherlands eScience Center) <[email protected]>
// SPDX-FileCopyrightText: 2024 Netherlands eScience Center
//
// SPDX-License-Identifier: Apache-2.0

package main

import (
"errors"
"io"
"log"
"net/http"
)

func GetAndReadBody(url string) (body []byte, err error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}

defer func(Body io.ReadCloser) {
closeErr := Body.Close()
if closeErr != nil {
log.Printf("Unknown error when closing response body for URL %v overview with error: %v", url, closeErr)
err = errors.Join(closeErr, err)
}
}(resp.Body)

body, err = io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

return body, err
}
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ services:

codemeta:
build: ./codemeta
image: rsd/codemeta:v1.0.0
image: rsd/codemeta:v1.1.0
expose:
- "8000"
environment:
Expand Down

0 comments on commit 27a7f15

Please sign in to comment.