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