Merge pull request #14 from KevinMidboe/client_feature

Client feature
This commit is contained in:
2017-07-16 11:19:15 +02:00
committed by GitHub
9 changed files with 187 additions and 45 deletions

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@ node_modules
*.pyc
npm-debug.log
webpage/js/env_variables.js
client/dist
src/webserver/access.log

View File

@@ -7,15 +7,18 @@ 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) {
console.log('Exists', id)
requestExisting(movie) {
console.log('Exists', movie)
}
requestMovie(id) {
console.log(id);
fetch('http://localhost:31459/api/v1/plex/request/' + id, {
method: 'POST'
})
}
getElement() {
@@ -30,11 +33,13 @@ class MovieObject {
returnList.push(<img src={posterPath}></img>);
if (this.matchedInPlex) {
returnList.push(<button onClick={() => this.requestExisting(this.id)}>Request anyway</button>)
returnList.push(<button onClick={() => this.requestExisting(this)}>Request anyway</button>)
} else {
returnList.push(<button onClick={() => this.requestMovie(this.id)}>Request</button>)
returnList.push(<button onClick={() => this.requestMovie(this)}>Request</button>)
}
returnList.push(<span>{this.overview}</span>);
returnList.push(<br></br>);
return returnList;
}

View File

@@ -2,72 +2,101 @@ 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)
// 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;
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})
}
// Handles all errors of the response of a fetch call
handleErrors(response) {
if (!response.ok) {
throw Error(response.status);
}
return response;
}
_handleKeyPress(e) {
fetchQuery() {
let url = this.URLs.request + this.state.searchQuery
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: <h1>Not Found</h1>
})
console.log('Error submit: ', error.toString());
});
}
// Updates the internal state of the query search field.
updateQueryState(event){
this.setState({
searchQuery: event.target.value
});
}
// For checking if the enter key was pressed in the search field.
_handleQueryKeyPress(e) {
if (e.key === 'Enter') {
this.fetchQuery();
}
}
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()));
// 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();
}
printMovies(item) {
if (item != undefined) {
let a = new MovieObject(item);
return a.getElement();
}
}
handleChange(event){
this.setState({
searchQuery: event.target.value
});
}
render(){
return(
<div>
<input
type="text"
onKeyPress={(event) => this._handleKeyPress(event)}
onChange={event => this.handleChange(event)}
onKeyPress={(event) => this._handleQueryKeyPress(event)}
onChange={event => this.updateQueryState(event)}
value={this.state.searchQuery}
/>
<button onClick={() => this.fetchQuery()}>Search</button>
<br></br>
{this.state.searchQuery}
<br></br>
{this.state.items.map((item) => this.printMovies(item))}
<span id='requestMovieList' ref='requestMovieList'>
{this.state.responseMovieList}
</span>
</div>
)
}

View File

@@ -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"

57
seasonMover.py Executable file
View File

@@ -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)

View File

@@ -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;

View File

@@ -36,7 +36,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'));

View File

@@ -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;

View File

@@ -1,4 +1,3 @@
const configuration = require('src/config/configuration').getInstance();
const StrayRepository = require('src/seasoned/strayRepository');
const strayRepository = new StrayRepository();