forked from tjhowse/cacheodon
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGeocaching.go
More file actions
141 lines (126 loc) · 3.56 KB
/
Geocaching.go
File metadata and controls
141 lines (126 loc) · 3.56 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
package main
import (
"os"
"github.com/dustin/go-humanize"
log "github.com/sirupsen/logrus"
)
type GeocachingAPIer interface {
Auth(clientID, clientSecret string) error
Search(st searchTerms) ([]Geocache, error)
GetLogs(geocache *Geocache) ([]GeocacheLog, error)
}
type Geocaching struct {
api GeocachingAPIer
db *FinderDB
conf configStore
}
func NewGeocaching(conf configStore, api GeocachingAPIer) (*Geocaching, error) {
var err error
g := &Geocaching{}
g.conf = conf
g.api = api
if err = g.api.Auth(os.Getenv("GEOCACHING_CLIENT_ID"), os.Getenv("GEOCACHING_CLIENT_SECRET")); err != nil {
log.Fatal(err)
os.Exit(1)
}
g.db, err = NewFinderDB(conf.DBFilename)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
return g, nil
}
func (g *Geocaching) Close() {
g.db.Close()
}
// This polls the API for a list of geocaches and updates our database
// with the results. It returns a slice of postDetails containing the
// information necessary to produce a post about the cache.
func (g *Geocaching) Update() ([]postDetails, error) {
var results []postDetails
caches, err := g.api.Search(g.conf.SearchTerms)
if err != nil {
return results, err
}
log.Println("Found", len(caches), "geocaches")
for _, cache := range caches {
new, updated := g.db.UpdateCache(&cache)
if !new && !updated {
continue
}
if post, err := g.buildPostDetails(&cache, new, updated); err == nil {
results = append(results, post)
} else {
log.Error(err)
}
}
return results, nil
}
// This truncates a string to the given maximum length and returns
// the result. If truncation was necessary, it adds an elipsis to
// the end of the string.
func truncate(s string, max int) string {
if len(s) >= max {
return s[:max-4] + "…\""
}
return s
}
type postDetails struct {
AreaName string
UserName string
CacheName string
DetailsURL string
UsersFindsToday int
LogText string
NewCache bool
PremiumOnly bool
}
func (p *postDetails) toString() string {
message := ""
if !p.NewCache {
message += "In " + p.AreaName + ", \"" + p.UserName + "\""
message += " just found the \"" + p.CacheName + "\""
if p.PremiumOnly {
message += " premium"
}
message += " geocache! " + p.DetailsURL
if p.UsersFindsToday > 1 {
message += " That's their " + humanize.Ordinal(p.UsersFindsToday) + " find today!"
}
message += " They wrote: \"" + p.LogText + "\""
}
geocachingHashtagString := " #geocaching"
message = truncate(message, 500-len(geocachingHashtagString))
message += geocachingHashtagString
return message
}
func (g *Geocaching) buildPostDetails(gc *Geocache, new, updated bool) (postDetails, error) {
var err error
var result postDetails
result.AreaName = g.conf.SearchTerms.AreaName
result.CacheName = gc.Name
result.DetailsURL = "https://www.geocaching.com" + gc.DetailsURL
result.PremiumOnly = gc.PremiumOnly
if new {
// If the cache is new, don't bother trying to get the find logs for it.
result.UserName = gc.Owner.Username
result.UsersFindsToday = 0
result.LogText = ""
result.NewCache = true
} else if updated {
// If the cache was updated, get the latest log and add it to the database.
var logs []GeocacheLog
if logs, err = g.GetLogs(gc); err != nil {
return result, err
}
g.db.AddLog(&logs[0], gc)
result.UserName = logs[0].UserName
result.UsersFindsToday = g.db.FindsSinceMidnight(logs[0].UserName)
result.LogText = logs[0].LogText
result.NewCache = false
}
return result, nil
}
func (g *Geocaching) GetLogs(geocache *Geocache) ([]GeocacheLog, error) {
return g.api.GetLogs(geocache)
}