~ubuntu-branches/ubuntu/saucy/vdr-plugin-live/saucy-proposed

« back to all changes in this revision

Viewing changes to recman.cpp

  • Committer: Package Import Robot
  • Author(s): Tobias Grimm
  • Date: 2012-01-15 10:22:53 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20120115102253-hixwx4gbcpyhtt2m
Tags: 0.2.0+git20120114-1
* New Upstream Snapshot (commit d2a85a6) (Closes: #654879)
* Dropped 02_timers_colon patch - fixed upstream
* Dropped 04_tntnet-2.0.patch - fixed upstream
* Dropped 01_ipv6.patch - fixed upstream
* Dropped 03_live-0.2.0-fix-INCLUDES.patch - fixed upstream
* Build-depend on libpcre3-dev
* Updated debian/copyright

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include <unistd.h>
2
 
#include <cstring>
3
2
#include <string>
4
3
#include <sstream>
5
4
#include <fstream>
13
12
#include "recman.h"
14
13
 
15
14
#define INDEXFILESUFFIX   "/index.vdr"
 
15
#define LENGTHFILESUFFIX  "/length.vdr"
16
16
 
17
17
using namespace std::tr1;
18
18
using namespace std;
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;
29
30
 
30
31
        // The RecordingsManager holds a VDR lock on the
75
76
                return RecordingsListPtr(recMan, shared_ptr< RecordingsList >(new RecordingsList(m_recList, ascending)));
76
77
        }
77
78
 
 
79
        DirectoryListPtr RecordingsManager::GetDirectoryList() const
 
80
        {
 
81
                RecordingsManagerPtr recMan = EnsureValidData();
 
82
                if (!recMan) {
 
83
                        return DirectoryListPtr(recMan, shared_ptr< DirectoryList >());
 
84
                }
 
85
                return DirectoryListPtr(recMan, m_recDirs);
 
86
        }
 
87
 
78
88
        string RecordingsManager::Md5Hash(cRecording const * recording) const
79
89
        {
80
90
                return "recording_" + MD5Hash(recording->FileName());
83
93
        cRecording const * RecordingsManager::GetByMd5Hash(string const & hash) const
84
94
        {
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))
88
98
                                        return rec;
89
99
                        }
91
101
                return 0;
92
102
        }
93
103
 
 
104
        bool RecordingsManager::MoveRecording(cRecording const * recording, string const & name, bool copy) const
 
105
        {
 
106
                if (!recording)
 
107
                        return false;
 
108
 
 
109
                string oldname = recording->FileName();
 
110
                size_t found = oldname.find_last_of("/");
 
111
 
 
112
                if (found == string::npos)
 
113
                        return false;
 
114
 
 
115
                string newname = string(VideoDirectory) + "/" + name + oldname.substr(found);
 
116
 
 
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());
 
119
                        return false;
 
120
                }
 
121
 
 
122
                if (!copy)
 
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());
 
126
 
 
127
                return true;
 
128
        }
 
129
 
 
130
        void RecordingsManager::DeleteResume(cRecording const * recording) const
 
131
        {
 
132
                if (!recording)
 
133
                        return;
 
134
 
 
135
                //dsyslog("[LIVE]: deleting resume '%s'", recording->Name());
 
136
#if VDRVERSNUM < 10704
 
137
                cResumeFile ResumeFile(recording->FileName());
 
138
#else
 
139
                cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording());
 
140
#endif
 
141
                ResumeFile.Delete();
 
142
        }
 
143
 
 
144
        void RecordingsManager::DeleteMarks(cRecording const * recording) const
 
145
        {
 
146
                if (!recording)
 
147
                        return;
 
148
 
 
149
                //dsyslog("[LIVE]: deleting marks '%s'", recording->Name());
 
150
                cMarks marks;
 
151
                marks.Load(recording->FileName());
 
152
                if (marks.Count()) {
 
153
                        cMark *mark = marks.First();
 
154
                        while (mark) {
 
155
                                cMark *nextmark = marks.Next(mark);
 
156
                                marks.Del(mark);
 
157
                                mark = nextmark;
 
158
                        }
 
159
                        marks.Save();
 
160
                }
 
161
        }
 
162
 
94
163
        void RecordingsManager::DeleteRecording(cRecording const * recording) const
