better handling for eServiceFS file extensions
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Mon, 14 Apr 2008 15:10:50 +0000 (15:10 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Mon, 14 Apr 2008 15:10:50 +0000 (15:10 +0000)
lib/python/Components/FileList.py
lib/python/Plugins/Extensions/MediaPlayer/plugin.py
lib/service/iservice.h
lib/service/service.cpp
lib/service/service.h
lib/service/servicedvb.cpp
lib/service/servicefs.cpp
lib/service/servicefs.h
lib/service/servicemp3.cpp

index e6e072cdf69a18767987dd9414d0b7b910b72bbc..bba846f6abe0bb4f3940dd1db5bef16a79c12ae2 100644 (file)
@@ -42,8 +42,9 @@ def FileEntryComponent(name, absolute = None, isDir = False):
        return res
 
 class FileList(MenuList):
-       def __init__(self, directory, showDirectories = True, showFiles = True, matchingPattern = None, useServiceRef = False, isTop = False, enableWrapAround = False):
+       def __init__(self, directory, showDirectories = True, showFiles = True, matchingPattern = None, useServiceRef = False, isTop = False, enableWrapAround = False, additionalExtensions = None):
                MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
+               self.additional_extensions = additionalExtensions
                self.mount_point = None
                self.current_directory = None
                self.useServiceRef = useServiceRef
@@ -107,6 +108,8 @@ class FileList(MenuList):
                        directories = [ ]
                elif self.useServiceRef:
                        root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + directory)
+                       if self.additional_extensions:
+                               root.setName(self.additional_extensions)
                        serviceHandler = eServiceCenter.getInstance()
                        list = serviceHandler.list(root)
 
index dcc601fdb4b4d9b9b01bfa8cbf1c6c14b8a55942..68645842ecc7a06f8bf6bd3f28c7c2577676bc44 100644 (file)
@@ -62,7 +62,7 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup
                self.addPlaylistParser(PlaylistIOInternal, "e2pls")
 
                # 'None' is magic to start at the list of mountpoints
-               self.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob)", useServiceRef = True)
+               self.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
                self["filelist"] = self.filelist
 
                self.playlist = MyPlayList()
index 3905a7fc23b2a77671b8d16ec3ccb3bfe7632a1e..896996b94445b659aadce0f15bc65cf44b8b221a 100644 (file)
@@ -84,7 +84,7 @@ public:
 #ifndef SWIG
        std::string name;
 #endif
-       std::string getName() { return name; }
+       std::string getName() const { return name; }
        void setName( const std::string &n ) { name=n; }
 
        eServiceReference()
index a044c66a0ec3480edcad4dd174c7b57120ed30ef..7721fed7adaaeffb4282d40699918db8064aa412 100644 (file)
@@ -187,18 +187,38 @@ RESULT eServiceCenter::offlineOperations(const eServiceReference &ref, ePtr<iSer
        return i->second->offlineOperations(ref, ptr);
 }
 
-RESULT eServiceCenter::addServiceFactory(int id, iServiceHandler *hnd)
+RESULT eServiceCenter::addServiceFactory(int id, iServiceHandler *hnd, std::list<std::string> &extensions)
 {
        handler.insert(std::pair<int,ePtr<iServiceHandler> >(id, hnd));
+       this->extensions[id]=extensions;
        return 0;
 }
 
 RESULT eServiceCenter::removeServiceFactory(int id)
 {
        handler.erase(id);
+       extensions.erase(id);
        return 0;
 }
 
