Client/update requested #42

Merged
KevinMidboe merged 16 commits from client/update_requested into master 2017-10-20 16:13:30 +00:00
9 changed files with 238 additions and 15 deletions

View File

@@ -4,16 +4,50 @@ import requestElement from './styles/requestElementStyle.jsx'
import { getCookie } from './Cookie.jsx'; import { getCookie } from './Cookie.jsx';
class DropdownList extends React.Component {
constructor(props) {
super(props);
this.state = {
filter: ['all', 'requested', 'downloading', 'downloaded'],
sort: ['requested_date', 'name', 'status', 'requested_by', 'ip', 'user_agent'],
status: ['requested', 'downloading', 'downloaded'],
}
}
render() {
const {elementType, elementId, elementStatus, elementCallback, props} = this.props;
console.log(elementCallback('downloaded'))
switch (elementType) {
case 'status':
return (
<div>HERE</div>
)
}
return (
<div {...props}>
</div>
);
}
}
class RequestElement extends React.Component { class RequestElement extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.default_requestList = null; this.state = {
dropDownState: undefined,
}
} }
filterRequestList(requestList, filter) { filterRequestList(requestList, filter) {
if (filter === 'all') if (filter === 'all')
return requestList return requestList
if (filter === 'movie' || filter === 'show')
return requestList.filter(item => item.type === filter)
return requestList.filter(item => item.status === filter) return requestList.filter(item => item.status === filter)
} }
@@ -28,26 +62,91 @@ class RequestElement extends React.Component {
requestList.reverse(); requestList.reverse();
} }
userAgent(agent) {
if (agent) {
try {
return agent.split(" ")[1].replace(/[\(\;]/g, '');
}
catch(e) {
return agent;
}
}
return '';
}
updateDropDownState(status) {
if (status !== this.dropDownState) {
this.dropDownState = status;
}
}
ItemsStatusDropdown(id, type, status) {
return (
<div>
<select id="lang"
defaultValue={status}
onChange={event => this.updateDropDownState(event.target.value)}
>
<option value='requested'>Requested</option>
<option value='downloading'>Downloading</option>
<option value='downloaded'>Downloaded</option>
</select>
<button onClick={() => { this.updateRequestedItem(id, type)}}>Update Status</button>
</div>
)
}
updateRequestedItem(id, type) {
console.log(id, type, this.dropDownState);
Promise.resolve()
fetch('https://apollo.kevinmidboe.com/api/v1/plex/request/' + id, {
method: 'PUT',
headers: {
'Content-type': 'application/json',
'authorization': getCookie('token')
},
body: JSON.stringify({
type: type,
status: this.dropDownState,
})
})
.then(response => {
if (response.status !== 200) {
console.log('error');
}
response.json()
.then(data => {
if (data.success === true) {
console.log('UPDATED :', id, ' with ', this.dropDownState)
}
})
})
.catch(error => {
new Error(error);
})
}
createHTMLElement(data, index) { createHTMLElement(data, index) {
var posterPath = 'https://image.tmdb.org/t/p/w300' + data.image_path; var posterPath = 'https://image.tmdb.org/t/p/w300' + data.image_path;
if (data.user_agent !== null) {
var user_agent = data.user_agent.split(" ");
var agent_shortened = user_agent[1].replace(/[\(\;]/g, '')
}
return ( return (
<div style={requestElement.wrappingDiv} key={index}> <div style={requestElement.wrappingDiv} key={index}>
<img style={requestElement.requestPoster} src={posterPath}></img> <img style={requestElement.requestPoster} src={posterPath}></img>
<div style={requestElement.infoDiv}> <div style={requestElement.infoDiv}>
<span><b>Name</b>: {data.name} </span> <span><b>Name</b>: {data.name} </span><br></br>
<span><b>Year</b>: {data.year}</span><br></br> <span><b>Year</b>: {data.year}</span><br></br>
<span><b>Type</b>: {data.type}</span><br></br>
<span><b>Status</b>: {data.status}</span><br></br> <span><b>Status</b>: {data.status}</span><br></br>
<span><b>Address</b>: {data.ip}</span><br></br> <span><b>Address</b>: {data.ip}</span><br></br>
<span><b>Requested Data:</b> {data.requested_date}</span><br></br> <span><b>Requested Data:</b> {data.requested_date}</span><br></br>
<span><b>Requested By:</b> {data.requested_by}</span><br></br> <span><b>Requested By:</b> {data.requested_by}</span><br></br>
<span><b>Agent</b>: {agent_shortened}</span><br></br> <span><b>Agent</b>: { this.userAgent(data.user_agent) }</span><br></br>
</div> </div>
{ this.ItemsStatusDropdown(data.id, data.type, data.status) }
</div> </div>
) )
} }
@@ -138,6 +237,8 @@ class FetchRequested extends React.Component {
<option value="requested">Requested</option> <option value="requested">Requested</option>
<option value="downloading">Downloading</option> <option value="downloading">Downloading</option>
<option value="downloaded">Downloaded</option> <option value="downloaded">Downloaded</option>
<option value='movie'>Movies</option>
<option value='show'>Shows</option>
</select> </select>
<select id="lang" onChange={event => this.updateSort(event.target.value)} value={this.state.value}> <select id="lang" onChange={event => this.updateSort(event.target.value)} value={this.state.value}>

View File

@@ -7,6 +7,10 @@ import movieStyle from './styles/movieObjectStyle.jsx';
var MediaQuery = require('react-responsive'); var MediaQuery = require('react-responsive');
import RequestButton from './buttons/request_button.jsx';
import { fetchJSON } from './http.jsx';
class MovieObject { class MovieObject {
constructor(object) { constructor(object) {
this.id = object.id; this.id = object.id;
@@ -27,14 +31,20 @@ class MovieObject {
requestMovie() { requestMovie() {
// fetch('http://localhost:31459/api/v1/plex/request/' + this.id + '?type='+this.type, { // fetch('http://localhost:31459/api/v1/plex/request/' + this.id + '?type='+this.type, {
fetch('https://apollo.kevinmidboe.com/api/v1/plex/request/' + this.id + '?type='+this.type, { // fetch('https://apollo.kevinmidboe.com/api/v1/plex/request/' + this.id + '?type='+this.type, {
method: 'POST' // method: 'POST'
}); // });
fetchJSON('https://apollo.kevinmidboe.com/api/v1/plex/request/' + this.id + '?type='+this.type, 'POST')
.then((response) => {
console.log(response);
})
notify.show(this.title + ' requested!', 'success', 3000); notify.show(this.title + ' requested!', 'success', 3000);
} }
getElement(index) { getElement(index) {
const element_key = index + this.id;
// TODO set the poster image async by updating the dom after this is returned // TODO set the poster image async by updating the dom after this is returned
if (this.poster == null || this.poster == undefined) { if (this.poster == null || this.poster == undefined) {
var posterPath = 'https://openclipart.org/image/2400px/svg_to_png/211479/Simple-Image-Not-Found-Icon.png' var posterPath = 'https://openclipart.org/image/2400px/svg_to_png/211479/Simple-Image-Not-Found-Icon.png'
@@ -59,8 +69,9 @@ class MovieObject {
// TODO add request button class
return ( return (
<div key={index}> <div key={element_key}>
<Notifications /> <Notifications />
<div style={movieStyle.resultItem} key={this.id}> <div style={movieStyle.resultItem} key={this.id}>
<MediaQuery minWidth={600}> <MediaQuery minWidth={600}>
@@ -87,7 +98,8 @@ class MovieObject {
</MediaQuery> </MediaQuery>
<span className='imdbLogo'> <span className='imdbLogo'>
</span> </span>
<div style={movieStyle.buttons}> <div style={movieStyle.buttons}>

View File

@@ -9,6 +9,8 @@ import movieStyle from './styles/movieObjectStyle.jsx';
import URI from 'urijs'; import URI from 'urijs';
import InfiniteScroll from 'react-infinite-scroller'; import InfiniteScroll from 'react-infinite-scroller';
import { fetchJSON } from './http.jsx';
var MediaQuery = require('react-responsive'); var MediaQuery = require('react-responsive');
// TODO add option for searching multi, movies or tv shows // TODO add option for searching multi, movies or tv shows

View File

@@ -0,0 +1,22 @@
import React from 'react';
class RequestButton extends React.Component {
constructor() {
super();
this.state = {textColor: 'white'};
}
render() {
return (
<Text
style={{color: this.state.textColor}}
onEnter={() => this.setState({textColor: 'red'})}
onExit={() => this.setState({textColor: 'white'})}>
This text will turn red when you look at it.
</Text>
);
}
}
export default RequestButton;

View File

@@ -0,0 +1,52 @@
import React from 'react';
import { getCookie } from './Cookie.jsx';
// class http {
// dispatch(obj) {
// console.log(obj);
// }
function checkStatus(response) {
const hasError = (response.status < 200 || response.status >= 300)
if (hasError) {
throw response.text();
}
return response;
}
function parseJSON(response) { response.json(); }
// *
// * Retrieve search results from tmdb with added seasoned information.
// * @param {String} uri query you want to search for
// * @param {Number} page representing pagination of results
// * @returns {Promise} succeeds if results were found
// fetchSearch(uri) {
// fetch(uri, {
// method: 'GET',
// headers: {
// 'authorization': getCookie('token')
// },
// })
// .then(response => {
// });
// }
// }
// export default http;
export function fetchJSON(url, method, data) {
return fetch(url, {
method: method,
headers: new Headers({
'Content-Type': 'application/json',
'authorization': getCookie('token'),
}),
body: JSON.stringify(data)
}).then(checkStatus).then(parseJSON);
}

View File

@@ -5,6 +5,7 @@ export default {
flexDirection: 'row', flexDirection: 'row',
flexWrap: 'wrap', flexWrap: 'wrap',
flexFlow: 'row wrap', flexFlow: 'row wrap',
justifyContent: 'space-around',
}, },
wrappingDiv: { wrappingDiv: {

View File

@@ -20,8 +20,9 @@ class RequestRepository {
constructor(database) { constructor(database) {
this.database = database || establishedDatabase; this.database = database || establishedDatabase;
this.queries = { this.queries = {
'insertRequest': "INSERT INTO requests VALUES (?, ?, ?, ?, ?, ?, CURRENT_DATE, 'requested', ?)", 'insertRequest': "INSERT INTO requests VALUES (?, ?, ?, ?, ?, ?, CURRENT_DATE, 'requested', ?, ?)",
'fetchRequstedItems': "SELECT * FROM requests", 'fetchRequstedItems': "SELECT * FROM requests",
'updateRequestedById': "UPDATE requests SET status = ? WHERE id is ? AND type is ?",
} }
} }
@@ -116,7 +117,7 @@ class RequestRepository {
tmdb.lookup(identifier, type).then(movie => { tmdb.lookup(identifier, type).then(movie => {
// Add request to database // Add request to database
this.database.run(this.queries.insertRequest, [movie.id, movie.title, movie.year, movie.poster, 'NULL', ip, user_agent]) this.database.run(this.queries.insertRequest, [movie.id, movie.title, movie.year, movie.poster, 'NULL', ip, user_agent, movie.type])
// //
@@ -167,6 +168,10 @@ class RequestRepository {
return this.database.all(this.queries.fetchRequstedItems); return this.database.all(this.queries.fetchRequstedItems);
} }
updateRequestedById(id, type, status) {
return this.database.run(this.queries.updateRequestedById, [status, id, type]);
}
} }
module.exports = RequestRepository; module.exports = RequestRepository;

View File

@@ -67,7 +67,11 @@ router.get('/v1/plex/request/:mediaId', require('./controllers/plex/readRequest.
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/plex/hook', require('./controllers/plex/hookDump.js'));
/**
* Requests
*/
router.get('/v1/plex/requests/all', mustBeAuthenticated, require('./controllers/plex/fetchRequested.js')); router.get('/v1/plex/requests/all', mustBeAuthenticated, require('./controllers/plex/fetchRequested.js'));
router.put('/v1/plex/request/:requestId', mustBeAuthenticated, require('./controllers/plex/updateRequested.js'));
/** /**
* TMDB * TMDB

View File

@@ -0,0 +1,24 @@
const RequestRepository = require('src/plex/requestRepository');
const requestRepository = new RequestRepository();
/**
* Controller: Retrieves search history of a logged in user
* @param {Request} req http request variable
* @param {Response} res
* @returns {Callback}
*/
function updateRequested(req, res) {
const id = req.params.requestId;
const type = req.body.type;
const status = req.body.status;
requestRepository.updateRequestedById(id, type, status)
.then(() => {
res.send({ success: true });
})
.catch((error) => {
res.status(401).send({ success: false, error: error.message });
});
}
module.exports = updateRequested;