From 9d294828579332e0e8d853b4a654d5c22ddd9fe1 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 3 Jun 2017 13:12:10 +0200 Subject: [PATCH 01/13] Added overview of requested movie to be printed. --- client/app/components/MovieObject.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/app/components/MovieObject.jsx b/client/app/components/MovieObject.jsx index eaf4667..7784c5a 100644 --- a/client/app/components/MovieObject.jsx +++ b/client/app/components/MovieObject.jsx @@ -7,7 +7,8 @@ class MovieObject { this.year = object.year; // Check if object.poster != undefined this.poster = object.poster; - this.matchedInPlex = object.matchedInPlex + this.matchedInPlex = object.matchedInPlex; + this.overview = object.overview; } requestExisting(id) { @@ -35,6 +36,8 @@ class MovieObject { returnList.push() } + returnList.push({this.overview}); + returnList.push(

); return returnList; } From 27edd29bd27581eb61b3f252a51f2039950bd2dd Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 4 Jun 2017 00:07:23 +0200 Subject: [PATCH 02/13] Started adding features for submitting a request to server --- client/app/components/MovieObject.jsx | 4 +++- client/app/components/SearchRequest.jsx | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/app/components/MovieObject.jsx b/client/app/components/MovieObject.jsx index 7784c5a..4f3e8ea 100644 --- a/client/app/components/MovieObject.jsx +++ b/client/app/components/MovieObject.jsx @@ -16,7 +16,9 @@ class MovieObject { } requestMovie(id) { - console.log(id); + fetch('http://localhost:31459/api/v1/plex/request/' + id, { + method: 'POST' + }) } getElement() { diff --git a/client/app/components/SearchRequest.jsx b/client/app/components/SearchRequest.jsx index e105c0c..c6da4be 100644 --- a/client/app/components/SearchRequest.jsx +++ b/client/app/components/SearchRequest.jsx @@ -58,7 +58,7 @@ class SearchRequest extends React.Component { this._handleKeyPress(event)} - onChange={event => this.handleChange(event)} + onChange={(event) => this.handleChange(event)} value={this.state.searchQuery} /> From b358c61efb020540b1a877d8a8b86f8058aa7bde Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 1 Jul 2017 08:29:49 +0200 Subject: [PATCH 03/13] Had a bug that when searched and empty return it tried to map the empty array. Now we check for the contents of the response before we map the items. --- client/app/components/SearchRequest.jsx | 58 +++++++++++++++++++------ 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/client/app/components/SearchRequest.jsx b/client/app/components/SearchRequest.jsx index c6da4be..13a5c56 100644 --- a/client/app/components/SearchRequest.jsx +++ b/client/app/components/SearchRequest.jsx @@ -13,12 +13,13 @@ class SearchRequest extends React.Component { componentDidMount(){ var that = this; - fetch("https://apollo.kevinmidboe.com/api/v1/plex/request?query=interstellar") - .then(response => response.json()) - .then(data => this.setState({ - items: data - }) - ).catch(err => console.error('Error load: ', err.toString())); + this.setState({items: []}) + // fetch("https://apollo.kevinmidboe.com/api/v1/plex/request?query=interstellar") + // .then(response => response.json()) + // .then(data => this.setState({ + // items: data + // }) + // ).catch(err => console.error('Error load: ', err.toString())); } _handleKeyPress(e) { @@ -27,15 +28,32 @@ class SearchRequest extends React.Component { } } + handleErrors(response) { + if (!response.ok) { + throw Error(response.statusText); + } + return response; + } + fetchQuery() { var query = 'https://apollo.kevinmidboe.com/api/v1/plex/request?query=' + this.state.searchQuery; fetch(query) - .then(response => response.json()) - .then(data => this.setState({ - items: data - }) - ).catch(err => console.error('Error submit: ', err.toString())); + // 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 (data.length > 0) { + this.setState({ + items: data + }) + } else { + this.setState({ + items: null + }) + } + }) + .catch(error => console.log('Error submit: ', error.toString())); } printMovies(item) { @@ -52,13 +70,27 @@ class SearchRequest extends React.Component { }); } + mapResponseToMovies() { + // Here we have some movie response items in our state + if (this.state.items) { + console.log('something') + } + // And here we are going to print a 404 message because the response was empty + else { + console.log('nothing') + } + for (var i = this.state.items.length - 1; i >= 0; i--) { + this.printMovies(this.state.items[i]) + } + } + render(){ return(
this._handleKeyPress(event)} - onChange={(event) => this.handleChange(event)} + onChange={event => this.handleChange(event)} value={this.state.searchQuery} /> @@ -67,7 +99,7 @@ class SearchRequest extends React.Component { {this.state.searchQuery}

- {this.state.items.map((item) => this.printMovies(item))} + {this.mapResponseToMovies()}
) } From 29e575cbf108ed4bacabfbd41db55710d3f7c189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Midb=C3=B8e?= Date: Wed, 12 Jul 2017 00:11:05 +0200 Subject: [PATCH 04/13] Start of fire script to move bulk files to wanted dir, while creating the respected folder names. --- seasonMover.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100755 seasonMover.py diff --git a/seasonMover.py b/seasonMover.py new file mode 100755 index 0000000..9205ff1 --- /dev/null +++ b/seasonMover.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# @Author: KevinMidboe +# @Date: 2017-07-11 19:16:23 +# @Last Modified by: KevinMidboe +# @Last Modified time: 2017-07-11 19:16:23 + +import fire, re, os + +class seasonMover(object): + ''' Moving multiple files to multiple folders with + identifer ''' + workingDir = os.getcwd() + + def create(self, name, interval): + pass + + def move(self, fileSyntax, folderName): + episodeRange = self.findInterval(fileSyntax) + + self.motherMover(fileSyntax, folderName, episodeRange) + + def findInterval(self, item): + if (re.search(r'\((.*)\)', item) is None): + raise ValueError('Need to declare an identifier e.g. (1..3) in: \n\t' + item) + + start = int(re.search('\((\d+)\.\.', item).group(1)) + end = int(re.search('\.\.(\d+)\)', item).group(1)) + + return list(range(start, end+1)) + + def removeUploadSign(self, file): + match = re.search('-[a-zA-Z\[\]\-]*.[a-z]{3}', file) + if match: + uploader = match.group(0)[:-4] + return re.sub(uploader, '', file) + + return file + + def motherMover(self, fileSyntax, folderName, episodeRange): + # Call for sub of fileList + # TODO check if range is same as folderContent + for episode in episodeRange: + leadingZeroNumber = "%02d" % episode + fileName = re.sub(r'\((.*)\)', leadingZeroNumber, fileSyntax) + + oldPath = os.path.join(self.workingDir,fileName) + newFolder = os.path.join(self.workingDir, folderName + leadingZeroNumber) + newPath = os.path.join(newFolder, self.removeUploadSign(fileName)) + + os.makedirs(newFolder) + os.rename(oldPath, newPath) + # print(newFolder) + # print(oldPath + ' --> ' + newPath) + +if __name__ == '__main__': + fire.Fire(seasonMover) \ No newline at end of file From c97ab972ef337b91b2e9cb3831d9e3b2a3151b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Midb=C3=B8e?= Date: Sun, 16 Jul 2017 10:51:02 +0200 Subject: [PATCH 05/13] Changed movieObject ot pass full object, not just it's id when clicked --- client/app/components/MovieObject.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/app/components/MovieObject.jsx b/client/app/components/MovieObject.jsx index 4f3e8ea..51a98d4 100644 --- a/client/app/components/MovieObject.jsx +++ b/client/app/components/MovieObject.jsx @@ -11,8 +11,8 @@ class MovieObject { this.overview = object.overview; } - requestExisting(id) { - console.log('Exists', id) + requestExisting(movie) { + console.log('Exists', movie) } requestMovie(id) { @@ -33,9 +33,9 @@ class MovieObject { returnList.push(); if (this.matchedInPlex) { - returnList.push() + returnList.push() } else { - returnList.push() + returnList.push() } returnList.push({this.overview}); From 97dea47a7a2d0939e4a9e6db560328be41f52f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Midb=C3=B8e?= Date: Sun, 16 Jul 2017 10:54:44 +0200 Subject: [PATCH 06/13] Updated inherits in yarn config file --- client/yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/yarn.lock b/client/yarn.lock index 0c88685..bddfae4 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -1757,11 +1757,11 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@~2.0.0, inherits@~2.0.1: +inherits@2, inherits@2.0.3, inherits@~2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -inherits@2.0.1, inherits@^2.0.1: +inherits@2.0.1, inherits@^2.0.1, inherits@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" From 2c97803d82bf082e2847f766c505ee4fe080def7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Midb=C3=B8e?= Date: Sun, 16 Jul 2017 11:03:30 +0200 Subject: [PATCH 07/13] Added a sendRequest function for handliing the post of a movie request --- src/plex/requestRepository.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/plex/requestRepository.js b/src/plex/requestRepository.js index 0cc27dd..a4f1872 100644 --- a/src/plex/requestRepository.js +++ b/src/plex/requestRepository.js @@ -8,6 +8,8 @@ const tmdb = new TMDB(configuration.get('tmdb', 'apiKey')); var Promise = require('bluebird'); var rp = require('request-promise'); +var pythonShell = require('python-shell'); + class RequestRepository { searchRequest(query, page, type) { @@ -55,6 +57,30 @@ class RequestRepository { }); } + sendRequest(identifier) { + // TODO try a cache hit on the movie item + + console.log(identifier) + tmdb.lookup(identifier).then(movie => { + console.log(movie.title) + + var options = { + args: [movie.title, movie.year, movie.poster] + } + + pythonShell.run('sendRequest.py', options, function (err, results) { + if (err) throw err; + // TODO Add error handling!! RequestRepository.ERROR + // results is an array consisting of messages collected during execution + + console.log('results: %j', results) + }) + return true; + }) + + + } + } module.exports = RequestRepository; \ No newline at end of file From 3047dce1475f0db678550150395ab9f7ca402bd4 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 16 Jul 2017 11:04:56 +0200 Subject: [PATCH 08/13] Opened the POST endpoint for requesting a movie in the server --- src/webserver/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webserver/app.js b/src/webserver/app.js index 1b0fc39..1867154 100644 --- a/src/webserver/app.js +++ b/src/webserver/app.js @@ -32,7 +32,7 @@ router.get('/v1/plex/search', require('./controllers/plex/searchMedia.js')); router.get('/v1/plex/playing', require('./controllers/plex/plexPlaying.js')); router.get('/v1/plex/request', require('./controllers/plex/searchRequest.js')); router.get('/v1/plex/request/:mediaId', require('./controllers/plex/readRequest.js')); -// router.post('/v1/plex/request/:mediaId', require('./controllers/plex/submitRequest.js')); +router.post('/v1/plex/request/:mediaId', require('./controllers/plex/submitRequest.js')); router.get('/v1/plex/hook', require('./controllers/plex/hookDump.js')); router.get('/v1/tmdb/search', require('./controllers/tmdb/searchMedia.js')); From 91606fc9b888137fcf4fea373fee3174560754ab Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 16 Jul 2017 11:05:30 +0200 Subject: [PATCH 09/13] Removed unused import --- src/webserver/controllers/seasoned/verifyStray.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/webserver/controllers/seasoned/verifyStray.js b/src/webserver/controllers/seasoned/verifyStray.js index ca9977d..a0e5178 100644 --- a/src/webserver/controllers/seasoned/verifyStray.js +++ b/src/webserver/controllers/seasoned/verifyStray.js @@ -1,4 +1,3 @@ -const configuration = require('src/config/configuration').getInstance(); const StrayRepository = require('src/seasoned/strayRepository'); const strayRepository = new StrayRepository(); From c45df8a131c82f003a012f115a970969c5140417 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 16 Jul 2017 11:08:14 +0200 Subject: [PATCH 10/13] Added controller for calling POST request function for media items. --- .../controllers/plex/submitRequest.js | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/webserver/controllers/plex/submitRequest.js diff --git a/src/webserver/controllers/plex/submitRequest.js b/src/webserver/controllers/plex/submitRequest.js new file mode 100644 index 0000000..80e1355 --- /dev/null +++ b/src/webserver/controllers/plex/submitRequest.js @@ -0,0 +1,24 @@ +const RequestRepository = require('src/plex/requestRepository.js'); +const requestRepository = new RequestRepository(); + +/** + * Controller: POST a media id to be donwloaded + * @param {Request} req http request variable + * @param {Response} res + * @returns {Callback} + */ + +function submitRequestController(req, res) { + // This is the id that is the param of the url + const id = req.params.mediaId; + + requestRepository.sendRequest(id) + .then(() => { + res.send({ success: true, message: 'Media item sucessfully requested!' }); + }) + .catch((error) => { + res.status(500).send({ success: false, error: error.message }); + }); +} + +module.exports = submitRequestController; \ No newline at end of file From b34e23077bdd0b7eace8cd632aa0e069a806102b Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 16 Jul 2017 11:08:36 +0200 Subject: [PATCH 11/13] Updated gitignore with dist folder --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 23b7eaf..46158bf 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ node_modules *.pyc npm-debug.log webpage/js/env_variables.js +client/dist +src/webserver/access.log From 90546755cced40360579e130b4661feaa4b132b8 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 16 Jul 2017 11:11:43 +0200 Subject: [PATCH 12/13] Rewrote much of the fetching of media items for the rendered request page. --- client/app/components/SearchRequest.jsx | 97 ++++++++++++------------- 1 file changed, 46 insertions(+), 51 deletions(-) diff --git a/client/app/components/SearchRequest.jsx b/client/app/components/SearchRequest.jsx index 13a5c56..0b313a0 100644 --- a/client/app/components/SearchRequest.jsx +++ b/client/app/components/SearchRequest.jsx @@ -5,101 +5,96 @@ import MovieObject from './MovieObject.jsx'; class SearchRequest extends React.Component { constructor(props){ super(props) + // Constructor with states holding the search query and the element of reponse. this.state = { searchQuery: '', - items: [] + responseMovieList: null + } + + this.URLs = { + request: 'https://apollo.kevinmidboe.com/api/v1/plex/request?query=', + sendRequest: 'https://apollo.kevinmidboe.com/api/v1/plex/request?query=' } } componentDidMount(){ var that = this; - this.setState({items: []}) - // fetch("https://apollo.kevinmidboe.com/api/v1/plex/request?query=interstellar") - // .then(response => response.json()) - // .then(data => this.setState({ - // items: data - // }) - // ).catch(err => console.error('Error load: ', err.toString())); + this.setState({responseMovieList: null}) } - - _handleKeyPress(e) { - if (e.key === 'Enter') { - this.fetchQuery(); - } - } - + + // Handles all errors of the response of a fetch call handleErrors(response) { if (!response.ok) { - throw Error(response.statusText); + throw Error(response.status); } return response; } fetchQuery() { - var query = 'https://apollo.kevinmidboe.com/api/v1/plex/request?query=' + this.state.searchQuery; + let url = this.URLs.request + this.state.searchQuery - fetch(query) + 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({ - items: data + this.setState({ + responseMovieList: data.map(item => this.createMovieObjects(item)) }) - } else { - this.setState({ - items: null - }) } }) - .catch(error => console.log('Error submit: ', error.toString())); + // If the -------- + .catch(error => { + console.log(error) + this.setState({ + responseMovieList:

Not Found

+ }) + + console.log('Error submit: ', error.toString()); + }); } - printMovies(item) { - if (item != undefined) { - let a = new MovieObject(item); - return a.getElement(); - } - } - - - handleChange(event){ + // Updates the internal state of the query search field. + updateQueryState(event){ this.setState({ searchQuery: event.target.value }); } - mapResponseToMovies() { - // Here we have some movie response items in our state - if (this.state.items) { - console.log('something') - } - // And here we are going to print a 404 message because the response was empty - else { - console.log('nothing') - } - for (var i = this.state.items.length - 1; i >= 0; i--) { - this.printMovies(this.state.items[i]) - } + // For checking if the enter key was pressed in the search field. + _handleQueryKeyPress(e) { + if (e.key === 'Enter') { + this.fetchQuery(); + } } + // When called passes the variable to MovieObject and calls it's interal function for + // generating the wanted HTML + createMovieObjects(item) { + let movie = new MovieObject(item); + return movie.getElement(); + } + + render(){ return(
this._handleKeyPress(event)} - onChange={event => this.handleChange(event)} + onKeyPress={(event) => this._handleQueryKeyPress(event)} + onChange={event => this.updateQueryState(event)} value={this.state.searchQuery} />

- {this.state.searchQuery}

- - {this.mapResponseToMovies()} + + {this.state.responseMovieList} +
) } From f2cc05307bf70a8bb2f8c7f28211a93ca1eb949c Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 16 Jul 2017 11:18:14 +0200 Subject: [PATCH 13/13] Added TODO --- client/app/components/SearchRequest.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/app/components/SearchRequest.jsx b/client/app/components/SearchRequest.jsx index 0b313a0..1e30183 100644 --- a/client/app/components/SearchRequest.jsx +++ b/client/app/components/SearchRequest.jsx @@ -2,6 +2,8 @@ import React from 'react'; import MovieObject from './MovieObject.jsx'; +// TODO add option for searching multi, movies or tv shows + class SearchRequest extends React.Component { constructor(props){ super(props)