Compare commits

...

26 Commits
v17.0 ... v17.1

Author SHA1 Message Date
Andrey Prygunkov
0c1fce27a2 update version string to "17.1" 2016-09-05 19:36:02 +02:00
Andrey Prygunkov
606cf56150 Merge branch 'develop' for v17.1 2016-09-05 19:19:34 +02:00
Andrey Prygunkov
af8451e16e updated ChangeLog for v17.1 2016-09-05 19:05:52 +02:00
Andrey Prygunkov
203a828bbd #224: corrected text in history delete confirmation dialog 2016-08-28 15:00:48 +02:00
Andrey Prygunkov
a990078884 fixed #265: compilation error if configured without TLS 2016-08-21 22:44:48 +02:00
Andrey Prygunkov
3e5bd203f3 fixed #86: javascript error on Chrome for Linux
Renamed “Notification” to “PopupNotification” to avoid conflict with
browsers built-in interface with the same name.
2016-08-21 22:34:42 +02:00
Andrey Prygunkov
042979d122 #245: removed debug logging 2016-08-16 20:43:13 +02:00
Andrey Prygunkov
11c464ed46 fixed #262: crash on malformed articles 2016-08-12 23:45:57 +02:00
Andrey Prygunkov
070054a814 fixed #261: hanging after marking as BAD from queue script 2016-08-12 22:28:37 +02:00
Andrey Prygunkov
5841cf5002 updated version string to 17.1-testing 2016-08-09 00:14:31 +02:00
Andrey Prygunkov
6dda360986 #253: reset stats if file on disk is missing on retry
Fixed: if by retrying download an included file is missing on disk it
was downloaded again but its stats (remaining size, etc.) were not
correctly reset.
2016-08-09 00:01:55 +02:00
Andrey Prygunkov
12ff14b397 #253: park active file too when deleting
If by deleting download only one file remains and it is partially
downloaded it should be counted as remaining (parked) file for command
“Download remaining files” be available (RemaingFileCount must be > 0).
2016-08-08 23:52:58 +02:00
Andrey Prygunkov
20aa83e0f7 #253: new field "RetryData" in RPC-method "history"
to more carefully indicate if “Retry failed articles” is possible.
2016-08-08 23:42:18 +02:00
Andrey Prygunkov
4c8c7ef46b #253: do not park when deleting without keeping files 2016-08-08 22:57:29 +02:00
Andrey Prygunkov
43a6717394 #253: pause-state when unparking par-files
if option ParCheck=Force then all par-files must be unpaused, otherwise
one par-file must be unpaused.
2016-08-06 22:09:08 +02:00
Andrey Prygunkov
b4fc57977b #253: do not park if all articles failed 2016-08-06 21:28:07 +02:00
Andrey Prygunkov
4f9dbdadc3 #253: fixed: not parking if all articles were successful 2016-08-06 21:16:13 +02:00
Chris
418acb052f #256: compatibility with gcc 4.8 2016-08-05 07:51:10 +02:00
Gokturk Yuksek
c741297d84 #255: do not compile par-tests if parcheck is disabled 2016-08-04 22:38:02 +02:00
Andrey Prygunkov
55fb4df411 fixed #254: installing multiple versions on Windows 2016-08-03 20:37:35 +02:00
Andrey Prygunkov
35643b0207 fixed #253: delete-with-parking sometimes didn't park 2016-08-03 19:55:07 +02:00
Andrey Prygunkov
45753410df fixed #251: performance issue on certain Windows systems 2016-08-02 20:03:41 +02:00
Andrey Prygunkov
b58de541b3 #162: corrected option description 2016-07-30 12:35:19 +02:00
Andrey Prygunkov
3d577777bb #136: improved error reporting on certain file operations 2016-07-29 16:45:15 +02:00
Andrey Prygunkov
a0e9c537a3 fixed #247: root drive paths on Windows
.. could not be used (for example “NzbDir=N:\”).
2016-07-29 16:22:11 +02:00
Andrey Prygunkov
a2d87de7b9 updated version string to 18.0-testing 2016-07-29 16:18:54 +02:00
28 changed files with 178 additions and 108 deletions

View File

