14 func (l *fidList) Touch() { l.Time = time.Now() }
15 func (l *fidList) IsStale() bool { return time.Now().Sub(l.Time) > FileCacheDuration }
17 // Gets the Files that the given Group has released for the given
18 // Episode. Convenience method that calls FilesByGID.
19 func (adb *AniDB) FilesByGroup(ep *Episode, g *Group) <-chan *File {
20 ch := make(chan *File, 1)
21 if ep == nil || g == nil {
26 return adb.FilesByGID(ep, g.GID)
29 // Gets the Files that the Group (given by its ID) has released
30 // for the given Episode. The returned channel may return multiple
31 // (or no) Files. Uses the UDP API.
33 // On API error (offline, etc), the first *File returned is nil,
34 // followed by cached files (which may also be nil).
35 func (adb *AniDB) FilesByGID(ep *Episode, gid GID) <-chan *File {
36 ch := make(chan *File, 10)
38 fidChan := adb.FIDsByGID(ep, gid)
41 chs := []<-chan *File{}
42 for fid := range fidChan {
43 chs = append(chs, adb.FileByID(fid))
45 for _, c := range chs {
55 // Gets the FIDs that the Group (given by its ID) has released
56 // for the given Episode. The returned channel may return multiple
57 // (or no) FIDs. Uses the UDP API.
59 // On API error (offline, etc), the first *File returned is nil,
60 // followed by cached files (which may also be nil).
61 func (adb *AniDB) FIDsByGID(ep *Episode, gid GID) <-chan FID {
62 keys := []cacheKey{"fid", "by-ep-gid", ep.EID, gid}
64 ch := make(chan FID, 10)
66 if ep == nil || gid < 1 {
72 ic := make(chan Cacheable, 1)
79 if intentMap.Intent(ic, keys...) {
83 if !cache.CheckValid(keys...) {
84 intentMap.Close(keys...)
89 if cache.Get(&fids, keys...) == nil {
90 is := intentMap.LockIntent(keys...)
92 defer intentMap.Free(is, keys...)
95 for _, fid := range fids.FIDs {
103 reply := <-adb.udp.SendRecv("FILE",
107 "epno": ep.Episode.String(),
112 is := intentMap.LockIntent(keys...)
113 defer intentMap.Free(is, keys...)
115 switch reply.Code() {
117 f := parseFileResponse(reply)
119 fids.FIDs = []FID{f.FID}
120 cache.Set(&fids, keys...)
122 cache.Set(&fidCache{FID: f.FID}, "fid", "by-ed2k", f.Ed2kHash, f.Filesize)
123 cache.Set(f, "fid", f.FID)
125 is.NotifyClose(f.FID)
128 parts := strings.Split(reply.Lines()[1], "|")
129 fids.FIDs = make([]FID, len(parts))
130 for i := range parts {
131 id, _ := strconv.ParseInt(parts[i], 10, 32)
132 fids.FIDs[i] = FID(id)
135 cache.Set(&fids, keys...)
137 cache.MarkInvalid(keys...)
138 cache.Delete(keys...)
146 for _, fid := range fids.FIDs {