From 517ff783d64ddb1b270f71d70a834007c73b09b7 Mon Sep 17 00:00:00 2001 From: Markus Ehrnsperger <> Date: Sun, 9 Oct 2022 16:48:08 +0200 Subject: [PATCH] languages --- README | 2 +- live/img/1280x720.png | 1515 ++++++++++++++++++++++++++++++++++++++ live/img/1920x1080.png | 1515 ++++++++++++++++++++++++++++++++++++++ live/img/3840x2160.png | 1515 ++++++++++++++++++++++++++++++++++++++ live/img/4K.png | 1515 ++++++++++++++++++++++++++++++++++++++ live/img/720x576.png | 1578 +++++++++++++++++++++++++++++++++++++++ live/img/7680x4320.png | 1515 ++++++++++++++++++++++++++++++++++++++ live/img/8K.png | 1584 ++++++++++++++++++++++++++++++++++++++++ live/img/ud.png | Bin 0 -> 2500 bytes osd_status.cpp | 38 +- osd_status.h | 2 +- pages/pageelems.ecpp | 7 +- pages/recordings.ecpp | 233 +++--- recman.cpp | 391 ++++------ recman.h | 38 +- services.h | 49 ++ setup.h | 4 +- 17 files changed, 11132 insertions(+), 369 deletions(-) create mode 100644 live/img/1280x720.png create mode 100644 live/img/1920x1080.png create mode 100644 live/img/3840x2160.png create mode 100644 live/img/4K.png create mode 100644 live/img/720x576.png create mode 100644 live/img/7680x4320.png create mode 100644 live/img/8K.png create mode 100644 live/img/ud.png diff --git a/README b/README index 561a5fcf..5d7df0b5 100644 --- a/README +++ b/README @@ -47,7 +47,7 @@ Requirements: VDR >= 2.0.0 -gcc >= 4.8.1 +gcc >= 4.8.1, must support -std=c++14 PCRE2 >= 10.38 - https://github.com/PhilipHazel/pcre2/releases Tntnet >= 1.5.3 - http://www.tntnet.org/download.hms Cxxtools >= 1.4.3 - http://www.tntnet.org/download.hms diff --git a/live/img/1280x720.png b/live/img/1280x720.png new file mode 100644 index 00000000..ba8c5531 --- /dev/null +++ b/live/img/1280x720.png @@ -0,0 +1,1515 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vdr-plugin-skinflatplus/1280x720.png at master · MegaV0lt/vdr-plugin-skinflatplus · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + +
+ + + + + + +
+ + +
+ + + + + + + + +Permalink + +
+ +
+
+ + + master + + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + Go to file + +
+ + + + +
+
+
+ + + + + + + + + +
+ +
+
+
 
+
+ +
+
 
+ Cannot retrieve contributors at this time +
+
+ + + + + + + + + +
+ +
+ + +
+ + 1.51 KB +
+ +
+ + + + +
+
+ +
+
+ +
+ +
+
+ + + +
+ +
+ 1280x720.png +
+
+ +
+ + + + +
+ + +
+ + +
+
+ + + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/live/img/1920x1080.png b/live/img/1920x1080.png new file mode 100644 index 00000000..8ba62f2e --- /dev/null +++ b/live/img/1920x1080.png @@ -0,0 +1,1515 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vdr-plugin-skinflatplus/1920x1080.png at master · MegaV0lt/vdr-plugin-skinflatplus · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + +
+ + + + + + +
+ + +
+ + + + + + + + +Permalink + +
+ +
+
+ + + master + + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + Go to file + +
+ + + + +
+
+
+ + + + + + + + + +
+ +
+
+
 
+
+ +
+
 
+ Cannot retrieve contributors at this time +
+
+ + + + + + + + + +
+ +
+ + +
+ + 1.45 KB +
+ +
+ + + + +
+
+ +
+
+ +
+ +
+
+ + + +
+ +
+ 1920x1080.png +
+
+ +
+ + + + +
+ + +
+ + +
+
+ + + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/live/img/3840x2160.png b/live/img/3840x2160.png new file mode 100644 index 00000000..e8b0ac7a --- /dev/null +++ b/live/img/3840x2160.png @@ -0,0 +1,1515 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vdr-plugin-skinflatplus/3840x2160.png at master · MegaV0lt/vdr-plugin-skinflatplus · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + +
+ + + + + + +
+ + +
+ + + + + + + + +Permalink + +
+ +
+
+ + + master + + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + Go to file + +
+ + + + +
+
+
+ + + + + + + + + +
+ +
+
+
 
+
+ +
+
 
+ Cannot retrieve contributors at this time +
+
+ + + + + + + + + +
+ +
+ + +
+ + 1.63 KB +
+ +
+ + + + +
+
+ +
+
+ +
+ +
+
+ + + +
+ +
+ 3840x2160.png +
+
+ +
+ + + + +
+ + +
+ + +
+
+ + + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/live/img/4K.png b/live/img/4K.png new file mode 100644 index 00000000..a4dfd932 --- /dev/null +++ b/live/img/4K.png @@ -0,0 +1,1515 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vdr-plugin-skinflatplus/4K.png at master · MegaV0lt/vdr-plugin-skinflatplus · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + +
+ + + + + + +
+ + +
+ + + + + + + + +Permalink + +
+ +
+
+ + + master + + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + Go to file + +
+ + + + +
+
+
+ + + + + + + + + +
+ +
+
+
 
+
+ +
+
 
+ Cannot retrieve contributors at this time +
+
+ + + + + + + + + +
+ +
+ + +
+ + 775 Bytes +
+ +
+ + + + +
+
+ +
+
+ +
+ +
+
+ + + +
+ +
+ 4K.png +
+
+ +
+ + + + +
+ + +
+ + +
+
+ + + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/live/img/720x576.png b/live/img/720x576.png new file mode 100644 index 00000000..ec95ff3e --- /dev/null +++ b/live/img/720x576.png @@ -0,0 +1,1578 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vdr-plugin-skinflatplus/720x576.png at master · MegaV0lt/vdr-plugin-skinflatplus · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + +
+ + + + + + +
+ + +
+ + + + + + + + +Permalink + +
+ +
+
+ + + master + + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + Go to file + +
+ + + + +
+
+
+ + + + + + + + + +
+ +
+
+ + + +
+ + + + + + +
+
+ + Latest commit + b7c5293 + Dec 21, 2020 + + + + + + History + + +
+
+ +
+ +
+
+ + + 1 + + contributor + + +
+ +

