Create backend implementing Detailer and Torrenter

This Detailer and Torrenter will fetch information from the database
This commit is contained in:
Lucas BEE 2017-02-19 11:50:30 +00:00
parent 9701c9c00f
commit 63aa470bf8
6 changed files with 217 additions and 21 deletions

View File

@ -21,7 +21,7 @@ var (
// UserBackend interface for user backend
type UserBackend interface {
Get(username string) (User, error)
GetUser(username string) (User, error)
}
// User interface for user
@ -64,7 +64,7 @@ func (a *Authorizer) GenHash(password string) (string, error) {
// Login cheks password and creates a jwt token
func (a *Authorizer) Login(rw http.ResponseWriter, req *http.Request, username, password string) (User, error) {
u, err := a.Backend.Get(username)
u, err := a.Backend.GetUser(username)
if err != nil {
return nil, err
}
@ -109,7 +109,7 @@ func (a *Authorizer) CurrentUser(rw http.ResponseWriter, req *http.Request) (Use
}
// Get the user
u, err := a.Backend.Get(tokenClaims.Username)
u, err := a.Backend.GetUser(tokenClaims.Username)
if err != nil {
return nil, err
}

View File

@ -0,0 +1,146 @@
package backend
import (
"database/sql"
"errors"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/auth"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/movies"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/shows"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/torrents"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/users"
"github.com/Sirupsen/logrus"
"github.com/jmoiron/sqlx"
polochon "github.com/odwrtw/polochon/lib"
)
// Backend represents the data backend
type Backend struct {
Database *sqlx.DB
}
// GetUser gets the username from the UserBackend
// Implements the UserBackend interface
func (b *Backend) GetUser(username string) (auth.User, error) {
return users.Get(b.Database, username)
}
// Name implements the Module interface
func (b *Backend) Name() string {
return "canape-backend"
}
// GetDetails implements the polochon Detailer interface
func (b *Backend) GetDetails(media interface{}, log *logrus.Entry) error {
switch t := media.(type) {
case *polochon.Show:
return b.GetShowDetails(t, log)
case *polochon.ShowEpisode:
return b.GetShowEpisodeDetails(t, log)
case *polochon.Movie:
return b.GetMovieDetails(t, log)
default:
return errors.New("invalid type")
}
}
// GetMovieDetails gets details for movies
func (b *Backend) GetMovieDetails(pmovie *polochon.Movie, log *logrus.Entry) error {
m := movies.New(pmovie.ImdbID)
if err := m.GetMovie(b.Database); err != nil {
return err
}
log.Debugf("got movie %s from backend", pmovie.ImdbID)
*pmovie = m.Movie
return nil
}
// GetShowDetails gets details for shows
func (b *Backend) GetShowDetails(pshow *polochon.Show, log *logrus.Entry) error {
s := shows.New(pshow.ImdbID)
if err := s.GetShow(b.Database); err != nil {
return err
}
log.Debugf("got show %s from backend", pshow.ImdbID)
*pshow = s.Show
return nil
}
// GetShowEpisodeDetails gets details for episodes
func (b *Backend) GetShowEpisodeDetails(pepisode *polochon.ShowEpisode, log *logrus.Entry) error {
e := shows.NewEpisode()
e.ShowImdbID = pepisode.ShowImdbID
e.Season = pepisode.Season
e.Episode = pepisode.Episode
if err := e.GetEpisode(b.Database); err != nil {
return err
}
log.Debugf("got episode S%02dE%02d %s from backend", pepisode.Season, pepisode.Episode, pepisode.ShowImdbID)
*pepisode = e.ShowEpisode
return nil
}
// GetTorrents implements the polochon Torrenter interface
func (b *Backend) GetTorrents(media interface{}, log *logrus.Entry) error {
switch t := media.(type) {
case *polochon.ShowEpisode:
return b.GetEpisodeTorrents(t, log)
case *polochon.Movie:
return b.GetMovieTorrents(t, log)
default:
return errors.New("invalid type")
}
}
// GetMovieTorrents fetch Torrents for movies
func (b *Backend) GetMovieTorrents(pmovie *polochon.Movie, log *logrus.Entry) error {
// m := movies.New(pmovie.ImdbID)
movieTorrents, err := torrents.GetMovieTorrents(b.Database, pmovie.ImdbID)
switch err {
case nil:
log.Debug("torrents found in backend")
case sql.ErrNoRows:
log.Debug("torrent not found in backend")
default:
// Unexpected error
return err
}
log.Debugf("got torrents for movie %s from backend", pmovie.ImdbID)
for _, t := range movieTorrents {
pmovie.Torrents = append(pmovie.Torrents, t.Torrent)
}
return nil
}
// GetEpisodeTorrents fetch Torrents for episodes
func (b *Backend) GetEpisodeTorrents(pepisode *polochon.ShowEpisode, log *logrus.Entry) error {
e := shows.NewEpisode()
e.ShowImdbID = pepisode.ShowImdbID
e.Season = pepisode.Season
e.Episode = pepisode.Episode
episodeTorrents, err := torrents.GetEpisodeTorrents(
b.Database,
pepisode.ShowImdbID,
pepisode.Season,
pepisode.Episode,
)
switch err {
case nil:
log.Debug("torrents found in backend")
case sql.ErrNoRows:
log.Debug("torrent not found in backend")
default:
// Unexpected error
return err
}
log.Debugf("got torrents for episode S%02dE%02d %s from backend", pepisode.Season, pepisode.Episode, pepisode.ShowImdbID)
// Add the torrents to the episode
for _, t := range episodeTorrents {
e.Torrents = append(e.Torrents, t.Torrent)
}
return nil
}

View File

@ -32,7 +32,7 @@ const (
tagline=:tagline
RETURNING id;`
getMovieQueryByImdbID = `
getUserMovieQueryByImdbID = `
SELECT
movies.id,
movies.title,
@ -54,7 +54,7 @@ const (
ON movies.imdb_id=movies_tracked.imdb_id AND movies_tracked.user_id=$2
WHERE movies.imdb_id=$1;`
getMovieQueryByID = `
getUserMovieQueryByID = `
SELECT
movies.id,
movies.title,
@ -76,6 +76,16 @@ const (
ON movies.imdb_id=movies_tracked.imdb_id AND movies_tracked.user_id=$2
WHERE movies.id=$1;`
getMovieQueryByImdbID = `
SELECT *
FROM movies
WHERE imdb_id=$1;`
getMovieQueryByID = `
SELECT *
FROM movies
WHERE movies.id=$1;`
deleteMovieQuery = `DELETE FROM movies WHERE id=$1;`
)
@ -170,9 +180,9 @@ func (m *Movie) Get(env *web.Env, user *users.User) error {
var mDB MovieDB
var err error
if m.ID != "" {
err = env.Database.QueryRowx(getMovieQueryByID, m.ID, user.ID).StructScan(&mDB)
err = env.Database.QueryRowx(getUserMovieQueryByID, m.ID, user.ID).StructScan(&mDB)
} else if m.ImdbID != "" {
err = env.Database.QueryRowx(getMovieQueryByImdbID, m.ImdbID, user.ID).StructScan(&mDB)
err = env.Database.QueryRowx(getUserMovieQueryByImdbID, m.ImdbID, user.ID).StructScan(&mDB)
} else {
err = fmt.Errorf("Can't get movie details, you have to specify an ID or ImdbID")
}
@ -187,7 +197,27 @@ func (m *Movie) Get(env *web.Env, user *users.User) error {
return nil
}
// GetDetails retrieves details for the movie, first try to get info from db,
// GetMovie returns show details in database from id or imdbid or an error
func (m *Movie) GetMovie(db *sqlx.DB) error {
var mDB MovieDB
var err error
if m.ID != "" {
err = db.QueryRowx(getMovieQueryByID, m.ID).StructScan(&mDB)
} else if m.ImdbID != "" {
err = db.QueryRowx(getMovieQueryByImdbID, m.ImdbID).StructScan(&mDB)
} else {
err = fmt.Errorf("Can't get movie details, you have to specify an ID or ImdbID")
}
if err != nil {
return err
}
// Set the poster url
// m.PosterURL = m.GetPosterURL(env)
m.FillFromDB(&mDB)
return nil
}
// if not exists, use polochon.Detailer and save informations in the database
// for future use
//

View File

@ -187,8 +187,13 @@ func (e *Episode) GetTorrents(env *web.Env, force bool) error {
// Get returns an episode
func (e *Episode) Get(env *web.Env) error {
return e.GetEpisode(env.Database)
}
// GetEpisode returns an episode
func (e *Episode) GetEpisode(db *sqlx.DB) error {
var episodeDB EpisodeDB
err := env.Database.QueryRowx(getEpisodeQuery, e.ShowImdbID, e.Season, e.Episode).StructScan(&episodeDB)
err := db.QueryRowx(getEpisodeQuery, e.ShowImdbID, e.Season, e.Episode).StructScan(&episodeDB)
if err != nil {
return err
}

View File

@ -171,6 +171,27 @@ func (s *Show) Get(env *web.Env, user *users.User) error {
return nil
}
// GetShow returns a show with user info like tracked
func (s *Show) GetShow(db *sqlx.DB) error {
var err error
var sDB ShowDB
if s.ID != "" {
err = db.QueryRowx(getShowQueryByID, s.ID).StructScan(&sDB)
} else if s.ImdbID != "" {
err = db.QueryRowx(getShowQueryByImdbID, s.ImdbID).StructScan(&sDB)
} else {
err = fmt.Errorf("Can't get show details, you have to specify an ID or ImdbID")
}
if err != nil {
return err
}
// Set the poster url
// s.PosterURL = s.GetPosterURL(env)
s.FillFromDB(&sDB)
return nil
}
// GetDetails retrieves details for the show, first try to
// get info from db, if not exists, use polochon.Detailer
// and save informations in the database for future use

View File

@ -5,6 +5,7 @@ import (
"os"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/auth"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/backend"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/config"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/external_medias"
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/movies"
@ -20,16 +21,6 @@ import (
"github.com/urfave/negroni"
)
// UserBackend represents the data backend to get the user
type UserBackend struct {
Database *sqlx.DB
}
// Get gets the username from the UserBackend
func (b *UserBackend) Get(username string) (auth.User, error) {
return users.Get(b.Database, username)
}
func main() {
var cfgPath string
cfgPath = os.Getenv("CONFIG_FILE")
@ -48,20 +39,23 @@ func main() {
log.Panic(err)
}
// Connect to the database
db, err := sqlx.Connect("postgres", cf.PGDSN)
if err != nil {
log.Panic(err)
}
uBackend := &UserBackend{Database: db}
backend := &backend.Backend{Database: db}
// Generate auth params
authParams := auth.Params{
Backend: uBackend,
Backend: backend,
Pepper: cf.Authorizer.Pepper,
Cost: cf.Authorizer.Cost,
Secret: cf.Authorizer.Secret,
}
authorizer := auth.New(authParams)
// Create web environment needed by the app
env := web.NewEnv(web.EnvParams{
Database: db,
Auth: authorizer,