2
* This file is part of nzbget
4
* Copyright (C) 2004 Sven Henkel <sidddy@users.sourceforge.net>
5
* Copyright (C) 2007-2010 Andrei Prygounkov <hugbug@users.sourceforge.net>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
* $Date: 2010-01-29 10:34:44 +0100 (Fri, 29 Jan 2010) $
42
#include "DownloadInfo.h"
47
extern Options* g_pOptions;
49
int FileInfo::m_iIDGen = 0;
50
int NZBInfo::m_iIDGen = 0;
51
int PostInfo::m_iIDGen = 0;
53
NZBParameter::NZBParameter(const char* szName)
55
m_szName = strdup(szName);
59
NZBParameter::~NZBParameter()
71
void NZBParameter::SetValue(const char* szValue)
77
m_szValue = strdup(szValue);
81
void NZBParameterList::SetParameter(const char* szName, const char* szValue)
83
NZBParameter* pParameter = NULL;
84
bool bDelete = !szValue || !*szValue;
86
for (iterator it = begin(); it != end(); it++)
88
NZBParameter* pLookupParameter = *it;
89
if (!strcmp(pLookupParameter->GetName(), szName))
93
delete pLookupParameter;
97
pParameter = pLookupParameter;
109
pParameter = new NZBParameter(szName);
110
push_back(pParameter);
113
pParameter->SetValue(szValue);
119
debug("Creating NZBInfo");
123
m_szCategory = strdup("");
125
m_iParkedFileCount = 0;
128
m_bPostProcess = false;
129
m_eParStatus = prNone;
130
m_eScriptStatus = srNone;
132
m_bParCleanup = false;
133
m_bCleanupDisk = false;
134
m_szQueuedFilename = strdup("");
145
debug("Destroying NZBInfo");
159
if (m_szQueuedFilename)
161
free(m_szQueuedFilename);
164
ClearCompletedFiles();
166
for (NZBParameterList::iterator it = m_ppParameters.begin(); it != m_ppParameters.end(); it++)
170
m_ppParameters.clear();
172
for (Messages::iterator it = m_Messages.begin(); it != m_Messages.end(); it++)
180
m_Owner->Remove(this);
184
void NZBInfo::AddReference()
189
void NZBInfo::Release()
192
if (m_iRefCount <= 0)
198
void NZBInfo::ClearCompletedFiles()
200
for (Files::iterator it = m_completedFiles.begin(); it != m_completedFiles.end(); it++)
204
m_completedFiles.clear();
207
void NZBInfo::SetDestDir(const char* szDestDir)
213
m_szDestDir = strdup(szDestDir);
216
void NZBInfo::SetFilename(const char * szFilename)
222
m_szFilename = strdup(szFilename);
225
void NZBInfo::SetCategory(const char* szCategory)
231
m_szCategory = strdup(szCategory);
234
void NZBInfo::SetQueuedFilename(const char * szQueuedFilename)
236
if (m_szQueuedFilename)
238
free(m_szQueuedFilename);
240
m_szQueuedFilename = strdup(szQueuedFilename);
243
void NZBInfo::GetNiceNZBName(char* szBuffer, int iSize)
245
MakeNiceNZBName(m_szFilename, szBuffer, iSize);
248
void NZBInfo::MakeNiceNZBName(const char * szNZBFilename, char * szBuffer, int iSize)
251
const char* szBaseName = Util::BaseFileName(szNZBFilename);
253
// if .nzb file has a certain structure, try to strip out certain elements
254
if (sscanf(szBaseName, "msgid_%*d_%1023s", postname) == 1)
256
// OK, using stripped name
260
// using complete filename
261
strncpy(postname, szBaseName, 1024);
262
postname[1024-1] = '\0';
266
if (char* p = strrchr(postname, '.')) *p = '\0';
268
Util::MakeValidFilename(postname, '_', false);
270
// if the resulting name is empty, use basename without cleaning up "msgid_"
271
if (strlen(postname) == 0)
273
// using complete filename
274
strncpy(postname, szBaseName, 1024);
275
postname[1024-1] = '\0';
278
if (char* p = strrchr(postname, '.')) *p = '\0';
280
Util::MakeValidFilename(postname, '_', false);
282
// if the resulting name is STILL empty, use "noname"
283
if (strlen(postname) == 0)
285
strncpy(postname, "noname", 1024);
289
strncpy(szBuffer, postname, iSize);
290
szBuffer[iSize-1] = '\0';
293
void NZBInfo::BuildDestDirName()
296
char szCategory[1024];
297
bool bHasCategory = m_szCategory && m_szCategory[0] != '\0';
298
if (g_pOptions->GetAppendCategoryDir() && bHasCategory)
300
strncpy(szCategory, m_szCategory, 1024);
301
szCategory[1024 - 1] = '\0';
302
Util::MakeValidFilename(szCategory, '_', true);
305
if (g_pOptions->GetAppendNZBDir())
307
char szNiceNZBName[1024];
308
GetNiceNZBName(szNiceNZBName, 1024);
309
if (g_pOptions->GetAppendCategoryDir() && bHasCategory)
311
snprintf(szBuffer, 1024, "%s%s%c%s", g_pOptions->GetDestDir(), szCategory, PATH_SEPARATOR, szNiceNZBName);
315
snprintf(szBuffer, 1024, "%s%s", g_pOptions->GetDestDir(), szNiceNZBName);
317
szBuffer[1024-1] = '\0';
321
if (g_pOptions->GetAppendCategoryDir() && bHasCategory)
323
snprintf(szBuffer, 1024, "%s%s", g_pOptions->GetDestDir(), szCategory);
327
strncpy(szBuffer, g_pOptions->GetDestDir(), 1024);
329
szBuffer[1024-1] = '\0'; // trim the last slash, always returned by GetDestDir()
332
SetDestDir(szBuffer);
335
void NZBInfo::SetParameter(const char* szName, const char* szValue)
337
m_ppParameters.SetParameter(szName, szValue);
340
NZBInfo::Messages* NZBInfo::LockMessages()
346
void NZBInfo::UnlockMessages()
351
void NZBInfo::AppendMessage(Message::EKind eKind, time_t tTime, const char * szText)
358
Message* pMessage = new Message(++m_iIDMessageGen, eKind, tTime, szText);
361
m_Messages.push_back(pMessage);
365
void NZBInfoList::Add(NZBInfo* pNZBInfo)
367
pNZBInfo->m_Owner = this;
371
void NZBInfoList::Remove(NZBInfo* pNZBInfo)
373
for (iterator it = begin(); it != end(); it++)
375
NZBInfo* pNZBInfo2 = *it;
376
if (pNZBInfo2 == pNZBInfo)
384
void NZBInfoList::ReleaseAll()
387
for (iterator it = begin(); it != end(); )
389
NZBInfo* pNZBInfo = *it;
390
bool bObjDeleted = pNZBInfo->m_iRefCount == 1;
404
ArticleInfo::ArticleInfo()
406
//debug("Creating ArticleInfo");
407
m_szMessageID = NULL;
409
m_eStatus = aiUndefined;
410
m_szResultFilename = NULL;
413
ArticleInfo::~ ArticleInfo()
415
//debug("Destroying ArticleInfo");
421
if (m_szResultFilename)
423
free(m_szResultFilename);
427
void ArticleInfo::SetMessageID(const char * szMessageID)
429
m_szMessageID = strdup(szMessageID);
432
void ArticleInfo::SetResultFilename(const char * v)
434
if (m_szResultFilename)
436
free(m_szResultFilename);
438
m_szResultFilename = strdup(v);
444
debug("Creating FileInfo");
450
m_bFilenameConfirmed = false;
452
m_lRemainingSize = 0;
457
m_bOutputInitialized = false;
463
FileInfo::~ FileInfo()
465
debug("Destroying FileInfo");
476
for (Groups::iterator it = m_Groups.begin(); it != m_Groups.end() ;it++)
486
m_pNZBInfo->Release();
490
void FileInfo::ClearArticles()
492
for (Articles::iterator it = m_Articles.begin(); it != m_Articles.end() ;it++)
499
void FileInfo::SetID(int s)
502
if (m_iIDGen < m_iID)
508
void FileInfo::SetNZBInfo(NZBInfo* pNZBInfo)
512
m_pNZBInfo->Release();
514
m_pNZBInfo = pNZBInfo;
515
m_pNZBInfo->AddReference();
518
void FileInfo::SetSubject(const char* szSubject)
520
m_szSubject = strdup(szSubject);
523
void FileInfo::SetFilename(const char* szFilename)
529
m_szFilename = strdup(szFilename);
532
void FileInfo::MakeValidFilename()
534
Util::MakeValidFilename(m_szFilename, '_', false);
537
void FileInfo::LockOutputFile()
539
m_mutexOutputFile.Lock();
542
void FileInfo::UnlockOutputFile()
544
m_mutexOutputFile.Unlock();
547
bool FileInfo::IsDupe(const char* szFilename)
550
snprintf(fileName, 1024, "%s%c%s", m_pNZBInfo->GetDestDir(), (int)PATH_SEPARATOR, szFilename);
551
fileName[1024-1] = '\0';
552
if (Util::FileExists(fileName))
556
snprintf(fileName, 1024, "%s%c%s_broken", m_pNZBInfo->GetDestDir(), (int)PATH_SEPARATOR, szFilename);
557
fileName[1024-1] = '\0';
558
if (Util::FileExists(fileName))
566
GroupInfo::GroupInfo()
570
m_iRemainingFileCount = 0;
571
m_iPausedFileCount = 0;
572
m_lRemainingSize = 0;
574
m_iRemainingParCount = 0;
579
GroupInfo::~GroupInfo()
583
m_pNZBInfo->Release();
589
debug("Creating PostInfo");
592
m_szParFilename = NULL;
597
m_eParStatus = psNone;
598
m_eRequestParCheck = rpNone;
599
m_eScriptStatus = srNone;
600
m_szProgressLabel = strdup("");
602
m_iStageProgress = 0;
606
m_pScriptThread = NULL;
613
PostInfo::~ PostInfo()
615
debug("Destroying PostInfo");
619
free(m_szParFilename);
625
if (m_szProgressLabel)
627
free(m_szProgressLabel);
630
for (Messages::iterator it = m_Messages.begin(); it != m_Messages.end(); it++)
638
m_pNZBInfo->Release();
642
void PostInfo::SetNZBInfo(NZBInfo* pNZBInfo)
646
m_pNZBInfo->Release();
648
m_pNZBInfo = pNZBInfo;
649
m_pNZBInfo->AddReference();
652
void PostInfo::SetParFilename(const char* szParFilename)
654
m_szParFilename = strdup(szParFilename);
657
void PostInfo::SetInfoName(const char* szInfoName)
659
m_szInfoName = strdup(szInfoName);
662
void PostInfo::SetProgressLabel(const char* szProgressLabel)
664
if (m_szProgressLabel)
666
free(m_szProgressLabel);
668
m_szProgressLabel = strdup(szProgressLabel);
671
PostInfo::Messages* PostInfo::LockMessages()
677
void PostInfo::UnlockMessages()
682
void PostInfo::AppendMessage(Message::EKind eKind, const char * szText)
684
Message* pMessage = new Message(++m_iIDMessageGen, eKind, time(NULL), szText);
687
m_Messages.push_back(pMessage);
689
while (m_Messages.size() > (unsigned int)g_pOptions->GetLogBufferSize())
691
Message* pMessage = m_Messages.front();
693
m_Messages.pop_front();
698
void DownloadQueue::BuildGroups(GroupQueue* pGroupQueue)
700
for (FileQueue::iterator it = GetFileQueue()->begin(); it != GetFileQueue()->end(); it++)
702
FileInfo* pFileInfo = *it;
703
GroupInfo* pGroupInfo = NULL;
704
for (GroupQueue::iterator itg = pGroupQueue->begin(); itg != pGroupQueue->end(); itg++)
706
GroupInfo* pGroupInfo1 = *itg;
707
if (pGroupInfo1->GetNZBInfo() == pFileInfo->GetNZBInfo())
709
pGroupInfo = pGroupInfo1;
715
pGroupInfo = new GroupInfo();
716
pGroupInfo->m_pNZBInfo = pFileInfo->GetNZBInfo();
717
pGroupInfo->m_pNZBInfo->AddReference();
718
pGroupInfo->m_iFirstID = pFileInfo->GetID();
719
pGroupInfo->m_iLastID = pFileInfo->GetID();
720
pGroupInfo->m_tMinTime = pFileInfo->GetTime();
721
pGroupInfo->m_tMaxTime = pFileInfo->GetTime();
722
pGroupQueue->push_back(pGroupInfo);
724
if (pFileInfo->GetID() < pGroupInfo->GetFirstID())
726
pGroupInfo->m_iFirstID = pFileInfo->GetID();
728
if (pFileInfo->GetID() > pGroupInfo->GetLastID())
730
pGroupInfo->m_iLastID = pFileInfo->GetID();
732
if (pFileInfo->GetTime() > 0)
734
if (pFileInfo->GetTime() < pGroupInfo->GetMinTime())
736
pGroupInfo->m_tMinTime = pFileInfo->GetTime();
738
if (pFileInfo->GetTime() > pGroupInfo->GetMaxTime())
740
pGroupInfo->m_tMaxTime = pFileInfo->GetTime();
743
pGroupInfo->m_iRemainingFileCount++;
744
pGroupInfo->m_lRemainingSize += pFileInfo->GetRemainingSize();
745
if (pFileInfo->GetPaused())
747
pGroupInfo->m_lPausedSize += pFileInfo->GetRemainingSize();
748
pGroupInfo->m_iPausedFileCount++;
751
char szLoFileName[1024];
752
strncpy(szLoFileName, pFileInfo->GetFilename(), 1024);
753
szLoFileName[1024-1] = '\0';
754
for (char* p = szLoFileName; *p; p++) *p = tolower(*p); // convert string to lowercase
755
if (strstr(szLoFileName, ".par2"))
757
pGroupInfo->m_iRemainingParCount++;