+ Users who have contributed to this file +

+
+ + + + + + +
+
+
+
+ + + + + + + + + +
+ +
+ + +
+ + 1.27 KB +
+ +
+ + + + +
+
+ +
+
+ +
+ +
+
+ + + +
+ +
+ 720x576.png +
+
+ +
+ + + + +
+ + +
+ + +
+
+ + + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/live/img/7680x4320.png b/live/img/7680x4320.png new file mode 100644 index 00000000..5c8368f6 --- /dev/null +++ b/live/img/7680x4320.png @@ -0,0 +1,1515 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vdr-plugin-skinflatplus/7680x4320.png at master · MegaV0lt/vdr-plugin-skinflatplus · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + +
+ + + + + + +
+ + +
+ + + + + + + + +Permalink + +
+ +
+
+ + + master + + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + Go to file + +
+ + + + +
+
+
+ + + + + + + + + +
+ +
+
+
 
+
+ +
+
 
+ Cannot retrieve contributors at this time +
+
+ + + + + + + + + +
+ +
+ + +
+ + 1.72 KB +
+ +
+ + + + +
+
+ +
+
+ +
+ +
+
+ + + +
+ +
+ 7680x4320.png +
+
+ +
+ + + + +
+ + +
+ + +
+
+ + + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/live/img/8K.png b/live/img/8K.png new file mode 100644 index 00000000..c3fd204f --- /dev/null +++ b/live/img/8K.png @@ -0,0 +1,1584 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vdr-plugin-skinflatplus/8K.png at master · MegaV0lt/vdr-plugin-skinflatplus · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + +
+ + + + + + +
+ + +
+ + + + + + + + +Permalink + +
+ +
+
+ + + master + + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + Go to file + +
+ + + + +
+
+
+ + + + + + + + + +
+ +
+
+ + + +
+
+ + + + Add UHD logos + +
+ + + + + + + + +
+
+ + Latest commit + 205baab + Jan 6, 2022 + + + + + + History + + +
+
+
Add logos for uhd (MV_Themes)
+ +
+ +
+
+ + + 1 + + contributor + + +
+ +

+ Users who have contributed to this file +