+int eServiceCenter::getServiceTypeForExtension(const char *str)
+{
+       for (std::map<int, std::list<std::string> >::iterator sit(extensions.begin()); sit != extensions.end(); ++sit)
+       {
+               for (std::list<std::string>::iterator eit(sit->second.begin()); eit != sit->second.end(); ++eit)
+               {
+                       if (*eit == str)
+                               return sit->first;
+               }
+       }
+       return -1;
+}
+
+int eServiceCenter::getServiceTypeForExtension(const std::string &str)
+{
+       return getServiceTypeForExtension(str.c_str());
+}
+
        /* default handlers */
 RESULT iServiceHandler::info(const eServiceReference &, ePtr<iStaticServiceInformation> &ptr)
 {
index 77173c53a60a48b3c4610962da19fdaa8a90ef8a..3929f7525e02ddf3b54b8cd5308e6d4d2decbac7 100644 (file)
@@ -16,6 +16,7 @@ class eServiceCenter: public iServiceHandler
 DECLARE_REF(eServiceCenter);
 private:
        std::map<int,ePtr<iServiceHandler> > handler;
+       std::map<int,std::list<std::string> > extensions;
        static eServiceCenter *instance;
 #ifdef SWIG
        eServiceCenter();
@@ -26,6 +27,9 @@ public:
        eServiceCenter();
        virtual ~eServiceCenter();
 
+       int getServiceTypeForExtension(const char *str);
+       int getServiceTypeForExtension(const std::string &str);
+
                // iServiceHandler
        RESULT play(const eServiceReference &, ePtr<iPlayableService> &ptr);
        RESULT record(const eServiceReference &, ePtr<iRecordableService> &ptr);
@@ -35,7 +39,7 @@ public:
        
                // eServiceCenter
        static RESULT getPrivInstance(ePtr<eServiceCenter> &ptr) { ptr = instance; return 0; }
-       RESULT addServiceFactory(int id, iServiceHandler *hnd);
+       RESULT addServiceFactory(int id, iServiceHandler *hnd, std::list<std::string> &extensions);
        RESULT removeServiceFactory(int id);
 #endif
        static SWIG_VOID(RESULT) getInstance(ePtr<iServiceHandler> &SWIG_NAMED_OUTPUT(ptr)) { ptr = instance; return 0; }
index a8485fa4888c9cd4a7d6f706b3934fb8f2601e1a..cd4d3394cc90efe0f987783b9ec7b842ebc17f68 100644 (file)
@@ -668,7 +668,11 @@ eServiceFactoryDVB::eServiceFactoryDVB()
        
        eServiceCenter::getPrivInstance(sc);
        if (sc)
-               sc->addServiceFactory(eServiceFactoryDVB::id, this);
+       {
+               std::list<std::string> extensions;
+               extensions.push_back("ts");
+               sc->addServiceFactory(eServiceFactoryDVB::id, this, extensions);
+       }
 
        m_StaticServiceDVBInfo = new eStaticServiceDVBInformation;
        m_StaticServiceDVBBouquetInfo = new eStaticServiceDVBBouquetInformation;
index 728bb460c204456b113fdd84aa2da4145918151d..1417f91468041a565a0c3e5fe19f694333dcf4b5 100644 (file)
@@ -36,7 +36,10 @@ eServiceFactoryFS::eServiceFactoryFS()
        
        eServiceCenter::getPrivInstance(sc);
        if (sc)
-               sc->addServiceFactory(eServiceFactoryFS::id, this);
+       {
+               std::list<std::string> extensions;
+               sc->addServiceFactory(eServiceFactoryFS::id, this, extensions);
+       }
        
        m_service_information = new eStaticServiceFSInformation();
 }
@@ -67,7 +70,7 @@ RESULT eServiceFactoryFS::record(const eServiceReference &ref, ePtr<iRecordableS
 
 RESULT eServiceFactoryFS::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
 {
-       ptr = new eServiceFS(ref.path.c_str());
+       ptr = new eServiceFS(ref.path.c_str(), ref.getName().length() ? ref.getName().c_str() : 0);
        return 0;
 }
 
@@ -87,9 +90,64 @@ RESULT eServiceFactoryFS::offlineOperations(const eServiceReference &, ePtr<iSer
 
 DEFINE_REF(eServiceFS);
 
-eServiceFS::eServiceFS(const char *path): path(path)
+eServiceFS::eServiceFS(const char *path, const char *additional_extensions): path(path)
 {
        m_list_valid = 0;
+       if (additional_extensions)
+       {
+               size_t slen=strlen(additional_extensions);
+               char buf[slen+1];
+               char *tmp=0, *cmds = buf;
+               memcpy(buf, additional_extensions, slen+1);
+
+               // strip spaces at beginning
+               while(cmds[0] == ' ')
+               {
+                       ++cmds;
+                       --slen;
+               }
+
+               // strip spaces at the end
+               while(slen && cmds[slen-1] == ' ')
+               {
+                       cmds[slen-1] = 0;
+                       --slen;
+               }
+
+               if (slen)
+               {
+                       if (*cmds)
+                       {
+                               int id;
+                               char buf2[16];
+                               while(1)
+                               {
+                                       tmp = strchr(cmds, ' ');
+                                       if (tmp)
+                                               *tmp = 0;
+                                       if (strstr(cmds, "0x"))
+                                       {
+                                               if (sscanf(cmds, "0x%x:%s", &id, buf2) == 2)
+                                                       m_additional_extensions[id].push_back(buf2);
+                                               else
+                                                       eDebug("parse additional_extension (%s) failed", cmds);
+                                       }
+                                       else
+                                       {
+                                               if (sscanf(cmds, "%d:%s", &id, buf2) == 2)
+                                                       m_additional_extensions[id].push_back(buf2);
+                                               else
+                                                       eDebug("parse additional_extension (%s) failed", cmds);
+                                       }
+                                       if (!tmp)
+                                               break;
+                                       cmds = tmp+1;
+                                       while (*cmds && *cmds == ' ')
+                                               ++cmds;
+                               }
+                       }
+               }
+       }
 }
 
 eServiceFS::~eServiceFS()
@@ -135,32 +193,29 @@ RESULT eServiceFS::getContent(std::list<eServiceReference> &list, bool sorted)
                } else
                {
                        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 = 0x1001;
-                       else if (extension == ".ogg")
-                               type = 0x1001;
-                       else if (extension == ".mpg")
-                               type = 0x1001;
-                       else if (extension == ".vob")
-                               type = 0x1001;
-                       else if (extension == ".wav" || extension == ".wave")
-                               type = 0x1001;
-                       else if (extension == ".m3u" || extension == ".pls" || extension == ".e2pls")
-                               type = 4098; // ?? this id is not defined in any service handler, just in python code.
-                       
-                       if (type != -1)
+                       if (e != std::string::npos && e+1 < filename.length())
                        {
-                               eServiceReference service(type,
-                                       0,
-                                       filename);
-                               service.data[0] = 0;
-                               list.push_back(service);
+                               std::string extension = filename.substr(e+1);
+                               std::transform(extension.begin(), extension.end(), extension.begin(), lower);
+                               int type = getServiceTypeForExtension(extension);
+
+                               if (type == -1)
+                               {
+                                       ePtr<eServiceCenter> sc;
+                                       eServiceCenter::getPrivInstance(sc);
+                                       type = sc->getServiceTypeForExtension(extension);
+                               }
+                       
+                               if (type != -1)
+                               {
+                                       eServiceReference service(type,
+                                               0,
+                                               filename);
+                                       service.data[0] = 0;
+                                       list.push_back(service);
+                               }
+                               else
+                                       eDebug("unhandled extension %s", extension.c_str());
                        }
                }
        }
