mirror of
https://github.com/nzbget/nzbget.git
synced 2026-02-25 10:35:52 -05:00
Compare commits
27 Commits
v20.0
...
v21.0-r222
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3339a2c520 | ||
|
|
17c5a9cbc8 | ||
|
|
4db9ef2535 | ||
|
|
5a0eae7bf4 | ||
|
|
86ac23b6aa | ||
|
|
fa1aa45fa7 | ||
|
|
f842a19544 | ||
|
|
f3cb44e7b2 | ||
|
|
e54ffbaaaa | ||
|
|
2d049f1904 | ||
|
|
5106979d5d | ||
|
|
75d05bce4a | ||
|
|
ea4ea2c901 | ||
|
|
5e15677218 | ||
|
|
93ad31b9d8 | ||
|
|
14c5a1caf7 | ||
|
|
f52f5b5de9 | ||
|
|
0916c2a908 | ||
|
|
ab1238dde4 | ||
|
|
758ce4047b | ||
|
|
c24bf0e8ce | ||
|
|
1264878a97 | ||
|
|
a85ff314f3 | ||
|
|
a349ab08f7 | ||
|
|
064de49edf | ||
|
|
ae79c56c07 | ||
|
|
d6353e9cee |
@@ -1,3 +1,7 @@
|
||||
nzbget-21.0:
|
||||
- please see repository change log at
|
||||
https://github.com/nzbget/nzbget/commits/develop
|
||||
|
||||
nzbget-20.0:
|
||||
- massive performance optimisations in downloader:
|
||||
- improved yEnc decoder;
|
||||
|
||||
@@ -345,6 +345,7 @@ linux_FILES = \
|
||||
linux/build-info.txt \
|
||||
linux/build-nzbget \
|
||||
linux/build-unpack \
|
||||
linux/build-toolchain-android \
|
||||
linux/build-toolchain-freebsd
|
||||
|
||||
doc_FILES = \
|
||||
@@ -413,6 +414,14 @@ testdata_FILES = \
|
||||
tests/testdata/parchecker/testfile.vol00+1.PAR2 \
|
||||
tests/testdata/parchecker/testfile.vol01+2.PAR2 \
|
||||
tests/testdata/parchecker/testfile.vol03+3.PAR2 \
|
||||
tests/testdata/parchecker2/crc.txt \
|
||||
tests/testdata/parchecker2/testfile.7z.001 \
|
||||
tests/testdata/parchecker2/testfile.7z.002 \
|
||||
tests/testdata/parchecker2/testfile.7z.003 \
|
||||
tests/testdata/parchecker2/testfile.7z.par2 \
|
||||
tests/testdata/parchecker2/testfile.7z.vol0+1.PAR2 \
|
||||
tests/testdata/parchecker2/testfile.7z.vol1+2.PAR2 \
|
||||
tests/testdata/parchecker2/testfile.7z.vol3+3.PAR2 \
|
||||
tests/testdata/rarrenamer/testfile3.part01.rar \
|
||||
tests/testdata/rarrenamer/testfile3.part02.rar \
|
||||
tests/testdata/rarrenamer/testfile3.part03.rar \
|
||||
|
||||
9
Makefile.in
vendored
9
Makefile.in
vendored
@@ -859,6 +859,7 @@ linux_FILES = \
|
||||
linux/build-info.txt \
|
||||
linux/build-nzbget \
|
||||
linux/build-unpack \
|
||||
linux/build-toolchain-android \
|
||||
linux/build-toolchain-freebsd
|
||||
|
||||
doc_FILES = \
|
||||
@@ -927,6 +928,14 @@ testdata_FILES = \
|
||||
tests/testdata/parchecker/testfile.vol00+1.PAR2 \
|
||||
tests/testdata/parchecker/testfile.vol01+2.PAR2 \
|
||||
tests/testdata/parchecker/testfile.vol03+3.PAR2 \
|
||||
tests/testdata/parchecker2/crc.txt \
|
||||
tests/testdata/parchecker2/testfile.7z.001 \
|
||||
tests/testdata/parchecker2/testfile.7z.002 \
|
||||
tests/testdata/parchecker2/testfile.7z.003 \
|
||||
tests/testdata/parchecker2/testfile.7z.par2 \
|
||||
tests/testdata/parchecker2/testfile.7z.vol0+1.PAR2 \
|
||||
tests/testdata/parchecker2/testfile.7z.vol1+2.PAR2 \
|
||||
tests/testdata/parchecker2/testfile.7z.vol3+3.PAR2 \
|
||||
tests/testdata/rarrenamer/testfile3.part01.rar \
|
||||
tests/testdata/rarrenamer/testfile3.part02.rar \
|
||||
tests/testdata/rarrenamer/testfile3.part03.rar \
|
||||
|
||||
@@ -86,6 +86,9 @@
|
||||
/* Define to 1 to use GnuTLS library for TLS/SSL-support. */
|
||||
#undef HAVE_LIBGNUTLS
|
||||
|
||||
/* Define to 1 if lockf is supported */
|
||||
#undef HAVE_LOCKF
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
@@ -101,6 +104,9 @@
|
||||
/* Define to 1 to use OpenSSL library for TLS/SSL-support and decryption. */
|
||||
#undef HAVE_OPENSSL
|
||||
|
||||
/* Define to 1 if pthread_cancel is supported */
|
||||
#undef HAVE_PTHREAD_CANCEL
|
||||
|
||||
/* Define to 1 if you have the <regex.h> header file. */
|
||||
#undef HAVE_REGEX_H
|
||||
|
||||
|
||||
46
configure
vendored
46
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for nzbget 20.0.
|
||||
# Generated by GNU Autoconf 2.69 for nzbget 21.0-testing.
|
||||
#
|
||||
# Report bugs to <hugbug@users.sourceforge.net>.
|
||||
#
|
||||
@@ -580,8 +580,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='nzbget'
|
||||
PACKAGE_TARNAME='nzbget'
|
||||
PACKAGE_VERSION='20.0'
|
||||
PACKAGE_STRING='nzbget 20.0'
|
||||
PACKAGE_VERSION='21.0-testing'
|
||||
PACKAGE_STRING='nzbget 21.0-testing'
|
||||
PACKAGE_BUGREPORT='hugbug@users.sourceforge.net'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1348,7 +1348,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 20.0 to adapt to many kinds of systems.
|
||||
\`configure' configures nzbget 21.0-testing to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1419,7 +1419,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of nzbget 20.0:";;
|
||||
short | recursive ) echo "Configuration of nzbget 21.0-testing:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1584,7 +1584,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
nzbget configure 20.0
|
||||
nzbget configure 21.0-testing
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2053,7 +2053,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 20.0, which was
|
||||
It was created by nzbget $as_me 21.0-testing, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -3026,7 +3026,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='nzbget'
|
||||
VERSION='20.0'
|
||||
VERSION='21.0-testing'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
@@ -6005,6 +6005,32 @@ fi
|
||||
|
||||
|
||||
|
||||
ac_fn_cxx_check_func "$LINENO" "lockf" "ac_cv_func_lockf"
|
||||
if test "x$ac_cv_func_lockf" = xyes; then :
|
||||
ac_fn_cxx_check_decl "$LINENO" "lockf" "ac_cv_have_decl_lockf" "#include <unistd.h>
|
||||
"
|
||||
if test "x$ac_cv_have_decl_lockf" = xyes; then :
|
||||
|
||||
$as_echo "#define HAVE_LOCKF 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_cxx_check_func "$LINENO" "pthread_cancel" "ac_cv_func_pthread_cancel"
|
||||
if test "x$ac_cv_func_pthread_cancel" = xyes; then :
|
||||
ac_fn_cxx_check_decl "$LINENO" "pthread_cancel" "ac_cv_have_decl_pthread_cancel" "#include <pthread.h>
|
||||
"
|
||||
if test "x$ac_cv_have_decl_pthread_cancel" = xyes; then :
|
||||
|
||||
$as_echo "#define HAVE_PTHREAD_CANCEL 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
ac_fn_cxx_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long"
|
||||
if test "x$ac_cv_func_getopt_long" = xyes; then :
|
||||
|
||||
@@ -9151,7 +9177,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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 20.0, which was
|
||||
This file was extended by nzbget $as_me 21.0-testing, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -9217,7 +9243,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
nzbget config.status 20.0
|
||||
nzbget config.status 21.0-testing
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
15
configure.ac
15
configure.ac
@@ -21,7 +21,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.65)
|
||||
AC_INIT(nzbget, 20.0, hugbug@users.sourceforge.net)
|
||||
AC_INIT(nzbget, 21.0-testing, hugbug@users.sourceforge.net)
|
||||
AC_CONFIG_AUX_DIR(posix)
|
||||
AC_CANONICAL_TARGET
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
@@ -77,6 +77,19 @@ AC_SEARCH_LIBS([inet_addr], [nsl])
|
||||
AC_SEARCH_LIBS([hstrerror], [resolv])
|
||||
|
||||
|
||||
dnl
|
||||
dnl Android NDK restrictions
|
||||
dnl
|
||||
AC_CHECK_FUNC(lockf,
|
||||
[AC_CHECK_DECL(lockf,
|
||||
[AC_DEFINE([HAVE_LOCKF], 1, [Define to 1 if lockf is supported])],,
|
||||
[#include <unistd.h>])])
|
||||
AC_CHECK_FUNC(pthread_cancel,
|
||||
[AC_CHECK_DECL(pthread_cancel,
|
||||
[AC_DEFINE([HAVE_PTHREAD_CANCEL], 1, [Define to 1 if pthread_cancel is supported])],,
|
||||
[#include <pthread.h>])])
|
||||
|
||||
|
||||
dnl
|
||||
dnl Getopt
|
||||
dnl
|
||||
|
||||
@@ -31,16 +31,12 @@ std::unique_ptr<Mutex> Connection::m_getHostByNameMutex;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class ConnectionFinalizer
|
||||
{
|
||||
public:
|
||||
~ConnectionFinalizer()
|
||||
{
|
||||
Connection::Final();
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<ConnectionFinalizer> m_connectionFinalizer;
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
// Activate DNS resolving workaround for Android:
|
||||
// - this is only necessary in general Linux build if we want it to run on Android.
|
||||
// - the workaround isn't needed when targeting specifically Android using Android NDK.
|
||||
#define ANDROID_RESOLVE
|
||||
#endif
|
||||
|
||||
void closesocket_gracefully(SOCKET socket)
|
||||
{
|
||||
@@ -80,7 +76,7 @@ void closesocket_gracefully(SOCKET socket)
|
||||
closesocket(socket);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef ANDROID_RESOLVE
|
||||
CString ResolveAndroidHost(const char* host);
|
||||
#endif
|
||||
|
||||
@@ -109,8 +105,6 @@ void Connection::Init()
|
||||
m_getHostByNameMutex = std::make_unique<Mutex>();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
m_connectionFinalizer = std::make_unique<ConnectionFinalizer>();
|
||||
}
|
||||
|
||||
void Connection::Final()
|
||||
@@ -600,7 +594,7 @@ bool Connection::DoConnect()
|
||||
int res = getaddrinfo(m_host, portStr, &addr_hints, &addr_list);
|
||||
debug("getaddrinfo for %s: %i", *m_host, res);
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef ANDROID_RESOLVE
|
||||
if (res != 0)
|
||||
{
|
||||
CString resolvedHost = ResolveAndroidHost(m_host);
|
||||
@@ -1146,7 +1140,7 @@ int Connection::FetchTotalBytesRead()
|
||||
}
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef ANDROID_RESOLVE
|
||||
|
||||
//******************************************************************************
|
||||
// Android resolver proxy from AOSP (reworked):
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
Connection(SOCKET socket, bool tls);
|
||||
virtual ~Connection();
|
||||
static void Init();
|
||||
static void Final();
|
||||
virtual bool Connect();
|
||||
virtual bool Disconnect();
|
||||
bool Bind();
|
||||
@@ -150,10 +151,6 @@ protected:
|
||||
int send(SOCKET s, const char* buf, int len, int flags);
|
||||
void CloseTls();
|
||||
#endif
|
||||
|
||||
private:
|
||||
static void Final();
|
||||
friend class ConnectionFinalizer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,16 +28,6 @@
|
||||
#include "Util.h"
|
||||
#include "FileSystem.h"
|
||||
|
||||
class TlsSocketFinalizer
|
||||
{
|
||||
public:
|
||||
~TlsSocketFinalizer()
|
||||
{
|
||||
TlsSocket::Final();
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<TlsSocketFinalizer> m_tlsSocketFinalizer;
|
||||
CString TlsSocket::m_certStore;
|
||||
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
@@ -189,8 +179,6 @@ void TlsSocket::Init()
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
m_tlsSocketFinalizer = std::make_unique<TlsSocketFinalizer>();
|
||||
}
|
||||
|
||||
void TlsSocket::Final()
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
virtual ~TlsSocket();
|
||||
static void Init();
|
||||
static void InitOptions(const char* certStore) { m_certStore = certStore; }
|
||||
static void Final();
|
||||
bool Start();
|
||||
void Close();
|
||||
int Send(const char* buffer, int size);
|
||||
@@ -62,9 +63,6 @@ private:
|
||||
|
||||
void ReportError(const char* errMsg, bool suppressable = true);
|
||||
bool ValidateCert();
|
||||
|
||||
static void Final();
|
||||
friend class TlsSocketFinalizer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "FeedScript.h"
|
||||
#include "DiskState.h"
|
||||
#include "DupeCoordinator.h"
|
||||
#include "UrlCoordinator.h"
|
||||
|
||||
std::unique_ptr<RegEx>& FeedCoordinator::FilterHelper::GetRegEx(int id)
|
||||
{
|
||||
@@ -308,12 +309,10 @@ void FeedCoordinator::FeedCompleted(FeedDownloader* feedDownloader)
|
||||
m_save = true;
|
||||
}
|
||||
|
||||
GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
|
||||
for (std::unique_ptr<NzbInfo>& nzbInfo : addedNzbs)
|
||||
{
|
||||
downloadQueue->GetQueue()->Add(std::move(nzbInfo));
|
||||
g_UrlCoordinator->AddUrlToQueue(std::move(nzbInfo), false);
|
||||
}
|
||||
downloadQueue->Save();
|
||||
}
|
||||
feedInfo->SetStatus(FeedInfo::fsFinished);
|
||||
}
|
||||
@@ -455,6 +454,9 @@ std::unique_ptr<NzbInfo> FeedCoordinator::CreateNzbInfo(FeedInfo* feedInfo, Feed
|
||||
nzbInfo->SetDupeKey(feedItemInfo.GetDupeKey());
|
||||
nzbInfo->SetDupeScore(feedItemInfo.GetDupeScore());
|
||||
nzbInfo->SetDupeMode(feedItemInfo.GetDupeMode());
|
||||
nzbInfo->SetSize(feedItemInfo.GetSize());
|
||||
nzbInfo->SetMinTime(feedItemInfo.GetTime());
|
||||
nzbInfo->SetMaxTime(feedItemInfo.GetTime());
|
||||
|
||||
return nzbInfo;
|
||||
}
|
||||
|
||||
@@ -225,11 +225,12 @@ private:
|
||||
bool m_daemonized = false;
|
||||
|
||||
void Init();
|
||||
void Final();
|
||||
void BootConfig();
|
||||
void CreateGlobals();
|
||||
void Cleanup();
|
||||
void PrintOptions();
|
||||
bool ProcessDirect();
|
||||
void ProcessDirect();
|
||||
void ProcessClientRequest();
|
||||
void ProcessWebGet();
|
||||
void ProcessSigVerify();
|
||||
@@ -320,6 +321,17 @@ void NZBGet::Init()
|
||||
InstallErrorHandler();
|
||||
}
|
||||
|
||||
void NZBGet::Final()
|
||||
{
|
||||
if (!m_reloading)
|
||||
{
|
||||
#ifndef DISABLE_TLS
|
||||
TlsSocket::Final();
|
||||
#endif
|
||||
Connection::Final();
|
||||
}
|
||||
}
|
||||
|
||||
void NZBGet::CreateGlobals()
|
||||
{
|
||||
#ifdef WIN32
|
||||
@@ -453,41 +465,35 @@ void NZBGet::Cleanup()
|
||||
#endif
|
||||
}
|
||||
|
||||
bool NZBGet::ProcessDirect()
|
||||
void NZBGet::ProcessDirect()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (m_commandLineParser->GetTestBacktrace())
|
||||
{
|
||||
TestSegFault();
|
||||
TestSegFault(); // never returns
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_commandLineParser->GetWebGet())
|
||||
{
|
||||
ProcessWebGet();
|
||||
return true;
|
||||
ProcessWebGet(); // never returns
|
||||
}
|
||||
|
||||
if (m_commandLineParser->GetSigVerify())
|
||||
{
|
||||
ProcessSigVerify();
|
||||
return true;
|
||||
ProcessSigVerify(); // never returns
|
||||
}
|
||||
|
||||
// client request
|
||||
if (m_commandLineParser->GetClientOperation() != CommandLineParser::opClientNoOperation)
|
||||
{
|
||||
ProcessClientRequest();
|
||||
return true;
|
||||
ProcessClientRequest(); // never returns
|
||||
}
|
||||
|
||||
if (m_commandLineParser->GetPrintOptions())
|
||||
{
|
||||
PrintOptions();
|
||||
return true;
|
||||
PrintOptions(); // never returns
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void NZBGet::StartRemoteServer()
|
||||
@@ -700,10 +706,7 @@ void NZBGet::Run(bool reload)
|
||||
|
||||
Init();
|
||||
|
||||
if (ProcessDirect())
|
||||
{
|
||||
return;
|
||||
}
|
||||
ProcessDirect();
|
||||
|
||||
StartRemoteServer();
|
||||
StartFrontend();
|
||||
@@ -722,6 +725,8 @@ void NZBGet::Run(bool reload)
|
||||
|
||||
StopRemoteServer();
|
||||
StopFrontend();
|
||||
|
||||
Final();
|
||||
}
|
||||
|
||||
void NZBGet::ProcessClientRequest()
|
||||
@@ -900,6 +905,7 @@ void NZBGet::PrintOptions()
|
||||
{
|
||||
printf("%s = \"%s\"\n", optEntry.GetName(), optEntry.GetValue());
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
@@ -932,7 +938,12 @@ void NZBGet::Daemonize()
|
||||
error("Starting daemon failed: could not create lock-file %s", m_options->GetLockFile());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOCKF
|
||||
if (lockf(lfp, F_TLOCK, 0) < 0)
|
||||
#else
|
||||
if (flock(lfp, LOCK_EX) < 0)
|
||||
#endif
|
||||
{
|
||||
error("Starting daemon failed: could not acquire lock on lock-file %s", m_options->GetLockFile());
|
||||
exit(1);
|
||||
|
||||
@@ -169,6 +169,7 @@ using namespace MSXML;
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/file.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of nzbget. See <http://nzbget.net>.
|
||||
*
|
||||
* Copyright (C) 2007-2017 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
* Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -197,11 +197,13 @@ void PrePostProcessor::DownloadQueueUpdate(void* aspect)
|
||||
}
|
||||
|
||||
DownloadQueue::Aspect* queueAspect = (DownloadQueue::Aspect*)aspect;
|
||||
if (queueAspect->action == DownloadQueue::eaNzbFound)
|
||||
if (queueAspect->action == DownloadQueue::eaNzbFound ||
|
||||
queueAspect->action == DownloadQueue::eaUrlFound)
|
||||
{
|
||||
NzbFound(queueAspect->downloadQueue, queueAspect->nzbInfo);
|
||||
}
|
||||
else if (queueAspect->action == DownloadQueue::eaNzbAdded)
|
||||
else if (queueAspect->action == DownloadQueue::eaNzbAdded ||
|
||||
queueAspect->action == DownloadQueue::eaUrlAdded)
|
||||
{
|
||||
NzbAdded(queueAspect->downloadQueue, queueAspect->nzbInfo);
|
||||
}
|
||||
@@ -220,6 +222,14 @@ void PrePostProcessor::DownloadQueueUpdate(void* aspect)
|
||||
"Collection %s deleted from queue", queueAspect->nzbInfo->GetName());
|
||||
NzbDeleted(queueAspect->downloadQueue, queueAspect->nzbInfo);
|
||||
}
|
||||
else if (queueAspect->action == DownloadQueue::eaUrlDeleted)
|
||||
{
|
||||
NzbDeleted(queueAspect->downloadQueue, queueAspect->nzbInfo);
|
||||
}
|
||||
else if (queueAspect->action == DownloadQueue::eaUrlFailed)
|
||||
{
|
||||
NzbCompleted(queueAspect->downloadQueue, queueAspect->nzbInfo, true);
|
||||
}
|
||||
else if ((queueAspect->action == DownloadQueue::eaFileCompleted ||
|
||||
queueAspect->action == DownloadQueue::eaFileDeleted))
|
||||
{
|
||||
@@ -371,6 +381,7 @@ void PrePostProcessor::NzbDeleted(DownloadQueue* downloadQueue, NzbInfo* nzbInfo
|
||||
|
||||
void PrePostProcessor::NzbCompleted(DownloadQueue* downloadQueue, NzbInfo* nzbInfo, bool saveQueue)
|
||||
{
|
||||
bool downloadDupe = nzbInfo->GetDupeHint() == NzbInfo::dhRedownloadAuto;
|
||||
bool addToHistory = g_Options->GetKeepHistory() > 0 && !nzbInfo->GetAvoidHistory();
|
||||
if (addToHistory)
|
||||
{
|
||||
@@ -384,7 +395,8 @@ void PrePostProcessor::NzbCompleted(DownloadQueue* downloadQueue, NzbInfo* nzbIn
|
||||
(nzbInfo->GetDeleteStatus() == NzbInfo::dsNone ||
|
||||
nzbInfo->GetDeleteStatus() == NzbInfo::dsHealth ||
|
||||
nzbInfo->GetDeleteStatus() == NzbInfo::dsBad ||
|
||||
nzbInfo->GetDeleteStatus() == NzbInfo::dsScan))
|
||||
nzbInfo->GetDeleteStatus() == NzbInfo::dsScan ||
|
||||
(nzbInfo->GetDeleteStatus() == NzbInfo::dsCopy && downloadDupe)))
|
||||
{
|
||||
g_DupeCoordinator->NzbCompleted(downloadQueue, nzbInfo);
|
||||
needSave = true;
|
||||
@@ -628,6 +640,8 @@ void PrePostProcessor::CheckPostQueue()
|
||||
|
||||
void PrePostProcessor::StartJob(DownloadQueue* downloadQueue, PostInfo* postInfo, bool allowPar)
|
||||
{
|
||||
NzbInfo* nzbInfo = postInfo->GetNzbInfo();
|
||||
|
||||
if (!postInfo->GetStartTime())
|
||||
{
|
||||
postInfo->SetStartTime(Util::CurrentTime());
|
||||
@@ -637,8 +651,8 @@ void PrePostProcessor::StartJob(DownloadQueue* downloadQueue, PostInfo* postInfo
|
||||
postInfo->SetFileProgress(0);
|
||||
postInfo->SetProgressLabel("");
|
||||
|
||||
if (postInfo->GetNzbInfo()->GetParRenameStatus() == NzbInfo::rsNone &&
|
||||
postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone &&
|
||||
if (nzbInfo->GetParRenameStatus() == NzbInfo::rsNone &&
|
||||
nzbInfo->GetDeleteStatus() == NzbInfo::dsNone &&
|
||||
g_Options->GetParRename())
|
||||
{
|
||||
EnterStage(downloadQueue, postInfo, PostInfo::ptParRenaming);
|
||||
@@ -647,10 +661,10 @@ void PrePostProcessor::StartJob(DownloadQueue* downloadQueue, PostInfo* postInfo
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PARCHECK
|
||||
if (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psNone &&
|
||||
postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone)
|
||||
if (nzbInfo->GetParStatus() == NzbInfo::psNone &&
|
||||
nzbInfo->GetDeleteStatus() == NzbInfo::dsNone)
|
||||
{
|
||||
if (ParParser::FindMainPars(postInfo->GetNzbInfo()->GetDestDir(), nullptr))
|
||||
if (ParParser::FindMainPars(nzbInfo->GetDestDir(), nullptr))
|
||||
{
|
||||
if (!allowPar)
|
||||
{
|
||||
@@ -664,54 +678,54 @@ void PrePostProcessor::StartJob(DownloadQueue* downloadQueue, PostInfo* postInfo
|
||||
}
|
||||
else
|
||||
{
|
||||
postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo,
|
||||
"Nothing to par-check for %s", postInfo->GetNzbInfo()->GetName());
|
||||
postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psSkipped);
|
||||
nzbInfo->PrintMessage(Message::mkInfo,
|
||||
"Nothing to par-check for %s", nzbInfo->GetName());
|
||||
nzbInfo->SetParStatus(NzbInfo::psSkipped);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSkipped &&
|
||||
if (nzbInfo->GetParStatus() == NzbInfo::psSkipped &&
|
||||
((g_Options->GetParScan() != Options::psDupe &&
|
||||
postInfo->GetNzbInfo()->CalcHealth() < postInfo->GetNzbInfo()->CalcCriticalHealth(false) &&
|
||||
postInfo->GetNzbInfo()->CalcCriticalHealth(false) < 1000) ||
|
||||
postInfo->GetNzbInfo()->CalcHealth() == 0) &&
|
||||
ParParser::FindMainPars(postInfo->GetNzbInfo()->GetDestDir(), nullptr))
|
||||
nzbInfo->CalcHealth() < nzbInfo->CalcCriticalHealth(false) &&
|
||||
nzbInfo->CalcCriticalHealth(false) < 1000) ||
|
||||
nzbInfo->CalcHealth() == 0) &&
|
||||
ParParser::FindMainPars(nzbInfo->GetDestDir(), nullptr))
|
||||
{
|
||||
if (postInfo->GetNzbInfo()->CalcHealth() == 0)
|
||||
if (nzbInfo->CalcHealth() == 0)
|
||||
{
|
||||
postInfo->GetNzbInfo()->PrintMessage(Message::mkWarning,
|
||||
"Skipping par-check for %s due to health 0%%", postInfo->GetNzbInfo()->GetName());
|
||||
nzbInfo->PrintMessage(Message::mkWarning,
|
||||
"Skipping par-check for %s due to health 0%%", nzbInfo->GetName());
|
||||
}
|
||||
else
|
||||
{
|
||||
postInfo->GetNzbInfo()->PrintMessage(Message::mkWarning,
|
||||
nzbInfo->PrintMessage(Message::mkWarning,
|
||||
"Skipping par-check for %s due to health %.1f%% below critical %.1f%%",
|
||||
postInfo->GetNzbInfo()->GetName(),
|
||||
postInfo->GetNzbInfo()->CalcHealth() / 10.0, postInfo->GetNzbInfo()->CalcCriticalHealth(false) / 10.0);
|
||||
nzbInfo->GetName(),
|
||||
nzbInfo->CalcHealth() / 10.0, nzbInfo->CalcCriticalHealth(false) / 10.0);
|
||||
}
|
||||
postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psFailure);
|
||||
nzbInfo->SetParStatus(NzbInfo::psFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSkipped &&
|
||||
postInfo->GetNzbInfo()->GetFailedSize() - postInfo->GetNzbInfo()->GetParFailedSize() > 0 &&
|
||||
ParParser::FindMainPars(postInfo->GetNzbInfo()->GetDestDir(), nullptr))
|
||||
if (nzbInfo->GetParStatus() == NzbInfo::psSkipped &&
|
||||
nzbInfo->GetFailedSize() - nzbInfo->GetParFailedSize() > 0 &&
|
||||
ParParser::FindMainPars(nzbInfo->GetDestDir(), nullptr))
|
||||
{
|
||||
postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo,
|
||||
nzbInfo->PrintMessage(Message::mkInfo,
|
||||
"Collection %s with health %.1f%% needs par-check",
|
||||
postInfo->GetNzbInfo()->GetName(), postInfo->GetNzbInfo()->CalcHealth() / 10.0);
|
||||
nzbInfo->GetName(), nzbInfo->CalcHealth() / 10.0);
|
||||
postInfo->SetRequestParCheck(true);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
NzbParameter* unpackParameter = postInfo->GetNzbInfo()->GetParameters()->Find("*Unpack:");
|
||||
NzbParameter* unpackParameter = nzbInfo->GetParameters()->Find("*Unpack:");
|
||||
bool wantUnpack = !(unpackParameter && !strcasecmp(unpackParameter->GetValue(), "no"));
|
||||
bool unpack = wantUnpack && postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usNone &&
|
||||
postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone;
|
||||
bool unpack = wantUnpack && nzbInfo->GetUnpackStatus() == NzbInfo::usNone &&
|
||||
nzbInfo->GetDeleteStatus() == NzbInfo::dsNone;
|
||||
|
||||
if (postInfo->GetNzbInfo()->GetRarRenameStatus() == NzbInfo::rsNone &&
|
||||
if (nzbInfo->GetRarRenameStatus() == NzbInfo::rsNone &&
|
||||
unpack && g_Options->GetRarRename())
|
||||
{
|
||||
EnterStage(downloadQueue, postInfo, PostInfo::ptRarRenaming);
|
||||
@@ -719,43 +733,63 @@ void PrePostProcessor::StartJob(DownloadQueue* downloadQueue, PostInfo* postInfo
|
||||
return;
|
||||
}
|
||||
|
||||
bool parFailed = postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psFailure ||
|
||||
postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psRepairPossible ||
|
||||
postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psManual;
|
||||
#ifndef DISABLE_PARCHECK
|
||||
if (nzbInfo->GetParStatus() == NzbInfo::psSkipped &&
|
||||
nzbInfo->GetDeleteStatus() == NzbInfo::dsNone &&
|
||||
g_Options->GetParCheck() == Options::pcAuto &&
|
||||
!UnpackController::HasCompletedArchiveFiles(nzbInfo) &&
|
||||
ParParser::FindMainPars(nzbInfo->GetDestDir(), nullptr))
|
||||
{
|
||||
nzbInfo->PrintMessage(Message::mkInfo,
|
||||
"Requesting par-check for collection %s without archive files",
|
||||
nzbInfo->GetName());
|
||||
postInfo->SetRequestParCheck(true);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool parFailed = nzbInfo->GetParStatus() == NzbInfo::psFailure ||
|
||||
nzbInfo->GetParStatus() == NzbInfo::psRepairPossible ||
|
||||
nzbInfo->GetParStatus() == NzbInfo::psManual;
|
||||
|
||||
bool cleanup = !unpack && wantUnpack &&
|
||||
postInfo->GetNzbInfo()->GetCleanupStatus() == NzbInfo::csNone &&
|
||||
nzbInfo->GetCleanupStatus() == NzbInfo::csNone &&
|
||||
!Util::EmptyStr(g_Options->GetExtCleanupDisk()) &&
|
||||
((postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSuccess &&
|
||||
postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usFailure &&
|
||||
postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usSpace &&
|
||||
postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usPassword) ||
|
||||
(postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usSuccess &&
|
||||
postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psFailure) ||
|
||||
((postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usNone ||
|
||||
postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usSkipped) &&
|
||||
(postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psNone ||
|
||||
postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSkipped) &&
|
||||
postInfo->GetNzbInfo()->CalcHealth() == 1000));
|
||||
((nzbInfo->GetParStatus() == NzbInfo::psSuccess &&
|
||||
nzbInfo->GetUnpackStatus() != NzbInfo::usFailure &&
|
||||
nzbInfo->GetUnpackStatus() != NzbInfo::usSpace &&
|
||||
nzbInfo->GetUnpackStatus() != NzbInfo::usPassword) ||
|
||||
(nzbInfo->GetUnpackStatus() == NzbInfo::usSuccess &&
|
||||
nzbInfo->GetParStatus() != NzbInfo::psFailure) ||
|
||||
((nzbInfo->GetUnpackStatus() == NzbInfo::usNone ||
|
||||
nzbInfo->GetUnpackStatus() == NzbInfo::usSkipped) &&
|
||||
(nzbInfo->GetParStatus() == NzbInfo::psNone ||
|
||||
nzbInfo->GetParStatus() == NzbInfo::psSkipped) &&
|
||||
nzbInfo->CalcHealth() == 1000));
|
||||
|
||||
bool moveInter = !unpack &&
|
||||
postInfo->GetNzbInfo()->GetMoveStatus() == NzbInfo::msNone &&
|
||||
postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usFailure &&
|
||||
postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usSpace &&
|
||||
postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usPassword &&
|
||||
postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psFailure &&
|
||||
postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psManual &&
|
||||
postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone &&
|
||||
nzbInfo->GetMoveStatus() == NzbInfo::msNone &&
|
||||
nzbInfo->GetUnpackStatus() != NzbInfo::usFailure &&
|
||||
nzbInfo->GetUnpackStatus() != NzbInfo::usSpace &&
|
||||
nzbInfo->GetUnpackStatus() != NzbInfo::usPassword &&
|
||||
nzbInfo->GetParStatus() != NzbInfo::psFailure &&
|
||||
nzbInfo->GetParStatus() != NzbInfo::psManual &&
|
||||
nzbInfo->GetDeleteStatus() == NzbInfo::dsNone &&
|
||||
!(((nzbInfo->GetUnpackStatus() == NzbInfo::usNone ||
|
||||
nzbInfo->GetUnpackStatus() == NzbInfo::usSkipped) &&
|
||||
(nzbInfo->GetParStatus() == NzbInfo::psNone ||
|
||||
nzbInfo->GetParStatus() == NzbInfo::psSkipped) &&
|
||||
nzbInfo->CalcHealth() < 1000)) &&
|
||||
!Util::EmptyStr(g_Options->GetInterDir()) &&
|
||||
!strncmp(postInfo->GetNzbInfo()->GetDestDir(), g_Options->GetInterDir(), strlen(g_Options->GetInterDir())) &&
|
||||
postInfo->GetNzbInfo()->GetDestDir()[strlen(g_Options->GetInterDir())] == PATH_SEPARATOR;
|
||||
!strncmp(nzbInfo->GetDestDir(), g_Options->GetInterDir(), strlen(g_Options->GetInterDir())) &&
|
||||
nzbInfo->GetDestDir()[strlen(g_Options->GetInterDir())] == PATH_SEPARATOR;
|
||||
|
||||
if (unpack && parFailed)
|
||||
{
|
||||
postInfo->GetNzbInfo()->PrintMessage(Message::mkWarning,
|
||||
"Skipping unpack for %s due to %s", postInfo->GetNzbInfo()->GetName(),
|
||||
postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psManual ? "required par-repair" : "par-failure");
|
||||
postInfo->GetNzbInfo()->SetUnpackStatus(NzbInfo::usSkipped);
|
||||
nzbInfo->PrintMessage(Message::mkWarning,
|
||||
"Skipping unpack for %s due to %s", nzbInfo->GetName(),
|
||||
nzbInfo->GetParStatus() == NzbInfo::psManual ? "required par-repair" : "par-failure");
|
||||
nzbInfo->SetUnpackStatus(NzbInfo::usSkipped);
|
||||
unpack = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of nzbget. See <http://nzbget.net>.
|
||||
*
|
||||
* Copyright (C) 2013-2017 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
* Copyright (C) 2013-2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -929,3 +929,23 @@ void UnpackController::SetProgressLabel(const char* progressLabel)
|
||||
GuardedDownloadQueue guard = DownloadQueue::Guard();
|
||||
m_postInfo->SetProgressLabel(progressLabel);
|
||||
}
|
||||
|
||||
bool UnpackController::HasCompletedArchiveFiles(NzbInfo* nzbInfo)
|
||||
{
|
||||
RegEx regExRar(".*\\.rar$");
|
||||
RegEx regExSevenZip(".*\\.7z$");
|
||||
RegEx regExSevenZipMulti(".*\\.7z\\.[0-9]+$");
|
||||
|
||||
for (CompletedFile& completedFile: nzbInfo->GetCompletedFiles())
|
||||
{
|
||||
const char* filename = completedFile.GetFilename();
|
||||
if (regExRar.Match(filename) ||
|
||||
regExSevenZip.Match(filename) ||
|
||||
regExSevenZipMulti.Match(filename))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of nzbget. See <http://nzbget.net>.
|
||||
*
|
||||
* Copyright (C) 2013-2017 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
* Copyright (C) 2013-2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
virtual void Run();
|
||||
virtual void Stop();
|
||||
static void StartJob(PostInfo* postInfo);
|
||||
static bool HasCompletedArchiveFiles(NzbInfo* nzbInfo);
|
||||
|
||||
protected:
|
||||
virtual bool ReadLine(char* buf, int bufSize, FILE* stream);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of nzbget. See <http://nzbget.net>.
|
||||
*
|
||||
* Copyright (C) 2007-2017 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
* Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "FileSystem.h"
|
||||
|
||||
static const char* FORMATVERSION_SIGNATURE = "nzbget diskstate file version ";
|
||||
const int DISKSTATE_QUEUE_VERSION = 60;
|
||||
const int DISKSTATE_QUEUE_VERSION = 61;
|
||||
const int DISKSTATE_FILE_VERSION = 5;
|
||||
const int DISKSTATE_STATS_VERSION = 3;
|
||||
const int DISKSTATE_FEEDS_VERSION = 3;
|
||||
@@ -464,7 +464,7 @@ void DiskState::SaveNzbInfo(NzbInfo* nzbInfo, StateDiskFile& outfile)
|
||||
outfile.PrintLine("%i,%i,%i", nzbInfo->GetTotalArticles(), nzbInfo->GetSuccessArticles(), nzbInfo->GetFailedArticles());
|
||||
|
||||
outfile.PrintLine("%s", nzbInfo->GetDupeKey());
|
||||
outfile.PrintLine("%i,%i", (int)nzbInfo->GetDupeMode(), nzbInfo->GetDupeScore());
|
||||
outfile.PrintLine("%i,%i,%i", (int)nzbInfo->GetDupeMode(), nzbInfo->GetDupeScore(), (int)nzbInfo->GetDupeHint());
|
||||
|
||||
Util::SplitInt64(nzbInfo->GetDownloadedSize(), &High1, &Low1);
|
||||
outfile.PrintLine("%u,%u,%i,%i,%i,%i,%i", High1, Low1, nzbInfo->GetDownloadSec(), nzbInfo->GetPostTotalSec(),
|
||||
@@ -690,10 +690,19 @@ bool DiskState::LoadNzbInfo(NzbInfo* nzbInfo, Servers* servers, StateDiskFile& i
|
||||
if (!infile.ReadLine(buf, sizeof(buf))) goto error;
|
||||
nzbInfo->SetDupeKey(buf);
|
||||
|
||||
int dupeMode, dupeScore;
|
||||
if (infile.ScanLine("%i,%i", &dupeMode, &dupeScore) != 2) goto error;
|
||||
int dupeMode, dupeScore, dupeHint;
|
||||
dupeHint = 0; //clang requires initialization in a separate line (due to goto statements)
|
||||
if (formatVersion >= 61)
|
||||
{
|
||||
if (infile.ScanLine("%i,%i,%i", &dupeMode, &dupeScore, &dupeHint) != 3) goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (infile.ScanLine("%i,%i", &dupeMode, &dupeScore) != 2) goto error;
|
||||
}
|
||||
nzbInfo->SetDupeMode((EDupeMode)dupeMode);
|
||||
nzbInfo->SetDupeScore(dupeScore);
|
||||
nzbInfo->SetDupeMode((EDupeMode)dupeHint);
|
||||
|
||||
if (formatVersion >= 48)
|
||||
{
|
||||
@@ -1451,7 +1460,8 @@ void DiskState::CleanupQueueDir(DownloadQueue* downloadQueue)
|
||||
|
||||
for (HistoryInfo* historyInfo : downloadQueue->GetHistory())
|
||||
{
|
||||
if (historyInfo->GetKind() == HistoryInfo::hkNzb)
|
||||
if (historyInfo->GetKind() == HistoryInfo::hkNzb ||
|
||||
historyInfo->GetKind() == HistoryInfo::hkUrl)
|
||||
{
|
||||
NzbInfo* nzbInfo = historyInfo->GetNzbInfo();
|
||||
nzbIdList.push_back(nzbInfo->GetId());
|
||||
|
||||
@@ -346,10 +346,12 @@ void NzbInfo::UpdateMinMaxTime()
|
||||
}
|
||||
}
|
||||
|
||||
void NzbInfo::AddMessage(Message::EKind kind, const char * text)
|
||||
void NzbInfo::AddMessage(Message::EKind kind, const char * text, bool print)
|
||||
{
|
||||
switch (kind)
|
||||
if (print)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case Message::mkDetail:
|
||||
detail("%s", text);
|
||||
break;
|
||||
@@ -369,6 +371,7 @@ void NzbInfo::AddMessage(Message::EKind kind, const char * text)
|
||||
case Message::mkDebug:
|
||||
debug("%s", text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Guard guard(m_logMutex);
|
||||
@@ -496,6 +499,9 @@ bool NzbInfo::IsDupeSuccess()
|
||||
m_parStatus == NzbInfo::psFailure ||
|
||||
m_unpackStatus == NzbInfo::usFailure ||
|
||||
m_unpackStatus == NzbInfo::usPassword ||
|
||||
m_urlStatus == NzbInfo::lsFailed ||
|
||||
m_urlStatus == NzbInfo::lsScanSkipped ||
|
||||
m_urlStatus == NzbInfo::lsScanFailed ||
|
||||
(m_parStatus == NzbInfo::psSkipped &&
|
||||
m_unpackStatus == NzbInfo::usSkipped &&
|
||||
CalcHealth() < CalcCriticalHealth(true)));
|
||||
@@ -628,6 +634,10 @@ const char* NzbInfo::MakeTextStatus(bool ignoreScriptStatus)
|
||||
{
|
||||
status = "DELETED/DUPE";
|
||||
}
|
||||
else if (m_deleteStatus == NzbInfo::dsGood)
|
||||
{
|
||||
status = "DELETED/GOOD";
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* urlStatusName[] = { "FAILURE/INTERNAL_ERROR", "FAILURE/INTERNAL_ERROR", "FAILURE/INTERNAL_ERROR",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of nzbget. See <http://nzbget.net>.
|
||||
*
|
||||
* Copyright (C) 2004 Sven Henkel <sidddy@users.sourceforge.net>
|
||||
* Copyright (C) 2007-2017 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
* Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -446,6 +446,13 @@ public:
|
||||
nkUrl
|
||||
};
|
||||
|
||||
enum EDupeHint
|
||||
{
|
||||
dhNone,
|
||||
dhRedownloadManual,
|
||||
dhRedownloadAuto
|
||||
};
|
||||
|
||||
int GetId() { return m_id; }
|
||||
void SetId(int id);
|
||||
static void ResetGenId(bool max);
|
||||
@@ -580,6 +587,8 @@ public:
|
||||
void SetDupeScore(int dupeScore) { m_dupeScore = dupeScore; }
|
||||
EDupeMode GetDupeMode() { return m_dupeMode; }
|
||||
void SetDupeMode(EDupeMode dupeMode) { m_dupeMode = dupeMode; }
|
||||
EDupeHint GetDupeHint() { return m_dupeHint; }
|
||||
void SetDupeHint(EDupeHint dupeHint) { m_dupeHint = dupeHint; }
|
||||
uint32 GetFullContentHash() { return m_fullContentHash; }
|
||||
void SetFullContentHash(uint32 fullContentHash) { m_fullContentHash = fullContentHash; }
|
||||
uint32 GetFilteredContentHash() { return m_filteredContentHash; }
|
||||
@@ -615,7 +624,7 @@ public:
|
||||
void LeavePostProcess();
|
||||
bool IsDupeSuccess();
|
||||
const char* MakeTextStatus(bool ignoreScriptStatus);
|
||||
void AddMessage(Message::EKind kind, const char* text);
|
||||
void AddMessage(Message::EKind kind, const char* text, bool print = true);
|
||||
void PrintMessage(Message::EKind kind, const char* format, ...) PRINTF_SYNTAX(3);
|
||||
int GetMessageCount() { return m_messageCount; }
|
||||
void SetMessageCount(int messageCount) { m_messageCount = messageCount; }
|
||||
@@ -698,6 +707,7 @@ private:
|
||||
CString m_dupeKey = "";
|
||||
int m_dupeScore = 0;
|
||||
EDupeMode m_dupeMode = dmScore;
|
||||
EDupeHint m_dupeHint = dhNone;
|
||||
uint32 m_fullContentHash = 0;
|
||||
uint32 m_filteredContentHash = 0;
|
||||
FileList m_fileList;
|
||||
@@ -918,7 +928,11 @@ public:
|
||||
eaNzbNamed,
|
||||
eaFileCompleted,
|
||||
eaFileDeleted,
|
||||
eaUrlCompleted
|
||||
eaUrlFound,
|
||||
eaUrlAdded,
|
||||
eaUrlDeleted,
|
||||
eaUrlCompleted,
|
||||
eaUrlFailed
|
||||
};
|
||||
|
||||
struct Aspect
|
||||
|
||||
@@ -202,12 +202,19 @@ void DupeCoordinator::NzbFound(DownloadQueue* downloadQueue, NzbInfo* nzbInfo)
|
||||
}
|
||||
}
|
||||
|
||||
if (!sameContent && nzbInfo->GetDupeHint() != NzbInfo::dhNone)
|
||||
{
|
||||
// dupe check when "download again" URLs: checking same content only
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sameContent && !good && nzbInfo->GetDupeMode() == dmScore)
|
||||
{
|
||||
// nzb-files having success-duplicates in recent history (with different content) are added to history for backup
|
||||
for (HistoryInfo* historyInfo : downloadQueue->GetHistory())
|
||||
{
|
||||
if (historyInfo->GetKind() == HistoryInfo::hkNzb &&
|
||||
if ((historyInfo->GetKind() == HistoryInfo::hkNzb ||
|
||||
historyInfo->GetKind() == HistoryInfo::hkUrl) &&
|
||||
historyInfo->GetNzbInfo()->GetDupeMode() != dmForce &&
|
||||
SameNameOrKey(historyInfo->GetNzbInfo()->GetName(), historyInfo->GetNzbInfo()->GetDupeKey(),
|
||||
nzbInfo->GetName(), nzbInfo->GetDupeKey()) &&
|
||||
@@ -237,7 +244,7 @@ void DupeCoordinator::NzbFound(DownloadQueue* downloadQueue, NzbInfo* nzbInfo)
|
||||
sameContent ? "exactly same content" : good ? "good status" : "success status");
|
||||
}
|
||||
|
||||
if (nzbInfo->GetFeedId())
|
||||
if (nzbInfo->GetFeedId() && nzbInfo->GetDupeHint() == NzbInfo::dhNone)
|
||||
{
|
||||
warn("%s", *message);
|
||||
// Flag saying QueueCoordinator to skip nzb-file
|
||||
@@ -263,7 +270,9 @@ void DupeCoordinator::NzbFound(DownloadQueue* downloadQueue, NzbInfo* nzbInfo)
|
||||
{
|
||||
NzbInfo* queuedNzbInfo = (*it++).get();
|
||||
if (queuedNzbInfo != nzbInfo &&
|
||||
queuedNzbInfo->GetKind() == NzbInfo::nkNzb &&
|
||||
queuedNzbInfo->GetDeleteStatus() == NzbInfo::dsNone &&
|
||||
(queuedNzbInfo->GetKind() == NzbInfo::nkNzb ||
|
||||
(queuedNzbInfo->GetKind() == NzbInfo::nkUrl && nzbInfo->GetKind() == NzbInfo::nkUrl)) &&
|
||||
queuedNzbInfo->GetDupeMode() != dmForce &&
|
||||
SameNameOrKey(queuedNzbInfo->GetName(), queuedNzbInfo->GetDupeKey(),
|
||||
nzbInfo->GetName(), nzbInfo->GetDupeKey()))
|
||||
@@ -286,9 +295,13 @@ void DupeCoordinator::NzbFound(DownloadQueue* downloadQueue, NzbInfo* nzbInfo)
|
||||
// the existing queue item is moved to history as dupe-backup
|
||||
info("Moving collection %s with lower duplicate score to history", queuedNzbInfo->GetName());
|
||||
queuedNzbInfo->SetDeleteStatus(NzbInfo::dsDupe);
|
||||
int oldSize = downloadQueue->GetQueue()->size();
|
||||
downloadQueue->EditEntry(queuedNzbInfo->GetId(),
|
||||
DownloadQueue::eaGroupDelete, nullptr);
|
||||
int newSize = downloadQueue->GetQueue()->size();
|
||||
index += oldSize == newSize ? 1 : 0;
|
||||
it = downloadQueue->GetQueue()->begin() + index;
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -377,7 +390,8 @@ void DupeCoordinator::ReturnBestDupe(DownloadQueue* downloadQueue, NzbInfo* nzbI
|
||||
HistoryInfo* historyDupe = nullptr;
|
||||
for (HistoryInfo* historyInfo : downloadQueue->GetHistory())
|
||||
{
|
||||
if (historyInfo->GetKind() == HistoryInfo::hkNzb &&
|
||||
if ((historyInfo->GetKind() == HistoryInfo::hkNzb ||
|
||||
historyInfo->GetKind() == HistoryInfo::hkUrl) &&
|
||||
historyInfo->GetNzbInfo()->GetDupeMode() != dmForce &&
|
||||
historyInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsDupe &&
|
||||
historyInfo->GetNzbInfo()->CalcHealth() >= historyInfo->GetNzbInfo()->CalcCriticalHealth(true) &&
|
||||
@@ -395,6 +409,7 @@ void DupeCoordinator::ReturnBestDupe(DownloadQueue* downloadQueue, NzbInfo* nzbI
|
||||
if (historyDupe)
|
||||
{
|
||||
info("Found duplicate %s for %s", historyDupe->GetNzbInfo()->GetName(), nzbName);
|
||||
historyDupe->GetNzbInfo()->SetDupeHint(NzbInfo::dhRedownloadAuto);
|
||||
g_HistoryCoordinator->Redownload(downloadQueue, historyDupe);
|
||||
}
|
||||
}
|
||||
@@ -465,7 +480,8 @@ void DupeCoordinator::HistoryCleanup(DownloadQueue* downloadQueue, HistoryInfo*
|
||||
{
|
||||
HistoryInfo* historyInfo = (*it).get();
|
||||
|
||||
if (historyInfo->GetKind() == HistoryInfo::hkNzb &&
|
||||
if ((historyInfo->GetKind() == HistoryInfo::hkNzb ||
|
||||
historyInfo->GetKind() == HistoryInfo::hkUrl) &&
|
||||
historyInfo->GetNzbInfo()->GetDupeMode() != dmForce &&
|
||||
historyInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsDupe &&
|
||||
historyInfo != markHistoryInfo &&
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of nzbget. See <http://nzbget.net>.
|
||||
*
|
||||
* Copyright (C) 2007-2017 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
* Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -183,6 +183,8 @@ void HistoryCoordinator::AddToHistory(DownloadQueue* downloadQueue, NzbInfo* nzb
|
||||
nzbInfo->SetDirectRenameStatus(NzbInfo::tsFailure);
|
||||
}
|
||||
|
||||
nzbInfo->SetDupeHint(NzbInfo::dhNone);
|
||||
|
||||
nzbInfo->PrintMessage(Message::mkInfo, "Collection %s added to history", nzbInfo->GetName());
|
||||
}
|
||||
|
||||
@@ -433,6 +435,7 @@ void HistoryCoordinator::HistoryRedownload(DownloadQueue* downloadQueue, History
|
||||
historyInfo->DiscardNzbInfo();
|
||||
nzbInfo->SetUrlStatus(NzbInfo::lsNone);
|
||||
nzbInfo->SetDeleteStatus(NzbInfo::dsNone);
|
||||
nzbInfo->SetDupeHint(nzbInfo->GetDupeHint() == NzbInfo::dhNone ? NzbInfo::dhRedownloadManual : nzbInfo->GetDupeHint());
|
||||
downloadQueue->GetQueue()->Add(std::unique_ptr<NzbInfo>(nzbInfo), true);
|
||||
downloadQueue->GetHistory()->erase(itHistory);
|
||||
return;
|
||||
|
||||
@@ -177,7 +177,7 @@ void QueueCoordinator::Run()
|
||||
AdjustDownloadsLimit();
|
||||
bool wasStandBy = true;
|
||||
bool articeDownloadsRunning = false;
|
||||
int resetCounter = 0;
|
||||
time_t lastReset = 0;
|
||||
g_StatMeter->IntervalCheck();
|
||||
|
||||
while (!IsStopped())
|
||||
@@ -245,8 +245,8 @@ void QueueCoordinator::Run()
|
||||
|
||||
Util::SetStandByMode(standBy);
|
||||
|
||||
resetCounter += sleepInterval;
|
||||
if (resetCounter >= 1000)
|
||||
time_t currentTime = Util::CurrentTime();
|
||||
if (lastReset != currentTime)
|
||||
{
|
||||
// this code should not be called too often, once per second is OK
|
||||
g_ServerPool->CloseUnusedConnections();
|
||||
@@ -255,10 +255,10 @@ void QueueCoordinator::Run()
|
||||
{
|
||||
SaveAllPartialState();
|
||||
}
|
||||
resetCounter = 0;
|
||||
g_StatMeter->IntervalCheck();
|
||||
g_Log->IntervalCheck();
|
||||
AdjustDownloadsLimit();
|
||||
lastReset = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of nzbget. See <http://nzbget.net>.
|
||||
*
|
||||
* Copyright (C) 2007-2016 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
* Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -438,6 +438,7 @@ bool Scanner::AddFileToQueue(const char* filename, const char* nzbName, const ch
|
||||
nzbInfo->SetUrl(urlInfo->GetUrl());
|
||||
nzbInfo->SetUrlStatus(urlInfo->GetUrlStatus());
|
||||
nzbInfo->SetFeedId(urlInfo->GetFeedId());
|
||||
nzbInfo->SetDupeHint(urlInfo->GetDupeHint());
|
||||
}
|
||||
|
||||
if (nzbFile.GetPassword())
|
||||
@@ -458,7 +459,14 @@ bool Scanner::AddFileToQueue(const char* filename, const char* nzbName, const ch
|
||||
{
|
||||
addedNzb = g_QueueCoordinator->AddNzbFileToQueue(std::move(nzbInfo), std::move(urlInfo), addTop);
|
||||
}
|
||||
else if (!urlInfo)
|
||||
else if (urlInfo)
|
||||
{
|
||||
for (Message& message : nzbInfo->GuardCachedMessages())
|
||||
{
|
||||
urlInfo->AddMessage(message.GetKind(), message.GetText(), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nzbInfo->SetDeleteStatus(NzbInfo::dsScan);
|
||||
addedNzb = g_QueueCoordinator->AddNzbFileToQueue(std::move(nzbInfo), std::move(urlInfo), addTop);
|
||||
|
||||
@@ -277,13 +277,11 @@ void UrlCoordinator::UrlCompleted(UrlDownloader* urlDownloader)
|
||||
// remove downloader from downloader list
|
||||
m_activeDownloads.erase(std::find(m_activeDownloads.begin(), m_activeDownloads.end(), urlDownloader));
|
||||
|
||||
nzbInfo->SetActiveDownloads(0);
|
||||
|
||||
retry = urlDownloader->GetStatus() == WebDownloader::adRetry && !nzbInfo->GetDeleting();
|
||||
|
||||
if (nzbInfo->GetDeleting())
|
||||
{
|
||||
nzbInfo->SetDeleteStatus(NzbInfo::dsManual);
|
||||
nzbInfo->SetDeleteStatus(nzbInfo->GetDeleteStatus() == NzbInfo::dsNone ? NzbInfo::dsManual : nzbInfo->GetDeleteStatus());
|
||||
nzbInfo->SetUrlStatus(NzbInfo::lsNone);
|
||||
nzbInfo->SetDeleting(false);
|
||||
}
|
||||
@@ -309,6 +307,7 @@ void UrlCoordinator::UrlCompleted(UrlDownloader* urlDownloader)
|
||||
|
||||
if (retry)
|
||||
{
|
||||
nzbInfo->SetActiveDownloads(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -324,7 +323,7 @@ void UrlCoordinator::UrlCompleted(UrlDownloader* urlDownloader)
|
||||
|
||||
if (addStatus == Scanner::asSuccess)
|
||||
{
|
||||
// if scanner has successfully added nzb-file to queue, our pNZBInfo is
|
||||
// if scanner has successfully added nzb-file to queue, our nzbInfo is
|
||||
// already removed from queue and destroyed
|
||||
return;
|
||||
}
|
||||
@@ -336,31 +335,13 @@ void UrlCoordinator::UrlCompleted(UrlDownloader* urlDownloader)
|
||||
|
||||
g_QueueScriptCoordinator->EnqueueScript(nzbInfo, QueueScriptCoordinator::qeUrlCompleted);
|
||||
|
||||
std::unique_ptr<NzbInfo> oldNzbInfo;
|
||||
|
||||
{
|
||||
GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
|
||||
|
||||
// delete URL from queue
|
||||
oldNzbInfo = downloadQueue->GetQueue()->Remove(nzbInfo);
|
||||
nzbInfo->SetActiveDownloads(0);
|
||||
|
||||
// add failed URL to history
|
||||
if (g_Options->GetKeepHistory() > 0 &&
|
||||
nzbInfo->GetUrlStatus() != NzbInfo::lsFinished &&
|
||||
!nzbInfo->GetAvoidHistory())
|
||||
{
|
||||
std::unique_ptr<HistoryInfo> historyInfo = std::make_unique<HistoryInfo>(std::move(oldNzbInfo));
|
||||
historyInfo->SetTime(Util::CurrentTime());
|
||||
downloadQueue->GetHistory()->Add(std::move(historyInfo), true);
|
||||
downloadQueue->HistoryChanged();
|
||||
}
|
||||
|
||||
downloadQueue->Save();
|
||||
}
|
||||
|
||||
if (oldNzbInfo)
|
||||
{
|
||||
g_DiskState->DiscardFiles(oldNzbInfo.get());
|
||||
DownloadQueue::Aspect aspect = {DownloadQueue::eaUrlFailed, downloadQueue, nzbInfo, nullptr};
|
||||
downloadQueue->Notify(&aspect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,26 +361,39 @@ bool UrlCoordinator::DeleteQueueEntry(DownloadQueue* downloadQueue, NzbInfo* nzb
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
info("Deleting URL %s", nzbInfo->GetName());
|
||||
|
||||
nzbInfo->SetDeleteStatus(NzbInfo::dsManual);
|
||||
nzbInfo->SetDeleteStatus(nzbInfo->GetDeleteStatus() == NzbInfo::dsNone ? NzbInfo::dsManual : nzbInfo->GetDeleteStatus());
|
||||
nzbInfo->SetUrlStatus(NzbInfo::lsNone);
|
||||
|
||||
std::unique_ptr<NzbInfo> oldNzbInfo = downloadQueue->GetQueue()->Remove(nzbInfo);
|
||||
|
||||
if (g_Options->GetKeepHistory() > 0 && !avoidHistory)
|
||||
{
|
||||
std::unique_ptr<HistoryInfo> historyInfo = std::make_unique<HistoryInfo>(std::move(oldNzbInfo));
|
||||
historyInfo->SetTime(Util::CurrentTime());
|
||||
downloadQueue->GetHistory()->Add(std::move(historyInfo), true);
|
||||
downloadQueue->HistoryChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_DiskState->DiscardFiles(oldNzbInfo.get());
|
||||
}
|
||||
DownloadQueue::Aspect deletedAspect = {DownloadQueue::eaUrlDeleted, downloadQueue, nzbInfo, nullptr};
|
||||
downloadQueue->Notify(&deletedAspect);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UrlCoordinator::AddUrlToQueue(std::unique_ptr<NzbInfo> nzbInfo, bool addFirst)
|
||||
{
|
||||
debug("Adding URL to queue");
|
||||
|
||||
NzbInfo* addedNzb = nzbInfo.get();
|
||||
|
||||
GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
|
||||
|
||||
DownloadQueue::Aspect foundAspect = {DownloadQueue::eaUrlFound, downloadQueue, addedNzb, nullptr};
|
||||
downloadQueue->Notify(&foundAspect);
|
||||
|
||||
if (addedNzb->GetDeleteStatus() != NzbInfo::dsManual)
|
||||
{
|
||||
downloadQueue->GetQueue()->Add(std::move(nzbInfo), addFirst);
|
||||
|
||||
DownloadQueue::Aspect addedAspect = {DownloadQueue::eaUrlAdded, downloadQueue, addedNzb, nullptr};
|
||||
downloadQueue->Notify(&addedAspect);
|
||||
}
|
||||
|
||||
downloadQueue->Save();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
void Update(Subject* caller, void* aspect);
|
||||
|
||||
// Editing the queue
|
||||
void AddUrlToQueue(std::unique_ptr<NzbInfo> nzbInfo, bool addFirst);
|
||||
bool HasMoreJobs() { return m_hasMoreJobs; }
|
||||
bool DeleteQueueEntry(DownloadQueue* downloadQueue, NzbInfo* nzbInfo, bool avoidHistory);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "DownloadInfo.h"
|
||||
#include "Scanner.h"
|
||||
#include "StatMeter.h"
|
||||
#include "UrlCoordinator.h"
|
||||
|
||||
extern void ExitProc();
|
||||
extern void Reload();
|
||||
@@ -430,9 +431,7 @@ void DownloadBinCommand::Execute()
|
||||
nzbInfo->SetDupeScore(dupeScore);
|
||||
nzbInfo->SetDupeMode((EDupeMode)dupeMode);
|
||||
|
||||
GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
|
||||
downloadQueue->GetQueue()->Add(std::move(nzbInfo), addTop);
|
||||
downloadQueue->Save();
|
||||
g_UrlCoordinator->AddUrlToQueue(std::move(nzbInfo), addTop);
|
||||
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "ScriptConfig.h"
|
||||
#include "QueueScript.h"
|
||||
#include "CommandScript.h"
|
||||
#include "UrlCoordinator.h"
|
||||
|
||||
extern void ExitProc();
|
||||
extern void Reload();
|
||||
@@ -892,7 +893,7 @@ bool XmlCommand::NextParamAsInt(int* value)
|
||||
}
|
||||
*value = atoi(param + 1);
|
||||
m_requestPtr = param + 1;
|
||||
while (strchr("-+0123456789&", *m_requestPtr))
|
||||
while (*m_requestPtr && strchr("-+0123456789&", *m_requestPtr))
|
||||
{
|
||||
m_requestPtr++;
|
||||
}
|
||||
@@ -2256,11 +2257,7 @@ void DownloadXmlCommand::Execute()
|
||||
|
||||
info("Queue %s", *nzbInfo->MakeNiceUrlName(nzbContent, nzbFilename));
|
||||
|
||||
{
|
||||
GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
|
||||
downloadQueue->GetQueue()->Add(std::move(nzbInfo), addTop);
|
||||
downloadQueue->Save();
|
||||
}
|
||||
g_UrlCoordinator->AddUrlToQueue(std::move(nzbInfo), addTop);
|
||||
|
||||
if (v13)
|
||||
{
|
||||
|
||||
@@ -140,7 +140,12 @@ bool Thread::Kill()
|
||||
#ifdef WIN32
|
||||
bool terminated = TerminateThread(m_threadObj, 0) != 0;
|
||||
#else
|
||||
#ifdef HAVE_PTHREAD_CANCEL
|
||||
bool terminated = pthread_cancel(m_threadObj) == 0;
|
||||
#else
|
||||
bool terminated = false;
|
||||
warn("Could not kill thread: thread cancelling isn't supported on this platform");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (terminated)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# This file is part of nzbget
|
||||
#
|
||||
# Copyright (C) 2015-2017 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
# Copyright (C) 2015-2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
#
|
||||
# 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
|
||||
@@ -25,7 +25,7 @@ set -o errexit
|
||||
# Uncomment next line for debuging
|
||||
#set -x
|
||||
|
||||
ALLTARGETS="dist i686 x86_64 armel armhf mipsel mipseb ppc6xx ppc500 x86_64-bsd"
|
||||
ALLTARGETS="dist i686 x86_64 armel armhf mipsel mipseb ppc6xx ppc500 x86_64-bsd i686-ndk armhf-ndk"
|
||||
ROOT=`pwd`
|
||||
ROOTPATH=$PATH
|
||||
OUTPUTDIR=$ROOT/output
|
||||
@@ -133,6 +133,8 @@ ParseCommandLine()
|
||||
do
|
||||
if [[ $TARGET == *-bsd ]]; then
|
||||
PLATFORM="freebsd"
|
||||
elif [[ $TARGET == *-ndk ]]; then
|
||||
PLATFORM="android"
|
||||
else
|
||||
PLATFORM="linux"
|
||||
fi
|
||||
@@ -180,9 +182,9 @@ UpdateFromRepository()
|
||||
touch Makefile.in configure config.h.in
|
||||
|
||||
echo "Updating root certificates"
|
||||
cd ../setup
|
||||
curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem
|
||||
cd $BUILDDIR
|
||||
cd ../setup
|
||||
curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem
|
||||
cd $BUILDDIR
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -235,6 +237,8 @@ ConstructSuffix()
|
||||
|
||||
if [ $PLATFORM == "freebsd" ]; then
|
||||
PLATSUFF="-bsd"
|
||||
elif [ $PLATFORM == "android" ]; then
|
||||
PLATSUFF="-ndk"
|
||||
else
|
||||
PLATSUFF=""
|
||||
fi
|
||||
@@ -262,12 +266,19 @@ ConstructArchParams()
|
||||
case $PLATFORM in
|
||||
linux)
|
||||
TOOLKIND=buildroot
|
||||
TOOLNAME=linux
|
||||
ARCH=$ARCH-linux
|
||||
;;
|
||||
android)
|
||||
TOOLKIND=ndk
|
||||
ARCH=$ARCH-linux-android
|
||||
if [ "$ARCH" == "arm-linux-android" ]; then
|
||||
ARCH="arm-linux-androideabi"
|
||||
fi
|
||||
;;
|
||||
freebsd)
|
||||
TOOLKIND=crossclang
|
||||
TOOLNAME=pc-freebsd
|
||||
SYSROOT="$TOOLCHAIN_ROOT/sysroot"
|
||||
ARCH=$ARCH-pc-freebsd
|
||||
SYSROOT="$TOOLCHAIN_ROOT/sysroot"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -286,7 +297,7 @@ ConfigureTarget()
|
||||
|
||||
LUBACKTRACE=""
|
||||
if [ -f "$STAGING/lib/libubacktrace.so.1" ] ; then
|
||||
LUBACKTRACE="-lubacktrace"
|
||||
LUBACKTRACE="-lubacktrace"
|
||||
fi
|
||||
|
||||
case "$TOOLKIND-$CONFIG" in
|
||||
@@ -294,44 +305,68 @@ ConfigureTarget()
|
||||
LDFLAGS="-static $STRIP" \
|
||||
CXXFLAGS="-std=c++14 -g -fasynchronous-unwind-tables" \
|
||||
LIBS="-lcrypto -ldl -lz $LUBACKTRACE" \
|
||||
./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME --enable-debug
|
||||
./configure --disable-dependency-tracking --host=$ARCH --enable-debug
|
||||
;;
|
||||
buildroot-release|buildroot-release-nostrip)
|
||||
LDFLAGS="-static $STRIP" \
|
||||
CXXFLAGS="-std=c++14 -O2 $DEBUG" \
|
||||
LIBS="-lcrypto -ldl -lz" \
|
||||
./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME
|
||||
./configure --disable-dependency-tracking --host=$ARCH
|
||||
;;
|
||||
ndk-debug|ndk-debug-strip)
|
||||
LDFLAGS="-static -static-libstdc++ $STRIP" \
|
||||
CXXFLAGS="-std=c++14 -g -fasynchronous-unwind-tables" \
|
||||
CXX="$ARCH-clang++" \
|
||||
PKG_CONFIG_LIBDIR="$STAGING/usr/lib/pkgconfig" \
|
||||
./configure --disable-dependency-tracking --disable-largefile --host=$ARCH --enable-debug
|
||||
;;
|
||||
ndk-release|ndk-release-nostrip)
|
||||
LDFLAGS="-static -static-libstdc++ $STRIP" \
|
||||
CXXFLAGS="-std=c++14 -O2 $DEBUG" \
|
||||
CXX="$ARCH-clang++" \
|
||||
PKG_CONFIG_LIBDIR="$STAGING/usr/lib/pkgconfig" \
|
||||
./configure --disable-dependency-tracking --disable-largefile --host=$ARCH
|
||||
;;
|
||||
crossclang-debug|crossclang-debug-strip)
|
||||
CXX="$CROSSCLANG" \
|
||||
LDFLAGS="-static $STRIP -fuse-ld=lld --target=$ARCH-$TOOLNAME -lc++ -lm --sysroot=$SYSROOT" \
|
||||
CXXFLAGS="-g --target=$ARCH-$TOOLNAME --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \
|
||||
LDFLAGS="-static $STRIP -fuse-ld=lld --target=$ARCH -lc++ -lm --sysroot=$SYSROOT" \
|
||||
CXXFLAGS="-g --target=$ARCH --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \
|
||||
PKG_CONFIG_LIBDIR="$STAGING/usr/lib/pkgconfig" \
|
||||
./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME --enable-debug
|
||||
./configure --disable-dependency-tracking --host=$ARCH --enable-debug
|
||||
;;
|
||||
crossclang-release|crossclang-release-nostrip)
|
||||
CXX="$CROSSCLANG" \
|
||||
LDFLAGS="-static $STRIP -fuse-ld=lld --target=$ARCH-$TOOLNAME -lc++ -lm --sysroot=$SYSROOT" \
|
||||
CXXFLAGS="-O2 $DEBUG --target=$ARCH-$TOOLNAME --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \
|
||||
LDFLAGS="-static $STRIP -fuse-ld=lld --target=$ARCH -lc++ -lm --sysroot=$SYSROOT" \
|
||||
CXXFLAGS="-O2 $DEBUG --target=$ARCH --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \
|
||||
PKG_CONFIG_LIBDIR="$STAGING/usr/lib/pkgconfig" \
|
||||
./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME --enable-debug
|
||||
./configure --disable-dependency-tracking --host=$ARCH --enable-debug
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
PrecompileHeaders()
|
||||
{
|
||||
rm -f nzbget.h.gch
|
||||
if [ $PCH == "yes" -a $TOOLKIND != "crossclang" ]; then
|
||||
OPTIM=""
|
||||
if [ $CONFIG == "release" -o $CONFIG == "release-nostrip" ]; then
|
||||
OPTIM="-O2"
|
||||
fi
|
||||
rm -f nzbget.h.*
|
||||
|
||||
$ARCH-$TOOLNAME-g++ -std=c++14 -DHAVE_CONFIG_H \
|
||||
OPTIM=""
|
||||
if [ $CONFIG == "release" -o $CONFIG == "release-nostrip" ]; then
|
||||
OPTIM="-O2"
|
||||
fi
|
||||
|
||||
if [ $PCH == "yes" -a $TOOLKIND == "buildroot" ]; then
|
||||
$ARCH-g++ -std=c++14 -DHAVE_CONFIG_H \
|
||||
-I. -I$STAGING/usr/include -I$STAGING/usr/include/libxml2 \
|
||||
-g $OPTIM daemon/main/nzbget.h -o nzbget.h.gch
|
||||
fi
|
||||
|
||||
if [ $PCH == "yes" -a $TOOLKIND == "ndk" ]; then
|
||||
$ARCH-clang++ -std=c++14 -DHAVE_CONFIG_H \
|
||||
-I. -I$STAGING/usr/include -I$STAGING/usr/include/libxml2 \
|
||||
-g $OPTIM -x c++-header daemon/main/nzbget.h -o nzbget.h.pch
|
||||
CXXFLAGS=`sed -n 's:^CXXFLAGS =.\(.*\):\1:p' Makefile`
|
||||
sed 's:^CXXFLAGS = :CXXFLAGS = -include-pch nzbget.h.pch :' -i Makefile
|
||||
sed "s: CXXFLAGS+=: CXXFLAGS=$CXXFLAGS :" -i Makefile
|
||||
fi
|
||||
}
|
||||
|
||||
PackTarget()
|
||||
@@ -521,6 +556,9 @@ FilterTargets()
|
||||
if [[ $TARGET == *-bsd ]]; then
|
||||
PLAT="freebsd"
|
||||
TARGET="${TARGET%-bsd}"
|
||||
elif [[ $TARGET == *-ndk ]]; then
|
||||
PLAT="android"
|
||||
TARGET="${TARGET%-ndk}"
|
||||
else
|
||||
PLAT="linux"
|
||||
fi
|
||||
|
||||
197
linux/build-toolchain-android
Executable file
197
linux/build-toolchain-android
Executable file
@@ -0,0 +1,197 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This file is part of nzbget. See <http://nzbget.net>.
|
||||
#
|
||||
# Copyright (C) 2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# This script builds cross-compiling toolchain, which can compile NZBGet for Android.
|
||||
# The toolchain itself runs on Linux.
|
||||
|
||||
# Setup strict bash error handling
|
||||
set -o nounset
|
||||
set -o errexit
|
||||
|
||||
# Uncomment next line for debuging
|
||||
#set -x
|
||||
|
||||
|
||||
# Android API level
|
||||
APILEVEL=21
|
||||
|
||||
# Architecture
|
||||
ARCH=$1
|
||||
case "$ARCH" in
|
||||
i686)
|
||||
NDK_ARCH="x86"
|
||||
NDK_TARGET="i686-linux-android"
|
||||
OPENSSL_TARGET="android-x86"
|
||||
;;
|
||||
x86_64)
|
||||
NDK_ARCH="x86_64"
|
||||
NDK_TARGET="x86_64-linux-android"
|
||||
OPENSSL_TARGET="android64"
|
||||
;;
|
||||
armhf)
|
||||
NDK_ARCH="arm"
|
||||
NDK_TARGET="arm-linux-androideabi"
|
||||
OPENSSL_TARGET="android-armeabi"
|
||||
;;
|
||||
aarch64)
|
||||
NDK_ARCH="arm64"
|
||||
NDK_TARGET="aarch64-linux-android"
|
||||
OPENSSL_TARGET="android64-aarch64"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 (i686|x86_64|armhf|aarch64)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Creating toolchain for $ARCH"
|
||||
|
||||
# Android NDK
|
||||
NDK_VERSION="r17"
|
||||
NDK_DIRNAME="android-ndk-$NDK_VERSION"
|
||||
NDK_ARCHIVE="$NDK_DIRNAME-linux-x86_64.zip"
|
||||
NDK_URL="https://dl.google.com/android/repository/$NDK_ARCHIVE"
|
||||
|
||||
# Libxml
|
||||
LIBXML2_VERSION="2.9.4"
|
||||
LIBXML2_ARCHIVE="libxml2-$LIBXML2_VERSION.tar.gz"
|
||||
LIBXML2_URL="http://xmlsoft.org/sources/$LIBXML2_ARCHIVE"
|
||||
|
||||
# OpenSSL
|
||||
OPENSSL_VERSION="1.1.0h"
|
||||
OPENSSL_ARCHIVE="openssl-$OPENSSL_VERSION.tar.gz"
|
||||
OPENSSL_URL="https://www.openssl.org/source/$OPENSSL_ARCHIVE"
|
||||
|
||||
# NCurses
|
||||
NCURSES_VERSION="6.0"
|
||||
NCURSES_ARCHIVE="ncurses-$NCURSES_VERSION.tar.gz"
|
||||
NCURSES_URL="https://ftp.gnu.org/pub/gnu/ncurses/$NCURSES_ARCHIVE"
|
||||
|
||||
### START OF THE SCRIPT
|
||||
|
||||
ROOTDIR=`pwd`
|
||||
ROOTDIR="$ROOTDIR/$ARCH-ndk"
|
||||
|
||||
rm -rf $ROOTDIR
|
||||
mkdir $ROOTDIR
|
||||
cd $ROOTDIR
|
||||
|
||||
# Download all required tools and libraries
|
||||
cd ..
|
||||
mkdir -p downloads
|
||||
cd downloads
|
||||
if [ ! -d $NDK_DIRNAME -a ! -f $NDK_ARCHIVE ]; then
|
||||
wget $NDK_URL
|
||||
fi
|
||||
if [ ! -f $LIBXML2_ARCHIVE ]; then
|
||||
wget $LIBXML2_URL
|
||||
fi
|
||||
if [ ! -f $OPENSSL_ARCHIVE ]; then
|
||||
wget $OPENSSL_URL
|
||||
fi
|
||||
if [ ! -f $NCURSES_ARCHIVE ]; then
|
||||
wget $NCURSES_URL
|
||||
fi
|
||||
cd ..
|
||||
|
||||
# Unpack NDK
|
||||
if [ ! -d ./$NDK_DIRNAME ]; then
|
||||
echo "Unpacking NDK"
|
||||
unzip ./downloads/$NDK_ARCHIVE
|
||||
fi
|
||||
|
||||
# Create toolchain for target
|
||||
echo "Preparing standalone NDK toolchain"
|
||||
./$NDK_DIRNAME/build/tools/make_standalone_toolchain.py --arch $NDK_ARCH --api $APILEVEL --install-dir $ROOTDIR/output/host/usr
|
||||
|
||||
cd $ROOTDIR
|
||||
|
||||
# Configure toolchain
|
||||
export PATH=$PATH:$ROOTDIR/output/host/usr/bin
|
||||
export CC=$NDK_TARGET-clang
|
||||
export CXX=$NDK_TARGET-clang++
|
||||
export AS=$NDK_TARGET-clang
|
||||
export AR=$NDK_TARGET-ar
|
||||
export LD=$NDK_TARGET-ld
|
||||
export RANLIB=$NDK_TARGET-ranlib
|
||||
export CFLAGS="-fPIE -fPIC"
|
||||
export CXXFLAGS=$CFLAGS
|
||||
export LDFLAGS=""
|
||||
|
||||
mkdir output/build
|
||||
ln -s host/usr/sysroot output/staging
|
||||
|
||||
cd $ROOTDIR/output/build
|
||||
|
||||
# Build OpenSSL (5 minutes)
|
||||
tar xf ../../../downloads/$OPENSSL_ARCHIVE
|
||||
cd openssl-$OPENSSL_VERSION
|
||||
./Configure --prefix=$ROOTDIR/output/staging/usr --sysroot=$ROOTDIR/output/staging no-shared no-dso no-hw no-zlib no-unit-test "$OPENSSL_TARGET"
|
||||
sed 's:-mandroid::' -i Makefile
|
||||
make -j2
|
||||
make install_sw
|
||||
cd ..
|
||||
|
||||
# Build libxml2 (2 minutes)
|
||||
tar xf ../../../downloads/$LIBXML2_ARCHIVE
|
||||
cd libxml2-$LIBXML2_VERSION
|
||||
./configure --host=$NDK_TARGET -prefix=$ROOTDIR/output/staging/usr --disable-dependency-tracking --without-zlib --without-lzma --without-python --disable-shared
|
||||
sed 's:^PROGRAMS =.*:PROGRAMS = :' -i Makefile
|
||||
sed 's:^bin_PROGRAMS =.*:bin_PROGRAMS = :' -i Makefile
|
||||
sed 's:^SUBDIRS =.*:SUBDIRS = include .:' -i Makefile
|
||||
make -j2
|
||||
make install
|
||||
cd ..
|
||||
|
||||
# Build NCurses (2 minutes)
|
||||
tar xf ../../../downloads/$NCURSES_ARCHIVE
|
||||
cd ncurses-$NCURSES_VERSION
|
||||
./configure --host=$NDK_TARGET -prefix=$ROOTDIR/output/staging/usr --disable-dependency-tracking --disable-largefile
|
||||
make -j2
|
||||
make install
|
||||
cd ..
|
||||
|
||||
cd ..
|
||||
|
||||
# Create missing package descriptions
|
||||
echo "prefix=$ROOTDIR/output/staging/usr
|
||||
|
||||
Name: zlib
|
||||
Description: zlib
|
||||
Version: 1
|
||||
Libs: -L\${prefix}/lib -lz
|
||||
Cflags: -I\${prefix}/include
|
||||
" > $ROOTDIR/output/staging/usr/lib/pkgconfig/zlib.pc
|
||||
|
||||
echo "prefix=$ROOTDIR/output/staging/usr
|
||||
|
||||
Name: ncurses
|
||||
Description: ncurses
|
||||
Version: 5
|
||||
Libs: -L\${prefix}/lib -lncurses
|
||||
Cflags: -I\${prefix}/include
|
||||
" > $ROOTDIR/output/staging/usr/lib/pkgconfig/ncurses.pc
|
||||
|
||||
# Remove "-L${prefix}/lib" and "-L${libdir}" from all packages to fix strange linker error
|
||||
find $ROOTDIR/output/staging/usr/lib/pkgconfig -type f -exec sed 's:-L\${prefix}/lib::' -i {} \;
|
||||
find $ROOTDIR/output/staging/usr/lib/pkgconfig -type f -exec sed 's:-L\${libdir}::' -i {} \;
|
||||
|
||||
echo "Toolchain creation completed for $ARCH"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# This file is part of nzbget. See <http://nzbget.net>.
|
||||
#
|
||||
# Copyright (C) 2015-2017 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
# Copyright (C) 2015-2018 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
#
|
||||
# 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
|
||||
@@ -25,7 +25,7 @@ set -o errexit
|
||||
# Uncomment next line for debuging
|
||||
#set -x
|
||||
|
||||
ALLTARGETS="i686 x86_64 armel armhf mipsel mipseb ppc6xx ppc500 x86_64-bsd"
|
||||
ALLTARGETS="i686 x86_64 armel armhf mipsel mipseb ppc6xx ppc500 x86_64-bsd i686-ndk x86_64-ndk armhf-ndk aarch64-ndk"
|
||||
ROOT=`pwd`
|
||||
OUTPUTDIR=$ROOT/setup
|
||||
BUILDDIR=temp
|
||||
@@ -111,27 +111,22 @@ for TARGET in $TARGETS; do
|
||||
if [[ $TARGET == *-bsd ]]; then
|
||||
TARGET="${TARGET%-bsd}"
|
||||
TOOLKIND=crossclang
|
||||
TOOLNAME=pc-freebsd
|
||||
SYSROOT="$TOOLCHAIN_ROOT/sysroot"
|
||||
PLATSUFF="-bsd"
|
||||
elif [[ $TARGET == *-ndk ]]; then
|
||||
TARGET="${TARGET%-ndk}"
|
||||
TOOLKIND=ndk
|
||||
else
|
||||
TOOLKIND=buildroot
|
||||
TOOLNAME=linux
|
||||
PLATSUFF=""
|
||||
fi
|
||||
|
||||
ARCH=$TARGET
|
||||
ENDIAN=little
|
||||
case $TARGET in
|
||||
mipsel|i?86|x86_64|aarch64)
|
||||
ARCH=$TARGET
|
||||
ENDIAN=little
|
||||
;;
|
||||
mipseb)
|
||||
ARCH=mips
|
||||
ENDIAN=big
|
||||
;;
|
||||
arm*)
|
||||
ARCH=arm
|
||||
ENDIAN=little
|
||||
;;
|
||||
ppc*)
|
||||
ARCH=powerpc
|
||||
@@ -139,6 +134,25 @@ for TARGET in $TARGETS; do
|
||||
;;
|
||||
esac
|
||||
|
||||
case $TOOLKIND in
|
||||
buildroot)
|
||||
ARCH="$ARCH-linux"
|
||||
PLATSUFF=""
|
||||
;;
|
||||
ndk)
|
||||
ARCH="$ARCH-linux-android"
|
||||
if [ "$ARCH" == "arm-linux-android" ]; then
|
||||
ARCH="arm-linux-androideabi"
|
||||
fi
|
||||
PLATSUFF="-ndk"
|
||||
;;
|
||||
crossclang)
|
||||
ARCH="$ARCH-pc-freebsd"
|
||||
SYSROOT="$TOOLCHAIN_ROOT/sysroot"
|
||||
PLATSUFF="-bsd"
|
||||
;;
|
||||
esac
|
||||
|
||||
rm -rf "$ROOT/$BUILDDIR/$UNPACKER"
|
||||
cd $ROOT/$BUILDDIR
|
||||
|
||||
@@ -157,6 +171,10 @@ for TARGET in $TARGETS; do
|
||||
sed 's:^DEFINES=:DEFINES=-DUSE_FALLOCATE :' -i makefile
|
||||
fi
|
||||
sed 's:setlocale://setlocale:' -i rar.cpp
|
||||
if [ "$TOOLKIND" == "ndk" ] ; then
|
||||
sed 's:^#if defined(_EMX) || defined (__VMS)$:#if defined(_EMX) || defined (__VMS) || defined (__ANDROID__):' -i consio.cpp
|
||||
sed 's:^#define USE_LUTIMES$:#undef USE_LUTIMES:' -i os.hpp
|
||||
fi
|
||||
|
||||
EXEDIR=
|
||||
LICENSE=license.txt
|
||||
@@ -173,7 +191,11 @@ for TARGET in $TARGETS; do
|
||||
cp makefile.linux_any_cpu_gcc_4.X makefile.machine
|
||||
sed 's:^CXX=g++:#CXX=g++:' -i makefile.machine
|
||||
sed 's:^CC=gcc:#CC=gcc:' -i makefile.machine
|
||||
if [ "$TOOLKIND" == "crossclang" ] ; then
|
||||
if [ "$TOOLKIND" == "ndk" ] ; then
|
||||
sed 's:-DENV_UNIX:-DENV_UNIX -DANDROID_NDK:' -i makefile.machine
|
||||
sed 's:LOCAL_LIBS=-lpthread:LOCAL_LIBS=:' -i makefile.machine
|
||||
fi
|
||||
if [ "$TOOLKIND" != "buildroot" ] ; then
|
||||
sed 's:^PRE_COMPILED_HEADER=:#PRE_COMPILED_HEADER=:' -i makefile.machine
|
||||
sed 's:^ALLFLAGS=${OPTFLAGS} -pipe -s:ALLFLAGS=${OPTFLAGS} -pipe ${CPPFLAGS}:' -i makefile.machine
|
||||
fi
|
||||
@@ -189,23 +211,34 @@ for TARGET in $TARGETS; do
|
||||
|
||||
make clean
|
||||
|
||||
if [ "$TOOLKIND" == "crossclang" ] ; then
|
||||
CXX="$CROSSCLANG" \
|
||||
CC="$CROSSCLANG" \
|
||||
LDFLAGS="-static -fuse-ld=lld -lc++ -lm -lpthread --sysroot=$SYSROOT" \
|
||||
CXXFLAGS="-O2 --target=$ARCH-$TOOLNAME --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \
|
||||
CPPFLAGS="-O2 --target=$ARCH-$TOOLNAME --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \
|
||||
STRIP=strip \
|
||||
make -j $COREX $BUILDTARGET
|
||||
else
|
||||
CXX=$TOOLPATH/$ARCH-$TOOLNAME-g++ \
|
||||
CC=$TOOLPATH/$ARCH-$TOOLNAME-gcc \
|
||||
STRIP=$TOOLPATH/$ARCH-$TOOLNAME-strip \
|
||||
CXXFLAGS=-O2 \
|
||||
LDFLAGS=-static \
|
||||
LIBS=-lpthread \
|
||||
make -j $COREX $BUILDTARGET
|
||||
fi
|
||||
case $TOOLKIND in
|
||||
buildroot)
|
||||
CXX=$TOOLPATH/$ARCH-g++ \
|
||||
CC=$TOOLPATH/$ARCH-gcc \
|
||||
STRIP=$TOOLPATH/$ARCH-strip \
|
||||
CXXFLAGS=-O2 \
|
||||
LDFLAGS=-static \
|
||||
LIBS=-lpthread \
|
||||
make -j $COREX $BUILDTARGET
|
||||
;;
|
||||
ndk)
|
||||
CXX=$TOOLPATH/$ARCH-clang++ \
|
||||
CC=$TOOLPATH/$ARCH-clang \
|
||||
STRIP=$TOOLPATH/$ARCH-strip \
|
||||
CXXFLAGS=-O2 \
|
||||
LDFLAGS="-static -static-libstdc++" \
|
||||
make -j $COREX $BUILDTARGET
|
||||
;;
|
||||
crossclang)
|
||||
CXX="$CROSSCLANG" \
|
||||
CC="$CROSSCLANG" \
|
||||
LDFLAGS="-static -fuse-ld=lld -lc++ -lm -lpthread --sysroot=$SYSROOT" \
|
||||
CXXFLAGS="-O2 --target=$ARCH --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \
|
||||
CPPFLAGS="-O2 --target=$ARCH --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \
|
||||
STRIP=strip \
|
||||
make -j $COREX $BUILDTARGET
|
||||
;;
|
||||
esac
|
||||
|
||||
cp $EXEDIR$EXENAME ../../setup/$EXENAME-$TARGET$PLATSUFF
|
||||
cp $LICENSE ../../setup/license-$UNPACKER.txt
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.\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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="20.0";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="21.0-testing";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
@@ -101,7 +101,7 @@
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.\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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="20.0";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="21.0-testing";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
@@ -120,7 +120,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.\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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="20.0";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="21.0-testing";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@@ -151,7 +151,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.\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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="20.0";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="21.0-testing";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
|
||||
@@ -26,11 +26,11 @@ def prepare_testdata(request):
|
||||
|
||||
if not os.path.exists(nserv_datadir + '/medium.nzb'):
|
||||
sizemb = int(pytest.config.getini('sample_medium'))
|
||||
create_test_file(nserv_datadir + '/medium', sevenzip_bin, sizemb)
|
||||
create_test_file(nserv_datadir + '/medium', sevenzip_bin, sizemb, 50)
|
||||
|
||||
if not os.path.exists(nserv_datadir + '/large.nzb'):
|
||||
sizemb = int(pytest.config.getini('sample_large'))
|
||||
create_test_file(nserv_datadir + '/large', sevenzip_bin, sizemb)
|
||||
create_test_file(nserv_datadir + '/large', sevenzip_bin, sizemb, 50)
|
||||
|
||||
if not os.path.exists(nserv_datadir + '/medium.nzb') or not os.path.exists(nserv_datadir + '/large.nzb'):
|
||||
if 0 != subprocess.call([nzbget_bin, '--nserv', '-d', nserv_datadir, '-v', '2', '-z', '500000', '-q']):
|
||||
@@ -51,20 +51,19 @@ def prepare_testdata(request):
|
||||
pytest.exit('Test file generation failed')
|
||||
|
||||
|
||||
def create_test_file(bigdir, sevenzip_bin, sizemb):
|
||||
def create_test_file(bigdir, sevenzip_bin, sizemb, partmb):
|
||||
print('Preparing test file (' + str(sizemb) + 'MB)')
|
||||
|
||||
if not os.path.exists(bigdir):
|
||||
os.makedirs(bigdir)
|
||||
|
||||
f = open(bigdir + '/' + str(sizemb) + 'mb.dat', 'wb')
|
||||
for n in xrange(64 * sizemb / 1024):
|
||||
if n % 8 == 0:
|
||||
print('Writing block %i from %i' % (n, 64 * sizemb / 1024))
|
||||
f.write(os.urandom(1024 * 1024 * 16))
|
||||
for n in xrange(sizemb / partmb):
|
||||
print('Writing block %i from %i' % (n + 1, sizemb / partmb))
|
||||
f.write(os.urandom(partmb * 1024 * 1024))
|
||||
f.close()
|
||||
|
||||
if 0 != subprocess.call([sevenzip_bin, 'a', bigdir + '/' + str(sizemb) + 'mb.7z', '-mx=0', '-v50m', bigdir + '/' + str(sizemb) + 'mb.dat']):
|
||||
if 0 != subprocess.call([sevenzip_bin, 'a', bigdir + '/' + str(sizemb) + 'mb.7z', '-mx=0', '-v' + str(partmb) + 'm', bigdir + '/' + str(sizemb) + 'mb.dat']):
|
||||
pytest.exit('Test file generation failed')
|
||||
|
||||
os.remove(bigdir + '/' + str(sizemb) + 'mb.dat')
|
||||
|
||||
85
tests/functional/download/unpack_test.py
Normal file
85
tests/functional/download/unpack_test.py
Normal file
@@ -0,0 +1,85 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(scope='session', autouse=True)
|
||||
def prepare_testdata(request):
|
||||
print('Preparing test data for "unpack"')
|
||||
|
||||
nserv_datadir = pytest.config.getini('nserv_datadir')
|
||||
nzbget_bin = pytest.config.getini('nzbget_bin')
|
||||
sevenzip_bin = pytest.config.getini('sevenzip_bin')
|
||||
par2_bin = pytest.config.getini('par2_bin')
|
||||
|
||||
if not os.path.exists(nserv_datadir):
|
||||
print('Creating nserv datadir')
|
||||
os.makedirs(nserv_datadir)
|
||||
|
||||
if not os.path.exists(nserv_datadir + '/unpack-damaged.nzb'):
|
||||
create_test_file(nserv_datadir + '/unpack-damaged', sevenzip_bin, 3, 1)
|
||||
os.chdir(nserv_datadir + '/unpack-damaged')
|
||||
|
||||
if 0 != subprocess.call([par2_bin, 'c', '-b100', 'unpackcrc-damaged.par2', '*']):
|
||||
pytest.exit('Test file generation failed')
|
||||
|
||||
outf = open("3mb.7z.001","rb+")
|
||||
outf.seek(100000)
|
||||
outf.write(b"\x0a\x1b\x2c")
|
||||
outf.close()
|
||||
|
||||
if not os.path.exists(nserv_datadir + '/unpackcrc-par.nzb'):
|
||||
create_test_file(nserv_datadir + '/unpackcrc-par', sevenzip_bin, 3, 1)
|
||||
os.chdir(nserv_datadir + '/unpackcrc-par')
|
||||
|
||||
outf = open("3mb.7z.001","rb+")
|
||||
outf.seek(100000)
|
||||
outf.write(b"\x0a\x1b\x2c")
|
||||
outf.close()
|
||||
|
||||
if 0 != subprocess.call([par2_bin, 'c', '-b100', 'unpackcrc-par.par2', '*']):
|
||||
pytest.exit('Test file generation failed')
|
||||
|
||||
if not os.path.exists(nserv_datadir + '/unpackcrc-nopar.nzb'):
|
||||
create_test_file(nserv_datadir + '/unpackcrc-nopar', sevenzip_bin, 3, 1)
|
||||
os.chdir(nserv_datadir + '/unpackcrc-nopar')
|
||||
|
||||
outf = open("3mb.7z.001","rb+")
|
||||
outf.seek(100000)
|
||||
outf.write(b"\x0a\x1b\x2c")
|
||||
outf.close()
|
||||
|
||||
if 0 != subprocess.call([nzbget_bin, '--nserv', '-d', nserv_datadir, '-v', '2', '-z', '3000', '-q']):
|
||||
pytest.exit('Test file generation failed')
|
||||
|
||||
|
||||
def create_test_file(bigdir, sevenzip_bin, sizemb, partmb):
|
||||
print('Preparing test file (' + str(sizemb) + 'MB)')
|
||||
|
||||
if not os.path.exists(bigdir):
|
||||
os.makedirs(bigdir)
|
||||
|
||||
f = open(bigdir + '/' + str(sizemb) + 'mb.dat', 'wb')
|
||||
for n in xrange(sizemb / partmb):
|
||||
print('Writing block %i from %i' % (n + 1, sizemb / partmb))
|
||||
f.write(os.urandom(partmb * 1024 * 1024))
|
||||
f.close()
|
||||
|
||||
if 0 != subprocess.call([sevenzip_bin, 'a', bigdir + '/' + str(sizemb) + 'mb.7z', '-mx=0', '-v' + str(partmb) + 'm', bigdir + '/' + str(sizemb) + 'mb.dat']):
|
||||
pytest.exit('Test file generation failed')
|
||||
|
||||
os.remove(bigdir + '/' + str(sizemb) + 'mb.dat')
|
||||
|
||||
|
||||
def test_unpack_repair(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('unpack-damaged.nzb', unpack = True)
|
||||
assert hist['Status'] == 'SUCCESS/UNPACK'
|
||||
|
||||
def test_unpack_crcerror_par(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('unpackcrc-par.nzb', unpack = True)
|
||||
assert hist['Status'] == 'FAILURE/UNPACK'
|
||||
|
||||
def test_unpack_crcerror_nopar(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('unpackcrc-nopar.nzb', unpack = True)
|
||||
assert hist['Status'] == 'FAILURE/UNPACK'
|
||||
@@ -21,6 +21,8 @@ def prepare_testdata(request):
|
||||
testdata_dir = nzbget_srcdir + '/tests/testdata'
|
||||
if not os.path.exists(nserv_datadir + '/parchecker'):
|
||||
shutil.copytree(testdata_dir +'/parchecker', nserv_datadir + '/parchecker')
|
||||
if not os.path.exists(nserv_datadir + '/parchecker2'):
|
||||
shutil.copytree(testdata_dir +'/parchecker2', nserv_datadir + '/parchecker2')
|
||||
|
||||
if 0 != subprocess.call([nzbget_bin, '--nserv', '-d', nserv_datadir, '-v', '2', '-z', '3000', '-q']):
|
||||
pytest.exit('Test file generation failed')
|
||||
|
||||
@@ -1,19 +1,37 @@
|
||||
nzbget_options = ['ParCheck=auto', 'ParQuick=yes', 'PostStrategy=sequential']
|
||||
|
||||
def test_parchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_subject(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
nzb_content = nzb_content.replace('subject=""', 'subject="')
|
||||
nzb_content = nzb_content.replace('" yEnc', '.dat yEnc')
|
||||
hist = nzbget.download_nzb('parchecker.subject.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_middle(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.middle.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_last(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('<segment bytes="3000" number="18">parchecker2/testfile.7z.001?18=51000:200</segment>', '')
|
||||
hist = nzbget.download_nzb('parchecker.last.nzb', nzb_content, unpack=False)
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
|
||||
def test_parchecker_last_unpack(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('<segment bytes="3000" number="18">parchecker2/testfile.7z.001?18=51000:200</segment>', '')
|
||||
hist = nzbget.download_nzb('parchecker.last.unpack.nzb', nzb_content, unpack=True)
|
||||
assert hist['Status'] == 'SUCCESS/UNPACK'
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
nzbget_options = ['ParCheck=force', 'ParQuick=yes', 'PostStrategy=sequential']
|
||||
|
||||
def test_parchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_middle(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.middle.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_last(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('<segment bytes="3000" number="18">parchecker2/testfile.7z.001?18=51000:200</segment>', '')
|
||||
hist = nzbget.download_nzb('parchecker.last.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
nzbget_options = ['ParCheck=manual', 'ParQuick=yes', 'PostStrategy=sequential']
|
||||
|
||||
def test_parchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content)
|
||||
assert hist['Status'] == 'WARNING/DAMAGED'
|
||||
|
||||
def test_parchecker_middle(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('<segment bytes="3000" number="16">parchecker2/testfile.7z.001?16=45000:3000</segment>', '')
|
||||
hist = nzbget.download_nzb('parchecker.middle.nzb', nzb_content)
|
||||
assert hist['Status'] == 'WARNING/DAMAGED'
|
||||
|
||||
def test_parchecker_last(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('<segment bytes="3000" number="18">parchecker2/testfile.7z.001?18=51000:200</segment>', '')
|
||||
hist = nzbget.download_nzb('parchecker.last.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
nzbget_options = ['ParCheck=auto', 'ParQuick=yes', 'PostStrategy=balanced']
|
||||
|
||||
def test_parchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
nzbget_options = ['ParCheck=force', 'ParQuick=yes', 'PostStrategy=balanced']
|
||||
|
||||
def test_parchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
nzbget_options = ['ParCheck=manual', 'ParQuick=yes', 'PostStrategy=balanced']
|
||||
|
||||
def test_parchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content)
|
||||
assert hist['Status'] == 'WARNING/DAMAGED'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
nzbget_options = ['ParCheck=force', 'ParQuick=no', 'PostStrategy=balanced']
|
||||
|
||||
def test_parchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
nzbget_options = ['ParCheck=auto', 'ParQuick=no', 'PostStrategy=rocket']
|
||||
|
||||
def test_parchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzbget.api.pausepost();
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
nzbget.append_nzb('parchecker.1.nzb', nzb_content, dupemode='FORCE')
|
||||
nzbget.append_nzb('parchecker.2.nzb', nzb_content, dupemode='FORCE')
|
||||
nzbget.append_nzb('parchecker.3.nzb', nzb_content, dupemode='FORCE')
|
||||
|
||||
@@ -67,19 +67,19 @@ def test_rename_obf3dmf2(nserv, nzbget):
|
||||
assert hist['Status'] == 'WARNING/HEALTH'
|
||||
|
||||
def test_renameparchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_dmp(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.par2?1=0:3000', 'parchecker/testfile.par2?1=0:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.damagedpar.nzb', nzb_content)
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.par2?1=0:3000', 'parchecker2/testfile.7z.par2?1=0:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker2.damagedpar.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
for entry in nzbget.api.loadlog(hist['ID'], 0, 10000):
|
||||
assert entry['Kind'] != 'ERROR', entry['Text']
|
||||
|
||||
@@ -67,19 +67,19 @@ def test_rename_obf3dmf2(nserv, nzbget):
|
||||
assert hist['Status'] == 'SUCCESS/UNPACK'
|
||||
|
||||
def test_parchecker_healthy(nserv, nzbget):
|
||||
hist = nzbget.download_nzb('parchecker.nzb')
|
||||
hist = nzbget.download_nzb('parchecker2.nzb')
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
|
||||
def test_parchecker_repair(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content)
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker2.repair.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/PAR'
|
||||
|
||||
def test_parchecker_dmp(nserv, nzbget):
|
||||
nzb_content = nzbget.load_nzb('parchecker.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker/testfile.par2?1=0:3000', 'parchecker/testfile.par2?1=0:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker.damagedpar.nzb', nzb_content)
|
||||
nzb_content = nzbget.load_nzb('parchecker2.nzb')
|
||||
nzb_content = nzb_content.replace('parchecker2/testfile.7z.par2?1=0:3000', 'parchecker2/testfile.7z.par2?1=0:3000!0')
|
||||
hist = nzbget.download_nzb('parchecker2.damagedpar.nzb', nzb_content)
|
||||
assert hist['Status'] == 'SUCCESS/HEALTH'
|
||||
for entry in nzbget.api.loadlog(hist['ID'], 0, 10000):
|
||||
assert entry['Kind'] != 'ERROR', entry['Text']
|
||||
|
||||
4
tests/testdata/parchecker2/crc.txt
vendored
Normal file
4
tests/testdata/parchecker2/crc.txt
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
testfile.7z.001 2c4f3383
|
||||
testfile.7z.002 153f2b08
|
||||
testfile.7z.003 f4c85a77
|
||||
testfile.nfo 0f294d41
|
||||
BIN
tests/testdata/parchecker2/testfile.7z.001
vendored
Normal file
BIN
tests/testdata/parchecker2/testfile.7z.001
vendored
Normal file
Binary file not shown.
868
tests/testdata/parchecker2/testfile.7z.002
vendored
Normal file
868
tests/testdata/parchecker2/testfile.7z.002
vendored
Normal file
@@ -0,0 +1,868 @@
|
||||
rmediate destination directory
|
||||
names now include unique numbers to avoid several downloads with same
|
||||
name to use the same directory and interfere with each other;
|
||||
- when option "UnpackCleanupDisk" is active all archive files are now
|
||||
deleted from download directory without relying on output printed by
|
||||
unrar; this solves issues with non-ascii-characters in archive file
|
||||
names on some platforms and especially in combination with rar5;
|
||||
- improved handling of non-ascii characters in file names on windows;
|
||||
- added support for rar5-format when checking signatures of archives
|
||||
with non-standard file extensions;
|
||||
- small restructure in settings order:
|
||||
- combined sections "REMOTE CONTROL" and "PERMISSIONS" into one
|
||||
section with name "SECURITY";
|
||||
- moved sections "CATEGORIES" and "RSS FEEDS" higher in the
|
||||
section list;
|
||||
- improved par-check: if main par2-file is corrupted and can not be
|
||||
loaded other par2-files are downloaded and then used as replacement
|
||||
for main par2-file;
|
||||
- if unpack did not find archive files the par-check is not requested
|
||||
anymore if par-rename was already done;
|
||||
- better handling of obfuscated nzb-files containing multiple files
|
||||
with same names; removed option "StrictParName" which was not working
|
||||
good with obfuscated files; if more par-files are required for repair
|
||||
the files with strict names are tried first and then other par-files;
|
||||
- added new scheduler commands "ActivateServer", "DeactivateServer" and
|
||||
"FetchFeed"; combined options "TaskX.DownloadRate" and "TaskX.Process"
|
||||
into one option "TaskX.Param", also used by new commands;
|
||||
- added status filter buttons to history page;
|
||||
- if unpack fails with write error (usually because of not enough space
|
||||
on disk) this is shown as status "Unpack: space" in web-interface;
|
||||
this unpack-status is handled as "success" by duplicate handling
|
||||
(no download of other duplicate); also added new unpack-status "wrong
|
||||
password" (only for rar5-archives); env.var. NZBPP_UNPACKSTATUS has
|
||||
two new possible values: 3 (write error) and 4 (wrong password);
|
||||
updated pp-script "EMail.py" to support new unpack-statuses;
|
||||
- fixed a potential seg. fault in a commonly used function;
|
||||
- added new option "TimeCorrection" to adjust conversion from system
|
||||
time to local time (solves issues with scheduler when using a
|
||||
binary compiled for other platform);
|
||||
- NZBIDs are now generated with more care avoiding numbering holes
|
||||
possible in previous versions;
|
||||
- fixed: invalid "Offset" passed to RPC-method "editqueue" or command
|
||||
line action "-E/--edit" could crash the program;
|
||||
- fixed: crash after downloading of an URL (happen only on certain systems);
|
||||
- fixed: restoring of settings didn't work for multi-sections (servers,
|
||||
categories, etc.) if they were empty;
|
||||
- fixed: choosing local files didn't work in Opera;
|
||||
- fixed: certain characters printed by pp-scripts could crash the
|
||||
program;
|
||||
- fixed: malformed nzb-file could cause a memory leak;
|
||||
- fixed: when a duplicate file was detected in collection it was
|
||||
automatically deleted (if option DupeCheck is active) but the
|
||||
total size of collection was not updated;
|
||||
- when deleting individual files the total count of files in collection
|
||||
was not updated;
|
||||
- fixed: when multiple nzb-files were added via URL (rss including) at
|
||||
the same time the info about category and priority could get lost for
|
||||
some of files;
|
||||
- fixed: if unpack fails the created destination directory was not
|
||||
automatically removed (only if option "InterDir" was active);
|
||||
- fixed scrolling to the top of page happening by clicking on items in
|
||||
downloads/history lists and on action-buttons in edit-download and
|
||||
history dialogs;
|
||||
- fixed potential buffer overflow in remote client;
|
||||
- improved error reporting when creation of temporary output file fails;
|
||||
- fixed: when deleting download, if all remaining queued files are
|
||||
par2-files the disk cleanup should not be performed, but it was
|
||||
sometimes;
|
||||
- fixed a potential problem in incorrect using of one library function.
|
||||
|
||||
nzbget-11.0:
|
||||
- reworked concept of post-processing scripts:
|
||||
- multiple scripts can be assigned to each nzb-file;
|
||||
- all assigned scripts are executed after the nzb-file is
|
||||
downloaded and internally processed (unpack, repair);
|
||||
- option <PostProcess> is obsolete;
|
||||
- new option <ScriptDir> sets directory where all pp-scripts must
|
||||
be stored;
|
||||
- new option <DefScript> sets the default list of pp-scripts to
|
||||
be assigned to nzb-file when it's added to queue;
|
||||
- new option <CategoryX.DefScript> to set the default list of
|
||||
pp-scripts on a category basis;
|
||||
- the execution order of pp-scripts can be set using new option
|
||||
<ScriptOrder>;
|
||||
- there are no separate configuration files for pp-scripts;
|
||||
- configuration options and pp-parameters are defined in the
|
||||
pp-scripts;
|
||||
- script configuration options are saved in nzbget configuration
|
||||
file (nzbget.conf);
|
||||
- changed parameters list of RPC-methods <loadconfig> and
|
||||
<saveconfig>;
|
||||
- new RPC-method <configtemplates> returns configuration
|
||||
descriptions for the program and for all pp-scripts;
|
||||
- configuration of all scripts can be done in web-interface;
|
||||
- the pp-scripts assigned to a particular nzb-file can be viewed
|
||||
and changed in web-interface on page <pp-parameters> in the
|
||||
edit download dialog;
|
||||
- option <PostPauseQueue> renamed to <ScriptPauseQueue> (the old
|
||||
name is still recognized);
|
||||
- new option <ConfigTemplate> to define the location of template
|
||||
configuration file (in previous versions it must be always
|
||||
stored in <WebDir>);
|
||||
- history dialog shows status of every script;
|
||||
- the old example post-processing script replaced with two new scripts:
|
||||
- EMail.py - sends E-Mail notification;
|
||||
- Logger.py - saves the full post-processing log of the job into
|
||||
file _postprocesslog.txt;
|
||||
- both pp-scripts are written in python and work on Windows too
|
||||
(in addition to Linux, Mac, etc.);
|
||||
- added possibility to set post-processing parameters for history items:
|
||||
- pp-parameters can now be viewed and changed in history dialog
|
||||
in web-interface;
|
||||
- useful before post-processing again;
|
||||
- new action <HistorySetParameter> in RPC-method <editqueue>;
|
||||
- new action <O> in remote command <--edit/-E> for history items
|
||||
(subcommand <H>);
|
||||
- added new feature <split download> which creates new download from
|
||||
selected files of source download;
|
||||
- new command <Split> in web-interface in edit download dialog
|
||||
on page <Files>;
|
||||
- new action <S> in remote command <--edit/-E>;
|
||||
- new action <FileSplit> in JSON-/XML-RPC method <editqueue>;
|
||||
- added support for manual par-check:
|
||||
- if option <ParCheck> is set to <Manual> and a damaged download
|
||||
is detected the program downloads all par2-files but doesn't
|
||||
perform par-check; the user must perform par-check/repair
|
||||
manually then (possibly on another, faster computer);
|
||||
- old values <yes/no> of option <ParCheck> renamed to <Force>
|
||||
and <Auto> respectively;
|
||||
- when set to <Force> all par2-files are always downloaded;
|
||||
- removed option <LoadPars> since its functionality is now
|
||||
covered by option <ParCheck>;
|
||||
- result of par-check can now have new value <Manual repair
|
||||
necessary>;
|
||||
- field <ParStatus> in RPC-method <history> can have new value
|
||||
<MANUAL>;
|
||||
- parameter <NZBPP_PARSTATUS> for pp-script can have new value
|
||||
<4 = manual repair necessary>;
|
||||
- when download is resumed in web-interface the option <ParCheck=Force>
|
||||
is respected and all par2-files are resumed (not only main par2-file);
|
||||
- automatic deletion of backup-source files after successful par-repair;
|
||||
important when repairing renamed rar-files since this could cause
|
||||
failure during unpack;
|
||||
- par-checker and renamer now add messages into the log of pp-item
|
||||
(like unpack- and pp-scripts-messages); these message now appear in
|
||||
the log created by scripts Logger.py and EMail.py;
|
||||
- when a nzb-file is added via web-interface or via remote call the
|
||||
file is now put into incoming nzb-directory (option "NzbDir") and
|
||||
then scanned; this has two advantages over the old behavior when the
|
||||
file was parsed directly in memory:
|
||||
- the file serves as a backup for troubleshootings;
|
||||
- the file is processed by nzbprocess-script (if defined in
|
||||
option "NzbProcess") making the pre-processing much easier;
|
||||
- new env-var parameters are passed to NzbProcess-script: NZBNP_NZBNAME,
|
||||
NZBNP_CATEGORY, NZBNP_PRIORITY, NZBNP_TOP, NZBNP_PAUSED;
|
||||
- new commands for use in NzbProcess-scripts: "[NZB] TOP=1" to add nzb
|
||||
to the top of queue and "[NZB] PAUSED=1" to add nzb-file in paused state;
|
||||
- reworked post-processor queue:
|
||||
- only one job is created for each nzb-file; no more separate
|
||||
jobs are created for par-collections within one nzb-file;
|
||||
- option <AllowReProcess> removed; a post-processing script is
|
||||
called only once per nzb-file, this behavior cannot be altered
|
||||
anymore;
|
||||
- with a new feature <Split> individual par-collections can be
|
||||
processed separately in a more effective way than before
|
||||
- improved unicode (utf8) support:
|
||||
- non-ascii characters are now correctly transferred via JSON-RPC;
|
||||
- correct displaying of nzb-names and paths in web-interface;
|
||||
- it is now possible to use non-ascii characters on settings page
|
||||
for option values (such as paths or category names);
|
||||
- improved unicode support in XML-RPC and JSON-RPC;
|
||||
- if username and password are defined for a news-server the
|
||||
authentication is now forced (in previous versions the authentication
|
||||
was performed only if requested by server); needed for servers
|
||||
supporting both anonymous (restricted) and authorized (full access)
|
||||
accounts;
|
||||
- added option <ExtCleanupDisk> to automatically delete unwanted files
|
||||
(with specified extensions or names) after successful par-check or unpack;
|
||||
- improvement in JSON-/XML-RPC:
|
||||
- all ID fields including NZBID are now persistent and remain
|
||||
their values after restart;
|
||||
- this allows for third-party software to identify nzb-files by
|
||||
ID;
|
||||
- method <history> now returns ID of NZB-file in the field
|
||||
<NZBID>;
|
||||
- in versions up to 0.8.0 the field <NZBID> was used to identify
|
||||
history items in the edit-commands <HistoryDelete>,
|
||||
<HistoryReturn>, <HistoryProcess>; since version 9 field <ID>
|
||||
is used for this purpose; in versions 9-10 field <NZBID> still
|
||||
existed and had the same value as field <ID> for compatibility
|
||||
with version 0.8.0; the compatibility is not provided anymore;
|
||||
this change was needed to provide a consistent using of field
|
||||
<NZBID> across all RPC-methods;
|
||||
- added support for rar-files with non-standard extensions (such as
|
||||
.001, etc.);
|
||||
- added functions to backup and restore settings from web-interface;
|
||||
when restoring it's possible to choose what sections to restore
|
||||
(for example only news servers settings or only settings of a
|
||||
certain pp-script) or restore the whole configuration;
|
||||
- new option "ControlUsername" to define login user name (if you don't
|
||||
like default username "nzbget");
|
||||
- if a communication error occurs in web-interface, it retries multiple
|
||||
times before giving up with an error message;
|
||||
- the maximum number of download threads are now managed automatically
|
||||
taking into account the number of allowed connections to news servers;
|
||||
removed option <ThreadLimit>;
|
||||
- pp-scripts terminated with unknown status are now considered failed
|
||||
(status=FAILURE instead of status=UNKNOWN);
|
||||
- new parameter (env. var) <NZBPP_NZBID> is passed to pp_scripts and
|
||||
contains an internal ID of NZB-file;
|
||||
- improved thread synchronisation to avoid (short-time) lockings of
|
||||
the program during creation of destination files;
|
||||
- more detailed error message if a directory could not be created
|
||||
(<DstDir>, <NzbDir>, etc.); the message includes error text reported
|
||||
by OS such as <permission denied> or similar;
|
||||
- when unpacking the unpack start time is now measured after receiving
|
||||
of unrar copyright message; this provides better unpack time
|
||||
estimation in a case when user uses unpack-script to do some things
|
||||
before executing unrar (for example sending Wake-On-Lan message to
|
||||
the destination NAS); it works with unrar only, it's not possible
|
||||
with 7-Zip because it buffers printed messages;
|
||||
- when the program is reloaded, a message with version number is
|
||||
printed like on start;
|
||||
- configuration can now be saved in web-interface even if there were
|
||||
no changes made but if obsolete or invalid options were detected in
|
||||
the config file; the saving removes invalid entries from config file;
|
||||
- option <ControlPassword> can now be set to en empty value to disable
|
||||
authentication; useful if nzbget works behind other web-server with
|
||||
its own authentication;
|
||||
- when deleting downloads via web-interface a proper hint regarding
|
||||
deleting of already downloaded files from disk depending on option
|
||||
<DeleteCleanupDisk> is displayed;
|
||||
- if a news-server returns empty or bad article (this may be caused
|
||||
by errors on the news server), the program tries again from the same
|
||||
or other servers (in previous versions the article was marked as
|
||||
failed without other download attempts);
|
||||
- when a nzb-file whose name ends with ".queued" is added via web-
|
||||
interface the ".queued"-part is automatically removed;
|
||||
- small improvement in multithread synchronization of download queue;
|
||||
- added link to catalog of pp-scripts to web-interface;
|
||||
- updated forum URL in about dialog in web-interface;
|
||||
- small correction in a log-message: removed <Request:> from message
|
||||
<Request: Queue collection...>;
|
||||
- removed option "ProcessLogKind"; scripts should use prefixes ([INFO],
|
||||
[DETAIL], etc); messages printed without prefixes are added as [INFO];
|
||||
- removed option "AppendNzbDir"; if it was disabled that caused problems
|
||||
in par-checker and unpacker; the option is now assumed always active;
|
||||
- removed option "RenameBroken"; it caused problems in par-checker
|
||||
(the option existed since early program versions before the par-check
|
||||
was added);
|
||||
- configure-script now defines "SIGCHLD_HANDLER" by default on all
|
||||
systems including BSD; this eliminates the need of configure-
|
||||
parameter "--enable-sigchld-handler" on 64-Bit BSD; the trade-off:
|
||||
32-Bit BSD now requires "--disable-sigchld-handler";
|
||||
- improved configure-script: defining of symbol "FILE_OFFSET_BITS=64",
|
||||
required on some systems, is not necessary anymore;
|
||||
- fixed: in the option "NzbAddedProcess" the env-var parameter with
|
||||
nzb-name was passed in "NZBNA_NAME", should be "NZBNA_NZBNAME";
|
||||
the old parameter name "NZBNA_NAME" is still supported for
|
||||
compatibility;
|
||||
- fixed: download time in statistics were incorrect if the computer
|
||||
was put into standby (thanks Frank Kuypers for the patch);
|
||||
- fixed: when option <InterDir> was active and the download after
|
||||
unpack contained rar-file with the same name as one of original
|
||||
files (sometimes happen with included subtitles) the original
|
||||
rar-file was kept with name <.rar_duplicate1> even if the option
|
||||
<UnpackCleanupDisk> was active;
|
||||
- fixed: failed to read download queue from disk if post-processing
|
||||
queue was not empty;
|
||||
- fixed: when a duplicate file was detected during download the
|
||||
program could hang;
|
||||
- fixed: symbol <DISABLE_TLS> must be defined in project settings;
|
||||
defining it in <win32.h> didn't work properly (Windows only);
|
||||
- fixed: crash when adding malformed nzb-files with certain
|
||||
structure (Windows only);
|
||||
- fixed: by deleting of a partially downloaded nzb-file from queue,
|
||||
when the option <DeleteCleanupDisk> was active, the file
|
||||
<_brokenlog.txt> was not deleted preventing the directory from
|
||||
automatic deletion;
|
||||
- fixed: if an error occurs when a RPC-client or web-browser
|
||||
communicates with nzbget the program could crash;
|
||||
- fixed: if the last file of collection was detected as duplicate
|
||||
after the download of the first article the file was deleted from
|
||||
queue (that's OK) but the post-processing was not triggered
|
||||
(that's a bug);
|
||||
- fixed: support for splitted files (.001, .002, etc.) were broken.
|
||||
|
||||
nzbget-10.2:
|
||||
- fixed potential segfault which could happen with file paths longer
|
||||
than 1024 characters;
|
||||
- fixed: when options <DirectWrite> and <ContinuePartial> were both
|
||||
active, a restart or reload of the program during download may cause
|
||||
damaged files in the active download;
|
||||
- increased width of speed indication ui-element to avoid layout
|
||||
breaking on some linux-browsers;
|
||||
- fixed a race condition in unpacker which could lead to a segfault
|
||||
(although the chances were low because the code wasn't executed often).
|
||||
|
||||
nzbget-10.1:
|
||||
- fixed: articles with decoding errors (incomplete or damaged posts)
|
||||
caused infinite retry-loop in downloader.
|
||||
|
||||
nzbget-10.0:
|
||||
- added built-in unpack:
|
||||
- rar and 7-zip formats are supported (via external Unrar and
|
||||
7-Zip executables);
|
||||
- new options <Unpack>, <UnpackPauseQueue>, <UnpackCleanupDisk>,
|
||||
<UnrarCmd>, <SevenZipCmd>;
|
||||
- web-interface now shows progress and estimated time during
|
||||
unpack (rar only; for 7-Zip progress is not available due to
|
||||
limitations of 7-Zip);
|
||||
- when built-in unpack is enabled, the post-processing script is
|
||||
called after unpack and possibly par-check/repair (if needed);
|
||||
- for nzb-files containing multiple collections (par-sets) the
|
||||
post-processing script is called only once, after the last
|
||||
par-set;
|
||||
- new parameter <NZBPP_UNPACKSTATUS> passed to post-processing
|
||||
script;
|
||||
- if the option <AllowReProcess> is enabled the post-processing-
|
||||
script is called after each par-set (as in previous versions);
|
||||
- example post-processing script updated: removed unrar-code,
|
||||
added check for unpack status;
|
||||
- new field <UnpackStatus> in result of RPC-method <history>;
|
||||
- history-dialog in web-interface shows three status: par-status,
|
||||
unpack-status, script-status;
|
||||
- with two built-in special post-processing parameters <*Unpack:>
|
||||
and <*Unpack:Password> the unpack can be disabled for individual
|
||||
nzb-file or the password can be set;
|
||||
- built-in special post-processing parameters can be set via web-
|
||||
interface on page <PP-Parameters> (when built-in unpack is
|
||||
enabled);
|
||||
- added support for HTTPS to the built-in web-server (web-interface and
|
||||
XML/JSON-RPC):
|
||||
- new options <SecureControl>, <SecurePort>, <SecureCert> and
|
||||
<SecureKey>;
|
||||
- module <TLS.c/h> completely rewritten with support for server-
|
||||
side sockets, newer versions of GnuTLS, proper thread lockings
|
||||
in OpenSSL;
|
||||
- improved the automatic par-scan (option <ParScan=auto>) to
|
||||
significantly reduce the verify-time in some common cases with renamed
|
||||
rar-files:
|
||||
- the extra files are scanned in an optimized order;
|
||||
- the scan stops when all missings files are found;
|
||||
- added fast renaming of intentionally misnamed (rar-) files:
|
||||
- the new renaming algorithm doesn't require full par-scan and
|
||||
restores original filenames in just a few seconds, even on very
|
||||
slow computers (NAS, media players, etc.);
|
||||
- the fast renaming is performed automatically when requested by
|
||||
the built-in unpacker (option <Unpack> must be active);
|
||||
- added new option <InterDir> to put intermediate files during download
|
||||
into a separate directory (instead of storing them directly in
|
||||
destination directory (option <DestDir>):
|
||||
- when nzb-file is completely (successfully) downloaded, repaired
|
||||
(if neccessary) and unpacked the files are moved to destination
|
||||
directory (option <DestDir> or <CategoryX.DestDir>);
|
||||
- intermediate directory can significantly improve unpack
|
||||
performance if it is located on a separate physical hard drive;
|
||||
- added new option <ServerX.Cipher> to manually select cipher for
|
||||
encrypted communication with news server:
|
||||
- manually choosing a faster cipher (such as <RC4>) can
|
||||
significantly improve performance (if CPU is a limiting factor);
|
||||
- major improvements in news-server/connection management (main and fill
|
||||
servers):
|
||||
- if download of article fails, the program tries all servers of
|
||||
the same level before trying higher level servers;
|
||||
- this ensures that fill servers are used only if all main servers
|
||||
fail;
|
||||
- this makes the configuring of multiple servers much easier than
|
||||
before: in most cases the simple configuration of level 0 for
|
||||
all main servers and level 1 for all fill servers suffices;
|
||||
- in previous versions the level was increased immediately after
|
||||
the first tried server of the level failed; to make sure all
|
||||
main servers were tried before downloading from fill servers it
|
||||
was required to create complex server configurations with
|
||||
duplicates; these configurations were still not as effective as
|
||||
now;
|
||||
- do not reconnect on <article/group not found> errors since this
|
||||
doesn't help but unnecessary increases CPU load and network
|
||||
traffic;
|
||||
- removed option <RetryOnCrcError>; it's not required anymore;
|
||||
- new option <ServerX.Group> allows more flexible configuration
|
||||
of news servers when using multiple accounts on the same server;
|
||||
with this option it's also possible to imitate the old server
|
||||
management behavior regarding levels;
|
||||
- news servers configuration is now less error-prone:
|
||||
- the option <ServerX.Level> is not required to start from <0> and
|
||||
when several news servers are configured the Levels can be any
|
||||
integers - the program sorts the servers and corrects the Levels
|
||||
to 0,1,2,etc. automatically if needed;
|
||||
- when option <ServerX.Connections> is set to <0> the server is
|
||||
ignored (in previous version such a server could cause hanging
|
||||
when the program was trying to go to the next level);
|
||||
- if no news servers are defined (or all definitions are invalid)
|
||||
a warning is printed to inform that the download is not
|
||||
possible;
|
||||
- categories can now have their own destination directories; new option
|
||||
<CategoryX.DestDir>;
|
||||
- new feature <Pause for X Minutes> in web-interface; new XML-/JSON-RPC
|
||||
method <scheduleresume>;
|
||||
- improved the handling of hanging connections: if a connection hangs
|
||||
longer than defined by option <ConnectionTimeout> the program tries to
|
||||
gracefully close connection first (this is new); if it still hangs
|
||||
after <TerminateTimeout> the download thread is terminated as a last
|
||||
resort (as in previous versions);
|
||||
- added automatic speed meter recalibration to recover after possible
|
||||
synchronization errors which can occur when the option <AccurateRate>
|
||||
is not active; this makes the default (less accurate but fast) speed
|
||||
meter almost as good as the accurate one; important when speed
|
||||
throttling is active;
|
||||
- when the par-checked requests more par-files, they get an extra
|
||||
priority and are downloaded before other files regardless of their
|
||||
priorities; this is needed to avoid hanging of par-checker-job if a
|
||||
file with a higher priority gets added to queue during par-check;
|
||||
- when post-processing-parameters are passed to the post-processing
|
||||
script a second version of each parameter with a normalized parameter-
|
||||
name is passed in addition to the original parameter name; in the
|
||||
normalized name the special characters <*> and <:> are replaced with
|
||||
<_> and all characters are passed in upper case; this is important for
|
||||
internal post-processing-parameters (*Unpack:=yes/no) which include
|
||||
special characters;
|
||||
- warning <Non-nzbget request received> now is not printed when the
|
||||
connection was aborted before the request signature was read;
|
||||
- changed formatting of remaining time for post-processing to short
|
||||
format (as used for remaining download time);
|
||||
- added link to article <Performance tips> to settings tab on web-
|
||||
interface;
|
||||
- removed hint <Post-processing script may have moved files elsewhere>
|
||||
from history dialog since it caused more questions than helped;
|
||||
- changed default value for option <ServerX.JoinGroup> to <no>; most
|
||||
news servers nowadays do not require joining the group and many
|
||||
servers do not keep headers for many groups making the join-command
|
||||
fail even if the articles still can be successfully downloaded;
|
||||
- small change in example post-processing script: message <Deleting
|
||||
source ts-files> are now printed only if ts-files really existed;
|
||||
- improved configure-script:
|
||||
- libs which are added via pkgconfig are now put into LIBS instead
|
||||
of LDFLAGS - improves compatibility with newer Linux linkers;
|
||||
- OpenSSL libs/includes are now added using pkgconfig to better
|
||||
handle dependencies;
|
||||
- additional check for libcrypto (part of OpenSSL) ensures the
|
||||
library is added to linker command even if pkgconfig is not
|
||||
used;
|
||||
- adding of local files via web-interface now works in IE10;
|
||||
- if an obsolete option is found in the config file a warning is printed
|
||||
instead of an error and the program is not paused anymore;
|
||||
- fixed: the reported line numbers for configuration errors were
|
||||
sometimes inaccurate;
|
||||
- fixed warning <file glyphicons-halflings.png not found>;
|
||||
- fixed: some XML-/JSON-RPC methods may return negative values for file
|
||||
sizes between 2-4GB; this had also influence on web-interface.
|
||||
- fixed: if an external program (unrar, pp-script, etc.) could not be
|
||||
started, the execute-function has returned code 255 although the code
|
||||
-1 were expected in this case; this could break designed post-
|
||||
processing flow;
|
||||
- fixed: some characters with codes below 32 were not properly encoded
|
||||
in JSON-RPC; sometimes output from unrar contained such characters
|
||||
and could break web-interface;
|
||||
- fixed: special characters (quotation marks, etc.) in unpack password
|
||||
and in configuration options were not displayed properly and could be
|
||||
discarded on saving;
|
||||
|
||||
nzbget-9.1:
|
||||
- added full par-scan feature needed to par-check/repair files which
|
||||
were renamed after creation of par-files:
|
||||
- new option <ParScan> to activate full par-scan (always or automatic);
|
||||
the automatic full par-scan activates if missing files are detected
|
||||
during par-check, this avoids unnecessary full scan for normal
|
||||
(not renamed) par sets;
|
||||
- improved the post-processing script to better handle renamed rar-files;
|
||||
- replaced a browser error message when trying to add local files in
|
||||
IE9 with a better message dialog;
|
||||
|
||||
nzbget-9.0:
|
||||
- changed version naming scheme by removing the leading zero: current
|
||||
version is now called 9.0 instead of 0.9.0 (it's really the 9th major
|
||||
version of the program);
|
||||
- added built-in web-interface:
|
||||
- completely new designed and written from scratch;
|
||||
- doesn't require a separate web-server;
|
||||
- doesn't require PHP;
|
||||
- 100% Javascript application; the built-in web-server hosts only
|
||||
static files; the javascript app communicates with NZBGet via
|
||||
JSON-RPC;
|
||||
- very efficient usage of server resources (CPU and memory);
|
||||
- easy installation. Since neither a separate web-server nor PHP
|
||||
are needed the installation of new web-interface is very easy.
|
||||
Actually it is performed automatically when you "make install"
|
||||
or "ipkg install nzbget";
|
||||
- modern look: better layout, popup dialogs, nice animations,
|
||||
hi-def icons;
|
||||
- built-in phone-theme (activates automatically);
|
||||
- combined view for "currently downloading", "queued", "currently
|
||||
processing" and "queued for processing";
|
||||
- renaming of nzb-files;
|
||||
- multiselect with multiedit or merge of downloads;
|
||||
- fast paging in the lists (downloads, history, messages);
|
||||
- search box for filtering in the lists (downloads, history, messages)
|
||||
and in settings;
|
||||
- adding nzb-files to download queue was improved in several ways:
|
||||
- add multiple files at once. The "select files dialog" allows
|
||||
to select multiple files;
|
||||
- add files using drag and drop. Just drop the files from your
|
||||
file manager directly into the web-browser;
|
||||
- add files via URLs. Put the URL and NZBGet downloads the
|
||||
nzb-file and adds it to download queue automatically;
|
||||
- the priority of nzb-file can now be set when adding local-files
|
||||
or URLs;
|
||||
- the history can be cleared completely or selected items can be removed;
|
||||
- file mode is now nzb-file related;
|
||||
- added the ability to queue URLs:
|
||||
- the program automatically downloads nzb-files from given URLs
|
||||
and put them to download queue.
|
||||
- when multiple URLs are added in a short time, they are put
|
||||
into a special URL-queue.
|
||||
- the number of simultaneous URL-downloads are controlled via
|
||||
new option UrlConnections.
|
||||
- with the new option ReloadUrlQueue can be controlled if the URL-queue
|
||||
should be reloaded after the program is restarted (if the URL-queue
|
||||
was not empty).
|
||||
- new switch <-U> for remote-command <--append/-A> to queue an URL.
|
||||
- new subcommand <-U> in the remote command <--list/-L> prints the
|
||||
current URL-queue.
|
||||
- if URL-download fails, the URL is moved into history.
|
||||
- with subcommand <-R> of command <--edit> the failed URL can be
|
||||
returned to URL-queue for redownload.
|
||||
- the remote command <--list/-L> for history can now print the infos
|
||||
for URL history items.
|
||||
- new XML/JSON-RPC command <appendurl> to add an URL or multiple
|
||||
URLs for download.
|
||||
- new XML/JSON-RPC command <urlqueue> returns the items from the
|
||||
URL-queue.
|
||||
- the XML/JSON-RPC command <history> was extended to provide
|
||||
infos about URL history items.
|
||||
- the URL-queue obeys the pause-state of download queue.
|
||||
- the URL-downloads support HTTP and HTTPS protocols;
|
||||
- added new field <name> to nzb-info-object.
|
||||
- it is initially set to the cleaned up name of the nzb-file.
|
||||
- the renaming of the group changes this field.
|
||||
- all RPC-methods related to nzb-object return the new field, the
|
||||
old field <NZBNicename> is now deprecated.
|
||||
- the option <MergeNZB> now checks the <name>-field instead of
|
||||
<nzbfilename> (the latter is not changed when the nzb is renamed).
|
||||
- new env-var-parameter <NZBPP_NZBNAME> for post-processing script;
|
||||
- added options <GN> and <FN> for remote command <--edit/-E>. With these
|
||||
options the name of group or file can be used in edit-command instead
|
||||
of file ID;
|
||||
- added support for regular expressions (POSIX ERE Syntax) in remote
|
||||
commands <--list/-L> and <--edit/-E> using new subcommands <GR> and <FR>;
|
||||
- improved performance of RPC-command <listgroups>;
|
||||
- added new command <FileReorder> to RPC-method <editqueue> to set the
|
||||
order of individual files in the group;
|
||||
- added gzip-support to built-in web-server (including RPC);
|
||||
- added processing of http-request <OPTIONS> in RPC-server for better
|
||||
support of cross domain requests;
|
||||
- renamed example configuration file and postprocessing script to make
|
||||
the installation easier;
|
||||
- improved the automatic installation (<make install>) to install all
|
||||
necessary files (not only the binary as it was before);
|
||||
- improved handling of configuration errors: the program now does not
|
||||
terminate on errors but rather logs all of them and uses default option values;
|
||||
- added new XML/JSON-RPC methods <config>, <loadconfig> and <saveconfig>;
|
||||
- with active option <AllowReProcess> the NZB considered completed even if
|
||||
there are paused non-par-files (the paused non-par-files are treated the
|
||||
same way as paused par-files): as a result the reprocessable script is called;
|
||||
- added subcommand <W> to remote command <-S/--scan> to scan synchronously
|
||||
(wait until scan completed);
|
||||
- added parameter <SyncMode> to XML/JSON-RPC method <scan>;
|
||||
- the command <Scan> in web-interface now waits for completing of scan
|
||||
before reporting the status;
|
||||
- added remote command <--reload/-O> and JSON/XML-RPC method <reload> to
|
||||
reload configuration from disk and reintialize the program; the reload
|
||||
can be performed from web-interface;
|
||||
- JSON/XML-RPC method <append> extended with parameter <priority>;
|
||||
- categories available in web-interface are now configured in program
|
||||
configuration file (nzbget.conf) and can be managed via web-interface
|
||||
on settings page;
|
||||
- updated descriptions in example configuration file;
|
||||
- changes in configuration file:
|
||||
- renamed options <ServerIP>, <ServerPort> and <ServerPassword> to
|
||||
<ControlIP>, <ControlPort> and <ControlPassword> to avoid confusion
|
||||
with news-server options <ServerX.Host>, <ServerX.Port> and
|
||||
<ServerX.Password>;
|
||||
- the old option names are still recognized and are automatically
|
||||
renamed when the configuration is saved from web-interface;
|
||||
- also renamed option <$MAINDIR> to <MainDir>;
|
||||
- extended remote command <--append/-A> with optional parameters:
|
||||
- <T> - adds the file/URL to the top of queue;
|
||||
- <P> - pauses added files;
|
||||
- <C category-name> - sets category for added nzb-file/URL;
|
||||
- <N nzb-name> - sets nzb filename for added URL;
|
||||
- the old switches <--category/-K> and <--top/-T> are deprecated
|
||||
but still supported for compatibility;
|
||||
- renamed subcommand <K> of command <--edit/-E> to <C> (the old
|
||||
subcommand is still supported for compatibility);
|
||||
- added new option <NzbAddedProcess> to setup a script called after
|
||||
a nzb-file is added to queue;
|
||||
- added debug messages for speed meter;
|
||||
- improved the startup script <nzbgetd> so it can be directly used in
|
||||
</etc/init.d> without modifications;
|
||||
- fixed: after renaming of a group, the new name was not displayed
|
||||
by remote commands <-L G> and <-C in curses mode>;
|
||||
- fixed incompatibility with OpenSLL 1.0 (thanks to OpenWRT team
|
||||
for the patch);
|
||||
- fixed: RPC-method <log(0, IdFrom)> could return wrong results if
|
||||
the log was filtered with options <XXXTarget>;
|
||||
- fixed: free disk space calculated incorrectly on some OSes;
|
||||
- fixed: unrar failure was not always properly detected causing the
|
||||
post-processing to delete not yet unpacked rar-files;
|
||||
- fixed compilation error on recent linux versions;
|
||||
- fixed compilation error on older systems;
|
||||
|
||||
nzbget-0.8.0:
|
||||
- added priorities; new action <I> for remote command <--edit/-E> to set
|
||||
priorities for groups or individual files; new actions <SetGroupPriority>
|
||||
and <SetFilePriority> of RPC-command <editqueue>; remote command
|
||||
<--list/-L> prints priorities and indicates files or groups being
|
||||
downloaded; ncurses-frontend prints priorities and indicates files or
|
||||
groups being download; new command <PRIORITY> to set priority of nzb-file
|
||||
from nzbprocess-script; RPC-commands <listgroups> and <listfiles> return
|
||||
priorities and indicate files or groups being downloaded;
|
||||
- added renaming of groups; new subcommand <N> for command <--edit/-E>; new
|
||||
action <SetName> for RPC-method <editqueue>;
|
||||
- added new option <AccurateRate>, which enables syncronisation in speed
|
||||
meter; that makes the indicated speed more accurate by eliminating
|
||||
measurement errors possible due thread conflicts; thanks to anonymous
|
||||
nzbget user for the patch;
|
||||
- improved the parsing of filename from article subject;
|
||||
- option <DirectWrite> now efficiently works on Windows with NTFS partitions;
|
||||
- added URL-based-authentication as alternative to HTTP-header authentication
|
||||
for XML- and JSON-RPC;
|
||||
- fixed: nzb-files containing umlauts and other special characters could not
|
||||
be parsed - replaced XML-Reader with SAX-Parser - only on POSIX (not on
|
||||
Windows);
|
||||
- fixed incorrect displaying of group sizes bigger than 4GB on many 64-bit
|
||||
OSes;
|
||||
- fixed a bug causing error on decoding of input data in JSON-RPC;
|
||||
- fixed a compilation error on some windows versions;
|
||||
- fixed: par-repair could fail when the filenames were not correctly parsed
|
||||
from article subjects;
|
||||
- fixed a compatibility issue with OpenBSD (and possibly other BSD based
|
||||
systems); added the automatic configuring of required signal handling logic
|
||||
to better support BSD without breaking the compatibility with certain Linux
|
||||
systems;
|
||||
- corrected the address of Free Software Foundation in copyright notice.
|
||||
|
||||
nzbget-0.7.0:
|
||||
- added history: new option <KeepHistory>, new remote subcommand <H> for
|
||||
commands <L> (list history entries) and <E> (delete history entries,
|
||||
return history item, postprocess history item), new RPC-command <History>
|
||||
and subcommands <HistoryDelete>, <HistoryReturn>, <HistoryProcess> for
|
||||
command <EditQueue>;
|
||||
- added support for JSON-P (extension of JSON-RPC);
|
||||
- changed the result code returning status <ERROR> for postprocessing script
|
||||
from <1> to <94> (needed to show the proper script status in history);
|
||||
- improved the detection of new files in incoming nzb directory: now the
|
||||
scanner does not rely on system datum, but tracks the changing of file
|
||||
sizes during a last few (<NzbDirFileAge>) seconds instead;
|
||||
- improvements in example postprocessing script: 1) if download contains
|
||||
only par2-files the script do not delete them during cleanup;
|
||||
2) if download contains only nzb-files the script moves them to incoming
|
||||
nzb-directory for further download;
|
||||
- improved formatting of groups and added time info in curses output mode;
|
||||
- added second pause register, which is independent of main pause-state and
|
||||
therfore is intended for usage from external scripts;
|
||||
that allows to pause download without interfering with options
|
||||
<ParPauseQueue> and <PostPauseQueue> and scheduler tasks <PauseDownload>
|
||||
and <UnpauseDownload> - they all work with first (default) pause register;
|
||||
new subcommand <D2> for commands <--pause/-P> and <--unpause/-U>;
|
||||
new RPC-command <pausedownload2> and <resumedownload2>;
|
||||
existing RPC-commands <pause> und <resume> renamed to <pausedownload> and
|
||||
<resumedownload>;
|
||||
new field <Download2Paused> in result struct for RPC-command <status>;
|
||||
existing fields <ServerPaused> and <ParJobCount> renamed to
|
||||
<DownloadPaused> and <PostJobCount>;
|
||||
old RPC-commands and fields still exist for compatibility;
|
||||
the status output of command <--list/-L> indicates the state of second
|
||||
pause register;
|
||||
key <P> in curses-frontend can unpause second pause-register;
|
||||
- nzbprocess-script (option <NZBProcess>) can now set category and
|
||||
post-processing parameters for nzb-file;
|
||||
- redesigned server pool and par-checker to avoid using of semaphores
|
||||
(which are very platform specific);
|
||||
- added subcommand <S> to remote commands <--pause/-P> and <--unpause/-U> to
|
||||
pause/unpause the scanning of incoming nzb-directory;
|
||||
- added commands <PauseScan> and <UnpauseScan> for scheduler option
|
||||
<TaskX.Command>;
|
||||
- added remote commands <PauseScan> and <ResumeScan> for XML-/JSON-RPC;
|
||||
- command <pause post-processing> now not only pauses the post-processing
|
||||
queue but also pauses the current post-processing job (par-job or
|
||||
script-job);
|
||||
however the script-job can be paused only after the next line printed to
|
||||
screen;
|
||||
- improved error reporting while parsing nzb-files;
|
||||
- added field <NZBID> to NZBInfo; the field is now returned by XML-/JSON-RPC
|
||||
methods <listfiles>, <listgroups> and <postqueue>;
|
||||
- improvements in configure script;
|
||||
- added support for platforms without IPv6 (they do not have <getaddrinfo>);
|
||||
- debug-messages generated on early stages during initializing are now
|
||||
printed to screen/log-file;
|
||||
- messages about obsolete options are now printed to screen/log-file;
|
||||
- imporved example postprocessing script: added support for external
|
||||
configuration file, postprocessing parameters and configuration via
|
||||
web-interface;
|
||||
- option <TaskX.Process> now can contain parameters which must be passed
|
||||
to the script;
|
||||
- added pausing/resuming for post-processor queue;
|
||||
added new modifier <O> to remote commands <--pause/-P> and <--unpause/-U>;
|
||||
added new commands <postpause> and <postresume> to XML-/JSON-RPC;
|
||||
extended output of remote command <--list/-L> to indicate paused state
|
||||
of post-processor queue; extended command <status> of XML-/JSON-RPC
|
||||
with field <PostPause>;
|
||||
- changed the command line syntax for requesting of post-processor queue
|
||||
from <-O> to <-L O> for consistency with other post-queue related
|
||||
commands (<-P O>, <-U O> and <-E O>);
|
||||
- improved example post-processing script: added support for delayed
|
||||
par-check (try unrar first, par-repair if unrar failed);
|
||||
- added modifier <O> to command <-E/--edit> for editing of
|
||||
post-processor-queue;
|
||||
following subcommands are supported: <+/-offset>, <T>, <B>, <D>;
|
||||
subcommand <D> supports deletion of queued post-jobs and active job as well;
|
||||
deletion of active job means the cancelling of par-check/repair or
|
||||
terminating of post-processing-script (including child processes of the
|
||||
script);
|
||||
updated remote-server to support new edit-subcommands in XML/JSON-RPC;
|
||||
- extended the syntax of option <TaskX.Time> in two ways:
|
||||
1) it now accepts multiple comma-separated values;
|
||||
2) an asterix as hours-part means <every hour>;
|
||||
- added svn revision number to version string (commands <-v> and <-V>,
|
||||
startup log entry);
|
||||
svn revision is automatically read from svn-repository on each build;
|
||||
- added estimated remaining time and better distinguishing of server state
|
||||
in command <--list/-L>;
|
||||
- added new return code (93) for post-processing script to indicate
|
||||
successful processing; that results in cleaning up of download queue
|
||||
if option <ParCleanupQueue> is active;
|
||||
- added readonly options <AppBin>, <ConfigFile> and <Version> for usage
|
||||
in processing scripts (options are available as environment variables
|
||||
<NZBOP_APPBIN>, <NZBOP_CONFIGFILE> and <NZBOP_VERSION>);
|
||||
- renamed ParStatus constant <FAILED> to <FAILURE> for a consistence with
|
||||
ScriptStatus constant <FAILURE>, that also affects the results of
|
||||
RPC-command <history>;
|
||||
- added a new return code <95/POSTPROCESS_NONE> for post-processing scripts
|
||||
for cases when pp-script skips all post-processing work (typically upon
|
||||
a user's request via a pp-parameter);
|
||||
modified the example post-processing script to return the new code
|
||||
instead of a error code when a pp-parameter <PostProcess> was set to <no>;
|
||||
- added field <PostTime> to result of RPC-Command <listfiles> and fields
|
||||
<MinPostTime> and <MaxPostTime> for command <listgroups>;
|
||||
- in <curses> and <colored> output-modes the download speed is now printed
|
||||
with one decimal digit when the speed is lower than 10 KB/s;
|
||||
- improvement in example post-processing script: added check for existence
|
||||
of <unrar> and command <wc>;
|
||||
- added shell batch file for windows (nzbget-shell.bat);
|
||||
thanks to orbisvicis (orbisvicis@users.sourceforge.net) for the script;
|
||||
- added debian style init script (nzbgetd);
|
||||
thanks to orbisvicis (orbisvicis@users.sourceforge.net) for the script;
|
||||
- added the returning of a proper HTTP error code if the authorization was
|
||||
failed on RPC-calls;
|
||||
thanks to jdembski (jdembski@users.sourceforge.net) for the patch;
|
||||
- changed the sleep-time during the throttling of bandwidth from 200ms to
|
||||
10ms in order to achieve better uniformity;
|
||||
- modified example postprocessing script to not use the command <dirname>,
|
||||
which is not always available;
|
||||
thanks to Ger Teunis for the patch;
|
||||
- improved example post-processing script: added the check for existence
|
||||
of destination directory to return a proper ERROR-code (important for
|
||||
reprocessing of history items);
|
||||
- by saving the queue to disk now using relative paths for the list of
|
||||
compeled files to reduce the file's size;
|
||||
- eliminated few compiler warnings on GCC;
|
||||
- fixed: when option <DaemonUserName> was specified and nzbget was
|
||||
started as root, the lockfile was not removed;
|
||||
- fixed: nothing was downloaded when the option <Retries> was set to <0>;
|
||||
- fixed: base64 decoding function used by RPC-method <append> sometimes
|
||||
failed, in particular when called from Ruby-language;
|
||||
- fixed: JSON-RPC-commands failed, if parameters were placed before method
|
||||
name in the request;
|
||||
- fixed: RPC-method <append> did not work properly on Posix systems
|
||||
(it worked only on Windows);
|
||||
- fixed compilation error when using native curses library on OpenSolaris;
|
||||
- fixed linking error on OpenSolaris when using GnuTLS;
|
||||
- fixed: option <ContinuePartial> did not work;
|
||||
- fixed: seg. fault in service mode on program start (Windows only);
|
||||
- fixed: environment block was not passed correctly to child process,
|
||||
what could result in seg faults (windows only);
|
||||
- fixed: returning the postprocessing exit code <92 - par-check all
|
||||
collections> when there were no par-files results in endless calling
|
||||
of postprocessing script;
|
||||
- fixed compatibility issues with OS/2.
|
||||
|
||||
nzbget-0.6.0:
|
||||
- added scheduler; new options <TaskX.Time>, <TaskX.WeekDays>,
|
||||
<TaskX.Command>, <TaskX.DownloadRate> and <TaskX.Process>;
|
||||
- added support for postprocess-parameters; new subcommand <O> of remote
|
||||
command <E> to add/modify pp-parameter for group (nzb-file); new
|
||||
XML-/JSON-RPC-subcommand <GroupSetParameter> of method <editqueue> for
|
||||
the same purpose; updated example configuration file and example
|
||||
postprocess-script to indicate new method of passing arguments via
|
||||
environment variables;
|
||||
- added subcommands <F>, <G> and <S> to command line switch <-L/--list>,
|
||||
which prints list of files, groups or only status info respectively;
|
||||
extended binary communication protocol to transfer nzb-infos in addition
|
||||
to file-infos;
|
||||
- added new subcommand <M> to edit-command <E> for merging of two (or more)
|
||||
groups (useful after adding pars from a separate nzb-file);
|
||||
- added option <MergeNzb> to automatically merge nzb-files with the same
|
||||
filename (useful by adding pars from a different source);
|
||||
- added script-processing of files in incoming directory to allow automatic
|
||||
unpacking and queueing of compressed nzb-files; new option <NzbProcess>;
|
||||
- added the printing of post-process-parameters for groups in command
|
||||
<--list G>;
|
||||
- added the printing of nzbget version into the log-file on start;
|
||||
- added option <DeleteCleanupDisk> to automatically delete already downloaded
|
||||
files from disk if nzb-file was deleted from queue (the download was
|
||||
cancelled);
|
||||
- added option <ParTimeLimit> to define the max time allowed for par-repair;
|
||||
- added command <--scan/-S> to execute the scan of nzb-directory on remote
|
||||
server;
|
||||
- changed the method to pass arguments to postprocess/nzbprocess: now using
|
||||
environment variables (old method is still supported for compatibility with
|
||||
existing scripts);
|
||||
- added the passing of nzbget-options to postprocess/nzbprocess scripts as
|
||||
environment variables;
|
||||
- extended the communication between nzbget and post-process-script:
|
||||
collections are now detected even if parcheck is disabled;
|
||||
- added support for delayed par-check/repair: post-process-script can request
|
||||
par-check/repair using special exit codes to repair current collection or
|
||||
all collections;
|
||||
- implemented the normalizing of option names and values in option list; the
|
||||
command <-p> also prints normalized names and values now; that makes the
|
||||
parsing of output of command <-p> for external scripts easier;
|
||||
- replaced option <PostLogKind> with new option <ProcessLogKind> which is now
|
||||
used by all scripts (PostProcess, NzbProcess, TaskX.Process);
|
||||
- improved entering to paused state on connection errors (do not retry failed
|
||||
downloads if pause was activated);
|
||||
- improved error reporting on decoding failures;
|
||||
- improved compatibility of yenc-decoder;
|
||||
- improved the speed of deleting of groups from download queue (by avoiding
|
||||
the saving of queue after the deleting of each individual file);
|
||||
- updated configure-script for better compatibility with FreeBSD;
|
||||
- cleaning up of download queue (option <ParCleanupQueue>) and deletion of
|
||||
source nzb-file (option <NzbCleanupDisk>) after par-repair now works also
|
||||
if par-repair was cancelled (option <ParTimeLimit>); since required
|
||||
par-files were already downloaded the repair in an external tool is
|
||||
possible;
|
||||
- added workaround to avoid hangs in child processes (by starting of
|
||||
postprocess or nzbprocess), observed on uClibC based systems;
|
||||
- fixed: TLS/SSL didn't work in standalone mode;
|
||||
- fixed compatibility issues with Mac OS X;
|
||||
- fixed: not all necessary par2-files were unpaused on first request for
|
||||
par-blocks (although harmless, because additional files were unpaused
|
||||
later anyway);
|
||||
- fixed small memory leak appeared if process-script could not be started;
|
||||
- fixed: configure-script could not detect the right syntax for function
|
||||
<ctime_r> on OpenSolaris.
|
||||
- fixed: files downloaded with disabled decoder (option decode=no) sometimes
|
||||
were malformed and could not be decoded;
|
||||
- fixed: empty string parameters did not always work in XML-RPC.
|
||||
|
||||
nzbget-0.5.1:
|
||||
- improved the check of server responses to prevent unnecessary retrying
|
||||
if the article does not exist on server;
|
||||
- fixed: seg.fault in standalone mode if used without specifying the
|
||||
category (e.g. without switch <-K>);
|
||||
- fixed: download speed indicator could report not-null values in
|
||||
standby-mode (when paused);
|
||||
- fixed: parameter <category> in JSON/XML-RPC was not properly decoded by
|
||||
server, makin
|
||||
402
tests/testdata/parchecker2/testfile.7z.003
vendored
Normal file
402
tests/testdata/parchecker2/testfile.7z.003
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
g the setting of a nested category (containing slash or
|
||||
backslash character) via nzbgetweb not possible;
|
||||
|
||||
nzbget-0.5.0:
|
||||
- added TLS/SSL-support for encrypted communication with news-servers;
|
||||
- added IPv6-support for communication with news-servers as well as for
|
||||
communication between nzbget-server and nzbget-client;
|
||||
- added support for categories to organize downloaded files;
|
||||
- new option <AppendCategoryDir> to create the subdirectory for each category;
|
||||
- new switch <-K> for usage with switch <-A> to define a category during
|
||||
the adding a file to download queue;
|
||||
- new command <K> in switch <-E> to change the category of nzb-file in
|
||||
download queue; the already downloaded files are automatically moved to new
|
||||
directory if the option <AppendCategoryDir> is active;
|
||||
- new parameter <Category> in XML-/JSON-RPC-command <editqueue> to allow the
|
||||
changing of category via those protocols;
|
||||
- new parameter in a call to post-process-script with category name;
|
||||
- scanning of subdirectories inside incoming nzb-directory to automatically
|
||||
assign category names; nested categories are supported;
|
||||
- added option <ServerX.JoinGroup> to connect to servers, that do not accept
|
||||
<GROUP>-command;
|
||||
- added example post-process script for unraring of downloaded files
|
||||
(POSIX only);
|
||||
- added options <ParPauseQueue> and <PostPauseQueue> useful on slow CPUs;
|
||||
- added option <NzbCleanupDisk> to delete source nzb-file after successful
|
||||
download and parcheck;
|
||||
- switch <-P> can now be used together with switches <-s> and <-D> to start
|
||||
server/daemon in paused state;
|
||||
- changed the type of messages logged in a case of connection errors from
|
||||
<DEBUG> to <ERROR> to provide better error reporting;
|
||||
- now using OS-specific line-endings in log-file and brokenlog-file: LF on
|
||||
Posix and CRLF on Windows;
|
||||
- added detection of adjusting of system clock to correct uptime/download
|
||||
time (for NAS-devices, that do not have internal clock and set time from
|
||||
internet after booting, while nzbget may be already running);
|
||||
- added the printing of stack on segmentation faults (if configured with
|
||||
<--enable-debug>, POSIX only);
|
||||
- added option <DumpCore> for better debugging on Linux in a case of abnormal
|
||||
program termination;
|
||||
- fixed: configure-script could not automatically find libsigc++ on 64-bit
|
||||
systems;
|
||||
- few other small fixes;
|
||||
|
||||
nzbget-0.4.1:
|
||||
- to avoid accidental deletion of file in curses-frontend the key <D>
|
||||
now must be pressed in uppercase;
|
||||
- options <username> and <password> in news-server's configuration are now
|
||||
optional;
|
||||
- added the server's name to the detail-log-message, displayed on the start
|
||||
of article's download;
|
||||
- added the option <AllowReProcess> to help to post-process-scripts, which
|
||||
make par-check/-repair on it's own;
|
||||
- improved download-speed-meter: it uses now a little bit less cpu and
|
||||
calculates the speed for the last 30 seconds (instead of 5 seconds),
|
||||
providing better accuracy; Thanks to ydrol <ydrol@users.sourceforge.net>
|
||||
for the patch;
|
||||
- reduced CPU-usage in curses-outputmode; Thanks to ydrol for the patch
|
||||
<ydrol@users.sourceforge.net>;
|
||||
- fixed: line-endings in windows-style (CR-LF) in config-file were not
|
||||
read properly;
|
||||
- fixed: trailing spaces in nzb-filenames (before the file's extension)
|
||||
caused errors on windows. Now they will be trimmed;
|
||||
- fixed: XML-RPC and JSON-RPC did not work on Big-Endian-CPUs (ARM, PPC, etc),
|
||||
preventing the using of web-interface;
|
||||
- fixed: umask-option did not allow to enable write-permissions for <group>
|
||||
and <others>;
|
||||
- fixed: in curses-outputmode the remote-client showed on first screen-update
|
||||
only one item of queue;
|
||||
- fixed: edit-commands with negative offset did not work via XML-RPC
|
||||
(but worked via JSON-RPC);
|
||||
- fixed incompatibility issues with gcc 4.3; Thanks to Paul Bredbury
|
||||
<brebs@users.sourceforge.net> for the patch;
|
||||
- fixed: segmentation fault if a file listed in nzb-file does not have any
|
||||
segments (articles);
|
||||
|
||||
nzbget-0.4.0:
|
||||
- added the support for XML-RPC and JSON-RPC to easier control the server
|
||||
from other applications;
|
||||
- added web-interface - it is available for download from nzbget-project's
|
||||
home page as a separate package "web-interface";
|
||||
- added the automatic cleaning up of the download queue (deletion of unneeded
|
||||
paused par-files) after successful par-check/repair - new
|
||||
option <ParCleanupQueue>;
|
||||
- added option <DetailTarget> to allow to filter the (not so important)
|
||||
log-messages from articles' downloads (they have now the type <detail>
|
||||
instead of <info>);
|
||||
- added the gathering of progress-information during par-check; it is
|
||||
available via XML-RPC or JSON-RPC; it is also showed in web-interface;
|
||||
- improvements in internal decoder: added support for yEnc-files without
|
||||
ypart-statement (sometimes used for small files); added support for
|
||||
UU-format;
|
||||
- removed support for uulib-decoder (it did not work well anyway);
|
||||
- replaced the option <decoder (yenc, uulib, none)> with the option
|
||||
<decode (yes, no)>;
|
||||
- added detection of errors <server busy> and <remote server not available>
|
||||
(special case for NNTPCache-server) to consider them as connect-errors
|
||||
(and therefore not count as retries);
|
||||
- added check for incomplete articles (also mostly for NNTPCache-server) to
|
||||
differ such errors from CrcErrors (better error reporting);
|
||||
- improved error-reporting on moving of completed files from tmp- to
|
||||
dst-directory and added code to move files across drives if renaming fails;
|
||||
- improved handling of nzb-files with multiple collections in par-checker;
|
||||
- improved the parchecker: added the detection and processing of files
|
||||
splitted after parring;
|
||||
- added the queueing of post-process-scripts and waiting for script's
|
||||
completion before starting of a next job in postprocessor (par-job or
|
||||
script) to provide more balanced cpu utilization;
|
||||
- added the redirecting of post-process-script's output to log; new option
|
||||
<PostLogKind> to specify the default message-kind for unformatted
|
||||
log-messages;
|
||||
- added the returning of script-output by command <postqueue> via XML-RPC
|
||||
and JSON-RPC; the script-output is also showed in web-interface;
|
||||
- added the saving and restoring of the post-processor-queue (if server was
|
||||
stopped before all items were processed); new option <ReloadPostQueue>;
|
||||
- added new parameter to postprocess-script to indicate if any of par-jobs
|
||||
for the same nzb-file failed;
|
||||
- added remote command (switch O/--post) to request the post-processor-queue
|
||||
from server;
|
||||
- added remote command (switch -W/--write) to write messages to server's log;
|
||||
- added option <DiskSpace> to automatically pause the download on low disk
|
||||
space;
|
||||
- fixed few incompatibility-issues with unslung-platform on nslu2 (ARM);
|
||||
- fixed: articles with trailing text after binary data caused the decode
|
||||
failures and the reporting of CRC-errors;
|
||||
- fixed: dupecheck could cause seg.faults when all articles for a file failed;
|
||||
- fixed: by dupe-checking of files contained in nzb-file the files with the
|
||||
same size were ignored (not deleted from queue);
|
||||
- updated libpar2-patch for msvc to fix a segfault in libpar2 (windows only);
|
||||
- fixed: by registering the service on windows the fullpath to nzbget.exe
|
||||
was not always added to service's exename, making the registered service
|
||||
unusable;
|
||||
- fixed: the pausing of a group could cause the start of post-processing for
|
||||
that group;
|
||||
- fixed: too many info-messages <Need more N blocks> could be printed during
|
||||
par-check (appeared on posix only);
|
||||
|
||||
nzbget-0.3.1:
|
||||
- Greatly reduced the memory consumption by keeping articles' info on disk
|
||||
until the file download starts;
|
||||
- Implemented decode-on-the-fly-technique to reduce disk-io; downloaded
|
||||
and decoded data can also be saved directly to the destination file
|
||||
(without any intermediate files at all); this eliminates the necessity
|
||||
of joining of articles later (option "DirectWrite");
|
||||
- Improved communication with news-servers: connections are now keeped open
|
||||
until all files are downloaded (or server paused); this eliminates the
|
||||
need for establishing of connections and authorizations for each
|
||||
article and improves overal download speed;
|
||||
- Significantly better download speed is now possible on fast connection;
|
||||
it was limited by delays on starting of new articles' downloads;
|
||||
the synchronisation mechanism was reworked to fix this issue;
|
||||
- Download speed meter is much more accurate, especially on fast connections;
|
||||
this also means better speed throttling;
|
||||
- Speed optimisations in internal decoder (up to 25% faster);
|
||||
- CRC-calculation can be bypassed to increase performance on slow CPUs
|
||||
(option "CrcCheck");
|
||||
- Improved parsing of artcile's subject for better extracting of filename
|
||||
part from it and implemented a fallback-option if the parsing was incorrect;
|
||||
- Improved dupe check for files from the same nzb-request to detect reposted
|
||||
files and download only the best from them (if option "DupeCheck" is on);
|
||||
- Articles with incorrect CRC can be treated as "possibly recoverable errors"
|
||||
and relaunched for download (option "RetryOnCrcError"), it is useful if
|
||||
multiple servers are available;
|
||||
- Improved error-check for downloaded articles (crc-check and check for
|
||||
received message-id) decreases the number of broken files;
|
||||
- Extensions in curses-outputmode: added group-view-mode (key "G") to show
|
||||
items in download queue as groups, where one group represents all files
|
||||
from the same nzb-file; the editing of queue works also in group-mode
|
||||
(for all files in this group): pause/unpause/delete/move of groups;
|
||||
- Other extensions in curses-outputmode: key "T" toggles timestamps in log;
|
||||
added output of statistical data: uptime, download-time, average session
|
||||
download speed;
|
||||
- Edit-command accepts more than one ID or range of IDs.
|
||||
E.g: "nzbget -E P 2,6-10,33-39"; The switch "-I" is not used anymore;
|
||||
- Move-actions in Edit-command affect files in a smart order to guarantee
|
||||
that the relative order of files in queue is not changed after the moving;
|
||||
- Extended syntax of edit-command to edit groups (pause/unpause/delete/move
|
||||
of groups). E.g: "nzbget -E G P 2";
|
||||
- Added option "DaemonUserName" to set the user that the daemon (POSIX only)
|
||||
normally runs at. This allows nzbget daemon to be launched in rc.local
|
||||
(at boot), and download items as a specific user id; Thanks to Thierry
|
||||
MERLE <merlum@users.sourceforge.net> for the patch;
|
||||
- Added option "UMask" to specify permissions for newly created files and dirs
|
||||
(POSIX only);
|
||||
- Communication protocol used between server and client was revised to define
|
||||
the byte order for transferred data. This allows hosts with different
|
||||
endianness to communicate with each other;
|
||||
- Added options "CursesNzbName", "CursesGroup" and "CursesTime" to define
|
||||
initial state of curses-outputmode;
|
||||
- Added option "UpdateInterval" to adjust update interval for Frontend-output
|
||||
(useful in remote-mode to reduce network usage);
|
||||
- Added option "WriteBufferSize" to reduce disk-io (but it could slightly
|
||||
increase memory usage and therefore disabled by default);
|
||||
- List-command prints additional statistical info: uptime, download-time,
|
||||
total amount of downloaded data and average session download speed;
|
||||
- The creation of necessary directories on program's start was extended
|
||||
with automatic creation of all parent directories or error reporting
|
||||
if it was not possible;
|
||||
- Printed messages are now translated to oem-codepage to correctly print
|
||||
filenames with non-english characters (windows only);
|
||||
- Added remote-command "-V (--serverversion)" to print the server's version;
|
||||
- Added option "ThreadLimit" to prevent program from crash if it wants to
|
||||
create too many threads (sometimes could occur in special cases);
|
||||
- Added options "NzbDirInterval" and "NzbDirFileAge" to adjust interval and
|
||||
delay by monitoring of incoming-directory for new nzb-files;
|
||||
- Fixed error on parsing of nzb-files containing percent and other special
|
||||
characters in their names (bug appeared on windows only);
|
||||
- Reformated sample configuration file and changed default optionnames
|
||||
from lowercase to MixedCase for better readability;
|
||||
- Few bugs (seg faults) were fixed.
|
||||
|
||||
nzbget-0.3.0:
|
||||
- The download queue now contains newsgroup-files to be downloaded instead of
|
||||
nzb-jobs. By adding a new job, the nzb-file is immediately parsed and each
|
||||
newsgroup-file is added to download queue. Each file can therefore be
|
||||
managed separately (paused, deleted or moved);
|
||||
- Current queue state is saved after every change (file is completed or the
|
||||
queue is changed - entries paused, deleted or moved). The state is saved on
|
||||
disk using internal format, which allows fast loading on next program start
|
||||
(no need to parse xml-files again);
|
||||
- The remaining download-size is updated after every article is completed to
|
||||
indicate the correct remaining size and time for total files in queue;
|
||||
- Downloaded articles, which are saved in temp-directory, can be reused on
|
||||
next program start, if the file was not completed (option "continuepartial"
|
||||
in config-file);
|
||||
- Along with uulib the program has internal decoder for yEnc-format. This
|
||||
decoder was necessary, because uulib is so slow, that it prevents using of
|
||||
the program on not so powerful systems like linux-routers (MIPSEL CPU 200
|
||||
MHz). The new decoder is very fast. It is controlled over option "decoder"
|
||||
in config-file;
|
||||
- The decoder can be completely disabled. In this case all downloaded articles
|
||||
are saved in unaltered form and can be joined with an external program;
|
||||
UUDeview is one of them;
|
||||
- If download of article fails, the program attempts to download it again so
|
||||
many times, what the option "retries" in config-file says. This works even
|
||||
if no servers with level higher than "0" defined. After each retry the next
|
||||
server-level is used, if there are no more levels, the program switches to
|
||||
level "0" again. The pause between retries can be set with config-option
|
||||
"retryinterval";
|
||||
- If despite of a stated connection-timeout (it can be changed via
|
||||
config-option "connectiontimeout") connection hangs, the program tries to
|
||||
cancel the connection (after "terminatetimeout" seconds). If it doesn't
|
||||
work the download thread is killed and the article will be redownloaded in
|
||||
a new thread. This ensures, that there are no long-time hanging connections
|
||||
and all articles are downloaded, when a time to rejoin file comes;
|
||||
- Automatic par-checking and repairing. Only reuired par-files are downloaded.
|
||||
The program uses libpar2 and does not require any external tools. The big
|
||||
advantage of library is, that it allows to continue par-check after new
|
||||
par-blocks were downloaded. This were not possible with external
|
||||
par2cmdline-tool;
|
||||
- There is a daemon-mode now (command-line switch "-D" (--daemon)). In this
|
||||
mode a lock-file (default location "/tmp/nzbget.lock", can be changed via
|
||||
option "lockfile") contains PID of daemon;
|
||||
- The format of configuration-file was changed from xml to more common
|
||||
text-format. It allows also using of variables like
|
||||
"tempdir=${MAINDIR}/tmp";
|
||||
- Any option of config-file can be overwritten via command-line switch
|
||||
"-o" (--option). This includes also the definition of servers.
|
||||
This means that the program can now be started without a configuration-file
|
||||
at all (all required options must be passed via command-line);
|
||||
- The command-line switches were revised. The dedicated switches to change
|
||||
options in config-file were eliminated, since any option can now be changed
|
||||
via switch "-o" (--option);
|
||||
- If the name of configuration-file was not passed via command-line the
|
||||
program search it in following locations: "~/.nzbget", "/etc/nzbget.conf",
|
||||
"/usr/etc/nzbget.conf", "/usr/local/etc/nzbget.conf",
|
||||
"/opt/etc/nzbget.conf";
|
||||
- The new command-line switch "-n" (--noconfigfile) prevents the loading of
|
||||
a config-file. All required config-options must be passed via command-line
|
||||
(switch "-o" (--option));
|
||||
- To start the program in server mode either "-s" (--server) or
|
||||
"-D" (--daemon) switch must be used. If the program started without any
|
||||
parameters it prints help-screen. There is no a dedicated switch to start
|
||||
in a standalone mode. If switches "-s" and "-D" are omitted and none of
|
||||
client-request-switches used the standalone mode is default. This usage
|
||||
of switches is more common to programs like "wget". To add a file to
|
||||
server's download queue use switch "-A" (--append) and a name of nzb-file
|
||||
as last command-line parameter;
|
||||
- There is a new switch "-Q" (--quit) to gracefully stop server. BTW the
|
||||
SIGKIL-signal is now handled appropriately, so "killall nzbget" is also OK,
|
||||
where "killall -9 nzbget" terminates server immediately (helpful if it
|
||||
hangs, but it shouldn't);
|
||||
- With new switch "-T" (--top) the file will be added to the top of download
|
||||
queue. Use it with switch "-A" (--append);
|
||||
- The download queue can be edited via switch "-E" (--edit). It is possible
|
||||
to pause, unpause, delete and move files in queue. The IDs of file(s)
|
||||
to be affected are passed via switch "-I" (fileid), either one ID or a
|
||||
range in a form "IDForm-IDTo". This also means, that every file in queue
|
||||
have ID now;
|
||||
- The switch "-L" (--list) prints IDs of files consequently. It prints also
|
||||
name, size, percentage of completing and state (paused or not) of each file.
|
||||
Plus summary info: number of files, total remaining size and size of
|
||||
paused files, server state (paused or running), number of threads on
|
||||
server, current speed limit;
|
||||
- With new switch "-G" (--log) the last N lines printed to server's
|
||||
screen-log, can be printed on client. The max number of lines which can
|
||||
be returned from servers depends on option "logbuffersize";
|
||||
- The redesigned Frontends (known as outputmodes "loggable", "colored" and
|
||||
"curses") can connect to (remote) server and behave as if you were running
|
||||
server-instance of program itself (command-line switch "-C" (--connect)).
|
||||
The log-output updates constantly and even all control-functions in
|
||||
ncurses-mode works: pause/unpause server, set download rate limit, edit of
|
||||
queue (pause/unpause, delete, move entries). The number of connected
|
||||
clients is not limited. The "outputmode" on a client can be set
|
||||
independently from server. The client-mode is especially useful if the
|
||||
server runs as a daemon;
|
||||
- The writing to log-file can be disabled via option "createlog".
|
||||
The location of log-file controls the option "log-file";
|
||||
- Switch "-p" (--printconfig) prints the name of configuration file being
|
||||
used and all option/value-pairs, taking into account all used
|
||||
"-o" (--option) - switches;
|
||||
- The communication protocol between server and client was optimized to
|
||||
minimize the size of transferred data. Instead of fixing the size for
|
||||
Filenames in data-structures to 512 bytes only in fact used data
|
||||
are transferred;
|
||||
- Extensions in ncurses-outputmode: scrolling in queue-list works better,
|
||||
navigation in queue with keys Up, Down, PgUp, PgDn, Home, End.
|
||||
Keys to move entries are "U" (move up), "N" (move down), "T" (move to top),
|
||||
"B" (move to bottom). "P" to pause/unpause file. The size, percentage
|
||||
of completing and state (paused or not) for every file is printed.
|
||||
The header of queue shows number of total files, number of unpaused
|
||||
files and size for all and unpaused files. Better using of screen estate
|
||||
space - no more empty lines and separate header for status (total seven
|
||||
lines gain). The messages are printed on several lines (if they not fill
|
||||
in one line) without trimming now;
|
||||
- configure.ac-file updated to work with recent versions of autoconf/automake.
|
||||
There are new configure-options now: "--disable-uulib" to compile the
|
||||
program without uulib; "--disable-ncurses" to disable ncurses-support
|
||||
(eliminates necessity of ncurses-libs), useful on embedded systems with
|
||||
little resources; "--disable-parcheck" to compile without par-check;
|
||||
- The algorithm for parsing of nzb-files now uses XMLReader instead of
|
||||
DOM-Parser to minimize memory usage (no mor needs to build complete DOM-tree
|
||||
in memory). Thanks to Thierry MERLE <merlum@users.sourceforge.net> for
|
||||
the patch;
|
||||
- The log-file contains now thread-ID for all entry-types and additionally
|
||||
for debug-entries: filename, line number and function's name of source
|
||||
code, where the message was printed. Debug-messages can be disabled in
|
||||
config-file (option "debugtarget") like other messages;
|
||||
- The program is now compatible with windows. Project file for MS Visual
|
||||
C++ 2005 is included. Use "nzbget -install" and "nzbget -remove" to
|
||||
install/remove nzbget-Service. Servers and clients can run on diferrent
|
||||
operating systems;
|
||||
- Improved compatibility with POSIX systems; Tested on:
|
||||
- Linux Debian 3.1 on x86;
|
||||
- Linux BusyBox with uClibc on MIPSEL;
|
||||
- PC-BSD 1.4 (based on FreeBSD 6.2) on x86;
|
||||
- Solaris 10 on x86;
|
||||
- Many memory-leaks and thread issues were fixed;
|
||||
- The program was thoroughly worked over. Almost every line of code was
|
||||
revised.
|
||||
|
||||
nzbget-0.2.3
|
||||
- Fixed problem with losing connection to newsserver after too long idle time
|
||||
- Added functionality for dumping lots of debug info
|
||||
|
||||
nzbget-0.2.2
|
||||
- Added Florian Penzkofers fix for FreeBSD, exchanging base functionality in
|
||||
SingleServerPool.cpp with a more elegant solution
|
||||
- Added functionality for forcing answer to reloading queue upon startup of
|
||||
server
|
||||
+ use -y option to force from command-line
|
||||
+ use "reloadqueue" option in nzbget.cfg to control behavior
|
||||
- Added nzbget.cfg options to control where info, warnings and errors get
|
||||
directed to (either screen, log or both)
|
||||
- Added option "createbrokenfilelog" in nzbget.cfg
|
||||
|
||||
nzbget-0.2.1
|
||||
- Changed and extendddddddddddddddddd/server interface
|
||||
- Added timeout on sockets which prevents certain types of nzbget hanging
|
||||
- Added Kristian Hermansen's patch for renaming broken files
|
||||
|
||||
nzbget-0.2.0
|
||||
- Moved 0.1.2-alt4 to a official release as 0.2.0
|
||||
- Small fixes
|
||||
|
||||
nzbget-0.1.2-alt4
|
||||
- implemented tcp/ip communication between client & server (removing the
|
||||
rather defunct System V IPC)
|
||||
- added queue editing functionality in server-mode
|
||||
|
||||
nzbget-0.1.2-alt1
|
||||
- added new ncurses frontend
|
||||
- added server/client-mode (using System V IPC)
|
||||
- added functionality for queueing download requests
|
||||
|
||||
nzbget-0.1.2
|
||||
- performance-improvements
|
||||
- commandline-options
|
||||
- fixes
|
||||
|
||||
nzbget-0.1.1
|
||||
- new output
|
||||
- fixes
|
||||
|
||||
nzbget-0.1.0a
|
||||
- compiling-fixes
|
||||
|
||||
nzbget-0.1.0
|
||||
- initial release
|
||||
| ||||