Provide a base folder path and the folder browser will show subfolders which you can navigate to using the buttons.
-'Scan (Find new)' does 2 things - it removes files from the database which don't exist anymore, and adds newly detected files. Turn on 'Folder watch' to automate this process. New files will be scanned for every 30 seconds or so.
All new files will be added to both the transcode queues and the health check queues. If you're not interested in using one or the other, then just make sure not to fire up any workers for that respective queue.
@@ -824,7 +824,8 @@ class App extends Component {
In the library transcode settings, you can either use plugins or manually set either video file or audio file transcode settings.
You can stack plugins but this will increase the number of transcode/remux passes on a file. It's best to use/create a plugin which can do what you need all at once.
-See the plugins tab for plugins info on creating a plugin.
diff --git a/imports/ui/plugins/pluginTemplates/PluginGuide.jsx b/imports/ui/plugins/pluginTemplates/PluginGuide.jsx
index c335504d..c31e49f8 100644
--- a/imports/ui/plugins/pluginTemplates/PluginGuide.jsx
+++ b/imports/ui/plugins/pluginTemplates/PluginGuide.jsx
@@ -1,8 +1,10 @@
import React, { Component } from 'react';
import { withTracker } from 'meteor/react-meteor-data';
-import { Button} from 'react-bootstrap';
+import { Button } from 'react-bootstrap';
import ReactDOM from 'react-dom';
+import LocalImage from '../../Local_Image.jsx';
+
@@ -13,13 +15,13 @@ var ButtonStyle = {
- class App extends Component {
+class App extends Component {
constructor(props) {
super(props);
this.state = {
-
+
};
@@ -42,57 +44,58 @@ var ButtonStyle = {
-
-
-
+
+
+
-
Guide
+
Guide
-
-
-
+
+
+
-
Each of your libraries can have its own plugin stack. Use both community and local plugins to create a stack which processes your files to your requirements.
+
Each of your libraries can have its own plugin stack. Use both community and local plugins to create a stack which processes your files to your requirements.
-
Plugins created in the plugin creator will be saved locally in 'Tdarr/Plugins/Local' and can be viewed on the 'Local' plugins tab to the upper left. Plugins are written in JavaScript and are highly configurable. It is encouraged that you open up plugins in a text/code editor and modify them to do exactly what you need.
+
Plugins created in the plugin creator will be saved locally in 'Tdarr/Plugins/Local' and can be viewed on the 'Local' plugins tab to the upper left. Plugins are written in JavaScript and are highly configurable. It is encouraged that you open up plugins in a text/code editor and modify them to do exactly what you need.
-
-
+
+
-
The following illustrates how the plugin stack works.
+
The following illustrates how the plugin stack works.
-
+
-
-
-
+
+ {/* */}
+
+
-
+
-
It is best practice to put video transcode plugins at the top of your stack and then your other plugins. Think logically
- about how your files will be processed. For example, let's say you have 2 plugins:
+
It is best practice to put video transcode plugins at the top of your stack and then your other plugins. Think logically
+ about how your files will be processed. For example, let's say you have 2 plugins:
-
(1) Transcode non hevc files into hevc mkv
-
(2) Remux non-mkv files into mkv
-
It would not makes sense to put the remux plugin above the transcode plugin. In the above stack if, for example, a h264 MP4 file enters the stack, only the transcode plugin would need to be used. If the remux plugin was above the transcode plugin, 2 plugins would need to be used, resulting in additional processing time and more disk read/writes.
-
+
(1) Transcode non hevc files into hevc mkv
+
(2) Remux non-mkv files into mkv
+
It would not makes sense to put the remux plugin above the transcode plugin. In the above stack if, for example, a h264 MP4 file enters the stack, only the transcode plugin would need to be used. If the remux plugin was above the transcode plugin, 2 plugins would need to be used, resulting in additional processing time and more disk read/writes.
+
-
-
When using Tdarr it's important that you implement conditions/filters to prevent your files from going through an infinite transcode/remux cycle . For example, if you're transcoding into hevc, then add a filter to prevent hevc being transcoded. That way your new files (in hevc), won't be re-transcoded. You can use the 'Force processing' buttons to force a plugin through your first plugin (applies to plugins created in the plugin creator from 1.101+).
+
+
When using Tdarr it's important that you implement conditions/filters to prevent your files from going through an infinite transcode/remux cycle . For example, if you're transcoding into hevc, then add a filter to prevent hevc being transcoded. That way your new files (in hevc), won't be re-transcoded. You can use the 'Force processing' buttons to force a plugin through your first plugin (applies to plugins created in the plugin creator from 1.101+).
-
Some actions/plugins have built-in filters. This means they'll automatically detect if a file needs to be processed or not (such as the remove subtitles community plugin). Additional filters can be added.
+
Some actions/plugins have built-in filters. This means they'll automatically detect if a file needs to be processed or not (such as the remove subtitles community plugin). Additional filters can be added.
-
To use plugins, press the 'Copy id' button on one of the plugins on the 'Plugins' tab. Paste the id in the plugin id box in the 'Transcode' section of one of your libraries. Make sure to use the checkboxes to specify whether it's a Community or Local plugin.
+
To use plugins, press the 'Copy id' button on one of the plugins on the 'Plugins' tab. Paste the id in the plugin id box in the 'Transcode' section of one of your libraries. Make sure to use the checkboxes to specify whether it's a Community or Local plugin.
-
+
-
-
-
+
+
+
@@ -104,14 +107,14 @@ var ButtonStyle = {
export default withTracker(() => {
-
-return {
-
+
+ return {
+
-};
+ };
})(App);
diff --git a/imports/ui/tab_Dev.jsx b/imports/ui/tab_Dev.jsx
index 4458873b..626d4056 100644
--- a/imports/ui/tab_Dev.jsx
+++ b/imports/ui/tab_Dev.jsx
@@ -5,6 +5,8 @@ import { Button } from 'react-bootstrap';
import LatestDevNotes from './tab_Dev_latest.jsx';
+import LocalImage from './Local_Image.jsx';
+
@@ -55,7 +57,7 @@ export default class App extends Component {
-
+
@@ -85,7 +87,7 @@ export default class App extends Component {
-
+
diff --git a/imports/ui/tab_Help.jsx b/imports/ui/tab_Help.jsx
index 450f0a31..90d17407 100644
--- a/imports/ui/tab_Help.jsx
+++ b/imports/ui/tab_Help.jsx
@@ -9,6 +9,8 @@ import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import { render } from 'react-dom';
import ReactDOM from 'react-dom'
+import LocalImage from './Local_Image.jsx';
+
@@ -63,7 +65,7 @@ export default class App extends Component {
- runHelpCommand = (mode, input ) => {
+ runHelpCommand = (mode, input) => {
var text = ReactDOM.findDOMNode(this.refs[input]).value.trim()
@@ -93,35 +95,37 @@ export default class App extends Component {
-
-
+
-
+
-
-
-
window.open("https://discord.gg/GF8X8cq", "_blank")} alt='icon' height="60" width="60" />
-
-
-
window.open("https://github.com/HaveAGitGat/Tdarr/wiki", "_blank")} alt='icon' height="60" width="60" />
-
-
-
-
-
window.open("https://www.reddit.com/r/Tdarr", "_blank")} alt='icon' height="60" width="60" />
-
-
-
+
+
+ window.open("https://discord.gg/GF8X8cq", "_blank")} >
+
+
+
+
+ window.open("https://github.com/HaveAGitGat/Tdarr/wiki", "_blank")}>
+
+
+
+
+ window.open("https://www.reddit.com/r/Tdarr", "_blank")}>
+
+
+
+
-
+
-
+
-
-
+
+
unRAID: Enable NVENC: https://forums.unraid.net/topic/77813-plugin-linuxserverio-unraid-nvidia/
@@ -131,69 +135,71 @@ export default class App extends Component {
-
-
+
+
-
Terminal:
-
-
- FFmpeg
- HandBrake
-
+ Terminal:
+
+
+ FFmpeg
+ HandBrake
+
+
+
+
From 1a4776003e1c7ba73d4d45a7f2afbb8b7af3805e Mon Sep 17 00:00:00 2001
From: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com>
Date: Tue, 11 Feb 2020 01:52:19 +0000
Subject: [PATCH 03/31] fileScanner improvements
---
private/{ => fileScanner}/ccextractor.js | 0
.../{ => fileScanner}/ccextractor/ccextractor | Bin
.../ccextractor/ccextractorwin.exe | Bin
private/{ => fileScanner}/fileScanner.js | 252 +++---------------
private/fileScanner/runCCExtractor.js | 125 +++++++++
private/fileScanner/runExifTool.js | 52 ++++
private/fileScanner/runFFprobe.js | 58 ++++
7 files changed, 272 insertions(+), 215 deletions(-)
rename private/{ => fileScanner}/ccextractor.js (100%)
rename private/{ => fileScanner}/ccextractor/ccextractor (100%)
rename private/{ => fileScanner}/ccextractor/ccextractorwin.exe (100%)
rename private/{ => fileScanner}/fileScanner.js (66%)
create mode 100644 private/fileScanner/runCCExtractor.js
create mode 100644 private/fileScanner/runExifTool.js
create mode 100644 private/fileScanner/runFFprobe.js
diff --git a/private/ccextractor.js b/private/fileScanner/ccextractor.js
similarity index 100%
rename from private/ccextractor.js
rename to private/fileScanner/ccextractor.js
diff --git a/private/ccextractor/ccextractor b/private/fileScanner/ccextractor/ccextractor
similarity index 100%
rename from private/ccextractor/ccextractor
rename to private/fileScanner/ccextractor/ccextractor
diff --git a/private/ccextractor/ccextractorwin.exe b/private/fileScanner/ccextractor/ccextractorwin.exe
similarity index 100%
rename from private/ccextractor/ccextractorwin.exe
rename to private/fileScanner/ccextractor/ccextractorwin.exe
diff --git a/private/fileScanner.js b/private/fileScanner/fileScanner.js
similarity index 66%
rename from private/fileScanner.js
rename to private/fileScanner/fileScanner.js
index 5c822d27..6813ff58 100644
--- a/private/fileScanner.js
+++ b/private/fileScanner/fileScanner.js
@@ -64,17 +64,18 @@ var path = require("path");
var fs = require('fs');
if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
-
var rootModules = path.join(process.cwd(), '/npm/node_modules/')
-
} else {
var rootModules = ''
}
const isDocker = require(rootModules + 'is-docker');
-const exiftool = require(rootModules + "exiftool-vendored").exiftool
-var shell = require(rootModules + 'shelljs');
+const importFresh = require(rootModules + 'import-fresh');
+
+const runFFprobe = importFresh('./runFFprobe.js')
+const runExifTool = importFresh('./runExifTool.js')
+const runCCExtractor = importFresh('./runCCExtractor.js')
var home = require("os").homedir();
@@ -224,9 +225,6 @@ if (arrayOrPathSwitch == 1) {
-
-
-
} else {
if (checkContainer(fullPath) == true && isInIgnoredFolder(fullPath) == false) {
@@ -365,13 +363,9 @@ function ffprobeLaunch(filesToScan) {
updateConsole(scannerID, `ffprobeLaunch received these files:${filesToScan} `)
- var ffprobe = require(rootModules + 'ffprobe'),
- ffprobeStatic = require(rootModules + 'ffprobe-static');
var path = require("path");
- var ffprobeStaticPath = ''
-
-
- ffprobeStaticPath = require(rootModules + 'ffprobe-static').path
+ var ffprobeStaticPath = require(rootModules + 'ffprobe-static').path
+ const exiftool = require(rootModules + "exiftool-vendored").exiftool
var k = 0;
@@ -380,33 +374,42 @@ function ffprobeLaunch(filesToScan) {
function loopArray(filesToScan, i) {
-
-
-
-
var filepath = filesToScan[i]
-
-
try {
if (fs.existsSync(filepath)) {
- // Meteor.call('logthis', "Extracting data from this file:" + filepath, function (error, result) { });
+ updateConsole(scannerID, `Launching FFprobe on this file: ${filepath}`)
+ async function runExtractions(filepath) {
- updateConsole(scannerID, `Launching FFprobe on this file: ${filepath}`)
+ try {
+ var fileInfo = {
+ ffProbeData: '',
+ exifToolData: '',
+ ccextractorData: '',
+ }
- ffprobe(filepath, { path: ffprobeStaticPath }, function (err, jsonData) {
- //if (err) return done(err);
+ fileInfo.ffProbeData = await runFFprobe(filepath);
+ if (fileInfo.ffProbeData.result != 'error') {
+ fileInfo.exifToolData = await runExifTool(filepath, exiftool);
- if (err) {
- updateConsole(scannerID, `FFprobe extract error on this file:${filepath}`)
+ if (closedCaptionScan == 'true') {
+ fileInfo.ccextractorData = await runCCExtractor(filepath);
+ extractData(filepath, fileInfo.ffProbeData.data, fileInfo.exifToolData.data, fileInfo.ccextractorData.data)
+
+ } else {
+ extractData(filepath, fileInfo.ffProbeData.data, fileInfo.exifToolData.data, null)
+ }
+
- extractDataError(filepath, err)
+ } else {
+ extractDataError(filepath, fileInfo.ffProbeData.data)
+ }
i++;
if (i < filesToScan.length) {
@@ -415,196 +418,17 @@ function ffprobeLaunch(filesToScan) {
exiftool.end()
}
-
+ } catch (err) {
+ console.log(err)
}
- if (jsonData) {
-
- updateConsole(scannerID, `FFprobe extract success on this file:${filepath}. Launching exiftool`)
-
- exiftool
- .read(filepath)
- .then((tags /*: Tags */) => {
- // console.log(
- // `Title: ${tags.Title}`
- //)
- updateConsole(scannerID, `exiftool finished on this file:${filepath}`)
-
- // extractData(filepath, jsonData, tags)
-
-
- //
-
-
-
-
- if (closedCaptionScan == 'true') {
-
-
-
- var CCExtractorPath
- var workerCommand
-
- if (process.platform == 'win32') {
-
- if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
- CCExtractorPath = path.join(process.cwd(), '/assets/app/ccextractor/ccextractorwin.exe')
- } else {
- CCExtractorPath = path.join(process.cwd(), '/private/ccextractor/ccextractorwin.exe')
- }
-
- workerCommand = CCExtractorPath + " -debug -stdout -endat 01:00 --screenfuls 1 -out=null \"" + filepath + "\""
-
- }
-
- if (process.platform == 'linux') {
- if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
- CCExtractorPath = path.join(process.cwd(), '/assets/app/ccextractor/ccextractor')
- } else {
- CCExtractorPath = path.join(process.cwd(), '/private/ccextractor/ccextractor')
- }
-
- var filepathUnix = filepath.replace(/'/g, '\'\"\'\"\'');
-
- workerCommand = CCExtractorPath + " -debug -stdout -endat 01:00 --screenfuls 1 -out=null '" + filepathUnix + "'"
-
-
-
- }
-
- if (process.platform == 'darwin') {
- workerCommand = ""
-
- }
-
-
-
- // console.log(workerCommand)
-
- var CCExtractorOutput = ""
-
- // console.log("Checking for captions")
-
- updateConsole(scannerID, `Checking for captions`)
-
-
- //
-
- var childProcess = require('child_process');
-
- var workerPath = "assets/app/ccextractor.js"
-
- var hasClosedCaptions = false
-
-
- shellThreadModule = childProcess.fork(workerPath, [], {
- silent: true,
-
- });
-
-
- var infoArray = [
- "processFile",
- workerCommand
- ];
-
-
- shellThreadModule.send(infoArray);
-
- var killFlag = false
-
-
- shellThreadModule.stderr.on('data', function (data) {
-
- //console.log(data)
- // console.log(data.toString())
-
- if (data.includes('Permission denied') || data.includes('error while loading')) {
- console.log(data.toString())
- }
-
- if (data.includes('XDS:') || data.includes('Caption block')) {
-
- var infoArray = [
- "exitThread",
- "itemCancelled",
- ];
-
- try {
- killFlag = true
- if (shellThreadModule != "") {
- shellThreadModule.send(infoArray);
- }
- } catch (err) { }
-
- hasClosedCaptions = true
-
- }
-
- });
-
- // setTimeout(killCCExtractor, 1000);
-
- function killCCExtractor() {
- var infoArray = [
- "exitThread",
- "itemCancelled",
- ];
-
- if (killFlag == false) {
-
- try {
- if (shellThreadModule != "") {
- shellThreadModule.send(infoArray);
- }
- } catch (err) { }
- }
-
- }
-
-
-
- shellThreadModule.on("exit", function (code, ) {
-
- ('ccextractor:', code);
-
- extractData(filepath, jsonData, tags, hasClosedCaptions)
-
- i++;
- if (i < filesToScan.length) {
- loopArray(filesToScan, i);
- } else {
- exiftool.end()
- }
-
-
- });
-
-
-
- } else {
-
-
- extractData(filepath, jsonData, tags)
-
- i++;
- if (i < filesToScan.length) {
- loopArray(filesToScan, i);
- } else {
- exiftool.end()
- }
-
-
-
- }
+ }
+ runExtractions(filepath)
- //
- })
- }
- });
}
+
} catch (err) {
console.error(err.stack);
@@ -616,8 +440,6 @@ function ffprobeLaunch(filesToScan) {
} else {
exiftool.end()
}
-
-
}
}
@@ -626,9 +448,9 @@ function ffprobeLaunch(filesToScan) {
if (!Array.isArray(filesToScan) || !filesToScan.length) {
-
exiftool.end()
+
} else {
loopArray(filesToScan, k);
@@ -736,9 +558,9 @@ function ffprobeLaunch(filesToScan) {
//if (!!("video_codec_name" in thisFileObject)) {
- try{
+ try {
var exifToolVerdict = thisFileObject.meta.MIMEType.includes('video')
- }catch(err){
+ } catch (err) {
var exifToolVerdict = true
}
diff --git a/private/fileScanner/runCCExtractor.js b/private/fileScanner/runCCExtractor.js
new file mode 100644
index 00000000..f34a6c12
--- /dev/null
+++ b/private/fileScanner/runCCExtractor.js
@@ -0,0 +1,125 @@
+
+const fs = require('fs')
+const path = require('path');
+if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
+ var rootModules = path.join(process.cwd(), '/npm/node_modules/')
+} else {
+ var rootModules = ''
+}
+
+module.exports = function runCCExtractor(filepath) {
+
+
+ return new Promise(resolve => {
+ try {
+
+ var CCExtractorPath
+ var workerCommand
+
+ if (process.platform == 'win32') {
+
+ if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
+ CCExtractorPath = path.join(process.cwd(), '/assets/app/fileScanner/ccextractor/ccextractorwin.exe')
+ } else {
+ CCExtractorPath = path.join(process.cwd(), '/private/fileScanner/ccextractor/ccextractorwin.exe')
+ }
+
+ workerCommand = CCExtractorPath + " -debug -stdout -endat 01:00 --screenfuls 1 -out=null \"" + filepath + "\""
+
+ }
+
+ if (process.platform == 'linux') {
+ if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
+ CCExtractorPath = path.join(process.cwd(), '/assets/app/fileScanner/ccextractor/ccextractor')
+ } else {
+ CCExtractorPath = path.join(process.cwd(), '/private/fileScanner/ccextractor/ccextractor')
+ }
+
+ var filepathUnix = filepath.replace(/'/g, '\'\"\'\"\'');
+ workerCommand = CCExtractorPath + " -debug -stdout -endat 01:00 --screenfuls 1 -out=null '" + filepathUnix + "'"
+ }
+
+ if (process.platform == 'darwin') {
+ workerCommand = ""
+
+ }
+
+
+
+
+ const childProcess = require('child_process');
+ const workerPath = "assets/app/fileScanner/ccextractor.js"
+ var hasClosedCaptions = false
+
+
+ shellThreadModule = childProcess.fork(workerPath, [], {
+ silent: true,
+
+ });
+
+
+ var infoArray = [
+ "processFile",
+ workerCommand
+ ];
+
+
+ shellThreadModule.send(infoArray);
+
+
+ shellThreadModule.stderr.on('data', function (data) {
+
+ //console.log(data)
+ // console.log(data.toString())
+
+ if (data.includes('Permission denied') || data.includes('error while loading')) {
+ console.log(data.toString())
+ }
+
+ if (data.includes('XDS:') || data.includes('Caption block')) {
+
+ var infoArray = [
+ "exitThread",
+ "itemCancelled",
+ ];
+
+ try {
+ killFlag = true
+ if (shellThreadModule != "") {
+ shellThreadModule.send(infoArray);
+ }
+ } catch (err) { }
+
+ hasClosedCaptions = true
+
+ }
+
+ });
+
+
+
+ shellThreadModule.on("exit", function (code, ) {
+ resolve(
+ {
+ result: 'success',
+ data: hasClosedCaptions,
+ }
+ )
+ });
+
+
+ } catch (err) {
+
+ resolve(
+ {
+ result: 'error',
+ data: 'CCextractor encountered an error.',
+ }
+ )
+
+ }
+ });
+}
+
+
+
diff --git a/private/fileScanner/runExifTool.js b/private/fileScanner/runExifTool.js
new file mode 100644
index 00000000..37a6dea9
--- /dev/null
+++ b/private/fileScanner/runExifTool.js
@@ -0,0 +1,52 @@
+
+const fs = require('fs')
+const path = require('path');
+if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
+ var rootModules = path.join(process.cwd(), '/npm/node_modules/')
+} else {
+ var rootModules = ''
+}
+
+module.exports = function runExifTool(filepath,exiftool) {
+
+ //const exiftool = require(rootModules + "exiftool-vendored").exiftool
+
+ return new Promise(resolve => {
+ try {
+ exiftool
+ .read(filepath)
+ .then((tags /*: Tags */) => {
+
+ resolve(
+ {
+ result: 'success',
+ data: tags,
+ }
+ )
+ })
+ .catch((error) => {
+ resolve(
+ {
+ result: 'error',
+ data: error,
+ }
+ )
+ }
+ )
+
+ } catch (err) {
+
+
+ resolve(
+ {
+ result: 'error',
+ data: 'Exif tool encountered an error.',
+ }
+ )
+
+ }
+ });
+}
+
+
+
diff --git a/private/fileScanner/runFFprobe.js b/private/fileScanner/runFFprobe.js
new file mode 100644
index 00000000..a07e7885
--- /dev/null
+++ b/private/fileScanner/runFFprobe.js
@@ -0,0 +1,58 @@
+
+const fs = require('fs')
+const path = require('path');
+if (fs.existsSync(path.join(process.cwd(), "/npm"))) {
+ var rootModules = path.join(process.cwd(), '/npm/node_modules/')
+} else {
+ var rootModules = ''
+}
+
+
+module.exports = function runFFprobe(filepath) {
+
+ const ffprobe = require(rootModules + 'ffprobe')
+ const ffprobeStaticPath = require(rootModules + 'ffprobe-static').path
+
+
+
+ return new Promise(resolve => {
+ try {
+ ffprobe(filepath, { path: ffprobeStaticPath }, function (err, jsonData) {
+ //console.log(err)
+ //console.log(jsonData)
+ if (err) {
+ console.log(err)
+ resolve(
+ {
+ result: 'error',
+ data: 'FFprobe encountered an error:' + err,
+ }
+ )
+ }
+
+ if (jsonData) {
+ resolve(
+ {
+ result: 'success',
+ data: jsonData
+ }
+ )
+ }
+ });
+ } catch (err) {
+
+ console.log(err.stack)
+
+ resolve(
+ {
+ result: 'err',
+ data: 'FFprobe encountered an err:' + err,
+ }
+ )
+
+ }
+ });
+}
+
+
+
From 31634b91b3da4f460059fcda63f88d714705b666 Mon Sep 17 00:00:00 2001
From: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com>
Date: Tue, 11 Feb 2020 08:27:36 +0000
Subject: [PATCH 04/31] Refactor buttons + buttons now maintain load state
until queue updated
---
imports/ui/ButtonLibrary/Buttons.jsx | 118 +++
imports/ui/item_Button.jsx | 160 ++--
imports/ui/searchResults.jsx | 191 ++--
imports/ui/transcoding/tab_Transcoding.jsx | 990 +++++++++++----------
4 files changed, 839 insertions(+), 620 deletions(-)
create mode 100644 imports/ui/ButtonLibrary/Buttons.jsx
diff --git a/imports/ui/ButtonLibrary/Buttons.jsx b/imports/ui/ButtonLibrary/Buttons.jsx
new file mode 100644
index 00000000..d959adfc
--- /dev/null
+++ b/imports/ui/ButtonLibrary/Buttons.jsx
@@ -0,0 +1,118 @@
+
+import React, { Component } from 'react';
+import ItemButton from '../item_Button.jsx'
+
+
+export class BumpButton extends Component {
+
+ render() {
+ var obj = {
+ bumped: new Date(),
+ }
+ return
+
+ }
+}
+
+
+
+export class SkipButton extends Component {
+ render() {
+
+ var obj = {
+ TranscodeDecisionMaker:"Transcode success",
+ lastTranscodeDate: new Date(),
+ }
+ return
+
+ }
+}
+
+
+export class SkipHealthCheckButton extends Component {
+ render() {
+
+ var obj = {
+ HealthCheck: "Success",
+ lastHealthCheckDate: new Date(),
+ }
+ return
+
+ }
+}
+
+
+export class CancelBumpButton extends Component {
+ render() {
+
+ var obj = {
+ bumped: false,
+ }
+ return
+
+ }
+}
+
+
+
+
+export class RedoButton extends Component {
+
+ render() {
+
+ var obj = {
+ [this.props.mode]: "Queued",
+ processingStatus: false,
+ createdAt: new Date(),
+ }
+
+
+ return
+ }
+}
+
+export class ForceProcessingButton extends Component {
+
+ render() {
+ var obj = {
+ forceProcessing: true,
+ }
+ return
+ }
+}
+
+export class CancelForceProcessingButton extends Component {
+
+ render() {
+ var obj = {
+ forceProcessing: false,
+ }
+ return
+ }
+}
+
+
+
+export class IgnoreButton extends Component {
+
+ render() {
+ var obj = {
+ [this.props.mode]: "Ignored",
+ processingStatus: false,
+ createdAt: new Date(),
+ }
+ return
+ }
+}
+
+
+
+
+
+export class CreateSampleButton extends Component {
+ render() {
+
+ return
+ }
+}
+
diff --git a/imports/ui/item_Button.jsx b/imports/ui/item_Button.jsx
index c1e37ffa..91ce125d 100644
--- a/imports/ui/item_Button.jsx
+++ b/imports/ui/item_Button.jsx
@@ -13,30 +13,33 @@ export default class App extends Component {
constructor(props) {
super(props);
- this.state = { isShowState: true }
+ this.state = {
+ lastUpdate: 0,
+ }
}
triggerLoadState = () => {
+ var tempObj = {
+ lastUpdate: (new Date())
+
+ }
+ Meteor.call('modifyFileDB', 'update', this.props.file.file, tempObj, (error, result) => { })
this.setState({
- ...this.state,
- isShowState: false,
- isLoadState: true
+ lastUpdate: (new Date()).getTime(),
})
- setTimeout(this.reset, 1000);
+ // setTimeout(this.reset, 1000);
}
- reset = () => {
- this.setState({
- ...this.state,
- isShowState: true,
- isLoadState: false
- })
+ // reset = () => {
+ // this.setState({
+ // lastUpdate:0,
+ // })
- }
+ // }
@@ -48,31 +51,30 @@ export default class App extends Component {
// }
+ var serverTime = this.props.time
+ var lastUpdate = this.props.file.lastUpdate ? this.props.file.lastUpdate.getTime() : 0
+
+
if (this.props.type == "updateDBAction") {
return (
- {this.state.isShowState && {
+ {serverTime >= this.state.lastUpdate ? {
this.triggerLoadState();
- Meteor.call('modifyFileDB','update',this.props.file,this.props.obj, (error, result) => {})
-
- }}>{this.props.symbol} }
-
- {this.state.isLoadState && }
-
+ Meteor.call('modifyFileDB', 'update', this.props.file.file, this.props.obj, (error, result) => { })
+ }}>{this.props.symbol} : }
@@ -86,23 +88,25 @@ export default class App extends Component {
return (
- {this.state.isShowState &&
{
+ {true ? {
this.triggerLoadState();
- Meteor.call('createSample', this.props.file, (error, result) => {})
+ Meteor.call('createSample', this.props.file.file, (error, result) => {
+ alert('Sample created for '+this.props.file.file)
+ })
- }}>{this.props.symbol} }
+ }}>{this.props.symbol} :
}
- {this.state.isLoadState &&
}
@@ -119,65 +123,67 @@ export default class App extends Component {
return (
- {this.state.isShowState && {
+ {true ? {
this.triggerLoadState();
- Meteor.call('modifyFileDB','removeOne',this.props.file._id, (error, result) => {})
-
+ Meteor.call('modifyFileDB', 'removeOne', this.props.file._id, (error, result) => { })
- }}>{this.props.symbol} }
- {this.state.isLoadState && {this.props.symbol} : }
+
- sizeUnit={"px"}
- size={25}
- color={'white'}
- loading={true}
- />}
- )}
-
- if (this.props.type == "reScan") {
-
- return (
-
-
- {this.state.isShowState && {
-
-
- this.triggerLoadState();
-
- Meteor.call('modifyFileDB','removeOne',this.props.file._id, (error, result) => {})
-
- var obj = {
- HealthCheck: "Queued",
- TranscodeDecisionMaker: "Queued",
- cliLog: "",
- bumped: false,
- history: ""
- }
- Meteor.call('scanFiles', this.props.file.DB, [this.props.file._id], 0, 3, obj, function (error, result) { });
-
-
- }}>{this.props.symbol} }
-
- {this.state.isLoadState &&
+ {true ? {
+
+
+ this.triggerLoadState();
+
+ Meteor.call('modifyFileDB', 'removeOne', this.props.file._id, (error, result) => { })
+
+ var obj = {
+ HealthCheck: "Queued",
+ TranscodeDecisionMaker: "Queued",
+ cliLog: "",
+ bumped: false,
+ history: ""
+ }
+ Meteor.call('scanFiles', this.props.file.DB, [this.props.file._id], 0, 3, obj, function (error, result) { });
+
+
+ }}>{this.props.symbol} : }
-
-
-
- )}
-
+
+
+
+
+ )
+ }
+
+
}
}
diff --git a/imports/ui/searchResults.jsx b/imports/ui/searchResults.jsx
index 69ec5368..f388a6cb 100644
--- a/imports/ui/searchResults.jsx
+++ b/imports/ui/searchResults.jsx
@@ -14,15 +14,57 @@ import { withTracker } from 'meteor/react-meteor-data';
import JSONPretty from 'react-json-pretty';
import 'react-json-pretty/themes/monikai.css';
+import {
+ BumpButton,
+ SkipButton,
+ SkipHealthCheckButton,
+ CancelBumpButton,
+ RedoButton,
+ ForceProcessingButton,
+ CancelForceProcessingButton,
+ IgnoreButton
+} from './ButtonLibrary/Buttons.jsx'
+
class App extends Component{
+ constructor(props) {
+ super(props);
+ this.state = {
+ lastQueueUpdateTime:1
+ }
+ }
+
renderResults(result){
+ try {
+
+ const g = GlobalSettingsDB.find({}).fetch()[0]
+
+ if (g.lastQueueUpdateTime != undefined) {
+
+ var a = this.state.lastQueueUpdateTime
+ var b = g.lastQueueUpdateTime
+
+ if (a != b) {
+ this.setState({
+ lastQueueUpdateTime: b,
+ })
+
+ }
+
+ }
+ } catch (err) {
+
+ }
+
+
+
+
if ( !result || result.length == 0) {
return
No results
@@ -347,7 +389,7 @@ return null
),
id: 'Bump',
width: 'Bump'.length*10,
- accessor: row => !(row.bumped instanceof Date) ? this.renderBumpButton(row.file):this.renderCancelBumpButton(row.file),
+ accessor: row => !(row.bumped instanceof Date) ?
:
,
getProps: (state, rowInfo, column) => {
return {
style: {
@@ -368,7 +410,7 @@ return null
),
id: 'Create sample',
width: 'Create sample'.length*10,
- accessor: row => this.renderCreateSampleButton(row.file),
+ accessor: row => this.renderCreateSampleButton(row),
getProps: (state, rowInfo, column) => {
return {
style: {
@@ -389,7 +431,7 @@ return null
),
id: 'Transcode',
width: 'Transcode'.length*10,
- accessor: row => row.TranscodeDecisionMaker == "Queued" ?
Queued({row.tPosition}){this.renderSkipButton(row.file)} : this.renderRedoButton(row.file, 'TranscodeDecisionMaker'),
+ accessor: row => row.TranscodeDecisionMaker == "Queued" ?
Queued({row.tPosition}) :
,
getProps: (state, rowInfo, column) => {
return {
style: {
@@ -409,7 +451,7 @@ return null
),
id: 'Health check',
width: 'Health check'.length*10,
- accessor: row => row.HealthCheck == "Queued" ?
Queued({row.hPosition}){this.renderSkipHealthCheckButton(row.file)} : this.renderRedoButton(row.file, 'HealthCheck'),
+ accessor: row => row.HealthCheck == "Queued" ?
Queued({row.hPosition}) :
,
getProps: (state, rowInfo, column) => {
return {
style: {
@@ -485,7 +527,7 @@ return null
),
id: 'forceProcessing',
width: 'forceProcessing'.length*10,
- accessor: row => row.forceProcessing === true ? this.renderCancelForceProcessingButton(row.file) : this.renderForceProcessingButton(row.file),
+ accessor: row => row.forceProcessing === true ?
:
,
getProps: (state, rowInfo, column) => {
return {
style: {
@@ -634,85 +676,100 @@ return null
}
-renderBumpButton(file) {
- var obj = {
- bumped: new Date(),
- }
- return
+// renderBumpButton(file) {
+// var obj = {
+// bumped: new Date(),
+// }
+// return
- }
+// }
- renderSkipButton(file) {
- var obj = {
- TranscodeDecisionMaker:"Transcode success",
- lastTranscodeDate: new Date(),
- }
- return
- }
+ // renderSkipButton(file) {
+ // var obj = {
+ // TranscodeDecisionMaker:"Transcode success",
+ // lastTranscodeDate: new Date(),
+ // }
+ // return
+ // }
- renderSkipHealthCheckButton(file) {
- var obj = {
- HealthCheck: "Success",
- lastHealthCheckDate: new Date(),
- }
- return
- }
+ // renderSkipHealthCheckButton(file) {
+ // var obj = {
+ // HealthCheck: "Success",
+ // lastHealthCheckDate: new Date(),
+ // }
+ // return
+ // }
- renderCancelBumpButton(file) {
- var obj = {
- bumped: false,
- }
- return
- }
+ // renderCancelBumpButton(file) {
+ // var obj = {
+ // bumped: false,
+ // }
+ // return
+ // }
- renderCreateSampleButton(file){
+ // renderRedoButton(file, mode) {
- return
+
+ // var obj = {
+ // [mode]: "Queued",
+ // processingStatus: false,
+ // createdAt: new Date(),
+ // }
+
+
+ // return
+ // }
+
+ // renderForceProcessingButton(file) {
+ // var obj = {
+ // forceProcessing: true,
+ // }
+ // return
+ // }
+
+ // renderCancelForceProcessingButton(file) {
+ // var obj = {
+ // forceProcessing: false,
+ // }
+ // return
+ // }
- }
- renderRedoButton(file, mode) {
-
- var obj = {
- [mode]: "Queued",
- processingStatus: false,
- createdAt: new Date(),
- }
+ // renderIgnoreButton(file, mode) {
+ // var obj = {
+ // [mode]: "Ignored",
+ // processingStatus: false,
+ // createdAt: new Date(),
+ // }
+ // return
+
+
+ // }
- return
- }
- renderForceProcessingButton(file) {
- var obj = {
- forceProcessing: true,
- }
- return
- }
- renderCancelForceProcessingButton(file) {
- var obj = {
- forceProcessing: false,
- }
- return
- }
+ renderCreateSampleButton(file){
+ return
+ }
- renderIgnoreButton(file, mode) {
+ renderRemoveButton(file) {
- var obj = {
- [mode]: "Ignored",
- processingStatus: false,
- createdAt: new Date(),
- }
- return
+ return
+ }
+
+ renderReScanButton(file) {
+
+ return
}
+
renderInfoButton(row) {
var result = []
@@ -799,17 +856,7 @@ renderBumpButton(file) {
}
- renderRemoveButton(file) {
-
- return
- }
-
- renderReScanButton(file) {
-
- return
-
- }
handleChange(event){
diff --git a/imports/ui/transcoding/tab_Transcoding.jsx b/imports/ui/transcoding/tab_Transcoding.jsx
index 99bcd257..e6843263 100644
--- a/imports/ui/transcoding/tab_Transcoding.jsx
+++ b/imports/ui/transcoding/tab_Transcoding.jsx
@@ -29,6 +29,17 @@ import { Markup } from 'interweave';
+import {
+ BumpButton,
+ SkipButton,
+ SkipHealthCheckButton,
+ CancelBumpButton,
+ RedoButton,
+ ForceProcessingButton,
+ CancelForceProcessingButton,
+ IgnoreButton
+} from '../ButtonLibrary/Buttons.jsx'
+
var ButtonStyle = {
@@ -46,7 +57,12 @@ class App extends Component {
constructor(props) {
super(props);
- this.state = { value: true, lowCPU: true, x: 1, }
+ this.state = {
+ value: true,
+ lowCPU: true,
+ x: 1,
+ lastQueueUpdateTime: 1
+ }
@@ -56,54 +72,54 @@ class App extends Component {
- alterWorkerLimit(process,workerType){
+ alterWorkerLimit(process, workerType) {
var globsettings = this.props.globalSettings[0]
- globsettings= globsettings
+ globsettings = globsettings
- if(process == "increase"){
+ if (process == "increase") {
GlobalSettingsDB.update("globalsettings",
- {
- $inc: { [workerType]: 1 }
- }
- );
+ {
+ $inc: { [workerType]: 1 }
+ }
+ );
- }else if(process == "decrease"){
+ } else if (process == "decrease") {
- if(globsettings[workerType] > 0){
+ if (globsettings[workerType] > 0) {
GlobalSettingsDB.update("globalsettings",
- {
- $inc: { [workerType]: -1 }
- }
- );
+ {
+ $inc: { [workerType]: -1 }
+ }
+ );
}
}
}
- renderSlider(slider,sliderColour,sliderColour2) {
+ renderSlider(slider, sliderColour, sliderColour2) {
- if(slider == 'generalWorkerLimit'){
+ if (slider == 'generalWorkerLimit') {
var title = 'General'
- }else if(slider == 'transcodeWorkerLimit'){
+ } else if (slider == 'transcodeWorkerLimit') {
var title = 'Transcode'
- }else if(slider == 'healthcheckWorkerLimit'){
+ } else if (slider == 'healthcheckWorkerLimit') {
var title = 'Health check'
}
-
+
return this.props.globalSettings.map((item, i) => (
@@ -111,7 +127,7 @@ class App extends Component {
{/*
{title}({item[slider]})
*/}
-
+
-
+
));
@@ -192,28 +208,28 @@ class App extends Component {
renderLowCPUButton() {
-
+
return this.props.globalSettings.map((item, i) => (
{
+ thumbStyle={borderRadiusStyle}
+ trackStyle={borderRadiusStyle}
- GlobalSettingsDB.upsert('globalsettings',
- {
- $set: {
- lowCPUPriority: !item.lowCPUPriority,
+ value={item.lowCPUPriority} onToggle={() => {
+
+ GlobalSettingsDB.upsert('globalsettings',
+ {
+ $set: {
+ lowCPUPriority: !item.lowCPUPriority,
+ }
}
- }
- );
- }
- } />
+ );
+ }
+ } />
));
}
- renderSortBox(type){
+ renderSortBox(type) {
return this.props.globalSettings.map((item, i) => (
@@ -248,7 +264,7 @@ class App extends Component {
{
- if(type == `alternateLibraries` && event.target.checked){
+ if (type == `alternateLibraries` && event.target.checked) {
GlobalSettingsDB.upsert(
"globalsettings",
@@ -258,16 +274,16 @@ class App extends Component {
}
}
);
-
+
}
-
- if(type == `prioritiseLibraries` && event.target.checked){
-
+
+ if (type == `prioritiseLibraries` && event.target.checked) {
+
GlobalSettingsDB.upsert(
"globalsettings",
{
$set: {
- alternateLibraries: false,
+ alternateLibraries: false,
}
}
);
@@ -293,10 +309,15 @@ class App extends Component {
componentDidMount() {
- this.interval = setInterval(() => this.renderWorkers(), 500);
- this.interval2 = setInterval(() =>this.getServerTime(), 1000);
+ this.interval = setInterval(() => this.renderWorkers(), 500)
+ this.interval2 = setInterval(() => this.getServerTime(), 1000)
+
+ }
+ componentWillUnmount() {
+ clearInterval(this.interval);
+ clearInterval(this.interval2);
}
@@ -307,6 +328,8 @@ class App extends Component {
}
+
+
renderWorkers = () => {
@@ -347,6 +370,31 @@ class App extends Component {
+ try {
+
+ const g = GlobalSettingsDB.find({}).fetch()[0]
+
+ if (g.lastQueueUpdateTime != undefined) {
+
+ var a = this.state.lastQueueUpdateTime
+ var b = g.lastQueueUpdateTime
+
+ if (a != b) {
+ this.setState({
+ lastQueueUpdateTime: b,
+ })
+
+ }
+
+ }
+ } catch (err) {
+
+ }
+
+
+
+
+
var tables = this.props.clientDB
@@ -384,46 +432,46 @@ class App extends Component {
if (mode == "TranscodeDecisionMaker") {
-
-
- return data.map((row, i) => {
- if(row.file_size != undefined){
- var file_size = parseFloat((row.file_size/1000).toPrecision(4))
- }else{
- var file_size = "-"
- }
- // {row.bumped ? row.bumped.toISOString() : "-"}
+ return data.map((row, i) => {
+
+ if (row.file_size != undefined) {
+ var file_size = parseFloat((row.file_size / 1000).toPrecision(4))
+ } else {
+ var file_size = "-"
+ }
+
+ // {row.bumped ? row.bumped.toISOString() : "-"}
-
- return
- {i + 1}
{row.file}
{row.forceProcessing === true ? this.renderCancelForceProcessingButton(row.file) : this.renderForceProcessingButton(row.file)}
{row.video_codec_name}
{row.video_resolution}
{file_size}
{ !(row.bumped instanceof Date) ? this.renderBumpButton(row.file):this.renderCancelBumpButton(row.file) }
{this.renderSkipButton(row.file)}
+
+ return
+ {i + 1}
{row.file}
{row.forceProcessing === true ? : }
{row.video_codec_name}
{row.video_resolution}
{file_size}
{!(row.bumped instanceof Date) ? : }
- }
- );
+ }
+ );
- }else{
+ } else {
- return data.map((row, i) => {
+ return data.map((row, i) => {
- return
- {i + 1}
{row.file}
{!(row.bumped instanceof Date) ? this.renderBumpButton(row.file):this.renderCancelBumpButton(row.file) }
{this.renderSkipHealthCheckButton(row.file)}
+ return
+ {i + 1}
{row.file}
{!(row.bumped instanceof Date) ? : }
- }
- );
+ }
+ );
- }
+ }
}
if (type == "success") {
@@ -434,30 +482,30 @@ class App extends Component {
return data.map((row, i) => {
- if(row.lastTranscodeDate != undefined){
+ if (row.lastTranscodeDate != undefined) {
var lastTranscodeDate = this.toTime(row.lastTranscodeDate)
- }else{
+ } else {
var lastTranscodeDate = "-"
}
- if(row.oldSize != undefined){
- var oldSize = parseFloat((row.oldSize).toPrecision(4))
- }else{
+ if (row.oldSize != undefined) {
+ var oldSize = parseFloat((row.oldSize).toPrecision(4))
+ } else {
var oldSize = "-"
}
- if(row.newSize != undefined){
- var newSize = parseFloat((row.newSize).toPrecision(4))
- }else{
+ if (row.newSize != undefined) {
+ var newSize = parseFloat((row.newSize).toPrecision(4))
+ } else {
var newSize = "-"
}
-
- return
- {i + 1}
{lastTranscodeDate}
{row.file}
{row.video_codec_name}
{row.video_resolution}
{row.TranscodeDecisionMaker}
{oldSize}
{newSize}
{this.renderRedoButton(row.file, mode)}
{this.renderInfoButton(row.cliLog)}
{this.renderHistoryButton(row)}
+
+ return
+ {i + 1}
{lastTranscodeDate}
{row.file}
{row.video_codec_name}
{row.video_resolution}
{row.TranscodeDecisionMaker}
{oldSize}
{newSize}
{this.renderInfoButton(row.cliLog)}
{this.renderHistoryButton(row)}
@@ -467,14 +515,14 @@ class App extends Component {
return data.map((row, i) => {
- if(row.lastHealthCheckDate != undefined){
+ if (row.lastHealthCheckDate != undefined) {
var lastHealthCheckDate = this.toTime(row.lastHealthCheckDate)
- }else{
+ } else {
var lastHealthCheckDate = "-"
}
-
- return
- {i + 1}
{lastHealthCheckDate}
{row.file}
{this.renderRedoButton(row.file, mode)}
{this.renderInfoButton(row.cliLog)}
+
+ return
+ {i + 1}
{lastHealthCheckDate}
{row.file}
{this.renderInfoButton(row.cliLog)}
@@ -488,39 +536,39 @@ class App extends Component {
if (mode == "TranscodeDecisionMaker") {
- return data.map((row, i) => {
+ return data.map((row, i) => {
- if(row.lastTranscodeDate != undefined){
- var lastTranscodeDate = this.toTime(row.lastTranscodeDate)
- }else{
- var lastTranscodeDate = "-"
- }
+ if (row.lastTranscodeDate != undefined) {
+ var lastTranscodeDate = this.toTime(row.lastTranscodeDate)
+ } else {
+ var lastTranscodeDate = "-"
+ }
- return
- {i + 1}
{lastTranscodeDate}
{row.file}
{this.renderRedoButton(row.file, mode)}
{this.renderIgnoreButton(row.file, mode)}
{this.renderInfoButton(row.cliLog)}
-
+ return
+ {i + 1}
{lastTranscodeDate}
{row.file}
{this.renderInfoButton(row.cliLog)}
+
- });
+ });
- }else{
+ } else {
return data.map((row, i) => {
-
- if(row.lastHealthCheckDate != undefined){
- var lastHealthCheckDate = this.toTime(row.lastHealthCheckDate)
- }else{
- var lastHealthCheckDate = "-"
- }
- return
- {i + 1}
{lastHealthCheckDate}
{row.file}
{this.renderRedoButton(row.file, mode)}
{this.renderIgnoreButton(row.file, mode)}
{this.renderInfoButton(row.cliLog)}
+ if (row.lastHealthCheckDate != undefined) {
+ var lastHealthCheckDate = this.toTime(row.lastHealthCheckDate)
+ } else {
+ var lastHealthCheckDate = "-"
+ }
+
+ return
+ {i + 1}
{lastHealthCheckDate}
{row.file}
{this.renderInfoButton(row.cliLog)}
-
-
- });
+
+
+ });
@@ -545,62 +593,62 @@ class App extends Component {
}
- renderBumpButton(file) {
- var obj = {
- bumped: new Date(),
- }
- return
- }
-
- renderSkipButton(file) {
- var obj = {
- TranscodeDecisionMaker:"Transcode success",
- lastTranscodeDate: new Date(),
- }
- return
- }
-
- renderSkipHealthCheckButton(file) {
- var obj = {
- HealthCheck: "Success",
- lastHealthCheckDate: new Date(),
- }
- return
- }
-
- renderCancelBumpButton(file) {
- var obj = {
- bumped: false,
- }
- return
- }
-
- renderRedoButton(file, mode) {
-
-
- var obj = {
- [mode]: "Queued",
- processingStatus: false,
- createdAt: new Date(),
- }
-
-
- return
- }
-
- renderForceProcessingButton(file) {
- var obj = {
- forceProcessing: true,
- }
- return
- }
-
- renderCancelForceProcessingButton(file) {
- var obj = {
- forceProcessing: false,
- }
- return
- }
+ // renderBumpButton(file) {
+ // var obj = {
+ // bumped: new Date(),
+ // }
+ // return
+ // }
+
+ // renderSkipButton(file) {
+ // var obj = {
+ // TranscodeDecisionMaker: "Transcode success",
+ // lastTranscodeDate: new Date(),
+ // }
+ // return
+ // }
+
+ // renderSkipHealthCheckButton(file) {
+ // var obj = {
+ // HealthCheck: "Success",
+ // lastHealthCheckDate: new Date(),
+ // }
+ // return
+ // }
+
+ // renderCancelBumpButton(file) {
+ // var obj = {
+ // bumped: false,
+ // }
+ // return
+ // }
+
+ // renderRedoButton(file, mode) {
+
+
+ // var obj = {
+ // [mode]: "Queued",
+ // processingStatus: false,
+ // createdAt: new Date(),
+ // }
+
+
+ // return
+ // }
+
+ // renderForceProcessingButton(file) {
+ // var obj = {
+ // forceProcessing: true,
+ // }
+ // return
+ // }
+
+ // renderCancelForceProcessingButton(file) {
+ // var obj = {
+ // forceProcessing: false,
+ // }
+ // return
+ // }
renderIgnoreButton(file, mode) {
@@ -610,38 +658,38 @@ class App extends Component {
processingStatus: false,
createdAt: new Date(),
}
- return
+ return
}
renderInfoButton(cliLog) {
-
- try{
- cliLog = cliLog.split("\n")
+ try {
- cliLog = cliLog.map( row => {row}
)
+ cliLog = cliLog.split("\n")
- return i }
- modal
- closeOnDocumentClick
- >
-
-
+ cliLog = cliLog.map(row => {row}
)
+
+ return i }
+ modal
+ closeOnDocumentClick
+ >
+
+
- }catch(err){
+ } catch (err) {
return null
@@ -652,21 +700,21 @@ class App extends Component {
renderHistoryButton(row) {
- if(row.history == undefined){
- result =""
-
- }else{
+ if (row.history == undefined) {
+ result = ""
+
+ } else {
var result = row.history
result = result.split("\n")
- result = result.map((row, i) => (
-
-
- ));
-
+ result = result.map((row, i) => (
+
+ ));
- }
+
+
+ }
return
-
-
}
- setAllStatus(mode,table,processStatus,text) {
+ setAllStatus(mode, table, processStatus, text) {
if (confirm(`Are you sure you want to ${text} all files?`)) {
- Meteor.call('setAllStatus', 'all', mode,table,processStatus, function (error, result) { })
+ Meteor.call('setAllStatus', 'all', mode, table, processStatus, function (error, result) { })
}
}
@@ -738,168 +786,168 @@ class App extends Component {
-
-
-
-
i }
- modal
- closeOnDocumentClick
- >
-
-
-
+
+
-
-
-
Use the sliders to tell Tdarr to start up and maintain the specified number of workers.
-
Workers which are toggled 'Off' will finish their current item before closing down.
-
If you cancel an item, the worker will move onto the next item in the queue.
+
i }
+ modal
+ closeOnDocumentClick
+ >
+
+
+
-
-
Workers process newest items first and cycle between your libraries.
+
-
General workers process both transcode and health check items. They prioritise health check
-
-
-
+
Use the sliders to tell Tdarr to start up and maintain the specified number of workers.
+
Workers which are toggled 'Off' will finish their current item before closing down.
+
If you cancel an item, the worker will move onto the next item in the queue.
-
Important: Workers will not process items unless they are within the scheduled times set in the library settings.
-
-
-
-
-
+
+ Workers process newest items first and cycle between your libraries.
-
+
General workers process both transcode and health check items. They prioritise health check
+
+
+
-
Workers:
+
Important: Workers will not process items unless they are within the scheduled times set in the library settings.
+
+
+
+
-
+
-
+
Workers:
-
-
-
({this.props.globalSettings && this.props.globalSettings[0] && this.props.globalSettings[0].generalWorkerLimit ? this.props.globalSettings[0].generalWorkerLimit : 0})
-
+
+
-
-{this.renderSlider('generalWorkerLimit','black','#808080')}
-
+
+
({this.props.globalSettings && this.props.globalSettings[0] && this.props.globalSettings[0].generalWorkerLimit ? this.props.globalSettings[0].generalWorkerLimit : 0})
+
-
- this.alterWorkerLimit("decrease","generalWorkerLimit")} >-
- this.alterWorkerLimit("increase","generalWorkerLimit")} >+
-
+
+ {this.renderSlider('generalWorkerLimit', 'black', '#808080')}
+
+
+ this.alterWorkerLimit("decrease", "generalWorkerLimit")} >-
+ this.alterWorkerLimit("increase", "generalWorkerLimit")} >+
+
-
-
-
({this.props.globalSettings && this.props.globalSettings[0] && this.props.globalSettings[0].transcodeWorkerLimit ? this.props.globalSettings[0].transcodeWorkerLimit : 0})
-
+
-
-{this.renderSlider('transcodeWorkerLimit','#66ccff','#B3E6FF')}
-
+
+
({this.props.globalSettings && this.props.globalSettings[0] && this.props.globalSettings[0].transcodeWorkerLimit ? this.props.globalSettings[0].transcodeWorkerLimit : 0})
+
-
- this.alterWorkerLimit("decrease","transcodeWorkerLimit")} >-
- this.alterWorkerLimit("increase","transcodeWorkerLimit")} >+
-
+
+ {this.renderSlider('transcodeWorkerLimit', '#66ccff', '#B3E6FF')}
+
+
+ this.alterWorkerLimit("decrease", "transcodeWorkerLimit")} >-
+ this.alterWorkerLimit("increase", "transcodeWorkerLimit")} >+
+
-
-
-
({this.props.globalSettings && this.props.globalSettings[0] && this.props.globalSettings[0].healthcheckWorkerLimit ? this.props.globalSettings[0].healthcheckWorkerLimit : 0})
-
-
-{this.renderSlider('healthcheckWorkerLimit','#4CAF50','#A6D7A8')}
-
+
-
- this.alterWorkerLimit("decrease","healthcheckWorkerLimit")} >-
- this.alterWorkerLimit("increase","healthcheckWorkerLimit")} >+
-
+
+
({this.props.globalSettings && this.props.globalSettings[0] && this.props.globalSettings[0].healthcheckWorkerLimit ? this.props.globalSettings[0].healthcheckWorkerLimit : 0})
+
-
+
+ {this.renderSlider('healthcheckWorkerLimit', '#4CAF50', '#A6D7A8')}
+
-
+
+ this.alterWorkerLimit("decrease", "healthcheckWorkerLimit")} >-
+ this.alterWorkerLimit("increase", "healthcheckWorkerLimit")} >+
+
+
-
-
{
+
- if (confirm('Are you sure you want to cancel all workers?')) {
- Meteor.call('getWorkers', function (error, result) {
+
- var workers = result
+
{
- for (var i = 0; i < workers.length; i++) {
+ if (confirm('Are you sure you want to cancel all workers?')) {
- Meteor.call('killWorker', workers[i]._id, function (error, result) { })
- }
- });
+ Meteor.call('getWorkers', function (error, result) {
+ var workers = result
- }
- }
- } >Cancel all workers
+ for (var i = 0; i < workers.length; i++) {
-{'\u00A0'}{'\u00A0'}{'\u00A0'}{'\u00A0'}
+ Meteor.call('killWorker', workers[i]._id, function (error, result) { })
+ }
-
-
Low CPU priority:
+ });
- {this.renderLowCPUButton()}
+ }
+ }
+ } >Cancel all workers
-
-
-
+ {'\u00A0'}{'\u00A0'}{'\u00A0'}{'\u00A0'}
-
-
+
+
Low CPU priority:
+
+ {this.renderLowCPUButton()}
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -908,49 +956,49 @@ class App extends Component {
-
-
+
+
-
+
-
i }
- modal
- closeOnDocumentClick
- >
-
-
-
+
i }
+ modal
+ closeOnDocumentClick
+ >
+
+
+
-
-
-
All newly scanned files will be placed in the transcode and health check queues.
-
-
Files in the queues will be sent to available workers.
+
-
For transcodes, if files already meet the codec (etc) requirements they will be marked as 'Not required' in 'Transcode: Success/Not required' tab.
-
-
-
If files don't meet the requirements they will be transcoded. If transcoding is successful files will be marked as 'Transcode success' in the 'Transcode: Success/Not required' tab.
-
+
All newly scanned files will be placed in the transcode and health check queues.
-
-
If transcoding fails or is cancelled then files will be marked accordingly in the 'Transcode: Error/Cancelled' tab.
+
Files in the queues will be sent to available workers.
+
For transcodes, if files already meet the codec (etc) requirements they will be marked as 'Not required' in 'Transcode: Success/Not required' tab.
-
-
+
If files don't meet the requirements they will be transcoded. If transcoding is successful files will be marked as 'Transcode success' in the 'Transcode: Success/Not required' tab.
+
-
The end goal of Tdarr is to be able to run it on your library and all items come out as 'Transcode:Not required', meaning nothing needed to be transcoded/remuxed etc.
+
If transcoding fails or is cancelled then files will be marked accordingly in the 'Transcode: Error/Cancelled' tab.
-
-
-
-
-
-
+
+
+
+
+
+
The end goal of Tdarr is to be able to run it on your library and all items come out as 'Transcode:Not required', meaning nothing needed to be transcoded/remuxed etc.
+
+
+
+
+
+
+
+
@@ -978,197 +1026,197 @@ class App extends Component {
-
Library alternation: {this.renderCheckBox('alternateLibraries')}
-
Library prioritisation: {this.renderCheckBox('prioritiseLibraries')}
+
Library alternation: {this.renderCheckBox('alternateLibraries')}
+
Library prioritisation: {this.renderCheckBox('prioritiseLibraries')}
-
Items: {
-
- GlobalSettingsDB.upsert(
- "globalsettings",
- {
- $set: {
- tableSize: event.target.value,
- }
- }
- );
-}}>
+
Items: {
+ GlobalSettingsDB.upsert(
+ "globalsettings",
+ {
+ $set: {
+ tableSize: event.target.value,
+ }
+ }
+ );
+ }}>
-
-
-
-
- Transcode queue ({this.renderStat('table1Count')})
- Transcode: Success/Not required ({this.renderStat('table2Count')})
- Transcode: Error/Cancelled ({this.renderStat('table3Count')})
- Health check queue ({this.renderStat('table4Count')})
- Health check: Healthy ({this.renderStat('table5Count')})
- Health check: Error/Cancelled ({this.renderStat('table6Count')})
+
+
+ Transcode queue ({this.renderStat('table1Count')})
+ Transcode: Success/Not required ({this.renderStat('table2Count')})
+ Transcode: Error/Cancelled ({this.renderStat('table3Count')})
-
-
-
-
-
- No.
- File
- Force processingi }
- modal
- closeOnDocumentClick
- >
-
-
-
-
-
-
-
All new plugins created in v1.101 will have a new force processing switch which overrides filters (or you'll need to modify existing plugins).
-
-
It will allow for the FIRST plugin's filter in the plugin stack to be overridden. So you need to have your main transcode plugin at the top of your stack.
-
-
So a typical stack might look like:
-
-
(1) Transcode using HandBrake into h264 (Exclude files already in h264)
-
(2) Remove subs
-
(3) Remove closed captions
-
(4) Remux if not in mkv
-
-
Force processing will force the HandBrake transcode plugin on a file (even if it's already in h264) and then the status for force processing is reset to off.
-
-
-
-
-
-
-
-
- Codec
- Resolution
- Size (GB)
- Bump
- this.setAllStatus('TranscodeDecisionMaker','table1','Transcode success','skip')} >Skip
-
- {this.renderTable('table1', 'queue','TranscodeDecisionMaker')}
-
-
+
Health check queue ({this.renderStat('table4Count')})
+
Health check: Healthy ({this.renderStat('table5Count')})
+
Health check: Error/Cancelled ({this.renderStat('table6Count')})
+
+
-
-
-
-
- No.
- Time
- File
- Codec
- Resolution
- Transcode
- Old size (GB)
- New size (GB)
- this.setAllStatus('TranscodeDecisionMaker','table2','Queued','re-queue')} >Re-queue
- Info
- History
+
+
+ No.
+ File
+ Force processingi }
+ modal
+ closeOnDocumentClick
+ >
+
- {this.renderTable('table2', 'success', 'TranscodeDecisionMaker')}
+ All new plugins created in v1.101 will have a new force processing switch which overrides filters (or you'll need to modify existing plugins).
-
-
+ It will allow for the FIRST plugin's filter in the plugin stack to be overridden. So you need to have your main transcode plugin at the top of your stack.
+
+ So a typical stack might look like:
+
+ (1) Transcode using HandBrake into h264 (Exclude files already in h264)
+ (2) Remove subs
+ (3) Remove closed captions
+ (4) Remux if not in mkv
+
+ Force processing will force the HandBrake transcode plugin on a file (even if it's already in h264) and then the status for force processing is reset to off.
-
+
-
-
- No.
- Time
- File
- this.setAllStatus('TranscodeDecisionMaker','table3','Queued','re-queue')} >Re-queue
- Ignore
- Info
+
+
+
+
+ Codec
+ Resolution
+ Size (GB)
+ Bump
+ this.setAllStatus('TranscodeDecisionMaker', 'table1', 'Transcode success', 'skip')} >Skip
-
+
+ {this.renderTable('table1', 'queue', 'TranscodeDecisionMaker')}
+
- {this.renderTable('table3', 'error', 'TranscodeDecisionMaker')}
-
+
+
+
+
+ No.
+ Time
+ File
+ Codec
+ Resolution
+ Transcode
+ Old size (GB)
+ New size (GB)
+ this.setAllStatus('TranscodeDecisionMaker', 'table2', 'Queued', 're-queue')} >Re-queue
+ Info
+ History
-
+
+ {this.renderTable('table2', 'success', 'TranscodeDecisionMaker')}
-
+
+
-
-
- No.
- File
- Bump
- this.setAllStatus('HealthCheck','table4','Success','skip')} >Skip
+
-
- {this.renderTable('table4', 'queue','HealthCheck')}
+
+
+ No.
+ Time
+ File
+ this.setAllStatus('TranscodeDecisionMaker', 'table3', 'Queued', 're-queue')} >Re-queue
+ Ignore
+ Info
-
+
-
-
+ {this.renderTable('table3', 'error', 'TranscodeDecisionMaker')}
-
-
- No.
- Time
- File
- this.setAllStatus('HealthCheck','table5','Queued','re-queue')} >Re-queue
- Info
-
+
- {this.renderTable('table5', 'success', 'HealthCheck')}
+
+
-
+
+
+ No.
+ File
+ Bump
+ this.setAllStatus('HealthCheck', 'table4', 'Success', 'skip')} >Skip
+
+ {this.renderTable('table4', 'queue', 'HealthCheck')}
-
+
-
-
-
- No.
- Time
- File
- this.setAllStatus('HealthCheck','table6','Queued','re-queue')} >Re-queue
- Ignore
- Info
+
-
+
+
+
+
+ No.
+ Time
+ File
+ this.setAllStatus('HealthCheck', 'table5', 'Queued', 're-queue')} >Re-queue
+ Info
+
-
- {this.renderTable('table6', 'error', 'HealthCheck')}
+ {this.renderTable('table5', 'success', 'HealthCheck')}
-
-
-
-
-
+
+
+
+
+
+
+
+
+ No.
+ Time
+ File
+ this.setAllStatus('HealthCheck', 'table6', 'Queued', 're-queue')} >Re-queue
+ Ignore
+ Info
+
+
+
+
+
+
+
+ {this.renderTable('table6', 'error', 'HealthCheck')}
+
+
+
+
+
+
+
);
}
@@ -1186,7 +1234,7 @@ export default withTracker(() => {
globalSettings: GlobalSettingsDB.find({}, {}).fetch(),
- settingsDB:GlobalSettingsDB.find({}, {}).fetch(),
+ settingsDB: GlobalSettingsDB.find({}, {}).fetch(),
clientDB: ClientDB.find({}).fetch(),
statistics: StatisticsDB.find({}).fetch(),
From 97ef617fa33d24a4060c84e2b13f1c15fcd79538 Mon Sep 17 00:00:00 2001
From: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com>
Date: Tue, 11 Feb 2020 23:24:51 +0000
Subject: [PATCH 05/31] Change DB hook name
---
server/main.js | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/server/main.js b/server/main.js
index d5e12a6b..1e848009 100644
--- a/server/main.js
+++ b/server/main.js
@@ -56,7 +56,7 @@ var filesBeingProcessed = []
var backupStatus = false
-var hasFilesDBChanged = true
+var hasDBChanged = true
var workerLaunched = 0
@@ -334,8 +334,7 @@ Meteor.methods({
}
- Meteor.call('FilesDBHasChanged', (error, result) => { })
-
+ Meteor.call('DBHasChanged', (error, result) => { })
},
@@ -881,13 +880,15 @@ function main() {
Meteor.methods({
- 'FilesDBHasChanged'() {
+ 'DBHasChanged'() {
+
+ //console.log('DBHasChanged')
setTimeout(Meteor.bindEnvironment(setHasFilesDBChanged), 1000);
function setHasFilesDBChanged() {
- hasFilesDBChanged = true
+ hasDBChanged = true
}
@@ -3931,12 +3932,12 @@ function main() {
if (doTablesUpdate == false) {
- } else if (hasFilesDBChanged === true) {
+ } else if (hasDBChanged === true) {
//console.log('Updating queues')
- hasFilesDBChanged = false
+ hasDBChanged = false
addFilesToDB = false
@@ -4718,19 +4719,19 @@ function main() {
added: function (document) {
if (!initialising) {
//console.log('doc added');
- Meteor.call('FilesDBHasChanged', (error, result) => { })
+ Meteor.call('DBHasChanged', (error, result) => { })
}
},
changed: function (new_document, old_document) {
if (!initialising) {
//console.log('doc changed');
- Meteor.call('FilesDBHasChanged', (error, result) => { })
+ Meteor.call('DBHasChanged', (error, result) => { })
}
},
removed: function (document) {
if (!initialising) {
//console.log('doc removed');
- Meteor.call('FilesDBHasChanged', (error, result) => { })
+ Meteor.call('DBHasChanged', (error, result) => { })
}
}
});
@@ -4739,19 +4740,19 @@ function main() {
added: function (document) {
if (!initialising) {
//console.log('doc added');
- Meteor.call('FilesDBHasChanged', (error, result) => { })
+ Meteor.call('DBHasChanged', (error, result) => { })
}
},
changed: function (new_document, old_document) {
if (!initialising) {
//console.log('doc changed');
- Meteor.call('FilesDBHasChanged', (error, result) => { })
+ Meteor.call('DBHasChanged', (error, result) => { })
}
},
removed: function (document) {
if (!initialising) {
//console.log('doc removed');
- Meteor.call('FilesDBHasChanged', (error, result) => { })
+ Meteor.call('DBHasChanged', (error, result) => { })
}
}
});
From cd3409e4953450b6a7bc77855f6ea9fba6dcf783 Mon Sep 17 00:00:00 2001
From: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com>
Date: Wed, 12 Feb 2020 07:36:21 +0000
Subject: [PATCH 06/31] Load all plugins into state onload rather than
re-reading files on search
---
imports/ui/plugins/tab_Plugins.jsx | 511 ++++++++++++++++-------------
1 file changed, 287 insertions(+), 224 deletions(-)
diff --git a/imports/ui/plugins/tab_Plugins.jsx b/imports/ui/plugins/tab_Plugins.jsx
index 5f966aaf..332e554f 100644
--- a/imports/ui/plugins/tab_Plugins.jsx
+++ b/imports/ui/plugins/tab_Plugins.jsx
@@ -37,14 +37,36 @@ class App extends Component {
constructor(props) {
super(props);
+ this.state = {
+ pluginsStored: [],
+ };
+
}
componentDidMount() {
- //this.searchPlugins()
+ this.loadPlugins()
+
+ }
+
+ loadPlugins = () => {
+
+ Meteor.call('searchPlugins', '', 'Local', (error, result) => {
+ this.setState({
+ pluginsStored: result[0]
+ });
+
+ })
+
+ Meteor.call('searchPlugins', '', 'Community', (error, result) => {
+
+ var arr = this.state.pluginsStored
+ arr = arr.concat(result[0])
+ this.setState({
+ pluginsStored: arr
+ });
- this.searchPlugins(event, 'Community')
- this.searchPlugins(event, 'Local')
+ })
}
@@ -62,7 +84,7 @@ class App extends Component {
Meteor.call('updatePlugins', ReactDOM.findDOMNode(this.refs.searchStringCommunity).value.trim(), (error, result) => {
- setTimeout((event) => this.searchPlugins(event, 'Community'), 5000);
+ //setTimeout((event) => this.searchPlugins(event, 'Community'), 5000);
})
}
@@ -150,303 +172,344 @@ class App extends Component {
}
);
+
var string = "searchString" + pluginType
+ var searchTerm = ReactDOM.findDOMNode(this.refs[string]).value.trim()
- Meteor.call('searchPlugins', ReactDOM.findDOMNode(this.refs[string]).value.trim(), pluginType, (error, result) => {
+ var result = this.state.pluginsStored.filter(row => {
+ var string = JSON.stringify(row).toLocaleLowerCase()
- if (result[0].length == 0) {
+ if (row.source == pluginType && string.includes(searchTerm.toLocaleLowerCase())) {
- render(
No results
, document.getElementById('searchResults' + result[1]));
- } else {
+ return true
+ }
+ return false
- var data = result[0]
- var pluginType = result[1]
+ })
- const columns = [{
- Header: () => (
-
- ),
- id: 'id',
- width: 80,
- accessor: d =>
- Copy id
- ,
- }, {
+ if (result.length == 0) {
- Header: () => (
-
- ),
- accessor: 'Stage',
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
+ render(
No results
, document.getElementById('searchResults' + pluginType));
+ } else {
+
+
+ var data = result
+ var pluginType = pluginType
+
+ const columns = [{
+ Header: () => (
+
+ ),
+ id: 'id',
+ width: 80,
+ accessor: d =>
+ Copy id
+ ,
+
+
+ }, {
+
+ Header: () => (
+
+ ),
+ accessor: 'Stage',
+ width: 100,
+ getProps: (state, rowInfo, column) => {
+ return {
+ style: {
+ color: "#e1e1e1",
+ fontSize: "14px",
+ },
}
+ }
- }, {
+ }, {
- Header: () => (
-
- ),
- accessor: 'Type',
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
+ Header: () => (
+
+ ),
+ accessor: 'Type',
+ width: 100,
+ getProps: (state, rowInfo, column) => {
+ return {
+ style: {
+ color: "#e1e1e1",
+ fontSize: "14px",
+ },
}
+ }
- }, {
+ }, {
- Header: () => (
-
- ),
- accessor: 'Operation',
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
+ Header: () => (
+
+ ),
+ accessor: 'Operation',
+ width: 100,
+ getProps: (state, rowInfo, column) => {
+ return {
+ style: {
+ color: "#e1e1e1",
+ fontSize: "14px",
+ },
}
+ }
- }, {
+ }, {
- Header: () => (
-
- ),
- accessor: 'Name',
- width: 200,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
+ Header: () => (
+
+ ),
+ accessor: 'Name',
+ width: 200,
+ getProps: (state, rowInfo, column) => {
+ return {
+ style: {
+ color: "#e1e1e1",
+ fontSize: "14px",
+ },
}
+ }
- },
+ },
- {
+ {
- Header: () => (
-
- ),
- accessor: 'Description',
+ Header: () => (
+
+ ),
+ accessor: 'Description',
- id: 'Description',
- style: { 'white-space': 'unset' },
+ id: 'Description',
+ style: { 'white-space': 'unset' },
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- background: rowInfo && rowInfo.row.Description.includes("BUG") ? '#c72c53' : rowInfo && rowInfo.row.Description.includes("TESTING") ? '#ffa500' : null,
- },
- }
+ getProps: (state, rowInfo, column) => {
+ return {
+ style: {
+ color: "#e1e1e1",
+ fontSize: "14px",
+ background: rowInfo && rowInfo.row.Description.includes("BUG") ? '#c72c53' : rowInfo && rowInfo.row.Description.includes("TESTING") ? '#ffa500' : null,
+ },
}
+ }
- },
- {
- Header: () => (
-
- ),
- id: 'Inputs',
- width: 80,
- accessor: row => {
-
- if (row.Inputs == undefined) {
- return
- }
+ },
+ {
+ Header: () => (
+
+ ),
+ id: 'Inputs',
+ width: 80,
+ accessor: row => {
- var variableArray = row.Inputs
+ if (row.Inputs == undefined) {
+ return
+ }
+ var variableArray = row.Inputs
- var desc = variableArray.map(row => {
- var tooltip = row.tooltip.split('\\n')
+ var desc = variableArray.map(row => {
+ var tooltip = row.tooltip.split('\\n')
- for (var i = 0; i < tooltip.length; i++) {
- var current = i
+ for (var i = 0; i < tooltip.length; i++) {
- if (tooltip[i].includes('Example:') && i+1 < tooltip.length) {
- tooltip[i + 1] =
- i++
- }
+ var current = i
- tooltip[current] =
{tooltip[current]}
+ if (tooltip[i].includes('Example:') && i + 1 < tooltip.length) {
+ tooltip[i + 1] =
+ i++
}
- return
i }
- modal
- closeOnDocumentClick
- >
-
-
-
+ tooltip[current] =
{tooltip[current]}
+ }
+
+ return
i }
+ modal
+ closeOnDocumentClick
+ >
+
+
+
-
-
Usage:
-
-
- {tooltip}
+
+
Usage:
+
+
+ {tooltip}
-
-
{row.name}
- })
+
+
{row.name}
+ })
- return desc
+ return desc
- },
- style: { 'whiteSpace': 'unset' }
},
- {
+ style: { 'whiteSpace': 'unset' }
+ },
+ {
- Header: () => (
-
- ),
- accessor: 'Version',
- width: 100,
-
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
+ Header: () => (
+
+ ),
+ accessor: 'Version',
+ width: 100,
+
+ getProps: (state, rowInfo, column) => {
+ return {
+ style: {
+ color: "#e1e1e1",
+ fontSize: "14px",
+ },
}
+ }
- }, {
- show: pluginType == "Local" ? true : false,
- Header: () => (
-
- ),
- accessor: '',
- id: 'Delete',
- width: 70,
- accessor: d =>
{
- Meteor.call('deletePlugin', d.id, (error, result) => {
- if (result === true) {
+ }, {
+ show: pluginType == "Local" ? true : false,
+ Header: () => (
+
+ ),
+ accessor: '',
+ id: 'Delete',
+ width: 70,
+ accessor: d => {
- alert('Plugin deleted successfully!')
+
- } else {
+ var arr = this.state.pluginsStored
- alert('Error deleting plugin. Please delete manually.')
+ var idx = arr.findIndex(row => row.id == d.id)
- }
+ if(idx != -1){
- this.searchPlugins(event, 'Local')
+ arr.splice(idx,1)
- })
- }} >X ,
+ }
+
+ this.setState({
+ pluginsStored: arr
+ });
- }, {
+ Meteor.call('deletePlugin', d.id, (error, result) => {
+ if (result === true) {
- show: pluginType == "Community" ? true : false,
- Header: () => (
-
- ),
- accessor: 'Stars',
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
- }
+ alert('Plugin deleted successfully!')
+
+ } else {
+
+ alert('Error deleting plugin. Please delete manually.')
- }, {
- show: pluginType == "Community" ? true : false,
- Header: () => (
-
- ),
- id: 'Link',
- accessor: row => {
- e.preventDefault();
- window.open(row.Link, "_blank")
- }}>{row.Link}
,
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
}
+
+ this.searchPlugins(event, 'Local')
+
+ })
+ }} >X ,
+
+
+ }, {
+
+ show: pluginType == "Community" ? true : false,
+ Header: () => (
+
+ ),
+ accessor: 'Stars',
+ width: 100,
+ getProps: (state, rowInfo, column) => {
+ return {
+ style: {
+ color: "#e1e1e1",
+ fontSize: "14px",
+ },
}
+ }
+ }, {
+ show: pluginType == "Community" ? true : false,
+ Header: () => (
+
+ ),
+ id: 'Link',
+ accessor: row =>
{
+ e.preventDefault();
+ window.open(row.Link, "_blank")
+ }}>{row.Link}
,
+ width: 100,
+ getProps: (state, rowInfo, column) => {
+ return {
+ style: {
+ color: "#e1e1e1",
+ fontSize: "14px",
+ },
+ }
}
+ }
+
+
+ ]
+
+ render(
+
+
, document.getElementById('searchResults' + pluginType));
- ]
- render(
-
-
, document.getElementById('searchResults' + result[1]));
+ }
+
+ GlobalSettingsDB.upsert('globalsettings',
+ {
+ $set: {
+ pluginSearchLoading: false,
}
+ }
+ );
- })
} catch (err) {
GlobalSettingsDB.upsert('globalsettings',
{
From 60383733820fe54c3f7317335b6bec9b525bd1d7 Mon Sep 17 00:00:00 2001
From: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com>
Date: Wed, 12 Feb 2020 11:09:21 +0000
Subject: [PATCH 07/31] Put workers in flexbox
---
imports/ui/styles/main.scss | 4 ++--
imports/ui/transcoding/tab_Transcoding_Worker.jsx | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/imports/ui/styles/main.scss b/imports/ui/styles/main.scss
index f31faf22..e4cf1ddd 100644
--- a/imports/ui/styles/main.scss
+++ b/imports/ui/styles/main.scss
@@ -424,8 +424,8 @@ input[type="text"]
margin: auto;
display: 'inline-block';
- display: grid;
- grid-template-columns: repeat(3, 1fr);
+ display: flex;
+ flex-wrap: wrap;
}
.workerItemsGrid{
diff --git a/imports/ui/transcoding/tab_Transcoding_Worker.jsx b/imports/ui/transcoding/tab_Transcoding_Worker.jsx
index 73ee3763..e17c7464 100644
--- a/imports/ui/transcoding/tab_Transcoding_Worker.jsx
+++ b/imports/ui/transcoding/tab_Transcoding_Worker.jsx
@@ -10,7 +10,7 @@ import { render } from 'react-dom';
import ToggleButton from 'react-toggle-button'
-var path = require('path')
+const path = require('path')
var ButtonStyle = {
display: 'inline-block',
From 11a9a0cddfcc7b180cb597fedbad8fe1bcda2237 Mon Sep 17 00:00:00 2001
From: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com>
Date: Wed, 12 Feb 2020 11:45:58 +0000
Subject: [PATCH 08/31] Plugin organisation
---
imports/ui/plugins/PluginCategory.jsx | 371 +++++++++++++++++++++++
imports/ui/plugins/tab_Plugins.jsx | 413 +++-----------------------
imports/ui/styles/main.scss | 42 ++-
3 files changed, 446 insertions(+), 380 deletions(-)
create mode 100644 imports/ui/plugins/PluginCategory.jsx
diff --git a/imports/ui/plugins/PluginCategory.jsx b/imports/ui/plugins/PluginCategory.jsx
new file mode 100644
index 00000000..1e73a50c
--- /dev/null
+++ b/imports/ui/plugins/PluginCategory.jsx
@@ -0,0 +1,371 @@
+import React, { Component } from 'react';
+import { Button } from 'react-bootstrap';
+import { CopyToClipboard } from 'react-copy-to-clipboard';
+import Modal from "reactjs-popup";
+
+// App component - represents the whole app
+export default class App extends Component {
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ selectedNav: 'All',
+ };
+
+ }
+
+ componentDidMount() {
+
+
+ }
+
+ renderPlugins(pluginType, cattags) {
+
+ //'h265,hevc'
+
+
+ var result = this.props.pluginsStoredFiltered
+
+ if (result.length == 0) {
+
+ return
No plugins
+
+
+ } else {
+
+ result = this.props.pluginsStoredFiltered.filter(row => {
+ if (row.source == pluginType) {
+ return true
+ }
+ return false
+ })
+
+
+
+ cattags = cattags.split(',')
+
+ result = result.filter(row => {
+
+ // console.log(row)
+
+ var plugTags = row.Tags
+
+ try {
+ plugTags.split(',').map(row => row.toLowerCase())
+ } catch (err) {
+ plugTags = ['']
+ }
+
+ for (var i = 0; i < cattags.length; i++) {
+ if (plugTags.includes(cattags[i].toLowerCase()))
+
+ return true
+
+ }
+
+ return false
+
+ })
+
+
+
+ result = result.map(row =>
+
+
{row.Name}
+
+
+
{row.Description}
+
+
+
+
+
+ Copy id
+ {'\u00A0'}
+ {row.Inputs ?
Configurable }
+ modal
+ closeOnDocumentClick
+ >
+
+
+
+
+
+ {row.Inputs.map(row => {
+
+ var tooltip = row.tooltip.split('\\n')
+
+
+
+ for (var i = 0; i < tooltip.length; i++) {
+
+ var current = i
+
+ if (tooltip[i].includes('Example:') && i + 1 < tooltip.length) {
+ tooltip[i + 1] =
+ i++
+ }
+
+ tooltip[current] =
{tooltip[current]}
+ }
+
+ return
+
+
{row.name}
+
+ {tooltip}
+
+
+
+
+
+
+
+
+
+ })}
+
+
+
+
+
+
+
+
+
+ : null}
+
+
+
+
+
+
+
)
+
+ return
{result}
+
+
+ }
+ }
+
+
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{
+ this.setState({ selectedNav: 'All' })
+ }} className={this.state && this.state.selectedNav == "All" ? 'selectedNav' : 'unselectedNav'}>All
+
+
+
+
+
+
{
+ this.setState({ selectedNav: 'H265/HEVC' })
+ }} className={this.state && this.state.selectedNav == "H265/HEVC" ? 'selectedNav' : 'unselectedNav'}>H265/HEVC
+
+
+
{
+ this.setState({ selectedNav: 'H264' })
+ }} className={this.state && this.state.selectedNav == "H264" ? 'selectedNav' : 'unselectedNav'}>H264
+
+
+
+
+
+
+
+
+
{
+ this.setState({ selectedNav: 'NVENC H265' })
+ }} className={this.state && this.state.selectedNav == "NVENC H265" ? 'selectedNav' : 'unselectedNav'}>NVENC H265
+
+
+
+
{
+ this.setState({ selectedNav: 'NVENC H264' })
+ }} className={this.state && this.state.selectedNav == "NVENC H264" ? 'selectedNav' : 'unselectedNav'}>NVENC H264
+
+
+
+
+
+
+
{
+ this.setState({ selectedNav: 'Video only' })
+ }} className={this.state && this.state.selectedNav == "Video only" ? 'selectedNav' : 'unselectedNav'}>Video only
+
+
+
{
+ this.setState({ selectedNav: 'Audio only' })
+ }} className={this.state && this.state.selectedNav == "Audio only" ? 'selectedNav' : 'unselectedNav'}>Audio only
+
+
{
+ this.setState({ selectedNav: 'Subtitle only' })
+ }} className={this.state && this.state.selectedNav == "Subtitle only" ? 'selectedNav' : 'unselectedNav'}>Subtitle only
+
+
+
+
+
+
+
+
+
{
+ this.setState({ selectedNav: 'HandBrake' })
+ }} className={this.state && this.state.selectedNav == "HandBrake" ? 'selectedNav' : 'unselectedNav'}>HandBrake
+
+
+
+
{
+ this.setState({ selectedNav: 'FFmpeg' })
+ }} className={this.state && this.state.selectedNav == "FFmpeg" ? 'selectedNav' : 'unselectedNav'}>FFmpeg
+
+
+
+
+
+
+
{
+ this.setState({ selectedNav: 'Radarr' })
+ }} className={this.state && this.state.selectedNav == "Radarr" ? 'selectedNav' : 'unselectedNav'}>Radarr
+
+
{
+ this.setState({ selectedNav: 'Sonarr' })
+ }} className={this.state && this.state.selectedNav == "Sonarr" ? 'selectedNav' : 'unselectedNav'}>Sonarr
+
+
+
+
+
+
+
{
+ this.setState({ selectedNav: 'Pre-processing' })
+ }} className={this.state && this.state.selectedNav == "Pre-processing" ? 'selectedNav' : 'unselectedNav'}>Pre-processing
+
+
+
+
{
+ this.setState({ selectedNav: 'Post-processing' })
+ }} className={this.state && this.state.selectedNav == "Post-processing" ? 'selectedNav' : 'unselectedNav'}>Post-processing
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, '')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'h265,hevc')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'h264')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'nvenc h265')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'nvenc h264')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'video only')}
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'audio only')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'subtitle only')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'handbrake')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'ffmpeg')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'radarr')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'sonarr')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'pre-processing')}
+
+
+
+
+ {this.renderPlugins(this.props.pluginType, 'post-processing')}
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+
+
diff --git a/imports/ui/plugins/tab_Plugins.jsx b/imports/ui/plugins/tab_Plugins.jsx
index 332e554f..bb11efa8 100644
--- a/imports/ui/plugins/tab_Plugins.jsx
+++ b/imports/ui/plugins/tab_Plugins.jsx
@@ -2,9 +2,6 @@ import React, { Component } from 'react';
import { withTracker } from 'meteor/react-meteor-data';
import ReactDOM from 'react-dom';
import { render } from 'react-dom';
-import ReactTable from "react-table";
-
-import { CopyToClipboard } from 'react-copy-to-clipboard';
import { Button } from 'react-bootstrap';
import Modal from "reactjs-popup";
@@ -13,6 +10,8 @@ import { GlobalSettingsDB } from '../../api/tasks.js';
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
+import PluginCategory from './PluginCategory.jsx'
+
@@ -39,6 +38,7 @@ class App extends Component {
this.state = {
pluginsStored: [],
+ pluginsStoredFiltered:[],
};
}
@@ -63,7 +63,8 @@ class App extends Component {
var arr = this.state.pluginsStored
arr = arr.concat(result[0])
this.setState({
- pluginsStored: arr
+ pluginsStored: arr,
+ pluginsStoredFiltered: arr
});
})
@@ -108,10 +109,10 @@ class App extends Component {
this.searchPlugins(event, pluginType)} style={ButtonStyle}>Search {'\u00A0'}
-
{
+ {/* {
render('', document.getElementById('searchResults' + pluginType));
- }} style={ButtonStyle}>Clear {'\u00A0'}
+ }} style={ButtonStyle}>Clear {'\u00A0'} */}
{pluginType == "Community" ?
Update community plugins : null}
@@ -157,6 +158,9 @@ class App extends Component {
searchPlugins = (event, pluginType) => {
+
+ console.log('here')
+
try {
if (event) {
@@ -176,341 +180,39 @@ class App extends Component {
var string = "searchString" + pluginType
var searchTerm = ReactDOM.findDOMNode(this.refs[string]).value.trim()
- var result = this.state.pluginsStored.filter(row => {
-
- var string = JSON.stringify(row).toLocaleLowerCase()
-
-
- if (row.source == pluginType && string.includes(searchTerm.toLocaleLowerCase())) {
+ //row.source == pluginType &&
+ var result = this.state.pluginsStored.filter(row => {
+ var string = JSON.stringify(row).toLowerCase()
+ if (string.includes(searchTerm.toLowerCase())) {
return true
}
-
return false
-
})
- if (result.length == 0) {
-
- render(
No results
, document.getElementById('searchResults' + pluginType));
- } else {
-
-
- var data = result
- var pluginType = pluginType
-
- const columns = [{
- Header: () => (
-
- ),
- id: 'id',
- width: 80,
- accessor: d =>
- Copy id
- ,
-
-
- }, {
-
- Header: () => (
-
- ),
- accessor: 'Stage',
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
- }
-
- }, {
-
- Header: () => (
-
- ),
- accessor: 'Type',
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
- }
-
- }, {
-
- Header: () => (
-
- ),
- accessor: 'Operation',
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
- }
-
- }, {
-
- Header: () => (
-
- ),
- accessor: 'Name',
- width: 200,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
- }
-
- },
-
- {
-
- Header: () => (
-
- ),
- accessor: 'Description',
-
- id: 'Description',
- style: { 'white-space': 'unset' },
-
-
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- background: rowInfo && rowInfo.row.Description.includes("BUG") ? '#c72c53' : rowInfo && rowInfo.row.Description.includes("TESTING") ? '#ffa500' : null,
- },
- }
- }
-
- },
- {
- Header: () => (
-
- ),
- id: 'Inputs',
- width: 80,
- accessor: row => {
-
- if (row.Inputs == undefined) {
- return
- }
-
- var variableArray = row.Inputs
-
-
- var desc = variableArray.map(row => {
-
- var tooltip = row.tooltip.split('\\n')
-
+ this.setState({
+ pluginsStoredFiltered:result
+ })
- for (var i = 0; i < tooltip.length; i++) {
-
- var current = i
-
- if (tooltip[i].includes('Example:') && i + 1 < tooltip.length) {
- tooltip[i + 1] =
- i++
- }
-
- tooltip[current] =
{tooltip[current]}
- }
-
- return
i }
- modal
- closeOnDocumentClick
- >
-
-
-
-
-
Usage:
-
-
- {tooltip}
-
-
-
-
- {row.name}
- })
-
- return desc
-
- },
- style: { 'whiteSpace': 'unset' }
- },
+ GlobalSettingsDB.upsert('globalsettings',
{
-
- Header: () => (
-
- ),
- accessor: 'Version',
- width: 100,
-
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
- }
-
- }, {
- show: pluginType == "Local" ? true : false,
- Header: () => (
-
- ),
- accessor: '',
- id: 'Delete',
- width: 70,
- accessor: d =>
{
-
-
-
- var arr = this.state.pluginsStored
-
- var idx = arr.findIndex(row => row.id == d.id)
-
- if(idx != -1){
-
- arr.splice(idx,1)
-
- }
-
- this.setState({
- pluginsStored: arr
- });
-
-
- Meteor.call('deletePlugin', d.id, (error, result) => {
- if (result === true) {
-
- alert('Plugin deleted successfully!')
-
- } else {
-
- alert('Error deleting plugin. Please delete manually.')
-
- }
-
- this.searchPlugins(event, 'Local')
-
- })
- }} >X ,
-
-
- }, {
-
- show: pluginType == "Community" ? true : false,
- Header: () => (
-
- ),
- accessor: 'Stars',
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
- }
-
- }, {
- show: pluginType == "Community" ? true : false,
- Header: () => (
-
- ),
- id: 'Link',
- accessor: row =>
{
- e.preventDefault();
- window.open(row.Link, "_blank")
- }}>{row.Link}
,
- width: 100,
- getProps: (state, rowInfo, column) => {
- return {
- style: {
- color: "#e1e1e1",
- fontSize: "14px",
- },
- }
+ $set: {
+ pluginSearchLoading: false,
}
-
}
+ );
- ]
-
- render(
-
-
, document.getElementById('searchResults' + pluginType));
-
-
-
-
-
-
- }
-
- GlobalSettingsDB.upsert('globalsettings',
- {
- $set: {
- pluginSearchLoading: false,
- }
- }
- );
+
} catch (err) {
+ console.log(err)
GlobalSettingsDB.upsert('globalsettings',
{
$set: {
@@ -518,7 +220,11 @@ class App extends Component {
}
}
);
+
+
}
+
+
}
@@ -574,13 +280,11 @@ class App extends Component {
+
-
-
-
+
+
@@ -608,12 +312,12 @@ class App extends Component {
-
-
+
+
-
+
@@ -664,17 +368,6 @@ class App extends Component {
-
-
-
-
-
-
-
-
-
-
-
@@ -702,51 +395,15 @@ class App extends Component {
-
-
-
-
-
- {/*
-
-
-
-
-
-
-
-
*/}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/imports/ui/styles/main.scss b/imports/ui/styles/main.scss
index e4cf1ddd..380ff3b4 100644
--- a/imports/ui/styles/main.scss
+++ b/imports/ui/styles/main.scss
@@ -437,6 +437,7 @@ input[type="text"]
display: 'inline-block';
border-radius: 5px;
+ width:400px;
}
.borderStyleGeneral{
@@ -948,6 +949,44 @@ table.sliderTable td {
}
+.box {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.pluginCard{
+
+ border: 1px solid white;
+ border-radius: 5px;
+ margin:1em;
+ width:300px;
+ height:400px;
+ word-wrap: break-word;
+ padding:0.5em;
+ position: relative;
+ box-shadow: 3px 3px grey;
+
+
+}
+
+.pluginCardBottom{
+ position: absolute;
+ bottom: 1px;
+ left: 2px;
+}
+
+.pluginModal{
+
+ border-bottom: 1px solid black;
+
+}
+
+.pluginInput{
+ color:green;
+}
+
+
+
table.sliderTable {
border-radius: 5px;
width: 100%;
@@ -1086,8 +1125,7 @@ table.pluginStackTable td {
.pluginTabGrid-itemRight {
width:100%;
- padding: 0 0 0 2em
-
+ padding: 0 0 0 2em;
}
From 4e96df53d3414ef4727f6cbebb86d9ae1c58171f Mon Sep 17 00:00:00 2001
From: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com>
Date: Thu, 13 Feb 2020 01:31:41 +0000
Subject: [PATCH 09/31] Plugin cards
---
imports/ui/plugins/PluginCategory.jsx | 180 ++++++++++++++++----------
imports/ui/plugins/tab_Plugins.jsx | 8 +-
imports/ui/styles/main.scss | 7 +
3 files changed, 123 insertions(+), 72 deletions(-)
diff --git a/imports/ui/plugins/PluginCategory.jsx b/imports/ui/plugins/PluginCategory.jsx
index 1e73a50c..bb42007f 100644
--- a/imports/ui/plugins/PluginCategory.jsx
+++ b/imports/ui/plugins/PluginCategory.jsx
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { Button } from 'react-bootstrap';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import Modal from "reactjs-popup";
+import ClipLoader from 'react-spinners/ClipLoader';
// App component - represents the whole app
export default class App extends Component {
@@ -11,16 +12,24 @@ export default class App extends Component {
this.state = {
selectedNav: 'All',
+ showPlugin:false,
};
}
+
+
componentDidMount() {
+ setTimeout(this.showPluginCard, 1000);
+
+ }
+ showPluginCard = () => {
+ this.setState({showPlugin:true,})
}
- renderPlugins(pluginType, cattags) {
+ renderPlugins(returnCount, pluginType, cattags) {
//'h265,hevc'
@@ -29,7 +38,13 @@ export default class App extends Component {
if (result.length == 0) {
- return
No plugins
+ if (returnCount) {
+ return 0
+ } else {
+ return
No plugins
+ }
+
+
} else {
@@ -47,7 +62,7 @@ export default class App extends Component {
result = result.filter(row => {
- // console.log(row)
+ // console.log(row)
var plugTags = row.Tags
@@ -68,10 +83,14 @@ export default class App extends Component {
})
+ if (returnCount) {
+ return result.length
+ }
- result = result.map(row =>
-
+
+ result = result.map(row =>
+
{row.Name}
@@ -80,24 +99,24 @@ export default class App extends Component {
-
- Copy id
- {'\u00A0'}
- {row.Inputs ?
Configurable }
- modal
- closeOnDocumentClick
- >
-
-
-
-
+
+ Copy id
+ {'\u00A0'}
+ {row.Inputs ?
Configurable }
+ modal
+ closeOnDocumentClick
+ >
+
+
+
+
- {row.Inputs.map(row => {
+ {row.Inputs.map(input => {
+
+ var tooltip = input.tooltip.split('\\n')
- var tooltip = row.tooltip.split('\\n')
-
for (var i = 0; i < tooltip.length; i++) {
@@ -113,38 +132,58 @@ export default class App extends Component {
return
-
{row.name}
+
{input.name}
{tooltip}
-
-
-
+
+
+
})}
-
-
-
-
+
+
- : null}
-
+
+
+ : null}
+
+
Tags:{row.Tags}
+
+
+
+
+
+
+
-
)
- return
{result}
+ return
{result}
}
@@ -170,105 +209,110 @@ export default class App extends Component {
{
this.setState({ selectedNav: 'All' })
- }} className={this.state && this.state.selectedNav == "All" ? 'selectedNav' : 'unselectedNav'}>All
+ }} className={this.state && this.state.selectedNav == "All" ? 'selectedNav' : 'unselectedNav'}>All ({this.renderPlugins(true, this.props.pluginType, '')})
-
+
{
this.setState({ selectedNav: 'H265/HEVC' })
- }} className={this.state && this.state.selectedNav == "H265/HEVC" ? 'selectedNav' : 'unselectedNav'}>H265/HEVC
+ }} className={this.state && this.state.selectedNav == "H265/HEVC" ? 'selectedNav' : 'unselectedNav'}>H265/HEVC ({this.renderPlugins(true, this.props.pluginType, 'h265,hevc')})
{
this.setState({ selectedNav: 'H264' })
- }} className={this.state && this.state.selectedNav == "H264" ? 'selectedNav' : 'unselectedNav'}>H264
+ }} className={this.state && this.state.selectedNav == "H264" ? 'selectedNav' : 'unselectedNav'}>H264 ({this.renderPlugins(true, this.props.pluginType, 'h264')})
-
+
{
this.setState({ selectedNav: 'NVENC H265' })
- }} className={this.state && this.state.selectedNav == "NVENC H265" ? 'selectedNav' : 'unselectedNav'}>NVENC H265
+ }} className={this.state && this.state.selectedNav == "NVENC H265" ? 'selectedNav' : 'unselectedNav'}>NVENC H265 ({this.renderPlugins(true, this.props.pluginType, 'nvenc h265')})
{
this.setState({ selectedNav: 'NVENC H264' })
- }} className={this.state && this.state.selectedNav == "NVENC H264" ? 'selectedNav' : 'unselectedNav'}>NVENC H264
+ }} className={this.state && this.state.selectedNav == "NVENC H264" ? 'selectedNav' : 'unselectedNav'}>NVENC H264 ({this.renderPlugins(true, this.props.pluginType, 'nvenc h264')})
-
+
{
this.setState({ selectedNav: 'Video only' })
- }} className={this.state && this.state.selectedNav == "Video only" ? 'selectedNav' : 'unselectedNav'}>Video only
+ }} className={this.state && this.state.selectedNav == "Video only" ? 'selectedNav' : 'unselectedNav'}>Video only ({this.renderPlugins(true, this.props.pluginType, 'video only')})
{
this.setState({ selectedNav: 'Audio only' })
- }} className={this.state && this.state.selectedNav == "Audio only" ? 'selectedNav' : 'unselectedNav'}>Audio only
+ }} className={this.state && this.state.selectedNav == "Audio only" ? 'selectedNav' : 'unselectedNav'}>Audio only ({this.renderPlugins(true, this.props.pluginType, 'audio only')})
{
this.setState({ selectedNav: 'Subtitle only' })
- }} className={this.state && this.state.selectedNav == "Subtitle only" ? 'selectedNav' : 'unselectedNav'}>Subtitle only
+ }} className={this.state && this.state.selectedNav == "Subtitle only" ? 'selectedNav' : 'unselectedNav'}>Subtitle only ({this.renderPlugins(true, this.props.pluginType, 'subtitle only')})
-
+
{
this.setState({ selectedNav: 'HandBrake' })
- }} className={this.state && this.state.selectedNav == "HandBrake" ? 'selectedNav' : 'unselectedNav'}>HandBrake
+ }} className={this.state && this.state.selectedNav == "HandBrake" ? 'selectedNav' : 'unselectedNav'}>HandBrake ({this.renderPlugins(true, this.props.pluginType, 'handbrake')})
{
this.setState({ selectedNav: 'FFmpeg' })
- }} className={this.state && this.state.selectedNav == "FFmpeg" ? 'selectedNav' : 'unselectedNav'}>FFmpeg
+ }} className={this.state && this.state.selectedNav == "FFmpeg" ? 'selectedNav' : 'unselectedNav'}>FFmpeg ({this.renderPlugins(true, this.props.pluginType, 'ffmpeg')})
-
+
{
this.setState({ selectedNav: 'Radarr' })
- }} className={this.state && this.state.selectedNav == "Radarr" ? 'selectedNav' : 'unselectedNav'}>Radarr
+ }} className={this.state && this.state.selectedNav == "Radarr" ? 'selectedNav' : 'unselectedNav'}>Radarr ({this.renderPlugins(true, this.props.pluginType, 'radarr')})
{
this.setState({ selectedNav: 'Sonarr' })
- }} className={this.state && this.state.selectedNav == "Sonarr" ? 'selectedNav' : 'unselectedNav'}>Sonarr
+ }} className={this.state && this.state.selectedNav == "Sonarr" ? 'selectedNav' : 'unselectedNav'}>Sonarr ({this.renderPlugins(true, this.props.pluginType, 'sonarr')})
-
+
{
this.setState({ selectedNav: 'Pre-processing' })
- }} className={this.state && this.state.selectedNav == "Pre-processing" ? 'selectedNav' : 'unselectedNav'}>Pre-processing
+ }} className={this.state && this.state.selectedNav == "Pre-processing" ? 'selectedNav' : 'unselectedNav'}>Pre-processing ({this.renderPlugins(true, this.props.pluginType, 'pre-processing')})
{
this.setState({ selectedNav: 'Post-processing' })
- }} className={this.state && this.state.selectedNav == "Post-processing" ? 'selectedNav' : 'unselectedNav'}>Post-processing
+ }} className={this.state && this.state.selectedNav == "Post-processing" ? 'selectedNav' : 'unselectedNav'}>Post-processing ({this.renderPlugins(true, this.props.pluginType, 'post-processing')})
+
{
+ this.setState({ selectedNav: 'Configurable' })
+ }} className={this.state && this.state.selectedNav == "Configurable" ? 'selectedNav' : 'unselectedNav'}>Configurable ({this.renderPlugins(true, this.props.pluginType, 'configurable')})
+
+
@@ -288,71 +332,75 @@ export default class App extends Component {
- {this.renderPlugins(this.props.pluginType, '')}
+ {this.renderPlugins(false, this.props.pluginType, '')}
- {this.renderPlugins(this.props.pluginType, 'h265,hevc')}
+ {this.renderPlugins(false, this.props.pluginType, 'h265,hevc')}
- {this.renderPlugins(this.props.pluginType, 'h264')}
+ {this.renderPlugins(false, this.props.pluginType, 'h264')}
- {this.renderPlugins(this.props.pluginType, 'nvenc h265')}
+ {this.renderPlugins(false, this.props.pluginType, 'nvenc h265')}
- {this.renderPlugins(this.props.pluginType, 'nvenc h264')}
+ {this.renderPlugins(false, this.props.pluginType, 'nvenc h264')}
- {this.renderPlugins(this.props.pluginType, 'video only')}
+ {this.renderPlugins(false, this.props.pluginType, 'video only')}
- {this.renderPlugins(this.props.pluginType, 'audio only')}
+ {this.renderPlugins(false, this.props.pluginType, 'audio only')}
- {this.renderPlugins(this.props.pluginType, 'subtitle only')}
+ {this.renderPlugins(false, this.props.pluginType, 'subtitle only')}
- {this.renderPlugins(this.props.pluginType, 'handbrake')}
+ {this.renderPlugins(false, this.props.pluginType, 'handbrake')}
- {this.renderPlugins(this.props.pluginType, 'ffmpeg')}
+ {this.renderPlugins(false, this.props.pluginType, 'ffmpeg')}
- {this.renderPlugins(this.props.pluginType, 'radarr')}
+ {this.renderPlugins(false, this.props.pluginType, 'radarr')}
- {this.renderPlugins(this.props.pluginType, 'sonarr')}
+ {this.renderPlugins(false, this.props.pluginType, 'sonarr')}
- {this.renderPlugins(this.props.pluginType, 'pre-processing')}
+ {this.renderPlugins(false, this.props.pluginType, 'pre-processing')}
- {this.renderPlugins(this.props.pluginType, 'post-processing')}
+ {this.renderPlugins(false, this.props.pluginType, 'post-processing')}
+
+
+
+ {this.renderPlugins(false, this.props.pluginType, 'configurable')}
diff --git a/imports/ui/plugins/tab_Plugins.jsx b/imports/ui/plugins/tab_Plugins.jsx
index bb11efa8..070d5006 100644
--- a/imports/ui/plugins/tab_Plugins.jsx
+++ b/imports/ui/plugins/tab_Plugins.jsx
@@ -109,10 +109,7 @@ class App extends Component {
this.searchPlugins(event, pluginType)} style={ButtonStyle}>Search {'\u00A0'}
- {/*
{
- render('', document.getElementById('searchResults' + pluginType));
- }} style={ButtonStyle}>Clear {'\u00A0'} */}
{pluginType == "Community" ?
Update community plugins : null}
@@ -180,8 +177,7 @@ class App extends Component {
var string = "searchString" + pluginType
var searchTerm = ReactDOM.findDOMNode(this.refs[string]).value.trim()
- //row.source == pluginType &&
-
+
var result = this.state.pluginsStored.filter(row => {
var string = JSON.stringify(row).toLowerCase()
if (string.includes(searchTerm.toLowerCase())) {
@@ -311,7 +307,7 @@ class App extends Component {
-
+
diff --git a/imports/ui/styles/main.scss b/imports/ui/styles/main.scss
index 380ff3b4..77452dde 100644
--- a/imports/ui/styles/main.scss
+++ b/imports/ui/styles/main.scss
@@ -965,10 +965,17 @@ table.sliderTable td {
padding:0.5em;
position: relative;
box-shadow: 3px 3px grey;
+ background-color: #222b44;
}
+.pluginCardLoading{
+
+ width:300px;
+ height:400px;
+}
+
.pluginCardBottom{
position: absolute;
bottom: 1px;
From b19f77ab5011667f1e42246e193d87bc101de3ac Mon Sep 17 00:00:00 2001
From: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com>
Date: Sat, 15 Feb 2020 01:19:43 +0000
Subject: [PATCH 10/31] Tidy
---
.gitignore | 3 +-
.meteor/.gitignore | 1 +
imports/api/pluginCreatorMethods.js | 4 +-
imports/ui/ErrorBoundary.jsx | 1 +
imports/ui/libraries/tab_Libraries_Folder.jsx | 6 +-
imports/ui/styles/main.scss | 23 ++++--
imports/ui/tab_Search.jsx | 80 +++++++++----------
imports/ui/tab_Statistics.jsx | 2 -
private/fileScanner/ccextractor.js | 4 +-
private/fileScanner/fileScanner.js | 29 +++----
private/fileScanner/runExifTool.js | 6 +-
11 files changed, 83 insertions(+), 76 deletions(-)
diff --git a/.gitignore b/.gitignore
index d55def8e..0eb4fb67 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
node_modules
.meteor/local
-.idea
\ No newline at end of file
+.idea
+version.desktop
diff --git a/.meteor/.gitignore b/.meteor/.gitignore
index 40830374..5f1ac4cf 100644
--- a/.meteor/.gitignore
+++ b/.meteor/.gitignore
@@ -1 +1,2 @@
local
+desktop-build
\ No newline at end of file
diff --git a/imports/api/pluginCreatorMethods.js b/imports/api/pluginCreatorMethods.js
index e49b3f5a..6dff24f9 100644
--- a/imports/api/pluginCreatorMethods.js
+++ b/imports/api/pluginCreatorMethods.js
@@ -6,8 +6,8 @@ import { Meteor } from 'meteor/meteor';
const shortid = require('shortid');
//Globals
-var fs = require('fs');
-var path = require('path');
+const fs = require('fs');
+const path = require('path');
diff --git a/imports/ui/ErrorBoundary.jsx b/imports/ui/ErrorBoundary.jsx
index fe6b801f..1e2df398 100644
--- a/imports/ui/ErrorBoundary.jsx
+++ b/imports/ui/ErrorBoundary.jsx
@@ -12,6 +12,7 @@ export class ErrorBoundary extends React.Component {
componentDidCatch(error, errorInfo) {
console.error(error);
+ console.error(error.stack);
console.log(errorInfo);
}
diff --git a/imports/ui/libraries/tab_Libraries_Folder.jsx b/imports/ui/libraries/tab_Libraries_Folder.jsx
index 7926b7f2..a66e9b18 100644
--- a/imports/ui/libraries/tab_Libraries_Folder.jsx
+++ b/imports/ui/libraries/tab_Libraries_Folder.jsx
@@ -80,7 +80,6 @@ class Folder extends Component {
Meteor.call('searchPlugins', '', 'Community', (error, result) => {
var arr = this.state.pluginsStored
-
arr = arr.concat(result[0])
this.setState({
pluginsStored: arr
@@ -89,6 +88,11 @@ class Folder extends Component {
})
};
+ componentWillUnmount() {
+ clearInterval(this.interval2);
+}
+
+
getServerTime = () => {
Meteor.call('getTimeNow', (error, result) => {
diff --git a/imports/ui/styles/main.scss b/imports/ui/styles/main.scss
index 77452dde..0e4cdd29 100644
--- a/imports/ui/styles/main.scss
+++ b/imports/ui/styles/main.scss
@@ -198,12 +198,6 @@ input[type="text"]
size:14px;
}
- .resultColumnOptions {
-
- width: 100px;
- display: inline-block;
-
- }
.filterByDate {
@@ -1046,11 +1040,26 @@ table.pluginStackTable td {
}
.optionsDropdown{
-
background-color: #383838;
}
+.optionsDropdownSR{
+
+ background-color: black;
+
+}
+
+
+.resultColumnOptions {
+
+ width: 100px;
+ display: inline-block;
+
+ }
+
+
+
.dropdownScan{
color:green;
}
diff --git a/imports/ui/tab_Search.jsx b/imports/ui/tab_Search.jsx
index a7f31263..035de012 100644
--- a/imports/ui/tab_Search.jsx
+++ b/imports/ui/tab_Search.jsx
@@ -53,46 +53,46 @@ class App extends Component {
return
-
Search {'\u00A0'}
+
Search {'\u00A0'}
{
render('', document.getElementById('searchResults'));
- }} style={ButtonStyle}>Clear {'\u00A0'}
-
i }
- modal
- closeOnDocumentClick
- >
-
-
-
-
-
+ }} style={ButtonStyle}>
Clear {'\u00A0'}
+
i }
+ modal
+ closeOnDocumentClick
+ >
-
-
Search for files based on hundreds of properties
-
-
Codec suggestions: h264,hevc,mpeg4,mpeg2video,vp9,vp8,theora,aac,ac3,dts
-
Other suggestions: subtitle,mp4,mkv,shrek,stereo,1080p
+
+
+
-
Search for files with multiple properties by separating search terms with a comma. E.g.:
-
shrek,aac,h264,subtitle
+
+
Search for files based on hundreds of properties
+
Codec suggestions: h264,hevc,mpeg4,mpeg2video,vp9,vp8,theora,aac,ac3,dts
+
Other suggestions: subtitle,mp4,mkv,shrek,stereo,1080p
-
+
Search for files with multiple properties by separating search terms with a comma. E.g.:
-
Create a 30 second sample using the '✄' button. The sample will be placed in the 'Samples' folder in the Tdarr documents/data folder with suffix '- TdarrSample'. Use the sample to test plugins/transcode settings and to help when reporting bugs.
+
shrek,aac,h264,subtitle
-
-
To return a list of all files, leave the search bar empty.
+
+
+
Create a 30 second sample using the '✄' button. The sample will be placed in the 'Samples' folder in the Tdarr documents/data folder with suffix '- TdarrSample'. Use the sample to test plugins/transcode settings and to help when reporting bugs.
+
+
+
To return a list of all files, leave the search bar empty.
+
+
+
+
-
-
-
-
+
@@ -120,10 +120,10 @@ class App extends Component {
Meteor.call('searchDB', ReactDOM.findDOMNode(this.refs.searchString).value.trim(), (error, result) => {
-
-render(
, document.getElementById('searchResults'));
+
+ render(
, document.getElementById('searchResults'));
})
@@ -145,28 +145,28 @@ render(