diff --git a/.gitignore b/.gitignore index cef87b5..5810b5e 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,3 @@ yarn-error.log* .idea/ .vs/ db.json - diff --git a/apikey b/apikey index 8b9e5dd..e6651d2 100644 --- a/apikey +++ b/apikey @@ -1 +1 @@ -AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig \ No newline at end of file +'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' \ No newline at end of file diff --git a/db.json b/db.json deleted file mode 100644 index f91564c..0000000 --- a/db.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "videos": [ - { - "id": "cu3K1njbYqs", - "timesWatched": 1, - "lastWatched": "2018-12-02T20:43:18.202Z" - }, - { - "id": "PoSbnAFvqfA", - "timesWatched": 1, - "lastWatched": "2018-12-02T20:43:24.851Z" - }, - { - "id": "rzeLynj1GYM", - "timesWatched": 2, - "lastWatched": "2018-12-02T20:43:45.916Z" - }, - { - "id": "0J2QdDbelmY", - "timesWatched": 2, - "lastWatched": "2019-01-09T15:11:09.976Z" - }, - { - "id": "unRjK82bDLw", - "timesWatched": 2, - "lastWatched": "2018-12-02T20:49:50.769Z" - }, - { - "id": "g2N0TkfrQhY", - "timesWatched": 1, - "lastWatched": "2018-12-02T20:52:07.780Z" - }, - { - "id": "EM4vblG6BVQ", - "timesWatched": 1, - "lastWatched": "2018-12-02T20:52:43.282Z" - }, - { - "id": "tPwqOWK6EFw", - "timesWatched": 1, - "lastWatched": "2018-12-02T20:53:26.049Z" - } - ] -} \ No newline at end of file diff --git a/dev.js b/dev.js new file mode 100644 index 0000000..b607da5 --- /dev/null +++ b/dev.js @@ -0,0 +1,87 @@ +process.env['NODE_ENV'] = 'production'; +const express = require('express'); +const compression = require('compression') +const bodyParser = require('body-parser'); +const low = require('lowdb'); +const lodashId = require('lodash-id'); +const FileAsync = require('lowdb/adapters/FileAsync'); +const app = express(); // app is an instance of express + +app.use(compression()); // enables gzip compression +app.use(bodyParser.urlencoded({ extended: false })) // parse application/x-www-form-urlencoded +app.use(bodyParser.json()) // parse application/json + + +// Create database instance and start server +// const adapter = new FileAsync(__dirname + '/db.json'); +low(new FileAsync(__dirname + '/db.json')) // production + .then(db => { + db._.mixin(lodashId); + // DATABASE ROUTES + + // ============== + + app.post('/test', (req, res) => { + // "reason": { + // "fitali": req.body.reason.toString() === "fvitali" ? 1:0, + // "": req.body.reason.toString() === "" ? 1:0, + // "": req.body.reason.toString() === "" ? 1:0, + // } + // try { + // let test = table.updateById(req.body.id, { }) + // } + // catch(e) { + // } + res.send(req.body); + }); + + // ============== + + // GET /globpop + app.get('/globpop', (req, res) => { + req.query.id ? res.send(req.query.id) : res.status(400).send('Bad Request'); + }); + + // OPTIONS /videotrack + app.options('/videotrack', (req, res) => { + res.set({ + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type', + 'Access-Control-Max-Age': 600 + }) + res.status(200).end(); + }) + + // GET /videotrack + app.get('/videotrack', (req, res) => { + const videos = db.get('videos'); + req.query.id ? res.send(videos.getById(req.query.id).value()) : res.send(videos.value()) + }); + + // POST /videotrack + app.post('/videotrack', (req, res) => { + const videos = db.get('videos'); + const row = videos.getById(req.body.id); + if (row.value()) { + row + .update('timesWatched', (n) => ++n) + .update('lastWatched', () => new Date().toISOString()) + .write() + .then(output => res.send(output)) + } else { + let newRow = { + "id": req.body.id.toString(), + "timesWatched": 1, + "lastWatched": new Date().toISOString(), + } + videos.push(newRow).last().write().then(output => res.send(output)) + } + }); + + // Set db default values + return db.defaults({ videos: [] }).write(); + }) + .then(() => { + app.listen(8000, () => console.log('listen on 8000')); // bind to port 8000 as required from specs + }); diff --git a/node-entry.js b/node-entry.js index 8e18cbd..a63b013 100644 --- a/node-entry.js +++ b/node-entry.js @@ -1,5 +1,5 @@ process.env['NODE_ENV'] = 'production'; -process.env.APIKEY = 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig'; +//'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' = 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig'; const express = require('express'); const compression = require('compression') const bodyParser = require('body-parser'); @@ -13,8 +13,8 @@ app.use(bodyParser.urlencoded({ extended: false })) // parse application/x-www-f app.use(bodyParser.json()) // parse application/json -app.get('/a', (req, res) => { -res.send(process.env); +app.get('/a', (req, res) => { + res.send(process.env); }); @@ -26,14 +26,14 @@ low(new FileAsync(__dirname + '/db.json')) // production db._.mixin(lodashId); // DATABASE ROUTES -// ============== + // ============== - app.post('/test',(req,res)=>{ - // "reason": { - // "fitali": req.body.reason.toString() === "fvitali" ? 1:0, - // "": req.body.reason.toString() === "" ? 1:0, - // "": req.body.reason.toString() === "" ? 1:0, - // } + app.post('/test', (req, res) => { + // "reason": { + // "fitali": req.body.reason.toString() === "fvitali" ? 1:0, + // "": req.body.reason.toString() === "" ? 1:0, + // "": req.body.reason.toString() === "" ? 1:0, + // } // try { // let test = table.updateById(req.body.id, { }) // } @@ -42,39 +42,50 @@ low(new FileAsync(__dirname + '/db.json')) // production res.send(req.body); }); -// ============== + // ============== - // GET /videotrack/:id? + // GET /globpop app.get('/globpop', (req, res) => { - req.query.id ? res.send(req.query.id):res.status(400).send('Bad Request'); + req.query.id ? res.send(req.query.id) : res.status(400).send('Bad Request'); }); - // GET /videotrack/:id? - app.get('/videotrack/:id?', (req, res) => { + // OPTIONS /videotrack + app.options('/videotrack', (req, res) => { + res.set({ + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type', + 'Access-Control-Max-Age': 600 + }) + res.status(200).end(); + }) + + // GET /videotrack + app.get('/videotrack', (req, res) => { const videos = db.get('videos'); - req.params.id ? res.send(videos.getById(req.params.id).value()) : res.send(videos.value()) + req.query.id ? res.send(videos.getById(req.query.id).value()) : res.send(videos.value()) }); // POST /videotrack app.post('/videotrack', (req, res) => { - const videos = db.get('videos'); - const row = videos.getById(req.body.id); - if(row.value()) { + const videos = db.get('videos'); + const row = videos.getById(req.body.id); + if (row.value()) { row - .update('timesWatched',(n) => ++n) - .update('lastWatched',() => new Date().toISOString()) - .write() - .then(output => res.send(output)) + .update('timesWatched', (n) => ++n) + .update('lastWatched', () => new Date().toISOString()) + .write() + .then(output => res.send(output)) } else { let newRow = { - "id": req.body.id.toString(), + "id": req.body.id.toString(), "timesWatched": 1, "lastWatched": new Date().toISOString(), } videos.push(newRow).last().write().then(output => res.send(output)) } }); - + // Set db default values return db.defaults({ videos: [] }).write(); }) diff --git a/package-lock.json b/npm-shrinkwrap.json similarity index 99% rename from package-lock.json rename to npm-shrinkwrap.json index 407fd8f..dbd093e 100644 --- a/package-lock.json +++ b/npm-shrinkwrap.json @@ -5879,11 +5879,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5896,15 +5898,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -6007,7 +6012,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -6017,6 +6023,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6029,17 +6036,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -6056,6 +6066,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -6128,7 +6139,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -6138,6 +6150,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -6243,6 +6256,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/package.json b/package.json index b33d307..17161fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hazetv-alfatube-1", - "version": "0.1.0", + "version": "0.1.1", "private": true, "dependencies": { "@c0b41/ytclear": "^1.0.0", diff --git a/src/App.js b/src/App.js index 021c2d6..85810b4 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,5 @@ import React from 'react'; import { Route, Switch, withRouter, matchPath } from 'react-router-dom'; -import 'bootstrap/dist/css/bootstrap.css'; import { Row, Col, Button, Collapse } from 'react-bootstrap'; import TopBar from './TopBar'; import VideoPlayer from './VideoPlayer'; @@ -20,52 +19,53 @@ class App extends React.Component { videoId: localStorage['lastId'] }; -// componentDidMount(){ + // componentDidMount() { -// } + // } -// componentDidUpdate(prevProps, prevState) { - -// } + // componentDidUpdate(prevProps, prevState) { -static getDerivedStateFromProps(nextProps, prevState) { - let idMatch = matchPath(nextProps.location.pathname, { - path: "/video/:id", - exact: true, - strict: false - }); - if(idMatch && idMatch.params.id !== prevState.videoId){ - localStorage.setItem('lastId', idMatch.params.id) - return {videoId: idMatch.params.id }; + // } + + static getDerivedStateFromProps(nextProps, prevState) { + let idMatch = matchPath(nextProps.location.pathname, { + path: "/video/:id", + exact: true, + strict: false + }); + if (idMatch && idMatch.params.id !== prevState.videoId) { + localStorage.setItem('lastId', idMatch.params.id) + return { videoId: idMatch.params.id }; } - return null; -} + return null; + } render() { return ( - { this.setState({ navHeight: height }); }}> + - - this.setState({ blackbgHeight: height })} className="row upperSection p-2 px-5" > + + - this.setState({ playerHeight: height })}> - + { this.setState({ playerHeight: height }) }}> + -
+ className="p-0 p-xs-0" + style={window.innerWidth < 992 ? { 'overflow': "auto", 'display': 'fixed', 'maxHeight': this.state.playerHeight * 1.4 + 'px' } : { 'overflow': "auto", 'maxHeight': `${this.state.playerHeight}px` }}> + {/* true = style for xs ;; false = style for lg */} +
- + } />
- - + + - + +
URL not found
} />
diff --git a/src/VideoInfo.js b/src/VideoInfo.js index 64c9b9b..6ed6231 100644 --- a/src/VideoInfo.js +++ b/src/VideoInfo.js @@ -1,15 +1,12 @@ import React from 'react'; import Wikipedia from './areainfo/Wikipedia'; -import { Tabs, Tab } from 'react-bootstrap'; -import {Link, withRouter} from 'react-router-dom'; +import { Card, Tabs, Tab } from 'react-bootstrap'; +import {Link} from 'react-router-dom'; import axios from 'axios'; import Linkify from "react-linkify"; -import Card from "react-bootstrap/lib/Card"; import moment from 'moment'; import momentDurationFormat from 'moment-duration-format'; //eslint-disable-line no-unused-vars import './css/VideoInfo.scss'; - - const ytclear = require('@c0b41/ytclear'); class VideoInfo extends React.Component { @@ -31,88 +28,26 @@ class VideoInfo extends React.Component { return moment(a, moment.ISO_8601).format('ddd, DD/MM/YYYY hh:mm:ss'); } - isArtistOrTitle(a){ - // switch(parseInt(b)){ - // case 1: - - // break; - // case 2: - - // break; - // default: - // break; - // } - axios.all([ - axios.get("https://musicbrainz.org/ws/2/work", { - params: { - query: `work:${a[0]} AND artist:${a[1]}`, - //artist: a[1], - fmt: "json", - limit: 1, - inc: "aliases" - }}), - axios.get("https://musicbrainz.org/ws/2/work", { - params: { - query: `work:${a[1]} AND artist:${a[0]}`, - // artist: a[0], - fmt: "json", - limit: 1, - inc: "aliases" - }}) - ]) - .then(axios.spread((response1, response2) => { - console.log(response1.data, response2.data); - axios.all([ - axios.get(`https://musicbrainz.org/ws/2/work/${response1.data.works[0].id}`,{ - params:{ - fmt:'json', - limit:1, - inc: 'aliases' - } - }), - axios.get(`https://musicbrainz.org/ws/2/work/${response2.data.works[0].id}`,{ - params:{ - fmt:'json', - limit:1, - inc: 'recording-rels' - } - }), - ]).then(axios.spread((responseA1,responseA2)=>{ - console.log(responseA1.data, responseA2.data); - - })) - }), - error => { } - ); - } - - - getInfoComments() { return axios.all([ axios.get('https://www.googleapis.com/youtube/v3/videos', { //Richiesta per tutte le info sul video params: { 'part': 'snippet,contentDetails,statistics,topicDetails', - 'id': this.state.videoId, - 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // process.env.APIKEY in production + 'id': this.props.videoId, + 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production } }), axios.get('https://www.googleapis.com/youtube/v3/commentThreads', { //Richiesta per ottenere i commenti del video params: { 'part': 'snippet', - 'videoId': this.state.videoId, + 'videoId': this.props.videoId, 'order': 'relevance', - 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // process.env.APIKEY in production + 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production } })]) .then(axios.spread((videosResponse, commentThreadResponse) => { - this.isArtistOrTitle(ytclear(videosResponse.data.items[0].snippet.title).split('-')); this.setState({ VideoDetails: videosResponse.data.items[0], comments: commentThreadResponse.data.items, - others: { - artist: null, - title: videosResponse.data.items[0].snippet.title - }, isLoaded: true }); }), error => { @@ -124,19 +59,16 @@ class VideoInfo extends React.Component { }); } - static getDerivedStateFromProps(nextProps, prevState) { - if(nextProps.videoId !== prevState.videoId) - return { videoId: nextProps.videoId }; - return null; - } + // static getDerivedStateFromProps(nextProps, prevState) { + + // } componentDidMount() { this.getInfoComments(); } - componentDidUpdate(prevProps, prevState, snapshot) { - if(prevState.videoId !== this.state.videoId) - this.getInfoComments(); - } + // componentDidUpdate(prevProps, prevState, snapshot) { + + // } // shouldComponentUpdate(nextProps, nextState) { // } @@ -157,7 +89,7 @@ class VideoInfo extends React.Component { } else { return ( - {VideoDetails.snippet.title} + {VideoDetails.snippet.title}

