]> git.lizzy.rs Git - go-anidb.git/blob - groupcache.go
anidb: Don't use a nil fileLock
[go-anidb.git] / groupcache.go
1 package anidb
2
3 import (
4         "encoding/gob"
5         "github.com/Kovensky/go-anidb/http"
6         "strconv"
7         "strings"
8         "time"
9 )
10
11 func init() {
12         gob.RegisterName("*github.com/Kovensky/go-anidb.Group", &Group{})
13 }
14
15 func (g *Group) Touch() {
16         g.Cached = time.Now()
17 }
18
19 func (g *Group) IsStale() bool {
20         if g == nil {
21                 return true
22         }
23         return time.Now().Sub(g.Cached) > GroupCacheDuration
24 }
25
26 // Unique Group IDentifier
27 type GID int
28
29 // Retrieves the Group from the cache.
30 func (gid GID) Group() *Group {
31         var g Group
32         if cache.Get(&g, "gid", gid) == nil {
33                 return &g
34         }
35         return nil
36 }
37
38 // Returns a Group from the cache if possible.
39 //
40 // If the Group is stale, then retrieves the Group
41 // through the UDP API.
42 func (adb *AniDB) GroupByID(gid GID) <-chan *Group {
43         keys := []cacheKey{"gid", gid}
44         ch := make(chan *Group, 1)
45
46         ic := make(chan Cacheable, 1)
47         go func() { ch <- (<-ic).(*Group); close(ch) }()
48         if intentMap.Intent(ic, keys...) {
49                 return ch
50         }
51
52         if g := gid.Group(); !g.IsStale() {
53                 intentMap.Notify(g, keys...)
54                 return ch
55         }
56
57         go func() {
58                 reply := <-adb.udp.SendRecv("GROUP",
59                         paramMap{"gid": gid})
60
61                 var g *Group
62                 if reply.Error() == nil {
63                         parts := strings.Split(reply.Lines()[1], "|")
64                         ints := make([]int64, len(parts))
65                         for i := range parts {
66                                 ints[i], _ = strconv.ParseInt(parts[i], 10, 32)
67                         }
68
69                         irc := ""
70                         if parts[7] != "" {
71                                 irc = "irc://" + parts[8] + "/" + parts[7][1:]
72                         }
73
74                         pic := ""
75                         if parts[10] != "" {
76                                 pic = httpapi.AniDBImageBaseURL + parts[10]
77                         }
78
79                         rellist := strings.Split(parts[16], "'")
80                         relations := make(map[GID]GroupRelationType, len(rellist))
81                         for _, rel := range rellist {
82                                 r := strings.Split(rel, ",")
83                                 gid, _ := strconv.ParseInt(r[0], 10, 32)
84                                 typ, _ := strconv.ParseInt(r[1], 10, 32)
85
86                                 relations[GID(gid)] = GroupRelationType(typ)
87                         }
88
89                         ft := time.Unix(ints[11], 0)
90                         if ints[11] == 0 {
91                                 ft = time.Time{}
92                         }
93                         dt := time.Unix(ints[12], 0)
94                         if ints[12] == 0 {
95                                 dt = time.Time{}
96                         }
97                         lr := time.Unix(ints[14], 0)
98                         if ints[14] == 0 {
99                                 lr = time.Time{}
100                         }
101                         la := time.Unix(ints[15], 0)
102                         if ints[15] == 0 {
103                                 la = time.Time{}
104                         }
105
106                         g = &Group{
107                                 GID: GID(ints[0]),
108
109                                 Name:      parts[5],
110                                 ShortName: parts[6],
111
112                                 IRC:     irc,
113                                 URL:     parts[9],
114                                 Picture: pic,
115
116                                 Founded:   ft,
117                                 Disbanded: dt,
118                                 // ignore ints[13]
119                                 LastRelease:  lr,
120                                 LastActivity: la,
121
122                                 Rating: Rating{
123                                         Rating:    float32(ints[1]) / 100,
124                                         VoteCount: int(ints[2]),
125                                 },
126                                 AnimeCount: int(ints[3]),
127                                 FileCount:  int(ints[4]),
128
129                                 RelatedGroups: relations,
130
131                                 Cached: time.Now(),
132                         }
133                 }
134                 cache.Set(g, keys...)
135                 intentMap.Notify(g, keys...)
136         }()
137         return ch
138 }