#include #include #include #include #include #include "tools.h" #include "epg_events.h" #include "recordings.h" #include "stdext.h" using namespace std::tr1; using namespace std; namespace vdrlive { RecordingsManager::RecordingsManager() : m_recordingsLock(&Recordings) { } string RecordingsManager::Md5Hash(const cRecording* recording) const { return "recording_" + MD5Hash(recording->FileName()); /* unsigned char md5[MD5_DIGEST_LENGTH]; const char* fileName = recording->FileName(); MD5(reinterpret_cast(fileName), strlen(fileName), md5); ostringstream hashStr; hashStr << "MD5" << hex; for (size_t i = 0; i < MD5_DIGEST_LENGTH; i++) hashStr << (0 + md5[i]); return hashStr.str(); */ } const cRecording* RecordingsManager::GetByMd5Hash(const string& hash) const { if (!hash.empty()) { for (cRecording* rec = Recordings.First(); rec != 0; rec = Recordings.Next(rec)) { if (hash == Md5Hash(rec)) return rec; } } return 0; } bool RecordingsManager::IsArchived(const cRecording* recording) { string filename = recording->FileName(); string vdrFile = filename + "/001.vdr"; if (0 == access(vdrFile.c_str(), R_OK)) return false; filename += "/dvd.vdr"; return (0 == access(filename.c_str(), R_OK)); } const std::string RecordingsManager::GetArchiveId(const cRecording* recording) { string filename = recording->FileName(); filename += "/dvd.vdr"; ifstream dvd(filename.c_str()); if (dvd) { string archiveDisc; string videoDisc; dvd >> archiveDisc; if ("0000" == archiveDisc) { dvd >> videoDisc; return videoDisc; } return archiveDisc; } return ""; } const string RecordingsManager::GetArchiveDescr(const cRecording* recording) { string archived; if (IsArchived(recording)) { archived += " ["; archived += tr("On archive DVD No."); archived += ": "; archived += GetArchiveId(recording); archived += "]"; } return archived; } RecordingsTree::RecordingsTree(RecordingsManagerPtr recMan) : m_maxLevel(0), m_root(new RecordingsItemDir()), m_recManPtr(recMan) { // esyslog("DH: ****** RecordingsTree::RecordingsTree() ********"); for ( cRecording* recording = Recordings.First(); recording != 0; recording = Recordings.Next( recording ) ) { if (m_maxLevel < recording->HierarchyLevels()) { m_maxLevel = recording->HierarchyLevels(); } RecordingsItemPtr dir = m_root; string name(recording->Name()); // esyslog("DH: recName = '%s'", recording->Name()); int level = 0; size_t index = 0; size_t pos = 0; do { pos = name.find('~', index); if (pos != string::npos) { string dirName(name.substr(index, pos - index)); index = pos + 1; Map::iterator i = findDir(dir, dirName); if (i == dir->m_entries.end()) { RecordingsItemPtr recPtr (new RecordingsItemDir(dirName, level)); dir->m_entries.insert(pair< string, RecordingsItemPtr > (dirName, recPtr)); i = findDir(dir, dirName); if (i != dir->m_entries.end()) { // esyslog("DH: added dir: '%s'", dirName.c_str()); } else { // esyslog("DH: panic: didn't found inserted dir: '%s'", dirName.c_str()); } } dir = i->second; // esyslog("DH: current dir: '%s'", dir->Name().c_str()); level++; } else { string recName(name.substr(index, name.length() - index)); RecordingsItemPtr recPtr (new RecordingsItemRec(m_recManPtr->Md5Hash(recording), recName, recording)); dir->m_entries.insert(pair< string, RecordingsItemPtr > (recName, recPtr)); // esyslog("DH: added rec: '%s'", recName.c_str()); } } while (pos != string::npos); } // esyslog("DH: ------ RecordingsTree::RecordingsTree() --------"); } RecordingsTree::~RecordingsTree() { // esyslog("DH: ****** RecordingsTree::~RecordingsTree() ********"); } RecordingsTree::Map::iterator RecordingsTree::begin(const vector< string >& path) { if (path.empty()) { return m_root->m_entries.begin(); } RecordingsItemPtr recItem = m_root; for (vector< string >::const_iterator i = path.begin(); i != path.end(); ++i) { pair< Map::iterator, Map::iterator> range = recItem->m_entries.equal_range(*i); for (Map::iterator iter = range.first; iter != range.second; ++iter) { if (iter->second->IsDir()) { recItem = iter->second; break; } } } return recItem->m_entries.begin(); } RecordingsTree::Map::iterator RecordingsTree::end(const vector< string >&path) { if (path.empty()) { return m_root->m_entries.end(); } RecordingsItemPtr recItem = m_root; for (vector< string >::const_iterator i = path.begin(); i != path.end(); ++i) { pair< Map::iterator, Map::iterator> range = recItem->m_entries.equal_range(*i); for (Map::iterator iter = range.first; iter != range.second; ++iter) { if (iter->second->IsDir()) { recItem = iter->second; break; } } } return recItem->m_entries.end(); } RecordingsTree::Map::iterator RecordingsTree::findDir(RecordingsItemPtr& dir, const string& dirName) { pair< Map::iterator, Map::iterator > range = dir->m_entries.equal_range(dirName); for (Map::iterator i = range.first; i != range.second; ++i) { if (i->second->IsDir()) { return i; } } return dir->m_entries.end(); } RecordingsTree::RecordingsItem::RecordingsItem(const string& name) : m_name(name), m_entries() { } RecordingsTree::RecordingsItem::~RecordingsItem() { } RecordingsTree::RecordingsItemDir::RecordingsItemDir() : RecordingsItem(""), m_level(0) { } RecordingsTree::RecordingsItemDir::~RecordingsItemDir() { } RecordingsTree::RecordingsItemDir::RecordingsItemDir(const string& name, int level) : RecordingsItem(name), m_level(level) { } RecordingsTree::RecordingsItemRec::RecordingsItemRec(const string& id, const string& name, const cRecording* recording) : RecordingsItem(name), m_recording(recording), m_id(id) { } RecordingsTree::RecordingsItemRec::~RecordingsItemRec() { } time_t RecordingsTree::RecordingsItemRec::StartTime() const { return m_recording->start; } RecordingsManagerPtr LiveRecordingsManager() { static weak_ptr livingRecMan; RecordingsManagerPtr r = livingRecMan.lock(); if (r) { return r; } else { RecordingsManagerPtr n(new RecordingsManager); livingRecMan = n; return n; } } } // namespace vdrlive