add function to get a comparable service reference string (useable to
[enigma2.git] / lib / service / servicefs.cpp
index 9db85028197bc85ecac20a5677117625f83fa681..16948854484240a9af262edec8cad69c3e65315d 100644 (file)
@@ -4,6 +4,7 @@
 #include <errno.h>
 #include <lib/service/servicefs.h>
 #include <lib/service/service.h>
+#include <lib/service/servicedvb.h>
 #include <lib/base/init_num.h>
 #include <lib/base/init.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
-
 class eStaticServiceFSInformation: public iStaticServiceInformation
 {
        DECLARE_REF(eStaticServiceFSInformation);
 public:
        RESULT getName(const eServiceReference &ref, std::string &name);
+       int getLength(const eServiceReference &ref) { return -1; }
 };
 
 DEFINE_REF(eStaticServiceFSInformation);
@@ -24,6 +25,7 @@ DEFINE_REF(eStaticServiceFSInformation);
 RESULT eStaticServiceFSInformation::getName(const eServiceReference &ref, std::string &name)
 {
        name = ref.path;
+       return 0;
 }
 
 // eServiceFactoryFS
@@ -32,7 +34,7 @@ eServiceFactoryFS::eServiceFactoryFS()
 {
        ePtr<eServiceCenter> sc;
        
-       eServiceCenter::getInstance(sc);
+       eServiceCenter::getPrivInstance(sc);
        if (sc)
                sc->addServiceFactory(eServiceFactoryFS::id, this);
        
@@ -43,7 +45,7 @@ eServiceFactoryFS::~eServiceFactoryFS()
 {
        ePtr<eServiceCenter> sc;
        
-       eServiceCenter::getInstance(sc);
+       eServiceCenter::getPrivInstance(sc);
        if (sc)
                sc->removeServiceFactory(eServiceFactoryFS::id);
 }
@@ -75,19 +77,31 @@ RESULT eServiceFactoryFS::info(const eServiceReference &ref, ePtr<iStaticService
        return 0;
 }
 
+RESULT eServiceFactoryFS::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
+{
+       ptr = 0;
+       return -1;
+}
+
 // eServiceFS
 
 DEFINE_REF(eServiceFS);
 
 eServiceFS::eServiceFS(const char *path): path(path)
 {
+       m_list_valid = 0;
 }
 
 eServiceFS::~eServiceFS()
 {
 }
 
-RESULT eServiceFS::getContent(std::list<eServiceReference> &list)
+int lower(char c)
+{
+       return std::tolower(static_cast<unsigned char>(c));
+}
+
+RESULT eServiceFS::getContent(std::list<eServiceReference> &list, bool sorted)
 {
        DIR *d=opendir(path.c_str());
        if (!d)
@@ -120,16 +134,170 @@ RESULT eServiceFS::getContent(std::list<eServiceReference> &list)
                        list.push_back(service);
                } else
                {
-                       eServiceReference service(eServiceFactoryFS::id, 
-                               eServiceReference::isDirectory|
-                               eServiceReference::canDescent|eServiceReference::mustDescent|
-                               eServiceReference::shouldSort|eServiceReference::sort1,
-                               filename);
-                       service.data[0] = 0;
-                       list.push_back(service);
+                       size_t e = filename.rfind('.');
+                       std::string extension = (e != std::string::npos) ? filename.substr(e) : "";
+                       std::transform(extension.begin(), extension.end(), extension.begin(), lower);
+                       int type = -1;
+                       
+                       if (extension == ".ts")
+                               type = eServiceFactoryDVB::id;
+                       else if (extension == ".mp3")
+                               type = 4097;
+                       else if (extension == ".ogg")
+                               type = 4097;
+                       else if (extension == ".mpg")
+                               type = 4097;
+                       else if (extension == ".vob")
+                               type = 4097;
+                       else if (extension == ".wav" || extension == ".wave")
+                               type = 4097;
+                       else if (extension == ".m3u" || extension == ".pls" || extension == ".e2pls")
+                               type = 4098;
+                       
+                       if (type != -1)
+                       {
+                               eServiceReference service(type,
+                                       0,
+                                       filename);
+                               service.data[0] = 0;
+                               list.push_back(service);
+                       }
+               }
+       }
+       closedir(d);
+
+       if (sorted)
+               list.sort(iListableServiceCompare(this));
+
+       return 0;
+}
+
+//   The first argument of this function is a format string to specify the order and
+//   the content of the returned list
+//   useable format options are
+//   R = Service Reference (as swig object .. this is very slow)
+//   S = Service Reference (as python string object .. same as ref.toString())
+//   C = Service Reference (as python string object .. same as ref.toCompareString())
+//   N = Service Name (as python string object)
+//   when exactly one return value per service is selected in the format string,
+//   then each value is directly a list entry
+//   when more than one value is returned per service, then the list is a list of
+//   python tuples
+//   unknown format string chars are returned as python None values !
+PyObject *eServiceFS::getContent(const char* format, bool sorted)
+{
+       PyObject *ret=0;
+       std::list<eServiceReference> tmplist;
+       int retcount=1;
+
+       if (!format || !(retcount=strlen(format)))
+               format = "R"; // just return service reference swig object ...
+
+       if (!getContent(tmplist, sorted))
+       {
+               int services=tmplist.size();
+               ePtr<iStaticServiceInformation> sptr;
+               eServiceCenterPtr service_center;
+
+               if (strchr(format, 'N'))
+                       eServiceCenter::getPrivInstance(service_center);
+
+               ret = PyList_New(services);
+               std::list<eServiceReference>::iterator it(tmplist.begin());
+
+               for (int cnt=0; cnt < services; ++cnt)
+               {
+                       eServiceReference &ref=*it++;
+                       PyObject *tuple = retcount > 1 ? PyTuple_New(retcount) : 0;
+                       for (int i=0; i < retcount; ++i)
+                       {
+                               PyObject *tmp=0;
+                               switch(format[i])
+                               {
+                               case 'R':  // service reference (swig)object
+                                       tmp = New_eServiceReference(ref);
+                                       break;
+                               case 'C':  // service reference compare string
+                                       tmp = PyString_FromString(ref.toCompareString().c_str());
+                                       break;
+                               case 'S':  // service reference string
+                                       tmp = PyString_FromString(ref.toString().c_str());
+                                       break;
+                               case 'N':  // service name
+                                       if (service_center)
+                                       {
+                                               service_center->info(ref, sptr);
+                                               if (sptr)
+                                               {
+                                                       std::string name;
+                                                       sptr->getName(ref, name);
+                                                       if (name.length())
+                                                               tmp = PyString_FromString(name.c_str());
+                                               }
+                                       }
+                                       if (!tmp)
+                                               tmp = PyString_FromString("<n/a>");
+                                       break;
+                               default:
+                                       if (tuple)
+                                       {
+                                               tmp = Py_None;
+                                               Py_INCREF(Py_None);
+                                       }
+                                       break;
+                               }
+                               if (tmp)
+                               {
+                                       if (tuple)
+                                               PyTuple_SET_ITEM(tuple, i, tmp);
+                                       else
+                                               PyList_SET_ITEM(ret, cnt, tmp);
+                               }
+                       }
+                       if (tuple)
+                               PyList_SET_ITEM(ret, cnt, tuple);
                }
        }
+       return ret ? ret : PyList_New(0);
+}
+
+RESULT eServiceFS::getNext(eServiceReference &ptr)
+{
+       if (!m_list_valid)
+       {
+               m_list_valid = 1;
+               int res = getContent(m_list);
+               if (res)
+                       return res;
+       }
+       
+       if (!m_list.size())
+       {
+               ptr = eServiceReference();
+               return -ERANGE;
+       }
+       
+       ptr = m_list.front();
+       m_list.pop_front();
        return 0;
 }
 
+int eServiceFS::compareLessEqual(const eServiceReference &a, const eServiceReference &b)
+{
+               /* directories first */
+       if ((a.flags & ~b.flags) & eServiceReference::isDirectory)
+               return 1;
+       else if ((~a.flags & b.flags) & eServiceReference::isDirectory)
+               return 0;
+               /* sort by filename */
+       else
+               return a.path < b.path;
+}
+
+RESULT eServiceFS::startEdit(ePtr<iMutableServiceList> &res)
+{
+       res = 0;
+       return -1;
+}
+
 eAutoInitPtr<eServiceFactoryFS> init_eServiceFactoryFS(eAutoInitNumbers::service+1, "eServiceFactoryFS");