X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/771c2ef46032790eca3d3f2c480c8ab1c18c6247..20fdb2a2af40da98427a702a03a79b1fbec3d7af:/lib/dvb/db.cpp diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index c6871c1a..38a062a2 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -34,20 +35,31 @@ RESULT eBouquet::moveService(const eServiceReference &ref, unsigned int pos) { if ( pos < 0 || pos >= m_services.size() ) return -1; + ++pos; list::iterator source=m_services.end(); list::iterator dest=m_services.end(); + bool forward = false; for (list::iterator it(m_services.begin()); it != m_services.end(); ++it) { - if (dest == m_services.end() && !pos--) + if (dest == m_services.end() && !--pos) dest = it; if (*it == ref) + { source = it; + forward = pos>0; + } if (dest != m_services.end() && source != m_services.end()) break; } if (dest == m_services.end() || source == m_services.end() || source == dest) return -1; - std::iter_swap(source,dest); + while (source != dest) + { + if (forward) + std::iter_swap(source++, source); + else + std::iter_swap(source--, source); + } return 0; } @@ -113,10 +125,22 @@ eDVBService &eDVBService::operator=(const eDVBService &s) return *this; } +void eDVBService::genSortName() +{ + m_service_name_sort = removeDVBChars(m_service_name); + makeUpper(m_service_name_sort); + while ((!m_service_name_sort.empty()) && m_service_name_sort[0] == ' ') + m_service_name_sort.erase(0, 1); + + /* put unnamed services at the end, not at the beginning. */ + if (m_service_name_sort.empty()) + m_service_name_sort = "\xFF"; +} + RESULT eDVBService::getName(const eServiceReference &ref, std::string &name) { - if (!ref.name.empty()) - name = ref.name; + if (!ref.name.empty()) + name = ref.name; // use renamed service name.. else if (!m_service_name.empty()) name = m_service_name; else @@ -124,9 +148,10 @@ RESULT eDVBService::getName(const eServiceReference &ref, std::string &name) return 0; } -int eDVBService::getLength(const eServiceReference &ref) +RESULT eDVBService::getEvent(const eServiceReference &ref, ePtr &ptr) { - return -1; + time_t t=-1; + return eEPGCache::getInstance()->lookupEventTime(ref, t, ptr); } int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query) @@ -303,15 +328,8 @@ void eDVBDB::load() line[strlen(line)-1]=0; s->m_service_name = line; - s->m_service_name_sort = removeDVBChars(line); - makeUpper(s->m_service_name_sort); - while ((!s->m_service_name_sort.empty()) && s->m_service_name_sort[0] == ' ') - s->m_service_name_sort.erase(0, 1); - - /* put unnamed services at the end, not at the beginning. */ - if (s->m_service_name_sort.empty()) - s->m_service_name_sort = "\xFF"; - + s->genSortName(); + fgets(line, 256, f); if (strlen(line)) line[strlen(line)-1]=0; @@ -530,11 +548,6 @@ void eDVBDB::loadBouquet(const char *path) eDebug("%d entries in Bouquet %s", entries, bouquet_name.c_str()); } -void eDVBDB::saveBouquet(const char *path) -{ - -} - void eDVBDB::loadBouquets() { loadBouquet("bouquets.tv"); @@ -556,7 +569,7 @@ void eDVBDB::loadBouquets() parent.m_services.push_back(ref); parent.flushChanges(); } - if ( m_bouquets.find("userbouquets.favourites.radio") == m_bouquets.end() ) + if ( m_bouquets.find("userbouquet.favourites.radio") == m_bouquets.end() ) { eBouquet &b = m_bouquets["userbouquet.favourites.radio"]; b.m_path = "userbouquet.favourites.radio"; @@ -574,11 +587,6 @@ void eDVBDB::loadBouquets() } } -void eDVBDB::saveBouquets() -{ - -} - eDVBDB::eDVBDB() { load(); @@ -636,6 +644,12 @@ RESULT eDVBDB::getService(const eServiceReferenceDVB &reference, ePtr &query, eDVBChannelQuery *q, const eServiceReference &source) { - if ( q && q->m_bouquet_name.length() ) - query = new eDVBDBBouquetQuery(this, source, q); + if ( source.path.find("FROM") != std::string::npos ) + { + if ( source.path.find("BOUQUET") != std::string::npos ) + query = new eDVBDBBouquetQuery(this, source, q); + else if ( source.path.find("SATELLITES") != std::string::npos ) + query = new eDVBDBSatellitesQuery(this, source, q); + else if ( source.path.find("PROVIDERS") != std::string::npos ) + query = new eDVBDBProvidersQuery(this, source, q); + else + eFatal("invalid query %s", source.toString().c_str()); + } else query = new eDVBDBQuery(this, source, q); return 0; @@ -772,6 +795,118 @@ RESULT eDVBDBBouquetQuery::getNextResult(eServiceReferenceDVB &ref) return 1; } +eDVBDBListQuery::eDVBDBListQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query) + :eDVBDBQueryBase(db, source, query), m_cursor(m_list.end()) +{ +} + +RESULT eDVBDBListQuery::getNextResult(eServiceReferenceDVB &ref) +{ + if (m_cursor != m_list.end()) + { + ref = *m_cursor++; + return 0; + } + ref.type = eServiceReference::idInvalid; + return 1; +} + +int eDVBDBListQuery::compareLessEqual(const eServiceReferenceDVB &a, const eServiceReferenceDVB &b) +{ + if ( m_query->m_sort == eDVBChannelQuery::tSatellitePosition ) + return (a.getDVBNamespace().get() >> 16) < (b.getDVBNamespace().get() >> 16); + return a.name < b.name; +} + +eDVBDBSatellitesQuery::eDVBDBSatellitesQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query) + :eDVBDBListQuery(db, source, query) +{ + for (std::map >::iterator it(m_db->m_services.begin()); + it != m_db->m_services.end(); ++it) + { + int res = it->second->checkFilter(it->first, *query); + if (res) + { + unsigned int dvbnamespace = it->first.getDVBNamespace().get()&0xFFFF0000; + bool found=0; + for (std::list::iterator i(m_list.begin()); i != m_list.end(); ++i) + if ( (i->getDVBNamespace().get()&0xFFFF0000) == dvbnamespace ) + { + found=true; + break; + } + if (!found) + { + eServiceReferenceDVB ref; + ref.setDVBNamespace(dvbnamespace); + char buf[64]; +// TODO get real satellite name.. +// but i dont like to parse the satellites.xml here.. and in the python part + snprintf(buf, 64, "Services - %d", dvbnamespace>>16); + ref.name=buf; + snprintf(buf, 64, "(satellitePosition == %d) && ", dvbnamespace>>16); + ref.path=buf+source.path; + unsigned int pos=ref.path.find("FROM"); + ref.flags=eServiceReference::flagDirectory; + ref.path.erase(pos); + ref.path+="ORDER BY name"; +// eDebug("ref.path now %s", ref.path.c_str()); + m_list.push_back(ref); + + ref.path=buf+source.path; + pos=ref.path.find("FROM"); + ref.path.erase(pos+5); + ref.path+="PROVIDERS ORDER BY name"; +// eDebug("ref.path now %s", ref.path.c_str()); + snprintf(buf, 64, "Providers - %d", dvbnamespace>>16); + ref.name=buf; + m_list.push_back(ref); + } + } + } + m_cursor=m_list.begin(); +} + +eDVBDBProvidersQuery::eDVBDBProvidersQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query) + :eDVBDBListQuery(db, source, query) +{ + for (std::map >::iterator it(m_db->m_services.begin()); + it != m_db->m_services.end(); ++it) + { + int res = it->second->checkFilter(it->first, *query); + if (res) + { + bool found=0; + + const char *provider_name = it->second->m_provider_name.length() ? + it->second->m_provider_name.c_str() : + "Unknown"; + + for (std::list::iterator i(m_list.begin()); i != m_list.end(); ++i) + if (i->name == provider_name) + { + found=true; + break; + } + if (!found) + { + eServiceReferenceDVB ref; + char buf[64]; + ref.name=provider_name; + snprintf(buf, 64, "(provider == \"%s\") && ", provider_name); + ref.path=buf+source.path; + unsigned int pos = ref.path.find("FROM"); + ref.flags=eServiceReference::flagDirectory; + ref.path.erase(pos); + ref.path+="ORDER BY name"; +// eDebug("ref.path now %s", ref.path.c_str()); + m_list.push_back(ref); + } + } + } + m_cursor=m_list.begin(); +} + /* ( <==|...> <"string"|int>)[||,&& (..)] */ static int decodeType(const std::string &type) @@ -963,37 +1098,41 @@ RESULT eDVBChannelQuery::compile(ePtr &res, std::string query) int sort = eDVBChannelQuery::tName; /* check for "ORDER BY ..." */ - while (tokens.size() > 2) + std::list::iterator it = tokens.begin(); + while (it != tokens.end()) { - std::list::iterator it = tokens.end(); - --it; --it; --it; if (*it == "ORDER") { - ++it; - if (*it == "BY") + tokens.erase(it++); + if (it != tokens.end() && *it == "BY") { - ++it; + tokens.erase(it++); sort = decodeType(*it); - tokens.pop_back(); // ... - tokens.pop_back(); // BY - tokens.pop_back(); // ORDER + tokens.erase(it++); } else sort = -1; } else if (*it == "FROM") { - ++it; - if (*it == "BOUQUET") + tokens.erase(it++); + if (it != tokens.end() && *it == "BOUQUET") { - ++it; + tokens.erase(it++); bouquet_name = *it; - tokens.pop_back(); // ... - tokens.pop_back(); // FROM - tokens.pop_back(); // BOUQUET + tokens.erase(it++); + } + else if (it != tokens.end() && *it == "SATELLITES") + tokens.erase(it++); + else if (it != tokens.end() && *it == "PROVIDERS") + tokens.erase(it++); + else + { + eDebug("FROM unknown %s", (*it).c_str()); + tokens.erase(it++); } } else - break; + ++it; } if (sort == -1)