+
+ + + + + + +
+
+
+
+ + + + + + + + + +
+ +
+ + +
+ + 1.05 KB +
+ +
+ + + + +
+
+ +
+
+ +
+ +
+
+ + + +
+ +
+ 8K.png +
+
+ +
+ + + + +
+ + +
+ + +
+
+ + + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/live/img/ud.png b/live/img/ud.png new file mode 100644 index 0000000000000000000000000000000000000000..30aaf3ef60b25418372231063616df67e2985a21 GIT binary patch literal 2500 zcmeH|`8yMi1IPCIAFJ7Nq!49du|7LEvF3 zg%^GV0C;N9_O8~52>U1h=|2MhKLoU}V%)v*Tmbl?P2sK6XS;L1hy)maU+NOq zSlFj%wZ%l1sfa#f86XiELN@FvGmi)7#L&OV7$w5`9lnq6+~*{qKYd;dwCHVjlqfPqW}Qk1PTsw^9#$U!0YjDk4uRy8f+*3I1;GW*on= zu}eOdkg_9)T;CNQA%A{Wp}?@4E@T8PF`z#D9)xh8cV?h#pZrweV4{*P1ys@<7~B-; zB_Kzil|8ZDYjydmmDhKG5XNbC%$Da*$13%bh1#EZE1M6)OKI@CDmTRP^gF(;8Sq!5 zewYc1tvMx&OWaP!3Gc3d6XJ_~fow#J44Xy1-v~|!ETF|uNRn6lbJBthk!ToEd1ZUUTw00; zFK{yiQjCCJbR+?cL3v>Fq5Mq?)1Fuvj_<1rx9Zt5Vv}?bs>2)S^q z@>*kRhFbhFrZ7~c)FRwDZG-m!lu)YDcQI3zs8$&?Yye-xg4V*= zx4RAo6``e5Q4%DD$fsa_Z1lw*v=^5Kv_H{&{Y5~|DYA>+O< zQv`E0qfBEmHc97k5-#i8ZQl}uv4CfpE7h<`;Q9rLhuyuR>&RNI!eYnf8;%B#aTlSX zurwvw&T7Pm9>leMsAox$YvT5Bm&@De69Nb&xO2=w!CH?_#Hv7++rPQC2`MDzpTS`=3*b`q1z<=6=3@6=-%=27+ znxxKOzYsaCyLu$<+v9(gZmrqmmOo+0ioE_?ip5W>@J+EQ5tfp!s_iUibUYAV#Rj4R05tx3>-#-$h)>ShbQo8a`2 zwMuOL&f9oZxj{C~N5h7Qo!9iqeOP3Yw7}x zidfTGJ9LbZS6QNM4J=M`XTFWv+rlIPi}M@Aa{{U$d)nf}Gp2(pPp})AiDQ1rdt=jl zC0T*2Q#t2Lhw-JY&&m0r4Uh;ydgodHm@)WxUfa(^*z;&l`ilvrev3PmuM3ncoeTcZ z-v?)}_`ZDkHVo9itZDaZm9pQ;qP99@?=H}6>3EaW8BXmM5mj41cfH!Z%9{MX*)+TH zXcKyde6G2_)!X8(n)678M;!9*mrma(xajrjOWr}P5ey9{y$>NE-@z08^f#E3(ehML z83i)V!utD*lY4sw=OR0Tw6)D`x^gim@8CMyr|?Wpf=eEbyFP$NIOUc@^aXZ@8r!9o z{kH7e#B+J+T22HmoFU0@gM`miGtle`86{tmGD0zWpY1iB^9#x504Fi MvUY$oEPa#y2g`90hX4Qo literal 0 HcmV?d00001 diff --git a/osd_status.cpp b/osd_status.cpp index 5dcc10a9..e8c42492 100644 --- a/osd_status.cpp +++ b/osd_status.cpp @@ -120,24 +120,38 @@ std::string const OsdStatusMonitor::GetButtonsHtml() { } std::string const OsdStatusMonitor::GetItemsHtml(void){ - std::string buffer= ""; - for (cLiveOsdItem *item = items.First(); item; item = items.Next(item)) { - buffer += "
isSelected()) - buffer += " selected"; - buffer += "\">"; - buffer += EncodeHtml(item->Text()); - buffer += "
"; - } - return !buffer.empty() ? "
" + buffer + "
" : ""; + std::string buffer= ""; + for (cLiveOsdItem *item = items.First(); item; item = items.Next(item)) { + buffer += "
isSelected()) buffer += " selected"; + buffer += "\">"; +/* + if (tabs[0] > 0) { + buffer += EncodeHtml(item->Text(), true); + const char *tab = strchr(item->Text().c_str(), '\t'); + if (tab && *(tab + 1) ) { + int charsT1 = tab - item->Text().c_str(); + buffer.append(std::max(1, (int)tabs[0] - charsT1), ' '); + buffer += EncodeHtml(tab + 1); + } + } else { +*/ + buffer += EncodeHtml(item->Text()); +// } + buffer += "
"; + } + if (buffer.empty() ) return ""; +// if (tabs[0] > 0) return std::string("
") + buffer + "
"; + return std::string("
") + buffer + "
"; } + std::string const OsdStatusMonitor::GetHtml(){ std::stringstream ss; ss << lastUpdate; return "
" + GetTitleHtml() + GetItemsHtml() + GetTextHtml() + GetMessageHtml() + GetButtonsHtml() + "
"; } -std::string const OsdStatusMonitor::EncodeHtml(const std::string& html) { +std::string const OsdStatusMonitor::EncodeHtml(const std::string& html, bool stopAtTab) { std::stringstream ss; std::string::const_iterator i; for (i = html.begin(); i != html.end(); ++i) { @@ -149,6 +163,8 @@ std::string const OsdStatusMonitor::EncodeHtml(const std::string& html) { ss << "&"; else if (*i == '"') ss << """; + else if (*i == '\t' && stopAtTab) + break; else ss << static_cast(*i); // Copy untranslated } diff --git a/osd_status.h b/osd_status.h index a0ea6f23..a4c7f0f8 100644 --- a/osd_status.h +++ b/osd_status.h @@ -76,7 +76,7 @@ class OsdStatusMonitor: public cStatus virtual ~OsdStatusMonitor(); - std::string const EncodeHtml(const std::string& html); + std::string const EncodeHtml(const std::string& html, bool stopAtTab = false); }; OsdStatusMonitor& LiveOsdStatusMonitor(); diff --git a/pages/pageelems.ecpp b/pages/pageelems.ecpp index f88ae873..feac6c7d 100644 --- a/pages/pageelems.ecpp +++ b/pages/pageelems.ecpp @@ -858,7 +858,7 @@ for (const cTvMedia &media: *media_v) { <%cpp> } - (<$ tr("Homepage") $>)
+ (<$ tr("Homepage") $>)
Streamdev server:
@@ -877,8 +877,11 @@ for (const cTvMedia &media: *media_v) { <%cpp> } - (<$ tr("Homepage") $>)
+ (<$ tr("Homepage") $>)
+
<$ tr("Information providers") $>
+
Movie information provided by TMDB
+
Information provided by TheTVDB.com. Please consider supporting them
<$ tr("Bugs and suggestions") $>
<$ tr("If you encounter any bugs or would like to suggest new features, please use our bugtracker") $>:
https://github.com/MarkusEh/vdr-plugin-live/issues
diff --git a/pages/recordings.ecpp b/pages/recordings.ecpp index b0335832..850f0b12 100644 --- a/pages/recordings.ecpp +++ b/pages/recordings.ecpp @@ -142,7 +142,7 @@ function IMDB(im_db, name) { '\" target=\"_blank\">imdb.png\" title=\"<$tr("Find more at the Internet Movie Database.")$>\"/>') } } -// [0] : Level +// [0] : IMDB ID // [1] : ID (prefix "recording_" removed !!!) // [2] : ArchiveDescr() // [3] : image.path (nach "/tvscraper/") @@ -154,13 +154,12 @@ function IMDB(im_db, name) { // [9] : recording_spec: Day, time & duration // [10] : Number of recording errors - -function Recordings(data) { +function Recordings(level, argList, displayFolder, data) { for (obj of data) { document.write( '
  • ') - if (obj[0] > 0) document.write( - '') + if (level > 0) document.write( + '') if (obj[2] != "") { document.write('on_dvd.png\" alt=\"on_dvd\" title=\"') document.write(obj[2]) @@ -230,20 +229,24 @@ function Recordings(data) { document.write(obj[1]) document.write('\">') document.write(obj[15]) - document.write(obj[16]) + if (displayFolder == 1 && obj[16] != "") { + document.write(' (') + document.write(obj[16]) + document.write(')') + } document.write('
    ') document.write(obj[14]) if (obj[14] == "") document.write(' ') document.write('
    ') if (obj[2] == "") { - RecordingAction(obj[1], "vdr_request/play_recording?param=", "play.png", "<$tr("play this recording")$>", obj[17]) - RecordingAction(obj[1], "playlist.m3u?recid=", "playlist.png", "<$tr("Stream this recording into media player.")$>", obj[17]) - IMDB(obj[18], obj[15]) - RecordingAction(obj[1], "edit_recording.html?recid=", "edit.png", "<$tr("Edit recording")$>", obj[17]) - RecordingAction(obj[1], "recordings.html?todel=", "del.png", "<$tr("Delete this recording from hard disc!")$>", obj[17]) + RecordingAction(obj[1], "vdr_request/play_recording?param=", "play.png", "<$tr("play this recording")$>", argList) + RecordingAction(obj[1], "playlist.m3u?recid=", "playlist.png", "<$tr("Stream this recording into media player.")$>", argList) + IMDB(obj[0], obj[15]) + RecordingAction(obj[1], "edit_recording.html?recid=", "edit.png", "<$tr("Edit recording")$>", argList) + RecordingAction(obj[1], "recordings.html?todel=", "del.png", "<$tr("Delete this recording from hard disc!")$>", argList) } else { document.write('') - IMDB(obj[18], obj[15]) + IMDB(obj[0], obj[15]) } document.write('
    ') if (obj[2] != "") { @@ -363,6 +366,7 @@ if (!deleteResult.empty()) { uintptr_t iRecItem = 0; <%cpp> +// " recoring_item.reserve(6000); // Max Buffer used: 5.636 bytes RecordingsTreePtr recordingsTree(LiveRecordingsManager()->GetRecordingsTree()); @@ -377,112 +381,135 @@ std::list::iterator recIter; bool sorted = false; int level = 0; if( currentFlat != "true" ) { -sorted = recItemThisDir->addSubdirs(recItems); -if (!sorted) { - if (currentSort == "namedesc") - recItems.sort(RecordingsItemPtrCompare::ByDescendingNameDescSort); - else if (currentSort == "nameasc") - recItems.sort(RecordingsItemPtrCompare::ByAscendingNameDescSort); -} -for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) { - RecordingsItemPtr recItem = *recIter; - counter++; - - /* search trough directory for new recordings */ - bool newR = false; - if ( LiveSetup().GetMarkNewRec() ) newR = recItem->checkNew(); - level = recItem->Level(); +// create list of subdirs, in "recItems" + sorted = recItemThisDir->addSubdirs(recItems); + if (!sorted) { + if (currentSort == "namedesc") + recItems.sort(RecordingsItemPtrCompare::ByDescendingNameDescSort); + else if (currentSort == "nameasc") + recItems.sort(RecordingsItemPtrCompare::ByAscendingNameDescSort); + } + for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) { +// this is the loop over the subdirs + RecordingsItemPtr recItem = *recIter; + counter++; + + /* search trough directory for new recordings */ + bool newR = false; + if ( LiveSetup().GetMarkNewRec() ) newR = recItem->checkNew(); + level = recItem->Level(); -
  • -
    +
  • +
    - <{ if(level > 1) { }> <{ } }> -
    - <{ if (!recItem->scraperImage().path.empty() ) { }> -
    - scraperImage().width > recItem->scraperImage().height?"class=\"thumb\"":"class=\"thumbpt\"" $> - /> -
    - <{ } }> + <{ if(level > 1) { }> <{ } }> +
    + <{ if (!recItem->scraperImage().path.empty() ) { }> +
    + scraperImage().width > recItem->scraperImage().height?"class=\"thumb\"":"class=\"thumbpt\"" $> + /> +
    + <{ } }>
    "><$ recItem->Name() $>
     
    - + -<%cpp> - std::string combinedId = recItem->Name() + "_"; - combinedId += counter + "_" + recItem->Level(); - std::string idHash(MD5Hash(combinedId)); - iRecItem = (uintptr_t)&recItem; - - -
  • -<%cpp> -} -recItems.clear(); -sorted = recItemThisDir->addRecordings(recItems); -level = recItemThisDir->Level() + 1; + <%cpp> + std::string combinedId = recItem->Name() + "_"; + combinedId += counter + "_" + recItem->Level(); + std::string idHash(MD5Hash(combinedId)); + iRecItem = (uintptr_t)&recItem; + + + + <%cpp> + } // end of loop over subdirs +// now the items + recItems.clear(); + sorted = recItemThisDir->addRecordings(recItems); + level = recItemThisDir->Level() + 1; } else { -if (currentSort == "duplicates") { - addAllDuplicateRecordings(recItems, recordingsTree); -} else { - recordingsTree->addAllRecordings(recItems); -} +// here we prepare the items in case of a flat list, no folders + if (currentSort != "duplicates") recordingsTree->addAllRecordings(recItems); } -if (!sorted) { - if (currentSort == "dateasc") - recItems.sort(RecordingsItemPtrCompare::ByAscendingDate); - else if (currentSort == "datedesc") - recItems.sort(RecordingsItemPtrCompare::ByDescendingDate); - else if (currentSort == "namedesc") - recItems.sort(RecordingsItemPtrCompare::ByDescendingNameDescSort); - else if (currentSort == "nameasc") - recItems.sort(RecordingsItemPtrCompare::ByAscendingNameDescSort); - else if (currentSort == "errorsasc" || currentSort == "errorsdesc") - recItems.sort(RecordingsItemPtrCompare::ByDescendingRecordingErrors); -} - argList.clear(); argList.append("&sort="); argList.append(currentSort); argList.append("&filter="); argList.append(currentFilter); -bool first = true; - - + <%cpp> } else { +// duplicates + for (int i = 0; i < 3; i++) { + recItems.clear(); + bool first = true; + std::string nodeName; + if (i == 0) { + addDuplicateRecordingsSd(recItems, recordingsTree); + nodeName = tr("Duplicates identified by tvscraper"); + } else if (i == 1) { + addDuplicateRecordingsLang(recItems, recordingsTree); + nodeName = tr("Duplicates, with different languages"); + } else if (i == 2) { + addDuplicateRecordingsNoSd(recItems, recordingsTree); + nodeName = tr("Duplicates not identified by tvscraper"); + } + std::string idHash(MD5Hash(nodeName + "_1")); + if (!recItems.empty() ) { + +
  • +
    +
    +
    +
    +
    <$ nodeName $>
    +
    +
     
    +
    + +
  • + <%cpp> + } + } } - -]) + <# ---------------------------------------------------------------------- #> diff --git a/recman.cpp b/recman.cpp index 5003e800..6a194e51 100644 --- a/recman.cpp +++ b/recman.cpp @@ -1,3 +1,6 @@ +#ifdef HAVE_PCRE2 +#include "StringMatch.h" +#endif #include "recman.h" #include "tools.h" @@ -362,6 +365,11 @@ namespace vdrlive { return first->orderDuplicates(second, true); } + bool RecordingsItemPtrCompare::ByDuplicatesLanguage(const RecordingsItemPtr & first, const RecordingsItemPtr & second) // return first < second + { + return first->orderDuplicates(second, true, true); + } + bool RecordingsItemPtrCompare::ByAscendingNameDesc(const RecordingsItemPtr & first, const RecordingsItemPtr & second) // return first < second { int i = first->NameForSearch().compare(second->NameForSearch() ); @@ -506,6 +514,17 @@ namespace vdrlive { return result; } + bool RecordingsItem::matchesFilter(const std::string &filter) { + if (filter.empty() ) return true; +#ifdef HAVE_PCRE2 + StringMatch sm(filter); + return sm.Matches(Name()) or + sm.Matches(ShortText()?ShortText() : "" ) or + sm.Matches(Description()?Description() : ""); +#endif + return true; + } + bool RecordingsItem::checkNew() { if (Recording() && Recording()->GetResume() <= 0) return true; for (const auto &rec:m_entries) @@ -590,18 +609,26 @@ namespace vdrlive { return 0; } - bool RecordingsItem::orderDuplicates(const RecordingsItemPtr &second, bool alwaysShortText) const { + bool RecordingsItem::orderDuplicates(const RecordingsItemPtr &second, bool alwaysShortText, bool lang) const { // this is a < operation. Return false in case of == !!!!! - if (m_s_videoType != second->m_s_videoType) return (int)m_s_videoType < (int)second->m_s_videoType; + if (m_s_videoType != second->m_s_videoType) return (int)m_s_videoType > (int)second->m_s_videoType; // 0 if no scraper data. Move these to the end, by using > switch (m_s_videoType) { case eVideoType::movie: - return m_s_dbid < second->m_s_dbid; + if (m_s_dbid != second->m_s_dbid) return m_s_dbid < second->m_s_dbid; + if (!lang) return false; + return m_language < second->m_language; case eVideoType::tvShow: if (m_s_dbid != second->m_s_dbid) return m_s_dbid < second->m_s_dbid; if (m_s_season_number != second->m_s_season_number) return m_s_season_number < second->m_s_season_number; if (m_s_episode_number != second->m_s_episode_number) return m_s_episode_number < second->m_s_episode_number; - if (m_s_season_number != 0 || m_s_episode_number != 0) return false; // they are equal => < operator results in false ... - return CompareTexts(second) < 0; + if (m_s_season_number != 0 || m_s_episode_number != 0) { + if (!lang) return false; // they are equal => < operator results in false ... + return m_language < second->m_language; + } + if (!lang) return CompareTexts(second) < 0; + { int cmp = CompareTexts(second); + if (cmp != 0) return cmp < 0;} + return m_language < second->m_language; default: // no scraper data available int i = NameForSearch().compare(second->NameForSearch() ); @@ -642,7 +669,7 @@ namespace vdrlive { /** * Implementation of class RecordingsItemRec: */ - RecordingsItemRec::RecordingsItemRec(const std::string& id, const std::string& name, const cRecording* recording) : + RecordingsItemRec::RecordingsItemRec(const std::string& id, const std::string& name, const cRecording* recording, int language, int sdHdUhd) : RecordingsItem(name), m_recording(recording), m_id(id), @@ -650,6 +677,8 @@ namespace vdrlive { m_duration(m_recording->FileName() ? m_recording->LengthInSeconds() / 60 : 0) { // dsyslog("live: REC: C: rec %s -> %s", name.c_str(), parent->Name().c_str()); + m_language = language; + m_video_SD_HD = sdHdUhd; getScraperData(recording, cImageLevels(eImageLevel::episodeMovie, eImageLevel::seasonMovie, eImageLevel::tvShowCollection, eImageLevel::anySeasonCollection)); } @@ -659,19 +688,6 @@ namespace vdrlive { // dsyslog("live: REC: D: rec %s", Name().c_str()); } - void RecordingsItemRec::AppendHint(std::string &target) const - { - if (RecInfo()->ShortText() ) { - AppendHtmlEscapedAndCorrectNonUTF8(target, RecInfo()->ShortText() ); - target.append("<br />"); - } - else if (RecInfo()->Description() ) { - AppendHtmlEscapedAndCorrectNonUTF8(target, RecInfo()->Description() ); - target.append("<br />"); - } - AppendHtmlEscaped(target, tr("Click to view details.") ); - } - // Spielfilm Thailand / Deutschland / Großbritannien 2015 (Rak ti Khon Kaen) #define MAX_LEN_ST 70 void RecordingsItemRec::AppendShortTextOrDesc(std::string &target) const @@ -694,23 +710,6 @@ namespace vdrlive { if (*end) target.append("..."); } } - const char *RecordingsItemRec::RecordingErrorsIcon() const - { - if (RecordingErrors() == 0) return "NoRecordingErrors.png"; - if (RecordingErrors() > 0) return "RecordingErrors.png"; - return "NotCheckedForRecordingErrors.png"; - } - - void RecordingsItemRec::AppendRecordingErrorsStr(std::string &target) const - { - if (RecordingErrors() == 0) AppendHtmlEscaped(target, tr("No recording errors")); - if (RecordingErrors() > 0) { - AppendHtmlEscaped(target, tr("Number of recording errors:")); - target.append(" "); - target.append(std::to_string(RecordingErrors() )); - } - if (RecordingErrors() < 0) AppendHtmlEscaped(target, tr("Recording errors unknown")); - } const int RecordingsItemRec::SD_HD() { @@ -750,48 +749,11 @@ namespace vdrlive { return m_video_SD_HD; } - void RecordingsItemRec::AppendIMDb(std::string &target) const { - if (LiveSetup().GetShowIMDb()) { - if (m_s_IMDB_ID.empty() ) { - target.append("\n"); - } - } - - void RecordingsItemRec::AppendRecordingAction(std::string &target, const char *A, const char *Img, const char *Title, const std::string argList){ - target.append("\n"); - } - - void RecordingsItemRec::AppendasJSArray(std::string &target, bool displayFolder, const std::string argList, int level){ -// list item, classes, space depending on level -// target.append(""); } - void RecordingsItemRec::AppendasHtml(std::string &target, bool displayFolder, const std::string argList, int level){ -// list item, classes, space depending on level - target.append("
  • "); - if(!displayFolder) { -// add some space - target.append("\n"); - } - if (IsArchived() ) { - target.append("\"on_dvd\""); - } else { -#if TNTVERSION >= 30000 - target.append("" ); - } -// scraper data - if (!LiveSetup().GetTvscraperImageDir().empty() ) { - target.append("
    \n\n
    "); - AppendDateTime(target, tr("%a,"), StartTime()); // day of week - target.append(" "); - AppendDateTime(target, tr("%b %d %y"), StartTime()); // date - target.append(" "); - AppendDateTime(target, tr("%I:%M %p"), StartTime() ); // time - if(Duration() >= 0) { - target.append(" "); - AppendDuration(target, tr("(%d:%02d)"), Duration() / 60, Duration() % 60); - } - target.append("
    "); -// RecordingErrors, Icon -#if VDRVERSNUM >= 20505 - target.append("
    "); -#endif -// HD_SD, with channel name - target.append("
    ChannelName() ); - target.append("\" />
    \n"); -// Recording name - target.append("
    \n
    "); - if (!IsArchived()) { - AppendRecordingAction(target, "vdr_request/play_recording?param=", "play.png", "play this recording", argList); - AppendRecordingAction(target, "playlist.m3u?recid=", "playlist.png", "Stream this recording into media player.", argList); - AppendIMDb(target); - AppendRecordingAction(target, "edit_recording.html?recid=", "edit.png", "Edit recording", argList); - AppendRecordingAction(target, "recordings.html?todel=", "del.png", "Delete this recording from hard disc!", argList); - - } else { - target.append(""); - AppendIMDb(target); - } - target.append("
    "); - if (IsArchived()) { - target.append("
    "); - AppendHtmlEscaped(target, ArchiveDescr().c_str() ); - target.append("
    "); - } - target.append("
  • "); - } +void RecordingsItemRec::AppendAsJSArray(std::string &target, std::list::iterator recIterFirst, const std::list::iterator &recIterLast, bool &first, const std::string &filter, bool displayFolder) { + for (; recIterFirst != recIterLast; ++recIterFirst) { + RecordingsItemPtr recItem = *recIterFirst; + if (!recItem->matchesFilter(filter)) continue; + if (!first) target.append(","); + else first = false; + recItem->AppendAsJSArray(target, displayFolder); + } +} /** * Implemetation of class RecordingsItemDummy @@ -1050,6 +876,14 @@ namespace vdrlive { m_root(new RecordingsItemDir("", 0)) { // esyslog("live: DH: ****** RecordingsTree::RecordingsTree() ********"); +// languages + cGetChannelLanguages channelLanguages; + channelLanguages.m_defaultLanguage = 0; + channelLanguages.call(LiveSetup().GetPluginScraper() ); +// sd / hd / uhd + cGetChannelHD channelHD; + channelHD.call(LiveSetup().GetPluginScraper() ); + bool sdHdUhdAvailable = !channelHD.m_channelHD.empty(); // check availability of scraper data cGetScraperOverview scraperOverview; bool scraperDataAvailable = scraperOverview.call(LiveSetup().GetPluginScraper()); @@ -1078,6 +912,16 @@ namespace vdrlive { #endif if (scraperDataAvailable) m_maxLevel = std::max(m_maxLevel, recording->HierarchyLevels() + 1); else m_maxLevel = std::max(m_maxLevel, recording->HierarchyLevels() ); + int language; + auto lang_found = channelLanguages.m_channelLanguages.find(recording->Info()->ChannelID()); + if (lang_found == channelLanguages.m_channelLanguages.end() ) language = channelLanguages.m_defaultLanguage; + else language = lang_found->second; + int sdHdUhd = -1; + if (sdHdUhdAvailable) { + auto sdHdUhd_found = channelHD.m_channelHD.find(recording->Info()->ChannelID()); + if (sdHdUhd_found == channelHD.m_channelHD.end() ) sdHdUhd = 0; + else sdHdUhd = sdHdUhd_found->second; + } RecordingsItemPtr dir = m_rootFileSystem; std::string name(recording->Name()); @@ -1095,7 +939,7 @@ namespace vdrlive { } else { std::string recName(name.substr(index, name.length() - index)); - RecordingsItemPtr recPtr (new RecordingsItemRec(recMan->Md5Hash(recording), recName, recording)); + RecordingsItemPtr recPtr (new RecordingsItemRec(recMan->Md5Hash(recording), recName, recording, language, sdHdUhd)); dir->m_entries.insert(recPtr); // esyslog("live: DH: added rec: '%s'", recName.c_str()); if (scraperDataAvailable) { @@ -1182,7 +1026,6 @@ namespace vdrlive { void addAllDuplicateRecordings(std::list &DuplicateRecItems, RecordingsTreePtr &RecordingsTree){ std::list recItems; std::list::iterator currentRecItem, recIterUpName, recIterLowName, recIterUpShortText, recIterLowShortText; - int numberOfRecordingsWithThisName; bool isSeries; RecordingsTree->addAllRecordings(recItems); @@ -1198,6 +1041,7 @@ void addAllDuplicateRecordings(std::list &DuplicateRecItems, if ( (*recIterLowName)->scraperDataAvailable() ) { isSeries = false; // no special for series required } else { + int numberOfRecordingsWithThisName; for( numberOfRecordingsWithThisName = 1; currentRecItem != recIterUpName; currentRecItem++, numberOfRecordingsWithThisName++); if (numberOfRecordingsWithThisName > 5) isSeries = true; else isSeries = false; } @@ -1216,5 +1060,92 @@ void addAllDuplicateRecordings(std::list &DuplicateRecItems, } } } +void addDuplicateRecordingsNoSd(std::list &DuplicateRecItems, RecordingsTreePtr &RecordingsTree){ +// add duplicate recordings where NO scraper data are available. + std::list recItems; + std::list::iterator currentRecItem, recIterUpName, recIterLowName, recIterUpShortText, recIterLowShortText; + bool isSeries; + + RecordingsTree->addAllRecordings(recItems); + recItems.sort(RecordingsItemPtrCompare::ByDuplicates); + + for (currentRecItem = recItems.begin(); currentRecItem != recItems.end(); ) { + if ( (*currentRecItem)->scraperDataAvailable() ) { currentRecItem++; continue;} + recIterLowName = currentRecItem; + recIterUpName = std::upper_bound (currentRecItem , recItems.end(), *currentRecItem, RecordingsItemPtrCompare::ByDuplicatesName); + + currentRecItem++; + if (recIterLowName == recIterUpName ) continue; // there is no recording with this name (internal error) + if (currentRecItem == recIterUpName ) continue; // there is only one recording with this name + if ( (*recIterLowName)->scraperDataAvailable() ) { + isSeries = false; // no special for series required + } else { + int numberOfRecordingsWithThisName; + for( numberOfRecordingsWithThisName = 1; currentRecItem != recIterUpName; currentRecItem++, numberOfRecordingsWithThisName++); + if (numberOfRecordingsWithThisName > 5) isSeries = true; else isSeries = false; + } + if (isSeries) { + for (currentRecItem = recIterLowName; currentRecItem != recIterUpName;){ + recIterLowShortText = currentRecItem; + recIterUpShortText = std::upper_bound (currentRecItem , recIterUpName, *currentRecItem, RecordingsItemPtrCompare::ByDuplicates); + currentRecItem++; + if (currentRecItem == recIterUpShortText ) continue; // there is only one recording with this short text + for(currentRecItem = recIterLowShortText; currentRecItem != recIterUpShortText; currentRecItem++) + DuplicateRecItems.push_back(*currentRecItem); + } + } else { // not a series + for(currentRecItem = recIterLowName; currentRecItem != recIterUpName; currentRecItem++) + DuplicateRecItems.push_back(*currentRecItem); + } + } +} + +void addDuplicateRecordingsLang(std::list &DuplicateRecItems, RecordingsTreePtr &RecordingsTree){ +// add duplicate recordings where scraper data are available. +// add only recordings with different language + std::list recItems; + std::list::iterator currentRecItem, nextRecItem, recIterUpName, recIterLowName; + + RecordingsTree->addAllRecordings(recItems); + recItems.sort(RecordingsItemPtrCompare::ByDuplicatesLanguage); + + for (currentRecItem = recItems.begin(); currentRecItem != recItems.end(); currentRecItem++) { + if ( !(*currentRecItem)->scraperDataAvailable() ) break; + recIterLowName = currentRecItem; + recIterUpName = std::upper_bound (currentRecItem , recItems.end(), *currentRecItem, RecordingsItemPtrCompare::ByDuplicatesName); + + if (recIterLowName == recIterUpName ) continue; // there is no recording with this name (internal error) + nextRecItem = recIterLowName; + nextRecItem++; + if (nextRecItem == recIterUpName ) continue; // there is only one recording with this name + for(currentRecItem = recIterLowName; currentRecItem != recIterUpName && nextRecItem != recIterUpName; currentRecItem++, nextRecItem++) + if (RecordingsItemPtrCompare::ByDuplicatesLanguage(*currentRecItem, *nextRecItem) ) { + DuplicateRecItems.push_back(*currentRecItem); + DuplicateRecItems.push_back(*nextRecItem); + } + } +} +void addDuplicateRecordingsSd(std::list &DuplicateRecItems, RecordingsTreePtr &RecordingsTree){ +// add duplicate recordings where scraper data are available. +// recordings with different languages are NOT duplicates + std::list recItems; + std::list::iterator currentRecItem, recIterUpName, recIterLowName; + + RecordingsTree->addAllRecordings(recItems); + recItems.sort(RecordingsItemPtrCompare::ByDuplicatesLanguage); + + for (currentRecItem = recItems.begin(); currentRecItem != recItems.end(); ) { + if ( !(*currentRecItem)->scraperDataAvailable() ) break; + recIterLowName = currentRecItem; + recIterUpName = std::upper_bound (currentRecItem , recItems.end(), *currentRecItem, RecordingsItemPtrCompare::ByDuplicatesLanguage); + + currentRecItem++; + if (recIterLowName == recIterUpName ) continue; // there is no recording with this name (internal error) + if (currentRecItem == recIterUpName ) continue; // there is only one recording with this name + for(currentRecItem = recIterLowName; currentRecItem != recIterUpName; currentRecItem++) + DuplicateRecItems.push_back(*currentRecItem); + } +} + } // namespace vdrlive diff --git a/recman.h b/recman.h index 8abd558e..74898582 100644 --- a/recman.h +++ b/recman.h @@ -154,6 +154,7 @@ namespace vdrlive { static bool ByAscendingName(const RecordingsItemPtr & first, const RecordingsItemPtr & second); static bool ByDuplicatesName(const RecordingsItemPtr & first, const RecordingsItemPtr & second); static bool ByDuplicates(const RecordingsItemPtr & first, const RecordingsItemPtr & second); + static bool ByDuplicatesLanguage(const RecordingsItemPtr & first, const RecordingsItemPtr & second); static bool ByAscendingNameDesc(const RecordingsItemPtr & first, const RecordingsItemPtr & second); static bool ByAscendingNameDescSort(const RecordingsItemPtr & first, const RecordingsItemPtr & second); static bool ByDescendingNameDescSort(const RecordingsItemPtr & first, const RecordingsItemPtr & second); @@ -185,7 +186,7 @@ namespace vdrlive { virtual time_t StartTime() const = 0; virtual bool IsDir() const = 0; - virtual long Duration() const = 0; + virtual int Duration() const = 0; virtual const std::string& Name() const { return m_name; } virtual const std::string& NameForSort() const { return m_name_for_sort; } virtual const std::string& NameForSearch() const { return m_name_for_search; } @@ -223,21 +224,20 @@ namespace vdrlive { const std::string &scraperName() const { return m_s_title; } const std::string &scraperReleaseDate() const { return m_s_release_date; } const cTvMedia &scraperImage() const { return m_s_image; } + int language() const { return m_language; } virtual bool displayInOthers() const { return true; } int CompareTexts(const RecordingsItemPtr &second, int *numEqualChars=NULL) const; int CompareStD(const RecordingsItemPtr &second, int *numEqualChars=NULL) const; - bool orderDuplicates(const RecordingsItemPtr &second, bool alwaysShortText) const; + bool orderDuplicates(const RecordingsItemPtr &second, bool alwaysShortText, bool lang = false) const; // To display the recording on the UI + bool matchesFilter(const std::string &filter); virtual const int IsArchived() const { return 0 ; } virtual const std::string ArchiveDescr() const { return "" ; } virtual const char *NewR() const { return "" ; } virtual const int RecordingErrors() const { return -1; } - virtual const char *RecordingErrorsIcon() const { return ""; } - virtual void AppendRecordingErrorsStr(std::string &target) const { }; virtual const int SD_HD() { return 0; } virtual const char *SD_HD_icon() { return ""; } - virtual void AppendasHtml(std::string &target, bool displayFolder, const std::string argList, int level) { } - virtual void AppendasJSArray(std::string &target, bool displayFolder, const std::string argList, int level) { } + virtual void AppendAsJSArray(std::string &target, bool displayFolder) { } private: std::string GetNameForSearch(std::string const & name); @@ -261,6 +261,7 @@ namespace vdrlive { int m_s_collection_id = 0; int m_s_episode_number = 0; int m_s_season_number = 0; + int m_language = 0; }; @@ -276,7 +277,7 @@ namespace vdrlive { virtual ~RecordingsItemDir(); virtual time_t StartTime() const { return 0; } - virtual long Duration() const { return 0; } + virtual int Duration() const { return 0; } virtual bool IsDir() const { return true; } virtual std::string const Id() const { return ""; } virtual int Level() { return m_level; } @@ -308,12 +309,12 @@ namespace vdrlive { class RecordingsItemRec : public RecordingsItem { public: - RecordingsItemRec(const std::string& id, const std::string& name, const cRecording* recording); + RecordingsItemRec(const std::string& id, const std::string& name, const cRecording* recording, int language, int sdHdUhd); virtual ~RecordingsItemRec(); virtual time_t StartTime() const { return m_recording->Start(); } - virtual long Duration() const { return m_duration; } + virtual int Duration() const { return m_duration; } // duration in minutes virtual bool IsDir() const { return false; } virtual const std::string Id() const { return m_id; } @@ -329,24 +330,20 @@ namespace vdrlive { #else virtual const int RecordingErrors() const { return -1; } #endif - virtual const char *RecordingErrorsIcon() const; void AppendRecordingErrorsStr(std::string &target) const; virtual const int SD_HD(); - virtual const char *SD_HD_icon() { return SD_HD() == 0 ? "sd.png": "hd.png"; } - virtual void AppendasHtml(std::string &target, bool displayFolder, const std::string argList, int level); - virtual void AppendasJSArray(std::string &target, bool displayFolder, const std::string argList, int level); + virtual const char *SD_HD_icon() { return SD_HD() == 0 ? "sd.png": SD_HD() == 1 ? "hd.png":"ud.png"; } void AppendShortTextOrDesc(std::string &target) const; - void AppendHint(std::string &target) const; - void AppendIMDb(std::string &target) const; - void AppendRecordingAction(std::string &target, const char *A, const char *Img, const char *Title, const std::string argList); + virtual void AppendAsJSArray(std::string &target, bool displayFolder); + static void AppendAsJSArray(std::string &target, std::list::iterator recIterFirst, const std::list::iterator &recIterLast, bool &first, const std::string &filter, bool displayFolder); private: const cRecording *m_recording; const std::string m_id; const int m_isArchived; - const long m_duration; // duration in minutes - int m_video_SD_HD = -1; // 0 is SD, 1 is HD + const int m_duration; // duration in minutes + int m_video_SD_HD = -1; // 0 is SD, 1 is HD, 2 is UHD }; /** @@ -362,7 +359,7 @@ namespace vdrlive { const char * ShortText() const { return m_short_text; } const char * Description() const { return m_description; } virtual time_t StartTime() const { return 0; } - virtual long Duration() const { return m_duration; } // duration in minutes + virtual int Duration() const { return m_duration; } // duration in minutes virtual bool IsDir() const { return false; } virtual std::string const Id() const { return ""; } @@ -430,6 +427,9 @@ namespace vdrlive { RecordingsManagerPtr LiveRecordingsManager(); void addAllDuplicateRecordings(std::list &DuplicateRecItems, RecordingsTreePtr &RecordingsTree); +void addDuplicateRecordingsNoSd(std::list &DuplicateRecItems, RecordingsTreePtr &RecordingsTree); +void addDuplicateRecordingsLang(std::list &DuplicateRecItems, RecordingsTreePtr &RecordingsTree); +void addDuplicateRecordingsSd(std::list &DuplicateRecItems, RecordingsTreePtr &RecordingsTree); } // namespace vdrlive diff --git a/services.h b/services.h index c2c6c1d9..04bee9e2 100644 --- a/services.h +++ b/services.h @@ -5,6 +5,7 @@ #include #include #include +#include /********************************************************************* * Helper Structures @@ -251,6 +252,23 @@ class ScraperGetPosterBanner { cTvMedia banner; }; +// Data structure for service "GetPosterBannerV2" +class ScraperGetPosterBannerV2 { +public: + ScraperGetPosterBannerV2(void) { + type = tNone; + event = NULL; + recording = NULL; + }; +// in + const cEvent *event; // check type for this event + const cRecording *recording; // check type for this recording +//out + tvType type; //typeSeries or typeMovie + cTvMedia poster; + cTvMedia banner; +}; + // Data structure for service "GetPoster" class ScraperGetPoster { public: @@ -387,4 +405,35 @@ class cGetScraperUpdateTimes { else return pScraper->Service("GetScraperUpdateTimes", this); } }; + +inline bool operator< (const tChannelID &c1, const tChannelID &c2) { + if (c1.Source() != c2.Source() ) return c1.Source() < c2.Source(); + if (c1.Nid() != c2.Nid() ) return c1.Nid() < c2.Nid(); + if (c1.Tid() != c2.Tid() ) return c1.Tid() < c2.Tid(); + if (c1.Sid() != c2.Sid() ) return c1.Sid() < c2.Sid(); + return c1.Rid() < c2.Rid(); +} +class cGetChannelLanguages { +public: + cGetChannelLanguages() {} + std::map m_channelLanguages; // if a channel is not in this map, it has the default language + int m_defaultLanguage; + std::map m_channelNames; + bool call(cPlugin *pScraper) { + if (!pScraper) return false; + else return pScraper->Service("GetChannelLanguages", this); + } +}; + +class cGetChannelHD { +public: + cGetChannelHD() {} + std::map m_channelHD; // if a channel is not in this map, it is SD +// currently, only 0 (SD) and 1 (HD) are supported. More might be added +// note: if this map is empty, the SD/HD information was not maitained + bool call(cPlugin *pScraper) { + if (!pScraper) return false; + else return pScraper->Service("GetChannelHD", this); + } +}; #endif // __TVSCRAPER_SERVICES_H diff --git a/setup.h b/setup.h index 6c2cd68f..ad92fd5b 100644 --- a/setup.h +++ b/setup.h @@ -11,8 +11,8 @@ #include -#define LIVEVERSION "3.1.7" -#define LIVEVERSNUM 30107 +#define LIVEVERSION "3.1.8" +#define LIVEVERSNUM 30108 #define LIVESUMMARY trNOOP("Live Interactive VDR Environment") namespace vdrlive {