-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpx.go
139 lines (121 loc) · 2.96 KB
/
px.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"sort"
"net/url"
"strconv"
)
const (
pxApi = "https://api.500px.com/v1/photos/search/?"
rpp = 50
)
type Photo struct {
Views int `json:"times_viewed"`
Tags []string `json:"tags"`
}
type Photos struct {
Data []Photo `json:"photos"`
}
type TotalItems struct {
CurrentPage int `json:"current_page"`
}
func getPxTags(tags []ImageTag) ([]string, error) {
token := os.Getenv("PX_CONSUMER_KEY")
totalTags := 0
allTags := make(map[string]*TagData)
for _, tag := range tags {
//make sure to change rpp back to 100
requestUrl := constructUrl(tag, token)
resp, err := http.Get(requestUrl)
if err != nil {
fmt.Print("Unable to retrieve photos for " + tag.Name)
return nil, err
}
body, err := ioutil.ReadAll(resp.Body)
rawIn := json.RawMessage(body)
bytes, err := rawIn.MarshalJSON()
if err != nil {
fmt.Print("something went bad\n")
return nil, err
}
var response Photos
parseErr := json.Unmarshal(bytes, &response)
if parseErr != nil {
fmt.Printf("%s\n", bytes)
fmt.Print("Unable to parse the px response for " + tag.Name + "\n")
// fmt.Print(bytes)
return nil, err
}
for _, photo := range response.Data {
for _, tag := range photo.Tags {
totalTags++
var ok bool
_, ok = allTags[tag]
if !ok {
allTags[tag] = new(TagData)
allTags[tag].TagUses = 0
allTags[tag].TotalViews = 0
}
allTags[tag].TotalViews = allTags[tag].TotalViews + photo.Views
allTags[tag].TagUses++
}
}
}
// var topTags []string
topTags := make([]string, 0, 30)
sortedTags := sortAlgo(allTags, totalTags)
numOfTags := sortedTags.Len()
if numOfTags < 30 {
for _, tag := range sortedTags {
topTags = append(topTags, tag.Key)
}
} else {
for _, tag := range sortedTags[0:30] {
topTags = append(topTags, tag.Key)
}
}
return topTags, nil
}
func constructUrl(tag ImageTag, token string) string {
params := url.Values{}
params.Add("term", tag.Name)
params.Add("tags", "true")
params.Add("rpp", strconv.Itoa(rpp))
params.Add("consumer_key", token)
return pxApi + params.Encode()
}
func sortAlgo(wordFrequencies map[string]*TagData, totalTags int) PairList {
pl := make(PairList, len(wordFrequencies))
i := 0
for k, v := range wordFrequencies {
pl[i] = Pair{k, v}
ratioUses := float64(pl[i].Value.TagUses) / float64(totalTags)
pl[i].Value.SuperSecretValue = ratioUses * float64(pl[i].Value.TotalViews)
i++
}
sort.Sort(sort.Reverse(pl))
return pl
}
type TagData struct {
TotalViews int
TagUses int
SuperSecretValue float64
}
type Pair struct {
Key string
Value *TagData
}
type PairList []Pair
func (p PairList) Len() int { return len(p) }
func (p PairList) Less(i, j int) bool {
return p[i].Value.SuperSecretValue < p[j].Value.SuperSecretValue
}
func (p PairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func stringArrToJSON(s []string) []byte {
jsonArray, _ := json.Marshal(s)
return jsonArray
}