epgview: add imdb functionality into epgviewer

taken over from https://bitbucket.org/neutrino-images/ni-neutrino-hd
This commit is contained in:
2018-04-27 15:53:57 +02:00
parent 6110ba75d7
commit db64f1e094
11 changed files with 844 additions and 16 deletions

View File

@@ -820,6 +820,24 @@ imageinfo.kernel Kernel:
imageinfo.license Lizenz
imageinfo.vcs Git:
imageinfo.version Version:
imdb.data_actors Darsteller
imdb.data_awards Awards
imdb.data_boxoffice Einspielergebnis
imdb.data_director Regisseur
imdb.data_failed Keine Daten gefunden
imdb.data_genre Genre
imdb.data_metascore Metascore
imdb.data_plot Handlung
imdb.data_production Produktion
imdb.data_rating_failed Keine Bewertung
imdb.data_released Veröffentlicht
imdb.data_runtime Spieldauer
imdb.data_title Originaltitel
imdb.data_votes Stimmen
imdb.data_website Webseite
imdb.data_writer Drehbuchautor
imdb.info IMDb-Info
imdb.info_save Bild speichern
inetradio.name Internetradio
infoviewer.epgnotload Informationen noch nicht geladen ...
infoviewer.epgwait Warte auf EPG-Informationen ...
@@ -1723,6 +1741,7 @@ moviebrowser.hint_movieend Filmende in 5 Sekunden\n'0' zum Weitersehen
moviebrowser.hint_newbook_backward Neue Wiederholung gestartet.\n'%s' bestimmt die Endposition, '0' bricht ab.
moviebrowser.hint_newbook_forward Neuer Werbesprung gestartet.\n'%s' bestimmt die Endposition, '0' bricht ab.
moviebrowser.hint_truncate Entfernt den Filmteil hinter der Filmende-Markierung
moviebrowser.imdb_data Lade IMDb-Daten
moviebrowser.info_audio Audio
moviebrowser.info_channel Kanal
moviebrowser.info_file Datei
@@ -2431,6 +2450,7 @@ timing.static_messages Interaktive Meldungen
timing.volumebar Lautstärkeanzeige
tmdb.api_key TMDb API Schlüssel
tmdb.enabled TMDb-Unterstützung
tmdb.info TMDb-Info
tmdb.read_data Suche TMDb-Daten ...
tunersetup.cable Kabel (DVB-C)
tunersetup.hybrid Hybrid (DVB-C/T/T2)

View File

@@ -820,6 +820,24 @@ imageinfo.kernel Kernel:
imageinfo.license License
imageinfo.vcs Git:
imageinfo.version Version:
imdb.data_actors Actors
imdb.data_awards Awards
imdb.data_boxoffice Boxoffice
imdb.data_director Director
imdb.data_failed No data found
imdb.data_genre Genre
imdb.data_metascore Metascore
imdb.data_plot Plot
imdb.data_production Production
imdb.data_rating_failed No rating
imdb.data_released Released
imdb.data_runtime Runtime
imdb.data_title Original title
imdb.data_votes Votes
imdb.data_website Website
imdb.data_writer Screenplay author
imdb.info IMDb-Info
imdb.info_save save Cover
inetradio.name Internetradio
infoviewer.epgnotload EPG not loaded ...
infoviewer.epgwait waiting for EPG ...
@@ -1723,6 +1741,7 @@ moviebrowser.hint_movieend Film end in 5 seconds\n'0' to cancel
moviebrowser.hint_newbook_backward New jump back started\n'%s' to define endposition, '0' to cancel
moviebrowser.hint_newbook_forward New jump forward started\n'%s' to define endposition, '0' to cancel
moviebrowser.hint_truncate Truncating all data beyond the end-bookmark
moviebrowser.imdb_data Get IMDb data
moviebrowser.info_audio Audio
moviebrowser.info_channel Channel
moviebrowser.info_file File
@@ -2431,6 +2450,7 @@ timing.static_messages Interactive messages
timing.volumebar Volume bar
tmdb.api_key TMDb API key
tmdb.enabled TMDb support
tmdb.info TMDb-Info
tmdb.read_data Search TMDb data ...
tunersetup.cable Cable (DVB-C)
tunersetup.hybrid Hybrid (DVB-C/T/T2)

View File

@@ -62,6 +62,7 @@ libneutrino_gui_a_SOURCES = \
filebrowser.cpp \
followscreenings.cpp \
imageinfo.cpp \
imdb.cpp \
info_menue.cpp \
infoviewer.cpp \
infoviewer_bb.cpp \

View File

