5 "github.com/Kovensky/go-anidb/udp"
10 gob.RegisterName("*github.com/Kovensky/go-anidb.banCache", &banCache{})
13 const banDuration = 30*time.Minute + 1*time.Second
15 type banCache struct{ time.Time }
17 func (c *banCache) Touch() {
20 func (c *banCache) IsStale() bool {
21 return time.Now().Sub(c.Time) > banDuration
24 // Returns whether the last UDP API access returned a 555 BANNED message.
27 cache.Get(&banTime, "banned")
29 stale := banTime.IsStale()
31 cache.Delete("banned")
37 cache.Set(&banCache{}, "banned")
40 type paramSet struct {
43 ch chan udpapi.APIReply
49 sendQueueCh chan paramSet
51 credentials *credentials
55 func newUDPWrap() *udpWrap {
57 AniDBUDP: udpapi.NewAniDBUDP(),
58 sendQueueCh: make(chan paramSet, 10),
64 type paramMap udpapi.ParamMap // shortcut
66 type noauthAPIReply struct {
70 func (r *noauthAPIReply) Code() int {
74 func (r *noauthAPIReply) Text() string {
78 func (r *noauthAPIReply) Error() error {
79 return &udpapi.APIError{Code: r.Code(), Desc: r.Text()}
82 type bannedAPIReply struct {
86 func (r *bannedAPIReply) Code() int {
89 func (r *bannedAPIReply) Text() string {
92 func (r *bannedAPIReply) Error() error {
93 return &udpapi.APIError{Code: r.Code(), Desc: r.Text()}
96 var bannedReply udpapi.APIReply = &bannedAPIReply{}
98 func (udp *udpWrap) sendQueue() {
99 initialWait := 6 * time.Second
101 for set := range udp.sendQueueCh {
103 reply := <-udp.AniDBUDP.SendRecv(set.cmd, udpapi.ParamMap(set.params))
105 if reply.Error() == udpapi.TimeoutError {
107 wait = (wait * 15) / 10
108 if wait > time.Minute {
116 switch reply.Code() {
117 case 403, 501, 506: // not logged in, or session expired
118 if err := udp.ReAuth(); err == nil {
122 case 503, 504: // client library rejected
124 case 555: // IP (and user, possibly client) temporarily banned
132 func (udp *udpWrap) SendRecv(cmd string, params paramMap) <-chan udpapi.APIReply {
133 ch := make(chan udpapi.APIReply, 1)
134 if udp.credentials == nil {
135 ch <- &noauthAPIReply{}
146 udp.sendQueueCh <- paramSet{