-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi.go
More file actions
158 lines (126 loc) · 4.39 KB
/
api.go
File metadata and controls
158 lines (126 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright © 2025 Digital Curation Centre (UK) and contributors
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"path/filepath"
"strings"
"crypto/sha256"
"encoding/hex"
)
type ApiRequestData struct {
Cmd string `json:"cmd"`
Value json.RawMessage `json:"value"` // holds raw JSON — can be string or array
}
func handleSubmit(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Error reading request body", http.StatusInternalServerError)
return
}
defer r.Body.Close()
var apiRequestData ApiRequestData
if err := json.Unmarshal(body, &apiRequestData); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
response, err := processCommand(apiRequestData)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
jsonResponse, err := json.Marshal(response)
if err != nil {
http.Error(w, "Error creating response JSON", http.StatusInternalServerError)
return
}
w.Write(jsonResponse)
}
func processCommand(data ApiRequestData) (interface{}, error) {
switch data.Cmd {
case "search_by_domain":
var domain string
if err := json.Unmarshal(data.Value, &domain); err != nil {
return nil, fmt.Errorf("expected a string for domain: %v", err)
}
fmt.Println("Searching by domain:", domain)
return getOrgsByDomain(domain)
case "search_by_ror_id":
// Try to parse as array
var ids []string
if err := json.Unmarshal(data.Value, &ids); err == nil {
fmt.Println("Searching by multiple ROR IDs:", ids)
return getOrgsById(ids)
}
// If not an array, try to parse as a single ID
var id string
if err := json.Unmarshal(data.Value, &id); err != nil {
return nil, fmt.Errorf("invalid value for search_by_ror_id: must be string or array")
}
fmt.Println("Searching by single ROR ID:", id)
return getOrgsById([]string{id})
default:
return nil, fmt.Errorf("unknown command %s", data.Cmd)
}
}
func getOrgsById(rorIDs []string) (interface{}, error) {
var result []interface{}
for _, rorID := range rorIDs {
// Build file path
dirPath := filepath.Join("/storage/orgs", rorID[:2], rorID[2:4])
filePath := filepath.Join(dirPath, rorID + ".json")
// Read the file
file, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("error reading file for ROR ID %s: %v", rorID, err)
}
var data interface{}
if err := json.Unmarshal(file, &data); err != nil {
return nil, fmt.Errorf("error parsing JSON file for ROR ID %s: %v", rorID, err)
}
result = append(result, data)
}
return result, nil
}
func getOrgsByDomain(domain string) (interface{}, error) {
// Hash the domain
hash := sha256.Sum256([]byte(domain))
hashedDomain := hex.EncodeToString(hash[:])
// Build file path
dirPath := filepath.Join("/storage/domains", hashedDomain[:2], hashedDomain[2:4])
filePath := filepath.Join(dirPath, hashedDomain + ".txt")
// Read the file
content, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("error reading file for domain %s: %v", domain, err)
}
rorIDs := strings.Split(strings.TrimSpace(string(content)), "\n")
// Get org details for those ROR IDs
orgDetails, err := getOrgsById(rorIDs)
if err != nil {
return nil, fmt.Errorf("error retrieving org details: %v", err)
}
// Construct the final response
result := map[string]interface{}{
"ids": rorIDs,
"orgs": orgDetails,
}
return result, nil
}
func main() {
http.HandleFunc("/submit", handleSubmit)
fmt.Println("Server is starting on port 8080...")
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}