@@ -129,6 +129,11 @@ CEpgData::CEpgData()
Bottombox = NULL;
pb = NULL;
font_title = NULL;
imdb = CIMDB::getInstance();
imdb_active = false;
movie_filename.clear();
}
CEpgData::~CEpgData()
@@ -141,7 +146,7 @@ void CEpgData::start()
ox = frameBuffer->getWindowWidth(bigFonts ? false /* big */ : true /* small */);
oy = frameBuffer->getWindowHeight(bigFonts ? false /* big */ : true /* small */);
font_title = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_TITLE];
font_title = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE];
topheight = font_title->getHeight();
topboxheight = topheight + 6;
botboxheight = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->getHeight() + 2*OFFSET_INNER_MIN;
@@ -249,6 +254,9 @@ void CEpgData::showText(int startPos, int ypos, bool has_cover, bool fullClear)
if (has_cover)
{
if (imdb_active)
cover = imdb->posterfile;
g_PicViewer->getSize(cover.c_str(), &cover_width, &cover_height);
if (cover_width && cover_height)
{
@@ -263,6 +271,7 @@ void CEpgData::showText(int startPos, int ypos, bool has_cover, bool fullClear)
int offset = 0, count = 0;
int max_mon_w = 0, max_wday_w = 0;
int digi = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getRenderWidth("29..");
for(int i = 0; i < 12;i++){
max_mon_w = std::max(max_mon_w, g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getRenderWidth(std::string(g_Locale->getText(CLocaleManager::getMonth(i))) + " "));
if(i > 6)
@@ -273,7 +282,7 @@ void CEpgData::showText(int startPos, int ypos, bool has_cover, bool fullClear)
frameBuffer->paintBoxRel(sx+offs, y, ox-SCROLLBAR_WIDTH-offs, sb, COL_MENUCONTENT_PLUS_0); // background of the text box
if (has_cover) {
if (!g_PicViewer->DisplayImage(cover ,sx+OFFSET_INNER_MID ,y+OFFSET_INNER_MID+((sb-cover_height)/2), cover_width, cover_height, CFrameBuffer::TM_NONE)) {
if (!g_PicViewer->DisplayImage(cover ,sx+OFFSET_INNER_MID ,y+OFFSET_INNER_MID, cover_width, cover_height, CFrameBuffer::TM_NONE)) {
cover_offset = 0;
frameBuffer->paintBoxRel(sx, y, ox-SCROLLBAR_WIDTH, sb, COL_MENUCONTENT_PLUS_0); // background of the text box
}
@@ -287,6 +296,14 @@ void CEpgData::showText(int startPos, int ypos, bool has_cover, bool fullClear)
frameBuffer->paintIcon(NEUTRINO_ICON_TMDB, sx+OFFSET_INNER_MID+cover_offset, y+(medlineheight-icon_h)/2);
logo_offset = icon_w + OFFSET_INNER_MID;
}
if (imdb_active && startPos == 0)
{
frameBuffer->getIconSize(NEUTRINO_ICON_IMDB, &icon_w, &icon_h);
frameBuffer->paintIcon(NEUTRINO_ICON_IMDB, sx+OFFSET_INNER_MID+cover_offset, y+(medlineheight-icon_h)/2);
logo_offset = icon_w + OFFSET_INNER_MID;
}
if (stars > 0 && startPos == 0)
{
frameBuffer->getIconSize(NEUTRINO_ICON_STAR_OFF, &icon_w, &icon_h);
@@ -295,6 +312,29 @@ void CEpgData::showText(int startPos, int ypos, bool has_cover, bool fullClear)
for (int i = 0; i < stars; i++)
frameBuffer->paintIcon(NEUTRINO_ICON_STAR_ON, sx+10+cover_offset+logo_offset + i*(icon_w+3), y+(medlineheight-icon_h)/2);
}
#if 0
if ((stars > 0 || imdb_stars > 0) && (tmdb_active || imdb_active) && startPos == 0)
{
if (stars <= 10)
stars *= 10; // recalculate stars value for starbar
int stars_w = 0, stars_h = 0;
frameBuffer->getIconSize(NEUTRINO_ICON_STARS_BG, &stars_w, &stars_h);
//create starbar item
CProgressBar *cc_starbar = new CProgressBar();
cc_starbar->setProgress(sx+OFFSET_INNER_MID+cover_offset+logo_offset, y+(medlineheight-stars_h)/2, stars_w, medlineheight, imdb_active ? imdb_stars : stars, 100);
cc_starbar->setType(CProgressBar::PB_STARBAR);
cc_starbar->paint();
if (imdb_active)
{
int _x = sx+OFFSET_INNER_MID+cover_offset+logo_offset+cc_starbar->getWidth()+OFFSET_INNER_MID;
int _w = ox-OFFSET_INNER_MID-cover_offset-logo_offset-cc_starbar->getWidth()-OFFSET_INNER_MID;
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->RenderString(_x, y+medlineheight, _w, imdb_rating, COL_MENUCONTENT_TEXT, 0, true);
}
}
#endif
for (int i = startPos; i < textSize && i < startPos + medlinecount; i++, y += medlineheight)
{
if(epgText[i].second){
@@ -523,6 +563,7 @@ int CEpgData::show_mp(MI_MOVIE_INFO *mi, int mp_position, int mp_duration, bool
epgData.title = mp_movie_info->epgTitle;
epgData.info1 = mp_movie_info->epgInfo1;
epgData.info2 = mp_movie_info->epgInfo2;
movie_filename = mp_movie_info->file.Name;
epgData.itemDescriptions.clear();
epgData.items.clear();
@@ -868,6 +909,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
header->hideCCItems();
// set channel logo
if (g_settings.channellist_show_channellogo)
header->setChannelLogo(channel_id, channel_name);
//paint head
@@ -959,6 +1001,9 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
CNeutrinoApp::getInstance()->handleMsg(msg, data);
break;
case CRCInput::RC_left:
if(imdb_active)
imdb_active = false;
if ((prev_id != 0) && !call_fromfollowlist && !mp_info)
{
toph = topboxheight;
@@ -967,6 +1012,9 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
}
break;
case CRCInput::RC_right:
if(imdb_active)
imdb_active = false;
if ((next_id != 0) && !call_fromfollowlist && !mp_info)
{
toph = topboxheight;
@@ -978,7 +1026,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
if (showPos+scrollCount<textCount)
{
showPos += scrollCount;
showText(showPos, sy + toph, tmdb_active, false);
showText(showPos, sy + toph, tmdb_active || (imdb_active && imdb->gotPoster()), false);
}
break;
case CRCInput::RC_up:
@@ -986,7 +1034,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
showPos -= scrollCount;
if (showPos < 0)
showPos = 0;
showText(showPos, sy + toph, tmdb_active, false);
showText(showPos, sy + toph, tmdb_active || (imdb_active && imdb->gotPoster()), false);
}
break;
case CRCInput::RC_page_up:
@@ -1121,8 +1169,14 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
printf("timerd not available\n");
}
break;
case CRCInput::RC_help:
case CRCInput::RC_0: //imdb
{
if (imdb_active) {
imdb_active = false;
showTimerEventBar(true, !mp_info && isCurrentEPG(channel_id), mp_info); //show buttons
epgText = epgText_saved;
textCount = epgText.size();
}
if (g_settings.tmdb_enabled)
{
showPos = 0;
@@ -1140,7 +1194,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
processTextToArray(tmdb->CreateEPGText(), 0, tmdb->hasCover());
textCount = epgText.size();
stars = tmdb->getStars();
showText(showPos, sy + toph, tmdb_active);
showText(showPos, sy + toph, tmdb_active || (imdb_active && imdb->gotPoster()));
} else {
ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_EPGVIEWER_NODETAILED, CMsgBox::mbrOk , CMsgBox::mbrOk);
}
@@ -1155,6 +1209,50 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
}
break;
}
case CRCInput::RC_green:
{
if (tmdb_active) {
tmdb_active = false;
epgText = epgText_saved;
textCount = epgText.size();
stars=0;
}
if (!imdb_active)
{
//show IMDb info
imdb_active = true;
showIMDb(true); //show splashscreen only
imdb->getIMDb(epgData.title);
showIMDb();
showTimerEventBar(true, !mp_info && isCurrentEPG(channel_id), mp_info); //show buttons
timeoutEnd = CRCInput::calcTimeoutEnd(timeout);
}
else if (imdb_active && imdb->gotPoster())
{
imdb_active = false;
CHintBox * hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, LOCALE_IMDB_INFO_SAVE);
hintBox->paint();
std::string picname;
if (mp_info)
{
size_t _pos;
if ((_pos = movie_filename.rfind(".")) != std::string::npos)
picname = movie_filename.substr(0, _pos) + ".jpg";
}
else
picname = imdb->getFilename(channel, epgData.eventID);
CFileHelpers fh;
if (!fh.copyFile(imdb->posterfile.c_str(), picname.c_str(), 0644))
perror( "IMDb: error copy file" );
sleep(2);
hintBox->hide();
showTimerEventBar(true, !mp_info && isCurrentEPG(channel_id), mp_info); //show buttons
}
break;
}
case CRCInput::RC_yellow:
{
if (!mp_info)
@@ -1163,6 +1261,14 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
{
CAdZapMenu::getInstance()->exec(NULL, "enable");
loop = false;
std::string tmp_msg;
tmp_msg = g_Locale->getText(LOCALE_WORD_IN);
tmp_msg += " ";
tmp_msg += to_string(g_settings.adzap_zapBackPeriod / 60);
tmp_msg += " ";
tmp_msg += g_Locale->getText(LOCALE_UNIT_SHORT_MINUTE);
ShowMsg(LOCALE_ADZAP, tmp_msg, CMsgBox::mbrBack, CMsgBox::mbBack, NEUTRINO_ICON_INFO);
}
//CTimerdClient timerdclient;
else if (g_Timerd->isTimerdAvailable())
@@ -1182,6 +1288,9 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
}
case CRCInput::RC_blue:
{
if(imdb_active)
imdb_active = false;
if(!followlist.empty() && !call_fromfollowlist){
hide();
time_t tmp_sZeit = epgData.epg_times.startzeit;
@@ -1208,6 +1317,8 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
bigFonts = bigFonts ? false : true;
ResetModules();
frameBuffer->paintBackgroundBoxRel(sx, sy, ox, oy);
tmdb_active = false; // reset tmdb
imdb_active = false; // reset imdb
showTimerEventBar (false);
start();
// textypos = sy;
@@ -1228,6 +1339,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start
show(channel_id, id, &startzeit, false, call_fromfollowlist);
showPos=0;
break;
case CRCInput::RC_help:
case CRCInput::RC_ok:
case CRCInput::RC_timeout:
if(fader.StartFadeOut()) {
@@ -1286,6 +1398,10 @@ void CEpgData::hide()
frameBuffer->paintBackgroundBoxRel(sx, sy, ox, oy);
showTimerEventBar (false);
// imdb
imdb_active = false;
imdb->cleanup();
}
void CEpgData::GetEPGData(const t_channel_id channel_id, uint64_t id, time_t* startzeit, bool clear )
@@ -1318,7 +1434,7 @@ void CEpgData::GetEPGData(const t_channel_id channel_id, uint64_t id, time_t* st
char temp[20]={0};
strftime( temp, sizeof(temp),"%d.%m.%Y", pStartZeit);
epg_date = g_Locale->getText(CLocaleManager::getWeekday(pStartZeit));
epg_date += ".";
epg_date += ", ";
epg_date += temp;
strftime( temp, sizeof(temp), "%H:%M", pStartZeit);
epg_start= temp;
@@ -1449,23 +1565,26 @@ void CEpgData::showProgressBar()
// -- 2002-05-13 rasc
//
#define EpgButtonsMax 4
const struct button_label EpgButtons[][EpgButtonsMax] =
#define EpgButtonsMax 5
struct button_label EpgButtons[][EpgButtonsMax] =
{
{ // full view
{ NEUTRINO_ICON_BUTTON_RED, LOCALE_TIMERBAR_RECORDEVENT },
{ NEUTRINO_ICON_BUTTON_GREEN, LOCALE_IMDB_INFO },
{ NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_TIMERBAR_CHANNELSWITCH },
{ NEUTRINO_ICON_BUTTON_BLUE, LOCALE_EPGVIEWER_MORE_SCREENINGS_SHORT },
{ NEUTRINO_ICON_BUTTON_INFO_SMALL, LOCALE_CHANNELLIST_ADDITIONAL }
{ NEUTRINO_ICON_BUTTON_0, LOCALE_TMDB_INFO }
},
{ // w/o followscreenings
{ NEUTRINO_ICON_BUTTON_RED, LOCALE_TIMERBAR_RECORDEVENT },
{ NEUTRINO_ICON_BUTTON_GREEN, LOCALE_IMDB_INFO },
{ NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_TIMERBAR_CHANNELSWITCH },
{ NEUTRINO_ICON_BUTTON_INFO_SMALL, LOCALE_CHANNELLIST_ADDITIONAL }
{ NEUTRINO_ICON_BUTTON_0, LOCALE_TMDB_INFO }
},
{ // movieplayer mode
{ NEUTRINO_ICON_BUTTON_RED, LOCALE_EPG_SAVING },
{ NEUTRINO_ICON_BUTTON_INFO_SMALL, LOCALE_CHANNELLIST_ADDITIONAL }
{ NEUTRINO_ICON_BUTTON_GREEN, LOCALE_IMDB_INFO },
{ NEUTRINO_ICON_BUTTON_0, LOCALE_TMDB_INFO }
}
};
@@ -1494,8 +1613,19 @@ void CEpgData::showTimerEventBar (bool pshow, bool adzap, bool mp_info)
}
bool tmdb = g_settings.tmdb_enabled;
bool fscr = (has_follow_screenings && !call_fromfollowlist);
if (imdb_active)
{
EpgButtons[mp_info ? 2 : (fscr ? 0 : 1)][1].button = (imdb->gotPoster()) ? NEUTRINO_ICON_BUTTON_GREEN : NEUTRINO_ICON_BUTTON_DUMMY_SMALL;
EpgButtons[mp_info ? 2 : (fscr ? 0 : 1)][1].locale = LOCALE_IMDB_INFO_SAVE;
}
else
{
EpgButtons[mp_info ? 2 : (fscr ? 0 : 1)][1].button = NEUTRINO_ICON_BUTTON_GREEN;
EpgButtons[mp_info ? 2 : (fscr ? 0 : 1)][1].locale = LOCALE_IMDB_INFO;
}
if (mp_info)
::paintButtons(x, y, w, tmdb ? 2 : 1, EpgButtons[2], w, h);
::paintButtons(x, y, w, tmdb ? 3 : 2, EpgButtons[2], w, h);
else
{
int c = EpgButtonsMax;
@@ -1504,12 +1634,64 @@ void CEpgData::showTimerEventBar (bool pshow, bool adzap, bool mp_info)
if (!fscr)
c--; // reduce blue button
if (g_settings.recording_type != CNeutrinoApp::RECORDING_OFF)
::paintButtons(x, y, w, c, EpgButtons[fscr ? 0 : 1], w, h, "", false, COL_MENUFOOT_TEXT, adzap ? adzap_button.c_str() : NULL, 1);
::paintButtons(x, y, w, c, EpgButtons[fscr ? 0 : 1], w, h, "", false, COL_MENUFOOT_TEXT, adzap ? adzap_button.c_str() : NULL, 2);
else
::paintButtons(x, y, w, c, &EpgButtons[fscr ? 0 : 1][1], w, h, "", false, COL_MENUFOOT_TEXT, adzap ? adzap_button.c_str() : NULL, 0);
::paintButtons(x, y, w, c, &EpgButtons[fscr ? 0 : 1][1], w, h, "", false, COL_MENUFOOT_TEXT, adzap ? adzap_button.c_str() : NULL, 1);
}
}
//imdb start
int CEpgData::showIMDb(bool splash)
{
fontIMDb = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1];
frameBuffer->paintBoxRel(sx, sy+toph, ox /*- 15*/, sb, COL_MENUCONTENT_PLUS_0);
if (splash)
{
fontIMDb->RenderString(sx+OFFSET_INNER_MID, sy+toph+medlineheight, ox-OFFSET_INNER_MID, "IMDb: Daten werden geladen ...", COL_MENUCONTENT_TEXT, 0, true);
return 0;
}
//titel
std::string title = imdb->getIMDbElement("Title");
if(((title.find(imdb->search_error)) != std::string::npos))
return 1;
// clear epg array
epgText_saved = epgText;
epgText.clear();
//data
std::string txt;
txt.clear();
imdb->getIMDbData(txt);
processTextToArray(" ", 0, imdb->gotPoster()); // empty line to get space for the rating stars
processTextToArray(txt, 0, imdb->gotPoster());
textCount = epgText.size();
//rating
imdb_rating = imdb->getIMDbElement("imdbRating");
std::string value = imdb_rating;
if (imdb_rating == "N/A")
{
value = "0";
imdb_rating = g_Locale->getText(LOCALE_IMDB_DATA_RATING_FAILED);
}
else
imdb_rating += "/10";
size_t pos = value.find_first_of(",.");
if (pos != std::string::npos)
value.replace(pos, 1, ""); // change 8,1 or 8.1 to 81
imdb_stars = atoi(value);
showText(0, sy + toph, imdb->gotPoster());
return 0;
}
void CEpgData::ResetModules()
{
if (header){

View File

@@ -35,6 +35,7 @@
#include <system/settings.h>
#include <gui/imdb.h>
#include <driver/movieinfo.h>
#include "widget/menue.h"
#include "widget/navibar.h"
@@ -49,6 +50,8 @@ class CEpgData
CChannelEventList evtlist;
CChannelEventList followlist;
CEPGData epgData;
CIMDB *imdb;
CComponentsHeader *header;
CNaviBar *Bottombox;
CProgressBar *pb;
@@ -94,6 +97,15 @@ class CEpgData
void showProgressBar();
bool isCurrentEPG(const t_channel_id channel_id);
bool imdb_active;
int imdb_stars;
std::string imdb_rating;
std::string epg_title;
std::string movie_filename;
int showIMDb(bool splash = false);
Font *fontIMDb;
public:
CEpgData();

475
src/gui/imdb.cpp Normal file
View File

@@ -0,0 +1,475 @@
/*
imdb
(C) 2009-2016 NG-Team
(C) 2016 NI-Team
License: GPL
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; either version 2 of the License, or
(at your option) any later version.
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 <config.h>
#endif
#include <fstream>
#include <iostream>
#include <global.h>
#include <driver/screen_max.h>
#include <system/httptool.h>
#include <system/helpers.h>
#include <system/helpers-json.h>
#include <eitd/sectionsd.h>
#include <json/json.h>
#include "imdb.h"
CIMDB::CIMDB()
{
search_url = "http://www.google.de/search?q=";
search_outfile = "/tmp/google.out";
search_error = "IMDb: Google download failed";
imdb_url = "http://www.omdbapi.com/?plot=full&r=json&i=";
imdb_outfile = "/tmp/imdb.json";
omdb_apikey = "";
posterfile = "/tmp/imdb.jpg";
}
CIMDB::~CIMDB()
{
cleanup();
}
CIMDB* CIMDB::getInstance()
{
static CIMDB* imdb = NULL;
if(!imdb)
imdb = new CIMDB();
return imdb;
}
std::string CIMDB::utf82url(std::string s)
{
std::stringstream ss;
for (size_t i = 0; i < s.length(); ++i)
{
if (unsigned(s[i]) <= ' ') {
ss << '+';
}
else if (unsigned(s[i]) <= '\x27') {
ss << "%" << std::hex << unsigned(s[i]);
}
else {
ss << s[i];
}
}
return ss.str();
}
std::string CIMDB::parseString(std::string search1, std::string search2, std::string str)
{
std::string ret, search;
size_t pos_wildcard, pos_firstline, pos_search1, pos_search2;
pos_wildcard = pos_firstline = pos_search1 = pos_search2 = std::string::npos;
if((pos_wildcard = search1.find('*')) != std::string::npos)
{
search = search1.substr(0, pos_wildcard);
//std::cout << "wildcard detected" << '\t' << "= " << search << "[*]" << search1.substr(pos_wildcard+1) << std::endl;
}
else
search = search1;
//std::cout << "search1" << "\t\t\t" << "= " << '"' << search << '"' << std::endl;
if((pos_search1 = str.find(search)) != std::string::npos)
{
//std::cout << "search1 found" << "\t\t" << "= " << '"' << search << '"' << " at pos "<< (int)(pos_search1) << " => " << str << std::endl;
pos_search1 += search.length();
if(pos_wildcard != std::string::npos)
{
size_t pos_wildcard_ext;
std::string wildcard_ext = search1.substr(pos_wildcard+1);
//std::cout << "wildcard_ext" << "\t\t" << "= " << '"' << wildcard_ext << '"' << std::endl;
if((pos_wildcard_ext = str.find(wildcard_ext,pos_wildcard+1)) != std::string::npos)
{
//std::cout << "wildcard_ext found" << "\t" << "= " << '"' << wildcard_ext << '"' << " at pos "<< (int)(pos_wildcard_ext) << " => " << str << std::endl;
pos_search1 = pos_wildcard_ext + wildcard_ext.length();
}
else
{
//std::cout << "wildcard_ext not found in line " << acc << " - exit" << std::endl;
return("");
}
}
}
else
{
//std::cout << "search1 not found in line " << acc << " - exit" << std::endl;
return("");
}
if(pos_search1 != std::string::npos)
{
//std::cout << "search2 " << "\t\t" << "= " << '"' << search2 << '"' << std::endl;
if(search2 == "\n")
{
ret = str.substr(pos_search1, str.length() - pos_search1);
return(ret);
}
if((pos_search2 = str.find(search2, pos_search1)) != std::string::npos)
{
if(search2.empty())
pos_search2 = str.length();
//std::cout << "search2" << "\t\t\t" << "= " << '"' << search2 << '"' << " found at "<< (int)(pos_search2) << " => " << str << std::endl;
ret = str.substr(pos_search1, pos_search2 - pos_search1);
}
//else
//std::cout << "search2 not found in line " << acc << " - exit" << std::endl;
}
return(ret);
}
std::string CIMDB::parseFile(std::string search1, std::string search2, const char* file, std::string firstline, int line_offset)
{
int line = 0;
acc = 0;
std::ifstream fh;
std::string str, ret, search;
size_t pos_firstline, pos_search1, pos_search2;
pos_firstline = pos_search1 = pos_search2 = std::string::npos;
if(firstline.empty())
pos_firstline = 0;
fh.open(file, std::ios::in);
if(fh.is_open())
{
while (!fh.eof())
{
getline(fh, str);
acc++;
if(pos_firstline == std::string::npos)
{
if((pos_firstline = str.find(firstline)) != std::string::npos)
{
//std::cout << "firstline found " << str << std::endl;
}
continue;
}
if(line_offset /*&& pos_firstline != std::string::npos*/)
{
if(line+1 != line_offset)
{
line++;
continue;
}
}
ret = parseString(search1,search2,str);
if(!ret.empty())
break;
}
fh.close();
}
return(ret);
}
std::string CIMDB::googleIMDb(std::string s)
{
CHTTPTool httpTool;
std::string ret = search_error;
std::string search_string("title+");
char* search_char = (char*) s.c_str();
m.clear();
unlink(search_outfile.c_str());
unlink(imdb_outfile.c_str());
unlink(posterfile.c_str());
while (*search_char != 0)
{
if (*search_char == ' ')
{
search_string += '+';
}
else
{
search_string += *search_char;
}
search_char++;
}
std::string url = search_url + utf82url(search_string) + "%20site:www.imdb.com";
if (httpTool.downloadFile(url, search_outfile.c_str()))
{
ret = parseFile("http://www.imdb.com/title/", ">", search_outfile.c_str());
if(ret.empty())
ret = parseFile("http://www.imdb.de/title/", ">", search_outfile.c_str());
std::string delimiters = "/&;";
size_t next = ret.find_first_of(delimiters, 0);
ret = ret.substr(0, next);
}
return ret;
}
void CIMDB::initMap( std::map<std::string, std::string>& my )
{
std::string errMsg = "";
Json::Value root;
std::ostringstream ss;
std::ifstream fh(imdb_outfile.c_str(),std::ifstream::in);
ss << fh.rdbuf();
std::string filedata = ss.str();
bool parsedSuccess = parseJsonFromString(filedata, &root, &errMsg);
if(!parsedSuccess)
{
std::cout << "Failed to parse JSON\n";
std::cout << errMsg << std::endl;
my["Response"] = "False"; // we fake a false response
return;
}
/*
we grab only what we need to avoid bad surprises
when api is changed
*/
my["Actors"] = root.get("Actors", "").asString();
my["Awards"] = root.get("Awards", "").asString();
my["BoxOffice"] = root.get("BoxOffice", "").asString();
my["Country"] = root.get("Country", "").asString();
my["Director"] = root.get("Director", "").asString();
my["Genre"] = root.get("Genre", "").asString();
my["imdbID"] = root.get("imdbID", "").asString();
my["imdbRating"] = root.get("imdbRating", "N/A").asString();
my["imdbVotes"] = root.get("imdbVotes", "").asString();
my["Metascore"] = root.get("Metascore", "N/A").asString();
my["Plot"] = root.get("Plot", "").asString();
my["Poster"] = root.get("Poster", "N/A").asString();
my["Production"] = root.get("Production", "").asString();
my["Released"] = root.get("Released", "").asString();
my["Response"] = root.get("Response", "False").asString();
my["Runtime"] = root.get("Runtime", "").asString();
my["Title"] = root.get("Title", "").asString();
my["Website"] = root.get("Website", "").asString();
my["Writer"] = root.get("Writer", "").asString();
my["Year"] = root.get("Year", "").asString();
// currently unused
//my["Rated"] = root.get("Rated", "").asString();
//my["Type"] = root.get("Type", "").asString();
}
int CIMDB::getIMDb(const std::string& epgTitle)
{
CHTTPTool httpTool;
int ret = 0;
std::string imdb_id = googleIMDb(epgTitle);
if(((imdb_id.find(search_error)) != std::string::npos))
return ret;
std::string url = imdb_url + imdb_id + omdb_apikey;
if (httpTool.downloadFile(url, imdb_outfile.c_str()))
{
initMap(m);
//std::cout << "m now contains " << m.size() << " elements.\n";
if(m.empty() || m["Response"]!="True")
return 0;
//for (std::map<std::string,std::string>::iterator it=m.begin(); it!=m.end(); ++it)
// std::cout << it->first << " => " << it->second << '\n';
//download Poster
if(m["Poster"] != "N/A")
{
// if possible load bigger image
std::string origURL ("300");
std::string replURL ("600");
if (m["Poster"].compare(m["Poster"].size()-7,3,origURL) == 0){
//std::cout << "########## " << m["Poster"] << " contains " << origURL << '\n';
m["Poster"].replace(m["Poster"].size()-7,3,replURL);
//std::cout << "########## New string: " << m["Poster"] << '\n';
}
if (httpTool.downloadFile(m["Poster"], posterfile.c_str()))
return 2;
else {
if (access(posterfile.c_str(), F_OK) == 0)
unlink(posterfile.c_str());
return 1;
}
}
ret=2;
}
return ret;
}
bool CIMDB::checkIMDbElement(std::string element)
{
if (m[element].empty() || m[element].compare("N/A") == 0)
return false;
else
return true;
}
void CIMDB::getIMDbData(std::string& txt)
{
if (m["imdbID"].empty() || m["Response"] != "True")
{
txt = g_Locale->getText(LOCALE_IMDB_DATA_FAILED);
return;
}
txt += g_Locale->getString(LOCALE_IMDB_DATA_VOTES) + ": " + m["imdbVotes"] + "\n";
if (checkIMDbElement("Metascore"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_METASCORE) + ": " + m["Metascore"] + "/100\n";
txt += g_Locale->getString(LOCALE_IMDB_DATA_TITLE) + ": " + m["Title"] + "\n";
if (checkIMDbElement("Released"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_RELEASED) + ": " + m["Country"] + ", " + m["Released"] + "\n";
if (checkIMDbElement("Runtime"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_RUNTIME) + ": " + m["Runtime"] + "\n";
if (checkIMDbElement("Genre"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_GENRE) + ": " + m["Genre"] + "\n";
if (checkIMDbElement("Awards"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_AWARDS) + ": " + m["Awards"] + "\n";
if (checkIMDbElement("Director"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_DIRECTOR) + ": " + m["Director"] + "\n";
if (checkIMDbElement("Writer"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_WRITER) + ": " + m["Writer"] + "\n";
if (checkIMDbElement("Production"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_PRODUCTION) + ": " + m["Production"] + "\n";
if (checkIMDbElement("Website"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_WEBSITE) + ": " + m["Website"] + "\n";
if (checkIMDbElement("BoxOffice"))
txt += g_Locale->getString(LOCALE_IMDB_DATA_BOXOFFICE) + ": " + m["BoxOffice"] + "\n";
if (checkIMDbElement("Actors"))
{
txt += "\n";
txt += g_Locale->getString(LOCALE_IMDB_DATA_ACTORS) + ": " + m["Actors"] + "\n";
}
if (checkIMDbElement("Plot"))
{
txt += "\n";
txt += g_Locale->getString(LOCALE_IMDB_DATA_PLOT) + ": " + m["Plot"];
}
}
std::string CIMDB::getFilename(CZapitChannel * channel, uint64_t id)
{
char fname[512]; // UTF-8
char buf[256];
unsigned int pos = 0;
if(check_dir(g_settings.network_nfs_recordingdir.c_str()))
return ("");
snprintf(fname, sizeof(fname), "%s/", g_settings.network_nfs_recordingdir.c_str());
pos = strlen(fname);
// %C == channel, %T == title, %I == info1, %d == date, %t == time_t
std::string FilenameTemplate = g_settings.recording_filename_template;
if (FilenameTemplate.empty())
FilenameTemplate = "%C_%T_%d_%t";
StringReplace(FilenameTemplate,"%d","");
StringReplace(FilenameTemplate,"%t","");
StringReplace(FilenameTemplate,"__","_");
std::string channel_name = channel->getName();
if (!(channel_name.empty())) {
strcpy(buf, UTF8_TO_FILESYSTEM_ENCODING(channel_name.c_str()));
ZapitTools::replace_char(buf);
StringReplace(FilenameTemplate,"%C",buf);
}
else
StringReplace(FilenameTemplate,"%C","no_channel");
CShortEPGData epgdata;
if(CEitManager::getInstance()->getEPGidShort(id, &epgdata)) {
if (!(epgdata.title.empty())) {
strcpy(buf, epgdata.title.c_str());
ZapitTools::replace_char(buf);
StringReplace(FilenameTemplate,"%T",buf);
}
else
StringReplace(FilenameTemplate,"%T","no_title");
if (!(epgdata.info1.empty())) {
strcpy(buf, epgdata.info1.c_str());
ZapitTools::replace_char(buf);
StringReplace(FilenameTemplate,"%I",buf);
}
else
StringReplace(FilenameTemplate,"%I","no_info");
}
strcpy(&(fname[pos]), UTF8_TO_FILESYSTEM_ENCODING(FilenameTemplate.c_str()));
pos = strlen(fname);
strcpy(&(fname[pos]), ".jpg");
return (fname);
}
void CIMDB::StringReplace(std::string &str, const std::string search, const std::string rstr)
{
std::string::size_type ptr = 0;
std::string::size_type pos = 0;
while((ptr = str.find(search,pos)) != std::string::npos){
str.replace(ptr,search.length(),rstr);
pos = ptr + rstr.length();
}
}
void CIMDB::cleanup()
{
if (access(search_outfile.c_str(), F_OK) == 0)
unlink(search_outfile.c_str());
if (access(posterfile.c_str(), F_OK) == 0)
unlink(posterfile.c_str());
}

72
src/gui/imdb.h Normal file
View File

@@ -0,0 +1,72 @@
/*
imdb
(C) 2009-2016 NG-Team
(C) 2016 NI-Team
License: GPL
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; either version 2 of the License, or
(at your option) any later version.
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 __imdb__
#define __imdb__
#include <unistd.h>
#include <gui/components/cc.h>
#include <zapit/zapit.h>
class CIMDB
{
public:
CIMDB();
~CIMDB();
static CIMDB* getInstance();
std::string search_url;
std::string search_outfile;
std::string search_error;
std::string imdb_outfile;
std::string posterfile;
int getIMDb(const std::string& epgTitle);
std::string getFilename(CZapitChannel * channel, uint64_t id);
void StringReplace(std::string &str, const std::string search, const std::string rstr);
void cleanup();
void getIMDbData(std::string& txt);
bool gotPoster() { return (access(posterfile.c_str(), F_OK) == 0); };
bool checkIMDbElement(std::string element);
//FIXME: what if m[element] doesn't exist?
std::string getIMDbElement(std::string element) { return m[element]; };
private:
int acc;
std::string imdb_url;
std::string omdb_apikey;
std::string googleIMDb(std::string s);
std::string utf82url(std::string s);
std::string parseString(std::string search1, std::string search2, std::string str);
std::string parseFile(std::string search1, std::string search2, const char* file, std::string firstline="", int line_offset=0);
std::map<std::string, std::string> m;
void initMap(std::map<std::string, std::string>& my);
};
#endif

View File

@@ -253,6 +253,11 @@ const char * CLocaleManager::getText(const neutrino_locale_t keyName) const
return localeData[keyName];
}
std::string CLocaleManager::getString(const neutrino_locale_t keyName) const
{
return (std::string) localeData[keyName];
}
static const neutrino_locale_t locale_weekday[7] =
{
LOCALE_DATE_SUN,

View File

@@ -69,6 +69,7 @@ class CLocaleManager
loadLocale_ret_t loadLocale(const char * const locale, bool asdefault = false);
const char * getText(const neutrino_locale_t keyName) const;
std::string getString(const neutrino_locale_t keyName) const;
std::string getTextAsString(const neutrino_locale_t keyName) const {return (static_cast<std::string>(getText(keyName)));}
static neutrino_locale_t getMonth (const struct tm * struct_tm_p);

View File

@@ -847,6 +847,24 @@ typedef enum
LOCALE_IMAGEINFO_LICENSE,
LOCALE_IMAGEINFO_VCS,
LOCALE_IMAGEINFO_VERSION,
LOCALE_IMDB_DATA_ACTORS,
LOCALE_IMDB_DATA_AWARDS,
LOCALE_IMDB_DATA_BOXOFFICE,
LOCALE_IMDB_DATA_DIRECTOR,
LOCALE_IMDB_DATA_FAILED,
LOCALE_IMDB_DATA_GENRE,
LOCALE_IMDB_DATA_METASCORE,
LOCALE_IMDB_DATA_PLOT,
LOCALE_IMDB_DATA_PRODUCTION,
LOCALE_IMDB_DATA_RATING_FAILED,
LOCALE_IMDB_DATA_RELEASED,
LOCALE_IMDB_DATA_RUNTIME,
LOCALE_IMDB_DATA_TITLE,
LOCALE_IMDB_DATA_VOTES,
LOCALE_IMDB_DATA_WEBSITE,
LOCALE_IMDB_DATA_WRITER,
LOCALE_IMDB_INFO,
LOCALE_IMDB_INFO_SAVE,
LOCALE_INETRADIO_NAME,
LOCALE_INFOVIEWER_EPGNOTLOAD,
LOCALE_INFOVIEWER_EPGWAIT,
@@ -1750,6 +1768,7 @@ typedef enum
LOCALE_MOVIEBROWSER_HINT_NEWBOOK_BACKWARD,
LOCALE_MOVIEBROWSER_HINT_NEWBOOK_FORWARD,
LOCALE_MOVIEBROWSER_HINT_TRUNCATE,
LOCALE_MOVIEBROWSER_IMDB_DATA,
LOCALE_MOVIEBROWSER_INFO_AUDIO,
LOCALE_MOVIEBROWSER_INFO_CHANNEL,
LOCALE_MOVIEBROWSER_INFO_FILE,
@@ -2458,6 +2477,7 @@ typedef enum
LOCALE_TIMING_VOLUMEBAR,
LOCALE_TMDB_API_KEY,
LOCALE_TMDB_ENABLED,
LOCALE_TMDB_INFO,
LOCALE_TMDB_READ_DATA,
LOCALE_TUNERSETUP_CABLE,
LOCALE_TUNERSETUP_HYBRID,

View File

@@ -847,6 +847,24 @@ const char * locale_real_names[] =
"imageinfo.license",
"imageinfo.vcs",
"imageinfo.version",
"imdb.data_actors",
"imdb.data_awards",
"imdb.data_boxoffice",
"imdb.data_director",
"imdb.data_failed",
"imdb.data_genre",
"imdb.data_metascore",
"imdb.data_plot",
"imdb.data_production",
"imdb.data_rating_failed",
"imdb.data_released",
"imdb.data_runtime",
"imdb.data_title",
"imdb.data_votes",
"imdb.data_website",
"imdb.data_writer",
"imdb.info",
"imdb.info_save",
"inetradio.name",
"infoviewer.epgnotload",
"infoviewer.epgwait",
@@ -1750,6 +1768,7 @@ const char * locale_real_names[] =
"moviebrowser.hint_newbook_backward",
"moviebrowser.hint_newbook_forward",
"moviebrowser.hint_truncate",
"moviebrowser.imdb_data",
"moviebrowser.info_audio",
"moviebrowser.info_channel",
"moviebrowser.info_file",
@@ -2458,6 +2477,7 @@ const char * locale_real_names[] =
"timing.volumebar",
"tmdb.api_key",
"tmdb.enabled",
"tmdb.info",
"tmdb.read_data",
"tunersetup.cable",
"tunersetup.hybrid",