summaryrefslogtreecommitdiff
path: root/recording.c
diff options
context:
space:
mode:
Diffstat (limited to 'recording.c')
-rw-r--r--recording.c160
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;
+