95
164
        {
96
165
                if (!recording)
101
170
                Recordings.DelByName(name.c_str());
102
171
        }
103
172
 
104
 
        bool RecordingsManager::IsArchived(cRecording const * recording)
 
173
        int RecordingsManager::GetArchiveType(cRecording const * recording)
105
174
        {
106
175
                string filename = recording->FileName();
107
176
 
108
 
                string vdrFile = filename + "/001.vdr";
109
 
                if (0 == access(vdrFile.c_str(), R_OK))
110
 
                        return false;
111
 
 
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)) {
 
179
                        return 1;
 
180
                }
 
181
                string hddFile = filename + "/hdd.vdr";
 
182
                if (0 == access(hddFile.c_str(), R_OK)) {
 
183
                        return 2;
 
184
                }
 
185
                return 0;
114
186
        }
115
187
 
116
 
        string const RecordingsManager::GetArchiveId(cRecording const * recording)
 
188
        string const RecordingsManager::GetArchiveId(cRecording const * recording, int archiveType)
117
189
        {
118
190
                string filename = recording->FileName();
119
191
 
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());
122
195
 
123
196
                if (dvd) {
124
197
                        string archiveDisc;
130
203
                        }
131
204
                        return archiveDisc;
132
205
                }
 
206
                } else if(archiveType==2) {
 
207
                        string hddFile = filename + "/hdd.vdr";
 
208
                        ifstream hdd(hddFile.c_str());
 
209
 
 
210
                        if (hdd) {
 
211
                                string archiveDisc;
 
212
                                hdd >> archiveDisc;
 
213
                                return archiveDisc;
 
214
                        }
 
215
                }
133
216
                return "";
134
217
        }
135
218
 
136
219
        string const RecordingsManager::GetArchiveDescr(cRecording const * recording)
137
220
        {
 
221
                int archiveType;
138
222
                string archived;
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);
 
229
                        archived += "]";
 
230
                } else if (archiveType==2) {
 
231
                        archived += " [";
 
232
                        archived += tr("On archive HDD No.");
 
233
                        archived += ": ";
 
234
                        archived += GetArchiveId(recording, archiveType);
144
235
                        archived += "]";
145
236
                }
146
237
                return archived;
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();
 
260
                                m_recDirs.reset();
169
261
                        }
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();
183
275
                        }
 
276
                        if (stateChanged || !m_recDirs) {
 
277
                                m_recDirs = shared_ptr< DirectoryList >(new DirectoryList(recMan));
 
278
                        }
 
279
                        if (!m_recDirs) {
 
280
                                esyslog("[LIVE]: creation of directory list failed!");
 
281
                                return RecordingsManagerPtr();
 
282
                        }
 
283
 
184
284
                }
185
285
                return recMan;
186
286
        }
187
287
 
188
288
 
189
289
        /**
 
290
         * Implemetation of class RecordingsItemPtrCompare
 
291
         */
 
292
        bool RecordingsItemPtrCompare::ByAscendingDate(RecordingsItemPtr & first, RecordingsItemPtr & second)
 
293
        {
 
294
                if (first->StartTime() < second->StartTime())
 
295
                        return true;
 
296
                return false;
 
297
        }
 
298
 
 
299
        bool RecordingsItemPtrCompare::ByDescendingDate(RecordingsItemPtr & first, RecordingsItemPtr & second)
 
300
        {
 
301
                if (first->StartTime() < second->StartTime())
 
302
                        return false;
 
303
                return true;
 
304
        }
 
305
 
 
306
        bool RecordingsItemPtrCompare::ByAscendingName(RecordingsItemPtr & first, RecordingsItemPtr & second)
 
307
        {
 
308
                unsigned int i = 0;
 
309
                while (i < first->Name().length() && i < second->Name().length()) {
 
310
                        if (tolower((first->Name())[i]) < tolower((second->Name())[i]))
 
311
                                return true;
 
312
                        else if (tolower((first->Name())[i]) > tolower((second->Name())[i]))
 
313
                                return false;
 
314
                        ++i;
 
315
                }
 
316
                if (first->Name().length() < second->Name().length())
 
317
                        return true;
 
318
                return false;
 
319
        }
 
320
 
 
321
        bool RecordingsItemPtrCompare::ByDescendingName(RecordingsItemPtr & first, RecordingsItemPtr & second)
 
