diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 8a275ac33..d9cb6931e 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -98,6 +98,7 @@ libneutrino_gui_a_SOURCES = \ subchannel_select.cpp \ themes.cpp \ timeosd.cpp \ + tmdb.cpp \ update.cpp \ update_ext.cpp \ update_menue.cpp \ diff --git a/src/gui/epgview.cpp b/src/gui/epgview.cpp index dfd7bcd24..70abe52f7 100644 --- a/src/gui/epgview.cpp +++ b/src/gui/epgview.cpp @@ -48,6 +48,8 @@ #include #include #include +#include +#include #include #include @@ -118,6 +120,7 @@ CEpgData::CEpgData() { bigFonts = false; frameBuffer = CFrameBuffer::getInstance(); + tmdbtoggle = false; } void CEpgData::start() @@ -182,7 +185,7 @@ void CEpgData::processTextToArray(std::string text, int screening) // UTF-8 // check the wordwidth - add to this line if size ok int aktWordWidth = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getRenderWidth(aktWord); - if ((aktWordWidth+aktWidth)<(ox - 20 - 15)) + if ((aktWordWidth+aktWidth)<(ox - 20 - 15 - (tmdbtoggle? (std::min((sb-10)*342/513,342)) :0))) {//space ok, add aktWidth += aktWordWidth; aktLine += aktWord; @@ -217,12 +220,15 @@ void CEpgData::processTextToArray(std::string text, int screening) // UTF-8 addTextToArray( aktLine + aktWord, screening ); } -void CEpgData::showText( int startPos, int ypos ) +void CEpgData::showText( int startPos, int ypos, bool cover ) { // recalculate medlineheight = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->getHeight(); medlinecount = sb / medlineheight; + int cover_height = std::min(sb-10,513); + int cover_width = std::min((sb-10)*342/513,342); + int cover_offset = cover ? cover_width+3 : 0; int textSize = epgText.size(); int y=ypos; const char tok = ' '; @@ -236,6 +242,9 @@ void CEpgData::showText( int startPos, int ypos ) max_wday_w = std::max(max_wday_w, g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getRenderWidth(std::string(g_Locale->getText(CLocaleManager::getWeekday(i))) + " ")); } frameBuffer->paintBoxRel(sx, y, ox- 15, sb, COL_MENUCONTENT_PLUS_0); // background of the text box + if (cover) { + if (!g_PicViewer->DisplayImage("/tmp/tmdb.jpg",sx+3,y+3+((sb-cover_height)/2),cover_width,cover_height, 1)) + cover_offset = 0; } for (int i = startPos; i < textSize && i < startPos + medlinecount; i++, y += medlineheight) { if(epgText[i].second){ @@ -262,7 +271,18 @@ void CEpgData::showText( int startPos, int ypos ) count = 0; } else{ - g_Font[( i< info1_lines ) ?SNeutrinoSettings::FONT_TYPE_EPG_INFO1:SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->RenderString(sx+10, y+medlineheight, ox- 15- 15, epgText[i].first, COL_MENUCONTENT_TEXT); + g_Font[( i< info1_lines ) ?SNeutrinoSettings::FONT_TYPE_EPG_INFO1:SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->RenderString(sx+10+cover_offset, y+medlineheight, ox- 15- 15, epgText[i].first, COL_MENUCONTENT_TEXT); + } + } + + if (stars > 0 && startPos == 0){ + int icon_w,icon_h; + frameBuffer->getIconSize(ICONSDIR"/star-off.png", &icon_w, &icon_h); + for (int i=1; i < 11;i++) { + frameBuffer->paintIcon(ICONSDIR"/star-off.png", sx+3+cover_offset+i*icon_w+3, ypos+3); + } + for (int i=1; i < stars+1;i++) { + frameBuffer->paintIcon(ICONSDIR"/star-on.png", sx+3+cover_offset+i*icon_w+3, ypos+3); } } @@ -458,6 +478,9 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start startzeit=*a_startzeit; id=a_id; + tmdbtoggle = false; + stars = 0; + CComponentsHeader* header = NULL; CComponentsPicture* headerPic = NULL; CComponentsText* headerText = NULL; @@ -770,7 +793,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start if (showPos+scrollCountgetResults() > 0) && (!tmdb->getDescription().empty())) { + epgText_saved = epgText; + epgText.clear(); + if (tmdb->hasCover()) { + tmdbtoggle = !tmdbtoggle; + processTextToArray(tmdb->CreateEPGText()); + textCount = epgText.size(); + stars = tmdb->getStars(); + showText(showPos, sy + toph, tmdbtoggle); + } else { + processTextToArray(tmdb->CreateEPGText()); + textCount = epgText.size(); + stars = tmdb->getStars(); + showText(showPos, sy + toph, tmdbtoggle); + tmdbtoggle = !tmdbtoggle; + } + } else { + ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_EPGVIEWER_NODETAILED, CMessageBox::mbrOk , CMessageBox::mbrOk); + } + if (tmdb) + delete tmdb; + } else { + epgText.clear(); + epgText = epgText_saved; + textCount = epgText.size(); + stars=0; + showText(showPos, sy + toph); + tmdbtoggle = !tmdbtoggle; + } + break; + } // 31.05.2002 dirch zapto timer case CRCInput::RC_yellow: @@ -932,7 +990,6 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start } break; } - case CRCInput::RC_info: case CRCInput::RC_help: bigFonts = bigFonts ? false : true; frameBuffer->paintBackgroundBoxRel(sx, sy, ox, oy); @@ -1165,6 +1222,7 @@ const struct button_label EpgButtons[] = { { NEUTRINO_ICON_BUTTON_RED , LOCALE_TIMERBAR_RECORDEVENT }, { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_TIMERBAR_CHANNELSWITCH }, + { NEUTRINO_ICON_BUTTON_INFO_SMALL , LOCALE_CHANNELLIST_ADDITIONAL }, { NEUTRINO_ICON_BUTTON_BLUE, LOCALE_EPGVIEWER_MORE_SCREENINGS_SHORT } }; diff --git a/src/gui/epgview.h b/src/gui/epgview.h index e45b706cc..b1567b8bb 100644 --- a/src/gui/epgview.h +++ b/src/gui/epgview.h @@ -64,6 +64,8 @@ class CEpgData bool bigFonts; bool has_follow_screenings; bool call_fromfollowlist; + bool tmdbtoggle; + int stars; time_t tmp_curent_zeit; uint64_t prev_id; @@ -76,6 +78,7 @@ class CEpgData int textCount; typedef std::pair epg_pair; std::vector epgText; + std::vector epgText_saved; int topheight,topboxheight; int buttonheight,botboxheight; int medlineheight,medlinecount; @@ -84,7 +87,7 @@ class CEpgData void GetPrevNextEPGData( uint64_t id, time_t* startzeit ); void addTextToArray( const std::string & text, int screening ); void processTextToArray(std::string text, int screening = 0); - void showText( int startPos, int ypos ); + void showText( int startPos, int ypos, bool cover= false ); bool hasFollowScreenings(const t_channel_id channel_id, const std::string & title); int FollowScreenings(const t_channel_id channel_id, const std::string & title); void showTimerEventBar(bool show, bool adzap = false); diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index 66077c183..8218eea66 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -45,6 +45,7 @@ #include #include "moviebrowser.h" #include "filebrowser.h" +#include #include #include #include @@ -1981,6 +1982,46 @@ bool CMovieBrowser::onButtonPressMainFrame(neutrino_msg_t msg) smsInput.resetOldKey(); } } + else if (msg == CRCInput::RC_favorites) + { + if (m_movieSelectionHandler != NULL) { +#if 0 + if (ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_MOVIEBROWSER_DELETE_SCREENSHOT, CMessageBox::mbrNo, CMessageBox:: mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) { + std::string fname = getScreenshotName(m_movieSelectionHandler->file.Name, S_ISDIR(m_movieSelectionHandler->file.Mode)); + if (!fname.empty()) + unlink(fname.c_str()); + refresh(); + } +#else + std::string fname = m_movieSelectionHandler->file.Name.c_str(); + int ext_pos = 0; + ext_pos = fname.rfind('.'); + if( ext_pos > 0) { + std::string extension; + extension = fname.substr(ext_pos + 1, fname.length() - ext_pos); + extension = "." + extension; + strReplace(fname, extension.c_str(), ".jpg"); + } + printf("TMDB: %s : %s\n",m_movieSelectionHandler->file.Name.c_str(),fname.c_str()); + if (!access(fname, F_OK)) { + if (ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_MOVIEBROWSER_DELETE_SCREENSHOT, CMessageBox::mbrNo, CMessageBox:: mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) { + if (!fname.empty()) + unlink(fname.c_str()); + refresh(); + } + } else { + cTmdb* tmdb = new cTmdb(m_movieSelectionHandler->epgTitle); + if ((tmdb->getResults() > 0) && (tmdb->hasCover())) { + if (!fname.empty()) + if (tmdb->getSmallCover(fname)) + refresh(); + } + if (tmdb) + delete tmdb; + } +#endif + } + } else { //TRACE("[mb]->onButtonPressMainFrame none\n"); diff --git a/src/gui/tmdb.cpp b/src/gui/tmdb.cpp new file mode 100644 index 000000000..688ecacfb --- /dev/null +++ b/src/gui/tmdb.cpp @@ -0,0 +1,345 @@ +/* + Copyright (C) 2015 TangoCash + + License: GPLv2 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "system/settings.h" +#include "system/helpers.h" +#include "system/set_threadname.h" + +#include + +#include +#include + +#include "tmdb.h" + +#if LIBCURL_VERSION_NUM < 0x071507 +#include +#endif + +#define URL_TIMEOUT 60 +#define API_KEY_1 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +#define API_KEY_2 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +#define API_KEY_3 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +#define API_KEY_4 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +#define TMDB_COVER "/tmp/tmdb.jpg" + +cTmdb::cTmdb(std::string epgtitle) +{ + frameBuffer = CFrameBuffer::getInstance(); + minfo.epgtitle = epgtitle; + curl_handle = curl_easy_init(); + form = NULL; + + ox = frameBuffer->getScreenWidthRel(false); + oy = frameBuffer->getScreenHeightRel(false); + + int buttonheight = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight() + 6; + toph = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_TITLE]->getHeight() + 6; + + sx = getScreenStartX(ox); + sy = getScreenStartY(oy + buttonheight); /* button box is handled separately (why?) */ + + + GetMovieDetails(); +} + +cTmdb::~cTmdb() +{ + curl_easy_cleanup(curl_handle); + delete form; +} + +size_t cTmdb::CurlWriteToString(void *ptr, size_t size, size_t nmemb, void *data) +{ + if (size * nmemb > 0) { + std::string* pStr = (std::string*) data; + pStr->append((char*) ptr, nmemb); + } + return size*nmemb; +} + +std::string cTmdb::decodeUrl(std::string url) +{ + char * str = curl_easy_unescape(curl_handle, url.c_str(), 0, NULL); + if (str) + url = str; + curl_free(str); + return url; +} + +std::string cTmdb::encodeUrl(std::string txt) +{ + char * str = curl_easy_escape(curl_handle, txt.c_str(), txt.length()); + if (str) + txt = str; + curl_free(str); + return txt; +} + +bool cTmdb::getUrl(std::string &url, std::string &answer, CURL *_curl_handle) +{ + printf("[TMDB]: %s\n",__func__); + if (!_curl_handle) + _curl_handle = curl_handle; + + curl_easy_setopt(_curl_handle, CURLOPT_URL, url.c_str()); + curl_easy_setopt(_curl_handle, CURLOPT_WRITEFUNCTION, &cTmdb::CurlWriteToString); + curl_easy_setopt(_curl_handle, CURLOPT_FILE, (void *)&answer); + curl_easy_setopt(_curl_handle, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(_curl_handle, CURLOPT_TIMEOUT, URL_TIMEOUT); + curl_easy_setopt(_curl_handle, CURLOPT_NOSIGNAL, (long)1); + curl_easy_setopt(_curl_handle, CURLOPT_SSL_VERIFYPEER, false); + + if (!g_settings.softupdate_proxyserver.empty()) { + curl_easy_setopt(_curl_handle, CURLOPT_PROXY, g_settings.softupdate_proxyserver.c_str()); + if (!g_settings.softupdate_proxyusername.empty()) { + std::string tmp = g_settings.softupdate_proxyusername + ":" + g_settings.softupdate_proxypassword; + curl_easy_setopt(_curl_handle, CURLOPT_PROXYUSERPWD, tmp.c_str()); + } + } + + char cerror[CURL_ERROR_SIZE]; + curl_easy_setopt(_curl_handle, CURLOPT_ERRORBUFFER, cerror); + + printf("try to get [%s] ...\n", url.c_str()); + CURLcode httpres = curl_easy_perform(_curl_handle); + + printf("http: res %d size %d\n", httpres, (int)answer.size()); + + if (httpres != 0 || answer.empty()) { + printf("error: %s\n", cerror); + return false; + } + return true; +} + +bool cTmdb::DownloadUrl(std::string url, std::string file, CURL *_curl_handle) +{ + if (!_curl_handle) + _curl_handle = curl_handle; + + FILE * fp = fopen(file.c_str(), "wb"); + if (fp == NULL) { + perror(file.c_str()); + return false; + } + curl_easy_setopt(_curl_handle, CURLOPT_URL, url.c_str()); + curl_easy_setopt(_curl_handle, CURLOPT_WRITEFUNCTION, NULL); + curl_easy_setopt(_curl_handle, CURLOPT_FILE, fp); + curl_easy_setopt(_curl_handle, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(_curl_handle, CURLOPT_TIMEOUT, URL_TIMEOUT); + curl_easy_setopt(_curl_handle, CURLOPT_NOSIGNAL, (long)1); + curl_easy_setopt(_curl_handle, CURLOPT_SSL_VERIFYPEER, false); + + if (!g_settings.softupdate_proxyserver.empty()) { + curl_easy_setopt(_curl_handle, CURLOPT_PROXY, g_settings.softupdate_proxyserver.c_str()); + if (!g_settings.softupdate_proxyusername.empty()) { + std::string tmp = g_settings.softupdate_proxyusername + ":" + g_settings.softupdate_proxypassword; + curl_easy_setopt(_curl_handle, CURLOPT_PROXYUSERPWD, tmp.c_str()); + } + } + + char cerror[CURL_ERROR_SIZE]; + curl_easy_setopt(_curl_handle, CURLOPT_ERRORBUFFER, cerror); + + printf("try to get [%s] ...\n", url.c_str()); + CURLcode httpres = curl_easy_perform(_curl_handle); + + double dsize; + curl_easy_getinfo(_curl_handle, CURLINFO_SIZE_DOWNLOAD, &dsize); + fclose(fp); + + printf("http: res %d size %g.\n", httpres, dsize); + + if (httpres != 0) { + printf("curl error: %s\n", cerror); + unlink(file.c_str()); + return false; + } + return true; +} +std::string cTmdb::random_API_KEY() +{ + std::string keys[] = {API_KEY_1,API_KEY_2,API_KEY_3,API_KEY_4}; + int i = rand() % (sizeof(keys) / sizeof(keys[0])); + return keys[i]; +} + + +bool cTmdb::GetMovieDetails() +{ + printf("[TMDB]: %s\n",__func__); + std::string url = "http://api.themoviedb.org/3/search/multi?api_key="+random_API_KEY()+"&language=de&query=" + encodeUrl(minfo.epgtitle); + std::string answer; + if (!getUrl(url, answer)) + return false; + + Json::Value root; + Json::Reader reader; + bool parsedSuccess = reader.parse(answer, root, false); + if (!parsedSuccess) { + printf("Failed to parse JSON\n"); + printf("%s\n", reader.getFormattedErrorMessages().c_str()); + return false; + } + + minfo.result = root.get("total_results",0).asInt(); + + printf("[TMDB]: results: %d\n",minfo.result); + + if (minfo.result > 0) { + Json::Value elements = root["results"]; + minfo.id = elements[0].get("id",-1).asInt(); + minfo.media_type = elements[0].get("media_type","").asString(); + if (minfo.id > -1) { + url = "http://api.themoviedb.org/3/"+minfo.media_type+"/"+to_string(minfo.id)+"?api_key="+random_API_KEY()+"&language=de&append_to_response=credits"; + answer.clear(); + if (!getUrl(url, answer)) + return false; + parsedSuccess = reader.parse(answer, root, false); + if (!parsedSuccess) { + printf("Failed to parse JSON\n"); + printf("%s\n", reader.getFormattedErrorMessages().c_str()); + return false; + } + + minfo.overview = root.get("overview","").asString(); + minfo.poster_path = root.get("poster_path","").asString(); + minfo.original_title = root.get("original_title","").asString();; + minfo.release_date = root.get("release_date","").asString();; + minfo.vote_average = root.get("vote_average","").asString();; + minfo.vote_count = root.get("vote_count",0).asInt();; + minfo.runtime = root.get("runtime",0).asInt();; + if (minfo.media_type == "tv") { + minfo.original_title = root.get("original_name","").asString();; + minfo.episodes = root.get("number_of_episodes",0).asInt();; + minfo.seasons = root.get("number_of_seasons",0).asInt();; + minfo.release_date = root.get("first_air_date","").asString();; + elements = root["episode_run_time"]; + minfo.runtimes = elements[0].asString(); + for (unsigned int i= 1; igetText(LOCALE_EPGVIEWER_LENGTH)+": "+minfo.runtimes+"\n"; + else + epgtext += (std::string)g_Locale->getText(LOCALE_EPGVIEWER_LENGTH)+": "+to_string(minfo.runtime)+"\n"; + epgtext += (std::string)g_Locale->getText(LOCALE_EPGVIEWER_GENRE)+": "+minfo.genres+"\n"; + epgtext += (std::string)g_Locale->getText(LOCALE_EPGEXTENDED_ORIGINAL_TITLE) +" : "+ minfo.original_title+"\n"; + epgtext += (std::string)g_Locale->getText(LOCALE_EPGEXTENDED_YEAR_OF_PRODUCTION)+" : "+ minfo.release_date.substr(0,4) +"\n"; + if (minfo.media_type == "tv") + epgtext += "Seasons/Episodes: "+to_string(minfo.seasons)+"/"+to_string(minfo.episodes)+"\n"; + if (!minfo.cast.empty()) + epgtext += (std::string)g_Locale->getText(LOCALE_EPGEXTENDED_ACTORS)+":\n"+ minfo.cast+"\n"; + return epgtext; +} + +int cTmdb::exec() +{ + neutrino_msg_t msg; + neutrino_msg_data_t data; + + if (form == NULL) + form = new CComponentsForm(); + form->setDimensionsAll(sx, sy, ox, oy); + + CComponentsHeader *header = new CComponentsHeader(0, 0, ox, toph); + CComponentsText *headerText = new CComponentsText(15, 0, ox-15, toph, getTitle(), CTextBox::NO_AUTO_LINEBREAK, g_Font[SNeutrinoSettings::FONT_TYPE_EPG_TITLE]);; + headerText->doPaintBg(false); + headerText->setTextColor(COL_MENUHEAD_TEXT); + form->addCCItem(header); + form->addCCItem(headerText); + + + CComponentsPicture *ptmp = new CComponentsPicture(5, toph+5, "/tmp/tmdb.jpg"); + ptmp->setWidth(342); + ptmp->setHeight(513); + ptmp->setColorBody(COL_BLUE); + ptmp->setCorner(RADIUS_MID, CORNER_TOP_LEFT); + form->addCCItem(ptmp); + + CComponentsText *des = new CComponentsText(ptmp->getWidth()+10, toph+5, form->getWidth()-ptmp->getWidth()-10, form->getHeight(), CreateEPGText(), CTextBox::AUTO_LINEBREAK_NO_BREAKCHARS | CTextBox::TOP); + des->setCorner(RADIUS_MID, CORNER_BOTTOM_RIGHT); + des->setTextFont(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]); + form->addCCItem(des); + + form->paint(); + frameBuffer->blit(); + + while (1) { + g_RCInput->getMsg(&msg, &data, 100); + if (msg == CRCInput::RC_home) + break; + } + + if (form->isPainted()) { + form->hide(); + delete form; + form = NULL; + } +} diff --git a/src/gui/tmdb.h b/src/gui/tmdb.h new file mode 100644 index 000000000..751b48560 --- /dev/null +++ b/src/gui/tmdb.h @@ -0,0 +1,84 @@ +/* + Copyright (C) 2015 TangoCash + + License: GPLv2 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __TMDB__ +#define __TMDB__ + +#include +#include + +#include +#include + +typedef struct { + std::string epgtitle; + std::string poster_path; + std::string overview; + std::string original_title; + std::string release_date; + std::string vote_average; + int vote_count; + int id; + std::string media_type; + int result; + int runtime; + std::string runtimes; + std::string genres; + int episodes; + int seasons; + std::string cast; +}tmdbinfo; + +class cTmdb +{ + private: + CURL *curl_handle; + CComponentsForm *form; + tmdbinfo minfo; + + CFrameBuffer *frameBuffer; + int ox, oy, sx, sy, toph; + + static size_t CurlWriteToString(void *ptr, size_t size, size_t nmemb, void *data); + std::string encodeUrl(std::string txt); + std::string decodeUrl(std::string url); + std::string random_API_KEY(); + bool getUrl(std::string &url, std::string &answer, CURL *_curl_handle = NULL); + bool DownloadUrl(std::string url, std::string file, CURL *_curl_handle = NULL); + bool GetMovieDetails(); + + public: + cTmdb(std::string epgtitle); + ~cTmdb(); + int exec(); + std::string CreateEPGText(); + + std::string getTitle() { return minfo.epgtitle;} + std::string getOrgTitle() { return minfo.original_title;} + std::string getReleaseDate() { return minfo.release_date;} + std::string getDescription() { return minfo.overview;} + std::string getVote() { return minfo.vote_average;} + bool hasCover() { return !minfo.poster_path.empty();} + bool getBigCover(std::string cover) { return DownloadUrl("http://image.tmdb.org/t/p/w342" + minfo.poster_path, cover);} + bool getSmallCover(std::string cover) { return DownloadUrl("http://image.tmdb.org/t/p/w185" + minfo.poster_path, cover);} + int getResults() { return minfo.result;} + int getStars() { return (int) (atof(minfo.vote_average.c_str())+0.5);} +}; + +#endif