canape/backend/events/torrent_eventer.go
Grégoire Delattre e41c9bfdfa Return the video details embedded in the torrents
This requires the eventers to have the app env
2020-04-11 17:45:33 +02:00

130 lines
3.0 KiB
Go

package events
import (
"fmt"
"reflect"
"time"
"git.quimbo.fr/odwrtw/canape/backend/models"
"git.quimbo.fr/odwrtw/canape/backend/web"
"github.com/odwrtw/papi"
)
// 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(env *web.Env) *PolochonEventers {
eventer := NewEventers(env)
eventer.NewEventer = NewTorrentEventer
eventer.Name = torrentEventName
return eventer
}
// NewTorrentEventer returns a new Eventer for a specific Polochon
func NewTorrentEventer(env *web.Env, polo *models.Polochon) (Eventer, error) {
// Create a new papi client
client, err := polo.NewPapiClient()
if err != nil {
return nil, fmt.Errorf("failed to instanciate polochon client %s", err)
}
// This is the first time this polochon is requested, create the TorrentEventer
tn := &TorrentEventer{
BaseEventer: &BaseEventer{
env: env,
users: []*Channel{},
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.sendEvent(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.env.Log.Warnf("got error getting torrents: %s", err)
}
for {
select {
case <-timeTicker.C:
err := t.torrentsUpdate()
if err != nil {
t.env.Log.Warnf("got error getting torrents: %s", err)
}
case <-t.done:
t.env.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.env.Log.Debugf("torrents have changed!")
notification := make([]*models.TorrentVideo, len(torrents))
for i := range torrents {
notification[i] = models.NewTorrentVideo(&torrents[i])
notification[i].Update(t.env.Backend.Detailer, t.env.Log)
}
t.NotifyAll(notification)
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.env.Log.Debugf("sending the done channel")
t.done <- struct{}{}
}