diff --git a/README.md b/README.md
index 6af9825..8b34d0b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
-# *Seasoned*: an intelligent organizer for your shows
+# 🌶 seasonedShows
+Your customly seasoned movie and show requester, downloader and organizer
-*Seasoned* is a intelligent organizer for your tv show episodes. It is made to automate and simplify to process of renaming and moving newly downloaded tv show episodes following Plex file naming and placement.
+## About
+seasonedShows is a intelligent organizer for your tv show episodes. It is made to automate and simplify to process of renaming and moving newly downloaded tv show episodes following Plex file naming and placement.
## Architecture
The flow of the system will first check for new folders in your tv shows directory, if a new file is found it's contents are analyzed, stored and tweets suggested changes to it's contents to use_admin.
@@ -8,3 +10,21 @@ The flow of the system will first check for new folders in your tv shows directo
Then there is a script for looking for replies on twitter by user_admin, if caanges are needed, it handles the changes specified and updates dtabbase.
After approval by user the files are modified and moved to folders in resptected area. If error occours, pasteee link if log is sent to user.
+
+#### External
+ + Seasoned: request, discover and manage.
+ + Stray: Overview of downloaded episodes before they are organized.
+ + (+) Admin Panel: Overview of all stray episodes/movies.
+
+#### Api
+ + All communication between public website to server.
+ + Plex: All querying to what is localy available in your plex library.
+ + Stray (seasoned) -> also calls services (moveStray) through api.
+ + Tmdb: Requesting information from tmdb.
+ + (+) Admin Panel: Use secure login and session tokens to handle logged in viewer.
+
+#### Services
+ + Parse directories for new content.
+ + Extract and save in db information about stray item.
+ + Move a confirmed stray item.
+ + (+) Search for torrents matching new content.
\ No newline at end of file
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 0000000..c419263
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-cayman
\ No newline at end of file
diff --git a/client/app/components/MovieObject.jsx b/client/app/components/MovieObject.jsx
index e2c87aa..1349f68 100644
--- a/client/app/components/MovieObject.jsx
+++ b/client/app/components/MovieObject.jsx
@@ -1,102 +1,32 @@
import React from 'react';
-import glamorous from 'glamorous';
// StyleComponents
-import mediaResultItem from './styledComponents/mediaResultItem.jsx';
+import movieStyle from './styles/movieObjectStyle.jsx';
class MovieObject {
constructor(object) {
this.id = object.id;
this.title = object.title;
this.year = object.year;
+ this.type = object.type;
// Check if object.poster != undefined
this.poster = object.poster;
this.matchedInPlex = object.matchedInPlex;
- this.overview = object.overview;
+ this.summary = object.summary;
}
requestExisting(movie) {
console.log('Exists', movie);
}
- requestMovie(id) {
- fetch('https://apollo.kevinmidboe.com/api/v1/plex/request/' + id, {
+ requestMovie() {
+ // fetch('https://apollo.kevinmidboe.com/api/v1/plex/request/' + id, {
+ fetch('http://localhost:31459/api/v1/plex/request/' + this.id + '?type='+this.type, {
method: 'POST'
});
}
getElement() {
- // TODO move this to separate files.
- var resultItem = {
- maxWidth: '95%',
- margin: '0 auto',
- minHeight: '230px'
- }
- var movie_content = {
- marginLeft: '15px'
- }
- var resultTitle = {
- color: 'black',
- fontSize: '2em',
- }
-
- var resultPoster = {
- float: 'left',
- zIndex: '3',
- position: 'relative',
- marginRight: '30px'
- }
-
- var resultPosterImg = {
- border: '2px none',
- borderRadius: '2px',
- width: '150px'
- }
-
- var buttons = {
- paddingTop: '20px'
- }
-
- var requestButton = {
- color: '#e9a131',
- marginRight: '10px',
- background: 'white',
- border: '#e9a131 2px solid',
- borderRadius: '4px',
- textAlign: 'center',
- padding: '10px',
- minWidth: '100px',
- float: 'left',
- fontSize: '13px',
- fontWeight: '800',
- cursor: 'pointer'
- }
-
- var tmdbButton = {
- color: '#00d17c',
- marginRight: '10px',
- background: 'white',
- border: '#00d17c 2px solid',
- borderRadius: '4px',
- textAlign: 'center',
- padding: '10px',
- minWidth: '100px',
- float: 'left',
- fontSize: '13px',
- fontWeight: '800',
- cursor: 'pointer'
- }
-
- var row = {
- width: '100%'
- }
-
- var itemDivider = {
- width: '90%',
- borderBottom: '1px solid grey',
- margin: '2rem auto'
- }
-
// TODO set the poster image async by updating the dom after this is returned
if (this.poster == null || this.poster == undefined) {
var posterPath = 'https://openclipart.org/image/2400px/svg_to_png/211479/Simple-Image-Not-Found-Icon.png'
@@ -106,10 +36,10 @@ class MovieObject {
var foundInPlex;
if (this.matchedInPlex) {
foundInPlex = ;
+ style={movieStyle.requestButton}>Request Anyway;
} else {
- foundInPlex = ;
+ foundInPlex = ;
}
var themoviedbLink = 'https://www.themoviedb.org/movie/' + this.id
@@ -117,27 +47,29 @@ class MovieObject {
return (
)
diff --git a/client/app/components/SearchRequest.jsx b/client/app/components/SearchRequest.jsx
index 32c3be9..5ee5d20 100644
--- a/client/app/components/SearchRequest.jsx
+++ b/client/app/components/SearchRequest.jsx
@@ -2,67 +2,128 @@ import React from 'react';
import MovieObject from './MovieObject.jsx';
-// TODO add option for searching multi, movies or tv shows
+// StyleComponents
+import searchStyle from './styles/searchRequestStyle.jsx';
+import URI from 'urijs';
+
+// TODO add option for searching multi, movies or tv shows
class SearchRequest extends React.Component {
- constructor(props){
+ constructor(props){
super(props)
// Constructor with states holding the search query and the element of reponse.
this.state = {
searchQuery: '',
responseMovieList: null,
movieFilter: true,
- tvshowFilter: false
+ showFilter: false,
+ discoverType: '',
+ page: 1
}
+ this.allowedDiscoverTypes = [
+ 'discover', 'popular', 'nowplaying', 'upcoming'
+ ]
+
+ // this.baseUrl = 'https://apollo.kevinmidboe.com/api/v1/';
+ this.baseUrl = 'http://localhost:31459/api/v1/tmdb/';
+
this.URLs = {
- request: 'https://apollo.kevinmidboe.com/api/v1/plex/request?query=',
- sendRequest: 'https://apollo.kevinmidboe.com/api/v1/plex/request?query='
+ // request: 'https://apollo.kevinmidboe.com/api/v1/plex/request?page='+this.state.page+'&query=',
+ request: 'http://localhost:31459/api/v1/plex/request?page='+this.state.page+'&query=',
+ // upcoming: 'https://apollo.kevinmidboe.com/api/v1/tmdb/upcoming',
+ upcoming: 'http://localhost:31459/api/v1/tmdb/upcoming',
+ // sendRequest: 'https://apollo.kevinmidboe.com/api/v1/plex/request?query='
+ sendRequest: 'http://localhost:31459/api/v1/plex/request?query='
}
}
componentDidMount(){
- var that = this;
- this.setState({responseMovieList: null})
+ var that = this;
+ // this.setState({responseMovieList: null})
+ this.fetchDiscover('upcoming');
}
// Handles all errors of the response of a fetch call
handleErrors(response) {
- if (!response.ok) {
- throw Error(response.status);
- }
- return response;
+ if (!response.ok) {
+ throw Error(response.status);
+ }
+ return response;
}
+
+ fetchDiscover(queryDiscoverType) {
+ if (this.allowedDiscoverTypes.indexOf(queryDiscoverType) === -1)
+ throw Error('Invalid discover type: ' + queryDiscoverType);
+
+ var uri = new URI(this.baseUrl);
+ uri.segment(queryDiscoverType)
+ uri = uri.setSearch('page', this.state.page);
+ if (this.state.showFilter)
+ uri = uri.addSearch('type', 'show');
+
+ console.log(uri)
+
+ this.setState({
+ responseMovieList: 'Loading...'
+ });
+
+ fetch(uri)
+ // Check if the response is ok
+ .then(response => this.handleErrors(response))
+ .then(response => response.json()) // Convert to json object and pass to next then
+ .then(data => { // Parse the data of the JSON response
+ // If it is something here it updates the state variable with the HTML list of all
+ // movie objects that where returned by the search request
+ if (data.results.length > 0) {
+ this.setState({
+ responseMovieList: data.results.map(item => this.createMovieObjects(item))
+ })
+ }
+ })
+ // If the --------
+ .catch(error => {
+ console.log(error)
+ this.setState({
+ responseMovieList:
Not Found
+ })
+
+ console.log('Error submit: ', error.toString());
+ });
+ }
+
+
fetchQuery() {
let url = this.URLs.request + this.state.searchQuery
- if (this.state.tvshowFilter) {
+ if (this.state.showFilter) {
url = url + '&type=tv'
}
- fetch(url)
- // Check if the response is ok
- .then(response => this.handleErrors(response))
- .then(response => response.json()) // Convert to json object and pass to next then
- .then(data => { // Parse the data of the JSON response
- // If it is something here it updates the state variable with the HTML list of all
- // movie objects that where returned by the search request
- if (data.length > 0) {
- this.setState({
- responseMovieList: data.map(item => this.createMovieObjects(item))
- })
- }
- })
- // If the --------
- .catch(error => {
- console.log(error)
- this.setState({
- responseMovieList:
Not Found
- })
+ fetch(url)
+ // Check if the response is ok
+ .then(response => this.handleErrors(response))
+ .then(response => response.json()) // Convert to json object and pass to next then
+ .then(data => { // Parse the data of the JSON response
+ // If it is something here it updates the state variable with the HTML list of all
+ // movie objects that where returned by the search request
+ console.log(data)
+ if (data.length > 0) {
+ this.setState({
+ responseMovieList: data.map(item => this.createMovieObjects(item))
+ })
+ }
+ })
+ // If the --------
+ .catch(error => {
+ console.log(error)
+ this.setState({
+ responseMovieList: