package events import ( "fmt" "reflect" "time" "git.quimbo.fr/odwrtw/canape/backend/models" "github.com/odwrtw/papi" "github.com/sirupsen/logrus" ) // TorrentEventer represents the Eventer for torrents type TorrentEventer struct { *BaseEventer done chan struct{} pClient *papi.Client torrents []papi.Torrent } var torrentEventName = "torrents" // NewTorrentEventers returns a new PolochonEventers for torrents func NewTorrentEventers() *PolochonEventers { eventer := NewEventers() eventer.NewEventer = NewTorrentEventer eventer.Name = torrentEventName return eventer } // NewTorrentEventer returns a new Eventer for a specific Polochon func NewTorrentEventer(polo *models.Polochon, log *logrus.Entry) (Eventer, error) { // Create a new papi client client, err := polo.NewPapiClient() if err != nil { log.Warnf("failed to create the polochon client %s", err) return nil, fmt.Errorf("failed to instanciate polochon client") } // This is the first time this polochon is requested, create the TorrentEventer tn := &TorrentEventer{ BaseEventer: &BaseEventer{ users: []*Channel{}, log: log, name: torrentEventName, }, pClient: client, done: make(chan struct{}), torrents: []papi.Torrent{}, } return tn, nil } // Append implements the Eventer interface // It just appends a channel to the list of users // When the user is appended, send him the torrents infos we have func (t *TorrentEventer) Append(chanl *Channel) { event := ServerEvent{ Event: Event{ Type: torrentEventName, Status: OK, }, Data: t.torrents, } chanl.serverEventStream <- event t.BaseEventer.Append(chanl) } // Launch implements the Eventer interface // It starts a ticker to fetch torrents and notify the users func (t *TorrentEventer) Launch() error { // Create the timer that will check for the torrents every X seconds timeTicker := time.NewTicker(10 * time.Second) defer timeTicker.Stop() err := t.torrentsUpdate() if err != nil { t.log.Warnf("got error getting torrent update: %s", err) t.FatalError(err) return err } for { select { case <-timeTicker.C: err := t.torrentsUpdate() if err != nil { t.log.Warnf("got error getting torrent update: %s", err) t.FatalError(err) return err } case <-t.done: t.log.Debug("quit torrent notifier") return nil } } } // torrentsUpdate sends to the eventStream if torrents change func (t *TorrentEventer) torrentsUpdate() error { // Get torrents torrents, err := t.pClient.GetTorrents() if err != nil { return err } if reflect.DeepEqual(t.torrents, torrents) { return nil } t.log.Debugf("torrents have changed!") t.NotifyAll(torrents) t.torrents = torrents return nil } // Finish implements the Eventer interface // It is called when there is no more users subscribed func (t *TorrentEventer) Finish() { t.log.Debugf("sending the done channel") t.done <- struct{}{} }