diff --git a/src/App.vue b/src/App.vue
index b3ee099..e005bb0 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -46,18 +46,13 @@
-
+
@@ -126,7 +90,8 @@ body {
transition: background-color 0.5s ease, color 0.5s ease;
* {
- transition: background-color 0.5s ease, color 0.5s ease;
+ transition: background-color 0.5s ease, color 0.5s ease,
+ border-color 0.5s ease;
}
&.hidden {
@@ -158,20 +123,6 @@ img {
.wrapper {
position: relative;
}
-// .header {
-// position: fixed;
-// z-index: 15;
-// display: flex;
-// flex-direction: column;
-
-// @include tablet-min {
-// width: calc(100% - 170px);
-// margin-left: 95px;
-// border-top: 0;
-// border-bottom: 0;
-// top: 0;
-// }
-// }
// router view transition
.fade-enter-active,
diff --git a/src/api.js b/src/api.js
index d36b6c5..da86d0c 100644
--- a/src/api.js
+++ b/src/api.js
@@ -1,24 +1,34 @@
-import axios from 'axios'
-import storage from '@/storage'
-import config from '@/config.json'
-import path from 'path'
-import store from '@/store'
+import axios from "axios";
+import storage from "@/storage";
+import config from "@/config.json";
+import path from "path";
+import store from "@/store";
-const SEASONED_URL = config.SEASONED_URL
-const ELASTIC_URL = config.ELASTIC_URL
-const ELASTIC_INDEX = config.ELASTIC_INDEX
+const token = () => store.getters["user/token"];
+const plexId = () => store.getters["user/plexId"];
+
+const AUTHORIZATION_HEADERS = () => {
+ return {
+ Authorization: token(),
+ "Content-Type": "application/json"
+ };
+};
+
+const SEASONED_URL = config.SEASONED_URL;
+const ELASTIC_URL = config.ELASTIC_URL;
+const ELASTIC_INDEX = config.ELASTIC_INDEX;
// TODO
// - Move autorization token and errors here?
-const checkStatusAndReturnJson = (response) => {
+const checkStatusAndReturnJson = response => {
if (!response.ok) {
- throw resp
+ throw resp;
}
- return response.json()
-}
+ return response.json();
+};
-// - - - TMDB - - -
+// - - - TMDB - - -
/**
* Fetches tmdb movie by id. Can optionally include cast credits in result object.
@@ -26,23 +36,31 @@ const checkStatusAndReturnJson = (response) => {
* @param {boolean} [credits=false] Include credits
* @returns {object} Tmdb response
*/
-const getMovie = (id, checkExistance=false, credits=false, release_dates=false) => {
- const url = new URL('v2/movie', SEASONED_URL)
- url.pathname = path.join(url.pathname, id.toString())
+const getMovie = (
+ id,
+ checkExistance = false,
+ credits = false,
+ release_dates = false
+) => {
+ const url = new URL("v2/movie", SEASONED_URL);
+ url.pathname = path.join(url.pathname, id.toString());
if (checkExistance) {
- url.searchParams.append('check_existance', true)
+ url.searchParams.append("check_existance", true);
}
if (credits) {
- url.searchParams.append('credits', true)
+ url.searchParams.append("credits", true);
}
- if(release_dates) {
- url.searchParams.append('release_dates', true)
+ if (release_dates) {
+ url.searchParams.append("release_dates", true);
}
- return fetch(url.href)
+ return fetch(url.href, { headers: AUTHORIZATION_HEADERS() })
.then(resp => resp.json())
- .catch(error => { console.error(`api error getting movie: ${id}`); throw error })
-}
+ .catch(error => {
+ console.error(`api error getting movie: ${id}`);
+ throw error;
+ });
+};
/**
* Fetches tmdb show by id. Can optionally include cast credits in result object.
@@ -50,20 +68,23 @@ const getMovie = (id, checkExistance=false, credits=false, release_dates=false)
* @param {boolean} [credits=false] Include credits
* @returns {object} Tmdb response
*/
-const getShow = (id, checkExistance=false, credits=false) => {
- const url = new URL('v2/show', SEASONED_URL)
- url.pathname = path.join(url.pathname, id.toString())
+const getShow = (id, checkExistance = false, credits = false) => {
+ const url = new URL("v2/show", SEASONED_URL);
+ url.pathname = path.join(url.pathname, id.toString());
if (checkExistance) {
- url.searchParams.append('check_existance', true)
+ url.searchParams.append("check_existance", true);
}
if (credits) {
- url.searchParams.append('credits', true)
+ url.searchParams.append("credits", true);
}
- return fetch(url.href)
+ return fetch(url.href, { headers: AUTHORIZATION_HEADERS() })
.then(resp => resp.json())
- .catch(error => { console.error(`api error getting show: ${id}`); throw error })
-}
+ .catch(error => {
+ console.error(`api error getting show: ${id}`);
+ throw error;
+ });
+};
/**
* Fetches tmdb person by id. Can optionally include cast credits in result object.
@@ -71,17 +92,20 @@ const getShow = (id, checkExistance=false, credits=false) => {
* @param {boolean} [credits=false] Include credits
* @returns {object} Tmdb response
*/
-const getPerson = (id, credits=false) => {
- const url = new URL('v2/person', SEASONED_URL)
- url.pathname = path.join(url.pathname, id.toString())
+const getPerson = (id, credits = false) => {
+ const url = new URL("v2/person", SEASONED_URL);
+ url.pathname = path.join(url.pathname, id.toString());
if (credits) {
- url.searchParams.append('credits', true)
+ url.searchParams.append("credits", true);
}
return fetch(url.href)
.then(resp => resp.json())
- .catch(error => { console.error(`api error getting person: ${id}`); throw error })
-}
+ .catch(error => {
+ console.error(`api error getting person: ${id}`);
+ throw error;
+ });
+};
/**
* Fetches tmdb list by name.
@@ -89,41 +113,39 @@ const getPerson = (id, credits=false) => {
* @param {number} [page=1]
* @returns {object} Tmdb list response
*/
-const getTmdbMovieListByName = (name, page=1) => {
- const url = new URL('v2/movie/' + name, SEASONED_URL)
- url.searchParams.append('page', page)
- const headers = { authorization: storage.token }
+const getTmdbMovieListByName = (name, page = 1) => {
+ const url = new URL("v2/movie/" + name, SEASONED_URL);
+ url.searchParams.append("page", page);
- return fetch(url.href, { headers: headers })
- .then(resp => resp.json())
- // .catch(error => { console.error(`api error getting list: ${name}, page: ${page}`); throw error })
-}
+ return fetch(url.href, { headers: AUTHORIZATION_HEADERS() }).then(resp =>
+ resp.json()
+ );
+ // .catch(error => { console.error(`api error getting list: ${name}, page: ${page}`); throw error })
+};
/**
* Fetches requested items.
* @param {number} [page=1]
* @returns {object} Request response
*/
-const getRequests = (page=1) => {
- const url = new URL('v2/request', SEASONED_URL)
- url.searchParams.append('page', page)
- const headers = { authorization: storage.token }
+const getRequests = (page = 1) => {
+ const url = new URL("v2/request", SEASONED_URL);
+ url.searchParams.append("page", page);
- return fetch(url.href, { headers: headers })
- .then(resp => resp.json())
- // .catch(error => { console.error(`api error getting list: ${name}, page: ${page}`); throw error })
-}
+ return fetch(url.href, {
+ headers: AUTHORIZATION_HEADERS()
+ }).then(resp => resp.json());
+ // .catch(error => { console.error(`api error getting list: ${name}, page: ${page}`); throw error })
+};
+const getUserRequests = (page = 1) => {
+ const url = new URL("v1/user/requests", SEASONED_URL);
+ url.searchParams.append("page", page);
-const getUserRequests = (page=1) => {
- const url = new URL('v1/user/requests', SEASONED_URL)
- url.searchParams.append('page', page)
-
- const headers = { authorization: localStorage.getItem('token') }
-
- return fetch(url.href, { headers })
- .then(resp => resp.json())
-}
+ return fetch(url.href, {
+ headers: AUTHORIZATION_HEADERS()
+ }).then(resp => resp.json());
+};
/**
* Fetches tmdb movies and shows by query.
@@ -131,24 +153,27 @@ const getUserRequests = (page=1) => {
* @param {number} [page=1]
* @returns {object} Tmdb response
*/
-const searchTmdb = (query, page=1, adult=false, mediaType=null) => {
- const url = new URL('v2/search', SEASONED_URL)
- if (mediaType != null && ['movie', 'show', 'person'].includes(mediaType)) {
- url.pathname += `/${mediaType}`
+const searchTmdb = (query, page = 1, adult = false, mediaType = null) => {
+ const url = new URL("v2/search", SEASONED_URL);
+ if (mediaType != null && ["movie", "show", "person"].includes(mediaType)) {
+ url.pathname += `/${mediaType}`;
}
- url.searchParams.append('query', query)
- url.searchParams.append('page', page)
- url.searchParams.append('adult', adult)
+ url.searchParams.append("query", query);
+ url.searchParams.append("page", page);
+ url.searchParams.append("adult", adult);
- const headers = { authorization: localStorage.getItem('token') }
-
- return fetch(url.href, { headers })
+ return fetch(url.href, {
+ headers: AUTHORIZATION_HEADERS()
+ })
.then(resp => resp.json())
- .catch(error => { console.error(`api error searching: ${query}, page: ${page}`); throw error })
-}
+ .catch(error => {
+ console.error(`api error searching: ${query}, page: ${page}`);
+ throw error;
+ });
+};
-// - - - Torrents - - -
+// - - - Torrents - - -
/**
* Search for torrents by query
@@ -157,15 +182,18 @@ const searchTmdb = (query, page=1, adult=false, mediaType=null) => {
* @returns {object} Torrent response
*/
const searchTorrents = (query, authorization_token) => {
- const url = new URL('/api/v1/pirate/search', SEASONED_URL)
- url.searchParams.append('query', query)
+ const url = new URL("/api/v1/pirate/search", SEASONED_URL);
+ url.searchParams.append("query", query);
- const headers = { authorization: storage.token }
-
- return fetch(url.href, { headers: headers })
+ return fetch(url.href, {
+ headers: AUTHORIZATION_HEADERS()
+ })
.then(resp => resp.json())
- .catch(error => { console.error(`api error searching torrents: ${query}`); throw error })
-}
+ .catch(error => {
+ console.error(`api error searching torrents: ${query}`);
+ throw error;
+ });
+};
/**
* Add magnet to download queue.
@@ -175,28 +203,27 @@ const searchTorrents = (query, authorization_token) => {
* @returns {object} Success/Failure response
*/
const addMagnet = (magnet, name, tmdb_id) => {
- const url = new URL('v1/pirate/add', SEASONED_URL)
+ const url = new URL("v1/pirate/add", SEASONED_URL);
const body = JSON.stringify({
magnet: magnet,
name: name,
tmdb_id: tmdb_id
- })
- const headers = {
- 'Content-Type': 'application/json',
- authorization: storage.token
- }
+ });
return fetch(url.href, {
- method: 'POST',
- headers,
- body
- })
+ method: "POST",
+ headers: AUTHORIZATION_HEADERS(),
+ body
+ })
.then(resp => resp.json())
- .catch(error => { console.error(`api error adding magnet: ${name} ${error}`); throw error })
-}
+ .catch(error => {
+ console.error(`api error adding magnet: ${name} ${error}`);
+ throw error;
+ });
+};
-// - - - Plex/Request - - -
+// - - - Plex/Request - - -
/**
* Request a movie or show from id. If authorization token is included the user will be linked
@@ -206,28 +233,19 @@ const addMagnet = (magnet, name, tmdb_id) => {
* @param {string} [authorization_token] To identify the requesting user
* @returns {object} Success/Failure response
*/
-const request = (id, type, authorization_token=undefined) => {
- const url = new URL('v2/request', SEASONED_URL)
-// url.pathname = path.join(url.pathname, id.toString())
-// url.searchParams.append('type', type)
-
- const headers = {
- 'Authorization': authorization_token,
- 'Content-Type': 'application/json'
- }
- const body = {
- id: id,
- type: type
- }
-
+const request = (id, type) => {
+ const url = new URL("v2/request", SEASONED_URL);
return fetch(url.href, {
- method: 'POST',
- headers: headers,
- body: JSON.stringify(body)
+ method: "POST",
+ headers: AUTHORIZATION_HEADERS(),
+ body: JSON.stringify({ id, type })
})
- .then(resp => resp.json())
- .catch(error => { console.error(`api error requesting: ${id}, type: ${type}`); throw error })
-}
+ .then(resp => resp.json())
+ .catch(error => {
+ console.error(`api error requesting: ${id}, type: ${type}`);
+ throw error;
+ });
+};
/**
* Check request status by tmdb id and type
@@ -235,186 +253,182 @@ const request = (id, type, authorization_token=undefined) => {
* @param {string} type
* @returns {object} Success/Failure response
*/
-const getRequestStatus = (id, type, authorization_token=undefined) => {
- const url = new URL('v2/request', SEASONED_URL)
- url.pathname = path.join(url.pathname, id.toString())
- url.searchParams.append('type', type)
+const getRequestStatus = (id, type, authorization_token = undefined) => {
+ const url = new URL("v2/request", SEASONED_URL);
+ url.pathname = path.join(url.pathname, id.toString());
+ url.searchParams.append("type", type);
- return fetch(url.href)
+ return fetch(url.href, { headers: AUTHORIZATION_HEADERS() })
.then(resp => {
const status = resp.status;
- if (status === 200) { return true }
- else if (status === 404) { return false }
- else {
- console.error(`api error getting request status for id ${id} and type ${type}`)
+ if (status === 200) {
+ return true;
+ } else if (status === 404) {
+ return false;
+ } else {
+ console.error(
+ `api error getting request status for id ${id} and type ${type}`
+ );
}
})
- .catch(err => Promise.reject(err))
-}
+ .catch(err => Promise.reject(err));
+};
-const watchLink = (title, year, authorization_token=undefined) => {
- const url = new URL('v1/plex/watch-link', SEASONED_URL)
- url.searchParams.append('title', title)
- url.searchParams.append('year', year)
+const watchLink = (title, year) => {
+ const url = new URL("v1/plex/watch-link", SEASONED_URL);
+ url.searchParams.append("title", title);
+ url.searchParams.append("year", year);
+
+ return fetch(url.href, { headers: AUTHORIZATION_HEADERS() })
+ .then(resp => resp.json())
+ .then(response => response.link);
+};
+
+const movieImages = id => {
+ const url = new URL(`v2/movie/${id}/images`, SEASONED_URL);
const headers = {
- 'Authorization': authorization_token,
- 'Content-Type': 'application/json'
- }
+ "Content-Type": "application/json"
+ };
- return fetch(url.href, { headers })
- .then(resp => resp.json())
- .then(response => response.link)
-}
+ return fetch(url.href, { headers }).then(resp => resp.json());
+};
// - - - Seasoned user endpoints - - -
const register = (username, password) => {
- const url = new URL('v1/user', SEASONED_URL)
+ const url = new URL("v1/user", SEASONED_URL);
const options = {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
+ method: "POST",
+ headers: AUTHORIZATION_HEADERS(),
body: JSON.stringify({ username, password })
- }
+ };
return fetch(url.href, options)
.then(resp => resp.json())
.catch(error => {
- console.error('Unexpected error occured before receiving response. Error:', error)
+ console.error(
+ "Unexpected error occured before receiving response. Error:",
+ error
+ );
// TODO log to sentry the issue here
- throw error
- })
-}
+ throw error;
+ });
+};
-const login = (username, password, throwError=false) => {
- const url = new URL('v1/user/login', SEASONED_URL)
+const login = (username, password, throwError = false) => {
+ const url = new URL("v1/user/login", SEASONED_URL);
const options = {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password })
- }
+ };
- return fetch(url.href, options)
- .then(resp => {
- if (resp.status == 200)
- return resp.json();
+ return fetch(url.href, options).then(resp => {
+ if (resp.status == 200) return resp.json();
- if (throwError)
- throw resp;
- else
- console.error("Error occured when trying to sign in.\nError:", resp);
- })
-}
+ if (throwError) throw resp;
+ else console.error("Error occured when trying to sign in.\nError:", resp);
+ });
+};
const getSettings = () => {
- const settingsExists = (value) => {
- if (value instanceof Object && value.hasOwnProperty('settings'))
+ const settingsExists = value => {
+ if (value instanceof Object && value.hasOwnProperty("settings"))
return value;
throw "Settings does not exist in response object.";
- }
- const commitSettingsToStore = (response) => {
- store.dispatch('userModule/setSettings', response.settings)
- return response
- }
+ };
+ const commitSettingsToStore = response => {
+ store.dispatch("user/setSettings", response.settings);
+ return response;
+ };
- const url = new URL('v1/user/settings', SEASONED_URL)
+ const url = new URL("v1/user/settings", SEASONED_URL);
- const authorization_token = localStorage.getItem('token')
- const headers = authorization_token ? {
- 'Authorization': authorization_token,
- 'Content-Type': 'application/json'
- } : {}
-
- return fetch(url.href, { headers })
+ return fetch(url.href, { headers: AUTHORIZATION_HEADERS() })
.then(resp => resp.json())
.then(settingsExists)
.then(commitSettingsToStore)
.then(response => response.settings)
- .catch(error => { console.log('api error getting user settings'); throw error })
-}
-
-const updateSettings = (settings) => {
- const url = new URL('v1/user/settings', SEASONED_URL)
-
- const authorization_token = localStorage.getItem('token')
- const headers = authorization_token ? {
- 'Authorization': authorization_token,
- 'Content-Type': 'application/json'
- } : {}
+ .catch(error => {
+ console.log("api error getting user settings");
+ throw error;
+ });
+};
+const updateSettings = settings => {
+ const url = new URL("v1/user/settings", SEASONED_URL);
return fetch(url.href, {
- method: 'PUT',
- headers,
- body: JSON.stringify(settings)
- })
+ method: "PUT",
+ headers: AUTHORIZATION_HEADERS(),
+ body: JSON.stringify(settings)
+ })
.then(resp => resp.json())
- .catch(error => { console.log('api error updating user settings'); throw error })
-}
+ .catch(error => {
+ console.log("api error updating user settings");
+ throw error;
+ });
+};
// - - - Authenticate with plex - - -
const linkPlexAccount = (username, password) => {
- const url = new URL('v1/user/link_plex', SEASONED_URL)
- const body = { username, password }
- const headers = {
- 'Content-Type': 'application/json',
- authorization: storage.token
- }
+ const url = new URL("v1/user/link_plex", SEASONED_URL);
+ const body = { username, password };
return fetch(url.href, {
- method: 'POST',
- headers,
+ method: "POST",
+ headers: AUTHORIZATION_HEADERS(),
body: JSON.stringify(body)
})
- .then(resp => resp.json())
- .catch(error => { console.error(`api error linking plex account: ${username}`); throw error })
-}
+ .then(resp => resp.json())
+ .catch(error => {
+ console.error(`api error linking plex account: ${username}`);
+ throw error;
+ });
+};
const unlinkPlexAccount = (username, password) => {
- const url = new URL('v1/user/unlink_plex', SEASONED_URL)
- const headers = {
- 'Content-Type': 'application/json',
- authorization: storage.token
- }
+ const url = new URL("v1/user/unlink_plex", SEASONED_URL);
return fetch(url.href, {
- method: 'POST',
- headers
+ method: "POST",
+ headers: AUTHORIZATION_HEADERS()
})
- .then(resp => resp.json())
- .catch(error => { console.error(`api error unlinking plex account: ${username}`); throw error })
-}
-
+ .then(resp => resp.json())
+ .catch(error => {
+ console.error(`api error unlinking plex account: ${username}`);
+ throw error;
+ });
+};
// - - - User graphs - - -
const fetchChart = (urlPath, days, chartType) => {
- const url = new URL('v1/user' + urlPath, SEASONED_URL)
- url.searchParams.append('days', days)
- url.searchParams.append('y_axis', chartType)
+ const url = new URL("v1/user" + urlPath, SEASONED_URL);
+ url.searchParams.append("days", days);
+ url.searchParams.append("y_axis", chartType);
- const authorization_token = localStorage.getItem('token')
- const headers = authorization_token ? {
- 'Authorization': authorization_token,
- 'Content-Type': 'application/json'
- } : {}
-
- return fetch(url.href, { headers })
+ return fetch(url.href, { headers: AUTHORIZATION_HEADERS() })
.then(resp => resp.json())
- .catch(error => { console.log('api error fetching chart'); throw error })
-}
-
+ .catch(error => {
+ console.log("api error fetching chart");
+ throw error;
+ });
+};
// - - - Random emoji - - -
const getEmoji = () => {
- const url = new URL('v1/emoji', SEASONED_URL)
+ const url = new URL("v1/emoji", SEASONED_URL);
return fetch(url.href)
.then(resp => resp.json())
- .catch(error => { console.log('api error getting emoji'); throw error })
-}
-
+ .catch(error => {
+ console.log("api error getting emoji");
+ throw error;
+ });
+};
// - - - ELASTIC SEARCH - - -
// This elastic index contains titles mapped to ids. Lightning search
@@ -426,44 +440,41 @@ const getEmoji = () => {
* @param {string} query
* @returns {object} List of movies and shows matching query
*/
-const elasticSearchMoviesAndShows = (query) => {
- const url = new URL(path.join(ELASTIC_INDEX, '/_search'), ELASTIC_URL)
- const headers = {
- 'Content-Type': 'application/json'
- }
+const elasticSearchMoviesAndShows = query => {
+ const url = new URL(path.join(ELASTIC_INDEX, "/_search"), ELASTIC_URL);
const body = {
- "sort" : [
- { "popularity" : {"order" : "desc"}},
- "_score"
- ],
- "query": {
- "bool": {
- "should": [{
- "match_phrase_prefix": {
- "original_name": query
+ sort: [{ popularity: { order: "desc" } }, "_score"],
+ query: {
+ bool: {
+ should: [
+ {
+ match_phrase_prefix: {
+ original_name: query
+ }
+ },
+ {
+ match_phrase_prefix: {
+ original_title: query
+ }
}
- },
- {
- "match_phrase_prefix": {
- "original_title": query
- }
- }]
+ ]
}
},
- "size": 6
- }
+ size: 22
+ };
return fetch(url.href, {
- method: 'POST',
- headers: headers,
+ method: "POST",
+ headers: AUTHORIZATION_HEADERS(),
body: JSON.stringify(body)
})
.then(resp => resp.json())
- .catch(error => { console.log(`api error searching elasticsearch: ${query}`); throw error })
-}
-
-
+ .catch(error => {
+ console.log(`api error searching elasticsearch: ${query}`);
+ throw error;
+ });
+};
export {
getMovie,
@@ -477,6 +488,7 @@ export {
addMagnet,
request,
watchLink,
+ movieImages,
getRequestStatus,
linkPlexAccount,
unlinkPlexAccount,
@@ -487,4 +499,4 @@ export {
fetchChart,
getEmoji,
elasticSearchMoviesAndShows
-}
+};
diff --git a/src/components/404.vue b/src/components/404.vue
index 14cd231..68eca47 100644
--- a/src/components/404.vue
+++ b/src/components/404.vue
@@ -3,26 +3,31 @@
- go back to previous page
+ go back to previous page
diff --git a/src/components/Signin.vue b/src/components/Signin.vue
index 8baea18..1d056d9 100644
--- a/src/components/Signin.vue
+++ b/src/components/Signin.vue
@@ -2,88 +2,94 @@
Sign in
-
-
+
+
sign in
- Don't have a user? Register here
+ Don't have a user? Register here
-
-