From bb39010021b5fd8a1046200839c678afc76227d5 Mon Sep 17 00:00:00 2001 From: Andreas Brugger Date: Sun, 11 Dec 2005 12:00:00 +0100 Subject: 2005-12-11: Version 1.1-cvs_ext-0.3 (vdr-text2skin-1.1-cvs_ext-0.3.diff) - added recording-tokens: RecordingLength, RecordingCuttedLength --- common.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) (limited to 'common.c') diff --git a/common.c b/common.c index f45ed1c..f7011d6 100644 --- a/common.c +++ b/common.c @@ -115,6 +115,146 @@ const cRecording *GetRecordingByName(const char *Name) return NULL; } +const cRecording *GetRecordingByFileName(const char *FileName) +{ + return Recordings.GetByName(FileName); +} + +int GetRecordingSize(const char *FileName) +{ + if (FileName != NULL) { + bool bRet=false; + long long size = 0; + int nFiles; + struct stat fileinfo; // Holds file information structure + char *cmd = NULL; + cReadLine reader; + asprintf(&cmd, "find '%s' -follow -type f -name '*.*'|sort ", FileName); + + FILE *p = popen(cmd, "r"); + int ret=0; + if (p) + { + char *s; + + while ((s = reader.Read(p)) != NULL) + { + if ((ret=stat(s, &fileinfo)) != -1) + { + size += (long long)fileinfo.st_size; + nFiles++; + } + } + + bRet=true; + } + + pclose(p); + delete cmd; + + return (int)(size / 1024 / 1024); // [MB] + } + else + { + return 0; + } +} + +int GetRecordingLength(const char *FileName) +{ + // based on the enAIO-Patch for VDR + #define INDEXFILESUFFIX "/index.vdr" + + struct tIndex { int offset; uchar type; uchar number; short reserved; }; + tIndex *index; + char RecLength[21]; + char *filename = NULL; + int last = -1; + index = NULL; + if (FileName) { + filename = MALLOC(char, strlen(FileName) + strlen(INDEXFILESUFFIX) + 1); + if (filename) { + strcpy(filename, FileName); + char *pFileExt = filename + strlen(filename); + strcpy(pFileExt, INDEXFILESUFFIX); + int delta = 0; + if (access(filename, R_OK) == 0) { + struct stat buf; + if (stat(filename, &buf) == 0) { + delta = buf.st_size % sizeof(tIndex); + if (delta) { + delta = sizeof(tIndex) - delta; + esyslog("ERROR: invalid file size (%ld) in '%s'", buf.st_size, filename); + } + last = (buf.st_size + delta) / sizeof(tIndex) - 1; + char hour[2], min[3]; + snprintf(RecLength, sizeof(RecLength), "%s", *IndexToHMSF(last, true)); + snprintf(hour, sizeof(hour), "%c", RecLength[0]); + snprintf(min, sizeof(min), "%c%c", RecLength[2], RecLength[3]); + return (atoi(hour) * 60) + atoi(min); + } + } + free(filename); + } + } + + return 0; +} + +int GetRecordingCuttedLength(const char *FileName) +{ + cMarks marks; + double length = 0; + int totalLength = GetRecordingLength(FileName); + const double diffIFrame = FRAMESPERSEC / 2; // approx. 1/2 sec. + /* + // not useful + static std::string lastFileName = ""; + static uint64 nextUpdate = 0; + static int totalLength = 0; + const uint64 bufferTime = 30 * 1000; // [ms] + */ + + + marks.Load(FileName); + + /* + // buffer the result of 'GetRecordingLength' + if (FileName != lastFileName || time_ms() >= nextUpdate) + { + lastFileName = FileName; + nextUpdate = time_ms() + bufferTime; + totalLength = GetRecordingLength(FileName); + } + */ + + if (marks.Count()) + { + int start = 1; // first frame + bool isStart = true; + + for (cMark *m = marks.First(); m; m = marks.GetNext(m->position)) + { + if (isStart) + { + start = m->position; + } + else + { + length += (double)(m->position - start + 1 + diffIFrame) / (FRAMESPERSEC * 60); // [min] + } + + isStart = !isStart; + } + + // if there is no end-mark the last segment goes to the end of the rec. + if (!isStart) length += totalLength - (double)(start - 1 - diffIFrame) / (FRAMESPERSEC * 60); // [min] + } + + // just to avoid, that the cutted length is bigger than the total length + return (int)length > totalLength ? totalLength : (int)length; +} + cxType TimeType(time_t Time, const std::string &Format) { static char result[1000]; -- cgit v1.2.3 From eeda27b9d069161db0261f6e2f51ac9463bde910 Mon Sep 17 00:00:00 2001 From: Andreas Brugger Date: Sun, 18 Dec 2005 12:00:00 +0100 Subject: 2005-12-18: Version 1.1-cvs_ext-0.4 (vdr-text2skin-1.1-cvs_ext-0.4.diff) - modified the way, the current replayed recording is determined (status.c: cText2SkinStatus::Replaying) There remains a problem that recordings with the same name cannot be distinguished, so information optained from mReplay are not necessarily correct (all the ones added in vdr-text2skin-1.1-cvs_ext-0.2.diff) --- common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common.c') diff --git a/common.c b/common.c index f7011d6..c6b0a24 100644 --- a/common.c +++ b/common.c @@ -117,7 +117,7 @@ const cRecording *GetRecordingByName(const char *Name) const cRecording *GetRecordingByFileName(const char *FileName) { - return Recordings.GetByName(FileName); + return (FileName) ? Recordings.GetByName(FileName) : NULL; } int GetRecordingSize(const char *FileName) -- cgit v1.2.3 From eb6eaf285edd82c212810f066313f93dc4a8a129 Mon Sep 17 00:00:00 2001 From: Andreas Brugger Date: Sat, 7 Jan 2006 12:00:00 +0100 Subject: 2006-01-07: Version 1.1-cvs_ext-0.5 (vdr-text2skin-1.1-cvs_ext-0.5.diff) - modifications to compile with vdr-versions >= 1.3.18 - added tokens: OsdWidth, OsdHeight - activating the token ReplayVideoAR --- common.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'common.c') diff --git a/common.c b/common.c index c6b0a24..904c417 100644 --- a/common.c +++ b/common.c @@ -128,7 +128,9 @@ int GetRecordingSize(const char *FileName) int nFiles; struct stat fileinfo; // Holds file information structure char *cmd = NULL; +#if VDRVERSNUM >= 10318 cReadLine reader; +#endif asprintf(&cmd, "find '%s' -follow -type f -name '*.*'|sort ", FileName); FILE *p = popen(cmd, "r"); @@ -137,7 +139,11 @@ int GetRecordingSize(const char *FileName) { char *s; +#if VDRVERSNUM >= 10318 while ((s = reader.Read(p)) != NULL) +#else + while ((s = readline(p)) != NULL) +#endif { if ((ret=stat(s, &fileinfo)) != -1) { @@ -188,7 +194,11 @@ int GetRecordingLength(const char *FileName) } last = (buf.st_size + delta) / sizeof(tIndex) - 1; char hour[2], min[3]; +#if VDRVERSNUM >= 10318 snprintf(RecLength, sizeof(RecLength), "%s", *IndexToHMSF(last, true)); +#else + snprintf(RecLength, sizeof(RecLength), "%s", IndexToHMSF(last, true)); +#endif snprintf(hour, sizeof(hour), "%c", RecLength[0]); snprintf(min, sizeof(min), "%c%c", RecLength[2], RecLength[3]); return (atoi(hour) * 60) + atoi(min); -- cgit v1.2.3 From c1bf83aec2961a4e84dbc1c36042bd985f044a91 Mon Sep 17 00:00:00 2001 From: Andreas Brugger Date: Sat, 4 Feb 2006 11:49:02 +0100 Subject: 2006-02-04: Version 1.1-cvs_ext-0.7 (vdr-text2skin-1.1-cvs_ext-0.7.diff) - changed the routines to determine the next timers - added the possibility to have a scrollbar in every menu - not fully implemented yet (to position in menu-lists is not necessarily correct, if there are more items with the same osd-text) --- common.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'common.c') diff --git a/common.c b/common.c index 904c417..b9e1daf 100644 --- a/common.c +++ b/common.c @@ -121,6 +121,14 @@ const cRecording *GetRecordingByFileName(const char *FileName) } int GetRecordingSize(const char *FileName) +#if VDRVERSNUM >= 10338 +// use VDR's routine +{ + const cRecording *rec = GetRecordingByFileName(FileName); + return (rec) ? DirSizeMB(FileName) : 0; +} +#else +// use our own approach { if (FileName != NULL) { bool bRet=false; @@ -165,6 +173,7 @@ int GetRecordingSize(const char *FileName) return 0; } } +#endif int GetRecordingLength(const char *FileName) { @@ -217,27 +226,9 @@ int GetRecordingCuttedLength(const char *FileName) double length = 0; int totalLength = GetRecordingLength(FileName); const double diffIFrame = FRAMESPERSEC / 2; // approx. 1/2 sec. - /* - // not useful - static std::string lastFileName = ""; - static uint64 nextUpdate = 0; - static int totalLength = 0; - const uint64 bufferTime = 30 * 1000; // [ms] - */ - marks.Load(FileName); - /* - // buffer the result of 'GetRecordingLength' - if (FileName != lastFileName || time_ms() >= nextUpdate) - { - lastFileName = FileName; - nextUpdate = time_ms() + bufferTime; - totalLength = GetRecordingLength(FileName); - } - */ - if (marks.Count()) { int start = 1; // first frame -- cgit v1.2.3 From 74a5cc8e14900d48386e33cb576f154a6dd7e557 Mon Sep 17 00:00:00 2001 From: Andreas Brugger Date: Sun, 19 Nov 2006 16:58:14 +0100 Subject: 2006-11-19: Version 1.1-cvs_ext-0.9 (vdr-text2skin-1.1-cvs_ext-0.9.diff) - added a test-feature to search for reruns of a program and add the information to the extended epg-info (trigger DEVELOPMENT_FEATURES). This uses a service-interface of the epgsearch-plugin "Epgsearch-searchresults-v1.0" - the timer-conflicts are now checked with epgsearch (service-interface "Epgsearch-lastconflictinfo-v1.0", as it works more reliable and is supported by the plugin author - the extended epg-info and the recording-info are extended by AUX-Infos (configurable) there is also an option to strip known tags - the tab-widths are scaled for taking into account that different TT-Fonts have a different width than the default font from VDR - added tokens for signal-info: FrontendSTR, FrontendSNR, FrontendHasLock, FrontendHasSignal - changed token TimerConflict to TimerConflicts - added token PresentEventID for EPG-images - added tokens for recordings: RecordingFilename, RecordingPriority, RecordingLifetime - removed Text2skin.diff from the rotor-plugin --- common.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) (limited to 'common.c') diff --git a/common.c b/common.c index b9e1daf..d5bb0b4 100644 --- a/common.c +++ b/common.c @@ -3,7 +3,13 @@ */ #include "common.h" +#include #include +#include +#include +#include + +#define FRONTEND_DEVICE "/dev/dvb/adapter%d/frontend%d" const std::string &SkinPath(void) { @@ -69,6 +75,14 @@ const char *ChannelShortName(const cChannel *Channel, int Number) return buffer; } + +const char *EventType(uint Number) +{ + static char buffer[25]; + buffer[0] = '\0'; + snprintf(buffer, sizeof(buffer), "%d", Number); + return buffer; +} /* const char *ChannelBouquet(const cChannel *Channel, int Number) { static char buffer[256]; @@ -120,6 +134,137 @@ const cRecording *GetRecordingByFileName(const char *FileName) return (FileName) ? Recordings.GetByName(FileName) : NULL; } +int GetFrontendSTR(void) +{ + uint16_t value = 0; + char *dev = NULL; + + asprintf(&dev, FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0); + int fe = open(dev, O_RDONLY | O_NONBLOCK); + free(dev); + if (fe >= 0) { + CHECK(ioctl(fe, FE_READ_SIGNAL_STRENGTH, &value)); + close(fe); + } + return value / 655; +} + +int GetFrontendSNR(void) +{ + uint16_t value = 0; + char *dev = NULL; + + asprintf(&dev, FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0); + int fe = open(dev, O_RDONLY | O_NONBLOCK); + free(dev); + if (fe >= 0) { + CHECK(ioctl(fe, FE_READ_SNR, &value)); + close(fe); + } + return value / 655; +} + +bool GetFrontendHasLock(void) +{ + uint16_t value = 0; + char *dev = NULL; + + asprintf(&dev, FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0); + int fe = open(dev, O_RDONLY | O_NONBLOCK); + free(dev); + if (fe >= 0) { + CHECK(ioctl(fe, FE_READ_STATUS, &value)); + close(fe); + } + return value & FE_HAS_LOCK; +} + +bool GetFrontendHasSignal(void) +{ + uint16_t value = 0; + char *dev = NULL; + + asprintf(&dev, FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0); + int fe = open(dev, O_RDONLY | O_NONBLOCK); + free(dev); + if (fe >= 0) { + CHECK(ioctl(fe, FE_READ_STATUS, &value)); + close(fe); + } + return value & FE_HAS_SIGNAL; +} + +std::string AddExtInfoToDescription(const char *Title, const char *ShortText, const char *Description, const char *Aux, bool StripAux) +{ + // max. width so lines don't get wrapped + #define MAX_CHARS 50 + + // prepare the description + std::stringstream desc(""); + + if (!isempty(Description)) { + // it seems that sometimes the description ends with a newline + // and sometimes it does not + std::string buf(Description); + while (!buf.empty() && buf[buf.size() - 1] == '\n') buf.erase(buf.size() - 1); + desc << buf << "\n"; // keep one newline + } + +#ifdef DEVELOPMENT_FEATURES + // try to find a rerun of the show using epgsearch-service + if (!isempty(Title)) { + Epgsearch_searchresults_v1_0 data; + data.query = strdup(Title); + data.mode = 0; + data.channelNr = 0; + data.useTitle = true; + data.useSubTitle = false; + data.useDescription = false; + if (cPluginManager::CallFirstService("Epgsearch-searchresults-v1.0", &data)) { + cList* list = data.pResultList; + if (list) { + // die aktuelle Sendung wird noch als WH angezeigt !!! + if (!desc.str().empty()) desc << "\n"; + desc << tr("RERUNS OF THIS SHOW") << ":\n"; + int i = 0; + for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = + list->First(); r && i < 5; r = list->Next(r)) { + i++; + std::stringstream buf; + buf << " - "; + buf << *DayDateTime(r->event->StartTime()); + buf << ": " << r->event->Title(); + if (!isempty(r->event->ShortText())) buf << "~" << r->event->ShortText(); + desc << FitToWidth(buf, MAX_CHARS) << "\n"; + } + delete list; + } + } + } +#endif // DEVELOPMENT_FEATURES + + // Add the AUX-Info of the Recording + if (Aux) { + if (StripAux) { + std::string auxRaw(Aux); + std::string auxEpgsearch = StripXmlTag(auxRaw, "epgsearch"); + if (!auxEpgsearch.empty()) { + if (!desc.str().empty()) desc << "\n"; + desc << tr("AUXILIARY INFOS") << ":\n"; + std::stringstream buf; + buf << " - " << tr("Search timer") << ": " << StripXmlTag(auxRaw, "Search timer"); + desc << FitToWidth(buf, MAX_CHARS) << "\n"; + } + } else { + if (!desc.str().empty()) desc << "\n"; + desc << tr("AUXILIARY INFOS") << ":\n"; + desc << Aux << "\n"; + } + } + + return desc.str(); +} + int GetRecordingSize(const char *FileName) #if VDRVERSNUM >= 10338 // use VDR's routine @@ -404,3 +549,36 @@ void SkipQuotes(std::string &Value) { else esyslog("ERROR: text2skin: missing closing %c", quote); } + +std::string FitToWidth(std::string &Line, uint Width) { + std::string buf(Line); + if (buf.size() > Width) { + buf.erase(Width - 3); + buf.append("..."); + } + return buf; +} + +std::string FitToWidth(std::stringstream &Line, uint Width) { + std::string buf(Line.str()); + if (buf.size() > Width) { + buf.erase(Width - 3); + buf.append("..."); + } + return buf; +} + +std::string StripXmlTag(std::string &Line, const char *Tag) { + // set the search strings + std::stringstream strStart, strStop; + strStart << "<" << Tag << ">"; + strStop << ""; + // find the strings + std::string::size_type locStart = Line.find(strStart.str()); + std::string::size_type locStop = Line.find(strStop.str()); + if (locStart == std::string::npos || locStop == std::string::npos) return ""; + // extract relevant text + int pos = locStart + strStart.str().size(); + int len = locStop - pos; + return len < 0 ? "" : Line.substr(pos, len); +} -- cgit v1.2.3 From ac64ce03ec6b5766691ff2da3af6f51ed800792a Mon Sep 17 00:00:00 2001 From: Andreas Brugger Date: Sun, 3 Dec 2006 17:45:17 +0100 Subject: 2006-12-03: Version 1.1-cvs_ext-0.10 (vdr-text2skin-1.1-cvs_ext-0.10.diff) - set EditableWidth. This is important for plugins like 'rotor' or 'extrecmenu' - now setting the locale setting LC_TIME according to the language-selection in VDR --- common.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'common.c') diff --git a/common.c b/common.c index d5bb0b4..0bfb1d4 100644 --- a/common.c +++ b/common.c @@ -4,6 +4,7 @@ #include "common.h" #include +#include #include #include #include @@ -409,6 +410,7 @@ cxType TimeType(time_t Time, const std::string &Format) if (Time > 0) { if (Format.length() > 0) { + setlocale(LC_TIME, tr("en_US")); strftime(result, sizeof(result), Format.c_str(), tm); cxType r = result; -- cgit v1.2.3