improved reindexing to reindex in background
new button to cleanup gravity
This commit is contained in:
		@@ -1,18 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
$return = new stdClass();
 | 
					 | 
				
			||||||
if (file_exists("/tmp/output.log")) {
 | 
					 | 
				
			||||||
    $out = file_get_contents("/tmp/output.log");
 | 
					 | 
				
			||||||
    // clear log file
 | 
					 | 
				
			||||||
    file_put_contents("/tmp/output.log", "");
 | 
					 | 
				
			||||||
    $return->message = $out;
 | 
					 | 
				
			||||||
    $return->contentAvailable = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (substr($out, -strlen("-42")) == "-42") {
 | 
					 | 
				
			||||||
        unlink("/tmp/output.log");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
} else {
 | 
					 | 
				
			||||||
    $return->contentAvailable = false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
echo json_encode($return);
 | 
					 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
require_once './src/Database.php';
 | 
					require_once 'Database.php';
 | 
				
			||||||
require_once './src/TMDBMovie.php';
 | 
					require_once 'TMDBMovie.php';
 | 
				
			||||||
require_once './src/SSettings.php';
 | 
					require_once 'SSettings.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class VideoParser
 | 
					 * Class VideoParser
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
require_once 'src/Database.php';
 | 
					require_once __DIR__.'/../Database.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class RequestBase {
 | 
					abstract class RequestBase {
 | 
				
			||||||
    protected $conn;
 | 
					    protected $conn;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
require_once 'RequestBase.php';
 | 
					require_once 'RequestBase.php';
 | 
				
			||||||
 | 
					require_once __DIR__ . '/../VideoParser.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class Settings
 | 
					 * Class Settings
 | 
				
			||||||
@@ -9,6 +10,7 @@ class Settings extends RequestBase {
 | 
				
			|||||||
    function initHandlers() {
 | 
					    function initHandlers() {
 | 
				
			||||||
        $this->getFromDB();
 | 
					        $this->getFromDB();
 | 
				
			||||||
        $this->saveToDB();
 | 
					        $this->saveToDB();
 | 
				
			||||||
 | 
					        $this->reIndexHandling();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -102,4 +104,57 @@ class Settings extends RequestBase {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * methods for handling reindexing and cleanup of db gravity
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function reIndexHandling() {
 | 
				
			||||||
 | 
					        $this->addActionHandler("startReindex", function () {
 | 
				
			||||||
 | 
					            $indexrunning = false;
 | 
				
			||||||
 | 
					            if (file_exists("/tmp/output.log")) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $out = file_get_contents("/tmp/output.log");
 | 
				
			||||||
 | 
					                if (substr($out, -strlen("-42")) == "-42") {
 | 
				
			||||||
 | 
					                    unlink("/tmp/output.log");
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $indexrunning = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!$indexrunning) {
 | 
				
			||||||
 | 
					                // start extraction of video previews in background
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $cmd = 'php extractvideopreviews.php';
 | 
				
			||||||
 | 
					                exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, '/dev/zero', '/tmp/openmediacenterpid'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $this->commitMessage('{"success": true}');
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $this->commitMessage('{"success": false}');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->addActionHandler("cleanupGravity", function () {
 | 
				
			||||||
 | 
					            $vp = new VideoParser();
 | 
				
			||||||
 | 
					            $vp->cleanUpGravity();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->addActionHandler("getStatusMessage", function () {
 | 
				
			||||||
 | 
					            $return = new stdClass();
 | 
				
			||||||
 | 
					            if (file_exists("/tmp/output.log")) {
 | 
				
			||||||
 | 
					                $out = file_get_contents("/tmp/output.log");
 | 
				
			||||||
 | 
					                // clear log file
 | 
				
			||||||
 | 
					                file_put_contents("/tmp/output.log", "");
 | 
				
			||||||
 | 
					                $return->message = $out;
 | 
				
			||||||
 | 
					                $return->contentAvailable = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (substr($out, -strlen("-42")) == "-42") {
 | 
				
			||||||
 | 
					                    unlink("/tmp/output.log");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $return->contentAvailable = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->commitMessage(json_encode($return));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
require_once 'src/SSettings.php';
 | 
					require_once __DIR__.'/../SSettings.php';
 | 
				
			||||||
require_once 'RequestBase.php';
 | 
					require_once 'RequestBase.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@
 | 
				
			|||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "start": "react-scripts start",
 | 
					    "start": "react-scripts start",
 | 
				
			||||||
    "build": "react-scripts build",
 | 
					    "build": "react-scripts build",
 | 
				
			||||||
    "test": "react-scripts test --reporters=jest-junit --reporters=default",
 | 
					    "test": "react-scripts test --reporters=jest-junit --reporters=default --ci --silent",
 | 
				
			||||||
    "coverage": "react-scripts test --coverage --watchAll=false",
 | 
					    "coverage": "react-scripts test --coverage --watchAll=false",
 | 
				
			||||||
    "eject": "react-scripts eject"
 | 
					    "eject": "react-scripts eject"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,9 +16,6 @@ class MovieSettings extends React.Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentDidMount() {
 | 
					    componentDidMount() {
 | 
				
			||||||
        if (this.myinterval) {
 | 
					 | 
				
			||||||
            clearInterval(this.myinterval);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        this.myinterval = setInterval(this.updateStatus, 1000);
 | 
					        this.myinterval = setInterval(this.updateStatus, 1000);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,9 +26,12 @@ class MovieSettings extends React.Component {
 | 
				
			|||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <>
 | 
					            <>
 | 
				
			||||||
                <button disabled={this.state.startbtnDisabled} className='reindexbtn btn btn-success' onClick={() => {
 | 
					                <button disabled={this.state.startbtnDisabled}
 | 
				
			||||||
                    this.startReindex()
 | 
					                        className='btn btn-success'
 | 
				
			||||||
                }}>Reindex Movies
 | 
					                        onClick={() => {this.startReindex()}}>Reindex Movie
 | 
				
			||||||
 | 
					                </button>
 | 
				
			||||||
 | 
					                <button className='btn btn-warning'
 | 
				
			||||||
 | 
					                        onClick={() => {this.cleanupGravity()}}>Cleanup Gravity
 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
                <div className={style.indextextarea}>{this.state.text.map(m => (
 | 
					                <div className={style.indextextarea}>{this.state.text.map(m => (
 | 
				
			||||||
                    <div className='textarea-element'>{m}</div>
 | 
					                    <div className='textarea-element'>{m}</div>
 | 
				
			||||||
@@ -50,13 +50,19 @@ class MovieSettings extends React.Component {
 | 
				
			|||||||
        this.setState({startbtnDisabled: true});
 | 
					        this.setState({startbtnDisabled: true});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        console.log("starting");
 | 
					        console.log("starting");
 | 
				
			||||||
        const updateRequest = new FormData();
 | 
					        const request = new FormData();
 | 
				
			||||||
 | 
					        request.append("action", "startReindex");
 | 
				
			||||||
        // fetch all videos available
 | 
					        // fetch all videos available
 | 
				
			||||||
        fetch('/api/extractvideopreviews.php', {method: 'POST', body: updateRequest})
 | 
					        fetch('/api/settings.php', {method: 'POST', body: request})
 | 
				
			||||||
            .then((response) => response.text()
 | 
					            .then((response) => response.json()
 | 
				
			||||||
                .then((result) => {
 | 
					                .then((result) => {
 | 
				
			||||||
                    // todo 2020-07-4: some kind of return finished handler
 | 
					                    console.log(result);
 | 
				
			||||||
                    console.log("returned");
 | 
					                    if (result.success) {
 | 
				
			||||||
 | 
					                        console.log("started successfully");
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        console.log("error, reindex already running");
 | 
				
			||||||
 | 
					                        this.setState({startbtnDisabled: true});
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }))
 | 
					                }))
 | 
				
			||||||
            .catch(() => {
 | 
					            .catch(() => {
 | 
				
			||||||
                console.log("no connection to backend");
 | 
					                console.log("no connection to backend");
 | 
				
			||||||
@@ -71,8 +77,10 @@ class MovieSettings extends React.Component {
 | 
				
			|||||||
     * This interval function reloads the current status of reindexing from backend
 | 
					     * This interval function reloads the current status of reindexing from backend
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    updateStatus = () => {
 | 
					    updateStatus = () => {
 | 
				
			||||||
        const updateRequest = new FormData();
 | 
					        const request = new FormData();
 | 
				
			||||||
        fetch('/api/extractionData.php', {method: 'POST', body: updateRequest})
 | 
					        request.append("action", "getStatusMessage");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fetch('/api/settings.php', {method: 'POST', body: request})
 | 
				
			||||||
            .then((response) => response.json()
 | 
					            .then((response) => response.json()
 | 
				
			||||||
                .then((result) => {
 | 
					                .then((result) => {
 | 
				
			||||||
                    if (result.contentAvailable === true) {
 | 
					                    if (result.contentAvailable === true) {
 | 
				
			||||||
@@ -94,6 +102,25 @@ class MovieSettings extends React.Component {
 | 
				
			|||||||
                console.log("no connection to backend");
 | 
					                console.log("no connection to backend");
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * send request to cleanup db gravity
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    cleanupGravity() {
 | 
				
			||||||
 | 
					        const request = new FormData();
 | 
				
			||||||
 | 
					        request.append("action", "cleanupGravity");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fetch('/api/settings.php', {method: 'POST', body: request})
 | 
				
			||||||
 | 
					            .then((response) => response.text()
 | 
				
			||||||
 | 
					                .then((result) => {
 | 
				
			||||||
 | 
					                    this.setState({
 | 
				
			||||||
 | 
					                        text: ['successfully cleaned up gravity!']
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }))
 | 
				
			||||||
 | 
					            .catch(() => {
 | 
				
			||||||
 | 
					                console.log("no connection to backend");
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default MovieSettings;
 | 
					export default MovieSettings;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,5 +9,5 @@
 | 
				
			|||||||
    overflow-x: auto;
 | 
					    overflow-x: auto;
 | 
				
			||||||
    overflow-y: scroll;
 | 
					    overflow-y: scroll;
 | 
				
			||||||
    padding: 10px;
 | 
					    padding: 10px;
 | 
				
			||||||
    width: 50%;
 | 
					    width: 40%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,15 +22,33 @@ describe('<MovieSettings/>', function () {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('test simulate reindex', function () {
 | 
					    it('test simulate reindex', function () {
 | 
				
			||||||
        global.fetch = global.prepareFetchApi({});
 | 
					        global.fetch = global.prepareFetchApi({success: true});
 | 
				
			||||||
        const wrapper = shallow(<MovieSettings/>);
 | 
					        const wrapper = shallow(<MovieSettings/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        wrapper.find(".reindexbtn").simulate("click");
 | 
					        wrapper.find("button").findWhere(e => e.text() === "Reindex Movie" && e.type() === "button").simulate("click");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // initial send of reindex request to server
 | 
					        // initial send of reindex request to server
 | 
				
			||||||
        expect(global.fetch).toBeCalledTimes(1);
 | 
					        expect(global.fetch).toBeCalledTimes(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('test failing reindex start', done => {
 | 
				
			||||||
 | 
					        global.fetch = global.prepareFetchApi({success: false});
 | 
				
			||||||
 | 
					        const wrapper = shallow(<MovieSettings/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        wrapper.find("button").findWhere(e => e.text() === "Reindex Movie" && e.type() === "button").simulate("click");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // initial send of reindex request to server
 | 
				
			||||||
 | 
					        expect(global.fetch).toBeCalledTimes(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        process.nextTick(() => {
 | 
				
			||||||
 | 
					            // reindex already running --> so disable startbdn
 | 
				
			||||||
 | 
					            expect(wrapper.state()).toMatchObject({startbtnDisabled: true});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            global.fetch.mockClear();
 | 
				
			||||||
 | 
					            done();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('content available received and in state', done => {
 | 
					    it('content available received and in state', done => {
 | 
				
			||||||
        global.fetch = global.prepareFetchApi({
 | 
					        global.fetch = global.prepareFetchApi({
 | 
				
			||||||
            contentAvailable: true,
 | 
					            contentAvailable: true,
 | 
				
			||||||
@@ -51,4 +69,44 @@ describe('<MovieSettings/>', function () {
 | 
				
			|||||||
            done();
 | 
					            done();
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('test reindex with no content available', done=> {
 | 
				
			||||||
 | 
					        global.fetch = global.prepareFetchApi({
 | 
				
			||||||
 | 
					            contentAvailable: false
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        global.clearInterval = jest.fn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const wrapper = shallow(<MovieSettings/>);
 | 
				
			||||||
 | 
					        wrapper.instance().updateStatus();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        process.nextTick(() => {
 | 
				
			||||||
 | 
					            // expect the refresh interval to be cleared
 | 
				
			||||||
 | 
					            expect(global.clearInterval).toBeCalledTimes(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // expect startbtn to be reenabled
 | 
				
			||||||
 | 
					            expect(wrapper.state()).toMatchObject({startbtnDisabled: false});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            global.fetch.mockClear();
 | 
				
			||||||
 | 
					            done();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('test simulate gravity cleanup', done => {
 | 
				
			||||||
 | 
					        global.fetch = global.prepareFetchApi("mmi");
 | 
				
			||||||
 | 
					        const wrapper = shallow(<MovieSettings/>);
 | 
				
			||||||
 | 
					        wrapper.instance().setState = jest.fn(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        wrapper.find("button").findWhere(e => e.text() === "Cleanup Gravity" && e.type() === "button").simulate("click");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // initial send of reindex request to server
 | 
				
			||||||
 | 
					        expect(global.fetch).toBeCalledTimes(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        process.nextTick(() => {
 | 
				
			||||||
 | 
					            expect(wrapper.instance().setState).toBeCalledTimes(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            global.fetch.mockClear();
 | 
				
			||||||
 | 
					            done();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ global.prepareFetchApi = (response) => {
 | 
				
			|||||||
    const mockJsonPromise = Promise.resolve(response);
 | 
					    const mockJsonPromise = Promise.resolve(response);
 | 
				
			||||||
    const mockFetchPromise = Promise.resolve({
 | 
					    const mockFetchPromise = Promise.resolve({
 | 
				
			||||||
        json: () => mockJsonPromise,
 | 
					        json: () => mockJsonPromise,
 | 
				
			||||||
 | 
					        text: () => mockJsonPromise
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return (jest.fn().mockImplementation(() => mockFetchPromise));
 | 
					    return (jest.fn().mockImplementation(() => mockFetchPromise));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user