Merge branch 'tagprediction' into 'master'
quickadd Tags See merge request lukas/openmediacenter!15
This commit is contained in:
		@@ -95,7 +95,10 @@ class Video extends RequestBase {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private function loadVideos() {
 | 
					    private function loadVideos() {
 | 
				
			||||||
        $this->addActionHandler("loadVideo", function () {
 | 
					        $this->addActionHandler("loadVideo", function () {
 | 
				
			||||||
            $query = "SELECT movie_name,movie_id,movie_url,thumbnail,poster,likes,quality,length FROM videos WHERE movie_id='" . $_POST['movieid'] . "'";
 | 
					            $video_id = $_POST['movieid'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $query = "  SELECT movie_name,movie_id,movie_url,thumbnail,poster,likes,quality,length 
 | 
				
			||||||
 | 
					                        FROM videos WHERE movie_id=$video_id";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $result = $this->conn->query($query);
 | 
					            $result = $this->conn->query($query);
 | 
				
			||||||
            $row = $result->fetch_assoc();
 | 
					            $row = $result->fetch_assoc();
 | 
				
			||||||
@@ -112,7 +115,7 @@ class Video extends RequestBase {
 | 
				
			|||||||
            // todo drop video url from db -- maybe one with and one without extension
 | 
					            // todo drop video url from db -- maybe one with and one without extension
 | 
				
			||||||
            // extension hardcoded here!!!
 | 
					            // extension hardcoded here!!!
 | 
				
			||||||
            $arr["movie_url"] = str_replace("?", "%3F", $this->videopath . $row["movie_name"] . ".mp4");
 | 
					            $arr["movie_url"] = str_replace("?", "%3F", $this->videopath . $row["movie_name"] . ".mp4");
 | 
				
			||||||
            $arr["likes"] = $row["likes"];
 | 
					            $arr["likes"] = (int) $row["likes"];
 | 
				
			||||||
            $arr["quality"] = $row["quality"];
 | 
					            $arr["quality"] = $row["quality"];
 | 
				
			||||||
            $arr["length"] = $row["length"];
 | 
					            $arr["length"] = $row["length"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,13 +123,27 @@ class Video extends RequestBase {
 | 
				
			|||||||
            $arr['tags'] = array();
 | 
					            $arr['tags'] = array();
 | 
				
			||||||
            $query = "SELECT t.tag_name FROM video_tags 
 | 
					            $query = "SELECT t.tag_name FROM video_tags 
 | 
				
			||||||
                        INNER JOIN tags t on video_tags.tag_id = t.tag_id
 | 
					                        INNER JOIN tags t on video_tags.tag_id = t.tag_id
 | 
				
			||||||
                        WHERE video_tags.video_id=" . $_POST['movieid'] . "
 | 
					                        WHERE video_tags.video_id=$video_id
 | 
				
			||||||
                        GROUP BY t.tag_name";
 | 
					                        GROUP BY t.tag_name";
 | 
				
			||||||
            $result = $this->conn->query($query);
 | 
					            $result = $this->conn->query($query);
 | 
				
			||||||
            while ($r = mysqli_fetch_assoc($result)) {
 | 
					            while ($r = mysqli_fetch_assoc($result)) {
 | 
				
			||||||
                array_push($arr['tags'], $r);
 | 
					                array_push($arr['tags'], $r);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // get the random predict tags
 | 
				
			||||||
 | 
					            $arr['suggesttag'] = array();
 | 
				
			||||||
 | 
					            // select 5 random tags which are not selected for current video
 | 
				
			||||||
 | 
					            $query = "SELECT * FROM tags
 | 
				
			||||||
 | 
					                        WHERE tag_id NOT IN (
 | 
				
			||||||
 | 
					                            SELECT video_tags.tag_id FROM video_tags
 | 
				
			||||||
 | 
					                            WHERE video_id=$video_id)
 | 
				
			||||||
 | 
					                        ORDER BY rand()
 | 
				
			||||||
 | 
					                        LIMIT 5";
 | 
				
			||||||
 | 
					            $result = $this->conn->query($query);
 | 
				
			||||||
 | 
					            while ($r = mysqli_fetch_assoc($result)) {
 | 
				
			||||||
 | 
					                array_push($arr['suggesttag'], $r);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $this->commitMessage(json_encode($arr));
 | 
					            $this->commitMessage(json_encode($arr));
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,11 @@ class Tag extends React.Component {
 | 
				
			|||||||
     * click handling for a Tag
 | 
					     * click handling for a Tag
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    TagClick() {
 | 
					    TagClick() {
 | 
				
			||||||
 | 
					        if (this.props.onclick) {
 | 
				
			||||||
 | 
					            this.props.onclick();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const tag = this.props.children.toString().toLowerCase();
 | 
					        const tag = this.props.children.toString().toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // call callback functin to switch to category page with specified tag
 | 
					        // call callback functin to switch to category page with specified tag
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,4 +31,17 @@ describe('<Tag/>', function () {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        expect(func).toBeCalledTimes(1);
 | 
					        expect(func).toBeCalledTimes(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('test custom onclick function', function () {
 | 
				
			||||||
 | 
					        const func = jest.fn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const wrapper = shallow(<Tag
 | 
				
			||||||
 | 
					            onclick={() => {func()}}>test</Tag>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(func).toBeCalledTimes(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        wrapper.simulate("click");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(func).toBeCalledTimes(1);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,6 +41,7 @@ class Player extends React.Component {
 | 
				
			|||||||
            quality: null,
 | 
					            quality: null,
 | 
				
			||||||
            length: null,
 | 
					            length: null,
 | 
				
			||||||
            tags: [],
 | 
					            tags: [],
 | 
				
			||||||
 | 
					            suggesttag: [],
 | 
				
			||||||
            popupvisible: false
 | 
					            popupvisible: false
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -49,13 +50,48 @@ class Player extends React.Component {
 | 
				
			|||||||
        this.fetchMovieData();
 | 
					        this.fetchMovieData();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render() {
 | 
					    /**
 | 
				
			||||||
        return (
 | 
					     * quick add callback to add tag to db and change gui correctly
 | 
				
			||||||
            <div id='videocontainer'>
 | 
					     * @param tag_id id of tag to add
 | 
				
			||||||
                <PageTitle
 | 
					     * @param tag_name name of tag to add
 | 
				
			||||||
                    title='Watch'
 | 
					     */
 | 
				
			||||||
                    subtitle={this.state.movie_name}/>
 | 
					    quickAddTag(tag_id, tag_name) {
 | 
				
			||||||
 | 
					        // save the tag
 | 
				
			||||||
 | 
					        const updateRequest = new FormData();
 | 
				
			||||||
 | 
					        updateRequest.append('action', 'addTag');
 | 
				
			||||||
 | 
					        updateRequest.append('id', tag_id);
 | 
				
			||||||
 | 
					        updateRequest.append('movieid', this.props.movie_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fetch('/api/tags.php', {method: 'POST', body: updateRequest})
 | 
				
			||||||
 | 
					            .then((response) => response.json()
 | 
				
			||||||
 | 
					                .then((result) => {
 | 
				
			||||||
 | 
					                    if (result.result !== "success") {
 | 
				
			||||||
 | 
					                        console.error("error occured while writing to db -- todo error handling");
 | 
				
			||||||
 | 
					                        console.error(result.result);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        // update tags if successful
 | 
				
			||||||
 | 
					                        let array = [...this.state.suggesttag]; // make a separate copy of the array
 | 
				
			||||||
 | 
					                        const index = array.map(function (e) {
 | 
				
			||||||
 | 
					                            return e.tag_id;
 | 
				
			||||||
 | 
					                        }).indexOf(tag_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (index !== -1) {
 | 
				
			||||||
 | 
					                            array.splice(index, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            this.setState({
 | 
				
			||||||
 | 
					                                tags: [...this.state.tags, {tag_name: tag_name}],
 | 
				
			||||||
 | 
					                                suggesttag: array
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * generate sidebar with all items
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    assembleSideBar() {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
            <SideBar>
 | 
					            <SideBar>
 | 
				
			||||||
                <SideBarTitle>Infos:</SideBarTitle>
 | 
					                <SideBarTitle>Infos:</SideBarTitle>
 | 
				
			||||||
                <Line/>
 | 
					                <Line/>
 | 
				
			||||||
@@ -72,7 +108,29 @@ class Player extends React.Component {
 | 
				
			|||||||
                        key={m.tag_name}
 | 
					                        key={m.tag_name}
 | 
				
			||||||
                        viewbinding={this.props.viewbinding}>{m.tag_name}</Tag>
 | 
					                        viewbinding={this.props.viewbinding}>{m.tag_name}</Tag>
 | 
				
			||||||
                ))}
 | 
					                ))}
 | 
				
			||||||
 | 
					                <Line/>
 | 
				
			||||||
 | 
					                <SideBarTitle>Tag Quickadd:</SideBarTitle>
 | 
				
			||||||
 | 
					                {this.state.suggesttag.map((m) => (
 | 
				
			||||||
 | 
					                    <Tag
 | 
				
			||||||
 | 
					                        key={m.tag_name}
 | 
				
			||||||
 | 
					                        onclick={() => {
 | 
				
			||||||
 | 
					                            this.quickAddTag(m.tag_id, m.tag_name);
 | 
				
			||||||
 | 
					                        }}>
 | 
				
			||||||
 | 
					                        {m.tag_name}
 | 
				
			||||||
 | 
					                    </Tag>
 | 
				
			||||||
 | 
					                ))}
 | 
				
			||||||
            </SideBar>
 | 
					            </SideBar>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            <div id='videocontainer'>
 | 
				
			||||||
 | 
					                <PageTitle
 | 
				
			||||||
 | 
					                    title='Watch'
 | 
				
			||||||
 | 
					                    subtitle={this.state.movie_name}/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                {this.assembleSideBar()}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <div className={style.videowrapper}>
 | 
					                <div className={style.videowrapper}>
 | 
				
			||||||
                    {/* video component is added here */}
 | 
					                    {/* video component is added here */}
 | 
				
			||||||
@@ -131,8 +189,10 @@ class Player extends React.Component {
 | 
				
			|||||||
                    likes: result.likes,
 | 
					                    likes: result.likes,
 | 
				
			||||||
                    quality: result.quality,
 | 
					                    quality: result.quality,
 | 
				
			||||||
                    length: result.length,
 | 
					                    length: result.length,
 | 
				
			||||||
                    tags: result.tags
 | 
					                    tags: result.tags,
 | 
				
			||||||
 | 
					                    suggesttag: result.suggesttag
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					                console.log(this.state);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -149,10 +209,11 @@ class Player extends React.Component {
 | 
				
			|||||||
            .then((response) => response.json()
 | 
					            .then((response) => response.json()
 | 
				
			||||||
                .then((result) => {
 | 
					                .then((result) => {
 | 
				
			||||||
                    if (result.result === "success") {
 | 
					                    if (result.result === "success") {
 | 
				
			||||||
                        this.fetchMovieData();
 | 
					                        // likes +1 --> avoid reload of all data
 | 
				
			||||||
 | 
					                        this.setState({likes: this.state.likes + 1})
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        console.log("an error occured while liking");
 | 
					                        console.error("an error occured while liking");
 | 
				
			||||||
                        console.log(result);
 | 
					                        console.error(result);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }));
 | 
					                }));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,17 +23,8 @@ describe('<Player/>', function () {
 | 
				
			|||||||
        expect(wrapper.find("r")).toHaveLength(1);
 | 
					        expect(wrapper.find("r")).toHaveLength(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('likebtn click', done => {
 | 
					    function simulateLikeButtonClick(){
 | 
				
			||||||
        global.fetch = global.prepareFetchApi({result: 'success'});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const func = jest.fn();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const wrapper = shallow(<Player/>);
 | 
					        const wrapper = shallow(<Player/>);
 | 
				
			||||||
        wrapper.setProps({
 | 
					 | 
				
			||||||
            onHide: () => {
 | 
					 | 
				
			||||||
                func()
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // initial fetch for getting movie data
 | 
					        // initial fetch for getting movie data
 | 
				
			||||||
        expect(global.fetch).toHaveBeenCalledTimes(1);
 | 
					        expect(global.fetch).toHaveBeenCalledTimes(1);
 | 
				
			||||||
@@ -41,9 +32,19 @@ describe('<Player/>', function () {
 | 
				
			|||||||
        // fetch for liking
 | 
					        // fetch for liking
 | 
				
			||||||
        expect(global.fetch).toHaveBeenCalledTimes(2);
 | 
					        expect(global.fetch).toHaveBeenCalledTimes(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return wrapper;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('likebtn click', done => {
 | 
				
			||||||
 | 
					        global.fetch = global.prepareFetchApi({result: 'success'});
 | 
				
			||||||
 | 
					        global.console.error = jest.fn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        simulateLikeButtonClick();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        process.nextTick(() => {
 | 
					        process.nextTick(() => {
 | 
				
			||||||
            // refetch is called so fetch called 3 times
 | 
					            expect(global.fetch).toHaveBeenCalledTimes(2);
 | 
				
			||||||
            expect(global.fetch).toHaveBeenCalledTimes(3);
 | 
					            expect(global.console.error).toHaveBeenCalledTimes(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            global.fetch.mockClear();
 | 
					            global.fetch.mockClear();
 | 
				
			||||||
            done();
 | 
					            done();
 | 
				
			||||||
@@ -52,24 +53,14 @@ describe('<Player/>', function () {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    it('errored likebtn click', done => {
 | 
					    it('errored likebtn click', done => {
 | 
				
			||||||
        global.fetch = global.prepareFetchApi({result: 'nosuccess'});
 | 
					        global.fetch = global.prepareFetchApi({result: 'nosuccess'});
 | 
				
			||||||
        const func = jest.fn();
 | 
					        global.console.error = jest.fn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const wrapper = shallow(<Player/>);
 | 
					        simulateLikeButtonClick();
 | 
				
			||||||
        wrapper.setProps({
 | 
					 | 
				
			||||||
            onHide: () => {
 | 
					 | 
				
			||||||
                func()
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // initial fetch for getting movie data
 | 
					 | 
				
			||||||
        expect(global.fetch).toHaveBeenCalledTimes(1);
 | 
					 | 
				
			||||||
        wrapper.find('.videoactions').find("button").first().simulate('click');
 | 
					 | 
				
			||||||
        // fetch for liking
 | 
					 | 
				
			||||||
        expect(global.fetch).toHaveBeenCalledTimes(2);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        process.nextTick(() => {
 | 
					        process.nextTick(() => {
 | 
				
			||||||
            // refetch is called so fetch called 3 times
 | 
					            // refetch is called so fetch called 3 times
 | 
				
			||||||
            expect(global.fetch).toHaveBeenCalledTimes(2);
 | 
					            expect(global.fetch).toHaveBeenCalledTimes(2);
 | 
				
			||||||
 | 
					            expect(global.console.error).toHaveBeenCalledTimes(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            global.fetch.mockClear();
 | 
					            global.fetch.mockClear();
 | 
				
			||||||
            done();
 | 
					            done();
 | 
				
			||||||
@@ -117,4 +108,59 @@ describe('<Player/>', function () {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        expect(wrapper.find("Tag")).toHaveLength(2);
 | 
					        expect(wrapper.find("Tag")).toHaveLength(2);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('inserts tag quickadd correctly', function () {
 | 
				
			||||||
 | 
					        generatetag();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('test click of quickadd tag btn', done => {
 | 
				
			||||||
 | 
					        const wrapper = generatetag();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        global.fetch = prepareFetchApi({result: 'success'});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // render tag subcomponent
 | 
				
			||||||
 | 
					        const tag = wrapper.find("Tag").first().dive();
 | 
				
			||||||
 | 
					        tag.simulate('click');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        process.nextTick(() => {
 | 
				
			||||||
 | 
					            expect(global.fetch).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            global.fetch.mockClear();
 | 
				
			||||||
 | 
					            done();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('test failing quickadd', done => {
 | 
				
			||||||
 | 
					        const wrapper = generatetag();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        global.fetch = prepareFetchApi({result: 'nonsuccess'});
 | 
				
			||||||
 | 
					        global.console.error = jest.fn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // render tag subcomponent
 | 
				
			||||||
 | 
					        const tag = wrapper.find("Tag").first().dive();
 | 
				
			||||||
 | 
					        tag.simulate('click');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        process.nextTick(() => {
 | 
				
			||||||
 | 
					            expect(global.console.error).toHaveBeenCalledTimes(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            global.fetch.mockClear();
 | 
				
			||||||
 | 
					            done();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function generatetag(){
 | 
				
			||||||
 | 
					        const wrapper = shallow(<Player/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(wrapper.find("Tag")).toHaveLength(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        wrapper.setState({
 | 
				
			||||||
 | 
					            suggesttag: [
 | 
				
			||||||
 | 
					                {tag_name: 'first', tag_id: 1},
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(wrapper.find("Tag")).toHaveLength(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return wrapper;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user