-
Notifications
You must be signed in to change notification settings - Fork 6
/
misc.go
213 lines (182 loc) · 5.22 KB
/
misc.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
package entities
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"time"
"github.com/sasha-s/go-deadlock"
)
var (
Mutex deadlock.RWMutex
SharedInfo *sharedInfo
AnimeSchedule = &AnimeScheduleMap{AnimeSchedule: make(map[int][]*ShowAirTime)}
)
type AnimeScheduleMap struct {
deadlock.RWMutex
AnimeSchedule map[int][]*ShowAirTime
}
// LoadSharedDB loads global shared DBs in mem
func LoadSharedDB() {
// Creates missing "database" and "shared" folder if they don't exist
if _, err := os.Stat("database"); os.IsNotExist(err) {
err := os.Mkdir("database", 0777)
if err != nil {
log.Println(err)
return
}
}
if _, err := os.Stat("database/shared"); os.IsNotExist(err) {
err := os.Mkdir("database/shared", 0777)
if err != nil {
log.Println(err)
return
}
}
files, err := IOReadDir("database/shared")
if err != nil {
log.Panicln(err)
}
SharedInfo = newSharedInfo(make(map[string]*RemindMeSlice), make(map[string][]*ShowSub))
for _, file := range files {
LoadSharedDBFile(file)
}
}
func LoadSharedDBFile(file string) {
// Reads all the info from the file and puts them in infoByte as bytes
infoByte, err := ioutil.ReadFile(fmt.Sprintf("database/shared/%s", file))
if err != nil {
log.Println(err)
return
}
// Takes the data and puts it into the appropriate field
SharedInfo.Lock()
defer SharedInfo.Unlock()
switch file {
case "remindMes.json":
err = json.Unmarshal(infoByte, &SharedInfo.RemindMes)
if err != nil {
log.Println("LoadSharedDBFile remindMes error:", err)
return
}
case "animeSubs.json":
err = json.Unmarshal(infoByte, &SharedInfo.AnimeSubs)
if err != nil {
log.Println("LoadSharedDBFile animeSubs error:", err)
return
}
}
}
// RemindMeWrite writes RemindMes to remindMes.json
func RemindMeWrite(remindMe map[string]*RemindMeSlice) error {
// Checks if the user has hit the db limit
for _, remindMeSlice := range remindMe {
if remindMeSlice == nil {
continue
}
if remindMeSlice.GetPremium() && len(remindMeSlice.GetRemindMeSlice()) > 299 {
return fmt.Errorf("Error: You have reached the RemindMe limit (300) for this premium account.")
} else if !remindMeSlice.GetPremium() && len(remindMeSlice.GetRemindMeSlice()) > 49 {
return fmt.Errorf("Error: You have reached the RemindMe limit (50) for this account. Please remove some or increase it to 300 by upgrading to a premium user at <https://patreon.com/animeschedule>")
}
}
// Turns that slice into bytes to be ready to written to file
marshaledStruct, err := json.MarshalIndent(remindMe, "", " ")
if err != nil {
return err
}
// Writes to file
SharedInfo.Lock()
defer SharedInfo.Unlock()
err = ioutil.WriteFile("database/shared/remindMes.json", marshaledStruct, 0644)
if err != nil {
log.Println("RemindMeWrite error:", err)
return err
}
return nil
}
// Writes anime notfication subscription to animeSubs.json
func AnimeSubsWrite(animeSubs map[string][]*ShowSub) error {
// Turns that slice into bytes to be ready to written to file
marshaledStruct, err := json.MarshalIndent(animeSubs, "", " ")
if err != nil {
return err
}
// Writes to file
SharedInfo.Lock()
defer SharedInfo.Unlock()
err = ioutil.WriteFile("database/shared/animeSubs.json", marshaledStruct, 0644)
if err != nil {
log.Println("AnimeSubsWrite error:", err)
return err
}
return nil
}
// Reads and returns the names of every file in that directory
func IOReadDir(root string) ([]string, error) {
var files []string
fileInfo, err := ioutil.ReadDir(root)
if err != nil {
return files, err
}
for _, file := range fileInfo {
files = append(files, file.Name())
}
return files, nil
}
func SetupGuildSub(guildID string) {
var (
shows []*ShowSub
now = time.Now().UTC()
addedShows = make(map[string]bool)
)
// Adds every single non-duplicate show as a guild subscription
AnimeSchedule.RLock()
for dayInt, scheduleShows := range AnimeSchedule.AnimeSchedule {
if scheduleShows == nil {
continue
}
for _, show := range scheduleShows {
if show == nil {
continue
}
if _, ok := addedShows[show.GetKey()]; ok {
continue
}
// Checks if the show is from today and whether it has already passed (to avoid notifying the user today if it has passed)
var hasAiredToday bool
if int(now.Weekday()) == dayInt {
// Reset bool
hasAiredToday = false
// Parse the air hour and minute
t, err := time.Parse("3:04 PM", show.GetAirTime())
if err != nil {
log.Println(err)
continue
}
// Form the air date for today
scheduleDate := time.Date(now.Year(), now.Month(), now.Day(), t.Hour(), t.Minute(), now.Second(), now.Nanosecond(), time.UTC)
scheduleDate = scheduleDate.UTC()
// Calculates whether the show has already aired today
difference := now.Sub(scheduleDate.UTC())
if difference >= 0 {
hasAiredToday = true
}
}
guildSub := NewShowSub(show.GetName(), false, true)
if hasAiredToday {
guildSub.SetNotified(true)
}
shows = append(shows, guildSub)
addedShows[show.GetKey()] = true
}
}
AnimeSchedule.RUnlock()
SharedInfo.Lock()
SharedInfo.AnimeSubs[guildID] = shows
SharedInfo.Unlock()
}
func InTimeSpan(start, end, check time.Time) bool {
return check.After(start) && check.Before(end)
}