4 "github.com/Kovensky/go-anidb/udp"
5 "github.com/Kovensky/go-fscache"
11 func (e *MyListEntry) setCachedTS(ts time.Time) {
15 func (e *MyListEntry) IsStale() bool {
20 max := MyListCacheDuration
21 if !e.DateWatched.IsZero() {
22 max = MyListWatchedCacheDuration
24 return time.Now().Sub(e.Cached) > max
27 var _ cacheable = &MyListEntry{}
29 func (lid LID) MyListEntry() *MyListEntry {
31 if CacheGet(&e, "lid", lid) == nil {
37 func (adb *AniDB) MyListByFile(f *File) <-chan *MyListEntry {
38 ch := make(chan *MyListEntry, 1)
47 user := <-adb.GetCurrentUser()
49 var entry *MyListEntry
51 if lid := f.LID[user.UID]; lid != 0 {
52 entry = <-adb.MyListByLID(lid)
55 entry = <-adb.MyListByFID(f.FID)
63 func (adb *AniDB) MyListByLID(lid LID) <-chan *MyListEntry {
64 key := []fscache.CacheKey{"mylist", lid}
65 ch := make(chan *MyListEntry, 1)
73 ic := make(chan notification, 1)
74 go func() { ch <- (<-ic).(*MyListEntry); close(ch) }()
75 if intentMap.Intent(ic, key...) {
79 if !Cache.IsValid(InvalidKeyCacheDuration, key...) {
80 intentMap.NotifyClose((*MyListEntry)(nil), key...)
84 entry := lid.MyListEntry()
86 intentMap.NotifyClose(entry, key...)
91 reply := <-adb.udp.SendRecv("MYLIST", paramMap{"lid": lid})
95 entry = adb.parseMylistReply(reply) // caches
97 panic("Multiple MYLIST entries when querying for single LID")
99 Cache.SetInvalid(key...)
102 intentMap.NotifyClose(entry, key...)
107 func (adb *AniDB) MyListByFID(fid FID) <-chan *MyListEntry {
108 ch := make(chan *MyListEntry, 1)
116 // This is an odd one: we lack enough data at first to create the cache key
118 user := <-adb.GetCurrentUser()
119 if user == nil || user.UID < 1 {
125 key := []fscache.CacheKey{"mylist", "by-fid", fid, user.UID}
127 ic := make(chan notification, 1)
128 go func() { ch <- (<-ic).(*MyListEntry); close(ch) }()
129 if intentMap.Intent(ic, key...) {
133 if !Cache.IsValid(InvalidKeyCacheDuration, key...) {
134 intentMap.NotifyClose((*MyListEntry)(nil), key...)
139 switch ts, err := Cache.Get(&lid, key...); {
140 case err == nil && time.Now().Sub(ts) < LIDCacheDuration:
141 intentMap.NotifyClose(<-adb.MyListByLID(lid), key...)
145 reply := <-adb.udp.SendRecv("MYLIST", paramMap{"fid": fid})
147 var entry *MyListEntry
149 switch reply.Code() {
151 entry = adb.parseMylistReply(reply) // caches
153 panic("Multiple MYLIST entries when querying for single FID")
155 Cache.SetInvalid(key...)
158 intentMap.NotifyClose(entry, key...)
163 func (adb *AniDB) parseMylistReply(reply udpapi.APIReply) *MyListEntry {
164 if reply.Error() != nil {
168 parts := strings.Split(reply.Lines()[1], "|")
169 ints := make([]int64, len(parts))
170 for i := range parts {
171 ints[i], _ = strconv.ParseInt(parts[i], 10, 64)
174 da := time.Unix(ints[5], 0)
178 dw := time.Unix(ints[7], 0)
194 State: FileState(ints[11]),
195 MyListState: MyListState(ints[6]),
202 user := <-adb.GetCurrentUser()
205 if f := e.FID.File(); f != nil {
206 f.LID[user.UID] = e.LID
210 CacheSet(e, "mylist", "by-fid", e.FID, user.UID)
213 // TODO: Add mylist info to Anime, also update there
214 CacheSet(e, "mylist", e.LID)