forked from square/erg
/
erg.go
106 lines (91 loc) · 2.23 KB
/
erg.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
package erg
import (
"bufio"
"crypto/tls"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"sort"
"github.com/xaviershay/grange"
"vbom.ml/util/sortorder"
)
// Erg type
// Sort boolean - turn it off/on for sorting on expand
// default is true
type Erg struct {
host string
port int
ssl bool
Sort bool
}
// New(address string) returns a new erg
// takes two arguments
// host - hostname default - localhost
// port - port default - 8080
// ssl - use https or not default - false
func New(host string, port int) *Erg {
return &Erg{host: host, port: port, ssl: false, Sort: true}
}
func NewWithSsl(host string, port int) *Erg {
return &Erg{host: host, port: port, ssl: true, Sort: true}
}
// Expand takes a range expression as argument
// and returns an slice of strings as result
// err is set to nil on success
func (e *Erg) Expand(query string) (result []string, err error) {
protocol := "http"
if e.ssl {
protocol = "https"
}
// TODO: Remove this with go 1.4
// http://stackoverflow.com/questions/25008571/golang-issue-x509-cannot-verify-signature-algorithm-unimplemented-on-net-http
tr := &http.Transport{
TLSClientConfig: &tls.Config{
MaxVersion: tls.VersionTLS11,
PreferServerCipherSuites: true,
},
}
client := &http.Client{Transport: tr}
resp, err := client.Get(fmt.Sprintf("%s://%s:%d/range/list?%s",
protocol,
e.host,
e.port,
url.QueryEscape(query),
))
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
return nil, readErr
}
return nil, errors.New(string(body))
}
defer resp.Body.Close()
scanner := bufio.NewScanner(resp.Body)
grangeResult := grange.NewResult()
for scanner.Scan() {
grangeResult.Add(scanner.Text())
}
if grangeResult.Cardinality() > 0 {
for node := range grangeResult.Iter() {
result = append(result, node.(string))
}
if e.Sort {
sort.Sort(sortorder.Natural(result))
}
}
return result, nil
}
// Compress takes a slice of strings as argument
// and returns a compressed form.
func (*Erg) Compress(nodes []string) (result string) {
grangeResult := grange.NewResult()
for _, node := range nodes {
grangeResult.Add(node)
}
return grange.Compress(&grangeResult)
}