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