scan.cpp: more robust streamtype detection for pat scan.. use libdvbsi++ to parse...
[enigma2.git] / lib / dvb / metaparser.cpp
1 #include <lib/dvb/metaparser.h>
2 #include <lib/base/eerror.h>
3 #include <errno.h>
4
5 eDVBMetaParser::eDVBMetaParser()
6 {
7         m_time_create = 0;
8         m_data_ok = 0;
9         m_length = 0;
10         m_filesize = 0;
11 }
12
13 int eDVBMetaParser::parseFile(const std::string &basename)
14 {
15                 /* first, try parsing the .meta file */
16         if (!parseMeta(basename))
17                 return 0;
18         
19                 /* otherwise, use recordings.epl */
20         if (!parseRecordings(basename))
21                 return 0;
22         m_filesize = fileSize(basename);
23         return -1;
24
25 }
26
27 long long eDVBMetaParser::fileSize(const std::string &basename)
28 {
29         long long filesize = 0;
30         char buf[255];
31         struct stat64 s;
32                 /* get filesize */
33         if (!stat64(basename.c_str(), &s))
34                 filesize = (long long) s.st_size;
35                 /* handling for old splitted recordings (enigma 1) */
36         int slice=1;
37         while(true)
38         {
39                 snprintf(buf, 255, "%s.%03d", basename.c_str(), slice++);
40                 if (stat64(buf, &s) < 0)
41                         break;
42                 filesize += (long long) s.st_size;
43         }
44         return filesize;
45 }
46
47 int eDVBMetaParser::parseMeta(const std::string &tsname)
48 {
49                 /* if it's a PVR channel, recover service id. */
50         std::string filename = tsname + ".meta";
51                 
52         FILE *f = fopen(filename.c_str(), "r");
53         if (!f)
54                 return -ENOENT;
55
56         int linecnt = 0;
57         
58         m_time_create = 0;
59         
60         while (1)
61         {
62                 char line[1024];
63                 if (!fgets(line, 1024, f))
64                         break;
65                 if (*line && line[strlen(line)-1] == '\n')
66                         line[strlen(line)-1] = 0;
67
68                 if (*line && line[strlen(line)-1] == '\r')
69                         line[strlen(line)-1] = 0;
70
71                 switch (linecnt)
72                 {
73                 case 0:
74                         m_ref = eServiceReferenceDVB(line);
75                         break;
76                 case 1:
77                         m_name = line;
78                         break;
79                 case 2:
80                         m_description = line;
81                         break;
82                 case 3:
83                         m_time_create = atoi(line);
84                         break;
85                 case 4:
86                         m_tags = line;
87                         break;
88                 case 5:
89                         m_length = atoi(line);  //movielength in pts
90                         break;
91                 case 6:
92                         m_filesize = atoll(line);
93                         break;
94                 case 7:
95                         m_service_data = line;
96                         break;
97                 default:
98                         break;
99                 }
100                 ++linecnt;
101         }
102         fclose(f);
103         m_data_ok = 1;
104         return 0;
105 }
106
107 int eDVBMetaParser::parseRecordings(const std::string &filename)
108 {
109         std::string::size_type slash = filename.rfind('/');
110         if (slash == std::string::npos)
111                 return -1;
112         
113         std::string recordings = filename.substr(0, slash) + "/recordings.epl";
114         
115         FILE *f = fopen(recordings.c_str(), "r");
116         if (!f)
117         {
118 //              eDebug("no recordings.epl found: %s: %m", recordings.c_str());
119                 return -1;
120         }
121         
122         std::string description;
123         eServiceReferenceDVB ref;
124         
125 //      eDebug("parsing recordings.epl..");
126         
127         while (1)
128         {
129                 char line[1024];
130                 if (!fgets(line, 1024, f))
131                         break;
132                 
133                 if (strlen(line))
134                         line[strlen(line)-1] = 0;
135                 
136                 if (strlen(line) && line[strlen(line)-1] == '\r')
137                         line[strlen(line)-1] = 0;
138                 
139                 if (!strncmp(line, "#SERVICE: ", 10))
140                         ref = eServiceReferenceDVB(line + 10);
141                 if (!strncmp(line, "#DESCRIPTION: ", 14))
142                         description = line + 14;
143                 if ((line[0] == '/') && (ref.path.substr(ref.path.find_last_of('/')) == filename.substr(filename.find_last_of('/'))))
144                 {
145 //                      eDebug("hit! ref %s descr %s", m_ref.toString().c_str(), m_name.c_str());
146                         m_ref = ref;
147                         m_name = description;
148                         m_description = "";
149                         m_time_create = 0;
150                         m_length = 0;
151                         m_filesize = fileSize(filename);
152                                                 
153                         m_data_ok = 1;
154                         fclose(f);
155                         updateMeta(filename.c_str());
156                         return 0;
157                 }
158         }
159         fclose(f);
160         return -1;
161 }
162
163 int eDVBMetaParser::updateMeta(const std::string &tsname)
164 {
165         /* write meta file only if we have valid data. Note that we might convert recordings.epl data to .meta, which is fine. */
166         if (!m_data_ok)
167                 return -1;
168         std::string filename = tsname + ".meta";
169         eServiceReference ref = m_ref;
170         ref.path = "";
171
172         FILE *f = fopen(filename.c_str(), "w");
173         if (!f)
174                 return -ENOENT;
175         fprintf(f, "%s\n%s\n%s\n%d\n%s\n%d\n%lld\n%s\n", ref.toString().c_str(), m_name.c_str(), m_description.c_str(), m_time_create, m_tags.c_str(), m_length, m_filesize, m_service_data.c_str() );
176         fclose(f);
177         return 0;
178 }