-
Notifications
You must be signed in to change notification settings - Fork 0
/
job.go
123 lines (100 loc) · 2.5 KB
/
job.go
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
package gowup
import (
"encoding/json"
"net/url"
"time"
)
type Job struct {
Summary JobSummary `json:"request"`
Details JobDetails `json:"response"`
}
type JobSummary struct {
Url Url `json:"url"`
Ip string `json:"ip"`
StartTime Time `json:"start_time"`
ExpireTime Time `json:"expiry"`
Services []Service `json:"services"`
}
type Service struct {
Server string `json:"server"`
Tests []string `json:"checks"`
}
type JobRequest struct {
Url string `json:"uri"`
Tests []string `json:"tests"`
Locations []string `json:"sources"`
}
type JobDetails struct {
Done JobDetail `json:"complete"`
NotDone JobDetail `json:"in_progress"`
Error JobDetail `json:"error"`
}
type JobDetail map[string]map[string]interface{}
func (j *JobDetail) UnmarshalJSON(data []byte) error {
var raw interface{}
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
switch v := raw.(type) {
case []interface{}:
*j = JobDetail{}
case map[string]interface{}:
job := JobDetail{}
// there must be a better way.
for city, tests := range v {
job[city] = map[string]interface{}{}
for test, details := range tests.(map[string]interface{}) {
content, ok := details.(map[string]interface{})["summary"]
if ok {
job[city][test] = content
}
}
}
*j = job
}
return nil
}
type Url struct {
*url.URL
}
func (u *Url) UnmarshalJSON(data []byte) error {
var raw string
// convert the json string to a real string
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
// parse the string into a Url
parsed, err := url.Parse(raw)
if err != nil {
return err
}
u.URL = parsed
return nil
}
type Time struct {
time.Time
}
// time.Time has an unmarshaler, but it assumes the JSON is coming in as a
// string. ours is coming in as a float64, and sometimes it comes in a hashmap.
func (t *Time) UnmarshalJSON(data []byte) error {
var raw interface{}
// convert to a raw float
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
// this is just freaking black magic right here, i don't even know
switch v := raw.(type) {
case float64:
// there's an easier way to do this with json flags. oops
t.Time = time.Unix(int64(v), 0)
case map[string]interface{}:
sec, ok := v["sec"].(float64)
if !ok {
return &Error{msg: "No seconds found in expiry time type"}
}
t.Time = time.Unix(int64(sec), 0)
default:
return &Error{msg: "I have no idea what to do with this time type you gave me"}
}
return nil
}