diff options
author | louis <louis.braun@gmx.de> | 2014-10-18 16:50:33 +0200 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2014-10-18 16:50:33 +0200 |
commit | 3ef0db807d386553f1842ca0b8b0e931498237e1 (patch) | |
tree | 30f332068706af8f57715925c826fc39c92011a1 /libcore | |
parent | 762115bf818fb11b5f03525d115adad1f40c480d (diff) | |
download | vdr-plugin-skindesigner-3ef0db807d386553f1842ca0b8b0e931498237e1.tar.gz vdr-plugin-skindesigner-3ef0db807d386553f1842ca0b8b0e931498237e1.tar.bz2 |
added date of newest recording in a folder
Diffstat (limited to 'libcore')
-rw-r--r-- | libcore/recfolderinfo.c | 201 | ||||
-rw-r--r-- | libcore/recfolderinfo.h | 42 |
2 files changed, 243 insertions, 0 deletions
diff --git a/libcore/recfolderinfo.c b/libcore/recfolderinfo.c new file mode 100644 index 0000000..debc309 --- /dev/null +++ b/libcore/recfolderinfo.c @@ -0,0 +1,201 @@ +#include "recfolderinfo.h" + + +class cFolderInfoInternList; + +class cRecordingsFolderInfo::cFolderInfoIntern:public cListObject { +private: + cFolderInfoIntern *_parent; + cList<cFolderInfoIntern> *_subFolders; + + cString _name; + time_t _latest; + int _count; + + void UpdateData(cRecording *Recording); + cFolderInfoIntern *FindSubFolder(const char *Name) const; + +public: + cFolderInfoIntern(cFolderInfoIntern *Parent, const char *Name); + virtual ~cFolderInfoIntern(void); + + // split Name and find folder-info in tree + // if "Add", missing folders are created + cFolderInfoIntern *Find(const char *Name, bool Add); + + void Add(cRecording *Recording); + + cRecordingsFolderInfo::cFolderInfo *GetInfo(void) const; + + cString FullName(void) const; + cString ToText(void) const; + cString DebugOutput(void) const; +}; + + +cRecordingsFolderInfo::cFolderInfo::cFolderInfo(const char *Name, const char *FullName, time_t Latest, int Count) +{ + this->Name = Name; + this->FullName = FullName; + this->Latest = Latest; + this->Count = Count; +} + + +cRecordingsFolderInfo::cRecordingsFolderInfo(cRecordings &Recordings) +:_recordings(Recordings) +,_root(NULL) +{ + Rebuild(); +} + +cRecordingsFolderInfo::~cRecordingsFolderInfo(void) +{ + delete _root; + _root = NULL; +} + +void cRecordingsFolderInfo::Rebuild(void) +{ + delete _root; + _root = new cFolderInfoIntern(NULL, ""); + + cThreadLock RecordingsLock(&_recordings); + // re-get state with lock held + _recordings.StateChanged(_recState); + cFolderInfoIntern *info; + for (cRecording *rec = _recordings.First(); rec; rec = _recordings.Next(rec)) { + info = _root->Find(*rec->Folder(), true); + info->Add(rec); + } +} + +cRecordingsFolderInfo::cFolderInfo *cRecordingsFolderInfo::Get(const char *Folder) +{ + cMutexLock lock(&_rootLock); + + if (_recordings.StateChanged(_recState) || (_root == NULL)) + Rebuild(); + + cFolderInfoIntern *info = _root->Find(Folder, false); + if (info == NULL) + return NULL; + + return info->GetInfo(); +} + +cString cRecordingsFolderInfo::DebugOutput(void) const +{ + cMutexLock lock(&_rootLock); + + return _root->DebugOutput(); +} + + +cRecordingsFolderInfo::cFolderInfoIntern::cFolderInfoIntern(cFolderInfoIntern *Parent, const char *Name) +:_parent(Parent) +,_name(Name) +,_latest(0) +,_count(0) +{ + _subFolders = new cList<cFolderInfoIntern>(); +} + +cRecordingsFolderInfo::cFolderInfoIntern::~cFolderInfoIntern(void) +{ + delete _subFolders; + _subFolders = NULL; +} + +cRecordingsFolderInfo::cFolderInfoIntern *cRecordingsFolderInfo::cFolderInfoIntern::Find(const char *Name, bool Add) +{ + cFolderInfoIntern *info = NULL; + if (Add) + info = this; + + if (Name && *Name) { + static char delim[2] = { FOLDERDELIMCHAR, 0 }; + char *strtok_next; + cFolderInfoIntern *next; + char *folder = strdup(Name); + info = this; + for (char *t = strtok_r(folder, delim, &strtok_next); t; t = strtok_r(NULL, delim, &strtok_next)) { + next = info->FindSubFolder(t); + if (next == NULL) { + if (!Add) { + info = NULL; + break; + } + + next = new cFolderInfoIntern(info, t); + info->_subFolders->Add(next); + } + info = next; + } + free(folder); + } + + return info; +} + +void cRecordingsFolderInfo::cFolderInfoIntern::UpdateData(cRecording *Recording) +{ + // count every recording + _count++; + + // update date if newer + time_t recdate = Recording->Start(); + if (_latest < recdate) + _latest = recdate; +} + +cRecordingsFolderInfo::cFolderInfoIntern *cRecordingsFolderInfo::cFolderInfoIntern::FindSubFolder(const char *Name) const +{ + for (cRecordingsFolderInfo::cFolderInfoIntern *info = _subFolders->First(); info; info = _subFolders->Next(info)) { + if (strcmp(info->_name, Name) == 0) + return info; + } + return NULL; +} + +void cRecordingsFolderInfo::cFolderInfoIntern::Add(cRecording *Recording) +{ + if (Recording == NULL) + return; + + // update this and all parent folders + for (cFolderInfoIntern *p = this; p; p = p->_parent) + p->UpdateData(Recording); +} + +cRecordingsFolderInfo::cFolderInfo *cRecordingsFolderInfo::cFolderInfoIntern::GetInfo(void) const +{ + return new cRecordingsFolderInfo::cFolderInfo(*_name, *FullName(), _latest, _count); +} + +cString cRecordingsFolderInfo::cFolderInfoIntern::FullName(void) const +{ + static char delim[2] = { FOLDERDELIMCHAR, 0 }; + + cString name = _name; + for (cFolderInfoIntern *p = _parent; p; p = p->_parent) { + // don't add FOLDERDELIMCHAR at start of FullName + if (p->_parent == NULL) + break; + name = cString::sprintf("%s%s%s", *p->_name, delim, *name); + } + return name; +} + +cString cRecordingsFolderInfo::cFolderInfoIntern::ToText(void) const +{ + return cString::sprintf("%s (%d recordings, latest: %s)\n", *FullName(), _count, *ShortDateString(_latest)); +} + +cString cRecordingsFolderInfo::cFolderInfoIntern::DebugOutput(void) const +{ + cString output = ToText(); + for (cFolderInfoIntern *i = _subFolders->First(); i; i = _subFolders->Next(i)) + output = cString::sprintf("%s%s", *output, *i->DebugOutput()); + return output; +}
\ No newline at end of file diff --git a/libcore/recfolderinfo.h b/libcore/recfolderinfo.h new file mode 100644 index 0000000..65d0c70 --- /dev/null +++ b/libcore/recfolderinfo.h @@ -0,0 +1,42 @@ +#ifndef __RECFOLDERINFO_H +#define __RECFOLDERINFO_H + +#include <vdr/recording.h> + + +class cRecordingsFolderInfo { +public: + class cFolderInfoIntern; + +private: + cRecordings &_recordings; + int _recState; + cFolderInfoIntern *_root; + mutable cMutex _rootLock; + + void Rebuild(void); + +public: + class cFolderInfo { + public: + cString Name; + cString FullName; + time_t Latest; + int Count; + + cFolderInfo(const char *Name, const char *FullName, time_t Latest, int Count); + }; + + cRecordingsFolderInfo(cRecordings &Recordings); + ~cRecordingsFolderInfo(void); + + // caller must delete the cInfo object! + // returns NULL if folder doesn't exists + // will rebuild tree if recordings' state has changed + // is thread-safe + cFolderInfo *Get(const char *Folder); + + cString DebugOutput(void) const; +}; + +#endif // __RECFOLDERINFO_H
\ No newline at end of file |