From 96fbdcc1b0a2887ab181189db640c3749028dc6c Mon Sep 17 00:00:00 2001 From: dnzbk Date: Mon, 6 Nov 2023 12:26:10 +0300 Subject: [PATCH 001/182] init: JSON Read func, refs instead of raw pointers --- Makefile.am | 2 + Makefile.in | 1 + daemon/extension/ScriptConfig.cpp | 48 +++++++++---------- daemon/extension/ScriptConfig.h | 14 +++--- daemon/main/nzbget.h | 3 +- daemon/util/Json.cpp | 40 ++++++++++++++++ daemon/util/Json.h | 27 +++++++++++ lib/par2/par2cmdline.h | 1 - nzbget.vcxproj | 6 ++- scripts/Logger/Logger.py | 79 +++++++++++++++++++++++++++++++ scripts/Logger/manifest.json | 13 +++++ 11 files changed, 199 insertions(+), 35 deletions(-) create mode 100644 daemon/util/Json.cpp create mode 100644 daemon/util/Json.h create mode 100644 scripts/Logger/Logger.py create mode 100644 scripts/Logger/manifest.json diff --git a/Makefile.am b/Makefile.am index e325a1fc4..eddac5594 100644 --- a/Makefile.am +++ b/Makefile.am @@ -158,6 +158,8 @@ nzbget_SOURCES = \ daemon/util/Service.h \ daemon/util/FileSystem.cpp \ daemon/util/FileSystem.h \ + daemon/util/Json.cpp \ + daemon/util/Json.h \ daemon/util/Util.cpp \ daemon/util/Util.h \ daemon/nserv/NServMain.h \ diff --git a/Makefile.in b/Makefile.in index 4c9e67601..e761078d9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -287,6 +287,7 @@ am__nzbget_SOURCES_DIST = daemon/connect/Connection.cpp \ daemon/util/Thread.cpp daemon/util/Thread.h \ daemon/util/Service.cpp daemon/util/Service.h \ daemon/util/FileSystem.cpp daemon/util/FileSystem.h \ + daemon/util/Json.cpp daemon/util/Json.h \ daemon/util/Util.cpp daemon/util/Util.h \ daemon/nserv/NServMain.h daemon/nserv/NServMain.cpp \ daemon/nserv/NServFrontend.h daemon/nserv/NServFrontend.cpp \ diff --git a/daemon/extension/ScriptConfig.cpp b/daemon/extension/ScriptConfig.cpp index 322017b8c..ac02e8a42 100644 --- a/daemon/extension/ScriptConfig.cpp +++ b/daemon/extension/ScriptConfig.cpp @@ -168,7 +168,7 @@ bool ScriptConfig::LoadConfigTemplates(ConfigTemplates* configTemplates) } Scripts scriptList; - LoadScripts(&scriptList); + LoadScripts(scriptList); const int beginSignatureLen = strlen(BEGIN_SCRIPT_SIGNATURE); const int definitionSignatureLen = strlen(DEFINITION_SIGNATURE); @@ -232,10 +232,10 @@ void ScriptConfig::InitConfigTemplates() void ScriptConfig::InitScripts() { - LoadScripts(&m_scripts); + LoadScripts(m_scripts); } -void ScriptConfig::LoadScripts(Scripts* scripts) +void ScriptConfig::LoadScripts(Scripts& scripts) { if (Util::EmptyStr(g_Options->GetScriptDir())) { @@ -247,7 +247,7 @@ void ScriptConfig::LoadScripts(Scripts* scripts) Tokenizer tokDir(g_Options->GetScriptDir(), ",;"); while (const char* scriptDir = tokDir.Next()) { - LoadScriptDir(&tmpScripts, scriptDir, false); + LoadScriptDir(tmpScripts, scriptDir, false); } tmpScripts.sort( @@ -268,17 +268,17 @@ void ScriptConfig::LoadScripts(Scripts* scripts) if (pos != tmpScripts.end()) { - scripts->splice(scripts->end(), tmpScripts, pos); + scripts.splice(scripts.end(), tmpScripts, pos); } } // then add all other scripts from scripts directory - scripts->splice(scripts->end(), std::move(tmpScripts)); + scripts.splice(scripts.end(), std::move(tmpScripts)); BuildScriptDisplayNames(scripts); } -void ScriptConfig::LoadScriptDir(Scripts* scripts, const char* directory, bool isSubDir) +void ScriptConfig::LoadScriptDir(Scripts& scripts, const char* directory, bool isSubDir) { DirBrowser dir(directory); while (const char* filename = dir.Next()) @@ -296,9 +296,9 @@ void ScriptConfig::LoadScriptDir(Scripts* scripts, const char* directory, bool i } Script script(scriptName, fullFilename); - if (LoadScriptFile(&script)) + if (LoadScriptFile(script)) { - scripts->push_back(std::move(script)); + scripts.push_back(std::move(script)); } } else if (!isSubDir) @@ -309,10 +309,10 @@ void ScriptConfig::LoadScriptDir(Scripts* scripts, const char* directory, bool i } } -bool ScriptConfig::LoadScriptFile(Script* script) +bool ScriptConfig::LoadScriptFile(Script& script) { DiskFile infile; - if (!infile.Open(script->GetLocation(), DiskFile::omRead)) + if (!infile.Open(script.GetLocation(), DiskFile::omRead)) { return false; } @@ -402,18 +402,18 @@ bool ScriptConfig::LoadScriptFile(Script* script) while (taskTime && *taskTime && *(p = taskTime + strlen(taskTime) - 1) == '#') *p = '\0'; if (taskTime) taskTime = Util::Trim(taskTime); - script->SetPostScript(postScript); - script->SetScanScript(scanScript); - script->SetQueueScript(queueScript); - script->SetSchedulerScript(schedulerScript); - script->SetFeedScript(feedScript); - script->SetQueueEvents(queueEvents); - script->SetTaskTime(taskTime); + script.SetPostScript(postScript); + script.SetScanScript(scanScript); + script.SetQueueScript(queueScript); + script.SetSchedulerScript(schedulerScript); + script.SetFeedScript(feedScript); + script.SetQueueEvents(queueEvents); + script.SetTaskTime(taskTime); return true; } -BString<1024> ScriptConfig::BuildScriptName(const char* directory, const char* filename, bool isSubDir) +BString<1024> ScriptConfig::BuildScriptName(const char* directory, const char* filename, bool isSubDir) const { if (isSubDir) { @@ -433,16 +433,16 @@ BString<1024> ScriptConfig::BuildScriptName(const char* directory, const char* f } } -bool ScriptConfig::ScriptExists(Scripts* scripts, const char* scriptName) +bool ScriptConfig::ScriptExists(const Scripts& scripts, const char* scriptName) const { - return std::find_if(scripts->begin(), scripts->end(), - [scriptName](Script& script) + return std::find_if(scripts.begin(), scripts.end(), + [scriptName](const Script& script) { return !strcmp(script.GetName(), scriptName); - }) != scripts->end(); + }) != scripts.end(); } -void ScriptConfig::BuildScriptDisplayNames(Scripts* scripts) +void ScriptConfig::BuildScriptDisplayNames(Scripts& scripts) { // trying to use short name without path and extension. // if there are other scripts with the same short name - using a longer name instead (with ot without extension) diff --git a/daemon/extension/ScriptConfig.h b/daemon/extension/ScriptConfig.h index 8e6d03926..45258e885 100644 --- a/daemon/extension/ScriptConfig.h +++ b/daemon/extension/ScriptConfig.h @@ -34,7 +34,7 @@ class ScriptConfig Script(const char* name, const char* location) : m_name(name), m_location(location), m_displayName(name) {}; Script(Script&&) = default; - const char* GetName() { return m_name; } + const char* GetName() const { return m_name; } const char* GetLocation() { return m_location; } void SetDisplayName(const char* displayName) { m_displayName = displayName; } const char* GetDisplayName() { return m_displayName; } @@ -97,12 +97,12 @@ class ScriptConfig void InitScripts(); void InitConfigTemplates(); void CreateTasks(); - void LoadScriptDir(Scripts* scripts, const char* directory, bool isSubDir); - void BuildScriptDisplayNames(Scripts* scripts); - void LoadScripts(Scripts* scripts); - bool LoadScriptFile(Script* script); - BString<1024>BuildScriptName(const char* directory, const char* filename, bool isSubDir); - bool ScriptExists(Scripts* scripts, const char* scriptName); + void LoadScriptDir(Scripts& scripts, const char* directory, bool isSubDir); + void BuildScriptDisplayNames(Scripts& scripts); + void LoadScripts(Scripts& scripts); + bool LoadScriptFile(Script& script); + BString<1024>BuildScriptName(const char* directory, const char* filename, bool isSubDir) const; + bool ScriptExists(const Scripts& scripts, const char* scriptName) const; }; extern ScriptConfig* g_ScriptConfig; diff --git a/daemon/main/nzbget.h b/daemon/main/nzbget.h index eed5d1ca7..2729796a9 100644 --- a/daemon/main/nzbget.h +++ b/daemon/main/nzbget.h @@ -228,6 +228,8 @@ using namespace MSXML; #include #include +#include + // NOTE: do not include in "nzbget.h". contains objects requiring // intialization, causing every unit in nzbget to have initialization routine. This in particular // is causing fatal problems in SIMD units which must not have static initialization because @@ -287,7 +289,6 @@ typedef int pid_t; // WINDOWS -#define snprintf _snprintf #ifndef strdup #define strdup _strdup #endif diff --git a/daemon/util/Json.cpp b/daemon/util/Json.cpp new file mode 100644 index 000000000..a7e1a26a7 --- /dev/null +++ b/daemon/util/Json.cpp @@ -0,0 +1,40 @@ +/* + * This file is part of nzbget. See . + * + * Copyright (C) 2023 Denis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "nzbget.h" +#include "Json.h" + +Json::JSON Json::Read(std::istream &is, boost::json::error_code &ec) +{ + boost::json::stream_parser p; + std::string line; + + while (std::getline(is, line)) + { + p.write(line, ec); + if (ec) + return nullptr; + } + + p.finish(ec); + + if (ec) + return nullptr; + return p.release(); +} diff --git a/daemon/util/Json.h b/daemon/util/Json.h new file mode 100644 index 000000000..f3ff9f64c --- /dev/null +++ b/daemon/util/Json.h @@ -0,0 +1,27 @@ +/* + * This file is part of nzbget. See . + * + * Copyright (C) 2023 Denis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "nzbget.h" +#include + +namespace Json +{ + using JSON = boost::json::value; + JSON Read(std::istream &is, boost::json::error_code &ec); +} diff --git a/lib/par2/par2cmdline.h b/lib/par2/par2cmdline.h index 4c75cdc66..5240f094f 100644 --- a/lib/par2/par2cmdline.h +++ b/lib/par2/par2cmdline.h @@ -22,7 +22,6 @@ #ifdef WIN32 -//#define snprintf _snprintf #define stat _stat namespace Par2 diff --git a/nzbget.vcxproj b/nzbget.vcxproj index b692fb726..4b96e89d1 100755 --- a/nzbget.vcxproj +++ b/nzbget.vcxproj @@ -107,7 +107,7 @@ Disabled - ..\bin\Debug64;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\regex;.\lib\par2;.\lib\yencode;.\windows\resources;C:\Program Files (x86)\zlib\include;C:\Program Files\OpenSSL-Win64\include;%(AdditionalIncludeDirectories) + C:\Program Files\vcpkg\installed\x64-windows\include;..\bin\Debug64;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\regex;.\lib\par2;.\lib\yencode;.\windows\resources;C:\Program Files (x86)\zlib\include;C:\Program Files\OpenSSL-Win64\include;%(AdditionalIncludeDirectories) WIN32;PACKAGE="nzbget";VERSION="22.0";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) false EnableFastChecks @@ -121,7 +121,7 @@ true Console - C:\Program Files (x86)\zlib\lib;C:\Program Files\OpenSSL-Win64\lib\VC\static;%(AdditionalLibraryDirectories) + C:\Program Files\vcpkg\installed\x64-windows\lib;C:\Program Files (x86)\zlib\lib;C:\Program Files\OpenSSL-Win64\lib\VC\static;%(AdditionalLibraryDirectories) MachineX64 libcrypto64MTd.lib;libssl64MTd.lib;zlibstatic64d.lib;Dbghelp.lib;WS2_32.lib;ole32.lib;OleAut32.Lib;comsuppwd.lib;Advapi32.lib;gdi32.lib;shell32.lib;Winmm.lib;crypt32.lib;%(AdditionalDependencies) false @@ -281,6 +281,7 @@ + @@ -401,6 +402,7 @@ + diff --git a/scripts/Logger/Logger.py b/scripts/Logger/Logger.py new file mode 100644 index 000000000..3ba2f0c5b --- /dev/null +++ b/scripts/Logger/Logger.py @@ -0,0 +1,79 @@ +# +# Logger post-processing script for NZBGet +# +# Copyright (C) 2013-2016 Andrey Prygunkov +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import os +import sys +import datetime + +try: + from xmlrpclib import ServerProxy # python 2 + from urllib2 import quote +except ImportError: + from xmlrpc.client import ServerProxy # python 3 + from urllib.parse import quote + +# Exit codes used by NZBGet +POSTPROCESS_SUCCESS=93 +POSTPROCESS_NONE=95 +POSTPROCESS_ERROR=94 + +# Check if the script is called from nzbget 15.0 or later +if not 'NZBOP_NZBLOG' in os.environ: + print('*** NZBGet post-processing script ***') + print('This script is supposed to be called from nzbget (15.0 or later).') + sys.exit(POSTPROCESS_ERROR) + +if not os.path.exists(os.environ['NZBPP_DIRECTORY']): + print('Destination directory doesn\'t exist, exiting') + sys.exit(POSTPROCESS_NONE) + +# To get the item log we connect to NZBGet via XML-RPC and call +# method "loadlog", which returns the log for a given nzb item. +# For more info visit https://nzbget.com/documentation/api/ + +# First we need to know connection info: host, port and password of NZBGet server. +# NZBGet passes all configuration options to post-processing script as +# environment variables. +host = os.environ['NZBOP_CONTROLIP']; +port = os.environ['NZBOP_CONTROLPORT']; +username = os.environ['NZBOP_CONTROLUSERNAME']; +password = os.environ['NZBOP_CONTROLPASSWORD']; + +if host == '0.0.0.0': host = '127.0.0.1' + +# Build a URL for XML-RPC requests +rpcUrl = 'http://%s:%s@%s:%s/xmlrpc' % (quote(username), quote(password), host, port); + +# Create remote server object +server = ServerProxy(rpcUrl) + +# Call remote method 'loadlog' +nzbid = int(os.environ['NZBPP_NZBID']) +log = server.loadlog(nzbid, 0, 10000) + +# Now iterate through entries and save them to the output file +if len(log) > 0: + f = open('%s/_nzblog.txt' % os.environ['NZBPP_DIRECTORY'], 'wb') + for entry in log: + f.write((u'%s\t%s\t%s\n' % (entry['Kind'], datetime.datetime.fromtimestamp(int(entry['Time'])), entry['Text'])).encode('utf8')) + f.close() + +# All OK, returning exit status 'POSTPROCESS_SUCCESS' (int <93>) to let NZBGet know +# that our script has successfully completed. +sys.exit(POSTPROCESS_SUCCESS) diff --git a/scripts/Logger/manifest.json b/scripts/Logger/manifest.json new file mode 100644 index 000000000..79ef5ab26 --- /dev/null +++ b/scripts/Logger/manifest.json @@ -0,0 +1,13 @@ +{ + "main": "Logger.py", + "name": "logger", + "kind": "POST-PROCESSING", + "displayName": "Logger", + "version": "1.0.0", + "author": "Andrey Prygunkov", + "license": "GNU", + "description": "Save nzb log into a file.\nThis script saves the download and post-processing log of nzb-file\ninto file _nzblog.txt in the destination directory.\nNOTE: This script requires Python to be installed on your system.", + "options": [], + "commands": [], + "tasks": [] +} From c2ef1b57f4aadb50f4d774628572d0de2172fd12 Mon Sep 17 00:00:00 2001 From: dnzbk Date: Mon, 6 Nov 2023 12:41:31 +0300 Subject: [PATCH 002/182] add: boost license info --- webui/index.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/webui/index.html b/webui/index.html index a2dc35cce..434b2d6ae 100644 --- a/webui/index.html +++ b/webui/index.html @@ -3,6 +3,7 @@ * This file is part of nzbget. See . * * Copyright (C) 2012-2019 Andrey Prygunkov + * Copyright (C) 2023 Denis * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -626,6 +627,10 @@

Elycharts

iconSweets

NZBGet web-interface includes selected icons from collections iconSweets and iconSweets2 by Yummygum.

The icons are generally licensed under a custom license but used in NZBGet with author's permission.

+ +

Boost

+

NZBGet uses Boost by Boost organization and wider Boost community

+

Boost is licensed under the Boost Software License.

From ba1bf4ca4cdcc6c8a6ffb61b90239d7bc60e4fc4 Mon Sep 17 00:00:00 2001 From: dnzbk Date: Mon, 6 Nov 2023 17:39:50 +0300 Subject: [PATCH 003/182] find manifest test --- daemon/extension/ScriptConfig.cpp | 21 +++++++++++++++++++++ daemon/util/Json.cpp | 4 ++-- daemon/util/Json.h | 5 +++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/daemon/extension/ScriptConfig.cpp b/daemon/extension/ScriptConfig.cpp index ac02e8a42..4055b2ef8 100644 --- a/daemon/extension/ScriptConfig.cpp +++ b/daemon/extension/ScriptConfig.cpp @@ -24,6 +24,7 @@ #include "Options.h" #include "Log.h" #include "ScriptConfig.h" +#include "Json.h" static const char* BEGIN_SCRIPT_SIGNATURE = "### NZBGET "; static const char* POST_SCRIPT_SIGNATURE = "POST-PROCESSING"; @@ -277,10 +278,30 @@ void ScriptConfig::LoadScripts(Scripts& scripts) BuildScriptDisplayNames(scripts); } +#include +#include +void FindManifest(const char* directory) +{ + DirBrowser dir(directory); + const char* manifest = "manifest.json"; + while (const char* filename = dir.Next()) + { + if (strncmp(filename, manifest, sizeof(manifest)) == 0) + { + BString<1024> fullFilename("%s%c%s", directory, PATH_SEPARATOR, manifest); + std::fstream fs(fullFilename); + Json::error_code ec1; + Json::JSON json = Json::Read(fs, ec1); + std::cout << json << std::endl; + } + } +} void ScriptConfig::LoadScriptDir(Scripts& scripts, const char* directory, bool isSubDir) { DirBrowser dir(directory); + FindManifest(directory); + while (const char* filename = dir.Next()) { if (filename[0] != '.' && filename[0] != '_') diff --git a/daemon/util/Json.cpp b/daemon/util/Json.cpp index a7e1a26a7..6a23cc041 100644 --- a/daemon/util/Json.cpp +++ b/daemon/util/Json.cpp @@ -20,9 +20,9 @@ #include "nzbget.h" #include "Json.h" -Json::JSON Json::Read(std::istream &is, boost::json::error_code &ec) +Json::JSON Json::Read(std::istream &is, Json::error_code &ec) { - boost::json::stream_parser p; + Json::stream_parser p; std::string line; while (std::getline(is, line)) diff --git a/daemon/util/Json.h b/daemon/util/Json.h index f3ff9f64c..4176f9916 100644 --- a/daemon/util/Json.h +++ b/daemon/util/Json.h @@ -22,6 +22,7 @@ namespace Json { - using JSON = boost::json::value; - JSON Read(std::istream &is, boost::json::error_code &ec); + using namespace boost::json; + using JSON = value; + JSON Read(std::istream &is, error_code &ec); } From 9627f18dfc99fbb56196cb374d6ae3b93c71d599 Mon Sep 17 00:00:00 2001 From: dnzbk Date: Tue, 7 Nov 2023 10:14:46 +0300 Subject: [PATCH 004/182] use static --- daemon/util/Json.h | 5 +++++ nzbget.vcxproj | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/daemon/util/Json.h b/daemon/util/Json.h index 4176f9916..5c23094e9 100644 --- a/daemon/util/Json.h +++ b/daemon/util/Json.h @@ -17,6 +17,9 @@ * along with this program. If not, see . */ +#ifndef JSON_H +#define JSON_H + #include "nzbget.h" #include @@ -26,3 +29,5 @@ namespace Json using JSON = value; JSON Read(std::istream &is, error_code &ec); } + +#endif diff --git a/nzbget.vcxproj b/nzbget.vcxproj index 4b96e89d1..58b267c64 100755 --- a/nzbget.vcxproj +++ b/nzbget.vcxproj @@ -107,7 +107,7 @@ Disabled - C:\Program Files\vcpkg\installed\x64-windows\include;..\bin\Debug64;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\regex;.\lib\par2;.\lib\yencode;.\windows\resources;C:\Program Files (x86)\zlib\include;C:\Program Files\OpenSSL-Win64\include;%(AdditionalIncludeDirectories) + C:\Program Files\vcpkg\installed\x86-windows-static\include;..\bin\Debug64;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\regex;.\lib\par2;.\lib\yencode;.\windows\resources;C:\Program Files (x86)\zlib\include;C:\Program Files\OpenSSL-Win64\include;%(AdditionalIncludeDirectories) WIN32;PACKAGE="nzbget";VERSION="22.0";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) false EnableFastChecks @@ -121,9 +121,9 @@ true Console - C:\Program Files\vcpkg\installed\x64-windows\lib;C:\Program Files (x86)\zlib\lib;C:\Program Files\OpenSSL-Win64\lib\VC\static;%(AdditionalLibraryDirectories) + C:\Program Files\vcpkg\installed\x86-windows-static\lib;C:\Program Files (x86)\zlib\lib;C:\Program Files\OpenSSL-Win64\lib\VC\static;%(AdditionalLibraryDirectories) MachineX64 - libcrypto64MTd.lib;libssl64MTd.lib;zlibstatic64d.lib;Dbghelp.lib;WS2_32.lib;ole32.lib;OleAut32.Lib;comsuppwd.lib;Advapi32.lib;gdi32.lib;shell32.lib;Winmm.lib;crypt32.lib;%(AdditionalDependencies) + boost_json-vc140-mt.lib;libcrypto64MTd.lib;libssl64MTd.lib;zlibstatic64d.lib;Dbghelp.lib;WS2_32.lib;ole32.lib;OleAut32.Lib;comsuppwd.lib;Advapi32.lib;gdi32.lib;shell32.lib;Winmm.lib;crypt32.lib;%(AdditionalDependencies) false msvcrt.lib; libcmt.lib; msvcrtd.lib -s %(AdditionalOptions) @@ -173,7 +173,7 @@ - ..\bin\Release64;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\par2;.\lib\yencode;.\windows\resources;C:\Program Files (x86)\zlib\include;C:\Program Files\OpenSSL-Win64\include;.\lib\regex;%(AdditionalIncludeDirectories) + C:\Program Files\vcpkg\installed\x86-windows-static\include;..\bin\Release64;.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nserv;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\par2;.\lib\yencode;.\windows\resources;C:\Program Files (x86)\zlib\include;C:\Program Files\OpenSSL-Win64\include;.\lib\regex;%(AdditionalIncludeDirectories) WIN32;PACKAGE="nzbget";VERSION="22.0";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions) Sync MultiThreaded @@ -192,13 +192,13 @@ Fast - libcrypto64MT.lib;libssl64MT.lib;zlibstatic64.lib;WS2_32.lib;ole32.lib;OleAut32.Lib;comsuppwd.lib;Advapi32.lib;gdi32.lib;shell32.lib;Winmm.lib;crypt32.lib;%(AdditionalDependencies) + boost_json-vc140-mt.lib;libcrypto64MT.lib;libssl64MT.lib;zlibstatic64.lib;WS2_32.lib;ole32.lib;OleAut32.Lib;comsuppwd.lib;Advapi32.lib;gdi32.lib;shell32.lib;Winmm.lib;crypt32.lib;%(AdditionalDependencies) false Console true true UseLinkTimeCodeGeneration - C:\Program Files (x86)\zlib\lib;C:\Program Files\OpenSSL-Win64\lib\VC\static;%(AdditionalLibraryDirectories) + C:\Program Files\vcpkg\installed\x86-windows-static\lib;C:\Program Files (x86)\zlib\lib;C:\Program Files\OpenSSL-Win64\lib\VC\static;%(AdditionalLibraryDirectories) msvcrt.lib; libcmtd.lib; msvcrtd.lib From 14f7bffda647fc257d577ea568102a9a6605b8f4 Mon Sep 17 00:00:00 2001 From: dnzbk Date: Wed, 8 Nov 2023 12:40:20 +0300 Subject: [PATCH 005/182] basic strategies --- daemon/extension/ManifestFile.cpp | 56 +++++++ daemon/extension/ManifestFile.h | 44 ++++++ daemon/extension/ScriptConfig.cpp | 237 +++++++++++++++--------------- daemon/extension/ScriptConfig.h | 31 +++- daemon/util/Json.cpp | 28 ++-- nzbget.vcxproj | 2 + scripts/Logger/manifest.json | 2 +- 7 files changed, 262 insertions(+), 138 deletions(-) create mode 100644 daemon/extension/ManifestFile.cpp create mode 100644 daemon/extension/ManifestFile.h diff --git a/daemon/extension/ManifestFile.cpp b/daemon/extension/ManifestFile.cpp new file mode 100644 index 000000000..aaf3a1444 --- /dev/null +++ b/daemon/extension/ManifestFile.cpp @@ -0,0 +1,56 @@ +/* + * This file is part of nzbget. See . + * + * Copyright (C) 2023 Denis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "nzbget.h" +#include "ManifestFile.h" +#include "Json.h" +#include "FileSystem.h" +#include + +namespace ManifestFile +{ + bool Load(Manifest& manifest, const char* directory) + { + DirBrowser dir(directory); + while (const char* filename = dir.Next()) + { + if (strncmp(filename, MANIFEST_FILE, sizeof(MANIFEST_FILE)) == 0) + { + BString<1024> fullFilename("%s%c%s", directory, PATH_SEPARATOR, MANIFEST_FILE); + std::fstream fs(fullFilename); + Json::error_code ec; + + Json::JSON json = Json::Read(fs, ec); + if (ec) + return false; + + manifest.author = json.at("author").as_string().c_str(); + manifest.entry = json.at("entry").as_string().c_str(); + manifest.description = json.at("description").as_string().c_str(); + manifest.version = json.at("version").as_string().c_str(); + manifest.name = json.at("name").as_string().c_str(); + manifest.displayName = json.at("displayName").as_string().c_str(); + manifest.kind = json.at("kind").as_string().c_str(); + manifest.license = json.at("license").as_string().c_str(); + return true; + } + } + return false; + } +} diff --git a/daemon/extension/ManifestFile.h b/daemon/extension/ManifestFile.h new file mode 100644 index 000000000..5fe8d2420 --- /dev/null +++ b/daemon/extension/ManifestFile.h @@ -0,0 +1,44 @@ +/* + * This file is part of nzbget. See . + * + * Copyright (C) 2023 Denis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef MANIFESTFILE_H +#define MANIFESTFILE_H + +#include "nzbget.h" +#include "NString.h" + +namespace ManifestFile +{ + static const CString MANIFEST_FILE = "manifest.json"; + struct Manifest + { + CString author; + CString entry; + CString kind; + CString name; + CString displayName; + CString version; + CString license; + CString description; + }; + + bool Load(Manifest& manifest, const char* directory); +} + +#endif diff --git a/daemon/extension/ScriptConfig.cpp b/daemon/extension/ScriptConfig.cpp index 4055b2ef8..9fe60796a 100644 --- a/daemon/extension/ScriptConfig.cpp +++ b/daemon/extension/ScriptConfig.cpp @@ -24,7 +24,7 @@ #include "Options.h" #include "Log.h" #include "ScriptConfig.h" -#include "Json.h" +//#include "ManifestFile.h" static const char* BEGIN_SCRIPT_SIGNATURE = "### NZBGET "; static const char* POST_SCRIPT_SIGNATURE = "POST-PROCESSING"; @@ -37,6 +37,115 @@ static const char* QUEUE_EVENTS_SIGNATURE = "### QUEUE EVENTS:"; static const char* TASK_TIME_SIGNATURE = "### TASK TIME:"; static const char* DEFINITION_SIGNATURE = "###"; +bool LoadScriptFileHeaderBasedStrategy::Load(ScriptConfig::Script& script) const +{ + DiskFile infile; + if (!infile.Open(script.GetLocation(), DiskFile::omRead)) + { + return false; + } + + CharBuffer buffer(1024 * 10 + 1); + + const int beginSignatureLen = strlen(BEGIN_SCRIPT_SIGNATURE); + const int queueEventsSignatureLen = strlen(QUEUE_EVENTS_SIGNATURE); + const int taskTimeSignatureLen = strlen(TASK_TIME_SIGNATURE); + const int definitionSignatureLen = strlen(DEFINITION_SIGNATURE); + + // check if the file contains pp-script-signature + // read first 10KB of the file and look for signature + int readBytes = (int)infile.Read(buffer, buffer.Size() - 1); + infile.Close(); + buffer[readBytes] = '\0'; + + bool postScript = false; + bool scanScript = false; + bool queueScript = false; + bool schedulerScript = false; + bool feedScript = false; + char* queueEvents = nullptr; + char* taskTime = nullptr; + + bool inConfig = false; + bool afterConfig = false; + + // Declarations "QUEUE EVENT:" and "TASK TIME:" can be placed: + // - in script definition body (between opening and closing script signatures); + // - immediately before script definition (before opening script signature); + // - immediately after script definition (after closing script signature). + // The last two pissibilities are provided to increase compatibility of scripts with older + // nzbget versions which do not expect the extra declarations in the script defintion body. + + Tokenizer tok(buffer, "\n\r", true); + while (char* line = tok.Next()) + { + if (!strncmp(line, QUEUE_EVENTS_SIGNATURE, queueEventsSignatureLen)) + { + queueEvents = line + queueEventsSignatureLen; + } + else if (!strncmp(line, TASK_TIME_SIGNATURE, taskTimeSignatureLen)) + { + taskTime = line + taskTimeSignatureLen; + } + + bool header = !strncmp(line, DEFINITION_SIGNATURE, definitionSignatureLen); + if (!header && !inConfig) + { + queueEvents = nullptr; + taskTime = nullptr; + } + + if (!header && afterConfig) + { + break; + } + + if (!strncmp(line, BEGIN_SCRIPT_SIGNATURE, beginSignatureLen) && strstr(line, END_SCRIPT_SIGNATURE)) + { + if (!inConfig) + { + inConfig = true; + postScript = strstr(line, POST_SCRIPT_SIGNATURE); + scanScript = strstr(line, SCAN_SCRIPT_SIGNATURE); + queueScript = strstr(line, QUEUE_SCRIPT_SIGNATURE); + schedulerScript = strstr(line, SCHEDULER_SCRIPT_SIGNATURE); + feedScript = strstr(line, FEED_SCRIPT_SIGNATURE); + } + else + { + afterConfig = true; + } + } + } + + if (!(postScript || scanScript || queueScript || schedulerScript || feedScript)) + { + return false; + } + + // trim decorations + char* p; + while (queueEvents && *queueEvents && *(p = queueEvents + strlen(queueEvents) - 1) == '#') *p = '\0'; + if (queueEvents) queueEvents = Util::Trim(queueEvents); + while (taskTime && *taskTime && *(p = taskTime + strlen(taskTime) - 1) == '#') *p = '\0'; + if (taskTime) taskTime = Util::Trim(taskTime); + + script.SetPostScript(postScript); + script.SetScanScript(scanScript); + script.SetQueueScript(queueScript); + script.SetSchedulerScript(schedulerScript); + script.SetFeedScript(feedScript); + script.SetQueueEvents(queueEvents); + script.SetTaskTime(taskTime); + + return true; +} + +bool LoadScriptFileStrategy::Load(ScriptConfig::Script& script) const +{ + return false; +} + void ScriptConfig::InitOptions() { InitScripts(); @@ -278,29 +387,10 @@ void ScriptConfig::LoadScripts(Scripts& scripts) BuildScriptDisplayNames(scripts); } -#include -#include -void FindManifest(const char* directory) -{ - DirBrowser dir(directory); - const char* manifest = "manifest.json"; - while (const char* filename = dir.Next()) - { - if (strncmp(filename, manifest, sizeof(manifest)) == 0) - { - BString<1024> fullFilename("%s%c%s", directory, PATH_SEPARATOR, manifest); - std::fstream fs(fullFilename); - Json::error_code ec1; - Json::JSON json = Json::Read(fs, ec1); - std::cout << json << std::endl; - } - } -} void ScriptConfig::LoadScriptDir(Scripts& scripts, const char* directory, bool isSubDir) { DirBrowser dir(directory); - FindManifest(directory); while (const char* filename = dir.Next()) { @@ -317,10 +407,12 @@ void ScriptConfig::LoadScriptDir(Scripts& scripts, const char* directory, bool i } Script script(scriptName, fullFilename); - if (LoadScriptFile(script)) + LoadOldScriptFileStrategy strategy; + if (LoadScriptFile(script, strategy)) { scripts.push_back(std::move(script)); } + } else if (!isSubDir) { @@ -330,108 +422,9 @@ void ScriptConfig::LoadScriptDir(Scripts& scripts, const char* directory, bool i } } -bool ScriptConfig::LoadScriptFile(Script& script) +bool ScriptConfig::LoadScriptFile(Script& script, const LoadScriptFileStrategy& strategy) { - DiskFile infile; - if (!infile.Open(script.GetLocation(), DiskFile::omRead)) - { - return false; - } - - CharBuffer buffer(1024 * 10 + 1); - - const int beginSignatureLen = strlen(BEGIN_SCRIPT_SIGNATURE); - const int queueEventsSignatureLen = strlen(QUEUE_EVENTS_SIGNATURE); - const int taskTimeSignatureLen = strlen(TASK_TIME_SIGNATURE); - const int definitionSignatureLen = strlen(DEFINITION_SIGNATURE); - - // check if the file contains pp-script-signature - // read first 10KB of the file and look for signature - int readBytes = (int)infile.Read(buffer, buffer.Size() - 1); - infile.Close(); - buffer[readBytes] = '\0'; - - bool postScript = false; - bool scanScript = false; - bool queueScript = false; - bool schedulerScript = false; - bool feedScript = false; - char* queueEvents = nullptr; - char* taskTime = nullptr; - - bool inConfig = false; - bool afterConfig = false; - - // Declarations "QUEUE EVENT:" and "TASK TIME:" can be placed: - // - in script definition body (between opening and closing script signatures); - // - immediately before script definition (before opening script signature); - // - immediately after script definition (after closing script signature). - // The last two pissibilities are provided to increase compatibility of scripts with older - // nzbget versions which do not expect the extra declarations in the script defintion body. - - Tokenizer tok(buffer, "\n\r", true); - while (char* line = tok.Next()) - { - if (!strncmp(line, QUEUE_EVENTS_SIGNATURE, queueEventsSignatureLen)) - { - queueEvents = line + queueEventsSignatureLen; - } - else if (!strncmp(line, TASK_TIME_SIGNATURE, taskTimeSignatureLen)) - { - taskTime = line + taskTimeSignatureLen; - } - - bool header = !strncmp(line, DEFINITION_SIGNATURE, definitionSignatureLen); - if (!header && !inConfig) - { - queueEvents = nullptr; - taskTime = nullptr; - } - - if (!header && afterConfig) - { - break; - } - - if (!strncmp(line, BEGIN_SCRIPT_SIGNATURE, beginSignatureLen) && strstr(line, END_SCRIPT_SIGNATURE)) - { - if (!inConfig) - { - inConfig = true; - postScript = strstr(line, POST_SCRIPT_SIGNATURE); - scanScript = strstr(line, SCAN_SCRIPT_SIGNATURE); - queueScript = strstr(line, QUEUE_SCRIPT_SIGNATURE); - schedulerScript = strstr(line, SCHEDULER_SCRIPT_SIGNATURE); - feedScript = strstr(line, FEED_SCRIPT_SIGNATURE); - } - else - { - afterConfig = true; - } - } - } - - if (!(postScript || scanScript || queueScript || schedulerScript || feedScript)) - { - return false; - } - - // trim decorations - char* p; - while (queueEvents && *queueEvents && *(p = queueEvents + strlen(queueEvents) - 1) == '#') *p = '\0'; - if (queueEvents) queueEvents = Util::Trim(queueEvents); - while (taskTime && *taskTime && *(p = taskTime + strlen(taskTime) - 1) == '#') *p = '\0'; - if (taskTime) taskTime = Util::Trim(taskTime); - - script.SetPostScript(postScript); - script.SetScanScript(scanScript); - script.SetQueueScript(queueScript); - script.SetSchedulerScript(schedulerScript); - script.SetFeedScript(feedScript); - script.SetQueueEvents(queueEvents); - script.SetTaskTime(taskTime); - - return true; + return strategy.Load(script); } BString<1024> ScriptConfig::BuildScriptName(const char* directory, const char* filename, bool isSubDir) const diff --git a/daemon/extension/ScriptConfig.h b/daemon/extension/ScriptConfig.h index 45258e885..423069469 100644 --- a/daemon/extension/ScriptConfig.h +++ b/daemon/extension/ScriptConfig.h @@ -24,6 +24,9 @@ #include "NString.h" #include "Container.h" #include "Options.h" +#include "ManifestFile.h" + +class LoadScriptFileStrategy; class ScriptConfig { @@ -100,11 +103,35 @@ class ScriptConfig void LoadScriptDir(Scripts& scripts, const char* directory, bool isSubDir); void BuildScriptDisplayNames(Scripts& scripts); void LoadScripts(Scripts& scripts); - bool LoadScriptFile(Script& script); - BString<1024>BuildScriptName(const char* directory, const char* filename, bool isSubDir) const; + bool LoadScriptFile(Script& script, const LoadScriptFileStrategy& strategy); + BString<1024> BuildScriptName(const char* directory, const char* filename, bool isSubDir) const; bool ScriptExists(const Scripts& scripts, const char* scriptName) const; }; +class LoadScriptFileStrategy { +public: + virtual bool Load(ScriptConfig::Script& script) const = 0; + virtual ~LoadScriptFileStrategy() = default; +}; + +class LoadScriptFileHeaderBasedStrategy : public LoadScriptFileStrategy { +public: + bool Load(ScriptConfig::Script& script) const override; + ~LoadScriptFileHeaderBasedStrategy() {} +}; + +class LoadScriptFileStrategy : public LoadScriptFileStrategy { +public: + LoadNewScriptFileStrategy() = delete; + explicit LoadNewScriptFileStrategy(ManifestFile::Manifest&& manifest_) + : manifest{std::move(manifest_)} + {} + bool Load(ScriptConfig::Script& script) const override; + ~LoadNewScriptFileStrategy() {} +private: + ManifestFile::Manifest manifest; +}; + extern ScriptConfig* g_ScriptConfig; #endif diff --git a/daemon/util/Json.cpp b/daemon/util/Json.cpp index 6a23cc041..f5d82cb7a 100644 --- a/daemon/util/Json.cpp +++ b/daemon/util/Json.cpp @@ -20,21 +20,23 @@ #include "nzbget.h" #include "Json.h" -Json::JSON Json::Read(std::istream &is, Json::error_code &ec) -{ - Json::stream_parser p; - std::string line; - - while (std::getline(is, line)) +namespace Json { + JSON Read(std::istream &is, error_code &ec) { - p.write(line, ec); + stream_parser p; + std::string line; + + while (std::getline(is, line)) + { + p.write(line, ec); + if (ec) + return nullptr; + } + + p.finish(ec); + if (ec) return nullptr; + return p.release(); } - - p.finish(ec); - - if (ec) - return nullptr; - return p.release(); } diff --git a/nzbget.vcxproj b/nzbget.vcxproj index 58b267c64..abf4c7796 100755 --- a/nzbget.vcxproj +++ b/nzbget.vcxproj @@ -216,6 +216,7 @@ + @@ -337,6 +338,7 @@ + diff --git a/scripts/Logger/manifest.json b/scripts/Logger/manifest.json index 79ef5ab26..a0863fdc0 100644 --- a/scripts/Logger/manifest.json +++ b/scripts/Logger/manifest.json @@ -1,5 +1,5 @@ { - "main": "Logger.py", + "entry": "Logger.py", "name": "logger", "kind": "POST-PROCESSING", "displayName": "Logger", From cf22f3aa5236f51944eb9e449c40dec550ff54f4 Mon Sep 17 00:00:00 2001 From: dnzbk Date: Thu, 9 Nov 2023 15:03:46 +0300 Subject: [PATCH 006/182] Added: Header Config Based strategy --- daemon/extension/LoadScriptFileStrategy.cpp | 139 +++++++++++++++++ daemon/extension/LoadScriptFileStrategy.h | 62 ++++++++ daemon/extension/ManifestFile.cpp | 2 +- daemon/extension/ManifestFile.h | 23 ++- daemon/extension/NzbScript.h | 2 +- daemon/extension/Script.cpp | 44 ++++++ daemon/extension/Script.h | 62 ++++++++ daemon/extension/ScriptConfig.cpp | 147 ++---------------- daemon/extension/ScriptConfig.h | 73 +-------- daemon/main/Maintenance.h | 2 +- daemon/postprocess/Cleanup.h | 2 +- daemon/postprocess/DirectUnpack.h | 2 +- daemon/postprocess/DupeMatcher.cpp | 2 +- daemon/postprocess/Rename.h | 2 +- daemon/postprocess/Repair.h | 2 +- daemon/postprocess/Unpack.h | 2 +- daemon/util/Json.h | 1 - .../util/{Script.cpp => ScriptController.cpp} | 2 +- daemon/util/{Script.h => ScriptController.h} | 4 +- nzbget.vcxproj | 10 +- 20 files changed, 354 insertions(+), 231 deletions(-) create mode 100644 daemon/extension/LoadScriptFileStrategy.cpp create mode 100644 daemon/extension/LoadScriptFileStrategy.h create mode 100644 daemon/extension/Script.cpp create mode 100644 daemon/extension/Script.h rename daemon/util/{Script.cpp => ScriptController.cpp} (99%) rename daemon/util/{Script.h => ScriptController.h} (98%) diff --git a/daemon/extension/LoadScriptFileStrategy.cpp b/daemon/extension/LoadScriptFileStrategy.cpp new file mode 100644 index 000000000..3d412f2da --- /dev/null +++ b/daemon/extension/LoadScriptFileStrategy.cpp @@ -0,0 +1,139 @@ +/* + * This file is part of nzbget. See . + * + * Copyright (C) 2023 Denis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "nzbget.h" +#include "LoadScriptFileStrategy.h" +#include "FileSystem.h" +#include "Util.h" +#include "ScriptConfig.h" + +namespace LoadScriptFileStrategy +{ + bool HeaderConfigBased::Load(Script& script) const + { + // DiskFile infile; + // if (!infile.Open(script.GetLocation(), DiskFile::omRead)) + // { + // return false; + // } + + // CharBuffer buffer(1024 * 10 + 1); + + // const int beginSignatureLen = strlen(BEGIN_SCRIPT_SIGNATURE); + // const int queueEventsSignatureLen = strlen(QUEUE_EVENTS_SIGNATURE); + // const int taskTimeSignatureLen = strlen(TASK_TIME_SIGNATURE); + // const int definitionSignatureLen = strlen(DEFINITION_SIGNATURE); + + // // check if the file contains pp-script-signature + // // read first 10KB of the file and look for signature + // int readBytes = (int)infile.Read(buffer, buffer.Size() - 1); + // infile.Close(); + // buffer[readBytes] = '\0'; + + // bool postScript = false; + // bool scanScript = false; + // bool queueScript = false; + // bool schedulerScript = false; + // bool feedScript = false; + // char* queueEvents = nullptr; + // char* taskTime = nullptr; + + // bool inConfig = false; + // bool afterConfig = false; + + // // Declarations "QUEUE EVENT:" and "TASK TIME:" can be placed: + // // - in script definition body (between opening and closing script signatures); + // // - immediately before script definition (before opening script signature); + // // - immediately after script definition (after closing script signature). + // // The last two pissibilities are provided to increase compatibility of scripts with older + // // nzbget versions which do not expect the extra declarations in the script defintion body. + + // Tokenizer tok(buffer, "\n\r", true); + // while (char* line = tok.Next()) + // { + // if (!strncmp(line, QUEUE_EVENTS_SIGNATURE, queueEventsSignatureLen)) + // { + // queueEvents = line + queueEventsSignatureLen; + // } + // else if (!strncmp(line, TASK_TIME_SIGNATURE, taskTimeSignatureLen)) + // { + // taskTime = line + taskTimeSignatureLen; + // } + + // bool header = !strncmp(line, DEFINITION_SIGNATURE, definitionSignatureLen); + // if (!header && !inConfig) + // { + // queueEvents = nullptr; + // taskTime = nullptr; + // } + + // if (!header && afterConfig) + // { + // break; + // } + + // if (!strncmp(line, BEGIN_SCRIPT_SIGNATURE, beginSignatureLen) && strstr(line, END_SCRIPT_SIGNATURE)) + // { + // if (!inConfig) + // { + // inConfig = true; + // postScript = strstr(line, POST_SCRIPT_SIGNATURE); + // scanScript = strstr(line, SCAN_SCRIPT_SIGNATURE); + // queueScript = strstr(line, QUEUE_SCRIPT_SIGNATURE); + // schedulerScript = strstr(line, SCHEDULER_SCRIPT_SIGNATURE); + // feedScript = strstr(line, FEED_SCRIPT_SIGNATURE); + // } + // else + // { + // afterConfig = true; + // } + // } + // } + + // if (!(postScript || scanScript || queueScript || schedulerScript || feedScript)) + // { + // return false; + // } + + // // trim decorations + // char* p; + // while (queueEvents && *queueEvents && *(p = queueEvents + strlen(queueEvents) - 1) == '#') *p = '\0'; + // if (queueEvents) queueEvents = Util::Trim(queueEvents); + // while (taskTime && *taskTime && *(p = taskTime + strlen(taskTime) - 1) == '#') *p = '\0'; + // if (taskTime) taskTime = Util::Trim(taskTime); + + // script.SetPostScript(postScript); + // script.SetScanScript(scanScript); + // script.SetQueueScript(queueScript); + // script.SetSchedulerScript(schedulerScript); + // script.SetFeedScript(feedScript); + // script.SetQueueEvents(queueEvents); + // script.SetTaskTime(taskTime); + + return true; + } + + // ManifestBased::ManifestBased(ManifestFile::Manifest&& manifest_) + // : manifest{std::move(manifest_)} { } + + // bool ManifestBased::Load(Script& script) const + // { + // return false; + // } +} diff --git a/daemon/extension/LoadScriptFileStrategy.h b/daemon/extension/LoadScriptFileStrategy.h new file mode 100644 index 000000000..8d5307eb0 --- /dev/null +++ b/daemon/extension/LoadScriptFileStrategy.h @@ -0,0 +1,62 @@ +/* + * This file is part of nzbget. See . + * + * Copyright (C) 2023 Denis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOADSCRIPTFILESTRATEGY_H +#define LOADSCRIPTFILESTRATEGY_H + +#include "ManifestFile.h" +#include "Script.h" + +namespace LoadScriptFileStrategy +{ + static const char* BEGIN_SCRIPT_SIGNATURE = "### NZBGET "; + static const char* POST_SCRIPT_SIGNATURE = "POST-PROCESSING"; + static const char* SCAN_SCRIPT_SIGNATURE = "SCAN"; + static const char* QUEUE_SCRIPT_SIGNATURE = "QUEUE"; + static const char* SCHEDULER_SCRIPT_SIGNATURE = "SCHEDULER"; + static const char* FEED_SCRIPT_SIGNATURE = "FEED"; + static const char* END_SCRIPT_SIGNATURE = " SCRIPT"; + static const char* QUEUE_EVENTS_SIGNATURE = "### QUEUE EVENTS:"; + static const char* TASK_TIME_SIGNATURE = "### TASK TIME:"; + static const char* DEFINITION_SIGNATURE = "###"; + + class Strategy { + public: + virtual bool Load(Script& script) const = 0; + virtual ~Strategy() = default; + }; + + class HeaderConfigBased : public Strategy { + public: + bool Load(Script& script) const override; + ~HeaderConfigBased() = default; + }; + + // class ManifestBased : public Strategy { + // public: + // ManifestBased() = delete; + // explicit ManifestBased(ManifestFile::Manifest&& manifest_); + // bool Load(Script& script) const override; + // ~ManifestBased() {} + // private: + // ManifestFile::Manifest manifest; + // }; +} + +#endif diff --git a/daemon/extension/ManifestFile.cpp b/daemon/extension/ManifestFile.cpp index aaf3a1444..54444c85f 100644 --- a/daemon/extension/ManifestFile.cpp +++ b/daemon/extension/ManifestFile.cpp @@ -18,10 +18,10 @@ */ #include "nzbget.h" +#include #include "ManifestFile.h" #include "Json.h" #include "FileSystem.h" -#include namespace ManifestFile { diff --git a/daemon/extension/ManifestFile.h b/daemon/extension/ManifestFile.h index 5fe8d2420..1759e1c2e 100644 --- a/daemon/extension/ManifestFile.h +++ b/daemon/extension/ManifestFile.h @@ -20,25 +20,22 @@ #ifndef MANIFESTFILE_H #define MANIFESTFILE_H -#include "nzbget.h" -#include "NString.h" - namespace ManifestFile { - static const CString MANIFEST_FILE = "manifest.json"; + static const char* MANIFEST_FILE = "manifest.json"; struct Manifest { - CString author; - CString entry; - CString kind; - CString name; - CString displayName; - CString version; - CString license; - CString description; + const char* author; + const char* entry; + const char* kind; + const char* name; + const char* displayName; + const char* version; + const char* license; + const char* description; }; bool Load(Manifest& manifest, const char* directory); -} +}; #endif diff --git a/daemon/extension/NzbScript.h b/daemon/extension/NzbScript.h index 62acbf899..e2e7df693 100644 --- a/daemon/extension/NzbScript.h +++ b/daemon/extension/NzbScript.h @@ -21,7 +21,7 @@ #ifndef NZBSCRIPT_H #define NZBSCRIPT_H -#include "Script.h" +#include "ScriptController.h" #include "DownloadInfo.h" #include "ScriptConfig.h" diff --git a/daemon/extension/Script.cpp b/daemon/extension/Script.cpp new file mode 100644 index 000000000..8c4db467d --- /dev/null +++ b/daemon/extension/Script.cpp @@ -0,0 +1,44 @@ +/* + * This file is part of nzbget. See . + * + * Copyright (C) 2023 Denis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "nzbget.h" +#include "Script.h" +#include "NString.h" + +Script::Script(const char *name, const char *location) + : m_name(name), m_location(location), m_displayName(name){}; + +const char *Script::GetName() const { return m_name; } +const char *Script::GetLocation() const { return m_location; } +void Script::SetDisplayName(const char *displayName) { m_displayName = displayName; } +const char *Script::GetDisplayName() const { return m_displayName; } +bool Script::GetPostScript() const { return m_postScript; } +void Script::SetPostScript(bool postScript) { m_postScript = postScript; } +bool Script::GetScanScript() const { return m_scanScript; } +void Script::SetScanScript(bool scanScript) { m_scanScript = scanScript; } +bool Script::GetQueueScript() const { return m_queueScript; } +void Script::SetQueueScript(bool queueScript) { m_queueScript = queueScript; } +bool Script::GetSchedulerScript() const { return m_schedulerScript; } +void Script::SetSchedulerScript(bool schedulerScript) { m_schedulerScript = schedulerScript; } +bool Script::GetFeedScript() const { return m_feedScript; } +void Script::SetFeedScript(bool feedScript) { m_feedScript = feedScript; } +void Script::SetQueueEvents(const char *queueEvents) { m_queueEvents = queueEvents; } +const char *Script::GetQueueEvents() const { return m_queueEvents; } +void Script::SetTaskTime(const char *taskTime) { m_taskTime = taskTime; } +const char *Script::GetTaskTime() const { return m_taskTime; } diff --git a/daemon/extension/Script.h b/daemon/extension/Script.h new file mode 100644 index 000000000..7ca04b73a --- /dev/null +++ b/daemon/extension/Script.h @@ -0,0 +1,62 @@ +/* + * This file is part of nzbget. See . + * + * Copyright (C) 2023 Denis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SCRIPT_H +#define SCRIPT_H + +#include "NString.h" + +class Script +{ +public: + Script(const char *name, const char *location);; + Script(Script &&) = default; + const char *GetName() const; + const char *GetLocation() const; + void SetDisplayName(const char *displayName); + const char *GetDisplayName() const; + bool GetPostScript() const; + void SetPostScript(bool postScript); + bool GetScanScript() const; + void SetScanScript(bool scanScript); + bool GetQueueScript() const; + void SetQueueScript(bool queueScript); + bool GetSchedulerScript() const; + void SetSchedulerScript(bool schedulerScript); + bool GetFeedScript() const; + void SetFeedScript(bool feedScript); + void SetQueueEvents(const char *queueEvents); + const char *GetQueueEvents() const; + void SetTaskTime(const char *taskTime); + const char *GetTaskTime() const; + +private: + CString m_name; + CString m_location; + CString m_displayName; + bool m_postScript = false; + bool m_scanScript = false; + bool m_queueScript = false; + bool m_schedulerScript = false; + bool m_feedScript = false; + CString m_queueEvents; + CString m_taskTime; +}; + +#endif diff --git a/daemon/extension/ScriptConfig.cpp b/daemon/extension/ScriptConfig.cpp index 9fe60796a..86f302d12 100644 --- a/daemon/extension/ScriptConfig.cpp +++ b/daemon/extension/ScriptConfig.cpp @@ -24,127 +24,7 @@ #include "Options.h" #include "Log.h" #include "ScriptConfig.h" -//#include "ManifestFile.h" - -static const char* BEGIN_SCRIPT_SIGNATURE = "### NZBGET "; -static const char* POST_SCRIPT_SIGNATURE = "POST-PROCESSING"; -static const char* SCAN_SCRIPT_SIGNATURE = "SCAN"; -static const char* QUEUE_SCRIPT_SIGNATURE = "QUEUE"; -static const char* SCHEDULER_SCRIPT_SIGNATURE = "SCHEDULER"; -static const char* FEED_SCRIPT_SIGNATURE = "FEED"; -static const char* END_SCRIPT_SIGNATURE = " SCRIPT"; -static const char* QUEUE_EVENTS_SIGNATURE = "### QUEUE EVENTS:"; -static const char* TASK_TIME_SIGNATURE = "### TASK TIME:"; -static const char* DEFINITION_SIGNATURE = "###"; - -bool LoadScriptFileHeaderBasedStrategy::Load(ScriptConfig::Script& script) const -{ - DiskFile infile; - if (!infile.Open(script.GetLocation(), DiskFile::omRead)) - { - return false; - } - - CharBuffer buffer(1024 * 10 + 1); - - const int beginSignatureLen = strlen(BEGIN_SCRIPT_SIGNATURE); - const int queueEventsSignatureLen = strlen(QUEUE_EVENTS_SIGNATURE); - const int taskTimeSignatureLen = strlen(TASK_TIME_SIGNATURE); - const int definitionSignatureLen = strlen(DEFINITION_SIGNATURE); - - // check if the file contains pp-script-signature - // read first 10KB of the file and look for signature - int readBytes = (int)infile.Read(buffer, buffer.Size() - 1); - infile.Close(); - buffer[readBytes] = '\0'; - - bool postScript = false; - bool scanScript = false; - bool queueScript = false; - bool schedulerScript = false; - bool feedScript = false; - char* queueEvents = nullptr; - char* taskTime = nullptr; - - bool inConfig = false; - bool afterConfig = false; - - // Declarations "QUEUE EVENT:" and "TASK TIME:" can be placed: - // - in script definition body (between opening and closing script signatures); - // - immediately before script definition (before opening script signature); - // - immediately after script definition (after closing script signature). - // The last two pissibilities are provided to increase compatibility of scripts with older - // nzbget versions which do not expect the extra declarations in the script defintion body. - - Tokenizer tok(buffer, "\n\r", true); - while (char* line = tok.Next()) - { - if (!strncmp(line, QUEUE_EVENTS_SIGNATURE, queueEventsSignatureLen)) - { - queueEvents = line + queueEventsSignatureLen; - } - else if (!strncmp(line, TASK_TIME_SIGNATURE, taskTimeSignatureLen)) - { - taskTime = line + taskTimeSignatureLen; - } - - bool header = !strncmp(line, DEFINITION_SIGNATURE, definitionSignatureLen); - if (!header && !inConfig) - { - queueEvents = nullptr; - taskTime = nullptr; - } - - if (!header && afterConfig) - { - break; - } - - if (!strncmp(line, BEGIN_SCRIPT_SIGNATURE, beginSignatureLen) && strstr(line, END_SCRIPT_SIGNATURE)) - { - if (!inConfig) - { - inConfig = true; - postScript = strstr(line, POST_SCRIPT_SIGNATURE); - scanScript = strstr(line, SCAN_SCRIPT_SIGNATURE); - queueScript = strstr(line, QUEUE_SCRIPT_SIGNATURE); - schedulerScript = strstr(line, SCHEDULER_SCRIPT_SIGNATURE); - feedScript = strstr(line, FEED_SCRIPT_SIGNATURE); - } - else - { - afterConfig = true; - } - } - } - - if (!(postScript || scanScript || queueScript || schedulerScript || feedScript)) - { - return false; - } - - // trim decorations - char* p; - while (queueEvents && *queueEvents && *(p = queueEvents + strlen(queueEvents) - 1) == '#') *p = '\0'; - if (queueEvents) queueEvents = Util::Trim(queueEvents); - while (taskTime && *taskTime && *(p = taskTime + strlen(taskTime) - 1) == '#') *p = '\0'; - if (taskTime) taskTime = Util::Trim(taskTime); - - script.SetPostScript(postScript); - script.SetScanScript(scanScript); - script.SetQueueScript(queueScript); - script.SetSchedulerScript(schedulerScript); - script.SetFeedScript(feedScript); - script.SetQueueEvents(queueEvents); - script.SetTaskTime(taskTime); - - return true; -} - -bool LoadScriptFileStrategy::Load(ScriptConfig::Script& script) const -{ - return false; -} +#include "LoadScriptFileStrategy.h" void ScriptConfig::InitOptions() { @@ -280,8 +160,8 @@ bool ScriptConfig::LoadConfigTemplates(ConfigTemplates* configTemplates) Scripts scriptList; LoadScripts(scriptList); - const int beginSignatureLen = strlen(BEGIN_SCRIPT_SIGNATURE); - const int definitionSignatureLen = strlen(DEFINITION_SIGNATURE); + const int beginSignatureLen = strlen(LoadScriptFileStrategy::BEGIN_SCRIPT_SIGNATURE); + const int definitionSignatureLen = strlen(LoadScriptFileStrategy::DEFINITION_SIGNATURE); for (Script& script : scriptList) { @@ -299,13 +179,13 @@ bool ScriptConfig::LoadConfigTemplates(ConfigTemplates* configTemplates) while (infile.ReadLine(buf, sizeof(buf) - 1)) { - if (!strncmp(buf, BEGIN_SCRIPT_SIGNATURE, beginSignatureLen) && - strstr(buf, END_SCRIPT_SIGNATURE) && - (strstr(buf, POST_SCRIPT_SIGNATURE) || - strstr(buf, SCAN_SCRIPT_SIGNATURE) || - strstr(buf, QUEUE_SCRIPT_SIGNATURE) || - strstr(buf, SCHEDULER_SCRIPT_SIGNATURE) || - strstr(buf, FEED_SCRIPT_SIGNATURE))) + if (!strncmp(buf, LoadScriptFileStrategy::BEGIN_SCRIPT_SIGNATURE, beginSignatureLen) && + strstr(buf, LoadScriptFileStrategy::END_SCRIPT_SIGNATURE) && + (strstr(buf, LoadScriptFileStrategy::POST_SCRIPT_SIGNATURE) || + strstr(buf, LoadScriptFileStrategy::SCAN_SCRIPT_SIGNATURE) || + strstr(buf, LoadScriptFileStrategy::QUEUE_SCRIPT_SIGNATURE) || + strstr(buf, LoadScriptFileStrategy::SCHEDULER_SCRIPT_SIGNATURE) || + strstr(buf, LoadScriptFileStrategy::FEED_SCRIPT_SIGNATURE))) { if (inConfig) { @@ -316,7 +196,7 @@ bool ScriptConfig::LoadConfigTemplates(ConfigTemplates* configTemplates) continue; } - inHeader &= !strncmp(buf, DEFINITION_SIGNATURE, definitionSignatureLen); + inHeader &= !strncmp(buf, LoadScriptFileStrategy::DEFINITION_SIGNATURE, definitionSignatureLen); if (inConfig && !inHeader) { @@ -407,8 +287,7 @@ void ScriptConfig::LoadScriptDir(Scripts& scripts, const char* directory, bool i } Script script(scriptName, fullFilename); - LoadOldScriptFileStrategy strategy; - if (LoadScriptFile(script, strategy)) + if (LoadScriptFile(script, LoadScriptFileStrategy::HeaderConfigBased())) { scripts.push_back(std::move(script)); } @@ -422,7 +301,7 @@ void ScriptConfig::LoadScriptDir(Scripts& scripts, const char* directory, bool i } } -bool ScriptConfig::LoadScriptFile(Script& script, const LoadScriptFileStrategy& strategy) +bool ScriptConfig::LoadScriptFile(Script& script, const LoadScriptFileStrategy::Strategy &strategy) { return strategy.Load(script); } diff --git a/daemon/extension/ScriptConfig.h b/daemon/extension/ScriptConfig.h index 423069469..73a05b0b5 100644 --- a/daemon/extension/ScriptConfig.h +++ b/daemon/extension/ScriptConfig.h @@ -17,59 +17,20 @@ * along with this program. If not, see . */ - #ifndef SCRIPTCONFIG_H #define SCRIPTCONFIG_H #include "NString.h" #include "Container.h" #include "Options.h" -#include "ManifestFile.h" - -class LoadScriptFileStrategy; +#include "Script.h" +#include "LoadScriptFileStrategy.h" class ScriptConfig { public: - class Script - { - public: - Script(const char* name, const char* location) : - m_name(name), m_location(location), m_displayName(name) {}; - Script(Script&&) = default; - const char* GetName() const { return m_name; } - const char* GetLocation() { return m_location; } - void SetDisplayName(const char* displayName) { m_displayName = displayName; } - const char* GetDisplayName() { return m_displayName; } - bool GetPostScript() { return m_postScript; } - void SetPostScript(bool postScript) { m_postScript = postScript; } - bool GetScanScript() { return m_scanScript; } - void SetScanScript(bool scanScript) { m_scanScript = scanScript; } - bool GetQueueScript() { return m_queueScript; } - void SetQueueScript(bool queueScript) { m_queueScript = queueScript; } - bool GetSchedulerScript() { return m_schedulerScript; } - void SetSchedulerScript(bool schedulerScript) { m_schedulerScript = schedulerScript; } - bool GetFeedScript() { return m_feedScript; } - void SetFeedScript(bool feedScript) { m_feedScript = feedScript; } - void SetQueueEvents(const char* queueEvents) { m_queueEvents = queueEvents; } - const char* GetQueueEvents() { return m_queueEvents; } - void SetTaskTime(const char* taskTime) { m_taskTime = taskTime; } - const char* GetTaskTime() { return m_taskTime; } - - private: - CString m_name; - CString m_location; - CString m_displayName; - bool m_postScript = false; - bool m_scanScript = false; - bool m_queueScript = false; - bool m_schedulerScript = false; - bool m_feedScript = false; - CString m_queueEvents; - CString m_taskTime; - }; - - typedef std::list