#include #include #include #include #include #include #include "../services/scraper2vdr.h" #include "../services/weatherforecast.h" #include "../config.h" #include "../libcore/timers.h" #include "../libcore/helpers.h" #include "viewhelpers.h" cViewHelpers::cViewHelpers(void) { numDevices = 0; devicesInit = false; lSignalDisplay = 0; lSignalStrength = 0; lSignalQuality = 0; lastSecond = -1; lastMinute = -1; lastSystemLoad = 0.0; lastMemUsage = -1; lastEcmInfo.hops = -1; lastEcmInfo.ecmtime = -1; lastEcmInfo.caid = -1; lastEcmInfo.pid = -1; lastEcmInfo.prid = -1; } cViewHelpers::~cViewHelpers() { if (devicesInit) { delete[] lastSignalStrength; delete[] lastSignalQuality; delete[] recDevices; } } /****************************************************************** * Public Functions ******************************************************************/ bool cViewHelpers::SetDate(bool forced, stringmap &stringTokens, intmap &intTokens) { time_t t = time(0); // get time now struct tm * now = localtime(&t); int min = now->tm_min; if (!forced && min == lastMinute) { return false; } lastMinute = min; intTokens.insert(pair("year", now->tm_year + 1900)); intTokens.insert(pair("day", now->tm_mday)); char monthname[20]; char monthshort[10]; strftime(monthshort, sizeof(monthshort), "%b", now); strftime(monthname, sizeof(monthname), "%B", now); stringTokens.insert(pair("monthname", monthname)); stringTokens.insert(pair("monthnameshort", monthshort)); stringTokens.insert(pair("month", *cString::sprintf("%02d", now->tm_mon + 1))); stringTokens.insert(pair("dayleadingzero", *cString::sprintf("%02d", now->tm_mday))); stringTokens.insert(pair("dayname", *WeekDayNameFull(now->tm_wday))); stringTokens.insert(pair("daynameshort", *WeekDayName(now->tm_wday))); stringTokens.insert(pair("time", *TimeString(t))); return true; } bool cViewHelpers::SetTime(bool forced, stringmap &stringTokens, intmap &intTokens) { time_t t = time(0); // get time now struct tm * now = localtime(&t); int sec = now->tm_sec; if (!forced && sec == lastSecond) { return false; } int min = now->tm_min; int hour = now->tm_hour; int hourMinutes = hour%12 * 5 + min / 12; intTokens.insert(pair("sec", sec)); intTokens.insert(pair("min", min)); intTokens.insert(pair("hour", hour)); intTokens.insert(pair("hmins", hourMinutes)); lastSecond = sec; return true; } bool cViewHelpers::SetSignal(bool forced, stringmap &stringTokens, intmap &intTokens) { bool done = false; time_t Now = time(NULL); if (Now != lSignalDisplay) { int SignalStrength = cDevice::ActualDevice()->SignalStrength(); int SignalQuality = cDevice::ActualDevice()->SignalQuality(); if (SignalStrength < 0) SignalStrength = 0; if (SignalQuality < 0) SignalQuality = 0; if ((SignalStrength == 0)&&(SignalQuality==0)) return done; if ((lSignalStrength != SignalStrength) || (lSignalQuality != SignalQuality)) { intTokens.insert(pair("signalstrength", SignalStrength)); intTokens.insert(pair("signalquality", SignalQuality)); lSignalStrength = SignalStrength; lSignalQuality = SignalQuality; done = true; } lSignalDisplay = Now; } return done; } bool cViewHelpers::SetCurrentWeatherTokens(bool forced, stringmap &stringTokens, intmap &intTokens) { static cPlugin *pWeatherForecast = cPluginManager::GetPlugin("weatherforecast"); if (!pWeatherForecast) return false; cServiceCurrentWeather currentWeather; if (!pWeatherForecast->Service("GetCurrentWeather", ¤tWeather)) { return false; } stringTokens.insert(pair("timestamp", currentWeather.timeStamp)); stringTokens.insert(pair("temperature", currentWeather.temperature)); stringTokens.insert(pair("apparenttemperature", currentWeather.apparentTemperature)); stringTokens.insert(pair("mintemperature", currentWeather.minTemperature)); stringTokens.insert(pair("maxtemperature", currentWeather.maxTemperature)); stringTokens.insert(pair("summary", currentWeather.summary)); stringTokens.insert(pair("icon", currentWeather.icon)); stringTokens.insert(pair("precipitationintensity", currentWeather.precipitationIntensity)); intTokens.insert(pair("precipitationprobability", currentWeather.precipitationProbability)); stringTokens.insert(pair("precipitationtype", currentWeather.precipitationType)); intTokens.insert(pair("humidity", currentWeather.humidity)); stringTokens.insert(pair("windspeed", currentWeather.windSpeed)); intTokens.insert(pair("windbearing", currentWeather.windBearing)); stringTokens.insert(pair("windbearingstring", currentWeather.windBearingString)); stringTokens.insert(pair("visibility", currentWeather.visibility)); intTokens.insert(pair("cloudcover", currentWeather.cloudCover)); stringTokens.insert(pair("pressure", currentWeather.pressure)); stringTokens.insert(pair("ozone", currentWeather.ozone)); return true; } bool cViewHelpers::SetDiscUsage(bool forced, stringmap &stringTokens, intmap &intTokens) { string vdrUsageString = *cVideoDiskUsage::String(); int discUsage = cVideoDiskUsage::UsedPercent(); bool discAlert = (discUsage > 95) ? true : false; string freeTime = *cString::sprintf("%02d:%02d", cVideoDiskUsage::FreeMinutes() / 60, cVideoDiskUsage::FreeMinutes() % 60); int freeGB = cVideoDiskUsage::FreeMB() / 1024; intTokens.insert(pair("usedpercent", discUsage)); intTokens.insert(pair("freepercent", 100-discUsage)); intTokens.insert(pair("discalert", discAlert)); intTokens.insert(pair("freegb", freeGB)); stringTokens.insert(pair("freetime", freeTime)); stringTokens.insert(pair("vdrusagestring", vdrUsageString)); return true; } bool cViewHelpers::SetSystemLoad(bool forced, stringmap &stringTokens, intmap &intTokens) { double systemLoad; if (getloadavg(&systemLoad, 1) > 0) { if (lastSystemLoad == systemLoad) { return false; } string load = *cString::sprintf("%.2f", systemLoad); int loadHand = systemLoad * 1000; int loadHandValue = 0; if (loadHand > 2500) loadHandValue = 2525; else { int loadHandDec = loadHand - (loadHand / 100) * 100; if (loadHandDec <= 12) loadHandDec = 0; else if (loadHandDec <= 37) loadHandDec = 25; else if (loadHandDec <= 62) loadHandDec = 50; else if (loadHandDec <= 87) loadHandDec = 75; else loadHandDec = 0; loadHandValue = loadHand / 100 * 100 + loadHandDec; } stringTokens.insert(pair("load", load)); intTokens.insert(pair("loadhand", loadHandValue)); lastSystemLoad = systemLoad; } else { return false; } return true; } bool cViewHelpers::SetSystemMemory(bool forced, stringmap &stringTokens, intmap &intTokens) { struct sysinfo memInfo; sysinfo (&memInfo); long long totalMem = memInfo.totalram; totalMem += memInfo.totalswap; totalMem *= memInfo.mem_unit; int totalMemMB = totalMem / 1024 / 1024; long long usedMem = memInfo.totalram - memInfo.freeram; usedMem += memInfo.totalswap - memInfo.freeswap; usedMem *= memInfo.mem_unit; int usedMemMB = usedMem / 1024 / 1024; if (lastMemUsage == usedMemMB) { return false; } lastMemUsage = usedMemMB; intTokens.insert(pair("totalmem", totalMemMB)); intTokens.insert(pair("usedmem", usedMemMB)); if (totalMemMB > 0) intTokens.insert(pair("usedmempercent", usedMemMB * 100 / totalMemMB)); return true; } bool cViewHelpers::SetSystemTemperatures(bool forced, stringmap &stringTokens, intmap &intTokens) { cString execCommand = cString::sprintf("cd \"%s/\"; \"%s/temperatures\"", SCRIPTFOLDER, SCRIPTFOLDER); system(*execCommand); string tempCPU, tempGPU; int cpu, gpu; cString itemFilename = cString::sprintf("%s/cpu", SCRIPTOUTPUTPATH ); ifstream file(*itemFilename, ifstream::in); if( file.is_open() ) { std::getline(file, tempCPU); if (tempCPU.size() > 2) { cpu = atoi(tempCPU.substr(0,2).c_str()); } else cpu = 0; file.close(); } else { tempCPU = "0°C"; cpu = 0; } itemFilename = cString::sprintf("%s/gpu", SCRIPTOUTPUTPATH ); ifstream file2(*itemFilename, ifstream::in); if( file2.is_open() ) { std::getline(file2, tempGPU); if (tempGPU.size() > 2) { gpu = atoi(tempGPU.substr(0,2).c_str()); } else gpu = 0; file2.close(); } else { tempGPU = "0°C"; gpu = 0; } intTokens.insert(pair("cputemp", cpu)); intTokens.insert(pair("gputemp", gpu)); return true; } bool cViewHelpers::SetDummy(bool forced, stringmap &stringTokens, intmap &intTokens) { return true; } /****************************************************************** * Protected Functions ******************************************************************/ void cViewHelpers::InitDevices(void) { numDevices = cDevice::NumDevices(); lastSignalStrength = new int[numDevices]; lastSignalQuality = new int[numDevices]; recDevices = new bool[numDevices]; for (int i=0; i *devices) { if (!initial) { if (light) return false; //check if drawing is necessary bool changed = false; for (int i = 0; i < numDevices; i++) { const cDevice *device = cDevice::GetDevice(i); if (!device || !device->NumProvidedSystems()) { continue; } int signalStrength = device->SignalStrength(); int signalQuality = device->SignalQuality(); if ((signalStrength != lastSignalStrength[i]) || (signalQuality != lastSignalQuality[i])) { changed = true; break; } } if (!changed) { return false; } } //check device which currently displays live tv int deviceLiveTV = -1; cDevice *primaryDevice = cDevice::PrimaryDevice(); if (primaryDevice) { if (!primaryDevice->Replaying() || primaryDevice->Transferring()) deviceLiveTV = cDevice::ActualDevice()->DeviceNumber(); else deviceLiveTV = primaryDevice->DeviceNumber(); } //check currently recording devices for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) { if (!timer->Recording()) { continue; } if (cRecordControl *RecordControl = cRecordControls::GetRecordControl(timer)) { const cDevice *recDevice = RecordControl->Device(); if (recDevice) { recDevices[recDevice->DeviceNumber()] = true; } } } int actualNumDevices = 0; for (int i = 0; i < numDevices; i++) { const cDevice *device = cDevice::GetDevice(i); if (!device || !device->NumProvidedSystems()) { continue; } stringmap deviceVals; stringstream strNum; strNum << actualNumDevices; actualNumDevices++; deviceVals.insert(pair< string, string >("devices[num]", strNum.str())); deviceVals.insert(pair< string, string >("devices[type]", *(device->DeviceType()))); cCamSlot *camSlot = device->CamSlot(); int camNumber = -1; if (camSlot) { camNumber = camSlot->SlotNumber(); deviceVals.insert(pair< string, string >("devices[hascam]", "1")); } else { deviceVals.insert(pair< string, string >("devices[hascam]", "0")); } stringstream strCamNumber; strCamNumber << camNumber; deviceVals.insert(pair< string, string >("devices[cam]", strCamNumber.str())); int signalStrength = 0; int signalQuality = 0; if (!light) { signalStrength = device->SignalStrength(); signalQuality = device->SignalQuality(); } stringstream strStrength; strStrength << signalStrength; deviceVals.insert(pair< string, string >("devices[signalstrength]", strStrength.str())); stringstream strQuality; strQuality << signalQuality; deviceVals.insert(pair< string, string >("devices[signalquality]", strQuality.str())); deviceVals.insert(pair< string, string >("devices[livetv]", i == deviceLiveTV ? "1" : "0")); deviceVals.insert(pair< string, string >("devices[recording]", recDevices[i] ? "1" : "0")); const cChannel *channel = device->GetCurrentlyTunedTransponder(); const cSource *source = (channel) ? Sources.Get(channel->Source()) : NULL; if (channel && channel->Number() > 0) { stringstream strChanNum; strChanNum << channel->Number(); deviceVals.insert(pair< string, string >("devices[channelnumber]", strChanNum.str())); deviceVals.insert(pair< string, string >("devices[channelname]", channel->Name())); string channelID = *(channel->GetChannelID().ToString()); deviceVals.insert(pair< string, string >("devices[channelid]", channelID)); deviceVals.insert(pair< string, string >("devices[channellogoexists]", imgCache->LogoExists(channelID) ? "1" : "0")); deviceVals.insert(pair< string, string >("devices[istuned]", "1")); } else { deviceVals.insert(pair< string, string >("devices[channelnumber]", "0")); deviceVals.insert(pair< string, string >("devices[channelname]", "")); deviceVals.insert(pair< string, string >("devices[channelid]", "")); deviceVals.insert(pair< string, string >("devices[channellogoexists]", "0")); deviceVals.insert(pair< string, string >("devices[istuned]", "0")); } deviceVals.insert(pair< string, string >("devices[source]", source ? source->Description() : "")); devices->push_back(deviceVals); lastSignalStrength[i] = signalStrength; lastSignalQuality[i] = signalQuality; } intTokens->insert(pair("numdevices", actualNumDevices)); return true; } bool cViewHelpers::CheckNewMails(void) { static cPlugin *pMailbox = cPluginManager::GetPlugin("mailbox"); if (!pMailbox) { return false; } bool newMail = false; if (pMailbox->Service("MailBox-HasNewMail-1.0", &newMail)) { return newMail; } return false; } void cViewHelpers::SetScraperTokens(const cEvent *event, const cRecording *recording, stringmap &stringTokens, intmap &intTokens, map < string, vector > &loopTokens) { static cPlugin *pScraper = GetScraperPlugin(); if (!pScraper || (!event && !recording)) { intTokens.insert(pair("ismovie", false)); intTokens.insert(pair("isseries", false)); return; } ScraperGetEventType getType; getType.event = event; getType.recording = recording; if (!pScraper->Service("GetEventType", &getType)) { intTokens.insert(pair("ismovie", false)); intTokens.insert(pair("isseries", false)); return; } if (getType.type == tMovie) { cMovie movie; movie.movieId = getType.movieId; pScraper->Service("GetMovie", &movie); intTokens.insert(pair("ismovie", true)); intTokens.insert(pair("isseries", false)); stringTokens.insert(pair("movietitle", movie.title)); stringTokens.insert(pair("movieoriginalTitle", movie.originalTitle)); stringTokens.insert(pair("movietagline", movie.tagline)); stringTokens.insert(pair("movieoverview", movie.overview)); stringTokens.insert(pair("moviegenres", movie.genres)); stringTokens.insert(pair("moviehomepage", movie.homepage)); stringTokens.insert(pair("moviereleasedate", movie.releaseDate)); stringstream pop; pop << movie.popularity; stringTokens.insert(pair("moviepopularity", pop.str())); stringstream vote; vote << movie.voteAverage; stringTokens.insert(pair("movievoteaverage", pop.str())); stringTokens.insert(pair("posterpath", movie.poster.path)); stringTokens.insert(pair("fanartpath", movie.fanart.path)); stringTokens.insert(pair("collectionposterpath", movie.collectionPoster.path)); stringTokens.insert(pair("collectionfanartpath", movie.collectionFanart.path)); intTokens.insert(pair("movieadult", movie.adult)); intTokens.insert(pair("moviebudget", movie.budget)); intTokens.insert(pair("movierevenue", movie.revenue)); intTokens.insert(pair("movieruntime", movie.runtime)); intTokens.insert(pair("posterwidth", movie.poster.width)); intTokens.insert(pair("posterheight", movie.poster.height)); intTokens.insert(pair("fanartwidth", movie.fanart.width)); intTokens.insert(pair("fanartheight", movie.fanart.height)); intTokens.insert(pair("collectionposterwidth", movie.collectionPoster.width)); intTokens.insert(pair("collectionposterheight", movie.collectionPoster.height)); intTokens.insert(pair("collectionfanartwidth", movie.collectionFanart.width)); intTokens.insert(pair("collectionfanartheight", movie.collectionFanart.height)); vector< map< string, string > > actors; for (vector::iterator act = movie.actors.begin(); act != movie.actors.end(); act++) { map< string, string > actor; actor.insert(pair("actors[name]", (*act).name)); actor.insert(pair("actors[role]", (*act).role)); actor.insert(pair("actors[thumb]", (*act).actorThumb.path)); stringstream actWidth, actHeight; actWidth << (*act).actorThumb.width; actHeight << (*act).actorThumb.height; actor.insert(pair("actors[thumbwidth]", actWidth.str())); actor.insert(pair("actors[thumbheight]", actHeight.str())); actors.push_back(actor); } loopTokens.insert(pair > >("actors", actors)); } else if (getType.type == tSeries) { cSeries series; series.seriesId = getType.seriesId; series.episodeId = getType.episodeId; pScraper->Service("GetSeries", &series); intTokens.insert(pair("ismovie", false)); intTokens.insert(pair("isseries", true)); //Series Basics stringTokens.insert(pair("seriesname", series.name)); stringTokens.insert(pair("seriesoverview", series.overview)); stringTokens.insert(pair("seriesfirstaired", series.firstAired)); stringTokens.insert(pair("seriesnetwork", series.network)); stringTokens.insert(pair("seriesgenre", series.genre)); stringstream rating; rating << series.rating; stringTokens.insert(pair("seriesrating", rating.str())); stringTokens.insert(pair("seriesstatus", series.status)); //Episode Information intTokens.insert(pair("episodenumber", series.episode.number)); intTokens.insert(pair("episodeseason", series.episode.season)); stringTokens.insert(pair("episodetitle", series.episode.name)); stringTokens.insert(pair("episodefirstaired", series.episode.firstAired)); stringTokens.insert(pair("episodegueststars", series.episode.guestStars)); stringTokens.insert(pair("episodeoverview", series.episode.overview)); stringstream eprating; eprating << series.episode.rating; stringTokens.insert(pair("episoderating", eprating.str())); intTokens.insert(pair("episodeimagewidth", series.episode.episodeImage.width)); intTokens.insert(pair("episodeimageheight", series.episode.episodeImage.height)); stringTokens.insert(pair("episodeimagepath", series.episode.episodeImage.path)); //Seasonposter intTokens.insert(pair("seasonposterwidth", series.seasonPoster.width)); intTokens.insert(pair("seasonposterheight", series.seasonPoster.height)); stringTokens.insert(pair("seasonposterpath", series.seasonPoster.path)); //Posters int current = 1; for(vector::iterator poster = series.posters.begin(); poster != series.posters.end(); poster++) { stringstream labelWidth, labelHeight, labelPath; labelWidth << "seriesposter" << current << "width"; labelHeight << "seriesposter" << current << "height"; labelPath << "seriesposter" << current << "path"; intTokens.insert(pair(labelWidth.str(), (*poster).width)); intTokens.insert(pair(labelHeight.str(), (*poster).height)); stringTokens.insert(pair(labelPath.str(), (*poster).path)); current++; } if (current < 3) { for (; current < 4; current++) { stringstream labelWidth, labelHeight, labelPath; labelWidth << "seriesposter" << current << "width"; labelHeight << "seriesposter" << current << "height"; labelPath << "seriesposter" << current << "path"; intTokens.insert(pair(labelWidth.str(), 0)); intTokens.insert(pair(labelHeight.str(), 0)); stringTokens.insert(pair(labelPath.str(), "")); } } //Banners current = 1; for(vector::iterator banner = series.banners.begin(); banner != series.banners.end(); banner++) { stringstream labelWidth, labelHeight, labelPath; labelWidth << "seriesbanner" << current << "width"; labelHeight << "seriesbanner" << current << "height"; labelPath << "seriesbanner" << current << "path"; intTokens.insert(pair(labelWidth.str(), (*banner).width)); intTokens.insert(pair(labelHeight.str(), (*banner).height)); stringTokens.insert(pair(labelPath.str(), (*banner).path)); current++; } if (current < 3) { for (; current < 4; current++) { stringstream labelWidth, labelHeight, labelPath; labelWidth << "seriesbanner" << current << "width"; labelHeight << "seriesbanner" << current << "height"; labelPath << "seriesbanner" << current << "path"; intTokens.insert(pair(labelWidth.str(), 0)); intTokens.insert(pair(labelHeight.str(), 0)); stringTokens.insert(pair(labelPath.str(), "")); } } //Fanarts current = 1; for(vector::iterator fanart = series.fanarts.begin(); fanart != series.fanarts.end(); fanart++) { stringstream labelWidth, labelHeight, labelPath; labelWidth << "seriesfanart" << current << "width"; labelHeight << "seriesfanart" << current << "height"; labelPath << "seriesfanart" << current << "path"; intTokens.insert(pair(labelWidth.str(), (*fanart).width)); intTokens.insert(pair(labelHeight.str(), (*fanart).height)); stringTokens.insert(pair(labelPath.str(), (*fanart).path)); current++; } if (current < 3) { for (; current < 4; current++) { stringstream labelWidth, labelHeight, labelPath; labelWidth << "seriesfanart" << current << "width"; labelHeight << "seriesfanart" << current << "height"; labelPath << "seriesfanart" << current << "path"; intTokens.insert(pair(labelWidth.str(), 0)); intTokens.insert(pair(labelHeight.str(), 0)); stringTokens.insert(pair(labelPath.str(), "")); } } //Actors vector< map< string, string > > actors; for (vector::iterator act = series.actors.begin(); act != series.actors.end(); act++) { map< string, string > actor; actor.insert(pair("actors[name]", (*act).name)); actor.insert(pair("actors[role]", (*act).role)); actor.insert(pair("actors[thumb]", (*act).actorThumb.path)); stringstream actWidth, actHeight; actWidth << (*act).actorThumb.width; actHeight << (*act).actorThumb.height; actor.insert(pair("actors[thumbwidth]", actWidth.str())); actor.insert(pair("actors[thumbheight]", actHeight.str())); actors.push_back(actor); } loopTokens.insert(pair > >("actors", actors)); } else { intTokens.insert(pair("ismovie", false)); intTokens.insert(pair("isseries", false)); } } void cViewHelpers::SetPosterBanner(const cEvent *event, stringmap &stringTokens, intmap &intTokens) { static cPlugin *pScraper = GetScraperPlugin(); if (!pScraper) { return; } ScraperGetPosterBanner call; call.event = event; if (pScraper->Service("GetPosterBanner", &call)) { int mediaWidth = 0; int mediaHeight = 0; string mediaPath = ""; bool isBanner = false; int posterWidth = 0; int posterHeight = 0; string posterPath = ""; bool hasPoster = false; int bannerWidth = 0; int bannerHeight = 0; string bannerPath = ""; bool hasBanner = false; if ((call.type == tSeries) && call.banner.path.size() > 0) { mediaWidth = call.banner.width; mediaHeight = call.banner.height; mediaPath = call.banner.path; isBanner = true; bannerWidth = mediaWidth; bannerHeight = mediaHeight; bannerPath = mediaPath; hasBanner = true; ScraperGetPoster callPoster; callPoster.event = event; callPoster.recording = NULL; if (pScraper->Service("GetPoster", &callPoster)) { posterWidth = callPoster.poster.width; posterHeight = callPoster.poster.height; posterPath = callPoster.poster.path; hasPoster = true; } } else if (call.type == tMovie && call.poster.path.size() > 0 && call.poster.height > 0) { mediaWidth = call.poster.width; mediaHeight = call.poster.height; mediaPath = call.poster.path; posterWidth = call.poster.width; posterHeight = call.poster.height; posterPath = call.poster.path; hasPoster = true; } else return; intTokens.insert(pair("mediawidth", mediaWidth)); intTokens.insert(pair("mediaheight", mediaHeight)); intTokens.insert(pair("isbanner", isBanner)); stringTokens.insert(pair("mediapath", mediaPath)); intTokens.insert(pair("posterwidth", posterWidth)); intTokens.insert(pair("posterheight", posterHeight)); stringTokens.insert(pair("posterpath", posterPath)); intTokens.insert(pair("hasposter", hasPoster)); intTokens.insert(pair("bannerwidth", bannerWidth)); intTokens.insert(pair("bannerheight", bannerHeight)); stringTokens.insert(pair("bannerpath", bannerPath)); intTokens.insert(pair("hasbanner", hasBanner)); } } void cViewHelpers::SetTimers(map *intTokens, map *stringTokens, vector > *timers) { cGlobalSortedTimers SortedTimers;// local and remote timers int numTimers = SortedTimers.Size(); intTokens->insert(pair("numtimers", numTimers)); int numTimerConflicts = SortedTimers.NumTimerConfilicts(); intTokens->insert(pair("numtimerconflicts", numTimerConflicts)); for (int i=0; i<15; i++) { stringstream name; name << "timer" << i+1 << "exists"; if (i < numTimers) { intTokens->insert(pair(name.str(), true)); } else { intTokens->insert(pair(name.str(), false)); } } for (int i = 0; i < numTimers; i++) { if (i >=15) break; map< string, string > timerVals; const cTimer *Timer = SortedTimers[i]; string isRemoteTimer = SortedTimers.IsRemoteTimer(i) ? "1" : "0"; const cEvent *event = Timer->Event(); if (event) { timerVals.insert(pair< string, string >("timers[title]", event->Title())); } else { const char *File = Setup.FoldersInTimerMenu ? NULL : strrchr(Timer->File(), FOLDERDELIMCHAR); if (File && strcmp(File + 1, TIMERMACRO_TITLE) && strcmp(File + 1, TIMERMACRO_EPISODE)) File++; else File = Timer->File(); timerVals.insert(pair< string, string >("timers[title]", File)); } const cChannel *channel = Timer->Channel(); if (channel) { timerVals.insert(pair< string, string >("timers[channelname]", channel->Name())); stringstream chanNum; chanNum << channel->Number(); timerVals.insert(pair< string, string >("timers[channelnumber]", chanNum.str())); string channelID = *(channel->GetChannelID().ToString()); timerVals.insert(pair< string, string >("timers[channelid]", channelID)); bool logoExists = imgCache->LogoExists(channelID); timerVals.insert(pair< string, string >("timers[channellogoexists]", logoExists ? "1" : "0")); } else { timerVals.insert(pair< string, string >("timers[channelname]", "")); timerVals.insert(pair< string, string >("timers[channelnumber]", "0")); timerVals.insert(pair< string, string >("timers[channelid]", "")); timerVals.insert(pair< string, string >("timers[channellogoexists]", "0")); } timerVals.insert(pair< string, string >("timers[recording]", Timer->Recording() ? "1" : "0")); cString timerDate(""); if (Timer->Recording()) { timerDate = cString::sprintf("-%s", *TimeString(Timer->StopTime())); } else { time_t Now = time(NULL); cString Today = WeekDayName(Now); cString Time = TimeString(Timer->StartTime()); cString Day = WeekDayName(Timer->StartTime()); if (Timer->StartTime() > Now + 6 * SECSINDAY) { time_t ttm = Timer->StartTime(); struct tm * timerTime = localtime(&ttm); timerDate = cString::sprintf("%02d.%02d %s", timerTime->tm_mday, timerTime->tm_mon + 1, *Time); } else if (strcmp(Day, Today) != 0) timerDate = cString::sprintf("%s %s", *Day, *Time); else timerDate = Time; if (Timer->Flags() & tfVps) timerDate = cString::sprintf("VPS %s", *timerDate); } timerVals.insert(pair< string, string >("timers[datetime]", *timerDate)); timerVals.insert(pair< string, string >("timers[isremotetimer]", isRemoteTimer)); timers->push_back(timerVals); } } void cViewHelpers::SetLastRecordings(map *intTokens, map *stringTokens, vector *lastRecordings) { list orderedRecs; for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { if (orderedRecs.size() == 0) { orderedRecs.push_back(recording); continue; } bool inserted = false; for (list::iterator it = orderedRecs.begin(); it != orderedRecs.end(); it++) { const cRecording *orderedRec = *it; if (recording->Start() >= orderedRec->Start()) { orderedRecs.insert(it, recording); inserted = true; break; } } if (!inserted) { orderedRecs.push_back(recording); } } int found = 0; for (list::iterator it = orderedRecs.begin(); it != orderedRecs.end(); it++) { const cRecording *recording = *it; #if APIVERSNUM >= 20101 if (recording->IsInUse()) { continue; } #endif map< string, string > recVals; string recFullPath = recording->Name() ? recording->Name() : ""; string recName = ""; string recPath = ""; RecName(recFullPath, recName, recPath); stringstream recDuration; int dur = recording->LengthInSeconds()/60; recDuration << dur; string posterPath = ""; int posterWidth = 0; int posterHeight = 0; bool hasPoster = false; RecPoster(recording, posterWidth, posterHeight, posterPath, hasPoster); stringstream sPosterWidth; sPosterWidth << posterWidth; stringstream sPosterHeight; sPosterHeight << posterHeight; string sHasPoster = hasPoster ? "1" : "0"; recVals.insert(pair< string, string >("recordings[name]", recName)); recVals.insert(pair< string, string >("recordings[seriesname]", recPath)); recVals.insert(pair< string, string >("recordings[date]", *ShortDateString(recording->Start()))); recVals.insert(pair< string, string >("recordings[time]", *TimeString(recording->Start()))); recVals.insert(pair< string, string >("recordings[duration]", recDuration.str())); recVals.insert(pair< string, string >("recordings[hasposter]", sHasPoster)); recVals.insert(pair< string, string >("recordings[posterpath]", posterPath)); recVals.insert(pair< string, string >("recordings[posterwidth]", sPosterWidth.str())); recVals.insert(pair< string, string >("recordings[posterheight]", sPosterHeight.str())); lastRecordings->push_back(recVals); found++; if (found == 5) break; } } void cViewHelpers::SetMenuHeader(eMenuCategory cat, string menuTitle, stringmap &stringTokens, intmap &intTokens) { stringTokens.insert(pair("title", menuTitle)); stringTokens.insert(pair("vdrversion", VDRVERSION)); //check for standard menu entries bool hasIcon = false; string icon = imgCache->GetIconName(menuTitle, cat); if (imgCache->MenuIconExists(icon)) hasIcon = true; stringTokens.insert(pair("icon", icon)); intTokens.insert(pair("hasicon", hasIcon)); //Disc Usage string vdrUsageString = *cVideoDiskUsage::String(); int discUsage = cVideoDiskUsage::UsedPercent(); bool discAlert = (discUsage > 95) ? true : false; string freeTime = *cString::sprintf("%02d:%02d", cVideoDiskUsage::FreeMinutes() / 60, cVideoDiskUsage::FreeMinutes() % 60); int freeGB = cVideoDiskUsage::FreeMB() / 1024; intTokens.insert(pair("usedpercent", discUsage)); intTokens.insert(pair("freepercent", 100-discUsage)); intTokens.insert(pair("discalert", discAlert)); intTokens.insert(pair("freegb", freeGB)); stringTokens.insert(pair("freetime", freeTime)); stringTokens.insert(pair("vdrusagestring", vdrUsageString)); } void cViewHelpers::SetCurrentSchedule(string recName, stringmap &stringTokens, intmap &intTokens) { cDevice *device = cDevice::PrimaryDevice(); const cChannel *channel = NULL; if (!device->Replaying() || device->Transferring()) { channel = Channels.GetByNumber(device->CurrentChannel()); } if (channel) { SetCurrentScheduleFromChannel(channel, stringTokens, intTokens); } else { if (recName.size() == 0) return; const cRecording *recording = new cRecording(recName.c_str()); if (recording) { SetCurrentScheduleFromRecording(recording, stringTokens, intTokens); delete recording; } } } bool cViewHelpers::SetEcmInfos(int channelSid, stringmap &stringTokens, intmap &intTokens) { static cPlugin *pDVBApi = cPluginManager::GetPlugin("dvbapi"); if (!pDVBApi) return false; sDVBAPIEcmInfo ecmInfo; ecmInfo.sid = channelSid; if (!pDVBApi->Service("GetEcmInfo", &ecmInfo)) { return false; } if (ecmInfo.hops < 0 || ecmInfo.ecmtime <= 0) return false; if (CompareECMInfos(&ecmInfo)) return false; lastEcmInfo = ecmInfo; intTokens.insert(pair("caid", ecmInfo.caid)); intTokens.insert(pair("pid", ecmInfo.pid)); intTokens.insert(pair("prid", ecmInfo.prid)); intTokens.insert(pair("ecmtime", ecmInfo.ecmtime)); intTokens.insert(pair("hops", ecmInfo.hops)); stringTokens.insert(pair("cardsystem", *ecmInfo.cardsystem ? *ecmInfo.cardsystem : "")); stringTokens.insert(pair("reader", *ecmInfo.reader ? *ecmInfo.reader : "")); stringTokens.insert(pair("from", *ecmInfo.from ? *ecmInfo.from : "")); stringTokens.insert(pair("protocol", *ecmInfo.protocol ? *ecmInfo.protocol : "")); return true; } /******************************************************************************** * Private Functions ********************************************************************************/ void cViewHelpers::RecName(string &path, string &name, string &folder) { size_t delim = path.find_last_of('~'); if (delim == string::npos) { name = path; if (name.find('%') == 0) { name = name.substr(1); } return; } name = path.substr(delim+1); if (name.find('%') == 0) { name = name.substr(1); } folder = path.substr(0, delim); size_t delim2 = folder.find_last_of('~'); if (delim2 == string::npos) { return; } folder = folder.substr(delim2+1); } void cViewHelpers::RecPoster(const cRecording *rec, int &posterWidth, int &posterHeight, string &path, bool &hasPoster) { static cPlugin *pScraper = GetScraperPlugin(); if (!pScraper) return; ScraperGetPoster callPoster; callPoster.event = NULL; callPoster.recording = rec; if (pScraper->Service("GetPoster", &callPoster)) { posterWidth = callPoster.poster.width; posterHeight = callPoster.poster.height; path = callPoster.poster.path; hasPoster = true; } } void cViewHelpers::SetCurrentScheduleFromChannel(const cChannel *channel, stringmap &stringTokens, intmap &intTokens) { const cEvent *event = NULL; cSchedulesLock SchedulesLock; if (const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock)) if (const cSchedule *Schedule = Schedules->GetSchedule(channel)) event = Schedule->GetPresentEvent(); if (!event) return; intTokens.insert(pair("islivetv", 1)); stringTokens.insert(pair("title", (event->Title())?event->Title():"")); stringTokens.insert(pair("subtitle", (event->ShortText())?event->ShortText():"")); stringTokens.insert(pair("start", *event->GetTimeString())); stringTokens.insert(pair("stop", *event->GetEndTimeString())); intTokens.insert(pair("duration", event->Duration() / 60)); intTokens.insert(pair("durationhours", event->Duration() / 3600)); stringTokens.insert(pair("durationminutes", *cString::sprintf("%.2d", (event->Duration() / 60)%60))); intTokens.insert(pair("elapsed", (int)round((time(NULL) - event->StartTime())/60))); intTokens.insert(pair("remaining", (int)round((event->EndTime() - time(NULL))/60))); int mediaWidth = 0; int mediaHeight = 0; string mediaPath = ""; bool isBanner = false; int posterWidth = 0; int posterHeight = 0; string posterPath = ""; bool hasPoster = false; int bannerWidth = 0; int bannerHeight = 0; string bannerPath = ""; bool hasBanner = false; static cPlugin *pScraper = GetScraperPlugin(); if (pScraper) { ScraperGetPosterBanner call; call.event = event; if (pScraper->Service("GetPosterBanner", &call)) { if ((call.type == tSeries) && call.banner.path.size() > 0) { mediaWidth = call.banner.width; mediaHeight = call.banner.height; mediaPath = call.banner.path; isBanner = true; bannerWidth = mediaWidth; bannerHeight = mediaHeight; bannerPath = mediaPath; hasBanner = true; ScraperGetPoster callPoster; callPoster.event = event; callPoster.recording = NULL; if (pScraper->Service("GetPoster", &callPoster)) { posterWidth = callPoster.poster.width; posterHeight = callPoster.poster.height; posterPath = callPoster.poster.path; hasPoster = true; } } else if (call.type == tMovie && call.poster.path.size() > 0 && call.poster.height > 0) { mediaWidth = call.poster.width; mediaHeight = call.poster.height; mediaPath = call.poster.path; posterWidth = call.poster.width; posterHeight = call.poster.height; posterPath = call.poster.path; hasPoster = true; } } } intTokens.insert(pair("mediawidth", mediaWidth)); intTokens.insert(pair("mediaheight", mediaHeight)); intTokens.insert(pair("isbanner", isBanner)); stringTokens.insert(pair("mediapath", mediaPath)); intTokens.insert(pair("posterwidth", posterWidth)); intTokens.insert(pair("posterheight", posterHeight)); stringTokens.insert(pair("posterpath", posterPath)); intTokens.insert(pair("hasposter", hasPoster)); intTokens.insert(pair("bannerwidth", bannerWidth)); intTokens.insert(pair("bannerheight", bannerHeight)); stringTokens.insert(pair("bannerpath", bannerPath)); intTokens.insert(pair("hasbanner", hasBanner)); } void cViewHelpers::SetCurrentScheduleFromRecording(const cRecording *recording, stringmap &stringTokens, intmap &intTokens) { intTokens.insert(pair("islivetv", 0)); string recFullName = recording->Name() ? recording->Name() : ""; string recName = ""; string recFolder = ""; RecName(recFullName, recName, recFolder); stringTokens.insert(pair("title", recName)); const cRecordingInfo *info = recording->Info(); if (info) { stringTokens.insert(pair("subtitle", info->ShortText() ? info->ShortText() : "")); } else { stringTokens.insert(pair("subtitle", recFolder)); } stringTokens.insert(pair("start", "")); stringTokens.insert(pair("stop", "")); intTokens.insert(pair("duration", recording->LengthInSeconds() / 60)); intTokens.insert(pair("durationhours", recording->LengthInSeconds() / 3600)); stringTokens.insert(pair("durationminutes", *cString::sprintf("%.2d", (recording->LengthInSeconds() / 60)%60))); intTokens.insert(pair("elapsed", 0)); intTokens.insert(pair("remaining", 0)); int mediaWidth = 0; int mediaHeight = 0; string mediaPath = ""; bool isBanner = false; int posterWidth = 0; int posterHeight = 0; string posterPath = ""; bool hasPoster = false; int bannerWidth = 0; int bannerHeight = 0; string bannerPath = ""; bool hasBanner = false; static cPlugin *pScraper = GetScraperPlugin(); if (pScraper) { ScraperGetPosterBannerV2 call; call.event = NULL; call.recording = recording; if (pScraper->Service("GetPosterBannerV2", &call)) { if ((call.type == tSeries) && call.banner.path.size() > 0) { mediaWidth = call.banner.width; mediaHeight = call.banner.height; mediaPath = call.banner.path; isBanner = true; bannerWidth = mediaWidth; bannerHeight = mediaHeight; bannerPath = mediaPath; hasBanner = true; ScraperGetPoster callPoster; callPoster.event = NULL; callPoster.recording = recording; if (pScraper->Service("GetPoster", &callPoster)) { posterWidth = callPoster.poster.width; posterHeight = callPoster.poster.height; posterPath = callPoster.poster.path; hasPoster = true; } } else if (call.type == tMovie && call.poster.path.size() > 0 && call.poster.height > 0) { mediaWidth = call.poster.width; mediaHeight = call.poster.height; mediaPath = call.poster.path; posterWidth = call.poster.width; posterHeight = call.poster.height; posterPath = call.poster.path; hasPoster = true; } } } intTokens.insert(pair("mediawidth", mediaWidth)); intTokens.insert(pair("mediaheight", mediaHeight)); intTokens.insert(pair("isbanner", isBanner)); stringTokens.insert(pair("mediapath", mediaPath)); intTokens.insert(pair("posterwidth", posterWidth)); intTokens.insert(pair("posterheight", posterHeight)); stringTokens.insert(pair("posterpath", posterPath)); intTokens.insert(pair("hasposter", hasPoster)); intTokens.insert(pair("bannerwidth", bannerWidth)); intTokens.insert(pair("bannerheight", bannerHeight)); stringTokens.insert(pair("bannerpath", bannerPath)); intTokens.insert(pair("hasbanner", hasBanner)); } bool cViewHelpers::CompareECMInfos(sDVBAPIEcmInfo *ecmInfo) { if (ecmInfo->caid != lastEcmInfo.caid) return false; if (ecmInfo->pid != lastEcmInfo.pid) return false; if (ecmInfo->prid != lastEcmInfo.prid) return false; if (ecmInfo->ecmtime != lastEcmInfo.ecmtime) return false; if (ecmInfo->hops != lastEcmInfo.hops) return false; return true; }