2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -8,3 +8,5 @@ node_modules
 | 
			
		||||
*.pyc
 | 
			
		||||
npm-debug.log
 | 
			
		||||
webpage/js/env_variables.js
 | 
			
		||||
client/dist
 | 
			
		||||
src/webserver/access.log
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -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})
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  _handleKeyPress(e) {
 | 
			
		||||
  // Handles all errors of the response of a fetch call
 | 
			
		||||
  handleErrors(response) {
 | 
			
		||||
  	if (!response.ok) {
 | 
			
		||||
  		throw Error(response.status);
 | 
			
		||||
  	}
 | 
			
		||||
  	return response;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
								
							
							
						
						
									
										57
									
								
								seasonMover.py
									
									
									
									
									
										Executable 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)
 | 
			
		||||
@@ -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;
 | 
			
		||||
@@ -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'));
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								src/webserver/controllers/plex/submitRequest.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/webserver/controllers/plex/submitRequest.js
									
									
									
									
									
										Normal 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;
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
const configuration = require('src/config/configuration').getInstance();
 | 
			
		||||
const StrayRepository = require('src/seasoned/strayRepository');
 | 
			
		||||
const strayRepository = new StrayRepository();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user