diff options
Diffstat (limited to 'recording.c')
-rw-r--r-- | recording.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/recording.c b/recording.c new file mode 100644 index 0000000..c67bf61 --- /dev/null +++ b/recording.c @@ -0,0 +1,160 @@ +/* + * recording.c: Duplicate recording handling. + * + * See the README file for copyright information and how to reach the author. + * + * $Id$ + */ + +#include "config.h" +#include "recording.h" +#include <sys/time.h> +#include <sstream> + +// --- cDuplicateRecording ------------------------------------------------------- + +cDuplicateRecording::cDuplicateRecording(void) : visibility(NULL) { + duplicates = new cList<cDuplicateRecording>; +} + +cDuplicateRecording::cDuplicateRecording(const cRecording *Recording) : visibility(Recording->FileName()) { + checked = false; + fileName = std::string(Recording->FileName()); +#if defined LIEMIKUUTIO && LIEMIKUUTIO < 131 + text = std::string(Recording->Title('\t', true, -1, false)); +#else + text = std::string(Recording->Title('\t', true)); +#endif + if (dc.title && Recording->Info()->Title()) + title = std::string(Recording->Info()->Title()); + else + title = std::string(); + std::stringstream desc; + if (Recording->Info()->ShortText()) + desc << std::string(Recording->Info()->ShortText()); + if (Recording->Info()->Description()) + desc << std::string(Recording->Info()->Description()); + description = desc.str(); + while(true) { + size_t found = description.find("|"); + if (found == std::string::npos) + break; + description.replace(found, 1, ""); + } + while(true) { + size_t found = description.find(" "); + if (found == std::string::npos) + break; + description.replace(found, 1, ""); + } + duplicates = NULL; +} + +cDuplicateRecording::cDuplicateRecording(const cDuplicateRecording &DuplicateRecording) : + checked(DuplicateRecording.checked), + visibility(DuplicateRecording.visibility), + fileName(DuplicateRecording.fileName), + text(DuplicateRecording.text), + title(DuplicateRecording.title), + description(DuplicateRecording.description), + duplicates(DuplicateRecording.duplicates) {} + +cDuplicateRecording::~cDuplicateRecording() { + delete duplicates; +} + +bool cDuplicateRecording::IsDuplicate(cDuplicateRecording *DuplicateRecording) { + if (!HasDescription() || !DuplicateRecording->HasDescription()) + return false; + + size_t found; + if (dc.title) { + found = title.size() > DuplicateRecording->title.size() ? + title.find(DuplicateRecording->title) : DuplicateRecording->title.find(title); + if (found == std::string::npos) + return false; + } + + found = description.size() > DuplicateRecording->description.size() ? + description.find(DuplicateRecording->description) : DuplicateRecording->description.find(description); + if (found != std::string::npos) + return dc.hidden || visibility.Read() != HIDDEN && DuplicateRecording->visibility.Read() != HIDDEN; + + return false; +} + +// --- cDuplicateRecordings ------------------------------------------------------ + +cDuplicateRecordings::cDuplicateRecordings(void) {} + +void cDuplicateRecordings::Update(void) { + struct timeval startTime, stopTime; + gettimeofday(&startTime, NULL); + cMutexLock MutexLock(&mutex); +#ifdef DEBUG_VISIBILITY + cVisibility::ClearCounters(); + int isDuplicateCount = 0; +#endif + cDuplicateRecording *descriptionless = new cDuplicateRecording(); + cList<cDuplicateRecording> recordings; + Clear(); + { +#if VDRVERSNUM >= 20301 + cRecordings *Recordings = cRecordings::GetRecordingsWrite(recordingsStateKey); // write access is necessary for sorting! + Recordings->Sort(); + for (const cRecording *recording = Recordings->First(); recording; recording = Recordings->Next(recording)) { +#else + cThreadLock RecordingsLock(&Recordings); + Recordings.Sort(); + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { +#endif + cDuplicateRecording *Item = new cDuplicateRecording(recording); + if (Item->HasDescription()) + recordings.Add(Item); + else if (dc.hidden || Item->Visibility().Read() != HIDDEN) + descriptionless->Duplicates()->Add(Item); + } +#if VDRVERSNUM >= 20301 + recordingsStateKey.Remove(false); // sorting doesn't count as a real modification +#endif + } + for (cDuplicateRecording *recording = recordings.First(); recording; recording = recordings.Next(recording)) { + if (!recording->Checked()) { + recording->SetChecked(); + cDuplicateRecording *duplicates = new cDuplicateRecording(); + duplicates->Duplicates()->Add(new cDuplicateRecording(*recording)); + for (cDuplicateRecording *compare = recordings.First(); compare; compare = recordings.Next(compare)) { + if (!compare->Checked()) { +#ifdef DEBUG_VISIBILITY + isDuplicateCount++; +#endif + if (recording->IsDuplicate(compare)) { + duplicates->Duplicates()->Add(new cDuplicateRecording(*compare)); + compare->SetChecked(); + } + } + } + if (duplicates->Duplicates()->Count() > 1) { + duplicates->SetText(cString::sprintf(tr("%d duplicate recordings"), duplicates->Duplicates()->Count())); + Add(duplicates); + } else + delete duplicates; + } + } + if (descriptionless->Duplicates()->Count() > 0) { + descriptionless->SetText(cString::sprintf(tr("%d recordings without description"), descriptionless->Duplicates()->Count())); + Add(descriptionless); + } else + delete descriptionless; + gettimeofday(&stopTime, NULL); + double seconds = (((long long)stopTime.tv_sec * 1000000 + stopTime.tv_usec) - ((long long)startTime.tv_sec * 1000000 + startTime.tv_usec)) / 1000000.0; +#ifdef DEBUG_VISIBILITY + dsyslog("duplicates: Scanning of duplicates took %.2f seconds, is duplicate count %d, get count %d, read count %d, access count %d.", + seconds, isDuplicateCount, cVisibility::getCount, cVisibility::readCount, cVisibility::accessCount); +#else + dsyslog("duplicates: Scanning of duplicates took %.2f seconds.", seconds); +#endif +} + +cDuplicateRecordings DuplicateRecordings; + |