255f19397a6fd6db357bae249a3d882f360e32f7
[quanweb.git] / main / handler.go
1 package main
2
3 import (
4   "encoding/json"
5   "fmt"
6   "io"
7   "net/http"
8   "os"
9   "strconv"
10   "strings"
11 )
12
13 const PARAM_IDS = "ids"
14 const MAX_TERMS = 10
15
16 // ============================================================================
17 func efsPathForId(efsId int) string {
18   config := getConfig()
19
20   idStr := fmt.Sprintf("%010d", efsId)
21   path := fmt.Sprintf("%s/%s/%s/%s/%s/%s.dat", config.efsBasePath, idStr[0:2], idStr[2:4], idStr[4:6], idStr[6:8], idStr)
22
23   return path
24 }
25
26 func handler(w http.ResponseWriter, r *http.Request) {
27   err := r.ParseForm()
28   if nil != err {
29     fmt.Fprintln(w, "ERROR!", err)
30     return
31   }
32
33   action := strings.Split(r.URL.Path[1:], "/")[0]
34
35   switch(action) {
36   case "download":
37     handleDownload(w, r)
38   case "info":
39     handleInfo(w, r)
40   case "search":
41     handleSearch(w, r)
42   default:
43     fmt.Fprintf(w, "Unrecognized request:  %s\n", r.URL.Path[1:])
44     fmt.Fprintf(w, "id: %s\n", r.FormValue("id"))
45   
46     fmt.Fprintln(w, "URL: ", r.URL)
47     fmt.Fprintln(w, "Query: ", r.URL.Query())
48   }
49 }
50
51 func handleDownload(w http.ResponseWriter, r *http.Request) {
52   path := r.URL.Path[1:]
53   tok := strings.Split(path, "/")
54   if 2 != len(tok)  {
55     fmt.Fprintln(w, "Unexpected path for download:", path)
56     return
57   }
58   efsId, err := strconv.Atoi(tok[1])
59   if (nil != err) || (0 == efsId) {
60     fmt.Fprintln(w, "Invalid id for download:", path, err)
61     return
62   }
63   
64   mimeType := queryMimeTypeByEfsId(efsId)
65   if 0 == len(mimeType) {
66     fmt.Fprintln(w, "No MIME type found for id:", efsId)
67     return
68   }
69
70   efsPath := efsPathForId(efsId)
71
72   var fd *os.File
73   fd, err = os.Open(efsPath)
74   if nil != err {
75     fmt.Fprintln(w, "Failed to read file for id:", efsId, err)
76     return
77   }
78   defer fd.Close()
79
80   io.Copy(w, fd)
81 }
82
83 func handleInfo(w http.ResponseWriter, r *http.Request) {
84   idParams := r.Form[PARAM_IDS]
85   if 1 != len(idParams) {
86     fmt.Fprintln(w, "ERROR!  Detected either zero or multiple ids= parameters.  Exactly one expected.")
87     return 
88   } 
89
90   idParam := idParams[0]
91   idStrings := strings.Split(idParam, ",")
92   ids := make([]int, len(idStrings))
93   for i, v := range(idStrings) {
94     var err error
95     ids[i], err = strconv.Atoi(v)
96     if nil != err {
97       ids[i] = 0
98     }
99   }
100
101   books := queryBooksByIds(ids)
102
103   var jsonValue []byte
104   var err error
105   jsonValue, err = json.Marshal(books)
106   if nil != err {
107     fmt.Fprintln(w, "ERROR!", err)
108   } else {
109     w.Write(jsonValue)
110   }
111 }
112
113 func handleSearch(w http.ResponseWriter, r *http.Request) {
114   fields := []Field{Author, Title, Series}
115
116   terms := make([]SearchTerm, len(fields))
117   
118   count := 0
119   for _, fv := range(fields) {
120     paramName := fv.String()
121     paramValues := r.Form[paramName]
122     for _, pv := range(paramValues) {
123       if count >= len(terms) {
124         fmt.Printf("WARNING:  limit of %v search terms exceeded.  One or more terms ignored.")
125         break
126       }
127       terms[count] = SearchTerm{Attribute:fv, Text:pv}
128       count++
129     }
130   }
131
132   terms = terms[:count]
133
134   ids := queryIds(terms)
135
136   jsonValue, err := json.Marshal(ids)
137   if nil != err {
138     fmt.Fprintln(w, "ERROR!", err)
139   } else {
140     w.Write(jsonValue)
141   }
142 }