@@ -1,3 +1,22 @@
nzbget-17.1:
- adjustments and fixes for "Retry failed articles" function, better handling
of certain corner cases;
- partial compatibility with gcc 4.8;
- removed unnecessary debug logging to javascript console;
- improved error reporting on certain file operations;
- corrected option description;
- corrected text in history delete confirmation dialog;
- fixed performance issue on certain Windows systems;
- fixed: root drive paths on Windows could not be used (for example
"NzbDir=N:\");
- fixed hanging after marking as BAD from queue script;
- fixed: old nzbget.exe was deleted even when installing into a new directory
(Windows only);
- fixed: compilation error if configured with unit tests but without par-module;
- fixed crash on malformed articles;
- fixed javascript error on Chrome for Linux;
- fixed compilation error if configured without TLS.
nzbget-17.0:
- reworked the full source code base to utilize modern C++ features:
- with the main motivation to make the code nicer and more fun to work

View File

@@ -217,8 +217,6 @@ nzbget_SOURCES += \
tests/main/CommandLineParserTest.cpp \
tests/main/OptionsTest.cpp \
tests/feed/FeedFilterTest.cpp \
tests/postprocess/ParCheckerTest.cpp \
tests/postprocess/ParRenamerTest.cpp \
tests/postprocess/DupeMatcherTest.cpp \
tests/queue/NzbFileTest.cpp \
tests/nntp/ServerPoolTest.cpp \
@@ -226,6 +224,12 @@ nzbget_SOURCES += \
tests/util/NStringTest.cpp \
tests/util/UtilTest.cpp
if WITH_PAR2
nzbget_SOURCES += \
tests/postprocess/ParCheckerTest.cpp \
tests/postprocess/ParRenamerTest.cpp
endif
AM_CPPFLAGS += \
-I$(srcdir)/lib/catch \
-I$(srcdir)/tests/suite

20
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for nzbget 17.0.
# Generated by GNU Autoconf 2.61 for nzbget 17.1.
#
# Report bugs to <hugbug@users.sourceforge.net>.
#
@@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='nzbget'
PACKAGE_TARNAME='nzbget'
PACKAGE_VERSION='17.0'
PACKAGE_STRING='nzbget 17.0'
PACKAGE_VERSION='17.1'
PACKAGE_STRING='nzbget 17.1'
PACKAGE_BUGREPORT='hugbug@users.sourceforge.net'
ac_unique_file="daemon/main/nzbget.cpp"
@@ -1251,7 +1251,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures nzbget 17.0 to adapt to many kinds of systems.
\`configure' configures nzbget 17.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1322,7 +1322,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of nzbget 17.0:";;
short | recursive ) echo "Configuration of nzbget 17.1:";;
esac
cat <<\_ACEOF
@@ -1466,7 +1466,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
nzbget configure 17.0
nzbget configure 17.1
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1480,7 +1480,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by nzbget $as_me 17.0, which was
It was created by nzbget $as_me 17.1, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -2276,7 +2276,7 @@ fi
# Define the identity of the package.
PACKAGE='nzbget'
VERSION='17.0'
VERSION='17.1'
cat >>confdefs.h <<_ACEOF
@@ -11825,7 +11825,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by nzbget $as_me 17.0, which was
This file was extended by nzbget $as_me 17.1, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -11878,7 +11878,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
nzbget config.status 17.0
nzbget config.status 17.1
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View File

@@ -21,7 +21,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(nzbget, 17.0, hugbug@users.sourceforge.net)
AC_INIT(nzbget, 17.1, hugbug@users.sourceforge.net)
AC_CONFIG_AUX_DIR(posix)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([foreign])

View File

@@ -110,7 +110,7 @@ void QueueScriptController::Run()
NzbInfo* nzbInfo = downloadQueue->GetQueue()->Find(m_id);
if (nzbInfo)
{
PrintMessage(Message::mkWarning, "Cancelling download and deleting %s", *m_nzbName);
nzbInfo->PrintMessage(Message::mkWarning, "Cancelling download and deleting %s", *m_nzbName);
nzbInfo->SetDeleteStatus(NzbInfo::dsBad);
downloadQueue->EditEntry(m_id, DownloadQueue::eaGroupDelete, 0, nullptr);
}
@@ -215,9 +215,7 @@ void QueueScriptController::AddMessage(Message::EKind kind, const char* text)
NzbInfo* nzbInfo = QueueScriptCoordinator::FindNzbInfo(downloadQueue, m_id);
if (nzbInfo)
{
SetLogPrefix(nullptr);
PrintMessage(Message::mkWarning, "Marking %s as bad", *m_nzbName);
SetLogPrefix(m_script->GetDisplayName());
nzbInfo->PrintMessage(Message::mkWarning, "Marking %s as bad", *m_nzbName);
nzbInfo->SetMarkStatus(NzbInfo::ksBad);
}
}

View File

@@ -957,7 +957,8 @@ void Options::InitServers()
#ifdef DISABLE_TLS
if (tls)
{
ConfigError("Invalid value for option \"%s\": program was compiled without TLS/SSL-support", optname);
ConfigError("Invalid value for option \"%s\": program was compiled without TLS/SSL-support",
*BString<100>("Server%i.Encryption", n));
tls = false;
}
#endif

View File

@@ -40,7 +40,7 @@ void Scheduler::FirstCheck()
Guard guard(m_taskListMutex);
std::sort(m_taskList.begin(), m_taskList.end(),
[](std::unique_ptr<Task>& task1, std::unique_ptr<Task>& task2)
[](const std::unique_ptr<Task>& task1, const std::unique_ptr<Task>& task2)
{
return (task1->m_hours < task2->m_hours) ||
((task1->m_hours == task2->m_hours) && (task1->m_minutes < task2->m_minutes));

View File

@@ -340,4 +340,19 @@ typedef unsigned char uchar;
#define SCANF_SYNTAX(strindex)
#endif
// providing "std::make_unique" for GCC 4.8.x (only 4.8.x)
#if __GNUC__ && __cplusplus < 201402L && __cpp_generic_lambdas < 201304
namespace std {
template<class T> struct _Unique_if { typedef unique_ptr<T> _Single_object; };
template<class T> struct _Unique_if<T[]> { typedef unique_ptr<T[]> _Unknown_bound; };
template<class T, class... Args> typename _Unique_if<T>::_Single_object make_unique(Args&&... args) {
return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
template<class T> typename _Unique_if<T>::_Unknown_bound make_unique(size_t n) {
typedef typename remove_extent<T>::type U;
return unique_ptr<T>(new U[n]());
}
}
#endif
#endif /* NZBGET_H */

View File

@@ -129,13 +129,13 @@ void HistoryCoordinator::AddToHistory(DownloadQueue* downloadQueue, NzbInfo* nzb
// park remaining files
for (FileInfo* fileInfo : nzbInfo->GetFileList())
{
fileInfo->GetNzbInfo()->UpdateCompletedStats(fileInfo);
fileInfo->GetNzbInfo()->GetCompletedFiles()->emplace_back(fileInfo->GetId(),
nzbInfo->UpdateCompletedStats(fileInfo);
nzbInfo->GetCompletedFiles()->emplace_back(fileInfo->GetId(),
fileInfo->GetFilename(), CompletedFile::cfNone, 0);
}
// Cleaning up parked files if par-check was successful or unpack was successful or
// health is 100% (if unpack and par-check were not performed)
// health is 100% (if unpack and par-check were not performed) or if deleted
bool cleanupParkedFiles =
((nzbInfo->GetParStatus() == NzbInfo::psSuccess ||
nzbInfo->GetParStatus() == NzbInfo::psRepairPossible) &&
@@ -147,7 +147,13 @@ void HistoryCoordinator::AddToHistory(DownloadQueue* downloadQueue, NzbInfo* nzb
(nzbInfo->GetUnpackStatus() <= NzbInfo::usSkipped &&
nzbInfo->GetParStatus() != NzbInfo::psFailure &&
nzbInfo->GetFailedSize() - nzbInfo->GetParFailedSize() == 0) ||
nzbInfo->GetUnpackCleanedUpDisk();
(nzbInfo->GetDeleteStatus() != NzbInfo::dsNone);
// Do not cleanup when parking
cleanupParkedFiles &= !nzbInfo->GetParking();
// Parking not possible if files were already deleted
cleanupParkedFiles |= nzbInfo->GetUnpackCleanedUpDisk();
if (cleanupParkedFiles)
{
@@ -158,7 +164,10 @@ void HistoryCoordinator::AddToHistory(DownloadQueue* downloadQueue, NzbInfo* nzb
nzbInfo->SetParkedFileCount(0);
for (CompletedFile& completedFile : nzbInfo->GetCompletedFiles())
{
if (completedFile.GetStatus() == CompletedFile::cfNone)
if (completedFile.GetStatus() == CompletedFile::cfNone ||
// consider last completed file with partial status not completely tried
(completedFile.GetStatus() == CompletedFile::cfPartial &&
&completedFile == &*nzbInfo->GetCompletedFiles()->rbegin()))
{
nzbInfo->PrintMessage(Message::mkDetail, "Parking file %s", completedFile.GetFileName());
nzbInfo->SetParkedFileCount(nzbInfo->GetParkedFileCount() + 1);
@@ -576,7 +585,6 @@ void HistoryCoordinator::HistoryRetry(DownloadQueue* downloadQueue, HistoryList:
(resetFailed || fileInfo->GetRemainingSize() > 0))))
{
fileInfo->SetFilename(completedFile.GetFileName());
fileInfo->SetPaused(fileInfo->GetParFile());
fileInfo->SetNzbInfo(nzbInfo);
BString<1024> outputFilename("%s%c%s", nzbInfo->GetDestDir(), PATH_SEPARATOR, fileInfo->GetFilename());
@@ -595,6 +603,7 @@ void HistoryCoordinator::HistoryRetry(DownloadQueue* downloadQueue, HistoryList:
else if (!reprocess)
{
nzbInfo->PrintMessage(Message::mkWarning, "File %s could not be found on disk, downloading again", fileInfo->GetFilename());
fileInfo->SetPartialState(FileInfo::psNone);
}
}
@@ -619,6 +628,11 @@ void HistoryCoordinator::HistoryRetry(DownloadQueue* downloadQueue, HistoryList:
nzbInfo->UpdateCurrentStats();
MoveToQueue(downloadQueue, itHistory, historyInfo, reprocess);
if (g_Options->GetParCheck() != Options::pcForce)
{
downloadQueue->EditEntry(nzbInfo->GetId(), DownloadQueue::eaGroupPauseExtraPars, 0, nullptr);
}
}
void HistoryCoordinator::ResetArticles(FileInfo* fileInfo, bool allFailed, bool resetFailed)

View File

@@ -709,7 +709,8 @@ void QueueCoordinator::DeleteFileInfo(DownloadQueue* downloadQueue, FileInfo* fi
{
fileInfo->GetNzbInfo()->GetCompletedFiles()->emplace_back(
fileInfo->GetId(),
completed ? FileSystem::BaseFileName(fileInfo->GetOutputFilename()) : fileInfo->GetFilename(),
completed && fileInfo->GetOutputFilename() ?
FileSystem::BaseFileName(fileInfo->GetOutputFilename()) : fileInfo->GetFilename(),
fileStatus,
fileStatus == CompletedFile::cfSuccess ? fileInfo->GetCrc() : 0);
}

View File

@@ -38,7 +38,7 @@ public:
GroupSorter(NzbList* nzbList, QueueEditor::ItemList* sortItemList) :
m_nzbList(nzbList), m_sortItemList(sortItemList) {}
bool Execute(const char* sort);
bool operator()(std::unique_ptr<NzbInfo>& refNzbInfo1, std::unique_ptr<NzbInfo>& refNzbInfo2) const;
bool operator()(const std::unique_ptr<NzbInfo>& refNzbInfo1, const std::unique_ptr<NzbInfo>& refNzbInfo2) const;
private:
enum ESortCriteria
@@ -129,7 +129,7 @@ bool GroupSorter::Execute(const char* sort)
std::sort(m_nzbList->begin(), m_nzbList->end(), *this);
if (origSortOrder == soAuto &&
std::equal(tempList.begin(), tempList.end(), m_nzbList->begin(), m_nzbList->end(),
std::equal(tempList.begin(), tempList.end(), m_nzbList->begin(),
[](NzbInfo* nzbInfo1, std::unique_ptr<NzbInfo>& nzbInfo2)
{
return nzbInfo1 == nzbInfo2.get();
@@ -142,7 +142,7 @@ bool GroupSorter::Execute(const char* sort)
return true;
}
bool GroupSorter::operator()(std::unique_ptr<NzbInfo>& refNzbInfo1, std::unique_ptr<NzbInfo>& refNzbInfo2) const
bool GroupSorter::operator()(const std::unique_ptr<NzbInfo>& refNzbInfo1, const std::unique_ptr<NzbInfo>& refNzbInfo2) const
{
NzbInfo* nzbInfo1 = refNzbInfo1.get();
NzbInfo* nzbInfo2 = refNzbInfo2.get();
@@ -778,7 +778,7 @@ bool QueueEditor::EditGroup(NzbInfo* nzbInfo, DownloadQueue::EEditAction action,
nzbInfo->SetParking(action == DownloadQueue::eaGroupParkDelete &&
g_Options->GetKeepHistory() > 0 &&
!nzbInfo->GetUnpackCleanedUpDisk() &&
(nzbInfo->GetSuccessArticles() > 0 || nzbInfo->GetFailedArticles() > 0));
nzbInfo->GetCurrentSuccessArticles() > 0);
nzbInfo->SetAvoidHistory(action == DownloadQueue::eaGroupFinalDelete);
nzbInfo->SetDeletePaused(allPaused);
if (action == DownloadQueue::eaGroupDupeDelete)

View File

@@ -2426,6 +2426,7 @@ void HistoryXmlCommand::Execute()
"<member><name>ID</name><value><i4>%i</i4></value></member>\n" // Deprecated, use "NZBID" instead
"<member><name>Name</name><value><string>%s</string></value></member>\n"
"<member><name>RemainingFileCount</name><value><i4>%i</i4></value></member>\n"
"<member><name>RetryData</name><value><boolean>%s</boolean></value></member>\n"
"<member><name>HistoryTime</name><value><i4>%i</i4></value></member>\n"
"<member><name>Status</name><value><string>%s</string></value></member>\n"
"<member><name>Log</name><value><array><data></data></array></value></member>\n"; // Deprected, always empty
@@ -2435,6 +2436,7 @@ void HistoryXmlCommand::Execute()
"\"ID\" : %i,\n" // Deprecated, use "NZBID" instead
"\"Name\" : \"%s\",\n"
"\"RemainingFileCount\" : %i,\n"
"\"RetryData\" : %s,\n"
"\"HistoryTime\" : %i,\n"
"\"Status\" : \"%s\",\n"
"\"Log\" : [],\n"; // Deprected, always empty
@@ -2506,7 +2508,7 @@ void HistoryXmlCommand::Execute()
AppendFmtResponse(IsJson() ? JSON_HISTORY_ITEM_START : XML_HISTORY_ITEM_START,
historyInfo->GetId(), *EncodeStr(historyInfo->GetName()), nzbInfo->GetParkedFileCount(),
historyInfo->GetTime(), status);
BoolToStr(nzbInfo->GetCompletedFiles()->size()), historyInfo->GetTime(), status);
}
else if (historyInfo->GetKind() == HistoryInfo::hkDup)
{

View File

@@ -30,6 +30,16 @@ CString FileSystem::GetLastErrorMessage()
{
BString<1024> msg;
strerror_r(errno, msg, msg.Capacity());
#ifdef WIN32
if (!errno)
{
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
msg, 1024, nullptr);
}
#endif
return *msg;
}
@@ -105,6 +115,7 @@ bool FileSystem::ForceDirectories(const char* path, CString& errmsg)
}
}
errmsg.Format("path %s does not exist and could not be created", *normPath);
return false;
}
#else
@@ -249,6 +260,7 @@ bool FileSystem::AllocateFile(const char* filename, int64 size, bool sparse, CSt
HANDLE hFile = CreateFileW(UtfPathToWidePath(filename), GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_NEW, 0, nullptr);
if (hFile == INVALID_HANDLE_VALUE)
{
errno = 0; // wanting error message from WinAPI instead of C-lib
errmsg = GetLastErrorMessage();
return false;
}
@@ -526,17 +538,21 @@ bool FileSystem::DirectoryExists(const char* dirFilename)
{
#ifdef WIN32
WIN32_FIND_DATAW findData;
// extra "\*" needed for network shares
HANDLE handle = FindFirstFileW(UtfPathToWidePath(
BString<1024>(dirFilename && dirFilename[strlen(dirFilename) - 1] == PATH_SEPARATOR ? "%s*" : "%s\\*", dirFilename)),
&findData);
if (handle != INVALID_HANDLE_VALUE)
{
bool exists = ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) ||
(strlen(dirFilename) == 3 && dirFilename[1] == ':');
(dirFilename[0] != '\0' && dirFilename[1] == ':' && (dirFilename[2] == '\0' || dirFilename[3] == '\0'));
FindClose(handle);
return exists;
}
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
// path exists but doesn't have any file/directory entries - possible only for root paths (e. g. "C:\")
return true;
}
return false;
#else
struct stat buffer;
@@ -841,10 +857,8 @@ bool FileSystem::FlushFileBuffers(int fileDescriptor, CString& errmsg)
BOOL ok = ::FlushFileBuffers((HANDLE)_get_osfhandle(fileDescriptor));
if (!ok)
{
errmsg.Reserve(1024 - 1);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
errmsg, 1024, nullptr);
errno = 0; // wanting error message from WinAPI instead of C-lib
errmsg = GetLastErrorMessage();
}
return ok;
#else

View File

@@ -506,7 +506,23 @@ bool Util::RegReadStr(HKEY keyRoot, const char* keyName, const char* valueName,
time_t Util::CurrentTime()
{
#ifdef WIN32
// C-library function "time()" works on Windows too but is very CPU intensive
// since it uses high performance timer which we don't need anyway.
// A combination of GetSystemTime() + Timegm() works much faster.
SYSTEMTIME systm;
GetSystemTime(&systm);
struct tm tm;
tm.tm_year = systm.wYear - 1900;
tm.tm_mon = systm.wMonth - 1;
tm.tm_mday = systm.wDay;
tm.tm_hour = systm.wHour;
tm.tm_min = systm.wMinute;
tm.tm_sec = systm.wSecond;
return Timegm(&tm);
#else
return ::time(nullptr);
#endif
}
/* From boost */

View File

@@ -14,11 +14,6 @@ MainDir=~/downloads
#
# If you want to distinguish between partially downloaded files and
# completed downloads, use also option <InterDir>.
#
# It is allowed to enter multiple directories here by separating them with comma
# or semicolon. NZBGet checks how much free disk space is available in each
# directory (assuming all directories are located on different drives) and
# chooses the directory with the most free space.
DestDir=${MainDir}/dst
# Directory to store intermediate files.

View File

@@ -52,7 +52,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\par2;.\windows\resources;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="17.0";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="17.1";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@@ -72,7 +72,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.\daemon\connect;.\daemon\extension;.\daemon\feed;.\daemon\frontend;.\daemon\main;.\daemon\nntp;.\daemon\postprocess;.\daemon\queue;.\daemon\remote;.\daemon\util;.\daemon\windows;.\lib\par2;.\windows\resources;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="17.0";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="17.1";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>

View File

@@ -1537,7 +1537,7 @@ var Config = (new function($)
$('#Notif_Config_TestConnectionProgress').fadeOut(function() {
if (errtext == '')
{
Notification.show('#Notif_Config_TestConnectionOK');
PopupNotification.show('#Notif_Config_TestConnectionOK');
}
else
{
@@ -1662,7 +1662,7 @@ var Config = (new function($)
if (serverSaveRequest.length === 0 && webSaveRequest.length === 0)
{
Notification.show('#Notif_Config_Unchanged');
PopupNotification.show('#Notif_Config_Unchanged');
return;
}
@@ -1706,7 +1706,7 @@ var Config = (new function($)
}
else
{
Notification.show('#Notif_Config_Failed');
PopupNotification.show('#Notif_Config_Failed');
}
configSaved = true;
}
@@ -2556,7 +2556,7 @@ var RestoreSettingsDialog = (new function($)
var checkedCount = $SectionTable.fasttable('checkedCount');
if (checkedCount === 0)
{
Notification.show('#Notif_Config_RestoreSections');
PopupNotification.show('#Notif_Config_RestoreSections');
return;
}
@@ -2814,7 +2814,7 @@ var UpdateDialog = (new function($)
{
if (!started)
{
Notification.show('#Notif_StartUpdate_Failed');
PopupNotification.show('#Notif_StartUpdate_Failed');
return;
}

View File

@@ -355,7 +355,7 @@ var Downloads = (new function($)
Refresher.update();
if (notification)
{
Notification.show(notification);
PopupNotification.show(notification);
notification = null;
}
}
@@ -375,12 +375,12 @@ var Downloads = (new function($)
{
if (group.postprocess && !allowPostProcess)
{
Notification.show('#Notif_Downloads_CheckPostProcess');
PopupNotification.show('#Notif_Downloads_CheckPostProcess');
return null;
}
if (group.Kind === 'URL' && !allowUrl)
{
Notification.show('#Notif_Downloads_CheckURL');
PopupNotification.show('#Notif_Downloads_CheckURL');
return null;
}
@@ -390,7 +390,7 @@ var Downloads = (new function($)
if (checkedEditIDs.length === 0 && !allowEmpty)
{
Notification.show('#Notif_Downloads_Select');
PopupNotification.show('#Notif_Downloads_Select');
return null;
}
@@ -427,7 +427,7 @@ var Downloads = (new function($)
if (checkedEditIDs.length < 2)
{
Notification.show('#Notif_Downloads_SelectMulti');
PopupNotification.show('#Notif_Downloads_SelectMulti');
return;
}
@@ -490,7 +490,7 @@ var Downloads = (new function($)
if (downloadIDs.length === 0 && postprocessIDs.length === 0)
{
Notification.show('#Notif_Downloads_Select');
PopupNotification.show('#Notif_Downloads_Select');
return;
}

View File

@@ -299,7 +299,7 @@ var DownloadsEditDialog = (new function($)
Refresher.update();
if (notification)
{
Notification.show(notification);
PopupNotification.show(notification);
notification = null;
}
}
@@ -655,7 +655,7 @@ var DownloadsEditDialog = (new function($)
var checkedCount = $DownloadsFileTable.fasttable('checkedCount');
if (checkedCount === 0)
{
Notification.show('#Notif_Edit_Select');
PopupNotification.show('#Notif_Edit_Select');
return;
}
@@ -748,7 +748,7 @@ var DownloadsEditDialog = (new function($)
{
if (splitError)
{
Notification.show('#Notif_Downloads_SplitNotPossible');
PopupNotification.show('#Notif_Downloads_SplitNotPossible');
}
else
{
@@ -1416,7 +1416,7 @@ var DownloadsMultiDialog = (new function($)
Refresher.update();
if (notification)
{
Notification.show(notification);
PopupNotification.show(notification);
}
}
}(jQuery));
@@ -1484,7 +1484,7 @@ var DownloadsMergeDialog = (new function($)
{
$DownloadsMergeDialog.modal('hide');
Refresher.update();
Notification.show('#Notif_Downloads_Merged');
PopupNotification.show('#Notif_Downloads_Merged');
}
}(jQuery));
@@ -1541,7 +1541,7 @@ var DownloadsSplitDialog = (new function($)
$('#DownloadsEditDialog').modal('hide');
$DownloadsSplitDialog.modal('hide');
Refresher.update();
Notification.show(result ? '#Notif_Downloads_Splitted' : '#Notif_Downloads_SplitError');
PopupNotification.show(result ? '#Notif_Downloads_Splitted' : '#Notif_Downloads_SplitError');
}
}(jQuery));
@@ -1740,8 +1740,7 @@ var HistoryEditDialog = (new function()
Util.show('#HistoryEdit_Return', hist.RemainingFileCount > 0);
Util.show('#HistoryEdit_ReturnURL', hist.Kind === 'URL');
Util.show('#HistoryEdit_Redownload', hist.Kind === 'NZB');
Util.show('#HistoryEdit_RetryFailed', hist.Kind === 'NZB' && hist.FailedArticles > 0 && hist.ParStatus !== 'SUCCESS' &&
(hist.DeleteStatus === 'NONE' || hist.RemainingFileCount > 0));
Util.show('#HistoryEdit_RetryFailed', hist.Kind === 'NZB' && hist.FailedArticles > 0 && hist.RetryData);
Util.show('#HistoryEdit_PathGroup, #HistoryEdit_StatisticsGroup, #HistoryEdit_Reprocess', hist.Kind === 'NZB');
Util.show('#HistoryEdit_CategoryGroup', hist.Kind !== 'DUP');
Util.show('#HistoryEdit_DupGroup', hist.Kind === 'DUP');
@@ -1902,7 +1901,8 @@ var HistoryEditDialog = (new function()
{
e.preventDefault();
HistoryUI.deleteConfirm(doItemDelete, curHist.Kind === 'NZB', curHist.Kind === 'DUP',
curHist.ParStatus === 'FAILURE' || curHist.UnpackStatus === 'FAILURE', false);
curHist.ParStatus === 'FAILURE' || curHist.UnpackStatus === 'FAILURE' ||
curHist.DeleteStatus != 'NONE', false);
}
function doItemDelete(command)
@@ -1975,7 +1975,7 @@ var HistoryEditDialog = (new function()
Refresher.update();
if (notification)
{
Notification.show(notification);
PopupNotification.show(notification);
notification = null;
}
}

View File

@@ -80,7 +80,7 @@ var Feeds = (new function($)
var id = parseInt($(this).attr('data-id'));
RPC.call('fetchfeed', [id], function()
{
Notification.show('#Notif_Feeds_Fetch');
PopupNotification.show('#Notif_Feeds_Fetch');
});
}
@@ -88,7 +88,7 @@ var Feeds = (new function($)
{
RPC.call('fetchfeed', [0], function()
{
Notification.show('#Notif_Feeds_Fetch');
PopupNotification.show('#Notif_Feeds_Fetch');
});
}
}(jQuery));
@@ -333,7 +333,7 @@ var FeedDialog = (new function($)
var checkedCount = $ItemTable.fasttable('checkedCount');
if (checkedCount === 0)
{
Notification.show('#Notif_FeedDialog_Select');
PopupNotification.show('#Notif_FeedDialog_Select');
return;
}
@@ -372,7 +372,7 @@ var FeedDialog = (new function($)
else
{
$FeedDialog.modal('hide');
Notification.show('#Notif_FeedDialog_Fetched');
PopupNotification.show('#Notif_FeedDialog_Fetched');
}
}

View File

@@ -260,7 +260,7 @@ var History = (new function($)
var checkedCount = $HistoryTable.fasttable('checkedCount');
if (checkedCount === 0)
{
Notification.show('#Notif_History_Select');
PopupNotification.show('#Notif_History_Select');
return;
}
@@ -276,7 +276,8 @@ var History = (new function($)
hasNzb |= hist.Kind === 'NZB';
hasUrl |= hist.Kind === 'URL';
hasDup |= hist.Kind === 'DUP';
hasFailed |= hist.ParStatus === 'FAILURE' || hist.UnpackStatus === 'FAILURE';
hasFailed |= hist.ParStatus === 'FAILURE' || hist.UnpackStatus === 'FAILURE' ||
hist.DeleteStatus != 'NONE';
}
}
@@ -290,7 +291,7 @@ var History = (new function($)
case 'REPROCESS':
if (hasUrl || hasDup)
{
Notification.show('#Notif_History_CantReprocess');
PopupNotification.show('#Notif_History_CantReprocess');
return;
}
notification = '#Notif_History_Reprocess';
@@ -300,7 +301,7 @@ var History = (new function($)
case 'REDOWNLOAD':
if (hasDup)
{
Notification.show('#Notif_History_CantRedownload');
PopupNotification.show('#Notif_History_CantRedownload');
return;
}
notification = '#Notif_History_Returned';
@@ -315,7 +316,7 @@ var History = (new function($)
case 'MARKBAD':
if (hasUrl)
{
Notification.show('#Notif_History_CantMark');
PopupNotification.show('#Notif_History_CantMark');
return;
}
notification = '#Notif_History_Marked';
@@ -359,7 +360,7 @@ var History = (new function($)
Refresher.update();
if (notification)
{
Notification.show(notification);
PopupNotification.show(notification);
notification = null;
}
}
@@ -497,7 +498,6 @@ var HistoryUI = (new function($)
this.deleteConfirm = function(actionCallback, hasNzb, hasDup, hasFailed, multi, selCount)
{
var dupeCheck = Options.option('DupeCheck') === 'yes';
var cleanupDisk = Options.option('DeleteCleanupDisk') === 'yes';
var dialog = null;
function init(_dialog)
@@ -507,8 +507,7 @@ var HistoryUI = (new function($)
$('#HistoryDeleteConfirmDialog_Hide', dialog).prop('checked', true);
Util.show($('#HistoryDeleteConfirmDialog_Options', dialog), hasNzb && dupeCheck);
Util.show($('#HistoryDeleteConfirmDialog_Simple', dialog), !(hasNzb && dupeCheck));
Util.show($('#HistoryDeleteConfirmDialog_DeleteWillCleanup', dialog), hasNzb && hasFailed && cleanupDisk);
Util.show($('#HistoryDeleteConfirmDialog_DeleteCanCleanup', dialog), hasNzb && hasFailed && !cleanupDisk);
Util.show($('#HistoryDeleteConfirmDialog_DeleteWillCleanup', dialog), hasNzb && hasFailed);
Util.show($('#HistoryDeleteConfirmDialog_DeleteNoCleanup', dialog), !(hasNzb && hasFailed));
Util.show($('#HistoryDeleteConfirmDialog_DupAlert', dialog), !hasNzb && dupeCheck && hasDup);
Util.show('#ConfirmDialog_Help', hasNzb && dupeCheck);

View File

@@ -2043,14 +2043,9 @@
Selected records will be deleted from history. All files remain on disk.
</p>
<p id="HistoryDeleteConfirmDialog_DeleteCanCleanup" class="confirm-help-block">
Selected records will be deleted from history. All files remain on disk (for failed downloads this
behavior can be changed via option <strong><em>DeleteCleanupDisk</em></strong>).
</p>
<p id="HistoryDeleteConfirmDialog_DeleteWillCleanup" class="confirm-help-block">
Selected records will be deleted from history. For failed downloads (par-failure or unpack-failure)
all downloaded files will be deleted (this behavior can be changed via option <strong><em>DeleteCleanupDisk</em></strong>).
Selected records will be deleted from history. For failed downloads
all downloaded files will be deleted.
</p>
<p id="HistoryDeleteConfirmDialog_DupAlert" class="alert alert-warning" style="margin-top: 10px;">

View File

@@ -812,7 +812,7 @@ var Refresher = (new function($)
function TODO(text)
{
$('#Notif_NotImplemented_Param').html(text === undefined ? '' : ': ' + text);
Notification.show('#Notif_NotImplemented');
PopupNotification.show('#Notif_NotImplemented');
}
@@ -912,7 +912,7 @@ var AlertDialog = (new function($)
/*** NOTIFICATIONS *********************************************************/
var Notification = (new function($)
var PopupNotification = (new function($)
{
'use strict';

View File

@@ -304,7 +304,7 @@ var Messages = (new function($)
Refresher.update();
if (notification)
{
Notification.show(notification);
PopupNotification.show(notification);
notification = null;
}
}

View File

@@ -208,7 +208,7 @@ var Status = (new function($)
showBtn.fadeIn(500);
if (!Play && !status.ServerStandBy)
{
Notification.show('#Notif_Downloads_Pausing');
PopupNotification.show('#Notif_Downloads_Pausing');
}
}
else
@@ -258,7 +258,7 @@ var Status = (new function($)
this.playClick = function()
{
//Notification.show('#Notif_Play');
//PopupNotification.show('#Notif_Play');
if (lastPlayState)
{
@@ -415,7 +415,6 @@ var Status = (new function($)
if (title.indexOf(name) > -1)
{
var value = titleGen[name]();
console.log(name + '=' + value);
title = title.replace(name, value);
}
}
@@ -1273,7 +1272,7 @@ var StatDialog = (new function($)
var year = parseInt(period);
if (year < 2013 || year > 2050)
{
Notification.show('#Notif_StatRangeError');
PopupNotification.show('#Notif_StatRangeError');
return;
}
period = '' + year;
@@ -1284,7 +1283,7 @@ var StatDialog = (new function($)
var year = parseInt(period.substring(0, 4));
if (year < 2013 || year > 2050 || month < 1 || month > 12)
{
Notification.show('#Notif_StatRangeError');
PopupNotification.show('#Notif_StatRangeError');
return;
}
period = year + '-' + (month-1);
@@ -1305,7 +1304,7 @@ var StatDialog = (new function($)
{
RPC.call('resetservervolume', [curServer === 0 ? -1 : curServer, 'CUSTOM'], function()
{
Notification.show('#Notif_StatReset');
PopupNotification.show('#Notif_StatReset');
Refresher.update();
});
}
@@ -1476,7 +1475,7 @@ var LimitDialog = (new function($)
$LimitDialog.modal('hide');
if (changed)
{
Notification.show('#Notif_SetSpeedLimit');
PopupNotification.show('#Notif_SetSpeedLimit');
}
Refresher.update();
}
@@ -1599,7 +1598,7 @@ var FilterMenu = (new function($)
{
if ($Table_filter.val() === '')
{
Notification.show('#Notif_SaveFilterEmpty');
PopupNotification.show('#Notif_SaveFilterEmpty');
return;
}

View File

@@ -1298,7 +1298,7 @@ ul.help > li {
filter: alpha(opacity=0);
}
/* BEGIN: Notification alerts */
/* BEGIN: PopupNotification alerts */
.alert-inverse {
color: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
@@ -1339,7 +1339,7 @@ ul.help > li {
.alert-info.alert-center {
border-color: #3a87ad;
}
/* END: Notification alerts */
/* END: PopupNotification alerts */
.confirm-help-block {
color: #555555;

View File

@@ -448,7 +448,7 @@ var Upload = (new function($)
$AddDialog.modal('hide');
if (index > 0)
{
Notification.show('#Notif_AddFiles');
PopupNotification.show('#Notif_AddFiles');
}
}
}
@@ -465,7 +465,7 @@ var Upload = (new function($)
{
needRefresh = true;
$AddDialog.modal('hide');
Notification.show('#Notif_Scan');
PopupNotification.show('#Notif_Scan');
});
}
}(jQuery));

View File

@@ -103,26 +103,24 @@ LogSet on
SetOutPath "$INSTDIR"
; Stop NZBGet (if running)
ReadRegStr $R1 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NZBGet" "InstallLocation"
${If} $R1 != ""
${AndIf} ${FileExists} "$R1\nzbget.exe"
Delete "$R1\nzbget.exe"
ExecWait '"$R1\nzbget.exe" -Q' $R2
${If} ${FileExists} "$INSTDIR\nzbget.exe"
Delete "$INSTDIR\nzbget.exe"
ExecWait '"$INSTDIR\nzbget.exe" -Q' $R2
DetailPrint "Stopping NZBGet..."
try_delete:
; Wait up to 10 seconds until stopped
StrCpy $R2 20
${While} ${FileExists} "$R1\nzbget.exe"
${While} ${FileExists} "$INSTDIR\nzbget.exe"
${If} $R2 = 0
${Break}
${EndIf}
Sleep 500
IntOp $R2 $R2 - 1
Delete "$R1\nzbget.exe"
Delete "$INSTDIR\nzbget.exe"
${EndWhile}
${If} ${FileExists} "$R1\nzbget.exe"
${If} ${FileExists} "$INSTDIR\nzbget.exe"
MessageBox MB_RETRYCANCEL "NZBGet seems to be running right now. Please stop NZBGet and try again." \
IDRETRY try_delete IDCANCEL cancel
cancel: