1 #include <lib/base/eerror.h>
2 #include <lib/base/object.h>
5 #include <lib/service/servicefs.h>
6 #include <lib/service/service.h>
7 #include <lib/service/servicedvb.h>
8 #include <lib/base/init_num.h>
9 #include <lib/base/init.h>
11 #include <sys/types.h>
15 class eStaticServiceFSInformation: public iStaticServiceInformation
17 DECLARE_REF(eStaticServiceFSInformation);
19 RESULT getName(const eServiceReference &ref, std::string &name);
20 int getLength(const eServiceReference &ref) { return -1; }
23 DEFINE_REF(eStaticServiceFSInformation);
25 RESULT eStaticServiceFSInformation::getName(const eServiceReference &ref, std::string &name)
33 eServiceFactoryFS::eServiceFactoryFS()
35 ePtr<eServiceCenter> sc;
37 eServiceCenter::getPrivInstance(sc);
39 sc->addServiceFactory(eServiceFactoryFS::id, this);
41 m_service_information = new eStaticServiceFSInformation();
44 eServiceFactoryFS::~eServiceFactoryFS()
46 ePtr<eServiceCenter> sc;
48 eServiceCenter::getPrivInstance(sc);
50 sc->removeServiceFactory(eServiceFactoryFS::id);
53 DEFINE_REF(eServiceFactoryFS)
56 RESULT eServiceFactoryFS::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
62 RESULT eServiceFactoryFS::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
68 RESULT eServiceFactoryFS::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
70 ptr = new eServiceFS(ref.path.c_str());
74 RESULT eServiceFactoryFS::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
76 ptr = m_service_information;
80 RESULT eServiceFactoryFS::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
88 DEFINE_REF(eServiceFS);
90 eServiceFS::eServiceFS(const char *path): path(path)
95 eServiceFS::~eServiceFS()
101 return std::tolower(static_cast<unsigned char>(c));
104 RESULT eServiceFS::getContent(std::list<eServiceReference> &list, bool sorted)
106 DIR *d=opendir(path.c_str());
109 while (dirent *e=readdir(d))
111 if (!(strcmp(e->d_name, ".") && strcmp(e->d_name, "..")))
114 std::string filename;
117 filename += e->d_name;
120 if (::stat(filename.c_str(), &s) < 0)
123 if (S_ISDIR(s.st_mode))
126 if (S_ISDIR(s.st_mode))
128 eServiceReference service(eServiceFactoryFS::id,
129 eServiceReference::isDirectory|
130 eServiceReference::canDescent|eServiceReference::mustDescent|
131 eServiceReference::shouldSort|eServiceReference::sort1,
134 list.push_back(service);
137 size_t e = filename.rfind('.');
138 std::string extension = (e != std::string::npos) ? filename.substr(e) : "";
139 std::transform(extension.begin(), extension.end(), extension.begin(), lower);
142 if (extension == ".ts")
143 type = eServiceFactoryDVB::id;
144 else if (extension == ".mp3")
146 else if (extension == ".ogg")
148 else if (extension == ".mpg")
150 else if (extension == ".vob")
152 else if (extension == ".wav" || extension == ".wave")
154 else if (extension == ".m3u" || extension == ".pls" || extension == ".e2pls")
155 type = 4098; // ?? this id is not defined in any service handler, just in python code.
159 eServiceReference service(type,
163 list.push_back(service);
170 list.sort(iListableServiceCompare(this));
175 // The first argument of this function is a format string to specify the order and
176 // the content of the returned list
177 // useable format options are
178 // R = Service Reference (as swig object .. this is very slow)
179 // S = Service Reference (as python string object .. same as ref.toString())
180 // C = Service Reference (as python string object .. same as ref.toCompareString())
181 // N = Service Name (as python string object)
182 // when exactly one return value per service is selected in the format string,
183 // then each value is directly a list entry
184 // when more than one value is returned per service, then the list is a list of
186 // unknown format string chars are returned as python None values !
187 PyObject *eServiceFS::getContent(const char* format, bool sorted)
190 std::list<eServiceReference> tmplist;
193 if (!format || !(retcount=strlen(format)))
194 format = "R"; // just return service reference swig object ...
196 if (!getContent(tmplist, sorted))
198 int services=tmplist.size();
199 ePtr<iStaticServiceInformation> sptr;
200 eServiceCenterPtr service_center;
202 if (strchr(format, 'N'))
203 eServiceCenter::getPrivInstance(service_center);
205 ret = PyList_New(services);
206 std::list<eServiceReference>::iterator it(tmplist.begin());
208 for (int cnt=0; cnt < services; ++cnt)
210 eServiceReference &ref=*it++;
211 ePyObject tuple = retcount > 1 ? PyTuple_New(retcount) : ePyObject();
212 for (int i=0; i < retcount; ++i)
217 case 'R': // service reference (swig)object
218 tmp = NEW_eServiceReference(ref);
220 case 'C': // service reference compare string
221 tmp = PyString_FromString(ref.toCompareString().c_str());
223 case 'S': // service reference string
224 tmp = PyString_FromString(ref.toString().c_str());
226 case 'N': // service name
229 service_center->info(ref, sptr);
233 sptr->getName(ref, name);
235 tmp = PyString_FromString(name.c_str());
239 tmp = PyString_FromString("<n/a>");
252 PyTuple_SET_ITEM(tuple, i, tmp);
254 PyList_SET_ITEM(ret, cnt, tmp);
258 PyList_SET_ITEM(ret, cnt, tuple);
261 return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
264 RESULT eServiceFS::getNext(eServiceReference &ptr)
269 int res = getContent(m_list);
276 ptr = eServiceReference();
280 ptr = m_list.front();
285 int eServiceFS::compareLessEqual(const eServiceReference &a, const eServiceReference &b)
287 /* directories first */
288 if ((a.flags & ~b.flags) & eServiceReference::isDirectory)
290 else if ((~a.flags & b.flags) & eServiceReference::isDirectory)
292 /* sort by filename */
294 return a.path < b.path;
297 RESULT eServiceFS::startEdit(ePtr<iMutableServiceList> &res)
303 eAutoInitPtr<eServiceFactoryFS> init_eServiceFactoryFS(eAutoInitNumbers::service+1, "eServiceFactoryFS");