diff --git a/backend/models/episode_torrents.go b/backend/models/episode_torrents.go index da2c039..ba8dd96 100644 --- a/backend/models/episode_torrents.go +++ b/backend/models/episode_torrents.go @@ -42,40 +42,51 @@ type episodeTorrentDB struct { Updated time.Time `db:"updated_at"` } -// NewTorrentFromEpisodeTorrentDB returns a polochon.Torrent from an -// episodeTorrentDB -func NewTorrentFromEpisodeTorrentDB(eDB *episodeTorrentDB) *polochon.Torrent { - q, _ := polochon.StringToQuality(eDB.Quality) +// newTorrentFromEpisodeTorrentDB returns a polochon.Torrent from an +// EpisodeTorrentDB +func newTorrentFromEpisodeTorrentDB(eDB *episodeTorrentDB) *polochon.Torrent { return &polochon.Torrent{ - Quality: *q, - URL: eDB.URL, - Seeders: eDB.Seeders, - Leechers: eDB.Leechers, - Source: eDB.Source, - UploadUser: eDB.UploadUser, - Size: eDB.Size, + ImdbID: eDB.ImdbID, + Type: polochon.TypeEpisode, + Season: eDB.Season, + Episode: eDB.Episode, + Quality: polochon.Quality(eDB.Quality), + Result: &polochon.TorrentResult{ + URL: eDB.URL, + Seeders: eDB.Seeders, + Leechers: eDB.Leechers, + Source: eDB.Source, + UploadUser: eDB.UploadUser, + Size: eDB.Size, + }, } } -// NewEpisodeTorrentDB returns an episodeTorrentDB ready to be put in DB from a +// newEpisodeTorrentDB returns an episodeTorrentDB ready to be put in DB from a // polochon.Torrent -func NewEpisodeTorrentDB(t *polochon.Torrent, imdbID string, season, episode int) *episodeTorrentDB { - return &episodeTorrentDB{ - ImdbID: imdbID, - Season: season, - Episode: episode, - URL: t.URL, - Source: t.Source, - Quality: string(t.Quality), - UploadUser: t.UploadUser, - Seeders: t.Seeders, - Leechers: t.Leechers, - Size: t.Size, +func newEpisodeTorrentDB(t *polochon.Torrent) *episodeTorrentDB { + e := &episodeTorrentDB{ + ImdbID: t.ImdbID, + Quality: string(t.Quality), + Season: t.Season, + Episode: t.Episode, } + + if t.Result == nil { + return e + } + + e.URL = t.Result.URL + e.Source = t.Result.Source + e.UploadUser = t.Result.UploadUser + e.Seeders = t.Result.Seeders + e.Leechers = t.Result.Leechers + e.Size = t.Result.Size + return e } // GetEpisodeTorrents returns show episodes torrents from database -func GetEpisodeTorrents(db *sqlx.DB, imdbID string, season, episode int) ([]polochon.Torrent, error) { +func GetEpisodeTorrents(db *sqlx.DB, imdbID string, season, episode int) ([]*polochon.Torrent, error) { var torrentsDB = []*episodeTorrentDB{} err := db.Select(&torrentsDB, getEpisodeTorrentQuery, imdbID, season, episode) if err != nil { @@ -86,19 +97,19 @@ func GetEpisodeTorrents(db *sqlx.DB, imdbID string, season, episode int) ([]polo return nil, sql.ErrNoRows } - var torrents []polochon.Torrent + var torrents []*polochon.Torrent for _, torrentDB := range torrentsDB { - torrent := NewTorrentFromEpisodeTorrentDB(torrentDB) - torrents = append(torrents, *torrent) + torrent := newTorrentFromEpisodeTorrentDB(torrentDB) + torrents = append(torrents, torrent) } return torrents, nil } // UpsertEpisodeTorrent upserts an episode torrent from a polochon torrent -func UpsertEpisodeTorrent(db *sqlx.DB, torrent *polochon.Torrent, imdbID string, season, episode int) error { +func UpsertEpisodeTorrent(db *sqlx.DB, torrent *polochon.Torrent) error { // Create the EpisodeTorrent ready to be put in db - eDB := NewEpisodeTorrentDB(torrent, imdbID, season, episode) + eDB := newEpisodeTorrentDB(torrent) r, err := db.NamedQuery(upsertEpisodeTorrentQuery, eDB) if err != nil { return err diff --git a/backend/models/movie_torrents.go b/backend/models/movie_torrents.go index 7d5602b..4615273 100644 --- a/backend/models/movie_torrents.go +++ b/backend/models/movie_torrents.go @@ -39,38 +39,47 @@ type movieTorrentDB struct { Updated time.Time `db:"updated_at"` } -// NewTorrentFromMovieTorrentDB creates a new polochon.Torrent from a +// newTorrentFromMovieTorrentDB creates a new polochon.Torrent from a // movieTorrentDB -func NewTorrentFromMovieTorrentDB(mDB *movieTorrentDB) *polochon.Torrent { - q, _ := polochon.StringToQuality(mDB.Quality) +func newTorrentFromMovieTorrentDB(mDB *movieTorrentDB) *polochon.Torrent { return &polochon.Torrent{ - Quality: *q, - URL: mDB.URL, - Seeders: mDB.Seeders, - Leechers: mDB.Leechers, - Source: mDB.Source, - UploadUser: mDB.UploadUser, - Size: mDB.Size, + ImdbID: mDB.ImdbID, + Quality: polochon.Quality(mDB.Quality), + Type: polochon.TypeMovie, + Result: &polochon.TorrentResult{ + URL: mDB.URL, + Seeders: mDB.Seeders, + Leechers: mDB.Leechers, + Source: mDB.Source, + UploadUser: mDB.UploadUser, + Size: mDB.Size, + }, } } -// NewMovieTorrentDB returns a MovieTorrent ready to be put in DB from a +// newMovieTorrentDB returns a MovieTorrent ready to be put in DB from a // Torrent -func NewMovieTorrentDB(t *polochon.Torrent, imdbID string) movieTorrentDB { - return movieTorrentDB{ - ImdbID: imdbID, - URL: t.URL, - Source: t.Source, - Quality: string(t.Quality), - UploadUser: t.UploadUser, - Seeders: t.Seeders, - Leechers: t.Leechers, - Size: t.Size, +func newMovieTorrentDB(t *polochon.Torrent) movieTorrentDB { + m := movieTorrentDB{ + ImdbID: t.ImdbID, + Quality: string(t.Quality), } + + if t.Result == nil { + return m + } + + m.URL = t.Result.URL + m.Source = t.Result.Source + m.UploadUser = t.Result.UploadUser + m.Seeders = t.Result.Seeders + m.Leechers = t.Result.Leechers + m.Size = t.Result.Size + return m } // GetMovieTorrents returns polochon.Torrents from the database -func GetMovieTorrents(db *sqlx.DB, imdbID string) ([]polochon.Torrent, error) { +func GetMovieTorrents(db *sqlx.DB, imdbID string) ([]*polochon.Torrent, error) { var torrentsDB = []*movieTorrentDB{} // Get the torrents from the DB err := db.Select(&torrentsDB, getMovieTorrentQueryByImdbID, imdbID) @@ -83,18 +92,18 @@ func GetMovieTorrents(db *sqlx.DB, imdbID string) ([]polochon.Torrent, error) { } // Create polochon Torrents from the movieTorrentDB - var torrents []polochon.Torrent + var torrents []*polochon.Torrent for _, torrentDB := range torrentsDB { - torrent := NewTorrentFromMovieTorrentDB(torrentDB) - torrents = append(torrents, *torrent) + torrent := newTorrentFromMovieTorrentDB(torrentDB) + torrents = append(torrents, torrent) } return torrents, nil } // UpsertMovieTorrent adds or updates MovieTorrent in db -func UpsertMovieTorrent(db *sqlx.DB, t *polochon.Torrent, imdbID string) error { - mDB := NewMovieTorrentDB(t, imdbID) +func UpsertMovieTorrent(db *sqlx.DB, t *polochon.Torrent) error { + mDB := newMovieTorrentDB(t) r, err := db.NamedQuery(upsertMovieTorrentQuery, mDB) if err != nil { return err diff --git a/backend/movies/movies.go b/backend/movies/movies.go index 017a27e..f399a6f 100644 --- a/backend/movies/movies.go +++ b/backend/movies/movies.go @@ -223,7 +223,7 @@ func (m *Movie) RefreshTorrents(env *web.Env, torrenters []polochon.Torrenter) e // Update them in database for _, t := range m.Movie.Torrents { - err = models.UpsertMovieTorrent(env.Database, &t, m.ImdbID) + err = models.UpsertMovieTorrent(env.Database, t) if err != nil { log.Error("error while adding torrent", err) continue diff --git a/backend/shows/episodes.go b/backend/shows/episodes.go index dce9854..c9ac7f8 100644 --- a/backend/shows/episodes.go +++ b/backend/shows/episodes.go @@ -179,7 +179,7 @@ func RefreshTorrents(env *web.Env, showEpisode *polochon.ShowEpisode, torrenters // Upsert all the torrents we got for _, t := range showEpisode.Torrents { - err = models.UpsertEpisodeTorrent(env.Database, &t, showEpisode.ShowImdbID, showEpisode.Season, showEpisode.Episode) + err = models.UpsertEpisodeTorrent(env.Database, t) if err != nil { log.Errorf("error while adding torrent : %s", err) continue diff --git a/backend/torrents/handlers.go b/backend/torrents/handlers.go index f672231..58f975d 100644 --- a/backend/torrents/handlers.go +++ b/backend/torrents/handlers.go @@ -16,19 +16,12 @@ import ( // DownloadHandler downloads a movie via polochon func DownloadHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { - var data struct { - URL string `json:"url"` - Metadata *papi.TorrentMetadata `json:"metadata"` - } - err := json.NewDecoder(r.Body).Decode(&data) + torrent := &papi.Torrent{} + err := json.NewDecoder(r.Body).Decode(torrent) if err != nil { return env.RenderError(w, errors.New("failed to get the url")) } - if data.URL == "" { - return env.RenderError(w, errors.New("no given url")) - } - user := auth.GetCurrentUser(r, env.Log) client, err := user.NewPapiClient(env.Database) @@ -36,7 +29,7 @@ func DownloadHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error return env.RenderError(w, err) } - err = client.AddTorrent(data.URL, data.Metadata) + err = client.AddTorrent(torrent) if err != nil { return env.RenderError(w, err) } @@ -123,7 +116,15 @@ func SearchHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { // Sort by seeds sort.Slice(results, func(i, j int) bool { - return results[i].Seeders > results[j].Seeders + // Let's avoid the panic while sorting + if results[i].Result == nil { + results[i].Result = &polochon.TorrentResult{} + } + if results[j].Result == nil { + results[j].Result = &polochon.TorrentResult{} + } + + return results[i].Result.Seeders > results[j].Result.Seeders }) return env.RenderJSON(w, results) diff --git a/frontend/js/actions/torrents.js b/frontend/js/actions/torrents.js index 2ee9128..e1608b3 100644 --- a/frontend/js/actions/torrents.js +++ b/frontend/js/actions/torrents.js @@ -3,14 +3,9 @@ import { configureAxios, request } from "../requests"; import { addAlertOk } from "./alerts"; export function addTorrent(torrent) { - return request( - "ADD_TORRENT", - configureAxios().post("/torrents", { - url: torrent.url, - metadata: torrent.metadata, - }), - [addAlertOk("Torrent added")] - ); + return request("ADD_TORRENT", configureAxios().post("/torrents", torrent), [ + addAlertOk("Torrent added"), + ]); } export function removeTorrent(id) { diff --git a/frontend/js/components/buttons/torrents.js b/frontend/js/components/buttons/torrents.js index 97af697..1ed2727 100644 --- a/frontend/js/components/buttons/torrents.js +++ b/frontend/js/components/buttons/torrents.js @@ -27,7 +27,7 @@ const buildMenuItems = (torrents) => { entries.push({ type: "entry", quality: torrent.quality, - size: torrent.size, + size: torrent.result.size, torrent: torrent, }); }); diff --git a/frontend/js/components/torrents/list.js b/frontend/js/components/torrents/list.js index bd36f0e..39cdb50 100644 --- a/frontend/js/components/torrents/list.js +++ b/frontend/js/components/torrents/list.js @@ -25,7 +25,11 @@ const AddTorrent = () => { if (url === "") { return; } - dispatch(addTorrent({ url: url, metdata: null })); + dispatch( + addTorrent({ + result: { url: url }, + }) + ); setUrl(""); }; @@ -66,28 +70,28 @@ const Torrents = () => { const Torrent = ({ torrent }) => { const dispatch = useDispatch(); - var progressStyle = torrent.is_finished + var progressStyle = torrent.status.is_finished ? "success" : "info progress-bar-striped progress-bar-animated"; const progressBarClass = "progress-bar bg-" + progressStyle; - var percentDone = torrent.percent_done; + var percentDone = torrent.status.percent_done; const started = percentDone !== 0; if (started) { percentDone = Number(percentDone).toFixed(1) + "%"; } // Pretty sizes - const downloadedSize = prettySize(torrent.downloaded_size); - const totalSize = prettySize(torrent.total_size); - const downloadRate = prettySize(torrent.download_rate) + "/s"; + const downloadedSize = prettySize(torrent.status.downloaded_size); + const totalSize = prettySize(torrent.status.total_size); + const downloadRate = prettySize(torrent.status.download_rate) + "/s"; return (
- {torrent.name} + {torrent.status.name} dispatch(removeTorrent(torrent.id))} + onClick={() => dispatch(removeTorrent(torrent.status.id))} >
diff --git a/frontend/js/components/torrents/search.js b/frontend/js/components/torrents/search.js index 8a6e756..e2a85dd 100644 --- a/frontend/js/components/torrents/search.js +++ b/frontend/js/components/torrents/search.js @@ -136,17 +136,17 @@ const Torrent = ({ torrent }) => { return (
- {torrent.name} + {torrent.result.name}
- {torrent.size !== 0 && ( + {torrent.result.size !== 0 && ( - {prettySize(torrent.size)} + {prettySize(torrent.result.size)} )} @@ -154,18 +154,16 @@ const Torrent = ({ torrent }) => { {torrent.quality} - {torrent.source} + {torrent.result.source} - {torrent.upload_user} + {torrent.result.upload_user}
- dispatch(addTorrent({ url: torrent.url, metadata: null })) - } + onClick={() => dispatch(addTorrent(torrent))} >
diff --git a/frontend/js/reducers/movies.js b/frontend/js/reducers/movies.js index fbd9a63..64ffa8a 100644 --- a/frontend/js/reducers/movies.js +++ b/frontend/js/reducers/movies.js @@ -1,5 +1,7 @@ import { produce } from "immer"; +import { formatTorrents } from "../utils"; + const defaultState = { loading: false, movies: new Map(), @@ -8,29 +10,6 @@ const defaultState = { exploreOptions: {}, }; -const formatTorrents = (movie) => { - if (!movie.torrents || movie.torrents.length == 0) { - return undefined; - } - - let torrentMap = new Map(); - movie.torrents.forEach((torrent) => { - if (!torrentMap.has(torrent.source)) { - torrentMap.set(torrent.source, new Map()); - } - - torrent.metadata = { - type: "movie", - imdb_id: movie.imdb_id, // eslint-disable-line camelcase - quality: torrent.quality, - }; - - torrentMap.get(torrent.source).set(torrent.quality, torrent); - }); - - return torrentMap; -}; - const formatMovie = (movie) => { movie.fetchingDetails = false; movie.fetchingSubtitles = false; diff --git a/frontend/js/reducers/show.js b/frontend/js/reducers/show.js index 3734f6d..7beebac 100644 --- a/frontend/js/reducers/show.js +++ b/frontend/js/reducers/show.js @@ -1,35 +1,12 @@ import { produce } from "immer"; +import { formatTorrents } from "../utils"; + const defaultState = { loading: false, show: {}, }; -const formatTorrents = (episode) => { - if (!episode.torrents || episode.torrents.length == 0) { - return undefined; - } - - let torrentMap = new Map(); - episode.torrents.forEach((torrent) => { - if (!torrentMap.has(torrent.source)) { - torrentMap.set(torrent.source, new Map()); - } - - torrent.metadata = { - type: "episode", - imdb_id: episode.show_imdb_id, // eslint-disable-line camelcase - quality: torrent.quality, - season: episode.season, - episode: episode.episode, - }; - - torrentMap.get(torrent.source).set(torrent.quality, torrent); - }); - - return torrentMap; -}; - const formatEpisode = (episode) => { // Format the episode's torrents episode.torrents = formatTorrents(episode); diff --git a/frontend/js/utils.js b/frontend/js/utils.js index 36dda3d..e6ba682 100644 --- a/frontend/js/utils.js +++ b/frontend/js/utils.js @@ -31,3 +31,24 @@ export const prettySize = (fileSizeInBytes) => { return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i]; }; + +export const formatTorrents = (input) => { + if (!input.torrents || input.torrents.length == 0) { + return undefined; + } + + let torrentMap = new Map(); + input.torrents.forEach((torrent) => { + if (!torrent.result || !torrent.result.source) { + return; + } + + if (!torrentMap.has(torrent.result.source)) { + torrentMap.set(torrent.result.source, new Map()); + } + + torrentMap.get(torrent.result.source).set(torrent.quality, torrent); + }); + + return torrentMap; +}; diff --git a/go.mod b/go.mod index f940a2a..39b9c3a 100644 --- a/go.mod +++ b/go.mod @@ -15,8 +15,8 @@ require ( github.com/mattn/go-sqlite3 v1.10.0 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/odwrtw/errors v0.0.0-20170604160533-c747b9d17833 - github.com/odwrtw/papi v0.0.0-20200408160729-930e92b452fd - github.com/odwrtw/polochon v0.0.0-20200408160701-0455bb96acb0 + github.com/odwrtw/papi v0.0.0-20200410143325-49e6f827259d + github.com/odwrtw/polochon v0.0.0-20200410143337-006e3fb9fb55 github.com/phyber/negroni-gzip v0.0.0-20180113114010-ef6356a5d029 github.com/pioz/tvdb v0.0.0-20190503215423-f45c687faba9 // indirect github.com/robfig/cron v1.1.0 diff --git a/go.sum b/go.sum index d74cd32..31664ab 100644 --- a/go.sum +++ b/go.sum @@ -133,12 +133,11 @@ github.com/odwrtw/guessit v0.0.0-20200131084001-f88613483547 h1:O0wEl/ORBHpPpZti github.com/odwrtw/guessit v0.0.0-20200131084001-f88613483547/go.mod h1:W22g7wtc0AGczEARBAs+77gvBk8monDaM6U6i9Wa0vQ= github.com/odwrtw/imdb-watchlist v0.0.0-20190417175016-b7a9f7503d69 h1:ow6b/4Jj7J5iYwU678/rbijvaNUJrYkg13j9Nivkung= github.com/odwrtw/imdb-watchlist v0.0.0-20190417175016-b7a9f7503d69/go.mod h1:o2tLH95CtNdqhDb0aS2NbU+1I4PmaNsODpr33Ry0JC0= -github.com/odwrtw/papi v0.0.0-20190413103029-bd5bfea85ae6 h1:bF8XKFfYNY4quRdqJ5E9ERd+FdR26H1X1Z2fNRGePSk= github.com/odwrtw/papi v0.0.0-20190413103029-bd5bfea85ae6/go.mod h1:CXotdtODLpW0/yuFV5XH8Rmrj0eAfPLvdMKykPM2WCk= -github.com/odwrtw/papi v0.0.0-20200408160729-930e92b452fd h1:LsBK0gVXC8oRxyAwvkCg5fQWTD678Jl7n6a8MZpdUKo= -github.com/odwrtw/papi v0.0.0-20200408160729-930e92b452fd/go.mod h1:eY0skvVHJBwbSJ18uq2c1T4SvhdEV8R0XFSb0zKh5Yo= -github.com/odwrtw/polochon v0.0.0-20200408160701-0455bb96acb0 h1:p0pXoG89JVL/bZWJpqu2KRQwCU44yYnNnoP46SIPNPQ= -github.com/odwrtw/polochon v0.0.0-20200408160701-0455bb96acb0/go.mod h1:sAYf/A5tDmins2GHZn2mEFarmYltAZv+bcmSKSxDUaI= +github.com/odwrtw/papi v0.0.0-20200410143325-49e6f827259d h1:it4hnCveS8eFymg0ll9KRzO/iQm/olSW0sb8Ctm3gXI= +github.com/odwrtw/papi v0.0.0-20200410143325-49e6f827259d/go.mod h1:eY0skvVHJBwbSJ18uq2c1T4SvhdEV8R0XFSb0zKh5Yo= +github.com/odwrtw/polochon v0.0.0-20200410143337-006e3fb9fb55 h1:hcHBTi+HfYz5p6wgtvQCbrdog0uOB/7eVxPZA5Qff80= +github.com/odwrtw/polochon v0.0.0-20200410143337-006e3fb9fb55/go.mod h1:sAYf/A5tDmins2GHZn2mEFarmYltAZv+bcmSKSxDUaI= github.com/odwrtw/tpb v0.0.0-20200130133144-c846aa382c6f h1:fwEIGT+o3e8+XkBqrwsE3/+9ketTQXflPhCkv3/w990= github.com/odwrtw/tpb v0.0.0-20200130133144-c846aa382c6f/go.mod h1:updLvMbQo2xHoz94MX9+GqmSoKhf6E8fs/J+wLvvu6A= github.com/odwrtw/trakttv v0.0.0-20200404161731-0d594827e4f9 h1:PuQLHO75MXUsJpf9BcTVxvR/FCkdn1MZnZt6h3o6cJI=