only sample each 40MB at max, use fallback bitrate if no other bitrate available
[enigma2.git] / lib / service / servicefs.cpp
1 #include <lib/base/eerror.h>
2 #include <lib/base/object.h>
3 #include <string>
4 #include <errno.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>
10 #include <dirent.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <unistd.h>
14
15 class eStaticServiceFSInformation: public iStaticServiceInformation
16 {
17         DECLARE_REF(eStaticServiceFSInformation);
18 public:
19         RESULT getName(const eServiceReference &ref, std::string &name);
20         int getLength(const eServiceReference &ref) { return -1; }
21 };
22
23 DEFINE_REF(eStaticServiceFSInformation);
24
25 RESULT eStaticServiceFSInformation::getName(const eServiceReference &ref, std::string &name)
26 {
27         name = ref.path;
28         return 0;
29 }
30
31 // eServiceFactoryFS
32
33 eServiceFactoryFS::eServiceFactoryFS()
34 {
35         ePtr<eServiceCenter> sc;
36         
37         eServiceCenter::getPrivInstance(sc);
38         if (sc)
39                 sc->addServiceFactory(eServiceFactoryFS::id, this);
40         
41         m_service_information = new eStaticServiceFSInformation();
42 }
43
44 eServiceFactoryFS::~eServiceFactoryFS()
45 {
46         ePtr<eServiceCenter> sc;
47         
48         eServiceCenter::getPrivInstance(sc);
49         if (sc)
50                 sc->removeServiceFactory(eServiceFactoryFS::id);
51 }
52
53 DEFINE_REF(eServiceFactoryFS)
54
55         // iServiceHandler
56 RESULT eServiceFactoryFS::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
57 {
58         ptr=0;
59         return -1;
60 }
61
62 RESULT eServiceFactoryFS::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
63 {
64         ptr=0;
65         return -1;
66 }
67
68 RESULT eServiceFactoryFS::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
69 {
70         ptr = new eServiceFS(ref.path.c_str());
71         return 0;
72 }
73
74 RESULT eServiceFactoryFS::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
75 {
76         ptr = m_service_information;
77         return 0;
78 }
79
80 RESULT eServiceFactoryFS::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
81 {
82         ptr = 0;
83         return -1;
84 }
85
86 // eServiceFS
87
88 DEFINE_REF(eServiceFS);
89
90 eServiceFS::eServiceFS(const char *path): path(path)
91 {
92         m_list_valid = 0;
93 }
94
95 eServiceFS::~eServiceFS()
96 {
97 }
98
99 RESULT eServiceFS::getContent(std::list<eServiceReference> &list, bool sorted)
100 {
101         DIR *d=opendir(path.c_str());
102         if (!d)
103                 return -errno;
104         while (dirent *e=readdir(d))
105         {
106                 if (!(strcmp(e->d_name, ".") && strcmp(e->d_name, "..")))
107                         continue;
108                 
109                 std::string filename;
110                 
111                 filename = path;
112                 filename += e->d_name;
113                 
114                 struct stat s;
115                 if (::stat(filename.c_str(), &s) < 0)
116                         continue;
117                 
118                 if (S_ISDIR(s.st_mode))
119                         filename += "/";
120                 
121                 if (S_ISDIR(s.st_mode))
122                 {
123                         eServiceReference service(eServiceFactoryFS::id, 
124                                 eServiceReference::isDirectory|
125                                 eServiceReference::canDescent|eServiceReference::mustDescent|
126                                 eServiceReference::shouldSort|eServiceReference::sort1,
127                                 filename);
128                         service.data[0] = 1;
129                         list.push_back(service);
130                 } else
131                 {
132                                 /* FIIIIIX ME */
133                         if (filename.substr(filename.size()-3) == ".ts")
134                         {
135                                 eServiceReference service(eServiceFactoryDVB::id,
136                                         0,
137                                         filename);
138                                 service.data[0] = 0;
139                                 list.push_back(service);
140                         }
141                 }
142         }
143         closedir(d);
144
145         if (sorted)
146                 list.sort(iListableServiceCompare(this));
147
148         return 0;
149 }
150
151 RESULT eServiceFS::getContent(PyObject *list, bool sorted)
152 {
153         if (!list || !PyList_Check(list))
154                 return -1;
155
156         std::list<eServiceReference> tmplist;
157
158         getContent(tmplist, sorted);
159
160         if (sorted)
161                 tmplist.sort(iListableServiceCompare(this));
162
163         for (std::list<eServiceReference>::iterator it(tmplist.begin());
164                 it != tmplist.end(); ++it)
165         {
166                 PyObject *refobj = New_eServiceReference(*it);
167                 PyList_Append(list, refobj);
168                 Py_DECREF(refobj);
169         }
170
171         return 0;
172 }
173
174 RESULT eServiceFS::getNext(eServiceReference &ptr)
175 {
176         if (!m_list_valid)
177         {
178                 m_list_valid = 1;
179                 int res = getContent(m_list);
180                 if (res)
181                         return res;
182         }
183         
184         if (!m_list.size())
185         {
186                 ptr = eServiceReference();
187                 return -ERANGE;
188         }
189         
190         ptr = m_list.front();
191         m_list.pop_front();
192         return 0;
193 }
194
195 int eServiceFS::compareLessEqual(const eServiceReference &a, const eServiceReference &b)
196 {
197                 /* directories first */
198         if ((a.flags & ~b.flags) & eServiceReference::isDirectory)
199                 return 1;
200         else if ((~a.flags & b.flags) & eServiceReference::isDirectory)
201                 return 0;
202                 /* sort by filename */
203         else
204                 return a.path < b.path;
205 }
206
207 RESULT eServiceFS::startEdit(ePtr<iMutableServiceList> &res)
208 {
209         res = 0;
210         return -1;
211 }
212
213 eAutoInitPtr<eServiceFactoryFS> init_eServiceFactoryFS(eAutoInitNumbers::service+1, "eServiceFactoryFS");