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
|
<?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));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user