]> git.lizzy.rs Git - go-anidb.git/blob - misccache.go
Modernize
[go-anidb.git] / misccache.go
1 package anidb
2
3 import (
4         "github.com/EliasFleckenstein03/go-fscache"
5         "strconv"
6         "strings"
7         "time"
8 )
9
10 func (s *MyListStats) setCachedTS(t time.Time) { s.Cached = t }
11
12 func (s *MyListStats) IsStale() bool {
13         if s == nil || time.Now().Sub(s.Cached) > MyListCacheDuration {
14                 return true
15         }
16         return false
17 }
18
19 var _ cacheable = &MyListStats{}
20
21 func (u *User) Stats() *MyListStats {
22         if u == nil {
23                 return nil
24         }
25         var s MyListStats
26         if CacheGet(&s, "mylist-stats", u.UID) == nil {
27                 return &s
28         }
29         return nil
30 }
31
32 func (adb *AniDB) MyListStats(user *User) <-chan *MyListStats {
33         ch := make(chan *MyListStats, 1)
34         if user == nil || user.UID < 1 {
35                 ch <- nil
36                 close(ch)
37                 return ch
38         }
39
40         key := []fscache.CacheKey{"mylist-stats", user.UID}
41
42         ic := make(chan notification, 1)
43         go func() { ch <- (<-ic).(*MyListStats) }()
44         if intentMap.Intent(ic, key...) {
45                 return ch
46         }
47
48         stats := user.Stats()
49         if !stats.IsStale() {
50                 defer intentMap.NotifyClose(stats, key...)
51                 return ch
52         }
53
54         go func() {
55                 if adb.User() == nil {
56                         r := adb.udp.ReAuth()
57                         if r.Code() >= 500 {
58                                 intentMap.NotifyClose(stats, key...)
59                                 return
60                         }
61                 }
62
63                 if user.UID != adb.User().UID {
64                         intentMap.NotifyClose(stats, key...)
65                         return
66                 }
67
68                 reply := <-adb.udp.SendRecv("MYLISTSTATS", nil)
69                 switch reply.Code() {
70                 case 222:
71                         parts := strings.Split(reply.Lines()[1], "|")
72                         ints := make([]int64, len(parts))
73                         for i := range parts {
74                                 ints[i], _ = strconv.ParseInt(parts[i], 10, 64)
75                         }
76
77                         stats = &MyListStats{
78                                 Anime:    int(ints[0]),
79                                 Episodes: int(ints[1]),
80                                 Files:    int(ints[2]),
81                                 Filesize: ints[3] * 1024 * 1024, // it comes in MB
82
83                                 AddedAnime:    int(ints[4]),
84                                 AddedEpisodes: int(ints[5]),
85                                 AddedFiles:    int(ints[6]),
86                                 AddedGroups:   int(ints[7]),
87
88                                 Leech: float32(ints[8]) / 100,
89                                 Glory: float32(ints[9]) / 100,
90
91                                 ViewedPctDatabase: float32(ints[10]) / 100,
92                                 MyListPctDatabase: float32(ints[11]) / 100,
93                                 // ViewedPctMyList: float32(ints[12]) / 100, // we can calculate a more accurate value
94                                 ViewedEpisodes: int(ints[13]),
95
96                                 Votes:   int(ints[14]),
97                                 Reviews: int(ints[15]),
98
99                                 ViewedTime: time.Duration(ints[16]) * time.Minute,
100                         }
101                         stats.ViewedPctMyList = float32(stats.ViewedEpisodes) / float32(stats.Episodes)
102
103                         if ac := AnimeCount(); ac > 0 {
104                                 stats.AnimePctDatabase = float32(stats.Anime) / float32(ac)
105                         }
106
107                         CacheSet(stats, key...)
108                 }
109                 intentMap.NotifyClose(stats, key...)
110         }()
111         return ch
112 }