Merge branch 'nonblockingReindex' into 'master'
reindexing in background and gravity cleanup Closes #29 See merge request lukas/openmediacenter!20
This commit is contained in:
commit
8f7ba53c39
@ -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
|
||||
require_once './src/Database.php';
|
||||
require_once './src/TMDBMovie.php';
|
||||
require_once './src/SSettings.php';
|
||||
require_once 'Database.php';
|
||||
require_once 'TMDBMovie.php';
|
||||
require_once 'SSettings.php';
|
||||
|
||||
/**
|
||||
* Class VideoParser
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require_once 'src/Database.php';
|
||||
require_once __DIR__.'/../Database.php';
|
||||
|
||||
abstract class RequestBase {
|
||||
protected $conn;
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
require_once 'RequestBase.php';
|
||||
require_once __DIR__ . '/../VideoParser.php';
|
||||
|
||||
/**
|
||||
* Class Settings
|
||||
@ -9,6 +10,7 @@ class Settings extends RequestBase {
|
||||
function initHandlers() {
|
||||
$this->getFromDB();
|
||||
$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
|
||||
require_once 'src/SSettings.php';
|
||||
require_once __DIR__.'/../SSettings.php';
|
||||
require_once 'RequestBase.php';
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"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",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
|
@ -16,9 +16,6 @@ class MovieSettings extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.myinterval) {
|
||||
clearInterval(this.myinterval);
|
||||
}
|
||||
this.myinterval = setInterval(this.updateStatus, 1000);
|
||||
}
|
||||
|
||||
@ -29,9 +26,12 @@ class MovieSettings extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<button disabled={this.state.startbtnDisabled} className='reindexbtn btn btn-success' onClick={() => {
|
||||
this.startReindex()
|
||||
}}>Reindex Movies
|
||||
<button disabled={this.state.startbtnDisabled}
|
||||
className='btn btn-success'
|
||||
onClick={() => {this.startReindex()}}>Reindex Movie
|
||||
</button>
|
||||
<button className='btn btn-warning'
|
||||
onClick={() => {this.cleanupGravity()}}>Cleanup Gravity
|
||||
</button>
|
||||
<div className={style.indextextarea}>{this.state.text.map(m => (
|
||||
<div className='textarea-element'>{m}</div>
|
||||
@ -50,13 +50,19 @@ class MovieSettings extends React.Component {
|
||||
this.setState({startbtnDisabled: true});
|
||||
|
||||
console.log("starting");
|
||||
const updateRequest = new FormData();
|
||||
const request = new FormData();
|
||||
request.append("action", "startReindex");
|
||||
// fetch all videos available
|
||||
fetch('/api/extractvideopreviews.php', {method: 'POST', body: updateRequest})
|
||||
.then((response) => response.text()
|
||||
fetch('/api/settings.php', {method: 'POST', body: request})
|
||||
.then((response) => response.json()
|
||||
.then((result) => {
|
||||
// todo 2020-07-4: some kind of return finished handler
|
||||
console.log("returned");
|
||||
console.log(result);
|
||||
if (result.success) {
|
||||
console.log("started successfully");
|
||||
} else {
|
||||
console.log("error, reindex already running");
|
||||
this.setState({startbtnDisabled: true});
|
||||
}
|
||||
}))
|
||||
.catch(() => {
|
||||
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
|
||||
*/
|
||||
updateStatus = () => {
|
||||
const updateRequest = new FormData();
|
||||
fetch('/api/extractionData.php', {method: 'POST', body: updateRequest})
|
||||
const request = new FormData();
|
||||
request.append("action", "getStatusMessage");
|
||||
|
||||
fetch('/api/settings.php', {method: 'POST', body: request})
|
||||
.then((response) => response.json()
|
||||
.then((result) => {
|
||||
if (result.contentAvailable === true) {
|
||||
@ -94,6 +102,25 @@ class MovieSettings extends React.Component {
|
||||
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;
|
||||
|
@ -9,5 +9,5 @@
|
||||
overflow-x: auto;
|
||||
overflow-y: scroll;
|
||||
padding: 10px;
|
||||
width: 50%;
|
||||
width: 40%;
|
||||
}
|
||||
|
@ -22,15 +22,33 @@ describe('<MovieSettings/>', function () {
|
||||
});
|
||||
|
||||
it('test simulate reindex', function () {
|
||||
global.fetch = global.prepareFetchApi({});
|
||||
global.fetch = global.prepareFetchApi({success: true});
|
||||
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
|
||||
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 => {
|
||||
global.fetch = global.prepareFetchApi({
|
||||
contentAvailable: true,
|
||||
@ -51,4 +69,44 @@ describe('<MovieSettings/>', function () {
|
||||
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 mockFetchPromise = Promise.resolve({
|
||||
json: () => mockJsonPromise,
|
||||
text: () => mockJsonPromise
|
||||
});
|
||||
return (jest.fn().mockImplementation(() => mockFetchPromise));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user