@@ -300,4 +355,22 @@ RESULT eServiceFS::startEdit(ePtr<iMutableServiceList> &res)
        return -1;
 }
 
+int eServiceFS::getServiceTypeForExtension(const char *str)
+{
+       for (std::map<int, std::list<std::string> >::iterator sit(m_additional_extensions.begin()); sit != m_additional_extensions.end(); ++sit)
+       {
+               for (std::list<std::string>::iterator eit(sit->second.begin()); eit != sit->second.end(); ++eit)
+               {
+                       if (*eit == str)
+                               return sit->first;
+               }
+       }
+       return -1;
+}
+
+int eServiceFS::getServiceTypeForExtension(const std::string &str)
+{
+       return getServiceTypeForExtension(str.c_str());
+}
+
 eAutoInitPtr<eServiceFactoryFS> init_eServiceFactoryFS(eAutoInitNumbers::service+1, "eServiceFactoryFS");
index 390757a2d114a8001dbccac0ccbe3d97e248b503..d05eef19c70475a541d3ecf30478e2f9f7dbe7a6 100644 (file)
@@ -27,13 +27,16 @@ DECLARE_REF(eServiceFS);
 private:
        std::string path;
        friend class eServiceFactoryFS;
-       eServiceFS(const char *path);
+       eServiceFS(const char *path, const char *additional_extensions=0);
+       std::map<int, std::list<std::string> > m_additional_extensions;
        
        int m_list_valid;
        std::list<eServiceReference> m_list;
+       int getServiceTypeForExtension(const char *str);
+       int getServiceTypeForExtension(const std::string &str);
 public:
        virtual ~eServiceFS();
-       
+
        RESULT getContent(std::list<eServiceReference> &list, bool sorted=false);
        PyObject *getContent(const char *format, bool sorted=false);
        RESULT getNext(eServiceReference &ptr);
index a38ad4155915d7500e7d2624d8c526367bcb2225..f74cc8d061a88e5b5805cc3c306c8d85ed23d322 100644 (file)
@@ -20,7 +20,16 @@ eServiceFactoryMP3::eServiceFactoryMP3()
        
        eServiceCenter::getPrivInstance(sc);
        if (sc)
-               sc->addServiceFactory(eServiceFactoryMP3::id, this);
+       {
+               std::list<std::string> extensions;
+               extensions.push_back("mp3");
+               extensions.push_back("ogg");
+               extensions.push_back("mpg");
+               extensions.push_back("vob");
+               extensions.push_back("wav");
+               extensions.push_back("wave");
+               sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
+       }
 
        m_service_info = new eStaticServiceMP3Info();
 }