New upstream version 21.0~r2220+dfsg
Andreas Moog
5 years ago
0 | nzbget-21.0: | |
1 | - please see repository change log at | |
2 | https://github.com/nzbget/nzbget/commits/develop | |
3 | ||
0 | 4 | nzbget-20.0: |
1 | 5 | - massive performance optimisations in downloader: |
2 | 6 | - improved yEnc decoder; |
344 | 344 | linux/build-info.txt \ |
345 | 345 | linux/build-nzbget \ |
346 | 346 | linux/build-unpack \ |
347 | linux/build-toolchain-android \ | |
347 | 348 | linux/build-toolchain-freebsd |
348 | 349 | |
349 | 350 | doc_FILES = \ |
412 | 413 | tests/testdata/parchecker/testfile.vol00+1.PAR2 \ |
413 | 414 | tests/testdata/parchecker/testfile.vol01+2.PAR2 \ |
414 | 415 | tests/testdata/parchecker/testfile.vol03+3.PAR2 \ |
416 | tests/testdata/parchecker2/crc.txt \ | |
417 | tests/testdata/parchecker2/testfile.7z.001 \ | |
418 | tests/testdata/parchecker2/testfile.7z.002 \ | |
419 | tests/testdata/parchecker2/testfile.7z.003 \ | |
420 | tests/testdata/parchecker2/testfile.7z.par2 \ | |
421 | tests/testdata/parchecker2/testfile.7z.vol0+1.PAR2 \ | |
422 | tests/testdata/parchecker2/testfile.7z.vol1+2.PAR2 \ | |
423 | tests/testdata/parchecker2/testfile.7z.vol3+3.PAR2 \ | |
415 | 424 | tests/testdata/rarrenamer/testfile3.part01.rar \ |
416 | 425 | tests/testdata/rarrenamer/testfile3.part02.rar \ |
417 | 426 | tests/testdata/rarrenamer/testfile3.part03.rar \ |
858 | 858 | linux/build-info.txt \ |
859 | 859 | linux/build-nzbget \ |
860 | 860 | linux/build-unpack \ |
861 | linux/build-toolchain-android \ | |
861 | 862 | linux/build-toolchain-freebsd |
862 | 863 | |
863 | 864 | doc_FILES = \ |
926 | 927 | tests/testdata/parchecker/testfile.vol00+1.PAR2 \ |
927 | 928 | tests/testdata/parchecker/testfile.vol01+2.PAR2 \ |
928 | 929 | tests/testdata/parchecker/testfile.vol03+3.PAR2 \ |
930 | tests/testdata/parchecker2/crc.txt \ | |
931 | tests/testdata/parchecker2/testfile.7z.001 \ | |
932 | tests/testdata/parchecker2/testfile.7z.002 \ | |
933 | tests/testdata/parchecker2/testfile.7z.003 \ | |
934 | tests/testdata/parchecker2/testfile.7z.par2 \ | |
935 | tests/testdata/parchecker2/testfile.7z.vol0+1.PAR2 \ | |
936 | tests/testdata/parchecker2/testfile.7z.vol1+2.PAR2 \ | |
937 | tests/testdata/parchecker2/testfile.7z.vol3+3.PAR2 \ | |
929 | 938 | tests/testdata/rarrenamer/testfile3.part01.rar \ |
930 | 939 | tests/testdata/rarrenamer/testfile3.part02.rar \ |
931 | 940 | tests/testdata/rarrenamer/testfile3.part03.rar \ |
85 | 85 | /* Define to 1 to use GnuTLS library for TLS/SSL-support. */ |
86 | 86 | #undef HAVE_LIBGNUTLS |
87 | 87 | |
88 | /* Define to 1 if lockf is supported */ | |
89 | #undef HAVE_LOCKF | |
90 | ||
88 | 91 | /* Define to 1 if you have the <memory.h> header file. */ |
89 | 92 | #undef HAVE_MEMORY_H |
90 | 93 | |
99 | 102 | |
100 | 103 | /* Define to 1 to use OpenSSL library for TLS/SSL-support and decryption. */ |
101 | 104 | #undef HAVE_OPENSSL |
105 | ||
106 | /* Define to 1 if pthread_cancel is supported */ | |
107 | #undef HAVE_PTHREAD_CANCEL | |
102 | 108 | |
103 | 109 | /* Define to 1 if you have the <regex.h> header file. */ |
104 | 110 | #undef HAVE_REGEX_H |
0 | 0 | #! /bin/sh |
1 | 1 | # Guess values for system-dependent variables and create Makefiles. |
2 | # Generated by GNU Autoconf 2.69 for nzbget 20.0. | |
2 | # Generated by GNU Autoconf 2.69 for nzbget 21.0-testing. | |
3 | 3 | # |
4 | 4 | # Report bugs to <hugbug@users.sourceforge.net>. |
5 | 5 | # |
579 | 579 | # Identity of this package. |
580 | 580 | PACKAGE_NAME='nzbget' |
581 | 581 | PACKAGE_TARNAME='nzbget' |
582 | PACKAGE_VERSION='20.0' | |
583 | PACKAGE_STRING='nzbget 20.0' | |
582 | PACKAGE_VERSION='21.0-testing' | |
583 | PACKAGE_STRING='nzbget 21.0-testing' | |
584 | 584 | PACKAGE_BUGREPORT='hugbug@users.sourceforge.net' |
585 | 585 | PACKAGE_URL='' |
586 | 586 | |
1347 | 1347 | # Omit some internal or obsolete options to make the list less imposing. |
1348 | 1348 | # This message is too long to be a string in the A/UX 3.1 sh. |
1349 | 1349 | cat <<_ACEOF |
1350 | \`configure' configures nzbget 20.0 to adapt to many kinds of systems. | |
1350 | \`configure' configures nzbget 21.0-testing to adapt to many kinds of systems. | |
1351 | 1351 | |
1352 | 1352 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1353 | 1353 | |
1418 | 1418 | |
1419 | 1419 | if test -n "$ac_init_help"; then |
1420 | 1420 | case $ac_init_help in |
1421 | short | recursive ) echo "Configuration of nzbget 20.0:";; | |
1421 | short | recursive ) echo "Configuration of nzbget 21.0-testing:";; | |
1422 | 1422 | esac |
1423 | 1423 | cat <<\_ACEOF |
1424 | 1424 | |
1583 | 1583 | test -n "$ac_init_help" && exit $ac_status |
1584 | 1584 | if $ac_init_version; then |
1585 | 1585 | cat <<\_ACEOF |
1586 | nzbget configure 20.0 | |
1586 | nzbget configure 21.0-testing | |
1587 | 1587 | generated by GNU Autoconf 2.69 |
1588 | 1588 | |
1589 | 1589 | Copyright (C) 2012 Free Software Foundation, Inc. |
2052 | 2052 | This file contains any messages produced by compilers while |
2053 | 2053 | running configure, to aid debugging if configure makes a mistake. |
2054 | 2054 | |
2055 | It was created by nzbget $as_me 20.0, which was | |
2055 | It was created by nzbget $as_me 21.0-testing, which was | |
2056 | 2056 | generated by GNU Autoconf 2.69. Invocation command line was |
2057 | 2057 | |
2058 | 2058 | $ $0 $@ |
3025 | 3025 | |
3026 | 3026 | # Define the identity of the package. |
3027 | 3027 | PACKAGE='nzbget' |
3028 | VERSION='20.0' | |
3028 | VERSION='21.0-testing' | |
3029 | 3029 | |
3030 | 3030 | |
3031 | 3031 | cat >>confdefs.h <<_ACEOF |
6004 | 6004 | |
6005 | 6005 | |
6006 | 6006 | |
6007 | ac_fn_cxx_check_func "$LINENO" "lockf" "ac_cv_func_lockf" | |
6008 | if test "x$ac_cv_func_lockf" = xyes; then : | |
6009 | ac_fn_cxx_check_decl "$LINENO" "lockf" "ac_cv_have_decl_lockf" "#include <unistd.h> | |
6010 | " | |
6011 | if test "x$ac_cv_have_decl_lockf" = xyes; then : | |
6012 | ||
6013 | $as_echo "#define HAVE_LOCKF 1" >>confdefs.h | |
6014 | ||
6015 | fi | |
6016 | ||
6017 | fi | |
6018 | ||
6019 | ac_fn_cxx_check_func "$LINENO" "pthread_cancel" "ac_cv_func_pthread_cancel" | |
6020 | if test "x$ac_cv_func_pthread_cancel" = xyes; then : | |
6021 | ac_fn_cxx_check_decl "$LINENO" "pthread_cancel" "ac_cv_have_decl_pthread_cancel" "#include <pthread.h> | |
6022 | " | |
6023 | if test "x$ac_cv_have_decl_pthread_cancel" = xyes; then : | |
6024 | ||
6025 | $as_echo "#define HAVE_PTHREAD_CANCEL 1" >>confdefs.h | |
6026 | ||
6027 | fi | |
6028 | ||
6029 | fi | |
6030 | ||
6031 | ||
6032 | ||
6007 | 6033 | ac_fn_cxx_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long" |
6008 | 6034 | if test "x$ac_cv_func_getopt_long" = xyes; then : |
6009 | 6035 | |
9150 | 9176 | # report actual input values of CONFIG_FILES etc. instead of their |
9151 | 9177 | # values after options handling. |
9152 | 9178 | ac_log=" |
9153 | This file was extended by nzbget $as_me 20.0, which was | |
9179 | This file was extended by nzbget $as_me 21.0-testing, which was | |
9154 | 9180 | generated by GNU Autoconf 2.69. Invocation command line was |
9155 | 9181 | |
9156 | 9182 | CONFIG_FILES = $CONFIG_FILES |
9216 | 9242 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
9217 | 9243 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
9218 | 9244 | ac_cs_version="\\ |
9219 | nzbget config.status 20.0 | |
9245 | nzbget config.status 21.0-testing | |
9220 | 9246 | configured by $0, generated by GNU Autoconf 2.69, |
9221 | 9247 | with options \\"\$ac_cs_config\\" |
9222 | 9248 |
20 | 20 | # Process this file with autoconf to produce a configure script. |
21 | 21 | |
22 | 22 | AC_PREREQ(2.65) |
23 | AC_INIT(nzbget, 20.0, hugbug@users.sourceforge.net) | |
23 | AC_INIT(nzbget, 21.0-testing, hugbug@users.sourceforge.net) | |
24 | 24 | AC_CONFIG_AUX_DIR(posix) |
25 | 25 | AC_CANONICAL_TARGET |
26 | 26 | AM_INIT_AUTOMAKE([foreign subdir-objects]) |
74 | 74 | AC_SEARCH_LIBS([socket], [socket]) |
75 | 75 | AC_SEARCH_LIBS([inet_addr], [nsl]) |
76 | 76 | AC_SEARCH_LIBS([hstrerror], [resolv]) |
77 | ||
78 | ||
79 | dnl | |
80 | dnl Android NDK restrictions | |
81 | dnl | |
82 | AC_CHECK_FUNC(lockf, | |
83 | [AC_CHECK_DECL(lockf, | |
84 | [AC_DEFINE([HAVE_LOCKF], 1, [Define to 1 if lockf is supported])],, | |
85 | [#include <unistd.h>])]) | |
86 | AC_CHECK_FUNC(pthread_cancel, | |
87 | [AC_CHECK_DECL(pthread_cancel, | |
88 | [AC_DEFINE([HAVE_PTHREAD_CANCEL], 1, [Define to 1 if pthread_cancel is supported])],, | |
89 | [#include <pthread.h>])]) | |
77 | 90 | |
78 | 91 | |
79 | 92 | dnl |
30 | 30 | #endif |
31 | 31 | #endif |
32 | 32 | |
33 | class ConnectionFinalizer | |
34 | { | |
35 | public: | |
36 | ~ConnectionFinalizer() | |
37 | { | |
38 | Connection::Final(); | |
39 | } | |
40 | }; | |
41 | ||
42 | std::unique_ptr<ConnectionFinalizer> m_connectionFinalizer; | |
33 | #if defined(__linux__) && !defined(__ANDROID__) | |
34 | // Activate DNS resolving workaround for Android: | |
35 | // - this is only necessary in general Linux build if we want it to run on Android. | |
36 | // - the workaround isn't needed when targeting specifically Android using Android NDK. | |
37 | #define ANDROID_RESOLVE | |
38 | #endif | |
43 | 39 | |
44 | 40 | void closesocket_gracefully(SOCKET socket) |
45 | 41 | { |
79 | 75 | closesocket(socket); |
80 | 76 | } |
81 | 77 | |
82 | #ifdef __linux__ | |
78 | #ifdef ANDROID_RESOLVE | |
83 | 79 | CString ResolveAndroidHost(const char* host); |
84 | 80 | #endif |
85 | 81 | |
108 | 104 | m_getHostByNameMutex = std::make_unique<Mutex>(); |
109 | 105 | #endif |
110 | 106 | #endif |
111 | ||
112 | m_connectionFinalizer = std::make_unique<ConnectionFinalizer>(); | |
113 | 107 | } |
114 | 108 | |
115 | 109 | void Connection::Final() |
599 | 593 | int res = getaddrinfo(m_host, portStr, &addr_hints, &addr_list); |
600 | 594 | debug("getaddrinfo for %s: %i", *m_host, res); |
601 | 595 | |
602 | #ifdef __linux__ | |
596 | #ifdef ANDROID_RESOLVE | |
603 | 597 | if (res != 0) |
604 | 598 | { |
605 | 599 | CString resolvedHost = ResolveAndroidHost(m_host); |
1145 | 1139 | } |
1146 | 1140 | |
1147 | 1141 | |
1148 | #ifdef __linux__ | |
1142 | #ifdef ANDROID_RESOLVE | |
1149 | 1143 | |
1150 | 1144 | //****************************************************************************** |
1151 | 1145 | // Android resolver proxy from AOSP (reworked): |
55 | 55 | Connection(SOCKET socket, bool tls); |
56 | 56 | virtual ~Connection(); |
57 | 57 | static void Init(); |
58 | static void Final(); | |
58 | 59 | virtual bool Connect(); |
59 | 60 | virtual bool Disconnect(); |
60 | 61 | bool Bind(); |
149 | 150 | int send(SOCKET s, const char* buf, int len, int flags); |
150 | 151 | void CloseTls(); |
151 | 152 | #endif |
152 | ||
153 | private: | |
154 | static void Final(); | |
155 | friend class ConnectionFinalizer; | |
156 | 153 | }; |
157 | 154 | |
158 | 155 | #endif |
27 | 27 | #include "Util.h" |
28 | 28 | #include "FileSystem.h" |
29 | 29 | |
30 | class TlsSocketFinalizer | |
31 | { | |
32 | public: | |
33 | ~TlsSocketFinalizer() | |
34 | { | |
35 | TlsSocket::Final(); | |
36 | } | |
37 | }; | |
38 | ||
39 | std::unique_ptr<TlsSocketFinalizer> m_tlsSocketFinalizer; | |
40 | 30 | CString TlsSocket::m_certStore; |
41 | 31 | |
42 | 32 | #ifdef HAVE_LIBGNUTLS |
188 | 178 | OpenSSL_add_all_algorithms(); |
189 | 179 | |
190 | 180 | #endif /* HAVE_OPENSSL */ |
191 | ||
192 | m_tlsSocketFinalizer = std::make_unique<TlsSocketFinalizer>(); | |
193 | 181 | } |
194 | 182 | |
195 | 183 | void TlsSocket::Final() |
33 | 33 | virtual ~TlsSocket(); |
34 | 34 | static void Init(); |
35 | 35 | static void InitOptions(const char* certStore) { m_certStore = certStore; } |
36 | static void Final(); | |
36 | 37 | bool Start(); |
37 | 38 | void Close(); |
38 | 39 | int Send(const char* buffer, int size); |
61 | 62 | |
62 | 63 | void ReportError(const char* errMsg, bool suppressable = true); |
63 | 64 | bool ValidateCert(); |
64 | ||
65 | static void Final(); | |
66 | friend class TlsSocketFinalizer; | |
67 | 65 | }; |
68 | 66 | |
69 | 67 | #endif |
28 | 28 | #include "FeedScript.h" |
29 | 29 | #include "DiskState.h" |
30 | 30 | #include "DupeCoordinator.h" |
31 | #include "UrlCoordinator.h" | |
31 | 32 | |
32 | 33 | std::unique_ptr<RegEx>& FeedCoordinator::FilterHelper::GetRegEx(int id) |
33 | 34 | { |
307 | 308 | m_save = true; |
308 | 309 | } |
309 | 310 | |
310 | GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); | |
311 | 311 | for (std::unique_ptr<NzbInfo>& nzbInfo : addedNzbs) |
312 | 312 | { |
313 | downloadQueue->GetQueue()->Add(std::move(nzbInfo)); | |
314 | } | |
315 | downloadQueue->Save(); | |
313 | g_UrlCoordinator->AddUrlToQueue(std::move(nzbInfo), false); | |
314 | } | |
316 | 315 | } |
317 | 316 | feedInfo->SetStatus(FeedInfo::fsFinished); |
318 | 317 | } |
454 | 453 | nzbInfo->SetDupeKey(feedItemInfo.GetDupeKey()); |
455 | 454 | nzbInfo->SetDupeScore(feedItemInfo.GetDupeScore()); |
456 | 455 | nzbInfo->SetDupeMode(feedItemInfo.GetDupeMode()); |
456 | nzbInfo->SetSize(feedItemInfo.GetSize()); | |
457 | nzbInfo->SetMinTime(feedItemInfo.GetTime()); | |
458 | nzbInfo->SetMaxTime(feedItemInfo.GetTime()); | |
457 | 459 | |
458 | 460 | return nzbInfo; |
459 | 461 | } |
224 | 224 | bool m_daemonized = false; |
225 | 225 | |
226 | 226 | void Init(); |
227 | void Final(); | |
227 | 228 | void BootConfig(); |
228 | 229 | void CreateGlobals(); |
229 | 230 | void Cleanup(); |
230 | 231 | void PrintOptions(); |
231 | bool ProcessDirect(); | |
232 | void ProcessDirect(); | |
232 | 233 | void ProcessClientRequest(); |
233 | 234 | void ProcessWebGet(); |
234 | 235 | void ProcessSigVerify(); |
317 | 318 | } |
318 | 319 | |
319 | 320 | InstallErrorHandler(); |
321 | } | |
322 | ||
323 | void NZBGet::Final() | |
324 | { | |
325 | if (!m_reloading) | |
326 | { | |
327 | #ifndef DISABLE_TLS | |
328 | TlsSocket::Final(); | |
329 | #endif | |
330 | Connection::Final(); | |
331 | } | |
320 | 332 | } |
321 | 333 | |
322 | 334 | void NZBGet::CreateGlobals() |
452 | 464 | #endif |
453 | 465 | } |
454 | 466 | |
455 | bool NZBGet::ProcessDirect() | |
467 | void NZBGet::ProcessDirect() | |
456 | 468 | { |
457 | 469 | #ifdef DEBUG |
458 | 470 | if (m_commandLineParser->GetTestBacktrace()) |
459 | 471 | { |
460 | TestSegFault(); | |
472 | TestSegFault(); // never returns | |
461 | 473 | } |
462 | 474 | #endif |
463 | 475 | |
464 | 476 | if (m_commandLineParser->GetWebGet()) |
465 | 477 | { |
466 | ProcessWebGet(); | |
467 | return true; | |
478 | ProcessWebGet(); // never returns | |
468 | 479 | } |
469 | 480 | |
470 | 481 | if (m_commandLineParser->GetSigVerify()) |
471 | 482 | { |
472 | ProcessSigVerify(); | |
473 | return true; | |
483 | ProcessSigVerify(); // never returns | |
474 | 484 | } |
475 | 485 | |
476 | 486 | // client request |
477 | 487 | if (m_commandLineParser->GetClientOperation() != CommandLineParser::opClientNoOperation) |
478 | 488 | { |
479 | ProcessClientRequest(); | |
480 | return true; | |
489 | ProcessClientRequest(); // never returns | |
481 | 490 | } |
482 | 491 | |
483 | 492 | if (m_commandLineParser->GetPrintOptions()) |
484 | 493 | { |
485 | PrintOptions(); | |
486 | return true; | |
487 | } | |
488 | ||
489 | return false; | |
494 | PrintOptions(); // never returns | |
495 | } | |
490 | 496 | } |
491 | 497 | |
492 | 498 | void NZBGet::StartRemoteServer() |
699 | 705 | |
700 | 706 | Init(); |
701 | 707 | |
702 | if (ProcessDirect()) | |
703 | { | |
704 | return; | |
705 | } | |
708 | ProcessDirect(); | |
706 | 709 | |
707 | 710 | StartRemoteServer(); |
708 | 711 | StartFrontend(); |
721 | 724 | |
722 | 725 | StopRemoteServer(); |
723 | 726 | StopFrontend(); |
727 | ||
728 | Final(); | |
724 | 729 | } |
725 | 730 | |
726 | 731 | void NZBGet::ProcessClientRequest() |
899 | 904 | { |
900 | 905 | printf("%s = \"%s\"\n", optEntry.GetName(), optEntry.GetValue()); |
901 | 906 | } |
907 | exit(0); | |
902 | 908 | } |
903 | 909 | |
904 | 910 | #ifndef WIN32 |
931 | 937 | error("Starting daemon failed: could not create lock-file %s", m_options->GetLockFile()); |
932 | 938 | exit(1); |
933 | 939 | } |
940 | ||
941 | #ifdef HAVE_LOCKF | |
934 | 942 | if (lockf(lfp, F_TLOCK, 0) < 0) |
943 | #else | |
944 | if (flock(lfp, LOCK_EX) < 0) | |
945 | #endif | |
935 | 946 | { |
936 | 947 | error("Starting daemon failed: could not acquire lock on lock-file %s", m_options->GetLockFile()); |
937 | 948 | exit(1); |
168 | 168 | #include <sys/statvfs.h> |
169 | 169 | #include <sys/wait.h> |
170 | 170 | #include <sys/un.h> |
171 | #include <sys/file.h> | |
171 | 172 | #include <arpa/inet.h> |
172 | 173 | #include <netinet/in.h> |
173 | 174 | #include <stdint.h> |
0 | 0 | /* |
1 | 1 | * This file is part of nzbget. See <http://nzbget.net>. |
2 | 2 | * |
3 | * Copyright (C) 2007-2017 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
3 | * Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
4 | 4 | * |
5 | 5 | * This program is free software; you can redistribute it and/or modify |
6 | 6 | * it under the terms of the GNU General Public License as published by |
196 | 196 | } |
197 | 197 | |
198 | 198 | DownloadQueue::Aspect* queueAspect = (DownloadQueue::Aspect*)aspect; |
199 | if (queueAspect->action == DownloadQueue::eaNzbFound) | |
199 | if (queueAspect->action == DownloadQueue::eaNzbFound || | |
200 | queueAspect->action == DownloadQueue::eaUrlFound) | |
200 | 201 | { |
201 | 202 | NzbFound(queueAspect->downloadQueue, queueAspect->nzbInfo); |
202 | 203 | } |
203 | else if (queueAspect->action == DownloadQueue::eaNzbAdded) | |
204 | else if (queueAspect->action == DownloadQueue::eaNzbAdded || | |
205 | queueAspect->action == DownloadQueue::eaUrlAdded) | |
204 | 206 | { |
205 | 207 | NzbAdded(queueAspect->downloadQueue, queueAspect->nzbInfo); |
206 | 208 | } |
218 | 220 | queueAspect->nzbInfo->PrintMessage(Message::mkInfo, |
219 | 221 | "Collection %s deleted from queue", queueAspect->nzbInfo->GetName()); |
220 | 222 | NzbDeleted(queueAspect->downloadQueue, queueAspect->nzbInfo); |
223 | } | |
224 | else if (queueAspect->action == DownloadQueue::eaUrlDeleted) | |
225 | { | |
226 | NzbDeleted(queueAspect->downloadQueue, queueAspect->nzbInfo); | |
227 | } | |
228 | else if (queueAspect->action == DownloadQueue::eaUrlFailed) | |
229 | { | |
230 | NzbCompleted(queueAspect->downloadQueue, queueAspect->nzbInfo, true); | |
221 | 231 | } |
222 | 232 | else if ((queueAspect->action == DownloadQueue::eaFileCompleted || |
223 | 233 | queueAspect->action == DownloadQueue::eaFileDeleted)) |
370 | 380 | |
371 | 381 | void PrePostProcessor::NzbCompleted(DownloadQueue* downloadQueue, NzbInfo* nzbInfo, bool saveQueue) |
372 | 382 | { |
383 | bool downloadDupe = nzbInfo->GetDupeHint() == NzbInfo::dhRedownloadAuto; | |
373 | 384 | bool addToHistory = g_Options->GetKeepHistory() > 0 && !nzbInfo->GetAvoidHistory(); |
374 | 385 | if (addToHistory) |
375 | 386 | { |
383 | 394 | (nzbInfo->GetDeleteStatus() == NzbInfo::dsNone || |
384 | 395 | nzbInfo->GetDeleteStatus() == NzbInfo::dsHealth || |
385 | 396 | nzbInfo->GetDeleteStatus() == NzbInfo::dsBad || |
386 | nzbInfo->GetDeleteStatus() == NzbInfo::dsScan)) | |
397 | nzbInfo->GetDeleteStatus() == NzbInfo::dsScan || | |
398 | (nzbInfo->GetDeleteStatus() == NzbInfo::dsCopy && downloadDupe))) | |
387 | 399 | { |
388 | 400 | g_DupeCoordinator->NzbCompleted(downloadQueue, nzbInfo); |
389 | 401 | needSave = true; |
627 | 639 | |
628 | 640 | void PrePostProcessor::StartJob(DownloadQueue* downloadQueue, PostInfo* postInfo, bool allowPar) |
629 | 641 | { |
642 | NzbInfo* nzbInfo = postInfo->GetNzbInfo(); | |
643 | ||
630 | 644 | if (!postInfo->GetStartTime()) |
631 | 645 | { |
632 | 646 | postInfo->SetStartTime(Util::CurrentTime()); |
636 | 650 | postInfo->SetFileProgress(0); |
637 | 651 | postInfo->SetProgressLabel(""); |
638 | 652 | |
639 | if (postInfo->GetNzbInfo()->GetParRenameStatus() == NzbInfo::rsNone && | |
640 | postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone && | |
653 | if (nzbInfo->GetParRenameStatus() == NzbInfo::rsNone && | |
654 | nzbInfo->GetDeleteStatus() == NzbInfo::dsNone && | |
641 | 655 | g_Options->GetParRename()) |
642 | 656 | { |
643 | 657 | EnterStage(downloadQueue, postInfo, PostInfo::ptParRenaming); |
646 | 660 | } |
647 | 661 | |
648 | 662 | #ifndef DISABLE_PARCHECK |
649 | if (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psNone && | |
650 | postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone) | |
651 | { | |
652 | if (ParParser::FindMainPars(postInfo->GetNzbInfo()->GetDestDir(), nullptr)) | |
663 | if (nzbInfo->GetParStatus() == NzbInfo::psNone && | |
664 | nzbInfo->GetDeleteStatus() == NzbInfo::dsNone) | |
665 | { | |
666 | if (ParParser::FindMainPars(nzbInfo->GetDestDir(), nullptr)) | |
653 | 667 | { |
654 | 668 | if (!allowPar) |
655 | 669 | { |
663 | 677 | } |
664 | 678 | else |
665 | 679 | { |
666 | postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, | |
667 | "Nothing to par-check for %s", postInfo->GetNzbInfo()->GetName()); | |
668 | postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psSkipped); | |
680 | nzbInfo->PrintMessage(Message::mkInfo, | |
681 | "Nothing to par-check for %s", nzbInfo->GetName()); | |
682 | nzbInfo->SetParStatus(NzbInfo::psSkipped); | |
669 | 683 | } |
670 | 684 | return; |
671 | 685 | } |
672 | 686 | |
673 | if (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSkipped && | |
687 | if (nzbInfo->GetParStatus() == NzbInfo::psSkipped && | |
674 | 688 | ((g_Options->GetParScan() != Options::psDupe && |
675 | postInfo->GetNzbInfo()->CalcHealth() < postInfo->GetNzbInfo()->CalcCriticalHealth(false) && | |
676 | postInfo->GetNzbInfo()->CalcCriticalHealth(false) < 1000) || | |
677 | postInfo->GetNzbInfo()->CalcHealth() == 0) && | |
678 | ParParser::FindMainPars(postInfo->GetNzbInfo()->GetDestDir(), nullptr)) | |
679 | { | |
680 | if (postInfo->GetNzbInfo()->CalcHealth() == 0) | |
681 | { | |
682 | postInfo->GetNzbInfo()->PrintMessage(Message::mkWarning, | |
683 | "Skipping par-check for %s due to health 0%%", postInfo->GetNzbInfo()->GetName()); | |
689 | nzbInfo->CalcHealth() < nzbInfo->CalcCriticalHealth(false) && | |
690 | nzbInfo->CalcCriticalHealth(false) < 1000) || | |
691 | nzbInfo->CalcHealth() == 0) && | |
692 | ParParser::FindMainPars(nzbInfo->GetDestDir(), nullptr)) | |
693 | { | |
694 | if (nzbInfo->CalcHealth() == 0) | |
695 | { | |
696 | nzbInfo->PrintMessage(Message::mkWarning, | |
697 | "Skipping par-check for %s due to health 0%%", nzbInfo->GetName()); | |
684 | 698 | } |
685 | 699 | else |
686 | 700 | { |
687 | postInfo->GetNzbInfo()->PrintMessage(Message::mkWarning, | |
701 | nzbInfo->PrintMessage(Message::mkWarning, | |
688 | 702 | "Skipping par-check for %s due to health %.1f%% below critical %.1f%%", |
689 | postInfo->GetNzbInfo()->GetName(), | |
690 | postInfo->GetNzbInfo()->CalcHealth() / 10.0, postInfo->GetNzbInfo()->CalcCriticalHealth(false) / 10.0); | |
691 | } | |
692 | postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psFailure); | |
703 | nzbInfo->GetName(), | |
704 | nzbInfo->CalcHealth() / 10.0, nzbInfo->CalcCriticalHealth(false) / 10.0); | |
705 | } | |
706 | nzbInfo->SetParStatus(NzbInfo::psFailure); | |
693 | 707 | return; |
694 | 708 | } |
695 | 709 | |
696 | if (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSkipped && | |
697 | postInfo->GetNzbInfo()->GetFailedSize() - postInfo->GetNzbInfo()->GetParFailedSize() > 0 && | |
698 | ParParser::FindMainPars(postInfo->GetNzbInfo()->GetDestDir(), nullptr)) | |
699 | { | |
700 | postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, | |
710 | if (nzbInfo->GetParStatus() == NzbInfo::psSkipped && | |
711 | nzbInfo->GetFailedSize() - nzbInfo->GetParFailedSize() > 0 && | |
712 | ParParser::FindMainPars(nzbInfo->GetDestDir(), nullptr)) | |
713 | { | |
714 | nzbInfo->PrintMessage(Message::mkInfo, | |
701 | 715 | "Collection %s with health %.1f%% needs par-check", |
702 | postInfo->GetNzbInfo()->GetName(), postInfo->GetNzbInfo()->CalcHealth() / 10.0); | |
716 | nzbInfo->GetName(), nzbInfo->CalcHealth() / 10.0); | |
703 | 717 | postInfo->SetRequestParCheck(true); |
704 | 718 | return; |
705 | 719 | } |
706 | 720 | #endif |
707 | 721 | |
708 | NzbParameter* unpackParameter = postInfo->GetNzbInfo()->GetParameters()->Find("*Unpack:"); | |
722 | NzbParameter* unpackParameter = nzbInfo->GetParameters()->Find("*Unpack:"); | |
709 | 723 | bool wantUnpack = !(unpackParameter && !strcasecmp(unpackParameter->GetValue(), "no")); |
710 | bool unpack = wantUnpack && postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usNone && | |
711 | postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone; | |
712 | ||
713 | if (postInfo->GetNzbInfo()->GetRarRenameStatus() == NzbInfo::rsNone && | |
724 | bool unpack = wantUnpack && nzbInfo->GetUnpackStatus() == NzbInfo::usNone && | |
725 | nzbInfo->GetDeleteStatus() == NzbInfo::dsNone; | |
726 | ||
727 | if (nzbInfo->GetRarRenameStatus() == NzbInfo::rsNone && | |
714 | 728 | unpack && g_Options->GetRarRename()) |
715 | 729 | { |
716 | 730 | EnterStage(downloadQueue, postInfo, PostInfo::ptRarRenaming); |
718 | 732 | return; |
719 | 733 | } |
720 | 734 | |
721 | bool parFailed = postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psFailure || | |
722 | postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psRepairPossible || | |
723 | postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psManual; | |
735 | #ifndef DISABLE_PARCHECK | |
736 | if (nzbInfo->GetParStatus() == NzbInfo::psSkipped && | |
737 | nzbInfo->GetDeleteStatus() == NzbInfo::dsNone && | |
738 | g_Options->GetParCheck() == Options::pcAuto && | |
739 | !UnpackController::HasCompletedArchiveFiles(nzbInfo) && | |
740 | ParParser::FindMainPars(nzbInfo->GetDestDir(), nullptr)) | |
741 | { | |
742 | nzbInfo->PrintMessage(Message::mkInfo, | |
743 | "Requesting par-check for collection %s without archive files", | |
744 | nzbInfo->GetName()); | |
745 | postInfo->SetRequestParCheck(true); | |
746 | return; | |
747 | } | |
748 | #endif | |
749 | ||
750 | bool parFailed = nzbInfo->GetParStatus() == NzbInfo::psFailure || | |
751 | nzbInfo->GetParStatus() == NzbInfo::psRepairPossible || | |
752 | nzbInfo->GetParStatus() == NzbInfo::psManual; | |
724 | 753 | |
725 | 754 | bool cleanup = !unpack && wantUnpack && |
726 | postInfo->GetNzbInfo()->GetCleanupStatus() == NzbInfo::csNone && | |
755 | nzbInfo->GetCleanupStatus() == NzbInfo::csNone && | |
727 | 756 | !Util::EmptyStr(g_Options->GetExtCleanupDisk()) && |
728 | ((postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSuccess && | |
729 | postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usFailure && | |
730 | postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usSpace && | |
731 | postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usPassword) || | |
732 | (postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usSuccess && | |
733 | postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psFailure) || | |
734 | ((postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usNone || | |
735 | postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usSkipped) && | |
736 | (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psNone || | |
737 | postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSkipped) && | |
738 | postInfo->GetNzbInfo()->CalcHealth() == 1000)); | |
757 | ((nzbInfo->GetParStatus() == NzbInfo::psSuccess && | |
758 | nzbInfo->GetUnpackStatus() != NzbInfo::usFailure && | |
759 | nzbInfo->GetUnpackStatus() != NzbInfo::usSpace && | |
760 | nzbInfo->GetUnpackStatus() != NzbInfo::usPassword) || | |
761 | (nzbInfo->GetUnpackStatus() == NzbInfo::usSuccess && | |
762 | nzbInfo->GetParStatus() != NzbInfo::psFailure) || | |
763 | ((nzbInfo->GetUnpackStatus() == NzbInfo::usNone || | |
764 | nzbInfo->GetUnpackStatus() == NzbInfo::usSkipped) && | |
765 | (nzbInfo->GetParStatus() == NzbInfo::psNone || | |
766 | nzbInfo->GetParStatus() == NzbInfo::psSkipped) && | |
767 | nzbInfo->CalcHealth() == 1000)); | |
739 | 768 | |
740 | 769 | bool moveInter = !unpack && |
741 | postInfo->GetNzbInfo()->GetMoveStatus() == NzbInfo::msNone && | |
742 | postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usFailure && | |
743 | postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usSpace && | |
744 | postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usPassword && | |
745 | postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psFailure && | |
746 | postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psManual && | |
747 | postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone && | |
770 | nzbInfo->GetMoveStatus() == NzbInfo::msNone && | |
771 | nzbInfo->GetUnpackStatus() != NzbInfo::usFailure && | |
772 | nzbInfo->GetUnpackStatus() != NzbInfo::usSpace && | |
773 | nzbInfo->GetUnpackStatus() != NzbInfo::usPassword && | |
774 | nzbInfo->GetParStatus() != NzbInfo::psFailure && | |
775 | nzbInfo->GetParStatus() != NzbInfo::psManual && | |
776 | nzbInfo->GetDeleteStatus() == NzbInfo::dsNone && | |
777 | !(((nzbInfo->GetUnpackStatus() == NzbInfo::usNone || | |
778 | nzbInfo->GetUnpackStatus() == NzbInfo::usSkipped) && | |
779 | (nzbInfo->GetParStatus() == NzbInfo::psNone || | |
780 | nzbInfo->GetParStatus() == NzbInfo::psSkipped) && | |
781 | nzbInfo->CalcHealth() < 1000)) && | |
748 | 782 | !Util::EmptyStr(g_Options->GetInterDir()) && |
749 | !strncmp(postInfo->GetNzbInfo()->GetDestDir(), g_Options->GetInterDir(), strlen(g_Options->GetInterDir())) && | |
750 | postInfo->GetNzbInfo()->GetDestDir()[strlen(g_Options->GetInterDir())] == PATH_SEPARATOR; | |
783 | !strncmp(nzbInfo->GetDestDir(), g_Options->GetInterDir(), strlen(g_Options->GetInterDir())) && | |
784 | nzbInfo->GetDestDir()[strlen(g_Options->GetInterDir())] == PATH_SEPARATOR; | |
751 | 785 | |
752 | 786 | if (unpack && parFailed) |
753 | 787 | { |
754 | postInfo->GetNzbInfo()->PrintMessage(Message::mkWarning, | |
755 | "Skipping unpack for %s due to %s", postInfo->GetNzbInfo()->GetName(), | |
756 | postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psManual ? "required par-repair" : "par-failure"); | |
757 | postInfo->GetNzbInfo()->SetUnpackStatus(NzbInfo::usSkipped); | |
788 | nzbInfo->PrintMessage(Message::mkWarning, | |
789 | "Skipping unpack for %s due to %s", nzbInfo->GetName(), | |
790 | nzbInfo->GetParStatus() == NzbInfo::psManual ? "required par-repair" : "par-failure"); | |
791 | nzbInfo->SetUnpackStatus(NzbInfo::usSkipped); | |
758 | 792 | unpack = false; |
759 | 793 | } |
760 | 794 |
0 | 0 | /* |
1 | 1 | * This file is part of nzbget. See <http://nzbget.net>. |
2 | 2 | * |
3 | * Copyright (C) 2013-2017 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
3 | * Copyright (C) 2013-2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
4 | 4 | * |
5 | 5 | * This program is free software; you can redistribute it and/or modify |
6 | 6 | * it under the terms of the GNU General Public License as published by |
928 | 928 | GuardedDownloadQueue guard = DownloadQueue::Guard(); |
929 | 929 | m_postInfo->SetProgressLabel(progressLabel); |
930 | 930 | } |
931 | ||
932 | bool UnpackController::HasCompletedArchiveFiles(NzbInfo* nzbInfo) | |
933 | { | |
934 | RegEx regExRar(".*\\.rar$"); | |
935 | RegEx regExSevenZip(".*\\.7z$"); | |
936 | RegEx regExSevenZipMulti(".*\\.7z\\.[0-9]+$"); | |
937 | ||
938 | for (CompletedFile& completedFile: nzbInfo->GetCompletedFiles()) | |
939 | { | |
940 | const char* filename = completedFile.GetFilename(); | |
941 | if (regExRar.Match(filename) || | |
942 | regExSevenZip.Match(filename) || | |
943 | regExSevenZipMulti.Match(filename)) | |
944 | { | |
945 | return true; | |
946 | } | |
947 | } | |
948 | ||
949 | return false; | |
950 | } |
0 | 0 | /* |
1 | 1 | * This file is part of nzbget. See <http://nzbget.net>. |
2 | 2 | * |
3 | * Copyright (C) 2013-2017 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
3 | * Copyright (C) 2013-2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
4 | 4 | * |
5 | 5 | * This program is free software; you can redistribute it and/or modify |
6 | 6 | * it under the terms of the GNU General Public License as published by |
31 | 31 | virtual void Run(); |
32 | 32 | virtual void Stop(); |
33 | 33 | static void StartJob(PostInfo* postInfo); |
34 | static bool HasCompletedArchiveFiles(NzbInfo* nzbInfo); | |
34 | 35 | |
35 | 36 | protected: |
36 | 37 | virtual bool ReadLine(char* buf, int bufSize, FILE* stream); |
0 | 0 | /* |
1 | 1 | * This file is part of nzbget. See <http://nzbget.net>. |
2 | 2 | * |
3 | * Copyright (C) 2007-2017 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
3 | * Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
4 | 4 | * |
5 | 5 | * This program is free software; you can redistribute it and/or modify |
6 | 6 | * it under the terms of the GNU General Public License as published by |
26 | 26 | #include "FileSystem.h" |
27 | 27 | |
28 | 28 | static const char* FORMATVERSION_SIGNATURE = "nzbget diskstate file version "; |
29 | const int DISKSTATE_QUEUE_VERSION = 60; | |
29 | const int DISKSTATE_QUEUE_VERSION = 61; | |
30 | 30 | const int DISKSTATE_FILE_VERSION = 5; |
31 | 31 | const int DISKSTATE_STATS_VERSION = 3; |
32 | 32 | const int DISKSTATE_FEEDS_VERSION = 3; |
463 | 463 | outfile.PrintLine("%i,%i,%i", nzbInfo->GetTotalArticles(), nzbInfo->GetSuccessArticles(), nzbInfo->GetFailedArticles()); |
464 | 464 | |
465 | 465 | outfile.PrintLine("%s", nzbInfo->GetDupeKey()); |
466 | outfile.PrintLine("%i,%i", (int)nzbInfo->GetDupeMode(), nzbInfo->GetDupeScore()); | |
466 | outfile.PrintLine("%i,%i,%i", (int)nzbInfo->GetDupeMode(), nzbInfo->GetDupeScore(), (int)nzbInfo->GetDupeHint()); | |
467 | 467 | |
468 | 468 | Util::SplitInt64(nzbInfo->GetDownloadedSize(), &High1, &Low1); |
469 | 469 | outfile.PrintLine("%u,%u,%i,%i,%i,%i,%i", High1, Low1, nzbInfo->GetDownloadSec(), nzbInfo->GetPostTotalSec(), |
689 | 689 | if (!infile.ReadLine(buf, sizeof(buf))) goto error; |
690 | 690 | nzbInfo->SetDupeKey(buf); |
691 | 691 | |
692 | int dupeMode, dupeScore; | |
693 | if (infile.ScanLine("%i,%i", &dupeMode, &dupeScore) != 2) goto error; | |
692 | int dupeMode, dupeScore, dupeHint; | |
693 | dupeHint = 0; //clang requires initialization in a separate line (due to goto statements) | |
694 | if (formatVersion >= 61) | |
695 | { | |
696 | if (infile.ScanLine("%i,%i,%i", &dupeMode, &dupeScore, &dupeHint) != 3) goto error; | |
697 | } | |
698 | else | |
699 | { | |
700 | if (infile.ScanLine("%i,%i", &dupeMode, &dupeScore) != 2) goto error; | |
701 | } | |
694 | 702 | nzbInfo->SetDupeMode((EDupeMode)dupeMode); |
695 | 703 | nzbInfo->SetDupeScore(dupeScore); |
704 | nzbInfo->SetDupeMode((EDupeMode)dupeHint); | |
696 | 705 | |
697 | 706 | if (formatVersion >= 48) |
698 | 707 | { |
1450 | 1459 | |
1451 | 1460 | for (HistoryInfo* historyInfo : downloadQueue->GetHistory()) |
1452 | 1461 | { |
1453 | if (historyInfo->GetKind() == HistoryInfo::hkNzb) | |
1462 | if (historyInfo->GetKind() == HistoryInfo::hkNzb || | |
1463 | historyInfo->GetKind() == HistoryInfo::hkUrl) | |
1454 | 1464 | { |
1455 | 1465 | NzbInfo* nzbInfo = historyInfo->GetNzbInfo(); |
1456 | 1466 | nzbIdList.push_back(nzbInfo->GetId()); |
345 | 345 | } |
346 | 346 | } |
347 | 347 | |
348 | void NzbInfo::AddMessage(Message::EKind kind, const char * text) | |
349 | { | |
350 | switch (kind) | |
351 | { | |
348 | void NzbInfo::AddMessage(Message::EKind kind, const char * text, bool print) | |
349 | { | |
350 | if (print) | |
351 | { | |
352 | switch (kind) | |
353 | { | |
352 | 354 | case Message::mkDetail: |
353 | 355 | detail("%s", text); |
354 | 356 | break; |
368 | 370 | case Message::mkDebug: |
369 | 371 | debug("%s", text); |
370 | 372 | break; |
373 | } | |
371 | 374 | } |
372 | 375 | |
373 | 376 | Guard guard(m_logMutex); |
495 | 498 | m_parStatus == NzbInfo::psFailure || |
496 | 499 | m_unpackStatus == NzbInfo::usFailure || |
497 | 500 | m_unpackStatus == NzbInfo::usPassword || |
501 | m_urlStatus == NzbInfo::lsFailed || | |
502 | m_urlStatus == NzbInfo::lsScanSkipped || | |
503 | m_urlStatus == NzbInfo::lsScanFailed || | |
498 | 504 | (m_parStatus == NzbInfo::psSkipped && |
499 | 505 | m_unpackStatus == NzbInfo::usSkipped && |
500 | 506 | CalcHealth() < CalcCriticalHealth(true))); |
626 | 632 | else if (m_deleteStatus == NzbInfo::dsDupe) |
627 | 633 | { |
628 | 634 | status = "DELETED/DUPE"; |
635 | } | |
636 | else if (m_deleteStatus == NzbInfo::dsGood) | |
637 | { | |
638 | status = "DELETED/GOOD"; | |
629 | 639 | } |
630 | 640 | else |
631 | 641 | { |
1 | 1 | * This file is part of nzbget. See <http://nzbget.net>. |
2 | 2 | * |
3 | 3 | * Copyright (C) 2004 Sven Henkel <sidddy@users.sourceforge.net> |
4 | * Copyright (C) 2007-2017 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
4 | * Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
5 | 5 | * |
6 | 6 | * This program is free software; you can redistribute it and/or modify |
7 | 7 | * it under the terms of the GNU General Public License as published by |
443 | 443 | { |
444 | 444 | nkNzb, |
445 | 445 | nkUrl |
446 | }; | |
447 | ||
448 | enum EDupeHint | |
449 | { | |
450 | dhNone, | |
451 | dhRedownloadManual, | |
452 | dhRedownloadAuto | |
446 | 453 | }; |
447 | 454 | |
448 | 455 | int GetId() { return m_id; } |
579 | 586 | void SetDupeScore(int dupeScore) { m_dupeScore = dupeScore; } |
580 | 587 | EDupeMode GetDupeMode() { return m_dupeMode; } |
581 | 588 | void SetDupeMode(EDupeMode dupeMode) { m_dupeMode = dupeMode; } |
589 | EDupeHint GetDupeHint() { return m_dupeHint; } | |
590 | void SetDupeHint(EDupeHint dupeHint) { m_dupeHint = dupeHint; } | |
582 | 591 | uint32 GetFullContentHash() { return m_fullContentHash; } |
583 | 592 | void SetFullContentHash(uint32 fullContentHash) { m_fullContentHash = fullContentHash; } |
584 | 593 | uint32 GetFilteredContentHash() { return m_filteredContentHash; } |
614 | 623 | void LeavePostProcess(); |
615 | 624 | bool IsDupeSuccess(); |
616 | 625 | const char* MakeTextStatus(bool ignoreScriptStatus); |
617 | void AddMessage(Message::EKind kind, const char* text); | |
626 | void AddMessage(Message::EKind kind, const char* text, bool print = true); | |
618 | 627 | void PrintMessage(Message::EKind kind, const char* format, ...) PRINTF_SYNTAX(3); |
619 | 628 | int GetMessageCount() { return m_messageCount; } |
620 | 629 | void SetMessageCount(int messageCount) { m_messageCount = messageCount; } |
697 | 706 | CString m_dupeKey = ""; |
698 | 707 | int m_dupeScore = 0; |
699 | 708 | EDupeMode m_dupeMode = dmScore; |
709 | EDupeHint m_dupeHint = dhNone; | |
700 | 710 | uint32 m_fullContentHash = 0; |
701 | 711 | uint32 m_filteredContentHash = 0; |
702 | 712 | FileList m_fileList; |
917 | 927 | eaNzbNamed, |
918 | 928 | eaFileCompleted, |
919 | 929 | eaFileDeleted, |
920 | eaUrlCompleted | |
930 | eaUrlFound, | |
931 | eaUrlAdded, | |
932 | eaUrlDeleted, | |
933 | eaUrlCompleted, | |
934 | eaUrlFailed | |
921 | 935 | }; |
922 | 936 | |
923 | 937 | struct Aspect |
201 | 201 | } |
202 | 202 | } |
203 | 203 | |
204 | if (!sameContent && nzbInfo->GetDupeHint() != NzbInfo::dhNone) | |
205 | { | |
206 | // dupe check when "download again" URLs: checking same content only | |
207 | return; | |
208 | } | |
209 | ||
204 | 210 | if (!sameContent && !good && nzbInfo->GetDupeMode() == dmScore) |
205 | 211 | { |
206 | 212 | // nzb-files having success-duplicates in recent history (with different content) are added to history for backup |
207 | 213 | for (HistoryInfo* historyInfo : downloadQueue->GetHistory()) |
208 | 214 | { |
209 | if (historyInfo->GetKind() == HistoryInfo::hkNzb && | |
215 | if ((historyInfo->GetKind() == HistoryInfo::hkNzb || | |
216 | historyInfo->GetKind() == HistoryInfo::hkUrl) && | |
210 | 217 | historyInfo->GetNzbInfo()->GetDupeMode() != dmForce && |
211 | 218 | SameNameOrKey(historyInfo->GetNzbInfo()->GetName(), historyInfo->GetNzbInfo()->GetDupeKey(), |
212 | 219 | nzbInfo->GetName(), nzbInfo->GetDupeKey()) && |
236 | 243 | sameContent ? "exactly same content" : good ? "good status" : "success status"); |
237 | 244 | } |
238 | 245 | |
239 | if (nzbInfo->GetFeedId()) | |
246 | if (nzbInfo->GetFeedId() && nzbInfo->GetDupeHint() == NzbInfo::dhNone) | |
240 | 247 | { |
241 | 248 | warn("%s", *message); |
242 | 249 | // Flag saying QueueCoordinator to skip nzb-file |
262 | 269 | { |
263 | 270 | NzbInfo* queuedNzbInfo = (*it++).get(); |
264 | 271 | if (queuedNzbInfo != nzbInfo && |
265 | queuedNzbInfo->GetKind() == NzbInfo::nkNzb && | |
272 | queuedNzbInfo->GetDeleteStatus() == NzbInfo::dsNone && | |
273 | (queuedNzbInfo->GetKind() == NzbInfo::nkNzb || | |
274 | (queuedNzbInfo->GetKind() == NzbInfo::nkUrl && nzbInfo->GetKind() == NzbInfo::nkUrl)) && | |
266 | 275 | queuedNzbInfo->GetDupeMode() != dmForce && |
267 | 276 | SameNameOrKey(queuedNzbInfo->GetName(), queuedNzbInfo->GetDupeKey(), |
268 | 277 | nzbInfo->GetName(), nzbInfo->GetDupeKey())) |
285 | 294 | // the existing queue item is moved to history as dupe-backup |
286 | 295 | info("Moving collection %s with lower duplicate score to history", queuedNzbInfo->GetName()); |
287 | 296 | queuedNzbInfo->SetDeleteStatus(NzbInfo::dsDupe); |
297 | int oldSize = downloadQueue->GetQueue()->size(); | |
288 | 298 | downloadQueue->EditEntry(queuedNzbInfo->GetId(), |
289 | 299 | DownloadQueue::eaGroupDelete, nullptr); |
300 | int newSize = downloadQueue->GetQueue()->size(); | |
301 | index += oldSize == newSize ? 1 : 0; | |
290 | 302 | it = downloadQueue->GetQueue()->begin() + index; |
303 | index--; | |
291 | 304 | } |
292 | 305 | } |
293 | 306 | } |
376 | 389 | HistoryInfo* historyDupe = nullptr; |
377 | 390 | for (HistoryInfo* historyInfo : downloadQueue->GetHistory()) |
378 | 391 | { |
379 | if (historyInfo->GetKind() == HistoryInfo::hkNzb && | |
392 | if ((historyInfo->GetKind() == HistoryInfo::hkNzb || | |
393 | historyInfo->GetKind() == HistoryInfo::hkUrl) && | |
380 | 394 | historyInfo->GetNzbInfo()->GetDupeMode() != dmForce && |
381 | 395 | historyInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsDupe && |
382 | 396 | historyInfo->GetNzbInfo()->CalcHealth() >= historyInfo->GetNzbInfo()->CalcCriticalHealth(true) && |
394 | 408 | if (historyDupe) |
395 | 409 | { |
396 | 410 | info("Found duplicate %s for %s", historyDupe->GetNzbInfo()->GetName(), nzbName); |
411 | historyDupe->GetNzbInfo()->SetDupeHint(NzbInfo::dhRedownloadAuto); | |
397 | 412 | g_HistoryCoordinator->Redownload(downloadQueue, historyDupe); |
398 | 413 | } |
399 | 414 | } |
464 | 479 | { |
465 | 480 | HistoryInfo* historyInfo = (*it).get(); |
466 | 481 | |
467 | if (historyInfo->GetKind() == HistoryInfo::hkNzb && | |
482 | if ((historyInfo->GetKind() == HistoryInfo::hkNzb || | |
483 | historyInfo->GetKind() == HistoryInfo::hkUrl) && | |
468 | 484 | historyInfo->GetNzbInfo()->GetDupeMode() != dmForce && |
469 | 485 | historyInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsDupe && |
470 | 486 | historyInfo != markHistoryInfo && |
0 | 0 | /* |
1 | 1 | * This file is part of nzbget. See <http://nzbget.net>. |
2 | 2 | * |
3 | * Copyright (C) 2007-2017 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
3 | * Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
4 | 4 | * |
5 | 5 | * This program is free software; you can redistribute it and/or modify |
6 | 6 | * it under the terms of the GNU General Public License as published by |
182 | 182 | nzbInfo->SetDirectRenameStatus(NzbInfo::tsFailure); |
183 | 183 | } |
184 | 184 | |
185 | nzbInfo->SetDupeHint(NzbInfo::dhNone); | |
186 | ||
185 | 187 | nzbInfo->PrintMessage(Message::mkInfo, "Collection %s added to history", nzbInfo->GetName()); |
186 | 188 | } |
187 | 189 | |
432 | 434 | historyInfo->DiscardNzbInfo(); |
433 | 435 | nzbInfo->SetUrlStatus(NzbInfo::lsNone); |
434 | 436 | nzbInfo->SetDeleteStatus(NzbInfo::dsNone); |
437 | nzbInfo->SetDupeHint(nzbInfo->GetDupeHint() == NzbInfo::dhNone ? NzbInfo::dhRedownloadManual : nzbInfo->GetDupeHint()); | |
435 | 438 | downloadQueue->GetQueue()->Add(std::unique_ptr<NzbInfo>(nzbInfo), true); |
436 | 439 | downloadQueue->GetHistory()->erase(itHistory); |
437 | 440 | return; |
176 | 176 | AdjustDownloadsLimit(); |
177 | 177 | bool wasStandBy = true; |
178 | 178 | bool articeDownloadsRunning = false; |
179 | int resetCounter = 0; | |
179 | time_t lastReset = 0; | |
180 | 180 | g_StatMeter->IntervalCheck(); |
181 | 181 | |
182 | 182 | while (!IsStopped()) |
244 | 244 | |
245 | 245 | Util::SetStandByMode(standBy); |
246 | 246 | |
247 | resetCounter += sleepInterval; | |
248 | if (resetCounter >= 1000) | |
247 | time_t currentTime = Util::CurrentTime(); | |
248 | if (lastReset != currentTime) | |
249 | 249 | { |
250 | 250 | // this code should not be called too often, once per second is OK |
251 | 251 | g_ServerPool->CloseUnusedConnections(); |
254 | 254 | { |
255 | 255 | SaveAllPartialState(); |
256 | 256 | } |
257 | resetCounter = 0; | |
258 | 257 | g_StatMeter->IntervalCheck(); |
259 | 258 | g_Log->IntervalCheck(); |
260 | 259 | AdjustDownloadsLimit(); |
260 | lastReset = currentTime; | |
261 | 261 | } |
262 | 262 | } |
263 | 263 |
0 | 0 | /* |
1 | 1 | * This file is part of nzbget. See <http://nzbget.net>. |
2 | 2 | * |
3 | * Copyright (C) 2007-2016 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
3 | * Copyright (C) 2007-2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
4 | 4 | * |
5 | 5 | * This program is free software; you can redistribute it and/or modify |
6 | 6 | * it under the terms of the GNU General Public License as published by |
437 | 437 | nzbInfo->SetUrl(urlInfo->GetUrl()); |
438 | 438 | nzbInfo->SetUrlStatus(urlInfo->GetUrlStatus()); |
439 | 439 | nzbInfo->SetFeedId(urlInfo->GetFeedId()); |
440 | nzbInfo->SetDupeHint(urlInfo->GetDupeHint()); | |
440 | 441 | } |
441 | 442 | |
442 | 443 | if (nzbFile.GetPassword()) |
457 | 458 | { |
458 | 459 | addedNzb = g_QueueCoordinator->AddNzbFileToQueue(std::move(nzbInfo), std::move(urlInfo), addTop); |
459 | 460 | } |
460 | else if (!urlInfo) | |
461 | else if (urlInfo) | |
462 | { | |
463 | for (Message& message : nzbInfo->GuardCachedMessages()) | |
464 | { | |
465 | urlInfo->AddMessage(message.GetKind(), message.GetText(), false); | |
466 | } | |
467 | } | |
468 | else | |
461 | 469 | { |
462 | 470 | nzbInfo->SetDeleteStatus(NzbInfo::dsScan); |
463 | 471 | addedNzb = g_QueueCoordinator->AddNzbFileToQueue(std::move(nzbInfo), std::move(urlInfo), addTop); |
276 | 276 | // remove downloader from downloader list |
277 | 277 | m_activeDownloads.erase(std::find(m_activeDownloads.begin(), m_activeDownloads.end(), urlDownloader)); |
278 | 278 | |
279 | nzbInfo->SetActiveDownloads(0); | |
280 | ||
281 | 279 | retry = urlDownloader->GetStatus() == WebDownloader::adRetry && !nzbInfo->GetDeleting(); |
282 | 280 | |
283 | 281 | if (nzbInfo->GetDeleting()) |
284 | 282 | { |
285 | nzbInfo->SetDeleteStatus(NzbInfo::dsManual); | |
283 | nzbInfo->SetDeleteStatus(nzbInfo->GetDeleteStatus() == NzbInfo::dsNone ? NzbInfo::dsManual : nzbInfo->GetDeleteStatus()); | |
286 | 284 | nzbInfo->SetUrlStatus(NzbInfo::lsNone); |
287 | 285 | nzbInfo->SetDeleting(false); |
288 | 286 | } |
308 | 306 | |
309 | 307 | if (retry) |
310 | 308 | { |
309 | nzbInfo->SetActiveDownloads(0); | |
311 | 310 | return; |
312 | 311 | } |
313 | 312 | |
323 | 322 | |
324 | 323 | if (addStatus == Scanner::asSuccess) |
325 | 324 | { |
326 | // if scanner has successfully added nzb-file to queue, our pNZBInfo is | |
325 | // if scanner has successfully added nzb-file to queue, our nzbInfo is | |
327 | 326 | // already removed from queue and destroyed |
328 | 327 | return; |
329 | 328 | } |
335 | 334 | |
336 | 335 | g_QueueScriptCoordinator->EnqueueScript(nzbInfo, QueueScriptCoordinator::qeUrlCompleted); |
337 | 336 | |
338 | std::unique_ptr<NzbInfo> oldNzbInfo; | |
339 | ||
340 | 337 | { |
341 | 338 | GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); |
342 | 339 | |
343 | // delete URL from queue | |
344 | oldNzbInfo = downloadQueue->GetQueue()->Remove(nzbInfo); | |
345 | ||
346 | // add failed URL to history | |
347 | if (g_Options->GetKeepHistory() > 0 && | |
348 | nzbInfo->GetUrlStatus() != NzbInfo::lsFinished && | |
349 | !nzbInfo->GetAvoidHistory()) | |
350 | { | |
351 | std::unique_ptr<HistoryInfo> historyInfo = std::make_unique<HistoryInfo>(std::move(oldNzbInfo)); | |
352 | historyInfo->SetTime(Util::CurrentTime()); | |
353 | downloadQueue->GetHistory()->Add(std::move(historyInfo), true); | |
354 | downloadQueue->HistoryChanged(); | |
355 | } | |
356 | ||
357 | downloadQueue->Save(); | |
358 | } | |
359 | ||
360 | if (oldNzbInfo) | |
361 | { | |
362 | g_DiskState->DiscardFiles(oldNzbInfo.get()); | |
340 | nzbInfo->SetActiveDownloads(0); | |
341 | ||
342 | DownloadQueue::Aspect aspect = {DownloadQueue::eaUrlFailed, downloadQueue, nzbInfo, nullptr}; | |
343 | downloadQueue->Notify(&aspect); | |
363 | 344 | } |
364 | 345 | } |
365 | 346 | |
379 | 360 | return true; |
380 | 361 | } |
381 | 362 | } |
363 | ||
364 | return false; | |
382 | 365 | } |
383 | 366 | |
384 | 367 | info("Deleting URL %s", nzbInfo->GetName()); |
385 | 368 | |
386 | nzbInfo->SetDeleteStatus(NzbInfo::dsManual); | |
369 | nzbInfo->SetDeleteStatus(nzbInfo->GetDeleteStatus() == NzbInfo::dsNone ? NzbInfo::dsManual : nzbInfo->GetDeleteStatus()); | |
387 | 370 | nzbInfo->SetUrlStatus(NzbInfo::lsNone); |
388 | 371 | |
389 | std::unique_ptr<NzbInfo> oldNzbInfo = downloadQueue->GetQueue()->Remove(nzbInfo); | |
390 | ||
391 | if (g_Options->GetKeepHistory() > 0 && !avoidHistory) | |
392 | { | |
393 | std::unique_ptr<HistoryInfo> historyInfo = std::make_unique<HistoryInfo>(std::move(oldNzbInfo)); | |
394 | historyInfo->SetTime(Util::CurrentTime()); | |
395 | downloadQueue->GetHistory()->Add(std::move(historyInfo), true); | |
396 | downloadQueue->HistoryChanged(); | |
397 | } | |
398 | else | |
399 | { | |
400 | g_DiskState->DiscardFiles(oldNzbInfo.get()); | |
401 | } | |
372 | DownloadQueue::Aspect deletedAspect = {DownloadQueue::eaUrlDeleted, downloadQueue, nzbInfo, nullptr}; | |
373 | downloadQueue->Notify(&deletedAspect); | |
402 | 374 | |
403 | 375 | return true; |
404 | 376 | } |
377 | ||
378 | void UrlCoordinator::AddUrlToQueue(std::unique_ptr<NzbInfo> nzbInfo, bool addFirst) | |
379 | { | |
380 | debug("Adding URL to queue"); | |
381 | ||
382 | NzbInfo* addedNzb = nzbInfo.get(); | |
383 | ||
384 | GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); | |
385 | ||
386 | DownloadQueue::Aspect foundAspect = {DownloadQueue::eaUrlFound, downloadQueue, addedNzb, nullptr}; | |
387 | downloadQueue->Notify(&foundAspect); | |
388 | ||
389 | if (addedNzb->GetDeleteStatus() != NzbInfo::dsManual) | |
390 | { | |
391 | downloadQueue->GetQueue()->Add(std::move(nzbInfo), addFirst); | |
392 | ||
393 | DownloadQueue::Aspect addedAspect = {DownloadQueue::eaUrlAdded, downloadQueue, addedNzb, nullptr}; | |
394 | downloadQueue->Notify(&addedAspect); | |
395 | } | |
396 | ||
397 | downloadQueue->Save(); | |
398 | } |
38 | 38 | void Update(Subject* caller, void* aspect); |
39 | 39 | |
40 | 40 | // Editing the queue |
41 | void AddUrlToQueue(std::unique_ptr<NzbInfo> nzbInfo, bool addFirst); | |
41 | 42 | bool HasMoreJobs() { return m_hasMoreJobs; } |
42 | 43 | bool DeleteQueueEntry(DownloadQueue* downloadQueue, NzbInfo* nzbInfo, bool avoidHistory); |
43 | 44 |
28 | 28 | #include "DownloadInfo.h" |
29 | 29 | #include "Scanner.h" |
30 | 30 | #include "StatMeter.h" |
31 | #include "UrlCoordinator.h" | |
31 | 32 | |
32 | 33 | extern void ExitProc(); |
33 | 34 | extern void Reload(); |
429 | 430 | nzbInfo->SetDupeScore(dupeScore); |
430 | 431 | nzbInfo->SetDupeMode((EDupeMode)dupeMode); |
431 | 432 | |
432 | GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); | |
433 | downloadQueue->GetQueue()->Add(std::move(nzbInfo), addTop); | |
434 | downloadQueue->Save(); | |
433 | g_UrlCoordinator->AddUrlToQueue(std::move(nzbInfo), addTop); | |
435 | 434 | |
436 | 435 | ok = true; |
437 | 436 | } |
33 | 33 | #include "ScriptConfig.h" |
34 | 34 | #include "QueueScript.h" |
35 | 35 | #include "CommandScript.h" |
36 | #include "UrlCoordinator.h" | |
36 | 37 | |
37 | 38 | extern void ExitProc(); |
38 | 39 | extern void Reload(); |
891 | 892 | } |
892 | 893 | *value = atoi(param + 1); |
893 | 894 | m_requestPtr = param + 1; |
894 | while (strchr("-+0123456789&", *m_requestPtr)) | |
895 | while (*m_requestPtr && strchr("-+0123456789&", *m_requestPtr)) | |
895 | 896 | { |
896 | 897 | m_requestPtr++; |
897 | 898 | } |
2255 | 2256 | |
2256 | 2257 | info("Queue %s", *nzbInfo->MakeNiceUrlName(nzbContent, nzbFilename)); |
2257 | 2258 | |
2258 | { | |
2259 | GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); | |
2260 | downloadQueue->GetQueue()->Add(std::move(nzbInfo), addTop); | |
2261 | downloadQueue->Save(); | |
2262 | } | |
2259 | g_UrlCoordinator->AddUrlToQueue(std::move(nzbInfo), addTop); | |
2263 | 2260 | |
2264 | 2261 | if (v13) |
2265 | 2262 | { |
139 | 139 | #ifdef WIN32 |
140 | 140 | bool terminated = TerminateThread(m_threadObj, 0) != 0; |
141 | 141 | #else |
142 | #ifdef HAVE_PTHREAD_CANCEL | |
142 | 143 | bool terminated = pthread_cancel(m_threadObj) == 0; |
144 | #else | |
145 | bool terminated = false; | |
146 | warn("Could not kill thread: thread cancelling isn't supported on this platform"); | |
147 | #endif | |
143 | 148 | #endif |
144 | 149 | |
145 | 150 | if (terminated) |
1 | 1 | # |
2 | 2 | # This file is part of nzbget |
3 | 3 | # |
4 | # Copyright (C) 2015-2017 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
4 | # Copyright (C) 2015-2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
5 | 5 | # |
6 | 6 | # This program is free software; you can redistribute it and/or modify |
7 | 7 | # it under the terms of the GNU General Public License as published by |
24 | 24 | # Uncomment next line for debuging |
25 | 25 | #set -x |
26 | 26 | |
27 | ALLTARGETS="dist i686 x86_64 armel armhf mipsel mipseb ppc6xx ppc500 x86_64-bsd" | |
27 | ALLTARGETS="dist i686 x86_64 armel armhf mipsel mipseb ppc6xx ppc500 x86_64-bsd i686-ndk armhf-ndk" | |
28 | 28 | ROOT=`pwd` |
29 | 29 | ROOTPATH=$PATH |
30 | 30 | OUTPUTDIR=$ROOT/output |
132 | 132 | do |
133 | 133 | if [[ $TARGET == *-bsd ]]; then |
134 | 134 | PLATFORM="freebsd" |
135 | elif [[ $TARGET == *-ndk ]]; then | |
136 | PLATFORM="android" | |
135 | 137 | else |
136 | 138 | PLATFORM="linux" |
137 | 139 | fi |
179 | 181 | touch Makefile.in configure config.h.in |
180 | 182 | |
181 | 183 | echo "Updating root certificates" |
182 | cd ../setup | |
183 | curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem | |
184 | cd $BUILDDIR | |
184 | cd ../setup | |
185 | curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem | |
186 | cd $BUILDDIR | |
185 | 187 | fi |
186 | 188 | } |
187 | 189 | |
234 | 236 | |
235 | 237 | if [ $PLATFORM == "freebsd" ]; then |
236 | 238 | PLATSUFF="-bsd" |
239 | elif [ $PLATFORM == "android" ]; then | |
240 | PLATSUFF="-ndk" | |
237 | 241 | else |
238 | 242 | PLATSUFF="" |
239 | 243 | fi |
261 | 265 | case $PLATFORM in |
262 | 266 | linux) |
263 | 267 | TOOLKIND=buildroot |
264 | TOOLNAME=linux | |
268 | ARCH=$ARCH-linux | |
269 | ;; | |
270 | android) | |
271 | TOOLKIND=ndk | |
272 | ARCH=$ARCH-linux-android | |
273 | if [ "$ARCH" == "arm-linux-android" ]; then | |
274 | ARCH="arm-linux-androideabi" | |
275 | fi | |
265 | 276 | ;; |
266 | 277 | freebsd) |
267 | 278 | TOOLKIND=crossclang |
268 | TOOLNAME=pc-freebsd | |
269 | SYSROOT="$TOOLCHAIN_ROOT/sysroot" | |
279 | ARCH=$ARCH-pc-freebsd | |
280 | SYSROOT="$TOOLCHAIN_ROOT/sysroot" | |
270 | 281 | ;; |
271 | 282 | esac |
272 | 283 | } |
285 | 296 | |
286 | 297 | LUBACKTRACE="" |
287 | 298 | if [ -f "$STAGING/lib/libubacktrace.so.1" ] ; then |
288 | LUBACKTRACE="-lubacktrace" | |
299 | LUBACKTRACE="-lubacktrace" | |
289 | 300 | fi |
290 | 301 | |
291 | 302 | case "$TOOLKIND-$CONFIG" in |
293 | 304 | LDFLAGS="-static $STRIP" \ |
294 | 305 | CXXFLAGS="-std=c++14 -g -fasynchronous-unwind-tables" \ |
295 | 306 | LIBS="-lcrypto -ldl -lz $LUBACKTRACE" \ |
296 | ./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME --enable-debug | |
307 | ./configure --disable-dependency-tracking --host=$ARCH --enable-debug | |
297 | 308 | ;; |
298 | 309 | buildroot-release|buildroot-release-nostrip) |
299 | 310 | LDFLAGS="-static $STRIP" \ |
300 | 311 | CXXFLAGS="-std=c++14 -O2 $DEBUG" \ |
301 | 312 | LIBS="-lcrypto -ldl -lz" \ |
302 | ./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME | |
313 | ./configure --disable-dependency-tracking --host=$ARCH | |
314 | ;; | |
315 | ndk-debug|ndk-debug-strip) | |
316 | LDFLAGS="-static -static-libstdc++ $STRIP" \ | |
317 | CXXFLAGS="-std=c++14 -g -fasynchronous-unwind-tables" \ | |
318 | CXX="$ARCH-clang++" \ | |
319 | PKG_CONFIG_LIBDIR="$STAGING/usr/lib/pkgconfig" \ | |
320 | ./configure --disable-dependency-tracking --disable-largefile --host=$ARCH --enable-debug | |
321 | ;; | |
322 | ndk-release|ndk-release-nostrip) | |
323 | LDFLAGS="-static -static-libstdc++ $STRIP" \ | |
324 | CXXFLAGS="-std=c++14 -O2 $DEBUG" \ | |
325 | CXX="$ARCH-clang++" \ | |
326 | PKG_CONFIG_LIBDIR="$STAGING/usr/lib/pkgconfig" \ | |
327 | ./configure --disable-dependency-tracking --disable-largefile --host=$ARCH | |
303 | 328 | ;; |
304 | 329 | crossclang-debug|crossclang-debug-strip) |
305 | 330 | CXX="$CROSSCLANG" \ |
306 | LDFLAGS="-static $STRIP -fuse-ld=lld --target=$ARCH-$TOOLNAME -lc++ -lm --sysroot=$SYSROOT" \ | |
307 | CXXFLAGS="-g --target=$ARCH-$TOOLNAME --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \ | |
331 | LDFLAGS="-static $STRIP -fuse-ld=lld --target=$ARCH -lc++ -lm --sysroot=$SYSROOT" \ | |
332 | CXXFLAGS="-g --target=$ARCH --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \ | |
308 | 333 | PKG_CONFIG_LIBDIR="$STAGING/usr/lib/pkgconfig" \ |
309 | ./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME --enable-debug | |
334 | ./configure --disable-dependency-tracking --host=$ARCH --enable-debug | |
310 | 335 | ;; |
311 | 336 | crossclang-release|crossclang-release-nostrip) |
312 | 337 | CXX="$CROSSCLANG" \ |
313 | LDFLAGS="-static $STRIP -fuse-ld=lld --target=$ARCH-$TOOLNAME -lc++ -lm --sysroot=$SYSROOT" \ | |
314 | CXXFLAGS="-O2 $DEBUG --target=$ARCH-$TOOLNAME --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \ | |
338 | LDFLAGS="-static $STRIP -fuse-ld=lld --target=$ARCH -lc++ -lm --sysroot=$SYSROOT" \ | |
339 | CXXFLAGS="-O2 $DEBUG --target=$ARCH --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \ | |
315 | 340 | PKG_CONFIG_LIBDIR="$STAGING/usr/lib/pkgconfig" \ |
316 | ./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME --enable-debug | |
341 | ./configure --disable-dependency-tracking --host=$ARCH --enable-debug | |
317 | 342 | ;; |
318 | 343 | esac |
319 | 344 | } |
320 | 345 | |
321 | 346 | PrecompileHeaders() |
322 | 347 | { |
323 | rm -f nzbget.h.gch | |
324 | if [ $PCH == "yes" -a $TOOLKIND != "crossclang" ]; then | |
325 | OPTIM="" | |
326 | if [ $CONFIG == "release" -o $CONFIG == "release-nostrip" ]; then | |
327 | OPTIM="-O2" | |
328 | fi | |
329 | ||
330 | $ARCH-$TOOLNAME-g++ -std=c++14 -DHAVE_CONFIG_H \ | |
348 | rm -f nzbget.h.* | |
349 | ||
350 | OPTIM="" | |
351 | if [ $CONFIG == "release" -o $CONFIG == "release-nostrip" ]; then | |
352 | OPTIM="-O2" | |
353 | fi | |
354 | ||
355 | if [ $PCH == "yes" -a $TOOLKIND == "buildroot" ]; then | |
356 | $ARCH-g++ -std=c++14 -DHAVE_CONFIG_H \ | |
331 | 357 | -I. -I$STAGING/usr/include -I$STAGING/usr/include/libxml2 \ |
332 | 358 | -g $OPTIM daemon/main/nzbget.h -o nzbget.h.gch |
359 | fi | |
360 | ||
361 | if [ $PCH == "yes" -a $TOOLKIND == "ndk" ]; then | |
362 | $ARCH-clang++ -std=c++14 -DHAVE_CONFIG_H \ | |
363 | -I. -I$STAGING/usr/include -I$STAGING/usr/include/libxml2 \ | |
364 | -g $OPTIM -x c++-header daemon/main/nzbget.h -o nzbget.h.pch | |
365 | CXXFLAGS=`sed -n 's:^CXXFLAGS =.\(.*\):\1:p' Makefile` | |
366 | sed 's:^CXXFLAGS = :CXXFLAGS = -include-pch nzbget.h.pch :' -i Makefile | |
367 | sed "s: CXXFLAGS+=: CXXFLAGS=$CXXFLAGS :" -i Makefile | |
333 | 368 | fi |
334 | 369 | } |
335 | 370 | |
520 | 555 | if [[ $TARGET == *-bsd ]]; then |
521 | 556 | PLAT="freebsd" |
522 | 557 | TARGET="${TARGET%-bsd}" |
558 | elif [[ $TARGET == *-ndk ]]; then | |
559 | PLAT="android" | |
560 | TARGET="${TARGET%-ndk}" | |
523 | 561 | else |
524 | 562 | PLAT="linux" |
525 | 563 | fi |
0 | #!/bin/bash | |
1 | # | |
2 | # This file is part of nzbget. See <http://nzbget.net>. | |
3 | # | |
4 | # Copyright (C) 2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
5 | # | |
6 | # This program is free software; you can redistribute it and/or modify | |
7 | # it under the terms of the GNU General Public License as published by | |
8 | # the Free Software Foundation; either version 2 of the License, or | |
9 | # (at your option) any later version. | |
10 | # | |
11 | # This program is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License | |
17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | # | |
19 | ||
20 | # This script builds cross-compiling toolchain, which can compile NZBGet for Android. | |
21 | # The toolchain itself runs on Linux. | |
22 | ||
23 | # Setup strict bash error handling | |
24 | set -o nounset | |
25 | set -o errexit | |
26 | ||
27 | # Uncomment next line for debuging | |
28 | #set -x | |
29 | ||
30 | ||
31 | # Android API level | |
32 | APILEVEL=21 | |
33 | ||
34 | # Architecture | |
35 | ARCH=$1 | |
36 | case "$ARCH" in | |
37 | i686) | |
38 | NDK_ARCH="x86" | |
39 | NDK_TARGET="i686-linux-android" | |
40 | OPENSSL_TARGET="android-x86" | |
41 | ;; | |
42 | x86_64) | |
43 | NDK_ARCH="x86_64" | |
44 | NDK_TARGET="x86_64-linux-android" | |
45 | OPENSSL_TARGET="android64" | |
46 | ;; | |
47 | armhf) | |
48 | NDK_ARCH="arm" | |
49 | NDK_TARGET="arm-linux-androideabi" | |
50 | OPENSSL_TARGET="android-armeabi" | |
51 | ;; | |
52 | aarch64) | |
53 | NDK_ARCH="arm64" | |
54 | NDK_TARGET="aarch64-linux-android" | |
55 | OPENSSL_TARGET="android64-aarch64" | |
56 | ;; | |
57 | *) | |
58 | echo "Usage: $0 (i686|x86_64|armhf|aarch64)" | |
59 | exit 1 | |
60 | ;; | |
61 | esac | |
62 | ||
63 | echo "Creating toolchain for $ARCH" | |
64 | ||
65 | # Android NDK | |
66 | NDK_VERSION="r17" | |
67 | NDK_DIRNAME="android-ndk-$NDK_VERSION" | |
68 | NDK_ARCHIVE="$NDK_DIRNAME-linux-x86_64.zip" | |
69 | NDK_URL="https://dl.google.com/android/repository/$NDK_ARCHIVE" | |
70 | ||
71 | # Libxml | |
72 | LIBXML2_VERSION="2.9.4" | |
73 | LIBXML2_ARCHIVE="libxml2-$LIBXML2_VERSION.tar.gz" | |
74 | LIBXML2_URL="http://xmlsoft.org/sources/$LIBXML2_ARCHIVE" | |
75 | ||
76 | # OpenSSL | |
77 | OPENSSL_VERSION="1.1.0h" | |
78 | OPENSSL_ARCHIVE="openssl-$OPENSSL_VERSION.tar.gz" | |
79 | OPENSSL_URL="https://www.openssl.org/source/$OPENSSL_ARCHIVE" | |
80 | ||
81 | # NCurses | |
82 | NCURSES_VERSION="6.0" | |
83 | NCURSES_ARCHIVE="ncurses-$NCURSES_VERSION.tar.gz" | |
84 | NCURSES_URL="https://ftp.gnu.org/pub/gnu/ncurses/$NCURSES_ARCHIVE" | |
85 | ||
86 | ### START OF THE SCRIPT | |
87 | ||
88 | ROOTDIR=`pwd` | |
89 | ROOTDIR="$ROOTDIR/$ARCH-ndk" | |
90 | ||
91 | rm -rf $ROOTDIR | |
92 | mkdir $ROOTDIR | |
93 | cd $ROOTDIR | |
94 | ||
95 | # Download all required tools and libraries | |
96 | cd .. | |
97 | mkdir -p downloads | |
98 | cd downloads | |
99 | if [ ! -d $NDK_DIRNAME -a ! -f $NDK_ARCHIVE ]; then | |
100 | wget $NDK_URL | |
101 | fi | |
102 | if [ ! -f $LIBXML2_ARCHIVE ]; then | |
103 | wget $LIBXML2_URL | |
104 | fi | |
105 | if [ ! -f $OPENSSL_ARCHIVE ]; then | |
106 | wget $OPENSSL_URL | |
107 | fi | |
108 | if [ ! -f $NCURSES_ARCHIVE ]; then | |
109 | wget $NCURSES_URL | |
110 | fi | |
111 | cd .. | |
112 | ||
113 | # Unpack NDK | |
114 | if [ ! -d ./$NDK_DIRNAME ]; then | |
115 | echo "Unpacking NDK" | |
116 | unzip ./downloads/$NDK_ARCHIVE | |
117 | fi | |
118 | ||
119 | # Create toolchain for target | |
120 | echo "Preparing standalone NDK toolchain" | |
121 | ./$NDK_DIRNAME/build/tools/make_standalone_toolchain.py --arch $NDK_ARCH --api $APILEVEL --install-dir $ROOTDIR/output/host/usr | |
122 | ||
123 | cd $ROOTDIR | |
124 | ||
125 | # Configure toolchain | |
126 | export PATH=$PATH:$ROOTDIR/output/host/usr/bin | |
127 | export CC=$NDK_TARGET-clang | |
128 | export CXX=$NDK_TARGET-clang++ | |
129 | export AS=$NDK_TARGET-clang | |
130 | export AR=$NDK_TARGET-ar | |
131 | export LD=$NDK_TARGET-ld | |
132 | export RANLIB=$NDK_TARGET-ranlib | |
133 | export CFLAGS="-fPIE -fPIC" | |
134 | export CXXFLAGS=$CFLAGS | |
135 | export LDFLAGS="" | |
136 | ||
137 | mkdir output/build | |
138 | ln -s host/usr/sysroot output/staging | |
139 | ||
140 | cd $ROOTDIR/output/build | |
141 | ||
142 | # Build OpenSSL (5 minutes) | |
143 | tar xf ../../../downloads/$OPENSSL_ARCHIVE | |
144 | cd openssl-$OPENSSL_VERSION | |
145 | ./Configure --prefix=$ROOTDIR/output/staging/usr --sysroot=$ROOTDIR/output/staging no-shared no-dso no-hw no-zlib no-unit-test "$OPENSSL_TARGET" | |
146 | sed 's:-mandroid::' -i Makefile | |
147 | make -j2 | |
148 | make install_sw | |
149 | cd .. | |
150 | ||
151 | # Build libxml2 (2 minutes) | |
152 | tar xf ../../../downloads/$LIBXML2_ARCHIVE | |
153 | cd libxml2-$LIBXML2_VERSION | |
154 | ./configure --host=$NDK_TARGET -prefix=$ROOTDIR/output/staging/usr --disable-dependency-tracking --without-zlib --without-lzma --without-python --disable-shared | |
155 | sed 's:^PROGRAMS =.*:PROGRAMS = :' -i Makefile | |
156 | sed 's:^bin_PROGRAMS =.*:bin_PROGRAMS = :' -i Makefile | |
157 | sed 's:^SUBDIRS =.*:SUBDIRS = include .:' -i Makefile | |
158 | make -j2 | |
159 | make install | |
160 | cd .. | |
161 | ||
162 | # Build NCurses (2 minutes) | |
163 | tar xf ../../../downloads/$NCURSES_ARCHIVE | |
164 | cd ncurses-$NCURSES_VERSION | |
165 | ./configure --host=$NDK_TARGET -prefix=$ROOTDIR/output/staging/usr --disable-dependency-tracking --disable-largefile | |
166 | make -j2 | |
167 | make install | |
168 | cd .. | |
169 | ||
170 | cd .. | |
171 | ||
172 | # Create missing package descriptions | |
173 | echo "prefix=$ROOTDIR/output/staging/usr | |
174 | ||
175 | Name: zlib | |
176 | Description: zlib | |
177 | Version: 1 | |
178 | Libs: -L\${prefix}/lib -lz | |
179 | Cflags: -I\${prefix}/include | |
180 | " > $ROOTDIR/output/staging/usr/lib/pkgconfig/zlib.pc | |
181 | ||
182 | echo "prefix=$ROOTDIR/output/staging/usr | |
183 | ||
184 | Name: ncurses | |
185 | Description: ncurses | |
186 | Version: 5 | |
187 | Libs: -L\${prefix}/lib -lncurses | |
188 | Cflags: -I\${prefix}/include | |
189 | " > $ROOTDIR/output/staging/usr/lib/pkgconfig/ncurses.pc | |
190 | ||
191 | # Remove "-L${prefix}/lib" and "-L${libdir}" from all packages to fix strange linker error | |
192 | find $ROOTDIR/output/staging/usr/lib/pkgconfig -type f -exec sed 's:-L\${prefix}/lib::' -i {} \; | |
193 | find $ROOTDIR/output/staging/usr/lib/pkgconfig -type f -exec sed 's:-L\${libdir}::' -i {} \; | |
194 | ||
195 | echo "Toolchain creation completed for $ARCH" | |
196 |
1 | 1 | # |
2 | 2 | # This file is part of nzbget. See <http://nzbget.net>. |
3 | 3 | # |
4 | # Copyright (C) 2015-2017 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
4 | # Copyright (C) 2015-2018 Andrey Prygunkov <hugbug@users.sourceforge.net> | |
5 | 5 | # |
6 | 6 | # This program is free software; you can redistribute it and/or modify |
7 | 7 | # it under the terms of the GNU General Public License as published by |
24 | 24 | # Uncomment next line for debuging |
25 | 25 | #set -x |
26 | 26 | |
27 | ALLTARGETS="i686 x86_64 armel armhf mipsel mipseb ppc6xx ppc500 x86_64-bsd" | |
27 | ALLTARGETS="i686 x86_64 armel armhf mipsel mipseb ppc6xx ppc500 x86_64-bsd i686-ndk x86_64-ndk armhf-ndk aarch64-ndk" | |
28 | 28 | ROOT=`pwd` |
29 | 29 | OUTPUTDIR=$ROOT/setup |
30 | 30 | BUILDDIR=temp |
110 | 110 | if [[ $TARGET == *-bsd ]]; then |
111 | 111 | TARGET="${TARGET%-bsd}" |
112 | 112 | TOOLKIND=crossclang |
113 | TOOLNAME=pc-freebsd | |
114 | SYSROOT="$TOOLCHAIN_ROOT/sysroot" | |
115 | PLATSUFF="-bsd" | |
113 | elif [[ $TARGET == *-ndk ]]; then | |
114 | TARGET="${TARGET%-ndk}" | |
115 | TOOLKIND=ndk | |
116 | 116 | else |
117 | 117 | TOOLKIND=buildroot |
118 | TOOLNAME=linux | |
119 | PLATSUFF="" | |
120 | 118 | fi |
121 | 119 | |
120 | ARCH=$TARGET | |
121 | ENDIAN=little | |
122 | 122 | case $TARGET in |
123 | mipsel|i?86|x86_64|aarch64) | |
124 | ARCH=$TARGET | |
125 | ENDIAN=little | |
126 | ;; | |
127 | 123 | mipseb) |
128 | 124 | ARCH=mips |
129 | 125 | ENDIAN=big |
130 | 126 | ;; |
131 | 127 | arm*) |
132 | 128 | ARCH=arm |
133 | ENDIAN=little | |
134 | 129 | ;; |
135 | 130 | ppc*) |
136 | 131 | ARCH=powerpc |
137 | 132 | ENDIAN=big |
133 | ;; | |
134 | esac | |
135 | ||
136 | case $TOOLKIND in | |
137 | buildroot) | |
138 | ARCH="$ARCH-linux" | |
139 | PLATSUFF="" | |
140 | ;; | |
141 | ndk) | |
142 | ARCH="$ARCH-linux-android" | |
143 | if [ "$ARCH" == "arm-linux-android" ]; then | |
144 | ARCH="arm-linux-androideabi" | |
145 | fi | |
146 | PLATSUFF="-ndk" | |
147 | ;; | |
148 | crossclang) | |
149 | ARCH="$ARCH-pc-freebsd" | |
150 | SYSROOT="$TOOLCHAIN_ROOT/sysroot" | |
151 | PLATSUFF="-bsd" | |
138 | 152 | ;; |
139 | 153 | esac |
140 | 154 | |
156 | 170 | sed 's:^DEFINES=:DEFINES=-DUSE_FALLOCATE :' -i makefile |
157 | 171 | fi |
158 | 172 | sed 's:setlocale://setlocale:' -i rar.cpp |
173 | if [ "$TOOLKIND" == "ndk" ] ; then | |
174 | sed 's:^#if defined(_EMX) || defined (__VMS)$:#if defined(_EMX) || defined (__VMS) || defined (__ANDROID__):' -i consio.cpp | |
175 | sed 's:^#define USE_LUTIMES$:#undef USE_LUTIMES:' -i os.hpp | |
176 | fi | |
159 | 177 | |
160 | 178 | EXEDIR= |
161 | 179 | LICENSE=license.txt |
172 | 190 | cp makefile.linux_any_cpu_gcc_4.X makefile.machine |
173 | 191 | sed 's:^CXX=g++:#CXX=g++:' -i makefile.machine |
174 | 192 | sed 's:^CC=gcc:#CC=gcc:' -i makefile.machine |
175 | if [ "$TOOLKIND" == "crossclang" ] ; then | |
193 | if [ "$TOOLKIND" == "ndk" ] ; then | |
194 | sed 's:-DENV_UNIX:-DENV_UNIX -DANDROID_NDK:' -i makefile.machine | |
195 | sed 's:LOCAL_LIBS=-lpthread:LOCAL_LIBS=:' -i makefile.machine | |
196 | fi | |
197 | if [ "$TOOLKIND" != "buildroot" ] ; then | |
176 | 198 | sed 's:^PRE_COMPILED_HEADER=:#PRE_COMPILED_HEADER=:' -i makefile.machine |
177 | 199 | sed 's:^ALLFLAGS=${OPTFLAGS} -pipe -s:ALLFLAGS=${OPTFLAGS} -pipe ${CPPFLAGS}:' -i makefile.machine |
178 | 200 | fi |
188 | 210 | |
189 | 211 | make clean |
190 | 212 | |
191 | if [ "$TOOLKIND" == "crossclang" ] ; then | |
192 | CXX="$CROSSCLANG" \ | |
193 | CC="$CROSSCLANG" \ | |
194 | LDFLAGS="-static -fuse-ld=lld -lc++ -lm -lpthread --sysroot=$SYSROOT" \ | |
195 | CXXFLAGS="-O2 --target=$ARCH-$TOOLNAME --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \ | |
196 | CPPFLAGS="-O2 --target=$ARCH-$TOOLNAME --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \ | |
197 | STRIP=strip \ | |
198 | make -j $COREX $BUILDTARGET | |
199 | else | |
200 | CXX=$TOOLPATH/$ARCH-$TOOLNAME-g++ \ | |
201 | CC=$TOOLPATH/$ARCH-$TOOLNAME-gcc \ | |
202 | STRIP=$TOOLPATH/$ARCH-$TOOLNAME-strip \ | |
203 | CXXFLAGS=-O2 \ | |
204 | LDFLAGS=-static \ | |
205 | LIBS=-lpthread \ | |
206 | make -j $COREX $BUILDTARGET | |
207 | fi | |
213 | case $TOOLKIND in | |
214 | buildroot) | |
215 | CXX=$TOOLPATH/$ARCH-g++ \ | |
216 | CC=$TOOLPATH/$ARCH-gcc \ | |
217 | STRIP=$TOOLPATH/$ARCH-strip \ | |
218 | CXXFLAGS=-O2 \ | |
219 | LDFLAGS=-static \ | |
220 | LIBS=-lpthread \ | |
221 | make -j $COREX $BUILDTARGET | |
222 | ;; | |
223 | ndk) | |
224 | CXX=$TOOLPATH/$ARCH-clang++ \ | |
225 | CC=$TOOLPATH/$ARCH-clang \ | |
226 | STRIP=$TOOLPATH/$ARCH-strip \ | |
227 | CXXFLAGS=-O2 \ | |
228 | LDFLAGS="-static -static-libstdc++" \ | |
229 | make -j $COREX $BUILDTARGET | |
230 | ;; | |
231 | crossclang) | |
232 | CXX="$CROSSCLANG" \ | |
233 | CC="$CROSSCLANG" \ | |
234 | LDFLAGS="-static -fuse-ld=lld -lc++ -lm -lpthread --sysroot=$SYSROOT" \ | |
235 | CXXFLAGS="-O2 --target=$ARCH --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \ | |
236 | CPPFLAGS="-O2 --target=$ARCH --sysroot=$SYSROOT -I$SYSROOT/usr/include/c++/v1" \ | |
237 | STRIP=strip \ | |
238 | make -j $COREX $BUILDTARGET | |
239 | ;; | |
240 | esac | |
208 | 241 | |
209 | 242 | cp $EXEDIR$EXENAME ../../setup/$EXENAME-$TARGET$PLATSUFF |
210 | 243 | cp $LICENSE ../../setup/license-$UNPACKER.txt |
79 | 79 | <ClCompile> |
80 | 80 | <Optimization>Disabled</Optimization> |
81 | 81 | <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> |
82 | <PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="20.0";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
82 | <PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="21.0-testing";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
83 | 83 | <MinimalRebuild>false</MinimalRebuild> |
84 | 84 | <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> |
85 | 85 | <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> |
100 | 100 | <ClCompile> |
101 | 101 | <Optimization>Disabled</Optimization> |
102 | 102 | <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> |
103 | <PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="20.0";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
103 | <PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="21.0-testing";_DEBUG;_CONSOLE;DEBUG;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
104 | 104 | <MinimalRebuild>false</MinimalRebuild> |
105 | 105 | <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> |
106 | 106 | <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> |
119 | 119 | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
120 | 120 | <ClCompile> |
121 | 121 | <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> |
122 | <PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="20.0";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
122 | <PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="21.0-testing";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
123 | 123 | <ExceptionHandling>Sync</ExceptionHandling> |
124 | 124 | <RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
125 | 125 | <PrecompiledHeader>Use</PrecompiledHeader> |
150 | 150 | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
151 | 151 | <ClCompile> |
152 | 152 | <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> |
153 | <PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="20.0";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
153 | <PreprocessorDefinitions>WIN32;PACKAGE="nzbget";VERSION="21.0-testing";NDEBUG;_CONSOLE;_WIN32_WINNT=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
154 | 154 | <ExceptionHandling>Sync</ExceptionHandling> |
155 | 155 | <RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
156 | 156 | <PrecompiledHeader>Use</PrecompiledHeader> |
25 | 25 | |
26 | 26 | if not os.path.exists(nserv_datadir + '/medium.nzb'): |
27 | 27 | sizemb = int(pytest.config.getini('sample_medium')) |
28 | create_test_file(nserv_datadir + '/medium', sevenzip_bin, sizemb) | |
28 | create_test_file(nserv_datadir + '/medium', sevenzip_bin, sizemb, 50) | |
29 | 29 | |
30 | 30 | if not os.path.exists(nserv_datadir + '/large.nzb'): |
31 | 31 | sizemb = int(pytest.config.getini('sample_large')) |
32 | create_test_file(nserv_datadir + '/large', sevenzip_bin, sizemb) | |
32 | create_test_file(nserv_datadir + '/large', sevenzip_bin, sizemb, 50) | |
33 | 33 | |
34 | 34 | if not os.path.exists(nserv_datadir + '/medium.nzb') or not os.path.exists(nserv_datadir + '/large.nzb'): |
35 | 35 | if 0 != subprocess.call([nzbget_bin, '--nserv', '-d', nserv_datadir, '-v', '2', '-z', '500000', '-q']): |
50 | 50 | pytest.exit('Test file generation failed') |
51 | 51 | |
52 | 52 | |
53 | def create_test_file(bigdir, sevenzip_bin, sizemb): | |
53 | def create_test_file(bigdir, sevenzip_bin, sizemb, partmb): | |
54 | 54 | print('Preparing test file (' + str(sizemb) + 'MB)') |
55 | 55 | |
56 | 56 | if not os.path.exists(bigdir): |
57 | 57 | os.makedirs(bigdir) |
58 | 58 | |
59 | 59 | f = open(bigdir + '/' + str(sizemb) + 'mb.dat', 'wb') |
60 | for n in xrange(64 * sizemb / 1024): | |
61 | if n % 8 == 0: | |
62 | print('Writing block %i from %i' % (n, 64 * sizemb / 1024)) | |
63 | f.write(os.urandom(1024 * 1024 * 16)) | |
60 | for n in xrange(sizemb / partmb): | |
61 | print('Writing block %i from %i' % (n + 1, sizemb / partmb)) | |
62 | f.write(os.urandom(partmb * 1024 * 1024)) | |
64 | 63 | f.close() |
65 | 64 | |
66 | if 0 != subprocess.call([sevenzip_bin, 'a', bigdir + '/' + str(sizemb) + 'mb.7z', '-mx=0', '-v50m', bigdir + '/' + str(sizemb) + 'mb.dat']): | |
65 | if 0 != subprocess.call([sevenzip_bin, 'a', bigdir + '/' + str(sizemb) + 'mb.7z', '-mx=0', '-v' + str(partmb) + 'm', bigdir + '/' + str(sizemb) + 'mb.dat']): | |
67 | 66 | pytest.exit('Test file generation failed') |
68 | 67 | |
69 | 68 | os.remove(bigdir + '/' + str(sizemb) + 'mb.dat') |
0 | import os | |
1 | import shutil | |
2 | import subprocess | |
3 | import pytest | |
4 | ||
5 | ||
6 | @pytest.fixture(scope='session', autouse=True) | |
7 | def prepare_testdata(request): | |
8 | print('Preparing test data for "unpack"') | |
9 | ||
10 | nserv_datadir = pytest.config.getini('nserv_datadir') | |
11 | nzbget_bin = pytest.config.getini('nzbget_bin') | |
12 | sevenzip_bin = pytest.config.getini('sevenzip_bin') | |
13 | par2_bin = pytest.config.getini('par2_bin') | |
14 | ||
15 | if not os.path.exists(nserv_datadir): | |
16 | print('Creating nserv datadir') | |
17 | os.makedirs(nserv_datadir) | |
18 | ||
19 | if not os.path.exists(nserv_datadir + '/unpack-damaged.nzb'): | |
20 | create_test_file(nserv_datadir + '/unpack-damaged', sevenzip_bin, 3, 1) | |
21 | os.chdir(nserv_datadir + '/unpack-damaged') | |
22 | ||
23 | if 0 != subprocess.call([par2_bin, 'c', '-b100', 'unpackcrc-damaged.par2', '*']): | |
24 | pytest.exit('Test file generation failed') | |
25 | ||
26 | outf = open("3mb.7z.001","rb+") | |
27 | outf.seek(100000) | |
28 | outf.write(b"\x0a\x1b\x2c") | |
29 | outf.close() | |
30 | ||
31 | if not os.path.exists(nserv_datadir + '/unpackcrc-par.nzb'): | |
32 | create_test_file(nserv_datadir + '/unpackcrc-par', sevenzip_bin, 3, 1) | |
33 | os.chdir(nserv_datadir + '/unpackcrc-par') | |
34 | ||
35 | outf = open("3mb.7z.001","rb+") | |
36 | outf.seek(100000) | |
37 | outf.write(b"\x0a\x1b\x2c") | |
38 | outf.close() | |
39 | ||
40 | if 0 != subprocess.call([par2_bin, 'c', '-b100', 'unpackcrc-par.par2', '*']): | |
41 | pytest.exit('Test file generation failed') | |
42 | ||
43 | if not os.path.exists(nserv_datadir + '/unpackcrc-nopar.nzb'): | |
44 | create_test_file(nserv_datadir + '/unpackcrc-nopar', sevenzip_bin, 3, 1) | |
45 | os.chdir(nserv_datadir + '/unpackcrc-nopar') | |
46 | ||
47 | outf = open("3mb.7z.001","rb+") | |
48 | outf.seek(100000) | |
49 | outf.write(b"\x0a\x1b\x2c") | |
50 | outf.close() | |
51 | ||
52 | if 0 != subprocess.call([nzbget_bin, '--nserv', '-d', nserv_datadir, '-v', '2', '-z', '3000', '-q']): | |
53 | pytest.exit('Test file generation failed') | |
54 | ||
55 | ||
56 | def create_test_file(bigdir, sevenzip_bin, sizemb, partmb): | |
57 | print('Preparing test file (' + str(sizemb) + 'MB)') | |
58 | ||
59 | if not os.path.exists(bigdir): | |
60 | os.makedirs(bigdir) | |
61 | ||
62 | f = open(bigdir + '/' + str(sizemb) + 'mb.dat', 'wb') | |
63 | for n in xrange(sizemb / partmb): | |
64 | print('Writing block %i from %i' % (n + 1, sizemb / partmb)) | |
65 | f.write(os.urandom(partmb * 1024 * 1024)) | |
66 | f.close() | |
67 | ||
68 | if 0 != subprocess.call([sevenzip_bin, 'a', bigdir + '/' + str(sizemb) + 'mb.7z', '-mx=0', '-v' + str(partmb) + 'm', bigdir + '/' + str(sizemb) + 'mb.dat']): | |
69 | pytest.exit('Test file generation failed') | |
70 | ||
71 | os.remove(bigdir + '/' + str(sizemb) + 'mb.dat') | |
72 | ||
73 | ||
74 | def test_unpack_repair(nserv, nzbget): | |
75 | hist = nzbget.download_nzb('unpack-damaged.nzb', unpack = True) | |
76 | assert hist['Status'] == 'SUCCESS/UNPACK' | |
77 | ||
78 | def test_unpack_crcerror_par(nserv, nzbget): | |
79 | hist = nzbget.download_nzb('unpackcrc-par.nzb', unpack = True) | |
80 | assert hist['Status'] == 'FAILURE/UNPACK' | |
81 | ||
82 | def test_unpack_crcerror_nopar(nserv, nzbget): | |
83 | hist = nzbget.download_nzb('unpackcrc-nopar.nzb', unpack = True) | |
84 | assert hist['Status'] == 'FAILURE/UNPACK' |
20 | 20 | testdata_dir = nzbget_srcdir + '/tests/testdata' |
21 | 21 | if not os.path.exists(nserv_datadir + '/parchecker'): |
22 | 22 | shutil.copytree(testdata_dir +'/parchecker', nserv_datadir + '/parchecker') |
23 | if not os.path.exists(nserv_datadir + '/parchecker2'): | |
24 | shutil.copytree(testdata_dir +'/parchecker2', nserv_datadir + '/parchecker2') | |
23 | 25 | |
24 | 26 | if 0 != subprocess.call([nzbget_bin, '--nserv', '-d', nserv_datadir, '-v', '2', '-z', '3000', '-q']): |
25 | 27 | pytest.exit('Test file generation failed') |
0 | 0 | nzbget_options = ['ParCheck=auto', 'ParQuick=yes', 'PostStrategy=sequential'] |
1 | 1 | |
2 | 2 | def test_parchecker_healthy(nserv, nzbget): |
3 | hist = nzbget.download_nzb('parchecker.nzb') | |
3 | hist = nzbget.download_nzb('parchecker2.nzb') | |
4 | 4 | assert hist['Status'] == 'SUCCESS/HEALTH' |
5 | 5 | |
6 | 6 | def test_parchecker_repair(nserv, nzbget): |
7 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
7 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
9 | 9 | hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content) |
10 | 10 | assert hist['Status'] == 'SUCCESS/PAR' |
11 | 11 | |
12 | 12 | def test_parchecker_subject(nserv, nzbget): |
13 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
14 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
13 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
14 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
15 | 15 | nzb_content = nzb_content.replace('subject=""', 'subject="') |
16 | 16 | nzb_content = nzb_content.replace('" yEnc', '.dat yEnc') |
17 | 17 | hist = nzbget.download_nzb('parchecker.subject.nzb', nzb_content) |
18 | 18 | assert hist['Status'] == 'SUCCESS/PAR' |
19 | ||
20 | def test_parchecker_middle(nserv, nzbget): | |
21 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
22 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
23 | hist = nzbget.download_nzb('parchecker.middle.nzb', nzb_content) | |
24 | assert hist['Status'] == 'SUCCESS/PAR' | |
25 | ||
26 | def test_parchecker_last(nserv, nzbget): | |
27 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
28 | nzb_content = nzb_content.replace('<segment bytes="3000" number="18">parchecker2/testfile.7z.001?18=51000:200</segment>', '') | |
29 | hist = nzbget.download_nzb('parchecker.last.nzb', nzb_content, unpack=False) | |
30 | assert hist['Status'] == 'SUCCESS/HEALTH' | |
31 | ||
32 | def test_parchecker_last_unpack(nserv, nzbget): | |
33 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
34 | nzb_content = nzb_content.replace('<segment bytes="3000" number="18">parchecker2/testfile.7z.001?18=51000:200</segment>', '') | |
35 | hist = nzbget.download_nzb('parchecker.last.unpack.nzb', nzb_content, unpack=True) | |
36 | assert hist['Status'] == 'SUCCESS/UNPACK' |
0 | 0 | nzbget_options = ['ParCheck=force', 'ParQuick=yes', 'PostStrategy=sequential'] |
1 | 1 | |
2 | 2 | def test_parchecker_healthy(nserv, nzbget): |
3 | hist = nzbget.download_nzb('parchecker.nzb') | |
3 | hist = nzbget.download_nzb('parchecker2.nzb') | |
4 | 4 | assert hist['Status'] == 'SUCCESS/PAR' |
5 | 5 | |
6 | 6 | def test_parchecker_repair(nserv, nzbget): |
7 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
7 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
9 | 9 | hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content) |
10 | 10 | assert hist['Status'] == 'SUCCESS/PAR' |
11 | ||
12 | def test_parchecker_middle(nserv, nzbget): | |
13 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
14 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
15 | hist = nzbget.download_nzb('parchecker.middle.nzb', nzb_content) | |
16 | assert hist['Status'] == 'SUCCESS/PAR' | |
17 | ||
18 | def test_parchecker_last(nserv, nzbget): | |
19 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
20 | nzb_content = nzb_content.replace('<segment bytes="3000" number="18">parchecker2/testfile.7z.001?18=51000:200</segment>', '') | |
21 | hist = nzbget.download_nzb('parchecker.last.nzb', nzb_content) | |
22 | assert hist['Status'] == 'SUCCESS/PAR' |
0 | 0 | nzbget_options = ['ParCheck=manual', 'ParQuick=yes', 'PostStrategy=sequential'] |
1 | 1 | |
2 | 2 | def test_parchecker_healthy(nserv, nzbget): |
3 | hist = nzbget.download_nzb('parchecker.nzb') | |
3 | hist = nzbget.download_nzb('parchecker2.nzb') | |
4 | 4 | assert hist['Status'] == 'SUCCESS/HEALTH' |
5 | 5 | |
6 | 6 | def test_parchecker_repair(nserv, nzbget): |
7 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
7 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
9 | 9 | hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content) |
10 | 10 | assert hist['Status'] == 'WARNING/DAMAGED' |
11 | ||
12 | def test_parchecker_middle(nserv, nzbget): | |
13 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
14 | nzb_content = nzb_content.replace('<segment bytes="3000" number="16">parchecker2/testfile.7z.001?16=45000:3000</segment>', '') | |
15 | hist = nzbget.download_nzb('parchecker.middle.nzb', nzb_content) | |
16 | assert hist['Status'] == 'WARNING/DAMAGED' | |
17 | ||
18 | def test_parchecker_last(nserv, nzbget): | |
19 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
20 | nzb_content = nzb_content.replace('<segment bytes="3000" number="18">parchecker2/testfile.7z.001?18=51000:200</segment>', '') | |
21 | hist = nzbget.download_nzb('parchecker.last.nzb', nzb_content) | |
22 | assert hist['Status'] == 'SUCCESS/HEALTH' |
0 | 0 | nzbget_options = ['ParCheck=auto', 'ParQuick=yes', 'PostStrategy=balanced'] |
1 | 1 | |
2 | 2 | def test_parchecker_healthy(nserv, nzbget): |
3 | hist = nzbget.download_nzb('parchecker.nzb') | |
3 | hist = nzbget.download_nzb('parchecker2.nzb') | |
4 | 4 | assert hist['Status'] == 'SUCCESS/HEALTH' |
5 | 5 | |
6 | 6 | def test_parchecker_repair(nserv, nzbget): |
7 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
7 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
9 | 9 | hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content) |
10 | 10 | assert hist['Status'] == 'SUCCESS/PAR' |
0 | 0 | nzbget_options = ['ParCheck=force', 'ParQuick=yes', 'PostStrategy=balanced'] |
1 | 1 | |
2 | 2 | def test_parchecker_healthy(nserv, nzbget): |
3 | hist = nzbget.download_nzb('parchecker.nzb') | |
3 | hist = nzbget.download_nzb('parchecker2.nzb') | |
4 | 4 | assert hist['Status'] == 'SUCCESS/PAR' |
5 | 5 | |
6 | 6 | def test_parchecker_repair(nserv, nzbget): |
7 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
7 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
9 | 9 | hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content) |
10 | 10 | assert hist['Status'] == 'SUCCESS/PAR' |
0 | 0 | nzbget_options = ['ParCheck=manual', 'ParQuick=yes', 'PostStrategy=balanced'] |
1 | 1 | |
2 | 2 | def test_parchecker_healthy(nserv, nzbget): |
3 | hist = nzbget.download_nzb('parchecker.nzb') | |
3 | hist = nzbget.download_nzb('parchecker2.nzb') | |
4 | 4 | assert hist['Status'] == 'SUCCESS/HEALTH' |
5 | 5 | |
6 | 6 | def test_parchecker_repair(nserv, nzbget): |
7 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
7 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
9 | 9 | hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content) |
10 | 10 | assert hist['Status'] == 'WARNING/DAMAGED' |
0 | 0 | nzbget_options = ['ParCheck=force', 'ParQuick=no', 'PostStrategy=balanced'] |
1 | 1 | |
2 | 2 | def test_parchecker_healthy(nserv, nzbget): |
3 | hist = nzbget.download_nzb('parchecker.nzb') | |
3 | hist = nzbget.download_nzb('parchecker2.nzb') | |
4 | 4 | assert hist['Status'] == 'SUCCESS/PAR' |
5 | 5 | |
6 | 6 | def test_parchecker_repair(nserv, nzbget): |
7 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
7 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
8 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
9 | 9 | hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content) |
10 | 10 | assert hist['Status'] == 'SUCCESS/PAR' |
0 | 0 | nzbget_options = ['ParCheck=auto', 'ParQuick=no', 'PostStrategy=rocket'] |
1 | 1 | |
2 | 2 | def test_parchecker_healthy(nserv, nzbget): |
3 | hist = nzbget.download_nzb('parchecker.nzb') | |
3 | hist = nzbget.download_nzb('parchecker2.nzb') | |
4 | 4 | assert hist['Status'] == 'SUCCESS/HEALTH' |
5 | 5 | |
6 | 6 | def test_parchecker_repair(nserv, nzbget): |
7 | 7 | nzbget.api.pausepost(); |
8 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
9 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
8 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
9 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
10 | 10 | nzbget.append_nzb('parchecker.1.nzb', nzb_content, dupemode='FORCE') |
11 | 11 | nzbget.append_nzb('parchecker.2.nzb', nzb_content, dupemode='FORCE') |
12 | 12 | nzbget.append_nzb('parchecker.3.nzb', nzb_content, dupemode='FORCE') |
66 | 66 | assert hist['Status'] == 'WARNING/HEALTH' |
67 | 67 | |
68 | 68 | def test_renameparchecker_healthy(nserv, nzbget): |
69 | hist = nzbget.download_nzb('parchecker.nzb') | |
69 | hist = nzbget.download_nzb('parchecker2.nzb') | |
70 | 70 | assert hist['Status'] == 'SUCCESS/HEALTH' |
71 | 71 | |
72 | 72 | def test_parchecker_repair(nserv, nzbget): |
73 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
74 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
73 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
74 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
75 | 75 | hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content) |
76 | 76 | assert hist['Status'] == 'SUCCESS/PAR' |
77 | 77 | |
78 | 78 | def test_parchecker_dmp(nserv, nzbget): |
79 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
80 | nzb_content = nzb_content.replace('parchecker/testfile.par2?1=0:3000', 'parchecker/testfile.par2?1=0:3000!0') | |
81 | hist = nzbget.download_nzb('parchecker.damagedpar.nzb', nzb_content) | |
79 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
80 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.par2?1=0:3000', 'parchecker2/testfile.7z.par2?1=0:3000!0') | |
81 | hist = nzbget.download_nzb('parchecker2.damagedpar.nzb', nzb_content) | |
82 | 82 | assert hist['Status'] == 'SUCCESS/HEALTH' |
83 | 83 | for entry in nzbget.api.loadlog(hist['ID'], 0, 10000): |
84 | 84 | assert entry['Kind'] != 'ERROR', entry['Text'] |
66 | 66 | assert hist['Status'] == 'SUCCESS/UNPACK' |
67 | 67 | |
68 | 68 | def test_parchecker_healthy(nserv, nzbget): |
69 | hist = nzbget.download_nzb('parchecker.nzb') | |
69 | hist = nzbget.download_nzb('parchecker2.nzb') | |
70 | 70 | assert hist['Status'] == 'SUCCESS/HEALTH' |
71 | 71 | |
72 | 72 | def test_parchecker_repair(nserv, nzbget): |
73 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
74 | nzb_content = nzb_content.replace('parchecker/testfile.dat?1=0:3000', 'parchecker/testfile.dat?1=0:3000!0') | |
75 | hist = nzbget.download_nzb('parchecker.repair.nzb', nzb_content) | |
73 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
74 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.001?16=45000:3000', 'parchecker2/testfile.7z.001?16=45000:3000!0') | |
75 | hist = nzbget.download_nzb('parchecker2.repair.nzb', nzb_content) | |
76 | 76 | assert hist['Status'] == 'SUCCESS/PAR' |
77 | 77 | |
78 | 78 | def test_parchecker_dmp(nserv, nzbget): |
79 | nzb_content = nzbget.load_nzb('parchecker.nzb') | |
80 | nzb_content = nzb_content.replace('parchecker/testfile.par2?1=0:3000', 'parchecker/testfile.par2?1=0:3000!0') | |
81 | hist = nzbget.download_nzb('parchecker.damagedpar.nzb', nzb_content) | |
79 | nzb_content = nzbget.load_nzb('parchecker2.nzb') | |
80 | nzb_content = nzb_content.replace('parchecker2/testfile.7z.par2?1=0:3000', 'parchecker2/testfile.7z.par2?1=0:3000!0') | |
81 | hist = nzbget.download_nzb('parchecker2.damagedpar.nzb', nzb_content) | |
82 | 82 | assert hist['Status'] == 'SUCCESS/HEALTH' |
83 | 83 | for entry in nzbget.api.loadlog(hist['ID'], 0, 10000): |
84 | 84 | assert entry['Kind'] != 'ERROR', entry['Text'] |
0 | testfile.7z.001 2c4f3383 | |
1 | testfile.7z.002 153f2b08 | |
2 | testfile.7z.003 f4c85a77 | |
3 | testfile.nfo 0f294d41 |
Binary diff not shown
0 | rmediate destination directory | |
1 | names now include unique numbers to avoid several downloads with same | |
2 | name to use the same directory and interfere with each other; | |
3 | - when option "UnpackCleanupDisk" is active all archive files are now | |
4 | deleted from download directory without relying on output printed by | |
5 | unrar; this solves issues with non-ascii-characters in archive file | |
6 | names on some platforms and especially in combination with rar5; | |
7 | - improved handling of non-ascii characters in file names on windows; | |
8 | - added support for rar5-format when checking signatures of archives | |
9 | with non-standard file extensions; | |
10 | - small restructure in settings order: | |
11 | - combined sections "REMOTE CONTROL" and "PERMISSIONS" into one | |
12 | section with name "SECURITY"; | |
13 | - moved sections "CATEGORIES" and "RSS FEEDS" higher in the | |
14 | section list; | |
15 | - improved par-check: if main par2-file is corrupted and can not be | |
16 | loaded other par2-files are downloaded and then used as replacement | |
17 | for main par2-file; | |
18 | - if unpack did not find archive files the par-check is not requested | |
19 | anymore if par-rename was already done; | |
20 | - better handling of obfuscated nzb-files containing multiple files | |
21 | with same names; removed option "StrictParName" which was not working | |
22 | good with obfuscated files; if more par-files are required for repair | |
23 | the files with strict names are tried first and then other par-files; | |
24 | - added new scheduler commands "ActivateServer", "DeactivateServer" and | |
25 | "FetchFeed"; combined options "TaskX.DownloadRate" and "TaskX.Process" | |
26 | into one option "TaskX.Param", also used by new commands; | |
27 | - added status filter buttons to history page; | |
28 | - if unpack fails with write error (usually because of not enough space | |
29 | on disk) this is shown as status "Unpack: space" in web-interface; | |
30 | this unpack-status is handled as "success" by duplicate handling | |
31 | (no download of other duplicate); also added new unpack-status "wrong | |
32 | password" (only for rar5-archives); env.var. NZBPP_UNPACKSTATUS has | |
33 | two new possible values: 3 (write error) and 4 (wrong password); | |
34 | updated pp-script "EMail.py" to support new unpack-statuses; | |
35 | - fixed a potential seg. fault in a commonly used function; | |
36 | - added new option "TimeCorrection" to adjust conversion from system | |
37 | time to local time (solves issues with scheduler when using a | |
38 | binary compiled for other platform); | |
39 | - NZBIDs are now generated with more care avoiding numbering holes | |
40 | possible in previous versions; | |
41 | - fixed: invalid "Offset" passed to RPC-method "editqueue" or command | |
42 | line action "-E/--edit" could crash the program; | |
43 | - fixed: crash after downloading of an URL (happen only on certain systems); | |
44 | - fixed: restoring of settings didn't work for multi-sections (servers, | |
45 | categories, etc.) if they were empty; | |
46 | - fixed: choosing local files didn't work in Opera; | |
47 | - fixed: certain characters printed by pp-scripts could crash the | |
48 | program; | |
49 | - fixed: malformed nzb-file could cause a memory leak; | |
50 | - fixed: when a duplicate file was detected in collection it was | |
51 | automatically deleted (if option DupeCheck is active) but the | |
52 | total size of collection was not updated; | |
53 | - when deleting individual files the total count of files in collection | |
54 | was not updated; | |
55 | - fixed: when multiple nzb-files were added via URL (rss including) at | |
56 | the same time the info about category and priority could get lost for | |
57 | some of files; | |
58 | - fixed: if unpack fails the created destination directory was not | |
59 | automatically removed (only if option "InterDir" was active); | |
60 | - fixed scrolling to the top of page happening by clicking on items in | |
61 | downloads/history lists and on action-buttons in edit-download and | |
62 | history dialogs; | |
63 | - fixed potential buffer overflow in remote client; | |
64 | - improved error reporting when creation of temporary output file fails; | |
65 | - fixed: when deleting download, if all remaining queued files are | |
66 | par2-files the disk cleanup should not be performed, but it was | |
67 | sometimes; | |
68 | - fixed a potential problem in incorrect using of one library function. | |
69 | ||
70 | nzbget-11.0: | |
71 | - reworked concept of post-processing scripts: | |
72 | - multiple scripts can be assigned to each nzb-file; | |
73 | - all assigned scripts are executed after the nzb-file is | |
74 | downloaded and internally processed (unpack, repair); | |
75 | - option <PostProcess> is obsolete; | |
76 | - new option <ScriptDir> sets directory where all pp-scripts must | |
77 | be stored; | |
78 | - new option <DefScript> sets the default list of pp-scripts to | |
79 | be assigned to nzb-file when it's added to queue; | |
80 | - new option <CategoryX.DefScript> to set the default list of | |
81 | pp-scripts on a category basis; | |
82 | - the execution order of pp-scripts can be set using new option | |
83 | <ScriptOrder>; | |
84 | - there are no separate configuration files for pp-scripts; | |
85 | - configuration options and pp-parameters are defined in the | |
86 | pp-scripts; | |
87 | - script configuration options are saved in nzbget configuration | |
88 | file (nzbget.conf); | |
89 | - changed parameters list of RPC-methods <loadconfig> and | |
90 | <saveconfig>; | |
91 | - new RPC-method <configtemplates> returns configuration | |
92 | descriptions for the program and for all pp-scripts; | |
93 | - configuration of all scripts can be done in web-interface; | |
94 | - the pp-scripts assigned to a particular nzb-file can be viewed | |
95 | and changed in web-interface on page <pp-parameters> in the | |
96 | edit download dialog; | |
97 | - option <PostPauseQueue> renamed to <ScriptPauseQueue> (the old | |
98 | name is still recognized); | |
99 | - new option <ConfigTemplate> to define the location of template | |
100 | configuration file (in previous versions it must be always | |
101 | stored in <WebDir>); | |
102 | - history dialog shows status of every script; | |
103 | - the old example post-processing script replaced with two new scripts: | |
104 | - EMail.py - sends E-Mail notification; | |
105 | - Logger.py - saves the full post-processing log of the job into | |
106 | file _postprocesslog.txt; | |
107 | - both pp-scripts are written in python and work on Windows too | |
108 | (in addition to Linux, Mac, etc.); | |
109 | - added possibility to set post-processing parameters for history items: | |
110 | - pp-parameters can now be viewed and changed in history dialog | |
111 | in web-interface; | |
112 | - useful before post-processing again; | |
113 | - new action <HistorySetParameter> in RPC-method <editqueue>; | |
114 | - new action <O> in remote command <--edit/-E> for history items | |
115 | (subcommand <H>); | |
116 | - added new feature <split download> which creates new download from | |
117 | selected files of source download; | |
118 | - new command <Split> in web-interface in edit download dialog | |
119 | on page <Files>; | |
120 | - new action <S> in remote command <--edit/-E>; | |
121 | - new action <FileSplit> in JSON-/XML-RPC method <editqueue>; | |
122 | - added support for manual par-check: | |
123 | - if option <ParCheck> is set to <Manual> and a damaged download | |
124 | is detected the program downloads all par2-files but doesn't | |
125 | perform par-check; the user must perform par-check/repair | |
126 | manually then (possibly on another, faster computer); | |
127 | - old values <yes/no> of option <ParCheck> renamed to <Force> | |
128 | and <Auto> respectively; | |
129 | - when set to <Force> all par2-files are always downloaded; | |
130 | - removed option <LoadPars> since its functionality is now | |
131 | covered by option <ParCheck>; | |
132 | - result of par-check can now have new value <Manual repair | |
133 | necessary>; | |
134 | - field <ParStatus> in RPC-method <history> can have new value | |
135 | <MANUAL>; | |
136 | - parameter <NZBPP_PARSTATUS> for pp-script can have new value | |
137 | <4 = manual repair necessary>; | |
138 | - when download is resumed in web-interface the option <ParCheck=Force> | |
139 | is respected and all par2-files are resumed (not only main par2-file); | |
140 | - automatic deletion of backup-source files after successful par-repair; | |
141 | important when repairing renamed rar-files since this could cause | |
142 | failure during unpack; | |
143 | - par-checker and renamer now add messages into the log of pp-item | |
144 | (like unpack- and pp-scripts-messages); these message now appear in | |
145 | the log created by scripts Logger.py and EMail.py; | |
146 | - when a nzb-file is added via web-interface or via remote call the | |
147 | file is now put into incoming nzb-directory (option "NzbDir") and | |
148 | then scanned; this has two advantages over the old behavior when the | |
149 | file was parsed directly in memory: | |
150 | - the file serves as a backup for troubleshootings; | |
151 | - the file is processed by nzbprocess-script (if defined in | |
152 | option "NzbProcess") making the pre-processing much easier; | |
153 | - new env-var parameters are passed to NzbProcess-script: NZBNP_NZBNAME, | |
154 | NZBNP_CATEGORY, NZBNP_PRIORITY, NZBNP_TOP, NZBNP_PAUSED; | |
155 | - new commands for use in NzbProcess-scripts: "[NZB] TOP=1" to add nzb | |
156 | to the top of queue and "[NZB] PAUSED=1" to add nzb-file in paused state; | |
157 | - reworked post-processor queue: | |
158 | - only one job is created for each nzb-file; no more separate | |
159 | jobs are created for par-collections within one nzb-file; | |
160 | - option <AllowReProcess> removed; a post-processing script is | |
161 | called only once per nzb-file, this behavior cannot be altered | |
162 | anymore; | |
163 | - with a new feature <Split> individual par-collections can be | |
164 | processed separately in a more effective way than before | |
165 | - improved unicode (utf8) support: | |
166 | - non-ascii characters are now correctly transferred via JSON-RPC; | |
167 | - correct displaying of nzb-names and paths in web-interface; | |
168 | - it is now possible to use non-ascii characters on settings page | |
169 | for option values (such as paths or category names); | |
170 | - improved unicode support in XML-RPC and JSON-RPC; | |
171 | - if username and password are defined for a news-server the | |
172 | authentication is now forced (in previous versions the authentication | |
173 | was performed only if requested by server); needed for servers | |
174 | supporting both anonymous (restricted) and authorized (full access) | |
175 | accounts; | |
176 | - added option <ExtCleanupDisk> to automatically delete unwanted files | |
177 | (with specified extensions or names) after successful par-check or unpack; | |
178 | - improvement in JSON-/XML-RPC: | |
179 | - all ID fields including NZBID are now persistent and remain | |
180 | their values after restart; | |
181 | - this allows for third-party software to identify nzb-files by | |
182 | ID; | |
183 | - method <history> now returns ID of NZB-file in the field | |
184 | <NZBID>; | |
185 | - in versions up to 0.8.0 the field <NZBID> was used to identify | |
186 | history items in the edit-commands <HistoryDelete>, | |
187 | <HistoryReturn>, <HistoryProcess>; since version 9 field <ID> | |
188 | is used for this purpose; in versions 9-10 field <NZBID> still | |
189 | existed and had the same value as field <ID> for compatibility | |
190 | with version 0.8.0; the compatibility is not provided anymore; | |
191 | this change was needed to provide a consistent using of field | |
192 | <NZBID> across all RPC-methods; | |
193 | - added support for rar-files with non-standard extensions (such as | |
194 | .001, etc.); | |
195 | - added functions to backup and restore settings from web-interface; | |
196 | when restoring it's possible to choose what sections to restore | |
197 | (for example only news servers settings or only settings of a | |
198 | certain pp-script) or restore the whole configuration; | |
199 | - new option "ControlUsername" to define login user name (if you don't | |
200 | like default username "nzbget"); | |
201 | - if a communication error occurs in web-interface, it retries multiple | |
202 | times before giving up with an error message; | |
203 | - the maximum number of download threads are now managed automatically | |
204 | taking into account the number of allowed connections to news servers; | |
205 | removed option <ThreadLimit>; | |
206 | - pp-scripts terminated with unknown status are now considered failed | |
207 | (status=FAILURE instead of status=UNKNOWN); | |
208 | - new parameter (env. var) <NZBPP_NZBID> is passed to pp_scripts and | |
209 | contains an internal ID of NZB-file; | |
210 | - improved thread synchronisation to avoid (short-time) lockings of | |
211 | the program during creation of destination files; | |
212 | - more detailed error message if a directory could not be created | |
213 | (<DstDir>, <NzbDir>, etc.); the message includes error text reported | |
214 | by OS such as <permission denied> or similar; | |
215 | - when unpacking the unpack start time is now measured after receiving | |
216 | of unrar copyright message; this provides better unpack time | |
217 | estimation in a case when user uses unpack-script to do some things | |
218 | before executing unrar (for example sending Wake-On-Lan message to | |
219 | the destination NAS); it works with unrar only, it's not possible | |
220 | with 7-Zip because it buffers printed messages; | |
221 | - when the program is reloaded, a message with version number is | |
222 | printed like on start; | |
223 | - configuration can now be saved in web-interface even if there were | |
224 | no changes made but if obsolete or invalid options were detected in | |
225 | the config file; the saving removes invalid entries from config file; | |
226 | - option <ControlPassword> can now be set to en empty value to disable | |
227 | authentication; useful if nzbget works behind other web-server with | |
228 | its own authentication; | |
229 | - when deleting downloads via web-interface a proper hint regarding | |
230 | deleting of already downloaded files from disk depending on option | |
231 | <DeleteCleanupDisk> is displayed; | |
232 | - if a news-server returns empty or bad article (this may be caused | |
233 | by errors on the news server), the program tries again from the same | |
234 | or other servers (in previous versions the article was marked as | |
235 | failed without other download attempts); | |
236 | - when a nzb-file whose name ends with ".queued" is added via web- | |
237 | interface the ".queued"-part is automatically removed; | |
238 | - small improvement in multithread synchronization of download queue; | |
239 | - added link to catalog of pp-scripts to web-interface; | |
240 | - updated forum URL in about dialog in web-interface; | |
241 | - small correction in a log-message: removed <Request:> from message | |
242 | <Request: Queue collection...>; | |
243 | - removed option "ProcessLogKind"; scripts should use prefixes ([INFO], | |
244 | [DETAIL], etc); messages printed without prefixes are added as [INFO]; | |
245 | - removed option "AppendNzbDir"; if it was disabled that caused problems | |
246 | in par-checker and unpacker; the option is now assumed always active; | |
247 | - removed option "RenameBroken"; it caused problems in par-checker | |
248 | (the option existed since early program versions before the par-check | |
249 | was added); | |
250 | - configure-script now defines "SIGCHLD_HANDLER" by default on all | |
251 | systems including BSD; this eliminates the need of configure- | |
252 | parameter "--enable-sigchld-handler" on 64-Bit BSD; the trade-off: | |
253 | 32-Bit BSD now requires "--disable-sigchld-handler"; | |
254 | - improved configure-script: defining of symbol "FILE_OFFSET_BITS=64", | |
255 | required on some systems, is not necessary anymore; | |
256 | - fixed: in the option "NzbAddedProcess" the env-var parameter with | |
257 | nzb-name was passed in "NZBNA_NAME", should be "NZBNA_NZBNAME"; | |
258 | the old parameter name "NZBNA_NAME" is still supported for | |
259 | compatibility; | |
260 | - fixed: download time in statistics were incorrect if the computer | |
261 | was put into standby (thanks Frank Kuypers for the patch); | |
262 | - fixed: when option <InterDir> was active and the download after | |
263 | unpack contained rar-file with the same name as one of original | |
264 | files (sometimes happen with included subtitles) the original | |
265 | rar-file was kept with name <.rar_duplicate1> even if the option | |
266 | <UnpackCleanupDisk> was active; | |
267 | - fixed: failed to read download queue from disk if post-processing | |
268 | queue was not empty; | |
269 | - fixed: when a duplicate file was detected during download the | |
270 | program could hang; | |
271 | - fixed: symbol <DISABLE_TLS> must be defined in project settings; | |
272 | defining it in <win32.h> didn't work properly (Windows only); | |
273 | - fixed: crash when adding malformed nzb-files with certain | |
274 | structure (Windows only); | |
275 | - fixed: by deleting of a partially downloaded nzb-file from queue, | |
276 | when the option <DeleteCleanupDisk> was active, the file | |
277 | <_brokenlog.txt> was not deleted preventing the directory from | |
278 | automatic deletion; | |
279 | - fixed: if an error occurs when a RPC-client or web-browser | |
280 | communicates with nzbget the program could crash; | |
281 | - fixed: if the last file of collection was detected as duplicate | |
282 | after the download of the first article the file was deleted from | |
283 | queue (that's OK) but the post-processing was not triggered | |
284 | (that's a bug); | |
285 | - fixed: support for splitted files (.001, .002, etc.) were broken. | |
286 | ||
287 | nzbget-10.2: | |
288 | - fixed potential segfault which could happen with file paths longer | |
289 | than 1024 characters; | |
290 | - fixed: when options <DirectWrite> and <ContinuePartial> were both | |
291 | active, a restart or reload of the program during download may cause | |
292 | damaged files in the active download; | |
293 | - increased width of speed indication ui-element to avoid layout | |
294 | breaking on some linux-browsers; | |
295 | - fixed a race condition in unpacker which could lead to a segfault | |
296 | (although the chances were low because the code wasn't executed often). | |
297 | ||
298 | nzbget-10.1: | |
299 | - fixed: articles with decoding errors (incomplete or damaged posts) | |
300 | caused infinite retry-loop in downloader. | |
301 | ||
302 | nzbget-10.0: | |
303 | - added built-in unpack: | |
304 | - rar and 7-zip formats are supported (via external Unrar and | |
305 | 7-Zip executables); | |
306 | - new options <Unpack>, <UnpackPauseQueue>, <UnpackCleanupDisk>, | |
307 | <UnrarCmd>, <SevenZipCmd>; | |
308 | - web-interface now shows progress and estimated time during | |
309 | unpack (rar only; for 7-Zip progress is not available due to | |
310 | limitations of 7-Zip); | |
311 | - when built-in unpack is enabled, the post-processing script is | |
312 | called after unpack and possibly par-check/repair (if needed); | |
313 | - for nzb-files containing multiple collections (par-sets) the | |
314 | post-processing script is called only once, after the last | |
315 | par-set; | |
316 | - new parameter <NZBPP_UNPACKSTATUS> passed to post-processing | |
317 | script; | |
318 | - if the option <AllowReProcess> is enabled the post-processing- | |
319 | script is called after each par-set (as in previous versions); | |
320 | - example post-processing script updated: removed unrar-code, | |
321 | added check for unpack status; | |
322 | - new field <UnpackStatus> in result of RPC-method <history>; | |
323 | - history-dialog in web-interface shows three status: par-status, | |
324 | unpack-status, script-status; | |
325 | - with two built-in special post-processing parameters <*Unpack:> | |
326 | and <*Unpack:Password> the unpack can be disabled for individual | |
327 | nzb-file or the password can be set; | |
328 | - built-in special post-processing parameters can be set via web- | |
329 | interface on page <PP-Parameters> (when built-in unpack is | |
330 | enabled); | |
331 | - added support for HTTPS to the built-in web-server (web-interface and | |
332 | XML/JSON-RPC): | |
333 | - new options <SecureControl>, <SecurePort>, <SecureCert> and | |
334 | <SecureKey>; | |
335 | - module <TLS.c/h> completely rewritten with support for server- | |
336 | side sockets, newer versions of GnuTLS, proper thread lockings | |
337 | in OpenSSL; | |
338 | - improved the automatic par-scan (option <ParScan=auto>) to | |
339 | significantly reduce the verify-time in some common cases with renamed | |
340 | rar-files: | |
341 | - the extra files are scanned in an optimized order; | |
342 | - the scan stops when all missings files are found; | |
343 | - added fast renaming of intentionally misnamed (rar-) files: | |
344 | - the new renaming algorithm doesn't require full par-scan and | |
345 | restores original filenames in just a few seconds, even on very | |
346 | slow computers (NAS, media players, etc.); | |
347 | - the fast renaming is performed automatically when requested by | |
348 | the built-in unpacker (option <Unpack> must be active); | |
349 | - added new option <InterDir> to put intermediate files during download | |
350 | into a separate directory (instead of storing them directly in | |
351 | destination directory (option <DestDir>): | |
352 | - when nzb-file is completely (successfully) downloaded, repaired | |
353 | (if neccessary) and unpacked the files are moved to destination | |
354 | directory (option <DestDir> or <CategoryX.DestDir>); | |
355 | - intermediate directory can significantly improve unpack | |
356 | performance if it is located on a separate physical hard drive; | |
357 | - added new option <ServerX.Cipher> to manually select cipher for | |
358 | encrypted communication with news server: | |
359 | - manually choosing a faster cipher (such as <RC4>) can | |
360 | significantly improve performance (if CPU is a limiting factor); | |
361 | - major improvements in news-server/connection management (main and fill | |
362 | servers): | |
363 | - if download of article fails, the program tries all servers of | |
364 | the same level before trying higher level servers; | |
365 | - this ensures that fill servers are used only if all main servers | |
366 | fail; | |
367 | - this makes the configuring of multiple servers much easier than | |
368 | before: in most cases the simple configuration of level 0 for | |
369 | all main servers and level 1 for all fill servers suffices; | |
370 | - in previous versions the level was increased immediately after | |
371 | the first tried server of the level failed; to make sure all | |
372 | main servers were tried before downloading from fill servers it | |
373 | was required to create complex server configurations with | |
374 | duplicates; these configurations were still not as effective as | |
375 | now; | |
376 | - do not reconnect on <article/group not found> errors since this | |
377 | doesn't help but unnecessary increases CPU load and network | |
378 | traffic; | |
379 | - removed option <RetryOnCrcError>; it's not required anymore; | |
380 | - new option <ServerX.Group> allows more flexible configuration | |
381 | of news servers when using multiple accounts on the same server; | |
382 | with this option it's also possible to imitate the old server | |
383 | management behavior regarding levels; | |
384 | - news servers configuration is now less error-prone: | |
385 | - the option <ServerX.Level> is not required to start from <0> and | |
386 | when several news servers are configured the Levels can be any | |
387 | integers - the program sorts the servers and corrects the Levels | |
388 | to 0,1,2,etc. automatically if needed; | |
389 | - when option <ServerX.Connections> is set to <0> the server is | |
390 | ignored (in previous version such a server could cause hanging | |
391 | when the program was trying to go to the next level); | |
392 | - if no news servers are defined (or all definitions are invalid) | |
393 | a warning is printed to inform that the download is not | |
394 | possible; | |
395 | - categories can now have their own destination directories; new option | |
396 | <CategoryX.DestDir>; | |
397 | - new feature <Pause for X Minutes> in web-interface; new XML-/JSON-RPC | |
398 | method <scheduleresume>; | |
399 | - improved the handling of hanging connections: if a connection hangs | |
400 | longer than defined by option <ConnectionTimeout> the program tries to | |
401 | gracefully close connection first (this is new); if it still hangs | |
402 | after <TerminateTimeout> the download thread is terminated as a last | |
403 | resort (as in previous versions); | |
404 | - added automatic speed meter recalibration to recover after possible | |
405 | synchronization errors which can occur when the option <AccurateRate> | |
406 | is not active; this makes the default (less accurate but fast) speed | |
407 | meter almost as good as the accurate one; important when speed | |
408 | throttling is active; | |
409 | - when the par-checked requests more par-files, they get an extra | |
410 | priority and are downloaded before other files regardless of their | |
411 | priorities; this is needed to avoid hanging of par-checker-job if a | |
412 | file with a higher priority gets added to queue during par-check; | |
413 | - when post-processing-parameters are passed to the post-processing | |
414 | script a second version of each parameter with a normalized parameter- | |
415 | name is passed in addition to the original parameter name; in the | |
416 | normalized name the special characters <*> and <:> are replaced with | |
417 | <_> and all characters are passed in upper case; this is important for | |
418 | internal post-processing-parameters (*Unpack:=yes/no) which include | |
419 | special characters; | |
420 | - warning <Non-nzbget request received> now is not printed when the | |
421 | connection was aborted before the request signature was read; | |
422 | - changed formatting of remaining time for post-processing to short | |
423 | format (as used for remaining download time); | |
424 | - added link to article <Performance tips> to settings tab on web- | |
425 | interface; | |
426 | - removed hint <Post-processing script may have moved files elsewhere> | |
427 | from history dialog since it caused more questions than helped; | |
428 | - changed default value for option <ServerX.JoinGroup> to <no>; most | |
429 | news servers nowadays do not require joining the group and many | |
430 | servers do not keep headers for many groups making the join-command | |
431 | fail even if the articles still can be successfully downloaded; | |
432 | - small change in example post-processing script: message <Deleting | |
433 | source ts-files> are now printed only if ts-files really existed; | |
434 | - improved configure-script: | |
435 | - libs which are added via pkgconfig are now put into LIBS instead | |
436 | of LDFLAGS - improves compatibility with newer Linux linkers; | |
437 | - OpenSSL libs/includes are now added using pkgconfig to better | |
438 | handle dependencies; | |
439 | - additional check for libcrypto (part of OpenSSL) ensures the | |
440 | library is added to linker command even if pkgconfig is not | |
441 | used; | |
442 | - adding of local files via web-interface now works in IE10; | |
443 | - if an obsolete option is found in the config file a warning is printed | |
444 | instead of an error and the program is not paused anymore; | |
445 | - fixed: the reported line numbers for configuration errors were | |
446 | sometimes inaccurate; | |
447 | - fixed warning <file glyphicons-halflings.png not found>; | |
448 | - fixed: some XML-/JSON-RPC methods may return negative values for file | |
449 | sizes between 2-4GB; this had also influence on web-interface. | |
450 | - fixed: if an external program (unrar, pp-script, etc.) could not be | |
451 | started, the execute-function has returned code 255 although the code | |
452 | -1 were expected in this case; this could break designed post- | |
453 | processing flow; | |
454 | - fixed: some characters with codes below 32 were not properly encoded | |
455 | in JSON-RPC; sometimes output from unrar contained such characters | |
456 | and could break web-interface; | |
457 | - fixed: special characters (quotation marks, etc.) in unpack password | |
458 | and in configuration options were not displayed properly and could be | |
459 | discarded on saving; | |
460 | ||
461 | nzbget-9.1: | |
462 | - added full par-scan feature needed to par-check/repair files which | |
463 | were renamed after creation of par-files: | |
464 | - new option <ParScan> to activate full par-scan (always or automatic); | |
465 | the automatic full par-scan activates if missing files are detected | |
466 | during par-check, this avoids unnecessary full scan for normal | |
467 | (not renamed) par sets; | |
468 | - improved the post-processing script to better handle renamed rar-files; | |
469 | - replaced a browser error message when trying to add local files in | |
470 | IE9 with a better message dialog; | |
471 | ||
472 | nzbget-9.0: | |
473 | - changed version naming scheme by removing the leading zero: current | |
474 | version is now called 9.0 instead of 0.9.0 (it's really the 9th major | |
475 | version of the program); | |
476 | - added built-in web-interface: | |
477 | - completely new designed and written from scratch; | |
478 | - doesn't require a separate web-server; | |
479 | - doesn't require PHP; | |
480 | - 100% Javascript application; the built-in web-server hosts only | |
481 | static files; the javascript app communicates with NZBGet via | |
482 | JSON-RPC; | |
483 | - very efficient usage of server resources (CPU and memory); | |
484 | - easy installation. Since neither a separate web-server nor PHP | |
485 | are needed the installation of new web-interface is very easy. | |
486 | Actually it is performed automatically when you "make install" | |
487 | or "ipkg install nzbget"; | |
488 | - modern look: better layout, popup dialogs, nice animations, | |
489 | hi-def icons; | |
490 | - built-in phone-theme (activates automatically); | |
491 | - combined view for "currently downloading", "queued", "currently | |
492 | processing" and "queued for processing"; | |
493 | - renaming of nzb-files; | |
494 | - multiselect with multiedit or merge of downloads; | |
495 | - fast paging in the lists (downloads, history, messages); | |
496 | - search box for filtering in the lists (downloads, history, messages) | |
497 | and in settings; | |
498 | - adding nzb-files to download queue was improved in several ways: | |
499 | - add multiple files at once. The "select files dialog" allows | |
500 | to select multiple files; | |
501 | - add files using drag and drop. Just drop the files from your | |
502 | file manager directly into the web-browser; | |
503 | - add files via URLs. Put the URL and NZBGet downloads the | |
504 | nzb-file and adds it to download queue automatically; | |
505 | - the priority of nzb-file can now be set when adding local-files | |
506 | or URLs; | |
507 | - the history can be cleared completely or selected items can be removed; | |
508 | - file mode is now nzb-file related; | |
509 | - added the ability to queue URLs: | |
510 | - the program automatically downloads nzb-files from given URLs | |
511 | and put them to download queue. | |
512 | - when multiple URLs are added in a short time, they are put | |
513 | into a special URL-queue. | |
514 | - the number of simultaneous URL-downloads are controlled via | |
515 | new option UrlConnections. | |
516 | - with the new option ReloadUrlQueue can be controlled if the URL-queue | |
517 | should be reloaded after the program is restarted (if the URL-queue | |
518 | was not empty). | |
519 | - new switch <-U> for remote-command <--append/-A> to queue an URL. | |
520 | - new subcommand <-U> in the remote command <--list/-L> prints the | |
521 | current URL-queue. | |
522 | - if URL-download fails, the URL is moved into history. | |
523 | - with subcommand <-R> of command <--edit> the failed URL can be | |
524 | returned to URL-queue for redownload. | |
525 | - the remote command <--list/-L> for history can now print the infos | |
526 | for URL history items. | |
527 | - new XML/JSON-RPC command <appendurl> to add an URL or multiple | |
528 | URLs for download. | |
529 | - new XML/JSON-RPC command <urlqueue> returns the items from the | |
530 | URL-queue. | |
531 | - the XML/JSON-RPC command <history> was extended to provide | |
532 | infos about URL history items. | |
533 | - the URL-queue obeys the pause-state of download queue. | |
534 | - the URL-downloads support HTTP and HTTPS protocols; | |
535 | - added new field <name> to nzb-info-object. | |
536 | - it is initially set to the cleaned up name of the nzb-file. | |
537 | - the renaming of the group changes this field. | |
538 | - all RPC-methods related to nzb-object return the new field, the | |
539 | old field <NZBNicename> is now deprecated. | |
540 | - the option <MergeNZB> now checks the <name>-field instead of | |
541 | <nzbfilename> (the latter is not changed when the nzb is renamed). | |
542 | - new env-var-parameter <NZBPP_NZBNAME> for post-processing script; | |
543 | - added options <GN> and <FN> for remote command <--edit/-E>. With these | |
544 | options the name of group or file can be used in edit-command instead | |
545 | of file ID; | |
546 | - added support for regular expressions (POSIX ERE Syntax) in remote | |
547 | commands <--list/-L> and <--edit/-E> using new subcommands <GR> and <FR>; | |
548 | - improved performance of RPC-command <listgroups>; | |
549 | - added new command <FileReorder> to RPC-method <editqueue> to set the | |
550 | order of individual files in the group; | |
551 | - added gzip-support to built-in web-server (including RPC); | |
552 | - added processing of http-request <OPTIONS> in RPC-server for better | |
553 | support of cross domain requests; | |
554 | - renamed example configuration file and postprocessing script to make | |
555 | the installation easier; | |
556 | - improved the automatic installation (<make install>) to install all | |
557 | necessary files (not only the binary as it was before); | |
558 | - improved handling of configuration errors: the program now does not | |
559 | terminate on errors but rather logs all of them and uses default option values; | |
560 | - added new XML/JSON-RPC methods <config>, <loadconfig> and <saveconfig>; | |
561 | - with active option <AllowReProcess> the NZB considered completed even if | |
562 | there are paused non-par-files (the paused non-par-files are treated the | |
563 | same way as paused par-files): as a result the reprocessable script is called; | |
564 | - added subcommand <W> to remote command <-S/--scan> to scan synchronously | |
565 | (wait until scan completed); | |
566 | - added parameter <SyncMode> to XML/JSON-RPC method <scan>; | |
567 | - the command <Scan> in web-interface now waits for completing of scan | |
568 | before reporting the status; | |
569 | - added remote command <--reload/-O> and JSON/XML-RPC method <reload> to | |
570 | reload configuration from disk and reintialize the program; the reload | |
571 | can be performed from web-interface; | |
572 | - JSON/XML-RPC method <append> extended with parameter <priority>; | |
573 | - categories available in web-interface are now configured in program | |
574 | configuration file (nzbget.conf) and can be managed via web-interface | |
575 | on settings page; | |
576 | - updated descriptions in example configuration file; | |
577 | - changes in configuration file: | |
578 | - renamed options <ServerIP>, <ServerPort> and <ServerPassword> to | |
579 | <ControlIP>, <ControlPort> and <ControlPassword> to avoid confusion | |
580 | with news-server options <ServerX.Host>, <ServerX.Port> and | |
581 | <ServerX.Password>; | |
582 | - the old option names are still recognized and are automatically | |
583 | renamed when the configuration is saved from web-interface; | |
584 | - also renamed option <$MAINDIR> to <MainDir>; | |
585 | - extended remote command <--append/-A> with optional parameters: | |
586 | - <T> - adds the file/URL to the top of queue; | |
587 | - <P> - pauses added files; | |
588 | - <C category-name> - sets category for added nzb-file/URL; | |
589 | - <N nzb-name> - sets nzb filename for added URL; | |
590 | - the old switches <--category/-K> and <--top/-T> are deprecated | |
591 | but still supported for compatibility; | |
592 | - renamed subcommand <K> of command <--edit/-E> to <C> (the old | |
593 | subcommand is still supported for compatibility); | |
594 | - added new option <NzbAddedProcess> to setup a script called after | |
595 | a nzb-file is added to queue; | |
596 | - added debug messages for speed meter; | |
597 | - improved the startup script <nzbgetd> so it can be directly used in | |
598 | </etc/init.d> without modifications; | |
599 | - fixed: after renaming of a group, the new name was not displayed | |
600 | by remote commands <-L G> and <-C in curses mode>; | |
601 | - fixed incompatibility with OpenSLL 1.0 (thanks to OpenWRT team | |
602 | for the patch); | |
603 | - fixed: RPC-method <log(0, IdFrom)> could return wrong results if | |
604 | the log was filtered with options <XXXTarget>; | |
605 | - fixed: free disk space calculated incorrectly on some OSes; | |
606 | - fixed: unrar failure was not always properly detected causing the | |
607 | post-processing to delete not yet unpacked rar-files; | |
608 | - fixed compilation error on recent linux versions; | |
609 | - fixed compilation error on older systems; | |
610 | ||
611 | nzbget-0.8.0: | |
612 | - added priorities; new action <I> for remote command <--edit/-E> to set | |
613 | priorities for groups or individual files; new actions <SetGroupPriority> | |
614 | and <SetFilePriority> of RPC-command <editqueue>; remote command | |
615 | <--list/-L> prints priorities and indicates files or groups being | |
616 | downloaded; ncurses-frontend prints priorities and indicates files or | |
617 | groups being download; new command <PRIORITY> to set priority of nzb-file | |
618 | from nzbprocess-script; RPC-commands <listgroups> and <listfiles> return | |
619 | priorities and indicate files or groups being downloaded; | |
620 | - added renaming of groups; new subcommand <N> for command <--edit/-E>; new | |
621 | action <SetName> for RPC-method <editqueue>; | |
622 | - added new option <AccurateRate>, which enables syncronisation in speed | |
623 | meter; that makes the indicated speed more accurate by eliminating | |
624 | measurement errors possible due thread conflicts; thanks to anonymous | |
625 | nzbget user for the patch; | |
626 | - improved the parsing of filename from article subject; | |
627 | - option <DirectWrite> now efficiently works on Windows with NTFS partitions; | |
628 | - added URL-based-authentication as alternative to HTTP-header authentication | |
629 | for XML- and JSON-RPC; | |
630 | - fixed: nzb-files containing umlauts and other special characters could not | |
631 | be parsed - replaced XML-Reader with SAX-Parser - only on POSIX (not on | |
632 | Windows); | |
633 | - fixed incorrect displaying of group sizes bigger than 4GB on many 64-bit | |
634 | OSes; | |
635 | - fixed a bug causing error on decoding of input data in JSON-RPC; | |
636 | - fixed a compilation error on some windows versions; | |
637 | - fixed: par-repair could fail when the filenames were not correctly parsed | |
638 | from article subjects; | |
639 | - fixed a compatibility issue with OpenBSD (and possibly other BSD based | |
640 | systems); added the automatic configuring of required signal handling logic | |
641 | to better support BSD without breaking the compatibility with certain Linux | |
642 | systems; | |
643 | - corrected the address of Free Software Foundation in copyright notice. | |
644 | ||
645 | nzbget-0.7.0: | |
646 | - added history: new option <KeepHistory>, new remote subcommand <H> for | |
647 | commands <L> (list history entries) and <E> (delete history entries, | |
648 | return history item, postprocess history item), new RPC-command <History> | |
649 | and subcommands <HistoryDelete>, <HistoryReturn>, <HistoryProcess> for | |
650 | command <EditQueue>; | |
651 | - added support for JSON-P (extension of JSON-RPC); | |
652 | - changed the result code returning status <ERROR> for postprocessing script | |
653 | from <1> to <94> (needed to show the proper script status in history); | |
654 | - improved the detection of new files in incoming nzb directory: now the | |
655 | scanner does not rely on system datum, but tracks the changing of file | |
656 | sizes during a last few (<NzbDirFileAge>) seconds instead; | |
657 | - improvements in example postprocessing script: 1) if download contains | |
658 | only par2-files the script do not delete them during cleanup; | |
659 | 2) if download contains only nzb-files the script moves them to incoming | |
660 | nzb-directory for further download; | |
661 | - improved formatting of groups and added time info in curses output mode; | |
662 | - added second pause register, which is independent of main pause-state and | |
663 | therfore is intended for usage from external scripts; | |
664 | that allows to pause download without interfering with options | |
665 | <ParPauseQueue> and <PostPauseQueue> and scheduler tasks <PauseDownload> | |
666 | and <UnpauseDownload> - they all work with first (default) pause register; | |
667 | new subcommand <D2> for commands <--pause/-P> and <--unpause/-U>; | |
668 | new RPC-command <pausedownload2> and <resumedownload2>; | |
669 | existing RPC-commands <pause> und <resume> renamed to <pausedownload> and | |
670 | <resumedownload>; | |
671 | new field <Download2Paused> in result struct for RPC-command <status>; | |
672 | existing fields <ServerPaused> and <ParJobCount> renamed to | |
673 | <DownloadPaused> and <PostJobCount>; | |
674 | old RPC-commands and fields still exist for compatibility; | |
675 | the status output of command <--list/-L> indicates the state of second | |
676 | pause register; | |
677 | key <P> in curses-frontend can unpause second pause-register; | |
678 | - nzbprocess-script (option <NZBProcess>) can now set category and | |
679 | post-processing parameters for nzb-file; | |
680 | - redesigned server pool and par-checker to avoid using of semaphores | |
681 | (which are very platform specific); | |
682 | - added subcommand <S> to remote commands <--pause/-P> and <--unpause/-U> to | |
683 | pause/unpause the scanning of incoming nzb-directory; | |
684 | - added commands <PauseScan> and <UnpauseScan> for scheduler option | |
685 | <TaskX.Command>; | |
686 | - added remote commands <PauseScan> and <ResumeScan> for XML-/JSON-RPC; | |
687 | - command <pause post-processing> now not only pauses the post-processing | |
688 | queue but also pauses the current post-processing job (par-job or | |
689 | script-job); | |
690 | however the script-job can be paused only after the next line printed to | |
691 | screen; | |
692 | - improved error reporting while parsing nzb-files; | |
693 | - added field <NZBID> to NZBInfo; the field is now returned by XML-/JSON-RPC | |
694 | methods <listfiles>, <listgroups> and <postqueue>; | |
695 | - improvements in configure script; | |
696 | - added support for platforms without IPv6 (they do not have <getaddrinfo>); | |
697 | - debug-messages generated on early stages during initializing are now | |
698 | printed to screen/log-file; | |
699 | - messages about obsolete options are now printed to screen/log-file; | |
700 | - imporved example postprocessing script: added support for external | |
701 | configuration file, postprocessing parameters and configuration via | |
702 | web-interface; | |
703 | - option <TaskX.Process> now can contain parameters which must be passed | |
704 | to the script; | |
705 | - added pausing/resuming for post-processor queue; | |
706 | added new modifier <O> to remote commands <--pause/-P> and <--unpause/-U>; | |
707 | added new commands <postpause> and <postresume> to XML-/JSON-RPC; | |
708 | extended output of remote command <--list/-L> to indicate paused state | |
709 | of post-processor queue; extended command <status> of XML-/JSON-RPC | |
710 | with field <PostPause>; | |
711 | - changed the command line syntax for requesting of post-processor queue | |
712 | from <-O> to <-L O> for consistency with other post-queue related | |
713 | commands (<-P O>, <-U O> and <-E O>); | |
714 | - improved example post-processing script: added support for delayed | |
715 | par-check (try unrar first, par-repair if unrar failed); | |
716 | - added modifier <O> to command <-E/--edit> for editing of | |
717 | post-processor-queue; | |
718 | following subcommands are supported: <+/-offset>, <T>, <B>, <D>; | |
719 | subcommand <D> supports deletion of queued post-jobs and active job as well; | |
720 | deletion of active job means the cancelling of par-check/repair or | |
721 | terminating of post-processing-script (including child processes of the | |
722 | script); | |
723 | updated remote-server to support new edit-subcommands in XML/JSON-RPC; | |
724 | - extended the syntax of option <TaskX.Time> in two ways: | |
725 | 1) it now accepts multiple comma-separated values; | |
726 | 2) an asterix as hours-part means <every hour>; | |
727 | - added svn revision number to version string (commands <-v> and <-V>, | |
728 | startup log entry); | |
729 | svn revision is automatically read from svn-repository on each build; | |
730 | - added estimated remaining time and better distinguishing of server state | |
731 | in command <--list/-L>; | |
732 | - added new return code (93) for post-processing script to indicate | |
733 | successful processing; that results in cleaning up of download queue | |
734 | if option <ParCleanupQueue> is active; | |
735 | - added readonly options <AppBin>, <ConfigFile> and <Version> for usage | |
736 | in processing scripts (options are available as environment variables | |
737 | <NZBOP_APPBIN>, <NZBOP_CONFIGFILE> and <NZBOP_VERSION>); | |
738 | - renamed ParStatus constant <FAILED> to <FAILURE> for a consistence with | |
739 | ScriptStatus constant <FAILURE>, that also affects the results of | |
740 | RPC-command <history>; | |
741 | - added a new return code <95/POSTPROCESS_NONE> for post-processing scripts | |
742 | for cases when pp-script skips all post-processing work (typically upon | |
743 | a user's request via a pp-parameter); | |
744 | modified the example post-processing script to return the new code | |
745 | instead of a error code when a pp-parameter <PostProcess> was set to <no>; | |
746 | - added field <PostTime> to result of RPC-Command <listfiles> and fields | |
747 | <MinPostTime> and <MaxPostTime> for command <listgroups>; | |
748 | - in <curses> and <colored> output-modes the download speed is now printed | |
749 | with one decimal digit when the speed is lower than 10 KB/s; | |
750 | - improvement in example post-processing script: added check for existence | |
751 | of <unrar> and command <wc>; | |
752 | - added shell batch file for windows (nzbget-shell.bat); | |
753 | thanks to orbisvicis (orbisvicis@users.sourceforge.net) for the script; | |
754 | - added debian style init script (nzbgetd); | |
755 | thanks to orbisvicis (orbisvicis@users.sourceforge.net) for the script; | |
756 | - added the returning of a proper HTTP error code if the authorization was | |
757 | failed on RPC-calls; | |
758 | thanks to jdembski (jdembski@users.sourceforge.net) for the patch; | |
759 | - changed the sleep-time during the throttling of bandwidth from 200ms to | |
760 | 10ms in order to achieve better uniformity; | |
761 | - modified example postprocessing script to not use the command <dirname>, | |
762 | which is not always available; | |
763 | thanks to Ger Teunis for the patch; | |
764 | - improved example post-processing script: added the check for existence | |
765 | of destination directory to return a proper ERROR-code (important for | |
766 | reprocessing of history items); | |
767 | - by saving the queue to disk now using relative paths for the list of | |
768 | compeled files to reduce the file's size; | |
769 | - eliminated few compiler warnings on GCC; | |
770 | - fixed: when option <DaemonUserName> was specified and nzbget was | |
771 | started as root, the lockfile was not removed; | |
772 | - fixed: nothing was downloaded when the option <Retries> was set to <0>; | |
773 | - fixed: base64 decoding function used by RPC-method <append> sometimes | |
774 | failed, in particular when called from Ruby-language; | |
775 | - fixed: JSON-RPC-commands failed, if parameters were placed before method | |
776 | name in the request; | |
777 | - fixed: RPC-method <append> did not work properly on Posix systems | |
778 | (it worked only on Windows); | |
779 | - fixed compilation error when using native curses library on OpenSolaris; | |
780 | - fixed linking error on OpenSolaris when using GnuTLS; | |
781 | - fixed: option <ContinuePartial> did not work; | |
782 | - fixed: seg. fault in service mode on program start (Windows only); | |
783 | - fixed: environment block was not passed correctly to child process, | |
784 | what could result in seg faults (windows only); | |
785 | - fixed: returning the postprocessing exit code <92 - par-check all | |
786 | collections> when there were no par-files results in endless calling | |
787 | of postprocessing script; | |
788 | - fixed compatibility issues with OS/2. | |
789 | ||
790 | nzbget-0.6.0: | |
791 | - added scheduler; new options <TaskX.Time>, <TaskX.WeekDays>, | |
792 | <TaskX.Command>, <TaskX.DownloadRate> and <TaskX.Process>; | |
793 | - added support for postprocess-parameters; new subcommand <O> of remote | |
794 | command <E> to add/modify pp-parameter for group (nzb-file); new | |
795 | XML-/JSON-RPC-subcommand <GroupSetParameter> of method <editqueue> for | |
796 | the same purpose; updated example configuration file and example | |
797 | postprocess-script to indicate new method of passing arguments via | |
798 | environment variables; | |
799 | - added subcommands <F>, <G> and <S> to command line switch <-L/--list>, | |
800 | which prints list of files, groups or only status info respectively; | |
801 | extended binary communication protocol to transfer nzb-infos in addition | |
802 | to file-infos; | |
803 | - added new subcommand <M> to edit-command <E> for merging of two (or more) | |
804 | groups (useful after adding pars from a separate nzb-file); | |
805 | - added option <MergeNzb> to automatically merge nzb-files with the same | |
806 | filename (useful by adding pars from a different source); | |
807 | - added script-processing of files in incoming directory to allow automatic | |
808 | unpacking and queueing of compressed nzb-files; new option <NzbProcess>; | |
809 | - added the printing of post-process-parameters for groups in command | |
810 | <--list G>; | |
811 | - added the printing of nzbget version into the log-file on start; | |
812 | - added option <DeleteCleanupDisk> to automatically delete already downloaded | |
813 | files from disk if nzb-file was deleted from queue (the download was | |
814 | cancelled); | |
815 | - added option <ParTimeLimit> to define the max time allowed for par-repair; | |
816 | - added command <--scan/-S> to execute the scan of nzb-directory on remote | |
817 | server; | |
818 | - changed the method to pass arguments to postprocess/nzbprocess: now using | |
819 | environment variables (old method is still supported for compatibility with | |
820 | existing scripts); | |
821 | - added the passing of nzbget-options to postprocess/nzbprocess scripts as | |
822 | environment variables; | |
823 | - extended the communication between nzbget and post-process-script: | |
824 | collections are now detected even if parcheck is disabled; | |
825 | - added support for delayed par-check/repair: post-process-script can request | |
826 | par-check/repair using special exit codes to repair current collection or | |
827 | all collections; | |
828 | - implemented the normalizing of option names and values in option list; the | |
829 | command <-p> also prints normalized names and values now; that makes the | |
830 | parsing of output of command <-p> for external scripts easier; | |
831 | - replaced option <PostLogKind> with new option <ProcessLogKind> which is now | |
832 | used by all scripts (PostProcess, NzbProcess, TaskX.Process); | |
833 | - improved entering to paused state on connection errors (do not retry failed | |
834 | downloads if pause was activated); | |
835 | - improved error reporting on decoding failures; | |
836 | - improved compatibility of yenc-decoder; | |
837 | - improved the speed of deleting of groups from download queue (by avoiding | |
838 | the saving of queue after the deleting of each individual file); | |
839 | - updated configure-script for better compatibility with FreeBSD; | |
840 | - cleaning up of download queue (option <ParCleanupQueue>) and deletion of | |
841 | source nzb-file (option <NzbCleanupDisk>) after par-repair now works also | |
842 | if par-repair was cancelled (option <ParTimeLimit>); since required | |
843 | par-files were already downloaded the repair in an external tool is | |
844 | possible; | |
845 | - added workaround to avoid hangs in child processes (by starting of | |
846 | postprocess or nzbprocess), observed on uClibC based systems; | |
847 | - fixed: TLS/SSL didn't work in standalone mode; | |
848 | - fixed compatibility issues with Mac OS X; | |
849 | - fixed: not all necessary par2-files were unpaused on first request for | |
850 | par-blocks (although harmless, because additional files were unpaused | |
851 | later anyway); | |
852 | - fixed small memory leak appeared if process-script could not be started; | |
853 | - fixed: configure-script could not detect the right syntax for function | |
854 | <ctime_r> on OpenSolaris. | |
855 | - fixed: files downloaded with disabled decoder (option decode=no) sometimes | |
856 | were malformed and could not be decoded; | |
857 | - fixed: empty string parameters did not always work in XML-RPC. | |
858 | ||
859 | nzbget-0.5.1: | |
860 | - improved the check of server responses to prevent unnecessary retrying | |
861 | if the article does not exist on server; | |
862 | - fixed: seg.fault in standalone mode if used without specifying the | |
863 | category (e.g. without switch <-K>); | |
864 | - fixed: download speed indicator could report not-null values in | |
865 | standby-mode (when paused); | |
866 | - fixed: parameter <category> in JSON/XML-RPC was not properly decoded by | |
867 | server, makin⏎ |
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
503 | 503 | var $ConfigTabBadgeEmpty; |
504 | 504 | var $ConfigContent; |
505 | 505 | var $ConfigInfo; |
506 | var $ConfigAbout; | |
506 | 507 | var $ConfigTitle; |
507 | 508 | var $ConfigTable; |
508 | 509 | var $ViewButton; |
532 | 533 | $ConfigTabBadgeEmpty = $('#ConfigTabBadgeEmpty'); |
533 | 534 | $ConfigContent = $('#ConfigContent'); |
534 | 535 | $ConfigInfo = $('#ConfigInfo'); |
536 | $ConfigAbout = $('#ConfigAbout'); | |
535 | 537 | $ConfigTitle = $('#ConfigTitle'); |
536 | 538 | $ViewButton = $('#Config_ViewButton'); |
537 | 539 | $LeaveConfigDialog = $('#LeaveConfigDialog'); |
1207 | 1209 | $('li', $ConfigNav).removeClass('active'); |
1208 | 1210 | link.closest('li').addClass('active'); |
1209 | 1211 | $ConfigContent.removeClass('search'); |
1210 | Util.show($ViewButton, sectionId !== 'Config-Info'); | |
1212 | Util.show($ViewButton, sectionId !== 'Config-Info' && sectionId !== 'Config-About'); | |
1211 | 1213 | |
1212 | 1214 | $ConfigInfo.hide(); |
1215 | $ConfigAbout.hide(); | |
1213 | 1216 | |
1214 | 1217 | if (sectionId === 'Search') |
1215 | 1218 | { |
1224 | 1227 | $ConfigInfo.show(); |
1225 | 1228 | $ConfigData.children().hide(); |
1226 | 1229 | $ConfigTitle.text('INFO: SETTINGS'); |
1230 | return; | |
1231 | } | |
1232 | ||
1233 | if (sectionId === 'Config-About') | |
1234 | { | |
1235 | $ConfigAbout.show(); | |
1236 | $ConfigData.children().hide(); | |
1237 | $ConfigTitle.text('ABOUT NZBGET'); | |
1227 | 1238 | return; |
1228 | 1239 | } |
1229 | 1240 |
178 | 178 | var kind = hist.Kind; |
179 | 179 | hist.status = HistoryUI.buildStatusText(hist); |
180 | 180 | hist.name = hist.Name; |
181 | hist.size = kind === 'URL' ? '' : Util.formatSizeMB(hist.FileSizeMB); | |
181 | hist.size = kind === 'URL' && hist.FileSizeLo == 0 && hist.FileSizeHi == 0 ? '' : Util.formatSizeMB(hist.FileSizeMB); | |
182 | 182 | hist.sizemb = hist.FileSizeMB; |
183 | 183 | hist.sizegb = hist.FileSizeMB / 1024; |
184 | 184 | hist.time = Util.formatDateTime(hist.HistoryTime + UISettings.timeZoneCorrection*60*60); |
185 | 185 | hist.category = kind !== 'DUP' ? hist.Category : ''; |
186 | 186 | hist.dupe = DownloadsUI.buildDupeText(hist.DupeKey, hist.DupeScore, hist.DupeMode); |
187 | var age_sec = kind === 'NZB' ? new Date().getTime() / 1000 - (hist.MinPostTime + UISettings.timeZoneCorrection*60*60) : 0; | |
188 | hist.age = kind === 'NZB' ? Util.formatAge(hist.MinPostTime + UISettings.timeZoneCorrection*60*60) : ''; | |
187 | var age_sec = hist.MinPostTime > 0 ? new Date().getTime() / 1000 - (hist.MinPostTime + UISettings.timeZoneCorrection*60*60) : 0; | |
188 | hist.age = hist.MinPostTime > 0 ? Util.formatAge(hist.MinPostTime + UISettings.timeZoneCorrection*60*60) : ''; | |
189 | 189 | hist.agem = Util.round0(age_sec / 60); |
190 | 190 | hist.ageh = Util.round0(age_sec / (60*60)); |
191 | 191 | hist.aged = Util.round0(age_sec / (60*60*24)); |
23 | 23 | <meta charset="utf-8"> |
24 | 24 | <title>NZBGet</title> |
25 | 25 | <meta name="description" content="NZBGet web-interface"> |
26 | <meta name="author" content="Andrey Prygunkov (hugbug@users.sourceforge.net)"> | |
27 | 26 | |
28 | 27 | <!-- Mobile settings --> |
29 | 28 | <meta name="viewport" content="initial-scale=1.0, user-scalable=yes" /> |
96 | 95 | <div class="container-fluid navbar-container" id="NavbarContainer"> |
97 | 96 | |
98 | 97 | <!-- LOGO --> |
99 | <div id="Logo" data-toggle="modal" href="#InfoDialog"><i class="img-logo"></i></div> | |
98 | <div id="Logo" onclick="$('#DownloadsTabLink').click()"><i class="img-logo"></i></div> | |
100 | 99 | |
101 | 100 | <!-- PLAY/PAUSE-BUTTON --> |
102 | 101 | <div id="PlayBlock"> |
538 | 537 | <div class="span3"> |
539 | 538 | <ul class="nav nav-list" id="ConfigNav"> |
540 | 539 | <li class="config-static"><a href="#Config-Info">INFO</a></li> |
540 | <li class="config-static"><a href="#Config-About">ABOUT NZBGET</a></li> | |
541 | 541 | <li class="config-static"><a href="#Config-System">SYSTEM</a></li> |
542 | 542 | </ul> |
543 | 543 | </div> |
594 | 594 | <p> |
595 | 595 | This can be done in section <em><strong>SYSTEM</strong></em>. |
596 | 596 | </p> |
597 | </div> | |
598 | ||
599 | <div id="ConfigAbout"> | |
600 | <p>For info on NZBGet poject please visit <a href="http://nzbget.net">NZBGet Home Page</a>. Among other things the developers of third-party apps find there complete docs about RPC interface.</p> | |
601 | <p>Should you need help, have suggestions or want to share your improvements - <a href="http://nzbget.net/forum">NZBGet Forum</a> is a place to do that.</p> | |
602 | ||
603 | <h4>Copyright</h4> | |
604 | <p>This program is free software; you can redistribute it and/or modify | |
605 | it under the terms of the GNU General Public License as published by | |
606 | the Free Software Foundation; either version 2 of the License, or | |
607 | (at your option) any later version.</p> | |
608 | ||
609 | <p>The complete content of license is provided in file COPYING within distribution and also available <a href="http://www.gnu.org/licenses/gpl-2.0.html">online</a>.</p> | |
610 | ||
611 | <p>Additional exemption: compiling, linking, and/or using OpenSSL is allowed.</p> | |
612 | ||
613 | <h4>Par2</h4> | |
614 | <p>NZBGet uses <a href="http://parchive.sourceforge.net">Par2</a> by Peter Brian Clements with library interface by Francois Lesueur.</p> | |
615 | <p>Par2 is licensed under the <a href="http://github.com/jquery/jquery/blob/master/GPL-LICENSE.txt">GPL license</a>.</p> | |
616 | ||
617 | <h4>Catch</h4> | |
618 | <p>NZBGet uses C++ testing framework <a href="https://github.com/philsquared/Catch">Catch</a> by Two Blue Cubes Ltd.</p> | |
619 | <p>Catch is licensed under the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License</a>.</p> | |
620 | ||
621 | <h4>jQuery</h4> | |
622 | <p>NZBGet web-interface uses <a href="http://jquery.com">jQuery</a>. The jQuery Project is run by a distributed group of volunteers that all want to see jQuery become the best JavaScript tool possible.</p> | |
623 | <p>jQuery is licensed under the <a href="http://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt">MIT</a> and <a href="http://github.com/jquery/jquery/blob/master/GPL-LICENSE.txt">GPL</a> licenses.</p> | |
624 | ||
625 | <h4>Bootstrap</h4> | |
626 | <p>NZBGet web-interface uses <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a>. Designed and built with all the love in the world @twitter by @mdo and @fat.</p> | |
627 | <p>Bootstrap code is licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License v2.0</a>.</p> | |
628 | ||
629 | <h4>Raphaël</h4> | |
630 | <p>NZBGet web-interface makes use of <a href="http://raphaeljs.com">Raphaël</a> built by Dmitry Baranovskiy.</p> | |
631 | <p>Raphaël code is licensed under the <a href="http://raphaeljs.com/license.html">MIT license</a>.</p> | |
632 | ||
633 | <h4>Elycharts</h4> | |
634 | <p>For charts NZBGet relies on <a href="http://elycharts.com">Elycharts</a> by Void Labs s.n.c.</p> | |
635 | <p>Elycharts code is licensed under the <a href="http://creativecommons.org/licenses/MIT/">MIT license</a>.</p> | |
636 | ||
637 | <h4>iconSweets</h4> | |
638 | <p>NZBGet web-interface includes selected icons from collections <a href="http://www.iconsweets.com/">iconSweets</a> and <a href="http://www.iconsweets2.com/">iconSweets2</a> by <a href="http://yummygum.com">Yummygum</a>.</p> | |
639 | <p>The icons are generally licensed under a custom license but used in NZBGet with author's permission.</p> | |
597 | 640 | </div> |
598 | 641 | |
599 | 642 | <div> |
677 | 720 | </div> |
678 | 721 | </div> |
679 | 722 | </div> |
680 | ||
681 | </div> | |
682 | </div> | |
683 | ||
684 | <!-- *** INFO ************************************************************ --> | |
685 | ||
686 | <div class="modal no-footer hide" id="InfoDialog"> | |
687 | <div class="modal-header"> | |
688 | <a class="close" href='#' data-dismiss="modal"><i class="icon-close"></i></a> | |
689 | <h3>NZBGet <span id="version">version</h3> | |
690 | </div> | |
691 | <div class="modal-body"> | |
692 | <h1>Information about NZBGet</h1> | |
693 | <h2>Authors</h2> | |
694 | <p>NZBGet is developed and maintained by Andrey Prygunkov (<a href="mailto:hugbug@users.sourceforge.net">hugbug@users.sourceforge.net</a>).</p> | |
695 | ||
696 | <p>The original project was initially created by Sven Henkel (sidddy@users.sourceforge.net) in 2004 and later developed by Bo Cordes Petersen (placebodk@users.sourceforge.net) until 2005. In 2007 the abandoned project was overtaken by Andrey Prygunkov. Since then the program has been completely rewritten.</p> | |
697 | ||
698 | <h2>Copyright</h2> | |
699 | <p>This program is free software; you can redistribute it and/or modify | |
700 | it under the terms of the GNU General Public License as published by | |
701 | the Free Software Foundation; either version 2 of the License, or | |
702 | (at your option) any later version.</p> | |
703 | ||
704 | <p>The complete content of license is provided in file COPYING within distribution and also available <a href="http://www.gnu.org/licenses/gpl-2.0.html">online</a>.</p> | |
705 | ||
706 | <p>Additional exemption: compiling, linking, and/or using OpenSSL is allowed.</p> | |
707 | ||
708 | <h2>Contact</h2> | |
709 | <p>For more info please visit <a href="http://nzbget.net">NZBGet Home Page</a>. Among other things the developers of third-party apps find there complete docs about RPC interface.</p> | |
710 | <p>Should you need help, have suggestions or want to share your improvements - <a href="http://nzbget.net/forum">NZBGet Forum</a> is a place to do that.</p> | |
711 | <p>If you use NZBGet on a media player, router, NAS or other non-PC device the best place to get help is probably forums specialized on your device.</p> | |
712 | ||
713 | <h1>Information about included libraries</h1> | |
714 | ||
715 | <h2>Par2</h2> | |
716 | <p>NZBGet uses <a href="http://parchive.sourceforge.net">Par2</a> by Peter Brian Clements with library interface by Francois Lesueur.</p> | |
717 | <p>Par2 is licensed under the <a href="http://github.com/jquery/jquery/blob/master/GPL-LICENSE.txt">GPL license</a>.</p> | |
718 | ||
719 | <h2>Catch</h2> | |
720 | <p>NZBGet uses C++ testing framework <a href="https://github.com/philsquared/Catch">Catch</a> by Two Blue Cubes Ltd.</p> | |
721 | <p>Catch is licensed under the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License</a>.</p> | |
722 | ||
723 | <h2>jQuery</h2> | |
724 | <p>NZBGet web-interface uses <a href="http://jquery.com">jQuery</a>. The jQuery Project is run by a distributed group of volunteers that all want to see jQuery become the best JavaScript tool possible.</p> | |
725 | <p>jQuery is licensed under the <a href="http://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt">MIT</a> and <a href="http://github.com/jquery/jquery/blob/master/GPL-LICENSE.txt">GPL</a> licenses.</p> | |
726 | ||
727 | <h2>Bootstrap</h2> | |
728 | <p>NZBGet web-interface uses <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a>. Designed and built with all the love in the world @twitter by @mdo and @fat.</p> | |
729 | <p>Bootstrap code is licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License v2.0</a>.</p> | |
730 | ||
731 | <h2>Raphaël</h2> | |
732 | <p>NZBGet web-interface makes use of <a href="http://raphaeljs.com">Raphaël</a> built by Dmitry Baranovskiy.</p> | |
733 | <p>Raphaël code is licensed under the <a href="http://raphaeljs.com/license.html">MIT license</a>.</p> | |
734 | ||
735 | <h2>Elycharts</h2> | |
736 | <p>For charts NZBGet relies on <a href="http://elycharts.com">Elycharts</a> by Void Labs s.n.c.</p> | |
737 | <p>Elycharts code is licensed under the <a href="http://creativecommons.org/licenses/MIT/">MIT license</a>.</p> | |
738 | ||
739 | <h2>iconSweets</h2> | |
740 | <p>NZBGet web-interface includes selected icons from collections <a href="http://www.iconsweets.com/">iconSweets</a> and <a href="http://www.iconsweets2.com/">iconSweets2</a> by <a href="http://yummygum.com">Yummygum</a>.</p> | |
741 | <p>The icons are generally licensed under a custom license but used in NZBGet with author's permission.</p> | |
742 | 723 | |
743 | 724 | </div> |
744 | 725 | </div> |