25
25
weak_ptr< RecordingsManager > RecordingsManager::m_recMan;
26
26
shared_ptr< RecordingsTree > RecordingsManager::m_recTree;
27
27
shared_ptr< RecordingsList > RecordingsManager::m_recList;
28
shared_ptr< DirectoryList > RecordingsManager::m_recDirs;
28
29
int RecordingsManager::m_recordingsState = 0;
30
31
// The RecordingsManager holds a VDR lock on the
75
76
return RecordingsListPtr(recMan, shared_ptr< RecordingsList >(new RecordingsList(m_recList, ascending)));
79
DirectoryListPtr RecordingsManager::GetDirectoryList() const
81
RecordingsManagerPtr recMan = EnsureValidData();
83
return DirectoryListPtr(recMan, shared_ptr< DirectoryList >());
85
return DirectoryListPtr(recMan, m_recDirs);
78
88
string RecordingsManager::Md5Hash(cRecording const * recording) const
80
90
return "recording_" + MD5Hash(recording->FileName());
83
93
cRecording const * RecordingsManager::GetByMd5Hash(string const & hash) const
85
95
if (!hash.empty()) {
86
for (cRecording* rec = Recordings.First(); rec != 0; rec = Recordings.Next(rec)) {
96
for (cRecording* rec = Recordings.First(); rec; rec = Recordings.Next(rec)) {
87
97
if (hash == Md5Hash(rec))
104
bool RecordingsManager::MoveRecording(cRecording const * recording, string const & name, bool copy) const
109
string oldname = recording->FileName();
110
size_t found = oldname.find_last_of("/");
112
if (found == string::npos)
115
string newname = string(VideoDirectory) + "/" + name + oldname.substr(found);
117
if (!MoveDirectory(oldname.c_str(), newname.c_str(), copy)) {
118
esyslog("[LIVE]: renaming failed from '%s' to '%s'", oldname.c_str(), newname.c_str());
123
Recordings.DelByName(oldname.c_str());
124
Recordings.AddByName(newname.c_str());
125
cRecordingUserCommand::InvokeCommand(*cString::sprintf("rename \"%s\"", *strescape(oldname.c_str(), "\\\"$'")), newname.c_str());
130
void RecordingsManager::DeleteResume(cRecording const * recording) const
135
//dsyslog("[LIVE]: deleting resume '%s'", recording->Name());
136
#if VDRVERSNUM < 10704
137
cResumeFile ResumeFile(recording->FileName());
139
cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording());
144
void RecordingsManager::DeleteMarks(cRecording const * recording) const
149
//dsyslog("[LIVE]: deleting marks '%s'", recording->Name());
151
marks.Load(recording->FileName());
153
cMark *mark = marks.First();
155
cMark *nextmark = marks.Next(mark);
94
163
void RecordingsManager::DeleteRecording(cRecording const * recording) const
101
170
Recordings.DelByName(name.c_str());
104
bool RecordingsManager::IsArchived(cRecording const * recording)
173
int RecordingsManager::GetArchiveType(cRecording const * recording)
106
175
string filename = recording->FileName();
108
string vdrFile = filename + "/001.vdr";
109
if (0 == access(vdrFile.c_str(), R_OK))
112
filename += "/dvd.vdr";
113
return (0 == access(filename.c_str(), R_OK));
177
string dvdFile = filename + "/dvd.vdr";
178
if (0 == access(dvdFile.c_str(), R_OK)) {
181
string hddFile = filename + "/hdd.vdr";
182
if (0 == access(hddFile.c_str(), R_OK)) {
116
string const RecordingsManager::GetArchiveId(cRecording const * recording)
188
string const RecordingsManager::GetArchiveId(cRecording const * recording, int archiveType)
118
190
string filename = recording->FileName();
120
filename += "/dvd.vdr";
121
ifstream dvd(filename.c_str());
192
if (archiveType==1) {
193
string dvdFile = filename + "/dvd.vdr";
194
ifstream dvd(dvdFile.c_str());
124
197
string archiveDisc;
131
204
return archiveDisc;
206
} else if(archiveType==2) {
207
string hddFile = filename + "/hdd.vdr";
208
ifstream hdd(hddFile.c_str());
136
219
string const RecordingsManager::GetArchiveDescr(cRecording const * recording)
139
if (IsArchived(recording)) {
223
archiveType = GetArchiveType(recording);
224
if (archiveType==1) {
140
225
archived += " [";
141
226
archived += tr("On archive DVD No.");
142
227
archived += ": ";
143
archived += GetArchiveId(recording);
228
archived += GetArchiveId(recording, archiveType);
230
} else if (archiveType==2) {
232
archived += tr("On archive HDD No.");
234
archived += GetArchiveId(recording, archiveType);
162
253
// StateChanged must be executed every time, so not part of
163
254
// the short cut evaluation in the if statement below.
164
255
bool stateChanged = Recordings.StateChanged(m_recordingsState);
165
if (stateChanged || (!m_recTree) || (!m_recList)) {
256
if (stateChanged || (!m_recTree) || (!m_recList) || (!m_recDirs)) {
166
257
if (stateChanged) {
167
258
m_recTree.reset();
168
259
m_recList.reset();
170
262
if (stateChanged || !m_recTree) {
171
263
m_recTree = shared_ptr< RecordingsTree >(new RecordingsTree(recMan));
181
273
esyslog("[LIVE]: creation of recordings list failed!");
182
274
return RecordingsManagerPtr();
276
if (stateChanged || !m_recDirs) {
277
m_recDirs = shared_ptr< DirectoryList >(new DirectoryList(recMan));
280
esyslog("[LIVE]: creation of directory list failed!");
281
return RecordingsManagerPtr();
290
* Implemetation of class RecordingsItemPtrCompare
292
bool RecordingsItemPtrCompare::ByAscendingDate(RecordingsItemPtr & first, RecordingsItemPtr & second)
294
if (first->StartTime() < second->StartTime())
299
bool RecordingsItemPtrCompare::ByDescendingDate(RecordingsItemPtr & first, RecordingsItemPtr & second)
301
if (first->StartTime() < second->StartTime())
306
bool RecordingsItemPtrCompare::ByAscendingName(RecordingsItemPtr & first, RecordingsItemPtr & second)
309
while (i < first->Name().length() && i < second->Name().length()) {
310
if (tolower((first->Name())[i]) < tolower((second->Name())[i]))
312
else if (tolower((first->Name())[i]) > tolower((second->Name())[i]))
316
if (first->Name().length() < second->Name().length())
321
bool RecordingsItemPtrCompare::ByDescendingName(RecordingsItemPtr & first, RecordingsItemPtr & second)
324
while (i < first->Name().length() && i < second->Name().length()) {
325
if (tolower((second->Name())[i]) < tolower((first->Name())[i]))
327
else if (tolower((second->Name())[i]) > tolower((first->Name())[i]))
331
if (second->Name().length() < first->Name().length())
190
338
* Implementation of class RecordingsItem:
192
340
RecordingsItem::RecordingsItem(string const & name, RecordingsItemPtr parent) :
243
391
long RecLength = 0;
244
392
if (!m_recording->FileName()) return 0;
393
#if VDRVERSNUM < 10704
245
394
cString filename = cString::sprintf("%s%s", m_recording->FileName(), INDEXFILESUFFIX);
247
396
if (access(filename, R_OK) == 0) {
409
#elif VDRVERSNUM < 10721
410
// open index file for reading only
411
cIndexFile *index = new cIndexFile(m_recording->FileName(), false, m_recording->IsPesRecording());
412
if (index && index->Ok()) {
413
RecLength = (int) (index->Last() / SecondsToFrames(60, m_recording->FramesPerSecond()));
417
return m_recording->LengthInSeconds() / 60;
419
if (RecLength == 0) {
420
cString lengthFile = cString::sprintf("%s%s", m_recording->FileName(), LENGTHFILESUFFIX);
421
ifstream length(*lengthFile);
260
426
return RecLength;
268
434
m_root(new RecordingsItemDir("", 0, RecordingsItemPtr()))
270
436
// esyslog("DH: ****** RecordingsTree::RecordingsTree() ********");
271
for (cRecording* recording = Recordings.First(); recording != 0; recording = Recordings.Next(recording)) {
437
for (cRecording* recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
272
438
if (m_maxLevel < recording->HierarchyLevels()) {
273
439
m_maxLevel = recording->HierarchyLevels();
654
* Implementation of class DirectoryList:
656
DirectoryList::DirectoryList(RecordingsManagerPtr recManPtr) :
657
m_pDirVec(new DirVecType())
663
m_pDirVec->push_back(""); // always add root directory
664
#if APIVERSNUM >= 10712
665
for (cNestedItem* item = Folders.First(); item; item = Folders.Next(item)) { // add folders.conf entries
666
InjectFoldersConf(item);
669
for (cRecording* recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
670
string name = recording->Name();
671
size_t found = name.find_last_of("~");
673
if (found != string::npos) {
674
m_pDirVec->push_back(StringReplace(name.substr(0, found), "~", "/"));
681
DirectoryList::~DirectoryList()
684
delete m_pDirVec, m_pDirVec = 0;
688
#if APIVERSNUM >= 10712
689
void DirectoryList::InjectFoldersConf(cNestedItem * folder, string parent)
695
string dir = string((parent.size() == 0) ? "" : parent + "/") + folder->Text();
696
m_pDirVec->push_back(StringReplace(dir, "_", " "));
698
if (!folder->SubItems()) {
702
for(cNestedItem* item = folder->SubItems()->First(); item; item = folder->SubItems()->Next(item)) {
703
InjectFoldersConf(item, dir);
709
* Implementation of class DirectoryListPtr:
711
DirectoryListPtr::DirectoryListPtr(RecordingsManagerPtr recManPtr, shared_ptr< DirectoryList > recDirs) :
712
shared_ptr< DirectoryList >(recDirs),
713
m_recManPtr(recManPtr)
717
DirectoryListPtr::~DirectoryListPtr()
488
723
* Implementation of function LiveRecordingsManager:
490
725
RecordingsManagerPtr LiveRecordingsManager()