summaryrefslogtreecommitdiff
path: root/dataplaylist.c
diff options
context:
space:
mode:
Diffstat (limited to 'dataplaylist.c')
-rw-r--r--dataplaylist.c663
1 files changed, 663 insertions, 0 deletions
diff --git a/dataplaylist.c b/dataplaylist.c
new file mode 100644
index 0000000..d462b5b
--- /dev/null
+++ b/dataplaylist.c
@@ -0,0 +1,663 @@
+/*
+ * playlist: A plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: dataplaylist.c 0.2 2004/10/08 02:34:00 hflor Exp $
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "dataplaylist.h"
+#include "playlist.h"
+#include "i18n.h"
+#include "vdrtools.h"
+#include <vdr/keys.h>
+#include <vdr/tools.h>
+#include <vdr/videodir.h>
+
+// -- cPlaylistMark -----------------------------------------------------------------
+
+cPlaylistMark::cPlaylistMark(char *Filename)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistMark::cPlaylistMark Name=%s", plugin_name, Filename);
+#endif
+ filename = Filename ? strdup(Filename) : NULL;
+}
+
+cPlaylistMark::~cPlaylistMark(void)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistMark::~cPlaylistMark Name=%s", plugin_name, filename);
+#endif
+ FREENULL(filename);
+}
+
+// -- cPlaylistMarkCol -----------------------------------------------------------------
+
+cPlaylistMarkCol PlaylistMark;
+
+// -- cPlaylistRecord -----------------------------------------------------------------
+
+cPlaylistRecord::cPlaylistRecord(void)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecord::cPlaylistRecord", plugin_name);
+#endif
+ SetName(NULL);
+ SetDefaults();
+ playlist = NULL;
+}
+
+cPlaylistRecord::cPlaylistRecord(cPlaylist *Playlist, char *Filename)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecord::cPlaylistRecord Filename=%s", plugin_name, Filename);
+#endif
+ playlist = Playlist;
+ SetName(Filename);
+ SetDefaults();
+}
+
+cPlaylistRecord::cPlaylistRecord(cPlaylist *Playlist, cRecording *Recording, cPlaylistRecord *Parent)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecord::cPlaylistRecord Parent=%s", plugin_name, Parent ? Parent->name : "(null)");
+#endif
+ playlist = Playlist;
+ SetName(Recording->FileName());
+ parent = Parent;
+ SetDefaults(Recording);
+}
+
+
+cPlaylistRecord::~cPlaylistRecord(void)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecord::~cPlaylistRecord [%s]", plugin_name, name);
+#endif
+ FREENULL(filename);
+ FREENULL(summary);
+ FREENULL(title);
+ FREENULL(path);
+ parent = NULL; // no delete!
+}
+
+void cPlaylistRecord::SetName(const char *Filename)
+{
+ if (Filename)
+ {
+ char *buffer = strdup(Filename + strlen(VideoDirectory) + 1);
+
+//suche record ..
+
+ buffer = ExchangeChars(buffer, false);
+
+ char *temp = strrchr(buffer, '~');
+ if (temp)
+ {
+ *temp = 0;
+ temp = strrchr(buffer, '~');
+ }
+ if (temp)
+ strn0cpy(name, temp + 1, MaxFileName);
+ else
+ strn0cpy(name, buffer, MaxFileName);
+ path = strdup(buffer);
+ free(buffer);
+ filename = strdup(Filename);
+ isdir = filename[strlen(filename) - 1] == '/';
+ } else
+ {
+ name[0] = 0;
+ filename = NULL;
+ path = NULL;
+ isdir = false;
+ }
+ parent = NULL;
+}
+
+void cPlaylistRecord::SetDefaults(cRecording *Recording)
+{
+ for (int i = Option_confirmdeleterecord; i < Option_max; i++)
+ options[i] = parent ? NoYesDefault_defaultRecordDir : NoYesDefault_defaultPlaylist; // Option_playoption is not use
+ isdel = false;
+ isnew = false;
+ isedited = false;
+ start = 0;
+ title = NULL;
+ summary = NULL;
+ if (!isdir && filename)
+ if (!CopyFromRecording(Recording))
+ ERROR(tr("Error while accessing recording!"));
+}
+
+bool cPlaylistRecord::CopyFromRecording(cRecording *Recording)
+{
+ cRecording *recording = Recording ? Recording : Recordings.GetByName(filename);
+ if (recording)
+ {
+ isedited = recording->IsEdited();
+ isnew = recording->IsNew();
+ start = recording->start;
+ title = strdup(recording->Title('\t', true, recording->HierarchyLevels()));
+ char *temp = strrchr(title, '\t');
+ if (temp)
+ *temp = 0;
+ summary = recording->Summary() ? strdup(recording->Summary()) : NULL;
+ return true;
+ }
+ isdel = true;
+ return false;
+}
+
+void cPlaylistRecord::CopyOptions(cPlaylistRecord *PlaylistRecord)
+{
+ for (int i = Option_confirmdeleterecord; i < Option_max; i++)
+ options[i] = PlaylistRecord->options[i];
+}
+
+bool cPlaylistRecord::Parse(const char *s)
+{
+ static cPlaylistRecord *lastdir = NULL;
+ char *namebuf = NULL;
+ char *filenamebuf = NULL;
+ int hasparent = false;
+ int opt1, opt2, opt3;
+ int fields = sscanf(s, "%a[^:]:%a[^:]:%d:%d:%d:%d:%d:%d:%d:%d:%d[:%d]", &namebuf,
+ &filenamebuf,
+ &hasparent,
+ &isdel,
+ &options[Option_confirmdeleterecord],
+ &options[Option_confirmstartnewrecord],
+ &options[Option_deletefromlist],
+ &options[Option_deleterecord],
+ &options[Option_jumpmark],
+ &opt1, &opt2, &opt3);
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecord::Parse fields=%d line=%s*", plugin_name, fields, s);
+#endif
+ if (namebuf)
+ {
+ strn0cpy(name, namebuf, sizeof(name));
+ free(namebuf);
+ }
+ FREENULL(filename);
+ filename = (filenamebuf && !strcasecmp(filenamebuf, "@null@")) ? NULL : filenamebuf;
+ strreplace(name, '|', ':');
+ if (filename)
+ {
+ strreplace(filename, '|', ':');
+ char *buffer = strdup(filename + strlen(VideoDirectory) + 1);
+ buffer = ExchangeChars(buffer, false);
+ char *temp = strrchr(buffer, '~');
+ if (temp)
+ *temp = 0;
+ path = strdup(buffer);
+ free(buffer);
+ isdir = filename[strlen(filename) - 1] == '/';
+ if (isdir)
+ lastdir = this;
+ else
+ {
+ if (lastdir && hasparent)
+ {
+ if (strstr(filename, lastdir->filename) == filename)
+ parent = lastdir;
+ }
+ if (!CopyFromRecording())
+ esyslog("%s: Error while accessing recording (deleted from playlist) %s", plugin_name, filename);
+ }
+ }
+ if (fields == 12)
+ {
+ options[Option_playonlynew] = opt1;
+ options[Option_searchnewrecord] = opt2;
+ options[Option_searchrecordsub] = opt3;
+ } else
+ {
+ options[Option_playonlynew] = isdir ? NoYesDefault_defaultPlaylist : NoYesDefault_defaultRecordDir;
+ options[Option_searchnewrecord] = opt1;
+ options[Option_searchrecordsub] = opt2;
+ }
+ return fields == 11 || fields == 12;
+}
+
+bool cPlaylistRecord::Save(FILE *f)
+{
+dsyslog("%s: cPlaylistRecord::Save", plugin_name);
+ char *buffer = NULL;
+ bool result = true;
+ if (!isdel || parent)
+ {
+ strreplace(name, ':', '|');
+ if (filename)
+ strreplace(filename, ':', '|');
+ asprintf(&buffer, "%s:%s:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
+ name,
+ filename ? filename : "@null@",
+ parent ? true : false,
+ isdel,
+ options[Option_confirmdeleterecord],
+ options[Option_confirmstartnewrecord],
+ options[Option_deletefromlist],
+ options[Option_deleterecord],
+ options[Option_jumpmark],
+ options[Option_playonlynew],
+ options[Option_searchnewrecord],
+ options[Option_searchrecordsub]);
+
+ strreplace(name, '|', ':');
+ if (filename)
+ strreplace(filename, '|', ':');
+ result = fputs(buffer, f) > 0;
+ *(buffer + strlen(buffer) - 1) = 0;
+ if (verbose.u)
+ isyslog("%s: write line [%s]", plugin_name, buffer);
+ }
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecord::Save buffer=%s result=%s", plugin_name, buffer, result ? "true" : "false");
+#endif
+ FREENULL(buffer);
+ return result;
+}
+
+bool cPlaylistRecord::DeleteRecord(void)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecord::DeleteRecord Name=%s Filename=%s", plugin_name, name, filename);
+#endif
+ DeleteRecording(filename, false);
+ if (playlist && playlist->RecordCol2())
+ {
+ isdel = true;
+ playlist->RecordCol2()->SetChange();
+ }
+ return true;
+}
+
+int cPlaylistRecord::IndexRec(void)
+{
+ if (!playlist)
+ return -1;
+ int index = 0;
+ for (cPlaylistRecord *plr = playlist->First_PLR(); plr; plr = playlist->Next_PLR(plr))
+ {
+ if (!plr->isdir && !plr->isdel)
+ {
+ index++;
+ if (plr == this)
+ return index;
+ }
+ }
+ return -2;
+}
+
+bool cPlaylistRecord::Option(eOptions Select)
+{
+ if (Select < Option_confirmdeleterecord || Select >= Option_max)
+ return false;
+ switch (options[Select])
+ {
+ case NoYesDefault_no: return false;
+ case NoYesDefault_yes: return true;
+ case NoYesDefault_defaultRecordDir: if (parent)
+ return parent->Option(Select);
+ // no break
+ case NoYesDefault_defaultPlaylist: if (playlist)
+ return playlist->Option(Select);
+ // no break
+ case NoYesDefault_defaultPlugin: return PL_options[Select].u;
+ default: return PL_options[Select].d;
+ }
+}
+
+bool cPlaylistRecord::operator< (const cListObject &ListObject)
+{
+ return start == ((cPlaylistRecord *)&ListObject)->start ? strcmp(name, ((cPlaylistRecord *)&ListObject)->name) < 0 : start < ((cPlaylistRecord *)&ListObject)->start;
+}
+
+bool cPlaylistRecord::operator!= (const cPlaylistRecord &PlaylistRecordObject)
+{
+ bool temp;
+ if (strlen(PlaylistRecordObject.name))
+ if (strlen(name))
+ temp = strcmp(name, PlaylistRecordObject.name);
+ else
+ temp = true;
+ else
+ temp = strlen(name);
+ if (temp)
+ return true;
+ for (int i = Option_confirmdeleterecord; i < Option_max; i++)
+ if (options[i] != PlaylistRecordObject.options[i])
+ return true;
+ return false;
+}
+
+// -- cPlaylistRecordCol ----------------------------------------------------------------
+
+cPlaylistRecordCol::cPlaylistRecordCol(cPlaylist *Parent)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecordCol::cPlaylistRecordCol", plugin_name);
+#endif
+ change = false;
+ parent = Parent;
+}
+
+cPlaylistRecordCol::~cPlaylistRecordCol(void)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecordCol::~cPlaylistRecordCol", plugin_name);
+#endif
+ parent = NULL;
+}
+
+void cPlaylistRecordCol::DeleteFile()
+{
+ if (!access(FileName(), F_OK))
+ if (remove(FileName()) < 0)
+ LOG_ERROR_STR(FileName());
+}
+
+bool cPlaylistRecordCol::SaveWithFilename()
+{
+#ifdef PL_Debug1
+ dsyslog("%s: cPlaylistRecordCol::SaveWithFilename playlist=%s", plugin_name, parent ? parent->Name() : "(null)");
+#endif
+ DeleteFile();
+ if (!parent || !*parent->Name())
+ return false;
+ char *tempname = NULL;
+ asprintf(&tempname, "%s%s%s", "playlists.", parent->Name(), ".conf");
+ const char *filenew = PluginPlaylist->ExpandPath(tempname);
+ free(tempname);
+
+ bool result = true;
+ cSafeFile f(filenew);
+ if (f.Open())
+ {
+ for(cPlaylistRecord *plr = First(); plr; plr = Next(plr))
+ {
+ if (!plr->Save((FILE *)f))
+ {
+ result = false;
+ break;
+ }
+ }
+ if (!f.Close())
+ result = false;
+ } else
+ result = false;
+ if (result)
+// {
+// Load(filenew);
+ change = false;
+// }
+ return result;
+}
+
+bool cPlaylistRecordCol::SearchRecord(const char *Filename)
+{
+ bool result = false;
+ for (cPlaylistRecord *plr = First(); plr; plr = Next(plr))
+ {
+ if (strcasecmp(plr->Filename(), Filename) == 0)
+ {
+ result = true;
+ break;
+ }
+ }
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylistRecordCol::SearchRecord Filename=%s found=%s", plugin_name, Filename, result ? "true" : "false");
+#endif
+ return result;
+}
+
+
+// -- cPlaylistSortCol ----------------------------------------------------------------
+
+cPlaylistSortCol PlaylistSort;
+
+// -- cPlaylist ----------------------------------------------------------------
+
+cPlaylist::cPlaylist(void)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylist::cPlaylist", plugin_name);
+#endif
+ name[0] = 0;
+ lastrecord = NULL;
+ for (int i = Option_confirmdeleterecord; i < Option_max; i++)
+ options[i] = NoYesDefault_defaultPlugin;
+ options[Option_playoption1] = PlayOptions_defaultPlugin;
+ options[Option_playoption2] = PlayOptions_defaultPlugin;
+ recordcount = 0;
+ recordnew = 0;
+ recordcol = new cPlaylistRecordCol(this);
+}
+
+cPlaylist::~cPlaylist(void)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylist::~cPlaylist [%s]", plugin_name, name);
+#endif
+ FREENULL(lastrecord);
+ if (recordcol)
+ DELETENULL(recordcol);
+}
+
+bool cPlaylist::Parse(const char *s)
+{
+ char *namebuf = NULL;
+ char *lastbuf = NULL;
+ int opt1, opt2, opt3, opt4;
+ int fields = sscanf(s, "%a[^:]:%a[^:]:%d:%d:%d:%d:%d:%d:%d:%d[:%d][:%d]", &namebuf,
+ &lastbuf,
+ &options[Option_confirmdeleterecord],
+ &options[Option_confirmstartnewrecord],
+ &options[Option_deletefromlist],
+ &options[Option_deleterecord],
+ &options[Option_jumpmark],
+ &options[Option_playoption1],
+ &opt1, &opt2, &opt3, &opt4);
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylist::Parse fields=%d line=%s*", plugin_name, fields, s);
+#endif
+ if (namebuf)
+ {
+ strn0cpy(name, namebuf, sizeof(name));
+ free(namebuf);
+ }
+ FREENULL(lastrecord);
+ lastrecord = (lastbuf && !strcasecmp(lastbuf, "@null@")) ? NULL : lastbuf;
+ strreplace(name, '|', ':');
+ if (lastrecord)
+ strreplace(lastrecord, '|', ':');
+ if (fields == 12)
+ {
+ options[Option_playoption2] = opt1;
+ options[Option_playonlynew] = opt2;
+ options[Option_searchnewrecord] = opt3;
+ options[Option_searchrecordsub] = opt4;
+ } else
+ {
+ options[Option_playoption2] = PlayOptions_defaultPlugin;
+ options[Option_playonlynew] = NoYesDefault_defaultPlugin;
+ options[Option_searchnewrecord] = opt1;
+ options[Option_searchrecordsub] = opt2;
+ }
+ return fields == 10 || fields == 12;
+}
+
+bool cPlaylist::Save(FILE *f)
+{
+ char *buffer = NULL;
+ strreplace(name, ':', '|');
+ if (lastrecord)
+ strreplace(lastrecord, ':', '|');
+ asprintf(&buffer, "%s:%s:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
+ name,
+ lastrecord ? lastrecord : "@null@",
+ options[Option_confirmdeleterecord],
+ options[Option_confirmstartnewrecord],
+ options[Option_deletefromlist],
+ options[Option_deleterecord],
+ options[Option_jumpmark],
+ options[Option_playoption1],
+ options[Option_playoption2],
+ options[Option_playonlynew],
+ options[Option_searchnewrecord],
+ options[Option_searchrecordsub]);
+ strreplace(name, '|', ':');
+ if (lastrecord)
+ strreplace(lastrecord, '|', ':');
+ bool result = fputs(buffer, f) > 0;
+ if (verbose.u)
+ isyslog("%s: write line [%s]", plugin_name, buffer);
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylist::Save buffer=%s result=%s", plugin_name, buffer, result ? "true" : "false");
+#endif
+ free(buffer);
+ return result;
+}
+
+bool cPlaylist::SearchRecords(void)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylist::SearchRecords start", plugin_name);
+#endif
+ bool modifyplaylist = false;
+ for (cPlaylistRecord *searchdir = recordcol->First(); searchdir; searchdir = recordcol->Next(searchdir))
+ {
+ if (searchdir->IsDir() && searchdir->Option(Option_searchnewrecord))
+ {
+ PlaylistSort.Clear();
+ cPlaylistRecord *plr = NULL;
+ for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording))
+ {
+ if (strstr(recording->FileName(), searchdir->Filename()) == recording->FileName())
+ {
+ const char *next = NULL;
+ if (!searchdir->Option(Option_searchrecordsub))
+ {
+ const char *test = recording->FileName() + strlen(searchdir->Filename());
+ const char *temp = strchr(test, '/');
+ if (temp)
+ next = strchr(temp + 1, '/');
+ }
+ if ((!next || searchdir->Option(Option_searchrecordsub)) && !recordcol->SearchRecord(recording->FileName()))
+ {
+ plr = new cPlaylistRecord(this, recording, searchdir);
+ PlaylistSort.Add(plr);
+ }
+ }
+ }
+ if (PlaylistSort.Count())
+ {
+ PlaylistSort.Sort();
+ cPlaylistRecord *temp = NULL;
+ cPlaylistRecord *lastrecord = NULL;
+ for (cPlaylistRecord *testrecord = recordcol->Next(searchdir); PlaylistSort.Count() && testrecord && testrecord->ParentObj() == searchdir; testrecord = recordcol->Next(testrecord))
+ {
+ lastrecord = testrecord;
+ temp = PlaylistSort.First();
+ if (testrecord->Start() > temp->Start())
+ {
+ PlaylistSort.Del(temp, false);
+ recordcol->Ins(temp, lastrecord);
+ modifyplaylist = true;
+ testrecord = temp; // if more then one recording to insert
+ }
+ }
+ for (plr = PlaylistSort.Last(); plr; plr = temp)
+ {
+ temp = PlaylistSort.Prev(plr);
+ PlaylistSort.Del(plr, false);
+ recordcol->Add(plr, lastrecord);
+ modifyplaylist = true;
+ }
+ }
+ }
+ }
+ CountRecords();
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylist::SearchRecords modified=%s count=%d new=%d", plugin_name, modifyplaylist ? "true" : "false", recordcount, recordnew);
+#endif
+ return modifyplaylist;
+}
+
+void cPlaylist::CountRecords(void)
+{
+#ifdef PL_Debug2
+ dsyslog("%s: cPlaylist::CountRecords", plugin_name);
+#endif
+ recordcount = 0;
+ recordnew = 0;
+ for (cPlaylistRecord *plr = recordcol->First(); plr; plr = recordcol->Next(plr))
+ {
+ if (!plr->IsDirOrDel())
+ {
+ recordcount++;
+ if (plr->IsNew())
+ recordnew++;
+ }
+ }
+}
+
+cPlaylistRecord *cPlaylist::Firstnormal_PLR(void)
+{
+ if (recordcol)
+ for (cPlaylistRecord *plr = recordcol->First(); plr; plr = recordcol->Next(plr))
+ if (!plr->IsDirOrDel())
+ return plr;
+ return NULL;
+}
+
+cPlaylistRecord *cPlaylist::Firstnew_PLR(void)
+{
+ if (recordcol)
+ for (cPlaylistRecord *plr = recordcol->First(); plr; plr = recordcol->Next(plr))
+ if (!plr->IsDirOrDel())
+ if (plr->IsNew())
+ return plr;
+ return NULL;
+}
+
+cPlaylistRecord *cPlaylist::Lastplayed_PLR(void)
+{
+ if (recordcol && lastrecord)
+ for (cPlaylistRecord *plr = recordcol->First(); plr; plr = recordcol->Next(plr))
+ if (!plr->IsDirOrDel())
+ if (strcmp(lastrecord, plr->Filename()) == 0)
+ return plr;
+ FREENULL(lastrecord);
+ return NULL;
+}
+
+bool cPlaylist::operator!= (const cPlaylist &PlaylistObject)
+{
+ bool temp;
+ if (strlen(PlaylistObject.name))
+ if (strlen(name))
+ temp = strcmp(name, PlaylistObject.name);
+ else
+ return true;
+ else
+ temp = strlen(name);
+ if (temp)
+ return true;
+ for (int i = Option_confirmdeleterecord; i < Option_max; i++)
+ if (options[i] != PlaylistObject.options[i])
+ return true;
+ return false;
+}
+
+cPlaylistRecord *SelectPLR = NULL;
+cPlaylistRecord *PlayedPLR = NULL;
+
+// -- cPlaylistCol ----------------------------------------------------------------
+
+cPlaylistCol PlaylistCol;