322
        {
 
323
                unsigned int i = 0;
 
324
                while (i < first->Name().length() && i < second->Name().length()) {
 
325
                        if (tolower((second->Name())[i]) < tolower((first->Name())[i]))
 
326
                                return true;
 
327
                        else if (tolower((second->Name())[i]) > tolower((first->Name())[i]))
 
328
                                return false;
 
329
                        ++i;
 
330
                }
 
331
                if (second->Name().length() < first->Name().length())
 
332
                        return true;
 
333
                return false;
 
334
        }
 
335
 
 
336
 
 
337
        /**
190
338
         *  Implementation of class RecordingsItem:
191
339
         */
192
340
        RecordingsItem::RecordingsItem(string const & name, RecordingsItemPtr parent) :
242
390
        {
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);
246
395
                if (*filename) {
247
396
                        if (access(filename, R_OK) == 0) {
257
406
                                }
258
407
                        }
259
408
                }
 
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()));
 
414
                }
 
415
                delete index;
 
416
#else
 
417
                return m_recording->LengthInSeconds() / 60;
 
418
#endif
 
419
                if (RecLength == 0) {
 
420
                        cString lengthFile = cString::sprintf("%s%s", m_recording->FileName(), LENGTHFILESUFFIX);
 
421
                        ifstream length(*lengthFile);
 
422
                        if(length)
 
423
                                length >> RecLength;
 
424
                }
 
425
 
260
426
                return RecLength;
261
427
        }
262
428
 
268
434
                m_root(new RecordingsItemDir("", 0, RecordingsItemPtr()))
269
435
        {
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();
274
440
                        }
485
651
 
486
652
 
487
653
        /**
 
654
         *  Implementation of class DirectoryList:
 
655
         */
 
656
        DirectoryList::DirectoryList(RecordingsManagerPtr recManPtr) :
 
657
                m_pDirVec(new DirVecType())
 
658
        {
 
659
                if (!m_pDirVec) {
 
660
                        return;
 
661
                }
 
662
 
 
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);
 
667
                }
 
668
#endif
 
669
                for (cRecording* recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
 
670
                        string name = recording->Name();
 
671
                        size_t found = name.find_last_of("~");
 
672
 
 
673
                        if (found != string::npos) {
 
674
                                m_pDirVec->push_back(StringReplace(name.substr(0, found), "~", "/"));
 
675
                        }
 
676
                }
 
677
                m_pDirVec->sort();
 
678
                m_pDirVec->unique();
 
679
        }
 
680
 
 
681
        DirectoryList::~DirectoryList()
 
682
        {
 
683
                if (m_pDirVec) {
 
684
                        delete m_pDirVec, m_pDirVec = 0;
 
685
                }
 
686
        }
 
687
 
 
688
#if APIVERSNUM >= 10712
 
689
        void DirectoryList::InjectFoldersConf(cNestedItem * folder, string parent)
 
690
        {
 
691
                if (!folder) {
 
692
                        return;
 
693
                }
 
694
 
 
695
                string dir = string((parent.size() == 0) ? "" : parent + "/") + folder->Text();
 
696
                m_pDirVec->push_back(StringReplace(dir, "_", " "));
 
697
 
 
698
                if (!folder->SubItems()) {
 
699
                        return;
 
700
                }
 
701
 
 
702
                for(cNestedItem* item = folder->SubItems()->First(); item; item = folder->SubItems()->Next(item)) {
 
703
                        InjectFoldersConf(item, dir);
 
704
                }
 
705
        }
 
706
#endif
 
707
 
 
708
        /**
 
709
         *  Implementation of class DirectoryListPtr:
 
710
         */
 
711
        DirectoryListPtr::DirectoryListPtr(RecordingsManagerPtr recManPtr, shared_ptr< DirectoryList > recDirs) :
 
712
                shared_ptr< DirectoryList >(recDirs),
 
713
                m_recManPtr(recManPtr)
 
714
        {
 
715
        }
 
716
 
 
717
        DirectoryListPtr::~DirectoryListPtr()
 
718
        {
 
719
        }
 
720
 
 
721
 
 
722
        /**
488
723
         *  Implementation of function LiveRecordingsManager:
489
724
         */
490
725
        RecordingsManagerPtr LiveRecordingsManager()