]> git.vomp.tv Git - vompserver.git/blob - picturereader.c
Add support for events identified tvmedia in protocoll
[vompserver.git] / picturereader.c
1 #include "picturereader.h"
2 #include <vdr/plugin.h>
3 #include <vdr/channels.h>
4 #include <sstream>
5
6
7 PictureReader::PictureReader(VompClient *client)
8 {
9   logger = Log::getInstance();
10   inittedOK = 0;
11   tcp = NULL;
12   x = client;
13
14   pthread_mutex_init(&pictureLock, NULL);
15 }  
16
17 int PictureReader::init(TCP* ttcp)
18 {
19   tcp = ttcp;
20   threadStart();
21
22   return inittedOK;
23 }
24
25 PictureReader::~PictureReader()
26 {
27    threadStop();
28 }
29
30 void PictureReader::addTVMediaRequest(TVMediaRequest& req)
31 {
32     logger->log("PictRead",Log::DEBUG,"Got TVMediaRequest, signal thread!");
33
34     pthread_mutex_lock(&pictureLock);
35     pictures.push(req);
36     threadSignal(); // Signal, that we have something to do!!!
37     pthread_mutex_unlock(&pictureLock);
38 }
39
40 std::string PictureReader::getPictName(TVMediaRequest & req)
41 {
42    logger->log("PictRead",Log::DEBUG,
43         "Request %d %d;  %d %d %d %d",req.primary_id,req.secondary_id,
44          req.type,req.type_pict,
45         req.container,req.container_member);
46
47    switch (req.type) {
48    case 0: { //serie
49       if (series.seriesId != req.primary_id ||
50           series.episodeId != req.secondary_id) {
51           series.actors.clear();
52           series.posters.clear();
53           series.banners.clear();
54           series.fanarts.clear();
55
56           series.seriesId = req.primary_id;
57           series.episodeId = req.secondary_id;
58           x->scraper->Service("GetSeries",&series);
59       }
60       if (req.type_pict == 0) {
61         switch (req.container) {
62         case 0: {
63            return series.episode.episodeImage.path;
64         } break;
65         case 1: {
66           if (series.actors.size()>req.container_member) {
67                 return series.actors[req.container_member].actorThumb.path;
68           }
69         } break;
70         case 2: {
71           if (series.posters.size()>req.container_member) {
72                 return series.posters[req.container_member].path;
73           }
74         } break;
75         case 3: {
76           if (series.banners.size()>req.container_member) {
77                 return series.banners[req.container_member].path;
78           }
79         } break;
80         case 4: {
81           if (series.fanarts.size()>req.container_member) {
82                 return series.fanarts[req.container_member].path;
83           }
84         } break;
85         case 5: {
86            return series.seasonPoster.path;
87         } break;
88         default: {
89            return std::string("");
90            } break;
91         };
92       } else if (req.type_pict == 1 && series.posters.size()) { //poster
93            std::string str=series.posters[0].path;
94            size_t  pos=str.rfind('/');
95            if (pos!=std::string::npos) {
96               str.resize(pos);
97               str=str+"poster_thumb.jpg";
98               return str;
99            }
100         } else if (req.type_pict == 2) { //poster
101            std::string str=series.seasonPoster.path;
102            size_t  pos=str.rfind('/');
103            if (pos!=std::string::npos) {
104               str.resize(pos);
105               std::ostringstream out;
106               out << str << "season_" <<series.episode.season <<"_thumb.jpg";
107               return out.str();
108            }
109         } 
110        return std::string("");
111    } break;
112    case 1: { //movie
113       if (movie.movieId != req.primary_id ) {
114           movie.actors.clear();
115           movie.movieId = req.primary_id;
116           x->scraper->Service("GetMovie",&movie);
117       }
118       if (req.type_pict == 0) {
119
120         switch (req.container) {
121         case 0: {
122            return movie.poster.path;
123         } break;
124         case 1: {
125            return movie.fanart.path;
126         } break;
127         case 2: {
128            return movie.collectionPoster.path;
129         } break;
130         case 3: {
131            return movie.collectionFanart.path;
132         } break;
133         case 4: {
134           if (movie.actors.size()>req.container_member) {
135                 return movie.actors[req.container_member].actorThumb.path;
136           }
137         } break;
138         default: {
139            return std::string("");
140            } break;
141         };
142     } else if (req.type_pict == 1) { //poster
143         std::string str=movie.poster.path;
144         size_t  pos=str.rfind('/');
145         if (pos!=std::string::npos) {
146            str.resize(pos);
147            str=str+"poster_thumb.jpg";
148            return str;
149         }
150     } 
151     return std::string("");
152       
153    
154    } break;
155    case 3: { // I do not know
156    // First get the recording
157       cRecordings Recordings;
158       Recordings.Load();
159       cRecording *recording = Recordings.GetByName((char*) req.primary_name.c_str());
160       ScraperGetPosterThumb getter;
161       getter.recording = recording;
162       getter.event = NULL;
163       if (x->scraper && recording) {
164         x->scraper->Service("GetPosterThumb",&getter);
165         return getter.poster.path;
166       } else {
167          return std::string("");
168       }
169    }; break;
170    case 4: { // I do not know
171    // First get the schedules
172       cSchedulesLock MutexLock;
173       const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
174       const cSchedule *Schedule = NULL;
175       if (Schedules)
176       {
177         Schedule = Schedules->GetSchedule(
178                   Channels.GetByChannelID(
179                        tChannelID::FromString(req.primary_name.c_str())));
180       }
181       cEvent *event = NULL;
182       if (Schedule) Schedule->GetEvent(req.primary_id);
183       ScraperGetPosterThumb getter;
184       getter.event = event;
185       getter.recording = NULL;
186       if (x->scraper && event) {
187         x->scraper->Service("GetPosterThumb",&getter);
188         return getter.poster.path;
189       } else {
190          return std::string("");
191       }
192    }; break;
193    
194    default:
195      return std::string("");
196      break;
197    };
198      
199    
200 }
201
202
203 void PictureReader::threadMethod()
204 {
205   ULONG *p;
206   ULONG headerLength = sizeof(ULONG) * 4;
207   UCHAR buffer[headerLength];
208   int amountReceived;
209
210 //   threadSetKillable(); ??
211
212   logger->log("PictRead",Log::DEBUG,"PictureReaderThread started");
213   while(1)
214   {
215     threadLock();
216     threadWaitForSignal();
217     threadUnlock();
218     threadCheckExit();
219     bool newpicture;
220     logger->log("PictRead",Log::DEBUG,"Thread was signaled, wake up");
221
222     do
223     {
224       newpicture = false;
225       TVMediaRequest req;
226       pthread_mutex_lock(&pictureLock);
227       if (!pictures.empty()) {
228          newpicture = true;
229          req = pictures.front();
230          pictures.pop();
231       }
232       pthread_mutex_unlock(&pictureLock);
233       if (!newpicture) break;
234       std::string pictname = getPictName(req);
235       UCHAR * mem = NULL;
236       ULONG memsize = 0;
237       ULONG flag = 2;
238       logger->log("PictRead",Log::DEBUG,"Load Pict %s",pictname.c_str());
239
240       
241       if (pictname.length()) {
242          struct stat st;
243          ULONG filesize = 0 ;
244
245          stat(pictname.c_str(), &st);
246          filesize = st.st_size;
247          memsize = filesize + headerLength;
248
249          if (memsize && memsize < 1000000) { // No pictures over 1 MB
250             mem = (UCHAR*)malloc(memsize);
251             if (mem) {
252                 FILE * file=fopen(pictname.c_str(),"r");
253
254                 if (file) {
255                     size_t size=fread(mem+headerLength,1,filesize,file);
256
257                     fclose(file);
258                     if (size!=filesize) memsize=headerLength; // error
259                     else flag = 0;
260                 }
261              }
262            } 
263        } 
264        if (!mem) {
265           mem = buffer;
266        }
267
268          
269     
270       p = (ULONG*)&mem[0]; *p = htonl(5); // stream channel
271       p = (ULONG*)&mem[4]; *p = htonl(req.streamID);
272       p = (ULONG*)&mem[8]; *p = htonl(flag); // here insert flag: 0 = ok, data follows
273       p = (ULONG*)&mem[12]; *p = htonl(memsize);
274
275       if (!tcp->sendPacket(mem, memsize + headerLength)) {
276           logger->log("PictRead",Log::DEBUG,"Sending Picture failed");
277       }
278
279       if (mem != buffer && mem) free(mem);
280
281     } while (newpicture);
282   }
283   logger->log("PictRead",Log::DEBUG,"PictureReaderThread ended");
284   
285 }
286