Client/update requested #42
@@ -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}>
|
||||||
|
|||||||
@@ -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}>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
22
client/app/components/buttons/request_button.jsx
Normal file
22
client/app/components/buttons/request_button.jsx
Normal 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;
|
||||||
52
client/app/components/http.jsx
Normal file
52
client/app/components/http.jsx
Normal 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);
|
||||||
|
}
|
||||||
@@ -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: {
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
Reference in New Issue
Block a user