var _ cacheable = &MyListEntry{}
+func (uid UID) MyList(fid FID) *MyListEntry {
+ if f := fid.File(); f == nil {
+ return nil
+ } else if lid := f.LID[uid]; lid < 1 {
+ return nil
+ } else {
+ return f.LID[uid].MyListEntry()
+ }
+}
+
func (lid LID) MyListEntry() *MyListEntry {
var e MyListEntry
- if CacheGet(&e, "lid", lid) == nil {
+ if CacheGet(&e, "mylist", lid) == nil {
return &e
}
return nil
}
func (adb *AniDB) parseMylistReply(reply udpapi.APIReply) *MyListEntry {
- if reply.Error() != nil {
+ // 221: MYLIST ok, 310: MYLISTADD conflict (same return format as 221)
+ if reply.Code() != 221 && reply.Code() != 310 {
return nil
}
if user != nil {
if f := e.FID.File(); f != nil {
f.LID[user.UID] = e.LID
- cacheFile(f)
+ Cache.Set(f, "fid", f.FID)
+ Cache.Chtime(f.Cached, "fid", f.FID)
+
+ now := time.Now()
+ mla := <-adb.MyListAnime(f.AID)
+
+ key := []fscache.CacheKey{"mylist-anime", user.UID, f.AID}
+
+ intentMap.Intent(nil, key...)
+
+ if mla == nil {
+ mla = &MyListAnime{}
+ }
+
+ if mla.Cached.Before(now) {
+ el := mla.EpisodesWithState[e.MyListState]
+ el.Add(f.EpisodeNumber)
+ mla.EpisodesWithState[e.MyListState] = el
+
+ if e.DateWatched.IsZero() {
+ mla.WatchedEpisodes.Sub(f.EpisodeNumber)
+ } else {
+ mla.WatchedEpisodes.Add(f.EpisodeNumber)
+ }
+
+ eg := mla.EpisodesPerGroup[f.GID]
+ eg.Add(f.EpisodeNumber)
+ mla.EpisodesPerGroup[f.GID] = eg
+
+ if mla.Cached.IsZero() {
+ // as attractive as such an ancient mtime would be,
+ // few filesystems can represent it; just make it old enough
+ mla.Cached = time.Unix(0, 0)
+ }
+
+ Cache.Set(mla, key...)
+ Cache.Chtime(mla.Cached, key...)
+ }
+
+ // this unfortunately races if Intent returns true:
+ // only the first NotifyClose call actually notifies
+ go intentMap.NotifyClose(mla, key...)
}
CacheSet(e, "mylist", "by-fid", e.FID, user.UID)
}
- // TODO: Add mylist info to Anime, also update there
CacheSet(e, "mylist", e.LID)
return e