Compare commits
4 Commits
e3f6ff1fe2
...
114f022b8d
Author | SHA1 | Date | |
---|---|---|---|
114f022b8d | |||
83d1894a25 | |||
c9ecdac4f2 | |||
3bd51765b8 |
@ -42,40 +42,51 @@ type episodeTorrentDB struct {
|
|||||||
Updated time.Time `db:"updated_at"`
|
Updated time.Time `db:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTorrentFromEpisodeTorrentDB returns a polochon.Torrent from an
|
// newTorrentFromEpisodeTorrentDB returns a polochon.Torrent from an
|
||||||
// episodeTorrentDB
|
// EpisodeTorrentDB
|
||||||
func NewTorrentFromEpisodeTorrentDB(eDB *episodeTorrentDB) *polochon.Torrent {
|
func newTorrentFromEpisodeTorrentDB(eDB *episodeTorrentDB) *polochon.Torrent {
|
||||||
q, _ := polochon.StringToQuality(eDB.Quality)
|
|
||||||
return &polochon.Torrent{
|
return &polochon.Torrent{
|
||||||
Quality: *q,
|
ImdbID: eDB.ImdbID,
|
||||||
URL: eDB.URL,
|
Type: polochon.TypeEpisode,
|
||||||
Seeders: eDB.Seeders,
|
Season: eDB.Season,
|
||||||
Leechers: eDB.Leechers,
|
Episode: eDB.Episode,
|
||||||
Source: eDB.Source,
|
Quality: polochon.Quality(eDB.Quality),
|
||||||
UploadUser: eDB.UploadUser,
|
Result: &polochon.TorrentResult{
|
||||||
Size: eDB.Size,
|
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
|
// polochon.Torrent
|
||||||
func NewEpisodeTorrentDB(t *polochon.Torrent, imdbID string, season, episode int) *episodeTorrentDB {
|
func newEpisodeTorrentDB(t *polochon.Torrent) *episodeTorrentDB {
|
||||||
return &episodeTorrentDB{
|
e := &episodeTorrentDB{
|
||||||
ImdbID: imdbID,
|
ImdbID: t.ImdbID,
|
||||||
Season: season,
|
Quality: string(t.Quality),
|
||||||
Episode: episode,
|
Season: t.Season,
|
||||||
URL: t.URL,
|
Episode: t.Episode,
|
||||||
Source: t.Source,
|
|
||||||
Quality: string(t.Quality),
|
|
||||||
UploadUser: t.UploadUser,
|
|
||||||
Seeders: t.Seeders,
|
|
||||||
Leechers: t.Leechers,
|
|
||||||
Size: t.Size,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// 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{}
|
var torrentsDB = []*episodeTorrentDB{}
|
||||||
err := db.Select(&torrentsDB, getEpisodeTorrentQuery, imdbID, season, episode)
|
err := db.Select(&torrentsDB, getEpisodeTorrentQuery, imdbID, season, episode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -86,19 +97,19 @@ func GetEpisodeTorrents(db *sqlx.DB, imdbID string, season, episode int) ([]polo
|
|||||||
return nil, sql.ErrNoRows
|
return nil, sql.ErrNoRows
|
||||||
}
|
}
|
||||||
|
|
||||||
var torrents []polochon.Torrent
|
var torrents []*polochon.Torrent
|
||||||
for _, torrentDB := range torrentsDB {
|
for _, torrentDB := range torrentsDB {
|
||||||
torrent := NewTorrentFromEpisodeTorrentDB(torrentDB)
|
torrent := newTorrentFromEpisodeTorrentDB(torrentDB)
|
||||||
torrents = append(torrents, *torrent)
|
torrents = append(torrents, torrent)
|
||||||
}
|
}
|
||||||
|
|
||||||
return torrents, nil
|
return torrents, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpsertEpisodeTorrent upserts an episode torrent from a polochon torrent
|
// 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
|
// Create the EpisodeTorrent ready to be put in db
|
||||||
eDB := NewEpisodeTorrentDB(torrent, imdbID, season, episode)
|
eDB := newEpisodeTorrentDB(torrent)
|
||||||
r, err := db.NamedQuery(upsertEpisodeTorrentQuery, eDB)
|
r, err := db.NamedQuery(upsertEpisodeTorrentQuery, eDB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -39,38 +39,47 @@ type movieTorrentDB struct {
|
|||||||
Updated time.Time `db:"updated_at"`
|
Updated time.Time `db:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTorrentFromMovieTorrentDB creates a new polochon.Torrent from a
|
// newTorrentFromMovieTorrentDB creates a new polochon.Torrent from a
|
||||||
// movieTorrentDB
|
// movieTorrentDB
|
||||||
func NewTorrentFromMovieTorrentDB(mDB *movieTorrentDB) *polochon.Torrent {
|
func newTorrentFromMovieTorrentDB(mDB *movieTorrentDB) *polochon.Torrent {
|
||||||
q, _ := polochon.StringToQuality(mDB.Quality)
|
|
||||||
return &polochon.Torrent{
|
return &polochon.Torrent{
|
||||||
Quality: *q,
|
ImdbID: mDB.ImdbID,
|
||||||
URL: mDB.URL,
|
Quality: polochon.Quality(mDB.Quality),
|
||||||
Seeders: mDB.Seeders,
|
Type: polochon.TypeMovie,
|
||||||
Leechers: mDB.Leechers,
|
Result: &polochon.TorrentResult{
|
||||||
Source: mDB.Source,
|
URL: mDB.URL,
|
||||||
UploadUser: mDB.UploadUser,
|
Seeders: mDB.Seeders,
|
||||||
Size: mDB.Size,
|
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
|
// Torrent
|
||||||
func NewMovieTorrentDB(t *polochon.Torrent, imdbID string) movieTorrentDB {
|
func newMovieTorrentDB(t *polochon.Torrent) movieTorrentDB {
|
||||||
return movieTorrentDB{
|
m := movieTorrentDB{
|
||||||
ImdbID: imdbID,
|
ImdbID: t.ImdbID,
|
||||||
URL: t.URL,
|
Quality: string(t.Quality),
|
||||||
Source: t.Source,
|
|
||||||
Quality: string(t.Quality),
|
|
||||||
UploadUser: t.UploadUser,
|
|
||||||
Seeders: t.Seeders,
|
|
||||||
Leechers: t.Leechers,
|
|
||||||
Size: t.Size,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// 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{}
|
var torrentsDB = []*movieTorrentDB{}
|
||||||
// Get the torrents from the DB
|
// Get the torrents from the DB
|
||||||
err := db.Select(&torrentsDB, getMovieTorrentQueryByImdbID, imdbID)
|
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
|
// Create polochon Torrents from the movieTorrentDB
|
||||||
var torrents []polochon.Torrent
|
var torrents []*polochon.Torrent
|
||||||
for _, torrentDB := range torrentsDB {
|
for _, torrentDB := range torrentsDB {
|
||||||
torrent := NewTorrentFromMovieTorrentDB(torrentDB)
|
torrent := newTorrentFromMovieTorrentDB(torrentDB)
|
||||||
torrents = append(torrents, *torrent)
|
torrents = append(torrents, torrent)
|
||||||
}
|
}
|
||||||
|
|
||||||
return torrents, nil
|
return torrents, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpsertMovieTorrent adds or updates MovieTorrent in db
|
// UpsertMovieTorrent adds or updates MovieTorrent in db
|
||||||
func UpsertMovieTorrent(db *sqlx.DB, t *polochon.Torrent, imdbID string) error {
|
func UpsertMovieTorrent(db *sqlx.DB, t *polochon.Torrent) error {
|
||||||
mDB := NewMovieTorrentDB(t, imdbID)
|
mDB := newMovieTorrentDB(t)
|
||||||
r, err := db.NamedQuery(upsertMovieTorrentQuery, mDB)
|
r, err := db.NamedQuery(upsertMovieTorrentQuery, mDB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -223,7 +223,7 @@ func (m *Movie) RefreshTorrents(env *web.Env, torrenters []polochon.Torrenter) e
|
|||||||
|
|
||||||
// Update them in database
|
// Update them in database
|
||||||
for _, t := range m.Movie.Torrents {
|
for _, t := range m.Movie.Torrents {
|
||||||
err = models.UpsertMovieTorrent(env.Database, &t, m.ImdbID)
|
err = models.UpsertMovieTorrent(env.Database, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("error while adding torrent", err)
|
log.Error("error while adding torrent", err)
|
||||||
continue
|
continue
|
||||||
|
@ -179,7 +179,7 @@ func RefreshTorrents(env *web.Env, showEpisode *polochon.ShowEpisode, torrenters
|
|||||||
|
|
||||||
// Upsert all the torrents we got
|
// Upsert all the torrents we got
|
||||||
for _, t := range showEpisode.Torrents {
|
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 {
|
if err != nil {
|
||||||
log.Errorf("error while adding torrent : %s", err)
|
log.Errorf("error while adding torrent : %s", err)
|
||||||
continue
|
continue
|
||||||
|
@ -16,19 +16,12 @@ import (
|
|||||||
|
|
||||||
// DownloadHandler downloads a movie via polochon
|
// DownloadHandler downloads a movie via polochon
|
||||||
func DownloadHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error {
|
func DownloadHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error {
|
||||||
var data struct {
|
torrent := &papi.Torrent{}
|
||||||
URL string `json:"url"`
|
err := json.NewDecoder(r.Body).Decode(torrent)
|
||||||
Metadata *papi.TorrentMetadata `json:"metadata"`
|
|
||||||
}
|
|
||||||
err := json.NewDecoder(r.Body).Decode(&data)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return env.RenderError(w, errors.New("failed to get the url"))
|
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)
|
user := auth.GetCurrentUser(r, env.Log)
|
||||||
|
|
||||||
client, err := user.NewPapiClient(env.Database)
|
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)
|
return env.RenderError(w, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = client.AddTorrent(data.URL, data.Metadata)
|
err = client.AddTorrent(torrent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return env.RenderError(w, err)
|
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 by seeds
|
||||||
sort.Slice(results, func(i, j int) bool {
|
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)
|
return env.RenderJSON(w, results)
|
||||||
|
@ -3,14 +3,9 @@ import { configureAxios, request } from "../requests";
|
|||||||
import { addAlertOk } from "./alerts";
|
import { addAlertOk } from "./alerts";
|
||||||
|
|
||||||
export function addTorrent(torrent) {
|
export function addTorrent(torrent) {
|
||||||
return request(
|
return request("ADD_TORRENT", configureAxios().post("/torrents", torrent), [
|
||||||
"ADD_TORRENT",
|
addAlertOk("Torrent added"),
|
||||||
configureAxios().post("/torrents", {
|
]);
|
||||||
url: torrent.url,
|
|
||||||
metadata: torrent.metadata,
|
|
||||||
}),
|
|
||||||
[addAlertOk("Torrent added")]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeTorrent(id) {
|
export function removeTorrent(id) {
|
||||||
@ -27,6 +22,12 @@ export function searchTorrents(url) {
|
|||||||
return request("TORRENTS_SEARCH", configureAxios().get(url));
|
return request("TORRENTS_SEARCH", configureAxios().get(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function clearTorrentSearch() {
|
||||||
|
return {
|
||||||
|
type: "TORRENTS_SEARCH_CLEAR",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function setFetchedTorrents(torrents) {
|
export function setFetchedTorrents(torrents) {
|
||||||
return {
|
return {
|
||||||
type: "TORRENTS_FETCH_FULFILLED",
|
type: "TORRENTS_FETCH_FULFILLED",
|
||||||
|
@ -27,7 +27,7 @@ const buildMenuItems = (torrents) => {
|
|||||||
entries.push({
|
entries.push({
|
||||||
type: "entry",
|
type: "entry",
|
||||||
quality: torrent.quality,
|
quality: torrent.quality,
|
||||||
size: torrent.size,
|
size: torrent.result.size,
|
||||||
torrent: torrent,
|
torrent: torrent,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -109,7 +109,11 @@ export const TorrentsButton = ({ torrents, search, searching, url }) => {
|
|||||||
return (
|
return (
|
||||||
<Dropdown.Item
|
<Dropdown.Item
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() => dispatch(addTorrent(e.torrent))}
|
href={e.torrent.result.url}
|
||||||
|
onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
dispatch(addTorrent(e.torrent));
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{e.quality}
|
{e.quality}
|
||||||
{e.size !== 0 && (
|
{e.size !== 0 && (
|
||||||
|
@ -19,10 +19,8 @@ export const EpisodeTorrentsButton = ({ season, episode }) => {
|
|||||||
? state.show.show.seasons.get(season).get(episode).fetching
|
? state.show.show.seasons.get(season).get(episode).fetching
|
||||||
: false
|
: false
|
||||||
);
|
);
|
||||||
const torrents = useSelector((state) =>
|
const torrents = useSelector(
|
||||||
state.show.show.seasons.get(season).get(episode).torrents
|
(state) => state.show.show.seasons.get(season).get(episode).torrents
|
||||||
? state.show.show.seasons.get(season).get(episode).torrents
|
|
||||||
: []
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const url = useSelector(
|
const url = useSelector(
|
||||||
|
@ -25,7 +25,11 @@ const AddTorrent = () => {
|
|||||||
if (url === "") {
|
if (url === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch(addTorrent({ url: url, metdata: null }));
|
dispatch(
|
||||||
|
addTorrent({
|
||||||
|
result: { url: url },
|
||||||
|
})
|
||||||
|
);
|
||||||
setUrl("");
|
setUrl("");
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,28 +70,28 @@ const Torrents = () => {
|
|||||||
const Torrent = ({ torrent }) => {
|
const Torrent = ({ torrent }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
var progressStyle = torrent.is_finished
|
var progressStyle = torrent.status.is_finished
|
||||||
? "success"
|
? "success"
|
||||||
: "info progress-bar-striped progress-bar-animated";
|
: "info progress-bar-striped progress-bar-animated";
|
||||||
const progressBarClass = "progress-bar bg-" + progressStyle;
|
const progressBarClass = "progress-bar bg-" + progressStyle;
|
||||||
|
|
||||||
var percentDone = torrent.percent_done;
|
var percentDone = torrent.status.percent_done;
|
||||||
const started = percentDone !== 0;
|
const started = percentDone !== 0;
|
||||||
if (started) {
|
if (started) {
|
||||||
percentDone = Number(percentDone).toFixed(1) + "%";
|
percentDone = Number(percentDone).toFixed(1) + "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pretty sizes
|
// Pretty sizes
|
||||||
const downloadedSize = prettySize(torrent.downloaded_size);
|
const downloadedSize = prettySize(torrent.status.downloaded_size);
|
||||||
const totalSize = prettySize(torrent.total_size);
|
const totalSize = prettySize(torrent.status.total_size);
|
||||||
const downloadRate = prettySize(torrent.download_rate) + "/s";
|
const downloadRate = prettySize(torrent.status.download_rate) + "/s";
|
||||||
return (
|
return (
|
||||||
<div className="card w-100 mb-3">
|
<div className="card w-100 mb-3">
|
||||||
<h5 className="card-header">
|
<h5 className="card-header">
|
||||||
<span className="text text-break">{torrent.name}</span>
|
<span className="text text-break">{torrent.status.name}</span>
|
||||||
<span
|
<span
|
||||||
className="fa fa-trash clickable pull-right"
|
className="fa fa-trash clickable pull-right"
|
||||||
onClick={() => dispatch(removeTorrent(torrent.id))}
|
onClick={() => dispatch(removeTorrent(torrent.status.id))}
|
||||||
></span>
|
></span>
|
||||||
</h5>
|
</h5>
|
||||||
<div className="card-body pb-0">
|
<div className="card-body pb-0">
|
||||||
|
@ -1,40 +1,39 @@
|
|||||||
import React, { useState, useEffect, useCallback } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { addTorrent, searchTorrents } from "../../actions/torrents";
|
|
||||||
import Loader from "../loader/loader";
|
import Loader from "../loader/loader";
|
||||||
|
|
||||||
import { OverlayTrigger, Tooltip } from "react-bootstrap";
|
import { OverlayTrigger, Tooltip } from "react-bootstrap";
|
||||||
|
|
||||||
import { prettySize } from "../../utils";
|
import { prettySize } from "../../utils";
|
||||||
|
|
||||||
|
import {
|
||||||
|
addTorrent,
|
||||||
|
searchTorrents,
|
||||||
|
clearTorrentSearch,
|
||||||
|
} from "../../actions/torrents";
|
||||||
|
|
||||||
export const TorrentSearch = ({ history, match }) => {
|
export const TorrentSearch = ({ history, match }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const [search, setSearch] = useState(match.params.search || "");
|
const [search, setSearch] = useState(match.params.search || "");
|
||||||
const [type, setType] = useState(match.params.type || "");
|
const [type, setType] = useState(match.params.type || "");
|
||||||
|
|
||||||
const url = useCallback(() => {
|
const searchFunc = (type = "") => {
|
||||||
if (search === "" || type === "") {
|
if (search === "" || type === "") {
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return `/torrents/search/${type}/${encodeURI(search)}`;
|
|
||||||
}, [type, search]);
|
|
||||||
|
|
||||||
const searchFunc = useCallback(() => {
|
|
||||||
const searchURL = url();
|
|
||||||
if (searchURL === "") {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(searchTorrents(searchURL));
|
const url = `/torrents/search/${type}/${encodeURI(search)}`;
|
||||||
history.push(searchURL);
|
setType(type);
|
||||||
}, [dispatch, history, url]);
|
dispatch(searchTorrents(url));
|
||||||
|
history.push(url);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
searchFunc();
|
searchFunc(type);
|
||||||
}, [searchFunc]);
|
return () => dispatch(clearTorrentSearch());
|
||||||
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
@ -52,8 +51,7 @@ export const TorrentSearch = ({ history, match }) => {
|
|||||||
type="movies"
|
type="movies"
|
||||||
typeFromURL={type}
|
typeFromURL={type}
|
||||||
handleClick={() => {
|
handleClick={() => {
|
||||||
setType("movies");
|
searchFunc("movies");
|
||||||
searchFunc();
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<SearchButton
|
<SearchButton
|
||||||
@ -61,14 +59,13 @@ export const TorrentSearch = ({ history, match }) => {
|
|||||||
type="shows"
|
type="shows"
|
||||||
typeFromURL={type}
|
typeFromURL={type}
|
||||||
handleClick={() => {
|
handleClick={() => {
|
||||||
setType("shows");
|
searchFunc("shows");
|
||||||
searchFunc();
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<TorrentList search={search} />
|
<TorrentList />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -98,7 +95,7 @@ SearchButton.propTypes = {
|
|||||||
handleClick: PropTypes.func.isRequired,
|
handleClick: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const TorrentList = ({ search }) => {
|
const TorrentList = () => {
|
||||||
const searching = useSelector((state) => state.torrents.searching);
|
const searching = useSelector((state) => state.torrents.searching);
|
||||||
const results = useSelector((state) => state.torrents.searchResults);
|
const results = useSelector((state) => state.torrents.searchResults);
|
||||||
|
|
||||||
@ -106,10 +103,6 @@ const TorrentList = ({ search }) => {
|
|||||||
return <Loader />;
|
return <Loader />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (search === "") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.size === 0) {
|
if (results.size === 0) {
|
||||||
return (
|
return (
|
||||||
<div className="jumbotron">
|
<div className="jumbotron">
|
||||||
@ -126,9 +119,6 @@ const TorrentList = ({ search }) => {
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
TorrentList.propTypes = {
|
|
||||||
search: PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Torrent = ({ torrent }) => {
|
const Torrent = ({ torrent }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -136,17 +126,17 @@ const Torrent = ({ torrent }) => {
|
|||||||
return (
|
return (
|
||||||
<div className="alert d-flex border-bottom border-secondary align-items-center">
|
<div className="alert d-flex border-bottom border-secondary align-items-center">
|
||||||
<TorrentHealth
|
<TorrentHealth
|
||||||
url={torrent.url}
|
url={torrent.result.url}
|
||||||
seeders={torrent.seeders}
|
seeders={torrent.result.seeders}
|
||||||
leechers={torrent.leechers}
|
leechers={torrent.result.leechers}
|
||||||
/>
|
/>
|
||||||
<span className="mx-3 text text-start text-break flex-fill">
|
<span className="mx-3 text text-start text-break flex-fill">
|
||||||
{torrent.name}
|
{torrent.result.name}
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
{torrent.size !== 0 && (
|
{torrent.result.size !== 0 && (
|
||||||
<span className="mx-1 badge badge-pill badge-warning">
|
<span className="mx-1 badge badge-pill badge-warning">
|
||||||
{prettySize(torrent.size)}
|
{prettySize(torrent.result.size)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -154,18 +144,16 @@ const Torrent = ({ torrent }) => {
|
|||||||
{torrent.quality}
|
{torrent.quality}
|
||||||
</span>
|
</span>
|
||||||
<span className="mx-1 badge badge-pill badge-success">
|
<span className="mx-1 badge badge-pill badge-success">
|
||||||
{torrent.source}
|
{torrent.result.source}
|
||||||
</span>
|
</span>
|
||||||
<span className="mx-1 badge badge-pill badge-info">
|
<span className="mx-1 badge badge-pill badge-info">
|
||||||
{torrent.upload_user}
|
{torrent.result.upload_user}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="align-self-end ml-3">
|
<div className="align-self-end ml-3">
|
||||||
<i
|
<i
|
||||||
className="fa fa-cloud-download clickable"
|
className="fa fa-cloud-download clickable"
|
||||||
onClick={() =>
|
onClick={() => dispatch(addTorrent(torrent))}
|
||||||
dispatch(addTorrent({ url: torrent.url, metadata: null }))
|
|
||||||
}
|
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { produce } from "immer";
|
import { produce } from "immer";
|
||||||
|
|
||||||
|
import { formatTorrents } from "../utils";
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
loading: false,
|
loading: false,
|
||||||
movies: new Map(),
|
movies: new Map(),
|
||||||
@ -8,29 +10,6 @@ const defaultState = {
|
|||||||
exploreOptions: {},
|
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) => {
|
const formatMovie = (movie) => {
|
||||||
movie.fetchingDetails = false;
|
movie.fetchingDetails = false;
|
||||||
movie.fetchingSubtitles = false;
|
movie.fetchingSubtitles = false;
|
||||||
|
@ -1,35 +1,12 @@
|
|||||||
import { produce } from "immer";
|
import { produce } from "immer";
|
||||||
|
|
||||||
|
import { formatTorrents } from "../utils";
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
loading: false,
|
loading: false,
|
||||||
show: {},
|
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) => {
|
const formatEpisode = (episode) => {
|
||||||
// Format the episode's torrents
|
// Format the episode's torrents
|
||||||
episode.torrents = formatTorrents(episode);
|
episode.torrents = formatTorrents(episode);
|
||||||
|
@ -28,6 +28,10 @@ export default (state = defaultState, action) =>
|
|||||||
draft.searchResults = action.payload.response.data;
|
draft.searchResults = action.payload.response.data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "TORRENTS_SEARCH_CLEAR":
|
||||||
|
draft.searchResults = [];
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return draft;
|
return draft;
|
||||||
}
|
}
|
||||||
|
@ -31,3 +31,24 @@ export const prettySize = (fileSizeInBytes) => {
|
|||||||
|
|
||||||
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
|
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;
|
||||||
|
};
|
||||||
|
4
go.mod
4
go.mod
@ -15,8 +15,8 @@ require (
|
|||||||
github.com/mattn/go-sqlite3 v1.10.0 // indirect
|
github.com/mattn/go-sqlite3 v1.10.0 // indirect
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/odwrtw/errors v0.0.0-20170604160533-c747b9d17833
|
github.com/odwrtw/errors v0.0.0-20170604160533-c747b9d17833
|
||||||
github.com/odwrtw/papi v0.0.0-20200408160729-930e92b452fd
|
github.com/odwrtw/papi v0.0.0-20200410143325-49e6f827259d
|
||||||
github.com/odwrtw/polochon v0.0.0-20200408160701-0455bb96acb0
|
github.com/odwrtw/polochon v0.0.0-20200410143337-006e3fb9fb55
|
||||||
github.com/phyber/negroni-gzip v0.0.0-20180113114010-ef6356a5d029
|
github.com/phyber/negroni-gzip v0.0.0-20180113114010-ef6356a5d029
|
||||||
github.com/pioz/tvdb v0.0.0-20190503215423-f45c687faba9 // indirect
|
github.com/pioz/tvdb v0.0.0-20190503215423-f45c687faba9 // indirect
|
||||||
github.com/robfig/cron v1.1.0
|
github.com/robfig/cron v1.1.0
|
||||||
|
9
go.sum
9
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/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 h1:ow6b/4Jj7J5iYwU678/rbijvaNUJrYkg13j9Nivkung=
|
||||||
github.com/odwrtw/imdb-watchlist v0.0.0-20190417175016-b7a9f7503d69/go.mod h1:o2tLH95CtNdqhDb0aS2NbU+1I4PmaNsODpr33Ry0JC0=
|
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-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-20200410143325-49e6f827259d h1:it4hnCveS8eFymg0ll9KRzO/iQm/olSW0sb8Ctm3gXI=
|
||||||
github.com/odwrtw/papi v0.0.0-20200408160729-930e92b452fd/go.mod h1:eY0skvVHJBwbSJ18uq2c1T4SvhdEV8R0XFSb0zKh5Yo=
|
github.com/odwrtw/papi v0.0.0-20200410143325-49e6f827259d/go.mod h1:eY0skvVHJBwbSJ18uq2c1T4SvhdEV8R0XFSb0zKh5Yo=
|
||||||
github.com/odwrtw/polochon v0.0.0-20200408160701-0455bb96acb0 h1:p0pXoG89JVL/bZWJpqu2KRQwCU44yYnNnoP46SIPNPQ=
|
github.com/odwrtw/polochon v0.0.0-20200410143337-006e3fb9fb55 h1:hcHBTi+HfYz5p6wgtvQCbrdog0uOB/7eVxPZA5Qff80=
|
||||||
github.com/odwrtw/polochon v0.0.0-20200408160701-0455bb96acb0/go.mod h1:sAYf/A5tDmins2GHZn2mEFarmYltAZv+bcmSKSxDUaI=
|
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 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/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=
|
github.com/odwrtw/trakttv v0.0.0-20200404161731-0d594827e4f9 h1:PuQLHO75MXUsJpf9BcTVxvR/FCkdn1MZnZt6h3o6cJI=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user