diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..1be9fcb8f30 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,79 @@ +{ + "files.associations": { + "list": "cpp", + "algorithm": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "deque": "cpp", + "exception": "cpp", + "format": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "locale": "cpp", + "map": "cpp", + "memory": "cpp", + "mutex": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "queue": "cpp", + "ranges": "cpp", + "ratio": "cpp", + "regex": "cpp", + "set": "cpp", + "span": "cpp", + "sstream": "cpp", + "stack": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "utility": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp" + } +} \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index 20f7f713d44..323b860a581 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1187,3 +1187,42 @@ openvix: developer 6.4.008.013 openvix: developer 6.4.009.001 openvix: developer 6.4.009.002 openvix: developer 6.4.009.003 +openvix: developer 6.4.009.004 +openvix: developer 6.4.009.005 +openvix: developer 6.4.009.006 +openvix: developer 6.4.009.007 +openvix: developer 6.4.009.008 +openvix: developer 6.4.009.009 +openvix: developer 6.4.009.010 +openvix: developer 6.4.009.011 +openvix: developer 6.4.009.012 +openvix: developer 6.4.009.013 +openvix: developer 6.4.009.014 +openvix: developer 6.4.009.015 +openvix: developer 6.4.010.001 +openvix: developer 6.4.010.002 +openvix: developer 6.4.010.003 +openvix: developer 6.4.010.004 +openvix: developer 6.4.010.005 +openvix: developer 6.4.010.006 +openvix: developer 6.4.010.007 +openvix: developer 6.4.010.008 +openvix: developer 6.4.010.009 +openvix: developer 6.4.010.010 +openvix: developer 6.4.010.011 +openvix: developer 6.4.010.012 +openvix: developer 6.4.010.013 +openvix: developer 6.4.010.014 +openvix: developer 6.4.010.015 +openvix: developer 6.4.010.016 +openvix: developer 6.4.010.017 +openvix: developer 6.4.010.018 +openvix: developer 6.4.010.019 +openvix: developer 6.4.011.001 +openvix: developer 6.4.011.002 +openvix: developer 6.4.011.003 +openvix: developer 6.4.011.004 +openvix: developer 6.4.011.005 +openvix: developer 6.4.011.006 +openvix: developer 6.4.011.007 +openvix: developer 6.4.011.008 diff --git a/README.md b/README.md index 1a2c7dd4de1..669570b590b 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ 1 - Install packages on your buildserver - sudo apt-get install -y autoconf automake bison bzip2 chrpath coreutils cpio curl cvs debianutils default-jre default-jre-headless diffstat flex g++ gawk gcc gcc-12 gcc-multilib g++-multilib gettext git git-core gzip help2man info iputils-ping java-common libc6-dev libegl1-mesa libglib2.0-dev libncurses5-dev libperl4-corelibs-perl libproc-processtable-perl libsdl1.2-dev libserf-dev libtool libxml2-utils make ncurses-bin patch perl pkg-config psmisc python3 python3-git python3-jinja2 python3-pexpect python3-pip python-setuptools qemu quilt socat sshpass subversion tar texi2html texinfo unzip wget xsltproc xterm xz-utils zip zlib1g-dev zstd fakeroot lz4 + sudo apt-get install -y autoconf automake bison bzip2 chrpath coreutils cpio curl cvs debianutils default-jre default-jre-headless diffstat flex g++ gawk gcc gcc-12 gcc-multilib g++-multilib gettext git git-core gzip help2man info iputils-ping java-common libc6-dev libegl1-mesa libglib2.0-dev libncurses5-dev libperl4-corelibs-perl libproc-processtable-perl libsdl1.2-dev libserf-dev libtool libxml2-utils make ncurses-bin patch perl pkg-config psmisc python3 python3-git python3-jinja2 python3-pexpect python3-pip python-setuptools qemu quilt socat sshpass subversion tar texi2html texinfo unzip wget xsltproc xterm xz-utils zip zlib1g-dev zstd fakeroot lz4 liblz4-tool ---------- 2 - Set python3 as preferred provider for python diff --git a/configure.ac b/configure.ac index d9fbfb8d3bd..0df4240158a 100644 --- a/configure.ac +++ b/configure.ac @@ -554,8 +554,7 @@ AC_CHECK_FUNCS([klogctl]) ENIGMA2_CFLAGS="-fno-rtti -fno-exceptions -rdynamic -funwind-tables" AC_SUBST(ENIGMA2_CFLAGS) -AX_CXX_COMPILE_STDCXX_17([ext],[mandatory]) - +AX_CXX_COMPILE_STDCXX([17], [ext], [mandatory]) AX_CHECK_COMPILE_FLAG([-Wattribute-alias], [CXXFLAGS="$CXXFLAGS -Wattribute-alias"]) AX_CHECK_COMPILE_FLAG([-Wattribute-alias=1], [CXXFLAGS="$CXXFLAGS -Wattribute-alias=1"]) diff --git a/data/menu.xml b/data/menu.xml index 1c4f8de43b8..4183ed88ea3 100644 --- a/data/menu.xml +++ b/data/menu.xml @@ -120,7 +120,7 @@ self.session.openWithCallback(msgClosed, EpgDeleteMsg) - + @@ -144,16 +144,15 @@ self.session.open(SABnzbdSetupScreen) - - + + + + - - - @@ -163,7 +162,8 @@ self.session.open(SABnzbdSetupScreen) - + + diff --git a/data/setup.xml b/data/setup.xml index 79a0f241d54..09630474781 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -22,14 +22,17 @@ config.streaming.stream_ecm config.streaming.descramble config.streaming.descramble_client - config.misc.softcam_streamrelay_url - config.misc.softcam_streamrelay_port config.streaming.authentication config.usage.http_startdelay config.usage.wakeOnLAN config.misc.usegstplaybin3 config.misc.RCSource + + config.misc.softcam_streamrelay_url + config.misc.softcam_streamrelay_port + config.misc.softcam_streamrelay_delay + config.usage.output_12V config.usage.frontend_priority @@ -51,11 +54,12 @@ config.usage.infobar_timeout config.usage.show_second_infobar - config.usage.second_infobar_simple + config.usage.second_infobar_simple config.usage.show_infobar_do_dimming config.usage.show_infobar_dimming_speed config.vixsettings.InfoBarEpg_mode config.usage.show_spinner + config.usage.enable_blinking config.usage.jobtaskextensions config.usage.showdish config.misc.showrotorposition @@ -106,12 +110,12 @@ config.usage.panicbutton config.usage.hide_number_markers config.usage.show_channel_jump_in_servicelist - config.usage.show_event_progress_in_servicelist + config.usage.servicelist_twolines + config.usage.show_event_progress_in_servicelist config.usage.show_channel_numbers_in_servicelist - config.usage.servicelist_twolines - config.usage.crypto_icon_mode - config.usage.servicetype_icon_mode - config.usage.record_indicator_mode + config.usage.crypto_icon_mode + config.usage.servicetype_icon_mode + config.usage.record_indicator_mode config.usage.service_icon_enable config.usage.servicelist_column config.usage.serviceitems_per_page @@ -195,26 +199,37 @@ config.autolanguage.audio_epglanguage config.autolanguage.audio_epglanguage_alternative - + config.usage.default_path - config.usage.timer_path - config.usage.instantrec_path - config.recording.setstreamto1 + config.usage.timer_path + config.usage.instantrec_path + + config.recording.setstreamto1 - config.recording.asktozap - config.recording.margin_before - config.recording.margin_after - config.recording.split_programme_minutes - config.usage.show_message_when_recording_starts - config.usage.leave_movieplayer_onExit + config.recording.asktozap + config.recording.margin_before + config.recording.margin_after + config.recording.split_programme_minutes + config.usage.show_message_when_recording_starts + config.recording.ascii_filenames + config.recording.filename_composition + config.usage.timerlist_showpicons + config.usage.timerlist_finished_timer_position + config.recording.keep_timers + config.recording.keep_finished_timer_logs + config.recording.ecm_data + config.recording.record_icon_match + + + config.usage.on_movie_start config.usage.on_movie_stop config.usage.on_movie_eof - config.usage.next_movie_msg - config.seek.on_pause config.seek.selfdefined_13 config.seek.selfdefined_46 config.seek.selfdefined_79 + config.usage.leave_movieplayer_onExit + config.seek.on_pause config.seek.baractivation config.seek.sensibility config.seek.speeds_forward @@ -222,14 +237,9 @@ config.seek.speeds_slowmotion config.seek.enter_forward config.seek.enter_backward - config.recording.ascii_filenames - config.recording.filename_composition - config.usage.timerlist_showpicons - config.usage.timerlist_finished_timer_position - config.recording.keep_timers - config.recording.keep_finished_timer_logs + config.usage.next_movie_msg config.recording.offline_decode_delay - config.recording.ecm_data + config.usage.hdd_standby @@ -344,12 +354,14 @@ config.usage.timeshift_path - config.timeshift.startdelay - config.usage.check_timeshift - config.timeshift.favoriteSaveAction - config.timeshift.stopwhilerecording - config.timeshift.showinfobar - config.usage.timeshift_skipreturntolive + + config.timeshift.startdelay + config.usage.check_timeshift + config.timeshift.favoriteSaveAction + config.timeshift.stopwhilerecording + config.timeshift.showinfobar + config.usage.timeshift_skipreturntolive + config.epgselection.sort diff --git a/doc/AUTOMATICBUTTONS b/doc/AUTOMATICBUTTONS new file mode 100644 index 00000000000..fdefc5cf5b8 --- /dev/null +++ b/doc/AUTOMATICBUTTONS @@ -0,0 +1,98 @@ +Automatic button bar +==================== + +There are two parts to this. + 1) The colour button bar, which shows a combination of graphic and text. + 2) Action button graphics that advise the user of availability of certain buttons (e.g. MENU, HELP, INFO, TEXT, etc). + +For each of the above types we just add one simple widget to our main template in skin.xml and the buttons appear +in the screens correctly as if we had added them manually to every single screen. + +========================================================================================================================================================================= + +1) Colour buttons. Add the following widget to skin.xml (in the main template or similar). + + + +Attributes: + connection: comma separated list of the buttons this widget will control. + pixmaps: comma separated list that contains "key_name" then a ":" then the path to the graphic to be used. + spacing: is the spacing between the text and the next button. + spacingPixmapText: is the spacing between the graphic and the text. + +By default the foreground text color will be the same as the default listbox text color. But this can be altered for each +button with the "textColors" attribute. + textColors="key_red:buttonred,key_green:buttongreen,key_yellow:buttonyellow,key_blue:buttonblue" + textColors: comma separated list that contains "key_name" then a ":" then the name the color to be used. Color names as declared in the section of skin.xml. + +Example widget with colored text: + + + +It is also possible to have colored text and no graphics: + + + +========================================================================================================================================================================= + +2) Action buttons. Add the following widget to skin.xml (in the main template or similar). + + + +Attributes: + connection: comma separated list of the buttons this widget will control. + pixmaps: comma separated list that contains "key_name" then a ":" then the path to the graphic to be used. + spacing: is the spacing between the text and the next button. + +In "connection" and "pixmap" add the buttons you want this widget to display. + +There must be hooks in the Python code for the buttons to display. Hooks look like the following: + +self["key_menu"] = StaticText(_("MENU")) +self["key_previous"] = StaticText(_("PREVIOUS")) +self["key_next"] = StaticText(_("NEXT")) + +========================================================================================================================================================================= diff --git a/doc/BOXINFO_BOXBRANDING b/doc/BOXINFO_BOXBRANDING new file mode 100644 index 00000000000..481eb4b55d4 --- /dev/null +++ b/doc/BOXINFO_BOXBRANDING @@ -0,0 +1,29 @@ +getBoxType = boxtype (only in OpenViX) +getBrandOEM = brand +getDisplayType = displaytype +getHaveAVJACK = avjack +getHaveHDMIinFHD = hdmifhdin +getHaveHDMIinHD = hdmihdin +getHaveRCA = rca +getHaveSCART = scart +getHaveSCARTYUV = scartyuv +getHaveYUV = yuv +getImageType = imagetype +getMachineBrand = displaybrand +getMachineBuild = model +getMachineMtdRoot = mtdrootfs +getMachineName = machinename (only in OpenViX) or MachineName +getDriverDate = driversdate +getImageDistro = distro +getDisplayType = displaytype +getFeedsUrl = feedsurl +getImageBuild = imagebuild +getImageVersion = imageversion +getMachineMake = machinebuild +getImageDevBuild = imagedevbuild +getImageFolder = imagedir +getImageFileSystem = imagefs +getMachineMtdKernel = mtdkernel +getMachineKernelFile = kernelfile +getMachineUBINIZE = ubinize +getMachineMKUBIFS = mkubifs diff --git a/doc/BUTTONGUIDE b/doc/BUTTONGUIDE index 279d475a7fe..83e0073ef9a 100644 --- a/doc/BUTTONGUIDE +++ b/doc/BUTTONGUIDE @@ -4,6 +4,14 @@ Proposal for Standardised and Uniform Buttons in Enigma2 Written by IanSav - 12-Feb-2018 Updated by IanSav - 14-Feb-2018 +PLEASE NOTE: +============ + +01-Nov-2023 + +For fully automatic buttons controlled by one simple widget using StaticText, +Label or Button modules please see the AUTOMATICBUTTONS document. + INTRODUCTION: ============= diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index a6f3df4a143..fa9a705acbd 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -17,6 +17,7 @@ #include #include #include +#include /* * Copyright (C) 2017 Marcus Metzler @@ -221,6 +222,20 @@ bool eDVBService::isCrypted() int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { + bool isStreamRelayService = false; + eServiceReferenceDVB sRelayOrigSref; + ePtr refCur; + eNavigation::getInstance()->getCurrentService(refCur); + if (refCur) { + ePtr tmp_info; + refCur->info(tmp_info); + std::string ref_s = tmp_info->getInfoString(iServiceInformation::sServiceref); + eServiceReferenceDVB currentlyPlaying = eServiceReferenceDVB(ref_s); + isStreamRelayService = currentlyPlaying.getSROriginal(sRelayOrigSref); + } else { + return 1; + } + ePtr res_mgr; bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false); @@ -228,13 +243,19 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc eDebug("[eDVBService] isPlayble... no res manager!!"); else { - eDVBChannelID chid, chid_ignore; + eDVBChannelID chid, chid_ignore, chid_ignore_sr; int system; ((const eServiceReferenceDVB&)ref).getChannelID(chid); ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); - if (res_mgr->canAllocateChannel(chid, chid_ignore, system, simulate)) + if (isStreamRelayService) { + sRelayOrigSref.getChannelID(chid_ignore_sr); + } else { + chid_ignore_sr = eDVBChannelID(); + } + + if (res_mgr->canAllocateChannel(chid, chid_ignore, chid_ignore_sr, system, simulate)) { bool use_ci_assignment = eConfigManager::getConfigBoolValue("config.misc.use_ci_assignment", false); if (use_ci_assignment) diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 7055212132f..eda003b5a4d 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -1440,7 +1440,7 @@ int tuner_type_channel_default(ePtr &channellist, const eDVBCha return 0; } -int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, int &system, bool simulate) +int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, const eDVBChannelID& ignoresr, int &system, bool simulate) { std::list &active_channels = simulate ? m_active_simulate_channels : m_active_channels; int ret = 0; @@ -1448,8 +1448,9 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons if (!simulate && m_cached_channel) { eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel); - if(channelid==cache_chan->getChannelID()) + if(channelid==cache_chan->getChannelID()) { return tuner_type_channel_default(m_list, channelid, system); + } } /* first, check if a channel is already existing. */ @@ -1471,6 +1472,7 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons std::vector fcc_decremented_fe_usecounts; std::map fcc_chids; int apply_to_ignore = 0; + int apply_to_ignoresr = 0; if (!eFCCServiceManager::getFCCChannelID(fcc_chids)) { for (std::map::iterator i(fcc_chids.begin()); i != fcc_chids.end(); ++i) @@ -1517,6 +1519,18 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons } } + // For stream relayed channel make a check is it in the available channels and if it is ignore it + if (ignoresr) { + for (std::list::iterator i(active_channels.begin()); i != active_channels.end(); ++i) + { + if (i->m_channel_id == ignoresr) + { + apply_to_ignoresr = 1; + break; + } + } + } + for (std::list::iterator i(active_channels.begin()); i != active_channels.end(); ++i) { eSmartPtrList &frontends = simulate ? m_simulate_frontend : m_frontend; @@ -1530,6 +1544,7 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons // or 2 when the cached channel is not equal to the compared channel int check_usecount = channel == &(*m_cached_channel) ? 1 : 0; check_usecount += (apply_to_ignore+1) * 2; // one is used in eDVBServicePMTHandler and another is used in eDVBScan. + check_usecount += apply_to_ignoresr; //eDebug("[eDVBResourceManager] canAllocateChannel channel->getUseCount() : %d , check_usecount : %d (cached : %d)", channel->getUseCount(), check_usecount, channel == &(*m_cached_channel)); if (channel->getUseCount() == check_usecount) // channel only used once..(except fcc) { diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index 238c37d302e..3909c7a9099 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -216,7 +216,7 @@ class eDVBResourceManager: public iObject, public sigc::trackable }; RESULT connectChannelAdded(const sigc::slot &channelAdded, ePtr &connection); - int canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID &ignore, int &system, bool simulate=false); + int canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID &ignore, const eDVBChannelID& ignoresr, int &system, bool simulate=false); /* allocate channel... */ RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr &channel, bool simulate=false); diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 874f247e5ac..ed6977836d4 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -1360,9 +1360,9 @@ void eDVBFrontend::calculateSignalQuality(int snr, int &signalquality, int &sign ret = snr; sat_max = 1620; } - else if (!strcmp(m_description, "Vuplus DVB-S NIM(Si2166)")) // VU+ Zero4K + else if (!strcmp(m_description, "Vuplus DVB-S NIM(SI2166)")) // VU+ Zero4K { - ret = snr; + ret = snr / 40; } else if (!strncmp(m_description, "Si216", 5)) // New models with SI tuners { diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index d6a89945206..9c2fdcc87e0 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -12,6 +12,8 @@ #include #include #include +#include // access to python config +#include #define CAID_LIST std::list @@ -249,6 +251,24 @@ class eServiceReferenceDVB: public eServiceReference chid = eDVBChannelID(getDVBNamespace(), getTransportStreamID(), getOriginalNetworkID()); } + bool getSROriginal(eServiceReferenceDVB &sref) const + { + std::string s_ref = this->toString(); + std::string sr_url = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_url"); + sr_url = replace_all(replace_all(replace_all(sr_url, "[", ""), "]", ""), ", ", "."); + std::string sr_port = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_port"); + if (s_ref.find(sr_url + "%3a" + sr_port) != std::string::npos) { + std::vector s_split = split(s_ref, ":"); + std::string url_sr = s_split[s_split.size() - 2]; + std::vector sr_split = split(url_sr, "/"); + std::string ref_orig = sr_split.back(); + ref_orig = replace_all(ref_orig, "%3a", ":"); + sref = eServiceReferenceDVB(ref_orig); + return true; + } + return false; + } + eServiceReferenceDVB() :eServiceReference(eServiceReference::idDVB, 0) { diff --git a/lib/dvb/metaparser.h b/lib/dvb/metaparser.h index 8614f1a8199..45055a80617 100644 --- a/lib/dvb/metaparser.h +++ b/lib/dvb/metaparser.h @@ -40,7 +40,7 @@ class eDVBMetaParser eServiceReferenceDVB m_ref; int m_data_ok, m_time_create, m_packet_size, m_scrambled; - std::string m_name, m_description, m_tags, m_service_data; + std::string m_name, m_description, m_tags, m_service_data, m_prov; long long m_filesize, m_length; }; #endif diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index b8c8da42944..fb7ea7e254e 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -795,7 +795,11 @@ int eDVBServicePMTHandler::compareAudioSubtitleCode(const std::string &subtitleT int eDVBServicePMTHandler::getChannel(eUsePtr &channel) { - channel = m_channel; + if (m_sr_channel) { + channel = m_sr_channel; + } else { + channel = m_channel; + } if (channel) return 0; else @@ -955,6 +959,29 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, ePtr &s if (!simulate) { + // If is stream relay service then allocate the real channel so to provide correct frontend info + eDVBChannelID chid; + eServiceReferenceDVB sRelayOrigSref; + bool isStreamRelay = ref.getSROriginal(sRelayOrigSref); + + if (isStreamRelay) { + sRelayOrigSref.getChannelID(chid); + res = m_resourceManager->allocateChannel(chid, m_sr_channel, simulate); + } + + + if (m_sr_channel) { + m_sr_channel->connectStateChange( + sigc::mem_fun(*this, &eDVBServicePMTHandler::channelStateChanged), + m_channelStateChanged_connection); + m_last_channel_state = -1; + channelStateChanged(m_sr_channel); + + m_sr_channel->connectEvent( + sigc::mem_fun(*this, &eDVBServicePMTHandler::channelEvent), + m_channelEvent_connection); + } + if (m_channel) { m_channel->connectStateChange( diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index b9aec9a0cd3..f86d96ef490 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -57,6 +57,7 @@ class eDVBServicePMTHandler: public eDVBPMTParser eAUTable > m_OC; eUsePtr m_channel; + eUsePtr m_sr_channel; eUsePtr m_pvr_channel; ePtr m_resourceManager; ePtr m_demux, m_pvr_demux_tmp; diff --git a/lib/dvb_ci/descrambler.cpp b/lib/dvb_ci/descrambler.cpp index b89b55db55d..f7fea6ccfc7 100644 --- a/lib/dvb_ci/descrambler.cpp +++ b/lib/dvb_ci/descrambler.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include #ifndef CA_SET_PID @@ -38,33 +40,94 @@ struct ca_descr_data { unsigned char *data; }; +struct vu_ca_descr_data { + int slot_id; + int fix1; // = 0x6f7c + int demux_id; + int tunernum; + int use_count; + int program_number; + int reserved1; + int fix2; // = 0x1 -> add pids + int video_pid; + int audio_pid; + int reserved2; + int fix3; // = 0x12345678 + int reserved3; + int key_register; + int use_aes; // 0x2 for AES + unsigned char key[16]; + unsigned char iv[16]; + int audio_number; + int audio_pids[16]; +}; + #define CA_SET_DESCR_DATA _IOW('o', 137, struct ca_descr_data) -int descrambler_set_key(int desc_fd, int index, int parity, unsigned char *data) +int descrambler_set_key(int& desc_fd, eDVBCISlot *slot, int parity, unsigned char *data) { - struct ca_descr_data d; - - d.index = index; - d.parity = (enum ca_descr_parity)parity; - d.data_type = CA_DATA_KEY; - d.length = 16; - d.data = data; - - if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { - eWarning("[CI descrambler] set key failed"); - return -1; + bool vuIoctlSuccess = false; + + if (slot->getTunerNum() > 7) // might be VU box with 2 FBC tuners -> try to use VU ioctl + { + struct vu_ca_descr_data d; + + d.slot_id = slot->getSlotID(); + d.fix1 = 0x6f7c; + d.demux_id = slot->getCADemuxID(); + d.tunernum = slot->getTunerNum(); + d.use_count = slot->getUseCount(); + d.program_number = slot->getProgramNumber(); + d.fix2 = 0x1; + d.video_pid = slot->getVideoPid(); + d.audio_pid = slot->getAudioPid(); + d.fix3 = 0x12345678; + d.key_register = parity; + d.use_aes = 0x2; // AES + memcpy(d.key, data, 16); + memcpy(d.iv, data + 16, 16); + d.audio_number = slot->getAudioNumber(); + memcpy(d.audio_pids, slot->getAudioPids(), 16*4); + + unsigned int ret = ioctl(slot->getFd(), 0x10, &d); + if (ret == 0) + { + vuIoctlSuccess = true; + descrambler_deinit(desc_fd); // don't set pids for VU ioctl + desc_fd = -1; + } + eDebug("[CI%d] descrambler_set_key vu ret %u", slot->getSlotID(), ret); } - d.index = index; - d.parity = (enum ca_descr_parity)parity; - d.data_type = CA_DATA_IV; - d.length = 16; - d.data = data + 16; - - if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { - eWarning("[CI descrambler] set iv failed"); - return -1; + if (!vuIoctlSuccess) + { + struct ca_descr_data d; + + if (desc_fd < 0) + return -1; + + d.index = slot->getSlotID(); + d.parity = (enum ca_descr_parity)parity; + d.data_type = CA_DATA_KEY; + d.length = 16; + d.data = data; + + if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { + eWarning("[CI%d descrambler] set key failed", slot->getSlotID()); + return -1; + } + + d.index = slot->getSlotID(); + d.parity = (enum ca_descr_parity)parity; + d.data_type = CA_DATA_IV; + d.length = 16; + d.data = data + 16; + + if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { + eWarning("[CI%d descrambler] set iv failed", slot->getSlotID()); + return -1; + } } return 0; @@ -75,6 +138,9 @@ int descrambler_set_pid(int desc_fd, int index, int enable, int pid) struct ca_pid p; unsigned int flags = 0x80; + if (desc_fd < 0) + return -1; + if (index) flags |= 0x40; @@ -85,27 +151,31 @@ int descrambler_set_pid(int desc_fd, int index, int enable, int pid) p.index = flags; if (ioctl(desc_fd, CA_SET_PID, &p) == -1) { - eWarning("[CI descrambler] set pid failed"); + eWarning("[CI%d descrambler] set pid failed", index); return -1; } return 0; } -int descrambler_init(void) +int descrambler_init(int slot, uint8_t ca_demux_id) { int desc_fd; - const char *filename = "/dev/dvb/adapter0/ca0"; - desc_fd = open(filename, O_RDWR); + std::string filename = "/dev/dvb/adapter0/ca" + std::to_string(ca_demux_id); + + desc_fd = open(filename.c_str(), O_RDWR); if (desc_fd == -1) { - eWarning("[CI descrambler] can not open %s", filename); + eWarning("[CI%d descrambler] can not open %s", slot, filename.c_str()); } + eDebug("[CI%d descrambler] using ca device %s", slot, filename.c_str()); return desc_fd; } void descrambler_deinit(int desc_fd) { - close(desc_fd); + if (desc_fd >= 0) + close(desc_fd); + desc_fd = -1; } diff --git a/lib/dvb_ci/descrambler.h b/lib/dvb_ci/descrambler.h index 85e6c56393d..dfd3213d553 100644 --- a/lib/dvb_ci/descrambler.h +++ b/lib/dvb_ci/descrambler.h @@ -1,9 +1,11 @@ #ifndef __DESCR_H_ #define __DESCR_H_ -int descrambler_init(void); +#include + +int descrambler_init(int slot, uint8_t ca_demux_id); void descrambler_deinit(int desc_fd); -int descrambler_set_key(int desc_fd, int index, int parity, unsigned char *data); +int descrambler_set_key(int& desc_fd, eDVBCISlot *slot, int parity, unsigned char *data); int descrambler_set_pid(int desc_fd, int index, int enable, int pid); #endif diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 42b59b69ccd..ef2955fb315 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -115,8 +115,6 @@ eDVBCIInterfaces::eDVBCIInterfaces() eDebug("[CI] Streaming CI finish interface not advertised, assuming \"tuner\" method"); } } - m_ciplus_routing_active = false; - m_ciplus_routing_tunernum = -1; run(); } @@ -626,6 +624,7 @@ void eDVBCIInterfaces::recheckPMTHandlers() ci_it->linked_next->setSource(ci_source.str()); } it->cislot = ci_it; + it->cislot->setCamMgrRoutingActive(true); eTrace("[CI] assigned!"); gotPMT(pmthandler); } @@ -789,7 +788,10 @@ void eDVBCIInterfaces::gotPMT(eDVBServicePMTHandler *pmthandler) { eTrace("[CI] check slot %d %d %d", tmp->getSlotID(), tmp->running_services.empty(), canDescrambleMultipleServices(tmp)); if (tmp->running_services.empty() || canDescrambleMultipleServices(tmp)) + { + tmp->setCaParameter(pmthandler); tmp->sendCAPMT(pmthandler); + } tmp = tmp->linked_next; } } @@ -1049,6 +1051,10 @@ int eDVBCIInterfaces::setCIClockRate(int slotid, const std::string &rate) (with correct caid) */ void eDVBCIInterfaces::setCIPlusRouting(int slotid) { + int ciplus_routing_tunernum; + std::string ciplus_routing_input; + std::string ciplus_routing_ci_input; + eDebug("[CI] setCIRouting slotid=%d", slotid); singleLock s(m_pmt_handler_lock); if (m_pmt_handlers.size() == 0) @@ -1056,12 +1062,14 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) eDebug("[CI] setCIRouting no pmt handler available! Unplug/plug again the CI module."); return; } - if (m_ciplus_routing_active) + + eDVBCISlot *slot = getSlot(slotid); + if (slot->isCamMgrRoutingActive()) // CamMgr has already set up routing. Don't change that. { - eDebug("[CI] setCIRouting authentification of other module active. Unplug/plug again the CI module after first authentification was successful."); + eDebug("[CI] CamMgrRouting is active -> return"); return; } - eDVBCISlot *slot = getSlot(slotid); + PMTHandlerList::iterator it = m_pmt_handlers.begin(); while (it != m_pmt_handlers.end()) { @@ -1080,6 +1088,8 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) if (tunernum < 0) continue; + ciplus_routing_tunernum = slot->getCIPlusRoutingTunerNum(); + // read and store old routing config char file_name[64]; char tmp[8]; @@ -1092,8 +1102,8 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) rd = read(fd, tmp, 8); if (rd > 0) { - if (m_ciplus_routing_tunernum != tunernum) - m_ciplus_routing_input = std::string(tmp, rd-1); + if (ciplus_routing_tunernum != tunernum) + ciplus_routing_input = std::string(tmp, rd-1); } else continue; @@ -1109,8 +1119,8 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) rd = read(fd, tmp, 8); if (rd > 0) { - if (m_ciplus_routing_tunernum != tunernum) - m_ciplus_routing_ci_input = std::string(tmp, rd-1); + if (ciplus_routing_tunernum != tunernum) + ciplus_routing_ci_input = std::string(tmp, rd-1); } else continue; @@ -1125,30 +1135,35 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) setInputSource(tunernum, new_input_source.str()); slot->setSource(eDVBCISlot::getTunerLetter(tunernum)); - m_ciplus_routing_tunernum = tunernum; - m_ciplus_routing_active = true; + slot->setCIPlusRoutingParameter(tunernum, ciplus_routing_input, ciplus_routing_ci_input); + eDebug("[CI] CIRouting active slotid=%d tuner=%d old_input=%s old_ci_input=%s", slotid, tunernum, ciplus_routing_input.c_str(), ciplus_routing_ci_input.c_str()); break; ++it; } - eDebug("[CI] setCIRouting slotid=%d tuner=%d old_input=%s old_ci_input=%s", slotid, m_ciplus_routing_tunernum, m_ciplus_routing_input.c_str(), m_ciplus_routing_ci_input.c_str()); } void eDVBCIInterfaces::revertCIPlusRouting(int slotid) { eDVBCISlot *slot = getSlot(slotid); - eDebug("[CI] revertCIPlusRouting: active=%d slot=%d tuner=%d input=%s ci_input=%s", m_ciplus_routing_active, slotid, m_ciplus_routing_tunernum, m_ciplus_routing_input.c_str(), m_ciplus_routing_ci_input.c_str()); + int ciplus_routing_tunernum = slot->getCIPlusRoutingTunerNum(); + std::string ciplus_routing_input = slot->getCIPlusRoutingInput(); + std::string ciplus_routing_ci_input = slot->getCIPlusRoutingCIInput(); - if(m_ciplus_routing_active) + eDebug("[CI] revertCIPlusRouting: camMgrActive=%d ciRoutingActive=%d slot=%d tuner=%d input=%s ci_input=%s", slot->isCamMgrRoutingActive(), slot->ciplusRoutingDone(), slotid, ciplus_routing_tunernum, ciplus_routing_input.c_str(), ciplus_routing_ci_input.c_str()); + + if (slot->isCamMgrRoutingActive() || // CamMgr has set up routing. Don't revert that. + slot->ciplusRoutingDone()) // need to only run once during CI initialization { - slot->setSource(m_ciplus_routing_ci_input); - setInputSource(m_ciplus_routing_tunernum, m_ciplus_routing_input); + slot->setCIPlusRoutingDone(); + return; } - m_ciplus_routing_active = false; - m_ciplus_routing_tunernum = -1; - m_ciplus_routing_input = ""; - m_ciplus_routing_ci_input = ""; + + slot->setSource(ciplus_routing_ci_input); + setInputSource(ciplus_routing_tunernum, ciplus_routing_input); + + slot->setCIPlusRoutingDone(); } int eDVBCISlot::send(const unsigned char *data, size_t len) @@ -1156,7 +1171,7 @@ int eDVBCISlot::send(const unsigned char *data, size_t len) singleLock s(eDVBCIInterfaces::m_slot_lock); int res=0; unsigned int i; - eTraceNoNewLineStart("< "); + eTraceNoNewLineStart("[CI%d] < ", slotid); for(i = 0; i < len; i++) eTraceNoNewLine("%02x ",data[i]); eTraceNoNewLine("\n"); @@ -1178,7 +1193,7 @@ int eDVBCISlot::send(const unsigned char *data, size_t len) void eDVBCISlot::data(int what) { singleLock s(eDVBCIInterfaces::m_slot_lock); - eTrace("[CI] Slot %d what %d\n", getSlotID(), what); + eTrace("[CI%d] what %d\n", slotid, what); if(what == eSocketNotifier::Priority) { if(state != stateRemoved) { state = stateRemoved; @@ -1199,7 +1214,7 @@ void eDVBCISlot::data(int what) reset(); if(state != stateInserted) { - eDebug("[CI] ci inserted in slot %d", getSlotID()); + eDebug("[CI%d] ci inserted", slotid); state = stateInserted; /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::slotStateChanged, getSlotID(), 1)); notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority); @@ -1212,7 +1227,7 @@ void eDVBCISlot::data(int what) r = ::read(fd, data, 4096); if(r > 0) { int i; - eTraceNoNewLineStart("> "); + eTraceNoNewLineStart("[CI%d] > ", slotid); for(i=0;i= 0) @@ -1342,13 +1361,13 @@ void eDVBCISlot::determineCIVersion() char lv1Info[256] = { 0 }; if (ioctl(fd, 1, lv1Info) < 0) { - eTrace("[CI] Slot %d ioctl not supported: assume CI+ version 1", getSlotID()); + eTrace("[CI%d] ioctl not supported: assume CI+ version 1", slotid); m_ci_version = versionCIPlus1; return; } if (strlen(lv1Info) == 0) { - eTrace("[CI] Slot %d no LV1 info: assume CI+ version 1", getSlotID()); + eTrace("[CI%d] no LV1 info: assume CI+ version 1", slotid); m_ci_version = versionCIPlus1; return; } @@ -1371,12 +1390,12 @@ void eDVBCISlot::determineCIVersion() } if(!compatId) { - eTrace("[CI] Slot %d CI CAM detected", getSlotID()); + eTrace("[CI%d] CI CAM detected", slotid); m_ci_version = versionCI; return; } - eTrace("[CI] Slot %d CI+ compatibility ID: %s", getSlotID(), compatId); + eTrace("[CI%d] CI+ compatibility ID: %s", slotid, compatId); char *label, *id, flag = '+'; int version = versionCI; @@ -1393,7 +1412,7 @@ void eDVBCISlot::determineCIVersion() flag = *id++; version = strtol(id, 0, 0); - eDebug("[CI] Slot %d CI+ %c%d CAM detected", getSlotID(), flag, version); + eDebug("[CI%d] CI+ %c%d CAM detected", slotid, flag, version); break; } } @@ -1408,14 +1427,21 @@ int eDVBCISlot::getNumOfServices() return running_services.size(); } +void eDVBCISlot::setCIPlusRoutingParameter(int tunernum, std::string ciplus_routing_input, std::string ciplus_routing_ci_input) +{ + m_ciplus_routing_tunernum = tunernum; + m_ciplus_routing_input = ciplus_routing_input; + m_ciplus_routing_ci_input = ciplus_routing_ci_input; +} + int eDVBCISlot::reset() { - eDebug("[CI] Slot %d: reset requested", getSlotID()); + eDebug("[CI%d] reset requested", slotid); if (state == stateInvalid) { unsigned char buf[256]; - eDebug("[CI] flush"); + eDebug("[CI%d] flush", slotid); while(::read(fd, buf, 256)>0); state = stateResetted; } @@ -1433,7 +1459,7 @@ int eDVBCISlot::reset() int eDVBCISlot::startMMI() { - eDebug("[CI] Slot %d: startMMI()", getSlotID()); + eDebug("[CI%d] startMMI()", slotid); if(application_manager) application_manager->startMMI(); @@ -1443,7 +1469,7 @@ int eDVBCISlot::startMMI() int eDVBCISlot::stopMMI() { - eDebug("[CI] Slot %d: stopMMI()", getSlotID()); + eDebug("[CI%d] stopMMI()", slotid); if(mmi_session) mmi_session->stopMMI(); @@ -1453,7 +1479,7 @@ int eDVBCISlot::stopMMI() int eDVBCISlot::answerText(int answer) { - eDebug("[CI] Slot %d: answerText(%d)", getSlotID(), answer); + eDebug("[CI%d] answerText(%d)", slotid, answer); if(mmi_session) mmi_session->answerText(answer); @@ -1471,7 +1497,7 @@ int eDVBCISlot::getMMIState() int eDVBCISlot::answerEnq(char *value) { - eDebug("[CI] Slot %d: answerENQ(%s)", getSlotID(), value); + eDebug("[CI%d] answerENQ(%s)", slotid, value); if(mmi_session) mmi_session->answerEnq(value); @@ -1481,7 +1507,7 @@ int eDVBCISlot::answerEnq(char *value) int eDVBCISlot::cancelEnq() { - eDebug("[CI] Slot %d: cancelENQ", getSlotID()); + eDebug("[CI%d] cancelENQ", slotid); if(mmi_session) mmi_session->cancelEnq(); @@ -1489,11 +1515,67 @@ int eDVBCISlot::cancelEnq() return 0; } +int eDVBCISlot::setCaParameter(eDVBServicePMTHandler *pmthandler) +{ + ePtr demux; + eDVBServicePMTHandler::program program; + eServiceReferenceDVB ref; + uint8_t dmx_id; + eUsePtr channel; + ePtr frontend; + + eDebug("[CI%d] setCaParameter", slotid); + + if (!pmthandler->getDataDemux(demux)) + { + if (!demux->getCADemuxID(dmx_id)) + { + m_ca_demux_id = dmx_id; + eDebug("[CI%d] CA demux_id = %d", slotid, m_ca_demux_id); + } + else + m_ca_demux_id = -1; + } + + pmthandler->getServiceReference(ref); + m_program_number = ref.getServiceID().get(); + + pmthandler->getProgramInfo(program); + m_audio_number = program.audioStreams.size(); + + if (m_audio_number > 16) + m_audio_number = 16; + for(int i = 0; i < m_audio_number ; i++) + { + m_audio_pids[i] = program.audioStreams[i].pid; + } + + m_video_pid = program.videoStreams.empty()? 0 : program.videoStreams[0].pid; + m_audio_pid = program.audioStreams.empty()? 0 : program.audioStreams[program.defaultAudioStream].pid; + + m_tunernum = -1; + if (!pmthandler->getChannel(channel)) + { + if (!channel->getFrontend(frontend)) + { + eDVBFrontend *fe = (eDVBFrontend*) &(*frontend); + m_tunernum = fe->getSlotID(); + if (m_tunernum > 7 && !fe->is_FBCTuner()) // use vu ioctl only for second FBC tuner + { + m_tunernum = -1; + } + } + eDebug("[CI%d] tunernum = %d", slotid, m_tunernum); + } + + return 0; +} + int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vector &ids) { if (!ca_manager) { - eDebug("[CI] no ca_manager (no CI plugged?)"); + eDebug("[CI%d] no ca_manager (no CI plugged?)", slotid); return -1; } const std::vector &caids = ids.empty() ? ca_manager->getCAIDs() : ids; @@ -1517,7 +1599,7 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vectorsecond) && !sendEmpty ) { - eDebug("[CI] [eDVBCISlot] dont send self capmt version twice"); + eDebug("[CI%d] dont send self capmt version twice", slotid); return -1; } @@ -1528,15 +1610,15 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vectorgetSections().end() ) { - // eDebug("[CI] append"); + // eDebug("[CI%d] append", slotid); capmt.append(*i++); } capmt.writeToBuffer(raw_data); @@ -1564,7 +1646,7 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vector &caids=std::vector()); + int setCaParameter(eDVBServicePMTHandler *pmthandler); void removeService(uint16_t program_number=0xFFFF); int setSource(const std::string &source); int setClockRate(const std::string &rate); @@ -103,9 +124,18 @@ class eDVBCISlot: public iObject, public sigc::trackable void setCAManager( eDVBCICAManagerSession *session ); void setCCManager( eDVBCICcSession *session ); + int getFd() { return fd; }; int getSlotID(); int getNumOfServices(); int getVersion(); + int16_t getCADemuxID() { return m_ca_demux_id; }; + int getTunerNum() { return m_tunernum; }; + int getUseCount() { return use_count; }; + int getProgramNumber() { return (int)m_program_number; }; + int getVideoPid() { return m_video_pid; }; + int getAudioPid() { return m_audio_pid; }; + int getAudioNumber() { return m_audio_number; }; + int* getAudioPids() { return m_audio_pids; }; }; struct CIPmtHandler @@ -160,10 +190,6 @@ class eDVBCIInterfaces: public eMainloop, private eThread eFixedMessagePump m_messagepump_main; // message handling in the e2 mainloop ePtr m_runTimer; // workaround to interrupt thread mainloop as some ci drivers don't implement poll properly static pthread_mutex_t m_pmt_handler_lock; - bool m_ciplus_routing_active; - int m_ciplus_routing_tunernum; - std::string m_ciplus_routing_input; - std::string m_ciplus_routing_ci_input; int sendCAPMT(int slot); diff --git a/lib/dvb_ci/dvbci_app_mmi.cpp b/lib/dvb_ci/dvbci_app_mmi.cpp index b390977d23e..7c01c8652ec 100644 --- a/lib/dvb_ci/dvbci_app_mmi.cpp +++ b/lib/dvb_ci/dvbci_app_mmi.cpp @@ -5,7 +5,7 @@ int eDVBCIApplicationMMISession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI AMMI] SESSION(%d)/AMMI %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d AMMI] SESSION(%d)/AMMI %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -27,7 +27,7 @@ int eDVBCIApplicationMMISession::doAction() switch (state) { default: - eWarning("[CI AMMI] unknown state"); + eWarning("[CI%d AMMI] unknown state", slot->getSlotID()); break; } diff --git a/lib/dvb_ci/dvbci_appmgr.cpp b/lib/dvb_ci/dvbci_appmgr.cpp index 96b832f8d0b..5c35566fe69 100644 --- a/lib/dvb_ci/dvbci_appmgr.cpp +++ b/lib/dvb_ci/dvbci_appmgr.cpp @@ -3,6 +3,7 @@ #include #include #include +#include eDVBCIApplicationManagerSession::eDVBCIApplicationManagerSession(eDVBCISlot *tslot) { @@ -18,7 +19,7 @@ eDVBCIApplicationManagerSession::~eDVBCIApplicationManagerSession() int eDVBCIApplicationManagerSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI AM] SESSION(%d)/APP %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d AM] SESSION(%d)/APP %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID()); + eDebug("[CI%d AM] len: %d", slot->getSlotID(), len); + eDebug("[CI%d AM] application_type: %d", slot->getSlotID(), ((unsigned char*)data)[0]); + eDebug("[CI%d AM] application_manufacturer: %02x %02x", slot->getSlotID(), ((unsigned char*)data)[2], ((unsigned char*)data)[1]); + eDebug("[CI%d AM] manufacturer_code: %02x %02x", slot->getSlotID(), ((unsigned char*)data)[4],((unsigned char*)data)[3]); dl=((unsigned char*)data)[5]; if ((dl + 6) > len) { - eDebug("[CI AM] warning, invalid length (%d vs %d)", dl+6, len); + eDebug("[CI%d AM] warning, invalid length (%d vs %d)", slot->getSlotID(), dl+6, len); dl=len-6; } char str[dl + 1]; memcpy(str, ((char*)data) + 6, dl); str[dl] = '\0'; - eDebugNoNewLine("[CI AM] menu string: "); + eDebugNoNewLine("[CI%d AM] menu string: ", slot->getSlotID()); for (int i = 0; i < dl; ++i) eDebugNoNewLine("%c", ((unsigned char*)data)[i+6]); eDebugNoNewLine("\n"); m_app_name = str; - /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::appNameChanged, slot->getSlotID(), str)); + if (m_app_name.size() > 0 && !isUTF8(m_app_name)) + { + m_app_name = repairUTF8(m_app_name.c_str(), m_app_name.size()); + eDebug("[CI%d AM] fixed menu string: %s", slot->getSlotID(), m_app_name.c_str()); + } + /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::appNameChanged, slot->getSlotID(), m_app_name.c_str())); /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::slotStateChanged, slot->getSlotID(), 2)); break; } default: - eWarning("[CI AM] unknown APDU tag 9F 80 %02x", tag[2]); + eWarning("[CI%d AM] unknown APDU tag 9F 80 %02x", slot->getSlotID(), tag[2]); break; } } @@ -75,11 +81,11 @@ int eDVBCIApplicationManagerSession::doAction() return 1; } case stateFinal: - eDebug("[CI AM] in final state."); + eDebug("[CI%d AM] in final state.", slot->getSlotID()); wantmenu = 0; if (wantmenu) { - eDebug("[CI AM] wantmenu: sending Tenter_menu"); + eDebug("[CI%d AM] wantmenu: sending Tenter_menu", slot->getSlotID()); const unsigned char tag[3]={0x9F, 0x80, 0x22}; // Tenter_menu sendAPDU(tag); wantmenu=0; @@ -93,7 +99,7 @@ int eDVBCIApplicationManagerSession::doAction() int eDVBCIApplicationManagerSession::startMMI() { - eDebug("[CI AM] in appmanager -> startmmi()"); + eDebug("[CI%d AM] in appmanager -> startmmi()", slot->getSlotID()); const unsigned char tag[3]={0x9F, 0x80, 0x22}; // Tenter_menu sendAPDU(tag); return 0; diff --git a/lib/dvb_ci/dvbci_cam_upgrade.cpp b/lib/dvb_ci/dvbci_cam_upgrade.cpp index 2d25906b649..6a2b24b0b0f 100644 --- a/lib/dvb_ci/dvbci_cam_upgrade.cpp +++ b/lib/dvb_ci/dvbci_cam_upgrade.cpp @@ -5,7 +5,7 @@ int eDVBCICAMUpgradeSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI CAMUP] SESSION(%d)/CAMUP %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d CAMUP] SESSION(%d)/CAMUP %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -27,7 +27,7 @@ int eDVBCICAMUpgradeSession::doAction() switch (state) { default: - eWarning("[CI CAMUP] unknown state"); + eWarning("[CI%d CAMUP] unknown state", slot->getSlotID()); break; } diff --git a/lib/dvb_ci/dvbci_camgr.cpp b/lib/dvb_ci/dvbci_camgr.cpp index c5b81def13e..7a8e334cab2 100644 --- a/lib/dvb_ci/dvbci_camgr.cpp +++ b/lib/dvb_ci/dvbci_camgr.cpp @@ -16,7 +16,7 @@ eDVBCICAManagerSession::~eDVBCICAManagerSession() int eDVBCICAManagerSession::receivedAPDU(const unsigned char *tag, const void *data, int len) { - eTraceNoNewLine("[CI CA] SESSION(%d)/CA %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d CA] SESSION(%d)/CA %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID()); for (int i=0; iexecuteRecheckPMTHandlersInMainloop(); break; default: - eWarning("[CI CA] unknown APDU tag 9F 80 %02x", tag[2]); + eWarning("[CI%d CA] unknown APDU tag 9F 80 %02x", slot->getSlotID(), tag[2]); break; } } @@ -56,7 +56,7 @@ int eDVBCICAManagerSession::doAction() return 0; } case stateFinal: - eWarning("[CI CA] stateFinal and action should not happen"); + eWarning("[CI%d CA] stateFinal and action should not happen", slot->getSlotID()); [[fallthrough]]; default: return 0; diff --git a/lib/dvb_ci/dvbci_ccmgr.cpp b/lib/dvb_ci/dvbci_ccmgr.cpp index bf03719f306..7b9f4229a48 100644 --- a/lib/dvb_ci/dvbci_ccmgr.cpp +++ b/lib/dvb_ci/dvbci_ccmgr.cpp @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -18,22 +19,27 @@ eDVBCICcSession::eDVBCICcSession(eDVBCISlot *slot, int version): uint8_t buf[32], host_id[8]; m_slot->setCCManager(this); - m_descrambler_fd = descrambler_init(); - parameter_init(m_dh_p, m_dh_g, m_dh_q, m_s_key, m_key_data, m_iv); + m_descrambler_fd = -1; + m_current_ca_demux_id = 0; + m_descrambler_new_key = false; + + parameter_init(m_slot->getSlotID(), m_dh_p, m_dh_g, m_dh_q, m_s_key, m_key_data, m_iv); m_ci_elements.init(); memset(buf, 0, 1); if (!m_ci_elements.set(STATUS_FIELD, buf, 1)) - eWarning("[CI RCC] can not set status"); + eWarning("[CI%d RCC] can not set status", m_slot->getSlotID()); memset(buf, 0, 32); buf[31] = 0x01; // URI_PROTOCOL_V1 - if (version == 2) + if (version >= 2) buf[31] |= 0x02; // URI_PROTOCOL_V2 + if (version >= 4) + buf[31] |= 0x04; // URI_PROTOCOL_V4 if (!m_ci_elements.set(URI_VERSIONS, buf, 32)) - eWarning("[CI RCC] can not set uri_versions"); + eWarning("[CI%d RCC] can not set uri_versions", m_slot->getSlotID()); if (!get_authdata(host_id, m_dhsk, buf, m_slot->getSlotID(), m_akh_index)) { @@ -42,10 +48,10 @@ eDVBCICcSession::eDVBCICcSession(eDVBCISlot *slot, int version): } if (!m_ci_elements.set(AKH, buf, 32)) - eWarning("[CI RCC] can not set AKH"); + eWarning("[CI%d RCC] can not set AKH", m_slot->getSlotID()); if (!m_ci_elements.set(HOST_ID, host_id, 8)) - eWarning("[CI RCC] can not set host_id"); + eWarning("[CI%d RCC] can not set host_id", m_slot->getSlotID()); } eDVBCICcSession::~eDVBCICcSession() @@ -73,7 +79,7 @@ eDVBCICcSession::~eDVBCICcSession() int eDVBCICcSession::receivedAPDU(const unsigned char *tag, const void *data, int len) { - eTraceNoNewLineStart("[CI CC] SESSION(%d)/CC %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLineStart("[CI%d CC] SESSION(%d)/CC %02x %02x %02x: ", m_slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -101,7 +107,7 @@ int eDVBCICcSession::doAction() case stateStarted: break; default: - eWarning("[CI CC] unknown state"); + eWarning("[CI%d CC] unknown state", m_slot->getSlotID()); break; } return 0; @@ -114,7 +120,10 @@ void eDVBCICcSession::send(const unsigned char *tag, const void *data, int len) void eDVBCICcSession::addProgram(uint16_t program_number, std::vector& pids) { - eDebugNoNewLineStart("[CI CC] SESSION(%d)/ADD PROGRAM %04x: ", session_nb, program_number); + // first open ca device and set descrambler key if it's not set yet + set_descrambler_key(); + + eDebugNoNewLineStart("[CI%d CC] SESSION(%d)/ADD PROGRAM %04x: ", m_slot->getSlotID(), session_nb, program_number); for (std::vector::iterator it = pids.begin(); it != pids.end(); ++it) eDebugNoNewLine("%02x ", *it); eDebugNoNewLine("\n"); @@ -125,7 +134,7 @@ void eDVBCICcSession::addProgram(uint16_t program_number, std::vector& void eDVBCICcSession::removeProgram(uint16_t program_number, std::vector& pids) { - eDebugNoNewLineStart("[CI CC] SESSION(%d)/REMOVE PROGRAM %04x: ", session_nb, program_number); + eDebugNoNewLineStart("[CI%d CC] SESSION(%d)/REMOVE PROGRAM %04x: ", m_slot->getSlotID(), session_nb, program_number); for (std::vector::iterator it = pids.begin(); it != pids.end(); ++it) eDebugNoNewLine("%02x ", *it); eDebugNoNewLine("\n"); @@ -152,7 +161,7 @@ void eDVBCICcSession::cc_data_req(const uint8_t *data, unsigned int len) if (len < 2) { - eWarning("[CI RCC] too short data"); + eWarning("[CI%d RCC] too short data", m_slot->getSlotID()); return; } @@ -169,7 +178,7 @@ void eDVBCICcSession::cc_data_req(const uint8_t *data, unsigned int len) unsigned int dest_len = sizeof(dest); if (dest_len < 2) { - eWarning("[CI RCC] not enough space"); + eWarning("[CI%d RCC] not enough space", m_slot->getSlotID()); return; } @@ -179,7 +188,7 @@ void eDVBCICcSession::cc_data_req(const uint8_t *data, unsigned int len) answ_len = data_req_loop(&dest[2], dest_len - 2, &data[rp], len - rp, dt_nr); if (answ_len <= 0) { - eWarning("[CI RCC] can not get data"); + eWarning("[CI%d RCC] can not get data", m_slot->getSlotID()); return; } @@ -210,7 +219,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) if (len < 10) return; - eTraceNoNewLineStart("[CI RCC] cc_sac_data_req: "); + eTraceNoNewLineStart("[CI%d RCC] cc_sac_data_req: ", m_slot->getSlotID()); traceHexdump(data, len); memcpy(tmp, data, 8); @@ -219,7 +228,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) if (!sac_check_auth(data, len)) { - eWarning("[CI RCC] check_auth of message failed"); + eWarning("[CI%d RCC] check_auth of message failed", m_slot->getSlotID()); return; } @@ -237,7 +246,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) if (len < rp + 1) { - eWarning("[CI RCC] check_auth of message too short"); + eWarning("[CI%d RCC] check_auth of message too short", m_slot->getSlotID()); return; } @@ -248,7 +257,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) if (dest_len < 10) { - eWarning("[CI RCC] not enough space"); + eWarning("[CI%d RCC] not enough space", m_slot->getSlotID()); return; } @@ -261,7 +270,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) answ_len = data_req_loop(&dest[pos], dest_len - 10, &data[rp], len - rp, dt_nr); if (answ_len <= 0) { - eWarning("[CI RCC] can not get data"); + eWarning("[CI%d RCC] can not get data", m_slot->getSlotID()); return; } pos += answ_len; @@ -276,11 +285,11 @@ void eDVBCICcSession::cc_sac_sync_req(const uint8_t *data, unsigned int len) unsigned int serial; int pos = 0; - eTraceNoNewLineStart("[CI RCC] cc_sac_sync_req: "); + eTraceNoNewLineStart("[CI%d RCC] cc_sac_sync_req: ", m_slot->getSlotID()); traceHexdump(data, len); serial = UINT32(data, 4); - eTrace("[CI RCC] serial %u\n", serial); + eTrace("[CI%d RCC] serial %u\n", m_slot->getSlotID(), serial); pos += BYTE32(&dest[pos], serial); pos += BYTE32(&dest[pos], 0x01000000); @@ -288,6 +297,8 @@ void eDVBCICcSession::cc_sac_sync_req(const uint8_t *data, unsigned int len) /* status OK */ dest[pos++] = 0; + set_descrambler_key(); + cc_sac_send(sync_cnf_tag, dest, pos); } @@ -295,7 +306,7 @@ void eDVBCICcSession::cc_sac_send(const uint8_t *tag, uint8_t *data, unsigned in { if (pos < 8) { - eWarning("[CI RCC] too short data"); + eWarning("[CI%d RCC] too short data", m_slot->getSlotID()); return; } @@ -328,7 +339,7 @@ int eDVBCICcSession::data_get_loop(const uint8_t *data, unsigned int datalen, un if (pos + dt_len > datalen) return 0; - eTraceNoNewLineStart("[CI RCC] set element %d: ", dt_id); + eTraceNoNewLineStart("[CI%d RCC] set element %d: ", m_slot->getSlotID(), dt_id); traceHexdump(&data[pos], dt_len); m_ci_elements.set(dt_id, &data[pos], dt_len); @@ -359,14 +370,14 @@ int eDVBCICcSession::data_req_loop(uint8_t *dest, unsigned int dest_len, const u len = m_ci_elements.get_buf(NULL, dt_id); if ((len + 3) > dest_len) { - eWarning("[CI RCC] req element %d: not enough space", dt_id); + eWarning("[CI%d RCC] req element %d: not enough space", m_slot->getSlotID(), dt_id); return -1; } len = m_ci_elements.get_req(dest, dt_id); if (len > 0) { - eTraceNoNewLineStart("[CI RCC] req element %d: ", dt_id); + eTraceNoNewLineStart("[CI%d RCC] req element %d: ", m_slot->getSlotID(), dt_id); traceHexdump(&dest[3], len - 3); } @@ -415,7 +426,7 @@ int eDVBCICcSession::data_get_handle_new(unsigned int id) break; default: - eWarning("[CI RCC] unhandled id %u", id); + eWarning("[CI%d RCC] unhandled id %u", m_slot->getSlotID(), id); break; } @@ -426,7 +437,7 @@ int eDVBCICcSession::data_req_handle_new(unsigned int id) { switch (id) { - case 22: + case AKH: { uint8_t akh[32], host_id[8]; @@ -438,13 +449,20 @@ int eDVBCICcSession::data_req_handle_new(unsigned int id) m_akh_index = 5; if (!m_ci_elements.set(AKH, akh, 32)) - eWarning("[CI RCC] can not set AKH in elements"); + eWarning("[CI%d RCC] can not set AKH in elements", m_slot->getSlotID()); if (!m_ci_elements.set(HOST_ID, host_id, 8)) - eWarning("[CI RCC] can not set host_id in elements"); + eWarning("[CI%d RCC] can not set host_id in elements", m_slot->getSlotID()); } break; } + case CRITICAL_SEC_UPDATE: + { + uint8_t csu[1]; + csu[0] = 0x00; + m_ci_elements.set(CRITICAL_SEC_UPDATE, csu, 1); + break; + } default: break; } @@ -473,7 +491,7 @@ int eDVBCICcSession::compute_dh_key() int len = DH_size(m_dh); if (len > 256) { - eWarning("[CI RCC] too long shared key"); + eWarning("[CI%d RCC] too long shared key", m_slot->getSlotID()); return -1; } @@ -485,14 +503,14 @@ int eDVBCICcSession::compute_dh_key() BIGNUM *out = BN_new(); if (BN_cmp(BN_value_one(), bn_in) >= 0) - eWarning("[CI RCC] DHPM <= 1!!!"); + eWarning("[CI%d RCC] DHPM <= 1!!!", m_slot->getSlotID()); if (BN_cmp(bn_in, m_dh->p) >= 0) - eWarning("[CI RCC] DHPM >= dh_p!!!"); + eWarning("[CI%d RCC] DHPM >= dh_p!!!", m_slot->getSlotID()); BN_mod_exp(out, bn_in, m_dh->q, m_dh->p, ctx); if (BN_cmp(out, BN_value_one()) != 0) - eWarning("[CI RCC] DHPM ^ dh_q mod dh_p != 1!!!"); + eWarning("[CI%d RCC] DHPM ^ dh_q mod dh_p != 1!!!", m_slot->getSlotID()); BN_free(out); BN_CTX_free(ctx); @@ -501,11 +519,11 @@ int eDVBCICcSession::compute_dh_key() int codes = 0; int ok = DH_check_pub_key(m_dh, bn_in, &codes); if (ok == 0) - eDebug("[CI RCC] check_pub_key failed"); + eDebug("[CI%d RCC] check_pub_key failed", m_slot->getSlotID()); if (codes & DH_CHECK_PUBKEY_TOO_SMALL) - eDebug("[CI RCC] too small public key"); + eDebug("[CI%d RCC] too small public key", m_slot->getSlotID()); if (codes & DH_CHECK_PUBKEY_TOO_LARGE) - eDebug("[CI RCC] too large public key"); + eDebug("[CI%d RCC] too large public key", m_slot->getSlotID()); int gap = 256 - len; memset(m_dhsk, 0, gap); @@ -535,7 +553,7 @@ bool eDVBCICcSession::check_dh_challenge() m_akh_index = 5; - eDebug("[CI RCC] writing..."); + eDebug("[CI%d RCC] writing...", m_slot->getSlotID()); write_authdata(m_slot->getSlotID(), m_ci_elements.get_ptr(HOST_ID), m_dhsk, m_ci_elements.get_ptr(AKH)); return true; @@ -563,7 +581,7 @@ int eDVBCICcSession::generate_dh_key() len = BN_num_bytes(pub_key); if (len > 256) { - eWarning("[CI RCC] too long public key"); + eWarning("[CI%d RCC] too long public key", m_slot->getSlotID()); return -1; } @@ -573,12 +591,12 @@ int eDVBCICcSession::generate_dh_key() BIGNUM *out = BN_new(); if (BN_cmp(BN_value_one(), m_dh->pub_key) >= 0) - eWarning("[CI RCC] DHPH <= 1!!!"); + eWarning("[CI%d RCC] DHPH <= 1!!!", m_slot->getSlotID()); if (BN_cmp(m_dh->pub_key, m_dh->p) >= 0) - eWarning("[CI RCC] DHPH >= dh_p!!!"); + eWarning("[CI%d RCC] DHPH >= dh_p!!!", m_slot->getSlotID()); BN_mod_exp(out, m_dh->pub_key, m_dh->q, m_dh->p, ctx); if (BN_cmp(out, BN_value_one()) != 0) - eWarning("[CI RCC] DHPH ^ dh_q mod dh_p != 1!!!"); + eWarning("[CI%d RCC] DHPH ^ dh_q mod dh_p != 1!!!", m_slot->getSlotID()); BN_free(out); BN_CTX_free(ctx); @@ -631,7 +649,7 @@ int eDVBCICcSession::generate_sign_A() m_rsa_device_key = rsa_privatekey_open("/etc/ciplus/device.pem"); if (!m_rsa_device_key) { - eWarning("[CI RCC] can not read private key"); + eWarning("[CI%d RCC] can not read private key", m_slot->getSlotID()); return -1; } @@ -648,18 +666,18 @@ int eDVBCICcSession::restart_dh_challenge() if (!m_ci_elements.valid(AUTH_NONCE)) return -1; - //eDebug("[CI RCC] rechecking..."); + //eDebug("[CI%d RCC] rechecking...", m_slot->getSlotID()); m_root_ca_store = X509_STORE_new(); if (!m_root_ca_store) { - eWarning("[CI RCC] can not create root_ca"); + eWarning("[CI%d RCC] can not create root_ca", m_slot->getSlotID()); return -1; } if (X509_STORE_load_locations(m_root_ca_store, "/etc/ciplus/root.pem", NULL) != 1) { - eWarning("[CI RCC] can not load root_ca"); + eWarning("[CI%d RCC] can not load root_ca", m_slot->getSlotID()); return -1; } @@ -668,18 +686,18 @@ int eDVBCICcSession::restart_dh_challenge() if (!m_cust_cert || !m_device_cert) { - eWarning("[CI RCC] can not check loader certificates"); + eWarning("[CI%d RCC] can not check loader certificates", m_slot->getSlotID()); return -1; } if (!ci_element_set_certificate(HOST_BRAND_CERT, m_cust_cert)) - eWarning("[CI RCC] can not store brand certificate"); + eWarning("[CI%d RCC] can not store brand certificate", m_slot->getSlotID()); if (!ci_element_set_certificate(HOST_DEV_CERT, m_device_cert)) - eWarning("[CI RCC] can not store device certificate"); + eWarning("[CI%d RCC] can not store device certificate", m_slot->getSlotID()); if (!ci_element_set_hostid_from_certificate(HOST_ID, m_device_cert)) - eWarning("[CI RCC] can not store HOST_ID"); + eWarning("[CI%d RCC] can not store HOST_ID", m_slot->getSlotID()); m_ci_elements.invalidate(CICAM_ID); m_ci_elements.invalidate(DHPM); @@ -698,7 +716,7 @@ int eDVBCICcSession::generate_uri_confirm() uint8_t uck[32]; uint8_t uri_confirm[32]; - //eDebug("[CI RCC] uri_confirm..."); + //eDebug("[CI%d RCC] uri_confirm...", m_slot->getSlotID()); // UCK SHA256_Init(&sha); @@ -730,7 +748,7 @@ void eDVBCICcSession::check_new_key() if (!m_ci_elements.valid(KEY_REGISTER)) return; - //eDebug("[CI RCC] key checking..."); + //eDebug("[CI%d RCC] key checking...", m_slot->getSlotID()); kp = m_ci_elements.get_ptr(KP); m_ci_elements.get_buf(&slot, KEY_REGISTER); @@ -745,12 +763,48 @@ void eDVBCICcSession::check_new_key() if (slot != 0 && slot != 1) slot = 1; - descrambler_set_key(m_descrambler_fd, m_slot->getSlotID(), slot, dec); + memcpy(m_descrambler_key_iv, dec, 32); + m_descrambler_odd_even = slot; + m_descrambler_new_key = true; + + eDVBCIInterfaces::getInstance()->revertCIPlusRouting(m_slot->getSlotID()); m_ci_elements.invalidate(KP); m_ci_elements.invalidate(KEY_REGISTER); } +/* Opens /dev/caX device if it's not open yet. + * If ca demux has changed close current /dev/caX device and open new ca device. + * Sets new key or old one if /dev/caX device has changed */ +void eDVBCICcSession::set_descrambler_key() +{ + eDebug("[CI%d RCC] set_descrambler_key", m_slot->getSlotID()); + bool set_key = (m_current_ca_demux_id != m_slot->getCADemuxID()) || (m_slot->getTunerNum() > 7); + + if (m_descrambler_fd != -1 && m_current_ca_demux_id != m_slot->getCADemuxID()) + { + descrambler_deinit(m_descrambler_fd); + m_descrambler_fd = descrambler_init(m_slot->getSlotID(), m_slot->getCADemuxID()); + m_current_ca_demux_id = m_slot->getCADemuxID(); + } + + if (m_descrambler_fd == -1 && m_slot->getCADemuxID() > -1) + { + m_descrambler_fd = descrambler_init(m_slot->getSlotID(), m_slot->getCADemuxID()); + m_current_ca_demux_id = m_slot->getCADemuxID(); + } + + if (m_descrambler_fd != -1 && (set_key || m_descrambler_new_key)) + { + eDebug("[CI%d RCC] setting key: new ca device: %d, new key: %d", m_slot->getSlotID(), set_key, m_descrambler_new_key); + descrambler_set_key(m_descrambler_fd, m_slot, m_descrambler_odd_even, m_descrambler_key_iv); + if (m_descrambler_new_key) + { + m_descrambler_new_key = false; + } + } +} + void eDVBCICcSession::generate_key_seed() { SHA256_CTX sha; @@ -797,7 +851,7 @@ bool eDVBCICcSession::sac_check_auth(const uint8_t *data, unsigned int len) if (len < 16) { - eWarning("[CI RCC] signature too short"); + eWarning("[CI%d RCC] signature too short", m_slot->getSlotID()); return false; } @@ -808,7 +862,7 @@ bool eDVBCICcSession::sac_check_auth(const uint8_t *data, unsigned int len) if (memcmp(&data[len - 16], calced_signature, 16)) { - eWarning("[CI RCC] signature wrong"); + eWarning("[CI%d RCC] signature wrong", m_slot->getSlotID()); return false; } @@ -851,14 +905,14 @@ X509 *eDVBCICcSession::import_ci_certificates(unsigned int id) if (!m_ci_elements.valid(id)) { - eWarning("[CI RCC] %u not valid", id); + eWarning("[CI%d RCC] %u not valid", m_slot->getSlotID(), id); return NULL; } cert = certificate_import_and_check(m_root_ca_store, m_ci_elements.get_ptr(id), m_ci_elements.get_buf(NULL, id)); if (!cert) { - eWarning("[CI RCC] can not verify certificate %u", id); + eWarning("[CI%d RCC] can not verify certificate %u", m_slot->getSlotID(), id); return NULL; } @@ -875,19 +929,19 @@ int eDVBCICcSession::check_ci_certificates() if ((m_ci_cust_cert = import_ci_certificates(CICAM_BRAND_CERT)) == NULL) { - eWarning("[CI RCC] can not import CICAM brand certificate"); + eWarning("[CI%d RCC] can not import CICAM brand certificate", m_slot->getSlotID()); return -1; } if ((m_ci_device_cert = import_ci_certificates(CICAM_DEV_CERT)) == NULL) { - eWarning("[CI RCC] can not import CICAM device certificate"); + eWarning("[CI%d RCC] can not import CICAM device certificate", m_slot->getSlotID()); return -1; } if (!ci_element_set_hostid_from_certificate(CICAM_ID, m_ci_device_cert)) { - eWarning("[CI RCC] can not store CICAM_ID"); + eWarning("[CI%d RCC] can not store CICAM_ID", m_slot->getSlotID()); return -1; } @@ -902,12 +956,12 @@ bool eDVBCICcSession::ci_element_set_certificate(unsigned int id, X509 *cert) cert_len = i2d_X509(cert, &cert_der); if (cert_len <= 0) { - eWarning("[CI RCC] can not encode certificate"); + eWarning("[CI%d RCC] can not encode certificate", m_slot->getSlotID()); return false; } if (!m_ci_elements.set(id, cert_der, cert_len)) { - eWarning("[CI RCC] can not store certificate id %u", id); + eWarning("[CI%d RCC] can not store certificate id %u", m_slot->getSlotID(), id); return false; } @@ -924,7 +978,7 @@ bool eDVBCICcSession::ci_element_set_hostid_from_certificate(unsigned int id, X5 if ((id != 5) && (id != 6)) { - eWarning("[CI RCC] wrong datatype_id %u for device id", id); + eWarning("[CI%d RCC] wrong datatype_id %u for device id", m_slot->getSlotID(), id); return false; } @@ -933,17 +987,17 @@ bool eDVBCICcSession::ci_element_set_hostid_from_certificate(unsigned int id, X5 if (strlen(hostid) != 16) { - eWarning("[CI RCC] bad device id"); + eWarning("[CI%d RCC] bad device id", m_slot->getSlotID()); return false; } - //eDebug("[CI RCC] DEVICE_ID: %s", hostid); + //eDebug("[CI%d RCC] DEVICE_ID: %s", m_slot->getSlotID(), hostid); str2bin(bin_hostid, hostid, 16); if (!m_ci_elements.set(id, bin_hostid, sizeof(bin_hostid))) { - eWarning("[CI RCC] can not store device id %u", id); + eWarning("[CI%d RCC] can not store device id %u", m_slot->getSlotID(), id); return false; } diff --git a/lib/dvb_ci/dvbci_ccmgr.h b/lib/dvb_ci/dvbci_ccmgr.h index 61efe6a75e6..83edbd8a66f 100644 --- a/lib/dvb_ci/dvbci_ccmgr.h +++ b/lib/dvb_ci/dvbci_ccmgr.h @@ -16,6 +16,7 @@ class eDVBCICcSession: public eDVBCISession { eDVBCISlot *m_slot; int m_descrambler_fd; + uint8_t m_current_ca_demux_id; // CI+ credentials enum @@ -49,7 +50,9 @@ class eDVBCICcSession: public eDVBCISession SRM_DATA = 31, SRM_CONFIRM = 32, - MAX_ELEMENTS = 33 + CRITICAL_SEC_UPDATE = 49, + + MAX_ELEMENTS = 50 }; struct ciplus_element @@ -240,6 +243,11 @@ class eDVBCICcSession: public eDVBCISession uint8_t m_key_data[16]; uint8_t m_iv[16]; + /* descrambler key */ + bool m_descrambler_new_key; + uint8_t m_descrambler_key_iv[32]; + uint8_t m_descrambler_odd_even; + int receivedAPDU(const unsigned char *tag, const void *data, int len); int doAction(); @@ -278,6 +286,8 @@ class eDVBCICcSession: public eDVBCISession bool ci_element_set_certificate(unsigned int id, X509 *cert); bool ci_element_set_hostid_from_certificate(unsigned int id, X509 *cert); + void set_descrambler_key(); + public: eDVBCICcSession(eDVBCISlot *tslot, int version); ~eDVBCICcSession(); diff --git a/lib/dvb_ci/dvbci_ccmgr_helper.cpp b/lib/dvb_ci/dvbci_ccmgr_helper.cpp index 6e527f95401..7c78475af77 100644 --- a/lib/dvb_ci/dvbci_ccmgr_helper.cpp +++ b/lib/dvb_ci/dvbci_ccmgr_helper.cpp @@ -139,7 +139,7 @@ bool get_authdata(uint8_t *host_id, uint8_t *dhsk, uint8_t *akh, unsigned int sl fd = open(filename, O_RDONLY); if (fd <= 0) { - eDebug("[CI RCC] can not open %s", filename); + eDebug("[CI%d RCC] can not open %s", slot, filename); return false; } @@ -147,7 +147,7 @@ bool get_authdata(uint8_t *host_id, uint8_t *dhsk, uint8_t *akh, unsigned int sl { if (read(fd, chunk, sizeof(chunk)) != sizeof(chunk)) { - eDebug("[CI RCC] can not read auth_data"); + eDebug("[CI%d RCC] can not read auth_data", slot); close(fd); return false; } @@ -178,7 +178,7 @@ bool write_authdata(unsigned int slot, const uint8_t *host_id, const uint8_t *dh /* check if we got this pair already */ if (!memcmp(&buf[offset + 8 + 256], akh, 32)) { - eDebug("[CI RCC] data already stored"); + eDebug("[CI%d RCC] data already stored", slot); return true; } } @@ -196,25 +196,25 @@ bool write_authdata(unsigned int slot, const uint8_t *host_id, const uint8_t *dh memcpy(buf + 8 + 256, akh, 32); entries++; - eDebug("[CI RCC] %d entries for writing", entries); + eDebug("[CI%d RCC] %d entries for writing", slot, entries); get_authdata_filename(filename, sizeof(filename), slot); fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); if (fd < 0) { - eWarning("[CI RCC] can not open %s", filename); + eWarning("[CI%d RCC] can not open %s", slot, filename); return false; } if (write(fd, buf, PAIR_SIZE * entries) != PAIR_SIZE * entries) - eWarning("[CI RCC] error in write"); + eWarning("[CI%d RCC] error in write", slot); close(fd); return true; } -bool parameter_init(uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, uint8_t* key_data, uint8_t* iv) +bool parameter_init(unsigned int slot, uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, uint8_t* key_data, uint8_t* iv) { int fd; unsigned char buf[592]; @@ -222,13 +222,13 @@ bool parameter_init(uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, fd = open("/etc/ciplus/param", O_RDONLY); if (fd <= 0) { - eDebug("[CI RCC] can not param file"); + eDebug("[CI%d RCC] can not param file", slot); return false; } if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { - eDebug("[CI RCC] can not read parameters"); + eDebug("[CI%d RCC] can not read parameters", slot); close(fd); return false; } diff --git a/lib/dvb_ci/dvbci_ccmgr_helper.h b/lib/dvb_ci/dvbci_ccmgr_helper.h index b622eb8889c..bf79ed169af 100644 --- a/lib/dvb_ci/dvbci_ccmgr_helper.h +++ b/lib/dvb_ci/dvbci_ccmgr_helper.h @@ -13,7 +13,7 @@ int BYTE32(uint8_t *dest, uint32_t val); int BYTE16(uint8_t *dest, uint16_t val); bool get_authdata(uint8_t *host_id, uint8_t *dhsk, uint8_t *akh, unsigned int slot, unsigned int index); bool write_authdata(unsigned int slot, const uint8_t *host_id, const uint8_t *dhsk, const uint8_t *akh); -bool parameter_init(uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, uint8_t* key_data, uint8_t* iv); +bool parameter_init(unsigned int slot, uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, uint8_t* key_data, uint8_t* iv); RSA *rsa_privatekey_open(const char *filename); int verify_cb(int ok, X509_STORE_CTX *ctx); X509 *certificate_load_and_check(X509_STORE *store, const char *filename); diff --git a/lib/dvb_ci/dvbci_datetimemgr.cpp b/lib/dvb_ci/dvbci_datetimemgr.cpp index 9d753a77401..340b4b4f472 100644 --- a/lib/dvb_ci/dvbci_datetimemgr.cpp +++ b/lib/dvb_ci/dvbci_datetimemgr.cpp @@ -12,7 +12,7 @@ eDVBCIDateTimeSession::eDVBCIDateTimeSession(): int eDVBCIDateTimeSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI DT] SESSION(%d)/DATETIME %02x %02x %02x: ", session_nb, tag[0],tag[1], tag[2]); + eTraceNoNewLine("[CI%d DT] SESSION(%d)/DATETIME %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0],tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -45,7 +45,7 @@ int eDVBCIDateTimeSession::doAction() sendDateTime(); return 0; case stateFinal: - eWarning("[CI DT] stateFinal and action should not happen"); + eWarning("[CI%d DT] stateFinal and action should not happen", slot->getSlotID()); [[fallthrough]]; default: return 0; diff --git a/lib/dvb_ci/dvbci_hlcmgr.cpp b/lib/dvb_ci/dvbci_hlcmgr.cpp index 2ae9dc46c05..bc2d7173a91 100644 --- a/lib/dvb_ci/dvbci_hlcmgr.cpp +++ b/lib/dvb_ci/dvbci_hlcmgr.cpp @@ -8,7 +8,7 @@ int eDVBCIHostLanguageAndCountrySession::receivedAPDU(const unsigned char *tag,c { int ret = 0; - eTraceNoNewLine("[CI HLC] SESSION(%d)/HLC %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d HLC] SESSION(%d)/HLC %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID()); state=stateCountryEnquiry; ret = 1; break; case 0x10: // language enquiry - eDebug("[CI HLC] Host language enquiry:"); + eDebug("[CI%d HLC] Host language enquiry:", slot->getSlotID()); state=stateLanguageEnquiry; ret = 1; break; default: - eWarning("[CI HLC] unknown APDU tag 9F 80 %02x", tag[2]); + eWarning("[CI%d HLC] unknown APDU tag 9F 80 %02x", slot->getSlotID(), tag[2]); state = stateFinal; break; } @@ -110,7 +110,7 @@ int eDVBCIHostLanguageAndCountrySession::doAction() break; } default: - eWarning("[CI HLC] unknown state"); + eWarning("[CI%d HLC] unknown state", slot->getSlotID()); break; } diff --git a/lib/dvb_ci/dvbci_host_ctrl.cpp b/lib/dvb_ci/dvbci_host_ctrl.cpp index 26ded0e101c..1062da71b1f 100644 --- a/lib/dvb_ci/dvbci_host_ctrl.cpp +++ b/lib/dvb_ci/dvbci_host_ctrl.cpp @@ -5,7 +5,7 @@ int eDVBCIHostControlSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI HCTRL] SESSION(%d)/HCTRL %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d HCTRL] SESSION(%d)/HCTRL %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -27,7 +27,7 @@ int eDVBCIHostControlSession::doAction() switch (state) { default: - eWarning("[CI HCTRL] unknown state"); + eWarning("[CI%d HCTRL] unknown state", slot->getSlotID()); break; } diff --git a/lib/dvb_ci/dvbci_mmi.cpp b/lib/dvb_ci/dvbci_mmi.cpp index 9e595d9cb6d..9e76fb95e6f 100644 --- a/lib/dvb_ci/dvbci_mmi.cpp +++ b/lib/dvb_ci/dvbci_mmi.cpp @@ -33,7 +33,7 @@ eDVBCIMMISession::~eDVBCIMMISession() int eDVBCIMMISession::receivedAPDU(const unsigned char *tag, const void *data, int len) { - eTraceNoNewLineStart("[CI MMI] SESSION(%d)/MMI %02x %02x %02x: ", session_nb, tag[0], tag[1],tag[2]); + eTraceNoNewLineStart("[CI%d MMI] SESSION(%d)/MMI %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1],tag[2]); for (int i=0; igetSlotID()); unsigned char tag[]={0x9f, 0x88, 0x00}; unsigned char data[]={0x00}; @@ -99,7 +99,7 @@ int eDVBCIMMISession::stopMMI() int eDVBCIMMISession::answerText(int answer) { - eDebug("[CI MMI] eDVBCIMMISession::answerText(%d)",answer); + eDebug("[CI%d MMI] eDVBCIMMISession::answerText(%d)", slot->getSlotID(), answer); unsigned char tag[]={0x9f, 0x88, 0x0B}; unsigned char data[]={0x00}; @@ -112,7 +112,7 @@ int eDVBCIMMISession::answerText(int answer) int eDVBCIMMISession::answerEnq(char *answer) { unsigned int len = strlen(answer); - eDebug("[CI MMI] eDVBCIMMISession::answerEnq(%d bytes)", len); + eDebug("[CI%d MMI] eDVBCIMMISession::answerEnq(%d bytes)", slot->getSlotID(), len); unsigned char data[len+1]; data[0] = 0x01; // answer ok @@ -126,7 +126,7 @@ int eDVBCIMMISession::answerEnq(char *answer) int eDVBCIMMISession::cancelEnq() { - eDebug("[CI MMI] eDVBCIMMISession::cancelEnq()"); + eDebug("[CI%d MMI] eDVBCIMMISession::cancelEnq()", slot->getSlotID()); unsigned char tag[]={0x9f, 0x88, 0x08}; unsigned char data[]={0x00}; // canceled diff --git a/lib/dvb_ci/dvbci_operatorprofile.cpp b/lib/dvb_ci/dvbci_operatorprofile.cpp index 27ebc61b6da..8b3dc108b97 100644 --- a/lib/dvb_ci/dvbci_operatorprofile.cpp +++ b/lib/dvb_ci/dvbci_operatorprofile.cpp @@ -9,7 +9,7 @@ eDVBCIOperatorProfileSession::eDVBCIOperatorProfileSession() int eDVBCIOperatorProfileSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI OP] SESSION(%d)/OPERATOR %02x %02x %02x: ", session_nb, tag[0],tag[1], tag[2]); + eTraceNoNewLine("[CI%d OP] SESSION(%d)/OPERATOR %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0],tag[1], tag[2]); for (int i=0; igetSlotID()); + state=stateStatus; break; case 0x03: - eDebug("operator_nit"); + eDebug("[CI%d OP] operator_nit", slot->getSlotID()); break; case 0x05: - eDebug("operator_info"); + eDebug("[CI%d OP] operator_info", slot->getSlotID()); break; case 0x07: - eDebug("operator_search_status"); + eDebug("[CI%d OP] operator_search_status", slot->getSlotID()); break; case 0x09: - eDebug("operator_tune"); + eDebug("[CI%d OP] operator_tune", slot->getSlotID()); break; default: - eWarning("[CI OP] unknown APDU tag 9F 9C %02x", tag[2]); + eWarning("[CI%d OP] unknown APDU tag 9F 9C %02x", slot->getSlotID(), tag[2]); break; } } @@ -46,7 +46,7 @@ int eDVBCIOperatorProfileSession::doAction() { switch (state) { - case stateStarted: + case stateStatusRequest: { const unsigned char tag[3]={0x9F, 0x9C, 0x00}; sendAPDU(tag); @@ -55,7 +55,7 @@ int eDVBCIOperatorProfileSession::doAction() } case stateFinal: { - eWarning("[CI OP] stateFinal and action should not happen"); + eWarning("[CI%d OP] stateFinal and action should not happen", slot->getSlotID()); break; } default: diff --git a/lib/dvb_ci/dvbci_operatorprofile.h b/lib/dvb_ci/dvbci_operatorprofile.h index 358c7e23a90..7f2f2bbc79c 100644 --- a/lib/dvb_ci/dvbci_operatorprofile.h +++ b/lib/dvb_ci/dvbci_operatorprofile.h @@ -6,7 +6,9 @@ class eDVBCIOperatorProfileSession: public eDVBCISession { enum { - stateFinal=statePrivate + stateStatusRequest=statePrivate, + stateStatus, + stateFinal }; int receivedAPDU(const unsigned char *tag, const void *data, int len); diff --git a/lib/dvb_ci/dvbci_resmgr.cpp b/lib/dvb_ci/dvbci_resmgr.cpp index 99bd8d194f0..17ab0902a86 100644 --- a/lib/dvb_ci/dvbci_resmgr.cpp +++ b/lib/dvb_ci/dvbci_resmgr.cpp @@ -6,7 +6,7 @@ int eDVBCIResourceManagerSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLineStart("[CI RM] SESSION(%d) %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLineStart("[CI%d RM] SESSION(%d) %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID()); state=stateProfileEnquiry; return 1; break; case 0x11: // Tprofile - eDebugNoNewLineStart("[CI RM] can do: "); + eDebugNoNewLineStart("[CI%d RM] can do: ", slot->getSlotID()); if (!len) eDebugNoNewLine("nothing"); else @@ -36,7 +36,7 @@ int eDVBCIResourceManagerSession::receivedAPDU(const unsigned char *tag,const vo state=stateFinal; break; default: - eWarning("[CI RM] unknown APDU tag 9F 80 %02x", tag[2]); + eWarning("[CI%d RM] unknown APDU tag 9F 80 %02x", slot->getSlotID(), tag[2]); } } @@ -63,7 +63,7 @@ int eDVBCIResourceManagerSession::doAction() } case stateProfileChange: { - eWarning("[CI RM] cannot deal with statProfileChange"); + eWarning("[CI%d RM] cannot deal with statProfileChange", slot->getSlotID()); break; } case stateProfileEnquiry: @@ -84,11 +84,13 @@ int eDVBCIResourceManagerSession::doAction() {0x00, 0x01, 0x00, 0x41}, // res mgr 1 // {0x00, 0x01, 0x00, 0x42}, // res mgr 2 {0x00, 0x02, 0x00, 0x41}, // app mgr 1 -// {0x00, 0x02, 0x00, 0x42}, // app mgr 2 + {0x00, 0x02, 0x00, 0x42}, // app mgr 2 {0x00, 0x02, 0x00, 0x43}, // app mgr 3 + {0x00, 0x02, 0x00, 0x45}, // app mgr 5 {0x00, 0x03, 0x00, 0x41}, // ca mgr {0x00, 0x20, 0x00, 0x41}, // host ctrl 1 {0x00, 0x20, 0x00, 0x42}, // host ctrl 2 + {0x00, 0x20, 0x00, 0x43}, // host ctrl 3 {0x00, 0x24, 0x00, 0x41}, // datetime {0x00, 0x40, 0x00, 0x41}, // mmi // {0x00, 0x10, 0x00, 0x41}, @@ -96,9 +98,11 @@ int eDVBCIResourceManagerSession::doAction() {0x00, 0x41, 0x00, 0x42}, // app mmi 2 {0x00, 0x8c, 0x10, 0x01}, // content ctrl 1 {0x00, 0x8c, 0x10, 0x02}, // content ctrl 2 + {0x00, 0x8c, 0x10, 0x04}, // content ctrl 4 {0x00, 0x8d, 0x10, 0x01}, // Host lang ctrl {0x00, 0x8e, 0x10, 0x01}, // Cam upgrade - {0x00, 0x8f, 0x10, 0x01}, // operator profile + {0x00, 0x8f, 0x10, 0x01}, // operator profile 1 + {0x00, 0x8f, 0x10, 0x02}, // operator profile 2 // {0x00, 0x97, 0x10, 0x01}, // {0x00, 0x60, 0x60, 0x03}, // {0x00, 0x04, 0x10, 0x01}, @@ -112,7 +116,7 @@ int eDVBCIResourceManagerSession::doAction() return 0; } case stateFinal: - eWarning("[CI RM] Should not happen: action on stateFinal"); + eWarning("[CI%d RM] Should not happen: action on stateFinal", slot->getSlotID()); default: break; } diff --git a/lib/dvb_ci/dvbci_session.cpp b/lib/dvb_ci/dvbci_session.cpp index e39d1df50e7..c8cc88638f6 100644 --- a/lib/dvb_ci/dvbci_session.cpp +++ b/lib/dvb_ci/dvbci_session.cpp @@ -97,7 +97,7 @@ void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char sess { char pkt[6]; pkt[0]=session_status; - eDebug("[CI SESS] sendOpenSessionResponse"); + eDebug("[CI%d SESS] sendOpenSessionResponse", slot->getSlotID()); memcpy(pkt + 1, resource_identifier, 4); sendSPDU(slot, 0x92, pkt, 5, session_nb); } @@ -107,14 +107,12 @@ void eDVBCISession::recvCreateSessionResponse(const unsigned char *data) status = data[0]; state = stateStarted; action = 1; - eDebug("[CI SESS] create Session Response, status %x", status); } void eDVBCISession::recvCloseSessionRequest(const unsigned char *data) { state = stateInDeletion; action = 1; - eDebug("[CI SESS] close Session Request"); } void eDVBCISession::deleteSessions(const eDVBCISlot *slot) @@ -151,74 +149,104 @@ void eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resourc { case 0x00010041: session=new eDVBCIResourceManagerSession(slot->getVersion()); - eDebug("[CI SESS] RESOURCE MANAGER"); + eDebug("[CI%d SESS] RESOURCE MANAGER 1", slot->getSlotID()); break; case 0x00020041: + session=new eDVBCIApplicationManagerSession(slot); + eDebug("[CI%d SESS] APPLICATION MANAGER 1", slot->getSlotID()); + break; + case 0x00020042: + session=new eDVBCIApplicationManagerSession(slot); + eDebug("[CI%d SESS] APPLICATION MANAGER 2", slot->getSlotID()); + break; case 0x00020043: session=new eDVBCIApplicationManagerSession(slot); - eDebug("[CI SESS] APPLICATION MANAGER"); + eDebug("[CI%d SESS] APPLICATION MANAGER 3", slot->getSlotID()); + break; + case 0x00020045: + session=new eDVBCIApplicationManagerSession(slot); + eDebug("[CI%d SESS] APPLICATION MANAGER 5", slot->getSlotID()); break; case 0x00030041: session = new eDVBCICAManagerSession(slot); - eDebug("[CI SESS] CA MANAGER"); + eDebug("[CI%d SESS] CA MANAGER", slot->getSlotID()); break; case 0x00200041: + session = new eDVBCIHostControlSession; + eDebug("[CI%d SESS] Host Control 1", slot->getSlotID()); + break; case 0x00200042: session = new eDVBCIHostControlSession; - eDebug("[CI SESS] Host Control"); + eDebug("[CI%d SESS] Host Control 2", slot->getSlotID()); + break; + case 0x00200043: + session = new eDVBCIHostControlSession; + eDebug("[CI%d SESS] Host Control 3", slot->getSlotID()); break; case 0x00240041: session=new eDVBCIDateTimeSession; - eDebug("[CI SESS] DATE-TIME"); + eDebug("[CI%d SESS] DATE-TIME", slot->getSlotID()); break; case 0x00400041: session = new eDVBCIMMISession(slot); - eDebug("[CI SESS] MMI - create session"); + eDebug("[CI%d SESS] MMI - create session", slot->getSlotID()); break; case 0x00410041: + session = new eDVBCIApplicationMMISession; + eDebug("[CI%d SESS] Application MMI 1", slot->getSlotID()); + break; case 0x00410042: session = new eDVBCIApplicationMMISession; - eDebug("[CI SESS] Application MMI"); + eDebug("[CI%d SESS] Application MMI 2", slot->getSlotID()); break; case 0x008C1001: eDVBCIInterfaces::getInstance()->setCIPlusRouting(slot->getSlotID()); session = new eDVBCICcSession(slot, 1); - eDebug("[CI SESS] Content Control v1"); + eDebug("[CI%d SESS] Content Control 1", slot->getSlotID()); break; case 0x008C1002: eDVBCIInterfaces::getInstance()->setCIPlusRouting(slot->getSlotID()); session = new eDVBCICcSession(slot, 2); - eDebug("[CI SESS] Content Control v2"); + eDebug("[CI%d SESS] Content Control 2", slot->getSlotID()); + break; + case 0x008C1004: + eDVBCIInterfaces::getInstance()->setCIPlusRouting(slot->getSlotID()); + session = new eDVBCICcSession(slot, 4); + eDebug("[CI%d SESS] Content Control 4", slot->getSlotID()); break; case 0x008D1001: session = new eDVBCIHostLanguageAndCountrySession; - eDebug("[CI SESS] Host Language & Country"); + eDebug("[CI%d SESS] Host Language & Country", slot->getSlotID()); break; case 0x008E1001: session = new eDVBCICAMUpgradeSession; - eDebug("[CI SESS] CAM Upgrade"); + eDebug("[CI%d SESS] CAM Upgrade", slot->getSlotID()); break; case 0x008F1001: session = new eDVBCIOperatorProfileSession; - eDebug("[CI SESS] Operator Profile"); + eDebug("[CI%d SESS] Operator Profile 1", slot->getSlotID()); + break; + case 0x008F1002: + session = new eDVBCIOperatorProfileSession; + eDebug("[CI%d SESS] Operator Profile 2", slot->getSlotID()); break; case 0x00100041: // session=new eDVBCIAuthSession; - eDebug("[CI SESS] AuthSession"); + eDebug("[CI%d SESS] AuthSession", slot->getSlotID()); [[fallthrough]]; default: - eDebug("[CI SESS] unknown resource type %02x %02x %02x %02x", resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]); + eDebug("[CI%d SESS] unknown resource type %02x %02x %02x %02x", slot->getSlotID(), resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]); session=0; status=0xF0; } if (!session) { - eWarning("[CI SESS] unknown session.. expect crash"); + eWarning("[CI%d SESS] unknown session.. expect crash", slot->getSlotID()); return; } - eDebug("[CI SESS] new session nb %d %p", session_nb, &(*session)); + eDebug("[CI%d SESS] new session nb %d %p", slot->getSlotID(), session_nb, &(*session)); session->session_nb = session_nb; if (session) @@ -263,9 +291,9 @@ void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size unsigned char tag = *pkt++; int llen, hlen; - eDebug("[CI SESS] slot: %p",slot); + eDebug("[CI%d SESS] slot: %p", slot->getSlotID(), slot); - eTraceNoNewLineStart("[CI SESS]: "); + eTraceNoNewLineStart("[CI%d SESS]: ", slot->getSlotID()); for(unsigned int i=0;i= SLMS)) { - eWarning("[CI SESS] PROTOCOL: illegal session number %x", session_nb); + eWarning("[CI%d SESS] PROTOCOL: illegal session number %x", slot->getSlotID(), session_nb); return; } session=sessions[session_nb-1]; if (!session) { - eWarning("[CI SESS] PROTOCOL: data on closed session %x", session_nb); + eWarning("[CI%d SESS] PROTOCOL: data on closed session %x", slot->getSlotID(), session_nb); return; } @@ -311,14 +339,15 @@ void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size case 0x90: break; case 0x94: + eDebug("[CI%d SESS] recvCreateSessionResponse, status %x", slot->getSlotID(), pkt[0]); session->recvCreateSessionResponse(pkt); break; case 0x95: - eDebug("[CI SESS] recvCloseSessionRequest"); + eDebug("[CI%d SESS] recvCloseSessionRequest", slot->getSlotID()); session->recvCloseSessionRequest(pkt); break; default: - eDebug("[CI SESS] INTERNAL: nyi, tag %02x.", tag); + eDebug("[CI%d SESS] INTERNAL: nyi, tag %02x.", slot->getSlotID(),tag); return; } } @@ -343,7 +372,7 @@ void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size { if (((len-alen) > 0) && ((len - alen) < 3)) { - eDebug("[CI SESS] WORKAROUND: applying work around MagicAPDULength"); + eDebug("[CI%d SESS] WORKAROUND: applying work around MagicAPDULength", slot->getSlotID()); alen=len; } } @@ -354,7 +383,7 @@ void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size } if (len) - eWarning("[CI SESS] PROTOCOL: warning, TL-Data has invalid length"); + eWarning("[CI%d SESS] PROTOCOL: warning, TL-Data has invalid length", slot->getSlotID()); } eDVBCISession::~eDVBCISession() diff --git a/lib/gui/elistbox.cpp b/lib/gui/elistbox.cpp index 66d07d0006a..06b5f949deb 100644 --- a/lib/gui/elistbox.cpp +++ b/lib/gui/elistbox.cpp @@ -914,6 +914,11 @@ void eListbox::setSelectionPicture(ePtr &pm) m_style.m_selection = pm; } +void eListbox::setSelectionPictureLarge(ePtr &pm) +{ + m_style.m_selection_large = pm; +} + void eListbox::setSelectionBorderHidden() { m_style.m_border_set = 1; diff --git a/lib/gui/elistbox.h b/lib/gui/elistbox.h index 5157830900b..a96c4b9aad9 100644 --- a/lib/gui/elistbox.h +++ b/lib/gui/elistbox.h @@ -62,7 +62,7 @@ class iListboxContent: public iObject #ifndef SWIG struct eListboxStyle { - ePtr m_background, m_selection; + ePtr m_background, m_selection, m_selection_large; int m_transparent_background; int m_border_set; gRGB m_background_color, m_background_color_selected, m_foreground_color, m_foreground_color_selected, m_border_color; @@ -166,6 +166,7 @@ class eListbox: public eWidget void setBorderWidth(int size); void setBackgroundPicture(ePtr &pixmap); void setSelectionPicture(ePtr &pixmap); + void setSelectionPictureLarge(ePtr &pixmap); void setSelectionBorderHidden(); void setFont(gFont *font); diff --git a/lib/gui/elistboxcontent.cpp b/lib/gui/elistboxcontent.cpp index 3f68334da68..ed13c38a388 100644 --- a/lib/gui/elistboxcontent.cpp +++ b/lib/gui/elistboxcontent.cpp @@ -287,13 +287,15 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, { const char *string = PyUnicode_Check(item) ? PyUnicode_AsUTF8(item) : ""; ePoint text_offset = offset; + ePoint style_text_offset = ePoint(0, 0); if (gray) painter.setForegroundColor(gRGB(0x808080)); int flags = 0; if (local_style) { - text_offset += local_style->m_text_offset; + style_text_offset = local_style->m_text_offset; + text_offset += style_text_offset; if (local_style->m_valign == eListboxStyle::alignTop) flags |= gPainter::RT_VALIGN_TOP; @@ -312,7 +314,8 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, flags |= gPainter::RT_HALIGN_BLOCK; } - painter.renderText(eRect(text_offset, m_itemsize), string, flags, border_color, border_size); + // Here we have to compensate the local style text offset from both sides + painter.renderText(eRect(text_offset.x(), text_offset.y(), m_itemsize.width() - style_text_offset.x()*2, m_itemsize.height() - style_text_offset.y()*2), string, flags, border_color, border_size); } } diff --git a/lib/mmi/mmi_ui.cpp b/lib/mmi/mmi_ui.cpp index 432ffc344b4..fd59e41916d 100644 --- a/lib/mmi/mmi_ui.cpp +++ b/lib/mmi/mmi_ui.cpp @@ -73,11 +73,12 @@ int eMMI_UI::processMMIData(int slot_id, const unsigned char *tag, const void *d eDebug("[eMMI_UI] %d bytes text", textlen); if ((d+textlen) > max) break; - char str[textlen + 1]; - memcpy(str, ((char*)d), textlen); + unsigned char str[textlen + 1]; + memcpy(str, ((unsigned char*)d), textlen); str[textlen] = '\0'; - eDebug("[eMMI_UI] enq-text: %s",str); - mmiScreenEnq(slot_id, blind, alen, (char*)convertDVBUTF8(str).c_str()); + std::string converted_str = convertDVBUTF8(str, textlen, -1, 1, 0); + eDebug("[eMMI_UI] enq-text: %s", converted_str.c_str()); + mmiScreenEnq(slot_id, blind, alen, (char*)converted_str.c_str()); break; } case 0x09: //Tmenu_last @@ -110,14 +111,13 @@ int eMMI_UI::processMMIData(int slot_id, const unsigned char *tag, const void *d eDebug("[eMMI_UI] %d bytes text", textlen); if ((d+textlen) > max) break; - char str[textlen + 1]; - memcpy(str, ((char*)d), textlen); + unsigned char str[textlen + 1]; + memcpy(str, ((unsigned char*)d), textlen); str[textlen] = '\0'; - mmiScreenAddText(slot_id, pos++, (char*)convertDVBUTF8(str).c_str()); - eDebugNoNewLineStart("[eMMI_UI] "); - while (textlen--) - eDebugNoNewLine("%c", *d++); - eDebugNoNewLine("\n"); + std::string converted_str = convertDVBUTF8(str, textlen, -1, 1, 0); + mmiScreenAddText(slot_id, pos++, (char*)converted_str.c_str()); + eDebug("[eMMI_UI] %s", converted_str.c_str()); + d += textlen; } mmiScreenFinish(slot_id); break; diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index d93093ee60b..d85716e79a1 100644 --- a/lib/python/Components/AVSwitch.py +++ b/lib/python/Components/AVSwitch.py @@ -1,7 +1,6 @@ from os import path from enigma import eAVSwitch, getDesktop -from boxbranding import getBoxType, getBrandOEM from Components.config import ConfigBoolean, ConfigEnableDisable, ConfigNothing, ConfigSelection, ConfigSelectionNumber, ConfigSlider, ConfigSubDict, ConfigSubsection, ConfigYesNo, NoSave, config from Components.SystemInfo import SystemInfo @@ -143,7 +142,7 @@ def setMode(self, port, mode, rate, force=None): except (IOError, OSError): print("[AVSwitch] cannot open /proc/stb/video/videomode_24hz") - if getBrandOEM() in ("gigablue",): + if SystemInfo["brand"] in ("gigablue",): try: # use 50Hz mode (if available) for booting with open("/etc/videomode", "w") as fd: @@ -486,7 +485,7 @@ def setEDIDBypass(configElement): if SystemInfo["havecolorspace"]: def setHDMIColorspace(configElement): open(SystemInfo["havecolorspace"], "w").write(configElement.value) - if getBrandOEM() == "vuplus" and SystemInfo["HasMMC"]: + if SystemInfo["brand"] == "vuplus" and SystemInfo["HasMMC"]: choices = [ ("Edid(Auto)", _("Auto")), ("Hdmi_Rgb", _("RGB")), @@ -862,7 +861,7 @@ def setScaler_sharpness(configElement): open("/proc/stb/vmpeg/0/pep_apply", "w").write("1") except (IOError, OSError): print("[AVSwitch] couldn't write pep_scaler_sharpness") - if getBoxType() in ("gbquad", "gbquadplus"): + if SystemInfo["boxtype"] in ("gbquad", "gbquadplus"): config.av.scaler_sharpness = ConfigSlider(default=5, limits=(0, 26)) else: config.av.scaler_sharpness = ConfigSlider(default=13, limits=(0, 26)) diff --git a/lib/python/Components/About.py b/lib/python/Components/About.py index 7aef5d9f290..bf5a28f805a 100644 --- a/lib/python/Components/About.py +++ b/lib/python/Components/About.py @@ -5,13 +5,12 @@ import fcntl import struct -from boxbranding import getDriverDate, getImageVersion, getMachineBuild, getBoxType - from enigma import getEnigmaVersionString def getVersionString(): - return getImageVersion() + from Components.SystemInfo import SystemInfo + return SystemInfo["imageversion"] def getFlashDateString(): @@ -23,7 +22,8 @@ def getFlashDateString(): def driversDate(): - return _formatDate(getDriverDate()) + from Components.SystemInfo import SystemInfo + return _formatDate(SystemInfo["driversdate"]) def getLastUpdate(): @@ -84,7 +84,8 @@ def getCPUSpeedMHzInt(): print("[About] getCPUSpeedMHzInt, /proc/cpuinfo not available") if cpu_speed == 0: - if getMachineBuild() in ("h7", "hd51", "sf4008", "osmio4k", "osmio4kplus", "osmini4k"): + from Components.SystemInfo import MODEL + if MODEL in ("h7", "hd51", "sf4008", "osmio4k", "osmio4kplus", "osmini4k"): try: import binascii with open("/sys/firmware/devicetree/base/cpus/cpu@0/clock-frequency", "rb") as f: @@ -113,7 +114,8 @@ def getCPUSpeedString(): def getCPUArch(): - if getBoxType() in ("osmio4k", ): + from Components.SystemInfo import MODEL + if MODEL.startswith("osmio4k"): return "ARM V7" if "ARM" in getCPUString(): return getCPUString() @@ -122,7 +124,7 @@ def getCPUArch(): def getCPUString(): try: - return [x.split(": ")[1].split(" ")[0] for x in open("/proc/cpuinfo").readlines() if (x.startswith("system type") or x.startswith("model name") or x.startswith("Processor")) and len(x.split(": ")) > 1][0] + return [x.split(": ")[1].split(" ")[0] for x in open("/proc/cpuinfo").readlines() if x.startswith(("system type", "model name", "Processor")) and len(x.split(": ")) > 1][0] except: return _("unavailable") diff --git a/lib/python/Components/Addons/ButtonSequence.py b/lib/python/Components/Addons/ButtonSequence.py new file mode 100644 index 00000000000..c58339e261b --- /dev/null +++ b/lib/python/Components/Addons/ButtonSequence.py @@ -0,0 +1,105 @@ +from Components.Addons.GUIAddon import GUIAddon + +from enigma import eListbox, eListboxPythonMultiContent, BT_ALIGN_CENTER + +from skin import parseScale, applySkinFactor + +from Components.MultiContent import MultiContentEntryPixmapAlphaBlend +from Components.Sources.Boolean import Boolean +from Components.Sources.StaticText import StaticText + +from Tools.Directories import resolveFilename, SCOPE_GUISKIN +from Tools.LoadPixmap import LoadPixmap + + +class ButtonSequence(GUIAddon): + def __init__(self): + GUIAddon.__init__(self) + self.l = eListboxPythonMultiContent() # noqa: E741 + self.l.setBuildFunc(self.buildEntry) + self.l.setItemHeight(36) + self.l.setItemWidth(36) + self.spacing = applySkinFactor(10) + self.orientations = {"orHorizontal": eListbox.orHorizontal, "orVertical": eListbox.orVertical} + self.orientation = eListbox.orHorizontal + self.alignment = "left" + self.pixmaps = {} + + def onContainerShown(self): + for x, val in self.sources.items(): + if self.constructButtonSequence not in val.onChanged: + val.onChanged.append(self.constructButtonSequence) + self.l.setItemHeight(self.instance.size().height()) + self.l.setItemWidth(self.instance.size().width()) + self.constructButtonSequence() + + GUI_WIDGET = eListbox + + def updateAddon(self, sequence): + l_list = [] + l_list.append((sequence,)) + self.l.setList(l_list) + + def buildEntry(self, sequence): + xPos = self.instance.size().width() if self.alignment == "right" else 0 + yPos = 0 + + res = [None] + + for x in sequence: + if x in self.pixmaps: + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmaps[x])) + if pic: + pixd_size = pic.size() + pixd_width = pixd_size.width() + pixd_height = pixd_size.height() + pic_x_pos = (xPos - pixd_width) if self.alignment == "right" else xPos + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(pic_x_pos, yPos), + size=(pixd_width, pixd_height), + png=pic, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + if self.alignment == "right": + xPos -= pixd_width + self.spacing + else: + xPos += pixd_width + self.spacing + return res + + def postWidgetCreate(self, instance): + instance.setSelectionEnable(False) + instance.setContent(self.l) + instance.allowNativeKeys(False) + + def constructButtonSequence(self): + sequence = [] + for x, val in self.sources.items(): + if isinstance(val, Boolean) and val.boolean: + if x not in sequence: + sequence.append(x) + elif isinstance(val, StaticText) and val.text: + if x not in sequence: + sequence.append(x) + + self.updateAddon(sequence) + + def applySkin(self, desktop, parent): + attribs = [] + for (attrib, value) in self.skinAttributes[:]: + if attrib == "pixmaps": + self.pixmaps = dict(item.split(':') for item in value.split(',')) + elif attrib == "spacing": + self.spacing = parseScale(value) + elif attrib == "alignment": + self.alignment = value + elif attrib == "orientation": + self.orientation = self.orientations.get(value, self.orientations["orHorizontal"]) + if self.orientation == eListbox.orHorizontal: + self.instance.setOrientation(eListbox.orVertical) + self.l.setOrientation(eListbox.orVertical) + else: + self.instance.setOrientation(eListbox.orHorizontal) + self.l.setOrientation(eListbox.orHorizontal) + else: + attribs.append((attrib, value)) + self.skinAttributes = attribs + return GUIAddon.applySkin(self, desktop, parent) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py new file mode 100644 index 00000000000..160d4218cec --- /dev/null +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -0,0 +1,161 @@ +from Components.Addons.GUIAddon import GUIAddon + +from enigma import eListbox, eListboxPythonMultiContent, BT_ALIGN_CENTER, RT_VALIGN_CENTER, RT_HALIGN_LEFT, eSize, getDesktop, gFont + +from skin import parseScale, parseColor, parseFont, applySkinFactor + +from Components.MultiContent import MultiContentEntryPixmapAlphaBlend +from Components.Label import Label + +from Tools.Directories import resolveFilename, SCOPE_GUISKIN +from Tools.LoadPixmap import LoadPixmap + + +class ColorButtonsSequence(GUIAddon): + def __init__(self): + GUIAddon.__init__(self) + self.foreColor = None + self.font = gFont("Regular", 18) + self.l = eListboxPythonMultiContent() # noqa: E741 + self.l.setBuildFunc(self.buildEntry) + self.l.setItemHeight(35) + self.l.setItemWidth(35) + self.spacingButtons = applySkinFactor(40) + self.spacingPixmapText = applySkinFactor(10) + self.layoutStyle = "fixed" + self.colorIndicatorStyle = "pixmap" + self.orientations = {"orHorizontal": eListbox.orHorizontal, "orVertical": eListbox.orVertical} + self.orientation = eListbox.orHorizontal + self.alignment = "left" + self.pixmaps = {} + self.colors = {} + self.textRenderer = Label("") + + def onContainerShown(self): + for x, val in self.sources.items(): + if self.constructColorButtonSequence not in val.onChanged: + val.onChanged.append(self.constructColorButtonSequence) + self.textRenderer.GUIcreate(self.relatedScreen.instance) + self.l.setItemHeight(self.instance.size().height()) + self.l.setItemWidth(self.instance.size().width()) + self.constructColorButtonSequence() + + GUI_WIDGET = eListbox + + def updateAddon(self, sequence): + l_list = [] + l_list.append((sequence,)) + self.l.setList(l_list) + + def buildEntry(self, sequence): + res = [None] + if len(sequence) == 0: + return res + width = self.instance.size().width() + height = self.instance.size().height() + xPos = width if self.alignment == "right" else 0 + yPos = 0 + minSectorWidth = width // 4 + + pic = None + pixd_width = 0 + + for x, val in sequence.items(): + textColor = self.foreColor + if x in self.colors: + textColor = parseColor(self.colors[x]).argb() + if x in self.pixmaps: + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmaps[x])) + if pic: + pixd_size = pic.size() + pixd_width = pixd_size.width() + pic_x_pos = (xPos - pixd_width) if self.alignment == "right" else xPos + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(pic_x_pos, yPos), + size=(pixd_width, height), + png=pic, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + if self.alignment == "right": + xPos -= pixd_width + self.spacingPixmapText + else: + xPos += pixd_width + self.spacingPixmapText + if hasattr(val, "text"): + buttonText = val.text + else: + buttonText = "" + + if buttonText: + textWidth = self._calcTextWidth(buttonText, font=self.font, size=eSize(self.getDesktopWith() // 3, 0)) + else: + textWidth = 0 + if self.layoutStyle != "fluid": + if textWidth < (minSectorWidth - self.spacingButtons - (self.spacingPixmapText if pic else 0) - pixd_width): + textWidth = minSectorWidth - self.spacingButtons - (self.spacingPixmapText if pic else 0) - pixd_width + if buttonText: + if textColor is not None: + res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor)) + else: + res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText)) + xPos += textWidth + self.spacingButtons + if xPos > width and self.layoutStyle != "fluid": + self.layoutStyle = "fluid" + return self.buildEntry(sequence) + + return res + + def postWidgetCreate(self, instance): + instance.setSelectionEnable(False) + instance.setContent(self.l) + instance.allowNativeKeys(False) + + def constructColorButtonSequence(self): + sequence = {} + for x, val in self.sources.items(): + if hasattr(val, "text") and val.text: + sequence[x] = val + + self.updateAddon(sequence) + + def applySkin(self, desktop, parent): + attribs = [] + for (attrib, value) in self.skinAttributes[:]: + if attrib == "pixmaps": + self.pixmaps = dict(item.split(':') for item in value.split(',')) + elif attrib == "spacing": + self.spacingButtons = parseScale(value) + elif attrib == "spacingPixmapText": + self.spacingPixmapText = parseScale(value) + elif attrib == "layoutStyle": + self.layoutStyle = value + elif attrib == "alignment": + self.alignment = value + elif attrib == "orientation": + self.orientation = self.orientations.get(value, self.orientations["orHorizontal"]) + if self.orientation == eListbox.orHorizontal: + self.instance.setOrientation(eListbox.orVertical) + self.l.setOrientation(eListbox.orVertical) + else: + self.instance.setOrientation(eListbox.orHorizontal) + self.l.setOrientation(eListbox.orHorizontal) + elif attrib == "font": + self.font = parseFont(value, ((1, 1), (1, 1))) + elif attrib == "foregroundColor": + self.foreColor = parseColor(value).argb() + elif attrib == "textColors": + self.colors = dict(item.split(':') for item in value.split(',')) + else: + attribs.append((attrib, value)) + self.skinAttributes = attribs + self.l.setFont(0, self.font) + return GUIAddon.applySkin(self, desktop, parent) + + def _calcTextWidth(self, text, font=None, size=None): + if size: + self.textRenderer.instance.resize(size) + if font: + self.textRenderer.instance.setFont(font) + self.textRenderer.text = text + return self.textRenderer.instance.calculateSize().width() + + def getDesktopWith(self): + return getDesktop(0).size().width() diff --git a/lib/python/Components/Addons/GUIAddon.py b/lib/python/Components/Addons/GUIAddon.py index 4257ac526d4..f1264cc34ed 100644 --- a/lib/python/Components/Addons/GUIAddon.py +++ b/lib/python/Components/Addons/GUIAddon.py @@ -4,10 +4,22 @@ class GUIAddon(GUIComponent): def __init__(self): GUIComponent.__init__(self) + self.sources = {} + self.relatedScreen = None def connectRelatedElement(self, relatedElementName, container): - self.source = container[relatedElementName] + relatedElementNames = relatedElementName.split(",") + if len(relatedElementNames) == 1: + self.source = container[relatedElementName] + elif len(relatedElementNames) > 1: + for x in relatedElementNames: + if x in container: + component = container[x] + self.sources[x] = component + if isinstance(component, GUIComponent) and x not in container.handledWidgets: + container.handledWidgets.append(x) container.onShow.append(self.onContainerShown) + self.relatedScreen = container def onContainerShown(self): pass diff --git a/lib/python/Components/Addons/Pager.py b/lib/python/Components/Addons/Pager.py index e30c22cc4cc..6cc9e71b181 100644 --- a/lib/python/Components/Addons/Pager.py +++ b/lib/python/Components/Addons/Pager.py @@ -21,9 +21,14 @@ def __init__(self): self.spacing = applySkinFactor(5) self.picDotPage = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/dot.png")) self.picDotCurPage = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/dotfull.png")) + self.picShevronLeft = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/shevronleft.png")) + self.picShevronRight = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/shevronright.png")) + self.picShevronUp = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/shevronup.png")) + self.picShevronDown = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/shevrondown.png")) self.showIcons = "showAll" # can be "showAll", "onlyFirst", "onlyLast" self.orientations = {"orHorizontal": eListbox.orHorizontal, "orVertical": eListbox.orVertical} self.orientation = eListbox.orHorizontal + self.max_pages = 10 def onContainerShown(self): # disable listboxes default scrollbars @@ -51,7 +56,51 @@ def buildEntry(self, currentPage, pageCount): xPos = (width - width_dots) / 2 - pixd_width / 2 if self.showIcons == "showAll" else 0 yPos = (height - height_dots) / 2 - pixd_height / 2 if self.showIcons == "showAll" else 0 res = [None] - if pageCount > (0 if self.showIcons == "showAll" else -1): + if self.showIcons == "showAll" and pageCount > 0 and self.max_pages > 0 and pageCount > self.max_pages: + width_dots = pixd_width + (pixd_width + self.spacing) * (2 if currentPage > 0 and currentPage < pageCount else 1) + xPos = (width - width_dots) / 2 - pixd_width / 2 + yPos = (height - height_dots) / 2 - pixd_height / 2 + if self.orientation == eListbox.orHorizontal: + if currentPage > 0: + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(xPos, 0), + size=(pixd_width, pixd_height), + png=self.picShevronLeft, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + xPos += pixd_width + self.spacing + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(xPos, 0), + size=(pixd_width, pixd_height), + png=self.picDotCurPage, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + xPos += pixd_width + self.spacing + if currentPage < pageCount: + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(xPos, 0), + size=(pixd_width, pixd_height), + png=self.picShevronRight, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + else: + if currentPage > 0: + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(0, yPos), + size=(pixd_width, pixd_height), + png=self.picShevronLeft, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + yPos += pixd_height + self.spacing + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(0, yPos), + size=(pixd_width, pixd_height), + png=self.picDotCurPage, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + yPos += pixd_height + self.spacing + if currentPage < pageCount: + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(0, yPos), + size=(pixd_width, pixd_height), + png=self.picShevronRight, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + elif pageCount > (0 if self.showIcons == "showAll" else -1): pages = list(range(pageCount + 1)) # add option to show just first or last icon if self.showIcons == "onlyFirst": @@ -113,6 +162,8 @@ def getListCount(self): return self.source.listCount elif hasattr(self.source, 'list'): return len(self.source.list) + elif hasattr(self.source, 'l') and hasattr(self.source.l, 'getListSize'): + return self.source.l.getListSize() return 0 def getListItemSize(self): @@ -163,6 +214,22 @@ def applySkin(self, desktop, parent): pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) if pic: self.picDotCurPage = pic + elif attrib == "picL": + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) + if pic: + self.picShevronLeft = pic + elif attrib == "picR": + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) + if pic: + self.picShevronRight = pic + elif attrib == "picU": + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) + if pic: + self.picShevronUp = pic + elif attrib == "picD": + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) + if pic: + self.picShevronDown = pic elif attrib == "itemHeight": self.l.setItemHeight(parseScale(value)) elif attrib == "itemWidth": @@ -171,6 +238,8 @@ def applySkin(self, desktop, parent): self.spacing = parseScale(value) elif attrib == "showIcons": self.showIcons = value + elif attrib == "maxPages": + self.max_pages = int(value) elif attrib == "orientation": self.orientation = self.orientations.get(value, self.orientations["orHorizontal"]) if self.orientation == eListbox.orHorizontal: diff --git a/lib/python/Components/Addons/ScreenHeader.py b/lib/python/Components/Addons/ScreenHeader.py new file mode 100644 index 00000000000..13534975c8f --- /dev/null +++ b/lib/python/Components/Addons/ScreenHeader.py @@ -0,0 +1,100 @@ +from Components.Addons.GUIAddon import GUIAddon + +from enigma import eListbox, eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_VALIGN_CENTER + +from skin import applySkinFactor, parseFont, parseColor + +from Components.MultiContent import MultiContentEntryText +from Components.Sources.StaticText import StaticText + + +class ScreenHeader(GUIAddon): + def __init__(self): + GUIAddon.__init__(self) + self.l = eListboxPythonMultiContent() # noqa: E741 + self.l.setBuildFunc(self.buildEntry) + self.l.setItemHeight(36) + self.l.setItemWidth(36) + self.orientation = eListbox.orHorizontal + self.titleFont = gFont("Regular", applySkinFactor(22)) + self.titleSingleFont = gFont("Regular", applySkinFactor(24)) + self.pathFont = gFont("Regular", applySkinFactor(16)) + self.titleForeground = 0xffffff + self.pathForeground = 0xffffff + self.backgroundColor = 0x000000 + + def onContainerShown(self): + for x, val in self.sources.items(): + if self.constructTitleItem not in val.onChanged: + val.onChanged.append(self.constructTitleItem) + self.l.setItemHeight(self.instance.size().height()) + self.l.setItemWidth(self.instance.size().width()) + self.constructTitleItem() + + GUI_WIDGET = eListbox + + def updateAddon(self, sequence): + l_list = [] + l_list.append((sequence,)) + self.l.setList(l_list) + + def buildEntry(self, sequence): + yPos = 0 + + res = [None] + isOneItem = len(sequence) == 1 + + for idx, x in enumerate(sequence): + foreColor = self.titleForeground if idx == 0 else self.pathForeground + if isOneItem: + itemHeight = self.instance.size().height() + if not isOneItem and idx == 0: + itemHeight = self.instance.size().height() * 2 // 3 + elif idx == 1: + yPos = self.instance.size().height() * 2 // 3 - 3 + itemHeight = self.instance.size().height() // 3 + res.append(MultiContentEntryText( + pos=(0, yPos), + size=(self.instance.size().width(), itemHeight), + font=2 if isOneItem and idx == 0 else idx, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, + text=x.text, + color=foreColor, color_sel=foreColor, + backcolor=self.backgroundColor, backcolor_sel=self.backgroundColor)) + return res + + def postWidgetCreate(self, instance): + instance.setSelectionEnable(False) + instance.setContent(self.l) + instance.allowNativeKeys(False) + + def constructTitleItem(self): + sequence = [] + for x, val in self.sources.items(): + if isinstance(val, StaticText) and val.text: + if val not in sequence: + sequence.append(val) + + self.updateAddon(sequence) + + def applySkin(self, desktop, parent): + attribs = [] + for (attrib, value) in self.skinAttributes[:]: + if attrib == "titleFont": + self.titleFont = parseFont(value, ((1, 1), (1, 1))) + if attrib == "titleSingleFont": + self.titleSingleFont = parseFont(value, ((1, 1), (1, 1))) + elif attrib == "pathFont": + self.pathFont = parseFont(value, ((1, 1), (1, 1))) + elif attrib == "titleForegroundColor": + self.titleForeground = parseColor(value).argb() + elif attrib == "pathForegroundColor": + self.pathForeground = parseColor(value).argb() + elif attrib == "backgroundColor": + self.backgroundColor = parseColor(value).argb() + else: + attribs.append((attrib, value)) + self.skinAttributes = attribs + self.l.setFont(0, self.titleFont) + self.l.setFont(1, self.pathFont) + self.l.setFont(2, self.titleSingleFont) + return GUIAddon.applySkin(self, desktop, parent) diff --git a/lib/python/Components/ChannelsImporter.py b/lib/python/Components/ChannelsImporter.py index 6c0e94fa0cc..a2ee8d7c9ae 100644 --- a/lib/python/Components/ChannelsImporter.py +++ b/lib/python/Components/ChannelsImporter.py @@ -21,15 +21,25 @@ def autostart(): autoClientModeTimer = AutoClientModeTimer() +def getRemoteAddress(): + if config.clientmode.serverAddressType.value == "ip": + return "%d.%d.%d.%d" % (config.clientmode.serverIP.value[0], config.clientmode.serverIP.value[1], config.clientmode.serverIP.value[2], config.clientmode.serverIP.value[3]) + else: + return config.clientmode.serverDomain.value + + class AutoClientModeTimer: instance = None def __init__(self): self.clientmodetimer = eTimer() self.clientmodetimer.callback.append(self.ClientModeonTimer) + self.autostartscantimer = eTimer() + self.autostartscantimer.callback.append(self.doautostartscan) self.clientmodeactivityTimer = eTimer() self.clientmodeactivityTimer.timeout.get().append(self.clientmodedatedelay) now = int(time()) + self.attempts = 0 self.doautostartscan() # import at boot time global ClientModeTime @@ -111,14 +121,40 @@ def ClientModeonTimer(self): self.clientmodedate(atLeast) def doClientMode(self, answer): + self.autostartscantimer.stop() + self.attempts = 0 now = int(time()) - self.timer = eTimer() - self.timer.callback.append(self.doautostartscan) print("[ClientModeScheduler][doClientMode] Running ClientMode", strftime("%c", localtime(now))) - self.timer.start(100, 1) + self.autostartscantimer.start(100, 1) def doautostartscan(self): - ChannelsImporter() + self.autostartscantimer.stop() + if self.checkFTPconnection(): + self.attempts = 0 + ChannelsImporter() + else: + if self.attempts < 5: + print("[ChannelsImporter] attempt %d failed. Retrying..." % (self.attempts + 1,)) + self.autostartscantimer.startLongTimer(10) + self.attempts += 1 + + def checkFTPconnection(self): + print("[ChannelsImporter][checkFTPconnection] Testing FTP connection...") + try: + from ftplib import FTP + ftp = FTP() + ftp.set_pasv(config.clientmode.passive.value) + ftp.connect(host=getRemoteAddress(), port=config.clientmode.serverFTPPort.value, timeout=5) + result = ftp.login(user=config.clientmode.serverFTPusername.value, passwd=config.clientmode.serverFTPpassword.value) + ftp.quit() + if result.startswith("230"): + print("[ChannelsImporter][checkFTPconnection] FTP connection success:", result) + return True + print("[ChannelsImporter][checkFTPconnection] FTP connection failure:", result) + return False + except Exception as err: + print("[ChannelsImporter][checkFTPconnection] Error:", err) + return False def doneConfiguring(self): now = int(time()) @@ -320,10 +356,7 @@ def copyFile(self, source, dest): shutil.copy2(source, dest) def getRemoteAddress(self): - if config.clientmode.serverAddressType.value == "ip": - return "%d.%d.%d.%d" % (config.clientmode.serverIP.value[0], config.clientmode.serverIP.value[1], config.clientmode.serverIP.value[2], config.clientmode.serverIP.value[3]) - else: - return config.clientmode.serverDomain.value + return getRemoteAddress() def FTPdownloadFile(self, sourcefolder, sourcefile, destfile): print("[ChannelsImporter] Downloading remote file '%s'" % sourcefile) @@ -355,6 +388,6 @@ def forceSaveEPGonRemoteReceiver(self): except HTTPError as err: print("[ChannelsImporter][saveEPGonRemoteReceiver] ERROR:", err) except URLError as err: - print("[ChannelsImporter][saveEPGonRemoteReceiver] ERROR:", err.reason[0]) + print("[ChannelsImporter][saveEPGonRemoteReceiver] ERROR:", err.reason) except: print("[ChannelsImporter][saveEPGonRemoteReceiver] undefined error") diff --git a/lib/python/Components/ConfigList.py b/lib/python/Components/ConfigList.py index b92c32d76b2..f87de314e64 100644 --- a/lib/python/Components/ConfigList.py +++ b/lib/python/Components/ConfigList.py @@ -16,7 +16,7 @@ class ConfigList(GUIComponent): def __init__(self, list, session=None): GUIComponent.__init__(self) - self.l = eListboxPythonConfigContent() + self.l = eListboxPythonConfigContent() # noqa: E741 seperation = parameters.get("ConfigListSeperator", applySkinFactor(200)) self.l.setSeperation(seperation) height, space = parameters.get("ConfigListSlider", applySkinFactor(17, 0)) @@ -106,11 +106,11 @@ def preWidgetRemove(self, instance): instance.selectionChanged.get().remove(self.selectionChanged) instance.setContent(None) - def setList(self, l): - self.__list = l + def setList(self, configList): + self.__list = configList self.l.setList(self.__list) - if l is not None: - for x in l: + if configList is not None: + for x in configList: assert len(x) < 2 or isinstance(x[1], ConfigElement), "[ConfigList] Error: Entry in ConfigList '%s' must be a ConfigElement!" % str(x[1]) def getList(self): diff --git a/lib/python/Components/Converter/ConditionalShowHide.py b/lib/python/Components/Converter/ConditionalShowHide.py index b6b144e30d9..31456b70185 100644 --- a/lib/python/Components/Converter/ConditionalShowHide.py +++ b/lib/python/Components/Converter/ConditionalShowHide.py @@ -1,6 +1,7 @@ from enigma import eTimer from Components.Converter.Converter import Converter +from Components.config import config class ConditionalShowHide(Converter): @@ -8,7 +9,7 @@ def __init__(self, argstr): Converter.__init__(self, argstr) args = argstr.split(',') self.invert = "Invert" in args - self.blink = "Blink" in args + self.blink = "Blink" in args and config.usage.enable_blinking.value if self.blink: self.blinktime = len(args) == 2 and args[1].isdigit() and int(args[1]) or 500 self.timer = eTimer() diff --git a/lib/python/Components/Converter/Converter.py b/lib/python/Components/Converter/Converter.py index b50fb3a50b7..712efb9c449 100644 --- a/lib/python/Components/Converter/Converter.py +++ b/lib/python/Components/Converter/Converter.py @@ -13,9 +13,9 @@ def __repr__(self): def handleCommand(self, cmd): self.source.handleCommand(cmd) - def appendToStringWithSeparator(self, str, part): - if str == "": - str = part + def appendToStringWithSeparator(self, text, part): + if text == "": + text = part else: - str = str + self.separatorChar + part - return str + text = f"{text} {self.separatorChar} {part}" + return text diff --git a/lib/python/Components/Converter/ConverterRotator.py b/lib/python/Components/Converter/ConverterRotator.py index 66bcde363ff..dabb965b4e4 100644 --- a/lib/python/Components/Converter/ConverterRotator.py +++ b/lib/python/Components/Converter/ConverterRotator.py @@ -56,8 +56,8 @@ def changed(self, what, parent=None): upstream = upstream.source if len(self.sourceList): self.mainstream = self.sourceList.pop(0)[0] - #if what[0] == self.CHANGED_POLL and \ - # self.poll_enabled and \ - # not self.sourceList[self.sourceIndex][1]: - # return + # if what[0] == self.CHANGED_POLL and \ + # self.poll_enabled and \ + # not self.sourceList[self.sourceIndex][1]: + # return self.downstream_elements.changed(what) diff --git a/lib/python/Components/Converter/CpuUsage.py b/lib/python/Components/Converter/CpuUsage.py index c9f82fd3c9c..bbd242d087b 100644 --- a/lib/python/Components/Converter/CpuUsage.py +++ b/lib/python/Components/Converter/CpuUsage.py @@ -40,7 +40,7 @@ def __init__(self, type): if pos == -1: break if pos < len(self.sfmt) - 1 and self.sfmt[pos + 1].isdigit() and int(self.sfmt[pos + 1]) > cpus: - self.sfmt = self.sfmt.replace("$" + self.sfmt[pos + 1], "n/a") + self.sfmt = self.sfmt.replace("$" + self.sfmt[pos + 1], "n/a") pos += 1 def doSuspend(self, suspended): diff --git a/lib/python/Components/Converter/EventName.py b/lib/python/Components/Converter/EventName.py index 006f5436227..a38e3ea1988 100644 --- a/lib/python/Components/Converter/EventName.py +++ b/lib/python/Components/Converter/EventName.py @@ -169,16 +169,16 @@ def __init__(self, type): if len(self.parts) > 1: self.type = self.FORMAT_STRING self.separatorChar = self.parts[0] - - for arg in args: - name, value = self.KEYWORDS.get(arg, ("Error", None)) - if name == "Error": - print("[EventName] ERROR: Unexpected / Invalid argument token '%s'!" % arg) - else: - setattr(self, name, value) - if self.separator is None: - default_sep = "SeparatorComma" if self.type == self.GENRELIST else "NotSeparated" - self.separator = self.KEYWORDS[default_sep][1] + else: + for arg in args: + name, value = self.KEYWORDS.get(arg, ("Error", None)) + if name == "Error": + print("[EventName] ERROR: Unexpected / Invalid argument token '%s'!" % arg) + else: + setattr(self, name, value) + if self.separator is None: + default_sep = "SeparatorComma" if self.type == self.GENRELIST else "NotSeparated" + self.separator = self.KEYWORDS[default_sep][1] def trimText(self, text): if self.trim: @@ -199,6 +199,8 @@ def formatDescription(self, description, extended): def getBoolean(self): event = self.source.event if event: + if self.type == self.NAME: + return bool(self.getText()) if self.type == self.PDC and event.getPdcPil(): return True return False @@ -283,7 +285,7 @@ def getText(self): if running_status in (6, 7): return _("Reserved for future use") return _("Undefined") - elif self.type in (self.NAME_NEXT, self.NAME_NEXT2) or self.type >= self.NEXT_DESCRIPTION: + elif self.type in (self.NAME_NEXT, self.NAME_NEXT2) or (self.type >= self.NEXT_DESCRIPTION and not self.type == self.FORMAT_STRING): try: reference = self.source.service info = reference and self.source.info @@ -329,7 +331,19 @@ def getText(self): duration_str = "%d min" % (duration / 60) start_time_str = "%2d:%02d" % (t_start.tm_hour, t_start.tm_min) end_time_str = "%2d:%02d" % (t_end.tm_hour, t_end.tm_min) - res_str = "%s - %s %s %s" % (start_time_str, end_time_str, self.separator, duration_str) + name = self.trimText(event.getEventName()) + res_str = "" + for x in self.parts[1:]: + if x == "NAME" and name: + res_str = self.appendToStringWithSeparator(res_str, name) + if x == "STARTTIME" and start_time_str: + res_str = self.appendToStringWithSeparator(res_str, start_time_str) + if x == "ENDTIME" and end_time_str: + res_str = self.appendToStringWithSeparator(res_str, end_time_str) + if x == "TIMERANGE" and start_time_str and end_time_str: + res_str = self.appendToStringWithSeparator(res_str, "%s - %s" % (start_time_str, end_time_str)) + if x == "DURATION" and duration_str: + res_str = self.appendToStringWithSeparator(res_str, duration_str) return res_str return "" diff --git a/lib/python/Components/Converter/HddState.py b/lib/python/Components/Converter/HddState.py index 42bcdee7c4e..028842ba09f 100644 --- a/lib/python/Components/Converter/HddState.py +++ b/lib/python/Components/Converter/HddState.py @@ -7,17 +7,18 @@ from skin import parameters from enigma import eTimer - -#*************************************************************** -# internalAll/internalHDD/internalSSD/external - disk type -# Example : internalAll -# or all type - internal and external -# Example : -# noLetterName - do not print a letter "I"(internal)/"S"(SSD)/"E"(external) -# Example : noLetterName -# allVisible - show "Disk state: standby " when use noLetterName -# Example : noLetterName,allVisible -#*************************************************************** +''' + *************************************************************** + internalAll/internalHDD/internalSSD/external - disk type + Example : internalAll + or all type - internal and external + Example : + noLetterName - do not print a letter "I"(internal)/"S"(SSD)/"E"(external) + Example : noLetterName + allVisible - show "Disk state: standby " when use noLetterName + Example : noLetterName,allVisible + *************************************************************** +''' class HddState(Converter): diff --git a/lib/python/Components/Converter/LayoutInfo.py b/lib/python/Components/Converter/LayoutInfo.py index b3bdd88f9b8..525a02ac623 100644 --- a/lib/python/Components/Converter/LayoutInfo.py +++ b/lib/python/Components/Converter/LayoutInfo.py @@ -4,217 +4,188 @@ from Components.Element import cached from Components.Converter.Poll import Poll -SIZE_UNITS = ['B', - 'KB', - 'MB', - 'GB', - 'TB', - 'PB', - 'EB'] +SIZE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'] class LayoutInfo(Poll, Converter): - HDDTEMP = 0 - LOADAVG = 1 - MEMTOTAL = 2 - MEMFREE = 3 - SWAPTOTAL = 4 - SWAPFREE = 5 - USBINFO = 6 - HDDINFO = 7 - FLASHINFO = 8 - - def __init__(self, type): - Converter.__init__(self, type) - Poll.__init__(self) - type = type.split(',') - self.shortFormat = 'Short' in type - self.fullFormat = 'Full' in type - if 'HddTemp' in type: - self.type = self.HDDTEMP - elif 'LoadAvg' in type: - self.type = self.LOADAVG - elif 'MemTotal' in type: - self.type = self.MEMTOTAL - elif 'MemFree' in type: - self.type = self.MEMFREE - elif 'SwapTotal' in type: - self.type = self.SWAPTOTAL - elif 'SwapFree' in type: - self.type = self.SWAPFREE - elif 'UsbInfo' in type: - self.type = self.USBINFO - elif 'HddInfo' in type: - self.type = self.HDDINFO - else: - self.type = self.FLASHINFO - if self.type in (self.FLASHINFO, self.HDDINFO, self.USBINFO): - self.poll_interval = 5000 - else: - self.poll_interval = 1600 - self.poll_enabled = True - - @cached - def getText(self): - text = 'N/A' - if self.type == self.HDDTEMP: - text = self.getHddTemp() - elif self.type == self.LOADAVG: - text = self.getLoadAvg() - else: - entry = {self.MEMTOTAL: ('Mem', 'Ram'), - self.MEMFREE: ('Mem', 'Ram'), - self.SWAPTOTAL: ('Swap', 'Swap'), - self.SWAPFREE: ('Swap', 'Swap'), - self.USBINFO: ('/media/usb', 'USB'), - self.HDDINFO: ('/media/hdd', 'HDD'), - self.FLASHINFO: ('/', 'Flash')}[self.type] - if self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): - list = self.getDiskInfo(entry[0]) - else: - list = self.getMemInfo(entry[0]) - if list[0] == 0: - text = '%s: N/A' % entry[1] - elif self.shortFormat: - text = '%s%%' % (list[3]) - elif self.fullFormat: - text = '%s: %s Free:%s Used:%s (%s%%)' % (entry[1], - self.getSizeStr(list[0]), - self.getSizeStr(list[2]), - self.getSizeStr(list[1]), - list[3]) - else: - text = '%s: %s Used:%s Free:%s' % (entry[1], - self.getSizeStr(list[0]), - self.getSizeStr(list[1]), - self.getSizeStr(list[2])) - return text - - @cached - def getValue(self): - result = 0 - if self.type in (self.MEMTOTAL, - self.MEMFREE, - self.SWAPTOTAL, - self.SWAPFREE): - entry = {self.MEMTOTAL: 'Mem', - self.MEMFREE: 'Mem', - self.SWAPTOTAL: 'Swap', - self.SWAPFREE: 'Swap'}[self.type] - result = self.getMemInfo(entry)[3] - elif self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): - path = {self.USBINFO: '/media/usb', - self.HDDINFO: '/media/hdd', - self.FLASHINFO: '/'}[self.type] - result = self.getDiskInfo(path)[3] - return result - - text = property(getText) - value = property(getValue) - range = 100 - - def getHddTemp(self): - textvalue = 'No info' - info = '0' - try: - out_line = popen('hddtemp -n -q /dev/sda').readline() - info = 'Hdd C:' + out_line[:4] - textvalue = info - except: - pass - - return textvalue - - def getLoadAvg(self): - textvalue = 'No info' - info = '0' - try: - out_line = popen('cat /proc/loadavg').readline() - info = 'loadavg:' + out_line[:15] - textvalue = info - except: - pass - - return textvalue - - def getMemInfo(self, value): - result = [0, - 0, - 0, - 0] - try: - check = 0 - fd = open('/proc/meminfo') - for line in fd: - if value + 'Total' in line: - check += 1 - result[0] = int(line.split()[1]) * 1024 - elif value + 'Free' in line: - check += 1 - result[2] = int(line.split()[1]) * 1024 - if check > 1: - if result[0] > 0: - result[1] = result[0] - result[2] - result[3] = result[1] * 100 // result[0] - break - - fd.close() - except: - pass - - return result - - def getDiskInfo(self, path): - - def isMountPoint(): - try: - fd = open('/proc/mounts', 'r') - for line in fd: - l = line.split() - if len(l) > 1 and l[1] == path: - return True - - fd.close() - except: - return None - - return False - - result = [0, - 0, - 0, - 0] - if isMountPoint(): - try: - st = statvfs(path) - except: - st = None - - if st is not None and 0 not in (st.f_bsize, st.f_blocks): - result[0] = st.f_bsize * st.f_blocks - result[2] = st.f_bsize * st.f_bavail - result[1] = result[0] - result[2] - result[3] = result[1] * 100 // result[0] - return result - - def getSizeStr(self, value, u=0): - fractal = 0 - if value >= 1024: - fmt = '%(size)u.%(frac)d %(unit)s' - while value >= 1024 and u < len(SIZE_UNITS): - value, mod = divmod(value, 1024) - fractal = mod * 10 // 1024 - u += 1 - - else: - fmt = '%(size)u %(unit)s' - return fmt % {'size': value, - 'frac': fractal, - 'unit': SIZE_UNITS[u]} - - def doSuspend(self, suspended): - if suspended: - self.poll_enabled = False - else: - self.downstream_elements.changed((self.CHANGED_POLL,)) - self.poll_enabled = True + HDDTEMP = 0 + LOADAVG = 1 + MEMTOTAL = 2 + MEMFREE = 3 + SWAPTOTAL = 4 + SWAPFREE = 5 + USBINFO = 6 + HDDINFO = 7 + FLASHINFO = 8 + + def __init__(self, type): + Converter.__init__(self, type) + Poll.__init__(self) + type = type.split(',') + self.shortFormat = 'Short' in type + self.fullFormat = 'Full' in type + if 'HddTemp' in type: + self.type = self.HDDTEMP + elif 'LoadAvg' in type: + self.type = self.LOADAVG + elif 'MemTotal' in type: + self.type = self.MEMTOTAL + elif 'MemFree' in type: + self.type = self.MEMFREE + elif 'SwapTotal' in type: + self.type = self.SWAPTOTAL + elif 'SwapFree' in type: + self.type = self.SWAPFREE + elif 'UsbInfo' in type: + self.type = self.USBINFO + elif 'HddInfo' in type: + self.type = self.HDDINFO + else: + self.type = self.FLASHINFO + if self.type in (self.FLASHINFO, self.HDDINFO, self.USBINFO): + self.poll_interval = 5000 + else: + self.poll_interval = 1600 + self.poll_enabled = True + + @cached + def getText(self): + text = 'N/A' + if self.type == self.HDDTEMP: + text = self.getHddTemp() + elif self.type == self.LOADAVG: + text = self.getLoadAvg() + else: + entry = {self.MEMTOTAL: ('Mem', 'Ram'), + self.MEMFREE: ('Mem', 'Ram'), + self.SWAPTOTAL: ('Swap', 'Swap'), + self.SWAPFREE: ('Swap', 'Swap'), + self.USBINFO: ('/media/usb', 'USB'), + self.HDDINFO: ('/media/hdd', 'HDD'), + self.FLASHINFO: ('/', 'Flash')}[self.type] + if self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): + list = self.getDiskInfo(entry[0]) + else: + list = self.getMemInfo(entry[0]) + if list[0] == 0: + text = '%s: N/A' % entry[1] + elif self.shortFormat: + text = '%s%%' % (list[3]) + elif self.fullFormat: + text = '%s: %s Free:%s Used:%s (%s%%)' % (entry[1], self.getSizeStr(list[0]), self.getSizeStr(list[2]), self.getSizeStr(list[1]), list[3]) + else: + text = '%s: %s Used:%s Free:%s' % (entry[1], self.getSizeStr(list[0]), self.getSizeStr(list[1]), self.getSizeStr(list[2])) + return text + + @cached + def getValue(self): + result = 0 + if self.type in (self.MEMTOTAL, + self.MEMFREE, + self.SWAPTOTAL, + self.SWAPFREE): + entry = {self.MEMTOTAL: 'Mem', + self.MEMFREE: 'Mem', + self.SWAPTOTAL: 'Swap', + self.SWAPFREE: 'Swap'}[self.type] + result = self.getMemInfo(entry)[3] + elif self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): + path = {self.USBINFO: '/media/usb', + self.HDDINFO: '/media/hdd', + self.FLASHINFO: '/'}[self.type] + result = self.getDiskInfo(path)[3] + return result + + text = property(getText) # noqa: F821 + value = property(getValue) # noqa: F821 + range = 100 + + def getHddTemp(self): + textvalue = 'No info' + info = '0' + try: + out_line = popen('hddtemp -n -q /dev/sda').readline() + info = 'Hdd C:' + out_line[:4] + textvalue = info + except: + pass + return textvalue + + def getLoadAvg(self): + textvalue = 'No info' + info = '0' + try: + out_line = popen('cat /proc/loadavg').readline() + info = 'loadavg:' + out_line[:15] + textvalue = info + except: + pass + return textvalue + + def getMemInfo(self, value): + result = [0, 0, 0, 0] + try: + check = 0 + fd = open('/proc/meminfo') + for line in fd: + if value + 'Total' in line: + check += 1 + result[0] = int(line.split()[1]) * 1024 + elif value + 'Free' in line: + check += 1 + result[2] = int(line.split()[1]) * 1024 + if check > 1: + if result[0] > 0: + result[1] = result[0] - result[2] + result[3] = result[1] * 100 // result[0] + break + fd.close() + except: + pass + return result + + def getDiskInfo(self, path): + + def isMountPoint(): + try: + fd = open('/proc/mounts', 'r') + for line in fd: + partLine = line.split() + if len(partLine) > 1 and partLine[1] == path: + return True + fd.close() + except: + return None + return False + + result = [0, 0, 0, 0] + if isMountPoint(): + try: + st = statvfs(path) + except: + st = None + if st is not None and 0 not in (st.f_bsize, st.f_blocks): + result[0] = st.f_bsize * st.f_blocks + result[2] = st.f_bsize * st.f_bavail + result[1] = result[0] - result[2] + result[3] = result[1] * 100 // result[0] + return result + + def getSizeStr(self, value, u=0): + fractal = 0 + if value >= 1024: + fmt = '%(size)u.%(frac)d %(unit)s' + while value >= 1024 and u < len(SIZE_UNITS): + value, mod = divmod(value, 1024) + fractal = mod * 10 // 1024 + u += 1 + else: + fmt = '%(size)u %(unit)s' + return fmt % {'size': value, 'frac': fractal, 'unit': SIZE_UNITS[u]} + + def doSuspend(self, suspended): + if suspended: + self.poll_enabled = False + else: + self.downstream_elements.changed((self.CHANGED_POLL,)) + self.poll_enabled = True diff --git a/lib/python/Components/Converter/MovieInfo.py b/lib/python/Components/Converter/MovieInfo.py index c742a1acd58..7088b34f25a 100644 --- a/lib/python/Components/Converter/MovieInfo.py +++ b/lib/python/Components/Converter/MovieInfo.py @@ -63,15 +63,16 @@ def __init__(self, type): self.type = self.FORMAT_STRING self.separatorChar = self.parts[0] - for arg in args: - name, value = self.KEYWORDS.get(arg, ("Error", None)) - if name == "Error": - print("[MovieInfo] ERROR: Unexpected / Invalid argument token '%s'!" % arg) - else: - setattr(self, name, value) - if ((name == "Error") or (type is None)): - print("[MovieInfo] Valid arguments are: ShortDescription|MetaDescription|FullDescription|RecordServiceName|RecordServiceRef|FileSize.") - print("[MovieInfo] Valid options for descriptions are: Separated|NotSeparated|Trimmed|NotTrimmed.") + if self.type != self.FORMAT_STRING: + for arg in args: + name, value = self.KEYWORDS.get(arg, ("Error", None)) + if name == "Error": + print("[MovieInfo] ERROR: Unexpected / Invalid argument token '%s'!" % arg) + else: + setattr(self, name, value) + if ((name == "Error") or (type is None)): + print("[MovieInfo] Valid arguments are: ShortDescription|MetaDescription|FullDescription|RecordServiceName|RecordServiceRef|FileSize.") + print("[MovieInfo] Valid options for descriptions are: Separated|NotSeparated|Trimmed|NotTrimmed.") def destroy(self): Converter.destroy(self) @@ -145,14 +146,18 @@ def getText(self): timeCreate = strftime("%A %d %b %Y", localtime(info.getInfo(service, iServiceInformation.sTimeCreate))) duration = "%d min" % (info.getLength(service) / 60) filesize = "%d MB" % (info.getInfoObject(service, iServiceInformation.sFileSize) / (1024 * 1024)) + rec_ref_str = info.getInfoString(service, iServiceInformation.sServiceref) + rec_service_name = eServiceReference(rec_ref_str).getServiceName() res_str = "" for x in self.parts[1:]: - if x == "TIMECREATED" and timeCreate != '': + if x == "TIMECREATED" and timeCreate: res_str = self.appendToStringWithSeparator(res_str, timeCreate) - if x == "DURATION" and duration != '': + if x == "DURATION" and duration: res_str = self.appendToStringWithSeparator(res_str, duration) - if x == "FILESIZE" and filesize != '': + if x == "FILESIZE" and filesize: res_str = self.appendToStringWithSeparator(res_str, filesize) + if x == "RECSERVICE" and rec_service_name: + res_str = self.appendToStringWithSeparator(res_str, rec_service_name) return res_str return "" diff --git a/lib/python/Components/Converter/MovieReference.py b/lib/python/Components/Converter/MovieReference.py index 4705c5c22f4..1c1d2928f0b 100644 --- a/lib/python/Components/Converter/MovieReference.py +++ b/lib/python/Components/Converter/MovieReference.py @@ -1,11 +1,13 @@ -# Movie Selection: -# -# -# -# Movie Player Infobar: -# -# -# +''' + Movie Selection: + + + + Movie Player Infobar: + + + +''' from enigma import iServiceInformation, eServiceReference, iPlayableServicePtr diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 02a99703ccd..06301668abd 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -8,24 +8,25 @@ from Tools.GetEcmInfo import GetEcmInfo from Tools.Hex2strColor import Hex2strColor from Components.Converter.Poll import Poll +from Tools.Directories import pathExists from skin import parameters caid_data = ( - ("0x100", "0x1ff", "Seca", "S", True), - ("0x500", "0x5ff", "Via", "V", True), - ("0x600", "0x6ff", "Irdeto", "I", True), - ("0x900", "0x9ff", "NDS", "Nd", True), - ("0xb00", "0xbff", "Conax", "Co", True), - ("0xd00", "0xdff", "CryptoW", "Cw", True), - ("0xe00", "0xeff", "PowerVU", "P", False), - ("0x1000", "0x10FF", "Tandberg", "TB", False), - ("0x1700", "0x17ff", "Beta", "B", True), - ("0x1800", "0x18ff", "Nagra", "N", True), - ("0x2600", "0x2600", "Biss", "Bi", False), - ("0x2700", "0x2710", "Dre3", "D3", False), - ("0x4ae0", "0x4ae1", "Dre", "D", False), - ("0x4aee", "0x4aee", "BulCrypt", "B1", False), - ("0x5581", "0x5581", "BulCrypt", "B2", False) + ("0x100", "0x1ff", "Seca", "S", "SECA", True), + ("0x500", "0x5ff", "Via", "V", "VIA", True), + ("0x600", "0x6ff", "Irdeto", "I", "IRD", True), + ("0x900", "0x9ff", "NDS", "Nd", "NDS", True), + ("0xb00", "0xbff", "Conax", "Co", "CONAX", True), + ("0xd00", "0xdff", "CryptoW", "Cw", "CRW", True), + ("0xe00", "0xeff", "PowerVU", "P", "PV", False), + ("0x1000", "0x10FF", "Tandberg", "TB", "TAND", False), + ("0x1700", "0x17ff", "Beta", "B", "BETA", True), + ("0x1800", "0x18ff", "Nagra", "N", "NAGRA", True), + ("0x2600", "0x2600", "Biss", "Bi", "BiSS", False), + ("0x2700", "0x2710", "Dre3", "D3", "DRE3", False), + ("0x4ae0", "0x4ae1", "Dre", "D", "DRE", False), + ("0x4aee", "0x4aee", "BulCrypt", "B1", "BUL", False), + ("0x5581", "0x5581", "BulCrypt", "B2", "BUL", False) ) # stream type to codec map @@ -110,7 +111,7 @@ def __init__(self, type): "ServiceInfo": ( "ProviderName", "TunerSystem", - "TransponderFrequency", + "TransponderFrequencyMHz", "TransponderPolarization", "TransponderSymbolRate", "TransponderFEC", @@ -222,7 +223,7 @@ def createCryptoBar(self, info): except: pass - if color != Hex2strColor(colors[2]) or caid_entry[4]: + if color != Hex2strColor(colors[2]) or caid_entry[5]: if res: res += " " res += color + caid_entry[3] @@ -230,6 +231,16 @@ def createCryptoBar(self, info): res += Hex2strColor(colors[3]) # white (this acts like a color "reset" for following strings return res + def createCurrentCaidLabel(self): + res = "" + if not pathExists("/tmp/ecm.info"): + return "FTA" + for caid_entry in caid_data: + if int(caid_entry[0], 16) <= int(self.current_caid, 16) <= int(caid_entry[1], 16): + res = caid_entry[4] + + return res + def createCryptoSeca(self, info): available_caids = info.getInfoObject(iServiceInformation.sCAIDs) if int('0x100', 16) <= int(self.current_caid, 16) <= int('0x1ff', 16): @@ -506,18 +517,49 @@ def createPIDInfo(self, info): onid = 0 return "%d-%d:%05d:%04d:%04d:%04d" % (onid, tsid, sidpid, vpid, apid, pcrpid) - def createTransponderInfo(self, fedata, feraw, info): - if not feraw: - refstr = info.getInfoString(iServiceInformation.sServiceref) - if "%3a//" in refstr.lower(): - return refstr.split(":")[10].replace("%3a", ":").replace("%3A", ":") - return "" - elif "DVB-T" in feraw.get("tuner_type"): - tmp = addspace(self.createChannelNumber(fedata, feraw)) + addspace(self.createFrequency(fedata)) + addspace(self.createPolarization(fedata)) - else: - tmp = addspace(self.createFrequency(fedata)) + addspace(self.createPolarization(fedata)) - return addspace(self.createTunerSystem(fedata)) + tmp + addspace(self.createSymbolRate(fedata, feraw)) + addspace(self.createFEC(fedata, feraw)) \ - + addspace(self.createModulation(fedata)) + addspace(self.createOrbPos(feraw)) + addspace(self.createMisPls(fedata)) + def createInfoString(self, fieldGroup, fedata, feraw, info): + if fieldGroup in self.recursionCheck: + return _("?%s-recursive?") % fieldGroup + self.recursionCheck.add(fieldGroup) + + fields = self.info_fields[fieldGroup] + if fields and isinstance(fields[0], (tuple, list)): + if fieldGroup == "TransponderInfo": + fields = fields[feraw and int("DVB-T" in feraw.get("tuner_type", "")) + 1 or 0] + else: + fields = fields[int(config.usage.show_cryptoinfo.value) > 0] + + ret = "" + vals = [] + for field in fields: + val = None + if field == "CryptoCurrentSource": + self.getCryptoInfo(info) + vals.append(self.current_source) + elif field == "StreamURLInfo": + val = self.createStreamURLInfo(info) + elif field == "TransponderModulationFEC": + val = self.createModulation(fedata) + '-' + self.createFEC(fedata, feraw) + elif field == "TransponderName": + val = self.createTransponderName(feraw) + elif field == "ProviderName": + val = self.createProviderName(info) + elif field in ("NewLine", "NL"): + ret += " ".join(vals) + "\n" + vals = [] + else: + val = self.getTextByType(field) + + if val: + vals.append(val) + + return ret + " ".join(vals) + + def createStreamURLInfo(self, info): + refstr = info.getInfoString(iServiceInformation.sServiceref) + if "%3a//" in refstr.lower(): + return refstr.replace("%3a", ":").replace("%3A", ":").split("://")[1].split("/")[0].split('@')[-1] + return "" def createFrequency(self, fedata): frequency = fedata.get("frequency") @@ -572,15 +614,18 @@ def createTunerType(self, feraw): def createTunerSystem(self, fedata): return fedata.get("system") or "" - def createOrbPos(self, feraw): - orbpos = feraw.get("orbital_position") - if orbpos != None: + def formatOrbPos(self, orbpos): + if isinstance(orbpos, int) and 0 <= orbpos <= 3600: # sanity if orbpos > 1800: return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" - elif orbpos > 0: + else: return str((float(orbpos)) / 10.0) + "\xb0" + "E" return "" + def createOrbPos(self, feraw): + orbpos = feraw.get("orbital_position") + return self.formatOrbPos(orbpos) + def createOrbPosOrTunerSystem(self, fedata, feraw): orbpos = self.createOrbPos(feraw) if orbpos != "": @@ -692,10 +737,8 @@ def createTransponderName(self, feraw): if orbpos in sat_names: return sat_names[orbpos] - elif orbpos > 1800: - return str((float(3600 - orbpos)) / 10.0) + "W" else: - return str((float(orbpos)) / 10.0) + "E" + return self.formatOrbPos(orbpos) def createProviderName(self, info): return info.getInfoString(iServiceInformation.sProvider) @@ -725,14 +768,14 @@ def getText(self): if not info: return "" - if self.type == "CryptoInfo": - self.getCryptoInfo(info) + if textType == "CurrentCrypto": if int(config.usage.show_cryptoinfo.value) > 0: - return addspace(self.createCryptoBar(info)) + self.createCryptoSpecial(info) + self.getCryptoInfo(info) + return self.createCurrentCaidLabel() else: - return addspace(self.createCryptoBar(info)) + addspace(self.current_source) + self.createCryptoSpecial(info) + return "" - if self.type == "CryptoBar": + if textType == "CryptoBar": if int(config.usage.show_cryptoinfo.value) > 0: self.getCryptoInfo(info) return self.createCryptoBar(info) diff --git a/lib/python/Components/Converter/RemainingToText.py b/lib/python/Components/Converter/RemainingToText.py index 2632f112854..056691389b0 100644 --- a/lib/python/Components/Converter/RemainingToText.py +++ b/lib/python/Components/Converter/RemainingToText.py @@ -95,7 +95,7 @@ def getText(self): else: (duration, remaining) = self.source.time - l = duration # Length + l = duration # noqa: E741 Length p = elapsed # Position r = remaining # Remaining diff --git a/lib/python/Components/Converter/ServiceInfo.py b/lib/python/Components/Converter/ServiceInfo.py index d0e84873909..8c6f505c28f 100644 --- a/lib/python/Components/Converter/ServiceInfo.py +++ b/lib/python/Components/Converter/ServiceInfo.py @@ -9,6 +9,66 @@ WIDESCREEN = [3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10] +def getProcVal(pathname, base=10): + val = None + try: + f = open(pathname, "r") + val = int(f.read(), base) + f.close() + if val >= 2 ** 31: + val -= 2 ** 32 + except: + pass + return val + + +def getVal(pathname, info, infoVal, base=10): + val = getProcVal(pathname, base=base) + return val if val is not None else info.getInfo(infoVal) + + +def getValInt(pathname, info, infoVal, base=10, default=-1): + val = getVal(pathname, info, infoVal, base) + return val if val is not None else default + + +def getValStr(pathname, info, infoVal, base=10, convert=lambda x: "%d" % x, instance=None): + val = getProcVal(pathname, base=base) + return convert(val) if val is not None else instance.getServiceInfoString(info, infoVal, convert) + + +def getVideoHeight(info): + return getValInt("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16) + + +def getVideoHeightStr(info, convert=lambda x: "%d" % x if x > 0 else "?", instance=None): + return getValStr("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16, convert=convert, instance=instance) + + +def getVideoWidth(info): + return getValInt("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16) + + +def getVideoWidthStr(info, convert=lambda x: "%d" % x if x > 0 else "?", instance=None): + return getValStr("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16, convert=convert, instance=instance) + + +def getFrameRate(info): + return getValInt("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate) + + +def getFrameRateStr(info, convert=lambda x: "%d" % x if x > 0 else "", instance=None): + return getValStr("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate, convert=convert, instance=instance) + + +def getProgressive(info): + return getValInt("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, default=0) + + +def getProgressiveStr(info, convert=lambda x: "" if x else "i", instance=None): + return getValStr("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, convert=convert, instance=instance) + + class ServiceInfo(Poll, Converter): HAS_TELETEXT = 1 IS_MULTICHANNEL = 2 @@ -117,54 +177,6 @@ def getServiceInfoString(self, info, what, convert=lambda x: "%d" % x): return info.getInfoString(what) return convert(v) - def _getProcVal(self, pathname, base=10): - val = None - try: - f = open(pathname, "r") - val = int(f.read(), base) - f.close() - if val >= 2 ** 31: - val -= 2 ** 32 - except: - pass - return val - - def _getVal(self, pathname, info, infoVal, base=10): - val = self._getProcVal(pathname, base=base) - return val if val is not None else info.getInfo(infoVal) - - def _getValInt(self, pathname, info, infoVal, base=10, default=-1): - val = self._getVal(pathname, info, infoVal, base) - return val if val is not None else default - - def _getValStr(self, pathname, info, infoVal, base=10, convert=lambda x: "%d" % x): - val = self._getProcVal(pathname, base=base) - return convert(val) if val is not None else self.getServiceInfoString(info, infoVal, convert) - - def _getVideoHeight(self, info): - return self._getValInt("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16) - - def _getVideoHeightStr(self, info, convert=lambda x: "%d" % x if x > 0 else "?"): - return self._getValStr("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16, convert=convert) - - def _getVideoWidth(self, info): - return self._getValInt("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16) - - def _getVideoWidthStr(self, info, convert=lambda x: "%d" % x if x > 0 else "?"): - return self._getValStr("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16, convert=convert) - - def _getFrameRate(self, info): - return self._getValInt("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate) - - def _getFrameRateStr(self, info, convert=lambda x: "%d" % x if x > 0 else ""): - return self._getValStr("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate, convert=convert) - - def _getProgressive(self, info): - return self._getValInt("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, default=0) - - def _getProgressiveStr(self, info, convert=lambda x: "" if x else "i"): - return self._getValStr("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, convert=convert) - @cached def getBoolean(self): service = self.source.service @@ -173,7 +185,7 @@ def getBoolean(self): return False video_height = None video_aspect = None - video_height = self._getVideoHeight(info) + video_height = getVideoHeight(info) video_aspect = info.getInfo(iServiceInformation.sAspect) if self.type == self.HAS_TELETEXT: tpid = info.getInfo(iServiceInformation.sTXTPID) @@ -241,7 +253,7 @@ def getBoolean(self): elif self.type == self.IS_4K: return video_height >= 1500 elif self.type == self.PROGRESSIVE: - return bool(self._getProgressive(info)) + return bool(getProgressive(info)) elif self.type == self.IS_SDR: return info.getInfo(iServiceInformation.sGamma) == 0 elif self.type == self.IS_HDR: @@ -255,7 +267,10 @@ def getBoolean(self): elif self.type == self.IS_VIDEO_AVC: return info.getInfo(iServiceInformation.sVideoType) == 1 elif self.type == self.IS_VIDEO_HEVC: - return info.getInfo(iServiceInformation.sVideoType) == 7 + if info.getInfoString(iServiceInformation.sServiceref).startswith("5002") and info.getInfo(iServiceInformation.sVideoType) == -1: + return 7 + else: + return info.getInfo(iServiceInformation.sVideoType) == 7 return False boolean = property(getBoolean) @@ -267,9 +282,9 @@ def getText(self): if not info: return "" if self.type == self.XRES: - return self._getVideoWidthStr(info) + return getVideoWidthStr(info, instance=self) elif self.type == self.YRES: - return self._getVideoHeightStr(info) + return getVideoHeightStr(info, instance=self) elif self.type == self.APID: return self.getServiceInfoString(info, iServiceInformation.sAudioPID) elif self.type == self.VPID: @@ -287,9 +302,9 @@ def getText(self): elif self.type == self.SID: return self.getServiceInfoString(info, iServiceInformation.sSID) elif self.type == self.FRAMERATE: - return self._getFrameRateStr(info, convert=lambda x: "%d fps" % ((x + 500) // 1000)) + return getFrameRateStr(info, convert=lambda x: "%d fps" % ((x + 500) // 1000), instance=self) elif self.type == self.PROGRESSIVE: - return self._getProgressiveStr(info) + return getProgressiveStr(info, instance=self) elif self.type == self.TRANSFERBPS: return self.getServiceInfoString(info, iServiceInformation.sTransferBPS, lambda x: "%d kB/s" % (x // 1024)) elif self.type == self.HAS_HBBTV: @@ -319,15 +334,15 @@ def getText(self): out = "Freq: %s %s %s %s %s" % (frequency, polarization, sr_txt, symbolrate, fec) return out elif self.type == self.VIDEO_INFO: - progressive = self._getProgressiveStr(info) - fieldrate = self._getFrameRate(info) + progressive = getProgressiveStr(info, instance=self) + fieldrate = getFrameRate(info) if fieldrate > 0: if progressive == 'i': fieldrate *= 2 fieldrate = "%dHz" % ((fieldrate + 500) // 1000,) else: fieldrate = "" - return "%sx%s%s %s" % (self._getVideoWidthStr(info), self._getVideoHeightStr(info), progressive, fieldrate) + return "%sx%s%s %s" % (getVideoWidthStr(info, instance=self), getVideoHeightStr(info, instance=self), progressive, fieldrate) return "" text = property(getText) @@ -339,11 +354,11 @@ def getValue(self): if not info: return -1 if self.type == self.XRES: - return str(self._getVideoWidth(info)) + return str(getVideoWidth(info)) elif self.type == self.YRES: - return str(self._getVideoHeight(info)) + return str(getVideoHeight(info)) elif self.type == self.FRAMERATE: - return str(self._getFrameRate(self, info)) + return str(getFrameRate(self, info)) return -1 value = property(getValue) diff --git a/lib/python/Components/Converter/ServiceName.py b/lib/python/Components/Converter/ServiceName.py index a664579609e..c422f68c111 100644 --- a/lib/python/Components/Converter/ServiceName.py +++ b/lib/python/Components/Converter/ServiceName.py @@ -6,6 +6,7 @@ from ServiceReference import resolveAlternate from Components.Element import cached from Tools.Directories import fileExists +from Tools.Transponder import ConvertToHumanReadable class ServiceName(Converter): @@ -88,10 +89,11 @@ def getText(self): return service.toString() elif self.type == self.FORMAT_STRING: name = self.getName(service, info) - numservice = self.source.serviceref - num = self.getNumber(numservice, info) - provider = self.getProvider(service, info) - orbpos = self.getOrbitalPos(service, info) + numservice = hasattr(self.source, "serviceref") and self.source.serviceref + num = numservice and self.getNumber(numservice, info) or "" + orbpos, tp_data = self.getOrbitalPos(service, info) + provider = self.getProvider(service, info, tp_data) + tuner_system = service and info and self.getServiceSystem(service, info, tp_data) res_str = "" for x in self.parts[1:]: if x == "NUMBER" and num: @@ -102,12 +104,14 @@ def getText(self): res_str = self.appendToStringWithSeparator(res_str, orbpos) if x == "PROVIDER" and provider: res_str = self.appendToStringWithSeparator(res_str, provider) + if x == "TUNERSYSTEM" and tuner_system: + res_str = self.appendToStringWithSeparator(res_str, tuner_system) return res_str text = property(getText) def changed(self, what): - if what[0] != self.CHANGED_SPECIFIC or what[1] in (iPlayableService.evStart,): + if what[0] != self.CHANGED_SPECIFIC or what[1] in (iPlayableService.evStart, iPlayableService.evNewProgramInfo): Converter.changed(self, what) def getName(self, ref, info): @@ -124,7 +128,7 @@ def getNumber(self, ref, info): num = str(num) return num - def getProvider(self, ref, info): + def getProvider(self, ref, info, tp_data=None): if ref: return info.getInfoString(ref, iServiceInformation.sProvider) return info.getInfoString(iServiceInformation.sProvider) @@ -135,6 +139,7 @@ def getOrbitalPos(self, ref, info): tp_data = info.getInfoObject(ref, iServiceInformation.sTransponderData) else: tp_data = info.getInfoObject(iServiceInformation.sTransponderData) + if tp_data is not None: try: position = tp_data["orbital_position"] @@ -144,4 +149,20 @@ def getOrbitalPos(self, ref, info): orbitalpos = "%.1f " % (float(position) / 10) + _("E") except: pass - return orbitalpos + return orbitalpos, tp_data + + def getServiceSystem(self, ref, info, feraw): + if ref: + sref = info.getInfoObject(ref, iServiceInformation.sServiceref) + else: + sref = info.getInfoObject(iServiceInformation.sServiceref) + + if not sref: + sref = ref.toString() + + if sref and "%3a//" in sref: + return "IPTV" + + fedata = ConvertToHumanReadable(feraw) + + return fedata.get("system") or "" diff --git a/lib/python/Components/Converter/ServiceName2.py b/lib/python/Components/Converter/ServiceName2.py index c5865bac6b5..5801186bff4 100644 --- a/lib/python/Components/Converter/ServiceName2.py +++ b/lib/python/Components/Converter/ServiceName2.py @@ -233,7 +233,7 @@ def getTransponderInfo(self, info, ref, fmt): elif type == 'IP-TV': return _("Streaming") else: - fmt = ["O ", "s ", "M ", "F ", "p ", "Y ", "f"] #(orbital_position frequency polarization symbol_rate fec) + fmt = ["O ", "s ", "M ", "F ", "p ", "Y ", "f"] # (orbital_position frequency polarization symbol_rate fec) for line in fmt: f = line[:1] if f == 't': # %t - tuner_type (dvb-s/s2/c/t) @@ -296,12 +296,12 @@ def getTransponderInfo(self, info, ref, fmt): elif f == 'r': # %r - rolloff (dvb-s2) if not self.isStream: x = self.tpdata.get('rolloff') - if not x is None: + if x is not None: result += x in range(3) and {0: '0.35', 1: '0.25', 2: '0.20'}[x] or '' elif f == 'o': # %o - pilot (dvb-s2) if not self.isStream: x = self.tpdata.get('pilot') - if not x is None: + if x is not None: result += x in range(3) and {0: 'Off', 1: 'On', 2: 'Auto'}[x] or '' elif f == 'c': # %c - constellation (dvb-t) if type == 'DVB-T': @@ -532,7 +532,7 @@ def getText(self): return bouq elif self.type == self.PROVIDER: if self.isStream: - if self.refstr and ('%3a//' in self.refstr or '%3a//' in self.refstr): + if self.refstr and ('%3a//' in self.refstr): return self.getIPTVProvider(self.refstr) return self.getIPTVProvider(refstr) else: diff --git a/lib/python/Components/Converter/ServiceOrbitalPosition.py b/lib/python/Components/Converter/ServiceOrbitalPosition.py index 707fd49d7c2..bbbd46babca 100644 --- a/lib/python/Components/Converter/ServiceOrbitalPosition.py +++ b/lib/python/Components/Converter/ServiceOrbitalPosition.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- -from Components.Converter.Converter import Converter - from enigma import iServiceInformation, iPlayableService, iPlayableServicePtr, eServiceCenter -from ServiceReference import resolveAlternate +from Components.Converter.Converter import Converter from Components.Element import cached +from ServiceReference import resolveAlternate class ServiceOrbitalPosition(Converter): @@ -57,7 +56,20 @@ def getText(self): return _("Stream") if refString.startswith("1:134:"): return _("Alternative") - return "" + elif info: + if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): + nmspc = info.getInfo(iServiceInformation.sNamespace) & 0xFFFFFFFF + namespace = "%08X" % nmspc + EW = "E" + orbpos = int(namespace[:4], 16) + if orbpos > 1800: + orbpos = 3600 - orbpos + EW = "W" + return "%s\xb0 %s" % (float(orbpos) / 10.0, EW) + else: + return "" + else: + return "" text = property(getText) diff --git a/lib/python/Components/Converter/ServicePosition.py b/lib/python/Components/Converter/ServicePosition.py index cec06a1e489..74c770d78bd 100644 --- a/lib/python/Components/Converter/ServicePosition.py +++ b/lib/python/Components/Converter/ServicePosition.py @@ -103,29 +103,29 @@ def getText(self): e = (self.length / 90000) - s return "%02d:%02d +%2dm" % (s / 60, s % 60, e / 60) - l = self.length + len = self.length p = self.position r = self.length - self.position # Remaining - if l < 0: + if len < 0: return "" if not self.detailed: - l /= 90000 + len /= 90000 p /= 90000 r /= 90000 if self.negate: - l = -l + len = -len if self.negate: p = -p if self.negate: r = -r - if l >= 0: + if len >= 0: sign_l = "" else: - l = -l + len = -len sign_l = "-" if p >= 0: @@ -152,7 +152,7 @@ def getText(self): if config.usage.swap_media_time_display_on_osd.value == "1": # Mins if self.type == self.TYPE_LENGTH: - return ngettext("%d Min", "%d Mins", (l / 60)) % (l / 60) + return ngettext("%d Min", "%d Mins", (len / 60)) % (len / 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed return sign_p + ngettext("%d Min", "%d Mins", (p / 60)) % (p / 60) @@ -171,7 +171,7 @@ def getText(self): return sign_r + ngettext("%d Min", "%d Mins", (r / 60)) % (r / 60) elif config.usage.swap_media_time_display_on_osd.value == "2": # Mins Secs if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 60, l % 60) + return sign_l + "%d:%02d" % (len / 60, len % 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed return sign_p + "%d:%02d" % (p / 60, p % 60) @@ -190,7 +190,7 @@ def getText(self): return sign_r + "%d:%02d" % (r / 60, r % 60) elif config.usage.swap_media_time_display_on_osd.value == "3": # Hours Mins if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed return sign_p + "%d:%02d" % (p / 3600, p % 3600 / 60) @@ -209,7 +209,7 @@ def getText(self): return sign_r + "%d:%02d" % (r / 3600, r % 3600 / 60) elif config.usage.swap_media_time_display_on_osd.value == "4": # Hours Mins Secs if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + return sign_l + "%d:%02d:%02d" % (len / 3600, len % 3600 / 60, len % 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed return sign_p + "%d:%02d:%02d" % (p / 3600, p % 3600 / 60, p % 60) @@ -228,39 +228,39 @@ def getText(self): return sign_r + "%d:%02d:%02d" % (r / 3600, r % 3600 / 60, r % 60) elif config.usage.swap_media_time_display_on_osd.value == "5": # Percentage if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed try: - return sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif config.usage.swap_time_remaining_on_osd.value == "2": # Elapsed & Remaining try: - return sign_p + "%d%% " % ((float(p + 0.0) / float(l + 0.0)) * 100) + sign_r + "%d%%" % ((float(r + 0.0) / float(l + 0.0)) * 100 + 1) + return sign_p + "%d%% " % ((float(p + 0.0) / float(len + 0.0)) * 100) + sign_r + "%d%%" % ((float(r + 0.0) / float(len + 0.0)) * 100 + 1) except: return "" elif config.usage.swap_time_remaining_on_osd.value == "3": # Remaining & Elapsed try: - return sign_r + "%d%% " % ((float(r + 0.0) / float(l + 0.0)) * 100 + 1) + sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%% " % ((float(r + 0.0) / float(len + 0.0)) * 100 + 1) + sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" else: try: - return sign_r + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif self.type == self.TYPE_REMAINING: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed try: - return sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif config.usage.swap_time_remaining_on_osd.value == "2" or config.usage.swap_time_remaining_on_osd.value == "3": # Elapsed & Remaining return "" else: try: - return sign_r + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" @@ -269,14 +269,14 @@ def getText(self): if self.showHours: if self.showNoSeconds: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_POSITION: return sign_p + "%d:%02d" % (p / 3600, p % 3600 / 60) elif self.type == self.TYPE_REMAINING: return sign_r + "%d:%02d" % (r / 3600, r % 3600 / 60) else: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + return sign_l + "%d:%02d:%02d" % (len / 3600, len % 3600 / 60, len % 60) elif self.type == self.TYPE_POSITION: return sign_p + "%d:%02d:%02d" % (p / 3600, p % 3600 / 60, p % 60) elif self.type == self.TYPE_REMAINING: @@ -284,14 +284,14 @@ def getText(self): else: if self.showNoSeconds: if self.type == self.TYPE_LENGTH: - return ngettext("%d Min", "%d Mins", (l / 60)) % (l / 60) + return ngettext("%d Min", "%d Mins", (len / 60)) % (len / 60) elif self.type == self.TYPE_POSITION: return sign_p + ngettext("%d Min", "%d Mins", (p / 60)) % (p / 60) elif self.type == self.TYPE_REMAINING: return sign_r + ngettext("%d Min", "%d Mins", (r / 60)) % (r / 60) else: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 60, l % 60) + return sign_l + "%d:%02d" % (len / 60, len % 60) elif self.type == self.TYPE_POSITION: return sign_p + "%d:%02d" % (p / 60, p % 60) elif self.type == self.TYPE_REMAINING: @@ -299,14 +299,14 @@ def getText(self): else: if self.showHours: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d:%02d:%03d" % ((l / 3600 / 90000), (l / 90000) % 3600 / 60, (l / 90000) % 60, (l % 90000) / 90) + return sign_l + "%d:%02d:%02d:%03d" % ((len / 3600 / 90000), (len / 90000) % 3600 / 60, (len / 90000) % 60, (len % 90000) / 90) elif self.type == self.TYPE_POSITION: return sign_r + "%d:%02d:%02d:%03d" % ((r / 3600 / 90000), (r / 90000) % 3600 / 60, (r / 90000) % 60, (r % 90000) / 90) elif self.type == self.TYPE_REMAINING: return sign_p + "%d:%02d:%02d:%03d" % ((p / 3600 / 90000), (p / 90000) % 3600 / 60, (p / 90000) % 60, (p % 90000) / 90) else: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d:%03d" % ((l / 60 / 90000), (l / 90000) % 60, (l % 90000) / 90) + return sign_l + "%d:%02d:%03d" % ((len / 60 / 90000), (len / 90000) % 60, (len % 90000) / 90) elif self.type == self.TYPE_POSITION: return sign_p + "%d:%02d:%03d" % ((p / 60 / 90000), (p / 90000) % 60, (p % 90000) / 90) elif self.type == self.TYPE_REMAINING: @@ -321,7 +321,7 @@ def getText(self): sign_r = "+" if config.usage.swap_media_time_display_on_vfd.value == "1": # Mins if self.type == self.TYPE_VFD_LENGTH: - return ngettext("%d Min", "%d Mins", (l / 60)) % (l / 60) + return ngettext("%d Min", "%d Mins", (len / 60)) % (len / 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed return sign_p + ngettext("%d Min", "%d Mins", (p / 60)) % (p / 60) @@ -340,7 +340,7 @@ def getText(self): return sign_r + ngettext("%d Min", "%d Mins", (r / 60)) % (r / 60) elif config.usage.swap_media_time_display_on_vfd.value == "2": # Mins Secs if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 60, l % 60) + return sign_l + "%d:%02d" % (len / 60, len % 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed return sign_p + "%d:%02d" % (p / 60, p % 60) @@ -359,7 +359,7 @@ def getText(self): return sign_r + "%d:%02d" % (r / 60, r % 60) elif config.usage.swap_media_time_display_on_vfd.value == "3": # Hours Mins if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed return sign_p + "%d:%02d" % (p / 3600, p % 3600 / 60) @@ -378,7 +378,7 @@ def getText(self): return sign_r + "%d:%02d" % (r / 3600, r % 3600 / 60) elif config.usage.swap_media_time_display_on_vfd.value == "4": # Hours Mins Secs if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + return sign_l + "%d:%02d:%02d" % (len / 3600, len % 3600 / 60, len % 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed return sign_p + "%d:%02d:%02d" % (p / 3600, p % 3600 / 60, p % 60) @@ -397,39 +397,39 @@ def getText(self): return sign_r + "%d:%02d:%02d" % (r / 3600, r % 3600 / 60, r % 60) elif config.usage.swap_media_time_display_on_vfd.value == "5": # Percentage if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed try: - return sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif config.usage.swap_time_remaining_on_vfd.value == "2": # Elapsed & Remaining try: - return sign_p + "%d%% " % ((float(p + 0.0) / float(l + 0.0)) * 100) + sign_r + "%d%%" % ((float(r + 0.0) / float(l + 0.0)) * 100 + 1) + return sign_p + "%d%% " % ((float(p + 0.0) / float(len + 0.0)) * 100) + sign_r + "%d%%" % ((float(r + 0.0) / float(len + 0.0)) * 100 + 1) except: return "" elif config.usage.swap_time_remaining_on_vfd.value == "3": # Remaining & Elapsed try: - return sign_r + "%d%% " % ((float(r + 0.0) / float(l + 0.0)) * 100 + 1) + sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%% " % ((float(r + 0.0) / float(len + 0.0)) * 100 + 1) + sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" else: try: - return sign_r + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif self.type == self.TYPE_VFD_REMAINING: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed try: - return sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif config.usage.swap_time_remaining_on_vfd.value == "2" or config.usage.swap_time_remaining_on_vfd.value == "3": # Elapsed & Remaining return "" else: try: - return sign_r + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" @@ -438,14 +438,14 @@ def getText(self): if self.showHours: if self.showNoSeconds: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_VFD_POSITION: return sign_p + "%d:%02d" % (p / 3600, p % 3600 / 60) elif self.type == self.TYPE_REMAINING: return sign_r + "%d:%02d" % (r / 3600, r % 3600 / 60) else: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + return sign_l + "%d:%02d:%02d" % (len / 3600, len % 3600 / 60, len % 60) elif self.type == self.TYPE_VFD_POSITION: return sign_p + "%d:%02d:%02d" % (p / 3600, p % 3600 / 60, p % 60) elif self.type == self.TYPE_REMAINING: @@ -453,14 +453,14 @@ def getText(self): else: if self.showNoSeconds: if self.type == self.TYPE_VFD_LENGTH: - return ngettext("%d Min", "%d Mins", (l / 60)) % (l / 60) + return ngettext("%d Min", "%d Mins", (len / 60)) % (len / 60) elif self.type == self.TYPE_VFD_POSITION: return sign_p + ngettext("%d Min", "%d Mins", (p / 60)) % (p / 60) elif self.type == self.TYPE_VFD_REMAINING: return sign_r + ngettext("%d Min", "%d Mins", (r / 60)) % (r / 60) else: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 60, l % 60) + return sign_l + "%d:%02d" % (len / 60, len % 60) elif self.type == self.TYPE_VFD_POSITION: return sign_p + "%d:%02d" % (p / 60, p % 60) elif self.type == self.TYPE_REMAINING: @@ -468,14 +468,14 @@ def getText(self): else: if self.showHours: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d:%02d:%03d" % ((l / 3600 / 90000), (l / 90000) % 3600 / 60, (l / 90000) % 60, (l % 90000) / 90) + return sign_l + "%d:%02d:%02d:%03d" % ((len / 3600 / 90000), (len / 90000) % 3600 / 60, (len / 90000) % 60, (len % 90000) / 90) elif self.type == self.TYPE_VFD_POSITION: return sign_r + "%d:%02d:%02d:%03d" % ((r / 3600 / 90000), (r / 90000) % 3600 / 60, (r / 90000) % 60, (r % 90000) / 90) elif self.type == self.TYPE_REMAINING: return sign_p + "%d:%02d:%02d:%03d" % ((p / 3600 / 90000), (p / 90000) % 3600 / 60, (p / 90000) % 60, (p % 90000) / 90) else: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d:%03d" % ((l / 60 / 90000), (l / 90000) % 60, (l % 90000) / 90) + return sign_l + "%d:%02d:%03d" % ((len / 60 / 90000), (len / 90000) % 60, (len % 90000) / 90) elif self.type == self.TYPE_VFD_POSITION: return sign_p + "%d:%02d:%03d" % ((p / 60 / 90000), (p / 90000) % 60, (p % 90000) / 90) elif self.type == self.TYPE_REMAINING: diff --git a/lib/python/Components/Converter/StreamInfo.py b/lib/python/Components/Converter/StreamInfo.py index 42e7ef3bc73..7d582bb1ec6 100644 --- a/lib/python/Components/Converter/StreamInfo.py +++ b/lib/python/Components/Converter/StreamInfo.py @@ -1,6 +1,6 @@ from Components.Converter.Converter import Converter from Components.Element import cached -from Screens.InfoBarGenerics import whitelist +from Screens.InfoBarGenerics import streamrelay import NavigationInstance from enigma import iPlayableService @@ -22,7 +22,7 @@ def streamtype(self): if playref: refstr = playref.toString() strtype = refstr.replace('%3a', ':') - if refstr in whitelist.streamrelay: + if refstr in streamrelay.data: return 'iCAM' elif strtype.startswith('1:0:'): if bool([1 for x in ('0.0.0.0:', '127.0.0.1:', 'localhost:') if x in strtype]): @@ -41,7 +41,7 @@ def streamurl(self): playref = NavigationInstance.instance.getCurrentlyPlayingServiceReference() if playref: refstr = playref.toString() - if refstr in whitelist.streamrelay: + if refstr in streamrelay.data: return 'Stream Relay' if '%3a' in refstr: strurl = refstr.split(':') diff --git a/lib/python/Components/Converter/VAudioInfo.py b/lib/python/Components/Converter/VAudioInfo.py index be7671ca98f..b557a29a387 100644 --- a/lib/python/Components/Converter/VAudioInfo.py +++ b/lib/python/Components/Converter/VAudioInfo.py @@ -122,7 +122,7 @@ def getAudioCodec(self, info): return description_str def getAudioIcon(self, info): - description_str = self.get_short(self.getAudioCodec(info).translate(str.maketrans(None, ' .')).lower()) + description_str = self.get_short(self.getAudioCodec(info).translate(str.maketrans(' ', ' .')).lower()) return description_str def get_short(self, audioName): diff --git a/lib/python/Components/Element.py b/lib/python/Components/Element.py index 10c841bd539..656d8c170ed 100644 --- a/lib/python/Components/Element.py +++ b/lib/python/Components/Element.py @@ -44,6 +44,7 @@ def __init__(self): self.source = None self.__suspended = True self.cache = None + self.onChanged = [] def connectDownstream(self, downstream): self.downstream_elements.append(downstream) @@ -90,19 +91,24 @@ def changed(self, *args, **kwargs): self.cache = {} self.downstream_elements.changed(*args, **kwargs) self.cache = None + for x in self.onChanged: + x() def setSuspend(self, suspended): - changed = self.__suspended != suspended - if not self.__suspended and suspended: - self.doSuspend(1) - elif self.__suspended and not suspended: - self.doSuspend(0) - - self.__suspended = suspended - if changed: - for s in self.sources: - s.checkSuspend() - + try: + changed = self.__suspended != suspended + except AttributeError: + print("[Element][setSuspend]self.__suspended - No attribute __suspended") + else: + if not self.__suspended and suspended: + self.doSuspend(1) + elif self.__suspended and not suspended: + self.doSuspend(0) + + self.__suspended = suspended + if changed: + for s in self.sources: + s.checkSuspend() suspended = property(lambda self: self.__suspended, setSuspend) def checkSuspend(self): diff --git a/lib/python/Components/EpgBouquetList.py b/lib/python/Components/EpgBouquetList.py index 2f0aa60c9e7..1e680282765 100644 --- a/lib/python/Components/EpgBouquetList.py +++ b/lib/python/Components/EpgBouquetList.py @@ -11,7 +11,7 @@ class EPGBouquetList(GUIComponent): def __init__(self, graphic=False): GUIComponent.__init__(self) self.graphic = graphic - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.l.setBuildFunc(self.buildEntry) self.onSelChanged = [] diff --git a/lib/python/Components/EpgListBase.py b/lib/python/Components/EpgListBase.py index f8b333ef8d1..ad6ad675f4f 100644 --- a/lib/python/Components/EpgListBase.py +++ b/lib/python/Components/EpgListBase.py @@ -16,7 +16,7 @@ def __init__(self, session, selChangedCB=None): self.onSelChanged = [] if selChangedCB is not None: self.onSelChanged.append(selChangedCB) - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.epgcache = eEPGCache.getInstance() # Load the common clock icons. diff --git a/lib/python/Components/EpgListGrid.py b/lib/python/Components/EpgListGrid.py index a575f612ad9..06ecea72d4d 100644 --- a/lib/python/Components/EpgListGrid.py +++ b/lib/python/Components/EpgListGrid.py @@ -573,6 +573,8 @@ def buildEntry(self, service, serviceName, events, picon, channel): borderRightPix = self.borderSelectedRightPix infoPix = self.selInfoPix bgpng = self.nowSelEvPix if isNow else self.selEvPix + if timer: + bgpng = self.recSelEvPix if timer.justplay == 0 and timer.always_zap == 0 else self.zapSelEvPix else: borderTopPix = self.borderTopPix borderLeftPix = self.borderLeftPix @@ -648,31 +650,36 @@ def buildEntry(self, service, serviceName, events, picon, channel): flags=BT_SCALE)) # Recording icons. - if timerIcon is not None and ewidth > 23: + if timerIcon is not None and ewidth > timerIcon.size().width(): if config.epgselection.grid.rec_icon_height.value != "hide": - clockSize = applySkinFactor(17) + pix_size = timerIcon.size() + pix_width = pix_size.width() + pix_height = pix_size.height() if config.epgselection.grid.rec_icon_height.value == "middle": - recIconHeight = top + (height - clockSize) // 2 + recIconHeight = top + (height - pix_height) // 2 elif config.epgselection.grid.rec_icon_height.value == "top": recIconHeight = top + 3 else: - recIconHeight = top + height - clockSize + recIconHeight = top + height - pix_height - applySkinFactor(5) if matchType == 0: - pos = (left + xpos + ewidth - applySkinFactor(10), recIconHeight) + pos = (left + xpos + ewidth - pix_width - applySkinFactor(5), recIconHeight) else: - pos = (left + xpos + ewidth - clockSize, recIconHeight) + pos = (left + xpos + ewidth - pix_width - applySkinFactor(5), recIconHeight) res.append(MultiContentEntryPixmapAlphaBlend( - pos=pos, size=(clockSize, clockSize), + pos=pos, size=(pix_width, pix_height), png=timerIcon)) if autoTimerIcon: + pix_size = autoTimerIcon.size() + pix_width = pix_size.width() + pix_height = pix_size.height() res.append(MultiContentEntryPixmapAlphaBlend( - pos=(pos[0] - clockSize, pos[1]), size=(clockSize, clockSize), + pos=(pos[0] - pix_width - applySkinFactor(5), pos[1]), size=(pix_width, pix_height), png=autoTimerIcon)) return res def getSelectionPosition(self): _, sely = EPGListBase.getSelectionPosition(self) - return self.selectionRect.left() + self.selectionRect.width(), sely + return self.selectionRect.left() + self.selectionRect.width() + self.instance.position().x(), sely def refreshSelection(self): events = self.selectedService and self.selectedService[2] # (service, serviceName, events, picon) @@ -828,11 +835,11 @@ def snapshotTimers(self, startTime, endTime): if (startTime <= timer.end or timer.repeated) and timer.begin < endTime: serviceref = timer.service_ref.ref.toCompareString() serviceref = "1" + serviceref[4:] if serviceref[:4] in config.recording.setstreamto1.value else serviceref # converts 4097, 5001, 5002 to 1 - l = self.filteredTimerList.get(serviceref) - if l is None: - self.filteredTimerList[serviceref] = l = [timer] + srefl = self.filteredTimerList.get(serviceref) + if srefl is None: + self.filteredTimerList[serviceref] = srefl = [timer] else: - l.append(timer) + srefl.append(timer) def getChannelNumber(self, service): if service.ref and "0:0:0:0:0:0:0:0:0" not in service.ref.toString(): @@ -854,7 +861,7 @@ def __init__(self, epgConfig, graphic): GUIComponent.__init__(self) self.epgConfig = epgConfig self.graphic = graphic - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.l.setSelectionClip(eRect(0, 0, 0, 0)) self.itemHeight = 30 self.timelineDate = None @@ -958,7 +965,7 @@ def setEntries(self, list, timelineNow, timeLines, force): bgpng = self.timelineDate if bgpng is not None and self.graphic: backColor = None - backColorSel = None + # backColorSel = None res.append(MultiContentEntryPixmapAlphaBlend( pos=(0, 0), size=(serviceRect.width(), self.listHeight), @@ -984,7 +991,7 @@ def setEntries(self, list, timelineNow, timeLines, force): xpos = 0 if bgpng is not None and self.graphic: backColor = None - backColorSel = None + # backColorSel = None res.append(MultiContentEntryPixmapAlphaBlend( pos=(serviceRect.width(), 0), size=(eventRect.width(), self.listHeight), diff --git a/lib/python/Components/EpgListMulti.py b/lib/python/Components/EpgListMulti.py index d75859f5dd0..cbc1dbeccfb 100644 --- a/lib/python/Components/EpgListMulti.py +++ b/lib/python/Components/EpgListMulti.py @@ -118,11 +118,11 @@ def snapshotTimers(self, startTime): for x in timerList: if x.end >= startTime: service = ":".join(x.service_ref.ref.toString().split(':')[:11]) - l = self.filteredTimerList.get(service) - if l is None: - self.filteredTimerList[service] = l = [x] + srefl = self.filteredTimerList.get(service) + if srefl is None: + self.filteredTimerList[service] = srefl = [x] else: - l.append(x) + srefl.append(x) if x.begin > startTime + 6 * 3600: break diff --git a/lib/python/Components/EpgListSingle.py b/lib/python/Components/EpgListSingle.py index 8ffc50bb0e3..1af1b1d0d15 100644 --- a/lib/python/Components/EpgListSingle.py +++ b/lib/python/Components/EpgListSingle.py @@ -1,7 +1,7 @@ from time import localtime, time, strftime from enigma import eEPGCache, eListboxPythonMultiContent, gFont, eRect, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_VALIGN_CENTER -from skin import parameters, parseFont, applySkinFactor +from skin import parameters, parseFont, parseScale, applySkinFactor from Components.config import config from Components.EpgListBase import EPGListBase @@ -18,6 +18,7 @@ def __init__(self, session, epgConfig, selChangedCB=None): self.epgConfig = epgConfig self.eventFontName = "Regular" self.eventFontSize = applySkinFactor(19) + self.sidesMargin = 0 self.l.setBuildFunc(self.buildEntry) def applySkin(self, desktop, screen): @@ -28,6 +29,8 @@ def applySkin(self, desktop, screen): font = parseFont(value, ((1, 1), (1, 1))) self.eventFontName = font.family self.eventFontSize = font.pointSize + elif attrib == "sidesMargin": + self.sidesMargin = parseScale(value) else: attribs.append((attrib, value)) self.skinAttributes = attribs @@ -57,13 +60,14 @@ def recalcEntrySize(self): dateW = int(fontSize * dateScale) timesW = int(fontSize * timesScale) left, dateWidth, sepWidth, timesWidth, breakWidth = parameters.get("EPGSingleColumnSpecs", (0, dateW, 5, timesW, 20)) + left += self.sidesMargin if config.usage.time.wide.value: timesWidth = int(timesWidth * wideScale) self._weekdayRect = eRect(left, 0, dateWidth, height) left += dateWidth + sepWidth self._datetimeRect = eRect(left, 0, timesWidth, height) left += timesWidth + breakWidth - self._descrRect = eRect(left, 0, width - left, height) + self._descrRect = eRect(left, 0, width - left - self.sidesMargin, height) self.showend = True # This is not an unused variable. It is a flag used by EPGSearch plugin def buildEntry(self, service, eventId, beginTime, duration, eventName): @@ -83,12 +87,17 @@ def buildEntry(self, service, eventId, beginTime, duration, eventName): ] eventW = r3.width() if timerIcon: - clockSize = applySkinFactor(17) - eventW -= clockSize - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, r3.left() + r3.width() - clockSize, (r3.height() - clockSize) // 2, clockSize, clockSize, timerIcon)) + pix_size = timerIcon.size() + pix_width = pix_size.width() + pix_height = pix_size.height() + eventW -= pix_width + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, r3.left() + r3.width() - pix_width, (r3.height() - pix_height) // 2, pix_width, pix_height, timerIcon)) if autoTimerIcon: - eventW -= clockSize - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, r3.left() + r3.width() - clockSize * 2, (r3.height() - clockSize) // 2, clockSize, clockSize, autoTimerIcon)) + pix_size = autoTimerIcon.size() + pix_width = pix_size.width() + pix_height = pix_size.height() + eventW -= pix_width + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, r3.left() + r3.width() - pix_width * 2 - 10, (r3.height() - pix_height) // 2, pix_width, pix_height, autoTimerIcon)) res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), eventW, r3.height(), 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, eventName)) return res diff --git a/lib/python/Components/FanControl.py b/lib/python/Components/FanControl.py index 87774df5604..c2116754c16 100644 --- a/lib/python/Components/FanControl.py +++ b/lib/python/Components/FanControl.py @@ -5,7 +5,6 @@ import NavigationInstance from enigma import iRecordableService -from boxbranding import getBoxType class FanControl: @@ -66,12 +65,7 @@ def setPWM(fancontrol, fanid, configElement): for fanid in range(self.getFanCount()): fan = ConfigSubsection() fan.vlt = ConfigSlider(default=15, increment=5, limits=(0, 255)) - if getBoxType() == 'tm2t': - fan.pwm = ConfigSlider(default=150, increment=5, limits=(0, 255)) - if getBoxType() == 'tmsingle': - fan.pwm = ConfigSlider(default=100, increment=5, limits=(0, 255)) - else: - fan.pwm = ConfigSlider(default=50, increment=5, limits=(0, 255)) + fan.pwm = ConfigSlider(default=50, increment=5, limits=(0, 255)) fan.vlt_standby = ConfigSlider(default=5, increment=5, limits=(0, 255)) fan.pwm_standby = ConfigSlider(default=0, increment=5, limits=(0, 255)) fan.vlt.addNotifier(boundFunction(setVlt, self, fanid)) diff --git a/lib/python/Components/FileList.py b/lib/python/Components/FileList.py index 48e64a40f9e..dbafa1cdfd6 100644 --- a/lib/python/Components/FileList.py +++ b/lib/python/Components/FileList.py @@ -143,11 +143,11 @@ def getSelection(self): return self.l.getCurrentSelection()[0] def getCurrentEvent(self): - l = self.l.getCurrentSelection() - if not l or l[0][1] is True: + currl = self.l.getCurrentSelection() + if not currl or currl[0][1] is True: return None else: - return self.serviceHandler.info(l[0][0]).getEvent(l[0][0]) + return self.serviceHandler.info(currl[0][0]).getEvent(currl[0][0]) def getFileList(self): return self.list diff --git a/lib/python/Components/Harddisk.py b/lib/python/Components/Harddisk.py index 0d1f468eb1f..30c2c8a8218 100644 --- a/lib/python/Components/Harddisk.py +++ b/lib/python/Components/Harddisk.py @@ -669,10 +669,10 @@ def enumerateBlockDevices(self): # # print("[Harddisk] DEBUG: Device '%s' (%s) has removable media." % (device, physicalDevice)) try: open(ospath.join("/dev", device), "r").close() - mediumFound = True # Check for medium. + mediumFound = True # noqa: F841 Check for medium set for debug. except (IOError, OSError) as err: if err.errno in (123, 159): # ENOMEDIUM - No medium found. (123 = Common Linux, 159 = MIPS Linux) - mediumFound = False + mediumFound = False # noqa: F841 set for Debug else: print("[Harddisk] Error: Device '%s' (%s) media availability test failed:" % (device, physicalDevice), err) continue @@ -716,7 +716,11 @@ def enumerateNetworkMounts(self): mountEntry = ospath.join("/media", entry) if not ospath.isdir(mountEntry): continue - mounts = listdir(mountEntry) + try: # protect against drive being removed unexpectedly + mounts = listdir(mountEntry) + except IOError as err: + print("[Harddisk] drive not accessible", err) + continue if len(mounts) > 0: for mount in mounts: mountDir = ospath.join(mountEntry, mount, "") diff --git a/lib/python/Components/HdmiCec.py b/lib/python/Components/HdmiCec.py index 2da82fc4588..356e24af081 100644 --- a/lib/python/Components/HdmiCec.py +++ b/lib/python/Components/HdmiCec.py @@ -552,7 +552,7 @@ def sendMessage(self, msgaddress, message): def sendMsgQ(self): if len(self.queue): (msgaddress, cmd, data) = self.queue.pop(0) - CECcmd = cmdList.get(cmd, "") + CECcmd = cmdList.get(cmd, "") # noqa: F841 # print("[HdmiCEC][sendMsgQ1]: msgaddress=%s, CECcmd=%s cmd=%X,data=%s \n" % (msgaddress, CECcmd, cmd, data)) eHdmiCEC.getInstance().sendMessage(msgaddress, cmd, data, len(data)) self.wait.start(int(config.hdmicec.minimum_send_interval.value), True) diff --git a/lib/python/Components/InputDevice.py b/lib/python/Components/InputDevice.py index fd4fa8a9532..2c7c46de66b 100644 --- a/lib/python/Components/InputDevice.py +++ b/lib/python/Components/InputDevice.py @@ -5,7 +5,7 @@ from enigma import eRCInput from keyids import KEYIDNAMES -from boxbranding import getBrandOEM +from Components.SystemInfo import SystemInfo from Components.config import config, ConfigInteger, ConfigSlider, ConfigSubsection, ConfigText, ConfigYesNo from Screens.Rc import RcPositions @@ -141,7 +141,7 @@ def createConfig(self, *args): for device in sorted(iter(iInputDevices.Devices.keys())): # print("[InputDevice][createConfig]", sorted(iter(iInputDevices.Devices.keys()))) self.currentDevice = device - #print("[InputDevice] creating config entry for device: %s -> %s " % (self.currentDevice, iInputDevices.Devices[device]["name"])) + # print("[InputDevice] creating config entry for device: %s -> %s " % (self.currentDevice, iInputDevices.Devices[device]["name"])) self.setupConfigEntries(self.currentDevice) self.remapRemoteControl(self.currentDevice) self.currentDevice = "" @@ -215,7 +215,7 @@ def remapRemoteControl(self, device): class RcTypeControl(): def __init__(self): self.boxType = "Default" - if path.exists('/proc/stb/ir/rc/type') and path.exists('/proc/stb/info/boxtype') and getBrandOEM() != 'gigablue': + if path.exists('/proc/stb/ir/rc/type') and path.exists('/proc/stb/info/boxtype') and SystemInfo["brand"] != 'gigablue': self.isSupported = True with open("/proc/stb/info/boxtype", "r") as fd: self.boxType = fd.read().strip() diff --git a/lib/python/Components/Ipkg.py b/lib/python/Components/Ipkg.py index 023bc0a5a59..1b11df1f533 100644 --- a/lib/python/Components/Ipkg.py +++ b/lib/python/Components/Ipkg.py @@ -3,7 +3,7 @@ from enigma import eConsoleAppContainer from Components.Harddisk import harddiskmanager from Tools.Directories import resolveFilename, SCOPE_LIBDIR -from boxbranding import getImageDistro +from Components.SystemInfo import SystemInfo opkgDestinations = [] opkgStatusPath = '' @@ -90,7 +90,7 @@ def runCmd(self, cmd): def startCmd(self, cmd, args=None): if cmd == self.CMD_UPDATE: for fn in listdir('/var/lib/opkg'): - if fn.startswith(getImageDistro()): + if fn.startswith(SystemInfo["distro"]): remove('/var/lib/opkg/' + fn) self.runCmdEx("update") elif cmd == self.CMD_UPGRADE: diff --git a/lib/python/Components/Lcd.py b/lib/python/Components/Lcd.py index 7c1e73d697d..2fb9294ac49 100644 --- a/lib/python/Components/Lcd.py +++ b/lib/python/Components/Lcd.py @@ -1,7 +1,5 @@ from sys import maxsize -from boxbranding import getBoxType, getDisplayType - from enigma import eDBoxLCD, eTimer, eActionMap from Components.config import config, ConfigSubsection, ConfigSelection, ConfigSlider, ConfigYesNo, ConfigNothing @@ -179,7 +177,7 @@ def standbyCounterChanged(dummy): def InitLcd(): if SystemInfo["HasNoDisplay"]: detected = False - elif getBoxType() in ('gbtrio4k',): + elif SystemInfo["boxtype"] in ('gbtrio4k',): detected = True else: detected = eDBoxLCD.getInstance().detected() @@ -411,14 +409,14 @@ def lcdLiveTvChanged(configElement): if "live_enable" in SystemInfo["LcdLiveTV"]: config.misc.standbyCounter.addNotifier(standbyCounterChangedLCDLiveTV, initial_call=False) - if SystemInfo["LCDMiniTV"] and getBoxType() not in ('gbquad4k', 'gbue4k'): + if SystemInfo["LCDMiniTV"] and SystemInfo["boxtype"] not in ('gbquad4k', 'gbue4k'): config.lcd.minitvmode = ConfigSelection([("0", _("normal")), ("1", _("MiniTV")), ("2", _("OSD")), ("3", _("MiniTV with OSD"))], "0") config.lcd.minitvmode.addNotifier(setLCDminitvmode) config.lcd.minitvpipmode = ConfigSelection([("0", _("off")), ("5", _("PIP")), ("7", _("PIP with OSD"))], "0") config.lcd.minitvpipmode.addNotifier(setLCDminitvpipmode) config.lcd.minitvfps = ConfigSlider(default=30, limits=(0, 30)) config.lcd.minitvfps.addNotifier(setLCDminitvfps) - elif can_lcdmodechecking and getBoxType() in ('gbquad4k', 'gbue4k'): + elif can_lcdmodechecking and SystemInfo["boxtype"] in ('gbquad4k', 'gbue4k'): # (0:normal, 1:video0, 2:fb, 3:vide0+fb, 4:video1, 5:vide0+video1, 6:video1+fb, 7:video0+video1+fb) config.lcd.minitvmode = ConfigSelection(default="0", choices=[ ("0", _("normal")), @@ -442,20 +440,20 @@ def lcdLiveTvChanged(configElement): config.lcd.minitvpipmode = ConfigNothing() config.lcd.minitvfps = ConfigNothing() - if SystemInfo["VFD_scroll_repeats"] and getDisplayType() not in ('7segment'): + if SystemInfo["VFD_scroll_repeats"] and SystemInfo["displaytype"] not in ('7segment'): def scroll_repeats(el): open(SystemInfo["VFD_scroll_repeats"], "w").write(el.value) choicelist = [("0", _("None")), ("1", _("1X")), ("2", _("2X")), ("3", _("3X")), ("4", _("4X")), ("500", _("Continues"))] config.usage.vfd_scroll_repeats = ConfigSelection(default="3", choices=choicelist) config.usage.vfd_scroll_repeats.addNotifier(scroll_repeats, immediate_feedback=False) - if SystemInfo["VFD_scroll_delay"] and getDisplayType() not in ('7segment'): + if SystemInfo["VFD_scroll_delay"] and SystemInfo["displaytype"] not in ('7segment'): def scroll_delay(el): open(SystemInfo["VFD_scroll_delay"], "w").write(str(el.value)) config.usage.vfd_scroll_delay = ConfigSlider(default=150, increment=10, limits=(0, 500)) config.usage.vfd_scroll_delay.addNotifier(scroll_delay, immediate_feedback=False) - if SystemInfo["VFD_initial_scroll_delay"] and getDisplayType() not in ('7segment'): + if SystemInfo["VFD_initial_scroll_delay"] and SystemInfo["displaytype"] not in ('7segment'): def initial_scroll_delay(el): open(SystemInfo["VFD_initial_scroll_delay"], "w").write(el.value) choicelist = [ @@ -466,7 +464,7 @@ def initial_scroll_delay(el): config.usage.vfd_initial_scroll_delay = ConfigSelection(default="1000", choices=choicelist) config.usage.vfd_initial_scroll_delay.addNotifier(initial_scroll_delay, immediate_feedback=False) - if SystemInfo["VFD_final_scroll_delay"] and getDisplayType() not in ('7segment'): + if SystemInfo["VFD_final_scroll_delay"] and SystemInfo["displaytype"] not in ('7segment'): def final_scroll_delay(el): open(SystemInfo["VFD_final_scroll_delay"], "w").write(el.value) choicelist = [ diff --git a/lib/python/Components/MediaPlayer.py b/lib/python/Components/MediaPlayer.py index fbb88bd85f8..eec62df1400 100644 --- a/lib/python/Components/MediaPlayer.py +++ b/lib/python/Components/MediaPlayer.py @@ -106,12 +106,12 @@ def getCurrentIndex(self): return self.currPlaying def getCurrentEvent(self): - l = self.l.getCurrentSelection() - return l and self.serviceHandler.info(l[0]).getEvent(l[0]) + currl = self.l.getCurrentSelection() + return currl and self.serviceHandler.info(currl[0]).getEvent(currl[0]) def getCurrent(self): - l = self.l.getCurrentSelection() - return l and l[0] + currl = self.l.getCurrentSelection() + return currl and currl[0] def getServiceRefList(self): return [x[0] for x in self.list] diff --git a/lib/python/Components/MenuList.py b/lib/python/Components/MenuList.py index cc77325de33..9d312174524 100644 --- a/lib/python/Components/MenuList.py +++ b/lib/python/Components/MenuList.py @@ -5,7 +5,7 @@ class MenuList(GUIComponent): def __init__(self, list, enableWrapAround=True, content=eListboxPythonStringContent): GUIComponent.__init__(self) - self.l = content() + self.l = content() # noqa: E741 self.onSelectionChanged = [] self.setList(list) self.enableWrapAround = enableWrapAround diff --git a/lib/python/Components/MovieList.py b/lib/python/Components/MovieList.py index bec5ec90e19..395aac80d3f 100644 --- a/lib/python/Components/MovieList.py +++ b/lib/python/Components/MovieList.py @@ -230,6 +230,7 @@ def __init__(self, root, sort_type=None, descr_state=None, allowCollections=Fals self.pbarColourPlayRec = 0xffc71d self.partIconeShift = None self.spaceRight = 2 + self.spaceLeft = 2 self.spaceIconeText = 2 self.iconsWidth = 22 self.durationWidth = 160 @@ -237,7 +238,7 @@ def __init__(self, root, sort_type=None, descr_state=None, allowCollections=Fals if config.usage.time.wide.value: self.dateWidth = int(self.dateWidth * 1.15) self.reloadDelayTimer = None - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.tags = set() self.markList = [] self.allowCollections = allowCollections # used to disable collections when loaded by OpenWebIf @@ -377,6 +378,9 @@ def spaceIconeText(value): def iconsWidth(value): self.iconsWidth = parseScale(value) + def spaceLeft(value): + self.spaceLeft = parseScale(value) + def spaceRight(value): self.spaceRight = parseScale(value) @@ -443,24 +447,24 @@ def buildMovieListEntry(self, serviceref, info, begin, data): if serviceref.flags & eServiceReference.isGroup: # Collection - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconCollection, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconCollection, flags=BT_ALIGN_CENTER | BT_SCALE | BT_KEEP_ASPECT_RATIO)) if self.getCurrent() in self.markList: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) - res.append(MultiContentEntryText(pos=(col0iconSize + space, 0), size=(width - 220, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + col0iconSize + space, 0), size=(width - 220, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) recordingCount = ngettext("%d Recording", "%d Recordings", data.collectionCount) % data.collectionCount res.append(MultiContentEntryText(pos=(width - 220 - r, 0), size=(220, self.itemHeight), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=recordingCount)) return res if serviceref.flags & eServiceReference.mustDescent: # Directory if data.txt == ".Trash": - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconTrash, flags=BT_ALIGN_CENTER)) - res.append(MultiContentEntryText(pos=(col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=_("Deleted items"))) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconTrash, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=_("Deleted items"))) res.append(MultiContentEntryText(pos=(width - 145 - r, 0), size=(145, self.itemHeight), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=_("Trash can"))) return res - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconFolder, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconFolder, flags=BT_ALIGN_CENTER | BT_SCALE | BT_KEEP_ASPECT_RATIO)) if self.getCurrent() in self.markList: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) - res.append(MultiContentEntryText(pos=(col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) res.append(MultiContentEntryText(pos=(width - 145 - r, 0), size=(145, self.itemHeight), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=_("Directory"))) return res if data.dirty: @@ -518,25 +522,25 @@ def addProgress(): if data: if switch == 'i' and data.icon is not None: if self.partIconeShift is None: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(colX, 0), size=(iconSize, ih), png=data.icon, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft + colX, 0), size=(iconSize, ih), png=data.icon, flags=BT_ALIGN_CENTER)) else: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(colX, self.partIconeShift), size=(iconSize, data.icon.size().height()), png=data.icon)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft + colX, self.partIconeShift), size=(iconSize, data.icon.size().height()), png=data.icon)) elif switch in ('p', 's'): if data.part > 0: pbarY = (self.itemHeight - self.pbarHeight) // 2 if self.pbarShift is None else self.pbarShift - res.append(MultiContentEntryProgress(pos=(colX, pbarY), size=(iconSize, self.pbarHeight), percent=data.part, borderWidth=2, foreColor=data.partcol, foreColorSelected=None, backColor=None, backColorSelected=None)) + res.append(MultiContentEntryProgress(pos=(self.spaceLeft + colX, pbarY), size=(iconSize, self.pbarHeight), percent=data.part, borderWidth=2, foreColor=data.partcol, foreColorSelected=None, backColor=None, backColorSelected=None)) elif data.icon is not None: if self.pbarShift is None: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(colX, 0), size=(iconSize, ih), png=data.icon, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft + colX, 0), size=(iconSize, ih), png=data.icon, flags=BT_ALIGN_CENTER)) else: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(colX, self.pbarShift), size=(iconSize, self.pbarHeight), png=data.icon)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft + colX, self.pbarShift), size=(iconSize, self.pbarHeight), png=data.icon)) return iconSize if piconWidth > 0: # Picon if data and data.picon is not None: res.append(MultiContentEntryPixmapAlphaBlend( - pos=(colX, 0), size=(piconWidth, ih), + pos=(self.spaceLeft + colX, 0), size=(piconWidth, ih), png=data.picon, backcolor=None, backcolor_sel=None, flags=BT_SCALE | BT_KEEP_ASPECT_RATIO | BT_HALIGN_CENTER | BT_VALIGN_CENTER)) colX += piconWidth @@ -545,11 +549,11 @@ def addProgress(): # The selection mark floats over the top of the first column if self.getCurrent() in self.markList: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(colX, self.itemHeight), png=self.iconMarked)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(colX, self.itemHeight), png=self.iconMarked)) colX += space # Recording name - res.append(MultiContentEntryText(pos=(colX, 0), size=(width - iconSize - space - durationWidth - dateWidth - r - colX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + colX, 0), size=(width - iconSize - space - durationWidth - dateWidth - r - colX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) colX = width - iconSize - space - durationWidth - dateWidth - r if piconWidth > 0: @@ -561,7 +565,7 @@ def addProgress(): length = data.len if length > 0: length = ngettext("%d Min", "%d Mins", (length // 60)) % (length // 60) - res.append(MultiContentEntryText(pos=(colX, 0), size=(durationWidth, ih), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=length)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + colX, 0), size=(durationWidth, ih), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=length)) # Date begin_string = "" @@ -603,12 +607,12 @@ def getCurrentIndex(self): return self.instance.getCurrentIndex() def getCurrentEvent(self): - l = self.l.getCurrentSelection() - return l and l[0] and l[1] and l[1].getEvent(l[0]) + currl = self.l.getCurrentSelection() + return currl and currl[0] and currl[1] and currl[1].getEvent(currl[0]) def getCurrent(self): - l = self.l.getCurrentSelection() - return l and l[0] + currl = self.l.getCurrentSelection() + return currl and currl[0] def getItem(self, index): if self.list: diff --git a/lib/python/Components/Network.py b/lib/python/Components/Network.py index 59df199a75e..70eecc555d2 100644 --- a/lib/python/Components/Network.py +++ b/lib/python/Components/Network.py @@ -1,7 +1,7 @@ from os import listdir, path, system import re import netifaces as ni -from socket import * # 'from socket import *' used; unable to detect undefined names +from socket import * # noqa: F401,F403 'from socket import *' used; unable to detect undefined names from Components.Console import Console from Components.PluginComponent import plugins diff --git a/lib/python/Components/OnlineUpdateCheck.py b/lib/python/Components/OnlineUpdateCheck.py index 95f57f2091b..1fb5592bef4 100644 --- a/lib/python/Components/OnlineUpdateCheck.py +++ b/lib/python/Components/OnlineUpdateCheck.py @@ -1,10 +1,10 @@ from time import time -from boxbranding import getImageVersion, getImageBuild, getMachineBrand, getMachineName, getMachineBuild, getImageType, getBoxType, getFeedsUrl from enigma import eTimer from Components.About import about from Components.config import config from Components.Ipkg import IpkgComponent +from Components.SystemInfo import SystemInfo import Components.Task import socket @@ -80,7 +80,7 @@ def getFeedStatus(self): trafficLight = "unknown" if self.adapterAvailable(): if self.NetworkUp(): - if getImageType() == "release" and officialReleaseFeedsUri in getFeedsUrl(): # we know the network is good now so only do this check on release images where the release domain applies + if SystemInfo["imagetype"] == "release" and officialReleaseFeedsUri in SystemInfo["feedsurl"]: # we know the network is good now so only do this check on release images where the release domain applies try: print("[OnlineUpdateCheck][getFeedStatus] checking feeds state") req = Request("http://openvix.co.uk/TrafficLightState.php") @@ -98,11 +98,11 @@ def getFeedStatus(self): except: print("[OnlineUpdateCheck][getFeedStatus] ERROR:", sys.exc_info()[0]) trafficLight = -2 - if getImageType() == "developer" and "openvixdev" in getFeedsUrl(): + if SystemInfo["imagetype"] == "developer" and "openvixdev" in SystemInfo["feedsurl"]: print("[OnlineUpdateCheck][getFeedStatus] Official developer feeds") trafficLight = "developer" - elif officialReleaseFeedsUri not in getFeedsUrl(): # if not using official feeds mark as alien. There is no status test for alien feeds (including official developer feeds). - print("[OnlineUpdateCheck][getFeedStatus] Alien feeds url: %s" % getFeedsUrl()) + elif officialReleaseFeedsUri not in SystemInfo["feedsurl"]: # if not using official feeds mark as alien. There is no status test for alien feeds (including official developer feeds). + print("[OnlineUpdateCheck][getFeedStatus] Alien feeds url: %s" % SystemInfo["feedsurl"]) status = 0 trafficLight = "alien" config.softwareupdate.updateisunstable.value = status @@ -151,11 +151,11 @@ def getFeedsBool(self): def getFeedsErrorMessage(self): global error if self.feedstatus == -2: - return _("Your %s %s has no internet access, please check your network settings and make sure you have network cable connected and try again.") % (getMachineBrand(), getMachineName()) + return _("Your %s %s has no internet access, please check your network settings and make sure you have network cable connected and try again.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) elif self.feedstatus == -3: - return _("Your %s %s has no network access, please check your network settings and make sure you have network cable connected and try again.") % (getMachineBrand(), getMachineName()) + return _("Your %s %s has no network access, please check your network settings and make sure you have network cable connected and try again.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) elif self.feedstatus == 404: - return _("Your %s %s is not able to connect to the feeds, please try again later. If this persists please report on the OpenViX forum at world-of-satellite.com.") % (getMachineBrand(), getMachineName()) + return _("Your %s %s is not able to connect to the feeds, please try again later. If this persists please report on the OpenViX forum at world-of-satellite.com.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) elif self.feedstatus in ("updating", 403): return _("Sorry feeds are down for maintenance, please try again later. If this issue persists please check openvix.co.uk or world-of-satellite.com.") elif error: @@ -178,7 +178,7 @@ def ipkgCallback(self, event, param): self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE_LIST) elif self.ipkg.currentCommand == IpkgComponent.CMD_UPGRADE_LIST: self.total_packages = len(self.ipkg.getFetchedList()) - if self.total_packages and (getImageType() != "release" or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value) or config.softwareupdate.updateisunstable.value == 0): + if self.total_packages and (SystemInfo["imagetype"] != "release" or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value) or config.softwareupdate.updateisunstable.value == 0): print(("[OnlineUpdateCheck][ipkgCallback] %s Updates available" % self.total_packages)) config.softwareupdate.updatefound.setValue(True) pass @@ -249,7 +249,7 @@ def createCheckJob(self): def JobStart(self): config.softwareupdate.updatefound.setValue(False) - if (getImageType() != "release" and feedsstatuscheck.getFeedsBool() == "unknown") or (getImageType() == "release" and feedsstatuscheck.getFeedsBool() in ("stable", "unstable")): + if (SystemInfo["imagetype"] != "release" and feedsstatuscheck.getFeedsBool() == "unknown") or (SystemInfo["imagetype"] == "release" and feedsstatuscheck.getFeedsBool() in ("stable", "unstable")): print("[OnlineUpdateCheckPoller] Starting background check.") feedsstatuscheck.startCheck() else: @@ -266,7 +266,7 @@ def __init__(self): def getStableUpdateAvailable(self): if config.softwareupdate.updatefound.value and config.softwareupdate.check.value: - if getImageType() != "release" or config.softwareupdate.updateisunstable.value == 0: + if SystemInfo["imagetype"] != "release" or config.softwareupdate.updateisunstable.value == 0: print("[OnlineVersionCheck] New Release updates found") return True else: @@ -277,7 +277,7 @@ def getStableUpdateAvailable(self): def getUnstableUpdateAvailable(self): if config.softwareupdate.updatefound.value and config.softwareupdate.check.value: - if getImageType() != "release" or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): + if SystemInfo["imagetype"] != "release" or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): print("[OnlineVersionCheck] New Experimental updates found") return True else: @@ -300,7 +300,7 @@ def kernelMismatch(): print("[OnlineUpdateCheck][kernelMismatch] unable to retrieve kernel version from STB") return False - uri = "%s/%s/Packages.gz" % (getFeedsUrl(), getMachineBuild()) + uri = "%s/%s/Packages.gz" % (SystemInfo["feedsurl"], SystemInfo["model"]) try: req = Request(uri) d = urlopen(req) @@ -332,7 +332,7 @@ def kernelMismatch(): def statusMessage(): # returns message if status message is found, else False. # status-message.php goes in the root folder of the feeds webserver - uri = "http://%s/status-message.php?machine=%s&version=%s&build=%s" % (getFeedsUrl().split("/")[2], getBoxType(), getImageVersion(), getImageBuild()) + uri = "http://%s/status-message.php?machine=%s&version=%s&build=%s" % (SystemInfo["feedsurl"].split("/")[2], SystemInfo["boxtype"], SystemInfo["imageversion"], SystemInfo["imagebuild"]) try: req = Request(uri) d = urlopen(req) diff --git a/lib/python/Components/PackageInfo.py b/lib/python/Components/PackageInfo.py index fae814a3d4f..9632984a75d 100644 --- a/lib/python/Components/PackageInfo.py +++ b/lib/python/Components/PackageInfo.py @@ -3,7 +3,7 @@ from Components.NimManager import nimmanager from Components.Ipkg import IpkgComponent from Components.config import config, configfile -from boxbranding import getBoxType +from Components.SystemInfo import SystemInfo from enigma import eConsoleAppContainer, eDVBDB from os import listdir, path, system @@ -65,7 +65,7 @@ def startElement(self, name, attrs): self.printError("file tag with no name attribute") else: if "directory" not in attrs: - directory = self.directory # what is this? Variable assigned, not used. Is this supposed to be attrs["directory"] = self.directory? + directory = self.directory # noqa: F841 - PackageInfo only use by unused SoftwareManager plugin type = attrs["type"] if type not in self.validFileTypes: self.printError("file tag with invalid type attribute") @@ -271,7 +271,7 @@ def prerequisiteMet(self, prerequisites): if "hardware" in prerequisites: hardware_found = False for hardware in prerequisites["hardware"]: - if hardware == getBoxType(): + if hardware == SystemInfo["boxtype"]: hardware_found = True if not hardware_found: return False diff --git a/lib/python/Components/Pixmap.py b/lib/python/Components/Pixmap.py index b636eb5dedf..fbb55fb9c5e 100644 --- a/lib/python/Components/Pixmap.py +++ b/lib/python/Components/Pixmap.py @@ -4,7 +4,7 @@ from Components.ConditionalWidget import ConditionalWidget from Components.GUIComponent import GUIComponent -from Tools.Directories import resolveFilename, fileExists, SCOPE_SKIN_IMAGE, SCOPE_CURRENT_SKIN, SCOPE_ACTIVE_LCDSKIN +from Tools.Directories import resolveFilename, fileExists, SCOPE_CURRENT_SKIN, SCOPE_ACTIVE_LCDSKIN from skin import loadPixmap @@ -143,9 +143,11 @@ def doMove(self): class MultiPixmap(Pixmap): def __init__(self): Pixmap.__init__(self) + self.pixmapfiles = [] self.pixmaps = [] def applySkin(self, desktop, screen): + self.desktop = desktop if self.skinAttributes is not None: skin_path_prefix = getattr(screen, "skin_path", path) pixmap = None @@ -153,30 +155,12 @@ def applySkin(self, desktop, screen): for (attrib, value) in self.skinAttributes: if attrib == "pixmaps": pixmaps = value.split(',') - for p in pixmaps: - pngfile = "" - if fileExists(resolveFilename(SCOPE_CURRENT_SKIN, p, path_prefix=skin_path_prefix)): - pngfile = resolveFilename(SCOPE_CURRENT_SKIN, p, path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_SKIN_IMAGE, p, path_prefix=skin_path_prefix)): - pngfile = resolveFilename(SCOPE_SKIN_IMAGE, p, path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_ACTIVE_LCDSKIN, p, path_prefix=skin_path_prefix)): - pngfile = resolveFilename(SCOPE_ACTIVE_LCDSKIN, p, path_prefix=skin_path_prefix) - if path.exists(pngfile): - self.pixmaps.append(loadPixmap(pngfile, desktop)) - if not pixmap: - if fileExists(resolveFilename(SCOPE_CURRENT_SKIN, pixmaps[0], path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_CURRENT_SKIN, pixmaps[0], path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_SKIN_IMAGE, pixmaps[0], path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_SKIN_IMAGE, pixmaps[0], path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_ACTIVE_LCDSKIN, pixmaps[0], path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_ACTIVE_LCDSKIN, pixmaps[0], path_prefix=skin_path_prefix) + self.pixmapfiles = [pngfile for p in pixmaps if (pngfile := self.checkPaths(p.strip(), skin_path_prefix))] + if not pixmap and self.pixmapfiles: + pixmap = self.pixmapfiles[0] elif attrib == "pixmap": - if fileExists(resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix) + if (pngfile := self.checkPaths(value, skin_path_prefix)): + pixmap = pngfile else: attribs.append((attrib, value)) if pixmap: @@ -184,9 +168,16 @@ def applySkin(self, desktop, screen): self.skinAttributes = attribs return GUIComponent.applySkin(self, desktop, screen) + def checkPaths(self, value, skin_path_prefix): + return (fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix))) and pngfile + def setPixmapNum(self, x): if self.instance: + if not self.pixmaps and self.pixmapfiles: + width, height = self.getSize() + for file in self.pixmapfiles: + self.pixmaps.append(loadPixmap(file, self.desktop, width, height)) if len(self.pixmaps) > x: self.instance.setPixmap(self.pixmaps[x]) else: - print("[Pixmap] setPixmapNum(%d) failed! defined pixmaps:" % x, self.pixmaps) + print("[MultiPixmap] setPixmapNum(%d) failed! defined pixmaps:" % x, self.pixmaps) diff --git a/lib/python/Components/Playlist.py b/lib/python/Components/Playlist.py index eea2827cdd7..e9c6e17816b 100644 --- a/lib/python/Components/Playlist.py +++ b/lib/python/Components/Playlist.py @@ -52,10 +52,13 @@ def open(self, filename): except IOError: return None while True: - entry = file.readline().strip() - if entry == "": - break - self.addService(ServiceReference(entry)) + try: + entry = file.readline().strip() + if entry == "": + break + self.addService(ServiceReference(entry)) + except UnicodeDecodeError: + pass file.close() return self.list diff --git a/lib/python/Components/PluginComponent.py b/lib/python/Components/PluginComponent.py index 0b04be850b0..27a731b133b 100644 --- a/lib/python/Components/PluginComponent.py +++ b/lib/python/Components/PluginComponent.py @@ -36,7 +36,8 @@ def removePlugin(self, plugin): if plugin in self.pluginList: self.pluginList.remove(plugin) for x in plugin.where: - self.plugins[x].remove(plugin) + if x in self.plugins: + self.plugins[x].remove(plugin) if x == PluginDescriptor.WHERE_AUTOSTART: plugin(reason=1) diff --git a/lib/python/Components/PowerTimerList.py b/lib/python/Components/PowerTimerList.py index 3308d290f8c..c7ef3769f0c 100644 --- a/lib/python/Components/PowerTimerList.py +++ b/lib/python/Components/PowerTimerList.py @@ -125,7 +125,7 @@ def buildTimerEntry(self, timer, processed): def __init__(self, list): GUIComponent.__init__(self) self.onSelectionChanged = [] - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.l.setBuildFunc(self.buildTimerEntry) self.serviceNameFont = gFont("Regular", 20) self.font = gFont("Regular", 18) diff --git a/lib/python/Components/ProgressBar.py b/lib/python/Components/ProgressBar.py index a41da2926cb..49c976e41ba 100644 --- a/lib/python/Components/ProgressBar.py +++ b/lib/python/Components/ProgressBar.py @@ -19,9 +19,9 @@ def postWidgetCreate(self, instance): instance.setRange(self.__start, self.__end) def setRange(self, range): - (__start, __end) = range if self.instance is not None: - self.instance.setRange(__start, __end) + self.__start, self.__end = range + self.instance.setRange(self.__start, self.__end) def getRange(self): return self.__start, self.__end diff --git a/lib/python/Components/RecordingConfig.py b/lib/python/Components/RecordingConfig.py index e81c3936462..e9dbc22eca5 100644 --- a/lib/python/Components/RecordingConfig.py +++ b/lib/python/Components/RecordingConfig.py @@ -28,3 +28,4 @@ def InitRecordingConfig(): ("long", _("Long filenames"))]) config.recording.offline_decode_delay = ConfigSelectionNumber(min=1, max=10000, stepwidth=10, default=1000, wraparound=True) config.recording.ecm_data = ConfigSelection(choices=[("normal", _("normal")), ("descrambled+ecm", _("descramble and record ecm")), ("scrambled+ecm", _("don't descramble, record ecm"))], default="normal") + config.recording.record_icon_match = ConfigSelection(default="Sref + stream url", choices=[("Sref only", _("Sref only")), ("Sref + stream url", _("Sref + stream url"))]) diff --git a/lib/python/Components/Renderer/AnalogClockLCD.py b/lib/python/Components/Renderer/AnalogClockLCD.py index 3b6ca7af3af..eaa96d14d0a 100644 --- a/lib/python/Components/Renderer/AnalogClockLCD.py +++ b/lib/python/Components/Renderer/AnalogClockLCD.py @@ -57,16 +57,16 @@ def hand(self, opt): height = self.positionheight r = (width // 2) r1 = (height // 2) - l = self.linesize + len = self.linesize if opt == 'sec': - l = self.linesize + len = self.linesize self.fColor = self.fColors elif opt == 'min': - l = self.linesize + len = self.linesize self.fColor = self.fColorm else: self.fColor = self.fColorh - (endX, endY,) = self.calc(self.forend, l, r, r1) + (endX, endY,) = self.calc(self.forend, len, r, r1) self.line_draw(r, r1, endX, endY) def line_draw(self, x0, y0, x1, y1): diff --git a/lib/python/Components/Renderer/AudioIcon.py b/lib/python/Components/Renderer/AudioIcon.py new file mode 100644 index 00000000000..3b9300c4e60 --- /dev/null +++ b/lib/python/Components/Renderer/AudioIcon.py @@ -0,0 +1,63 @@ +from Components.Renderer.Renderer import Renderer +from enigma import ePixmap +from Tools.Directories import fileExists, SCOPE_GUISKIN, resolveFilename +from Tools.LoadPixmap import LoadPixmap + + +class AudioIcon(Renderer): + def __init__(self): + Renderer.__init__(self) + self.size = None + self.width = 51 + self.height = 30 + self.nameAudioCache = {} + self.pngname = "" + self.path = "" + + def applySkin(self, desktop, parent): + attribs = [] + for (attrib, value) in self.skinAttributes: + if attrib == "path": + self.path = value + if value.endswith("/"): + self.path = value + else: + self.path = value + "/" + else: + attribs.append((attrib, value)) + if attrib == "size": + value = value.split(',') + if len(value) == 2: + self.width = int(value[0]) + self.height = int(value[1]) + self.size = value[0] + "x" + value[1] + self.skinAttributes = attribs + return Renderer.applySkin(self, desktop, parent) + + GUI_WIDGET = ePixmap + + def changed(self, what): + if self.instance: + pngname = "" + if what[0] != self.CHANGED_CLEAR: + sname = self.source.text + pngname = self.nameAudioCache.get(sname, "") + if pngname == "": + pngname = self.findAudioIcon(sname) + if pngname != "": + self.nameAudioCache[sname] = pngname + if pngname == "": + self.instance.hide() + else: + self.instance.show() + if pngname != "" and self.pngname != pngname: + is_svg = pngname.endswith(".svg") + png = LoadPixmap(pngname, width=self.width, height=0 if is_svg else self.height) + self.instance.setPixmap(png) + self.pngname = pngname + + def findAudioIcon(self, audioName): + pngname = resolveFilename(SCOPE_GUISKIN, self.path + audioName + ".svg") + if fileExists(pngname): + return pngname + return "" diff --git a/lib/python/Components/Renderer/Canvas.py b/lib/python/Components/Renderer/Canvas.py index aef12e9726f..aca79ed7145 100644 --- a/lib/python/Components/Renderer/Canvas.py +++ b/lib/python/Components/Renderer/Canvas.py @@ -29,17 +29,17 @@ def pull_updates(self): self.draw_count = len(list[1]) def draw(self, list): - for l in list: - if l[0] == 1: - self.instance.fillRect(eRect(l[1], l[2], l[3], l[4]), gRGB(l[5])) - elif l[0] == 2: - self.instance.writeText(eRect(l[1], l[2], l[3], l[4]), gRGB(l[5]), gRGB(l[6]), l[7], l[8], l[9]) - elif l[0] == 3: - self.instance.drawLine(l[1], l[2], l[3], l[4], gRGB(l[5])) - elif l[0] == 4: - self.instance.drawRotatedLine(l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8], gRGB(l[9])) + for element in list: + if element[0] == 1: + self.instance.fillRect(eRect(element[1], element[2], element[3], element[4]), gRGB(element[5])) + elif element[0] == 2: + self.instance.writeText(eRect(element[1], element[2], element[3], element[4]), gRGB(element[5]), gRGB(element[6]), element[7], element[8], element[9]) + elif element[0] == 3: + self.instance.drawLine(element[1], element[2], element[3], element[4], gRGB(element[5])) + elif element[0] == 4: + self.instance.drawRotatedLine(element[1], element[2], element[3], element[4], element[5], element[6], element[7], element[8], gRGB(element[9])) else: - print("drawlist entry:", l) + print("drawlist entry:", element) raise RuntimeError("invalid drawlist entry") def changed(self, what): diff --git a/lib/python/Components/Renderer/LcdPicon.py b/lib/python/Components/Renderer/LcdPicon.py index 970f9aced48..aef6c86ba6e 100644 --- a/lib/python/Components/Renderer/LcdPicon.py +++ b/lib/python/Components/Renderer/LcdPicon.py @@ -2,13 +2,13 @@ from Components.Renderer.Renderer import Renderer from enigma import ePixmap, ePicLoad from Tools.Directories import pathExists, SCOPE_CURRENT_SKIN, resolveFilename -from boxbranding import getDisplayType from Components.config import config +from Components.SystemInfo import SystemInfo from Components.Renderer.Picon import PiconLocator def useLcdPicons(): - return getDisplayType() in ('bwlcd255', 'bwlcd140', 'bwlcd128') or config.lcd.picon_pack.value + return SystemInfo["displaytype"] in ('bwlcd255', 'bwlcd140', 'bwlcd128') or config.lcd.picon_pack.value lcdPiconLocator = None diff --git a/lib/python/Components/Renderer/Picon.py b/lib/python/Components/Renderer/Picon.py index be5698143a9..8a1954d2663 100644 --- a/lib/python/Components/Renderer/Picon.py +++ b/lib/python/Components/Renderer/Picon.py @@ -1,5 +1,5 @@ from os import listdir, path as ospath -import re +from re import sub from enigma import ePixmap, eServiceReference @@ -67,7 +67,7 @@ def addSearchPath(self, value): if pathExists(value): if not value.endswith("/"): value += "/" - if not value.startswith("/media/net") and not value.startswith("/media/autofs") and value not in self.searchPaths: + if not value.startswith(("/media/net", "/media/autofs")) and value not in self.searchPaths: self.searchPaths.append(value) def getPiconName(self, serviceRef): @@ -90,13 +90,11 @@ def getPiconName(self, serviceRef): pngname = self.findPicon("_".join(fields)) if not pngname: # picon by channel name name = sanitizeFilename(eServiceReference(serviceRef).getServiceName()) - name = re.sub("[^a-z0-9]", "", name.replace("&", "and").replace("+", "plus").replace("*", "star").lower()) - if len(name) > 0: - pngname = self.findPicon(name) - if not pngname and len(name) > 2 and name.endswith("hd"): - pngname = self.findPicon(name[:-2]) + name = sub("[^a-z0-9]", "", name.replace("&", "and").replace("+", "plus").replace("*", "star").lower()) + if name: + pngname = self.findPicon(name) or self.findPicon(sub("(fhd|uhd|hd|sd|4k)$", "", name).strip()) if not pngname and len(name) > 6: - series = re.sub(r"s[0-9]*e[0-9]*$", "", name) + series = sub(r"s[0-9]*e[0-9]*$", "", name) pngname = self.findPicon(series) return pngname diff --git a/lib/python/Components/Renderer/RollerCharLCD.py b/lib/python/Components/Renderer/RollerCharLCD.py index 87a733b5ec2..a646520352b 100644 --- a/lib/python/Components/Renderer/RollerCharLCD.py +++ b/lib/python/Components/Renderer/RollerCharLCD.py @@ -1,5 +1,4 @@ from enigma import eLabel, eTimer -from boxbranding import getBoxType from Components.config import config from Components.Renderer.Renderer import Renderer @@ -11,10 +10,7 @@ class RollerCharLCD(VariableText, Renderer): def __init__(self): Renderer.__init__(self) VariableText.__init__(self) - if getBoxType() in ('vuduo', 'sf4008'): - self.stringlength = 16 - else: - self.stringlength = 12 + self.stringlength = 12 GUI_WIDGET = eLabel diff --git a/lib/python/Components/Scanner.py b/lib/python/Components/Scanner.py index 01501a9de72..76be5b9f30f 100644 --- a/lib/python/Components/Scanner.py +++ b/lib/python/Components/Scanner.py @@ -174,11 +174,10 @@ def scanDevice(mountpoint): scanner = [] for p in plugins.getPlugins(PluginDescriptor.WHERE_FILESCAN): - l = p() - if not isinstance(l, list): - l = [l] - scanner += l - + scanDev = p() + if not isinstance(scanDev, list): + scanDev = [scanDev] + scanner += scanDev print("[Scanner] ", scanner) res = {} @@ -227,11 +226,11 @@ def openList(session, files): scanner = [] for p in plugins.getPlugins(PluginDescriptor.WHERE_FILESCAN): - l = p() - if not isinstance(l, list): - scanner.append(l) + scanDev = p() + if not isinstance(scanDev, list): + scanner.append(scanDev) else: - scanner += l + scanner += scanDev print("[Scanner] ", scanner) diff --git a/lib/python/Components/ScrollLabel.py b/lib/python/Components/ScrollLabel.py index 8ac4a4ed5f1..02b50c7092f 100644 --- a/lib/python/Components/ScrollLabel.py +++ b/lib/python/Components/ScrollLabel.py @@ -150,7 +150,7 @@ def isAtLastPage(self): def updateScrollbar(self): vis = max(100 * self.pageHeight // self.TotalTextHeight, 3) - start = (100 - vis) * self.curPos // (self.TotalTextHeight - self.pageHeight) + start = (100 - vis) * self.curPos // ((self.TotalTextHeight - self.pageHeight) or 1) self.scrollbar.setStartEnd(start, start + vis) def GUIcreate(self, parent): diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 4e065ebef70..253abe28dd2 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -1,9 +1,9 @@ from Components.GUIComponent import GUIComponent -from skin import parseColor, parseFont, parseScale +from skin import parseColor, parseFont, parseScale, applySkinFactor from enigma import eListboxServiceContent, eListbox, eServiceCenter, eServiceReference, gFont, eRect, eSize from Tools.LoadPixmap import LoadPixmap -from Tools.TextBoundary import getTextBoundarySize +# from Tools.TextBoundary import getTextBoundarySize from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN @@ -27,7 +27,7 @@ class ServiceList(GUIComponent): def __init__(self, serviceList): self.serviceList = serviceList GUIComponent.__init__(self) - self.l = eListboxServiceContent() + self.l = eListboxServiceContent() # noqa: E741 pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/folder.png")) pic and self.l.setPixmap(self.l.picFolder, pic) @@ -56,9 +56,23 @@ def __init__(self, serviceList): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/record.png")) pic and self.l.setPixmap(self.l.picRecord, pic) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_hd-fs8.png")) + pic and self.l.setPixmap(self.l.picHD, pic) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_sd-fs8.png")) + pic and self.l.setPixmap(self.l.picSD, pic) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_uhd-fs8.png")) + pic and self.l.setPixmap(self.l.pic4K, pic) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_catchup-fs8.png")) + pic and self.l.setPixmap(self.l.picCatchup, pic) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_altref-fs8.png")) + pic and self.l.setPixmap(self.l.picBackup, pic) + + self.l.setAlternativeRecordMatching(config.recording.record_icon_match.value == "Sref only") + self.root = None self.mode = self.MODE_NORMAL self.listHeight = 0 + self.listHeightOrig = 0 self.listWidth = 0 self.ServiceNumberFontName = "Regular" self.ServiceNumberFontSize = 20 @@ -68,11 +82,18 @@ def __init__(self, serviceList): self.ServiceInfoFontSize = 18 self.ServiceNextInfoFontName = "Regular" self.ServiceNextInfoFontSize = 15 + self.ServiceRemainingInfoFontName = "Regular" + self.ServiceRemainingInfoFontSize = 18 self.progressBarWidth = 52 self.progressPercentWidth = 0 self.fieldMargins = 10 - self.ItemHeight = None - self.skinItemHeight = None + self.sidesMargin = 0 + self.ItemHeight = applySkinFactor(28) + self.ItemHeightTwoLine = applySkinFactor(58) + self.ItemHeightSkin = applySkinFactor(28) + self.ItemHeightTwoLineSkin = applySkinFactor(58) + self.selectionPixmapSingle = None + self.selectionPixmapDouble = None self.onSelectionChanged = [] @@ -101,6 +122,9 @@ def foregroundColorEvent(value): def foregroundColorNextEvent(value): self.l.setColor(eListboxServiceContent.eventNextForeground, parseColor(value)) + def foregroundColorEventRemaining(value): + self.l.setColor(eListboxServiceContent.eventRemainingForeground, parseColor(value)) + def colorServiceDescription(value): self.l.setColor(eListboxServiceContent.eventForeground, parseColor(value)) @@ -110,6 +134,9 @@ def foregroundColorEventSelected(value): def foregroundColorEventNextSelected(value): self.l.setColor(eListboxServiceContent.eventNextForegroundSelected, parseColor(value)) + def foregroundColorEventRemainingSelected(value): + self.l.setColor(eListboxServiceContent.eventRemainingForegroundSelected, parseColor(value)) + def colorServiceDescriptionSelected(value): self.l.setColor(eListboxServiceContent.eventForegroundSelected, parseColor(value)) @@ -152,13 +179,16 @@ def colorServiceNextDescriptionFallback(value): def colorServiceNextDescriptionSelectedFallback(value): self.l.setColor(eListboxServiceContent.eventNextForegroundSelectedFallback, parseColor(value)) + def colorServiceRemainingDescriptionFallback(value): + self.l.setColor(eListboxServiceContent.eventRemainingForegroundFallback, parseColor(value)) + + def colorServiceRemainingDescriptionSelectedFallback(value): + self.l.setColor(eListboxServiceContent.eventRemainingForegroundSelectedFallback, parseColor(value)) + def picServiceEventProgressbar(value): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value)) pic and self.l.setPixmap(self.l.picServiceEventProgressbar, pic) - def serviceItemHeight(value): - self.skinItemHeight = parseScale(value) - def serviceNameFont(value): font = parseFont(value, ((1, 1), (1, 1))) self.ServiceNameFontName = font.family @@ -172,6 +202,11 @@ def serviceInfoFont(value): self.ServiceNextInfoFontName = font.family self.ServiceNextInfoFontSize = font.pointSize + def serviceRemainingInfoFont(value): + font = parseFont(value, ((1, 1), (1, 1))) + self.ServiceRemainingInfoFontName = font.family + self.ServiceRemainingInfoFontSize = font.pointSize + def serviceNumberFont(value): font = parseFont(value, ((1, 1), (1, 1))) self.ServiceNumberFontName = font.family @@ -198,7 +233,33 @@ def nonplayableMargins(value): def itemsDistances(value): self.l.setItemsDistances(parseScale(value)) - for (attrib, value) in self.skinAttributes[:]: + def sidesMargin(value): + self.sidesMargin = parseScale(value) + + def textSeparator(value): + self.l.setTextSeparator(value) + + def itemHeightTwoLine(value): + self.ItemHeightTwoLine = parseScale(value) + self.ItemHeightTwoLineSkin = self.ItemHeightTwoLine + + def itemHeight(value): + self.ItemHeight = parseScale(value) + self.ItemHeightSkin = self.ItemHeight + + def markerLine(value): + self.l.setMarkerAsLine(parseScale(value)) + + def markerLineColor(value): + self.l.setMarkerLineColor(parseColor(value)) + + def markerTextAlignment(value): + self.l.setMarkerTextAlignment(value) + + def serviceItemHeight(value): # for legacy support + itemHeight(value) + + for (attrib, value) in sorted(self.skinAttributes, key=lambda x: 0 if x[0] == "itemHeight" else 1): try: locals().get(attrib)(value) self.skinAttributes.remove((attrib, value)) @@ -207,6 +268,7 @@ def itemsDistances(value): rc = GUIComponent.applySkin(self, desktop, parent) self.listHeight = self.instance.size().height() self.listWidth = self.instance.size().width() + self.listHeightOrig = self.listHeight self.setFontsize() self.setMode(self.mode) return rc @@ -229,7 +291,7 @@ def setCurrent(self, ref, adjust=True): from Components.ServiceEventTracker import InfoBarCount if adjust and config.usage.multibouquet.value and InfoBarCount == 1 and ref and ref.type != 8192: print("[servicelist] search for service in userbouquets") - isRadio = ref.toString().startswith("1:0:2:") or ref.toString().startswith("1:0:A:") + isRadio = ref.toString().startswith(("1:0:2:", "1:0:A:")) if self.serviceList: revert_mode = config.servicelist.lastmode.value revert_root = self.getRoot() @@ -323,11 +385,19 @@ def getCurrentIndex(self): def setItemsPerPage(self): numberOfRows = config.usage.serviceitems_per_page.value - itemHeight = (self.listHeight // numberOfRows if numberOfRows > 0 else self.skinItemHeight) or 28 - self.ItemHeight = itemHeight + two_lines_val = int(config.usage.servicelist_twolines.value) + if two_lines_val: + numberOfRows = int(numberOfRows / ((self.ItemHeightTwoLineSkin / self.ItemHeightSkin)) if self.ItemHeightSkin and self.ItemHeightTwoLineSkin else 2) + itemHeight = self.ItemHeightSkin if not two_lines_val else self.ItemHeightTwoLineSkin + if numberOfRows > 0: + itemHeight = self.listHeight // numberOfRows + if two_lines_val: + self.ItemHeightTwoLine = itemHeight + else: + self.ItemHeight = itemHeight self.l.setItemHeight(itemHeight) - if self.listHeight: - self.instance.resize(eSize(self.listWidth, self.listHeight // itemHeight * itemHeight)) + if self.listHeight and itemHeight: + self.instance.resize(eSize(self.listWidth, self.listHeightOrig // itemHeight * itemHeight)) def getSelectionPosition(self): # Adjust absolute index to index in displayed view @@ -336,16 +406,21 @@ def getSelectionPosition(self): sely = self.instance.position().y() + self.ItemHeight * index if sely >= self.instance.position().y() + self.listHeight: sely -= self.listHeight - return self.listWidth, sely + return self.listWidth + self.instance.position().x(), sely def setFontsize(self): - self.ServiceNumberFont = gFont(self.ServiceNameFontName, self.ServiceNameFontSize + config.usage.servicenum_fontsize.value) + self.ServiceNumberFont = gFont(self.ServiceNumberFontName, self.ServiceNumberFontSize + config.usage.servicenum_fontsize.value) self.ServiceNameFont = gFont(self.ServiceNameFontName, self.ServiceNameFontSize + config.usage.servicename_fontsize.value) self.ServiceInfoFont = gFont(self.ServiceInfoFontName, self.ServiceInfoFontSize + config.usage.serviceinfo_fontsize.value) self.ServiceNextInfoFont = gFont(self.ServiceNextInfoFontName, self.ServiceNextInfoFontSize + config.usage.serviceinfo_fontsize.value) + self.ServiceRemainingInfoFont = gFont(self.ServiceRemainingInfoFontName, self.ServiceRemainingInfoFontSize + config.usage.serviceinfo_fontsize.value) self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) + self.l.setElementFont(self.l.celServiceNextInfo, self.ServiceNextInfoFont) + self.l.setElementFont(self.l.celServiceInfoRemainingTime, self.ServiceRemainingInfoFont) + if "perc" in config.usage.show_event_progress_in_servicelist.value: + self.l.setElementFont(self.l.celServiceEventProgressbar, self.ServiceInfoFont) def postWidgetCreate(self, instance): instance.setWrapAround(True) @@ -430,55 +505,40 @@ def setMode(self, mode): self.mode = mode self.setItemsPerPage() two_lines_val = int(config.usage.servicelist_twolines.value) - show_two_lines = two_lines_val and mode == self.MODE_FAVOURITES - self.ItemHeight *= (2 if show_two_lines else 1) - self.l.setItemHeight(self.ItemHeight) - self.l.setVisualMode(eListboxServiceContent.visModeComplex) + self.l.setItemHeight(self.ItemHeight if not two_lines_val else self.ItemHeightTwoLine) + self.l.setVisualMode(eListboxServiceContent.visModeComplex if not two_lines_val else eListboxServiceContent.visSkinDefined) + + if two_lines_val: + timeText = _("%d min") + self.l.setTextTime(timeText) + + if two_lines_val > 1: + nextTitle = _("NEXT") + ": " + self.l.setNextTitle(nextTitle) + + self.l.setHasNextEvent(two_lines_val > 1) if config.usage.service_icon_enable.value: self.l.setGetPiconNameFunc(getPiconName) else: self.l.setGetPiconNameFunc(None) - rowWidth = self.instance.size().width() - 30 # scrollbar is fixed 20 + 10 Extra marge - - if mode == self.MODE_NORMAL or not config.usage.show_channel_numbers_in_servicelist.value: - channelNumberWidth = 0 - channelNumberSpace = 0 - else: - channelNumberWidth = config.usage.alternative_number_mode.value and getTextBoundarySize(self.instance, self.ServiceNumberFont, self.instance.size(), "0000").width() or getTextBoundarySize(self.instance, self.ServiceNumberFont, self.instance.size(), "00000").width() - channelNumberSpace = self.fieldMargins - - self.l.setElementPosition(self.l.celServiceNumber, eRect(0, 0, channelNumberWidth, self.ItemHeight)) - progressWidth = self.progressBarWidth if "perc" in config.usage.show_event_progress_in_servicelist.value: progressWidth = self.progressPercentWidth or self.progressBarWidth - if "left" in config.usage.show_event_progress_in_servicelist.value: - self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(channelNumberWidth + channelNumberSpace, 0, progressWidth, self.ItemHeight)) - self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins, 0, rowWidth - (channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins), self.ItemHeight)) - elif "right" in config.usage.show_event_progress_in_servicelist.value: - self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(rowWidth - progressWidth, 0, progressWidth, self.ItemHeight)) - self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace, 0, rowWidth - (channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins), self.ItemHeight)) - else: - self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, 0, 0)) - self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace, 0, rowWidth - (channelNumberWidth + channelNumberSpace), self.ItemHeight)) - self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) - self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) - self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) - if show_two_lines and two_lines_val == 2: - self.l.setElementFont(self.l.celServiceNextInfo, self.ServiceNextInfoFont) - nextTitle = _("NEXT") + ": " - self.l.setNextTitle(nextTitle) - if "perc" in config.usage.show_event_progress_in_servicelist.value: - self.l.setElementFont(self.l.celServiceEventProgressbar, self.ServiceInfoFont) - self.l.setShowTwoLines(two_lines_val) + self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, progressWidth, self.ItemHeight)) + + self.setFontsize() + self.l.setHideNumberMarker(config.usage.hide_number_markers.value) self.l.setServiceTypeIconMode(int(config.usage.servicetype_icon_mode.value)) self.l.setCryptoIconMode(int(config.usage.crypto_icon_mode.value)) self.l.setRecordIndicatorMode(int(config.usage.record_indicator_mode.value)) - self.l.setColumnWidth(-1 if show_two_lines else int(config.usage.servicelist_column.value)) + self.l.setColumnWidth(-1 if two_lines_val else int(config.usage.servicelist_column.value)) + self.l.setProgressBarMode(config.usage.show_event_progress_in_servicelist.value) + self.l.setChannelNumbersVisible(config.usage.show_channel_numbers_in_servicelist.value) + self.l.setAlternativeNumberingMode(config.usage.alternative_number_mode.value) def selectionEnabled(self, enabled): if self.instance is not None: diff --git a/lib/python/Components/ServicePosition.py b/lib/python/Components/ServicePosition.py index 15fb48c722c..d0eaf6cfdd6 100644 --- a/lib/python/Components/ServicePosition.py +++ b/lib/python/Components/ServicePosition.py @@ -21,7 +21,7 @@ def __init__(self, navcore, type): }) self.type = type self.relative_base = 0 -# self.setType(type) + # self.setType(type) def newService(self): self.setType(self.type) @@ -57,19 +57,19 @@ def update(self): if seek is not None: if self.type != self.TYPE_RELATIVE: if self.type == self.TYPE_LENGTH: - l = self.get(self.TYPE_LENGTH) + argument = self.get(self.TYPE_LENGTH) elif self.type == self.TYPE_POSITION: - l = self.get(self.TYPE_POSITION) + argument = self.get(self.TYPE_POSITION) elif self.type == self.TYPE_REMAINING: - l = self.get(self.TYPE_LENGTH) - self.get(self.TYPE_POSITION) + argument = self.get(self.TYPE_LENGTH) - self.get(self.TYPE_POSITION) - self.setText("%d:%02d" % (l // 60, l % 60)) + self.setText("%d:%02d" % (argument // 60, argument % 60)) else: - l = self.get(self.TYPE_POSITION) - if l != -1: - l += self.relative_base + argument = self.get(self.TYPE_POSITION) + if argument != -1: + argument += self.relative_base try: - t = time.localtime(l) + t = time.localtime(argument) timestr = "%2d:%02d:%02d" % (t.tm_hour, t.tm_min, t.tm_sec) except ValueError: timestr = "" diff --git a/lib/python/Components/Sources/HelpMenuList.py b/lib/python/Components/Sources/HelpMenuList.py index 0a61c7faa12..08e8cd5ad23 100644 --- a/lib/python/Components/Sources/HelpMenuList.py +++ b/lib/python/Components/Sources/HelpMenuList.py @@ -237,12 +237,12 @@ def _sortHeadingsAlpha(self, a): def ok(self): # a list entry has a "private" tuple as first entry... - l = self.getCurrent() - if l is None: + listEntry = self.getCurrent() + if listEntry is None: return # ...containing (Actionmap, Context, Action, keydata). # we returns this tuple to the callback. - self.callback(l[0], l[1], l[2]) + self.callback(listEntry[0], listEntry[1], listEntry[2]) def handleButton(self, keyId, flag): if keyId not in self.skipKeys: diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index 7306d93ef04..fbb76948d1d 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -1,6 +1,6 @@ from os import listdir +from hashlib import md5 from os.path import isfile, join as pathjoin -from boxbranding import getBoxType, getBrandOEM, getDisplayType, getHaveAVJACK, getHaveHDMIinFHD, getHaveHDMIinHD, getHaveRCA, getHaveSCART, getHaveSCARTYUV, getHaveYUV, getImageType, getMachineBrand, getMachineBuild, getMachineMtdRoot, getMachineName from enigma import Misc_Options, eDVBCIInterfaces, eDVBResourceManager from Components.About import getChipSetString @@ -17,26 +17,26 @@ def __init__(self, root=""): self.boxInfo = {} file = root + pathjoin(resolveFilename(SCOPE_LIBDIR), "enigma.info") self.boxInfo["overrideactive"] = False # not currently used by us + self.boxInfo["checksumerror"] = True lines = fileReadLines(file) if lines: for line in lines: - if line.startswith("#") or line.strip() == "" or line.strip().lower().startswith("checksum") or "=" not in line: + if line.startswith("#") or line.strip() == "" or "=" not in line: continue item, value = [x.strip() for x in line.split("=", 1)] - if item: - self.immutableList.append(item) - # Temporary fix: some items that look like floats are not floats and should be handled as strings, e.g. python "3.10" should not be processed as "3.1". - if not (value.startswith("\"") or value.startswith("'")) and item in ("python", "imageversion", "imgversion"): - value = '"' + value + '"' # wrap it so it is treated as a string - self.boxInfo[item] = self.processValue(value) - # print("[SystemInfo] Enigma information file data loaded into BoxInfo.") + if item.lower() == "checksum": + self.boxInfo["checksumerror"] = (i := lines.index(line)) < 1 or md5(bytearray("\n".join(lines[:i]) + "\n", "UTF-8", errors="ignore")).hexdigest() != value + elif item: + self.setItem(item, self.processValue(value), immutable=True) + if self.boxInfo["checksumerror"]: + print("[BoxInfo] Data integrity of %s could not be verified." % file) + # else: + # print("[SystemInfo] Enigma information file data loaded into BoxInfo.") else: print("[BoxInfo] ERROR: %s is not available! The system is unlikely to boot or operate correctly." % file) def processValue(self, value): - if value is None: - pass - elif (value.startswith("\"") or value.startswith("'")) and value.endswith(value[0]): + if len(value) > 1 and value[0] in ("\"", "'") and value[-1] == value[0]: value = value[1:-1] elif value.startswith("(") and value.endswith(")"): data = [] @@ -48,20 +48,20 @@ def processValue(self, value): for item in [x.strip() for x in value[1:-1].split(",")]: data.append(self.processValue(item)) value = list(data) - elif value.upper() == "NONE": - value = None elif value.upper() in ("FALSE", "NO", "OFF", "DISABLED"): value = False elif value.upper() in ("TRUE", "YES", "ON", "ENABLED"): value = True + elif value.upper() == "NONE": + value = None elif value.isdigit() or ((value[0:1] == "-" or value[0:1] == "+") and value[1:].isdigit()): if value[0] != "0": # if this is zero padded it must be a string, so skip value = int(value) - elif value.startswith("0x") or value.startswith("0X"): + elif value.lower().startswith("0x"): value = int(value, 16) - elif value.startswith("0o") or value.startswith("0O"): + elif value.lower().startswith("0o"): value = int(value, 8) - elif value.startswith("0b") or value.startswith("0B"): + elif value.lower().startswith("0b"): value = int(value, 2) else: try: @@ -81,12 +81,10 @@ def getItemsList(self): def getItem(self, item, default=None): if item in self.boxInfo: - value = self.boxInfo[item] + return self.boxInfo[item] elif item in SystemInfo: - value = SystemInfo[item] - else: - value = default - return value + return SystemInfo[item] + return default def setItem(self, item, value, immutable=False, forceOverride=False): if item in self.immutableList and not forceOverride: @@ -121,8 +119,42 @@ def deleteItem(self, item, forceOverride=False): MACHINEBUILD = BoxInfo.getItem("machinebuild") +def getBoxType(): # this function mimics the function of the same name in branding module + if MACHINEBUILD == "sf8008": + boxtype = open("/proc/stb/info/type").read().strip() + if boxtype == "10": + return "sf8008s" + elif boxtype == "11": + return "sf8008t" + elif MACHINEBUILD == "sfx6008": + boxtype = open("/proc/stb/info/type").read().strip() + if boxtype == "10": + return "sfx6018" + return MACHINEBUILD + + +BoxInfo.setItem("boxtype", getBoxType(), immutable=True) + + +def getMachineName(): # this function mimics the function of the same name in branding module + if MACHINEBUILD == "sf8008": + boxtype = open("/proc/stb/info/type").read().strip() + if boxtype == "10": + return "SF8008 4K Single" + elif boxtype == "11": + return "SF8008 4K Twin" + elif MACHINEBUILD == "sfx6008": + boxtype = open("/proc/stb/info/type").read().strip() + if boxtype == "10": + return "SFX6018" + return DISPLAYMODEL + + +BoxInfo.setItem("machinename", getMachineName(), immutable=True) + + def getBoxDisplayName(): # This function returns a tuple like ("BRANDNAME", "BOXNAME") - return (DISPLAYBRAND, DISPLAYMODEL) + return (DISPLAYBRAND, SystemInfo["machinename"]) def getRCFile(ext): @@ -150,7 +182,7 @@ def setRCFile(source): SystemInfo["HasKexecUSB"] = False # This needs to be here so it can be reset by getMultibootslots! SystemInfo["HasKexecMultiboot"] = fileHas("/proc/cmdline", "kexec=1") # This needs to be here so it can be tested by getMultibootslots! from Tools.Multiboot import getMultibootslots # noqa: E402 # This import needs to be here to avoid a SystemInfo load loop! -SystemInfo["HasHiSi"] = pathExists("/proc/hisi") and getBoxType() not in ("vipertwin", "viper4kv20", "viper4kv40", "sfx6008", "sfx6018") # This needs to be for later checks +SystemInfo["HasHiSi"] = pathExists("/proc/hisi") and SystemInfo["boxtype"] not in ("vipertwin", "viper4kv20", "viper4kv40", "sfx6008", "sfx6018") # This needs to be for later checks SystemInfo["canMultiBoot"] = getMultibootslots() # SystemInfo["MBbootdevice"] = device set in Tools/Multiboot.py # SystemInfo["MultiBootSlot"] = current slot set in Tools/Multiboot.py @@ -174,14 +206,14 @@ def hasInitCam(): return bool([f for f in listdir("/etc/init.d") if f.startswith("softcam.") and f != "softcam.None"]) -SystemInfo["CanKexecVu"] = getBoxType() in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse", "vuzero4k") and not SystemInfo["HasKexecMultiboot"] +SystemInfo["CanKexecVu"] = SystemInfo["boxtype"] in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse", "vuzero4k") and not SystemInfo["HasKexecMultiboot"] SystemInfo["HasUsbhdd"] = {} SystemInfo["ArchIsARM"] = ARCHITECTURE.startswith(("arm", "cortex")) SystemInfo["ArchIsARM64"] = "64" in ARCHITECTURE SystemInfo["HasInitCam"] = hasInitCam() -SystemInfo["MachineBrand"] = getMachineBrand() -SystemInfo["MachineName"] = getMachineName() -SystemInfo["DeveloperImage"] = getImageType().lower() != "release" +SystemInfo["MachineBrand"] = DISPLAYBRAND +SystemInfo["MachineName"] = SystemInfo["machinename"] +SystemInfo["DeveloperImage"] = SystemInfo["imagetype"].lower() != "release" SystemInfo["CommonInterface"] = eDVBCIInterfaces.getInstance().getNumOfSlots() SystemInfo["CommonInterfaceCIDelay"] = fileCheck("/proc/stb/tsmux/rmx_delay") for cislot in range(0, SystemInfo["CommonInterface"]): @@ -189,22 +221,22 @@ def hasInitCam(): SystemInfo["CI%dRelevantPidsRoutingSupport" % cislot] = fileCheck("/proc/stb/tsmux/ci%d_relevant_pids_routing" % cislot) SystemInfo["NumVideoDecoders"] = getNumVideoDecoders() SystemInfo["Udev"] = not fileExists("/dev/.devfsd") -SystemInfo["HasFullHDSkinSupport"] = getBoxType() not in ("vipertwin",) -SystemInfo["PIPAvailable"] = getMachineBuild() not in ("i55plus") and SystemInfo["NumVideoDecoders"] > 1 +SystemInfo["HasFullHDSkinSupport"] = SystemInfo["boxtype"] not in ("vipertwin",) +SystemInfo["PIPAvailable"] = MODEL not in ("i55plus") and SystemInfo["NumVideoDecoders"] > 1 SystemInfo["CanMeasureFrontendInputPower"] = eDVBResourceManager.getInstance().canMeasureFrontendInputPower() SystemInfo["12V_Output"] = Misc_Options.getInstance().detected_12V_output() SystemInfo["ZapMode"] = fileCheck("/proc/stb/video/zapmode") or fileCheck("/proc/stb/video/zapping_mode") SystemInfo["NumFrontpanelLEDs"] = countFrontpanelLEDs() SystemInfo["FrontpanelDisplay"] = fileExists("/dev/dbox/oled0") or fileExists("/dev/dbox/lcd0") -SystemInfo["7segment"] = getDisplayType() in ("7segment") -SystemInfo["ConfigDisplay"] = SystemInfo["FrontpanelDisplay"] and getDisplayType() not in ("7segment") +SystemInfo["7segment"] = SystemInfo["displaytype"] in ("7segment") +SystemInfo["ConfigDisplay"] = SystemInfo["FrontpanelDisplay"] and SystemInfo["displaytype"] not in ("7segment") SystemInfo["LCDSKINSetup"] = pathExists("/usr/share/enigma2/display") and not SystemInfo["7segment"] SystemInfo["OledDisplay"] = fileExists("/dev/dbox/oled0") SystemInfo["LcdDisplay"] = fileExists("/dev/dbox/lcd0") -SystemInfo["LCDsymbol_hdd"] = getBoxType() in ("mutant51",) and fileCheck("/proc/stb/lcd/symbol_hdd") -SystemInfo["HasNoDisplay"] = getBoxType() in ("et4x00", "et5x00", "et6x00", "gb800se", "gb800solo", "gbx34k", "iqonios300hd", "mbmicro", "sf128", "sf138", "tmsingle", "tmnano2super", "tmnanose", "tmnanoseplus", "tmnanosem2", "tmnanosem2plus", "tmnanosecombo", "vusolo") -SystemInfo["DisplayLED"] = getBoxType() in ("gb800se", "gb800solo", "gbx1", "gbx2", "gbx3", "gbx3h") -SystemInfo["LEDButtons"] = False # getBoxType() == "vuultimo", For some reason this causes a cpp crash on vuultimo (which we no longer build). The cause needs investigating or the dead code in surrounding modules that this change causes should be removed. +SystemInfo["LCDsymbol_hdd"] = SystemInfo["boxtype"] in ("mutant51",) and fileCheck("/proc/stb/lcd/symbol_hdd") +SystemInfo["HasNoDisplay"] = SystemInfo["boxtype"] in ("et4x00", "et5x00", "et6x00", "gb800se", "gb800solo", "gbx34k", "iqonios300hd", "mbmicro", "sf128", "sf138", "tmsingle", "tmnano2super", "tmnanose", "tmnanoseplus", "tmnanosem2", "tmnanosem2plus", "tmnanosecombo", "vusolo") +SystemInfo["DisplayLED"] = SystemInfo["boxtype"] in ("gb800se", "gb800solo", "gbx1", "gbx2", "gbx3", "gbx3h") +SystemInfo["LEDButtons"] = False # SystemInfo["boxtype"] == "vuultimo", For some reason this causes a cpp crash on vuultimo (which we no longer build). The cause needs investigating or the dead code in surrounding modules that this change causes should be removed. SystemInfo["DeepstandbySupport"] = HardwareInfo().has_deepstandby() SystemInfo["Fan"] = fileCheck("/proc/stb/fp/fan") SystemInfo["FanPWM"] = SystemInfo["Fan"] and fileCheck("/proc/stb/fp/fan_pwm") @@ -218,35 +250,35 @@ def hasInitCam(): SystemInfo["Power24x7On"] = fileExists("/proc/stb/fp/power4x7on") SystemInfo["Power24x7Standby"] = fileExists("/proc/stb/fp/power4x7standby") SystemInfo["Power24x7Suspend"] = fileExists("/proc/stb/fp/power4x7suspend") -SystemInfo["WakeOnLAN"] = getBoxType() not in ("et8000", "et10000") and fileCheck("/proc/stb/power/wol") or fileCheck("/proc/stb/fp/wol") +SystemInfo["WakeOnLAN"] = SystemInfo["boxtype"] not in ("et8000", "et10000") and fileCheck("/proc/stb/power/wol") or fileCheck("/proc/stb/fp/wol") SystemInfo["hasHdmiCec"] = fileExists("/dev/hdmi_cec") or fileExists("/dev/misc/hdmi_cec0") -SystemInfo["HasExternalPIP"] = getMachineBuild() not in ("et9x00", "et6x00", "et5x00") and fileCheck("/proc/stb/vmpeg/1/external") +SystemInfo["HasExternalPIP"] = MODEL not in ("et9x00", "et6x00", "et5x00") and fileCheck("/proc/stb/vmpeg/1/external") SystemInfo["VideoDestinationConfigurable"] = fileExists("/proc/stb/vmpeg/0/dst_left") SystemInfo["hasPIPVisibleProc"] = fileCheck("/proc/stb/vmpeg/1/visible") -SystemInfo["VFD_scroll_repeats"] = not SystemInfo["7segment"] and getBoxType() not in ("et8500",) and fileCheck("/proc/stb/lcd/scroll_repeats") -SystemInfo["VFD_scroll_delay"] = not SystemInfo["7segment"] and getBoxType() not in ("et8500",) and fileCheck("/proc/stb/lcd/scroll_delay") -SystemInfo["VFD_initial_scroll_delay"] = not SystemInfo["7segment"] and getBoxType() not in ("et8500",) and fileCheck("/proc/stb/lcd/initial_scroll_delay") -SystemInfo["VFD_final_scroll_delay"] = not SystemInfo["7segment"] and getBoxType() not in ("et8500",) and fileCheck("/proc/stb/lcd/final_scroll_delay") +SystemInfo["VFD_scroll_repeats"] = not SystemInfo["7segment"] and SystemInfo["boxtype"] not in ("et8500",) and fileCheck("/proc/stb/lcd/scroll_repeats") +SystemInfo["VFD_scroll_delay"] = not SystemInfo["7segment"] and SystemInfo["boxtype"] not in ("et8500",) and fileCheck("/proc/stb/lcd/scroll_delay") +SystemInfo["VFD_initial_scroll_delay"] = not SystemInfo["7segment"] and SystemInfo["boxtype"] not in ("et8500",) and fileCheck("/proc/stb/lcd/initial_scroll_delay") +SystemInfo["VFD_final_scroll_delay"] = not SystemInfo["7segment"] and SystemInfo["boxtype"] not in ("et8500",) and fileCheck("/proc/stb/lcd/final_scroll_delay") SystemInfo["LcdLiveTV"] = fileCheck("/proc/stb/fb/sd_detach") or fileCheck("/proc/stb/lcd/live_enable") SystemInfo["LCDMiniTV"] = fileExists("/proc/stb/lcd/mode") -SystemInfo["LCDMiniTVPiP"] = SystemInfo["LCDMiniTV"] and getBoxType() != "gb800ueplus" +SystemInfo["LCDMiniTVPiP"] = SystemInfo["LCDMiniTV"] and SystemInfo["boxtype"] != "gb800ueplus" SystemInfo["LcdPowerOn"] = fileExists("/proc/stb/power/vfd") SystemInfo["FastChannelChange"] = False SystemInfo["3DMode"] = fileCheck("/proc/stb/fb/3dmode") or fileCheck("/proc/stb/fb/primary/3d") SystemInfo["3DZNorm"] = fileCheck("/proc/stb/fb/znorm") or fileCheck("/proc/stb/fb/primary/zoffset") -SystemInfo["Blindscan_t2_available"] = fileCheck("/proc/stb/info/vumodel") and getBoxType().startswith("vu") +SystemInfo["Blindscan_t2_available"] = fileCheck("/proc/stb/info/vumodel") and SystemInfo["boxtype"].startswith("vu") SystemInfo["HasTranscoding"] = pathExists("/proc/stb/encoder/0") or fileCheck("/dev/bcm_enc0") SystemInfo["HasH265Encoder"] = fileHas("/proc/stb/encoder/0/vcodec_choices", "h265") -SystemInfo["CanNotDoSimultaneousTranscodeAndPIP"] = getBoxType() in ("vusolo4k", "gbquad4k", "gbue4k") -SystemInfo["hasXcoreVFD"] = getBoxType() in ("osmega", "spycat4k", "spycat4kmini", "spycat4kcomb") and fileCheck("/sys/module/brcmstb_%s/parameters/pt6302_cgram" % getBoxType()) -SystemInfo["HasHDMIin"] = getHaveHDMIinHD() in ("True",) or getHaveHDMIinFHD() in ("True",) +SystemInfo["CanNotDoSimultaneousTranscodeAndPIP"] = SystemInfo["boxtype"] in ("vusolo4k", "gbquad4k", "gbue4k") +SystemInfo["hasXcoreVFD"] = SystemInfo["boxtype"] in ("osmega", "spycat4k", "spycat4kmini", "spycat4kcomb") and fileCheck("/sys/module/brcmstb_%s/parameters/pt6302_cgram" % SystemInfo["boxtype"]) +SystemInfo["HasHDMIin"] = SystemInfo["hdmifhdin"] or SystemInfo["hdmihdin"] SystemInfo["Has24hz"] = fileCheck("/proc/stb/video/videomode_24hz") -SystemInfo["canBackupEMC"] = getMachineBuild() in ("hd51", "h7") and ("disk.img", "%s" % SystemInfo["MBbootdevice"]) or getMachineBuild() in ("osmio4k", "osmio4kplus", "osmini4k") and ("emmc.img", "%s" % SystemInfo["MBbootdevice"]) or SystemInfo["HasHiSi"] and ("usb_update.bin", "none") -SystemInfo["canMode12"] = getMachineBuild() in ("hd51", "h7") and ("brcm_cma=440M@328M brcm_cma=192M@768M", "brcm_cma=520M@248M brcm_cma=200M@768M") -SystemInfo["HasMMC"] = fileHas("/proc/cmdline", "root=/dev/mmcblk") or "mmcblk" in getMachineMtdRoot() -SystemInfo["HasH9SD"] = getMachineBuild() in ("h9", "i55plus") and pathExists("/dev/mmcblk0p1") -SystemInfo["HasSDnomount"] = getMachineBuild() in ("h9", "i55plus") and (False, "none") or getMachineBuild() in ("multibox", "h9combo", "h9combose", "h9twin", "h9se", "pulse4kmini", "hd61", "pulse4k", "h11") and (True, "mmcblk0") -SystemInfo["CanProc"] = SystemInfo["HasMMC"] and getBrandOEM() != "vuplus" +SystemInfo["canBackupEMC"] = MODEL in ("hd51", "h7") and ("disk.img", "%s" % SystemInfo["MBbootdevice"]) or MODEL in ("osmio4k", "osmio4kplus", "osmini4k") and ("emmc.img", "%s" % SystemInfo["MBbootdevice"]) or SystemInfo["HasHiSi"] and ("usb_update.bin", "none") +SystemInfo["canMode12"] = MODEL in ("hd51", "h7") and ("brcm_cma=440M@328M brcm_cma=192M@768M", "brcm_cma=520M@248M brcm_cma=200M@768M") +SystemInfo["HasMMC"] = fileHas("/proc/cmdline", "root=/dev/mmcblk") or "mmcblk" in SystemInfo["mtdrootfs"] +SystemInfo["HasH9SD"] = MODEL in ("h9", "i55plus") and pathExists("/dev/mmcblk0p1") +SystemInfo["HasSDnomount"] = MODEL in ("h9", "i55plus") and (False, "none") or MODEL in ("multibox", "h9combo", "h9combose", "h9twin", "h9se", "pulse4kmini", "hd61", "pulse4k", "h11") and (True, "mmcblk0") +SystemInfo["CanProc"] = SystemInfo["HasMMC"] and SystemInfo["brand"] != "vuplus" SystemInfo["Canaudiosource"] = fileCheck("/proc/stb/hdmi/audio_source") SystemInfo["Can3DSurround"] = fileHas("/proc/stb/audio/3d_surround_choices", "none") and fileCheck("/proc/stb/audio/3d_surround") SystemInfo["Can3DSpeaker"] = fileHas("/proc/stb/audio/3d_surround_speaker_position_choices", "center") and fileCheck("/proc/stb/audio/3d_surround_speaker_position") @@ -273,11 +305,11 @@ def hasInitCam(): SystemInfo["Canedidchecking"] = fileCheck("/proc/stb/hdmi/bypass_edid_checking") SystemInfo["haveboxmode"] = fileCheck("/proc/stb/info/boxmode") SystemInfo["HasScaler_sharpness"] = pathExists("/proc/stb/vmpeg/0/pep_scaler_sharpness") -SystemInfo["hasJack"] = getHaveAVJACK() in ('True',) -SystemInfo["hasRCA"] = getHaveRCA() in ('True',) -SystemInfo["hasScart"] = getHaveSCART() in ('True',) -SystemInfo["hasScartYUV"] = getHaveSCARTYUV() in ('True',) -SystemInfo["hasYUV"] = getHaveYUV() in ('True',) +SystemInfo["hasJack"] = SystemInfo["avjack"] +SystemInfo["hasRCA"] = SystemInfo["rca"] +SystemInfo["hasScart"] = SystemInfo["scart"] +SystemInfo["hasScartYUV"] = SystemInfo["scartyuv"] +SystemInfo["hasYUV"] = SystemInfo["yuv"] SystemInfo["VideoModes"] = getChipSetString() in ( # 2160p and 1080p capable hardware... "5272s", "7251", "7251s", "7252", "7252s", "7278", "7366", "7376", "7444s", "72604", "3798mv200", "3798cv200", "3798mv200h", "3798mv300", "hi3798mv200", "hi3798mv200h", "hi3798mv200advca", "hi3798cv200", "hi3798mv300" ) and ( @@ -293,7 +325,7 @@ def hasInitCam(): {"720p", "1080i"} # Widescreen modes. ) -SystemInfo["FbcTunerPowerAlwaysOn"] = getBoxType() in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse") +SystemInfo["FbcTunerPowerAlwaysOn"] = SystemInfo["boxtype"] in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse") SystemInfo["HasPhysicalLoopthrough"] = ["Vuplus DVB-S NIM(AVL2108)", "GIGA DVB-S2 NIM (Internal)"] SystemInfo["HasFBCtuner"] = ["Vuplus DVB-C NIM(BCM3158)", "Vuplus DVB-C NIM(BCM3148)", "Vuplus DVB-S NIM(7376 FBC)", "Vuplus DVB-S NIM(45308X FBC)", "Vuplus DVB-S NIM(45208 FBC)", "DVB-S2 NIM(45208 FBC)", "DVB-S2X NIM(45308X FBC)", "DVB-S2 NIM(45308 FBC)", "DVB-C NIM(3128 FBC)", "BCM45208", "BCM45308X", "BCM3158"] SystemInfo["FCCactive"] = False diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index a82f0571b47..b8f3c6733f9 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -1,6 +1,6 @@ # A Job consists of many "Tasks". # A task is the run of an external tool, with proper methods for failure handling -from os import access, environ, path as ospath, pathsep, statvfs, F_OK, X_OK, W_OK +from os import access, environ, path as ospath, pathsep, statvfs, X_OK, W_OK from Tools.CList import CList @@ -432,38 +432,38 @@ def getPendingJobs(self): return list # some examples: -#class PartitionExistsPostcondition: -# def __init__(self, device): -# self.device = device +# class PartitionExistsPostcondition: +# def __init__(self, device): +# self.device = device # -# def check(self, task): -# return access(self.device + "part1", F_OK) +# def check(self, task): +# return access(self.device + "part1", F_OK) # -#class CreatePartitionTask(Task): -# def __init__(self, device): -# Task.__init__(self, "Creating partition") -# self.device = device -# self.setTool("/sbin/sfdisk") -# self.args += ["-f", self.device + "disc"] -# self.initial_input = "0,\n;\n;\n;\ny\n" -# self.postconditions.append(PartitionExistsPostcondition(self.device)) +# class CreatePartitionTask(Task): +# def __init__(self, device): +# Task.__init__(self, "Creating partition") +# self.device = device +# self.setTool("/sbin/sfdisk") +# self.args += ["-f", self.device + "disc"] +# self.initial_input = "0,\n;\n;\n;\ny\n" +# self.postconditions.append(PartitionExistsPostcondition(self.device)) # -#class CreateFilesystemTask(Task): -# def __init__(self, device, partition = 1, largefile = True): -# Task.__init__(self, "Creating filesystem") -# self.setTool("/sbin/mkfs.ext") -# if largefile: -# self.args += ["-T", "largefile"] -# self.args.append("-m0") -# self.args.append(device + "part%d" % partition) +# class CreateFilesystemTask(Task): +# def __init__(self, device, partition = 1, largefile = True): +# Task.__init__(self, "Creating filesystem") +# self.setTool("/sbin/mkfs.ext") +# if largefile: +# self.args += ["-T", "largefile"] +# self.args.append("-m0") +# self.args.append(device + "part%d" % partition) # -#class FilesystemMountTask(Task): -# def __init__(self, device, partition = 1, filesystem = "ext3"): -# Task.__init__(self, "Mounting filesystem") -# self.setTool("/bin/mount") -# if filesystem is not None: -# self.args += ["-t", filesystem] -# self.args.append(device + "part%d" % partition) +# class FilesystemMountTask(Task): +# def __init__(self, device, partition = 1, filesystem = "ext3"): +# Task.__init__(self, "Mounting filesystem") +# self.setTool("/bin/mount") +# if filesystem is not None: +# self.args += ["-t", filesystem] +# self.args.append(device + "part%d" % partition) class Condition: @@ -567,20 +567,20 @@ def getErrorMessage(self, task): def check(self, task): return (self.exception is None) or (self.exception == 0) -#class HDDInitJob(Job): -# def __init__(self, device): -# Job.__init__(self, _("Initialize Harddisk")) -# self.device = device -# self.fromDescription(self.createDescription()) +# class HDDInitJob(Job): +# def __init__(self, device): +# Job.__init__(self, _("Initialize Harddisk")) +# self.device = device +# self.fromDescription(self.createDescription()) # -# def fromDescription(self, description): -# self.device = description["device"] -# self.addTask(CreatePartitionTask(self.device)) -# self.addTask(CreateFilesystemTask(self.device)) -# self.addTask(FilesystemMountTask(self.device)) +# def fromDescription(self, description): +# self.device = description["device"] +# self.addTask(CreatePartitionTask(self.device)) +# self.addTask(CreateFilesystemTask(self.device)) +# self.addTask(FilesystemMountTask(self.device)) # -# def createDescription(self): -# return {"device": self.device} +# def createDescription(self): +# return {"device": self.device} job_manager = JobManager() diff --git a/lib/python/Components/TimerList.py b/lib/python/Components/TimerList.py index e967a95df07..fd9fe9303a9 100644 --- a/lib/python/Components/TimerList.py +++ b/lib/python/Components/TimerList.py @@ -8,7 +8,7 @@ from Components.Renderer.Picon import getPiconName from skin import parseFont, parseScale from Tools.Alternatives import GetWithAlternative -from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN +from Tools.Directories import resolveFilename, SCOPE_GUISKIN from Tools.FuzzyDate import FuzzyTime from Tools.LoadPixmap import LoadPixmap from Tools.TextBoundary import getTextBoundarySize @@ -49,12 +49,12 @@ def addPicon(): backcolor=None, backcolor_sel=None, flags=BT_SCALE | BT_KEEP_ASPECT_RATIO | BT_ALIGN_CENTER)) return piconWidth - colX = 0 + colX = self.sidesMargin if config.usage.timerlist_showpicons.value: colX += addPicon() - res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.iconWidth + self.iconMargin, 0, nameWidth, self.rowSplit, 2, RT_HALIGN_LEFT | RT_VALIGN_BOTTOM, timer.name)) - res.append((eListboxPythonMultiContent.TYPE_TEXT, width - serviceNameWidth, 0, serviceNameWidth, self.rowSplit, 0, RT_HALIGN_RIGHT | RT_VALIGN_BOTTOM, serviceName)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.iconWidth + self.iconMargin, 0, nameWidth, self.rowSplit, 2, RT_HALIGN_LEFT | RT_VALIGN_BOTTOM, timer.name)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, width - serviceNameWidth - self.sidesMargin, 0, serviceNameWidth, self.rowSplit, 0, RT_HALIGN_RIGHT | RT_VALIGN_BOTTOM, serviceName)) begin = FuzzyTime(timer.begin) if timer.repeated: @@ -74,7 +74,7 @@ def addPicon(): else: repeatedtext = ", ".join(repeatedtext) if self.iconRepeat: - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, colX + self.iconMargin, self.rowSplit + (self.itemHeight - self.rowSplit - self.iconHeight) // 2, self.iconWidth, self.iconHeight, self.iconRepeat)) + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, colX + self.sidesMargin + self.iconMargin // 2, self.rowSplit + (self.itemHeight - self.rowSplit - self.iconHeight) // 2, self.iconWidth, self.iconHeight, self.iconRepeat)) else: repeatedtext = begin[0] # date if timer.justplay: @@ -120,23 +120,23 @@ def addPicon(): state = _("done!") icon = self.iconDone - icon and res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, colX + self.iconMargin // 2, (self.rowSplit - self.iconHeight) // 2, self.iconWidth, self.iconHeight, icon)) + icon and res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, colX + self.sidesMargin + self.iconMargin // 2, (self.rowSplit - self.iconHeight) // 2, self.iconWidth, self.iconHeight, icon)) orbpos = self.getOrbitalPos(timer.service_ref) orbposWidth = getTextBoundarySize(self.instance, self.font, self.l.getItemSize(), orbpos).width() - res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.satPosLeft, self.rowSplit, orbposWidth, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, orbpos)) - res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.iconWidth + self.iconMargin, self.rowSplit, self.satPosLeft - self.iconWidth - self.iconMargin, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, state)) - res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.satPosLeft + orbposWidth, self.rowSplit, width - self.satPosLeft - orbposWidth - colX, self.itemHeight - self.rowSplit, 1, RT_HALIGN_RIGHT | RT_VALIGN_TOP, text)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.satPosLeft, self.rowSplit, orbposWidth, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, orbpos)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.iconWidth + self.iconMargin, self.rowSplit, self.satPosLeft - self.iconWidth - self.iconMargin, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, state)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.satPosLeft + orbposWidth, self.rowSplit, width - self.satPosLeft - orbposWidth - colX - self.sidesMargin * 2, self.itemHeight - self.rowSplit, 1, RT_HALIGN_RIGHT | RT_VALIGN_TOP, text)) - line = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, 0, height - 2, width, 2, line)) + if self.sepLinePixmap: + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, 0, height - 2, width, 2, self.sepLinePixmap)) return res def __init__(self, list): GUIComponent.__init__(self) self.onSelectionChanged = [] - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.l.setBuildFunc(self.buildTimerEntry) self.serviceNameFont = gFont("Regular", 20) self.font = gFont("Regular", 18) @@ -145,21 +145,23 @@ def __init__(self, list): self.l.setList(list) self.listCount = len(list) # used by pager self.itemHeight = 50 + self.sidesMargin = 0 self.rowSplit = 25 self.iconMargin = 4 self.satPosLeft = 160 - self.iconWait = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_wait.png")) - #currently intended that all icons have the same size + self.sepLinePixmap = None + self.iconWait = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_wait.png")) + # currently intended that all icons have the same size self.iconWidth = self.iconWait.size().width() self.iconHeight = self.iconWait.size().height() - self.iconRecording = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_rec.png")) - self.iconPrepared = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_prep.png")) - self.iconDone = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_done.png")) - self.iconRepeat = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_rep.png")) - self.iconZapped = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_zap.png")) - self.iconDisabled = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_off.png")) - self.iconFailed = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_failed.png")) - self.iconAutoTimer = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_autotimer.png")) + self.iconRecording = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_rec.png")) + self.iconPrepared = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_prep.png")) + self.iconDone = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_done.png")) + self.iconRepeat = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_rep.png")) + self.iconZapped = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_zap.png")) + self.iconDisabled = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_off.png")) + self.iconFailed = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_failed.png")) + self.iconAutoTimer = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_autotimer.png")) try: from Plugins.SystemPlugins.IceTV import loadIceTVIcon self.iconIceTVTimer = loadIceTVIcon("timer_icetv.png") @@ -188,6 +190,12 @@ def iconMargin(value): def satPosLeft(value): self.satPosLeft = parseScale(value) + def sidesMargin(value): + self.sidesMargin = parseScale(value) + + def sepLinePixmap(value): + self.sepLinePixmap = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) + for (attrib, value) in self.skinAttributes[:]: try: locals().get(attrib)(value) diff --git a/lib/python/Components/TimerSanityCheck.py b/lib/python/Components/TimerSanityCheck.py index 47be68cb35c..3e04c948055 100644 --- a/lib/python/Components/TimerSanityCheck.py +++ b/lib/python/Components/TimerSanityCheck.py @@ -73,7 +73,7 @@ def checkTimerlist(self, ext_timer=None): if ext_timer and isinstance(ext_timer, RecordTimer.RecordTimerEntry): self.newtimer = ext_timer - #GML:1 - A timer which has already ended (happens during start-up check) can't clash!! + # GML:1 - A timer which has already ended (happens during start-up check) can't clash!! # # NOTE: that when adding a timer it also cannot clash with: # o any timers which run before the latest period of no timers running @@ -223,9 +223,9 @@ def checkTimerlist(self, ext_timer=None): else: fakeRecResult = -1 # TODO - #if fakeRecResult == -6 and len(NavigationInstance.instance.getRecordings(True)) < 2: - # print "[TimerSanityCheck] less than two timers in the simulated recording list - timer conflict is not plausible - ignored !" - # fakeRecResult = 0 + # if fakeRecResult == -6 and len(NavigationInstance.instance.getRecordings(True)) < 2: + # print "[TimerSanityCheck] less than two timers in the simulated recording list - timer conflict is not plausible - ignored !" + # fakeRecResult = 0 if not fakeRecResult: # tune okay if hasattr(fakeRecService, 'frontendInfo'): feinfo = fakeRecService.frontendInfo() diff --git a/lib/python/Components/Timeshift.py b/lib/python/Components/Timeshift.py index e60c3791b18..02ab05d5cbc 100644 --- a/lib/python/Components/Timeshift.py +++ b/lib/python/Components/Timeshift.py @@ -48,7 +48,6 @@ from Tools.TimeShift import CopyTimeshiftJob, MergeTimeshiftJob, CreateAPSCFilesJob from enigma import eBackgroundFileEraser, eTimer, eServiceCenter, iServiceInformation, iPlayableService, eEPGCache, eServiceReference -from boxbranding import getBoxType, getBrandOEM from time import time, localtime, strftime from random import randint @@ -408,7 +407,7 @@ def stopTimeshiftcheckTimeshiftRunningCallback(self, answer): ts = self.getTimeshift() if ts and ts.isTimeshiftEnabled(): # print("[Timeshift]TEST5") - was_enabled = ts.isTimeshiftEnabled() # "was_enabled" assigned but not used? This code is nonsense. + was_enabled = ts.isTimeshiftEnabled() # noqa: F841 "was_enabled" assigned but not used? This code is nonsense. if answer and ts: # print("[Timeshift]TEST6") if int(config.timeshift.startdelay.value): @@ -435,13 +434,13 @@ def activateTimeshiftEnd(self, back=True): if seekable is not None: seekable.seekTo(-90000) # seek approx. 1 sec before end if back: - if getBrandOEM() == "xtrend": + if SystemInfo["brand"] == "xtrend": self.ts_rewind_timer.start(1000, 1) else: self.ts_rewind_timer.start(100, 1) def rewindService(self): - if getBrandOEM() in ("gigablue", "xp"): + if SystemInfo["brand"] in ("gigablue", "xp"): self.setSeekState(self.SEEK_STATE_PLAY) self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value))) @@ -465,19 +464,19 @@ def checkTimeshiftRunning(self, returnFunction): # print("[Timeshift]TEST3") message = _("You have chosen to save the current timeshift event, but the event has not yet finished\nWhat do you want to do ?") choice = [ - (_("Save timeshift as movie and stop recording"), "savetimeshift"), - (_("Save timeshift as movie and continue recording"), "savetimeshiftandrecord"), - (_("Cancel save timeshift as movie"), "noSave"), - (_("Nothing, just leave this menu"), "no")] + (_("Save timeshift as movie and stop recording"), "savetimeshift"), + (_("Save timeshift as movie and continue recording"), "savetimeshiftandrecord"), + (_("Cancel save timeshift as movie"), "noSave"), + (_("Nothing, just leave this menu"), "no")] self.session.openWithCallback(boundFunction(self.checkTimeshiftRunningCallback, returnFunction), MessageBox, message, simple=True, list=choice) else: # print("[Timeshift]TEST4") message = _("You seem to be in timeshift, Do you want to leave timeshift? Streams & IPTV not fully supported!") choice = [ - (_("Yes, but save timeshift as movie and stop recording"), "savetimeshift"), - (_("Yes, but save timeshift as movie and continue recording"), "savetimeshiftandrecord"), - (_("Yes, but don't save timeshift as movie"), "noSave"), - (_("No"), "no")] + (_("Yes, but save timeshift as movie and stop recording"), "savetimeshift"), + (_("Yes, but save timeshift as movie and continue recording"), "savetimeshiftandrecord"), + (_("Yes, but don't save timeshift as movie"), "noSave"), + (_("No"), "no")] self.session.openWithCallback(boundFunction(self.checkTimeshiftRunningCallback, returnFunction), MessageBox, message, simple=True, list=choice) else: # print("[Timeshift]TEST5") @@ -505,7 +504,7 @@ def checkTimeshiftRunningCallback(self, returnFunction, answer): def eraseTimeshiftFile(self): for filename in os.listdir(config.usage.timeshift_path.value): - if filename.startswith("timeshift.") and not filename.endswith(".del") and not filename.endswith(".copy"): + if filename.startswith("timeshift.") and not filename.endswith((".del", ".copy")): self.BgFileEraser.erase("%s%s" % (config.usage.timeshift_path.value, filename)) def autostartPermanentTimeshift(self): @@ -545,7 +544,7 @@ def activatePermanentTimeshift(self): self.stopTimeshiftcheckTimeshiftRunningCallback(True) ts = self.getTimeshift() if ts and not ts.startTimeshift(): - if (getBoxType() == "vuuno" or getBoxType() == "vuduo") and os.path.exists("/proc/stb/lcd/symbol_timeshift"): + if (SystemInfo["boxtype"] == "vuuno" or SystemInfo["boxtype"] == "vuduo") and os.path.exists("/proc/stb/lcd/symbol_timeshift"): if self.session.nav.RecordTimer.isRecording(): f = open("/proc/stb/lcd/symbol_timeshift", "w") f.write("0") @@ -593,9 +592,9 @@ def saveTimeshiftEventPopup(self): if statinfo.st_mtime < (time() - 5.0): # Get Event Info from meta file readmetafile = open("%s%s.meta" % (config.usage.timeshift_path.value, filename), "r") - servicerefname = readmetafile.readline()[0:-1] # local variable 'servicerefname' is assigned to but never used + servicerefname = readmetafile.readline()[0:-1] # noqa: F841 local variable 'servicerefname' is assigned to but never used eventname = readmetafile.readline()[0:-1] - description = readmetafile.readline()[0:-1] # local variable 'description' is assigned to but never used + description = readmetafile.readline()[0:-1] # noqa: F841 local variable 'description' is assigned to but never used begintime = readmetafile.readline()[0:-1] readmetafile.close() @@ -777,7 +776,7 @@ def SaveTimeshift(self, timeshiftfile=None, mergelater=False): # Get Event Info from meta file if os.path.exists("%s.ts.meta" % fullname): readmetafile = open("%s.ts.meta" % fullname, "r") - servicerefname = readmetafile.readline()[0:-1] # local variable 'servicerefname' is assigned to but never used + servicerefname = readmetafile.readline()[0:-1] # noqa: F841 local variable 'servicerefname' is assigned to but never used eventname = readmetafile.readline()[0:-1] readmetafile.close() else: @@ -809,20 +808,20 @@ def ptsCleanTimeshiftFolder(self): return for filename in os.listdir(config.usage.timeshift_path.value): - if (filename.startswith("timeshift.") or filename.startswith("pts_livebuffer_")) and (filename.endswith(".del") is False and filename.endswith(".copy") is False): + if filename.startswith(("timeshift.", "pts_livebuffer_")) and not filename.endswith((".del", ".copy")): # print("[Timeshift]filename:", filename) statinfo = os.stat("%s%s" % (config.usage.timeshift_path.value, filename)) # if no write for 3 sec = stranded timeshift if statinfo.st_mtime < (time() - 3.0): - # try: - # print("[Timeshift][TimeShift] Erasing stranded timeshift %s" % filename) + # try: + # print("[Timeshift][TimeShift] Erasing stranded timeshift %s" % filename) self.BgFileEraser.erase("%s%s" % (config.usage.timeshift_path.value, filename)) - # Delete Meta and EIT File too - # if filename.startswith("pts_livebuffer_") is True: - # self.BgFileEraser.erase("%s%s.meta" % (config.usage.timeshift_path.value, filename)) - # self.BgFileEraser.erase("%s%s.eit" % (config.usage.timeshift_path.value, filename)) - # except: - # print("[Timeshift][TimeShift] IO-Error while cleaning Timeshift Folder ...") + # Delete Meta and EIT File too + # if filename.startswith("pts_livebuffer_") is True: + # self.BgFileEraser.erase("%s%s.meta" % (config.usage.timeshift_path.value, filename)) + # self.BgFileEraser.erase("%s%s.eit" % (config.usage.timeshift_path.value, filename)) + # except: + # print("[Timeshift][TimeShift] IO-Error while cleaning Timeshift Folder ...") def ptsGetEventInfo(self): event = None @@ -883,7 +882,7 @@ def ptsCreateHardlink(self): # print("[Timeshift]ptsCreateHardlink") for filename in os.listdir(config.usage.timeshift_path.value): # if filename.startswith("timeshift") and not os.path.splitext(filename)[1]: - if filename.startswith("timeshift.") and not filename.endswith(".sc") and not filename.endswith(".del") and not filename.endswith(".copy") and not filename.endswith(".ap"): + if filename.startswith("timeshift.") and not filename.endswith((".sc", ".del", ".copy", ".ap")): if os.path.exists("%spts_livebuffer_%s.eit" % (config.usage.timeshift_path.value, self.pts_eventcount)): self.BgFileEraser.erase("%spts_livebuffer_%s.eit" % (config.usage.timeshift_path.value, self.pts_eventcount)) if os.path.exists("%spts_livebuffer_%s.meta" % (config.usage.timeshift_path.value, self.pts_eventcount)): @@ -1001,7 +1000,7 @@ def ptsCreateAPSCFiles(self, filename): if fileExists(filename + ".meta", "r"): # Get Event Info from meta file readmetafile = open(filename + ".meta", "r") - servicerefname = readmetafile.readline()[0:-1] # local variable 'servicerefname' is assigned to but never used + servicerefname = readmetafile.readline()[0:-1] # noqa: F841 local variable 'servicerefname' is assigned to but never used eventname = readmetafile.readline()[0:-1] readmetafile.close() else: @@ -1299,7 +1298,7 @@ def ptsTimerEntryStateChange(self, timer): self.ptsFrontpanelActions("start") # This will already be set if it needs to be set and otherwise it must # *not* be set. - # config.timeshift.isRecording.value = True + # config.timeshift.isRecording.value = True def ptsLiveTVStatus(self): service = self.session.nav.getCurrentService() diff --git a/lib/python/Components/Timezones.py b/lib/python/Components/Timezones.py index 16a9aad4a8b..53022792334 100644 --- a/lib/python/Components/Timezones.py +++ b/lib/python/Components/Timezones.py @@ -121,7 +121,7 @@ def loadTimezones(self): } for (root, dirs, files) in walk(TIMEZONE_DATA): base = root[len(TIMEZONE_DATA):] - if base.startswith("posix") or base.startswith("right"): # Skip these alternate copies of the time zone data if they exist. + if base.startswith(("posix", "right")): # Skip these alternate copies of the time zone data if they exist. continue if base == "": base = "Generic" diff --git a/lib/python/Components/TuneTest.py b/lib/python/Components/TuneTest.py index 80de8546b12..e82decbdb0f 100644 --- a/lib/python/Components/TuneTest.py +++ b/lib/python/Components/TuneTest.py @@ -80,7 +80,7 @@ def tuneCab(self, transponder): parm.modulation = transponder[2] parm.fec_inner = transponder[3] parm.inversion = transponder[4] - #parm.system = transponder[5] + # parm.system = transponder[5] self.tuneCabObj(parm) def tuneCabObj(self, transponderObj): diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index 20484950b32..14ea5bd6a2e 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -1,8 +1,7 @@ +import io import locale import os import skin -from time import time -from boxbranding import getBrandOEM, getDisplayType from enigma import eDVBDB, eEPGCache, setTunerTypePriorityOrder, setPreferredTuner, setSpinnerOnOff, setEnableTtCachingOnOff, eEnv, Misc_Options, eServiceEvent @@ -18,7 +17,6 @@ # getting a time-stamp prepended. # stderr expect unicode, not str, so we decode as utf-8 # -import io def raw_stderr_print(text): @@ -32,7 +30,7 @@ def raw_stderr_print(text): def InitUsageConfig(): config.version = ConfigNumber(default=0) - if getBrandOEM() in ('vuplus', 'ini'): + if SystemInfo["brand"] in ('vuplus', 'ini'): config.misc.remotecontrol_text_support = ConfigYesNo(default=True) else: config.misc.remotecontrol_text_support = ConfigYesNo(default=False) @@ -54,27 +52,27 @@ def alternativeNumberModeChange(configElement): refreshServiceList() config.usage.alternative_number_mode.addNotifier(alternativeNumberModeChange) - config.usage.servicelist_twolines = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("two lines")), ("2", _("two lines and next event"))]) - config.usage.servicelist_twolines.addNotifier(refreshServiceList) + config.usage.servicelist_twolines = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("two lines")), ("2", _("two lines+next event"))]) + config.usage.servicelist_twolines.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) config.usage.hide_number_markers = ConfigYesNo(default=True) - config.usage.hide_number_markers.addNotifier(refreshServiceList) + config.usage.hide_number_markers.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) - config.usage.servicetype_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename")), ("2", _("Right from servicename"))]) - config.usage.servicetype_icon_mode.addNotifier(refreshServiceList) - config.usage.crypto_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename")), ("2", _("Right from servicename"))]) - config.usage.crypto_icon_mode.addNotifier(refreshServiceList) - config.usage.record_indicator_mode = ConfigSelection(default="3", choices=[("0", _("None")), ("1", _("Left from servicename")), ("2", _("Right from servicename")), ("3", _("Red colored"))]) - config.usage.record_indicator_mode.addNotifier(refreshServiceList) + config.usage.servicetype_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename (only available in single line mode)")), ("2", _("Right from servicename"))]) + config.usage.servicetype_icon_mode.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) + config.usage.crypto_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename (only available in single line mode)")), ("2", _("Right from servicename"))]) + config.usage.crypto_icon_mode.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) + config.usage.record_indicator_mode = ConfigSelection(default="3", choices=[("0", _("None")), ("1", _("Left from servicename (only available in single line mode)")), ("2", _("Right from servicename")), ("3", _("Red colored"))]) + config.usage.record_indicator_mode.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) choicelist = [("-1", _("Disable"))] for i in range(0, 1300, 25): choicelist.append((str(i), ngettext("%d pixel wide", "%d pixels wide", i) % i)) config.usage.servicelist_column = ConfigSelection(default="-1", choices=choicelist) - config.usage.servicelist_column.addNotifier(refreshServiceList) + config.usage.servicelist_column.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) config.usage.service_icon_enable = ConfigYesNo(default=False) - config.usage.service_icon_enable.addNotifier(refreshServiceList) + config.usage.service_icon_enable.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) config.usage.servicelist_cursor_behavior = ConfigSelection(default="keep", choices=[ ("standard", _("Standard")), ("keep", _("Keep service")), @@ -108,11 +106,6 @@ def showsecondinfobarChanged(configElement): SystemInfo["InfoBarEpg"] = False config.usage.show_second_infobar.addNotifier(showsecondinfobarChanged) - try: - SystemInfo["SecondInfoBarSimple"] = skin.parameters.get("SecondInfoBarSimple", 0) > 0 - except Exception as err: - print("[UsageConfig] Error loading 'SecondInfoBarSimple' skin parameter! (%s)" % err) - SystemInfo["SecondInfoBarSimple"] = False config.usage.second_infobar_simple = ConfigBoolean(descriptions={False: _("Standard"), True: _("Simple")}, graphic=False) config.usage.infobar_frontend_source = ConfigSelection(default="tuner", choices=[("settings", _("Settings")), ("tuner", _("Tuner"))]) @@ -137,6 +130,7 @@ def showsecondinfobarChanged(configElement): print("[UserConfig] DEBUG: The 'show_menupath' setting of '%s' has been transferred to 'showScreenPath'." % config.usage.showScreenPath.value) # End of temporary code. config.usage.show_spinner = ConfigYesNo(default=True) + config.usage.enable_blinking = ConfigYesNo(default=True) config.usage.enable_tt_caching = ConfigYesNo(default=True) config.usage.sort_settings = ConfigYesNo(default=False) config.usage.sort_pluginlist = ConfigYesNo(default=True) @@ -322,9 +316,9 @@ def showsecondinfobarChanged(configElement): config.usage.show_bouquetalways = ConfigYesNo(default=False) config.usage.show_event_progress_in_servicelist = ConfigSelection(default='barright', choices=[ ('barleft', _("Progress bar left")), - ('barright', _("Progress bar right")), + ('barright', _("Progress bar right (only available in single line mode)")), ('percleft', _("Percentage left")), - ('percright', _("Percentage right")), + ('percright', _("Percentage right (only available in single line mode)")), ('no', _("No"))]) config.usage.show_channel_numbers_in_servicelist = ConfigYesNo(default=True) config.usage.show_channel_jump_in_servicelist = ConfigSelection(default="alpha", choices=[ @@ -332,8 +326,8 @@ def showsecondinfobarChanged(configElement): ("alpha", _("Alpha")), ("number", _("Number"))]) - config.usage.show_event_progress_in_servicelist.addNotifier(refreshServiceList) - config.usage.show_channel_numbers_in_servicelist.addNotifier(refreshServiceList) + config.usage.show_event_progress_in_servicelist.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) + config.usage.show_channel_numbers_in_servicelist.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) if SystemInfo["WakeOnLAN"]: def wakeOnLANChanged(configElement): @@ -344,8 +338,8 @@ def wakeOnLANChanged(configElement): config.usage.wakeOnLAN = ConfigYesNo(default=False) config.usage.wakeOnLAN.addNotifier(wakeOnLANChanged) - #standby - if getDisplayType() in ("textlcd7segment"): + # standby + if SystemInfo["displaytype"] in ("textlcd7segment"): config.usage.blinking_display_clock_during_recording = ConfigSelection(default="Rec", choices=[ ("Rec", _("REC")), ("RecBlink", _("Blinking REC")), @@ -353,13 +347,13 @@ def wakeOnLANChanged(configElement): else: config.usage.blinking_display_clock_during_recording = ConfigYesNo(default=False) - #in use - if getDisplayType() in ("textlcd"): + # in use + if SystemInfo["displaytype"] in ("textlcd"): config.usage.blinking_rec_symbol_during_recording = ConfigSelection(default="Channel", choices=[ ("Rec", _("REC Symbol")), ("RecBlink", _("Blinking REC Symbol")), ("Channel", _("Channelname"))]) - if getDisplayType() in ("textlcd7segment"): + if SystemInfo["displaytype"] in ("textlcd7segment"): config.usage.blinking_rec_symbol_during_recording = ConfigSelection(default="Rec", choices=[ ("Rec", _("REC")), ("RecBlink", _("Blinking REC")), @@ -367,7 +361,7 @@ def wakeOnLANChanged(configElement): else: config.usage.blinking_rec_symbol_during_recording = ConfigYesNo(default=True) - if getDisplayType() in ("textlcd7segment"): + if SystemInfo["displaytype"] in ("textlcd7segment"): config.usage.show_in_standby = ConfigSelection(default="time", choices=[ ("time", _("Time")), ("nothing", _("Nothing"))]) @@ -1138,6 +1132,7 @@ def setEpgLanguageAlternative(configElement): ("s", _("Restart softcam"))]) config.misc.softcam_streamrelay_url = ConfigIP(default=[127, 0, 0, 1], auto_jump=True) config.misc.softcam_streamrelay_port = ConfigInteger(default=17999, limits=(0, 65535)) + config.misc.softcam_streamrelay_delay = ConfigSelectionNumber(min=0, max=2000, stepwidth=50, default=100, wraparound=True) SystemInfo["OScamInstalled"] = False config.cccaminfo = ConfigSubsection() @@ -1161,7 +1156,7 @@ def setEpgLanguageAlternative(configElement): if softcam.lower().startswith("cccam"): config.cccaminfo.showInExtensions = ConfigYesNo(default=True) SystemInfo["CCcamInstalled"] = True - elif softcam.lower().startswith('oscam') or softcam.lower().startswith('ncam'): + elif softcam.lower().startswith(('oscam', 'ncam')): config.oscaminfo.showInExtensions = ConfigYesNo(default=True) SystemInfo["OScamInstalled"] = True diff --git a/lib/python/Components/VariableText.py b/lib/python/Components/VariableText.py index 407ef8dacaa..04a2c225d24 100644 --- a/lib/python/Components/VariableText.py +++ b/lib/python/Components/VariableText.py @@ -5,15 +5,14 @@ def __init__(self): object.__init__(self) self.message = "" self.instance = None + self.onChanged = [] def setText(self, text): - try: - self.message = text - if self.instance: - self.instance.setText(self.message or "") - except: - self.message = "" - self.instance.setText(self.message or "") + self.message = text + if self.instance: + self.instance.setText(str(self.message) or "") + for x in self.onChanged: + x() def setMarkedPos(self, pos): if self.instance: @@ -25,7 +24,4 @@ def getText(self): text = property(getText, setText) def postWidgetCreate(self, instance): - try: - instance.setText(self.message or "") - except: - pass + instance.setText(str(self.message) or "") diff --git a/lib/python/Components/VolumeControl.py b/lib/python/Components/VolumeControl.py index b4732ecebd7..17422a8d357 100644 --- a/lib/python/Components/VolumeControl.py +++ b/lib/python/Components/VolumeControl.py @@ -2,7 +2,7 @@ from Tools.Profile import profile from Screens.Volume import Volume from Screens.Mute import Mute -from GlobalActions import globalActionMap +from GlobalActions import globalActionMap # noqa: F401 from Components.config import config, ConfigSubsection, ConfigInteger import skin @@ -65,7 +65,6 @@ def volDown(self): self.setVolume(-1) def setVolume(self, direction): - oldvol = self.volctrl.getVolume() # local variable 'oldvol' is assigned to but never used if direction > 0: self.volctrl.volumeUp() else: diff --git a/lib/python/Components/config.py b/lib/python/Components/config.py index 00ada7e1199..98aaab16812 100644 --- a/lib/python/Components/config.py +++ b/lib/python/Components/config.py @@ -1065,10 +1065,10 @@ def __init__(self, default): # dafault can either be a timestamp # or an (hours, minutes) tuple. if isinstance(default, tuple): - l = list(localtime()) - l[3] = default[0] # hours - l[4] = default[1] # minutes - default = int(mktime(tuple(l))) + itemList = list(localtime()) + itemList[3] = default[0] # hours + itemList[4] = default[1] # minutes + default = int(mktime(tuple(itemList))) t = localtime(default) ConfigSequence.__init__(self, seperator=":", limits=clock_limits, default=[t.tm_hour, t.tm_min]) @@ -2198,11 +2198,11 @@ def pickle(self): def unpickle(self, lines, base_file=True): tree = {} configbase = tree.setdefault("config", {}) - for l in lines: - if not l or l[0] == '#': + for element in lines: + if not element or element[0] == '#': continue - result = l.split('=', 1) + result = element.split('=', 1) if len(result) != 2: continue (name, val) = result diff --git a/lib/python/Components/opkg.py b/lib/python/Components/opkg.py index 141798d0283..cec8e747232 100644 --- a/lib/python/Components/opkg.py +++ b/lib/python/Components/opkg.py @@ -55,7 +55,7 @@ def enumPlugins(filter_start=''): def listsDirPath(): try: for line in open('/etc/opkg/opkg.conf', "r"): - if line.startswith('option lists_dir') or line.startswith('lists_dir'): + if line.startswith(('option lists_dir', 'lists_dir')): return line.replace('\n', '').split(' ')[2] except IOError: print("[Opkg] cannot open /etc/opkg/opkg.conf") diff --git a/lib/python/Makefile.am b/lib/python/Makefile.am index 1193a496c70..10ea22649ae 100644 --- a/lib/python/Makefile.am +++ b/lib/python/Makefile.am @@ -12,6 +12,7 @@ install_PYTHON = \ PowerTimer.py \ RecordTimer.py \ ServiceReference.py \ + Session.py \ skin.py \ StartEnigma.py \ timer.py \ diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py index eeeb27a3e8f..16143821477 100644 --- a/lib/python/Navigation.py +++ b/lib/python/Navigation.py @@ -10,12 +10,12 @@ from Tools.StbHardware import getFPWasTimerWakeup import RecordTimer import PowerTimer -from ServiceReference import ServiceReference +from ServiceReference import ServiceReference # noqa: F401 import Screens.Standby import NavigationInstance from Screens.InfoBar import InfoBar from Components.Sources.StreamService import StreamServiceList -from Screens.InfoBarGenerics import streamrelayChecker +from Screens.InfoBarGenerics import streamrelay # TODO: remove pNavgation, eNavigation and rewrite this stuff in python. @@ -39,6 +39,7 @@ def __init__(self, nextRecordTimerAfterEventActionAuto=False, nextPowerManagerAf self.currentlyPlayingServiceReference = None self.currentlyPlayingServiceOrGroup = None self.currentlyPlayingService = None + self.currentServiceIsStreamRelay = False self.skipServiceReferenceReset = False self.RecordTimer = RecordTimer.RecordTimer() self.PowerTimer = PowerTimer.PowerTimer() @@ -181,7 +182,7 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust else: self.skipServiceReferenceReset = True self.currentlyPlayingServiceReference = playref - playref = streamrelayChecker(playref) + playref = streamrelay.streamrelayChecker(playref) self.currentlyPlayingServiceOrGroup = ref if InfoBarInstance and InfoBarInstance.servicelist.servicelist.setCurrent(ref, adjust): self.currentlyPlayingServiceOrGroup = InfoBarInstance.servicelist.servicelist.getCurrent() @@ -213,7 +214,15 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust if config.usage.frontend_priority_dvbs.value != config.usage.frontend_priority.value: setPreferredTuner(int(config.usage.frontend_priority_dvbs.value)) setPriorityFrontend = True - if self.pnav.playService(playref): + if config.misc.softcam_streamrelay_delay.value and self.currentServiceIsStreamRelay: + self.currentServiceIsStreamRelay = False + self.currentlyPlayingServiceReference = None + self.currentlyPlayingServiceOrGroup = None + print("[Navigation] Streamrelay was active -> delay the zap till tuner is freed") + self.retryServicePlayTimer = eTimer() + self.retryServicePlayTimer.callback.append(boundFunction(self.playService, ref, checkParentalControl, forceRestart, adjust)) + self.retryServicePlayTimer.start(config.misc.softcam_streamrelay_delay.value, True) + elif self.pnav.playService(playref): # print("[Navigation] Failed to start", playref) self.currentlyPlayingServiceReference = None self.currentlyPlayingServiceOrGroup = None @@ -225,6 +234,8 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust self.skipServiceReferenceReset = False if setPriorityFrontend: setPreferredTuner(int(config.usage.frontend_priority.value)) + if self.currentlyPlayingServiceReference and self.currentlyPlayingServiceReference.toString() in streamrelay.data: + self.currentServiceIsStreamRelay = True return 0 elif oldref and InfoBarInstance and InfoBarInstance.servicelist.servicelist.setCurrent(oldref, adjust): self.currentlyPlayingServiceOrGroup = InfoBarInstance.servicelist.servicelist.getCurrent() @@ -243,7 +254,7 @@ def recordService(self, ref, simulate=False): if ref: if ref.flags & eServiceReference.isGroup: ref = getBestPlayableServiceReference(ref, eServiceReference(), simulate) - ref = streamrelayChecker(ref) + ref = streamrelay.streamrelayChecker(ref) service = ref and self.pnav and self.pnav.recordService(ref, simulate) if service is None: print("[Navigation] record returned non-zero") diff --git a/lib/python/Plugins/Extensions/CutListEditor/ui.py b/lib/python/Plugins/Extensions/CutListEditor/ui.py index 0bab3b180f8..d6258b64055 100644 --- a/lib/python/Plugins/Extensions/CutListEditor/ui.py +++ b/lib/python/Plugins/Extensions/CutListEditor/ui.py @@ -2,16 +2,16 @@ from Screens.MessageBox import MessageBox from Components.ServicePosition import ServicePositionGauge from Components.ActionMap import HelpableActionMap -from Components.MultiContent import MultiContentEntryText +from Components.MultiContent import MultiContentEntryText # noqa: F401 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase from Components.VideoWindow import VideoWindow from Components.Label import Label from Components.config import config, ConfigSubsection, ConfigYesNo from Screens.InfoBarGenerics import InfoBarSeek, InfoBarCueSheetSupport -from enigma import getDesktop, gFont, iPlayableService, RT_HALIGN_RIGHT +from enigma import getDesktop, gFont, iPlayableService, RT_HALIGN_RIGHT # noqa: F401 from Screens.FixedMenu import FixedMenu from Screens.HelpMenu import HelpableScreen -from ServiceReference import ServiceReference +from ServiceReference import ServiceReference # noqa: F401 from Components.Sources.List import List from Components.Console import Console from Screens.ChoiceBox import ChoiceBox diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py index 567b0ae35cb..510ffc44033 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py @@ -1,8 +1,8 @@ import xml.dom.minidom -from boxbranding import getMachineBrand, getMachineName from Tools.Directories import fileExists from Components.config import ConfigSubsection, ConfigInteger, ConfigText, ConfigSelection, ConfigSequence, ConfigSubList +from Components.SystemInfo import getBoxDisplayName from . import DVDTitle from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_FONTS @@ -39,7 +39,7 @@ def __init__(self): self.target = None self.settings = ConfigSubsection() self.settings.name = ConfigText(fixed_size=False, visible_width=40) - self.settings.authormode = ConfigSelection(choices=[("menu_linked", _("Linked titles with a DVD menu")), ("just_linked", _("Direct playback of linked titles without menu")), ("menu_seperate", _("Seperate titles with a main menu")), ("data_ts", _("%s %s format data DVD (HDTV compatible)") % (getMachineBrand(), getMachineName()))]) + self.settings.authormode = ConfigSelection(choices=[("menu_linked", _("Linked titles with a DVD menu")), ("just_linked", _("Direct playback of linked titles without menu")), ("menu_seperate", _("Seperate titles with a main menu")), ("data_ts", _("%s %s format data DVD (HDTV compatible)") % getBoxDisplayName())]) self.settings.titlesetmode = ConfigSelection(choices=[("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi") self.settings.output = ConfigSelection(choices=[("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))]) self.settings.isopath = ConfigText(fixed_size=False, visible_width=40) diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py index 573c97d3242..e24b5416fe8 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py @@ -96,8 +96,7 @@ def formatDVDmenuText(self, template, track): template = template.replace("$A", audiostring) if template.find("$l") >= 0: - l = self.length - lengthstring = "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + lengthstring = "%d:%02d:%02d" % (self.length / 3600, self.length % 3600 / 60, self.length % 60) template = template.replace("$l", lengthstring) if self.timeCreate: template = template.replace("$Y", str(self.timeCreate[0])) diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py index 85fca143a66..2c0d2e123ae 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py @@ -206,7 +206,7 @@ def processOutputLine(self, line): if line.startswith("- media is already formatted"): self.error = self.ERROR_ALREADYFORMATTED self.retryargs = ["-force"] - if line.startswith("- media is not blank") or line.startswith(" -format=full to perform full (lengthy) reformat;"): + if line.startswith(("- media is not blank", " -format=full to perform full (lengthy) reformat;")): self.error = self.ERROR_ALREADYFORMATTED self.retryargs = ["-blank"] if line.startswith(":-( mounted media doesn't appear to be"): diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index f28871620bc..d4f888146e8 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -135,7 +135,7 @@ def processOutputLine(self, line): elif line.startswith(MSG_PROGRESS): progress = line[len(MSG_PROGRESS):] self.haveProgress(progress) - elif line.startswith(MSG_NEW_MP2) or line.startswith(MSG_NEW_AC3): + elif line.startswith((MSG_NEW_MP2, MSG_NEW_AC3)): try: self.currentPID = str(int(line.split(': PID 0x', 1)[1].split(' ', 1)[0], 16)) except ValueError: diff --git a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py index 534d78327fe..5c8d5d3dd99 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py +++ b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py @@ -23,27 +23,27 @@ def __init__(self, session, scope, configRef): currDir = "/" if self.scope == "project": currDir = self.getDir() - pattern = "(?i)^.*\.(ddvdp\.xml)" + pattern = r"(?i)^.*\.(ddvdp\.xml)" elif self.scope == "menutemplate": currDir = self.getDir() - pattern = "(?i)^.*\.(ddvdm\.xml)" + pattern = r"(?i)^.*\.(ddvdm\.xml)" if self.scope == "menubg": currDir = self.getDir(configRef.value) - pattern = "(?i)^.*\.(jpeg|jpg|jpe|png|bmp)" + pattern = r"(?i)^.*\.(jpeg|jpg|jpe|png|bmp)" elif self.scope == "menuaudio": currDir = self.getDir(configRef.value) - pattern = "(?i)^.*\.(mp2|m2a|ac3)" + pattern = r"(?i)^.*\.(mp2|m2a|ac3)" elif self.scope == "vmgm": currDir = self.getDir(configRef.value) - pattern = "(?i)^.*\.(mpg|mpeg)" + pattern = r"(?i)^.*\.(mpg|mpeg)" elif self.scope == "font_face": currDir = self.getDir(configRef.value, resolveFilename(SCOPE_FONTS)) - pattern = "(?i)^.*\.(ttf)" + pattern = r"(?i)^.*\.(ttf)" elif self.scope == "isopath": currDir = configRef.value elif self.scope == "image": currDir = resolveFilename(SCOPE_HDD) - pattern = "(?i)^.*\.(iso)" + pattern = r"(?i)^.*\.(iso)" self.filelist = FileList(currDir, matchingPattern=pattern) self["filelist"] = self.filelist @@ -53,7 +53,7 @@ def __init__(self, session, scope, configRef): "save": self.ok, "ok": self.ok, "cancel": self.exit - }) + }) # noqa: E123 self["key_red"] = StaticText(_("Cancel")) self["key_green"] = StaticText(_("OK")) self.onLayoutFinish.append(self.layoutFinished) diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py index 00b1acf3490..e2ad1a4f0d3 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py +++ b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py @@ -1,5 +1,3 @@ -from boxbranding import getMachineBrand, getMachineName - from . import DVDProject from . import TitleCutter from . import TitleProperties @@ -17,6 +15,7 @@ from Components.Sources.StaticText import StaticText from Components.Sources.Progress import Progress from Components.Label import MultiColorLabel +from Components.SystemInfo import getBoxDisplayName from Tools.Directories import resolveFilename, SCOPE_PLUGINS @@ -227,7 +226,7 @@ def selectedSource(self, source=None): if source is None: return None if not source.getPath().endswith(".ts"): - self.session.open(MessageBox, text=_("You can only burn %s %s recordings!") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_ERROR) + self.session.open(MessageBox, text=_("You can only burn %s %s recordings!") % getBoxDisplayName(), type=MessageBox.TYPE_ERROR) return None t = self.project.addService(source) try: @@ -365,7 +364,7 @@ def titleEditDone(self, cutlist): t = self.current_edit_title t.titleEditDone(cutlist) if t.VideoType != 0: - self.session.openWithCallback(self.DVDformatCB, MessageBox, text=_("The DVD standard doesn't support H.264 (HDTV) video streams. Do you want to create a %s %s format data DVD (which will not play in stand-alone DVD players) instead?") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_YESNO) + self.session.openWithCallback(self.DVDformatCB, MessageBox, text=_("The DVD standard doesn't support H.264 (HDTV) video streams. Do you want to create a %s %s format data DVD (which will not play in stand-alone DVD players) instead?") % getBoxDisplayName(), type=MessageBox.TYPE_YESNO) else: self.updateTitleList() diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 44e3350e224..cf6a5bbadd0 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -1,7 +1,6 @@ from os import listdir, path as ospath, remove as osremove from time import strftime import random -from boxbranding import getMachineBrand, getMachineName from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, ePicLoad from Components.ActionMap import NumberActionMap, HelpableActionMap @@ -128,7 +127,7 @@ def __init__(self, session, args=None): # 'None' is magic to start at the list of mountpoints defaultDir = config.mediaplayer.defaultDir.getValue() - self.filelist = FileList(defaultDir, matchingPattern="(?i)^.*\.(dts|mp3|wav|wave|wv|oga|ogg|flac|m4a|mp2|m2a|wma|ac3|mka|aac|ape|alac|mpg|vob|m4v|mkv|avi|divx|dat|flv|mp4|mov|wmv|asf|3gp|3g2|mpeg|mpe|rm|rmvb|ogm|ogv|m2ts|mts|ts|m3u|e2pls|pls|amr|au|mid|pva|wtv)", useServiceRef=True, additionalExtensions="4098:m3u 4098:e2pls 4098:pls") + self.filelist = FileList(defaultDir, matchingPattern=r"(?i)^.*\.(dts|mp3|wav|wave|wv|oga|ogg|flac|m4a|mp2|m2a|wma|ac3|mka|aac|ape|alac|mpg|vob|m4v|mkv|avi|divx|dat|flv|mp4|mov|wmv|asf|3gp|3g2|mpeg|mpe|rm|rmvb|ogm|ogv|m2ts|mts|ts|m3u|e2pls|pls|amr|au|mid|pva|wtv)", useServiceRef=True, additionalExtensions="4098:m3u 4098:e2pls 4098:pls") self["filelist"] = self.filelist self.playlist = MyPlayList() @@ -353,13 +352,13 @@ def __evAudioDecodeError(self): currPlay = self.session.nav.getCurrentService() sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec) print("[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % sTagAudioCodec) - self.session.open(MessageBox, _("This %s %s cannot decode %s streams!") % (getMachineBrand(), getMachineName(), sTagAudioCodec), type=MessageBox.TYPE_INFO, timeout=20) + self.session.open(MessageBox, _("This %s %s cannot decode %s streams!") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], sTagAudioCodec), type=MessageBox.TYPE_INFO, timeout=20) def __evVideoDecodeError(self): currPlay = self.session.nav.getCurrentService() sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec) print("[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % sTagVideoCodec) - self.session.open(MessageBox, _("This %s %s cannot decode %s streams!") % (getMachineBrand(), getMachineName(), sTagVideoCodec), type=MessageBox.TYPE_INFO, timeout=20) + self.session.open(MessageBox, _("This %s %s cannot decode %s streams!") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], sTagVideoCodec), type=MessageBox.TYPE_INFO, timeout=20) def __evPluginError(self): currPlay = self.session.nav.getCurrentService() @@ -1135,16 +1134,16 @@ def prevBouquet(self): class MediaPlayerLCDScreen(Screen): skin = ( - """ - - - - """, - """ - - - - """) + """ + + + + """, + """ + + + + """) def __init__(self, session, parent): Screen.__init__(self, session) diff --git a/lib/python/Plugins/Extensions/MediaPlayer/settings.py b/lib/python/Plugins/Extensions/MediaPlayer/settings.py index 2eda3db2cf6..523b848308e 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/settings.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/settings.py @@ -93,8 +93,6 @@ def initConfigList(self, element=None): self.list.append(getConfigListEntry(_("repeat playlist"), config.mediaplayer.repeat)) self.list.append(getConfigListEntry(_("save playlist on exit"), config.mediaplayer.savePlaylistOnExit)) self.list.append(getConfigListEntry(_("save last directory on exit"), config.mediaplayer.saveDirOnExit)) - if not config.mediaplayer.saveDirOnExit.value: - self.list.append(getConfigListEntry(_("start directory"), config.mediaplayer.defaultDir)) self.list.append(getConfigListEntry(_("sorting of playlists"), config.mediaplayer.sortPlaylists)) self.list.append(getConfigListEntry(_("Always hide infobar"), config.mediaplayer.alwaysHideInfoBar)) self.list.append(getConfigListEntry(_("show mediaplayer on mainmenu"), config.mediaplayer.onMainMenu)) diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index 7df9a4cbe64..7b3d4ee37dc 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -39,7 +39,7 @@ def checkFile(self, file): paths_to_scan=[ ScanPath(path="DCIM", with_subdirs=True), ScanPath(path="", with_subdirs=False), - ], + ], # noqa: E123 name="Pictures", description=_("View photos..."), openfnc=filescan_open, @@ -54,5 +54,5 @@ def Plugins(**kwargs): PluginDescriptor(name=_("Picture player"), where=PluginDescriptor.WHERE_FILESCAN, needsRestart=False, fnc=filescan)] else: return \ - [PluginDescriptor(name=_("Picture player"), description=_("fileformats (BMP, PNG, JPG, GIF)"), icon="pictureplayer.png", where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=False, fnc=main), - PluginDescriptor(name=_("Picture player"), where=PluginDescriptor.WHERE_FILESCAN, needsRestart=False, fnc=filescan)] + [PluginDescriptor(name=_("Picture player"), description=_("fileformats (BMP, PNG, JPG, GIF)"), icon="pictureplayer.png", where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=False, fnc=main), + PluginDescriptor(name=_("Picture player"), where=PluginDescriptor.WHERE_FILESCAN, needsRestart=False, fnc=filescan)] diff --git a/lib/python/Plugins/Extensions/PicturePlayer/ui.py b/lib/python/Plugins/Extensions/PicturePlayer/ui.py index 8c134b952a8..0b905d9ae2c 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/ui.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/ui.py @@ -69,7 +69,7 @@ def __init__(self, session): if not pathExists(currDir): currDir = "/" - self.filelist = FileList(currDir, matchingPattern="(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif|svg)") + self.filelist = FileList(currDir, matchingPattern=r"(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif|svg)") self["filelist"] = self.filelist self["filelist"].onSelectionChanged.append(self.selectionChanged) @@ -493,7 +493,7 @@ def setPicloadConf(self): self.start_decode() def setConf(self, retval=None): - sc = getScale() + # sc = getScale() # 0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) self.picload.setPara([self["pic"].instance.size().width(), self["pic"].instance.size().height(), 1, 1, 0, int(config.pic.resize.value), self.bgcolor, config.pic.autoOrientation.value]) diff --git a/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py b/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py index 533b43ada8e..be12e4a9ea0 100644 --- a/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py @@ -5,17 +5,16 @@ from Components.MenuList import MenuList from Components.Sources.StaticText import StaticText from Components.config import config, ConfigNumber, ConfigSelectionNumber, getConfigListEntry +from Components.SystemInfo import SystemInfo from Plugins.Plugin import PluginDescriptor from enigma import setAnimation_current, setAnimation_speed -from boxbranding import getBrandOEM - # default = disabled g_default = { "current": 0, "speed": 20, - } + } # noqa: E123 g_max_speed = 30 g_animation_paused = False @@ -51,7 +50,7 @@ def __init__(self, session): "yellow": self.keyYellow, "red": self.keyRed, "cancel": self.keyRed, - }, -2) + }, -2) # noqa: E123 self["key_red"] = StaticText(_("Cancel")) self["key_green"] = StaticText(_("Save")) self["key_yellow"] = StaticText(_("Default")) @@ -90,7 +89,7 @@ def makeConfigList(self): class AnimationSetupScreen(Screen): - if getBrandOEM() == 'gigablue': + if SystemInfo["brand"] == 'gigablue': animationSetupItems = [ {"idx": 0, "name": _("Disable Animations")}, {"idx": 1, "name": _("Simple fade")}, @@ -155,20 +154,20 @@ def __init__(self, session): "ok": self.ok, "yellow": self.config, "blue": self.preview - }, -3) + }, -3) # noqa: E123 self["list"] = MenuList(self.animationList) self.onLayoutFinish.append(self.layoutFinished) def layoutFinished(self): - l = [] + lani = [] for x in self.animationSetupItems: key = x.get("idx", 0) name = x.get("name", "??") if key == config.misc.window_animation_default.value: name = "* %s" % (name) - l.append((name, key)) + lani.append((name, key)) - self["list"].setList(l) + self["list"].setList(lani) def ok(self): current = self["list"].getCurrent() diff --git a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py index 622df10446f..36886ae0f49 100644 --- a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py +++ b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py @@ -3,6 +3,7 @@ from Plugins.Plugin import PluginDescriptor from Screens.Screen import Screen from Screens.InfoBar import InfoBar +from Screens.InfoBarGenerics import streamrelay from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigYesNo, ConfigSelection from Components.ConfigList import ConfigListScreen from Components.Sources.StaticText import StaticText @@ -211,7 +212,7 @@ def enableEventTracker(self, activate): iPlayableService.evEnd: self.getEvEnd, iPlayableService.evTunedIn: self.getEvTunedIn, iPlayableService.evTuneFailed: self.getEvTuneFailed - }) + }) # noqa: E123 elif self.__event_tracker: # run ServiceEventTracker.__del_event() @@ -247,6 +248,9 @@ def isPlayableFCC(self, sref): elif int(sref.getData(0)) in (2, 10): # is RADIO? playable = False + elif sref.toString() in streamrelay.data: + playable = False + return playable def getZapUpDownList(self): @@ -567,19 +571,19 @@ def Plugins(**kwargs): PluginDescriptor(name="FCCSupport", description="Fast Channel Change support", where=[PluginDescriptor.WHERE_SESSIONSTART], - fnc=FCCSupportInit)) + fnc=FCCSupportInit)) # noqa: E122 list.append( PluginDescriptor(name="FCCExtensionMenu", description="Fast Channel Change menu", where=[PluginDescriptor.WHERE_EXTENSIONSINGLE], - fnc=addExtentions)) + fnc=addExtentions)) # noqa: E122 list.append( PluginDescriptor(name=_("FCCSetup"), description=_("Fast Channel Change setup"), - where=[PluginDescriptor.WHERE_MENU], - needsRestart=False, - fnc=main)) + where=[PluginDescriptor.WHERE_MENU], # noqa: E122 + needsRestart=False, # noqa: E122 + fnc=main)) # noqa: E122 return list diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py b/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py index fd6f3a3dc1c..b45be2f9b4a 100644 --- a/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py +++ b/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py @@ -1,12 +1,12 @@ from os import system from enigma import eTimer -from boxbranding import getMachineBrand, getMachineName from Components.config import config from Components.Label import Label from Components.Network import iNetwork from Components.Pixmap import Pixmap from Components.Sources.Boolean import Boolean +from Components.SystemInfo import getBoxDisplayName from Screens.MessageBox import MessageBox from Screens.Rc import Rc from Screens.WizardLanguage import WizardLanguage @@ -246,7 +246,7 @@ def checkWlanStateCB(self, data, status): if data is not None: if data is True: if status is not None: - text1 = _("Your %s %s is now ready to be used.\n\nYour internet connection is working now.\n\n") % (getMachineBrand(), getMachineName()) + text1 = _("Your %s %s is now ready to be used.\n\nYour internet connection is working now.\n\n") % getBoxDisplayName() text2 = _('Accesspoint:') + "\t" + str(status[self.selectedInterface]["accesspoint"]) + "\n" text3 = _('SSID:') + "\t" + str(status[self.selectedInterface]["essid"]) + "\n" text4 = _('Link quality:') + "\t" + str(status[self.selectedInterface]["quality"]) + "\n" diff --git a/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py b/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py index 900926c2434..705485f650f 100644 --- a/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py +++ b/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py @@ -607,8 +607,8 @@ def writeLamedb5(self, path, transponders, filename="lamedb5"): pass if "t2mi_plp_id" in transponder and "t2mi_pid" in transponder: t2mi = ',T2MI:%d:%d' % ( - transponder["t2mi_plp_id"], - transponder["t2mi_pid"]) + transponder["t2mi_plp_id"], + transponder["t2mi_pid"]) lamedblist.append("s:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d%s%s\n" % (transponder["frequency"], transponder["symbol_rate"], diff --git a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py index fa83b8eebde..f8d369922d9 100644 --- a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py @@ -188,6 +188,9 @@ def __init__(self, session, feid): self.blue = Button("") self["key_blue"] = self.blue + self["key_info"] = StaticText(_("INFO")) + self["key_menu"] = StaticText(_("MENU")) + self.list = [] self["list"] = ConfigList(self.list) diff --git a/lib/python/Plugins/SystemPlugins/SABnzbdSetup/plugin.py b/lib/python/Plugins/SystemPlugins/SABnzbdSetup/plugin.py index c1f8cf3fe71..5719b0fa10b 100644 --- a/lib/python/Plugins/SystemPlugins/SABnzbdSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/SABnzbdSetup/plugin.py @@ -1,4 +1,3 @@ -from boxbranding import getMachineBrand, getMachineName import time from Screens.Screen import Screen @@ -7,6 +6,7 @@ from Components.Label import Label from Components.Sources.StaticText import StaticText from Components.ActionMap import ActionMap +from Components.SystemInfo import getBoxDisplayName from Tools.Directories import fileExists @@ -56,7 +56,7 @@ def InstallCheck(self): def InstalldataAvail(self, result, retval, extra_args): if not result: - restartbox = self.session.openWithCallback(self.InstallPackage, MessageBox, _('Your %s %s will be restarted after the installation of service.\n\nDo you want to install now ?') % (getMachineBrand(), getMachineName()), MessageBox.TYPE_YESNO) + restartbox = self.session.openWithCallback(self.InstallPackage, MessageBox, _('Your %s %s will be restarted after the installation of service.\n\nDo you want to install now ?') % getBoxDisplayName(), MessageBox.TYPE_YESNO) restartbox.setTitle(_('Ready to install "%s" ?') % self.service_name) else: self.updateService() @@ -83,7 +83,7 @@ def UninstallCheck(self): def UninstalldataAvail(self, result, retval, extra_args): if result: - restartbox = self.session.openWithCallback(self.RemovePackage, MessageBox, _('Your %s %s will be restarted after the removal of service\nDo you want to remove now ?') % (getMachineBrand(), getMachineName()), MessageBox.TYPE_YESNO) + restartbox = self.session.openWithCallback(self.RemovePackage, MessageBox, _('Your %s %s will be restarted after the removal of service\nDo you want to remove now ?') % getBoxDisplayName(), MessageBox.TYPE_YESNO) restartbox.setTitle(_('Ready to remove "%s" ?') % self.service_name) else: self.updateService() diff --git a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py index 7ede92e2d63..437fa3f6651 100644 --- a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py +++ b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py @@ -8,7 +8,6 @@ from Plugins.Plugin import PluginDescriptor from Screens.MessageBox import MessageBox from Screens.ScanSetup import ScanSetup, buildTerTransponder -from Screens.Screen import Screen # for services found class from Screens.ServiceScan import ServiceScan from Tools.Transponder import getChannelNumber, channel2frequency from Tools.BoundFunction import boundFunction diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py deleted file mode 100644 index 34d1b7a8526..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py +++ /dev/null @@ -1,335 +0,0 @@ -from os import path, makedirs, listdir, stat, rename, remove -from datetime import date - -from Screens.Screen import Screen -from Screens.MessageBox import MessageBox -from Screens.Console import Console -from Components.ActionMap import ActionMap, NumberActionMap -from Components.Sources.StaticText import StaticText -from Components.MenuList import MenuList -from Components.config import configfile, ConfigSubsection, ConfigText, ConfigLocations -from Components.config import config -from Components.ConfigList import ConfigListScreen -from Components.FileList import MultiFileSelectList -from Plugins.Plugin import PluginDescriptor -from enigma import eTimer, eEnv, eEPGCache -from Tools.Directories import * - - -config.plugins.configurationbackup = ConfigSubsection() -config.plugins.configurationbackup.backuplocation = ConfigText(default='/media/hdd/', visible_width=50, fixed_size=False) -config.plugins.configurationbackup.backupdirs = ConfigLocations(default=[eEnv.resolve('${sysconfdir}/enigma2/'), '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/wpa_supplicant.ath0.conf', '/etc/wpa_supplicant.wlan0.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname']) - - -def getBackupPath(): - backuppath = config.plugins.configurationbackup.backuplocation.value - if backuppath.endswith('/'): - return backuppath + 'backup' - else: - return backuppath + '/backup' - - -def getBackupFilename(): - return "enigma2settingsbackup.tar.gz" - - -class BackupScreen(ConfigListScreen, Screen): - skin = """ - - - """ - - def __init__(self, session, runBackup=False): - Screen.__init__(self, session) - self.session = session - self.runBackup = runBackup - self["actions"] = ActionMap(["WizardActions", "DirectionActions"], - { - "ok": self.close, - "back": self.close, - "cancel": self.close, - }, -1) - self.finished_cb = None - self.backuppath = getBackupPath() - self.backupfile = getBackupFilename() - self.fullbackupfilename = self.backuppath + "/" + self.backupfile - self.list = [] - ConfigListScreen.__init__(self, self.list) - self.onLayoutFinish.append(self.layoutFinished) - if self.runBackup: - self.onShown.append(self.doBackup) - - def layoutFinished(self): - self.setWindowTitle() - - def setWindowTitle(self): - self.setTitle(_("Backup is running...")) - - def doBackup(self): - configfile.save() - if config.plugins.softwaremanager.epgcache.value: - eEPGCache.getInstance().save() - try: - if not path.exists(self.backuppath): - makedirs(self.backuppath) - self.backupdirs = ' '.join(config.plugins.configurationbackup.backupdirs.value) - if path.exists(self.fullbackupfilename): - dt = str(date.fromtimestamp(stat(self.fullbackupfilename).st_ctime)) - self.newfilename = self.backuppath + "/" + dt + '-' + self.backupfile - if path.exists(self.newfilename): - remove(self.newfilename) - rename(self.fullbackupfilename, self.newfilename) - if self.finished_cb: - self.session.openWithCallback(self.finished_cb, Console, title=_("Backup is running..."), cmdlist=["tar -czvf " + self.fullbackupfilename + " " + self.backupdirs], finishedCallback=self.backupFinishedCB, closeOnSuccess=True) - else: - self.session.open(Console, title=_("Backup is running..."), cmdlist=["tar -czvf " + self.fullbackupfilename + " " + self.backupdirs], finishedCallback=self.backupFinishedCB, closeOnSuccess=True) - except OSError: - if self.finished_cb: - self.session.openWithCallback(self.finished_cb, MessageBox, _("Sorry, your backup destination is not writeable.\nPlease select a different one."), MessageBox.TYPE_INFO, timeout=10) - else: - self.session.openWithCallback(self.backupErrorCB, MessageBox, _("Sorry, your backup destination is not writeable.\nPlease select a different one."), MessageBox.TYPE_INFO, timeout=10) - - def backupFinishedCB(self, retval=None): - self.close(True) - - def backupErrorCB(self, retval=None): - self.close(False) - - def runAsync(self, finished_cb): - self.finished_cb = finished_cb - self.doBackup() - - -class BackupSelection(Screen): - skin = """ - - - - - - - - - """ - - def __init__(self, session): - Screen.__init__(self, session) - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Save")) - self["key_yellow"] = StaticText() - - self.selectedFiles = config.plugins.configurationbackup.backupdirs.value - defaultDir = '/' - inhibitDirs = ["/bin", "/boot", "/dev", "/autofs", "/lib", "/proc", "/sbin", "/sys", "/hdd", "/tmp", "/mnt", "/media"] - self.filelist = MultiFileSelectList(self.selectedFiles, defaultDir, inhibitDirs=inhibitDirs) - self["checkList"] = self.filelist - - self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ShortcutActions"], - { - "cancel": self.exit, - "red": self.exit, - "yellow": self.changeSelectionState, - "green": self.saveSelection, - "ok": self.okClicked, - "left": self.left, - "right": self.right, - "down": self.down, - "up": self.up - }, -1) - if not self.selectionChanged in self["checkList"].onSelectionChanged: - self["checkList"].onSelectionChanged.append(self.selectionChanged) - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - idx = 0 - self["checkList"].moveToIndex(idx) - self.setWindowTitle() - self.selectionChanged() - - def setWindowTitle(self): - self.setTitle(_("Select files/folders to backup")) - - def selectionChanged(self): - current = self["checkList"].getCurrent()[0] - if current[2] is True: - self["key_yellow"].setText(_("Deselect")) - else: - self["key_yellow"].setText(_("Select")) - - def up(self): - self["checkList"].up() - - def down(self): - self["checkList"].down() - - def left(self): - self["checkList"].pageUp() - - def right(self): - self["checkList"].pageDown() - - def changeSelectionState(self): - self["checkList"].changeSelectionState() - self.selectedFiles = self["checkList"].getSelectedList() - - def saveSelection(self): - self.selectedFiles = self["checkList"].getSelectedList() - config.plugins.configurationbackup.backupdirs.value = self.selectedFiles - config.plugins.configurationbackup.backupdirs.save() - config.plugins.configurationbackup.save() - config.save() - self.close(None) - - def exit(self): - self.close(None) - - def okClicked(self): - if self.filelist.canDescent(): - self.filelist.descent() - - -class RestoreMenu(Screen): - skin = """ - - - - - - - - - """ - - def __init__(self, session, plugin_path): - Screen.__init__(self, session) - self.skin_path = plugin_path - - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Restore")) - self["key_yellow"] = StaticText(_("Delete")) - - self.sel = [] - self.val = [] - self.entry = False - self.exe = False - - self.path = "" - - self["actions"] = NumberActionMap(["SetupActions"], - { - "ok": self.KeyOk, - "cancel": self.keyCancel - }, -1) - - self["shortcuts"] = ActionMap(["ShortcutActions"], - { - "red": self.keyCancel, - "green": self.KeyOk, - "yellow": self.deleteFile, - }) - self.flist = [] - self["filelist"] = MenuList(self.flist) - self.fill_list() - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setWindowTitle() - - def setWindowTitle(self): - self.setTitle(_("Restore backups")) - - def fill_list(self): - self.flist = [] - self.path = getBackupPath() - if not path.exists(self.path): - makedirs(self.path) - for file in listdir(self.path): - if file.endswith(".tar.gz"): - self.flist.append(file) - self.entry = True - self.flist.sort(reverse=True) - self["filelist"].l.setList(self.flist) - - def KeyOk(self): - if (self.exe == False) and (self.entry == True): - self.sel = self["filelist"].getCurrent() - if self.sel: - self.val = self.path + "/" + self.sel - self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore\nthe following backup:\n%s\nYour receiver will restart after the backup has been restored!") % self.sel) - - def keyCancel(self): - self.close() - - def startRestore(self, ret=False): - if ret: - self.exe = True - self.session.open(Console, title=_("Restoring..."), cmdlist=["tar -xzvf " + self.path + "/" + self.sel + " -C /", "killall -9 enigma2"]) - - def deleteFile(self): - if (self.exe == False) and (self.entry == True): - self.sel = self["filelist"].getCurrent() - if self.sel: - self.val = self.path + "/" + self.sel - self.session.openWithCallback(self.startDelete, MessageBox, _("Are you sure you want to delete\nthe following backup:\n") + self.sel) - - def startDelete(self, ret=False): - if ret: - self.exe = True - print("removing:", self.val) - if path.exists(self.val): - remove(self.val) - self.exe = False - self.fill_list() - - -class RestoreScreen(ConfigListScreen, Screen): - skin = """ - - - """ - - def __init__(self, session, runRestore=False): - Screen.__init__(self, session) - self.session = session - self.runRestore = runRestore - self["actions"] = ActionMap(["WizardActions", "DirectionActions"], - { - "ok": self.close, - "back": self.close, - "cancel": self.close, - }, -1) - self.finished_cb = None - self.backuppath = getBackupPath() - self.backupfile = getBackupFilename() - self.fullbackupfilename = self.backuppath + "/" + self.backupfile - self.list = [] - ConfigListScreen.__init__(self, self.list) - self.onLayoutFinish.append(self.layoutFinished) - if self.runRestore: - self.onShown.append(self.doRestore) - - def layoutFinished(self): - self.setWindowTitle() - - def setWindowTitle(self): - self.setTitle(_("Restoring...")) - - def doRestore(self): - if path.exists("/proc/stb/vmpeg/0/dst_width"): - restorecmdlist = ["tar -xzvf " + self.fullbackupfilename + " -C /", "echo 0 > /proc/stb/vmpeg/0/dst_height", "echo 0 > /proc/stb/vmpeg/0/dst_left", "echo 0 > /proc/stb/vmpeg/0/dst_top", "echo 0 > /proc/stb/vmpeg/0/dst_width", "killall -9 enigma2"] - else: - restorecmdlist = ["tar -xzvf " + self.fullbackupfilename + " -C /", "killall -9 enigma2"] - if self.finished_cb: - self.session.openWithCallback(self.finished_cb, Console, title=_("Restoring..."), cmdlist=restorecmdlist) - else: - self.session.open(Console, title=_("Restoring..."), cmdlist=restorecmdlist) - - def backupFinishedCB(self, retval=None): - self.close(True) - - def backupErrorCB(self, retval=None): - self.close(False) - - def runAsync(self, finished_cb): - self.finished_cb = finished_cb - self.doRestore() diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py deleted file mode 100644 index 0a95118247e..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py +++ /dev/null @@ -1,123 +0,0 @@ -from os import access, W_OK, R_OK - -from enigma import eEnv - -from Screens.WizardLanguage import WizardLanguage -from Screens.Wizard import wizardManager -from Screens.Rc import Rc -from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS -from Components.Pixmap import Pixmap -from Components.config import config, ConfigSubsection, ConfigText, ConfigLocations, ConfigBoolean -from Components.Harddisk import harddiskmanager - - -config.misc.firstrun = ConfigBoolean(default=True) -config.plugins.configurationbackup = ConfigSubsection() -config.plugins.configurationbackup.backuplocation = ConfigText(default='/media/hdd/', visible_width=50, fixed_size=False) -config.plugins.configurationbackup.backupdirs = ConfigLocations(default=[eEnv.resolve('${sysconfdir}/enigma2/'), '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/wpa_supplicant.ath0.conf', '/etc/wpa_supplicant.wlan0.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname']) - - -backupfile = "enigma2settingsbackup.tar.gz" - - -def checkConfigBackup(): - parts = [(r.description, r.mountpoint) for r in harddiskmanager.getMountedPartitions(onlyhotplug=False)] - for x in parts: - if x[1] == '/': - parts.remove(x) - if len(parts): - for x in parts: - if x[1].endswith('/'): - fullbackupfile = x[1] + 'backup/' + backupfile - if fileExists(fullbackupfile): - config.plugins.configurationbackup.backuplocation.value = str(x[1]) - config.plugins.configurationbackup.backuplocation.save() - config.plugins.configurationbackup.save() - return x - else: - fullbackupfile = x[1] + '/backup/' + backupfile - if fileExists(fullbackupfile): - config.plugins.configurationbackup.backuplocation.value = str(x[1]) - config.plugins.configurationbackup.backuplocation.save() - config.plugins.configurationbackup.save() - return x - return None - - -def checkBackupFile(): - backuplocation = config.plugins.configurationbackup.backuplocation.value - if backuplocation.endswith('/'): - fullbackupfile = backuplocation + 'backup/' + backupfile - if fileExists(fullbackupfile): - return True - else: - return False - else: - fullbackupfile = backuplocation + '/backup/' + backupfile - if fileExists(fullbackupfile): - return True - else: - return False - - -if checkConfigBackup() is None: - backupAvailable = 0 -else: - backupAvailable = 1 - - -class ImageWizard(WizardLanguage, Rc): - skin = """ - - - - - - - - - - - - - - - """ - - def __init__(self, session): - self.xmlfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/imagewizard.xml") - WizardLanguage.__init__(self, session, showSteps=False, showStepSlider=False) - Rc.__init__(self) - self.session = session - self["wizard"] = Pixmap() - self.selectedDevice = None - - def markDone(self): - pass - - def listDevices(self): - list = [(r.description, r.mountpoint) for r in harddiskmanager.getMountedPartitions(onlyhotplug=False)] - for x in list: - result = access(x[1], W_OK) and access(x[1], R_OK) - if result is False or x[1] == '/': - list.remove(x) - for x in list: - if x[1].startswith('/autofs/'): - list.remove(x) - return list - - def deviceSelectionMade(self, index): - self.deviceSelect(index) - - def deviceSelectionMoved(self): - self.deviceSelect(self.selection) - - def deviceSelect(self, device): - self.selectedDevice = device - config.plugins.configurationbackup.backuplocation.value = self.selectedDevice - config.plugins.configurationbackup.backuplocation.save() - config.plugins.configurationbackup.save() - - -if config.misc.firstrun.value: - wizardManager.registerWizard(ImageWizard, backupAvailable, priority=10) diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am b/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am deleted file mode 100644 index 2267b81ae7c..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -installdir = $(pkglibdir)/python/Plugins/SystemPlugins/SoftwareManager - -SUBDIRS = meta - -install_PYTHON = \ - __init__.py \ - plugin.py \ - BackupRestore.py \ - ImageWizard.py \ - SoftwareTools.py - -dist_install_DATA = \ - imagewizard.xml \ - installable.png \ - installed.png \ - install.png \ - noprev.png \ - remove.png \ - update.png \ - upgradeable.png \ - upgrade.png diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py deleted file mode 100644 index 294715406c0..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py +++ /dev/null @@ -1,277 +0,0 @@ -# -*- coding: iso-8859-1 -*- -from time import time -from boxbranding import getImageVersion - -from enigma import eConsoleAppContainer - -from Components.Console import Console -from Components.PackageInfo import PackageInfoHandler -from Components.Language import language -from Components.Sources.List import List -from Components.Ipkg import IpkgComponent -from Components.Network import iNetwork -from Tools.Directories import resolveFilename, SCOPE_METADIR -from boxbranding import getBoxType - - -class SoftwareTools(PackageInfoHandler): - lastDownloadDate = None - NetworkConnectionAvailable = None - list_updating = False - available_updates = 0 - available_updatelist = [] - available_packetlist = [] - installed_packetlist = {} - - def __init__(self): - aboutInfo = getImageVersion() - if aboutInfo.startswith("dev-"): - self.ImageVersion = 'Experimental' - else: - self.ImageVersion = 'Stable' - self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country" - PackageInfoHandler.__init__(self, self.statusCallback, neededTag='ALL_TAGS', neededFlag=self.ImageVersion) - self.directory = resolveFilename(SCOPE_METADIR) - self.list = List([]) - self.NotifierCallback = None - self.Console = Console() - self.UpdateConsole = Console() - self.cmdList = [] - self.unwanted_extensions = ('-dbg', '-dev', '-doc', '-staticdev', '-src') - self.ipkg = IpkgComponent() - self.ipkg.addCallback(self.ipkgCallback) - - def statusCallback(self, status, progress): - pass - - def startSoftwareTools(self, callback=None): - if callback is not None: - self.NotifierCallback = callback - iNetwork.checkNetworkState(self.checkNetworkCB) - - def checkNetworkCB(self, data): - if data is not None: - if data <= 2: - self.NetworkConnectionAvailable = True - self.getUpdates() - else: - self.NetworkConnectionAvailable = False - self.getUpdates() - - def getUpdates(self, callback=None): - if self.lastDownloadDate is None: - if self.NetworkConnectionAvailable: - self.lastDownloadDate = time() - if self.list_updating is False and callback is None: - self.list_updating = True - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - elif self.list_updating is False and callback is not None: - self.list_updating = True - self.NotifierCallback = callback - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - elif self.list_updating is True and callback is not None: - self.NotifierCallback = callback - else: - self.list_updating = False - if callback is not None: - callback(False) - elif self.NotifierCallback is not None: - self.NotifierCallback(False) - else: - if self.NetworkConnectionAvailable: - self.lastDownloadDate = time() - if self.list_updating is False and callback is None: - self.list_updating = True - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - elif self.list_updating is False and callback is not None: - self.list_updating = True - self.NotifierCallback = callback - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - elif self.list_updating is True and callback is not None: - self.NotifierCallback = callback - else: - if self.list_updating and callback is not None: - self.NotifierCallback = callback - self.startIpkgListAvailable() - else: - self.list_updating = False - if callback is not None: - callback(False) - elif self.NotifierCallback is not None: - self.NotifierCallback(False) - - def ipkgCallback(self, event, param): - if event == IpkgComponent.EVENT_ERROR: - self.list_updating = False - if self.NotifierCallback is not None: - self.NotifierCallback(False) - elif event == IpkgComponent.EVENT_DONE: - if self.list_updating: - self.startIpkgListAvailable() - pass - - def startIpkgListAvailable(self, callback=None): - if callback is not None: - self.list_updating = True - if self.list_updating: - if not self.UpdateConsole: - self.UpdateConsole = Console() - cmd = self.ipkg.ipkg + " list" - self.UpdateConsole.ePopen(cmd, self.IpkgListAvailableCB, callback) - - def IpkgListAvailableCB(self, result, retval, extra_args=None): - (callback) = extra_args or None - if result: - if self.list_updating: - self.available_packetlist = [] - for x in result.splitlines(): - tokens = x.split(' - ') - name = tokens[0].strip() - if not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 1 and tokens[1].strip() or "" - descr = l > 2 and tokens[2].strip() or "" - self.available_packetlist.append([name, version, descr]) - if callback is None: - self.startInstallMetaPackage() - else: - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - callback(True) - else: - self.list_updating = False - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - if callback is not None: - callback(False) - - def startInstallMetaPackage(self, callback=None): - if callback is not None: - self.list_updating = True - if self.list_updating: - if self.NetworkConnectionAvailable: - if not self.UpdateConsole: - self.UpdateConsole = Console() - cmd = self.ipkg.ipkg + " install enigma2-meta enigma2-plugins-meta enigma2-skins-meta" - self.UpdateConsole.ePopen(cmd, self.InstallMetaPackageCB, callback) - else: - self.InstallMetaPackageCB(True) - - def InstallMetaPackageCB(self, result, retval=None, extra_args=None): - (callback) = extra_args or None - if result: - self.fillPackagesIndexList() - if callback is None: - self.startIpkgListInstalled() - else: - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - callback(True) - else: - self.list_updating = False - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - if callback is not None: - callback(False) - - def startIpkgListInstalled(self, callback=None): - if callback is not None: - self.list_updating = True - if self.list_updating: - if not self.UpdateConsole: - self.UpdateConsole = Console() - cmd = self.ipkg.ipkg + " list_installed" - self.UpdateConsole.ePopen(cmd, self.IpkgListInstalledCB, callback) - - def IpkgListInstalledCB(self, result, retval, extra_args=None): - (callback) = extra_args or None - if result: - self.installed_packetlist = {} - for x in result.splitlines(): - tokens = x.split(' - ') - name = tokens[0].strip() - if not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 1 and tokens[1].strip() or "" - self.installed_packetlist[name] = version - for package in self.packagesIndexlist[:]: - if not self.verifyPrerequisites(package[0]["prerequisites"]): - self.packagesIndexlist.remove(package) - for package in self.packagesIndexlist[:]: - attributes = package[0]["attributes"] - if "packagetype" in attributes: - if attributes["packagetype"] == "internal": - self.packagesIndexlist.remove(package) - if callback is None: - self.countUpdates() - else: - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - callback(True) - else: - self.list_updating = False - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - if callback is not None: - callback(False) - - def countUpdates(self, callback=None): - self.available_updates = 0 - self.available_updatelist = [] - for package in self.packagesIndexlist[:]: - attributes = package[0]["attributes"] - packagename = attributes["packagename"] - for x in self.available_packetlist: - if x[0] == packagename: - if packagename in self.installed_packetlist: - if self.installed_packetlist[packagename] != x[1]: - self.available_updates += 1 - self.available_updatelist.append([packagename]) - - self.list_updating = False - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - if callback is not None: - callback(True) - callback = None - elif self.NotifierCallback is not None: - self.NotifierCallback(True) - self.NotifierCallback = None - - def startIpkgUpdate(self, callback=None): - if not self.Console: - self.Console = Console() - cmd = self.ipkg.ipkg + " update" - self.Console.ePopen(cmd, self.IpkgUpdateCB, callback) - - def IpkgUpdateCB(self, result, retval, extra_args=None): - (callback) = extra_args or None - if result: - if self.Console: - if not self.Console.appContainers: - if callback is not None: - callback(True) - callback = None - - def cleanupSoftwareTools(self): - self.list_updating = False - if self.NotifierCallback is not None: - self.NotifierCallback = None - self.ipkg.stop() - if self.Console is not None: - self.Console.killAll() - if self.UpdateConsole is not None: - self.UpdateConsole.killAll() - - def verifyPrerequisites(self, prerequisites): - if "hardware" in prerequisites: - hardware_found = False - for hardware in prerequisites["hardware"]: - if hardware == getBoxType(): - hardware_found = True - if not hardware_found: - return False - return True - - -iSoftwareTools = SoftwareTools() diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/__init__.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml b/lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml deleted file mode 100644 index 374a915c64a..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - -from Plugins.SystemPlugins.SoftwareManager.ImageWizard import checkConfigBackup -self.backuppath = checkConfigBackup() -self.condition = (self.backuppath is not None and config.misc.firstrun.value) - - - - - - - -self.clearSelectedKeys() -self.selectKey("OK") - - - - - - - - - - - - - - - - - - - - - - - - - - - - -self.currStep = self.getStepWithID('backupresult') -self.afterAsyncCode() - - - - - -from Plugins.SystemPlugins.SoftwareManager.ImageWizard import checkBackupFile -self.backuppath = checkBackupFile() -self.condition = (self.backuppath is True) - - - - - - -from Plugins.SystemPlugins.SoftwareManager.ImageWizard import checkBackupFile -self.backuppath = checkBackupFile() -self.condition = (self.backuppath is False) - - - - - - - - - - - - - - - - - - - - - - - - - - - -from enigma import quitMainloop -quitMainloop(1) - - - - - - -self.condition = self.isLastWizard - - - - diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/install.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/install.png deleted file mode 100644 index 1287c35a683..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/install.png and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png deleted file mode 100644 index a9193039a06..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png deleted file mode 100644 index 75dfc4f33a1..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/Makefile.am b/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/Makefile.am deleted file mode 100644 index bf064c29470..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -installdir = $(datadir)/meta - -dist_install_DATA = plugin_softwaremanager.xml - -EXTRA_DIST = softwaremanager_en.jpg softwaremanager_de.jpg diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/plugin_softwaremanager.xml b/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/plugin_softwaremanager.xml deleted file mode 100644 index 0b0f7a67ce1..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/plugin_softwaremanager.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - Dream Multimedia - SoftwareManager - enigma2-plugin-systemplugins-softwaremanager - Software manager manages your receiver software - The software manager manages your receiver's software.\n - It's easy to update your receiver's software, install or remove plugins or even backup and restore your system settings. - - - - - - - - - diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_de.jpg b/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_de.jpg deleted file mode 100644 index 54e64196916..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_de.jpg and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_en.jpg b/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_en.jpg deleted file mode 100644 index 0832f0ac8c6..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_en.jpg and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/noprev.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/noprev.png deleted file mode 100644 index 0a7cf2b480b..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/noprev.png and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py deleted file mode 100644 index 8e680a12ec2..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py +++ /dev/null @@ -1,2013 +0,0 @@ -from boxbranding import getMachineBrand, getMachineName -from pickle import dump, load -from os import path as os_path, stat, mkdir, makedirs, listdir, access, remove, W_OK, R_OK, F_OK -from time import time -from stat import ST_MTIME - -from enigma import eTimer, getDesktop, ePicLoad, eRCInput, getPrevAsciiCode, eEnv -from twisted.web import client - -from Plugins.Plugin import PluginDescriptor -from Screens.ChoiceBox import ChoiceBox -from Screens.MessageBox import MessageBox -from Screens.Screen import Screen -from Screens.Standby import TryQuitMainloop -from Screens.Ipkg import Ipkg -from Screens.SoftwareUpdate import UpdatePlugin -from Components.ActionMap import ActionMap, NumberActionMap -from Components.Input import Input -from Components.Ipkg import IpkgComponent -from Components.Sources.StaticText import StaticText -from Components.ScrollLabel import ScrollLabel -from Components.Pixmap import Pixmap -from Components.MenuList import MenuList -from Components.Sources.List import List -from Components.Harddisk import harddiskmanager -from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigText, ConfigLocations, ConfigYesNo, ConfigSelection -from Components.ConfigList import ConfigListScreen -from Components.Console import Console -from Components.SelectionList import SelectionList -from Components.PluginComponent import plugins -from Components.PackageInfo import PackageInfoHandler -from Components.Language import language -from Components.AVSwitch import AVSwitch -from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR -from Tools.LoadPixmap import LoadPixmap -from Tools.NumericalTextInput import NumericalTextInput -from ImageWizard import ImageWizard -from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename -from SoftwareTools import iSoftwareTools - - -config.plugins.configurationbackup = ConfigSubsection() -config.plugins.configurationbackup.backuplocation = ConfigText(default='/media/hdd/', visible_width=50, fixed_size=False) -config.plugins.configurationbackup.backupdirs = ConfigLocations(default=[eEnv.resolve('${sysconfdir}/enigma2/'), '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/wpa_supplicant.ath0.conf', '/etc/wpa_supplicant.wlan0.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname']) - -config.plugins.softwaremanager = ConfigSubsection() -config.plugins.softwaremanager.overwriteConfigFiles = ConfigSelection( - [ - ("Y", _("Yes, always")), - ("N", _("No, never")), - ("ask", _("Always ask")) - ], "Y") -config.plugins.softwaremanager.onSetupMenu = ConfigYesNo(default=False) -config.plugins.softwaremanager.onBlueButton = ConfigYesNo(default=False) -config.plugins.softwaremanager.epgcache = ConfigYesNo(default=False) - - -def write_cache(cache_file, cache_data): - #Does a pickle dump - if not os_path.isdir(os_path.dirname(cache_file)): - try: - mkdir(os_path.dirname(cache_file)) - except OSError: - print(os_path.dirname(cache_file), 'is a file') - fd = open(cache_file, 'w') - dump(cache_data, fd, -1) - fd.close() - - -def valid_cache(cache_file, cache_ttl): - #See if the cache file exists and is still living - try: - mtime = stat(cache_file)[ST_MTIME] - except: - return 0 - curr_time = time() - if (curr_time - mtime) > cache_ttl: - return 0 - else: - return 1 - - -def load_cache(cache_file): - #Does a pickle load - fd = open(cache_file) - cache_data = load(fd) - fd.close() - return cache_data - - -class UpdatePluginMenu(Screen): - skin = """ - - - - - - - {"template": [ - MultiContentEntryText(pos = (2, 2), size = (330, 24), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText, - ], - "fonts": [gFont("Regular", 22)], - "itemHeight": 25 - } - - - - - {"template": [ - MultiContentEntryText(pos = (2, 2), size = (240, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 2 is the Description, - ], - "fonts": [gFont("Regular", 22)], - "itemHeight": 300 - } - - - - """ - - def __init__(self, session, args=0): - Screen.__init__(self, session) - Screen.setTitle(self, _("Software management")) - self.skin_path = plugin_path - self.menu = args - self.list = [] - self.oktext = _("\nPress OK on your remote control to continue.") - self.menutext = _("Press MENU on your remote control for additional options.") - self.infotext = _("Press INFO on your remote control for additional information.") - self.text = "" - self.backupdirs = ' '.join(config.plugins.configurationbackup.backupdirs.value) - if self.menu == 0: - print("building menu entries") - self.list.append(("install-extensions", _("Manage extensions"), _("\nManage extensions or plugins for your %s %s") % (getMachineBrand(), getMachineName()) + self.oktext, None)) - self.list.append(("software-update", _("Software update"), _("\nOnline update of your %s %s software.") % (getMachineBrand(), getMachineName()) + self.oktext, None)) - self.list.append(("software-restore", _("Software restore"), _("\nRestore your %s %s with a new firmware.") % (getMachineBrand(), getMachineName()) + self.oktext, None)) - self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your %s %s settings.") % (getMachineBrand(), getMachineName()) + self.oktext + "\n\n" + self.infotext, None)) - self.list.append(("system-restore", _("Restore system settings"), _("\nRestore your %s %s settings.") % (getMachineBrand(), getMachineName()) + self.oktext, None)) - self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local extensions and install them.") + self.oktext, None)) - for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER): - if "SoftwareSupported" in p.fnc: - callFnc = p.fnc["SoftwareSupported"](None) - if callFnc is not None: - if "menuEntryName" in p.fnc: - menuEntryName = p.fnc["menuEntryName"](None) - else: - menuEntryName = _('Extended Software') - if "menuEntryDescription" in p.fnc: - menuEntryDescription = p.fnc["menuEntryDescription"](None) - else: - menuEntryDescription = _('Extended Software Plugin') - self.list.append(('default-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc)) - if config.usage.setup_level.index >= 2: # expert+ - self.list.append(("advanced", _("Advanced options"), _("\nAdvanced options and settings.") + self.oktext, None)) - elif self.menu == 1: - self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date.") + self.oktext, None)) - self.list.append(("backuplocation", _("Select backup location"), _("\nSelect your backup device.\nCurrent device: ") + config.plugins.configurationbackup.backuplocation.value + self.oktext, None)) - self.list.append(("backupfiles", _("Select backup files"), _("Select files for backup.") + self.oktext + "\n\n" + self.infotext, None)) - if config.usage.setup_level.index >= 2: # expert+ - self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages.") + self.oktext, None)) - self.list.append(("ipkg-source", _("Select upgrade source"), _("\nEdit the upgrade source address.") + self.oktext, None)) - for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER): - if "AdvancedSoftwareSupported" in p.fnc: - callFnc = p.fnc["AdvancedSoftwareSupported"](None) - if callFnc is not None: - if "menuEntryName" in p.fnc: - menuEntryName = p.fnc["menuEntryName"](None) - else: - menuEntryName = _('Advanced software') - if "menuEntryDescription" in p.fnc: - menuEntryDescription = p.fnc["menuEntryDescription"](None) - else: - menuEntryDescription = _('Advanced software plugin') - self.list.append(('advanced-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc)) - - self["menu"] = List(self.list) - self["key_red"] = StaticText(_("Close")) - self["key_menu"] = StaticText(_("MENU")) - self["status"] = StaticText(self.menutext) - - self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "MenuActions", "NumberActions"], - { - "ok": self.go, - "back": self.close, - "red": self.close, - "menu": self.handleMenu, - "showEventInfo": self.handleInfo, - "1": self.go, - "2": self.go, - "3": self.go, - "4": self.go, - "5": self.go, - "6": self.go, - "7": self.go, - "8": self.go, - "9": self.go, - }, -1) - self.onLayoutFinish.append(self.layoutFinished) - self.backuppath = getBackupPath() - self.backupfile = getBackupFilename() - self.fullbackupfilename = self.backuppath + "/" + self.backupfile - self.onShown.append(self.setWindowTitle) - self.onChangedEntry = [] - self["menu"].onSelectionChanged.append(self.selectionChanged) - - def createSummary(self): - from Screens.PluginBrowser import PluginBrowserSummary - return PluginBrowserSummary - - def selectionChanged(self): - item = self["menu"].getCurrent() - if item: - name = item[1] - desc = item[2] - else: - name = "-" - desc = "" - for cb in self.onChangedEntry: - cb(name, desc) - - def layoutFinished(self): - idx = 0 - self["menu"].index = idx - - def setWindowTitle(self): - self.setTitle(_("Software management")) - - def cleanup(self): - iSoftwareTools.cleanupSoftwareTools() - - def getUpdateInfos(self): - if iSoftwareTools.NetworkConnectionAvailable is True: - if iSoftwareTools.available_updates is not 0: - self.text = _("There are at least %s updates available.") % (str(iSoftwareTools.available_updates)) - else: - self.text = "" # _("There are no updates available.") - if iSoftwareTools.list_updating is True: - self.text += "\n" + _("A search for available updates is currently in progress.") - else: - self.text = _("No network connection available.") - self["status"].setText(self.text) - - def handleMenu(self): - self.session.open(SoftwareManagerSetup) - - def handleInfo(self): - current = self["menu"].getCurrent() - if current: - currentEntry = current[0] - if currentEntry in ("system-backup", "backupfiles"): - self.session.open(SoftwareManagerInfo, mode="backupinfo") - - def go(self, num=None): - if num is not None: - num -= 1 - if not num < self["menu"].count(): - return - self["menu"].setIndex(num) - current = self["menu"].getCurrent() - if current: - currentEntry = current[0] - if self.menu == 0: - if currentEntry == "software-update": - self.session.open(UpdatePlugin) - elif currentEntry == "software-restore": - self.session.open(ImageWizard) - elif currentEntry == "install-extensions": - self.session.open(PluginManager, self.skin_path) - elif currentEntry == "system-backup": - self.session.openWithCallback(self.backupDone, BackupScreen, runBackup=True) - elif currentEntry == "system-restore": - if os_path.exists(self.fullbackupfilename): - self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore the backup?\nYour receiver will restart after the backup has been restored!")) - else: - self.session.open(MessageBox, _("Sorry, no backups found!"), MessageBox.TYPE_INFO, timeout=10) - elif currentEntry == "ipkg-install": - try: - from Plugins.Extensions.MediaScanner.plugin import main - main(self.session) - except: - self.session.open(MessageBox, _("Sorry, %s has not been installed!") % "MediaScanner", MessageBox.TYPE_INFO, timeout=10) - elif currentEntry == "default-plugin": - self.extended = current[3] - self.extended(self.session, None) - elif currentEntry == "advanced": - self.session.open(UpdatePluginMenu, 1) - elif self.menu == 1: - if currentEntry == "ipkg-manager": - self.session.open(PacketManager, self.skin_path) - elif currentEntry == "backuplocation": - parts = [(r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug=False)] - for x in parts: - if not access(x[1], F_OK | R_OK | W_OK) or x[1] == '/': - parts.remove(x) - if len(parts): - self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title=_("Please select medium to use as backup location"), list=parts) - elif currentEntry == "backupfiles": - self.session.openWithCallback(self.backupfiles_choosen, BackupSelection) - elif currentEntry == "advancedrestore": - self.session.open(RestoreMenu, self.skin_path) - elif currentEntry == "ipkg-source": - self.session.open(IPKGMenu, self.skin_path) - elif currentEntry == "advanced-plugin": - self.extended = current[3] - self.extended(self.session, None) - - def backupfiles_choosen(self, ret): - self.backupdirs = ' '.join(config.plugins.configurationbackup.backupdirs.value) - config.plugins.configurationbackup.backupdirs.save() - config.plugins.configurationbackup.save() - config.save() - - def backuplocation_choosen(self, option): - oldpath = config.plugins.configurationbackup.backuplocation.value - if option is not None: - config.plugins.configurationbackup.backuplocation.value = str(option[1]) - config.plugins.configurationbackup.backuplocation.save() - config.plugins.configurationbackup.save() - config.save() - newpath = config.plugins.configurationbackup.backuplocation.value - if newpath != oldpath: - self.createBackupfolders() - - def createBackupfolders(self): - print("Creating backup folder if not already there...") - self.backuppath = getBackupPath() - try: - if not os_path.exists(self.backuppath): - makedirs(self.backuppath) - except OSError: - self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\nPlease select a different one."), MessageBox.TYPE_INFO, timeout=10) - - def backupDone(self, retval=None): - if retval is True: - self.session.open(MessageBox, _("Backup completed."), MessageBox.TYPE_INFO, timeout=10) - else: - self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO, timeout=10) - - def startRestore(self, ret=False): - if ret: - self.exe = True - self.session.open(RestoreScreen, runRestore=True) - - -class SoftwareManagerSetup(ConfigListScreen, Screen): - - skin = """ - - - - - - - - - - - - - """ - - def __init__(self, session, skin_path=None): - Screen.__init__(self, session) - self.session = session - self.skin_path = skin_path - if self.skin_path is None: - self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager") - - self.onChangedEntry = [] - self.setup_title = _("Software manager setup") - self.overwriteConfigfilesEntry = None - - self.list = [] - ConfigListScreen.__init__(self, self.list, session=session, on_change=self.changedEntry) - - self["actions"] = ActionMap(["SetupActions", "MenuActions"], - { - "cancel": self.keyCancel, - "save": self.apply, - "menu": self.closeRecursive, - }, -2) - - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("OK")) - self["key_yellow"] = StaticText() - self["key_blue"] = StaticText() - self["introduction"] = StaticText() - - self.createSetup() - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setTitle(self.setup_title) - - def createSetup(self): - self.list = [] - self.overwriteConfigfilesEntry = getConfigListEntry(_("Overwrite configuration files?"), config.plugins.softwaremanager.overwriteConfigFiles) - self.list.append(self.overwriteConfigfilesEntry) - self.list.append(getConfigListEntry(_("show softwaremanager in plugin menu"), config.plugins.softwaremanager.onSetupMenu)) - self.list.append(getConfigListEntry(_("show softwaremanager on blue button"), config.plugins.softwaremanager.onBlueButton)) - self.list.append(getConfigListEntry(_("epg cache backup"), config.plugins.softwaremanager.epgcache)) - - self["config"].list = self.list - self["config"].l.setSeperation(400) - if not self.selectionChanged in self["config"].onSelectionChanged: - self["config"].onSelectionChanged.append(self.selectionChanged) - self.selectionChanged() - - def selectionChanged(self): - if self["config"].getCurrent() == self.overwriteConfigfilesEntry: - self["introduction"].setText(_("Overwrite configuration files during software upgrade?")) - else: - self["introduction"].setText("") - - def newConfig(self): - pass - - def keyLeft(self): - ConfigListScreen.keyLeft(self) - - def keyRight(self): - ConfigListScreen.keyRight(self) - - def confirm(self, confirmed): - if not confirmed: - print("not confirmed") - return - else: - self.keySave() - plugins.clearPluginList() - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - - def apply(self): - self.session.openWithCallback(self.confirm, MessageBox, _("Use these settings?"), MessageBox.TYPE_YESNO, timeout=20, default=True) - - def cancelConfirm(self, result): - if not result: - return - for x in self["config"].list: - x[1].cancel() - self.close() - - def keyCancel(self): - if self["config"].isChanged(): - self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"), MessageBox.TYPE_YESNO, timeout=20, default=False) - else: - self.close() - - # for summary: - def changedEntry(self): - for x in self.onChangedEntry: - x() - self.selectionChanged() - - def getCurrentEntry(self): - return self["config"].getCurrent()[0] - - def getCurrentValue(self): - return str(self["config"].getCurrent()[1].value) - - def createSummary(self): - from Screens.Setup import SetupSummary - return SetupSummary - - -class SoftwareManagerInfo(Screen): - skin = """ - - - - - - - - - - - - {"template": [ - MultiContentEntryText(pos = (5, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT | RT_HALIGN_CENTER, text = 0), # index 0 is the name - ], - "fonts": [gFont("Regular", 24),gFont("Regular", 22)], - "itemHeight": 26 - } - - - - - """ - - def __init__(self, session, skin_path=None, mode=None): - Screen.__init__(self, session) - self.session = session - self.mode = mode - self.skin_path = skin_path - if self.skin_path is None: - self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager") - - self["actions"] = ActionMap(["ShortcutActions", "WizardActions"], - { - "back": self.close, - "red": self.close, - }, -2) - - self.list = [] - self["list"] = List(self.list) - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText() - self["key_yellow"] = StaticText() - self["key_blue"] = StaticText() - self["introduction"] = StaticText() - - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setTitle(_("Softwaremanager information")) - if self.mode is not None: - self.showInfos() - - def showInfos(self): - if self.mode == "backupinfo": - self.list = [] - backupfiles = config.plugins.configurationbackup.backupdirs.value - for entry in backupfiles: - self.list.append((entry,)) - self['list'].setList(self.list) - - -class PluginManager(Screen, PackageInfoHandler): - - skin = """ - - - - - - - - - - - - {"templates": - {"default": (51,[ - MultiContentEntryText(pos = (0, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (0, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description - MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap - ]), - "category": (40,[ - MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description - MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap - ]) - }, - "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)], - "itemHeight": 52 - } - - - - """ - - def __init__(self, session, plugin_path=None, args=None): - Screen.__init__(self, session) - Screen.setTitle(self, _("Extensions management")) - self.session = session - self.skin_path = plugin_path - if self.skin_path is None: - self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager") - - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions"], - { - "ok": self.handleCurrent, - "back": self.exit, - "red": self.exit, - "green": self.handleCurrent, - "yellow": self.handleSelected, - "showEventInfo": self.handleSelected, - "displayHelp": self.handleHelp, - }, -1) - - self.list = [] - self.statuslist = [] - self.selectedFiles = [] - self.categoryList = [] - self.packetlist = [] - self["list"] = List(self.list) - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText("") - self["key_yellow"] = StaticText("") - self["key_blue"] = StaticText("") - self["status"] = StaticText("") - - self.cmdList = [] - self.oktext = _("\nAfter pressing OK, please wait!") - if not self.selectionChanged in self["list"].onSelectionChanged: - self["list"].onSelectionChanged.append(self.selectionChanged) - - self.currList = "" - self.currentSelectedTag = None - self.currentSelectedIndex = None - self.currentSelectedPackage = None - self.saved_currentSelectedPackage = None - self.restartRequired = False - - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.getUpdateInfos) - - def setWindowTitle(self): - self.setTitle(_("Extensions management")) - - def exit(self): - if self.currList == "packages": - self.currList = "category" - self.currentSelectedTag = None - self["list"].style = "category" - self['list'].setList(self.categoryList) - self["list"].setIndex(self.currentSelectedIndex) - self["list"].updateList(self.categoryList) - self.selectionChanged() - else: - iSoftwareTools.cleanupSoftwareTools() - self.prepareInstall() - if len(self.cmdList): - self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList) - else: - self.close() - - def handleHelp(self): - if self.currList != "status": - self.session.open(PluginManagerHelp, self.skin_path) - - def setState(self, status=None): - if status: - self.currList = "status" - self.statuslist = [] - self["key_green"].setText("") - self["key_blue"].setText("") - self["key_yellow"].setText("") - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if status == 'update': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - self.statuslist.append((_("Updating software catalog"), '', _("Searching for available updates. Please wait..."), '', '', statuspng, divpng, None, '')) - elif status == 'sync': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - self.statuslist.append((_("Package list update"), '', _("Searching for new installed or removed packages. Please wait..."), '', '', statuspng, divpng, None, '')) - elif status == 'error': - self["key_green"].setText(_("Continue")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - self.statuslist.append((_("Error"), '', _("An error occurred while downloading the packetlist. Please try again."), '', '', statuspng, divpng, None, '')) - self["list"].style = "default" - self['list'].setList(self.statuslist) - - def getUpdateInfos(self): - if iSoftwareTools.lastDownloadDate is not None and iSoftwareTools.NetworkConnectionAvailable is False: - self.rebuildList() - else: - self.setState('update') - iSoftwareTools.startSoftwareTools(self.getUpdateInfosCB) - - def getUpdateInfosCB(self, retval=None): - if retval is not None: - if retval is True: - if iSoftwareTools.available_updates is not 0: - self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + ' ' + _("updates available.")) - else: - self["status"].setText(_("There are no updates available.")) - self.rebuildList() - elif retval is False: - if iSoftwareTools.lastDownloadDate is None: - self.setState('error') - if iSoftwareTools.NetworkConnectionAvailable: - self["status"].setText(_("Updatefeed not available.")) - else: - self["status"].setText(_("No network connection available.")) - else: - iSoftwareTools.lastDownloadDate = time() - iSoftwareTools.list_updating = True - self.setState('update') - iSoftwareTools.getUpdates(self.getUpdateInfosCB) - - def rebuildList(self, retval=None): - if self.currentSelectedTag is None: - self.buildCategoryList() - else: - self.buildPacketList(self.currentSelectedTag) - - def selectionChanged(self): - current = self["list"].getCurrent() - self["status"].setText("") - if current: - if self.currList == "packages": - self["key_red"].setText(_("Back")) - if current[4] == 'installed': - self["key_green"].setText(_("Uninstall")) - elif current[4] == 'installable': - self["key_green"].setText(_("Install")) - if iSoftwareTools.NetworkConnectionAvailable is False: - self["key_green"].setText("") - elif current[4] == 'remove': - self["key_green"].setText(_("Undo uninstall")) - elif current[4] == 'install': - self["key_green"].setText(_("Undo install")) - if iSoftwareTools.NetworkConnectionAvailable is False: - self["key_green"].setText("") - self["key_yellow"].setText(_("View details")) - self["key_blue"].setText("") - if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0: - self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + ' ' + _("updates available.")) - elif len(self.selectedFiles) is not 0: - self["status"].setText(str(len(self.selectedFiles)) + ' ' + _("packages selected.")) - else: - self["status"].setText(_("There are currently no outstanding actions.")) - elif self.currList == "category": - self["key_red"].setText(_("Close")) - self["key_green"].setText("") - self["key_yellow"].setText("") - self["key_blue"].setText("") - if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0: - self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + ' ' + _("updates available.")) - self["key_yellow"].setText(_("Update")) - elif len(self.selectedFiles) is not 0: - self["status"].setText(str(len(self.selectedFiles)) + ' ' + _("packages selected.")) - self["key_yellow"].setText(_("Process")) - else: - self["status"].setText(_("There are currently no outstanding actions.")) - - def getSelectionState(self, detailsFile): - for entry in self.selectedFiles: - if entry[0] == detailsFile: - return True - return False - - def handleCurrent(self): - current = self["list"].getCurrent() - if current: - if self.currList == "category": - self.currentSelectedIndex = self["list"].index - selectedTag = current[2] - self.buildPacketList(selectedTag) - elif self.currList == "packages": - if current[7] is not '': - idx = self["list"].getIndex() - detailsFile = self.list[idx][1] - if self.list[idx][7]: - for entry in self.selectedFiles: - if entry[0] == detailsFile: - self.selectedFiles.remove(entry) - else: - alreadyinList = False - for entry in self.selectedFiles: - if entry[0] == detailsFile: - alreadyinList = True - if not alreadyinList: - if iSoftwareTools.NetworkConnectionAvailable is False and current[4] in ('installable', 'install'): - pass - else: - self.selectedFiles.append((detailsFile, current[4], current[3])) - self.currentSelectedPackage = ((detailsFile, current[4], current[3])) - if current[4] == 'installed': - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True) - elif current[4] == 'installable': - if iSoftwareTools.NetworkConnectionAvailable: - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True) - elif current[4] == 'remove': - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False) - elif current[4] == 'install': - if iSoftwareTools.NetworkConnectionAvailable: - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable', False) - self["list"].setList(self.list) - self["list"].setIndex(idx) - self["list"].updateList(self.list) - self.selectionChanged() - elif self.currList == "status": - iSoftwareTools.lastDownloadDate = time() - iSoftwareTools.list_updating = True - self.setState('update') - iSoftwareTools.getUpdates(self.getUpdateInfosCB) - - def handleSelected(self): - current = self["list"].getCurrent() - if current: - if self.currList == "packages": - if current[7] is not '': - detailsfile = iSoftwareTools.directory[0] + "/" + current[1] - if os_path.exists(detailsfile): - self.saved_currentSelectedPackage = self.currentSelectedPackage - self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current) - else: - self.session.open(MessageBox, _("Sorry, no details available!"), MessageBox.TYPE_INFO, timeout=10) - elif self.currList == "category": - self.prepareInstall() - if len(self.cmdList): - self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList) - - def detailsClosed(self, result=None): - if result is not None: - if result is not False: - self.setState('sync') - iSoftwareTools.lastDownloadDate = time() - for entry in self.selectedFiles: - if entry == self.saved_currentSelectedPackage: - self.selectedFiles.remove(entry) - iSoftwareTools.startIpkgListInstalled(self.rebuildList) - - def buildEntryComponent(self, name, details, description, packagename, state, selected=False): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")): - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")) - else: - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")): - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")) - else: - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")): - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")) - else: - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) - if state == 'installed': - return name, details, description, packagename, state, installedpng, divpng, selected - elif state == 'installable': - return name, details, description, packagename, state, installablepng, divpng, selected - elif state == 'remove': - return name, details, description, packagename, state, removepng, divpng, selected - elif state == 'install': - return name, details, description, packagename, state, installpng, divpng, selected - - def buildPacketList(self, categorytag=None): - if categorytag is not None: - self.currList = "packages" - self.currentSelectedTag = categorytag - self.packetlist = [] - for package in iSoftwareTools.packagesIndexlist[:]: - prerequisites = package[0]["prerequisites"] - if "tag" in prerequisites: - for foundtag in prerequisites["tag"]: - if categorytag == foundtag: - attributes = package[0]["attributes"] - if "packagetype" in attributes: - if attributes["packagetype"] == "internal": - continue - self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]]) - else: - self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]]) - self.list = [] - for x in self.packetlist: - status = "" - name = x[0].strip() - details = x[1].strip() - description = x[2].strip() - if not description: - description = "No description available." - packagename = x[3].strip() - selectState = self.getSelectionState(details) - if packagename in iSoftwareTools.installed_packetlist: - if selectState: - status = "remove" - else: - status = "installed" - self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected=selectState)) - else: - if selectState: - status = "install" - else: - status = "installable" - self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected=selectState)) - if len(self.list): - self.list.sort(key=lambda x: x[0]) - self["list"].style = "default" - self['list'].setList(self.list) - self["list"].updateList(self.list) - self.selectionChanged() - - def buildCategoryList(self): - self.currList = "category" - self.categories = [] - self.categoryList = [] - for package in iSoftwareTools.packagesIndexlist[:]: - prerequisites = package[0]["prerequisites"] - if "tag" in prerequisites: - for foundtag in prerequisites["tag"]: - attributes = package[0]["attributes"] - if foundtag not in self.categories: - self.categories.append(foundtag) - self.categoryList.append(self.buildCategoryComponent(foundtag)) - self.categoryList.sort(key=lambda x: x[0]) - self["list"].style = "category" - self['list'].setList(self.categoryList) - self["list"].updateList(self.categoryList) - self.selectionChanged() - - def buildCategoryComponent(self, tag=None): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if tag is not None: - if tag == 'System': - return _("System"), _("View list of available system extensions"), tag, divpng - elif tag == 'Skin': - return _("Skins"), _("View list of available skins"), tag, divpng - elif tag == 'Recording': - return _("Recordings"), _("View list of available recording extensions"), tag, divpng - elif tag == 'Network': - return _("Network"), _("View list of available networking extensions"), tag, divpng - elif tag == 'CI': - return _("Common Interface"), _("View list of available CommonInterface extensions"), tag, divpng - elif tag == 'Default': - return _("Default settings"), _("View list of available default settings"), tag, divpng - elif tag == 'SAT': - return _("Satellite equipment"), _("View list of available Satellite equipment extensions."), tag, divpng - elif tag == 'Software': - return _("Software"), _("View list of available software extensions"), tag, divpng - elif tag == 'Multimedia': - return _("Multimedia"), _("View list of available multimedia extensions."), tag, divpng - elif tag == 'Display': - return _("Display and user interface"), _("View list of available display and userinterface extensions."), tag, divpng - elif tag == 'EPG': - return _("Electronic Program Guide"), _("View list of available EPG extensions."), tag, divpng - elif tag == 'Communication': - return _("Communication"), _("View list of available communication extensions."), tag, divpng - else: # dynamically generate non existent tags - return str(tag), _("View list of available ") + str(tag) + ' ' + _("extensions."), tag, divpng - - def prepareInstall(self): - self.cmdList = [] - if iSoftwareTools.available_updates > 0: - self.cmdList.append((IpkgComponent.CMD_UPGRADE, {"test_only": False})) - if self.selectedFiles and len(self.selectedFiles): - for plugin in self.selectedFiles: - detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0] - if os_path.exists(detailsfile): - iSoftwareTools.fillPackageDetails(plugin[0]) - self.package = iSoftwareTools.packageDetails[0] - if "attributes" in self.package[0]: - self.attributes = self.package[0]["attributes"] - if "needsRestart" in self.attributes: - self.restartRequired = True - if "package" in self.attributes: - self.packagefiles = self.attributes["package"] - if plugin[1] == 'installed': - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": package["name"]})) - else: - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": plugin[2]})) - else: - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": package["name"]})) - else: - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": plugin[2]})) - else: - if plugin[1] == 'installed': - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": plugin[2]})) - else: - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": plugin[2]})) - - def runExecute(self, result=None): - if result is not None: - if result[0] is True: - self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList=self.cmdList) - elif result[0] is False: - self.cmdList = result[1] - self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList=self.cmdList) - else: - self.close() - - def runExecuteFinished(self): - self.reloadPluginlist() - if plugins.restartRequired or self.restartRequired: - self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") + " " + _("Do you want to reboot your receiver?"), MessageBox.TYPE_YESNO) - else: - self.selectedFiles = [] - self.restartRequired = False - self.detailsClosed(True) - - def ExecuteReboot(self, result): - if result: - self.session.open(TryQuitMainloop, retvalue=3) - else: - self.selectedFiles = [] - self.restartRequired = False - self.detailsClosed(True) - - def reloadPluginlist(self): - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - - -class PluginManagerInfo(Screen): - skin = """ - - - - - - - - {"template": [ - MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state - MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap - ], - "fonts": [gFont("Regular", 24),gFont("Regular", 22)], - "itemHeight": 50 - } - - - - - """ - - def __init__(self, session, plugin_path, cmdlist=None): - Screen.__init__(self, session) - Screen.setTitle(self, _("Plugin manager activity information")) - self.session = session - self.skin_path = plugin_path - self.cmdlist = cmdlist - - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], - { - "ok": self.process_all, - "back": self.exit, - "red": self.exit, - "green": self.process_extensions, - }, -1) - - self.list = [] - self["list"] = List(self.list) - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Only extensions.")) - self["status"] = StaticText(_("Following tasks will be done after you press OK!")) - - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.rebuildList) - - def setWindowTitle(self): - self.setTitle(_("Plugin manager activity information")) - - def rebuildList(self): - self.list = [] - if self.cmdlist is not None: - for entry in self.cmdlist: - action = "" - info = "" - cmd = entry[0] - if cmd == 0: - action = 'install' - elif cmd == 2: - action = 'remove' - else: - action = 'upgrade' - args = entry[1] - if cmd == 0: - info = args['package'] - elif cmd == 2: - info = args['package'] - else: - info = _("%s %s software because updates are available.") % (getMachineBrand(), getMachineName()) - - self.list.append(self.buildEntryComponent(action, info)) - self['list'].setList(self.list) - self['list'].updateList(self.list) - - def buildEntryComponent(self, action, info): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")): - upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")) - else: - upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")): - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")) - else: - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - if action == 'install': - return _('Installing'), info, installpng, divpng - elif action == 'remove': - return _('Removing'), info, removepng, divpng - else: - return _('Upgrading'), info, upgradepng, divpng - - def exit(self): - self.close() - - def process_all(self): - self.close((True, None)) - - def process_extensions(self): - self.list = [] - if self.cmdlist is not None: - for entry in self.cmdlist: - cmd = entry[0] - if entry[0] in (0, 2): - self.list.append(entry) - self.close((False, self.list)) - - -class PluginManagerHelp(Screen): - skin = """ - - - - - - {"template": [ - MultiContentEntryText(pos = (50, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state - MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap - ], - "fonts": [gFont("Regular", 24),gFont("Regular", 22)], - "itemHeight": 50 - } - - - - - """ - - def __init__(self, session, plugin_path): - Screen.__init__(self, session) - Screen.setTitle(self, _("Plugin manager help")) - self.session = session - self.skin_path = plugin_path - - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], - { - "back": self.exit, - "red": self.exit, - }, -1) - - self.list = [] - self["list"] = List(self.list) - self["key_red"] = StaticText(_("Close")) - self["status"] = StaticText(_("A small overview of the available icon states and actions.")) - - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.rebuildList) - - def setWindowTitle(self): - self.setTitle(_("Plugin manager help")) - - def rebuildList(self): - self.list = [] - self.list.append(self.buildEntryComponent('install')) - self.list.append(self.buildEntryComponent('installable')) - self.list.append(self.buildEntryComponent('installed')) - self.list.append(self.buildEntryComponent('remove')) - self['list'].setList(self.list) - self['list'].updateList(self.list) - - def buildEntryComponent(self, state): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")): - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")) - else: - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")): - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")) - else: - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")): - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")) - else: - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) - - if state == 'installed': - return _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng - elif state == 'installable': - return _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng - elif state == 'install': - return _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng - elif state == 'remove': - return _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng - - def exit(self): - self.close() - - -class PluginDetails(Screen, PackageInfoHandler): - skin = """ - - - - - - - - - - - """ - - def __init__(self, session, plugin_path, packagedata=None): - Screen.__init__(self, session) - Screen.setTitle(self, _("Plugin details")) - self.skin_path = plugin_path - self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country" - self.attributes = None - PackageInfoHandler.__init__(self, self.statusCallback) - self.directory = resolveFilename(SCOPE_METADIR) - if packagedata: - self.pluginname = packagedata[0] - self.details = packagedata[1] - self.pluginstate = packagedata[4] - self.statuspicinstance = packagedata[5] - self.divpicinstance = packagedata[6] - self.fillPackageDetails(self.details) - - self.thumbnail = "" - - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], - { - "back": self.exit, - "red": self.exit, - "green": self.go, - "up": self.pageUp, - "down": self.pageDown, - "left": self.pageUp, - "right": self.pageDown, - }, -1) - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText("") - self["author"] = StaticText() - self["statuspic"] = Pixmap() - self["divpic"] = Pixmap() - self["screenshot"] = Pixmap() - self["detailtext"] = ScrollLabel() - - self["statuspic"].hide() - self["screenshot"].hide() - self["divpic"].hide() - - self.package = self.packageDetails[0] - if "attributes" in self.package[0]: - self.attributes = self.package[0]["attributes"] - self.restartRequired = False - self.cmdList = [] - self.oktext = _("\nAfter pressing OK, please wait!") - self.picload = ePicLoad() - self.picload.PictureData.get().append(self.paintScreenshotPixmapCB) - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.setInfos) - - def setWindowTitle(self): - self.setTitle(_("Details for plugin: ") + self.pluginname) - - def exit(self): - self.close(False) - - def pageUp(self): - self["detailtext"].pageUp() - - def pageDown(self): - self["detailtext"].pageDown() - - def statusCallback(self, status, progress): - pass - - def setInfos(self): - if "screenshot" in self.attributes: - self.loadThumbnail(self.attributes) - - if "name" in self.attributes: - self.pluginname = self.attributes["name"] - else: - self.pluginname = _("unknown") - - if "author" in self.attributes: - self.author = self.attributes["author"] - else: - self.author = _("unknown") - - if "description" in self.attributes: - self.description = _(self.attributes["description"].replace("\\n", "\n")) - else: - self.description = _("No description available.") - - self["author"].setText(_("Author: ") + self.author) - self["detailtext"].setText(_(self.description)) - if self.pluginstate in ('installable', 'install'): - if iSoftwareTools.NetworkConnectionAvailable: - self["key_green"].setText(_("Install")) - else: - self["key_green"].setText("") - else: - self["key_green"].setText(_("Remove")) - - def loadThumbnail(self, entry): - thumbnailUrl = None - if "screenshot" in entry: - thumbnailUrl = entry["screenshot"] - if self.language == "de": - if thumbnailUrl[-7:] == "_en.jpg": - thumbnailUrl = thumbnailUrl[:-7] + "_de.jpg" - - if thumbnailUrl is not None: - self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1] - print("[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail) - if iSoftwareTools.NetworkConnectionAvailable: - client.downloadPage(thumbnailUrl, self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed) - else: - self.setThumbnail(noScreenshot=True) - else: - self.setThumbnail(noScreenshot=True) - - def setThumbnail(self, noScreenshot=False): - if not noScreenshot: - filename = self.thumbnail - else: - filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png") - - sc = AVSwitch().getFramebufferScale() - self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000")) - self.picload.startDecode(filename) - - if self.statuspicinstance is not None: - self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__()) - self["statuspic"].show() - if self.divpicinstance is not None: - self["divpic"].instance.setPixmap(self.divpicinstance.__deref__()) - self["divpic"].show() - - def paintScreenshotPixmapCB(self, picInfo=None): - ptr = self.picload.getData() - if ptr is not None: - self["screenshot"].instance.setPixmap(ptr.__deref__()) - self["screenshot"].show() - else: - self.setThumbnail(noScreenshot=True) - - def go(self): - if "package" in self.attributes: - self.packagefiles = self.attributes["package"] - if "needsRestart" in self.attributes: - self.restartRequired = True - self.cmdList = [] - if self.pluginstate in ('installed', 'remove'): - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": package["name"]})) - if len(self.cmdList): - self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext) - else: - if iSoftwareTools.NetworkConnectionAvailable: - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": package["name"]})) - if len(self.cmdList): - self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext) - - def runUpgrade(self, result): - if result: - self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList=self.cmdList) - - def runUpgradeFinished(self): - self.reloadPluginlist() - if plugins.restartRequired or self.restartRequired: - self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") + " " + _("Do you want to reboot your receiver?"), MessageBox.TYPE_YESNO) - else: - self.close(True) - - def UpgradeReboot(self, result): - if result: - self.session.open(TryQuitMainloop, retvalue=3) - self.close(True) - - def runRemove(self, result): - if result: - self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList=self.cmdList) - - def runRemoveFinished(self): - self.close(True) - - def reloadPluginlist(self): - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - - def fetchFailed(self, string): - self.setThumbnail(noScreenshot=True) - print("[PluginDetails] fetch failed " + string.getErrorMessage()) - - -class IPKGMenu(Screen): - skin = """ - - - - - - - """ - - def __init__(self, session, plugin_path): - Screen.__init__(self, session) - Screen.setTitle(self, _("Select upgrade source to edit.")) - self.skin_path = plugin_path - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText(_("Edit")) - - self.sel = [] - self.val = [] - self.entry = False - self.exe = False - - self.path = "" - - self["actions"] = NumberActionMap(["SetupActions"], - { - "ok": self.KeyOk, - "cancel": self.keyCancel - }, -1) - - self["shortcuts"] = ActionMap(["ShortcutActions"], - { - "red": self.keyCancel, - "green": self.KeyOk, - }) - self["filelist"] = MenuList([]) - self.fill_list() - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setWindowTitle() - - def setWindowTitle(self): - self.setTitle(_("Select upgrade source to edit.")) - - def fill_list(self): - flist = [] - self.path = '/etc/opkg/' - if not os_path.exists(self.path): - self.entry = False - return - for file in listdir(self.path): - if file.endswith(".conf"): - if file not in ('arch.conf', 'opkg.conf'): - flist.append(file) - self.entry = True - self["filelist"].l.setList(flist) - - def KeyOk(self): - if (self.exe == False) and (self.entry == True): - self.sel = self["filelist"].getCurrent() - self.val = self.path + self.sel - self.session.open(IPKGSource, self.val) - - def keyCancel(self): - self.close() - - def Exit(self): - self.close() - - -class IPKGSource(Screen): - skin = """ - - - - - - - """ - - def __init__(self, session, configfile=None): - Screen.__init__(self, session) - self.session = session - self.configfile = configfile - text = "" - if self.configfile: - try: - fp = file(configfile, 'r') - sources = fp.readlines() - if sources: - text = sources[0] - fp.close() - except IOError: - pass - - desk = getDesktop(0) - x = int(desk.size().width()) - y = int(desk.size().height()) - - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Save")) - - if y >= 720: - self["text"] = Input(text, maxSize=False, type=Input.TEXT) - else: - self["text"] = Input(text, maxSize=False, visible_width=55, type=Input.TEXT) - - self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions", "ShortcutActions"], - { - "ok": self.go, - "back": self.close, - "red": self.close, - "green": self.go, - "left": self.keyLeft, - "right": self.keyRight, - "home": self.keyHome, - "end": self.keyEnd, - "deleteForward": self.keyDeleteForward, - "deleteBackward": self.keyDeleteBackward, - "1": self.keyNumberGlobal, - "2": self.keyNumberGlobal, - "3": self.keyNumberGlobal, - "4": self.keyNumberGlobal, - "5": self.keyNumberGlobal, - "6": self.keyNumberGlobal, - "7": self.keyNumberGlobal, - "8": self.keyNumberGlobal, - "9": self.keyNumberGlobal, - "0": self.keyNumberGlobal - }, -1) - - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setWindowTitle() - self["text"].right() - - def setWindowTitle(self): - self.setTitle(_("Edit upgrade source url.")) - - def go(self): - text = self["text"].getText() - if text: - fp = file(self.configfile, 'w') - fp.write(text) - fp.write("\n") - fp.close() - self.close() - - def keyLeft(self): - self["text"].left() - - def keyRight(self): - self["text"].right() - - def keyHome(self): - self["text"].home() - - def keyEnd(self): - self["text"].end() - - def keyDeleteForward(self): - self["text"].delete() - - def keyDeleteBackward(self): - self["text"].deleteBackward() - - def keyNumberGlobal(self, number): - self["text"].number(number) - - -class PacketManager(Screen, NumericalTextInput): - skin = """ - - - - - - - - {"template": [ - MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description - MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap - ], - "fonts": [gFont("Regular", 22),gFont("Regular", 14)], - "itemHeight": 52 - } - - - """ - - def __init__(self, session, plugin_path, args=None): - Screen.__init__(self, session) - NumericalTextInput.__init__(self) - self.session = session - self.skin_path = plugin_path - - if config.usage.show_channel_jump_in_servicelist.value == "alpha": - self.setUseableChars(u'abcdefghijklmnopqrstuvwxyz1234567890') - else: - self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz') - - self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "NumberActions", "InputActions", "InputAsciiActions", "KeyboardInputActions"], - { - "ok": self.go, - "back": self.exit, - "red": self.exit, - "green": self.reload, - "gotAsciiCode": self.keyGotAscii, - "1": self.keyNumberGlobal, - "2": self.keyNumberGlobal, - "3": self.keyNumberGlobal, - "4": self.keyNumberGlobal, - "5": self.keyNumberGlobal, - "6": self.keyNumberGlobal, - "7": self.keyNumberGlobal, - "8": self.keyNumberGlobal, - "9": self.keyNumberGlobal, - "0": self.keyNumberGlobal - }, -1) - - self.list = [] - self.statuslist = [] - self["list"] = List(self.list) - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText(_("Reload")) - - self.list_updating = True - self.packetlist = [] - self.installed_packetlist = {} - self.upgradeable_packages = {} - self.Console = Console() - self.cmdList = [] - self.cachelist = [] - self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs) - self.cache_file = eEnv.resolve('${libdir}/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache') # Path to cache directory - self.oktext = _("\nAfter pressing OK, please wait!") - self.unwanted_extensions = ('-dbg', '-dev', '-doc', '-staticdev', '-src', 'busybox') - - self.ipkg = IpkgComponent() - self.ipkg.addCallback(self.ipkgCallback) - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.rebuildList) - - rcinput = eRCInput.getInstance() - rcinput.setKeyboardMode(rcinput.kmAscii) - - def keyNumberGlobal(self, val): - key = self.getKey(val) - if key is not None: - keyvalue = key.encode("utf-8") - if len(keyvalue) == 1: - self.setNextIdx(keyvalue[0]) - - def keyGotAscii(self): - keyvalue = unichr(getPrevAsciiCode()).encode("utf-8") - if len(keyvalue) == 1: - self.setNextIdx(keyvalue[0]) - - def setNextIdx(self, char): - if char in ("0", "1", "a"): - self["list"].setIndex(0) - else: - idx = self.getNextIdx(char) - if idx and idx <= self["list"].count: - self["list"].setIndex(idx) - - def getNextIdx(self, char): - for idx, i in enumerate(self["list"].list): - if i[0] and (i[0][0] == char): - return idx - - def exit(self): - self.ipkg.stop() - if self.Console is not None: - self.Console.killAll() - rcinput = eRCInput.getInstance() - rcinput.setKeyboardMode(rcinput.kmNone) - self.close() - - def reload(self): - if os_path.exists(self.cache_file): - remove(self.cache_file) - self.list_updating = True - self.rebuildList() - - def setWindowTitle(self): - self.setTitle(_("Packet manager")) - - def setStatus(self, status=None): - if status: - self.statuslist = [] - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if status == 'update': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - self.statuslist.append((_("Package list update"), '', _("Trying to download a new packetlist. Please wait..."), '', statuspng, divpng)) - self['list'].setList(self.statuslist) - elif status == 'error': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - self.statuslist.append((_("Error"), '', _("An error occurred while downloading the packetlist. Please try again."), '', statuspng, divpng)) - self['list'].setList(self.statuslist) - - def rebuildList(self): - self.setStatus('update') - self.inv_cache = 0 - self.vc = valid_cache(self.cache_file, self.cache_ttl) - if self.cache_ttl > 0 and self.vc != 0: - try: - self.buildPacketList() - except: - self.inv_cache = 1 - if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0: - self.run = 0 - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - - def go(self, returnValue=None): - cur = self["list"].getCurrent() - if cur: - status = cur[3] - package = cur[0] - self.cmdList = [] - if status == 'installed': - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": package})) - if len(self.cmdList): - self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext) - elif status == 'upgradeable': - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": package})) - if len(self.cmdList): - self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext) - elif status == "installable": - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": package})) - if len(self.cmdList): - self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext) - - def runRemove(self, result): - if result: - self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList=self.cmdList) - - def runRemoveFinished(self): - self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") + " " + _("Do you want to reboot your receiver?"), MessageBox.TYPE_YESNO) - - def RemoveReboot(self, result): - if result is None: - return - if result is False: - cur = self["list"].getCurrent() - if cur: - item = self['list'].getIndex() - self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable') - self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable'] - self['list'].setList(self.list) - write_cache(self.cache_file, self.cachelist) - self.reloadPluginlist() - if result: - self.session.open(TryQuitMainloop, retvalue=3) - - def runUpgrade(self, result): - if result: - self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList=self.cmdList) - - def runUpgradeFinished(self): - self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") + " " + _("Do you want to reboot your receiver?"), MessageBox.TYPE_YESNO) - - def UpgradeReboot(self, result): - if result is None: - return - if result is False: - cur = self["list"].getCurrent() - if cur: - item = self['list'].getIndex() - self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed') - self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed'] - self['list'].setList(self.list) - write_cache(self.cache_file, self.cachelist) - self.reloadPluginlist() - if result: - self.session.open(TryQuitMainloop, retvalue=3) - - def ipkgCallback(self, event, param): - if event == IpkgComponent.EVENT_ERROR: - self.list_updating = False - self.setStatus('error') - elif event == IpkgComponent.EVENT_DONE: - if self.list_updating: - self.list_updating = False - if not self.Console: - self.Console = Console() - cmd = self.ipkg.ipkg + " list" - self.Console.ePopen(cmd, self.IpkgList_Finished) - pass - - def IpkgList_Finished(self, result, retval, extra_args=None): - result = result.replace('\n ', ' - ') - if result: - self.packetlist = [] - last_name = "" - for x in result.splitlines(): - if ' - ' in x: - tokens = x.split(' - ') - name = tokens[0].strip() - if name and not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 1 and tokens[1].strip() or "" - descr = l > 2 and tokens[2].strip() or "" - if name == last_name: - continue - last_name = name - self.packetlist.append([name, version, descr]) - elif len(self.packetlist) > 0: - # no ' - ' in the text, assume that this is the description - # therefore add this text to the last packet description - last_packet = self.packetlist[-1] - last_packet[2] = last_packet[2] + x - self.packetlist[:-1] + last_packet - - if not self.Console: - self.Console = Console() - cmd = self.ipkg.ipkg + " list_installed" - self.Console.ePopen(cmd, self.IpkgListInstalled_Finished) - - def IpkgListInstalled_Finished(self, result, retval, extra_args=None): - if result: - self.installed_packetlist = {} - for x in result.splitlines(): - tokens = x.split(' - ') - name = tokens[0].strip() - if not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 1 and tokens[1].strip() or "" - self.installed_packetlist[name] = version - if not self.Console: - self.Console = Console() - cmd = "opkg list-upgradable" - self.Console.ePopen(cmd, self.OpkgListUpgradeable_Finished) - - def OpkgListUpgradeable_Finished(self, result, retval, extra_args=None): - if result: - self.upgradeable_packages = {} - for x in result.splitlines(): - tokens = x.split(' - ') - name = tokens[0].strip() - if not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 2 and tokens[2].strip() or "" - self.upgradeable_packages[name] = version - self.buildPacketList() - - def buildEntryComponent(self, name, version, description, state): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if not description: - description = "No description available." - if state == 'installed': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")): - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")) - else: - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) - return name, version, _(description), state, installedpng, divpng - elif state == 'upgradeable': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgradeable.png")): - upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgradeable.png")) - else: - upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png")) - return name, version, _(description), state, upgradeablepng, divpng - else: - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")): - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")) - else: - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) - return name, version, _(description), state, installablepng, divpng - - def buildPacketList(self): - self.list = [] - self.cachelist = [] - if self.cache_ttl > 0 and self.vc != 0: - print('Loading packagelist cache from ', self.cache_file) - try: - self.cachelist = load_cache(self.cache_file) - if len(self.cachelist) > 0: - for x in self.cachelist: - self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3])) - self['list'].setList(self.list) - except: - self.inv_cache = 1 - - if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0: - print('rebuilding fresh package list') - for x in self.packetlist: - status = "" - if x[0] in self.installed_packetlist: - if x[0] in self.upgradeable_packages: - status = "upgradeable" - else: - status = "installed" - else: - status = "installable" - self.list.append(self.buildEntryComponent(x[0], x[1], x[2], status)) - self.cachelist.append([x[0], x[1], x[2], status]) - write_cache(self.cache_file, self.cachelist) - self['list'].setList(self.list) - - def reloadPluginlist(self): - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - - -class IpkgInstaller(Screen): - skin = """ - - - - - - - - - - - - - """ - - def __init__(self, session, list): - Screen.__init__(self, session) - - self.list = SelectionList() - self["list"] = self.list - - p = 0 - if len(list): - p = list[0].rfind("/") - title = list[0][:p] - self.title = ("%s %s %s") % (_("Install extensions"), _("from"), title) - - for listindex in range(len(list)): - self.list.addSelection(list[listindex][p + 1:], list[listindex], listindex, False) - self.list.sort() - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText(_("Install")) - self["key_yellow"] = StaticText() - self["key_blue"] = StaticText(_("Invert")) - self["introduction"] = StaticText(_("Press OK to toggle the selection.")) - - self["actions"] = ActionMap(["OkCancelActions", "ColorActions"], - { - "ok": self.list.toggleSelection, - "cancel": self.close, - "red": self.close, - "green": self.install, - "blue": self.list.toggleAllSelection - }, -1) - - def install(self): - list = self.list.getSelectionsList() - cmdList = [] - for item in list: - cmdList.append((IpkgComponent.CMD_INSTALL, {"package": item[1]})) - self.session.open(Ipkg, cmdList=cmdList) - - -def filescan_open(list, session, **kwargs): - filelist = [x.path for x in list] - session.open(IpkgInstaller, filelist) # list - - -def filescan(**kwargs): - from Components.Scanner import Scanner, ScanPath - return \ - Scanner(mimetypes=["application/x-debian-package"], - paths_to_scan=[ - ScanPath(path="ipk", with_subdirs=True), - ScanPath(path="", with_subdirs=False), - ], - name="Ipkg", - description=_("Install extensions."), - openfnc=filescan_open, ) - - -def UpgradeMain(session, **kwargs): - session.open(UpdatePluginMenu) - - -def startSetup(menuid): - if menuid == "setup" and config.plugins.softwaremanager.onSetupMenu.value: - return [(_("Software management"), UpgradeMain, "software_manager", 50)] - return [] - - -def Plugins(path, **kwargs): - global plugin_path - plugin_path = path - list = [ - PluginDescriptor(name=_("Software management"), description=_("Manage your %s %s's software") % (getMachineBrand(), getMachineName()), where=PluginDescriptor.WHERE_MENU, needsRestart=False, fnc=startSetup), - PluginDescriptor(name=_("Ipkg"), where=PluginDescriptor.WHERE_FILESCAN, needsRestart=False, fnc=filescan) - ] - if not config.plugins.softwaremanager.onSetupMenu.value and not config.plugins.softwaremanager.onBlueButton.value: - list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your %s %s's software") % (getMachineBrand(), getMachineName()), where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=False, fnc=UpgradeMain)) - if config.plugins.softwaremanager.onBlueButton.value: - list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your %s %s's software") % (getMachineBrand(), getMachineName()), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=False, fnc=UpgradeMain)) - return list diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/remove.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/remove.png deleted file mode 100644 index 4d00781e5f4..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/remove.png and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/update.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/update.png deleted file mode 100644 index 0ece6c76a7a..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/update.png and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/upgrade.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/upgrade.png deleted file mode 100644 index 135058409c1..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/upgrade.png and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png deleted file mode 100644 index 1702177f7b6..00000000000 Binary files a/lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png and /dev/null differ diff --git a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py index 26fbe7064e1..bd5540665e3 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py @@ -5,7 +5,6 @@ import glob from enigma import eTimer, eEnv, eDVBDB, quitMainloop -from boxbranding import getImageType, getImageDistro, getImageVersion, getImageBuild, getImageDevBuild, getMachineBrand, getMachineMake, getMachineName from Components.About import about from Components.ActionMap import ActionMap from Components.Button import Button @@ -16,6 +15,7 @@ from Components.Label import Label from Components.MenuList import MenuList from Components.Sources.StaticText import StaticText +from Components.SystemInfo import SystemInfo import Components.Task from Screens.MessageBox import MessageBox from Screens.Screen import Screen @@ -27,7 +27,7 @@ SETTINGSRESTOREQUESTIONID = "RestoreSettingsNotification" PLUGINRESTOREQUESTIONID = "RestorePluginsNotification" NOPLUGINS = "NoPluginsNotification" -defaultprefix = getImageDistro()[4:] +defaultprefix = SystemInfo["distro"][4:] def getMountChoices(): @@ -167,7 +167,7 @@ class VIXBackupManager(Screen): 10, 105, 540, 260, 20, # list 10, 370, 400, 30, 20, # backupstatus 26, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -581,7 +581,7 @@ def Stage3(self): self.kernelcheck = False AddPopupWithCallback( self.Stage6, - _("Your %s %s is not connected to a network. Please check your network settings and try again.") % (getMachineBrand(), getMachineName()), + _("Your %s %s is not connected to a network. Please check your network settings and try again.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]), MessageBox.TYPE_INFO, 15, NOPLUGINS @@ -601,7 +601,7 @@ def Stage3(self): self.kernelcheck = False AddPopupWithCallback( self.Stage6, - _("Your %s %s is not connected to the Internet. Please check your network settings and try again.") % (getMachineBrand(), getMachineName()), + _("Your %s %s is not connected to the Internet. Please check your network settings and try again.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]), MessageBox.TYPE_INFO, 15, NOPLUGINS @@ -656,8 +656,8 @@ def Stage3Complete(self, result, retval, extra_args): devmounts = [] self.plugfile = self.plugfiles[3] # print("[BackupManager] self.plugfile, self.plugfiles", self.plugfile, self.plugfiles) - for dir in ["/media/%s/%s" % (media, self.plugfile) for media in listdir("/media/") if path.isdir(path.join("/media/", media)) and path.exists("/media/%s/%s" % (media, self.plugfile))]: # noqa: F821 - if media not in ("autofs", "net"): + for dir in ["/media/%s/%s" % (media, self.plugfile) for media in listdir("/media/") if path.isdir(path.join("/media/", media)) and path.exists("/media/%s/%s" % (media, self.plugfile))]: + if media not in ("autofs", "net"): # noqa: F821 devmounts.append(dir) if len(devmounts): for x in devmounts: @@ -776,7 +776,7 @@ class BackupSelection(Screen): 140, 0, 140, 40, 20, 280, 0, 140, 40, 20, 5, 50, 550, 250, 25, 19, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -815,7 +815,10 @@ def layoutFinished(self): self.selectionChanged() def selectionChanged(self): - current = self["checkList"].getCurrent()[0] + cursor = self["checkList"].getCurrent() + if not cursor: + return + current = cursor[0] if current[2] is True: self["key_yellow"].setText(_("Deselect")) else: @@ -944,43 +947,9 @@ def closeRecursive(self): class VIXBackupManagerMenu(Setup): - skin = [""" - - - - - - - - - - - - - - - - - """, - 560, 550, # screen - 0, 0, 140, 40, # colors - 140, 0, 140, 40, - 280, 0, 140, 40, - 420, 0, 140, 40, - 0, 0, 140, 40, 20, - 140, 0, 140, 40, 20, - 280, 0, 140, 40, 20, - 420, 0, 140, 40, 20, - 450, 510, # HelpWindow - 0, 500, 35, 25, # VKeyIcon - 0, 50, 300, 20, 20, # footnote - 0, 90, 560, 375, 25, 19, # config - 0, 75, 560, 75, 18, # description - ] - def __init__(self, session, setup, plugin=None, PluginLanguageDomain=None): - Setup.__init__(self, session, setup, plugin, PluginLanguageDomain) self.skinName = "VIXBackupManagerMenu" + Setup.__init__(self, session, setup, plugin, PluginLanguageDomain) self["actions2"] = ActionMap( ["SetupActions", "ColorActions", "VirtualKeyboardActions", "MenuActions"], @@ -1014,7 +983,7 @@ class VIXBackupManagerLogView(TextBox): """, 560, 400, 0, 0, 560, 400, 16, - ] + ] # noqa: E124 def __init__(self, session, filename): TextBox.__init__(self, session, label="list") @@ -1094,12 +1063,12 @@ def BackuponTimer(self): self.backuptimer.stop() now = int(time()) wake = self.getBackupTime() - atLeast = 0 # If we're close enough, we're okay... + atLeast = 0 # noqa: F841 if we're close enough, we're okay... if wake - now < 60: print("[BackupManager] Backup onTimer occured at", strftime("%c", localtime(now))) from Screens.Standby import inStandby if not inStandby and config.backupmanager.query.value: # Check for querying enabled - message = _("Your %s %s is about to run a backup of your settings and to detect your plugins.\nDo you want to allow this?") % (getMachineBrand(), getMachineName()) + message = _("Your %s %s is about to run a backup of your settings and to detect your plugins.\nDo you want to allow this?") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) ybox = self.session.openWithCallback(self.doBackup, MessageBox, message, MessageBox.TYPE_YESNO, timeout=30) ybox.setTitle("Scheduled backup.") else: @@ -1374,12 +1343,12 @@ def Stage5(self): elif self.backuptype == self.TYPE_FACTORYRESET: backupType = "-FR-" imageSubBuild = "" - if getImageType() != "release": - imageSubBuild = ".%s" % getImageDevBuild() + if SystemInfo["imagetype"] != "release": + imageSubBuild = ".%s" % SystemInfo["imagedevbuild"] boxname = "" if config.backupmanager.showboxname.value: - boxname = "-" + getMachineMake() - self.Backupfile = self.BackupDirectory + config.backupmanager.folderprefix.value + boxname + "-" + getImageType()[0:3] + backupType + getImageVersion() + "." + getImageBuild() + imageSubBuild + "-" + backupdate.strftime("%Y%m%d-%H%M") + ".tar.gz" + boxname = "-" + SystemInfo["machinebuild"] + self.Backupfile = self.BackupDirectory + config.backupmanager.folderprefix.value + boxname + "-" + SystemInfo["imagetype"][0:3] + backupType + SystemInfo["imageversion"] + "." + SystemInfo["imagebuild"] + imageSubBuild + "-" + backupdate.strftime("%Y%m%d-%H%M") + ".tar.gz" with open(BackupFiles.tar_flist, "w") as tfl: # Need to create a list of what to backup, so that spaces and special characters don't get lost on, or mangle, the command line for fn in tmplist: tfl.write(fn + "\n") diff --git a/lib/python/Plugins/SystemPlugins/ViX/IPKInstaller.py b/lib/python/Plugins/SystemPlugins/ViX/IPKInstaller.py index 1b5b03dceea..e9d8fd72994 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/IPKInstaller.py +++ b/lib/python/Plugins/SystemPlugins/ViX/IPKInstaller.py @@ -40,7 +40,7 @@ class VIXIPKInstaller(Screen): 0, 50, 560, 50, 18, # lab1 10, 105, 540, 260, 20, # list 26, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -185,7 +185,7 @@ class IpkgInstaller(Screen): 5, 50, 540, 360, 20, # list 0, 410, 560, 2, 5, 420, 550, 30, 22, - ] + ] # noqa: E124 def __init__(self, session, list): Screen.__init__(self, session) diff --git a/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py b/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py index c4e76d5c187..e6b732514e5 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py @@ -3,7 +3,6 @@ import json import tempfile -from boxbranding import getBoxType, getImageType, getImageDistro, getImageVersion, getImageBuild, getImageDevBuild, getImageFolder, getImageFileSystem, getBrandOEM, getMachineBrand, getMachineName, getMachineBuild, getMachineMake, getMachineMtdRoot, getMachineRootFile, getMachineMtdKernel, getMachineKernelFile, getMachineMKUBIFS, getMachineUBINIZE from enigma import eTimer, fbClass from os import path, stat, system, mkdir, makedirs, listdir, remove, rename, rmdir, sep as ossep, statvfs, chmod, walk from shutil import copy, copyfile, move, rmtree @@ -57,7 +56,7 @@ def __onPartitionChange(*args, **kwargs): config.imagemanager.backuplocation.setChoices(choices=choices, default=getMountDefault(choices)) -defaultprefix = getImageDistro() +defaultprefix = SystemInfo["distro"] config.imagemanager = ConfigSubsection() config.imagemanager.autosettingsbackup = ConfigYesNo(default=True) choices = getMountChoices() @@ -102,7 +101,7 @@ def __onPartitionChange(*args, **kwargs): rmtree(config.imagemanager.backuplocation.value + "imagebackups/imagerestore") except Exception: pass -TMPDIR = config.imagemanager.backuplocation.value + "imagebackups/" + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-mount" +TMPDIR = config.imagemanager.backuplocation.value + "imagebackups/" + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-mount" if path.exists(TMPDIR + "/root") and path.ismount(TMPDIR + "/root"): try: system("umount " + TMPDIR + "/root") @@ -165,7 +164,7 @@ class VIXImageManager(Screen): 10, 105, 540, 260, 20, # list 10, 370, 400, 30, 20, # backupstatus 26, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -329,9 +328,9 @@ def populate_List(self): try: if not path.exists(self.BackupDirectory): mkdir(self.BackupDirectory, 0o755) - if path.exists(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup"): - system("swapoff " + self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") - remove(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") + if path.exists(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup"): + system("swapoff " + self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") + remove(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") self.refreshList() except Exception: self["lab1"].setText(_("Device: ") + config.imagemanager.backuplocation.value + "\n" + _("There is a problem with this device. Please reformat it and try again.")) @@ -427,7 +426,7 @@ def getImages(files): def checkMachineNameInFilename(filename): return model in filename or "-" + device_name + "-" in filename - model = getMachineMake() + model = SystemInfo["machinebuild"] device_name = HardwareInfo().get_device_name() imagesFound = [] if config.imagemanager.extensive_location_search.value: @@ -503,9 +502,9 @@ def keyRestorez1(self, retval): def keyRestore1(self): self.HasSDmmc = False self.multibootslot = 1 - self.MTDKERNEL = getMachineMtdKernel() - self.MTDROOTFS = getMachineMtdRoot() - if getMachineMake() == "et8500" and path.exists("/proc/mtd"): + self.MTDKERNEL = SystemInfo["mtdkernel"] + self.MTDROOTFS = SystemInfo["mtdrootfs"] + if SystemInfo["machinebuild"] == "et8500" and path.exists("/proc/mtd"): self.dualboot = self.dualBoot() recordings = self.session.nav.getRecordings() if not recordings: @@ -540,7 +539,7 @@ def keyRestore2(self, retval): else: self.MTDROOTFS = SystemInfo["canMultiBoot"][self.multibootslot]["root"].split("/")[2] if SystemInfo["HasHiSi"] and SystemInfo["MultiBootSlot"] > 4 and self.multibootslot < 4: - self.session.open(MessageBox, _("ImageManager - %s - cannot flash eMMC slot from sd card slot.") % getBoxType(), MessageBox.TYPE_INFO, timeout=10) + self.session.open(MessageBox, _("ImageManager - %s - cannot flash eMMC slot from sd card slot.") % SystemInfo["boxtype"], MessageBox.TYPE_INFO, timeout=10) return if self.sel: if SystemInfo["MultiBootSlot"] != 0 and config.imagemanager.autosettingsbackup.value: @@ -568,12 +567,12 @@ def keyRestore3(self, *args, **kwargs): def keyRestore4(self, result, retval, extra_args=None): if retval == 0: self.session.openWithCallback(self.restore_infobox.close, MessageBox, _("Flash image unzip successful."), MessageBox.TYPE_INFO, timeout=4) - if getMachineMake() == "et8500" and self.dualboot: + if SystemInfo["machinebuild"] == "et8500" and self.dualboot: message = _("ET8500 Multiboot: Yes to restore OS1 No to restore OS2:\n ") + self.sel[1] ybox = self.session.openWithCallback(self.keyRestore5_ET8500, MessageBox, message) ybox.setTitle(_("ET8500 Image Restore")) else: - MAINDEST = "%s/%s" % (self.TEMPDESTROOT, getImageFolder()) + MAINDEST = "%s/%s" % (self.TEMPDESTROOT, SystemInfo["imagedir"]) if pathExists("%s/SDAbackup" % MAINDEST) and self.multibootslot != 1: self.session.open(MessageBox, _("Multiboot only able to restore this backup to mmc slot1"), MessageBox.TYPE_INFO, timeout=20) print("[ImageManager] SF8008 mmc restore to SDcard failed:\n", end=' ') @@ -592,14 +591,14 @@ def keyRestore5_ET8500(self, answer): self.keyRestore6(1) def keyRestore6(self, ret): - MAINDEST = "%s/%s" % (self.TEMPDESTROOT, getImageFolder()) + MAINDEST = "%s/%s" % (self.TEMPDESTROOT, SystemInfo["imagedir"]) print("[ImageManager] MAINDEST=%s" % MAINDEST) if ret == 0: CMD = "/usr/bin/ofgwrite -r -k '%s'" % MAINDEST # normal non multiboot receiver if SystemInfo["canMultiBoot"]: if self.multibootslot == 0 and SystemInfo["HasKexecMultiboot"]: # reset Vu Multiboot slot0 - kz0 = getMachineMtdKernel() - rz0 = getMachineMtdRoot() + kz0 = SystemInfo["mtdkernel"] + rz0 = SystemInfo["mtdrootfs"] CMD = "/usr/bin/ofgwrite -k%s -r%s '%s'" % (kz0, rz0, MAINDEST) # slot0 treat as kernel/root only multiboot receiver elif SystemInfo["HasHiSi"] and SystemInfo["canMultiBoot"][self.multibootslot]["rootsubdir"] is None: # sf8008 type receiver using SD card in multiboot CMD = "/usr/bin/ofgwrite -r%s -k%s -m0 '%s'" % (self.MTDROOTFS, self.MTDKERNEL, MAINDEST) @@ -608,7 +607,7 @@ def keyRestore6(self, ret): copyfile("/boot/STARTUP_%s" % self.multibootslot, "/boot/STARTUP") elif SystemInfo["HasKexecMultiboot"]: if SystemInfo["HasKexecUSB"] and "mmcblk" not in self.MTDROOTFS: - CMD = "/usr/bin/ofgwrite -r%s -kzImage -s'%s/linuxrootfs' -m%s '%s'" % (self.MTDROOTFS, getBoxType()[2:], self.multibootslot, MAINDEST) + CMD = "/usr/bin/ofgwrite -r%s -kzImage -s'%s/linuxrootfs' -m%s '%s'" % (self.MTDROOTFS, SystemInfo["boxtype"][2:], self.multibootslot, MAINDEST) else: CMD = "/usr/bin/ofgwrite -r%s -kzImage -m%s '%s'" % (self.MTDROOTFS, self.multibootslot, MAINDEST) print("[ImageManager] running commnd:%s slot = %s" % (CMD, self.multibootslot)) @@ -691,13 +690,13 @@ def VuKexecCopyimage(self): installedHDD = True break if installedHDD and pathExists("/media/hdd"): - if not pathExists("/media/hdd/%s" % getBoxType()): - mkdir("/media/hdd/%s" % getBoxType()) + if not pathExists("/media/hdd/%s" % SystemInfo["boxtype"]): + mkdir("/media/hdd/%s" % SystemInfo["boxtype"]) for slotnum in range(1, 4): if pathExists("/linuxrootfs%s" % slotnum): - if pathExists("/media/hdd/%s/linuxrootfs%s/" % (getBoxType(), slotnum)): - rmtree("/media/hdd/%s/linuxrootfs%s" % (getBoxType(), slotnum), ignore_errors=True) - Console().ePopen("cp -R /linuxrootfs%s . /media/hdd/%s/" % (slotnum, getBoxType())) + if pathExists("/media/hdd/%s/linuxrootfs%s/" % (SystemInfo["boxtype"], slotnum)): + rmtree("/media/hdd/%s/linuxrootfs%s" % (SystemInfo["boxtype"], slotnum), ignore_errors=True) + Console().ePopen("cp -R /linuxrootfs%s . /media/hdd/%s/" % (slotnum, SystemInfo["boxtype"])) if not installedHDD: self.session.open(MessageBox, _("ImageManager - no HDD unable to backup Vu Multiboot eMMC slots"), MessageBox.TYPE_INFO, timeout=5) self.multibootslot = 0 # set slot0 to be flashed @@ -817,7 +816,7 @@ def BackuponTimer(self): from Screens.Standby import inStandby if not inStandby and config.imagemanager.query.value: - message = _("Your %s %s is about to create a full image backup, this can take about 6 minutes to complete.\nDo you want to allow this?") % (getMachineBrand(), getMachineName()) + message = _("Your %s %s is about to create a full image backup, this can take about 6 minutes to complete.\nDo you want to allow this?") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) ybox = self.session.openWithCallback(self.doBackup, MessageBox, message, MessageBox.TYPE_YESNO, timeout=30) ybox.setTitle("Scheduled backup.") else: @@ -892,7 +891,7 @@ class ImageBackup(Screen): 0, 50, 560, 50, 18, # lab1 10, 105, 540, 260, 20, # list 26, - ] + ] # noqa: E124 def __init__(self, session, updatebackup=False): Screen.__init__(self, session) @@ -903,28 +902,28 @@ def __init__(self, session, updatebackup=False): self.BackupDirectory = config.imagemanager.backuplocation.value + "imagebackups/" print("[ImageManager] Directory: " + self.BackupDirectory) self.BackupDate = strftime("%Y%m%d_%H%M%S", localtime()) - self.WORKDIR = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-temp" - self.TMPDIR = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-mount" + self.WORKDIR = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-temp" + self.TMPDIR = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-mount" backupType = "-" if updatebackup: backupType = "-SoftwareUpdate-" imageSubBuild = "" - if getImageType() != "release": - imageSubBuild = ".%s" % getImageDevBuild() - self.MAINDESTROOT = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + backupType + getImageVersion() + "." + getImageBuild() + imageSubBuild + "-" + self.BackupDate - self.KERNELFILE = getMachineKernelFile() - self.ROOTFSFILE = getMachineRootFile() - self.MAINDEST = self.MAINDESTROOT + "/" + getImageFolder() + "/" + if SystemInfo["imagetype"] != "release": + imageSubBuild = ".%s" % SystemInfo["imagedevbuild"] + self.MAINDESTROOT = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + backupType + SystemInfo["imageversion"] + "." + SystemInfo["imagebuild"] + imageSubBuild + "-" + self.BackupDate + self.KERNELFILE = SystemInfo["kernelfile"] + self.ROOTFSFILE = SystemInfo["rootfile"] + self.MAINDEST = self.MAINDESTROOT + "/" + SystemInfo["imagedir"] + "/" self.MAINDEST2 = self.MAINDESTROOT + "/" - self.MODEL = getMachineMake() - self.MCBUILD = getMachineBuild() - self.IMAGEDISTRO = getImageDistro() - self.DISTROVERSION = getImageVersion() - self.DISTROBUILD = getImageBuild() - self.KERNELBIN = getMachineKernelFile() - self.UBINIZE_ARGS = getMachineUBINIZE() - self.MKUBIFS_ARGS = getMachineMKUBIFS() - self.ROOTFSTYPE = getImageFileSystem().strip() + self.MODEL = SystemInfo["machinebuild"] + self.MCBUILD = SystemInfo["model"] + self.IMAGEDISTRO = SystemInfo["distro"] + self.DISTROVERSION = SystemInfo["imageversion"] + self.DISTROBUILD = SystemInfo["imagebuild"] + self.KERNELBIN = SystemInfo["kernelfile"] + self.UBINIZE_ARGS = SystemInfo["ubinize"] + self.MKUBIFS_ARGS = SystemInfo["mkubifs"] + self.ROOTFSTYPE = SystemInfo["imagefs"].strip() self.ROOTFSSUBDIR = "none" self.VuSlot0 = "" self.EMMCIMG = "none" @@ -938,8 +937,8 @@ def __init__(self, session, updatebackup=False): slot = SystemInfo["MultiBootSlot"] print("[ImageManager] slot: ", slot) if SystemInfo["HasKexecMultiboot"]: - self.MTDKERNEL = getMachineMtdKernel() if slot == 0 else SystemInfo["canMultiBoot"][slot]["kernel"] - self.MTDROOTFS = getMachineMtdRoot() if slot == 0 else SystemInfo["canMultiBoot"][slot]["root"].split("/")[2] + self.MTDKERNEL = SystemInfo["mtdkernel"] if slot == 0 else SystemInfo["canMultiBoot"][slot]["kernel"] + self.MTDROOTFS = SystemInfo["mtdrootfs"] if slot == 0 else SystemInfo["canMultiBoot"][slot]["root"].split("/")[2] self.VuSlot0 = "-VuSlot0" if slot == 0 else "" else: self.MTDKERNEL = SystemInfo["canMultiBoot"][slot]["kernel"].split("/")[2] @@ -950,9 +949,9 @@ def __init__(self, session, updatebackup=False): if SystemInfo["HasRootSubdir"] and slot != 0: self.ROOTFSSUBDIR = SystemInfo["canMultiBoot"][slot]["rootsubdir"] else: - self.MTDKERNEL = getMachineMtdKernel() - self.MTDROOTFS = getMachineMtdRoot() - if getMachineBuild() in ("gb7252", "gbx34k"): + self.MTDKERNEL = SystemInfo["mtdkernel"] + self.MTDROOTFS = SystemInfo["mtdrootfs"] + if SystemInfo["model"] in ("gb7252", "gbx34k"): self.GB4Kbin = "boot.bin" self.GB4Krescue = "rescue.bin" if "sda" in self.MTDKERNEL: @@ -1056,9 +1055,9 @@ def JobStart(self): try: if not path.exists(self.BackupDirectory): mkdir(self.BackupDirectory, 0o755) - if path.exists(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup"): - system("swapoff " + self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") - remove(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") + if path.exists(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup"): + system("swapoff " + self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") + remove(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") except Exception as e: print(str(e)) print("[ImageManager] Device: " + config.imagemanager.backuplocation.value + ", i don't seem to have write access to this device.") @@ -1117,15 +1116,15 @@ def MemCheck(self): self.SwapCreated = True def MemCheck2(self): - self.ConsoleB.ePopen("dd if=/dev/zero of=" + self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup bs=1024 count=61440", self.MemCheck3) + self.ConsoleB.ePopen("dd if=/dev/zero of=" + self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup bs=1024 count=61440", self.MemCheck3) def MemCheck3(self, result, retval, extra_args=None): if retval == 0: - self.ConsoleB.ePopen("mkswap " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup", self.MemCheck4) + self.ConsoleB.ePopen("mkswap " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup", self.MemCheck4) def MemCheck4(self, result, retval, extra_args=None): if retval == 0: - self.ConsoleB.ePopen("swapon " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup", self.MemCheck5) + self.ConsoleB.ePopen("swapon " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup", self.MemCheck5) def MemCheck5(self, result, retval, extra_args=None): self.SwapCreated = True @@ -1172,7 +1171,7 @@ def doBackup2(self): if "jffs2" in self.ROOTFSTYPE.split(): print("[ImageManager] Stage2: JFFS2 Detected.") self.ROOTFSTYPE = "jffs2" - if getMachineBuild() == "gb800solo": + if SystemInfo["model"] == "gb800solo": JFFS2OPTIONS = " --disable-compressor=lzo -e131072 -l -p125829120" else: JFFS2OPTIONS = " --disable-compressor=lzo --eraseblock=0x20000 -n -l" @@ -1191,7 +1190,7 @@ def doBackup2(self): output.write("vol_flags=autoresize\n") self.commands.append("mount -o bind,ro / %s/root" % self.TMPDIR) - if getMachineBuild() in ("h9", "i55plus"): + if SystemInfo["model"] in ("h9", "i55plus"): with open("/proc/cmdline", "r") as z: if SystemInfo["HasMMC"] and "root=/dev/mmcblk0p1" in z.read(): self.ROOTFSTYPE = "tar.bz2" @@ -1214,7 +1213,7 @@ def doBackup2(self): self.commands.append('echo "' + _("Create:") + " logo dump" + '"') self.commands.append("dd if=/dev/mtd4 of=%s/logo.bin" % self.WORKDIR) else: - if not getMachineBuild() in ("h8"): + if not SystemInfo["model"] in ("h8"): self.MKUBIFS_ARGS = "-m 2048 -e 126976 -c 4096 -F" self.UBINIZE_ARGS = "-m 2048 -p 128KiB" self.commands.append("touch %s/root.ubi" % self.WORKDIR) @@ -1237,7 +1236,7 @@ def doBackup2(self): else: self.commands.append("/bin/tar -jcf %s/rootfs.tar.bz2 -C %s/root --exclude ./var/nmbd --exclude ./.resizerootfs --exclude ./.resize-rootfs --exclude ./.resize-linuxrootfs --exclude ./.resize-userdata --exclude ./var/lib/samba/private/msg.sock ." % (self.WORKDIR, self.TMPDIR)) self.commands.append("sync") - if getMachineBuild() in ("gb7252", "gbx34k"): + if SystemInfo["model"] in ("gb7252", "gbx34k"): self.commands.append("dd if=/dev/mmcblk0p1 of=%s/boot.bin" % self.WORKDIR) self.commands.append("dd if=/dev/mmcblk0p3 of=%s/rescue.bin" % self.WORKDIR) print("[ImageManager] Stage2: Create: boot dump boot.bin:", self.MODEL) @@ -1436,7 +1435,7 @@ def doBackup5(self): else: move("%s/vmlinux.gz" % self.WORKDIR, "%s/%s" % (self.MAINDEST, self.KERNELFILE)) self.h9root = False - if getMachineBuild() in ("h9", "i55plus"): + if SystemInfo["model"] in ("h9", "i55plus"): system("mv %s/fastboot.bin %s/fastboot.bin" % (self.WORKDIR, self.MAINDEST)) system("mv %s/bootargs.bin %s/bootargs.bin" % (self.WORKDIR, self.MAINDEST)) system("mv %s/pq_param.bin %s/pq_param.bin" % (self.WORKDIR, self.MAINDEST)) @@ -1454,18 +1453,18 @@ def doBackup5(self): else: move("%s/rootfs.%s" % (self.WORKDIR, self.ROOTFSTYPE), "%s/%s" % (self.MAINDEST, self.ROOTFSFILE)) - if getMachineBuild() in ("gb7252", "gbx34k"): + if SystemInfo["model"] in ("gb7252", "gbx34k"): move("%s/%s" % (self.WORKDIR, self.GB4Kbin), "%s/%s" % (self.MAINDEST, self.GB4Kbin)) move("%s/%s" % (self.WORKDIR, self.GB4Krescue), "%s/%s" % (self.MAINDEST, self.GB4Krescue)) system("cp -f /usr/share/gpt.bin %s/gpt.bin" % self.MAINDEST) print("[ImageManager] Stage5: Create: gpt.bin:", self.MODEL) with open(self.MAINDEST + "/imageversion", "w") as fileout: - line = defaultprefix + "-" + getMachineMake() + "-" + getImageType() + "-backup-" + getImageVersion() + "." + getImageBuild() + "-" + self.BackupDate + line = defaultprefix + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-backup-" + SystemInfo["imageversion"] + "." + SystemInfo["imagebuild"] + "-" + self.BackupDate fileout.write(line) - if getBrandOEM() == "vuplus": - if getMachineBuild() == "vuzero": + if SystemInfo["brand"] == "vuplus": + if SystemInfo["model"] == "vuzero": with open(self.MAINDEST + "/force.update", "w") as fileout: line = "This file forces the update." fileout.write(line) @@ -1474,8 +1473,8 @@ def doBackup5(self): with open(self.MAINDEST + "/reboot.update", "w") as fileout: line = "This file forces a reboot after the update." fileout.write(line) - elif getBrandOEM() in ("xtrend", "gigablue", "octagon", "odin", "xp", "ini"): - if getBrandOEM() in ("xtrend", "octagon", "odin", "ini"): + elif SystemInfo["brand"] in ("xtrend", "gigablue", "octagon", "odin", "xp", "ini"): + if SystemInfo["brand"] in ("xtrend", "octagon", "odin", "ini"): with open(self.MAINDEST + "/noforce", "w") as fileout: line = "rename this file to 'force' to force an update without confirmation" fileout.write(line) @@ -1497,12 +1496,12 @@ def doBackup5(self): fileout.write(line1) print("[ImageManager] Stage5: Removing Swap.") - if path.exists(self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup"): - system("swapoff " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") - remove(self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") + if path.exists(self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup"): + system("swapoff " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") + remove(self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") if path.exists(self.WORKDIR): rmtree(self.WORKDIR) - if (path.exists(self.MAINDEST + "/" + self.ROOTFSFILE) and path.exists(self.MAINDEST + "/" + self.KERNELFILE)) or (getMachineBuild() in ("h9", "i55plus") and self.h9root): + if (path.exists(self.MAINDEST + "/" + self.ROOTFSFILE) and path.exists(self.MAINDEST + "/" + self.KERNELFILE)) or (SystemInfo["model"] in ("h9", "i55plus") and self.h9root): for root, dirs, files in walk(self.MAINDEST): for momo in dirs: chmod(path.join(root, momo), 0o644) @@ -1537,7 +1536,7 @@ def BackupComplete(self, answer=None): try: if config.imagemanager.number_to_keep.value > 0 and path.exists(self.BackupDirectory): # !?! images = listdir(self.BackupDirectory) - patt = config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-*.zip" + patt = config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-*.zip" emlist = [] for fil in images: if fnmatch.fnmatchcase(fil, patt): @@ -1588,14 +1587,14 @@ class ImageManagerDownload(Screen): 0, 50, 560, 50, 18, # lab1 10, 105, 540, 260, 20, # list 26, - ] + ] # noqa: E124 def __init__(self, session, BackupDirectory, imagefeed): Screen.__init__(self, session) self.setTitle(_("%s downloads") % imagefeed[DISTRO]) self.imagefeed = imagefeed self.BackupDirectory = BackupDirectory - self["lab1"] = Label(_("Select an image to download for %s:") % getMachineMake()) + self["lab1"] = Label(_("Select an image to download for %s:") % SystemInfo["machinebuild"]) self["key_red"] = Button(_("Close")) self["key_green"] = Button(_("Download")) self["ImageDown"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "KeyboardInputActions", "MenuActions"], { @@ -1617,7 +1616,7 @@ def __init__(self, session, BackupDirectory, imagefeed): self.setIndex = 0 self.expanded = [] self["list"] = ChoiceList(list=[ChoiceEntryComponent("", ((_("No images found on the selected download server...if password check validity")), "Waiter"))]) - self.getImageDistro() + self.SystemInfo["distro"] def showError(self): self.session.open(MessageBox, self.msg, MessageBox.TYPE_ERROR) @@ -1634,12 +1633,12 @@ def getImageDistro(self): self.pausetimer.callback.append(self.showError) self.pausetimer.start(50, True) return - boxtype = getMachineMake() + boxtype = SystemInfo["machinebuild"] if self.imagefeed[ACTION] == "HardwareInfo": boxtype = HardwareInfo().get_device_name() print("[ImageManager1] boxtype:%s" % (boxtype)) if "dm800" in boxtype: - boxtype = getMachineMake() + boxtype = SystemInfo["machinebuild"] if not self.imagesList: # Legacy: self.imagefeed[URL] didn't contain "%s" where to insert the boxname. @@ -1724,7 +1723,7 @@ def keyDownload(self): self.expanded.remove(currentSelected[0][0]) else: self.expanded.append(currentSelected[0][0]) - self.getImageDistro() + self.SystemInfo["distro"] elif currentSelected[0][1] != "Waiter": self.sel = currentSelected[0][0] @@ -1789,7 +1788,7 @@ def keySave(self): def check_URL_format(self, configElement): if configElement.value: - configElement.value = "%s%s" % (not (configElement.value.startswith("http://") or configElement.value.startswith("https://") or configElement.value.startswith("ftp://")) and "http://" or "", configElement.value) + configElement.value = "%s%s" % (not configElement.value.startswith(("http://", "https://", "ftp://")) and "http://" or "", configElement.value) configElement.value = configElement.value.strip("/") # remove any trailing slash else: configElement.value = configElement.default diff --git a/lib/python/Plugins/SystemPlugins/ViX/MountManager.py b/lib/python/Plugins/SystemPlugins/ViX/MountManager.py index 6ec967a0ae8..9006fe4364a 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/MountManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/MountManager.py @@ -2,7 +2,6 @@ from os import mkdir, path, rename, statvfs, system import re -from boxbranding import getMachineBrand, getMachineName # , getMachineBuild from enigma import eTimer from Components.ActionMap import ActionMap @@ -226,7 +225,7 @@ class VIXDevicesPanel(Screen): 140, 0, 140, 40, 20, 280, 0, 140, 40, 20, 420, 0, 140, 40, 20, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -377,7 +376,7 @@ class DeviceMountSetup(Screen, ConfigListScreen): 140, 0, 140, 40, 20, 0, 50, 560, 275, 26, 20, # config 0, 365, 560, 20, 18, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -398,7 +397,7 @@ def __init__(self, session): self.setconfTimer() def setconfTimer(self, result=None, retval=None, extra_args=None): - scanning = _("Please wait while scanning your %s %s devices...") % (getMachineBrand(), getMachineName()) + scanning = _("Please wait while scanning your %s %s devices...") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) self["lab1"].setText(scanning) self.activityTimer.start(10) @@ -424,9 +423,9 @@ def saveconfMounts(self): ybox.setTitle(_("Please wait.")) def delay(self, val): - message = _("The changes need a system restart to take effect.\nRestart your %s %s now?") % (getMachineBrand(), getMachineName()) + message = _("The changes need a system restart to take effect.\nRestart your %s %s now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) ybox = self.session.openWithCallback(self.restartBox, MessageBox, message, MessageBox.TYPE_YESNO) - ybox.setTitle(_("Restart %s %s.") % (getMachineBrand(), getMachineName())) + ybox.setTitle(_("Restart %s %s.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) def addconfFstab(self, result=None, retval=None, extra_args=None): # print("[MountManager] RESULT:", result) diff --git a/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py b/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py index fdfe977768f..3cfb1175555 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py +++ b/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py @@ -1,5 +1,4 @@ from os import listdir, path, stat -from boxbranding import getMachineBrand, getMachineName, getImageDistro from .BackupManager import isRestorableSettings, isRestorablePlugins, isRestorableKernel from Components.About import about @@ -36,14 +35,14 @@ def __init__(self, session): self.Console = Console() def getTranslation(self, text): - return _(text).replace("%s %s", "%s %s" % (getMachineBrand(), getMachineName())) + return _(text).replace("%s %s", "%s %s" % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) def listDevices(self): devmounts = [] list = [] files = [] mtimes = [] - defaultprefix = getImageDistro()[4:] + defaultprefix = SystemInfo["distro"][4:] for dir in ["/media/%s/backup" % media for media in listdir("/media/") if path.isdir(path.join("/media/", media))]: # noqa: F821 devmounts.append(dir) @@ -160,7 +159,7 @@ def buildList(self, action): print("[RestoreWizard] Stage 6: No Network") self.didPluginRestore = True self.NextStep = "reboot" - self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to the Internet. Please try using Backup manager to restore plugins later.") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) + self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to the Internet. Please try using Backup manager to restore plugins later.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) self.buildListRef.setTitle(_("Restore wizard")) elif self.feeds == "ERROR": self.NextStep = "pluginrestore" @@ -259,15 +258,15 @@ def doRestorePluginsTestComplete(self, result='', retval=None, extra_args=None): print("[RestoreWizard] Stage 4: Feeds Test Result", result) if result.find("wget returned 4") != -1: self.NextStep = "reboot" - self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to a network. Please try using the Backup manager to restore plugins later when a network connection is available.") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) + self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to a network. Please try using the Backup manager to restore plugins later when a network connection is available.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) self.buildListRef.setTitle(_("Restore wizard")) elif result.find("wget returned 8") != -1: self.NextStep = "reboot" - self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s could not connect to the plugin feeds at this time. Please try using the Backup manager to restore plugins later.") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) + self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s could not connect to the plugin feeds at this time. Please try using the Backup manager to restore plugins later.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) self.buildListRef.setTitle(_("Restore wizard")) elif result.find("bad address") != -1: self.NextStep = "reboot" - self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to the Internet. Please try using the Backup manager to restore plugins later.") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) + self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to the Internet. Please try using the Backup manager to restore plugins later.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) self.buildListRef.setTitle(_("Restore wizard")) elif result.find("wget returned 1") != -1 or result.find("wget returned 255") != -1 or result.find("404 Not Found") != -1: self.NextStep = "reboot" @@ -328,7 +327,7 @@ def doRestorePlugins2(self, result, retval, extra_args): devmounts = [] self.plugfile = self.plugfiles[3] for dir in ["/media/%s/%s" % (media, self.plugfile) for media in listdir("/media/") if path.isdir(path.join("/media/", media)) and path.exists("/media/%s/%s" % (media, self.plugfile))]: - if media not in ("autofs", "net"): + if media not in ("autofs", "net"): # noqa: F821 devmounts.append(dir) if len(devmounts): for x in devmounts: diff --git a/lib/python/Plugins/SystemPlugins/ViX/ScriptRunner.py b/lib/python/Plugins/SystemPlugins/ViX/ScriptRunner.py index ad9619b5f66..80e508c92c4 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/ScriptRunner.py +++ b/lib/python/Plugins/SystemPlugins/ViX/ScriptRunner.py @@ -46,6 +46,7 @@ def __init__(self, session, list=None): self.skinName = ["VIXScriptRunner", "IpkgInstaller"] self["key_green"] = StaticText(_("Run")) + self["key_menu"] = StaticText(_("MENU")) # hook for automatic menu key self["myactions"] = ActionMap( ["MenuActions"], diff --git a/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py b/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py index a562f68b9c6..dc78b2a36e2 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py @@ -73,7 +73,7 @@ def spinnerSkin(skinName): """, 484, 150, 460, 60, 20, - ] + ] # noqa: E124 class VIXSoftcamManager(Screen): @@ -113,7 +113,7 @@ class VIXSoftcamManager(Screen): 40, 215, 170, 30, 22, # lab2 225, 216, 240, 100, 20, # activecam 25, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -191,7 +191,7 @@ def selectionChanged(self): else: self["key_green"].setText(_("Stop")) if self.currentactivecam.find(selcam) < 0: - self["key_yellow"].setText(" ") + self["key_yellow"].setText("") else: self["key_yellow"].setText(_("Restart")) @@ -357,7 +357,7 @@ def keyRestart(self, result, retval, extra_args): self.session.open(MessageBox, _("MGcamd can't run whilst CCcam is running."), MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) elif selectedcam.lower().startswith("scam"): self.session.openWithCallback(self.showActivecam, VIXStartCam, self.sel[0]) - elif not selectedcam.lower().startswith("cccam") or selectedcam.lower().startswith("oscam") or selectedcam.lower().startswith("ncam") or selectedcam.lower().startswith("mgcamd"): + elif not selectedcam.lower().startswith(("cccam", "oscam", "ncam", "mgcamd")): self.session.open(MessageBox, _("Found non-standard softcam, trying to start, this may fail."), MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) self.session.openWithCallback(self.showActivecam, VIXStartCam, self.sel[0]) @@ -570,7 +570,7 @@ class VIXSoftcamLog(Screen): """, 560, 400, 0, 0, 560, 400, 14, - ] + ] # noqa: E124 def __init__(self, session): self.session = session @@ -584,14 +584,13 @@ def __init__(self, session): else: softcamlog = "" self["list"] = ScrollLabel(str(softcamlog)) - self["setupActions"] = ActionMap( - ["SetupActions", "ColorActions", "DirectionActions"], - { + self["setupActions"] = ActionMap(["SetupActions", "ColorActions", "DirectionActions"], + { "cancel": self.cancel, "ok": self.cancel, "up": self["list"].pageUp, "down": self["list"].pageDown - }, -2) + }, -2) # noqa: E123 def cancel(self): self.close() @@ -752,7 +751,7 @@ def JobStart(self): now = datetime.now() output.write(now.strftime("%Y-%m-%d %H:%M") + ": " + softcamcheck + " running OK\n") output.close() - if softcamcheck.lower().startswith("oscam") or softcamcheck.lower().startswith("ncam"): + if softcamcheck.lower().startswith(("oscam", "ncam")): if path.exists("/tmp/status.html"): remove("/tmp/status.html") camconf = port = "" @@ -889,7 +888,7 @@ def JobStart(self): now = datetime.now() output.write(now.strftime("%Y-%m-%d %H:%M") + ": Couldn't find " + softcamcheck + " running, Starting " + softcamcheck + "\n") output.close() - if softcamcheck.lower().startswith("oscam") or softcamcheck.lower().startswith("ncam"): + if softcamcheck.lower().startswith(("oscam", "ncam")): self.Console.ePopen("ps.procps | grep softcams | grep -v grep | awk 'NR==1' | awk '{print $5}'| awk -F'[/]' '{print $4}' > /tmp/softcamRuningCheck.tmp") sleep(2) file = open("/tmp/softcamRuningCheck.tmp") diff --git a/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py b/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py index 01e781f5350..1f5a2d21917 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py @@ -60,9 +60,7 @@ def startSwap2(self, result=None, retval=None, extra_args=None): # lets find sw devicelist = [] for p in harddiskmanager.getMountedPartitions(): d = path.normpath(p.mountpoint) - if (path.exists(p.mountpoint) and p.mountpoint != "/" - and not p.mountpoint.startswith("/media/net/") - and not p.mountpoint.startswith("/media/autofs/")): + if (path.exists(p.mountpoint) and p.mountpoint != "/" and not p.mountpoint.startswith(("/media/net/", "/media/autofs/"))): devicelist.append((p.description, d)) if len(devicelist): for device in devicelist: @@ -127,7 +125,7 @@ class VIXSwap(Screen): 160, 150, 220, 30, 20, 160, 200, 100, 30, 20, 160, 200, 100, 30, 20, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -348,12 +346,12 @@ def createDel2(self, result, retval, extra_args=None): self.Console.ePopen("rm " + self.swap_Fname, self.createDel3) def createDel3(self, result, retval, extra_args=None): - print("[SwapManager][createDel3] delete swap, retval, result", retval, " ", result) - if config.swapmanager.swapautostart.value: - config.swapmanager.swapautostart.setValue(False) - config.swapmanager.swapautostart.save() - configfile.save() - self.updateSwap() + print("[SwapManager][createDel3] delete swap, retval, result", retval, " ", result) + if config.swapmanager.swapautostart.value: + config.swapmanager.swapautostart.setValue(False) + config.swapmanager.swapautostart.save() + configfile.save() + self.updateSwap() def doCreateSwap(self): supported_filesystems = frozenset(("ext4", "ext3")) diff --git a/lib/python/Plugins/SystemPlugins/ViX/plugin.py b/lib/python/Plugins/SystemPlugins/ViX/plugin.py index 46b12e0a5e2..b0353113d59 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/plugin.py +++ b/lib/python/Plugins/SystemPlugins/ViX/plugin.py @@ -101,7 +101,7 @@ def SoftcamMenu(session, **kwargs): def SoftcamSetup(menuid): if menuid == "cam": - return [(_("Softcam manager"), SoftcamMenu, "softcamsetup", 1005)] + return [(_("Softcam Manager"), SoftcamMenu, "softcamsetup", 1005)] return [] diff --git a/lib/python/Plugins/SystemPlugins/ViX/ui.py b/lib/python/Plugins/SystemPlugins/ViX/ui.py index 8163201059c..f7cee81dcd1 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/ui.py +++ b/lib/python/Plugins/SystemPlugins/ViX/ui.py @@ -46,7 +46,7 @@ class VIXMenu(Screen, ProtectedScreen): 22, # fonts 300, # itemHeight 5, 360, 600, 50, 22, # status - ] + ] # noqa: E124 def __init__(self, session, args=0): Screen.__init__(self, session) @@ -81,7 +81,7 @@ def __init__(self, session, args=0): "7": self.go, "8": self.go, "9": self.go, - }, -1) + }, -1) # noqa: E123 self.onLayoutFinish.append(self.layoutFinished) self.onChangedEntry = [] self["menu"].onSelectionChanged.append(self.selectionChanged) diff --git a/lib/python/Plugins/SystemPlugins/VideoEnhancement/VideoEnhancement.py b/lib/python/Plugins/SystemPlugins/VideoEnhancement/VideoEnhancement.py index 80c15bb1e03..3725fc17919 100644 --- a/lib/python/Plugins/SystemPlugins/VideoEnhancement/VideoEnhancement.py +++ b/lib/python/Plugins/SystemPlugins/VideoEnhancement/VideoEnhancement.py @@ -267,7 +267,7 @@ def setDynamic_contrast(config): config.pep.dynamic_contrast = NoSave(ConfigNothing()) try: - x = config.av.scaler_sharpness + x = config.av.scaler_sharpness # noqa: F841 except NameError: if os_path.exists("/proc/stb/vmpeg/0/pep_scaler_sharpness"): def setScaler_sharpness(config): diff --git a/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py b/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py index f176792100b..c73bdf70ca9 100644 --- a/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py +++ b/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py @@ -11,7 +11,7 @@ from Screens.MessageBox import MessageBox from Screens.Screen import Screen -from . import VideoEnhancement +from . import VideoEnhancement # noqa: F401 class VideoEnhancementSetup(ConfigListScreen, Screen): diff --git a/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py b/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py index c31479e4470..8b0c9b56cbf 100644 --- a/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py +++ b/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py @@ -140,7 +140,7 @@ def testpic_brightness(self): xres, yres = getDesktop(0).size().width(), getDesktop(0).size().height() - bbw, bbh = xres // 192, yres // 192 + # bbw, bbh = xres // 192, yres // 192 c.fill(0, 0, xres, yres, RGB(0, 0, 0)) for i in range(15): @@ -178,11 +178,9 @@ def testpic_contrast(self): xres, yres = getDesktop(0).size().width(), getDesktop(0).size().height() - bbw, bbh = xres // 192, yres // 192 + # bbw, bbh = xres // 192, yres // 192 c.fill(0, 0, xres, yres, RGB(0, 0, 0)) - bbw = xres // 192 - bbh = yres // 192 c.fill(0, 0, xres, yres, RGB(255, 255, 255)) for i in range(15): @@ -319,18 +317,18 @@ def testpic_gamma(self): for y in range(0, height, 4): c.fill(offset_x, offset_y + y, width // 2, 2, RGB(255, 255, 255)) - l = 0 + offset = 0 fnt = gFont("Regular", height // 14) import math for i in range(1, 15): y = i * height // 14 - h = y - l + h = y - offset gamma = 0.6 + i * 0.2 col = int(math.pow(.5, 1.0 / gamma) * 256.0) - c.fill(offset_x + width // 2, offset_y + l, width // 2, h, RGB(col, col, col)) + c.fill(offset_x + width // 2, offset_y + offset, width // 2, h, RGB(col, col, col)) - c.writeText(offset_x + width // 2, offset_y + l, width // 2, h, RGB(0, 0, 0), RGB(col, col, col), fnt, "%1.2f" % gamma, RT_WRAP | RT_HALIGN_RIGHT) - l = y + c.writeText(offset_x + width // 2, offset_y + offset, width // 2, h, RGB(0, 0, 0), RGB(col, col, col), fnt, "%1.2f" % gamma, RT_WRAP | RT_HALIGN_RIGHT) + offset = y c.flush() diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py b/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py index d93894ab2b9..351cd6fd1cc 100644 --- a/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py +++ b/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py @@ -320,8 +320,8 @@ def buildEntryComponent(self, essid, bssid, encrypted, iface, maxrate, signal, f return essid, bssid, _("Signal: ") + str(signal), _("Max. bitrate: ") + str(maxrate), _("Encrypted: ") + encryption, _("Interface: ") + str(iface), frequency_norm, self.divpng def updateAPList(self): - newList = [] - newList = self.getAccessPoints(refresh=True) + # newList = [] + # newList = self.getAccessPoints(refresh=True) # noqa: F841 self.newAPList = [] tmpList = [] currentListEntry = None diff --git a/lib/python/PowerTimer.py b/lib/python/PowerTimer.py index b00c7d55227..2bab472a8ec 100644 --- a/lib/python/PowerTimer.py +++ b/lib/python/PowerTimer.py @@ -3,11 +3,11 @@ from time import ctime, time from timer import Timer, TimerEntry -from boxbranding import getMachineBrand, getMachineName from enigma import eActionMap, quitMainloop from Components.config import config from Components.Harddisk import internalHDDNotSleeping +from Components.SystemInfo import SystemInfo from Components.TimerSanityCheck import TimerSanityCheck from Screens.MessageBox import MessageBox import Screens.Standby @@ -164,7 +164,7 @@ def activate(self): elif self.timerType == TIMERTYPE.STANDBY: if not Screens.Standby.inStandby: # not already in standby - Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True elif self.timerType == TIMERTYPE.AUTOSTANDBY: @@ -173,7 +173,7 @@ def activate(self): # retry return False if not Screens.Standby.inStandby: # not already in standby - Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) if self.autosleeprepeat == "once": eActionMap.getInstance().unbindAction('', self.keyPressed) return True @@ -213,7 +213,7 @@ def activate(self): quitMainloop(1) return True else: - Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) if self.autosleeprepeat == "once": eActionMap.getInstance().unbindAction('', self.keyPressed) return True @@ -234,7 +234,7 @@ def activate(self): if Screens.Standby.inStandby: # in standby quitMainloop(1) else: - Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True elif self.timerType == TIMERTYPE.REBOOT: @@ -246,7 +246,7 @@ def activate(self): if Screens.Standby.inStandby: # in standby quitMainloop(2) else: - Notifications.AddNotificationWithUniqueIDCallback(self.sendTryToRebootNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to reboot your %s %s.\nDo that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendTryToRebootNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to reboot your %s %s.\nDo that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True elif self.timerType == TIMERTYPE.RESTART: @@ -265,7 +265,7 @@ def activate(self): NavigationInstance.instance.PowerTimer.saveTimer() if self.afterEvent == AFTEREVENT.STANDBY: if not Screens.Standby.inStandby: # not already in standby - Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) elif self.afterEvent == AFTEREVENT.DEEPSTANDBY: if NavigationInstance.instance.RecordTimer.isRecording() or abs(NavigationInstance.instance.RecordTimer.getNextRecordingTime() - time()) <= 900 or abs(NavigationInstance.instance.RecordTimer.getNextZapTime() - time()) <= 900: self.do_backoff() @@ -275,7 +275,7 @@ def activate(self): if Screens.Standby.inStandby: # in standby quitMainloop(1) else: - Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True def setAutoincreaseEnd(self, entry=None): diff --git a/lib/python/RecordTimer.py b/lib/python/RecordTimer.py index a47b237a260..5dd8ee5099b 100644 --- a/lib/python/RecordTimer.py +++ b/lib/python/RecordTimer.py @@ -5,7 +5,6 @@ from time import localtime, strftime, ctime, time from enigma import eEPGCache, getBestPlayableServiceReference, eStreamServer, eServiceReference, iRecordableService, quitMainloop, eActionMap, setPreferredTuner, eServiceCenter -from boxbranding import getMachineBrand, getMachineName, getBoxType from Components.config import config import Components.ParentalControl from Components.UsageConfig import defaultMoviePath @@ -113,7 +112,7 @@ def findSafeRecordPath(dirname): "mbtwin": ("/proc/stb/lcd/symbol_circle", 4) } -SID_code_states = SID_symbol_states.setdefault(getBoxType(), (None, 0)) +SID_code_states = SID_symbol_states.setdefault(SystemInfo["boxtype"], (None, 0)) n_recordings = 0 # Must be when we start running... @@ -737,7 +736,7 @@ def activate(self): if self.afterEvent == AFTEREVENT.STANDBY or (not wasRecTimerWakeup and self.autostate and self.afterEvent == AFTEREVENT.AUTO) or self.wasInStandby: self.keypress() # this unbinds the keypress detection if not Screens.Standby.inStandby: # not already in standby - Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A finished record timer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A finished record timer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) elif self.afterEvent == AFTEREVENT.DEEPSTANDBY or (wasRecTimerWakeup and self.afterEvent == AFTEREVENT.AUTO and Screens.Standby.inStandby): if (abs(NavigationInstance.instance.RecordTimer.getNextRecordingTime() - time()) <= 900 or abs(NavigationInstance.instance.RecordTimer.getNextZapTime() - time()) <= 900) or NavigationInstance.instance.RecordTimer.getStillRecording(): print("[RecordTimer] Recording or Recording due is next 15 mins, not return to deepstandby") @@ -752,7 +751,7 @@ def activate(self): if int(ClientsStreaming("NUMBER").getText()) > 0: if not Screens.Standby.inStandby: # not already in standby Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, - _("A finished record timer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()) + _("A finished record timer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + _("\n(DeepStandby request changed to Standby owing to there being streaming clients.)"), timeout=180) return True @@ -760,7 +759,7 @@ def activate(self): if Screens.Standby.inStandby: # in standby quitMainloop(1) else: - Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A finished record timer wants to shut down\nyour %s %s. Shutdown now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A finished record timer wants to shut down\nyour %s %s. Shutdown now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True def keypress(self, key=None, flag=1): diff --git a/lib/python/Screens/About.py b/lib/python/Screens/About.py index 605b48199f7..3401bd80f15 100644 --- a/lib/python/Screens/About.py +++ b/lib/python/Screens/About.py @@ -1,7 +1,6 @@ from os import listdir, path, popen from re import search from enigma import eTimer, getDesktop -from boxbranding import getMachineBrand, getMachineName, getImageVersion, getImageType, getImageBuild, getImageDevBuild from Components.About import about from Components.ActionMap import ActionMap from Components.Button import Button @@ -12,7 +11,7 @@ from Components.NimManager import nimmanager from Components.Pixmap import MultiPixmap from Components.Sources.StaticText import StaticText -from Components.SystemInfo import SystemInfo, BoxInfo +from Components.SystemInfo import SystemInfo from Screens.GitCommitInfo import CommitInfo from Screens.Screen import Screen, ScreenSummary from Screens.SoftwareUpdate import UpdatePlugin @@ -55,7 +54,7 @@ def __init__(self, session): def populate(self): AboutText = "" - AboutText += _("Model:\t%s %s\n") % (getMachineBrand(), getMachineName()) + AboutText += _("Model:\t%s %s\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) if about.getChipSetString() != _("unavailable"): if SystemInfo["HasHiSi"]: @@ -67,7 +66,7 @@ def populate(self): AboutText += _("CPU:\t%s %s %s\n") % (about.getCPUArch(), about.getCPUSpeedString(), about.getCpuCoresString()) - AboutText += _("SoC:\t%s\n") % BoxInfo.getItem("socfamily").upper() + AboutText += _("SoC:\t%s\n") % SystemInfo["socfamily"].upper() tempinfo = "" if path.exists("/proc/stb/sensors/temp0/value"): @@ -102,16 +101,16 @@ def populate(self): AboutText += _("Processor temp:\t%s") % tempinfo.replace("\n", "").replace(" ", "") + "\xb0" + "C\n" imageSubBuild = "" - if getImageType() != "release": - imageSubBuild = ".%s" % getImageDevBuild() - AboutText += _("Image:\t%s.%s%s (%s)\n") % (getImageVersion(), getImageBuild(), imageSubBuild, getImageType().title()) + if SystemInfo["imagetype"] != "release": + imageSubBuild = ".%s" % SystemInfo["imagedevbuild"] + AboutText += _("Image:\t%s.%s%s (%s)\n") % (SystemInfo["imageversion"], SystemInfo["imagebuild"], imageSubBuild, SystemInfo["imagetype"].title()) VuPlustxt = "Vu+ Multiboot - " if SystemInfo["HasKexecMultiboot"] else "" if fileHas("/proc/cmdline", "rootsubdir=linuxrootfs0"): AboutText += _("Boot Device: \tRecovery Slot\n") else: - if BoxInfo.getItem("mtdbootfs") != "" and " " not in BoxInfo.getItem("mtdbootfs"): - AboutText += _("Boot Device:\t%s%s\n") % (VuPlustxt, BoxInfo.getItem("mtdbootfs")) + if SystemInfo["mtdbootfs"] != "" and " " not in SystemInfo["mtdbootfs"]: + AboutText += _("Boot Device:\t%s%s\n") % (VuPlustxt, SystemInfo["mtdbootfs"]) if SystemInfo["HasH9SD"]: if "rootfstype=ext4" in open("/sys/firmware/devicetree/base/chosen/bootargs", "r").read(): @@ -132,7 +131,7 @@ def populate(self): bootmode = _("bootmode = %s") % GetCurrentImageMode() if SystemInfo["canMode12"] else "" AboutText += (_("Image Slot:\tStartup %s - %s %s") % (str(slot), part, bootmode)) + "\n" - if getMachineName() in ("ET8500") and path.exists("/proc/mtd"): + if SystemInfo["MachineName"] in ("ET8500") and path.exists("/proc/mtd"): self.dualboot = self.dualBoot() if self.dualboot: AboutText += _("ET8500 Multiboot: Installed\n") @@ -312,7 +311,7 @@ def Stage1Complete(self, result, retval, extra_args=None): self.mountinfo = "" for line in result: self.parts = line.split() - if line and self.parts[0] and (self.parts[0].startswith("192") or self.parts[0].startswith("//192")): + if line and self.parts[0] and self.parts[0].startswith(("192", "//192")): line = line.split() ipaddress = line[0] mounttotal = line[1] @@ -622,8 +621,8 @@ def __init__(self, session, parent): self.skinName = "AboutSummary" self.aboutText = [] self["AboutText"] = StaticText() - self.aboutText.append(_("OpenViX: %s") % getImageVersion() + "." + getImageBuild() + "\n") - self.aboutText.append(_("Model: %s %s\n") % (getMachineBrand(), getMachineName())) + self.aboutText.append(_("OpenViX: %s") % SystemInfo["imageversion"] + "." + SystemInfo["imagebuild"] + "\n") + self.aboutText.append(_("Model: %s %s\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) self.aboutText.append(_("Updated: %s") % about.getLastUpdate() + "\n") tempinfo = "" if path.exists("/proc/stb/sensors/temp0/value"): diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index ca01a0fdd88..c86f4c4bd45 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -62,6 +62,19 @@ FLAG_CENTER_DVB_SUBS = 2048 # define in lib/dvb/idvb.h as dxNewFound = 64 and dxIsDedicated3D = 128 +def getStreamRelayRef(sref): + try: + if "http" in sref: + sr_port = config.misc.softcam_streamrelay_port.value + sr_ip = ".".join("%d" % d for d in config.misc.softcam_streamrelay_url.value) + sr_url = f"http%3a//{sr_ip}%3a{sr_port}/" + if sr_url in sref: + return sref.split(sr_url)[1].split(":")[0].replace("%3a", ":") + except Exception: + pass + return sref + + class BouquetSelector(Screen): def __init__(self, session, bouquets, selectedFunc, enableWrapAround=True): Screen.__init__(self, session) @@ -344,7 +357,8 @@ def toggleVBI(self): self.close() def toggleStreamrelay(self): - Screens.InfoBar.InfoBar.instance.ToggleStreamrelay(self.csel.getCurrentSelection()) + from Screens.InfoBarGenerics import streamrelay + streamrelay.toggle(self.session.nav, self.csel.getCurrentSelection()) self.close() def addCenterDVBSubsFlag(self): @@ -2086,6 +2100,7 @@ def __evServiceStart(self): info = service.info() if info: refstr = info.getInfoString(iServiceInformation.sServiceref) + refstr = getStreamRelayRef(refstr) self.servicelist.setPlayableIgnoreService(eServiceReference(refstr)) def __evServiceEnd(self): diff --git a/lib/python/Screens/CronTimer.py b/lib/python/Screens/CronTimer.py index df5b4674150..e94db87ab21 100644 --- a/lib/python/Screens/CronTimer.py +++ b/lib/python/Screens/CronTimer.py @@ -1,7 +1,6 @@ from os import system, listdir, rename, path, mkdir from time import sleep -from boxbranding import getImageType from Components.ActionMap import ActionMap from Components.config import getConfigListEntry, ConfigText, ConfigSelection, ConfigInteger, ConfigClock from Components.ConfigList import ConfigListScreen @@ -9,6 +8,7 @@ from Components.Label import Label from Components.Sources.List import List from Components.OnlineUpdateCheck import feedsstatuscheck +from Components.SystemInfo import SystemInfo from Screens.Screen import Screen from Screens.Setup import Setup from Screens.MessageBox import MessageBox @@ -67,7 +67,7 @@ def checkNetworkState(self, result, retval, extra_args): if 'Collected errors' in result: self.session.openWithCallback(self.close, MessageBox, _("A background update check is in progress, please wait a few minutes and try again."), type=MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) elif not result: - if (getImageType() != 'release' and feedsstatuscheck.getFeedsBool() != 'unknown') or (getImageType() == 'release' and feedsstatuscheck.getFeedsBool() not in ('stable', 'unstable')): + if (SystemInfo["imagetype"] != 'release' and feedsstatuscheck.getFeedsBool() != 'unknown') or (SystemInfo["imagetype"] == 'release' and feedsstatuscheck.getFeedsBool() not in ('stable', 'unstable')): self.session.openWithCallback(self.InstallPackageFailed, MessageBox, feedsstatuscheck.getFeedsErrorMessage(), type=MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) else: self.session.openWithCallback(self.InstallPackage, MessageBox, _('Ready to install "%s" ?') % self.service_name, MessageBox.TYPE_YESNO) diff --git a/lib/python/Screens/DVD.py b/lib/python/Screens/DVD.py index 31730983e33..ee305d0f4cc 100644 --- a/lib/python/Screens/DVD.py +++ b/lib/python/Screens/DVD.py @@ -519,7 +519,7 @@ def FileBrowserClosed(self, val): if curref is None or curref != newref: if newref.toString().endswith("/VIDEO_TS") or newref.toString().endswith("/"): names = newref.toString().rsplit("/", 3) - if names[2].startswith("Disk ") or names[2].startswith("DVD "): + if names[2].startswith(("Disk ", "DVD ")): name = str(names[1]) + " - " + str(names[2]) else: name = names[2] diff --git a/lib/python/Screens/GitCommitInfo.py b/lib/python/Screens/GitCommitInfo.py index 67f32a55b69..7a89f93410c 100644 --- a/lib/python/Screens/GitCommitInfo.py +++ b/lib/python/Screens/GitCommitInfo.py @@ -2,10 +2,10 @@ from Components.Button import Button from Components.Label import Label from Components.ScrollLabel import ScrollLabel +from Components.SystemInfo import SystemInfo from Screens.Screen import Screen from enigma import eTimer -from boxbranding import getImageBuild, getImageDevBuild, getImageType from sys import modules from datetime import datetime from json import loads @@ -13,10 +13,10 @@ from urllib.request import urlopen, Request # raises ImportError in Python 2 from urllib.error import HTTPError, URLError # raises ImportError in Python 2 -if getImageType() == 'release': - ImageVer = "%03d" % int(getImageBuild()) +if SystemInfo["imagetype"] == 'release': + ImageVer = "%03d" % int(SystemInfo["imagebuild"]) else: - ImageVer = "%s.%s" % (getImageBuild(), getImageDevBuild()) + ImageVer = "%s.%s" % (SystemInfo["imagebuild"], SystemInfo["imagedevbuild"]) ImageVer = float(ImageVer) E2Branches = { @@ -27,7 +27,7 @@ project = 0 projects = [ ("https://api.github.com/repos/oe-alliance/oe-alliance-core/commits?sha=5.3", "OE-A Core"), - ("https://api.github.com/repos/OpenViX/enigma2/commits?sha=%s" % getattr(E2Branches, getImageType(), "Release"), "Enigma2"), + ("https://api.github.com/repos/OpenViX/enigma2/commits?sha=%s" % getattr(E2Branches, SystemInfo["imagetype"], "Release"), "Enigma2"), ("https://api.github.com/repos/OpenViX/skins/commits", "ViX Skins"), ("https://api.github.com/repos/oe-alliance/oe-alliance-plugins/commits", "OE-A Plugins"), ("https://api.github.com/repos/oe-alliance/AutoBouquetsMaker/commits", "AutoBouquetsMaker"), @@ -53,15 +53,15 @@ def readGithubCommitLogsSoftwareUpdate(): continue if c['commit']['message'].startswith('openvix:'): gitstart = False - if getImageType() == 'release' and c['commit']['message'].startswith('openvix: developer'): + if SystemInfo["imagetype"] == 'release' and c['commit']['message'].startswith('openvix: developer'): print('[GitCommitLog] Skipping developer line') continue - elif getImageType() != 'release' and c['commit']['message'].startswith('openvix: release'): + elif SystemInfo["imagetype"] != 'release' and c['commit']['message'].startswith('openvix: release'): print('[GitCommitLog] Skipping release line') continue tmp = c['commit']['message'].split(' ')[2].split('.') if len(tmp) > 2: - if getImageType() == 'release': + if SystemInfo["imagetype"] == 'release': releasever = tmp[2] releasever = "%03d" % int(releasever) else: @@ -112,15 +112,15 @@ def readGithubCommitLogs(): if c['commit']['message'].startswith('openvix:'): blockstart = False gitstart = False - if getImageType() == 'release' and c['commit']['message'].startswith('openvix: developer'): + if SystemInfo["imagetype"] == 'release' and c['commit']['message'].startswith('openvix: developer'): print('[GitCommitLog] Skipping developer line') continue - elif getImageType() == 'developer' and c['commit']['message'].startswith('openvix: release'): + elif SystemInfo["imagetype"] == 'developer' and c['commit']['message'].startswith('openvix: release'): print('[GitCommitLog] Skipping release line') continue tmp = c['commit']['message'].split(' ')[2].split('.') if len(tmp) > 2: - if getImageType() == 'release': + if SystemInfo["imagetype"] == 'release': releasever = tmp[2] releasever = "%03d" % int(releasever) else: diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index f2e6941f50f..361c88573c4 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -68,6 +68,7 @@ import datetime import pickle from gettext import dgettext +from re import match # hack alert! from Screens.Menu import MainMenu, Menu, mdom @@ -165,7 +166,6 @@ def updateresumePointCache(): class whitelist: vbi = [] - streamrelay = [] def reload_whitelist_vbi(): @@ -175,26 +175,58 @@ def reload_whitelist_vbi(): reload_whitelist_vbi() -def reload_streamrelay(): - whitelist.streamrelay = [line.strip() for line in open('/etc/enigma2/whitelist_streamrelay', 'r').readlines()] if os.path.isfile('/etc/enigma2/whitelist_streamrelay') else [] +class InfoBarStreamRelay: + FILENAME = "/etc/enigma2/whitelist_streamrelay" -reload_streamrelay() + def __init__(self): + self.__srefs = self.__sanitizeData(open(self.FILENAME, 'r').readlines()) if os.path.isfile(self.FILENAME) else [] -subservice_groupslist = None + def __sanitizeData(self, data): + return list(set([line.strip() for line in data if line and isinstance(line, str) and match("^(?:[0-9A-F]+[:]){10}$", line.strip())])) if isinstance(data, list) else [] + def __saveToFile(self): + self.__srefs.sort(key=lambda ref: (int((x := ref.split(":"))[6], 16), int(x[5], 16), int(x[4], 16), int(x[3], 16))) + open(self.FILENAME, 'w').write('\n'.join(self.__srefs)) -def streamrelayChecker(playref): - playrefstring = playref.toString() - if '%3a//' not in playrefstring and playrefstring in whitelist.streamrelay: - url = "http://%s:%s/" % (config.misc.softcam_streamrelay_url.getHTML(), config.misc.softcam_streamrelay_port.value) - if "127.0.0.1" in url: - playrefmod = ":".join([("%x" % (int(x[1], 16) + 1)).upper() if x[0] == 6 else x[1] for x in enumerate(playrefstring.split(':'))]) - else: - playrefmod = playrefstring - playref = eServiceReference("%s%s%s:%s" % (playrefmod, url.replace(":", "%3a"), playrefstring.replace(":", "%3a"), ServiceReference(playref).getServiceName())) - print("[Whitelist_StreamRelay] Play service via streamrelay as it is whitelisted as such", playref.toString()) - return playref + def toggle(self, nav, service): + if (servicestring := (service and service.toString())): + if servicestring in self.__srefs: + self.__srefs.remove(servicestring) + else: + self.__srefs.append(servicestring) + if nav.getCurrentlyPlayingServiceReference() == service: + nav.restartService() + self.__saveToFile() + + def getData(self): + return self.__srefs + + def setData(self, data): + self.__srefs = self.__sanitizeData(data) + self.__saveToFile() + + data = property(getData, setData) + + def streamrelayChecker(self, playref): + playrefstring = playref.toString() + if '%3a//' not in playrefstring and playrefstring in self.__srefs: + url = "http://%s:%s/" % (config.misc.softcam_streamrelay_url.getHTML(), config.misc.softcam_streamrelay_port.value) + if "127.0.0.1" in url: + playrefmod = ":".join([("%x" % (int(x[1], 16) + 1)).upper() if x[0] == 6 else x[1] for x in enumerate(playrefstring.split(':'))]) + else: + playrefmod = playrefstring + playref = eServiceReference("%s%s%s:%s" % (playrefmod, url.replace(":", "%3a"), playrefstring.replace(":", "%3a"), ServiceReference(playref).getServiceName())) + print(f"[{self.__class__.__name__}] Play service {playref.toString()} via streamrelay") + return playref + + def checkService(self, service): + return service and service.toString() in self.__srefs + + +streamrelay = InfoBarStreamRelay() + +subservice_groupslist = None def reload_subservice_groupslist(force=False): @@ -840,7 +872,7 @@ def toggleShow(self): self.show() if self.secondInfoBarScreen: self.secondInfoBarScreen.hide() - self.secondInfoBarWasShown = False + self.secondInfoBarWasShown = False self.EventViewIsShown = False elif isStandardInfoBar(self) and config.usage.show_second_infobar.value == "EPG": self.showDefaultEPG() @@ -913,9 +945,6 @@ def checkHideVBI(self, service=None): return ".hidevbi." in servicepath.lower() return service and service.toString() in whitelist.vbi - def checkStreamrelay(self, service=None): - return (service or self.session.nav.getCurrentlyPlayingServiceReference()) and service.toString() in whitelist.streamrelay - def showHideVBI(self): if self.checkHideVBI(): self.hideVBILineScreen.show() @@ -933,17 +962,8 @@ def ToggleHideVBI(self, service=None): open('/etc/enigma2/whitelist_vbi', 'w').write('\n'.join(whitelist.vbi)) self.showHideVBI() - def ToggleStreamrelay(self, service=None): - service = service or self.session.nav.getCurrentlyPlayingServiceReference() - if service: - servicestring = service.toString() - if servicestring in whitelist.streamrelay: - whitelist.streamrelay.remove(servicestring) - else: - whitelist.streamrelay.append(servicestring) - if self.session.nav.getCurrentlyPlayingServiceReference() == service: - self.session.nav.restartService() - open('/etc/enigma2/whitelist_streamrelay', 'w').write('\n'.join(whitelist.streamrelay)) + def checkStreamrelay(self, service): + return streamrelay.checkService(service) def queueChange(self): self._waitForEventInfoTimer.stop() @@ -1531,26 +1551,22 @@ def toggleAspectRatio(self): self.session.open(MessageBox, _("AV aspect is %s." % ASPECT_MSG[config.av.aspect.value]), MessageBox.TYPE_INFO, timeout=5, simple=True) def showSystemMenu(self): - menulist = mdom.getroot().findall('menu') - for item in menulist: - if item.attrib['entryID'] == 'setup_selection': - menulist = item.findall('menu') - for item in menulist: - if item.attrib['entryID'] == 'system_selection': - menu = item - assert menu.tag == "menu", "root element in menu must be 'menu'!" - self.session.openWithCallback(self.mainMenuClosed, Menu, menu) + menulist = mdom.getroot().findall("menu") + for menuItem in menulist: + if menuItem.get("key") == "setup": + menulist2 = menuItem.findall("menu") + for menuItems in menulist2: + if menuItems.get('key') == "system": + self.session.openWithCallback(self.mainMenuClosed, Menu, menuItems) def showNetworkMounts(self): menulist = mdom.getroot().findall('menu') - for item in menulist: - if item.attrib['entryID'] == 'setup_selection': - menulist = item.findall('menu') - for item in menulist: - if item.attrib['entryID'] == 'network_menu': - menu = item - assert menu.tag == "menu", "root element in menu must be 'menu'!" - self.session.openWithCallback(self.mainMenuClosed, Menu, menu) + for menuItem in menulist: + if menuItem.get('key') == "setup": + menulist2 = menuItem.findall('menu') + for menuItems in menulist2: + if menuItems.get('key') == "network": + self.session.openWithCallback(self.mainMenuClosed, Menu, menuItems) def showRFSetup(self): self.session.openWithCallback(self.mainMenuClosed, Setup, 'RFmod') @@ -2138,7 +2154,7 @@ def skipString(skip): @staticmethod def generateSkipHelp(context): skipHelp = [] - for action in [act for ctx, act in getKeyBindingKeys(filterfn=lambda key: key[0] == context and (key[1].startswith("seek:") or key[1].startswith("seekdef:")))]: + for action in [act for ctx, act in getKeyBindingKeys(filterfn=lambda key: key[0] == context and (key[1].startswith(("seek:", "seekdef:"))))]: if action.startswith("seekdef:"): skipTime = boundFunction(InfoBarSeekActionMap.seekTime, action) else: @@ -2835,7 +2851,7 @@ def getOScamInfo(self): if pathExists('/usr/softcams/'): softcams = os.listdir('/usr/softcams/') for softcam in softcams: - if (softcam.lower().startswith('oscam') or softcam.lower().startswith('ncam')) and config.oscaminfo.showInExtensions.value: + if softcam.lower().startswith(('oscam', 'ncam')) and config.oscaminfo.showInExtensions.value: return [((boundFunction(self.getOSname), boundFunction(self.openOScamInfo), lambda: True), None)] or [] else: return [] diff --git a/lib/python/Screens/InputDeviceSetup.py b/lib/python/Screens/InputDeviceSetup.py index cb3a92f1692..d662e40a9da 100644 --- a/lib/python/Screens/InputDeviceSetup.py +++ b/lib/python/Screens/InputDeviceSetup.py @@ -7,9 +7,9 @@ from Components.config import config, ConfigYesNo, getConfigListEntry, ConfigSelection from Components.ConfigList import ConfigListScreen from Components.ActionMap import ActionMap, HelpableActionMap +from Components.SystemInfo import SystemInfo from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN from Tools.LoadPixmap import LoadPixmap -from boxbranding import getBoxType, getMachineBrand, getMachineName, getMachineBuild class InputDeviceSelection(Screen, HelpableScreen): @@ -128,7 +128,7 @@ def __init__(self, session, device=None): self["introduction"] = StaticText() # for generating strings into .po only - devicenames = [_("%s %s front panel") % (getMachineBrand(), getMachineName()), _("%s %s remote control (native)") % (getMachineBrand(), getMachineName()), _("%s %s advanced remote control (native)") % (getMachineBrand(), getMachineName()), _("%s %s ir keyboard") % (getMachineBrand(), getMachineName()), _("%s %s ir mouse") % (getMachineBrand(), getMachineName())] # noqa: F841 + devicenames = [_("%s %s front panel") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), _("%s %s remote control (native)") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), _("%s %s advanced remote control (native)") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), _("%s %s ir keyboard") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), _("%s %s ir mouse") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])] # noqa: F841 self.createSetup() self.onLayoutFinish.append(self.layoutFinished) @@ -217,7 +217,7 @@ def getCurrentValue(self): # required because getCurrentValue() in ConfigListSc class RemoteControlType(ConfigListScreen, Screen): odinRemote = "OdinM9" - if getBoxType() == "maram9": + if SystemInfo["boxtype"] == "maram9": odinRemote = "MaraM9" rcList = [ @@ -314,8 +314,8 @@ def __init__(self, session): self.getDefaultRcType() def getDefaultRcType(self): - boxtype = getMachineBuild() - procBoxtype = iRcTypeControl.getBoxType() + boxtype = SystemInfo["model"] + procBoxtype = iRcTypeControl.SystemInfo["boxtype"] print("[InputDevice] procBoxtype = %s, self.boxType = %s" % (procBoxtype, boxtype)) for x in self.defaultRcList: if x[0] in boxtype or x[0] in procBoxtype: diff --git a/lib/python/Screens/MovieSelection.py b/lib/python/Screens/MovieSelection.py index 6206d5b3eb6..20dd339afc3 100644 --- a/lib/python/Screens/MovieSelection.py +++ b/lib/python/Screens/MovieSelection.py @@ -390,8 +390,8 @@ def selectionChanged(self): class MovieContextMenu(Screen, ProtectedScreen): # Contract: On OK returns a callable object (e.g. delete) def __init__(self, session, csel, currentSelection): - Screen.__init__(self, session) - self.skinName = "Setup" + Screen.__init__(self, session, mandatoryWidgets=["config"]) + self.skinName = ["MovieContextMenu", "Setup"] self.setup_title = _("Movie List Setup") Screen.setTitle(self, _(self.setup_title)) @@ -1207,7 +1207,7 @@ def callLater(self, function): def __evEOF(self): playInBackground = self.list.playInBackground - playInForeground = self.list.playInForeground + # playInForeground = self.list.playInForeground if not playInBackground: print("[MovieSelection] Not playing anything in background") return @@ -2084,7 +2084,7 @@ def renameCallback(self, renameList, newname): else: metafile = open(meta, "r+") sid = metafile.readline() - oldtitle = metafile.readline() #noqa: F841 # local variable 'oldtitle' is assigned to but never used. Must be to skip a line. + oldtitle = metafile.readline() # noqa: F841 # local variable 'oldtitle' is assigned to but never used. Must be to skip a line. rest = metafile.read() metafile.seek(0) metafile.write("%s%s\n%s" % (sid, newname, rest)) diff --git a/lib/python/Screens/MultiBootSelector.py b/lib/python/Screens/MultiBootSelector.py index ab8d8b18669..78f87dd4524 100644 --- a/lib/python/Screens/MultiBootSelector.py +++ b/lib/python/Screens/MultiBootSelector.py @@ -2,7 +2,6 @@ import tempfile import struct -from boxbranding import getBoxType from Components.ActionMap import HelpableActionMap from Components.ChoiceList import ChoiceEntryComponent, ChoiceList from Components.Console import Console @@ -183,7 +182,7 @@ def addSTARTUPs(self, answer): if answer is False: self.close() else: - boxmodel = getBoxType()[2:] + boxmodel = SystemInfo["boxtype"][2:] for usbslot in range(hiKey + 1, hiKey + 5): STARTUP_usbslot = "kernel=%s/linuxrootfs%d/zImage root=%s rootsubdir=%s/linuxrootfs%d" % (boxmodel, usbslot, SystemInfo["VuUUIDSlot"][0], boxmodel, usbslot) # /STARTUP_ if boxmodel in ("duo4k"): @@ -197,7 +196,7 @@ def addSTARTUPs(self, answer): def KexecMountRet(self, result=None, retval=None, extra_args=None): self.device_uuid = "UUID=" + result.split("UUID=")[1].split(" ")[0].replace('"', '') - boxmodel = getBoxType()[2:] + boxmodel = SystemInfo["boxtype"][2:] # using UUID kernel=/linuxrootfs1/boot/zImage root=UUID="12c2025e-2969-4bd1-9e0c-da08b97d40ce" rootsubdir=linuxrootfs1 # using dev = "kernel=/linuxrootfs4/zImage root=/dev/%s rootsubdir=linuxrootfs4" % hdd[0] # /STARTUP_4 diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py index a8310a83d46..2517fab93aa 100644 --- a/lib/python/Screens/NetworkSetup.py +++ b/lib/python/Screens/NetworkSetup.py @@ -1,13 +1,10 @@ -import six - from os import system, path as os_path, unlink, rename import netifaces as ni from random import Random import string import time - +import glob from enigma import eTimer, eConsoleAppContainer -from boxbranding import getBoxType, getMachineBrand, getMachineName, getImageType, getImageVersion from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap from Components.config import config, ConfigSubsection, ConfigYesNo, ConfigIP, ConfigText, ConfigPassword, ConfigSelection, getConfigListEntry, ConfigNumber, ConfigLocations, NoSave, ConfigMacText @@ -22,6 +19,7 @@ from Components.PluginComponent import plugins from Components.Sources.StaticText import StaticText from Components.Sources.List import List +from Components.SystemInfo import SystemInfo from Plugins.Plugin import PluginDescriptor from Screens.HelpMenu import HelpableScreen from Screens.MessageBox import MessageBox @@ -29,16 +27,29 @@ from Screens.Setup import Setup from Screens.Standby import TryQuitMainloop from Screens.TextBox import TextBox -from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_SKIN +from Tools.Directories import fileExists, isPluginInstalled, resolveFilename, SCOPE_CURRENT_SKIN, SCOPE_PLUGINS from Tools.LoadPixmap import LoadPixmap +networkWizard = False +XML_networkWizard = False +wirelessLan = False + +if os_path.exists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")): + XML_networkWizard = True +if isPluginInstalled("NetworkWizard"): + networkWizard = True + from Plugins.SystemPlugins.NetworkWizard.NetworkWizard import NetworkWizard +if isPluginInstalled("WirelessLan"): + wirelessLan = True + from Plugins.SystemPlugins.WirelessLan.Wlan import brcmWLConfig, iStatus, wpaSupplicant + from Plugins.SystemPlugins.WirelessLan.plugin import WlanScan, WlanStatus + # Define a function to determine whether a service is configured to # start at boot time. # This checks for a start file in rc2.d (rc4.d might be more # appropriate, but historically it's been rc2.d, so...). # -import glob def ServiceIsEnabled(service_name): @@ -83,7 +94,7 @@ def StartStopCallback(self, result=None, retval=None, extra_args=None): def removeComplete(self, result=None, retval=None, extra_args=None): if self.reboot_at_end: restartbox = self.session.openWithCallback(self.operationComplete, MessageBox, - _('Your %s %s needs to be restarted to complete the removal of %s\nDo you want to reboot now ?') % (getMachineBrand(), getMachineName(), self.getTitle()), MessageBox.TYPE_YESNO) + _('Your %s %s needs to be restarted to complete the removal of %s\nDo you want to reboot now ?') % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], self.getTitle()), MessageBox.TYPE_YESNO) restartbox.setTitle(_("Reboot required")) else: self.operationComplete() @@ -91,7 +102,7 @@ def removeComplete(self, result=None, retval=None, extra_args=None): def installComplete(self, result=None, retval=None, extra_args=None): if self.reboot_at_end: restartbox = self.session.openWithCallback(self.operationComplete, MessageBox, - _('Your %s %s needs to be restarted to complete the installation of %s\nDo you want to reboot now ?') % (getMachineBrand(), getMachineName(), self.getTitle()), MessageBox.TYPE_YESNO) + _('Your %s %s needs to be restarted to complete the installation of %s\nDo you want to reboot now ?') % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], self.getTitle()), MessageBox.TYPE_YESNO) restartbox.setTitle(_("Reboot required")) else: self.message.close() @@ -113,11 +124,10 @@ def doInstall(self, callback, pkgname): self.ConsoleB.ePopen("/usr/bin/opkg install " + pkgname, callback) def checkNetworkState(self, str, retval, extra_args): - str = six.ensure_str(str) if "Collected errors" in str: self.session.openWithCallback(self.close, MessageBox, _("A background update check is in progress, please wait a few minutes and then try again."), type=MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) elif not str: - if (getImageType() != "release" and feedsstatuscheck.getFeedsBool() not in ("unknown", "alien", "developer")) or (getImageType() == "release" and feedsstatuscheck.getFeedsBool() not in ("stable", "unstable", "alien", "developer")): + if (SystemInfo["imagetype"] != "release" and feedsstatuscheck.getFeedsBool() not in ("unknown", "alien", "developer")) or (SystemInfo["imagetype"] == "release" and feedsstatuscheck.getFeedsBool() not in ("stable", "unstable", "alien", "developer")): self.session.openWithCallback(self.InstallPackageFailed, MessageBox, feedsstatuscheck.getFeedsErrorMessage(), type=MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) else: mtext = _("Are you ready to install %s ?") % self.getTitle() @@ -159,7 +169,7 @@ def __init__(self, session): Screen.__init__(self, session) HelpableScreen.__init__(self) self.setTitle(_("Device")) - + # print("[NetworkSetup][NetworkAdapterSelection]") self.wlan_errortext = _("No working wireless network adapter found.\nPlease verify that you have attached a compatible WLAN device and your network is configured correctly.") self.lan_errortext = _("No working local network adapter found.\nPlease verify that you have attached a network cable and your network is configured correctly.") self.oktext = _("Press OK on your remote control to continue.") @@ -174,22 +184,22 @@ def __init__(self, session): self["introduction"] = StaticText(self.edittext) self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", - { - "cancel": (self.close, _("Exit network interface list")), - "ok": (self.okbuttonClick, _("Select interface")), - }) + { + "cancel": (self.close, _("Exit network interface list")), + "ok": (self.okbuttonClick, _("Select interface")), + }) self["ColorActions"] = HelpableActionMap(self, "ColorActions", - { - "red": (self.close, _("Exit network interface list")), - "green": (self.okbuttonClick, _("Select interface")), - "blue": (self.openNetworkWizard, _("Use the network wizard to configure selected network adapter")), - }) + { + "red": (self.close, _("Exit network interface list")), + "green": (self.okbuttonClick, _("Select interface")), + "blue": (self.openNetworkWizard, _("Use the network wizard to configure selected network adapter")), + }) self["DefaultInterfaceAction"] = HelpableActionMap(self, "ColorActions", - { - "yellow": (self.setDefaultInterface, [_("Set interface as the default Interface"), _("* Only available if more than one interface is active.")]), - }) + { + "yellow": (self.setDefaultInterface, [_("Set interface as the default Interface"), _("* Only available if more than one interface is active.")]), + }) self.adapters = [(iNetwork.getFriendlyAdapterName(x), x) for x in iNetwork.getAdapterList()] @@ -295,7 +305,7 @@ def updateList(self): active_int = False self.list.append(self.buildInterfaceList(x[1], _(x[0]), default_int, active_int)) - if os_path.exists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")): + if XML_networkWizard: self["key_blue"].setText(_("Network wizard")) self["list"].list = self.list @@ -350,15 +360,12 @@ def restartfinishedCB(self, data): self.session.open(MessageBox, _("Finished configuring your network"), type=MessageBox.TYPE_INFO, timeout=10, default=False) def openNetworkWizard(self): - if os_path.exists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")): - try: - from Plugins.SystemPlugins.NetworkWizard.NetworkWizard import NetworkWizard - except ImportError: - self.session.open(MessageBox, _("The network wizard extension is not installed!\nPlease install it."), type=MessageBox.TYPE_INFO, timeout=10) - else: - selection = self["list"].getCurrent() - if selection is not None: - self.session.openWithCallback(self.AdapterSetupClosed, NetworkWizard, selection[0]) + if networkWizard and XML_networkWizard: + selection = self["list"].getCurrent() + if selection is not None: + self.session.openWithCallback(self.AdapterSetupClosed, NetworkWizard, selection[0]) + else: + self.session.open(MessageBox, _("The network wizard extension is not installed!\nPlease install it."), type=MessageBox.TYPE_INFO, timeout=10) class NameserverSetup(ConfigListScreen, HelpableScreen, Screen): @@ -368,7 +375,7 @@ def __init__(self, session): self.setTitle(_("Nameserver Settings")) self.skinName = ["NameserverSetup", "Setup"] self.backupNameserverList = iNetwork.getNameserverList()[:] - print("[NameserverSetup] backup-list:%s" % self.backupNameserverList) + # print("[NetworkSetup][NameserverSetup] backup-list:%s" % self.backupNameserverList) self["key_yellow"] = StaticText(_("Add")) self["key_blue"] = StaticText(_("Delete")) @@ -376,7 +383,7 @@ def __init__(self, session): { "yellow": (self.add, _("Add a nameserver entry")), "blue": (self.remove, _("Remove a nameserver entry")), - }) + }) # noqa: E123 ConfigListScreen.__init__(self, [], session=session, on_change=self.changedEntry, fullUI=True) self.createConfig() self.createSetup() @@ -386,7 +393,7 @@ def createConfig(self): self.nameserverEntries = [NoSave(ConfigIP(default=nameserver)) for nameserver in self.nameservers] def createSetup(self): - self["config"].list = [getConfigListEntry(_("Nameserver %d") % (i + 1), x) for i, x in enumerate(self.nameserverEntries)] + self["config"].list = [getConfigListEntry(_("Nameserver %d") % (i + 1), x) for i, x in enumerate(self.nameserverEntries)] # noqa: E226 def keySave(self): iNetwork.clearNameservers() @@ -423,6 +430,7 @@ class NetworkMacSetup(ConfigListScreen, HelpableScreen, Screen): def __init__(self, session): Screen.__init__(self, session) HelpableScreen.__init__(self) + # print("[NetworkSetup][NetworkMacSetup]") self.skinName = ["NetworkMacSetup", "Setup"] self.setTitle(_("MAC Address Settings")) ifacex = "wlan0" @@ -484,7 +492,7 @@ class AdapterSetup(ConfigListScreen, HelpableScreen, Screen): def __init__(self, session, networkinfo=None, essid=None): Screen.__init__(self, session) HelpableScreen.__init__(self) - + # print("[NetworkSetup][AdapterSetup] ") if isinstance(networkinfo, (list, tuple)): self.iface = networkinfo[0] self.essid = networkinfo[1] @@ -496,16 +504,16 @@ def __init__(self, session, networkinfo=None, essid=None): self.extended = None self.applyConfigRef = None - self.finished_cb = None + self.finished_cb = None # switch used by Wizard/NetworkWizard to control Wizard process self.oktext = _("Press OK on your remote control to continue.") self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up") self.createConfig() self["ColorActions"] = HelpableActionMap(self, "ColorActions", - { - "blue": (self.KeyBlue, _("Open nameserver configuration")), - }) + { + "blue": (self.KeyBlue, _("Open nameserver configuration")), + }) ConfigListScreen.__init__(self, [], session=session, on_change=self.newConfig, fullUI=True) @@ -529,7 +537,7 @@ def __init__(self, session, networkinfo=None, essid=None): self["Adaptertext"] = StaticText(_("Network:")) self["Adapter"] = StaticText() - self["introduction2"] = StaticText(_("Press OK to activate the settings.")) + self["introduction2"] = StaticText(_("Enter adapter settings or disable adapter, then Save to action changed setup.")) self["key_blue"] = StaticText(_("Edit DNS")) def layoutFinished(self): @@ -578,10 +586,8 @@ def createConfig(self): if iNetwork.isWirelessInterface(self.iface): driver = iNetwork.detectWlanModule(self.iface) if driver in ("brcm-wl", ): - from Plugins.SystemPlugins.WirelessLan.Wlan import brcmWLConfig self.ws = brcmWLConfig() else: - from Plugins.SystemPlugins.WirelessLan.Wlan import wpaSupplicant self.ws = wpaSupplicant() self.encryptionlist = [] self.encryptionlist.append(("Unencrypted", _("Unencrypted"))) @@ -643,7 +649,6 @@ def createSetup(self): self.extended = callFnc if "configStrings" in p.fnc: self.configStrings = p.fnc["configStrings"] - isExistBcmWifi = os_path.exists("/tmp/bcm/" + self.iface) if not isExistBcmWifi: self.hiddenSSID = getConfigListEntry(_("Hidden network"), config.plugins.wlan.hiddenessid) @@ -681,7 +686,11 @@ def newConfig(self): def keySave(self): self.hideInputHelp() if self["config"].isChanged(): - self.session.openWithCallback(self.keySaveConfirm, MessageBox, (_("Are you sure you want to activate this network configuration?\n\n") + self.oktext)) + # print("[NetworkSetup][AdapterSetup][keySave] interface value", self.activateInterfaceEntry.value) + if self.activateInterfaceEntry.value: + self.session.openWithCallback(self.keySaveConfirm, MessageBox, (_("Are you sure you want to activate this network configuration?\n\n") + self.oktext)) + else: + self.session.openWithCallback(self.keySaveConfirm, MessageBox, (_("Are you sure you want to disable this network configuration?\n\n") + self.oktext)) else: if self.finished_cb: self.finished_cb() @@ -728,7 +737,6 @@ def applyConfig(self, ret=False): iNetwork.setAdapterAttribute(self.iface, "gateway", self.gatewayConfigEntry.value) else: iNetwork.removeAdapterAttribute(self.iface, "gateway") - if self.extended is not None and self.configStrings is not None: iNetwork.setAdapterAttribute(self.iface, "configStrings", self.configStrings(self.iface)) self.ws.writeConfig(self.iface) @@ -736,7 +744,7 @@ def applyConfig(self, ret=False): if self.activateInterfaceEntry.value is False: iNetwork.deactivateInterface(self.iface, self.deactivateInterfaceCB) iNetwork.writeNetworkConfig() - self.applyConfigRef = self.session.openWithCallback(self.applyConfigfinishedCB, MessageBox, _("Please wait while your network configuration is activated..."), type=MessageBox.TYPE_INFO, enable_input=False) + self.applyConfigRef = self.session.openWithCallback(self.applyConfigfinishedCB, MessageBox, _("Please wait while your network configuration is deactivated..."), type=MessageBox.TYPE_INFO, enable_input=False) else: if self.oldInterfaceState is False: iNetwork.activateInterface(self.iface, self.deactivateInterfaceCB) @@ -765,15 +773,16 @@ def getInterfacesDataAvail(self, data): def applyConfigfinishedCB(self, data): if data is True: - if self.finished_cb: + if self.finished_cb: # switch set by Wizard/NetworkWizard to control return to wizard self.session.openWithCallback(lambda x: self.finished_cb(), MessageBox, _("Your network configuration has been activated."), type=MessageBox.TYPE_INFO, timeout=10) + elif self.activateInterfaceEntry.value is False: # if not wizard check for disable/enable Adapter + self.session.openWithCallback(self.ConfigfinishedCB, MessageBox, _("Your network configuration has been disabled."), type=MessageBox.TYPE_INFO, timeout=10) else: self.session.openWithCallback(self.ConfigfinishedCB, MessageBox, _("Your network configuration has been activated."), type=MessageBox.TYPE_INFO, timeout=10) def ConfigfinishedCB(self, data): - if data is not None: - if data is True: - self.close("ok") + if data is not None and data: + self.close('ok') def keyCancelConfirm(self, result): if not result: @@ -791,11 +800,11 @@ def keyCancel(self): self.close("cancel") def keyCancelCB(self, data): - if data is not None: - if data is True: - self.close("cancel") + if data is not None and data: + self.close("cancel") - def runAsync(self, finished_cb): + def runAsync(self, finished_cb): # Async used by Wizard/NetworkWizard to control Wizard code flow + # print("[NetworkSetup][AdapterSetup][runAsync1] finished_cb", finished_cb) self.finished_cb = finished_cb self.keySave() @@ -848,23 +857,23 @@ def __init__(self, session, iface=None): self.missingwlanplugintxt = _("The wireless LAN plugin is not installed!\nPlease install it.") self["WizardActions"] = HelpableActionMap(self, "WizardActions", - { - "up": (self.up, _("Move up to previous entry")), - "down": (self.down, _("Move down to next entry")), - "left": (self.left, _("Move up to first entry")), - "right": (self.right, _("Move down to last entry")), - }) + { + "up": (self.up, _("Move up to previous entry")), + "down": (self.down, _("Move down to next entry")), + "left": (self.left, _("Move up to first entry")), + "right": (self.right, _("Move down to last entry")), + }) self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", - { - "cancel": (self.close, _("Exit network adapter setup menu")), - "ok": (self.ok, _("Select menu entry")), - }) + { + "cancel": (self.close, _("Exit network adapter setup menu")), + "ok": (self.ok, _("Select menu entry")), + }) self["ColorActions"] = HelpableActionMap(self, "ColorActions", - { - "red": (self.close, _("Exit network adapter setup menu")), - }) + { + "red": (self.close, _("Exit network adapter setup menu")), + }) self["actions"] = NumberActionMap(["WizardActions", "ShortcutActions"], { @@ -875,7 +884,7 @@ def __init__(self, session, iface=None): "red": self.close, "left": self.left, "right": self.right, - }, -2) + }, -2) # noqa: E123 self.updateStatusbar() self.onClose.append(self.cleanup) @@ -893,7 +902,7 @@ def queryWirelessDevice(self, iface): else: try: system("ifconfig %s up" % iface) - wlanresponse = list(Cell.all(iface)) # what is this? local variable 'wlanresponse' is assigned to but never used + wlanresponse = list(Cell.all(iface)) # noqa: F841 call to check setup except IOError as err: error_no, error_str = err.args if error_no in (errno.EOPNOTSUPP, errno.ENODEV, errno.EPERM): @@ -908,15 +917,10 @@ def ok(self): self.cleanup() if self["menulist"].getCurrent()[1] == "edit": if iNetwork.isWirelessInterface(self.iface): - try: - from Plugins.SystemPlugins.WirelessLan.plugin import WlanScan - except ImportError: - self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) + if wirelessLan and self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface) else: - if self.queryWirelessDevice(self.iface): - self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface) - else: - self.showErrorMessage() # Display Wlan not available Message + self.showErrorMessage() # Display Wlan not available Message else: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface) if self["menulist"].getCurrent()[1] == "test": @@ -926,29 +930,18 @@ def ok(self): if self["menulist"].getCurrent()[1] == 'mac': self.session.open(NetworkMacSetup) if self["menulist"].getCurrent()[1] == "scanwlan": - try: - from Plugins.SystemPlugins.WirelessLan.plugin import WlanScan - except ImportError: - self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) + if wirelessLan and self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.WlanScanClosed, WlanScan, self.iface) else: - if self.queryWirelessDevice(self.iface): - self.session.openWithCallback(self.WlanScanClosed, WlanScan, self.iface) - else: - self.showErrorMessage() # Display Wlan not available Message + self.showErrorMessage() # Display Wlan not available Message if self["menulist"].getCurrent()[1] == "wlanstatus": - try: - from Plugins.SystemPlugins.WirelessLan.plugin import WlanStatus - except ImportError: - self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) + if wirelessLan and self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.WlanStatusClosed, WlanStatus, self.iface) else: - if self.queryWirelessDevice(self.iface): - self.session.openWithCallback(self.WlanStatusClosed, WlanStatus, self.iface) - else: - self.showErrorMessage() # Display Wlan not available Message + self.showErrorMessage() # Display Wlan not available Message if self["menulist"].getCurrent()[1] == "lanrestart": self.session.openWithCallback(self.restartLan, MessageBox, (_("Are you sure you want to restart your network interfaces?\n\n") + self.oktext)) if self["menulist"].getCurrent()[1] == "openwizard": - from Plugins.SystemPlugins.NetworkWizard.NetworkWizard import NetworkWizard self.session.openWithCallback(self.AdapterSetupClosed, NetworkWizard, self.iface) if self["menulist"].getCurrent()[1][0] == "extendedSetup": self.extended = self["menulist"].getCurrent()[1][2] @@ -972,11 +965,11 @@ def createSummary(self): def selectionChanged(self): if self["menulist"].getCurrent()[1] == "edit": - self["description"].setText(_("Edit the network configuration of your %s %s.\n") % (getMachineBrand(), getMachineName()) + self.oktext) + self["description"].setText(_("Edit the network configuration of your %s %s.\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + self.oktext) if self["menulist"].getCurrent()[1] == "test": - self["description"].setText(_("Test the network configuration of your %s %s.\n") % (getMachineBrand(), getMachineName()) + self.oktext) + self["description"].setText(_("Test the network configuration of your %s %s.\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + self.oktext) if self["menulist"].getCurrent()[1] == "dns": - self["description"].setText(_("Edit the Nameserver configuration of your %s %s.\n") % (getMachineBrand(), getMachineName()) + self.oktext) + self["description"].setText(_("Edit the Nameserver configuration of your %s %s.\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + self.oktext) if self["menulist"].getCurrent()[1] == "scanwlan": self["description"].setText(_("Scan your network for wireless access points and connect to them using your selected wireless device.\n") + self.oktext) if self["menulist"].getCurrent()[1] == "wlanstatus": @@ -988,7 +981,7 @@ def selectionChanged(self): if self["menulist"].getCurrent()[1][0] == "extendedSetup": self["description"].setText(_(self["menulist"].getCurrent()[1][1]) + self.oktext) if self["menulist"].getCurrent()[1] == "mac": - self["description"].setText(_("Set the MAC address of your %s %s.\n") % (getMachineBrand(), getMachineName()) + self.oktext) + self["description"].setText(_("Set the MAC address of your %s %s.\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + self.oktext) item = self["menulist"].getCurrent() if item: name = str(self["menulist"].getCurrent()[0]) @@ -1008,13 +1001,11 @@ def updateStatusbar(self, data=None): if iNetwork.isWirelessInterface(self.iface): self["devicepic"].setPixmapNum(1) - try: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus - except: + if wirelessLan: + iStatus.getDataForInterface(self.iface, self.getInfoCB) + else: self["statuspic"].setPixmapNum(1) self["statuspic"].show() - else: - iStatus.getDataForInterface(self.iface, self.getInfoCB) else: iNetwork.getLinkState(self.iface, self.dataAvail) self["devicepic"].setPixmapNum(0) @@ -1048,25 +1039,23 @@ def genMainMenu(self): self.extendedSetup = ("extendedSetup", menuEntryDescription, self.extended) menu.append((menuEntryName, self.extendedSetup)) - if os_path.exists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")): + if XML_networkWizard: menu.append((_("Network wizard"), "openwizard")) - # kernel_ver = about.getKernelVersionString() - # if kernel_ver <= "3.5.0": + # kernel_ver = about.getKernelVersionString() + # if kernel_ver <= "3.5.0": menu.append((_("Network MAC settings"), "mac")) return menu def AdapterSetupClosed(self, *ret): if ret is not None and len(ret): if ret[0] == "ok" and (iNetwork.isWirelessInterface(self.iface) and iNetwork.getAdapterAttribute(self.iface, "up") is True): - try: - from Plugins.SystemPlugins.WirelessLan.plugin import WlanStatus - except ImportError: - self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) - else: + if wirelessLan: if self.queryWirelessDevice(self.iface): self.session.openWithCallback(self.WlanStatusClosed, WlanStatus, self.iface) else: self.showErrorMessage() # Display Wlan not available Message + else: + self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) else: self.updateStatusbar() else: @@ -1074,7 +1063,6 @@ def AdapterSetupClosed(self, *ret): def WlanStatusClosed(self, *ret): if ret is not None and len(ret): - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus iStatus.stopWlanConsole() self.updateStatusbar() @@ -1082,7 +1070,6 @@ def WlanScanClosed(self, *ret): if ret[0] is not None: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface, ret[0]) else: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus iStatus.stopWlanConsole() self.updateStatusbar() @@ -1105,7 +1092,6 @@ def restartfinishedCB(self, data): self.session.open(MessageBox, _("Your network has finished restarting"), type=MessageBox.TYPE_INFO, timeout=10, default=False) def dataAvail(self, data): - data = six.ensure_str(data) self.LinkState = None for line in data.splitlines(): line = line.strip() @@ -1128,11 +1114,7 @@ def cleanup(self): iNetwork.stopDeactivateInterfaceConsole() iNetwork.stopActivateInterfaceConsole() iNetwork.stopPingConsole() - try: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus - except ImportError: - pass - else: + if wirelessLan: iStatus.stopWlanConsole() def getInfoCB(self, data, status): @@ -1495,15 +1477,13 @@ def setLabels(self): def getLinkState(self, iface): if iface in iNetwork.wlan_interfaces: - try: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus - except: + if wirelessLan: + iStatus.getDataForInterface(self.iface, self.getInfoCB) + else: self["Network"].setForegroundColorNum(1) self["Network"].setText(_("disconnected")) self["NetworkInfo_Check"].setPixmapNum(1) self["NetworkInfo_Check"].show() - else: - iStatus.getDataForInterface(self.iface, self.getInfoCB) else: iNetwork.getLinkState(iface, self.LinkStatedataAvail) @@ -1578,11 +1558,7 @@ def getInfoCB(self, data, status): def cleanup(self): iNetwork.stopLinkStateConsole() iNetwork.stopDNSConsole() - try: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus - except ImportError: - pass - else: + if wirelessLan: iStatus.stopWlanConsole() @@ -1599,23 +1575,23 @@ def __init__(self, session): self["introduction"] = StaticText() self["WizardActions"] = HelpableActionMap(self, "WizardActions", - { - "up": (self.up, _("Move up to previous entry")), - "down": (self.down, _("Move down to next entry")), - "left": (self.left, _("Move up to first entry")), - "right": (self.right, _("Move down to last entry")), - }) + { + "up": (self.up, _("Move up to previous entry")), + "down": (self.down, _("Move down to next entry")), + "left": (self.left, _("Move up to first entry")), + "right": (self.right, _("Move down to last entry")), + }) self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", - { - "cancel": (self.close, _("Exit mounts setup menu")), - "ok": (self.ok, _("Select menu entry")), - }) + { + "cancel": (self.close, _("Exit mounts setup menu")), + "ok": (self.ok, _("Select menu entry")), + }) self["ColorActions"] = HelpableActionMap(self, "ColorActions", - { - "red": (self.close, _("Exit networkadapter setup menu")), - }) + { + "red": (self.close, _("Exit networkadapter setup menu")), + }) self["actions"] = NumberActionMap(["WizardActions", "ShortcutActions"], { @@ -1626,7 +1602,7 @@ def __init__(self, session): "red": self.close, "left": self.left, "right": self.right, - }, -2) + }, -2) # noqa: E123 if self.selectionChanged not in self["menulist"].onSelectionChanged: self["menulist"].onSelectionChanged.append(self.selectionChanged) @@ -2284,7 +2260,7 @@ def updateService(self): line = line[18:] line = (int(line) // 60) self["labtime"].setText(str(line)) - elif line.startswith("dyndns_system ") or line.startswith("#dyndns_system "): + elif line.startswith(("dyndns_system ", "#dyndns_system ")): if line.startswith("#"): line = line[15:] self["sactive"].hide() @@ -2344,7 +2320,7 @@ def updateList(self): line = (int(line[18:]) // 60) self.ina_period = NoSave(ConfigNumber(default=line)) # overwrite so we start with the correct defaults self.list.append(getConfigListEntry(_("Time update in minutes") + ":", self.ina_period)) - elif line.startswith("dyndns_system ") or line.startswith("#dyndns_system "): + elif line.startswith(("dyndns_system ", "#dyndns_system ")): if not line.startswith("#"): default = True line = line[14:] @@ -2376,7 +2352,7 @@ def keySave(self): # saveIna strview = (self.ina_period.value * 60) strview = str(strview) line = ("update_period_sec " + strview) - elif line.startswith("dyndns_system ") or line.startswith("#dyndns_system "): + elif line.startswith(("dyndns_system ", "#dyndns_system ")): if self.ina_sysactive.value: line = ("dyndns_system " + self.ina_system.value.strip()) else: @@ -2581,7 +2557,7 @@ def __init__(self, session): def updateList(self, ret=None): self.list = [] - self.ushare_user = NoSave(ConfigText(default=getBoxType(), fixed_size=False)) + self.ushare_user = NoSave(ConfigText(default=SystemInfo["boxtype"], fixed_size=False)) self.ushare_iface = NoSave(ConfigText(fixed_size=False)) self.ushare_port = NoSave(ConfigNumber()) self.ushare_telnetport = NoSave(ConfigNumber()) @@ -2946,7 +2922,7 @@ def __init__(self, session): def updateList(self, ret=None): self.list = [] - self.minidlna_name = NoSave(ConfigText(default=getBoxType(), fixed_size=False)) + self.minidlna_name = NoSave(ConfigText(default=SystemInfo["boxtype"], fixed_size=False)) self.minidlna_iface = NoSave(ConfigText(fixed_size=False)) self.minidlna_port = NoSave(ConfigNumber()) self.minidlna_serialno = NoSave(ConfigNumber()) @@ -3168,7 +3144,7 @@ def newRandom(self): self["config"].invalidateCurrent() def createSetup(self): - instructions = _("Setting a network password is mandatory in OpenViX %s if you wish to use network services. \nTo set a password using the virtual keyboard press the 'text' button on your remote control.") % getImageVersion() + instructions = _("Setting a network password is mandatory in OpenViX %s if you wish to use network services. \nTo set a password using the virtual keyboard press the 'text' button on your remote control.") % SystemInfo["imageversion"] self.list.append(getConfigListEntry(_('New password'), self.password, instructions)) self['config'].list = self.list diff --git a/lib/python/Screens/OScamInfo.py b/lib/python/Screens/OScamInfo.py index 6427b8bf0fe..76a7743a078 100644 --- a/lib/python/Screens/OScamInfo.py +++ b/lib/python/Screens/OScamInfo.py @@ -137,17 +137,17 @@ def getUserData(self): elif "httpport" in i.lower(): port = i.split("=")[1].strip() elif "httpallowed" in i.lower(): - # Once we encounter a httpallowed statement, we have to assume oscam/ncam webif is blocking us ... - blocked = True + # Once we encounter a httpallowed statement, we have to assume oscam/ncam webif is blocking us allowed = i.split("=")[1].strip() - if "::1" in allowed or "127.0.0.1" in allowed or "0.0.0.0-255.255.255.255" in allowed: - # ... until we find either 127.0.0.1 or ::1 in allowed list - blocked = False if "::1" not in allowed: ipconfigured = False - - ret = [user, pwd, port, ipconfigured] # 127.0.0.1 gets 403 in oscam webif so ignore block fix later - + if "::1" in allowed or "127.0.0.1" in allowed or "0.0.0.0-255.255.255.255" in allowed: + # ... until we find either 127.0.0.1 or ::1 in allowed list + blocked = False # noqa: F841 + else: + blocked = True + if not blocked: + ret = [user, pwd, port, ipconfigured] return ret def openWebIF(self, part=None, reader=None): @@ -245,10 +245,10 @@ def readXML(self, typ): for client in clients: name = client.attrib["name"] proto = client.attrib["protocol"] - if "au" in client.attrib: - au = client.attrib["au"] - else: - au = "" + # au = client.attrib["au"] if "au" in client.attrib else "" + # login = client.find("times").attrib["login"] + # online = client.find("times").attrib["online"] + # port = client.find("connection").attrib["port"] caid = client.find("request").attrib["caid"] srvid = client.find("request").attrib["srvid"] if "ecmtime" in client.find("request").attrib: @@ -260,22 +260,15 @@ def readXML(self, typ): else: ecmtime = _("n/a") srvname = client.find("request").text + srvname_short = _("n/a") if srvname is not None: - if ":" in srvname: - srvname_short = srvname.split(":")[1].strip() - else: - srvname_short = srvname - else: - srvname_short = _("n/a") - login = client.find("times").attrib["login"] - online = client.find("times").attrib["online"] + srvname_short = srvname.split(":")[1].strip() if ":" in srvname else srvname if proto.lower() == "dvbapi": ip = "" else: ip = client.find("connection").attrib["ip"] if ip == "0.0.0.0": ip = "" - port = client.find("connection").attrib["port"] connstatus = client.find("connection").text if name != "" and name != "anonymous" and proto != "": try: @@ -423,7 +416,6 @@ def __init__(self, list, itemH=30): class OscamInfoMenu(Screen): def __init__(self, session): Screen.__init__(self, session) - NAMEBIN = check_NAMEBIN() NAMEBIN2 = check_NAMEBIN2() self.setTitle(_("%s Info - Main Menu" % NAMEBIN2)) self.menu = [_("Show Ecm info"), _("Show Clients"), _("Show Readers/Proxies"), _("Show Log"), _("Card info (CCcam-Reader)"), _("Ecm Statistics"), _("Setup")] @@ -585,7 +577,6 @@ def buildMenu(self, mlist): return menuentries def showMenu(self): - NAMEBIN = check_NAMEBIN() entr = self.buildMenu(self.menu) self["mainmenu"].l.setList(entr) self["mainmenu"].moveToIndex(0) @@ -626,7 +617,7 @@ def buildListEntry(self, listentry): def showData(self): dataECM = self.getECMInfo(self.ecminfo) out = [] - y = 0 + # y = 0 for i in dataECM: out.append(self.buildListEntry(i)) self["output"].l.setItemHeight(int(30 * f)) @@ -814,7 +805,6 @@ def buildLogListEntry(self, listentry): return res def showData(self): - NAMEBIN = check_NAMEBIN() NAMEBIN2 = check_NAMEBIN2() if self.firstrun: data = self.webif_data @@ -1133,20 +1123,20 @@ def showData(self): if dataWebif[0]: dataReader = ElementTree.XML(dataWebif[1]) rdr = dataReader.find("reader") -# emms = rdr.find("emmstats") -# if "totalwritten" in emms.attrib: -# emm_wri = emms.attrib["totalwritten"] -# if "totalskipped" in emms.attrib: -# emm_ski = emms.attrib["totalskipped"] -# if "totalblocked" in emms.attrib: -# emm_blk = emms.attrib["totalblocked"] -# if "totalerror" in emms.attrib: -# emm_err = emms.attrib["totalerror"] + # emms = rdr.find("emmstats") + # if "totalwritten" in emms.attrib: + # emm_wri = emms.attrib["totalwritten"] + # if "totalskipped" in emms.attrib: + # emm_ski = emms.attrib["totalskipped"] + # if "totalblocked" in emms.attrib: + # emm_blk = emms.attrib["totalblocked"] + # if "totalerror" in emms.attrib: + # emm_err = emms.attrib["totalerror"] ecmstat = rdr.find("ecmstats") - totalecm = ecmstat.attrib["totalecm"] + # totalecm = ecmstat.attrib["totalecm"] ecmcount = ecmstat.attrib["count"] and int(ecmstat.attrib["count"]) or 0 - lastacc = ecmstat.attrib["lastaccess"] + # lastacc = ecmstat.attrib["lastaccess"] ecm = ecmstat.findall("ecm") if ecmcount > 0: for j in ecm: @@ -1154,7 +1144,7 @@ def showData(self): channel = j.attrib["channelname"] avgtime = j.attrib["avgtime"] lasttime = j.attrib["lasttime"] - retcode = j.attrib["rc"] + # retcode = j.attrib["rc"] rcs = j.attrib["rcs"] num = j.text if rcs == "found": diff --git a/lib/python/Screens/ParentalControlSetup.py b/lib/python/Screens/ParentalControlSetup.py index 167c2e2d917..8dc9776d8ba 100644 --- a/lib/python/Screens/ParentalControlSetup.py +++ b/lib/python/Screens/ParentalControlSetup.py @@ -1,8 +1,8 @@ -from operator import itemgetter +from operator import itemgetter # noqa: F401 -from Components.config import config, getConfigListEntry, ConfigNothing, NoSave, ConfigPIN, configfile +from Components.config import config, getConfigListEntry, ConfigNothing, NoSave, ConfigPIN, configfile # noqa: F401 from Components.ConfigList import ConfigListScreen -from Screens.ChoiceBox import ChoiceBox +from Screens.ChoiceBox import ChoiceBox # noqa: F401 from Screens.InputBox import PinInput from Screens.MessageBox import MessageBox from Screens.Screen import Screen diff --git a/lib/python/Screens/PictureInPicture.py b/lib/python/Screens/PictureInPicture.py index f80fcaf3e40..628de6e9be2 100644 --- a/lib/python/Screens/PictureInPicture.py +++ b/lib/python/Screens/PictureInPicture.py @@ -218,8 +218,8 @@ def getModeName(self): def playService(self, service): if service is None: return False - from Screens.InfoBarGenerics import streamrelayChecker - ref = streamrelayChecker(self.resolveAlternatePipService(service)) + from Screens.InfoBarGenerics import streamrelay + ref = streamrelay.streamrelayChecker(self.resolveAlternatePipService(service)) if ref: if SystemInfo["CanNotDoSimultaneousTranscodeAndPIP"] and StreamServiceList: self.pipservice = None diff --git a/lib/python/Screens/PluginBrowser.py b/lib/python/Screens/PluginBrowser.py index afe3ca39fd6..ed015ca1dea 100644 --- a/lib/python/Screens/PluginBrowser.py +++ b/lib/python/Screens/PluginBrowser.py @@ -1,7 +1,6 @@ from os import path, unlink from enigma import eConsoleAppContainer, eDVBDB, eTimer -from boxbranding import getImageType, getMachineBrand, getMachineName from Components.ActionMap import ActionMap, NumberActionMap from Components.Button import Button @@ -14,6 +13,7 @@ from Components.PluginComponent import plugins from Components.PluginList import PluginList, PluginEntryComponent, PluginCategoryComponent, PluginDownloadComponent from Components.Sources.StaticText import StaticText +from Components.SystemInfo import SystemInfo from Plugins.Plugin import PluginDescriptor from Screens.ChoiceBox import ChoiceBox from Screens.Console import Console @@ -470,13 +470,13 @@ def runInstall(self, val): self.doRemove(self.installFinished, self["list"].l.getCurrentSelection()[0].name + " --force-remove --force-depends") def doRemove(self, callback, pkgname): - if pkgname.startswith('kernel-module-') or pkgname.startswith('enigma2-locale-'): + if pkgname.startswith(('kernel-module-', 'enigma2-locale-')): self.session.openWithCallback(callback, Console, cmdlist=[self.ipkg_remove + Ipkg.opkgExtraDestinations() + " " + pkgname, "sync"], closeOnSuccess=True) else: self.session.openWithCallback(callback, Console, cmdlist=[self.ipkg_remove + Ipkg.opkgExtraDestinations() + " " + self.PLUGIN_PREFIX + pkgname, "sync"], closeOnSuccess=True) def doInstall(self, callback, pkgname): - if pkgname.startswith('kernel-module-') or pkgname.startswith('enigma2-locale-'): + if pkgname.startswith(('kernel-module-', 'enigma2-locale-')): self.session.openWithCallback(callback, Console, cmdlist=[self.ipkg_install + " " + pkgname, "sync"], closeOnSuccess=True) else: self.session.openWithCallback(callback, Console, cmdlist=[self.ipkg_install + " " + self.PLUGIN_PREFIX + pkgname, "sync"], closeOnSuccess=True) @@ -505,9 +505,9 @@ def startRun(self): self.listHeight = listsize.height() if self.type == self.DOWNLOAD: self.type = self.UPDATE - if (getImageType() != "release" and feedsstatuscheck.getFeedsBool() not in ("unknown", "alien", "developer")) or (getImageType() == "release" and feedsstatuscheck.getFeedsBool() not in ("stable", "unstable", "alien", "developer")): + if (SystemInfo["imagetype"] != "release" and feedsstatuscheck.getFeedsBool() not in ("unknown", "alien", "developer")) or (SystemInfo["imagetype"] == "release" and feedsstatuscheck.getFeedsBool() not in ("stable", "unstable", "alien", "developer")): self["text"].setText(feedsstatuscheck.getFeedsErrorMessage()) - elif getImageType() != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): + elif SystemInfo["imagetype"] != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): self["text"].setText(_("WARNING: feeds may be unstable.") + '\n' + _("Downloading plugin information. Please wait...")) self.container.execute(self.ipkg + " update") elif config.softwareupdate.updateisunstable.value == 1 and not config.softwareupdate.updatebeta.value: diff --git a/lib/python/Screens/PowerTimerEntry.py b/lib/python/Screens/PowerTimerEntry.py index 52adcc78aa5..cd6caf2447c 100644 --- a/lib/python/Screens/PowerTimerEntry.py +++ b/lib/python/Screens/PowerTimerEntry.py @@ -1,6 +1,5 @@ from Screens.TimerEntryBase import TimerEntryBase, TimerLogBase from Components.config import ConfigSelection, ConfigYesNo, ConfigInteger -from Components.ActionMap import HelpableActionMap, NumberActionMap from Components.SystemInfo import SystemInfo from PowerTimer import AFTEREVENT, TIMERTYPE from time import time diff --git a/lib/python/Screens/Recordings.py b/lib/python/Screens/Recordings.py index c36e2cee52c..2d50d16b46c 100644 --- a/lib/python/Screens/Recordings.py +++ b/lib/python/Screens/Recordings.py @@ -3,7 +3,6 @@ from Components.config import config from Components.UsageConfig import preferredPath from Screens.LocationBox import MovieLocationBox -from Screens.MessageBox import MessageBox from Screens.Setup import Setup from Tools.Directories import fileExists import Components.Harddisk @@ -16,11 +15,12 @@ def __init__(self, session): self.buildChoices("DefaultPath", config.usage.default_path, None) self.buildChoices("TimerPath", config.usage.timer_path, None) self.buildChoices("InstantPath", config.usage.instantrec_path, None) + self.errorItem = -1 Setup.__init__(self, session=session, setup="recording") self.greenText = self["key_green"].text - self.errorItem = -1 if self.getCurrentItem() in (config.usage.default_path, config.usage.timer_path, config.usage.instantrec_path): self.pathStatus(self.getCurrentValue()) + self.changedEntry() def buildChoices(self, item, configEntry, path): configList = config.movielist.videodirs.value[:] @@ -97,7 +97,6 @@ def selectionChanged(self): Setup.selectionChanged(self) else: self["config"].setCurrentIndex(self.errorItem) - self.errorMsg() def changedEntry(self): if self.getCurrentItem() in (config.usage.default_path, config.usage.timer_path, config.usage.instantrec_path): @@ -112,11 +111,6 @@ def keySelect(self): else: Setup.keySelect(self) - def errorMsg(self): - self.session.open(MessageBox, "%s\n\n%s" % (self.footnote, _("Please select a valid directory.")), type=MessageBox.TYPE_ERROR) - def keySave(self): if self.errorItem == -1: Setup.keySave(self) - else: - self.errorMsg() diff --git a/lib/python/Screens/Satconfig.py b/lib/python/Screens/Satconfig.py index 5e47109a1f1..624ec7b1e70 100644 --- a/lib/python/Screens/Satconfig.py +++ b/lib/python/Screens/Satconfig.py @@ -8,7 +8,7 @@ from Components.Label import Label from Components.UsageConfig import showrotorpositionChoicesUpdate, preferredTunerChoicesUpdate from Components.SelectionList import SelectionList, SelectionEntryComponent -from Components.config import getConfigListEntry, config, ConfigNothing, ConfigBoolean, configfile, NoSave, ConfigSelection +from Components.config import getConfigListEntry, config, ConfigNothing, ConfigBoolean, configfile, ConfigSelection from Components.Sources.List import List from Components.Sources.StaticText import StaticText from Screens.MessageBox import MessageBox @@ -18,7 +18,6 @@ from Tools.BoundFunction import boundFunction from Tools.Directories import fileExists -from boxbranding import getImageType from time import mktime, localtime, time from datetime import datetime @@ -832,7 +831,7 @@ def okbuttonClick(self): recordings = self.session.nav.getRecordings() next_rec_time = self.session.nav.RecordTimer.getNextRecordingTime() if recordings or (next_rec_time and next_rec_time > 0 and (next_rec_time - time()) < 360): - if getImageType() == 'release': + if SystemInfo["imagetype"] == 'release': self.session.open(MessageBox, _("Recording(s) are in progress or coming up in few seconds!"), MessageBox.TYPE_INFO, timeout=5, enable_input=False) else: message = _("Recording(s) are in progress or coming up in few seconds!") diff --git a/lib/python/Screens/Screen.py b/lib/python/Screens/Screen.py index 48593471f16..b3536a9544f 100644 --- a/lib/python/Screens/Screen.py +++ b/lib/python/Screens/Screen.py @@ -1,6 +1,6 @@ from enigma import eRCInput, eTimer, eWindow # , getDesktop -from skin import GUI_SKIN_ID, applyAllAttributes +from skin import GUI_SKIN_ID, applyAllAttributes # noqa: F401 GUI_SKIN_ID used by debug from Components.config import config from Components.GUIComponent import GUIComponent from Components.Sources.Source import Source @@ -50,6 +50,7 @@ def __init__(self, session, parent=None, mandatoryWidgets=None): self["title"] = StaticText() # DEBUG: Hack to support for some summary screens. self.screenPath = "" # This is the current screen path without the title. self.screenTitle = "" # This is the current screen title without the path. + self.handledWidgets = [] def __repr__(self): return str(type(self)) @@ -262,7 +263,7 @@ def createGUIScreen(self, parent, desktop, updateonly=False): if depr: print("[Screen] WARNING: OBSOLETE COMPONENT '%s' USED IN SKIN. USE '%s' INSTEAD!" % (key, depr[0])) print("[Screen] OBSOLETE COMPONENT WILL BE REMOVED %s, PLEASE UPDATE!" % depr[1]) - elif not depr: + elif not depr and key not in self.handledWidgets: print("[Screen] Warning: Skin is missing element '%s' in %s." % (key, str(self))) for w in self.additionalWidgets: if not updateonly: diff --git a/lib/python/Screens/ServiceInfo.py b/lib/python/Screens/ServiceInfo.py index 8c659beacb4..ca6ce171e06 100644 --- a/lib/python/Screens/ServiceInfo.py +++ b/lib/python/Screens/ServiceInfo.py @@ -172,9 +172,10 @@ def ShowServiceInformation(self): resolution = "-" if self.info: from Components.Converter.PliExtraInfo import codec_data + from Components.Converter.ServiceInfo import getVideoHeight, getVideoWidth videocodec = codec_data.get(self.info.getInfo(iServiceInformation.sVideoType), "N/A") - width = self.info.getInfo(iServiceInformation.sVideoWidth) - height = self.info.getInfo(iServiceInformation.sVideoHeight) + width = getVideoWidth(self.info) + height = getVideoHeight(self.info) if width > 0 and height > 0: fps = (self.info.getInfo(iServiceInformation.sFrameRate) + 500) // 1000 if fps in (0, -1): diff --git a/lib/python/Screens/Setup.py b/lib/python/Screens/Setup.py index 4f85501feea..b377271210b 100644 --- a/lib/python/Screens/Setup.py +++ b/lib/python/Screens/Setup.py @@ -58,11 +58,11 @@ def changedEntry(self): self.createSetup() ConfigListScreen.changedEntry(self) # force summary update immediately, not just on select/deselect - def createSetup(self): + def createSetup(self, appendItems=None, prependItems=None): oldList = self.list self.showDefaultChanged = False self.graphicSwitchChanged = False - self.list = [] + self.list = prependItems or [] title = None xmlData = setupDom(self.setup, self.plugin) for setup in xmlData.findall("setup"): @@ -76,6 +76,8 @@ def createSetup(self): # If this break is executed then there can only be one setup tag with this key. # This may not be appropriate if conditional setup blocks become available. break + if appendItems: + self.list += appendItems if title: title = dgettext(self.pluginLanguageDomain, title) if self.pluginLanguageDomain else _(title) self.setTitle(title if title else _("Setup")) diff --git a/lib/python/Screens/SoftwareUpdate.py b/lib/python/Screens/SoftwareUpdate.py index 8aaa463fffb..ea408bb8cde 100644 --- a/lib/python/Screens/SoftwareUpdate.py +++ b/lib/python/Screens/SoftwareUpdate.py @@ -1,6 +1,5 @@ from enigma import eTimer, eDVBDB -from boxbranding import getImageType, getMachineBrand, getMachineName from Components.ActionMap import ActionMap from Components.Button import Button from Components.config import config @@ -10,6 +9,7 @@ from Components.ScrollLabel import ScrollLabel # noqa: F401 from Components.Sources.StaticText import StaticText from Components.Slider import Slider +from Components.SystemInfo import SystemInfo import Components.Task from Screens.ChoiceBox import ChoiceBox from Screens.GitCommitInfo import CommitInfo, gitcommitinfo @@ -154,11 +154,11 @@ def checkNetworkState(self): self['tl_yellow'].show() else: self['tl_off'].show() - if (getImageType() != 'release' and self.trafficLight not in ("unknown", "alien", "developer")) or (getImageType() == 'release' and self.trafficLight not in ("stable", "unstable", "alien", "developer")): + if (SystemInfo["imagetype"] != 'release' and self.trafficLight not in ("unknown", "alien", "developer")) or (SystemInfo["imagetype"] == 'release' and self.trafficLight not in ("stable", "unstable", "alien", "developer")): self.session.openWithCallback(self.close, MessageBox, feedsstatuscheck.getFeedsErrorMessage(), type=MessageBox.TYPE_INFO, timeout=30, close_on_any_key=True) return else: - if getImageType() != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value) or config.softwareupdate.updateisunstable.value == 0: + if SystemInfo["imagetype"] != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value) or config.softwareupdate.updateisunstable.value == 0: if kernelMismatch(): self.session.openWithCallback(self.close, MessageBox, _("The Linux kernel has changed, an update is not permitted. \nInstall latest image using USB stick or Image Manager."), type=MessageBox.TYPE_INFO, timeout=30, close_on_any_key=True) return @@ -257,13 +257,13 @@ def ipkgCallback(self, event, param): self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE_LIST) elif self.ipkg.currentCommand == IpkgComponent.CMD_UPGRADE_LIST: self.total_packages = None - if (getImageType() != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value)) or config.softwareupdate.updateisunstable.value == 0: + if (SystemInfo["imagetype"] != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value)) or config.softwareupdate.updateisunstable.value == 0: self.total_packages = len(self.ipkg.getFetchedList()) packagesMsg = "\n(" + (ngettext("%s updated package available", "%s updated packages available", self.total_packages) % self.total_packages) + ")" - if getImageType() != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): - message = _("The current update may be unstable.") + "\n" + _("Are you sure you want to update your %s %s?") % (getMachineBrand(), getMachineName()) + packagesMsg + if SystemInfo["imagetype"] != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): + message = _("The current update may be unstable.") + "\n" + _("Are you sure you want to update your %s %s?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + packagesMsg elif config.softwareupdate.updateisunstable.value == 0: - message = _("Do you want to update your %s %s?") % (getMachineBrand(), getMachineName()) + packagesMsg + message = _("Do you want to update your %s %s?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + packagesMsg if self.total_packages: if self.total_packages > 150: message += " " + _("Reflash recommended!") @@ -315,14 +315,14 @@ def ipkgCallback(self, event, param): else: self.activityTimer.stop() self.activityslider.setValue(0) - error = _("Your %s %s might be unusable now. Please consult the manual for further assistance before rebooting your %s %s.") % (getMachineBrand(), getMachineName(), getMachineBrand(), getMachineName()) + error = _("Your %s %s might be unusable now. Please consult the manual for further assistance before rebooting your %s %s.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], SystemInfo["MachineBrand"], SystemInfo["MachineName"]) if self.packages == 0: if self.error != 0: error = _("Problem retrieving update list.\nIf this issue persists please check/report on forum") else: error = _("A background update check is in progress,\nplease wait a few minutes and try again.") if self.updating: - error = _("Update failed. Your %s %s does not have a working internet connection.") % (getMachineBrand(), getMachineName()) + error = _("Update failed. Your %s %s does not have a working internet connection.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) self.status.setText(_("Error") + " - " + error) self["actions"].setEnabled(True) elif event == IpkgComponent.EVENT_LISTITEM: @@ -347,9 +347,9 @@ def startActualUpgrade(self, answer): if answer[1] == "menu": packagesMsg = "\n(%s " % self.total_packages + _("Packages") + ")" if config.softwareupdate.updateisunstable.value == 1: - message = _("The current update may be unstable.") + "\n" + _("Are you sure you want to update your %s %s?") % (getMachineBrand(), getMachineName()) + packagesMsg + message = _("The current update may be unstable.") + "\n" + _("Are you sure you want to update your %s %s?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + packagesMsg elif config.softwareupdate.updateisunstable.value == 0: - message = _("Do you want to update your %s %s?") % (getMachineBrand(), getMachineName()) + packagesMsg + message = _("Do you want to update your %s %s?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + packagesMsg choices = [(_("View the changes"), "changes"), (_("Upgrade and reboot system"), "cold")] if not self.SettingsBackupDone and not config.softwareupdate.autosettingsbackup.value and config.backupmanager.backuplocation.value: @@ -393,7 +393,7 @@ def doSettingsBackup(self): self.showJobView(job) def doImageBackup(self): - backup = None + backup = None # noqa: F841 from Plugins.SystemPlugins.ViX.ImageManager import ImageBackup self.ImageBackup = ImageBackup(self.session, True) Components.Task.job_manager.AddJob(self.ImageBackup.createBackupJob()) @@ -428,7 +428,7 @@ def showJobView(self, job): def exit(self): if not self.ipkg.isRunning(): if self.packages != 0 and self.error == 0 and self.channellist_only == 0: - self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") + " " + _("Do you want to reboot your %s %s") % (getMachineBrand(), getMachineName())) + self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") + " " + _("Do you want to reboot your %s %s") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) else: self.close() else: diff --git a/lib/python/Screens/Standby.py b/lib/python/Screens/Standby.py index f43b6ff1827..c1b050ce245 100644 --- a/lib/python/Screens/Standby.py +++ b/lib/python/Screens/Standby.py @@ -1,9 +1,8 @@ from os import path from time import time -from enigma import eDVBVolumecontrol, eTimer, eDVBLocalTimeHandler, eServiceReference, eStreamServer +from enigma import eDVBVolumecontrol, eTimer, eDVBLocalTimeHandler, eServiceReference, eStreamServer, iRecordableService, quitMainloop -from boxbranding import getMachineBrand, getMachineName, getBoxType, getBrandOEM from Components.ActionMap import ActionMap from Components.AVSwitch import AVSwitch from Components.config import config @@ -11,9 +10,11 @@ import Components.ParentalControl from Components.SystemInfo import SystemInfo from Components.Sources.StreamService import StreamServiceList +from Components.Task import job_manager from GlobalActions import globalActionMap import Screens.InfoBar from Screens.Screen import Screen, ScreenSummary +from Screens.MessageBox import MessageBox import Tools.Notifications inStandby = None @@ -40,7 +41,7 @@ def setLCDMiniTVMode(value): class Standby2(Screen): def Power(self): - if getBrandOEM() in ('dinobot') or SystemInfo["HasHiSi"] or getBoxType() in ("sfx6008", "sfx6018"): + if SystemInfo["brand"] in ('dinobot') or SystemInfo["HasHiSi"] or SystemInfo["boxtype"] in ("sfx6008", "sfx6018"): try: open("/proc/stb/hdmi/output", "w").write("on") except: @@ -116,7 +117,7 @@ def __init__(self, session): self.avswitch.setInput("SCART") else: self.avswitch.setInput("AUX") - if getBrandOEM() in ('dinobot') or SystemInfo["HasHiSi"] or getBoxType() in ("sfx6008", "sfx6018"): + if SystemInfo["brand"] in ('dinobot') or SystemInfo["HasHiSi"] or SystemInfo["boxtype"] in ("sfx6008", "sfx6018"): try: open("/proc/stb/hdmi/output", "w").write("off") except: @@ -196,12 +197,6 @@ class StandbySummary(ScreenSummary): """ -from enigma import quitMainloop, iRecordableService -from Screens.MessageBox import MessageBox -from time import time -from Components.Task import job_manager - - class QuitMainloopScreen(Screen): def __init__(self, session, retvalue=1): self.skin = """ @@ -211,15 +206,15 @@ def __init__(self, session, retvalue=1): Screen.__init__(self, session) from Components.Label import Label text = { - QUIT_SHUTDOWN: _("Your %s %s is shutting down") % (getMachineBrand(), getMachineName()), - QUIT_REBOOT: _("Your %s %s is rebooting") % (getMachineBrand(), getMachineName()), - QUIT_RESTART: _("The user interface of your %s %s is restarting") % (getMachineBrand(), getMachineName()), - QUIT_ANDROID: _("Your %s %s is rebooting into Android Mode") % (getMachineBrand(), getMachineName()), - QUIT_MAINT: _("Your %s %s is rebooting into Recovery Mode") % (getMachineBrand(), getMachineName()), - QUIT_UPGRADE_FP: _("Your frontprocessor will be upgraded\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (getMachineBrand(), getMachineName()), - QUIT_ERROR_RESTART: _("The user interface of your %s %s is restarting\ndue to an error in StartEnigma.py") % (getMachineBrand(), getMachineName()), - QUIT_UPGRADE_PROGRAM: _("Upgrade in progress\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (getMachineBrand(), getMachineName()), - QUIT_IMAGE_RESTORE: _("Reflash in progress\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (getMachineBrand(), getMachineName()) + QUIT_SHUTDOWN: _("Your %s %s is shutting down") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_REBOOT: _("Your %s %s is rebooting") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_RESTART: _("The user interface of your %s %s is restarting") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_ANDROID: _("Your %s %s is rebooting into Android Mode") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_MAINT: _("Your %s %s is rebooting into Recovery Mode") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_UPGRADE_FP: _("Your frontprocessor will be upgraded\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_ERROR_RESTART: _("The user interface of your %s %s is restarting\ndue to an error in StartEnigma.py") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_UPGRADE_PROGRAM: _("Upgrade in progress\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_IMAGE_RESTORE: _("Reflash in progress\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) }.get(retvalue) self["text"] = Label(text) @@ -269,8 +264,8 @@ def __init__(self, session, retvalue=1, timeout=-1, default_yes=True): QUIT_ANDROID: _("Really reboot into Android Mode?"), QUIT_MAINT: _("Really reboot into Recovery Mode?"), QUIT_UPGRADE_FP: _("Really upgrade the frontprocessor and reboot now?"), - QUIT_UPGRADE_PROGRAM: _("Really upgrade your %s %s and reboot now?") % (getMachineBrand(), getMachineName()), - QUIT_IMAGE_RESTORE: _("Really reflash your %s %s and reboot now?") % (getMachineBrand(), getMachineName()) + QUIT_UPGRADE_PROGRAM: _("Really upgrade your %s %s and reboot now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_IMAGE_RESTORE: _("Really reflash your %s %s and reboot now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) }.get(retvalue) if text: MessageBox.__init__(self, session, "%s\n%s" % (reason, text), type=MessageBox.TYPE_YESNO, timeout=timeout, default=default_yes) @@ -301,23 +296,23 @@ def getRecordEvent(self, recservice, event): self.stopTimer() def sendCEC(self): - print("[Standby][sendCEC] entered ") - import struct - from enigma import eHdmiCEC - physicaladdress = eHdmiCEC.getInstance().getPhysicalAddress() - msgaddress = 0x0f # use broadcast for active source command - cmd0 = 0x9d # 157 sourceinactive - data0 = struct.pack("BB", int(physicaladdress // 256), int(physicaladdress % 256)) - data0 = data0.decode("UTF-8", "ignore") - cmd1 = 0x44 # 68 keypoweroff - data1 = struct.pack("B", 0x6c) - data1 = data1.decode("UTF-8", "ignore") - cmd2 = 0x36 # 54 standby - data2 = "" - eHdmiCEC.getInstance().sendMessage(msgaddress, cmd0, data0, len(data0)) - eHdmiCEC.getInstance().sendMessage(msgaddress, cmd1, data1, len(data1)) - eHdmiCEC.getInstance().sendMessage(msgaddress, cmd2, data2, len(data2)) - print("[Standby][sendCEC] departed ") + print("[Standby][sendCEC] entered ") + import struct + from enigma import eHdmiCEC # noqa: E402 + physicaladdress = eHdmiCEC.getInstance().getPhysicalAddress() + msgaddress = 0x0f # use broadcast for active source command + cmd0 = 0x9d # 157 sourceinactive + data0 = struct.pack("BB", int(physicaladdress // 256), int(physicaladdress % 256)) + data0 = data0.decode("UTF-8", "ignore") + cmd1 = 0x44 # 68 keypoweroff + data1 = struct.pack("B", 0x6c) + data1 = data1.decode("UTF-8", "ignore") + cmd2 = 0x36 # 54 standby + data2 = "" + eHdmiCEC.getInstance().sendMessage(msgaddress, cmd0, data0, len(data0)) + eHdmiCEC.getInstance().sendMessage(msgaddress, cmd1, data1, len(data1)) + eHdmiCEC.getInstance().sendMessage(msgaddress, cmd2, data2, len(data2)) + print("[Standby][sendCEC] departed ") def close(self, value): if self.connected: @@ -339,7 +334,7 @@ def close(self, value): # set LCDminiTV off / fix a deep-standby-crash on some boxes / gb4k print("[Standby] LCDminiTV off") setLCDMiniTVMode("0") - if getBoxType() == "vusolo4k": #workaround for white display flash + if SystemInfo["boxtype"] == "vusolo4k": # workaround for white display flash f = open("/proc/stb/fp/oled_brightness", "w") f.write("0") f.close() diff --git a/lib/python/Screens/StreamRelaySetup.py b/lib/python/Screens/StreamRelaySetup.py new file mode 100644 index 00000000000..339c98f9fcb --- /dev/null +++ b/lib/python/Screens/StreamRelaySetup.py @@ -0,0 +1,109 @@ +from Components.ActionMap import HelpableActionMap +from Components.config import ConfigNothing, NoSave +from Components.Sources.StaticText import StaticText +from Screens.InfoBarGenerics import streamrelay +from Screens.Setup import Setup + +from ServiceReference import ServiceReference + + +class StreamRelaySetup(Setup): + def __init__(self, session): + self.serviceitems = [] + self.services = streamrelay.data[:] + Setup.__init__(self, session=session, setup="streamrelay") + self["key_yellow"] = StaticText() + self["key_blue"] = StaticText() + self["addActions"] = HelpableActionMap(self, ["ColorActions"], { + "yellow": (self.keyAddService, _("Play service with Stream Relay")) + }, prio=0, description=_("Stream Relay Setup Actions")) + self["removeActions"] = HelpableActionMap(self, ["ColorActions"], { + "blue": (self.keyRemoveService, _("Play service without Stream Relay")) + }, prio=0, description=_("Stream Relay Setup Actions")) + self["removeActions"].setEnabled(False) + + def layoutFinished(self): + Setup.layoutFinished(self) + self.createItems() + + def createItems(self): + self.serviceitems = [] + if self.services: + for serviceref in self.services: + service = ServiceReference(serviceref) + self.serviceitems.append(((service and service.getServiceName() or serviceref) + " " + self.formatOrbPos(serviceref), NoSave(ConfigNothing()), serviceref, self.getOrbPos(serviceref))) + self.serviceitems.sort(key=self.sort) + self.serviceitems.insert(0, ("**************************",)) + self.createSetup() + + def createSetup(self): + Setup.createSetup(self, appendItems=self.serviceitems) + + def selectionChanged(self): + self.updateButtons() + Setup.selectionChanged(self) + + def updateButtons(self): + if self.services and isinstance(self.getCurrentItem(), ConfigNothing): + self["removeActions"].setEnabled(True) + self["key_blue"].setText(_("Remove")) + else: + self["removeActions"].setEnabled(False) + self["key_blue"].setText("") + self["key_yellow"].setText(_("Add service")) + + def keySelect(self): + if not isinstance(self.getCurrentItem(), ConfigNothing): + Setup.keySelect(self) + + def keyMenu(self): + if not isinstance(self.getCurrentItem(), ConfigNothing): + Setup.keyMenu(self) + + def keyRemoveService(self): + currentItem = self.getCurrentItem() + if currentItem: + serviceref = self["config"].getCurrent()[2] + self.services.remove(serviceref) + index = self["config"].getCurrentIndex() + self.createItems() + self["config"].setCurrentIndex(index) + + def keyAddService(self): + def keyAddServiceCallback(*result): + if result: + service = ServiceReference(result[0]) + serviceref = str(service) + if serviceref not in self.services: + self.services.append(serviceref) + self.createItems() + self["config"].setCurrentIndex(2) + + from Screens.ChannelSelection import SimpleChannelSelection # deferred to avoid circular import + self.session.openWithCallback(keyAddServiceCallback, SimpleChannelSelection, _("Select"), currentBouquet=False) + + def keySave(self): + if streamrelay.data != self.services: + streamrelay.data = self.services + Setup.keySave(self) + self.close() + + def getOrbPos(self, sref): + orbpos = 0 + try: + orbpos = int(sref.split(":")[6], 16) >> 16 + except: + pass + return orbpos + + def formatOrbPos(self, sref): + orbpos = self.getOrbPos(sref) + if isinstance(orbpos, int) and 1 <= orbpos <= 3600: # sanity + if orbpos > 1800: + return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" + else: + return str((float(orbpos)) / 10.0) + "\xb0" + "E" + return "" + + def sort(self, item): + return (item[3], item[0].lower() if item and item[0] and ord(item[0].lower()[0]) in range(97, 123) else f"zzzzz{item[0].lower()}") diff --git a/lib/python/Screens/TaskView.py b/lib/python/Screens/TaskView.py index e906ec0d788..5c7601f8ea6 100644 --- a/lib/python/Screens/TaskView.py +++ b/lib/python/Screens/TaskView.py @@ -1,5 +1,5 @@ from Components.ActionMap import ActionMap -from Components.config import config, ConfigSubsection, ConfigSelection, getConfigListEntry +from Components.config import config, ConfigSubsection, ConfigSelection, getConfigListEntry # noqa: F401 from Components.ConfigList import ConfigListScreen from Components.Sources.Progress import Progress from Components.Sources.StaticText import StaticText @@ -11,8 +11,6 @@ from Screens.MessageBox import MessageBox import Screens.Standby -from boxbranding import getMachineBrand, getMachineName - class JobView(InfoBarNotifications, ConfigListScreen, Screen): def __init__(self, session, job, parent=None, cancelable=True, backgroundable=True, afterEventChangeable=True, afterEvent="nothing"): @@ -121,9 +119,10 @@ def state_changed(self): self["summary_job_task"].text = j.getStatustext() if j.status in (j.FINISHED, j.FAILED): self.performAfterEvent() - self.backgroundable = False - self["key_blue"].setText("") - self["backgroundActions"].setEnabled(False) + if self.backgroundable: + self.backgroundable = False + self["key_blue"].setText("") + self["backgroundActions"].setEnabled(False) if j.status == j.FINISHED: self["key_green"].setText(_("OK")) self["okActions"].setEnabled(True) @@ -160,12 +159,12 @@ def performAfterEvent(self): return elif self.settings.afterEvent.value == "close" and self.job.status == self.job.FINISHED: self.close(False) - if self.settings.afterEvent.value == "deepstandby": + elif self.settings.afterEvent.value == "deepstandby": if not Screens.Standby.inTryQuitMainloop: - Tools.Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A sleep timer wants to shut down\nyour %s %s. Proceed?") % (getMachineBrand(), getMachineName()), timeout=20) + Tools.Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A sleep timer wants to shut down\nyour %s %s. Proceed?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=20) elif self.settings.afterEvent.value == "standby": if not Screens.Standby.inStandby: - Tools.Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A sleep timer wants to set your\n%s %s to standby. Proceed?") % (getMachineBrand(), getMachineName()), timeout=20) + Tools.Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A sleep timer wants to set your\n%s %s to standby. Proceed?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=20) def checkNotifications(self): InfoBarNotifications.checkNotifications(self) diff --git a/lib/python/Screens/TimerEdit.py b/lib/python/Screens/TimerEdit.py index 019f12cb35a..846ab4caf7f 100644 --- a/lib/python/Screens/TimerEdit.py +++ b/lib/python/Screens/TimerEdit.py @@ -13,10 +13,10 @@ from Screens.ChoiceBox import ChoiceBox from Screens.MessageBox import MessageBox from Screens.ParentalControlSetup import ProtectedScreen -from Screens.InputBox import PinInput +from Screens.InputBox import PinInput # noqa: F401 from ServiceReference import ServiceReference +from Screens.Recordings import RecordingSettings from Screens.TimerEntry import TimerEntry, TimerLog -from Screens.Setup import Setup from Tools.BoundFunction import boundFunction from Tools.FuzzyDate import FuzzyTime from time import time @@ -92,9 +92,8 @@ def onCreate(self): def createSetup(self): def onSetupClose(test=None): self.refill() - pass - self.session.openWithCallback(onSetupClose, Setup, 'recording') + self.session.openWithCallback(onSetupClose, RecordingSettings) def isProtected(self): return config.ParentalControl.setuppinactive.value and (not config.ParentalControl.config_sections.main_menu.value or hasattr(self.session, 'infobar') and self.session.infobar is None) and config.ParentalControl.config_sections.timer_menu.value and config.ParentalControl.servicepin[0].value diff --git a/lib/python/Screens/TimerEntry.py b/lib/python/Screens/TimerEntry.py index 8f7cb749301..fc18eb09f53 100644 --- a/lib/python/Screens/TimerEntry.py +++ b/lib/python/Screens/TimerEntry.py @@ -3,7 +3,6 @@ from enigma import eEPGCache -from Screens.Screen import Screen import Screens.ChannelSelection from ServiceReference import ServiceReference from Components.config import config, ConfigSelection, ConfigText, ConfigYesNo diff --git a/lib/python/Screens/Timeshift.py b/lib/python/Screens/Timeshift.py index 195beb527df..304f17c9031 100644 --- a/lib/python/Screens/Timeshift.py +++ b/lib/python/Screens/Timeshift.py @@ -4,7 +4,6 @@ from Components.config import config from Screens.LocationBox import TimeshiftLocationBox -from Screens.MessageBox import MessageBox from Screens.Setup import Setup from Tools.Directories import fileExists import Components.Harddisk @@ -13,11 +12,12 @@ class TimeshiftSettings(Setup): def __init__(self, session): self.buildChoices("TimeshiftPath", config.usage.timeshift_path, None) + self.errorItem = -1 Setup.__init__(self, session=session, setup="timeshift") self.greenText = self["key_green"].text - self.errorItem = -1 if self.getCurrentItem() is config.usage.timeshift_path: self.pathStatus(self.getCurrentValue()) + self.changedEntry() def buildChoices(self, item, configEntry, path): configList = config.usage.allowed_timeshift_paths.value[:] @@ -108,7 +108,6 @@ def selectionChanged(self): Setup.selectionChanged(self) else: self["config"].setCurrentIndex(self.errorItem) - self.errorMsg() def changedEntry(self): if self.getCurrentItem() is config.usage.timeshift_path: @@ -121,11 +120,6 @@ def keySelect(self): else: Setup.keySelect(self) - def errorMsg(self): - self.session.open(MessageBox, "%s\n\n%s" % (self.footnote, _("Please select a valid directory.")), type=MessageBox.TYPE_ERROR) - def keySave(self): if self.errorItem == -1: Setup.keySave(self) - else: - self.errorMsg() diff --git a/lib/python/Screens/UserInterfacePositioner.py b/lib/python/Screens/UserInterfacePositioner.py index e97f495fe0c..9cca94abd89 100644 --- a/lib/python/Screens/UserInterfacePositioner.py +++ b/lib/python/Screens/UserInterfacePositioner.py @@ -1,19 +1,16 @@ from Screens.MessageBox import MessageBox from Screens.Screen import Screen from Components.ActionMap import ActionMap -from Components.config import config, configfile, ConfigSubsection, getConfigListEntry, ConfigSelectionNumber, ConfigSelection, ConfigSlider, ConfigYesNo, NoSave, ConfigNumber, ConfigText +from Components.config import config, configfile, getConfigListEntry, ConfigSelectionNumber, ConfigSelection, ConfigSlider, ConfigYesNo, NoSave, ConfigNumber from Components.ConfigList import ConfigListScreen from Components.SystemInfo import SystemInfo from Components.Sources.StaticText import StaticText -from Components.Pixmap import Pixmap from Components.Console import Console from Tools.Directories import fileCheck, fileExists from enigma import getDesktop from os import access, R_OK import traceback -from boxbranding import getBoxType - def getFilePath(setting): return "/proc/stb/fb/dst_%s" % (setting) @@ -49,7 +46,7 @@ def InitOsd(): config.osd.show3dextensions = ConfigYesNo(default=False) def set3DMode(configElement): - if SystemInfo["CanChange3DOsd"] and getBoxType() not in ('spycat'): + if SystemInfo["CanChange3DOsd"] and SystemInfo["boxtype"] not in ('spycat'): print('[UserInterfacePositioner] Setting 3D mode:', configElement.value) file3d = fileCheck('/proc/stb/fb/3dmode') or fileCheck('/proc/stb/fb/primary/3d') f = open(file3d, "w") @@ -58,7 +55,7 @@ def set3DMode(configElement): config.osd.threeDmode.addNotifier(set3DMode) def set3DZnorm(configElement): - if SystemInfo["CanChange3DOsd"] and getBoxType() not in ('spycat'): + if SystemInfo["CanChange3DOsd"] and SystemInfo["boxtype"] not in ('spycat'): print('[UserInterfacePositioner] Setting 3D depth:', configElement.value) f = open("/proc/stb/fb/znorm", "w") f.write('%d' % int(configElement.value)) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index f3b735d0f5e..70ac3ccf04e 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -1,25 +1,24 @@ from os import path - from enigma import iPlayableService, iServiceInformation, eTimer, eServiceCenter, eServiceReference, eDVBDB -from Screens.Screen import Screen -from Screens.ChannelSelection import FLAG_IS_DEDICATED_3D -from Components.About import about from Components.ActionMap import ActionMap -from Components.SystemInfo import SystemInfo -from Components.ConfigList import ConfigListScreen +from Components.AVSwitch import iAVSwitch as iAV from Components.config import config, configfile, getConfigListEntry +from Components.ConfigList import ConfigListScreen from Components.Label import Label from Components.Pixmap import Pixmap -from Components.Sources.Boolean import Boolean from Components.ServiceEventTracker import ServiceEventTracker +from Components.Sources.Boolean import Boolean +from Components.SystemInfo import SystemInfo +from Screens.ChannelSelection import FLAG_IS_DEDICATED_3D +from Screens.Screen import Screen from Tools.Directories import isPluginInstalled from Tools.HardwareInfo import HardwareInfo -from Components.AVSwitch import iAVSwitch as iAV resolutionlabel = None previous = None isDedicated3D = False +videomode = "/proc/stb/video/videomode" class VideoSetup(ConfigListScreen, Screen): @@ -294,11 +293,19 @@ def VideoChanged(self): def VideoChangeDetect(self): global resolutionlabel config_port = config.av.videoport.value - config_mode = str(config.av.videomode[config_port].value).replace("\n", "") - config_res = str(config.av.videomode[config_port].value[:-1]).replace("\n", "") - config_pol = str(config.av.videomode[config_port].value[-1:]).replace("\n", "") - config_rate = str(config.av.videorate[config_mode].value).replace("Hz", "").replace("\n", "") - with open("/proc/stb/video/videomode", "r") as fd: + print("[VideoMode][VideoChangeDetect] config.av.videomode keys", list(config.av.videomode.keys())) + try: + config_mode = str(config.av.videomode[config_port].value).replace("\n", "") + config_res = str(config.av.videomode[config_port].value[:-1]).replace("\n", "") + config_pol = str(config.av.videomode[config_port].value[-1:]).replace("\n", "") + config_rate = str(config.av.videorate[config_mode].value).replace("Hz", "").replace("\n", "") + print("[VideoMode][VideoChangeDetect] config_port, config_mode, config_res, config_pol, config_rate", config_port, " ", config_mode, " ", config_res, " ", config_pol, " ", config_rate) + except KeyError as e: + print("[VideoMode][VideoChangeDetect] config_port Keyerror use current values", e) + self.delay = False + self.detecttimer.stop() + return + with open(videomode, "r") as fd: current_mode = fd.read()[:-1].replace("\n", "") if current_mode.upper() in ("PAL", "NTSC"): current_mode = current_mode.upper() @@ -306,36 +313,28 @@ def VideoChangeDetect(self): video_width = None video_pol = None video_rate = None - if path.exists("/proc/stb/vmpeg/0/yres"): + try: with open("/proc/stb/vmpeg/0/yres", "r") as fd: - try: - video_height = int(fd.read(), 16) - except Exception: - pass - if path.exists("/proc/stb/vmpeg/0/xres"): + video_height = int(fd.read(), 16) + except Exception: + pass + try: with open("/proc/stb/vmpeg/0/xres", "r") as fd: - try: - video_width = int(fd.read(), 16) - except Exception: - pass - if path.exists("/proc/stb/vmpeg/0/progressive"): + video_width = int(fd.read(), 16) + except Exception: + pass + try: with open("/proc/stb/vmpeg/0/progressive", "r") as fd: - try: - video_pol = "p" if int(fd.read(), 16) else "i" - except Exception: - pass - if path.exists("/proc/stb/vmpeg/0/framerate"): + video_pol = "p" if int(fd.read(), 16) else "i" + except Exception: + pass + try: with open("/proc/stb/vmpeg/0/framerate", "r") as fd: - try: - video_rate = int(fd.read()) - except Exception: - pass + video_rate = int(fd.read()) + except Exception: + pass if not video_height or not video_width or not video_pol or not video_rate: - service = self.session.nav.getCurrentService() - if service is not None: - info = service.info() - else: - info = None + info = None if self.session.nav.getCurrentService() is None else self.session.nav.getCurrentService().info() if info: video_height = int(info.getInfo(iServiceInformation.sVideoHeight)) video_width = int(info.getInfo(iServiceInformation.sVideoWidth)) @@ -369,7 +368,6 @@ def VideoChangeDetect(self): new_rate = str((new_rate + 500) // 1000) else: new_rate = config_rate - if video_pol != -1: new_pol = str(video_pol) else: @@ -429,9 +427,11 @@ def VideoChangeDetect(self): new_mode = config.av.autores_2160p30.value write_mode = new_mode else: - if path.exists("/proc/stb/video/videomode_%shz" % new_rate) and config_rate == "multi": - try: - with open("/proc/stb/video/videomode_%shz" % new_rate, "r") as fd: + if video_rate == 25000: # videomode_25hz is not in proc and will be reset 2nd pass thru , so do it now. + new_rate = 50 + if path.exists("%s_%shz" % (videomode, new_rate)) and config_rate == "multi": + try: # gbuhd4k/gbue4k sometimes will 1st time fail on open + with open("%s_%shz" % (videomode, new_rate), "r") as fd: multi_videomode = fd.read().replace("\n", "") if multi_videomode and (current_mode != multi_videomode): write_mode = multi_videomode @@ -443,9 +443,12 @@ def VideoChangeDetect(self): resolutionlabel["restxt"].setText(_("Video mode: %s") % write_mode) if config.av.autores.value != "disabled" and config.av.autores_label_timeout.value != "0": resolutionlabel.show() - print("[VideoMode] setMode - port: %s, mode: %s" % (config_port, write_mode)) - with open("/proc/stb/video/videomode", "w") as fd: + print("[VideoMode] setMode - port: %s, mode: %s" % (config.av.videoport.value, write_mode)) + with open(videomode, "w+") as fd: fd.write(write_mode) + # read_mode = fd.read().replace("\n", "") + # print("[VideoMode] fd.write_mode, read_mode", write_mode, " ", read_mode) + iAV.setAspect(config.av.aspect) iAV.setWss(config.av.wss) iAV.setPolicy43(config.av.policy_43) diff --git a/lib/python/Screens/VuWizard.py b/lib/python/Screens/VuWizard.py index 89cf855e393..cd942efafda 100644 --- a/lib/python/Screens/VuWizard.py +++ b/lib/python/Screens/VuWizard.py @@ -1,9 +1,9 @@ import glob -from boxbranding import getBoxType, getMachineMtdKernel, getMachineMtdRoot from Components.config import config, configfile from Components.Console import Console from Components.Pixmap import Pixmap from Components.Sources.Boolean import Boolean +from Components.SystemInfo import SystemInfo from Screens.MessageBox import MessageBox from Screens.Rc import Rc from Screens.WizardLanguage import WizardLanguage @@ -43,11 +43,11 @@ "enigma2-locale", ] -STARTUP = "kernel=/zImage root=/dev/%s rootsubdir=linuxrootfs0" % getMachineMtdRoot() # /STARTUP -STARTUP_RECOVERY = "kernel=/zImage root=/dev/%s rootsubdir=linuxrootfs0" % getMachineMtdRoot() # /STARTUP_RECOVERY -STARTUP_1 = "kernel=/linuxrootfs1/zImage root=/dev/%s rootsubdir=linuxrootfs1" % getMachineMtdRoot() # /STARTUP_1 -STARTUP_2 = "kernel=/linuxrootfs2/zImage root=/dev/%s rootsubdir=linuxrootfs2" % getMachineMtdRoot() # /STARTUP_2 -STARTUP_3 = "kernel=/linuxrootfs3/zImage root=/dev/%s rootsubdir=linuxrootfs3" % getMachineMtdRoot() # /STARTUP_3 +STARTUP = "kernel=/zImage root=/dev/%s rootsubdir=linuxrootfs0" % SystemInfo["mtdrootfs"] # /STARTUP +STARTUP_RECOVERY = "kernel=/zImage root=/dev/%s rootsubdir=linuxrootfs0" % SystemInfo["mtdrootfs"] # /STARTUP_RECOVERY +STARTUP_1 = "kernel=/linuxrootfs1/zImage root=/dev/%s rootsubdir=linuxrootfs1" % SystemInfo["mtdrootfs"] # /STARTUP_1 +STARTUP_2 = "kernel=/linuxrootfs2/zImage root=/dev/%s rootsubdir=linuxrootfs2" % SystemInfo["mtdrootfs"] # /STARTUP_2 +STARTUP_3 = "kernel=/linuxrootfs3/zImage root=/dev/%s rootsubdir=linuxrootfs3" % SystemInfo["mtdrootfs"] # /STARTUP_3 class VuWizard(WizardLanguage, Rc): @@ -98,8 +98,8 @@ def welcomeAction(self, answer): with open("/STARTUP_3", 'w') as f: f.write(STARTUP_3) cmdlist = [] - cmdlist.append("dd if=/dev/%s of=/zImage" % getMachineMtdKernel()) # backup old kernel - cmdlist.append("dd if=/usr/bin/kernel_auto.bin of=/dev/%s" % getMachineMtdKernel()) # create new kernel + cmdlist.append("dd if=/dev/%s of=/zImage" % SystemInfo["mtdkernel"]) # backup old kernel + cmdlist.append("dd if=/usr/bin/kernel_auto.bin of=/dev/%s" % SystemInfo["mtdkernel"]) # create new kernel cmdlist.append("mv /usr/bin/STARTUP.cpio.gz /STARTUP.cpio.gz") # copy userroot routine for file in glob.glob("/media/*/vuplus/*/force.update", recursive=True): cmdlist.append("mv %s %s" % (file, file.replace("force.update", "noforce.update"))) # remove Vu force update(Vu+ Zero4k) @@ -111,21 +111,21 @@ def welcomeAction(self, answer): if xline.find("/media/hdd") != -1 and "ext4" in xline: hddExt4 = True break - if hddExt4 and pathExists("/media/hdd/%s/linuxrootfs1" % getBoxType()): + if hddExt4 and pathExists("/media/hdd/%s/linuxrootfs1" % SystemInfo["boxtype"]): self.Console.eBatch(cmdlist, self.eMMCload, debug=True) elif hddExt4: - if not pathExists("/media/hdd/%s" % getBoxType()): - cmdlist.append("mkdir /media/hdd/%s" % getBoxType()) + if not pathExists("/media/hdd/%s" % SystemInfo["boxtype"]): + cmdlist.append("mkdir /media/hdd/%s" % SystemInfo["boxtype"]) cmdlist.append("mkdir /tmp/mmc") - cmdlist.append("mount /dev/%s /tmp/mmc" % getMachineMtdRoot()) - cmdlist.append("rsync -aAXHS /tmp/mmc/ /media/hdd/%s/linuxrootfs1" % getBoxType()) + cmdlist.append("mount /dev/%s /tmp/mmc" % SystemInfo["mtdrootfs"]) + cmdlist.append("rsync -aAXHS /tmp/mmc/ /media/hdd/%s/linuxrootfs1" % SystemInfo["boxtype"]) cmdlist.append("umount /tmp/mmc") - cmdlist.append("cp /zImage /media/hdd/%s/linuxrootfs1/" % getBoxType()) + cmdlist.append("cp /zImage /media/hdd/%s/linuxrootfs1/" % SystemInfo["boxtype"]) self.Console.eBatch(cmdlist, self.eMMCload, debug=True) else: cmdlist.append("mkdir /tmp/mmc") cmdlist.append("mkdir /linuxrootfs1") - cmdlist.append("mount /dev/%s /tmp/mmc" % getMachineMtdRoot()) + cmdlist.append("mount /dev/%s /tmp/mmc" % SystemInfo["mtdrootfs"]) cmdlist.append("/bin/tar -jcf /tmp/linuxrootfs1.tar.bz2 -C /tmp/mmc --exclude ./var/nmbd --exclude ./.resizerootfs --exclude ./linuxrootfs* --exclude ./.resize-rootfs --exclude ./.resize-linuxrootfs --exclude ./.resize-userdata --exclude ./var/lib/samba/private/msg.sock .") cmdlist.append("/bin/tar -jxf /tmp/linuxrootfs1.tar.bz2 -C /linuxrootfs1 .") cmdlist.append("cp /zimage /linuxrootfs1/") @@ -137,11 +137,11 @@ def welcomeAction(self, answer): def eMMCload(self, *args, **kwargs): cmdlist = [] for eMMCslot in range(1, 4): - if pathExists("/media/hdd/%s/linuxrootfs%s" % (getBoxType(), eMMCslot)): - cmdlist.append("cp -R /media/hdd/%s/linuxrootfs%s . /" % (getBoxType(), eMMCslot)) - cmdlist.append("rm -r /media/hdd/%s/linuxrootfs%s" % (getBoxType(), eMMCslot)) + if pathExists("/media/hdd/%s/linuxrootfs%s" % (SystemInfo["boxtype"], eMMCslot)): + cmdlist.append("cp -R /media/hdd/%s/linuxrootfs%s . /" % (SystemInfo["boxtype"], eMMCslot)) + cmdlist.append("rm -r /media/hdd/%s/linuxrootfs%s" % (SystemInfo["boxtype"], eMMCslot)) if cmdlist: - cmdlist.append("rm -rf /media/hdd/%s" % getBoxType()) + cmdlist.append("rm -rf /media/hdd/%s" % SystemInfo["boxtype"]) self.Console.eBatch(cmdlist, self.reBoot, debug=False) else: self.reBoot() diff --git a/lib/python/Screens/Wizard.py b/lib/python/Screens/Wizard.py index 3be7ae13c25..11595c37f78 100644 --- a/lib/python/Screens/Wizard.py +++ b/lib/python/Screens/Wizard.py @@ -3,7 +3,6 @@ from enigma import eTimer, eEnv -from boxbranding import getMachineBrand, getMachineName from Components.ActionMap import NumberActionMap from Components.config import config, ConfigText, ConfigPassword, KEY_LEFT, KEY_RIGHT, KEY_0, KEY_DELETE, KEY_BACKSPACE, KEY_ASCII # noqa: F401 from Components.ConfigList import ConfigList @@ -11,6 +10,7 @@ from Components.Slider import Slider from Components.Sources.List import List from Components.Sources.StaticText import StaticText +from Components.SystemInfo import SystemInfo from Screens.MessageBox import MessageBox from Screens.Screen import Screen @@ -462,7 +462,7 @@ def runCode(self, code): return False def getTranslation(self, text): - return _(text).replace("%s %s", "%s %s" % (getMachineBrand(), getMachineName())) + return _(text).replace("%s %s", "%s %s" % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) def updateText(self, firstset=False): text = self.getTranslation(self.wizard[self.currStep]["text"]) diff --git a/lib/python/Session.py b/lib/python/Session.py new file mode 100644 index 00000000000..6a5f8818be4 --- /dev/null +++ b/lib/python/Session.py @@ -0,0 +1,10 @@ +class SessionObject: + __session = None + + def setSession(self, Session): + SessionObject.__session = Session + + def getSession(self): + return self.__session + + session = property(getSession, setSession) diff --git a/lib/python/StartEnigma.py b/lib/python/StartEnigma.py index cf9c3a0fdf5..99ac6df74aa 100644 --- a/lib/python/StartEnigma.py +++ b/lib/python/StartEnigma.py @@ -4,7 +4,6 @@ from datetime import datetime from traceback import print_exc -from boxbranding import getImageArch, getImageBuild, getImageDevBuild, getImageType, getImageVersion from Tools.Profile import profile, profile_final import Tools.RedirectOutput # noqa: F401 # Don't remove this line. It may seem to do nothing, but if removed it will break output redirection for crash logs. import eConsoleImpl @@ -324,6 +323,9 @@ def runScreenTest(): profile("Init:Session") nav = Navigation(config.misc.isNextRecordTimerAfterEventActionAuto.value, config.misc.isNextPowerTimerAfterEventActionAuto.value) session = Session(desktop=enigma.getDesktop(0), summary_desktop=enigma.getDesktop(1), navigation=nav) + from Session import SessionObject + so = SessionObject() + so.session = session profile("Init:Trashcan") import Tools.Trashcan @@ -438,12 +440,14 @@ def runNextScreen(session, screensToRun, *result): profile("PYTHON_START") +from Components.SystemInfo import SystemInfo # noqa: E402 don't move this import + print("[StartEnigma] Starting Python Level Initialisation.") -print("[StartEnigma] Image Type -> '%s'" % getImageType()) -print("[StartEnigma] Image Version -> '%s'" % getImageVersion()) -print("[StartEnigma] Image Build -> '%s'" % getImageBuild()) -if getImageType() != "release": - print("[StartEnigma] Image DevBuild -> '%s'" % getImageDevBuild()) +print("[StartEnigma] Image Type -> '%s'" % SystemInfo["imagetype"]) +print("[StartEnigma] Image Version -> '%s'" % SystemInfo["imageversion"]) +print("[StartEnigma] Image Build -> '%s'" % SystemInfo["imagebuild"]) +if SystemInfo["imagetype"] != "release": + print("[StartEnigma] Image DevBuild -> '%s'" % SystemInfo["imagedevbuild"]) # SetupDevices sets up defaults:- language, keyboard, parental & expert config. @@ -454,7 +458,7 @@ def runNextScreen(session, screensToRun, *result): from Components.SetupDevices import InitSetupDevices # noqa: E402 InitSetupDevices() -if getImageArch() in ("aarch64"): +if SystemInfo["architecture"] in ("aarch64"): # something not right here from usb.backend import libusb1 # noqa: E402 libusb1.get_backend(find_library=lambda x: "/lib64/libusb-1.0.so.0") @@ -468,7 +472,7 @@ def runNextScreen(session, screensToRun, *result): print("[StartEnigma] Initialising InfoBar.") from Screens import InfoBar # noqa: E402 -from Components.SystemInfo import SystemInfo # noqa: E402 don't move this import +# from Components.SystemInfo import SystemInfo # noqa: E402 don't move this import VuRecovery = SystemInfo["HasKexecMultiboot"] and SystemInfo["MultiBootSlot"] == 0 # print("[StartEnigma] Is this VuRecovery?. Recovery = ", VuRecovery) @@ -690,7 +694,8 @@ def RCSelectionChanged(configelement): print("[StartEnigma] Initialising KeymapParser.") from keymapparser import readKeymap # noqa: E402 readKeymap(config.usage.keymap.value) -readKeymap(config.usage.keytrans.value) +if osexists(config.usage.keytrans.value): + readKeymap(config.usage.keytrans.value) if VuRecovery: SystemInfo["Display"] = False diff --git a/lib/python/Tools/Downloader.py b/lib/python/Tools/Downloader.py index c6fa0b6db0c..50ff9714116 100644 --- a/lib/python/Tools/Downloader.py +++ b/lib/python/Tools/Downloader.py @@ -2,7 +2,7 @@ import requests from twisted.internet import reactor from urllib.request import urlopen, Request -from boxbranding import getMachineBrand, getMachineName +from Components.SystemInfo import SystemInfo from enigma import eTimer @@ -10,7 +10,7 @@ class DownloadWithProgress: def __init__(self, url, outputFile, *args, **kwargs): self.url = url self.outputFile = outputFile - self.userAgent = "%s %s HbbTV/1.1.1 (+PVR+RTSP+DL; Sonic; TV44; 1.32.455; 2.002) Bee/3.5" % (getMachineBrand(), getMachineName()) + self.userAgent = "%s %s HbbTV/1.1.1 (+PVR+RTSP+DL; Sonic; TV44; 1.32.455; 2.002) Bee/3.5" % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) self.totalSize = 0 self.progress = 0 self.progressCallback = None diff --git a/lib/python/Tools/HardwareInfo.py b/lib/python/Tools/HardwareInfo.py index 3ccc31b8ff2..6d58be5d8b4 100644 --- a/lib/python/Tools/HardwareInfo.py +++ b/lib/python/Tools/HardwareInfo.py @@ -1,4 +1,3 @@ -from boxbranding import getBoxType, getBrandOEM from Components.About import about @@ -45,10 +44,12 @@ def get_device_version(self): return HardwareInfo.device_version def has_hdmi(self): - return getBrandOEM() in ('xtrend', 'gigablue', 'dags', 'ixuss', 'odin', 'vuplus', 'ini', 'ebox', 'ceryon') or (getBoxType() in ('dm7020hd', 'dm800se', 'dm500hd', 'dm8000') and HardwareInfo.device_version is not None) + from Components.SystemInfo import SystemInfo + return SystemInfo["brand"] in ('xtrend', 'gigablue', 'dags', 'ixuss', 'odin', 'vuplus', 'ini', 'ebox', 'ceryon') or (SystemInfo["boxtype"] in ('dm7020hd', 'dm800se', 'dm500hd', 'dm8000') and HardwareInfo.device_version is not None) def has_deepstandby(self): - return getBoxType() != 'dm800' + # from Components.SystemInfo import SystemInfo + return True # SystemInfo["boxtype"] != 'dm800' def is_nextgen(self): if about.getCpuCoresInt() < 2 or about.getCPUSpeedMHzInt() < 750: diff --git a/lib/python/Tools/Multiboot.py b/lib/python/Tools/Multiboot.py index f4330a7bb74..14f1fd7be89 100644 --- a/lib/python/Tools/Multiboot.py +++ b/lib/python/Tools/Multiboot.py @@ -4,7 +4,6 @@ import tempfile from os import path, rmdir, rename, sep, stat -from boxbranding import getMachineMtdRoot from Components.Console import Console from Components.SystemInfo import SystemInfo, BoxInfo as BoxInfoRunningInstance, BoxInformation from Tools.Directories import fileHas, fileExists @@ -15,7 +14,7 @@ from PIL import ImageFont MbootList1 = ("/dev/mmcblk0p1", "/dev/mmcblk1p1", "/dev/mmcblk0p3", "/dev/mmcblk0p4", "/dev/mtdblock2", "/dev/block/by-name/bootoptions") -MbootList2 = ("/dev/%s" % getMachineMtdRoot(), ) # kexec kernel Vu+ multiboot +MbootList2 = ("/dev/%s" % SystemInfo["mtdrootfs"], ) # kexec kernel Vu+ multiboot class tmp: diff --git a/lib/python/Tools/Profile.py b/lib/python/Tools/Profile.py index 43c51061933..381ab6e874b 100644 --- a/lib/python/Tools/Profile.py +++ b/lib/python/Tools/Profile.py @@ -1,5 +1,5 @@ # the implementation here is a bit crappy. -from boxbranding import getBoxType, getMachineBuild +# from boxbranding import getBoxType, getMachineBuild import time from Tools.Directories import resolveFilename, SCOPE_CONFIG @@ -37,21 +37,23 @@ def profile(id): # GML: Set the device and format here...probably more could be added? # - box_type = getBoxType() - if box_type in ("odinm7", "odinm6", "xp1000s"): - dev_fmt = ("/dev/dbox/oled0", "%d") - elif box_type in ("gb800se", "gb800solo"): - dev_fmt = ("/dev/dbox/oled0", "%d \n") - elif box_type == "mbtwin": - dev_fmt = ("/dev/dbox/oled0", "%d%%") - elif box_type == "gb800seplus": - dev_fmt = ("/dev/mcu", "%d \n") - elif box_type == "ebox5000": - dev_fmt = ("/proc/progress", "%d"), - elif getMachineBuild() in ("inihdp", "inihdx"): - dev_fmt = ("/proc/vfd", "Loading %d%%\n") - else: - dev_fmt = ("/proc/progress", "%d \n") + # box_type = getBoxType() + # if box_type in ("odinm7", "odinm6", "xp1000s"): + # dev_fmt = ("/dev/dbox/oled0", "%d") + # elif box_type in ("gb800se", "gb800solo"): + # dev_fmt = ("/dev/dbox/oled0", "%d \n") + # elif box_type == "mbtwin": + # dev_fmt = ("/dev/dbox/oled0", "%d%%") + # elif box_type == "gb800seplus": + # dev_fmt = ("/dev/mcu", "%d \n") + # elif box_type == "ebox5000": + # dev_fmt = ("/proc/progress", "%d"), + # elif getMachineBuild() in ("inihdp", "inihdx"): + # dev_fmt = ("/proc/vfd", "Loading %d%%\n") + # else: + # dev_fmt = ("/proc/progress", "%d \n") + + dev_fmt = ("/proc/progress", "%d \n") (dev, fmt) = dev_fmt if profile_file: diff --git a/lib/python/Tools/Trashcan.py b/lib/python/Tools/Trashcan.py index 473ff9ee546..d24a6d1bbb0 100644 --- a/lib/python/Tools/Trashcan.py +++ b/lib/python/Tools/Trashcan.py @@ -152,8 +152,7 @@ def work(self): if parts[1] == "/media/autofs": continue # skip network mounts unless the option to clean them is set - if (not config.usage.movielist_trashcan_network_clean.value and - (parts[1].startswith("/media/net") or parts[1].startswith("/media/autofs"))): + if not config.usage.movielist_trashcan_network_clean.value and parts[1].startswith(("/media/net", "/media/autofs")): continue # one trashcan in the root, one in movie subdirectory trashcanLocations.add(parts[1]) diff --git a/lib/python/skin.py b/lib/python/skin.py index 0b1bcce950f..a7f33ea0846 100644 --- a/lib/python/skin.py +++ b/lib/python/skin.py @@ -393,7 +393,7 @@ def loadPixmap(path, desktop, width=0, height=0): return pixmap -def collectAttributes(skinAttributes, node, context, skinPath=None, ignore=(), filenames=frozenset(("pixmap", "pointer", "seek_pointer", "backgroundPixmap", "selectionPixmap", "sliderPixmap", "scrollbarSliderPicture", "scrollbarbackgroundPixmap", "scrollbarBackgroundPicture"))): +def collectAttributes(skinAttributes, node, context, skinPath=None, ignore=(), filenames=frozenset(("pixmap", "pointer", "seek_pointer", "backgroundPixmap", "selectionPixmap", "selectionPixmapLarge", "sliderPixmap", "scrollbarSliderPicture", "scrollbarbackgroundPixmap", "scrollbarBackgroundPicture"))): size = None pos = None font = None @@ -517,6 +517,9 @@ def backgroundPixmap(self, value): def selectionPixmap(self, value): self.guiObject.setSelectionPicture(loadPixmap(value, self.desktop)) + def selectionPixmapLarge(self, value): + self.guiObject.setSelectionPictureLarge(loadPixmap(value, self.desktop)) + def sliderPixmap(self, value): self.guiObject.setScrollbarPixmap(loadPixmap(value, self.desktop)) @@ -1429,6 +1432,10 @@ def recurseNamelessPanel(panel): source = widget.get("source", None) if source is not None: widgetSet.add(source) + addonConnection = widget.get("connection", None) + if addonConnection is not None: + for x in addonConnection.split(","): + widgetSet.add(x) panels = element.findall("panel") if panels is not None: for panel in panels: diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 895fac20e18..2b975c9eea8 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -10,9 +10,65 @@ #include #include #include +#include +#include +#include ePyObject eListboxServiceContent::m_GetPiconNameFunc; +std::string toLower(std::string& data) { + std::string data_tmp = data; + std::transform(data_tmp.begin(), data_tmp.end(), data_tmp.begin(), tolower); + return data_tmp; +} + +// Next two functions are used for finding correct recording in case of dynamic iptv service url +void join(const std::vector& v, char c, std::string& s) { + + s.clear(); + + for (std::vector::const_iterator p = v.begin(); + p != v.end(); ++p) { + s += *p; + if (p != v.end() - 1) + s += c; + } +} + +bool compareServices(const eServiceReference &ref1, const eServiceReference &ref2, bool alternativeMatching) { + std::vector ref_split = split(ref1.toString(), ":"); + std::vector s_split = split(ref2.toString(), ":"); + + if (ref_split[1] == "7" || s_split[1] == "7") { + return ref1 == ref2; + } + + std::vector ref_split_r(ref_split.begin(), ref_split.begin() + 10); + std::string ref_s; + join(ref_split_r, ':', ref_s); + + std::vector s_split_r(s_split.begin(), s_split.begin() + 10); + std::string s_s; + join(s_split_r, ':', s_s); + + if (!alternativeMatching) { + if (ref1 == ref2) return true; + } else { + if (ref_s == s_s) return true; + } + // If "127.0.0.1" is in the service reference this is probably a stream relay + // so use partial matching logic + if (ref2.toString().find("127.0.0.1") != std::string::npos) { + std::string url_sr = s_split[s_split.size() - 2]; + std::vector sr_split = split(url_sr, "/"); + std::string ref_orig = sr_split.back(); + ref_orig = replace_all(ref_orig, "%3a", ":"); + return ref1.toString() == ref_orig; + } + + return false; +} + void eListboxServiceContent::addService(const eServiceReference &service, bool beforeCurrent) { if (beforeCurrent && m_size) @@ -62,6 +118,7 @@ void eListboxServiceContent::removeCurrent() void eListboxServiceContent::FillFinished() { m_size = m_list.size(); + m_size_visible = cursorResolve(m_size - 1) + 1; cursorHome(); if (m_listbox) @@ -166,7 +223,6 @@ PyObject *eListboxServiceContent::getList() int eListboxServiceContent::getNextBeginningWithChar(char c) { -// printf("Char: %c\n", c); int index=0; for (list::iterator i(m_list.begin()); i != m_list.end(); ++i, ++index) { @@ -177,7 +233,7 @@ int eListboxServiceContent::getNextBeginningWithChar(char c) continue; // failed to find service handler } service_info->getName(*i, text); -// printf("%c\n", text.c_str()[0]); + int idx=0; int len=text.length(); while ( idx <= len ) @@ -200,20 +256,28 @@ int eListboxServiceContent::getPrevMarkerPos() return 0; list::iterator i(m_cursor); int index = m_cursor_number; - while (index) // Skip precending markers + while (index) // Find marker for this section { --i; --index; - if (!(i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible))) + if (i->flags == eServiceReference::isMarker) break; } + + //eDebug("[eListboxServiceContent] prevMarkerIndex= %i; curSelIndex= %i; index= %i", cursorResolve(prevMarkerIndex), cursorResolve(m_cursor_number), index); + + // if currently selected service is not the first after the marker found - return the found marker index + if (cursorResolve(index) + 1 != cursorResolve(m_cursor_number)) return cursorResolve(index); + + while (index) { --i; --index; - if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible)) + if (i->flags == eServiceReference::isMarker) break; } + return cursorResolve(index); } @@ -227,7 +291,8 @@ int eListboxServiceContent::getNextMarkerPos() { ++i; ++index; - if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible)) + + if (i->flags == eServiceReference::isMarker) break; } return cursorResolve(index); @@ -335,7 +400,7 @@ void eListboxServiceContent::sort() DEFINE_REF(eListboxServiceContent); eListboxServiceContent::eListboxServiceContent() - :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_itemheight(25), m_hide_number_marker(false), m_show_two_lines(0), m_servicetype_icon_mode(0), m_crypto_icon_mode(0), m_record_indicator_mode(0), m_column_width(0), m_progressbar_height(6), m_progressbar_border_width(2), m_nonplayable_margins(10), m_items_distances(8) + :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_itemheight(25), m_hide_number_marker(false), m_servicetype_icon_mode(0), m_crypto_icon_mode(0), m_record_indicator_mode(0), m_column_width(0), m_progressbar_height(6), m_progressbar_border_width(2), m_nonplayable_margins(10), m_items_distances(8), m_sides_margin(0), m_marker_as_line(0), m_markerline_color_set(0) { memset(m_color_set, 0, sizeof(m_color_set)); cursorHome(); @@ -382,7 +447,7 @@ void eListboxServiceContent::cursorHome() m_cursor_number = 0; while (m_cursor != m_list.end()) { - if (!((m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) || (m_cursor->flags & eServiceReference::isInvisible))) + if (!((m_marked.empty() && m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) || (m_cursor->flags & eServiceReference::isInvisible))) break; m_cursor++; m_cursor_number++; @@ -470,7 +535,7 @@ int eListboxServiceContent::cursorMove(int count) m_listbox->entryChanged(cursorResolve(m_cursor_number)); } ++m_cursor_number; - if (!(m_hide_number_marker && m_cursor->flags & eServiceReference::isNumberedMarker) && !(m_cursor->flags & eServiceReference::isInvisible)) + if (!(m_marked.empty() && m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) && !(m_cursor->flags & eServiceReference::isInvisible)) --count; } } @@ -486,12 +551,12 @@ int eListboxServiceContent::cursorMove(int count) m_listbox->entryChanged(cursorResolve(m_cursor_number)); } --m_cursor_number; - if (!(m_hide_number_marker && m_cursor->flags & eServiceReference::isNumberedMarker) && !(m_cursor->flags & eServiceReference::isInvisible)) + if (!(m_marked.empty() && m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) && !(m_cursor->flags & eServiceReference::isInvisible)) ++count; } while (m_cursor != m_list.end()) { - if (!((m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) || (m_cursor->flags & eServiceReference::isInvisible))) + if (!((m_marked.empty() && m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) || (m_cursor->flags & eServiceReference::isInvisible))) break; m_cursor++; m_cursor_number++; @@ -521,7 +586,7 @@ int eListboxServiceContent::cursorResolve(int cursorPosition) if (count == cursorPosition) break; count++; - if ((m_hide_number_marker && (i->flags & eServiceReference::isNumberedMarker)) || (i->flags & eServiceReference::isInvisible)) + if ((m_marked.empty() && m_hide_number_marker && (i->flags & eServiceReference::isNumberedMarker)) || (i->flags & eServiceReference::isInvisible)) continue; strippedCursor++; } @@ -538,7 +603,7 @@ int eListboxServiceContent::currentCursorSelectable() if (cursorValid()) { /* don't allow markers to be selected, unless we're in edit mode (because we want to provide some method to the user to remove a marker) */ - if (m_cursor->flags & eServiceReference::isMarker && m_marked.empty()) + if ((m_cursor->flags & eServiceReference::isMarker) && m_marked.empty()) return 0; else return 1; @@ -564,7 +629,7 @@ int eListboxServiceContent::size() int size = 0; for (list::iterator i(m_list.begin()); i != m_list.end(); ++i) { - if ((m_hide_number_marker && (i->flags & eServiceReference::isNumberedMarker)) || (i->flags & eServiceReference::isInvisible)) + if ((m_marked.empty() && m_hide_number_marker && (i->flags & eServiceReference::isNumberedMarker)) || (i->flags & eServiceReference::isInvisible)) continue; size++; } @@ -612,24 +677,21 @@ bool eListboxServiceContent::checkServiceIsRecorded(eServiceReference ref) { ePtr db; ePtr res; - if (eDVBResourceManager::getInstance(res) == -1) - { - return false; - } - if (res->getChannelList(db) < 0) - { - return false; - } + eDVBResourceManager::getInstance(res); + res->getChannelList(db); eBouquet *bouquet = NULL; if (!db->getBouquet(ref, bouquet)) { - for (std::list::iterator i(bouquet->m_services.begin()); i != bouquet->m_services.end(); ++i) - if (*i == it->second) + for (std::list::iterator i(bouquet->m_services.begin()); i != bouquet->m_services.end(); ++i){ + if (compareServices(*i, it->second, m_alternative_record_match)) return true; + } } } - else if (ref == it->second) - return true; + else { + if (compareServices(ref, it->second, m_alternative_record_match)) + return true; + } } return false; } @@ -708,31 +770,50 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { if (local_style->m_background) painter.blit(local_style->m_background, offset, eRect(), gPainter::BT_ALPHABLEND); - else if (selected && !local_style->m_selection) + else if (selected && !local_style->m_selection && !local_style->m_selection_large) painter.clear(); } if (cursorValid()) { - if (selected && local_style && local_style->m_selection) + if (selected && local_style && local_style->m_selection && m_visual_mode != visSkinDefined){ painter.blit(local_style->m_selection, offset, eRect(), gPainter::BT_ALPHABLEND); + } + if (selected && local_style && local_style->m_selection_large && m_visual_mode == visSkinDefined){ + painter.blit(local_style->m_selection_large, offset, eRect(), gPainter::BT_ALPHABLEND); + } // Draw the frame for selected item here so to be under the content - if (selected && (!local_style || !local_style->m_selection)) + if (selected && (!local_style || (!local_style->m_selection && !local_style->m_selection_large))) style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry); + eServiceReference ref = *m_cursor; + std::string orig_ref_str = ref.toString(); + std::string service_res_str = toLower(split(orig_ref_str, ":")[2]); + + bool isBackupAvailable = false; + int catchUpDays = 0; + if (orig_ref_str.find("@") != std::string::npos) { + isBackupAvailable = true; + } + + if (orig_ref_str.find("|<|") != std::string::npos) { + catchUpDays = std::stoi(split(split(orig_ref_str, "|<|")[1], "@")[0]); + } + /* get service information */ ePtr service_info; - m_service_center->info(*m_cursor, service_info); - eServiceReference ref = *m_cursor; + m_service_center->info(ref, service_info); bool isMarker = ref.flags & eServiceReference::isMarker; - bool isPlayable = !(ref.flags & eServiceReference::isDirectory || isMarker); - bool isRecorded = m_record_indicator_mode && isPlayable && checkServiceIsRecorded(ref); + bool isDirectory = ref.flags & eServiceReference::isDirectory; + bool isPlayable = !(isDirectory || isMarker); + bool isRecorded = isPlayable && checkServiceIsRecorded(ref); ePtr evt, evt_next; bool serviceAvail = true; bool serviceFallback = false; int isplayable_value; gRGB EventProgressbarColor = 0xe7b53f; + ePtr refCur; if (!marked && isPlayable && service_info && m_is_playable_ignore.valid()) { @@ -764,421 +845,791 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.setForegroundColor(gRGB(0xb40431)); } - int xoffset=0; // used as offset when painting the folder/marker symbol or the serviceevent progress - int nameLeft=0, nameWidth=0, nameYoffs=0, nextYoffs=0; // used as temporary values for 'show two lines' option + int xoffset=0, xoffs=0, xoffs_col=0; // used as offset when painting the folder/marker symbol or the serviceevent progress + + if (m_separator == "") m_separator = " "; + + std::string text = ""; + + bool hasChannelNumbers = m_chanel_number_visible; time_t now = time(0); std::string event_name = "", next_event_name = ""; - int event_begin = 0, event_duration = 0; - bool is_event = isPlayable && service_info && !service_info->getEvent(*m_cursor, evt); - if (is_event) - { - event_name = evt->getEventName(); - event_begin = evt->getBeginTime(); - event_duration = evt->getDuration(); - if (m_show_two_lines == 2 && event_begin > 0 && !service_info->getEvent(*m_cursor, evt_next, (event_begin + event_duration))) - next_event_name = evt_next->getEventName(); - } + int event_begin = 0, event_duration = 0, xlpos = m_itemsize.width(), ctrlHeight=m_itemheight, yoffs=0, yoffs_orig=0; + bool is_event = isPlayable && service_info && !service_info->getEvent(ref, evt); + if (m_visual_mode == visSkinDefined) { + if (is_event){ + event_name = evt->getEventName(); + } + if (!event_name.empty()) { + ctrlHeight = m_itemheight/2; + yoffs_orig = 5; + yoffs = m_has_next_event ? ctrlHeight - 2 : 5; + } + if (!isMarker && !isDirectory) { + ePtr &pixmap = service_res_str == "1f" ? m_pixmaps[pic4K] : (service_res_str == "19" || service_res_str == "11") ? + m_pixmaps[picHD] : m_pixmaps[picSD]; - for (int e = 0; e != celServiceTypePixmap; ++e) - { - if (m_element_font[e]) - { - int flags=gPainter::RT_VALIGN_CENTER; - int yoffs = 0; - eRect area = m_element_position[e]; - std::string text = ""; - switch (e) - { - case celServiceNumber: + if (pixmap) { - if (area.width() <= 0) - continue; // no point in going on if we won't paint anything + eSize pixmap_size = pixmap->size(); + xlpos -= 15 + pixmap_size.width(); + eRect res_area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(res_area); + painter.blit(pixmap, ePoint(res_area.left(), res_area.top()), res_area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - if( m_cursor->getChannelNum() == 0 ) - continue; + int orbpos = m_cursor->getUnsignedData(4) >> 16; + if (m_servicetype_icon_mode) { + const char *filename = ref.path.c_str(); + ePtr &pixmap_system = + (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : + (strstr(filename, "://")) ? m_pixmaps[picStream] : + (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : + (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; - char buffer[15]; - snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); - text = buffer; - flags|=gPainter::RT_HALIGN_RIGHT; - if (isPlayable && serviceFallback && selected && m_color_set[serviceSelectedFallback]) - painter.setForegroundColor(m_color[serviceSelectedFallback]); - break; - } - case celServiceName: - { - if (service_info) - service_info->getName(*m_cursor, text); - if (!isPlayable) + if (pixmap_system) { - area.setWidth(area.width() + m_element_position[celServiceEventProgressbar].width() + m_nonplayable_margins); - if (m_element_position[celServiceEventProgressbar].left() == 0) - area.setLeft(0); - if (m_element_position[celServiceNumber].width() && m_element_position[celServiceEventProgressbar].left() == m_element_position[celServiceNumber].width() + m_nonplayable_margins) - area.setLeft(m_element_position[celServiceNumber].width() + m_nonplayable_margins); + eSize pixmap_size = pixmap_system->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(pixmap_system, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); } - if (!(m_record_indicator_mode == 3 && isRecorded) && isPlayable && serviceFallback && selected && m_color_set[serviceSelectedFallback]) - painter.setForegroundColor(m_color[serviceSelectedFallback]); - break; } - case celServiceInfo: + + if (m_crypto_icon_mode && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { - if (!event_name.empty()) - { - text = event_name; - std::replace(text.begin(), text.end(), '\n', ' '); - if (serviceAvail) - { - if (!selected && m_color_set[eventForeground]) - { - painter.setForegroundColor(m_color[eventForeground]); - EventProgressbarColor = m_color[eventForeground]; - } - else if (selected && m_color_set[eventForegroundSelected]) - { - painter.setForegroundColor(m_color[eventForegroundSelected]); - EventProgressbarColor = m_color[eventForegroundSelected]; - } - else - painter.setForegroundColor(gRGB(0xe7b53f)); + eSize pixmap_size = m_pixmaps[picCrypto]->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picCrypto], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver - { - painter.setForegroundColor(m_color[eventForegroundFallback]); - EventProgressbarColor = m_color[eventForegroundFallback]; - } - else if (serviceFallback && selected && m_color_set[eventForegroundSelectedFallback]) - { - painter.setForegroundColor(m_color[eventForegroundSelectedFallback]); - EventProgressbarColor = m_color[eventForegroundSelectedFallback]; - } - } - break; - } - continue; + if (m_pixmaps[picBackup] && isBackupAvailable) + { + eSize pixmap_size = m_pixmaps[picBackup]->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picBackup], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); } - case celServiceNextInfo: + + if (m_pixmaps[picCatchup] && catchUpDays > 0) { - if (!next_event_name.empty()) - { - text = m_next_title + next_event_name; - std::replace(text.begin(), text.end(), '\n', ' '); - if (serviceAvail) - { - if (!selected && m_color_set[eventNextForeground]) - painter.setForegroundColor(m_color[eventNextForeground]); - else if (selected && m_color_set[eventNextForegroundSelected]) - painter.setForegroundColor(m_color[eventNextForegroundSelected]); - else - painter.setForegroundColor(gRGB(0x787878)); + eSize pixmap_size = m_pixmaps[picCatchup]->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picCatchup], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - if (serviceFallback && !selected && m_color_set[eventNextForegroundFallback]) // fallback receiver - painter.setForegroundColor(m_color[eventNextForegroundFallback]); - else if (serviceFallback && selected && m_color_set[eventNextForegroundSelectedFallback]) - painter.setForegroundColor(m_color[eventNextForegroundSelectedFallback]); + if (m_pixmaps[picRecord] && isRecorded) + { + eSize pixmap_size = m_pixmaps[picRecord]->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picRecord], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + } + ePtr piconPixmap; + bool isPIconSVG = false; + bool hasPicon = PyCallable_Check(m_GetPiconNameFunc); + if (isPlayable && hasPicon) + { + ePyObject pArgs = PyTuple_New(1); + PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); + ePyObject pRet = PyObject_CallObject(m_GetPiconNameFunc, pArgs); + Py_DECREF(pArgs); + if (pRet) + { + if (PyUnicode_Check(pRet)) + { + std::string piconFilename = PyUnicode_AsUTF8(pRet); + if (endsWith(piconFilename, ".svg")) { + isPIconSVG = true; } - break; + if (!piconFilename.empty()) + loadImage(piconPixmap, piconFilename.c_str(), 0, isPIconSVG ? 125 : 0); } - continue; + Py_DECREF(pRet); + } + } + xoffs = xoffset + 16; + + if (hasPicon) + { + eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight); + /* PIcons are usually about 100:60. Make it a + * bit wider in case the icons are diffently + * shaped, and to add a bit of margin between + * icon and text. */ + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + if (!isPIconSVG) { + pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; } - case celServiceEventProgressbar: + if (piconPixmap) { - if (area.width() > 0 && is_event) - { - char buffer[15]; - snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - event_begin) / event_duration)); - text = buffer; - flags|=gPainter::RT_HALIGN_RIGHT; - break; + painter.clip(piconArea); + if (isPIconSVG) { + painter.blit(piconPixmap, + eRect(xoffs, offset.y(), 125, m_itemheight), + eRect(), + pflags + ); + } else { + painter.blitScale(piconPixmap, + eRect(xoffs, offset.y(), 125, m_itemheight), + piconArea, + pflags); } - continue; + painter.clippop(); } + if (!(isMarker || isDirectory)) xoffs += 125 + 16 + 8; + } + + // channel number + name + if (service_info) + service_info->getName(ref, text); + + ePtr paraName = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + paraName->setFont(m_element_font[celServiceName]); + paraName->renderString(text.c_str()); + eRect bboxName = paraName->getBoundBox(); + + int xoffsMarker = xoffs + ((isDirectory || isMarker) ? ((hasPicon && isMarker ? 125 : m_itemheight) + 16 + 8) : 0); + int correction = 0; + int service_name_end = 0; + if (!m_marker_alignment.empty() && m_marker_alignment == "center" && isMarker) { + xoffsMarker = (m_itemsize.width() - bboxName.width()) / 2; + correction = 16; + } + + if (!isMarker && !isDirectory) { + std::string chNum = ""; + if (hasChannelNumbers && m_cursor->getChannelNum() != 0) { + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); + chNum = buffer; } + if (chNum != "") text = chNum + m_separator + text; + } + ePtr &pixmap_mDir = isMarker ? m_pixmaps[picMarker] : isDirectory ? m_pixmaps[picFolder] : m_pixmaps[picElements];; + if (isMarker || isDirectory) { + if (isDirectory || (isMarker && !m_marker_as_line)) { + eSize pixmap_size = pixmap_mDir->size(); + if (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight) + xoffsMarker = xoffs + pixmap_size.width() + 16; + } + } - eRect tmp = area; - int xoffs = 0; - ePtr piconPixmap; + ePtr para = new eTextPara(eRect(0, 0, xlpos - xoffsMarker, m_itemheight/2)); + para->setFont(m_element_font[celServiceName]); + para->renderString(text.c_str()); + eRect bbox = para->getBoundBox(); + service_name_end = xoffsMarker - correction + bbox.width() + m_items_distances; + painter.renderPara(para, ePoint(xoffsMarker - correction, offset.y() + yoffs_orig + ((ctrlHeight - bbox.height())/2))); + + if (isDirectory || (isMarker && !m_marker_as_line)) { + if (pixmap_mDir) { + eSize pixmap_size = pixmap_mDir->size(); + if (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight){ + eRect area = eRect(xoffs, offset.y() + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(pixmap_mDir, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + } else { + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + eRect area = eRect(xoffs, offset.y(), 125, m_itemheight); + painter.clip(area); + painter.blitScale(pixmap_mDir, eRect(xoffs, offset.y(), 125, m_itemheight), area, pflags); + } + painter.clippop(); + } + } else if (isMarker && m_marker_as_line) { + if (m_markerline_color_set) painter.setForegroundColor(m_markerline_color); + eRect firstLineRect = eRect(xoffs, offset.y() + (m_itemheight - m_marker_as_line) / 2, xoffsMarker - 16 - 8 - xoffs - correction, m_marker_as_line); + painter.fill(firstLineRect); + int secondLineOffset = xoffsMarker + bboxName.width() + 16 + 8 - correction; + eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - 16 - 8, m_marker_as_line); + painter.fill(secondLineRect); + } - if (e == celServiceName) + // event name + if (is_event) + { + event_name = evt->getEventName(); + event_begin = evt->getBeginTime(); + event_duration = evt->getDuration(); + int timeLeft = event_begin + event_duration - now; + eRect progressBarRect = m_element_position[celServiceEventProgressbar]; + if (m_has_next_event && event_begin > 0 && !service_info->getEvent(*m_cursor, evt_next, (event_begin + event_duration))) + next_event_name = evt_next->getEventName(); + + if (!event_name.empty()) { - //picon stuff - if (isPlayable && PyCallable_Check(m_GetPiconNameFunc)) - { - ePyObject pArgs = PyTuple_New(1); - PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); - ePyObject pRet = PyObject_CallObject(m_GetPiconNameFunc, pArgs); - Py_DECREF(pArgs); - if (pRet) - { - if (PyUnicode_Check(pRet)) + int pb_xpos = xoffs; + //--------------------------------------------------- Event Progressbar ----------------------------------------------------------------- + if (progressBarRect.width() > 0) { + int pb_yoffs_corr = m_itemheight/2; + if (m_has_next_event) pb_yoffs_corr = 5; + if (m_has_next_event) { + pb_xpos = m_itemsize.width() - 15 - progressBarRect.width(); + } + int pb_ypos = offset.y() + pb_yoffs_corr + (m_itemheight/2 - m_progressbar_height - 2 * m_progressbar_border_width) / 2; + int pb_width = progressBarRect.width() - 2 * m_progressbar_border_width; + gRGB ProgressbarBorderColor = 0xdfdfdf; + int evt_done = pb_width * (now - event_begin) / event_duration; + + if (!startsWith(m_progress_mode, "perc")) { + // the progress data... + eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); + ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; + if (pixmap) { + painter.clip(tmp); + painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + else { + if (!selected && m_color_set[serviceEventProgressbarColor]) + painter.setForegroundColor(m_color[serviceEventProgressbarColor]); + else if (selected && m_color_set[serviceEventProgressbarColorSelected]) + painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); + painter.fill(tmp); + } + + // the progressbar border + if (!selected) { + if (m_color_set[serviceEventProgressbarBorderColor]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; + else if (m_color_set[eventborderForeground]) + ProgressbarBorderColor = m_color[eventborderForeground]; + } + else { /* !selected */ + if (m_color_set[serviceEventProgressbarBorderColorSelected]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; + else if (m_color_set[eventborderForegroundSelected]) + ProgressbarBorderColor = m_color[eventborderForegroundSelected]; + } + painter.setForegroundColor(ProgressbarBorderColor); + + if (m_progressbar_border_width) { - std::string piconFilename = PyUnicode_AsUTF8(pRet); - if (!piconFilename.empty()) - loadImage(piconPixmap, piconFilename.c_str()); + painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); } - Py_DECREF(pRet); + else + painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); + if (!m_has_next_event) xoffs += pb_width + 16; } } - xoffs = xoffset; - tmp.setWidth(((!isPlayable || m_column_width == -1 || (!piconPixmap && !m_column_width)) ? tmp.width() : m_column_width) - xoffs); - } - - ePtr para = new eTextPara(tmp); - para->setFont(m_element_font[e]); - para->renderString(text.c_str()); - - if (e == celServiceName) - { - eRect bbox = para->getBoundBox(); - int servicenameWidth = ((!isPlayable || m_column_width == -1 || (!piconPixmap && !m_column_width)) ? bbox.width() : m_column_width); - m_element_position[celServiceInfo].setLeft(area.left() + servicenameWidth + m_items_distances + xoffs); - m_element_position[celServiceInfo].setTop(area.top()); - m_element_position[celServiceInfo].setWidth(area.width() - (servicenameWidth + m_items_distances + xoffs)); - m_element_position[celServiceInfo].setHeight(area.height()); - if (!next_event_name.empty()) - m_element_position[celServiceNextInfo].setHeight(area.height()); - nameLeft = area.left(); - nameWidth = area.width(); - - if (isPlayable) + //------------------------------------------------------- Event Name -------------------------------------------------------------------- + text = event_name; + std::replace(text.begin(), text.end(), '\n', ' '); + if (serviceAvail) { - //picon stuff - if (PyCallable_Check(m_GetPiconNameFunc) and (m_column_width || piconPixmap)) + if (!selected && m_color_set[eventForeground]) { - eRect area = m_element_position[celServiceInfo]; - /* PIcons are usually about 100:60. Make it a - * bit wider in case the icons are diffently - * shaped, and to add a bit of margin between - * icon and text. */ - const int iconWidth = area.height() * 9 / (m_show_two_lines > 0 ? 10 : 5); - m_element_position[celServiceInfo].setLeft(area.left() + iconWidth); - m_element_position[celServiceInfo].setWidth(area.width() - iconWidth); - area = m_element_position[celServiceName]; - xoffs += iconWidth; - if (piconPixmap) - { - area.moveBy(offset); - painter.clip(area); - painter.blitScale(piconPixmap, - eRect(area.left(), area.top(), iconWidth, area.height()), - area, - gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER); - painter.clippop(); - } + painter.setForegroundColor(m_color[eventForeground]); } + else if (selected && m_color_set[eventForegroundSelected]) + { + painter.setForegroundColor(m_color[eventForegroundSelected]); + } + else + painter.setForegroundColor(gRGB(0xe7b53f)); - //record icon stuff part1 - int rec_pixmap_xoffs = 0; - if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) - rec_pixmap_xoffs = m_pixmaps[picRecord]->size().width() + m_items_distances; - - //service type marker stuff - if (m_servicetype_icon_mode) + if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver { - int orbpos = m_cursor->getUnsignedData(4) >> 16; - const char *filename = ref.path.c_str(); - ePtr &pixmap = - (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : - (strstr(filename, "://")) ? m_pixmaps[picStream] : - (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : - (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; - if (pixmap) + painter.setForegroundColor(m_color[eventForegroundFallback]); + } + else if (serviceFallback && selected && m_color_set[eventForegroundSelectedFallback]) + { + painter.setForegroundColor(m_color[eventForegroundSelectedFallback]); + } + } + + std::string percent = ""; + if (startsWith(m_progress_mode, "perc")) { + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - event_begin) / event_duration)); + percent = buffer; + } + + //------------------------------------------------- Event name ------------------------------------------------------------------------------ + if (m_has_next_event) { + ePtr para = new eTextPara(eRect(0, 0, pb_xpos - service_name_end - m_items_distances - 15, m_itemheight/2)); + para->setFont(m_element_font[celServiceInfo]); + para->renderString(text.c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(service_name_end, offset.y() + yoffs_orig + ((ctrlHeight - bbox.height())/2))); + + if (!percent.empty()) { + ePtr paraPrec = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + paraPrec->setFont(m_element_font[celServiceInfo]); + paraPrec->renderString(percent.c_str()); + eRect bboxPerc = paraPrec->getBoundBox(); + painter.renderPara(paraPrec, ePoint(m_itemsize.width() - 15 - bboxPerc.width() , offset.y() + yoffs_orig + ((ctrlHeight - bboxPerc.height())/2))); + } + + if (!next_event_name.empty()) { + if (serviceAvail) { - eSize pixmap_size = pixmap->size(); - eRect area = m_element_position[celServiceInfo]; - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); - int offs = rec_pixmap_xoffs; - if (m_servicetype_icon_mode == 1) + if (!selected && m_color_set[eventNextForeground]) { - area = m_element_position[celServiceName]; - offs = xoffs; - xoffs += pixmap_size.width() + m_items_distances; + painter.setForegroundColor(m_color[eventNextForeground]); } - else if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) - offs = offs + m_pixmaps[picCrypto]->size().width() + m_items_distances; - int correction = (!event_name.empty() && m_show_two_lines > 0 && m_servicetype_icon_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); - painter.clip(area); - painter.blit(pixmap, ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); - painter.clippop(); - } - } + else if (selected && m_color_set[eventNextForegroundSelected]) + { + painter.setForegroundColor(m_color[eventNextForegroundSelected]); + } + else + painter.setForegroundColor(gRGB(0x787878)); - //crypto icon stuff - if (m_crypto_icon_mode && m_pixmaps[picCrypto]) - { - eSize pixmap_size = m_pixmaps[picCrypto]->size(); - eRect area = m_element_position[celServiceInfo]; - int offs = rec_pixmap_xoffs; - if (m_crypto_icon_mode == 1) - { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); - area = m_element_position[celServiceName]; - offs = xoffs; - xoffs += pixmap_size.width() + m_items_distances; - } - int correction = (!event_name.empty() && m_show_two_lines > 0 && m_crypto_icon_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); - if (service_info && service_info->isCrypted()) - { - if (m_crypto_icon_mode == 2) + if (serviceFallback && !selected && m_color_set[eventNextForegroundFallback]) // fallback receiver { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + painter.setForegroundColor(m_color[eventNextForegroundFallback]); + } + else if (serviceFallback && selected && m_color_set[eventNextForegroundSelectedFallback]) + { + painter.setForegroundColor(m_color[eventNextForegroundSelectedFallback]); } - painter.clip(area); - painter.blit(m_pixmaps[picCrypto], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); - painter.clippop(); } + ePtr paraNext = new eTextPara(eRect(0, 0, xlpos - xoffs - m_items_distances, m_itemheight/2)); + paraNext->setFont(m_element_font[celServiceNextInfo]); + paraNext->renderString((m_next_title + next_event_name).c_str()); + eRect bboxNext = paraNext->getBoundBox(); + painter.renderPara(paraNext, ePoint(xoffs, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxNext.height())/2))); } + } else { + //------------------------------------------------ Event remaining ------------------------------------------------------------------------ + std::string timeLeft_str = ""; + char buffer[15]; + snprintf(buffer, sizeof(buffer), ("%s" + m_text_time).c_str(), timeLeft == 0 ? "" : "+", timeLeft/60); + timeLeft_str = buffer; + ePtr paraLeft = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + paraLeft->setFont(m_element_font[celServiceInfoRemainingTime]); + paraLeft->renderString(timeLeft_str.c_str()); + eRect bboxtLeft = paraLeft->getBoundBox(); + + ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - xoffs - bboxtLeft.width() - 25 - m_items_distances, m_itemheight/2)); + para->setFont(m_element_font[celServiceInfo]); + para->renderString(((!percent.empty() ? (percent + m_separator) : "") + text).c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(xoffs, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bbox.height())/2))); - //record icon stuff part2 - if (isRecorded && m_record_indicator_mode < 3 && m_pixmaps[picRecord]) + if (serviceAvail) { - eSize pixmap_size = m_pixmaps[picRecord]->size(); - eRect area = m_element_position[celServiceInfo]; - int offs = 0; - if (m_record_indicator_mode == 1) + if (!selected && m_color_set[eventRemainingForeground]) { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); - area = m_element_position[celServiceName]; - offs = xoffs; - xoffs += pixmap_size.width() + m_items_distances; + painter.setForegroundColor(m_color[eventRemainingForeground]); } - int correction = (!event_name.empty() && m_show_two_lines > 0 && m_record_indicator_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); - if (m_record_indicator_mode == 2) + else if (selected && m_color_set[eventRemainingForegroundSelected]) { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + painter.setForegroundColor(m_color[eventRemainingForegroundSelected]); } - painter.clip(area); - painter.blit(m_pixmaps[picRecord], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); - painter.clippop(); - } - if (m_show_two_lines > 0) - { - if(!next_event_name.empty()) + else + painter.setForegroundColor(gRGB(0x787878)); + + if (serviceFallback && !selected && m_color_set[eventRemainingForegroundFallback]) // fallback receiver { - m_element_position[celServiceNextInfo].setLeft(nameLeft + xoffs); - m_element_position[celServiceNextInfo].setWidth(nameWidth - xoffs); + painter.setForegroundColor(m_color[eventRemainingForegroundFallback]); } - else + else if (serviceFallback && selected && m_color_set[eventRemainingForegroundSelectedFallback]) { - m_element_position[celServiceInfo].setLeft(nameLeft + xoffs); - m_element_position[celServiceInfo].setWidth(nameWidth - xoffs); + painter.setForegroundColor(m_color[eventRemainingForegroundSelectedFallback]); } } + + painter.renderPara(paraLeft, ePoint(m_itemsize.width() - bboxtLeft.width() - 15, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxtLeft.height())/2))); } } + } + } else { + // Single line mode goes here + if (service_info) + service_info->getName(ref, text); - if (flags & gPainter::RT_HALIGN_RIGHT) - para->realign(eTextPara::dirRight); - else if (flags & gPainter::RT_HALIGN_CENTER) - para->realign(eTextPara::dirCenter); - else if (flags & gPainter::RT_HALIGN_BLOCK) - para->realign(eTextPara::dirBlock); + xoffs += m_sides_margin; + if (is_event) + { + event_name = evt->getEventName(); + event_begin = evt->getBeginTime(); + event_duration = evt->getDuration(); + } + int orbpos = m_cursor->getUnsignedData(4) >> 16; + const char *filename = ref.path.c_str(); - if (flags & gPainter::RT_VALIGN_CENTER) - { + ePtr &pixmap_system = + (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : + (strstr(filename, "://")) ? m_pixmaps[picStream] : + (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : + (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; + + eSize pixmap_system_size = eSize(); + eSize pixmap_crypto_size = eSize(); + eSize pixmap_rec_size = eSize(); + + if (pixmap_system) { + pixmap_system_size = pixmap_system->size(); + } + + if (m_pixmaps[picCrypto]) { + pixmap_crypto_size = m_pixmaps[picCrypto]->size(); + } + + if (m_pixmaps[picRecord]) { + pixmap_rec_size = m_pixmaps[picRecord]->size(); + } + + bool hasPicons = PyCallable_Check(m_GetPiconNameFunc); + bool isAlternativeNumberingMode = m_alternative_numbering; + std::string eventProgressConfig = m_progress_mode; + int serviceNameWidth = m_column_width > -1 && !isDirectory && !isMarker ? m_column_width : m_itemsize.width(); + bool shouldCorrect = serviceNameWidth >= m_column_width - pixmap_system_size.width()*3; + + if (m_servicetype_icon_mode == 2 && m_column_width > -1 && shouldCorrect) serviceNameWidth -= pixmap_system_size.width() + m_items_distances; + if (m_crypto_icon_mode == 2 && m_column_width > -1 && shouldCorrect) serviceNameWidth -= pixmap_crypto_size.width() + m_items_distances; + if (isRecorded && m_record_indicator_mode == 2 && m_column_width > -1 && shouldCorrect) serviceNameWidth -= pixmap_rec_size.width() + m_items_distances; + if ((m_servicetype_icon_mode == 2 || m_crypto_icon_mode == 2 || (isRecorded && m_record_indicator_mode == 2)) && m_column_width > -1) + serviceNameWidth -= m_items_distances; + + if (serviceNameWidth < 0) serviceNameWidth = 0; + + ePtr paraServiceName = new eTextPara(eRect(0, 0, serviceNameWidth, m_itemheight)); + paraServiceName->setFont(m_element_font[celServiceName]); + paraServiceName->renderString(text.c_str()); + eRect bboxServiceName = paraServiceName->getBoundBox(); + + if (isDirectory || (isMarker && !m_marker_as_line)) { + ePtr &pixmap_mDir = isMarker ? m_pixmaps[picMarker] : isDirectory ? m_pixmaps[picFolder] : m_pixmaps[picElements];; + eSize pixmap_size = pixmap_mDir->size(); + if (pixmap_size.height() < m_itemheight){ + eRect area = eRect(xoffs, offset.y() + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(pixmap_mDir, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + } else { + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + eRect area = eRect(xoffs, offset.y(), m_itemheight, m_itemheight); + painter.clip(area); + painter.blitScale(pixmap_mDir, eRect(xoffs, offset.y(), m_itemheight, m_itemheight), area, pflags); + } + painter.clippop(); + + painter.renderPara(paraServiceName, ePoint(xoffs + pixmap_size.width() + m_items_distances, offset.y() + ((ctrlHeight - bboxServiceName.height())/2))); + + } else if (isMarker && m_marker_as_line) { + int mTextLeft = (m_itemsize.width() - bboxServiceName.width())/2; + if (m_marker_alignment != "center") { + mTextLeft = 125 + m_items_distances; + } + painter.renderPara(paraServiceName, ePoint(mTextLeft, offset.y() + ((ctrlHeight - bboxServiceName.height())/2))); + + if (m_markerline_color_set) painter.setForegroundColor(m_markerline_color); + eRect firstLineRect = eRect(xoffs + m_items_distances, offset.y() + (m_itemheight - m_marker_as_line) / 2, mTextLeft - m_items_distances*2 - xoffs - 16, m_marker_as_line); + painter.fill(firstLineRect); + int secondLineOffset = mTextLeft + bboxServiceName.width() + m_items_distances + 16; + eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - m_items_distances - m_sides_margin, m_marker_as_line); + painter.fill(secondLineRect); + } + + if (!isDirectory && !isMarker) { + + ePtr paraCtrlText = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight)); + paraCtrlText->setFont(m_element_font[celServiceNumber]); + paraCtrlText->renderString((isAlternativeNumberingMode ? "0000" : "00000")); + eRect bboxCtrlText = paraCtrlText->getBoundBox(); + + if (hasChannelNumbers && m_cursor->getChannelNum() > 0) { + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); + std::string num = buffer; + ePtr para = new eTextPara(eRect(xoffs, 0, bboxCtrlText.width(), m_itemheight)); + para->setFont(m_element_font[celServiceNumber]); + para->renderString(num.c_str()); eRect bbox = para->getBoundBox(); - if (!event_name.empty() && m_show_two_lines > 0 && (e == celServiceName || (!next_event_name.empty() && e == celServiceInfo))) + painter.renderPara(para, ePoint(xoffs + (bboxCtrlText.width() - bbox.width()), offset.y() + (ctrlHeight - bbox.height())/2)); + xoffs += bboxCtrlText.width() + m_items_distances; + } + + eRect progressBarRect = m_element_position[celServiceEventProgressbar]; + + int pb_xpos = xoffs; + int pb_ypos = offset.y() + (m_itemheight - m_progressbar_height - 2 * m_progressbar_border_width) / 2; + int pb_width = progressBarRect.width() - 2 * m_progressbar_border_width; + gRGB ProgressbarBorderColor = 0xdfdfdf; + int evt_done = pb_width * (now - event_begin) / event_duration; + + if (eventProgressConfig == "barleft" || eventProgressConfig == "percleft") { + xoffs += progressBarRect.width() + m_items_distances; + } + + ePtr piconPixmap; + bool isPIconSVG = false; + int piconWidth = m_itemheight*1.67; + if (isPlayable && hasPicons) + { + ePyObject pArgs = PyTuple_New(1); + PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); + ePyObject pRet = PyObject_CallObject(m_GetPiconNameFunc, pArgs); + Py_DECREF(pArgs); + if (pRet) { - yoffs = ((area.height()/2) - bbox.height()) / 2 - bbox.top(); - if (e == celServiceName) - nameYoffs = yoffs/2; - else - nextYoffs = (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs); + if (PyUnicode_Check(pRet)) + { + std::string piconFilename = PyUnicode_AsUTF8(pRet); + if (endsWith(piconFilename, ".svg")) { + isPIconSVG = true; + } + if (!piconFilename.empty()) + loadImage(piconPixmap, piconFilename.c_str(), 0, isPIconSVG ? piconWidth : 0); + } + Py_DECREF(pRet); } - else if (!event_name.empty() && m_show_two_lines > 0 && ((next_event_name.empty() && e == celServiceInfo) || (!next_event_name.empty() && e == celServiceNextInfo))) - yoffs = (e == celServiceNextInfo ? nextYoffs : (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs)); - else - yoffs = (area.height() - bbox.height())/2 - bbox.top(); } - painter.renderPara(para, offset+ePoint(xoffs, yoffs)); - } - else if ((e == celFolderPixmap && m_cursor->flags & eServiceReference::isDirectory) || - (e == celMarkerPixmap && m_cursor->flags & eServiceReference::isMarker && - !(m_cursor->flags & eServiceReference::isNumberedMarker))) - { - ePtr &pixmap = - (e == celFolderPixmap) ? m_pixmaps[picFolder] : m_pixmaps[picMarker]; - if (pixmap) - { - eSize pixmap_size = pixmap->size(); - eRect area; - if (e == celFolderPixmap || m_element_position[celServiceNumber].width() < pixmap_size.width()) + if (hasPicons) { + eRect piconArea = eRect(xoffs, offset.y(), piconWidth, m_itemheight); + /* PIcons are usually about 100:60. Make it a + * bit wider in case the icons are diffently + * shaped, and to add a bit of margin between + * icon and text. */ + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + if (!isPIconSVG) { + pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + } + if (piconPixmap) { - area = m_element_position[celServiceName]; - if (m_element_position[celServiceEventProgressbar].left() == 0) - area.setLeft(0); - xoffset = pixmap_size.width() + m_items_distances; + painter.clip(piconArea); + if (isPIconSVG) { + painter.blit(piconPixmap, + eRect(xoffs, offset.y(), piconWidth, m_itemheight), + eRect(), + pflags + ); + } else { + painter.blitScale(piconPixmap, + eRect(xoffs, offset.y(), piconWidth, m_itemheight), + piconArea, + pflags); + } + painter.clippop(); } - else - area = m_element_position[celServiceNumber]; - int correction = (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); + xoffs += piconWidth + m_items_distances; + } + + int iconSystemPosX = xoffs + m_items_distances; + int iconCryptoPosX = iconSystemPosX; + int iconRecordPosX = iconSystemPosX; + int iconOffsX = iconSystemPosX; + + if (m_servicetype_icon_mode == 1 && pixmap_system) { + iconCryptoPosX += pixmap_system_size.width() + m_items_distances; + iconRecordPosX = iconCryptoPosX; + iconOffsX += pixmap_system_size.width() + m_items_distances; + } + + if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) { + iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; + iconOffsX += pixmap_crypto_size.width() + m_items_distances; + } + + if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) { + iconOffsX += pixmap_rec_size.width() + m_items_distances; + } + + if (m_servicetype_icon_mode == 1 && pixmap_system) { + eRect area = eRect(iconSystemPosX, offset.y() + (ctrlHeight - pixmap_system_size.height())/2, pixmap_system_size.width(), pixmap_system_size.height()); painter.clip(area); - painter.blit(pixmap, ePoint(area.left(), offset.y() + correction), area, gPainter::BT_ALPHABLEND); + painter.blit(pixmap_system, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); painter.clippop(); } - } - } - eRect area = m_element_position[celServiceEventProgressbar]; - if (area.width() > 0 && evt && !m_element_font[celServiceEventProgressbar]) - { - int pb_xpos = area.left(); - int pb_ypos = offset.y() + (m_itemsize.height() - m_progressbar_height - 2 * m_progressbar_border_width) / 2; - int pb_width = area.width()- 2 * m_progressbar_border_width; - gRGB ProgressbarBorderColor = 0xdfdfdf; - int evt_done = pb_width * (now - event_begin) / event_duration; - - // the progress data... - eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); - ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; - if (pixmap) { - painter.clip(tmp); - painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); - painter.clippop(); - } - else { - if (!selected && m_color_set[serviceEventProgressbarColor]) - painter.setForegroundColor(m_color[serviceEventProgressbarColor]); - else if (selected && m_color_set[serviceEventProgressbarColorSelected]) - painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); - else if (m_show_two_lines == 2) - painter.setForegroundColor(EventProgressbarColor); - painter.fill(tmp); - } + if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { + eRect area = eRect(iconCryptoPosX, offset.y() + (ctrlHeight - pixmap_crypto_size.height())/2, pixmap_crypto_size.width(), pixmap_crypto_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picCrypto], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - // the progressbar border - if (!selected) { - if (m_color_set[serviceEventProgressbarBorderColor]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; - else if (m_color_set[eventborderForeground]) - ProgressbarBorderColor = m_color[eventborderForeground]; - } - else { /* !selected */ - if (m_color_set[serviceEventProgressbarBorderColorSelected]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; - else if (m_color_set[eventborderForegroundSelected]) - ProgressbarBorderColor = m_color[eventborderForegroundSelected]; - } - painter.setForegroundColor(ProgressbarBorderColor); + if (isRecorded && m_pixmaps[picRecord] && m_record_indicator_mode == 1) { + eRect area = eRect(iconRecordPosX, offset.y() + (ctrlHeight - pixmap_rec_size.height())/2, pixmap_rec_size.width(), pixmap_rec_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picRecord], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + + xoffs = iconOffsX; + xoffs_col = xoffs + m_column_width; + + painter.renderPara(paraServiceName, ePoint(xoffs, offset.y() + (ctrlHeight - bboxServiceName.height())/2)); + + xoffs += std::min(serviceNameWidth, bboxServiceName.width()) + m_items_distances; + + iconSystemPosX = xoffs; + iconCryptoPosX = iconSystemPosX; + iconRecordPosX = iconSystemPosX; + iconOffsX = iconSystemPosX; + + if (m_servicetype_icon_mode == 2 && pixmap_system) { + iconCryptoPosX += pixmap_system_size.width() + m_items_distances; + iconRecordPosX = iconCryptoPosX; + iconOffsX += pixmap_system_size.width() + m_items_distances; + xoffs = iconOffsX; + } + + if (m_crypto_icon_mode == 2 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { + iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; + iconOffsX += pixmap_crypto_size.width() + m_items_distances; + xoffs = iconOffsX; + } + + if (isRecorded && m_record_indicator_mode == 2 && m_pixmaps[picRecord]) { + iconOffsX += pixmap_rec_size.width() + m_items_distances; + xoffs = iconOffsX; + } + + if (m_servicetype_icon_mode == 2 && pixmap_system) { + eRect area = eRect(iconSystemPosX, offset.y() + (ctrlHeight - pixmap_system_size.height())/2, pixmap_system_size.width(), pixmap_system_size.height()); + painter.clip(area); + painter.blit(pixmap_system, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + + if (m_crypto_icon_mode == 2 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { + eRect area = eRect(iconCryptoPosX, offset.y() + (ctrlHeight - pixmap_crypto_size.height())/2, pixmap_crypto_size.width(), pixmap_crypto_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picCrypto], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + + if (isRecorded && m_pixmaps[picRecord] && m_record_indicator_mode == 2) { + eRect area = eRect(iconRecordPosX, offset.y() + (ctrlHeight - pixmap_rec_size.height())/2, pixmap_rec_size.width(), pixmap_rec_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picRecord], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); - painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + if (eventProgressConfig == "barright" || eventProgressConfig == "percright") { + pb_xpos = m_itemsize.width() - progressBarRect.width() - m_items_distances*2 - m_sides_margin*2 - m_progressbar_border_width*2; + } + + if (is_event && !event_name.empty()) { + text = event_name; + std::replace(text.begin(), text.end(), '\n', ' '); + if (serviceAvail) + { + if (!selected && m_color_set[eventForeground]) + { + painter.setForegroundColor(m_color[eventForeground]); + EventProgressbarColor = m_color[eventForeground]; + } + else if (selected && m_color_set[eventForegroundSelected]) + { + painter.setForegroundColor(m_color[eventForegroundSelected]); + EventProgressbarColor = m_color[eventForegroundSelected]; + } + else + painter.setForegroundColor(gRGB(0xe7b53f)); + + if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver + { + painter.setForegroundColor(m_color[eventForegroundFallback]); + EventProgressbarColor = m_color[eventForegroundFallback]; + } + else if (serviceFallback && selected && m_color_set[eventForegroundSelectedFallback]) + { + painter.setForegroundColor(m_color[eventForegroundSelectedFallback]); + EventProgressbarColor = m_color[eventForegroundSelectedFallback]; + } + } + + int eventTextWidth = (eventProgressConfig == "barright" || eventProgressConfig == "percright") ? + (pb_xpos - (m_column_width > 0 ? xoffs_col : xoffs) - m_items_distances*2 ) : (m_itemsize.width() - m_sides_margin*2 - (m_column_width > 0 ? xoffs_col : xoffs) - m_items_distances*2); + + ePtr para = new eTextPara(eRect(0, 0, eventTextWidth, m_itemheight)); + para->setFont(m_element_font[celServiceInfo]); + para->renderString(text.c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(m_column_width > 0 ? xoffs_col : xoffs, offset.y() + (m_itemheight - bbox.height())/2)); + + if (eventProgressConfig != "no" && !startsWith(eventProgressConfig, "perc")) { + // the progress data... + eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); + ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; + if (pixmap) { + painter.clip(tmp); + painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + else { + if (!selected && m_color_set[serviceEventProgressbarColor]) + painter.setForegroundColor(m_color[serviceEventProgressbarColor]); + else if (selected && m_color_set[serviceEventProgressbarColorSelected]) + painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); + painter.fill(tmp); + } + + // the progressbar border + if (!selected) { + if (m_color_set[serviceEventProgressbarBorderColor]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; + else if (m_color_set[eventborderForeground]) + ProgressbarBorderColor = m_color[eventborderForeground]; + } + else { /* !selected */ + if (m_color_set[serviceEventProgressbarBorderColorSelected]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; + else if (m_color_set[eventborderForegroundSelected]) + ProgressbarBorderColor = m_color[eventborderForegroundSelected]; + } + painter.setForegroundColor(ProgressbarBorderColor); + + if (m_progressbar_border_width) + { + painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + } + else + painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); + } + if (startsWith(eventProgressConfig, "perc") && is_event) { + if (!selected && m_color_set[eventForeground]) + painter.setForegroundColor(m_color[eventForeground]); + else if (selected && m_color_set[eventForegroundSelected]) + painter.setForegroundColor(m_color[eventForegroundSelected]); + else + painter.setForegroundColor(gRGB(0x787878)); + + if (isRecorded && m_record_indicator_mode == 3) { + painter.setForegroundColor(m_color[serviceRecorded]); + } + + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - event_begin) / event_duration)); + std::string percent = buffer; + ePtr paraPerc = new eTextPara(eRect(pb_xpos, 0, progressBarRect.width(), m_itemheight)); + paraPerc->setFont(m_element_font[celServiceInfo]); + paraPerc->renderString(percent.c_str()); + eRect bboxPerc = paraPerc->getBoundBox(); + painter.renderPara(paraPerc, ePoint((progressBarRect.width() - bboxPerc.width())/(eventProgressConfig == "percright" ? 1 : 2), offset.y() + (ctrlHeight - bboxPerc.height())/2)); + } + } + } } } painter.clippop(); -} +} \ No newline at end of file diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index 36d51362767..349a198a2e1 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -28,6 +28,9 @@ class eListboxServiceContent: public virtual iListboxContent int getNextBeginningWithChar(char c); int getPrevMarkerPos(); int getNextMarkerPos(); + int getCurrentSelectionIndex() { return cursorResolve(m_cursor_number); } + eSize getItemSize() { return m_itemsize; } + int getListSize() { return m_size_visible; } /* support for marked services */ void initMarked(); @@ -44,7 +47,8 @@ class eListboxServiceContent: public virtual iListboxContent enum { visModeSimple, - visModeComplex + visModeComplex, + visSkinDefined }; void setVisualMode(int mode); @@ -59,6 +63,7 @@ class eListboxServiceContent: public virtual iListboxContent celServiceInfo, // "now" event celServiceNextInfo, // "next" event celServiceTypePixmap, + celServiceInfoRemainingTime, celElements }; @@ -73,6 +78,11 @@ class eListboxServiceContent: public virtual iListboxContent picServiceEventProgressbar, picCrypto, picRecord, + pic4K, + picHD, + picSD, + picBackup, + picCatchup, picElements }; @@ -87,7 +97,6 @@ class eListboxServiceContent: public virtual iListboxContent int getItemHeight() { return m_itemheight; } void setItemHeight(int height); void setHideNumberMarker(bool doHide) { m_hide_number_marker = doHide; } - void setShowTwoLines(int mode) { m_show_two_lines = mode; } void setServiceTypeIconMode(int mode) { m_servicetype_icon_mode = mode; } void setCryptoIconMode(int mode) { m_crypto_icon_mode = mode; } void setRecordIndicatorMode(int mode) { m_record_indicator_mode = mode; } @@ -96,8 +105,22 @@ class eListboxServiceContent: public virtual iListboxContent void setProgressbarBorderWidth(int value) { m_progressbar_border_width = value; } void setNonplayableMargins(int value) { m_nonplayable_margins = value; } void setItemsDistances(int value) { m_items_distances = value; } + void setSidesMargin(int value) { m_sides_margin = value; } + void setMarkerAsLine(int value) { m_marker_as_line = value; } + void setChannelNumbersVisible(bool visible) { m_chanel_number_visible = visible; } + void setAlternativeNumberingMode(bool b) { m_alternative_numbering = b; } + void setProgressBarMode(std::string s) { m_progress_mode = s; } + void setAlternativeRecordMatching(bool b) { m_alternative_record_match = b; } + void setHasNextEvent(bool b) { m_has_next_event = b; } void setNextTitle(const std::string &string) { m_next_title = string; } + void setTextTime(const std::string &string) { m_text_time = string; } + void setTextSeparator(const std::string &string) { m_separator = string; } + void setMarkerTextAlignment(const std::string &string) { m_marker_alignment = string; } // currently supports left and center + void setMarkerLineColor(const gRGB &col) { + m_markerline_color = col; + m_markerline_color_set = 1; + } static void setGetPiconNameFunc(SWIG_PYOBJECT(ePyObject) func); @@ -124,6 +147,10 @@ class eListboxServiceContent: public virtual iListboxContent serviceEventProgressbarBorderColor, serviceEventProgressbarBorderColorSelected, serviceRecorded, + eventRemainingForeground, + eventRemainingForegroundSelected, + eventRemainingForegroundFallback, + eventRemainingForegroundSelectedFallback, colorElements }; @@ -163,7 +190,7 @@ class eListboxServiceContent: public virtual iListboxContent list::iterator m_cursor, m_saved_cursor; int m_cursor_number, m_saved_cursor_number; - int m_size; + int m_size, m_size_visible; eSize m_itemsize; ePtr m_service_center; @@ -183,7 +210,8 @@ class eListboxServiceContent: public virtual iListboxContent int m_itemheight; bool m_hide_number_marker; - int m_show_two_lines; + bool m_chanel_number_visible; + bool m_alternative_numbering; int m_servicetype_icon_mode; int m_crypto_icon_mode; int m_record_indicator_mode; @@ -192,8 +220,18 @@ class eListboxServiceContent: public virtual iListboxContent int m_progressbar_border_width; int m_nonplayable_margins; int m_items_distances; - + int m_sides_margin; + int m_marker_as_line; + gRGB m_markerline_color; + int m_markerline_color_set; + bool m_alternative_record_match; + bool m_has_next_event; + + std::string m_text_time; std::string m_next_title; + std::string m_separator; + std::string m_marker_alignment; + std::string m_progress_mode; }; #endif diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index e5d97096bda..af3d3f68d90 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -108,7 +108,7 @@ int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const int system; ((const eServiceReferenceDVB&)ref).getChannelID(chid); ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); - return res_mgr->canAllocateChannel(chid, chid_ignore, system); + return res_mgr->canAllocateChannel(chid, chid_ignore, eDVBChannelID(), system); } return 0; } @@ -253,7 +253,7 @@ int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref }; int system; ((const eServiceReferenceDVB&)*it).getChannelID(chid); - int tmp = res->canAllocateChannel(chid, chid_ignore, system, simulate); + int tmp = res->canAllocateChannel(chid, chid_ignore, eDVBChannelID(), system, simulate); if (prio_order == 127) // ignore dvb-type priority, try all alternatives one-by-one { if (((tmp > 0) || (!it->path.empty()))) @@ -388,6 +388,13 @@ RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, st } m_parser.m_name = name; } + if (!name.empty()) { + std::vector name_split = split(name, "•"); + name = name_split[0]; + if (name_split.size() > 1) { + m_parser.m_prov = name_split[1]; + } + } return 0; } @@ -460,6 +467,13 @@ std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReferen return m_parser.m_ref.toString(); case iServiceInformation::sTags: return m_parser.m_tags; + case iServiceInformation::sProvider: + { + if (m_parser.m_prov.empty()) { + return ""; + } + return m_parser.m_prov; + } default: return ""; } @@ -2061,8 +2075,20 @@ std::string eDVBServicePlay::getInfoString(int w) switch (w) { case sProvider: + { if (!m_dvb_service) return ""; - return m_dvb_service->m_provider_name; + std::string prov = m_dvb_service->m_provider_name; + if (prov.empty()) { + eServiceReferenceDVB sRelayOrigSref; + bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(sRelayOrigSref); + if (res) { + ePtr sRelayServiceOrigSref; + eDVBDB::getInstance()->getService(sRelayOrigSref, sRelayServiceOrigSref); + return sRelayServiceOrigSref->m_provider_name; + } + } + return prov; + } case sServiceref: return m_reference.toString(); case sHBBTVUrl: @@ -2087,6 +2113,11 @@ std::string eDVBServicePlay::getInfoString(int w) ePtr eDVBServicePlay::getTransponderData() { + eServiceReferenceDVB orig; + bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(orig); + if (res) { + return eStaticServiceDVBInformation().getTransponderData(orig); + } return eStaticServiceDVBInformation().getTransponderData(m_reference); } @@ -2413,7 +2444,7 @@ bool eDVBServiceBase::tryFallbackTuner(eServiceReferenceDVB &service, bool &is_s service.getChannelID(chid); // this sets chid eServiceReferenceDVB().getChannelID(chid_ignore); // this sets chid_ignore - if(res_mgr->canAllocateChannel(chid, chid_ignore, system)) // this sets system + if(res_mgr->canAllocateChannel(chid, chid_ignore, eDVBChannelID(), system)) // this sets system return false; while((index = remote_fallback_url.find(':')) != std::string::npos) @@ -2456,7 +2487,7 @@ bool eDVBServiceBase::tryFallbackTuner(eServiceReferenceDVB &service, bool &is_s service = eServiceReferenceDVB(remote_service_ref.str()); is_stream = true; - + // m_is_streamx = true; // used by decoder.cpp to stop tuxtxt logging on text pid for streams return true; @@ -3066,7 +3097,7 @@ void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged) { selectAudioStream(); } - + if (!(m_is_pvr || m_is_stream || m_timeshift_active)) m_decoder->setSyncPCR(pcrpid); else @@ -3613,7 +3644,7 @@ void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p) // Where subtitles are delivered out of sync with video, only treat subtitles in the past as having bad timing. // Those that are delivered too early are cached for displaying at the appropriate later time - // Note that this can be due to buggy drivers, as well as problems with the broadcast + // Note that this can be due to buggy drivers, as well as problems with the broadcast if (pos-p.m_show_time > 1800000 && (m_is_pvr || m_timeshift_enabled)) { // Subtitles delivered over 20 seconds too late diff --git a/lib/service/servicedvd.cpp b/lib/service/servicedvd.cpp index 707e0b54475..f00856221d9 100644 --- a/lib/service/servicedvd.cpp +++ b/lib/service/servicedvd.cpp @@ -1120,7 +1120,7 @@ void eServiceDVD::saveCuesheet() if (stat("/home/root", &st) == 0 && stat(filename.c_str(), &st) != 0) if (mkdir(filename.c_str(), 0755)) return; // cannot create directory so no point in trying to save cue data - + filename += "/"; if (m_ddvd_titlestring[0] != '\0') filename += m_ddvd_titlestring; diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index 2fa2523602c..3aaaa9aeba5 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -261,6 +262,10 @@ RESULT eStaticServiceMP3Info::getName(const eServiceReference &ref, std::string else name = ref.path; } + if (!name.empty()) { + std::vector name_split = split(name, "•"); + name = name_split[0]; + } return 0; } @@ -1199,6 +1204,14 @@ RESULT eServiceMP3::getName(std::string &name) } else name = title; + + if (!name.empty()) { + std::vector name_split = split(name, "•"); + name = name_split[0]; + if (name_split.size() > 1) { + m_prov = name_split[1]; + } + } return 0; } @@ -1326,7 +1339,16 @@ std::string eServiceMP3::getInfoString(int w) switch (w) { case sProvider: - return m_sourceinfo.is_streaming ? "IPTV" : "FILE"; + { + if (m_sourceinfo.is_streaming) { + if (m_prov.empty()) { + return "IPTV"; + } else { + return m_prov; + } + } + return "FILE"; + } case sServiceref: return m_ref.toString(); default: diff --git a/lib/service/servicemp3.h b/lib/service/servicemp3.h index 0043372a6d0..d4127adf2e5 100644 --- a/lib/service/servicemp3.h +++ b/lib/service/servicemp3.h @@ -297,6 +297,7 @@ class eServiceMP3: public iPlayableService, public iPauseableService, gdouble m_currentTrickRatio; friend class eServiceFactoryMP3; eServiceReference m_ref; + std::string m_prov; int m_buffer_size; int m_ignore_buffering_messages; bool m_is_live; diff --git a/lib/service/servicets.cpp b/lib/service/servicets.cpp index 419e6509e07..5131e868acd 100644 --- a/lib/service/servicets.cpp +++ b/lib/service/servicets.cpp @@ -258,7 +258,7 @@ RESULT eServiceTS::start() m_streamthread = new eStreamThread(); CONNECT(m_streamthread->m_event, eServiceTS::recv_event); m_decoder->pause(); - if (unpause() != 0) + if (unpause() != 0) return -1; m_event(this, evStart); return 0; diff --git a/lib/service/servicewebts.cpp b/lib/service/servicewebts.cpp index d4f027f83a9..552d20dd6fe 100644 --- a/lib/service/servicewebts.cpp +++ b/lib/service/servicewebts.cpp @@ -383,7 +383,7 @@ void eServiceWebTS::recv_event(int evt) m_decoder->pause(); m_event(this, evStart); m_decoder->play(); - + } bool wasnull = !m_audioInfo; m_streamthread->getAudioInfo(m_audioInfo); diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 index 5a525e8d3d3..8edf5152ec7 100644 --- a/m4/ax_cxx_compile_stdcxx.m4 +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -10,8 +10,8 @@ # # Check for baseline language coverage in the compiler for the specified # version of the C++ standard. If necessary, add switches to CXX and -# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) -# or '14' (for the C++14 standard). +# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for +# the respective C++ standard version. # # The second argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. @@ -36,13 +36,14 @@ # Copyright (c) 2016, 2018 Krzesimir Nowak # Copyright (c) 2019 Enji Cooper # Copyright (c) 2020 Jason Merrill +# Copyright (c) 2021 Jörn Heusipp # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 12 +#serial 18 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). @@ -51,6 +52,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [$1], [20], [ax_cxx_compile_alternatives="20"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], @@ -102,9 +104,18 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" + dnl MSVC needs -std:c++NN for C++17 and later (default is C++14) for alternative in ${ax_cxx_compile_alternatives}; do - for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do + if test x"$switch" = xMSVC; then + dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide + dnl with -std=c++17. We suffix the cache variable name with _MSVC to + dnl avoid this. + switch=-std:c++${alternative} + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC]) + else + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + fi AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" @@ -151,7 +162,6 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) - dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], @@ -159,12 +169,24 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) +dnl Test body for checking C++17 support + m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ) +dnl Test body for checking C++20 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 +) + + dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ @@ -176,7 +198,11 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201103L +// MSVC always sets __cplusplus to 199711L in older versions; newer versions +// only set it correctly if /Zc:__cplusplus is specified as well as a +// /std:c++NN switch: +// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ +#elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" @@ -467,7 +493,7 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201402L +#elif __cplusplus < 201402L && !defined _MSC_VER #error "This is not a C++14 compiler" @@ -591,7 +617,7 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201703L +#elif __cplusplus < 201703L && !defined _MSC_VER #error "This is not a C++17 compiler" @@ -957,7 +983,36 @@ namespace cxx17 } // namespace cxx17 -#endif // __cplusplus < 201703L +#endif // __cplusplus < 201703L && !defined _MSC_VER ]]) + +dnl Tests for new features in C++20 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L && !defined _MSC_VER + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L && !defined _MSC_VER + +]]) diff --git a/m4/ax_cxx_compile_stdcxx_17.m4 b/m4/ax_cxx_compile_stdcxx_17.m4 deleted file mode 100644 index a6834171739..00000000000 --- a/m4/ax_cxx_compile_stdcxx_17.m4 +++ /dev/null @@ -1,35 +0,0 @@ -# ============================================================================= -# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_17.html -# ============================================================================= -# -# SYNOPSIS -# -# AX_CXX_COMPILE_STDCXX_17([ext|noext], [mandatory|optional]) -# -# DESCRIPTION -# -# Check for baseline language coverage in the compiler for the C++17 -# standard; if necessary, add switches to CXX and CXXCPP to enable -# support. -# -# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX -# macro with the version set to C++17. The two optional arguments are -# forwarded literally as the second and third argument respectively. -# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for -# more information. If you want to use this macro, you also need to -# download the ax_cxx_compile_stdcxx.m4 file. -# -# LICENSE -# -# Copyright (c) 2015 Moritz Klammler -# Copyright (c) 2016 Krzesimir Nowak -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 2 - -AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) -AC_DEFUN([AX_CXX_COMPILE_STDCXX_17], [AX_CXX_COMPILE_STDCXX([17], [$1], [$2])]) diff --git a/po/fi.po b/po/fi.po index da6df2390b9..bf9fcf37e74 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-10-20 19:33+0300\n" +"PO-Revision-Date: 2023-12-18 06:59+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -2240,7 +2240,7 @@ msgid "" "Are you sure you want to activate this network configuration?\n" "\n" msgstr "" -"Haluatko aktivoida nämä verkkoasetukset?\n" +"Haluatko varmasti aktivoida tämän verkkomäärityksen?\n" "\n" msgid "" @@ -3180,7 +3180,7 @@ msgid "Channel" msgstr "Kanava" msgid "Channel EPG" -msgstr "KanavaEPG" +msgstr "Kanava-ohjelmaopas" msgid "Channel List" msgstr "Kanavalista" @@ -3638,14 +3638,14 @@ msgstr "Määrittää kuinka monta minuuttia päättyneiden ohjelmien ohjelmatie msgid "Configure how recording filenames are constructed." msgstr "Määritä tallenteiden tiedostonimien rakenne." -msgid "Configure if and how crypto icons will be shown in the channel selection list." -msgstr "Määrittää näytetäänkö/miten näytetään salauksen kuvakkeet kanavalistassa." +msgid "Configure if and how crypto icons will be shown in the channel selection list (left alignment only available in single line mode)." +msgstr "Määrittää näytetäänkö/miten näytetään salauksen kuvakkeet kanavalistassa (tasaus vasemmalle käytössä vain yksirivisessä tilassa)." -msgid "Configure if and how service type icons will be shown." -msgstr "Määritä näytetäänkö/miten näytetään kanavatyypin kuvakkeet." +msgid "Configure if and how service type icons will be shown (left alignment only available in single line mode)." +msgstr "Määritä näytetäänkö/miten näytetään kanavatyypin kuvakkeet (tasaus vasemmalle käytössä vain yksirivisessä tilassa)." -msgid "Configure if and how the record indicator will be shown in the channel selection list." -msgstr "Määrittää kuinka tallennuksen indikaattori näytetään kanavalistassa." +msgid "Configure if and how the record indicator will be shown in the channel selection list (left alignment only available in single line mode)." +msgstr "Määrittää kuinka tallennuksen indikaattori näytetään kanavalistassa (tasaus vasemmalle käytössä vain yksirivisessä tilassa)." msgid "Configure if and how wide the service name column will be shown in the channel selection list." msgstr "Määrittää kuinka leveänä kanavanimet näytetään kanavalistassa." @@ -4633,7 +4633,7 @@ msgid "Delete Confirmation" msgstr "Poistamisen vahvistuskysely" msgid "Delete EPG Cache" -msgstr "Poista EPG" +msgstr "Poista ohjelmaopas" msgid "Delete Language(s)" msgstr "Poista kieli" @@ -6533,7 +6533,7 @@ msgid "Grey" msgstr "Harmaa" msgid "Grid EPG" -msgstr "Graafinen taulukko-ohjelmaopas" +msgstr "Taulukko-ohjelmaopas" msgid "Grow drop" msgstr "Kasvava pudotus" @@ -7088,7 +7088,7 @@ msgid "Image Slot:\t%s" msgstr "Image-paikka:\t%s" msgid "Image View On" -msgstr "Jakonäkymä" +msgstr "Kuvanäkymä päälle" msgid "Image manager" msgstr "Imagen hallinnointi" @@ -7201,13 +7201,13 @@ msgid "Infobar EPG" msgstr "Tietopalkki-ohjelmaopas" msgid "Infobar EPG activation" -msgstr "Hakupalkin aktivointi" +msgstr "Tietopalkki-ohjelmaopppan aktivointi" msgid "Infobar Grid EPG" -msgstr "Tietopalkin taulukko-EPG" +msgstr "Tietopalkin taulukko-ohjelmaopas" msgid "Infobar Single EPG" -msgstr "Tietopalkin yksittäinen EPG" +msgstr "Tietopalkin yksittäinen ohjelmaopas" msgid "Infobar fade-out speed" msgstr "Tietopalkin häivytysnopeus" @@ -7677,7 +7677,7 @@ msgstr "Myöhäis" msgctxt "third event: 'third' event label" msgid "Later" -msgstr "Myöhemmin" +msgstr "MYÖHEMMIN" msgid "Latitude" msgstr "Leveysaste" @@ -7700,8 +7700,8 @@ msgstr "Libanon" msgid "Left" msgstr "Vasen" -msgid "Left from servicename" -msgstr "Kanavanimestä vasemmalle" +msgid "Left from servicename (only available in single line mode)" +msgstr "Kanavanimestä vasemmalle (käytössä vain yksirivisessä tilassa)" msgid "Left long" msgstr "Pitkä vasemmalle" @@ -7821,7 +7821,7 @@ msgid "Load" msgstr "Lataa" msgid "Load EPG Cache" -msgstr "Lataa EPG" +msgstr "Lataa ohjelmaopas" msgid "Load playlist" msgstr "Lataa soittolista" @@ -7830,7 +7830,7 @@ msgid "Load unlinked userbouquets" msgstr "Näytä piilotetut suosikkilistat" msgid "Load, Save & Delete EPG Cache" -msgstr "Lataa, Tallenna ja Poista EPG" +msgstr "Lataa, Tallenna ja Poista ohjelmaopas" msgid "Loading skin" msgstr "Ladataan teemaa" @@ -8170,7 +8170,7 @@ msgid "Minimum age %d years" msgstr "Minimi-ikä %d vuotta" msgid "Minimum send interval" -msgstr "Minimi lähestysjakso" +msgstr "Minimi lähetysväli" msgid "Minority Sports" msgstr "Vähemmistöurheilu" @@ -8523,9 +8523,6 @@ msgstr "Ei saatavilla" msgid "n/a" msgstr "Ei saatavilla" -msgid "NEXT" -msgstr "SEURAAVA" - msgid "NFS" msgstr "NFS" @@ -8734,9 +8731,12 @@ msgstr "Uutiset/Ajankohtaisasiat/Sosiaalinen" msgid "Next" msgstr "Seuraava" +msgid "NEXT" +msgstr "SEURAAVA" + msgctxt "now/next: 'next' event label" msgid "Next" -msgstr "Seuraava" +msgstr "SEURAAVA" msgid "Nicaragua" msgstr "Nicaragua" @@ -9012,7 +9012,7 @@ msgstr "Ei mitään, sulje valikko" msgctxt "now/next: 'now' event label" msgid "Now" -msgstr "Nyt" +msgstr "NYT" msgid "Now, use the contrast setting to turn up the brightness of the background as much as possible, but make sure that you can still see the difference between the two brightest levels of shades.If you have done that, press OK." msgstr "Säädä kontrastisäädöllä tausta mahdollisimman valkoiseksi. Varmista, että näet yhä kahden kirkkaimman sävyn eron. Kun olet tyytyväinen tulokseen, paina OK." @@ -9171,7 +9171,7 @@ msgid "Open bouquet list" msgstr "Avaa suosikkilistat" msgid "Open infobar EPG" -msgstr "Avaa tietopalkin EPG" +msgstr "Avaa tietopalkin ohjelmaopas" msgid "Open menu" msgstr "Avaa valikko" @@ -9462,8 +9462,8 @@ msgstr "Prosenttia" msgid "Percentage left" msgstr "Prosentit vasemmalla" -msgid "Percentage right" -msgstr "Prosentit oikealla" +msgid "Percentage right (only available in single line mode)" +msgstr "Prosentit oikealla (käytössä vain yksirivisessä tilassa)" msgid "Perform a complete image backup before updating." msgstr "Suorita täydellinen image-varmuuskopiointi ennen päivitystä." @@ -9631,6 +9631,9 @@ msgstr "Valitse CCcam-lukija" msgid "Please choose an extension" msgstr "Valitse laajennus" +msgid "Please choose an extension..." +msgstr "Valitse laajennus..." + msgid "Choose reader" msgstr "Valitse lukija" @@ -10219,8 +10222,8 @@ msgstr "Etenemispalkki" msgid "Progress bar left" msgstr "Etenemispalkki vasemmalla" -msgid "Progress bar right" -msgstr "Etenemispalkki oikealla" +msgid "Progress bar right (only available in single line mode)" +msgstr "Etenemispalkki oikealla (käytössä vain yksirivisessä tilassa)" msgid "Prominent" msgstr "Kuuluisa" @@ -10247,7 +10250,7 @@ msgid "Protect movie list" msgstr "Suojaa tallennusvalikko" msgid "Protect on epg age" -msgstr "Suojaa epg" +msgstr "Suojaa ohjelmaopas" msgid "Protect plugin browser" msgstr "Suojaa lisäosavalikko" @@ -10514,7 +10517,7 @@ msgid "Record time limited due to conflicting timer %s" msgstr "Ajastusaika rajoitettu, ristiriita ajastukseen %s" msgid "Recording" -msgstr "Tallenne" +msgstr "Tallennus" msgid "Recording & Playback" msgstr "Tallennus ja toisto" @@ -11213,7 +11216,7 @@ msgid "Save / Enter text and exit" msgstr "Tallenna ja poistu" msgid "Save EPG Cache" -msgstr "Tallenna EPG" +msgstr "Tallenna ohjelmaopas" msgid "Save all changed settings and exit" msgstr "Tallenna ja poistu" @@ -12101,8 +12104,8 @@ msgstr "Kellonaika, jolloin ajastuksen pitää käynnistyä." msgid "Set the time the timer must stop." msgstr "Kellonaika, jolloin ajastuksen pitää pysähtyä." -msgid "Set the type of the progress indication in the channel selection screen." -msgstr "Määritä ohjelman pituuden osoittamisen tyyppi kanavien valintalistassa." +msgid "Set the type of the progress indication in the channel selection screen (right alignment only available in single line mode)." +msgstr "Määritä ohjelman pituuden osoittamisen tyyppi kanavien valintalistassa (tasaus oikealle käytössä vain yksirivisessä tilassa)." msgid "Set to the desired primetime." msgstr "Asetettu parhaaseen katseluaikaan." @@ -12237,7 +12240,7 @@ msgid "Show Ecm info" msgstr "Näytä ECM-tiedot" msgid "Show Grid EPG" -msgstr "Näytä taulukko-EPG" +msgstr "Näytä taulukko-ohjelmaopas" msgid "Show Log" msgstr "Näytä loki" @@ -12252,7 +12255,7 @@ msgid "Show MiniTV in the Front Display" msgstr "Näytä MiniTV etupaneelin näytössä" msgid "Show Multi EPG" -msgstr "Näytä Multi EPG" +msgstr "Näytä monikanavaohjelmaopas" msgid "Show OScam/Ncam Info in extensions?" msgstr "Näytä OScam/Ncam Info laajennusvalikossa?" @@ -12276,7 +12279,7 @@ msgid "Show SD as" msgstr "Näytä SD näin:" msgid "Show Single EPG" -msgstr "Näytä yksittäinen EPG" +msgstr "Näytä yksittäinen ohjelmaopas" msgid "Show Software Update in Extensions" msgstr "Näytä ohjelmapäivitys laajennuksissa" @@ -12405,7 +12408,7 @@ msgid "Show info line" msgstr "Näytä tietopalkki" msgid "Show infobar EPG" -msgstr "Tietopalkin EPG" +msgstr "Näytä tietopalkki-ohjelmaopas" msgid "Show infobar on channel change" msgstr "Näytä tietopalkki kanavaa vaihdettaessa" @@ -12510,7 +12513,7 @@ msgid "Show shutdown menu" msgstr "Näytä sammutusvalikko" msgid "Show single channel EPG" -msgstr "Näytä yhden kanavan EPG" +msgstr "Näytä yhden kanavan ohjelmaopas" msgid "Show single epg for current channel" msgstr "Näytä nykyisen kanavan ohjelmatiedot" @@ -12554,8 +12557,8 @@ msgstr "Näytä lisäosien selain" msgid "Show the radio player" msgstr "Näytä radiosoitin" -msgid "Show the service information on two lines in the channel selection screen. You can choose between the current event description below the channel name, or the current event description next to the channel name, and the next event description on the second line." -msgstr "Näytä kanavan tiedot kahdella rivillä kanavan valintanäytöllä. Voit valita nykyisen ohjelmatiedon kanavan nimen alle tai nykyisen ohjelmatiedon kanavan nimen viereen ja seuraavan ohjelmatiedon toiselle riville." +msgid "Show the service information on two lines in the channel selection screen." +msgstr "Näytä kanavan tiedot kahdella rivillä kanavanvalintanäytössä." msgid "Show the tv player" msgstr "Näytä tv" @@ -12870,7 +12873,7 @@ msgstr "Softcam-asetukset" msgid "SoftcamCheck" msgstr "SoftCam:in tarkistus" -msgid "SoftcamManager" +msgid "Softcam Management" msgstr "Softcam hallinta" msgid "SoftcamScript enable/disable cam restart" @@ -13258,16 +13261,16 @@ msgid "Stored position" msgstr "Sijainnin muistipaikka" msgid "Stream" -msgstr "Stream" +msgstr "Streami" msgid "Stream request" -msgstr "Streamin pyynti" +msgstr "Streamin pyyntö" msgid "Stream-tv" -msgstr "Stream" +msgstr "Streami-tv" msgid "Streaming" -msgstr "Stream" +msgstr "Streamaa" msgid "Streaming Clients" msgstr "Etäasiakkaat" @@ -13434,16 +13437,16 @@ msgid "Switch the PiP to the previous channel" msgstr "Vaihda PiP edelliselle kanavalle" msgid "Switch to Grid EPG" -msgstr "Vaihda taulukko-EPG:n" +msgstr "Vaihda taulukko-ohjelmaoppaaseen" msgid "Switch to HDMI in mode" msgstr "Vaihda HDMI In -tilaan" msgid "Switch to Multi EPG" -msgstr "Vaihda graafiseen EPG:n" +msgstr "Vaihda monikanavaohjelmaoppaaseen" msgid "Switch to Single EPG" -msgstr "Vaihda yksittäiseen-EPG:n" +msgstr "Vaihda yksittäiseen ohjelmaoppaaseen" msgid "Switch to TV mode" msgstr "Vaihda TV-tilaan" @@ -13540,7 +13543,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"20.10.2023\n" +"18.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -13653,7 +13656,7 @@ msgid "Text" msgstr "Teksti" msgid "Text Grid EPG" -msgstr "Teksti taulukko-ohjelmaopas" +msgstr "Tekstillinen taulukko-ohjelmaopas" msgid "Text View On" msgstr "Tekstinäkymä päällä" @@ -17394,8 +17397,11 @@ msgstr "tosi" msgid "two lines" msgstr "kaksi riviä" -msgid "two lines and next event" -msgstr "kaksi riviä ja seuraava ohjelma" +msgid "two lines+next event" +msgstr "kaksi riviä + seuraava ohjelma" + +msgid "two lines alternative" +msgstr "kahden rivin vaihtoehto" msgid "type" msgstr "DVB tyyppi" @@ -18331,7 +18337,7 @@ msgid "Checking softcams..." msgstr "Tarkistetaan softcameja..." msgid "Choose IPK folder" -msgstr "Valitse IPK kansio" +msgstr "Valitse IPK-kansio" msgid "Choose files" msgstr "Valitse tiedostot" @@ -18850,6 +18856,9 @@ msgstr "Koko: %sTt" msgid "Size: unavailable" msgstr "Koko: ei saatavilla" +msgid "Softcam Manager" +msgstr "Softcam:n hallinnointi" + msgid "Softcam manager" msgstr "Softcam:n hallinnointi" @@ -19093,14 +19102,75 @@ msgstr "Toista kanava striimin välityksellä" msgid "Stream relay" msgstr "Striimin välitys" -msgid "Streamrelay url" +msgid "Stream Relay url" msgstr "Striimin välitys -url" -msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" -msgstr "Striimin välitys -palvelimen IP-osoite, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" +msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via stream relay." +msgstr "Striimin välitys -palvelimen IP-osoite, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta." -msgid "Streamrelay port" +msgid "Stream Relay port" msgstr "Striimin välitys -portti" -msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" -msgstr "Striimin välitys -palvelimen portti, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" +msgid "Stream Relay delay" +msgstr "Striimin välityksen viive" + +msgid "Delay when closing a stream relay service before reallocating the tuner for another service. Using '0' is only recommended for boxes with multiple satellite tuners." +msgstr "Viive striimin välitys -palvelun sulkemisessa ennen virittimen uudelleenallokointia toista palvelua varten. 0:n käyttöä suositellaan vain bokseille, joissa on useita satelliittivirittimiä." + +msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via stream relay." +msgstr "Striimin välitys -palvelimen portti, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta." + +msgid "Enter adapter settings or disable adapter, then Save to action changed setup." +msgstr "Syötä sovittimen asetukset tai poista sovitin käytöstä ja sitten Tallenna toimintoon muutettu asetus." + +msgid "" +"Are you sure you want to disable this network configuration?\n" +"\n" +msgstr "" +"Haluatko varmasti poistaa tämän verkkomäärityksen käytöstä?\n" +"\n" + +msgid "Please wait while your network configuration is deactivated..." +msgstr "Odota, verkkoasetuksia poistetaan käytöstä..." + +msgid "Your network configuration has been disabled." +msgstr "Verkkoasetukset on poistettu käytöstä." + +msgid "Reception" +msgstr "Vastaanotto" + +msgid "Transmission" +msgstr "Lähetys" + +msgid "Enable blinking" +msgstr "Ota vilkkuminen käyttöön" + +msgid "Enable blinking for ui elements. For example for recording icon" +msgstr "Ota vilkkuminen käyttöön käyttöliittymäelementeissä. Esimerkiksi tallennuskuvakkeelle" + +msgid "Stream Relay Settings" +msgstr "Striimin välitysasetukset" + +msgid "Play service with Stream Relay" +msgstr "Toista kanava striimin välityksellä" + +msgid "Stream Relay Setup Actions" +msgstr "Striimin välitysasetustoiminnot" + +msgid "Play service without Stream Relay" +msgstr "Toista kanava ilman striimin välitystä" + +msgid "Record icon match" +msgstr "Tallennuskuvakkeen vastine" + +msgid "Select display of record icon based on 'Sref only' or 'Sref + Stream url' where applicable." +msgstr "Valitse tallennuskuvakkeen näyttö 'vain Sref' tai 'Sref + striimin url' perusteella, jos mahdollista." + +msgid "Sref only" +msgstr "Vain Sref" + +msgid "Sref + stream url" +msgstr "Sref + striimin url" + +msgid "Playback" +msgstr "Toisto" diff --git a/po/nl.po b/po/nl.po index 0569c5685f0..accbfb69fbb 100644 --- a/po/nl.po +++ b/po/nl.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: ViX\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-21 00:52+0000\n" -"PO-Revision-Date: 2023-09-21 12:39+0200\n" +"POT-Creation-Date: 2023-12-14 12:09+0000\n" +"PO-Revision-Date: 2023-12-15 11:16+0100\n" "Last-Translator: Rob van der Does \n" "Language-Team: Andy Blackburn, Rob van der Does\n" "Language: nl\n" @@ -13,7 +13,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-SourceCharset: iso-8859-15\n" -"X-Generator: Poedit 3.3.2\n" +"X-Generator: Poedit 3.4.1\n" #, python-format msgid "" @@ -30,35 +30,6 @@ msgstr "" "\n" "(verzoek tot afsluiten veranderd naar stand-by omdat er een stream-klant actief is.)" -msgid "" -"\n" -"Advanced options and settings." -msgstr "" -"\n" -"Geavanceerde opties en instellingen." - -msgid "" -"\n" -"After pressing OK, please wait!" -msgstr "" -"\n" -"Druk op OK en een ogenblik geduld!" - -#, python-format -msgid "" -"\n" -"Backup your %s %s settings." -msgstr "" -"\n" -"Maak een back-up van de instellingen van uw %s %s." - -msgid "" -"\n" -"Edit the upgrade source address." -msgstr "" -"\n" -"Wijzig het bronadres voor upgrades ." - msgid "" "\n" "It contains other items." @@ -66,14 +37,6 @@ msgstr "" "\n" "Het bevat andere items." -#, python-format -msgid "" -"\n" -"Manage extensions or plugins for your %s %s" -msgstr "" -"\n" -"Beheer extensies en plugins voor uw %s %s" - msgid "" "\n" "One is a directory that isn't empty." @@ -87,21 +50,6 @@ msgstr[1] "" "\n" "Er zijn mappen die niet leeg zijn." -#, python-format -msgid "" -"\n" -"Online update of your %s %s software." -msgstr "" -"\n" -"Online bijwerken van uw %s %s software." - -msgid "" -"\n" -"Press OK on your remote control to continue." -msgstr "" -"\n" -"Druk op OK om door te gaan." - msgid "" "\n" "Recording in progress." @@ -109,45 +57,6 @@ msgstr "" "\n" "Opname is bezig." -#, python-format -msgid "" -"\n" -"Restore your %s %s settings." -msgstr "" -"\n" -"De instellingen van uw %s %s terugplaatsen." - -#, python-format -msgid "" -"\n" -"Restore your %s %s with a new firmware." -msgstr "" -"\n" -"Plaats nieuwe firmware in uw %s %s." - -msgid "" -"\n" -"Restore your backups by date." -msgstr "" -"\n" -"Zet de back-up van een bepaalde datum terug." - -msgid "" -"\n" -"Scan for local extensions and install them." -msgstr "" -"\n" -"Zoek naar lokale extensies en installeer die." - -msgid "" -"\n" -"Select your backup device.\n" -"Current device: " -msgstr "" -"\n" -"Kies een back-up medium.\n" -"Huidig medium: " - #, python-format msgid "" "\n" @@ -156,13 +65,6 @@ msgstr "" "\n" "Timer '%s' uitgeschakeld!" -msgid "" -"\n" -"View, install and remove available or installed packages." -msgstr "" -"\n" -"Bekijk, installeer en verwijder beschikbare of geïnstalleerde pakketten." - msgid " " msgstr " " @@ -1078,10 +980,6 @@ msgstr "%s %s ir muis" msgid "%s %s remote control (native)" msgstr "%s %s afstandsbediening" -#, python-format -msgid "%s %s software because updates are available." -msgstr "%s %s software want er zijn updates beschikbaar." - #, python-format msgid "%s ( %s Cards )" msgstr "%s ( %s kaarten )" @@ -1187,7 +1085,7 @@ msgid "" msgstr "" "'Opslaan' verandert de actieve taal.\n" "'Voeg taal toe' of 'MENU' voegt additionele taal toe.\n" -"'Verwijder taal' verwijdert alle talen behalve Engels en de actieve taal OF de geselecteerde taal." +"'Verwijder taal' verwijdert alle talen behalve Engels en de actieve taal OF de geselecteerde taal" msgid "(All readers)" msgstr "(Alle lezers)" @@ -1697,9 +1595,6 @@ msgstr "Een herhalende timer of eenmalig?" msgid "A required tool (%s) was not found." msgstr "Een benodigd hulpmiddel (%s) is niet gevonden." -msgid "A search for available updates is currently in progress." -msgstr "Bezig met zoeken naar updates." - msgid "" "A second configured interface has been found.\n" "\n" @@ -1725,9 +1620,6 @@ msgstr "" "Een slaaptimer wil uw %s %s uitschakelen.\n" "Doorgaan?" -msgid "A small overview of the available icon states and actions." -msgstr "Een klein overzicht van gebruikte icoon-statussen en acties." - msgid "" "A timer failed to record!\n" "Disable TV and try again?\n" @@ -2031,15 +1923,6 @@ msgstr "Geavanceerd" msgid "Advanced options" msgstr "Geavanceerde opties" -msgid "Advanced restore" -msgstr "Geavanceerd herstellen" - -msgid "Advanced software" -msgstr "Geavanceerde software" - -msgid "Advanced software plugin" -msgstr "Geavanceerde software plugin" - msgid "Advanced video enhancement setup" msgstr "Geavanceerde videoverbeteringsinstellingen" @@ -2241,9 +2124,6 @@ msgstr "Alternatieve radiomodus" msgid "Alternative services tuner priority" msgstr "Alternatieve tunerprioriteit" -msgid "Always ask" -msgstr "Altijd vragen" - msgid "Always hide infobar" msgstr "Informatiebalk altijd verbergen" @@ -2265,9 +2145,6 @@ msgstr "Amerikaanse sporten" msgid "An empty filename is illegal." msgstr "Een lege bestandsnaam is ongeldig." -msgid "An error occurred while downloading the packetlist. Please try again." -msgstr "Er is een fout opgetreden bij het downloaden van de pakketlijst. Probeer het nogmaals." - msgid "An unknown error occurred!" msgstr "Er is een onbekende fout opgetreden!" @@ -2337,13 +2214,6 @@ msgstr "" "Wilt u deze netwerkconfiguratie nu activeren?\n" "\n" -msgid "" -"Are you sure you want to delete\n" -"the following backup:\n" -msgstr "" -"Weet u zeker dat u de volgende\n" -"back-up wilt verwijderen:\n" - msgid "Are you sure you want to delete all the selected logs:\n" msgstr "Weet u zeker dat u alle geselecteerde logs wilt verwijderen:\n" @@ -2363,6 +2233,13 @@ msgstr "" "Weet u zeker dat u dit wilt verwijderen:\n" " " +msgid "" +"Are you sure you want to disable this network configuration?\n" +"\n" +msgstr "" +"Wilt u deze netwerkconfiguratie nu uitschakelen?\n" +"\n" + msgid "" "Are you sure you want to download this image:\n" " " @@ -2402,25 +2279,6 @@ msgstr "" "Weet u zeker dat u de netwerk interface wilt herstarten?\n" "\n" -#, python-format -msgid "" -"Are you sure you want to restore\n" -"the following backup:\n" -"%s\n" -"Your receiver will restart after the backup has been restored!" -msgstr "" -"Weet u zeker dat u de volgende\n" -"back-up wilt flashen:\n" -"%s\n" -"Uw ontvanger zal herstarten nadat de back-up is teruggeplaatst!" - -msgid "" -"Are you sure you want to restore the backup?\n" -"Your receiver will restart after the backup has been restored!" -msgstr "" -"Weet u zeker dat u de back-up wilt flashen?\n" -"Uw ontvanger zal herstarten als het proces gereed is!" - msgid "" "Are you sure you want to restore this backup:\n" " " @@ -2543,9 +2401,6 @@ msgstr "Australisch" msgid "Austria" msgstr "Austria" -msgid "Author: " -msgstr "Auteur: " - msgid "Authoring mode" msgstr "Bewerkingswijze" @@ -2748,9 +2603,6 @@ msgstr "Back-up gereed." msgid "Backup complete..." msgstr "Back-up gereed." -msgid "Backup completed." -msgstr "Back-up gereed." - msgid "Backup confirmation" msgstr "Back-up bevestiging" @@ -2760,9 +2612,6 @@ msgstr "Back-up gemaakt" msgid "Backup failed - e. g. wrong backup destination or no space left on backup device." msgstr "Back-up mislukt - mogelijk a.g.v. verkeerde bestemming of te weinig ruimte op het back-up medium." -msgid "Backup failed." -msgstr "Back-up is mislukt." - msgid "" "Backup in progress,\n" "Please wait for it to finish, before trying again." @@ -2770,9 +2619,6 @@ msgstr "" "Back- up bezig.\n" "Wacht tot deze gereed is alvorens opnieuw te proberen." -msgid "Backup is running..." -msgstr "Back-up wordt uitgevoerd..." - msgid "Backup location" msgstr "Back-up locatie" @@ -2785,9 +2631,6 @@ msgstr "Back-up manager instellingen" msgid "Backup prefix" msgstr "Back-up voorvoegsel" -msgid "Backup system settings" -msgstr "Back-up uw instellingen" - msgid "Backup/Flash/ReBoot system image." msgstr "Backup/Flash/Reboot system image." @@ -3811,9 +3654,6 @@ msgstr "Common interface toewijzing" msgid "Common options" msgstr "Algemene instellingen" -msgid "Communication" -msgstr "Communicatie" - msgid "Comoros" msgstr "Comoros" @@ -4167,15 +4007,15 @@ msgstr "Verbinden" msgid "Connect to a wireless network" msgstr "Verbind met een draadloos netwerk" -msgid "Connected" -msgstr "Verbonden" - msgid "Connected clients" msgstr "Verbonden klanten" msgid "Connected satellites" msgstr "Verbonden satellieten" +msgid "Connected through another tuner" +msgstr "Verbonden door een andere tuner" + msgid "Connected to" msgstr "Verbonden met" @@ -4206,9 +4046,6 @@ msgstr "De inhoud past niet op een DVD!" msgid "Context" msgstr "Inhoud" -msgid "Continue" -msgstr "Doorgaan" - msgid "Continue playback" msgstr "Afspelen wordt hervat" @@ -4841,9 +4678,6 @@ msgstr "Default poort is '%d'. Pas aan indien gewenst." msgid "Default recording type" msgstr "Standaard opname type" -msgid "Default settings" -msgstr "Standaard instellingen" - #, python-format msgid "Default: '%s'." msgstr "Standaard: '%s'." @@ -4920,6 +4754,9 @@ msgstr "Vertraging in milliseconde voor het scrollen van tekst op het display be msgid "Delay time" msgstr "Vertragingstijd" +msgid "Delay when closing a stream relay service before reallocating the tuner for another service. Using '0' is only recommended for boxes with multiple satellite tuners." +msgstr "Vertraging na het sluiten van een streamrely-service voordat de tuner aan een andere service kan worden toegewezen. Het gebruik van \"0\" wordt alleen aanbevolen voor ontvangers met meerdere satelliettuners." + msgid "Delay:" msgstr "Vertraging:" @@ -5029,9 +4866,6 @@ msgstr "Beschrijving" msgid "Deselect" msgstr "Deselecteer" -msgid "Details for plugin: " -msgstr "Details voor plugin: " - msgid "Detect next boxes before standby" msgstr "Detecteert volgende apparaten alvorens naar stand-by te gaan" @@ -5135,24 +4969,24 @@ msgid "Directory %s does not exist." msgstr "Map %s bestaat niet." #, python-format -msgid "Directory '%s' does not exist!" -msgstr "Map '%s' bestaat niet!" +msgid "Directory '%s' does not exist." +msgstr "Map '%s' bestaat niet." #, python-format -msgid "Directory '%s' is not hard links capable!" -msgstr "In map '%s' kunnen geen harde links worden geschreven!" +msgid "Directory '%s' is not hard links capable." +msgstr "In map '%s' kunnen geen harde links worden geschreven." #, python-format -msgid "Directory '%s' not valid. Partition must be ext or nfs" -msgstr "Map '%s' is niet geldig. Partities moeten EXT of NFS geformatteerd zijn" +msgid "Directory '%s' not valid. Partition must be ext or nfs." +msgstr "Map '%s' is niet geldig. Partities moeten EXT of NFS geformatteerd zijn." #, python-format -msgid "Directory '%s' not writable!" -msgstr "In map '%s' kan niet worden geschreven!" +msgid "Directory '%s' not writable." +msgstr "In map '%s' kan niet worden geschreven." #, python-format -msgid "Directory '%s' not writeable!" -msgstr "In map '%s' kan niet worden geschreven!" +msgid "Directory '%s' not writeable." +msgstr "In map '%s' kan niet worden geschreven." msgid "Directory browser" msgstr "Bestandsverkenner" @@ -5211,9 +5045,6 @@ msgstr "Toon >16:9 materiaal als" msgid "Display Skin" msgstr "Display Skin" -msgid "Display and user interface" -msgstr "Scherm- en gebruikersinterface" - msgid "Display message before playing next movie" msgstr "Toon een bericht alvorens de volgende film te spelen" @@ -5367,9 +5198,6 @@ msgstr "" msgid "Do you want to install plugins" msgstr "Wilt u het plugins installeren" -msgid "Do you want to install the package:\n" -msgstr "Wilt u het volgende pakket installeren:\n" - msgid "Do you want to play DVD in drive?" msgstr "Wilt u de DVD in de speler afspelen?" @@ -5380,12 +5208,6 @@ msgstr "Wilt u de DVD bekijken alvorens te schrijven?" msgid "Do you want to reboot your %s %s" msgstr "Wilt u uw %s %s opnieuw opstarten?" -msgid "Do you want to reboot your receiver?" -msgstr "Wilt u uw ontvanger opnieuw opstarten?" - -msgid "Do you want to remove the package:\n" -msgstr "Wilt u het volgende pakket verwijderen:\n" - msgid "Do you want to restart GUI now ?" msgstr "Wilt u de gebruikersinterface nu opnieuw starten?" @@ -5408,9 +5230,6 @@ msgstr "Wilt u het afspelen vervolgen?" msgid "Do you want to update your %s %s?" msgstr "Wilt u uw %s %s updaten?" -msgid "Do you want to upgrade the package:\n" -msgstr "Wilt u een upgrade van het volgende pakket:\n" - msgid "Documentary" msgstr "Dcumentaire" @@ -5686,9 +5505,6 @@ msgstr "Bewerk de netwerkinstellingen van uw %s %s.\n" msgid "Edit title" msgstr "Wijzig titel" -msgid "Edit upgrade source url." -msgstr "Upgrade url bewerken." - msgid "Education" msgstr "Opleiding" @@ -5713,9 +5529,6 @@ msgstr "Verstreken" msgid "Elapsed & Remaining" msgstr "Verstreken en resterend" -msgid "Electronic Program Guide" -msgstr "Elektronische programmagids" - msgid "Empty slot" msgstr "Leeg slot" @@ -5783,6 +5596,12 @@ msgstr "Schakel automatisch downloaden van OpenTV EPG in. Als er slechts één t msgid "Enable automatic collections" msgstr "Automatische collecties inschakelen" +msgid "Enable blinking" +msgstr "Schakel knipperen in" + +msgid "Enable blinking for ui elements. For example for recording icon" +msgstr "Schakel knipperen in voor verschillende GUI-elementen. Bij voorbeeld voor de opname-icoon." + msgid "Enable blinking rec symbol on the LCD Display" msgstr "Schakel knipperend opnamesymbool in op het LCD-scherm" @@ -5937,6 +5756,9 @@ msgstr "Voer PIN in" msgid "Enter a number to jump to a service/channel" msgstr "Geef kanaalnummer in om naar te springen" +msgid "Enter adapter settings or disable adapter, then Save to action changed setup." +msgstr "Stel de adapter in of schakel deze uit en sla de wijziging op." + msgid "Enter if you are in the east or west hemisphere." msgstr "Geef aan of u op het westelijke of het oostelijke halfrond bent." @@ -6232,14 +6054,6 @@ msgstr "Uitgebreide instellingen..." msgid "Extended Shares" msgstr "Extended Shares" -# -msgid "Extended Software" -msgstr "Uitgebreide software" - -# -msgid "Extended Software Plugin" -msgstr "Uitgebreide software plugin" - msgid "Extended info" msgstr "Uitgebreide info" @@ -6252,8 +6066,8 @@ msgstr "Uitgebreide instellingen..." msgid "Extensions" msgstr "Extensies" -msgid "Extensions management" -msgstr "Applicatiebeheer" +msgid "Extensions menu" +msgstr "Extensie menu" msgid "Extensive search" msgstr "Uitgebreid zoeken" @@ -6615,9 +6429,6 @@ msgstr "Volk" msgid "Folkloric" msgstr "Folklore" -msgid "Following tasks will be done after you press OK!" -msgstr "Nadat u op OK drukt worden de volgende taken uitgevoerd!" - msgid "Font size" msgstr "Lettergrootte" @@ -7860,21 +7671,12 @@ msgstr "Installeer IPK's in uw tmp map." msgid "Install Plugins" msgstr "Installeer plugins" -msgid "Install a new image with a USB stick" -msgstr "Installeer een nieuwe image met een USB-stick" - -msgid "Install a new image with your web browser" -msgstr "Installeer een nieuwe image met uw browser" - msgid "Install channel list" msgstr "Installeer kanaallijst" msgid "Install confirmation" msgstr "Installeer bevestiging" -msgid "Install extensions" -msgstr "Installeer extensies" - msgid "Install extensions." msgstr "Installeer extensies." @@ -7884,15 +7686,9 @@ msgstr "Installeer LCD-Picons in" msgid "Install local extension" msgstr "Installeer lokale extensie" -msgid "Install or remove finished." -msgstr "Installeren of verwijderen voltooid." - msgid "Install picons on" msgstr "Installeer picons op" -msgid "Installation finished." -msgstr "Installatie mislukt." - #, python-format msgid "Installed:\t%s\n" msgstr "Geïnstalleerd:\t%s\n" @@ -8621,16 +8417,9 @@ msgstr "Mali" msgid "Malta" msgstr "Malta" -msgid "Manage extensions" -msgstr "Beheer van extensies" - msgid "Manage settings backup." msgstr "Beheer settings back-ups." -#, python-format -msgid "Manage your %s %s's software" -msgstr "Beheer de software van uw %s %s" - msgid "Manage your devices mount points." msgstr "Beheer hoe uw apparaten gemount zijn." @@ -9141,9 +8930,6 @@ msgstr "Multiboot FOUT! - geen STARTUP in bootpartitie." msgid "Multiboot only able to restore this backup to mmc slot1" msgstr "Multiboot kan deze back-up alleen maar herstellen van mmc slot1" -msgid "Multimedia" -msgstr "Multimedia" - msgid "Multiple service support" msgstr "Geschikt voor meervoudig decoderen" @@ -9464,9 +9250,6 @@ msgstr "Geen actief kanaal gevonden." msgid "No age block" msgstr "Geen leeftijdsblokkering" -msgid "No backup needed" -msgstr "Geen back-up nodig" - msgid "No card inserted!" msgstr "Geen kaart geplaatst!" @@ -9542,9 +9325,6 @@ msgstr "" msgid "No delay" msgstr "Geen vertraging" -msgid "No description available." -msgstr "Geen beschrijving beschikbaar." - msgid "No displayable files on this medium found!" msgstr "Geen weer te geven bestanden op dit medium gevonden!" @@ -9569,9 +9349,6 @@ msgstr "Geen images gevonden op de gekozen server... Controleer wachtwoord indie msgid "No module found" msgstr "Geen module gevonden" -msgid "No network connection available." -msgstr "Geen netwerkverbinding beschikbaar." - msgid "No networks found" msgstr "Geen netwerken gevonden" @@ -9651,15 +9428,6 @@ msgstr "" msgid "No, but restart from the beginning" msgstr "Nee, vanaf begin herstarten" -msgid "No, do nothing." -msgstr "Nee, geen actie." - -msgid "No, just start my %s %s" -msgstr "Nee, uitsluitend %s %s starten" - -msgid "No, never" -msgstr "Nee, nooit" - msgid "No, scan later manually" msgstr "Nee, later handmatig zoeken" @@ -9798,9 +9566,6 @@ msgstr "OK (lang) toets" msgid "OK button (short)" msgstr "OK (kort) toets" -msgid "OK, guide me through the upgrade process" -msgstr "OK, mij tijdens de software update begeleiden" - msgid "OK, to perform a restore" msgstr "JA, voer een herstelactie uit" @@ -9894,9 +9659,6 @@ msgstr "Uitsluitend actief in stand-by" msgid "Only change this setting if you are using a SCR device that has been reprogrammed with a custom programmer. For further information check with the person that reprogrammed the device." msgstr "Verander deze instelling alleen als u een SCR-apparaat gebruikt dat geprogrammeerd is met een aangepaste 'programmer'. Voor meer informatie overleg met degene die de aanpassing heeft gedaan." -msgid "Only extensions." -msgstr "Alleen extensies." - msgid "Only free scan" msgstr "Alleen ongecodeerde zenders scannen" @@ -10041,12 +9803,6 @@ msgstr "Output" msgid "Overwrite Recovery" msgstr "Overschrijf Recovery" -msgid "Overwrite configuration files during software upgrade?" -msgstr "Overschrijven configuratiebestanden tijdens de upgrade?" - -msgid "Overwrite configuration files?" -msgstr "Configuratiebestanden overschrijven?" - msgid "PAGE UP/DOWN" msgstr "PAGINA OP/NEER" @@ -10144,12 +9900,6 @@ msgstr "Pakketlijst vernieuwen" msgid "Packages" msgstr "Pakketten" -msgid "Packet management" -msgstr "Pakketbeheer" - -msgid "Packet manager" -msgstr "Pakketbeheer" - msgid "Page down" msgstr "Pagina naar beneden" @@ -10402,6 +10152,18 @@ msgstr "Speel vorige" msgid "Play recorded movies" msgstr "Speel opnames af" +msgid "Play service with Stream Relay" +msgstr "Speel service met streamrelay" + +msgid "Play service with streamrelay" +msgstr "Speel service met streamrelay" + +msgid "Play service without Stream Relay" +msgstr "Speel service zonder streamrelay" + +msgid "Play service without streamrelay" +msgstr "Speel service zonder streamrelay" + #, python-format msgid "Play the %d marked recordings" msgstr "Speel de %d geselecteerde opnames af" @@ -10412,6 +10174,9 @@ msgstr "Speel de gemarkeerde opname af" msgid "Play the selected recording" msgstr "Speel de geselecteerde opname af" +msgid "Playback" +msgstr "Afspelen" + msgid "" "Playback information missing\n" "Playback aborted to avoid crash\n" @@ -10437,6 +10202,9 @@ msgstr "Wijzig de eindtijd van de opname" msgid "Please choose an extension" msgstr "Kies een extensie" +msgid "Please choose an extension..." +msgstr "Kies een extensie..." + msgid "" "Please configure or verify your Nameservers by filling out the required values.\n" "When you are ready press OK to continue." @@ -10457,9 +10225,6 @@ msgstr "Verbind uw ontvanger met het internet" msgid "Please do not change any values unless you know what you are doing!" msgstr "Wijzig hier geen instellingen tenzij u precies weet wat u doet!" -msgid "Please enter a folder that contains some packages." -msgstr "Kies een folder die plugins bevat." - msgid "Please enter a name for the new bouquet" msgstr "Voer de naam voor uw nieuwe favorietenlijst in" @@ -10529,18 +10294,15 @@ msgstr "Selecteer een subkanaal voor opname..." msgid "Please select a subservice..." msgstr "Selecteer een subkanaal..." -msgid "Please select an acceptable directory." -msgstr "Kies een bruikbare map." - msgid "Please select device to use as SWAP file location." msgstr "Kies het medium voor het SWAP-bestand." +msgid "Please select folder that contains .ipk packages." +msgstr "Kies een folder die .ipk pakketen bevat." + msgid "Please select medium to be scanned" msgstr "Selecteer het te scannen medium" -msgid "Please select medium to use as backup location" -msgstr "Selecteer het te gebruiken medium als back-up lokatie" - msgid "Please select the default action of the EPG button" msgstr "Kies de standaard actie voor de EPG-toets" @@ -10696,6 +10458,9 @@ msgstr "Een ogenblikje geduld; uw netwerk wordt getest..." msgid "Please wait while your network configuration is activated..." msgstr "Een ogenblikje geduld; uw netwerk wordt opnieuw gestart..." +msgid "Please wait while your network configuration is deactivated..." +msgstr "Even tot uw netwerkconfiguratie uitgeschakeld is..." + #, python-format msgid "Please wait, initialising %s." msgstr "Even geduld, %s wordt geïnitialiseerd." @@ -10718,21 +10483,12 @@ msgstr "Pluginbrowser" msgid "Plugin browser settings" msgstr "Pluginbrowser instellingen" -msgid "Plugin details" -msgstr "Plugin details" - msgid "Plugin install" msgstr "Plugin installeren" msgid "Plugin listing failed - e. g. wrong backup destination or no space left on backup device." msgstr "Plugin-lijst mislukt - mogelijk a.g.v. een verkeerde back-up locatie of te weinig ruimte op het medium." -msgid "Plugin manager activity information" -msgstr "Pluginmanager activiteitinformatie" - -msgid "Plugin manager help" -msgstr "Pluginmanager helpfunctie" - msgid "Plugins" msgstr "Applicaties" @@ -10952,12 +10708,6 @@ msgstr "Druk op 'Menu' om een opslagruimte te kiezen" msgid "Press GREEN (Reboot) to switch images, YELLOW (Delete) to erase an image or BLUE (Restore) to restore all deleted images." msgstr "Druk op GROEN (Reboot) om van image te veranderen, op GEEL (Verwijder) om een image te verwijderen of op BLAUW (Herstel) om alle images te herstellen." -msgid "Press INFO on your remote control for additional information." -msgstr "Druk op INFO voor aanvullende informatie." - -msgid "Press MENU on your remote control for additional options." -msgstr "Druk op MENU voor extra opties." - msgid "Press OK" msgstr "Druk op OK" @@ -10968,9 +10718,6 @@ msgstr "Druk op de OK toets om door te gaan." msgid "Press OK to activate the selected%s skin." msgstr "Druk op OK om de geselecteerde%s skin te activeren." -msgid "Press OK to activate the settings." -msgstr "Druk op OK om instellingen te activeren." - msgid "Press OK to edit the settings." msgstr "Druk op OK om instellingen te wijzigen." @@ -11055,9 +10802,6 @@ msgstr "" "Probleem met verkrijgen updatelijst.\n" "Als dit probleem aanhoudt kunt u het forum raadplegen" -msgid "Process" -msgstr "Proces" - #, python-format msgid "Processor temp:\t%s" msgstr "Processortemp:\t%s" @@ -11388,6 +11132,9 @@ msgstr "Ontvanger of driver ondersteunt geen FCC" msgid "Record" msgstr "Opname" +msgid "Record icon match" +msgstr "Opname-icoon overeenkomst" + msgid "Record next" msgstr "Neem volgende op" @@ -11404,9 +11151,6 @@ msgstr "Opnametijd beperkt vanwege conflicterende timer %s" msgid "Recording" msgstr "Opname" -msgid "Recording & Playback" -msgstr "Opname & afspelen" - msgid "Recording 4097, 5001 and 5002 streams not possible with external players, so convert recordings to servicetype 1." msgstr "Opname van 4097, 5001 en 5002 streams is niet mogelijk met externe spelers; converteer deze naar servicetype 1." @@ -11417,9 +11161,6 @@ msgstr "" "Opname van IPTV met systeemapp is ingeschakeld, timer afgelopen!\n" "Controleer deze!" -msgid "Recording and playback" -msgstr "Opname en afspelen" - msgid "Recording and playback settings" msgstr "Opname-en afspeelinstellingen" @@ -11534,9 +11275,6 @@ msgstr "Relevante PIDs routering" msgid "Religion" msgstr "Religie" -msgid "Reload" -msgstr "Herlaad" - msgid "Reload blacklists" msgstr "Herlaad zwarte lijst" @@ -11654,9 +11392,6 @@ msgstr "Verwijder voltooide timers na X dagen" msgid "Remove finished timers after (days)" msgstr "Verwijder voltooide timers na X dagen" -msgid "Remove finished." -msgstr "Verwijderen voltooid." - msgid "Remove from parental protection" msgstr "Verwijder van kinderslot" @@ -11850,9 +11585,6 @@ msgstr "Flash" msgid "Restore Confirmation" msgstr "Bevestig herstellen" -msgid "Restore backups" -msgstr "Back-ups terugzetten" - msgid "Restore confirmation" msgstr "Herstel bevestiging" @@ -11865,9 +11597,6 @@ msgstr "Herstel standaard waardes" msgid "Restore deleted user bouquets" msgstr "Herstel verwijderde favorietenlijsten" -msgid "Restore system settings" -msgstr "Instellingen terugzetten" - msgid "Restore wizard" msgstr "Herstel-wizard" @@ -11880,9 +11609,6 @@ msgstr "Bezig plugins te installeren; dit kan lang duren..." msgid "Restoring plugins..." msgstr "Plaatst plugins terug..." -msgid "Restoring..." -msgstr "Bezig met terugzetten..." - msgid "Restricted 18+" msgstr "18+" @@ -12154,9 +11880,6 @@ msgstr "Satelliet" msgid "Satellite dish settings" msgstr "Schotelinstellingen" -msgid "Satellite equipment" -msgstr "Satelliet apparatuur" - msgid "Satellite equipment setup" msgstr "Apparatuurinstellingen" @@ -12400,13 +12123,6 @@ msgstr "Zoekt" msgid "Searching east ..." msgstr "Zoekt oost..." -# -msgid "Searching for available updates. Please wait..." -msgstr "Zoekt naar beschikbare updates. Even wachten..." - -msgid "Searching for new installed or removed packages. Please wait..." -msgstr "Zoeken naar nieuw geïnstalleerde of verwijderde pakketten. Even wachten..." - msgid "Searching west ..." msgstr "Zoekt west..." @@ -12608,12 +12324,6 @@ msgstr "Kies een image om te flashen." msgid "Select audio track" msgstr "Kies audiospoor" -msgid "Select backup files" -msgstr "Kies back-up bestanden" - -msgid "Select backup location" -msgstr "Kies een back-up lokatie" - msgid "Select channel from history" msgstr "Kies het kanaal uit geschiedenis" @@ -12638,20 +12348,20 @@ msgstr "Kies de standaard actie voor de INFO-toets" msgid "Select destination for:" msgstr "Selecteer bestemming voor:" +msgid "Select display of record icon based on 'Sref only' or 'Sref + Stream url' where applicable." +msgstr "Kies tussen tonen van opname-icoon op basis van 'alleen Sref' of 'Sref + stream url'." + msgid "Select extra packages folder" msgstr "Kies de folder met extra plugins" -msgid "Select files for backup." -msgstr "Selecteer bestanden voor back-up." - msgid "Select files/folders to backup" msgstr "Kies bestanden/mappen voor de back-up" msgid "Select first service in bouquet" msgstr "Selecteer eerste kanaal in boeket" -msgid "Select folder that contains plugins" -msgstr "Kies de folder met plugins" +msgid "Select folder containing plugins(.ipk) and Save" +msgstr "Kies de folder met plugins (.ipk) en sla op" msgid "Select horizontal resolution:" msgstr "Selecteer horizontale resolutie:" @@ -12815,12 +12525,6 @@ msgstr "Configureer type afstandsbediening" msgid "Select to restore all deleted images" msgstr "Kies alle verwijderde images te herstellen" -msgid "Select upgrade source" -msgstr "Kies de upgrade-bron" - -msgid "Select upgrade source to edit." -msgstr "Kies de te wijzigen upgrade-bron." - msgid "Select video input with up/down buttons" msgstr "Selecteer video-ingang met de omhoog/omlaag toetsen" @@ -13627,8 +13331,8 @@ msgstr "Toon de pluginbrowser" msgid "Show the radio player" msgstr "Radioweergave modus" -msgid "Show the service information on two lines in the channel selection screen. You can choose between the current event description below the channel name, or the current event description next to the channel name, and the next event description on the second line." -msgstr "Toon de kanaalinformatie in twee regels in het kanaalselectiescherm. U kunt kiezen tussen de huidige programmabeschrijving onder de kanaalnaam of de huidige programmabeschrijving naast de kanaalnaam en het volgende programma de tweede regel." +msgid "Show the service information on two lines in the channel selection screen." +msgstr "Toon de kanaalinformatie op twee regels in de kanaallijst." msgid "Show the tv player" msgstr "TV-weergave modus" @@ -13808,9 +13512,6 @@ msgstr "Skin:\t%s" msgid "SkinSelector: Restart GUI" msgstr "SkinSelector: Herstart GUI" -msgid "Skins" -msgstr "Skins" - msgid "Skip back" msgstr "Achteruit springen" @@ -13952,6 +13653,12 @@ msgstr "Samenleving & cultuur" msgid "Softcam Actions" msgstr "Softcam acties" +msgid "Softcam Management" +msgstr "Softcambeheer" + +msgid "Softcam Manager" +msgstr "Softcammanager" + msgid "Softcam Script" msgstr "Softcam script" @@ -13973,40 +13680,21 @@ msgstr "Softcam stopt..." msgid "SoftcamCheck" msgstr "Softcamcontrole" -msgid "SoftcamManager" -msgstr "Softcammanager" - msgid "SoftcamScript enable/disable cam restart" msgstr "SoftcamScript schakelt cam-herstart in/uit" msgid "SoftcamScript select camscript" msgstr "SoftcamScript kies cam script" -msgid "Software" -msgstr "Software" - msgid "Software Update" msgstr "Software-update" -# -msgid "Software management" -msgstr "Softwarebeheer" - -msgid "Software manager setup" -msgstr "Softwarebeheer instellingen" - -msgid "Software restore" -msgstr "Software herstellen" - msgid "Software update" msgstr "Software-update" msgid "Software update settings" msgstr "Software-update instellingen" -msgid "Softwaremanager information" -msgstr "Sofwarebeheer informatie" - msgid "Solomon Islands" msgstr "Solomon Islands" @@ -14052,22 +13740,12 @@ msgstr "MiniDLNA configuratie ontbreekt" msgid "Sorry your uShare config is missing" msgstr "Configuratie van uShare ontbreekt" -#, python-format -msgid "Sorry, %s has not been installed!" -msgstr "Sorry, %s is niet geïnstalleerd!" - msgid "Sorry, but the file is not compatible with this image version." msgstr "Het bestand is niet verenigbaar met deze versie van de firmware." msgid "Sorry, but the restore failed." msgstr "Het terugplaatsen is mislukt." -msgid "Sorry, no backups found!" -msgstr "Sorry, geen back-up gevonden!" - -msgid "Sorry, no details available!" -msgstr "Sorry, geen details beschikbaar!" - msgid "Sorry, no physical devices that supports SWAP attached. Can't create SWAP file on network or fat32 file-systems." msgstr "Er is geen medium dat SWAP-bestanden ondersteunt. Een SWAP-bestand kan niet op een netwerk of een FAT32 systeem worden geplaatst." @@ -14077,13 +13755,6 @@ msgstr "Er is niet genoeg vrij RAM en er is geen medium dat SWAP-bestanden onder msgid "Sorry, this tuner is in use." msgstr "Deze tuner is niet beschikbaar." -msgid "" -"Sorry, your backup destination is not writeable.\n" -"Please select a different one." -msgstr "" -"Uw back-up bestemming kan niet beschreven worden.\n" -"Kies een andere." - msgid "Sort" msgstr "Sorteer" @@ -14198,6 +13869,12 @@ msgstr "sportmagazine" msgid "Sprache" msgstr "Taal" +msgid "Sref + stream url" +msgstr "Sref + stream url" + +msgid "Sref only" +msgstr "Alleen Sref" + msgid "Sri Lanka" msgstr "Sri Lanka" @@ -14394,6 +14071,21 @@ msgstr "Opgeslagen positie" msgid "Stream" msgstr "Stream" +msgid "Stream Relay Settings" +msgstr "Streamrelay instellingen" + +msgid "Stream Relay Setup Actions" +msgstr "Streamrelay instellingen" + +msgid "Stream Relay delay" +msgstr "Streamrelay vertraging" + +msgid "Stream Relay port" +msgstr "Streamrelay poort" + +msgid "Stream Relay url" +msgstr "Streamrelay url" + msgid "Stream request" msgstr "Stream-verzoek" @@ -14872,6 +14564,9 @@ msgstr "" "De IMDb-plugin is niet geïnstalleerd!\n" "Installeer die." +msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via stream relay." +msgstr "Het IP-adres van de streamrelay-server die wordt gebruikt om te services te descramblen waarbij dat alleen via een streamrelay kan." + msgid "" "The Linux kernel has changed, an update is not permitted. \n" "Install latest image using USB stick or Image Manager." @@ -14905,9 +14600,6 @@ msgstr "" msgid "The backup creates a snapshot of the image exactly as it is at the current instant." msgstr "De back-up maakt een exact snapshot van het image zoals het op dit moment is." -msgid "The backup failed. Please choose a different backup location." -msgstr "Back-up is mislukt. Kies een andere back-up lokatie." - msgid "The backup location does not have enough free space." msgstr "De back-up locatie heeft onvoldoende ruimte." @@ -14976,6 +14668,9 @@ msgstr "Het pad %s bestaat al." msgid "The pin code you entered is wrong." msgstr "De ingevoerde pincode is onjuist." +msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via stream relay." +msgstr "De poort van de streamrelay-server die wordt gebruikt om te services te descramblen waarbij dat alleen via een streamrelay kan." + #, python-format msgid "The results have been written to %s." msgstr "De resultaten zijn bewaard op %s." @@ -15016,9 +14711,6 @@ msgid "" "Please install it." msgstr "De WiFi-plugin is niet geïnstalleerd. Deze plugin eerst installeren." -msgid "The wizard can backup your current settings. Do you want to do a backup now?" -msgstr "De wizard kan uw huidige settings opslaan. Wilt u nu een back-up maken?" - msgid "The wizard is finished now, and will reboot." msgstr "De wizard is nu gereed; de stb zal herstarten." @@ -15028,25 +14720,12 @@ msgstr "De wizard is nu gereed." msgid "Theater" msgstr "Theater" -msgid "There are at least " -msgstr "Er zijn ten minste " - -#, python-format -msgid "There are at least %s updates available." -msgstr "Er zijn minstens %s updates beschikbaar." - -msgid "There are currently no outstanding actions." -msgstr "Er zijn geen uitstaande acties." - msgid "There are no saved playlists to delete!" msgstr "Er zijn geen playlists om te verwijderen!" msgid "There are no saved playlists to load!" msgstr "Er zijn geen playlists om te laden!" -msgid "There are no updates available." -msgstr "Er zijn momenteel geen updates beschikbaar." - msgid "There has been an error, please try again later. If this issue persists, please check openvix.co.uk or world-of-satellite.com" msgstr "Er is een fout opgetreden. Als het probleem aanhoudt, controleert u op openvix.co.uk of op world-of-satellite.com wat er aan de hand is" @@ -15293,18 +14972,6 @@ msgstr "Hiermee stelt u de onderdrukking in van valse digitale contouren, die he msgid "This option sets up the picture sharpness, used when the picture is being upscaled." msgstr "Hiermee stelt u de beeldscherpte in als het beeld moet worden opgeschaald." -msgid "This plugin is installed." -msgstr "Deze plugin is geïnstalleerd." - -msgid "This plugin is not installed." -msgstr "Deze plugin is niet geïnstalleerd." - -msgid "This plugin will be installed." -msgstr "Deze plugin wordt geïnstalleerd." - -msgid "This plugin will be removed." -msgstr "Deze plugin wordt verwijderd." - msgid "This setting allows the tuner configuration to be a duplication of how another tuner is already configured." msgstr "Deze instelling maakt het mogelijk de instelling van een andere tuner te kopieren." @@ -15687,9 +15354,6 @@ msgstr "Probeert gebruikte transponders op het kabelnetwerk te vinden. Even wach msgid "Try to find used transponders in terrestrial network... please wait..." msgstr "Probeert gebruikte transponders op het terrestrische netwerk te vinden. Even wachten..." -msgid "Trying to download a new packetlist. Please wait..." -msgstr "Probeert een nieuwe pakketlijst te downloaden. Even wachten..." - msgid "Tue" msgstr "Di" @@ -15860,13 +15524,6 @@ msgstr "Niet gedefinieerd" msgid "Undetermined" msgstr "Onbepaald" -msgid "Undo install" -msgstr "Installatie ongedaan maken" - -# -msgid "Undo uninstall" -msgstr "Ongedaan" - msgid "Unencrypted" msgstr "Niet-encrypted" @@ -15882,10 +15539,6 @@ msgstr "Unicable-vertraging na aanpassen voltage vóór de schakelopdracht" msgid "Unicable delay after last diseqc command" msgstr "Unicable-vertraging na laatste DiSEqC opdracht" -# -msgid "Uninstall" -msgstr "De-installeer" - msgid "United Arab Emirates" msgstr "United Arab Emirates" @@ -15971,25 +15624,15 @@ msgstr "Bezig met update pakketten..." msgid "Updated: %s" msgstr "Geüpdatet: %s" -# -msgid "Updatefeed not available." -msgstr "Updatefeed niet beschikbaar." - msgid "Updating Cache" msgstr "Bezig cache te updaten" -msgid "Updating cache" -msgstr "Bezig cache te updaten" - msgid "Updating cache, please wait..." msgstr "Bezig cache te updaten, even wachten..." msgid "Updating mount locations..." msgstr "Mount-locaties worden geüpdatet..." -msgid "Updating software catalog" -msgstr "Softwarecatalogus wordt geupdate" - msgid "Upgrade and reboot system" msgstr "Upgrade en herstart system" @@ -16178,9 +15821,6 @@ msgstr "Start de wizard voor basisinstellingen" msgid "Use these input device settings?" msgstr "Deze instellingen gebruiken?" -msgid "Use these settings?" -msgstr "Deze settings gebruiken?" - msgid "Use this video enhancement settings?" msgstr "Gebruik deze videoverbetering instellingen?" @@ -16418,52 +16058,9 @@ msgstr "Bekijk opname..." msgid "View Video CD..." msgstr "Bekijk video CD..." -msgid "View details" -msgstr "Bekijk details" - msgid "View extensions" msgstr "Toon extensies" -msgid "View list of available " -msgstr "Bekijk de lijst met beschikbare " - -msgid "View list of available CommonInterface extensions" -msgstr "Bekijk de lijst met beschikbare commonInterface extensies" - -msgid "View list of available EPG extensions." -msgstr "Bekijk de lijst met beschikbare EPG-extensies." - -# -msgid "View list of available Satellite equipment extensions." -msgstr "Bekijk de lijst met beschikbare satellietapparatuur extensies." - -msgid "View list of available communication extensions." -msgstr "Bekijk de lijst met beschikbare communicatie extensies." - -msgid "View list of available default settings" -msgstr "Bekijk de lijst met beschikbare standaardinstellingen" - -msgid "View list of available display and userinterface extensions." -msgstr "Bekijk de lijst met beschikbare scherm en gebruikersinterface extensies." - -msgid "View list of available multimedia extensions." -msgstr "Bekijk de lijst van beschikbare multimedia extensies." - -msgid "View list of available networking extensions" -msgstr "Bekijk de lijst met beschikbare netwerk extensies" - -msgid "View list of available recording extensions" -msgstr "Bekijk de lijst met beschikbare opname extensies" - -msgid "View list of available skins" -msgstr "Bekijk de lijst met beschikbare skins" - -msgid "View list of available software extensions" -msgstr "Bekijk de lijst met beschikbare software extensies" - -msgid "View list of available system extensions" -msgstr "Bekijk de lijst met beschikbare systeem extensies" - msgid "View mode" msgstr "Bekijkmodus" @@ -16733,9 +16330,6 @@ msgstr "" "\n" "Ga naar het einde, druk op OK, selecteer 'end cut'. Eenvoudiger kan niet." -msgid "Welcome to the image upgrade wizard. The wizard will assist you in upgrading the firmware of your %s %s by providing a backup facility for your current settings and a short explanation of how to upgrade your firmware." -msgstr "Welkom bij de software-updatewizard. De wizard biedt u hulp bij het vernieuwen van de software in uw %s %s door het maken van een back-up van uw huidige instellingen en geeft u een korte uitleg over dit proces." - msgid "" "Welcome to the restore wizard.\n" "\n" @@ -16989,9 +16583,6 @@ msgstr "Als de ontvanger uit stand-by komt, zal ook de TV aangezet worden." msgid "When tuned to a service the system will normally scan the transponder for any changes and save them. Only set to 'yes' if you're absolutely sure of what you're doing." msgstr "Als uw ontvanger op een kanaal is afgestemd, wordt normaal gesproken de transponder gescand op veranderingen. Schakel dit alleen uit, als u zeker bent van wat u doet." -msgid "Where do you want to backup your settings?" -msgstr "Waar wilt u de instellingen opslaan?" - msgid "Where should the recording be saved?" msgstr "Waar moet de opname opgeslagen worden?" @@ -17142,18 +16733,12 @@ msgstr "Ja (sla index op in tuner instellingen)" msgid "Yes to all" msgstr "Ja op alles" -msgid "Yes, always" -msgstr "Ja, altijd" - msgid "Yes, and delete this movie" msgstr "Ja en verwijder dit bestand" msgid "Yes, and return to the movie list" msgstr "Ja, en keer terug naar de opnamelijst" -msgid "Yes, backup my settings!" -msgstr "Ja, mijn instellingen opslaan!" - msgid "Yes, but don't save timeshift as movie" msgstr "Ja, maar sla timeshift niet op als opname" @@ -17175,18 +16760,12 @@ msgstr "Ja, voer nu de automatische zoekfunctie uit" msgid "Yes, do another manual scan now" msgstr "Ja, ik wil nogmaals handmatig zoeken" -msgid "Yes, restore the settings now" -msgstr "Ja, de gegevens nu terugplaatsen" - msgid "Yes, show delete time" msgstr "Ja, toon verwijdertijd" msgid "Yes, show record time" msgstr "Ja, toon opnametijd" -msgid "Yes, shut down now." -msgstr "Ja, ik wil nu afsluiten." - msgid "Yesterday" msgstr "Gisteren" @@ -17214,29 +16793,17 @@ msgstr "U kunt MiniTV met en zonder OSD-menu tonen" msgid "You can Display PIP with or without OSD Menu" msgstr "U kubt PIP met en zonder OSD-menu tonen" -msgid "You can cancel the installation." -msgstr "Installatie kan worden geannuleerd." - -msgid "You can cancel the removal." -msgstr "Verwijderen kan worden geannuleerd." - msgid "You can continue watching TV while this is running." msgstr "U kunt doorgaan met TV kijken terwijl dit loopt." msgid "You can have the list sorted by time or alphanumerical." msgstr "U kunt de lijst op tijd of alfanumeriek sorteren." -msgid "You can install this plugin." -msgstr "Deze plugin kunt u installeren." - # #, python-format msgid "You can only burn %s %s recordings!" msgstr "U kunt alleen %s %s opnames schrijven!" -msgid "You can remove this plugin." -msgstr "Deze plugin kunt u verwijderen." - msgid "You cannot delete this!" msgstr "U kunt dit niet verwijderen!" @@ -17248,12 +16815,6 @@ msgid_plural "You have marked recordings" msgstr[0] "U heeft een gemarkeerde opname" msgstr[1] "U heeft gemarkeerde opnames" -msgid "You have chosen to backup your settings. Please press OK to start the backup now." -msgstr "U heeft gekozen een back-up van uw instellingen te maken. Druk op OK om te beginnen." - -msgid "You have chosen to restore your settings. Enigma2 will restart after restore. Please press OK to start the restore now." -msgstr "U heeft gekozen om uw instellingen te herstellen. Enigma2 zal herstarten na het herstel. Druk op OK om te beginnen met het herstel." - msgid "" "You have chosen to save the current timeshift event, but the event has not yet finished\n" "What do you want to do ?" @@ -17275,13 +16836,6 @@ msgstr "Wacht op %s!" msgid "You must switch to the service %s (%s - '%s')!\n" msgstr "U moet naar kanaal %s (%s - '%s') zappen!\n" -msgid "" -"You need a PC connected to your %s %s. If you need further instructions, please visit the website http://www.dm7025.de.\n" -"Your %s %s will now be halted. After you have performed the update instructions from the website, your new firmware will ask you to restore your settings." -msgstr "" -"U moet uw PC met uw %s %s verbinden. Voor meer informatie verwijzen wij u naar de website http://www.dm7025.de.\n" -"De %s %s word nu uitgeschakeld. Indien u deze aanwijzingen nauwgezet volgt, zal de %s %s u na de update vragen of u uw instellingen terug wilt plaatsen." - msgid "You seem to be in timeshft, the service will briefly stop as timeshift stops." msgstr "U bent in timeshift modus; het kanaal wordt even onderbroken als u timeshift stopt." @@ -17378,9 +16932,6 @@ msgstr "Uw %s %s wordt opnieuw gestart in herstelmodus" msgid "Your %s %s is shutting down" msgstr "Uw %s %s is aan het afsluiten" -msgid "Your %s %s is shutting down. Please wait..." -msgstr "Uw %s %s wordt nu afgesloten. Even wachten..." - #, python-format msgid "Your %s %s might be unusable now. Please consult the manual for further assistance before rebooting your %s %s." msgstr "Uw %s %s kan nu onbruikbaar zijn geworden. Raadpleeg voordat u uw %s %s herstart de handleiding." @@ -17422,9 +16973,6 @@ msgstr "" msgid "Your STB will restart after pressing OK on your remote control." msgstr "Als u op OK drukt zal uw ontvanger opnieuw opstarten." -msgid "Your backup succeeded. We will now continue to explain the further upgrade process." -msgstr "De back-up is geslaagd. U krijgt nu een korte uitleg over het vervolg van het updateproces." - msgid "Your collection exceeds the size of a single layer medium, you will need a blank dual layer DVD!" msgstr "Uw verzameling is groter dan wat erop een enkellaags medium past, u heeft een lege dubbellaags DVD nodig!" @@ -17480,6 +17028,9 @@ msgstr "" msgid "Your network configuration has been activated." msgstr "Configuratie van uw netwerk is geactiveerd." +msgid "Your network configuration has been disabled." +msgstr "Configuratie van uw netwerk is uitgeschakeld." + msgid "Your network has finished restarting" msgstr "Uw netwerk is opnieuw gestart" @@ -17985,9 +17536,6 @@ msgstr "ontspanning (6-14 jaar)" msgid "entertainment (general)" msgstr "ontspanning (algemeenr)" -msgid "epg cache backup" -msgstr "epg cache back-up" - msgid "equestrian" msgstr "ruitersport" @@ -18024,9 +17572,6 @@ msgstr "DVD-speler afsluiten of terug naar bestandslijst" msgid "experimental film/video" msgstr "experimentele film/video" -msgid "extensions." -msgstr "extensies." - msgid "extra wide" msgstr "extra breed" @@ -18096,9 +17641,6 @@ msgstr "vrij" msgid "free diskspace" msgstr "vrije ruimte" -msgid "from" -msgstr "van" - msgid "full" msgstr "vol" @@ -18465,9 +18007,6 @@ msgstr "origineel" msgid "original language" msgstr "originele taal" -msgid "packages selected." -msgstr "pakketten geselecteerd." - msgid "page left" msgstr "pagina links" @@ -18672,12 +18211,6 @@ msgstr "EPG details weergeven" msgid "show mediaplayer on mainmenu" msgstr "toon mediaplayer in hoofdmenu" -msgid "show softwaremanager in plugin menu" -msgstr "toon softwaremanager in pluginbrowser" - -msgid "show softwaremanager on blue button" -msgstr "toon softwaremanager onder blauwe knop" - msgid "show/game show (general)" msgstr "show/spelshow (algemeen)" @@ -18756,9 +18289,6 @@ msgstr "stand-by " msgid "start cut here" msgstr "start knippen hier" -msgid "start directory" -msgstr "startmap" - msgid "stepsize" msgstr "stapgrootte" @@ -18828,9 +18358,6 @@ msgstr "waar" msgid "two lines" msgstr "twee regels" -msgid "two lines and next event" -msgstr "twee regels en volgende programma" - msgid "type" msgstr "type" @@ -18873,9 +18400,6 @@ msgstr "niet gepubliceerd" msgid "until standby/restart" msgstr "tot stand-by/herstart" -msgid "updates available." -msgstr "updates beschikbaar." - msgid "use best / controlled by HDMI" msgstr "use best / controlled by HDMI" @@ -19000,6 +18524,104 @@ msgstr "zapte" msgid "| separated list of prefixes you'd like to be removed from event names, separated with |, e.g. New:|Live:" msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, gescheiden door |, e.g. New:|Live:" +#~ msgid "" +#~ "\n" +#~ "Advanced options and settings." +#~ msgstr "" +#~ "\n" +#~ "Geavanceerde opties en instellingen." + +#~ msgid "" +#~ "\n" +#~ "After pressing OK, please wait!" +#~ msgstr "" +#~ "\n" +#~ "Druk op OK en een ogenblik geduld!" + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Backup your %s %s settings." +#~ msgstr "" +#~ "\n" +#~ "Maak een back-up van de instellingen van uw %s %s." + +#~ msgid "" +#~ "\n" +#~ "Edit the upgrade source address." +#~ msgstr "" +#~ "\n" +#~ "Wijzig het bronadres voor upgrades ." + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Manage extensions or plugins for your %s %s" +#~ msgstr "" +#~ "\n" +#~ "Beheer extensies en plugins voor uw %s %s" + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Online update of your %s %s software." +#~ msgstr "" +#~ "\n" +#~ "Online bijwerken van uw %s %s software." + +#~ msgid "" +#~ "\n" +#~ "Press OK on your remote control to continue." +#~ msgstr "" +#~ "\n" +#~ "Druk op OK om door te gaan." + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Restore your %s %s settings." +#~ msgstr "" +#~ "\n" +#~ "De instellingen van uw %s %s terugplaatsen." + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Restore your %s %s with a new firmware." +#~ msgstr "" +#~ "\n" +#~ "Plaats nieuwe firmware in uw %s %s." + +#~ msgid "" +#~ "\n" +#~ "Restore your backups by date." +#~ msgstr "" +#~ "\n" +#~ "Zet de back-up van een bepaalde datum terug." + +#~ msgid "" +#~ "\n" +#~ "Scan for local extensions and install them." +#~ msgstr "" +#~ "\n" +#~ "Zoek naar lokale extensies en installeer die." + +#~ msgid "" +#~ "\n" +#~ "Select your backup device.\n" +#~ "Current device: " +#~ msgstr "" +#~ "\n" +#~ "Kies een back-up medium.\n" +#~ "Huidig medium: " + +#~ msgid "" +#~ "\n" +#~ "View, install and remove available or installed packages." +#~ msgstr "" +#~ "\n" +#~ "Bekijk, installeer en verwijder beschikbare of geïnstalleerde pakketten." + #, python-format #~ msgid "%.0f GB" #~ msgstr "%.0f GB" @@ -19028,6 +18650,10 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "%d.%03d GB" #~ msgstr "%d.%03d GB" +#, python-format +#~ msgid "%s %s software because updates are available." +#~ msgstr "%s %s software want er zijn updates beschikbaar." + #, python-format #~ msgid "%s GB" #~ msgstr "%s GB" @@ -19062,6 +18688,12 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "50 MB/s" #~ msgstr "50 MB/s" +#~ msgid "A search for available updates is currently in progress." +#~ msgstr "Bezig met zoeken naar updates." + +#~ msgid "A small overview of the available icon states and actions." +#~ msgstr "Een klein overzicht van gebruikte icoon-statussen en acties." + #~ msgid "AboutBoxInfo" #~ msgstr "About BoxInfo" @@ -19074,25 +18706,81 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Activate network adapter configuration" #~ msgstr "Start de netwerkadapter configuratie" +#~ msgid "Advanced restore" +#~ msgstr "Geavanceerd herstellen" + +#~ msgid "Advanced software" +#~ msgstr "Geavanceerde software" + +#~ msgid "Advanced software plugin" +#~ msgstr "Geavanceerde software plugin" + #~ msgid "Allow unstable (experimental) feeds" #~ msgstr "Accepteer onstabiele (experimentele) feeds" #~ msgid "Allows you to tag your image backup to a box. (default is box name/type)" #~ msgstr "U kunt de naam van de image back-ups aanpassen (standaard is stb name/type)." +#~ msgid "Always ask" +#~ msgstr "Altijd vragen" + +#~ msgid "An error occurred while downloading the packetlist. Please try again." +#~ msgstr "Er is een fout opgetreden bij het downloaden van de pakketlijst. Probeer het nogmaals." + #~ msgid "Android Mode" #~ msgstr "Android mode" +#~ msgid "" +#~ "Are you sure you want to delete\n" +#~ "the following backup:\n" +#~ msgstr "" +#~ "Weet u zeker dat u de volgende\n" +#~ "back-up wilt verwijderen:\n" + #, python-format #~ msgid "Are you sure you want to delete image slot %s ?" #~ msgstr "Weet u zeker dat u het image in slot %s wilt verwijderen?" +#, python-format +#~ msgid "" +#~ "Are you sure you want to restore\n" +#~ "the following backup:\n" +#~ "%s\n" +#~ "Your receiver will restart after the backup has been restored!" +#~ msgstr "" +#~ "Weet u zeker dat u de volgende\n" +#~ "back-up wilt flashen:\n" +#~ "%s\n" +#~ "Uw ontvanger zal herstarten nadat de back-up is teruggeplaatst!" + +#~ msgid "" +#~ "Are you sure you want to restore the backup?\n" +#~ "Your receiver will restart after the backup has been restored!" +#~ msgstr "" +#~ "Weet u zeker dat u de back-up wilt flashen?\n" +#~ "Uw ontvanger zal herstarten als het proces gereed is!" + +#~ msgid "Author: " +#~ msgstr "Auteur: " + #~ msgid "Background delete option" #~ msgstr "Verwijder op de achtergrond" #~ msgid "Background delete speed" #~ msgstr "Snelheid verwijderen op de achtergrond" +#~ msgid "Backup completed." +#~ msgstr "Back-up gereed." + +#~ msgid "Backup failed." +#~ msgstr "Back-up is mislukt." + +#~ msgid "Backup is running..." +#~ msgstr "Back-up wordt uitgevoerd..." + +#~ msgid "Backup system settings" +#~ msgstr "Back-up uw instellingen" + #, python-format #~ msgid "Build: %s" #~ msgstr "Build: %s" @@ -19122,12 +18810,21 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Collection" #~ msgstr "Collectie" +#~ msgid "Communication" +#~ msgstr "Communicatie" + #~ msgid "Configure on which devices the background delete option should be used." #~ msgstr "Geef aan op welk apparaat op de achtergrond bestanden mogen worden verwijderd." #~ msgid "Configure the speed of the background deletion process. Lower speed will consume less hard disk drive performance." #~ msgstr "Bepaal de snelheid waarmee bestanden op de achtergrond worden verwijderd. Een lage snelheid vergt minder prestaties van de schijf." +#~ msgid "Connected" +#~ msgstr "Verbonden" + +#~ msgid "Continue" +#~ msgstr "Doorgaan" + #~ msgid "Current CEC address" #~ msgstr "Huidig CEC adres" @@ -19135,9 +18832,18 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "D" #~ msgstr "3D" +#~ msgid "Default settings" +#~ msgstr "Standaard instellingen" + +#~ msgid "Details for plugin: " +#~ msgstr "Details voor plugin: " + #~ msgid "Device: none available" #~ msgstr "Apparaat: geen beschikbaar" +#~ msgid "Display and user interface" +#~ msgstr "Scherm- en gebruikersinterface" + #~ msgid "" #~ "Do you want to flash Recovery image?\n" #~ "This will change all eMMC slots." @@ -19145,6 +18851,18 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ "Wilt u het Recovery Image flashen?\n" #~ "Dit zal alle eMMC slots veranderen." +#~ msgid "Do you want to install the package:\n" +#~ msgstr "Wilt u het volgende pakket installeren:\n" + +#~ msgid "Do you want to reboot your receiver?" +#~ msgstr "Wilt u uw ontvanger opnieuw opstarten?" + +#~ msgid "Do you want to remove the package:\n" +#~ msgstr "Wilt u het volgende pakket verwijderen:\n" + +#~ msgid "Do you want to upgrade the package:\n" +#~ msgstr "Wilt u een upgrade van het volgende pakket:\n" + #~ msgid "DownLoad" #~ msgstr "DownLoad" @@ -19154,6 +18872,12 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "ERROR" #~ msgstr "FOUT" +#~ msgid "Edit upgrade source url." +#~ msgstr "Upgrade url bewerken." + +#~ msgid "Electronic Program Guide" +#~ msgstr "Elektronische programmagids" + #~ msgid "Enable Vu+ MultiBoot" #~ msgstr "Vu+ MultiBoot inschakelen" @@ -19179,6 +18903,17 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Exit network adapter configuration" #~ msgstr "Verlaat netwerkadapterconfiguratie" +# +#~ msgid "Extended Software" +#~ msgstr "Uitgebreide software" + +# +#~ msgid "Extended Software Plugin" +#~ msgstr "Uitgebreide software plugin" + +#~ msgid "Extensions management" +#~ msgstr "Applicatiebeheer" + #, fuzzy #~ msgid "F" #~ msgstr "F1" @@ -19191,6 +18926,9 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Flash directory '%s' not allowed!" #~ msgstr "Flash-map'%s' is niet toegestaan!" +#~ msgid "Following tasks will be done after you press OK!" +#~ msgstr "Nadat u op OK drukt worden de volgende taken uitgevoerd!" + #, fuzzy #~ msgid "G" #~ msgstr "GB" @@ -19246,6 +18984,21 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Init Vu+ MultiBoot" #~ msgstr "Init Vu+ MultiBoot" +#~ msgid "Install a new image with a USB stick" +#~ msgstr "Installeer een nieuwe image met een USB-stick" + +#~ msgid "Install a new image with your web browser" +#~ msgstr "Installeer een nieuwe image met uw browser" + +#~ msgid "Install extensions" +#~ msgstr "Installeer extensies" + +#~ msgid "Install or remove finished." +#~ msgstr "Installeren of verwijderen voltooid." + +#~ msgid "Installation finished." +#~ msgstr "Installatie mislukt." + #~ msgid "Instant recording..." #~ msgstr "Directe opname..." @@ -19256,33 +19009,94 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Last update: %s" #~ msgstr "Laatste update: %s" +#~ msgid "Manage extensions" +#~ msgstr "Beheer van extensies" + +#, python-format +#~ msgid "Manage your %s %s's software" +#~ msgstr "Beheer de software van uw %s %s" + #~ msgid "Max backups to keep (0==all)" #~ msgstr "Max aantal back-ups te bewaren (0==alle)" #~ msgid "Multiboot image manager" #~ msgstr "Multiboot image manager" +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + #~ msgid "Namespace" #~ msgstr "Namespace" +#~ msgid "No backup needed" +#~ msgstr "Geen back-up nodig" + #~ msgid "No data received yet" #~ msgstr "Nog geen data ontvangen" +#~ msgid "No description available." +#~ msgstr "Geen beschrijving beschikbaar." + +#~ msgid "No network connection available." +#~ msgstr "Geen netwerkverbinding beschikbaar." + +#~ msgid "No, do nothing." +#~ msgstr "Nee, geen actie." + +#~ msgid "No, just start my %s %s" +#~ msgstr "Nee, uitsluitend %s %s starten" + +#~ msgid "No, never" +#~ msgstr "Nee, nooit" + #~ msgid "Note: slot list does not show current image or empty slots." #~ msgstr "Opm.: De slot-lijst toont het huidige image en lege slots niet." +#~ msgid "OK, guide me through the upgrade process" +#~ msgstr "OK, mij tijdens de software update begeleiden" + +#~ msgid "Only extensions." +#~ msgstr "Alleen extensies." + #~ msgid "Open infobar EPG..." #~ msgstr "Open Informatiebalk EPG..." #~ msgid "OpenTV download setup" #~ msgstr "OpenTV download instellingen" +#~ msgid "Overwrite configuration files during software upgrade?" +#~ msgstr "Overschrijven configuratiebestanden tijdens de upgrade?" + +#~ msgid "Overwrite configuration files?" +#~ msgstr "Configuratiebestanden overschrijven?" + #~ msgid "PID" #~ msgstr "PID" +#~ msgid "Packet management" +#~ msgstr "Pakketbeheer" + +#~ msgid "Packet manager" +#~ msgstr "Pakketbeheer" + #~ msgid "Perform a settings backup, making a backup before updating is strongly advised." #~ msgstr "Maak een settingsback-up; het maken van een back-up alvorens te updaten wordt sterk geadviseerd." +#~ msgid "Please select a valid directory." +#~ msgstr "Kies een geldige map." + +#~ msgid "Please select medium to use as backup location" +#~ msgstr "Selecteer het te gebruiken medium als back-up lokatie" + +#~ msgid "Plugin details" +#~ msgstr "Plugin details" + +#~ msgid "Plugin manager activity information" +#~ msgstr "Pluginmanager activiteitinformatie" + +#~ msgid "Plugin manager help" +#~ msgstr "Pluginmanager helpfunctie" + #~ msgid "Polarisation:" #~ msgstr "Polarisatie:" @@ -19299,15 +19113,36 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ "tenzij u eMMC-slots wilt herstellen .\n" #~ "Herstellen van eMMC slots kan 1 -> 5 minutes per slot duren." +#~ msgid "Press INFO on your remote control for additional information." +#~ msgstr "Druk op INFO voor aanvullende informatie." + +#~ msgid "Press MENU on your remote control for additional options." +#~ msgstr "Druk op MENU voor extra opties." + +#~ msgid "Press OK to activate the settings." +#~ msgstr "Druk op OK om instellingen te activeren." + #~ msgid "Press OK to set the MAC address." #~ msgstr "Druk op OK om MAC-adres in te stellen." +#~ msgid "Process" +#~ msgstr "Proces" + #~ msgid "Query before backup starts" #~ msgstr "Vraag alvorens back-up te starten" #~ msgid "Query before image backup starts" #~ msgstr "Vraag alvorens image back-up te starten" +#~ msgid "Recording & Playback" +#~ msgstr "Opname & afspelen" + +#~ msgid "Recording and playback" +#~ msgstr "Opname en afspelen" + +#~ msgid "Reload" +#~ msgstr "Herlaad" + #, python-format #~ msgid "Removal of this slot will not show in %s Gui. Are you sure you want to delete image slot %s ?" #~ msgstr "Het verwijderen van dit slot zal niet zichtbaar zijn in de GUI van de %s. Weet u zeker dat u het image in slot %s wilt verwijderen?" @@ -19315,24 +19150,61 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Remove confirmation" #~ msgstr "Verwijder bevestiging" +#~ msgid "Remove finished." +#~ msgstr "Verwijderen voltooid." + +#~ msgid "Restore backups" +#~ msgstr "Back-ups terugzetten" + +#~ msgid "Restore system settings" +#~ msgstr "Instellingen terugzetten" + +#~ msgid "Restoring..." +#~ msgstr "Bezig met terugzetten..." + #~ msgid "SWAP place:" #~ msgstr "SWAP lokatie:" +#~ msgid "Satellite equipment" +#~ msgstr "Satelliet apparatuur" + #~ msgid "Scroll menu" #~ msgstr "Menu scrollen" +# +#~ msgid "Searching for available updates. Please wait..." +#~ msgstr "Zoekt naar beschikbare updates. Even wachten..." + +#~ msgid "Searching for new installed or removed packages. Please wait..." +#~ msgstr "Zoeken naar nieuw geïnstalleerde of verwijderde pakketten. Even wachten..." + #~ msgid "Select 'no' to flash a MultiBoot slot." #~ msgstr "Kies 'Nee' om een MultiBoot slot te flashen." #~ msgid "Select an image to flash:" #~ msgstr "Kies een image om te flashen:" +#~ msgid "Select backup files" +#~ msgstr "Kies back-up bestanden" + +#~ msgid "Select backup location" +#~ msgstr "Kies een back-up lokatie" + #~ msgid "Select between entering an IP address or a domain." #~ msgstr "Kies tussen ingave van IP-adres of domein." #~ msgid "Select directory for logfile" #~ msgstr "Kies map voor logbestand" +#~ msgid "Select files for backup." +#~ msgstr "Selecteer bestanden voor back-up." + +#~ msgid "Select upgrade source" +#~ msgstr "Kies de upgrade-bron" + +#~ msgid "Select upgrade source to edit." +#~ msgstr "Kies de te wijzigen upgrade-bron." + #~ msgid "Serv.Name" #~ msgstr "Serv.Naam" @@ -19352,9 +19224,48 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Show /tmp/ecm.info" #~ msgstr "Toon /tmp/ecm.info" +#~ msgid "Show the service information on two lines in the channel selection screen. You can choose between the current event description below the channel name, or the current event description next to the channel name, and the next event description on the second line." +#~ msgstr "Toon de kanaalinformatie in twee regels in het kanaalselectiescherm. U kunt kiezen tussen de huidige programmabeschrijving onder de kanaalnaam of de huidige programmabeschrijving naast de kanaalnaam en het volgende programma de tweede regel." + #~ msgid "Skin Setup" #~ msgstr "Skin instellingen" +#~ msgid "Skins" +#~ msgstr "Skins" + +#~ msgid "Software" +#~ msgstr "Software" + +# +#~ msgid "Software management" +#~ msgstr "Softwarebeheer" + +#~ msgid "Software manager setup" +#~ msgstr "Softwarebeheer instellingen" + +#~ msgid "Software restore" +#~ msgstr "Software herstellen" + +#~ msgid "Softwaremanager information" +#~ msgstr "Sofwarebeheer informatie" + +#, python-format +#~ msgid "Sorry, %s has not been installed!" +#~ msgstr "Sorry, %s is niet geïnstalleerd!" + +#~ msgid "Sorry, no backups found!" +#~ msgstr "Sorry, geen back-up gevonden!" + +#~ msgid "Sorry, no details available!" +#~ msgstr "Sorry, geen details beschikbaar!" + +#~ msgid "" +#~ "Sorry, your backup destination is not writeable.\n" +#~ "Please select a different one." +#~ msgstr "" +#~ "Uw back-up bestemming kan niet beschreven worden.\n" +#~ "Kies een andere." + #~ msgid "Subtitle selection..." #~ msgstr "Ondertitel-selectie..." @@ -19374,6 +19285,9 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "TB" #~ msgstr "TB" +#~ msgid "The backup failed. Please choose a different backup location." +#~ msgstr "Back-up is mislukt. Kies een andere back-up lokatie." + #~ msgid "" #~ "The software management extension is not installed!\n" #~ "Please install it." @@ -19387,12 +19301,40 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "The timer file (timers.xml) is corrupt and could not be loaded." #~ msgstr "Het timer-bestand (timer.xml) is beschadigd en kan niet worden geladen." +#~ msgid "The wizard can backup your current settings. Do you want to do a backup now?" +#~ msgstr "De wizard kan uw huidige settings opslaan. Wilt u nu een back-up maken?" + +#~ msgid "There are at least " +#~ msgstr "Er zijn ten minste " + +#, python-format +#~ msgid "There are at least %s updates available." +#~ msgstr "Er zijn minstens %s updates beschikbaar." + +#~ msgid "There are currently no outstanding actions." +#~ msgstr "Er zijn geen uitstaande acties." + #~ msgid "There are no items currently available for this screen." #~ msgstr "Er zijn momenteel geen onderdelen beschikbaar voor dit scherm." +#~ msgid "There are no updates available." +#~ msgstr "Er zijn momenteel geen updates beschikbaar." + #~ msgid "This option allows you to disable sorting of the menus" #~ msgstr "Hier kunt u het sorteren van menu's inschakelen" +#~ msgid "This plugin is installed." +#~ msgstr "Deze plugin is geïnstalleerd." + +#~ msgid "This plugin is not installed." +#~ msgstr "Deze plugin is niet geïnstalleerd." + +#~ msgid "This plugin will be installed." +#~ msgstr "Deze plugin wordt geïnstalleerd." + +#~ msgid "This plugin will be removed." +#~ msgstr "Deze plugin wordt verwijderd." + #~ msgid "Time of backup to start" #~ msgstr "Tijd waarop back-up moet starten" @@ -19402,6 +19344,9 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Transponder Information" #~ msgstr "Transponderinformatie" +#~ msgid "Trying to download a new packetlist. Please wait..." +#~ msgstr "Probeert een nieuwe pakketlijst te downloaden. Even wachten..." + # #~ msgid "Tuning Info: Live Values" #~ msgstr "Tunerinfo: terugmeldingen" @@ -19419,12 +19364,36 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ "\n" #~ "Weet u zeker dat u door wil gaan?" +#~ msgid "Undo install" +#~ msgstr "Installatie ongedaan maken" + +# +#~ msgid "Undo uninstall" +#~ msgstr "Ongedaan" + +# +#~ msgid "Uninstall" +#~ msgstr "De-installeer" + #~ msgid "Update Interval" #~ msgstr "Updateinterval" +# +#~ msgid "Updatefeed not available." +#~ msgstr "Updatefeed niet beschikbaar." + +#~ msgid "Updating cache" +#~ msgstr "Bezig cache te updaten" + +#~ msgid "Updating software catalog" +#~ msgstr "Softwarecatalogus wordt geupdate" + #~ msgid "Use the cursor keys to select an installed image and then Erase button." #~ msgstr "Gebruik de pijlthestoetsen om een geinstalleerd image te kiezen en vervolgens de 'wis-toets'." +#~ msgid "Use these settings?" +#~ msgstr "Deze settings gebruiken?" + #~ msgid "Using fixed address" #~ msgstr "Gebruik een vast adres" @@ -19432,6 +19401,49 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "ViX version: %s" #~ msgstr "ViX versie: %s" +#~ msgid "View details" +#~ msgstr "Bekijk details" + +#~ msgid "View list of available " +#~ msgstr "Bekijk de lijst met beschikbare " + +#~ msgid "View list of available CommonInterface extensions" +#~ msgstr "Bekijk de lijst met beschikbare commonInterface extensies" + +#~ msgid "View list of available EPG extensions." +#~ msgstr "Bekijk de lijst met beschikbare EPG-extensies." + +# +#~ msgid "View list of available Satellite equipment extensions." +#~ msgstr "Bekijk de lijst met beschikbare satellietapparatuur extensies." + +#~ msgid "View list of available communication extensions." +#~ msgstr "Bekijk de lijst met beschikbare communicatie extensies." + +#~ msgid "View list of available default settings" +#~ msgstr "Bekijk de lijst met beschikbare standaardinstellingen" + +#~ msgid "View list of available display and userinterface extensions." +#~ msgstr "Bekijk de lijst met beschikbare scherm en gebruikersinterface extensies." + +#~ msgid "View list of available multimedia extensions." +#~ msgstr "Bekijk de lijst van beschikbare multimedia extensies." + +#~ msgid "View list of available networking extensions" +#~ msgstr "Bekijk de lijst met beschikbare netwerk extensies" + +#~ msgid "View list of available recording extensions" +#~ msgstr "Bekijk de lijst met beschikbare opname extensies" + +#~ msgid "View list of available skins" +#~ msgstr "Bekijk de lijst met beschikbare skins" + +#~ msgid "View list of available software extensions" +#~ msgstr "Bekijk de lijst met beschikbare software extensies" + +#~ msgid "View list of available system extensions" +#~ msgstr "Bekijk de lijst met beschikbare systeem extensies" + #~ msgid "Visual impaired commentary" #~ msgstr "Audiodescriptie voor slechtzienden" @@ -19452,12 +19464,61 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Vu+ MultiBoot Manager" #~ msgstr "Vu+ MultiBoot Manager" +#~ msgid "Welcome to the image upgrade wizard. The wizard will assist you in upgrading the firmware of your %s %s by providing a backup facility for your current settings and a short explanation of how to upgrade your firmware." +#~ msgstr "Welkom bij de software-updatewizard. De wizard biedt u hulp bij het vernieuwen van de software in uw %s %s door het maken van een back-up van uw huidige instellingen en geeft u een korte uitleg over dit proces." + #~ msgid "When enabled the feeds and software updates may contain unstable experimental versions. Enable this at your own risk." #~ msgstr "Indien geactiveerd kunnen feeds en software updates die onstabiele, experimentele versies bevatten, gebruikt worden. Inschakelen geschiedt op uw eigen risico." +#~ msgid "Where do you want to backup your settings?" +#~ msgstr "Waar wilt u de instellingen opslaan?" + +#~ msgid "Yes, always" +#~ msgstr "Ja, altijd" + +#~ msgid "Yes, backup my settings!" +#~ msgstr "Ja, mijn instellingen opslaan!" + +#~ msgid "Yes, restore the settings now" +#~ msgstr "Ja, de gegevens nu terugplaatsen" + +#~ msgid "Yes, shut down now." +#~ msgstr "Ja, ik wil nu afsluiten." + +#~ msgid "You can cancel the installation." +#~ msgstr "Installatie kan worden geannuleerd." + +#~ msgid "You can cancel the removal." +#~ msgstr "Verwijderen kan worden geannuleerd." + +#~ msgid "You can install this plugin." +#~ msgstr "Deze plugin kunt u installeren." + +#~ msgid "You can remove this plugin." +#~ msgstr "Deze plugin kunt u verwijderen." + +#~ msgid "You have chosen to backup your settings. Please press OK to start the backup now." +#~ msgstr "U heeft gekozen een back-up van uw instellingen te maken. Druk op OK om te beginnen." + +#~ msgid "You have chosen to restore your settings. Enigma2 will restart after restore. Please press OK to start the restore now." +#~ msgstr "U heeft gekozen om uw instellingen te herstellen. Enigma2 zal herstarten na het herstel. Druk op OK om te beginnen met het herstel." + #~ msgid "You have decided not to flash image." #~ msgstr "U heeft besloten geen image te flashen." +#~ msgid "" +#~ "You need a PC connected to your %s %s. If you need further instructions, please visit the website http://www.dm7025.de.\n" +#~ "Your %s %s will now be halted. After you have performed the update instructions from the website, your new firmware will ask you to restore your settings." +#~ msgstr "" +#~ "U moet uw PC met uw %s %s verbinden. Voor meer informatie verwijzen wij u naar de website http://www.dm7025.de.\n" +#~ "De %s %s word nu uitgeschakeld. Indien u deze aanwijzingen nauwgezet volgt, zal de %s %s u na de update vragen of u uw instellingen terug wilt plaatsen." + +#~ msgid "Your %s %s is shutting down. Please wait..." +#~ msgstr "Uw %s %s wordt nu afgesloten. Even wachten..." + +#~ msgid "Your backup succeeded. We will now continue to explain the further upgrade process." +#~ msgstr "De back-up is geslaagd. U krijgt nu een korte uitleg over het vervolg van het updateproces." + #~ msgid "[VuplusKexec][create Vu Multiboot environment] - Unable to complete, Vu+ Multiboot files missing" #~ msgstr "[VuplusKexec][creëer Vu Multiboot omgeving] - Kan niet vervolgen, Vu+ Multiboot bestanden ontbreken" @@ -19470,9 +19531,18 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "by date" #~ msgstr "op datum" +#~ msgid "epg cache backup" +#~ msgstr "epg cache back-up" + +#~ msgid "extensions." +#~ msgstr "extensies." + #~ msgid "flat alphabetic reverse" #~ msgstr "omgekeerd plat alfabetisch" +#~ msgid "from" +#~ msgstr "van" + #~ msgid "is strongly advised." #~ msgstr "wordt sterk aangeraden." @@ -19485,9 +19555,18 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "n/A" #~ msgstr "NVT" +#~ msgid "packages selected." +#~ msgstr "pakketten geselecteerd." + #~ msgid "reverse by date" #~ msgstr "omgekeerd chronologisch" +#~ msgid "show softwaremanager in plugin menu" +#~ msgstr "toon softwaremanager in pluginbrowser" + +#~ msgid "show softwaremanager on blue button" +#~ msgstr "toon softwaremanager onder blauwe knop" + #, python-format #~ msgid "slot%s - %s" #~ msgstr "slot%s - %s" @@ -19499,3 +19578,12 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #, python-format #~ msgid "slot%s - %s (current image)" #~ msgstr "slot%s - %s (huidige image)" + +#~ msgid "start directory" +#~ msgstr "startmap" + +#~ msgid "two lines and next event" +#~ msgstr "twee regels en volgende programma" + +#~ msgid "updates available." +#~ msgstr "updates beschikbaar."