-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi.go
More file actions
144 lines (119 loc) · 3.43 KB
/
Copy pathapi.go
File metadata and controls
144 lines (119 loc) · 3.43 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
package main
import (
"encoding/json"
"fmt"
"github.com/gorilla/mux"
"github.com/opinionated/debugServer/debugAPI"
"io/ioutil"
"net/http"
)
// HandleAddArticle takes care of adding an article to article list.
// The article(s) to add are passed in as the JSON body.
// Endpoint should be api/add.
func HandleAddArticle(w http.ResponseWriter, r *http.Request) {
raw, err := ioutil.ReadAll(r.Body)
if err != nil {
w.Write(asbytes("error parsing input:", err.Error()))
return
}
// parse and push onto the cache
var article debugAPI.GenericArticle
err = json.Unmarshal(raw, &article)
if err != nil {
w.Write(asbytes("error parsing body:", err.Error()))
return
}
fmt.Println("adding input!")
cache.lock()
cache.push(article)
cache.unlock()
}
// HandleGetFrontpage returns a list of all the "top" articles.
// TODO: decide if this is how we want to do this perminently.
// The body will look something like this:
// [ {Title:"a"}, {Title:"b"} ]
// Endpoint should be api/frontpage.
func HandleGetFrontpage(w http.ResponseWriter, r *http.Request) {
// START CRITICAL SECTION
cache.lock()
// convert the list of articles to JSON
articleMap := make([]map[string]string, cache.count)
tmp := cache.start
i := 0
for tmp != nil {
articleMap[i] = map[string]string{
"Title": tmp.article.Title,
}
i++
tmp = tmp.next
}
cache.unlock()
// END CRITICAL SECTION
// marshal and send the data
data, err := json.Marshal(articleMap)
if err != nil {
w.Write(asbytes("error converting to json:", err.Error()))
return
}
n, err := w.Write(data)
if err != nil {
w.Write(asbytes("error writing data:", err.Error()))
} else if n != len(data) {
w.Write(asbytes("error writing data: did not write full json"))
}
if err != nil {
w.Write(asbytes("error setting header!"))
}
}
// HandleGetArticle returns an article body and list of related articles.
// It should be called after the article is clicked on.
// The body will look something like this:
// { Body:"...", DebugInfo:{}, Related:[{Title:"", DebugInfo:""}]}
// note that debug info can have anything in it and related is an array
// The endpoint should be api/article/{title}
func HandleGetArticle(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
cache.lock()
article, ok := cache.articleByTitle(vars["title"])
cache.unlock()
if !ok {
w.Write(asbytes("error finding article called", vars["title"]))
return
}
// doesn't yet have the body or the debug info
ret := make(map[string]interface{})
ret["Body"] = article.Body
ret["DebugInfo"] = article.DebugInfo
ret["Title"] = article.Title
// build the related articles only if they exist
if len(article.Related) > 0 {
related := make([]map[string]interface{}, len(article.Related))
for i, r := range article.Related {
// send the debug info with the article
related[i] = map[string]interface{}{
"Title": r.Title,
"DebugInfo": r.DebugInfo,
}
}
ret["Related"] = related
}
data, err := json.Marshal(ret)
if err != nil {
w.Write(asbytes("error marshalling json"))
return
}
w.Write(data)
}
// HandleClearArticles dumps the cache.
// By default the cache holds 10 articles on the home page.
// The endpoint should be api/clear
func HandleClearArticles(w http.ResponseWriter, r *http.Request) {
cache.lock()
cache.clear()
cache.unlock()
}
func asbytes(vars ...interface{}) []byte {
// helper converts a string to bytes for writing msgs
str := fmt.Sprint(vars...)
return []byte(str)
}