]> git.vomp.tv Git - vompserver.git/blob - picturereader.c
Add missing interface declarations for scraper2vdr plugin
[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    
155    default:
156      return std::string("");
157      break;
158    };
159      
160    
161 }
162
163
164 void PictureReader::threadMethod()
165 {
166   ULONG *p;
167   ULONG headerLength = sizeof(ULONG) * 4;
168   UCHAR buffer[headerLength];
169   int amountReceived;
170
171 //   threadSetKillable(); ??
172
173   logger->log("PictRead",Log::DEBUG,"PictureReaderThread started");
174   while(1)
175   {
176     threadLock();
177     threadWaitForSignal();
178     threadUnlock();
179     threadCheckExit();
180     bool newpicture;
181     logger->log("PictRead",Log::DEBUG,"Thread was signaled, wake up");
182
183     do
184     {
185       newpicture = false;
186       TVMediaRequest req;
187       pthread_mutex_lock(&pictureLock);
188       if (!pictures.empty()) {
189          newpicture = true;
190          req = pictures.front();
191          pictures.pop();
192       }
193       pthread_mutex_unlock(&pictureLock);
194       if (!newpicture) break;
195       std::string pictname = getPictName(req);
196       UCHAR * mem = NULL;
197       ULONG memsize = 0;
198       ULONG flag = 2;
199       logger->log("PictRead",Log::DEBUG,"Load Pict %s",pictname.c_str());
200
201       
202       if (pictname.length()) {
203          struct stat st;
204          ULONG filesize = 0 ;
205
206          stat(pictname.c_str(), &st);
207          filesize = st.st_size;
208          memsize = filesize + headerLength;
209
210          if (memsize && memsize < 1000000) { // No pictures over 1 MB
211             mem = (UCHAR*)malloc(memsize);
212             if (mem) {
213                 FILE * file=fopen(pictname.c_str(),"r");
214
215                 if (file) {
216                     size_t size=fread(mem+headerLength,1,filesize,file);
217
218                     fclose(file);
219                     if (size!=filesize) memsize=headerLength; // error
220                     else flag = 0;
221                 }
222              }
223            } 
224        } 
225        if (!mem) {
226           mem = buffer;
227        }
228
229          
230     
231       p = (ULONG*)&mem[0]; *p = htonl(5); // stream channel
232       p = (ULONG*)&mem[4]; *p = htonl(req.streamID);
233       p = (ULONG*)&mem[8]; *p = htonl(flag); // here insert flag: 0 = ok, data follows
234       p = (ULONG*)&mem[12]; *p = htonl(memsize);
235
236       if (!tcp->sendPacket(mem, memsize + headerLength)) {
237           logger->log("PictRead",Log::DEBUG,"Sending Picture failed");
238       }
239
240       if (mem != buffer && mem) free(mem);
241
242     } while (newpicture);
243   }
244   logger->log("PictRead",Log::DEBUG,"PictureReaderThread ended");
245   
246 }
247