@@ -166,11 +98,9 @@ class VideoInfo extends React.Component { Channel name: {VideoDetails.snippet.channelTitle}
Description: {VideoDetails.snippet.description}
Tags: {VideoDetails.snippet.tags ? - VideoDetails.snippet.tags.map(tag => ( {tag} )) : ""} + VideoDetails.snippet.tags.map((tag,i) => + ( {tag}{" "} )) + : ""}

@@ -203,13 +133,16 @@ class VideoInfo extends React.Component { })} - /* Insert code here */ + {/* Insert code here */}
@@ -217,10 +150,6 @@ class VideoInfo extends React.Component { ); } } - } -VideoInfo.propTypes = { -}; - -export default withRouter(VideoInfo); +export default VideoInfo; diff --git a/src/VideoList.js b/src/VideoList.js index 05e7f7c..5915df4 100644 --- a/src/VideoList.js +++ b/src/VideoList.js @@ -2,26 +2,28 @@ import React from 'react'; import { Col, ListGroup, Card, CardDeck } from 'react-bootstrap'; // eslint-disable-line no-unused-vars import axios from 'axios'; // eslint-disable-line no-unused-vars import { Link } from 'react-router-dom'; // eslint-disable-line no-unused-vars -import './css/VideoList.css'; /*eslint no-console: ["error", { allow: ["warn", "error", "info"] }] */ class VideoList extends React.Component { - constructor(props) { - super(props); - this.state = { + state = { error: null, isLoaded: false, items: [], headers: null }; - this.getThumbnails = this.getThumbnails.bind(this); - } + componentDidMount() { + localStorage['fixedVideoList'] ? + this.setState({ + items: this.shuffleArray(JSON.parse(localStorage.getItem('fixedVideoList'))), + isLoaded: true + }) : axios.get('http://site1825.tw.cs.unibo.it/video.json').then( response => { this.shuffleArray(response.data); - this.getThumbnails(response.data); + this.getThumbnails(response.data) + .then(videoList => localStorage.setItem('fixedVideoList',JSON.stringify(videoList))); }, // Note: it's important to handle errors here // instead of a catch() block so that we don't swallow @@ -33,21 +35,21 @@ class VideoList extends React.Component { error }); } - ); + ) } // METODI getThumbnails(videoItems) { let idToLookFor = videoItems.map(item => item.videoID); let finalChunk = (videoItems.length % 50) + 100; - axios + return axios .all([ // chain 3 parallel get axios.get('https://www.googleapis.com/youtube/v3/videos', { params: { part: 'snippet', id: idToLookFor.slice(0, 50).toString(), - key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // process.env.APIKEY in production + key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production fields: 'items(id,snippet/thumbnails/medium)' } }), @@ -56,7 +58,7 @@ class VideoList extends React.Component { params: { part: 'snippet', id: idToLookFor.slice(50, 100).toString(), - key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // process.env.APIKEY in production + key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production fields: 'items(id,snippet/thumbnails/medium)' } }), @@ -65,46 +67,45 @@ class VideoList extends React.Component { params: { part: 'snippet', id: idToLookFor.slice(100, finalChunk).toString(), - key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // process.env.APIKEY in production + key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production fields: 'items(id,snippet/thumbnails/medium)' } }) ]) .then( axios.spread((res1, res2, res3) => { - let allres = [].concat( - res1.data.items, - res2.data.items, - res3.data.items - ); - allres.map(resCurrentValue => { + [...res1.data.items,...res2.data.items,...res3.data.items] + .map(resCurrentValue => Object.defineProperty( videoItems.find(videoItem => { return videoItem.videoID === resCurrentValue.id; }), 'thumbnail', - { value: resCurrentValue.snippet.thumbnails.medium.url } - ); - }); + { value: resCurrentValue.snippet.thumbnails.medium.url, + enumerable: true } + ) + ); this.setState({ isLoaded: true, items: videoItems }); + return new Promise((resolve, reject) => resolve(videoItems)) }) - ); + ) } - shuffleArray(videoarray) { - for (let i = videoarray.length - 1; i > 0; i--) { + shuffleArray(videoArray) { + for (let i = videoArray.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); - [videoarray[i], videoarray[j]] = [videoarray[j], videoarray[i]]; // eslint-disable-line no-param-reassign + [videoArray[i], videoArray[j]] = [videoArray[j], videoArray[i]]; // eslint-disable-line no-param-reassign } + return videoArray // Durstenfeld shuffle. // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm } render() { - const { error, isLoaded, items, headers } = this.state; + const { error, isLoaded, items } = this.state; if (error) { return ( @@ -126,12 +127,12 @@ class VideoList extends React.Component { {/* {item.artist} - {item.title} {item.videoID} {item.category} */} { // post request to local db axios - .post('http://localhost:8000/videotrack', { + .post('http://site1854.tw.cs.unibo.it/videotrack', { id: videoIdWatched.toString() }) .then( response => console.info(response.data), - error => console.info(error, videoIdWatched.toString()) + error => console.error(error, videoIdWatched.toString()) ); // local storage logic for recent reccomender//tmp รจ il video che devo inserire sulla lista let tmp = JSON.parse(localStorage.getItem('lastWatched')) diff --git a/src/areainfo/Suggestion.js b/src/areainfo/Suggestion.js index 87335e1..926b7e5 100644 --- a/src/areainfo/Suggestion.js +++ b/src/areainfo/Suggestion.js @@ -1,11 +1,12 @@ import React, { Component } from 'react'; -import { Row, Col, Button, Collapse } from 'react-bootstrap'; +import { Row } from 'react-bootstrap'; import { Switch, Route } from 'react-router'; import Random from '../reccomenders/Random'; import Related from '../reccomenders/Related'; import Search from '../reccomenders/Search'; import fvitali from '../reccomenders/fvitali'; import popGlobaleAssoluta from '../reccomenders/popGlobaleAssoluta'; +import Recent from '../reccomenders/Recent'; // and so on.. @@ -40,6 +41,8 @@ class Suggestion extends Component { + + {/* lasciare questo per ultimo */} diff --git a/src/areainfo/Wikipedia.js b/src/areainfo/Wikipedia.js index d24b094..76388a1 100644 --- a/src/areainfo/Wikipedia.js +++ b/src/areainfo/Wikipedia.js @@ -17,7 +17,9 @@ class Wikipedia extends Component { isWikiLoaded: false, isWDataLoaded: false, isMBLoaded: false, - isLoaded: false + isLoaded: false, + wikidatakeys: null, + wikipediakeys: null }; ISO_8601toYYYY(a) { @@ -50,21 +52,39 @@ class Wikipedia extends Component { wikipediakeys: Object.keys(wikipediaRes[0].general), isWikiLoaded: true })) + else{ console.info('called here') + this.findWikiPage();} + }, error => console.error(error)) - // .then(() => { - // console.log(this.state.wikidata) - // .then(() => console.log(this.state.wikipedia)); - // }); + } + + findWikiPage = () => { + let wikiquery = `${'undefined' === typeof this.props.title ? this.props.title2.trim() : this.props.title.trim()} (${'undefined' === typeof this.props.artist ? this.props.artist2.trim() : this.props.artist.trim()} song)`; + console.info(wikiquery) + return wikijs() + .find(wikiquery) + .then(res => { + console.info(res,'a'); + return Promise.all([res.fullInfo(), res.summary()]); + }) // find by props.title (props.artist song) + .then(wikipediaRes => this.setState({ + wikipedia: { + "desc": wikipediaRes[1], + "info": wikipediaRes[0].general + }, + wikipediakeys: Object.keys(wikipediaRes[0].general), + isWikiLoaded: true + })) } wrapper() { const musicbrainzBaseUrl = "https://musicbrainz.org/ws/2"; // more readable - return axios.get(wdk.getReverseClaims('P1651', this.state.props.videoId)) // P1651 is youtube_video_id property + return axios.get(wdk.getReverseClaims('P1651', this.props.videoId)) // P1651 is youtube_video_id property .then(wikidataP1651Res => { if (wikidataP1651Res.data.results.bindings.length) { // got a match this.getWikidataPage(wdk.simplify.sparqlResults(wikidataP1651Res.data))// set in state wikidata .then(() => { - if (this.state.wikidata.claims.P435) { + if (this.state.wikidata.claims.P435) { // p435 == musicbrainzWorkId axios.get(`${musicbrainzBaseUrl}/work/${this.state.wikidata.claims.P435[0].mainsnak.datavalue.value}`, { // get musicbrainz info params: { 'inc': 'artist-rels url-rels', @@ -73,9 +93,9 @@ class Wikipedia extends Component { 'fmt': 'json' } }).then( - musicbrainzRes1 => + musicbrainzRes1 => this.setState({ musicbrainz: musicbrainzRes1.data, isMBLoaded: true }) - ); + ); } else {//oof P435 not found in wikidata axios.get(`${musicbrainzBaseUrl}/work`, { // search on mb by wikidata title @@ -97,7 +117,7 @@ class Wikipedia extends Component { .then( (musicbrainzWorkRes2) => this.setState({ musicbrainz: musicbrainzWorkRes2.data, isMBLoaded: true }) - ); + ); }); } }); @@ -105,7 +125,7 @@ class Wikipedia extends Component { else { //oof axios.get(`${musicbrainzBaseUrl}/work`, { params: { - 'query': this.state.props.title.trim(), + 'query': 'undefined' === typeof this.props.title ? this.props.title2 : this.props.title, 'limit': 1, 'offset': 0, 'fmt': 'json' @@ -122,44 +142,31 @@ class Wikipedia extends Component { }) ]).then( axios.spread((wikidataP435Res, musicbrainzWorkRes) => { - this.setState({ musicbrainz: musicbrainzWorkRes.data, isMBLoaded: true }); + this.setState({ + musicbrainz: musicbrainzWorkRes.data, + isMBLoaded: true + }); if (wikidataP435Res.data.results.bindings.length) // found a match this.getWikidataPage(wdk.simplify.sparqlResults(wikidataP435Res.data)); // set the result in the state else if (musicbrainzWorkRes.data.relations.find(currentRel => currentRel.type === "wikidata")) { // found wikidata on music brainz - let a = musicbrainzWorkRes.data.relations.find(currentRel => currentRel.type === "wikidata"); + let wikidataUrl = musicbrainzWorkRes.data.relations.find(currentRel => currentRel.type === "wikidata"); let wikidataEntityRegEx = new RegExp("[^/]+$"); // match last part of url https://regex101.com/r/0wCQHY/1 - this.getWikidataPage(wikidataEntityRegEx.exec(a.url.resource)) //.then(() => this.setState({ isWikiLoaded: true })); + this.getWikidataPage(wikidataEntityRegEx.exec(wikidataUrl.url.resource)) //.then(() => this.setState({ isWikiLoaded: true })); } else { // oof - wikijs().find(this.state.props.title).then(data => console.log('asd', data)) // find by props.title + this.findWikiPage() } }) ) }) } + return new Promise((resolve, reject) => resolve('ok')); }); } - static getDerivedStateFromProps(nextProps, prevState) { - if (prevState.props.videoId !== nextProps.videoId) - return { - props: { - videoId: nextProps.videoId, - artist: nextProps.artist, - title: nextProps.title - }, - isWikiLoaded: false, - isWDataLoaded: false, - isMBLoaded: false, - isLoaded: false - }; - return null - } - - componentDidMount() { - this.wrapper().then(()=>this.setState({isLoaded: true})); + this.wrapper().then(() => this.setState({ isLoaded: true })); } @@ -167,10 +174,9 @@ class Wikipedia extends Component { // } - componentDidUpdate(prevProps, prevState) { - if (prevState.props.videoId !== this.state.props.videoId) - this.wrapper().then(()=>this.setState({isLoaded: true})); - } + // componentDidUpdate(prevProps, prevState) { + + // } // componentWillUnmount() { @@ -185,19 +191,19 @@ class Wikipedia extends Component { return Loading...; } else { return ( - +
- { isWikiLoaded && + {isWikiLoaded && this.state.wikipediakeys.map(key => ( - + )) } - { isWDataLoaded && + {isWDataLoaded && this.state.wikidatakeys.map(key => ( - + )) } - { isMBLoaded && - musicbrainz.relations.map(relation => { + {isMBLoaded && + musicbrainz.relations.map((relation, i) => { if (relation["target-type"] === "artist") - return ( + return (); else if (relation["target-type"] === "url") - return ( + return () diff --git a/src/css/App.css b/src/css/App.css index 34f1e8e..d3b6c81 100644 --- a/src/css/App.css +++ b/src/css/App.css @@ -1,5 +1,6 @@ .upperSection{ background-color:#000000; + display: fixed; } .downSection{ diff --git a/src/index.js b/src/index.js index caf9c23..f8df9c0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,4 @@ +import 'bootstrap/dist/css/bootstrap.css'; import 'react-app-polyfill/ie9'; //import '@babel/polyfill'; import React from 'react'; @@ -5,8 +6,9 @@ import ReactDOM from 'react-dom'; import App from './App'; import registerServiceWorker from './registerServiceWorker'; import { HashRouter, BrowserRouter } from 'react-router-dom'; // eslint-disable-line + localStorage['lastWatched'] ? function (){}() : localStorage.setItem('lastWatched', JSON.stringify([])) localStorage['lastId'] ? function (){}() : localStorage.setItem('lastId','0J2QdDbelmY') -ReactDOM.render(, document.getElementById('root')); +ReactDOM.render(, document.getElementById('root')); registerServiceWorker(); diff --git a/src/reccomenders/Random.js b/src/reccomenders/Random.js index 9412adf..ff0a854 100644 --- a/src/reccomenders/Random.js +++ b/src/reccomenders/Random.js @@ -31,7 +31,7 @@ class RecommenderRandom extends Component{ 'type' : 'video', //che contiene tutti i generi di musica 'maxResults': '21', 'pageToken' : pageToken, - 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // process.env.APIKEY in production + 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' } }).then( response => { diff --git a/src/reccomenders/Recent.js b/src/reccomenders/Recent.js index e69de29..331c5c8 100644 --- a/src/reccomenders/Recent.js +++ b/src/reccomenders/Recent.js @@ -0,0 +1,147 @@ +//http://site1825.tw.cs.unibo.it/TW/globpop fvitali +//http://site1825.tw.cs.unibo.it/video.json originale videolist + +import React from 'react'; +import { Col, ListGroup, Card, CardDeck } from 'react-bootstrap'; // eslint-disable-line no-unused-vars +import axios from 'axios'; // eslint-disable-line no-unused-vars +import { Link } from 'react-router-dom'; // eslint-disable-line no-unused-vars +/*eslint no-console: ["error", { allow: ["warn", "error", "info"] }] */ +import moment from "moment"; + +class Recent extends React.Component { + state = { + error: null, + isLoaded: false, + items: [], + headers: null + }; + + ISO_8601parse(a) { + return moment(a, moment.ISO_8601).format('ddd, DD/MM/YYYY hh:mm:ss'); + } + + componentDidMount() { + // axios.get('http://site1825.tw.cs.unibo.it/TW/globpop', { + // 'params':{ + // 'id':this.props.id + // } + // }).then( + // response => { + // //this.shuffleArray(response.data); + // console.info ('a',response.data); + this.getThumbnailsNames(JSON.parse(localStorage.getItem('lastWatched'))); + // console.info(response.data.recommended); + // // this.setState({ + // // isLoaded: true, + // // items:response.data.recommended, + // // }); + + // }, + // // Note: it's important to handle errors here + // // instead of a catch() block so that we don't swallow + // // exceptions from actual bugs in components. + // error => { + // console.error(error); + // this.setState({ + // isLoaded: true, + // error + // }); + // } + // ); + } + + // METODI + getThumbnailsNames(recentVideoList) { + let idToLookFor = recentVideoList.map(item => item.id); + axios.get('https://www.googleapis.com/youtube/v3/videos', { + params: { + part: 'snippet', + id: idToLookFor.toString(), + key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', + fields: 'items(id,snippet/thumbnails/medium,snippet/title)' + } + }) + + .then( + res1 => { + res1.data.items.map(resCurrentValue => + Object.defineProperties( + recentVideoList.find(videoItem => { + return videoItem.id === resCurrentValue.id; + }), + { + 'thumbnail': + { value: resCurrentValue.snippet.thumbnails.medium.url }, + 'name': + { value: resCurrentValue.snippet.title } + }) + ); + this.setState({ + isLoaded: true, + items: recentVideoList + }); + }) + } + + + + /*shuffleArray(videoarray) { + for (let i = videoarray.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [videoarray[i], videoarray[j]] = [videoarray[j], videoarray[i]]; // eslint-disable-line no-param-reassign + } + // Durstenfeld shuffle. + // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + }*/ + + render() { + const recentVideoList = JSON.parse(localStorage.getItem('lastWatched')) + const { error, isLoaded, items } = this.state; + if (error) { + return ( + + Error: {error.message} -- Cannot get {error.config.url} + + ); + } else if (!isLoaded) { + return ( + + +

Loading...

+ + + ); + } else { + return ( + + {items.map(item => ( + + + + + + + {item.name}
+ {item.lastSelected} +
+
+ +
+ + ))} + + ); + } + } +} + + + +export default Recent; \ No newline at end of file diff --git a/src/reccomenders/Related.js b/src/reccomenders/Related.js index 17305cf..88b8082 100644 --- a/src/reccomenders/Related.js +++ b/src/reccomenders/Related.js @@ -33,7 +33,7 @@ class Related extends Component { 'relatedToVideoId' : this.state.videoId, 'type' : 'video', 'maxResults' : '21', - 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // process.env.APIKEY in production + 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' } }).then( response => { diff --git a/src/reccomenders/Search.js b/src/reccomenders/Search.js index 0fd41bc..eb7ab69 100644 --- a/src/reccomenders/Search.js +++ b/src/reccomenders/Search.js @@ -1,21 +1,45 @@ import React from 'react'; import axios from 'axios'; +import { Link } from 'react-router-dom'; +import { Card, Col } from 'react-bootstrap'; class Search extends React.Component { state = { query: '', + isLoaded: false, + error: null, res: null } - static getDerivedStateFromProps(nextProps, prevState) { - if (nextProps.match.params.query !== prevState.query) - return { query: nextProps.match.params.query }; - return null; - } + // static getDerivedStateFromProps(nextProps, prevState) { + // if (nextProps.match.params.query !== prevState.query) + // return { query: nextProps.match.params.query }; + // return null; + // } componentDidMount() { console.log('called didmo'); + if (new RegExp("[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]").test(this.props.match.params.query.toString())) + axios.get('https://www.googleapis.com/youtube/v3/videos', { + params: { + 'part': 'id', + 'id': this.props.match.params.query, + 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', + 'field': 'pageInfo/resultsPerPage' + } + }).then( + res => { + res.data.pageInfo.resultsPerPage ? + this.props.history.push('/video/' + this.props.match.params.query) : + this.youtubeSearch() + }, + error => { + console.error(error) + } + ) + else + this.youtubeSearch(); } // shouldComponentUpdate(nextProps, nextState) { @@ -24,26 +48,30 @@ class Search extends React.Component { componentDidUpdate(prevProps, prevState) { console.log('called didup'); - if(new RegExp("[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]").test(this.state.query.toString())) - axios.get('https://www.googleapis.com/youtube/v3/videos',{ - params: { - 'part':'id', - 'id': this.state.query, - 'key': process.env.APIKEY ? process.env.APIKEY : 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', - 'field': 'pageInfo/resultsPerPage' - } - }).then( - res => { - res.data.pageInfo.resultsPerPage ? - this.props.history.push('/video/' + this.state.query) : - this.youtubeSearch() - }, - error => { - console.error(error) - } - ) - else - this.youtubeSearch(); + if (prevProps.match.params.query !== this.props.match.params.query) + if (new RegExp("[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]").test(this.props.match.params.query.toString())) + axios.get('https://www.googleapis.com/youtube/v3/videos', { + params: { + 'part': 'id', + 'id': this.props.match.params.query, + 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', + 'field': 'pageInfo/resultsPerPage' + } + }).then( + res => { + res.data.pageInfo.resultsPerPage ? + this.props.history.push('/video/' + this.props.match.params.query) : + this.youtubeSearch() + }, + error => { + console.error(error) + this.setState({ + error + }) + } + ) + else + this.youtubeSearch(); } // componentWillUnmount() { @@ -54,18 +82,19 @@ class Search extends React.Component { return axios.get('https://www.googleapis.com/youtube/v3/search', { params: { 'part': 'snippet', - 'q': this.state.query, + 'q': this.props.match.params.query, 'videoEmbeddable': 'true', 'type': 'video', 'maxResults': 30, 'topicId': '/m/04rlf, /m/02jjt', - 'key': process.env.APIKEY ? process.env.APIKEY : 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' + 'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' } }).then( res => { console.log(res.data); this.setState({ - res: res.data + res: res.data, + isLoaded: true }) }, error => { console.error(error) } @@ -73,11 +102,36 @@ class Search extends React.Component { } render() { - return ( -
- {this.state.query} keyword -
- ); + if (this.state.error) { + return Error: {this.state.error.message}; + } else if (!this.state.isLoaded) { + return Loading...; + } else { + return ( + + {this.state.res.items.map(item => (+ + + + + + {item.snippet.title} + + + + + + ))} + + ); + } } } diff --git a/src/reccomenders/fvitali.js b/src/reccomenders/fvitali.js index 09fa81e..bd2bf5f 100644 --- a/src/reccomenders/fvitali.js +++ b/src/reccomenders/fvitali.js @@ -64,7 +64,7 @@ class fvitali extends React.Component { .then( res1 => { - res1.data.items.map(resCurrentValue => { + res1.data.items.map(resCurrentValue => Object.defineProperties( reccomended.find(videoItem => { return videoItem.videoID === resCurrentValue.id; @@ -74,8 +74,8 @@ class fvitali extends React.Component { { value: resCurrentValue.snippet.thumbnails.medium.url }, 'name': {value: resCurrentValue.snippet.title} - }); - }); + }) + ); this.setState({ isLoaded: true, items: reccomended @@ -95,8 +95,7 @@ class fvitali extends React.Component { }*/ render() { - const ISO_8601parse = this.ISO_8601parse; - const { error, isLoaded, items, headers } = this.state; + const { error, isLoaded, items } = this.state; if (error) { return ( @@ -115,7 +114,7 @@ class fvitali extends React.Component { return ( {items.map(item=>( - +
{key} {wikipedia.info[key].toLocaleString()}
{`${key} - ${wikidata.claims[key][0].mainsnak.datatype}`} { typeof wikidata.claims[key][0].mainsnak.datavalue.value === "string" ? @@ -211,15 +217,15 @@ class Wikipedia extends Component {
{relation.type} {relation.artist.name}
{relation.type} {relation.type}