improved tagging system
new settings page tab
This commit is contained in:
		| @@ -8,7 +8,7 @@ class Database | ||||
|     private $servername = "192.168.0.30"; | ||||
|     private $username = "root"; | ||||
|     private $password = "1qayxsw2"; | ||||
|     private $dbname = "hub"; | ||||
|     private $dbname = "mediacenter"; | ||||
|  | ||||
|     // The db connection is established in the private constructor. | ||||
|     private function __construct() | ||||
|   | ||||
| @@ -44,21 +44,21 @@ foreach ($arr as $elem) { | ||||
|                 if ($video_attributes['height'] >= 1080) { | ||||
|                     $query = "INSERT INTO video_tags(video_id,tag_id) VALUES ($last_id,2)"; | ||||
|                     if ($conn->query($query) !== TRUE) { | ||||
|                         echo "failed to add tag here.\n"; | ||||
|                         echo "failed to add default tag here.\n"; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if ($video_attributes['height'] >= 720 && $video_attributes['height'] < 1080) { | ||||
|                     $query = "INSERT INTO video_tags(video_id,tag_id) VALUES ($last_id,4)"; | ||||
|                     if ($conn->query($query) !== TRUE) { | ||||
|                         echo "failed to add tag here.\n"; | ||||
|                         echo "failed to add default tag here.\n"; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if ($video_attributes['height'] < 720) { | ||||
|                     $query = "INSERT INTO video_tags(video_id,tag_id) VALUES ($last_id,3)"; | ||||
|                     if ($conn->query($query) !== TRUE) { | ||||
|                         echo "failed to add tag here.\n"; | ||||
|                         echo "failed to add default tag here.\n"; | ||||
|                     } | ||||
|                 } | ||||
|                 $added++; | ||||
| @@ -125,19 +125,28 @@ function _get_video_attributes($video) | ||||
|     $command = "$ffmpeg -i \"../videos/prn/$video\" -vstats 2>&1"; | ||||
|     $output = shell_exec($command); | ||||
|  | ||||
|     $codec = "null"; | ||||
|     $width = 0; | ||||
|     $height = 0; | ||||
|  | ||||
|     $regex_sizes = "/Video: ([^,]*), ([^,]*), ([0-9]{1,4})x([0-9]{1,4})/"; // or : $regex_sizes = "/Video: ([^\r\n]*), ([^,]*), ([0-9]{1,4})x([0-9]{1,4})/"; (code from @1owk3y) | ||||
|     if (preg_match($regex_sizes, $output, $regs)) { | ||||
|         $codec = $regs [1] ? $regs [1] : null; | ||||
|         $width = $regs [3] ? $regs [3] : null; | ||||
|         $height = $regs [4] ? $regs [4] : null; | ||||
|         $codec = $regs [1] ? $regs [1] : "null"; | ||||
|         $width = $regs [3] ? $regs [3] : 0; | ||||
|         $height = $regs [4] ? $regs [4] : 0; | ||||
|     } | ||||
|  | ||||
|     $hours = 0; | ||||
|     $mins = 0; | ||||
|     $secs = 0; | ||||
|     $ms = 0; | ||||
|  | ||||
|     $regex_duration = "/Duration: ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}).([0-9]{1,2})/"; | ||||
|     if (preg_match($regex_duration, $output, $regs)) { | ||||
|         $hours = $regs [1] ? $regs [1] : null; | ||||
|         $mins = $regs [2] ? $regs [2] : null; | ||||
|         $secs = $regs [3] ? $regs [3] : null; | ||||
|         $ms = $regs [4] ? $regs [4] : null; | ||||
|         $hours = $regs [1] ? $regs [1] : 0; | ||||
|         $mins = $regs [2] ? $regs [2] : 0; | ||||
|         $secs = $regs [3] ? $regs [3] : 0; | ||||
|         $ms = $regs [4] ? $regs [4] : 0; | ||||
|     } | ||||
|  | ||||
|     return array('codec' => $codec, | ||||
|   | ||||
| @@ -3,7 +3,7 @@ require 'Database.php'; | ||||
|  | ||||
| $conn = Database::getInstance()->getConnection(); | ||||
|  | ||||
|  | ||||
| //$_POST['action'] = "getRandomMovies";$_POST['number'] =6; | ||||
| if (isset($_POST['action'])) { | ||||
|     $action = $_POST['action']; | ||||
|     switch ($action) { | ||||
| @@ -28,14 +28,31 @@ if (isset($_POST['action'])) { | ||||
|             echo(json_encode($rows)); | ||||
|             break; | ||||
|         case "getRandomMovies": | ||||
|             $return = new stdClass(); | ||||
|             $query = "SELECT movie_id,movie_name FROM videos ORDER BY RAND() LIMIT " . $_POST['number']; | ||||
|             $result = $conn->query($query); | ||||
|             $rows = array(); | ||||
|             $return->rows = array(); | ||||
|  | ||||
|             // get tags of random videos | ||||
|             $ids = []; | ||||
|             while ($r = mysqli_fetch_assoc($result)) { | ||||
|                 array_push($rows, $r); | ||||
|                 array_push($return->rows, $r); | ||||
|                 array_push($ids,"video_tags.video_id=".$r['movie_id']); | ||||
|             } | ||||
|  | ||||
|             echo(json_encode($rows)); | ||||
|             $idstring = implode(" OR ",$ids); | ||||
|  | ||||
|             $return->tags = array(); | ||||
|             $query = "SELECT t.tag_name FROM video_tags  | ||||
|                         INNER JOIN tags t on video_tags.tag_id = t.tag_id | ||||
|                         WHERE $idstring | ||||
|                         GROUP BY t.tag_name"; | ||||
|             $result = $conn->query($query); | ||||
|             while ($r = mysqli_fetch_assoc($result)) { | ||||
|                 array_push($return->tags, $r); | ||||
|             } | ||||
|  | ||||
|             echo(json_encode($return)); | ||||
|             break; | ||||
|         case "loadVideo": | ||||
|             $query = "SELECT movie_name,movie_url,thumbnail,likes,quality,length FROM videos WHERE movie_id='" . $_POST['movieid'] . "'"; | ||||
| @@ -50,6 +67,18 @@ if (isset($_POST['action'])) { | ||||
|             $arr["likes"] = $row["likes"]; | ||||
|             $arr["quality"] = $row["quality"]; | ||||
|             $arr["length"] = $row["length"]; | ||||
|  | ||||
|             // load tags of this video | ||||
|             $arr['tags'] = Array(); | ||||
|             $query = "SELECT t.tag_name FROM video_tags  | ||||
|                         INNER JOIN tags t on video_tags.tag_id = t.tag_id | ||||
|                         WHERE video_tags.video_id=".$_POST['movieid']." | ||||
|                         GROUP BY t.tag_name"; | ||||
|             $result = $conn->query($query); | ||||
|             while ($r = mysqli_fetch_assoc($result)) { | ||||
|                 array_push($arr['tags'], $r); | ||||
|             } | ||||
|  | ||||
|             echo(json_encode($arr)); | ||||
|  | ||||
|             break; | ||||
| @@ -77,6 +106,7 @@ if (isset($_POST['action'])) { | ||||
|  | ||||
|             break; | ||||
|         case "getTags": | ||||
|             // todo add this to loadVideo maybe | ||||
|             $movieid = $_POST['movieid']; | ||||
|  | ||||
|             $query = "SELECT tag_name FROM video_tags  | ||||
|   | ||||
| @@ -10,10 +10,12 @@ create table if not exists videos | ||||
|     movie_id    int auto_increment | ||||
|         primary key, | ||||
|     movie_name  varchar(200)                       null, | ||||
|     movie_url   varchar(200)                       null, | ||||
|     movie_url   varchar(250)                       null, | ||||
|     thumbnail   mediumblob                         null, | ||||
|     likes       int      default 0                 null, | ||||
|     create_date datetime default CURRENT_TIMESTAMP null | ||||
|     create_date datetime default CURRENT_TIMESTAMP null, | ||||
|     quality     int                                null, | ||||
|     length      int                                null comment 'in seconds' | ||||
| ); | ||||
|  | ||||
| create table if not exists video_tags | ||||
| @@ -24,4 +26,4 @@ create table if not exists video_tags | ||||
|         foreign key (tag_id) references tags (tag_id), | ||||
|     constraint video_tags_videos_movie_id_fk | ||||
|         foreign key (video_id) references videos (movie_id) | ||||
| ); | ||||
| ); | ||||
|   | ||||
							
								
								
									
										27
									
								
								src/App.js
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/App.js
									
									
									
									
									
								
							| @@ -48,19 +48,25 @@ class App extends React.Component { | ||||
|                         <li className="nav-item"> | ||||
|                             <div className="nav-link" | ||||
|                                  style={this.state.page === "default" ? {color: "rgba(255,255,255,.75"} : {}} | ||||
|                                  onClick={() => this.loadHomePage()}>Home | ||||
|                                  onClick={() => this.setState({page: "default"})}>Home | ||||
|                             </div> | ||||
|                         </li> | ||||
|                         <li className="nav-item"> | ||||
|                             <div className="nav-link" | ||||
|                                  style={this.state.page === "random" ? {color: "rgba(255,255,255,.75"} : {}} | ||||
|                                  onClick={() => this.loadRandomPage()}>Random Video | ||||
|                                  onClick={() => this.setState({page: "random"})}>Random Video | ||||
|                             </div> | ||||
|                         </li> | ||||
|                         <li className="nav-item"> | ||||
|                             <div className="nav-link" | ||||
|                                  style={this.state.page === "categories" ? {color: "rgba(255,255,255,.75"} : {}} | ||||
|                                  onClick={() => this.loadCategoriesPage()}>Categories | ||||
|                                  onClick={() => this.setState({page: "categories"})}>Categories | ||||
|                             </div> | ||||
|                         </li> | ||||
|                         <li className="nav-item"> | ||||
|                             <div className="nav-link" | ||||
|                                  style={this.state.page === "settings" ? {color: "rgba(255,255,255,.75"} : {}} | ||||
|                                  onClick={() => this.setState({page: "settings"})}>Settings | ||||
|                             </div> | ||||
|                         </li> | ||||
|                     </ul> | ||||
| @@ -70,21 +76,6 @@ class App extends React.Component { | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     loadCategoriesPage() { | ||||
|         console.log("click categories"); | ||||
|         this.setState({page: "categories"}); | ||||
|     } | ||||
|  | ||||
|     loadRandomPage() { | ||||
|         console.log("click random"); | ||||
|         this.setState({page: "random"}); | ||||
|     } | ||||
|  | ||||
|     loadHomePage() { | ||||
|         console.log("click default"); | ||||
|         this.setState({page: "default"}); | ||||
|     } | ||||
|  | ||||
|     showVideo(element) { | ||||
|         this.setState({ | ||||
|             page: "video" | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import SideBar from "./SideBar"; | ||||
|  | ||||
| import "./css/HomePage.css" | ||||
| import "./css/DefaultPage.css" | ||||
| import Tag from "./Tag"; | ||||
|  | ||||
| class HomePage extends React.Component { | ||||
|     // stores all available movies | ||||
| @@ -23,7 +24,8 @@ class HomePage extends React.Component { | ||||
|                 sdvideonr: null, | ||||
|                 tagnr: null | ||||
|             }, | ||||
|             tag: "all" | ||||
|             tag: "All", | ||||
|             selectionnr: null | ||||
|         }; | ||||
|     } | ||||
|  | ||||
| @@ -34,7 +36,12 @@ class HomePage extends React.Component { | ||||
|         this.fetchStartData(); | ||||
|     } | ||||
|  | ||||
|     // this function clears all preview elements an reloads gravity with tag | ||||
|     /** | ||||
|      * fetch available videos for specified tag | ||||
|      * this function clears all preview elements an reloads gravity with tag | ||||
|      * | ||||
|      * @param tag tag to fetch videos | ||||
|      */ | ||||
|     fetchVideoData(tag) { | ||||
|         const updateRequest = new FormData(); | ||||
|         updateRequest.append('action', 'getMovies'); | ||||
| @@ -45,7 +52,10 @@ class HomePage extends React.Component { | ||||
|             .then((response) => response.json() | ||||
|                 .then((result) => { | ||||
|                     this.data = result; | ||||
|                     this.setState({loadeditems: []}); | ||||
|                     this.setState({ | ||||
|                         loadeditems: [], | ||||
|                         selectionnr: this.data.length | ||||
|                     }); | ||||
|                     this.loadindex = 0; | ||||
|                     this.loadPreviewBlock(12); | ||||
|                 })) | ||||
| @@ -54,6 +64,9 @@ class HomePage extends React.Component { | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * fetch the necessary data for left info box | ||||
|      */ | ||||
|     fetchStartData() { | ||||
|         const updateRequest = new FormData(); | ||||
|         updateRequest.append('action', 'getStartData'); | ||||
| @@ -69,7 +82,8 @@ class HomePage extends React.Component { | ||||
|                             hdvideonr: result['hd'], | ||||
|                             sdvideonr: result['sd'], | ||||
|                             tagnr: result['tags'] | ||||
|                         }}); | ||||
|                         } | ||||
|                     }); | ||||
|                 })) | ||||
|             .catch(() => { | ||||
|                 console.log("no connection to backend"); | ||||
| @@ -86,7 +100,7 @@ class HomePage extends React.Component { | ||||
|             <div> | ||||
|                 <div className='pageheader'> | ||||
|                     <span className='pageheadertitle'>Home Page</span> | ||||
|                     <span className='pageheadersubtitle'>All Videos - {this.state.sideinfo.videonr}</span> | ||||
|                     <span className='pageheadersubtitle'>{this.state.tag} Videos - {this.state.selectionnr}</span> | ||||
|                     <hr/> | ||||
|                 </div> | ||||
|                 <SideBar> | ||||
| @@ -99,10 +113,26 @@ class HomePage extends React.Component { | ||||
|                     <div className='sidebarinfo'><b>{this.state.sideinfo.tagnr}</b> different Tags!</div> | ||||
|                     <hr/> | ||||
|                     <div className='sidebartitle'>Default Tags:</div> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("all")}>All</button> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("fullhd")}>FullHd</button> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("lowquality")}>LowQuality</button> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("hd")}>HD</button> | ||||
|                     <Tag onClick={() => { | ||||
|                         this.setState({tag: "All"}); | ||||
|                         this.fetchVideoData("all"); | ||||
|                     }}>All | ||||
|                     </Tag> | ||||
|                     <Tag onClick={() => { | ||||
|                         this.setState({tag: "Full HD"}); | ||||
|                         this.fetchVideoData("fullhd"); | ||||
|                     }}>FullHd | ||||
|                     </Tag> | ||||
|                     <Tag onClick={() => { | ||||
|                         this.setState({tag: "Low Quality"}); | ||||
|                         this.fetchVideoData("lowquality"); | ||||
|                     }}>LowQuality | ||||
|                     </Tag> | ||||
|                     <Tag onClick={() => { | ||||
|                         this.setState({tag: "HD"}); | ||||
|                         this.fetchVideoData("hd"); | ||||
|                     }}>HD | ||||
|                     </Tag> | ||||
|                 </SideBar> | ||||
|                 <div className='maincontent'> | ||||
|                     {this.state.loadeditems.map(elem => ( | ||||
|   | ||||
| @@ -2,13 +2,21 @@ import React from "react"; | ||||
| import "./css/Player.css" | ||||
| import {PlyrComponent} from 'plyr-react'; | ||||
| import SideBar from "./SideBar"; | ||||
| import Tag from "./Tag"; | ||||
|  | ||||
|  | ||||
| class Player extends React.Component { | ||||
|     constructor(props, context) { | ||||
|         super(props, context); | ||||
|  | ||||
|         this.state = {}; | ||||
|         this.state = { | ||||
|             sources: null, | ||||
|             movie_name: null, | ||||
|             likes: null, | ||||
|             quality: null, | ||||
|             length: null, | ||||
|             tags: [] | ||||
|         }; | ||||
|  | ||||
|         this.props = props; | ||||
|     } | ||||
| @@ -50,10 +58,9 @@ class Player extends React.Component { | ||||
|                     <div className='sidebarinfo'><b>{this.state.length}</b> Minutes of length!</div> | ||||
|                     <hr/> | ||||
|                     <div className='sidebartitle'>Tags:</div> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("all")}>All</button> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("fullhd")}>FullHd</button> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("lowquality")}>LowQuality</button> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("hd")}>HD</button> | ||||
|                     {this.state.tags.map((m) => ( | ||||
|                         <Tag>{m.tag_name}</Tag> | ||||
|                     ))} | ||||
|                 </SideBar> | ||||
|  | ||||
|                 <div className="videowrapper"> | ||||
| @@ -96,7 +103,8 @@ class Player extends React.Component { | ||||
|                     movie_name: result.movie_name, | ||||
|                     likes: result.likes, | ||||
|                     quality: result.quality, | ||||
|                     length: result.length | ||||
|                     length: result.length, | ||||
|                     tags: result.tags | ||||
|                 }); | ||||
|             }); | ||||
|     } | ||||
|   | ||||
| @@ -2,13 +2,15 @@ import React from "react"; | ||||
| import Preview from "./Preview"; | ||||
| import "./css/RandomPage.css" | ||||
| import SideBar from "./SideBar"; | ||||
| import Tag from "./Tag"; | ||||
|  | ||||
| class RandomPage extends React.Component { | ||||
|     constructor(props, context) { | ||||
|         super(props, context); | ||||
|  | ||||
|         this.state = { | ||||
|             videos: [] | ||||
|             videos: [], | ||||
|             tags: [] | ||||
|         }; | ||||
|     } | ||||
|  | ||||
| @@ -26,10 +28,9 @@ class RandomPage extends React.Component { | ||||
|                 </div> | ||||
|                 <SideBar> | ||||
|                     <div className='sidebartitle'>Visible Tags:</div> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("all")}>All</button> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("fullhd")}>FullHd</button> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("lowquality")}>LowQuality</button> | ||||
|                     <button className='tagbtn' onClick={() => this.fetchVideoData("hd")}>HD</button> | ||||
|                     {this.state.tags.map((m) => ( | ||||
|                         <Tag>{m.tag_name}</Tag> | ||||
|                     ))} | ||||
|                 </SideBar> | ||||
|  | ||||
|                 <div className='maincontent'> | ||||
| @@ -61,7 +62,11 @@ class RandomPage extends React.Component { | ||||
|         fetch('/api/videoload.php', {method: 'POST', body: updateRequest}) | ||||
|             .then((response) => response.json() | ||||
|                 .then((result) => { | ||||
|                     this.setState({videos: result}); | ||||
|                     console.log(result); | ||||
|                     this.setState({ | ||||
|                         videos: result.rows, | ||||
|                         tags: result.tags | ||||
|                     }); | ||||
|                 })) | ||||
|             .catch(() => { | ||||
|                 console.log("no connection to backend"); | ||||
|   | ||||
							
								
								
									
										21
									
								
								src/Tag.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/Tag.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| import React from "react"; | ||||
|  | ||||
| import "./css/Tag.css" | ||||
|  | ||||
| class Tag extends React.Component { | ||||
|  | ||||
|     constructor(props, context) { | ||||
|         super(props, context); | ||||
|  | ||||
|         this.props = props; | ||||
|     } | ||||
|  | ||||
|     render() { | ||||
|         // todo onclick events correctly | ||||
|         return ( | ||||
|             <button className='tagbtn' onClick={this.props.onClick}>{this.props.children}</button> | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export default Tag; | ||||
| @@ -9,26 +9,6 @@ | ||||
|     border: 2px #3574fe solid; | ||||
| } | ||||
|  | ||||
| .tagbtn { | ||||
|     color: white; | ||||
|     margin: 10px; | ||||
|     background-color: #3574fe; | ||||
|     border: none; | ||||
|     border-radius: 10px; | ||||
|     padding: 5px 15px 5px 15px; | ||||
|     /*font-weight: bold;*/ | ||||
|     display: block; | ||||
| } | ||||
|  | ||||
| .tagbtn:focus { | ||||
|     background-color: #004eff; | ||||
|     outline: none; | ||||
| } | ||||
|  | ||||
| .tagbtn:hover { | ||||
|     background-color: #004eff; | ||||
| } | ||||
|  | ||||
| .sidebartitle { | ||||
|     font-weight: bold; | ||||
|     font-size: larger; | ||||
|   | ||||
							
								
								
									
										19
									
								
								src/css/Tag.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/css/Tag.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| .tagbtn { | ||||
|     color: white; | ||||
|     margin: 10px; | ||||
|     background-color: #3574fe; | ||||
|     border: none; | ||||
|     border-radius: 10px; | ||||
|     padding: 5px 15px 5px 15px; | ||||
|     /*font-weight: bold;*/ | ||||
|     display: block; | ||||
| } | ||||
|  | ||||
| .tagbtn:focus { | ||||
|     background-color: #004eff; | ||||
|     outline: none; | ||||
| } | ||||
|  | ||||
| .tagbtn:hover { | ||||
|     background-color: #004eff; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user