From 7b0b4eec6f710727cd56afb03dbf8ef0bcf7864e Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Tue, 26 Feb 2013 20:55:32 +0200 Subject: [PATCH 1/4] connman: update to connman-1.12 --- packages/network/connman/meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/network/connman/meta b/packages/network/connman/meta index b0994f57a5..43b9195060 100644 --- a/packages/network/connman/meta +++ b/packages/network/connman/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="connman" -PKG_VERSION="1.11" +PKG_VERSION="1.12" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" From 2be7c80a01cacd048e13fcf49c624862a38bbedb Mon Sep 17 00:00:00 2001 From: vpeter4 Date: Tue, 26 Feb 2013 20:55:47 +0100 Subject: [PATCH 2/4] sundtek-mediatv: added addon settings for modifying tuner type (DVB-C, DVB-T) --- .../driver/sundtek-mediatv/changelog.txt | 2 + .../sundtek-mediatv/config/rc_key_enter | 32 ++++ .../driver/sundtek-mediatv/config/rc_key_ok | 32 ++++ .../driver/sundtek-mediatv/icon/icon.png | Bin 2806 -> 4371 bytes packages/addons/driver/sundtek-mediatv/meta | 2 +- .../source/bin/refresh-tuners.py | 172 ++++++++++++++++++ .../source/bin/userspace-driver.sh | 52 +++++- .../sundtek-mediatv/source/bin/xmlpp.py | 161 ++++++++++++++++ .../resources/language/English/strings.xml | 9 +- .../source/resources/settings.xml | 7 +- 10 files changed, 463 insertions(+), 6 deletions(-) create mode 100644 packages/addons/driver/sundtek-mediatv/config/rc_key_enter create mode 100644 packages/addons/driver/sundtek-mediatv/config/rc_key_ok create mode 100644 packages/addons/driver/sundtek-mediatv/source/bin/refresh-tuners.py create mode 100644 packages/addons/driver/sundtek-mediatv/source/bin/xmlpp.py diff --git a/packages/addons/driver/sundtek-mediatv/changelog.txt b/packages/addons/driver/sundtek-mediatv/changelog.txt index 000cb4f4e1..7161defcaf 100644 --- a/packages/addons/driver/sundtek-mediatv/changelog.txt +++ b/packages/addons/driver/sundtek-mediatv/changelog.txt @@ -1,3 +1,5 @@ +3.0.3 + added addon settings for modifying tuner type (DVB-C, DVB-T) 3.0.2 added addon settings enable HW PID filter (enabled for RPi by default) diff --git a/packages/addons/driver/sundtek-mediatv/config/rc_key_enter b/packages/addons/driver/sundtek-mediatv/config/rc_key_enter new file mode 100644 index 0000000000..8dc5d931cb --- /dev/null +++ b/packages/addons/driver/sundtek-mediatv/config/rc_key_enter @@ -0,0 +1,32 @@ +0x01 KEY_SELECT +0x02 KEY_3 +0x03 KEY_EXIT +0x04 KEY_1 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_CHANNELDOWN +0x08 KEY_2 +0x09 KEY_CHANNELUP +0x0a KEY_9 +0x0b KEY_ZOOM +0x0c KEY_7 +0x0d KEY_8 +0x0e KEY_VOLUMEUP +0x0f KEY_4 +0x10 KEY_BACK +0x11 KEY_0 +0x12 KEY_ENTER +0x13 KEY_VOLUMEDOWN +0x14 KEY_RECORD +0x15 KEY_STOP +0x16 KEY_PLAY +0x17 KEY_MUTE +0x18 KEY_UP +0x19 KEY_DOWN +0x1a KEY_LEFT +0x1b KEY_RIGHT +0x1c KEY_RED +0x1d KEY_GREEN +0x1e KEY_YELLOW +0x1f KEY_BLUE +0x43 KEY_POWER diff --git a/packages/addons/driver/sundtek-mediatv/config/rc_key_ok b/packages/addons/driver/sundtek-mediatv/config/rc_key_ok new file mode 100644 index 0000000000..13f2c608c8 --- /dev/null +++ b/packages/addons/driver/sundtek-mediatv/config/rc_key_ok @@ -0,0 +1,32 @@ +0x01 KEY_SELECT +0x02 KEY_3 +0x03 KEY_EXIT +0x04 KEY_1 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_CHANNELDOWN +0x08 KEY_2 +0x09 KEY_CHANNELUP +0x0a KEY_9 +0x0b KEY_ZOOM +0x0c KEY_7 +0x0d KEY_8 +0x0e KEY_VOLUMEUP +0x0f KEY_4 +0x10 KEY_BACK +0x11 KEY_0 +0x12 KEY_OK +0x13 KEY_VOLUMEDOWN +0x14 KEY_RECORD +0x15 KEY_STOP +0x16 KEY_PLAY +0x17 KEY_MUTE +0x18 KEY_UP +0x19 KEY_DOWN +0x1a KEY_LEFT +0x1b KEY_RIGHT +0x1c KEY_RED +0x1d KEY_GREEN +0x1e KEY_YELLOW +0x1f KEY_BLUE +0x43 KEY_POWER diff --git a/packages/addons/driver/sundtek-mediatv/icon/icon.png b/packages/addons/driver/sundtek-mediatv/icon/icon.png index 912c71d6b9b26c9ea7bc1a92d8f8368a5090c8fe..eb4144b290d0f516bb422a567ea2393ed26751e4 100644 GIT binary patch literal 4371 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 X(L*olpG93fI~YKZ%=D^sT;BX2qDDf) literal 2806 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 Jl%r22{RiCcNF4wG diff --git a/packages/addons/driver/sundtek-mediatv/meta b/packages/addons/driver/sundtek-mediatv/meta index 163e8d3de9..cb1b74034b 100644 --- a/packages/addons/driver/sundtek-mediatv/meta +++ b/packages/addons/driver/sundtek-mediatv/meta @@ -20,7 +20,7 @@ PKG_NAME="sundtek-mediatv" PKG_VERSION="3.0" -PKG_REV="2" +PKG_REV="3" PKG_ARCH="any" PKG_LICENSE="nonfree" PKG_SITE="http://support.sundtek.com/" diff --git a/packages/addons/driver/sundtek-mediatv/source/bin/refresh-tuners.py b/packages/addons/driver/sundtek-mediatv/source/bin/refresh-tuners.py new file mode 100644 index 0000000000..ba9771d103 --- /dev/null +++ b/packages/addons/driver/sundtek-mediatv/source/bin/refresh-tuners.py @@ -0,0 +1,172 @@ +""" +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2013 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2013 ultraman/vpeter +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ +""" + +import os +import sys +import shutil +import xmlpp +import xbmcaddon + +from xml.dom import minidom +from array import array + +__settings__ = xbmcaddon.Addon(id='driver.dvb.sundtek-mediatv') +__cwd__ = __settings__.getAddonInfo('path') +__mediaclient__ = xbmc.translatePath(os.path.join(__cwd__, 'bin', 'mediaclient')) +__ld_preload__ = xbmc.translatePath(os.path.join(__cwd__, 'lib', 'libmediaclient.so')) +__settings_xml__ = xbmc.translatePath(os.path.join(__cwd__, 'resources', 'settings.xml')) + +__mediaclient_e__ = 'LD_PRELOAD=' + __ld_preload__ + ' ' + __mediaclient__ + ' -e' + +# make backup settings only once +try: + with open(__settings_xml__ + '_orig') as f: pass +except IOError as e: + shutil.copyfile(__settings_xml__, __settings_xml__ + '_orig') + +###################################################################################################### + +# get supported devices on a system (name, serial number, type) +tuners = [] +p = os.popen(__mediaclient_e__, "r") +while 1: + line = p.readline() + if not line: + break + else: + str = line.strip() + if str.startswith('device '): + name = str[str.find("[")+1:str.find("]")] + tuners.append([name, 0, 's']) + + if str.startswith('[SERIAL]:'): + line = p.readline() + str = line.strip() + if str.startswith('ID:'): + id = str.split(':'); + id = id[1].strip() + tuners[len(tuners)-1] = [name, id, 's'] + + if str.startswith('[DVB-C]:'): + tuners[len(tuners)-1] = [name, id, 'c'] + elif str.startswith('[DVB-T]:'): + tuners[len(tuners)-1] = [name, id, 'c'] + elif str.startswith('[DVB-T2]:'): + tuners[len(tuners)-1] = [name, id, 'c'] + +""" +root ~ # mediaclient -e +**** List of Media Hardware Devices **** +device 0: [Sundtek MediaTV Pro (USB 2.0)] DVB-C, DVB-T, ANALOG-TV, FM-RADIO, REMOTE-CONTROL, OSS-AUDIO, RDS + [BUS]: + ID: 1-7 + [SERIAL]: + ID: U110714145205 + [DVB-C]: + FRONTEND: /dev/dvb/adapter0/frontend0 + DVR: /dev/dvb/adapter0/dvr0 + DMX: /dev/dvb/adapter0/demux0 + [DVB-T]: + FRONTEND: /dev/dvb/adapter0/frontend0 + DVR: /dev/dvb/adapter0/dvr0 + DMX: /dev/dvb/adapter0/demux0 + [ANALOG-TV]: + VIDEO0: /dev/video0 + VBI0: /dev/vbi0 + [FM-RADIO]: + RADIO0: /dev/radio0 + RDS: /dev/rds0 + [REMOTECONTROL]: + INPUT0: /dev/mediainput0 + [OSS]: + OSS0: /dev/dsp0 +""" + +###################################################################################################### + +xmldoc = minidom.parse(__settings_xml__) +category = xmldoc.getElementsByTagName('category') + +# remove all nodes with id started with ATTACHED_TUNER_ +for node_cat in category: + setting = node_cat.getElementsByTagName('setting') + for node_set in setting : + if 'id' in node_set.attributes.keys() and not node_set.getAttribute('id').find('ATTACHED_TUNER_'): + node_set.parentNode.removeChild(node_set) + +# add new ATTACHED_TUNER_ nodes for available tuners +for node_cat in category: + setting = node_cat.getElementsByTagName('setting') + for node_set in setting : + if 'label' in node_set.attributes.keys() and '9010' in node_set.getAttribute('label'): + for ix, tuner in enumerate(tuners): + tuner_name = tuner[0] + tuner_serial = tuner[1] + tuner_type = tuner[2] + + node1 = xmldoc.createElement("setting") + node1.setAttribute("id", 'ATTACHED_TUNER_' + tuner_serial + '_DVBMODE') + node1.setAttribute("label", tuner_name + ", " + tuner_serial) + node1.setAttribute("type", 'labelenum') + + if (tuner_type == 's'): + node1.setAttribute("default", 'DVB-S') + node1.setAttribute("values", 'DVB-S') + else: + node1.setAttribute("default", 'DVB-C') + node1.setAttribute("values", 'DVB-C|DVB-T') + + node_cat.appendChild(node1) + + node2 = xmldoc.createElement("setting") + node2.setAttribute("id", 'ATTACHED_TUNER_' + tuner_serial + '_IRPROT') + node2.setAttribute("label", '9020') + node2.setAttribute("type", 'labelenum') + node2.setAttribute("default", 'auto') + node2.setAttribute("values", 'auto|RC5|NEC|RC6') + node_cat.appendChild(node2) + + node3 = xmldoc.createElement("setting") + node3.setAttribute("id", 'ATTACHED_TUNER_' + tuner_serial + '_KEYMAP') + node3.setAttribute("label", '9030') + node3.setAttribute("type", 'text') + node3.setAttribute("default", 'rc_key_ok') + node_cat.appendChild(node3) + + # for tuner + break + +###################################################################################################### + +# save file back +try: + outputfile=open(__settings_xml__, 'w') + xmlpp.pprint(xmldoc.toxml(), output=outputfile, indent=2) + outputfile.close() +except IOError: + print 'Error writing file ', __settings_xml__ + +###################################################################################################### + +# dialog is closed already so just open settings again +xbmcaddon.Addon(id='driver.dvb.sundtek-mediatv').openSettings() diff --git a/packages/addons/driver/sundtek-mediatv/source/bin/userspace-driver.sh b/packages/addons/driver/sundtek-mediatv/source/bin/userspace-driver.sh index 3b50b046a5..b720d77cd5 100644 --- a/packages/addons/driver/sundtek-mediatv/source/bin/userspace-driver.sh +++ b/packages/addons/driver/sundtek-mediatv/source/bin/userspace-driver.sh @@ -46,7 +46,7 @@ else if [ -z "$entry_set" ]; then sed -i 's|^device_attach=.*|# device_attach not used anymore\n\n# enable HW PID filter\nuse_hwpidfilter=off\n\n# enable listening on network\nenablenetwork=off|g' $ADDON_HOME/sundtek.conf sed -i 's|^#first_adapter=.*|first_adapter=0|g' $ADDON_HOME/sundtek.conf - + sed -i 's|.*network tuner IP address (OpenELEC specific).*||g' $ADDON_HOME/sundtek.conf sed -i 's|.*network_tuner_ip=.*||g' $ADDON_HOME/sundtek.conf fi @@ -95,6 +95,7 @@ if [ ! -f $ADDON_DIR/bin/mediasrv ]; then # enable HW PID filter on RPi by default sed -i 's|^use_hwpidfilter=.*|use_hwpidfilter=on|g' $ADDON_DIR/config/sundtek.conf sed -i 's|^use_hwpidfilter=.*|use_hwpidfilter=on|g' $ADDON_HOME/sundtek.conf + sed -i 's|.*id="ENABLE_HW_PID_FILTER".*||' $ADDON_DIR/settings-default.xml sed -i 's|.*id="ENABLE_HW_PID_FILTER".*||' $ADDON_SETTINGS else logger -t Sundtek "### Unsupported architecture ###" @@ -214,7 +215,7 @@ if [ -z "$(pidof mediasrv)" ]; then # remove empty lines at the end of file sed -i '${/^$/d;}' $SUNDTEK_CONF_TMP # add entries - echo "[NETWORK]" >>$SUNDTEK_CONF_TMP + echo -e "\n[NETWORK]" >>$SUNDTEK_CONF_TMP for dev in $(seq 0 $DEVICE1_NUM); do echo "device=$DEVICE1_IP:$dev" >>$SUNDTEK_CONF_TMP done @@ -247,6 +248,53 @@ if [ -z "$(pidof mediasrv)" ]; then sed -i '${/^$/d;}' $SUNDTEK_CONF_TMP fi + if [ "$ENABLE_TUNER_TYPES" = "true" ]; then + # get tuner serial numbers + SERIALS=$(cat /var/config/sundtek-addon.conf | sed -n 's|^ATTACHED_TUNER_\(.*\)_DVBMODE=.*|\1|gp' | sort | uniq) + . /var/config/sundtek-addon.conf + + for SERIAL in ${SERIALS[@]}; do + DVBMODE=$(eval echo \$ATTACHED_TUNER_${SERIAL}_DVBMODE) + IRPROT=$(eval echo \$ATTACHED_TUNER_${SERIAL}_IRPROT) + KEYMAP=$(eval echo \$ATTACHED_TUNER_${SERIAL}_KEYMAP) + + if [ "$DVBMODE" = "DVB-T" ]; then + # only set DVB-T because default is DVB-C (and DVB-S is not set either) + DVBMODE="DVBT" + else + DVBMODE="" + fi + + [ "$IRPROT" = "NEC" -o "$IRPROT" = "auto" ] && IRPROT="" + + KEYMAP_FILE="$ADDON_HOME/$KEYMAP" + [ ! -f $KEYMAP_FILE ] && KEYMAP_FILE="" + + # remove setttings for this tuner + awk -v val="[$SERIAL]" '$0 == val {flag=1; next} /^ir_protocol=|^rcmap=|^initial_dvb_mode=|^#|^$/{if (flag==1) next} /.*/{flag=0; print}' $SUNDTEK_CONF_TMP >${SUNDTEK_CONF_TMP}-types + mv ${SUNDTEK_CONF_TMP}-types $SUNDTEK_CONF_TMP + echo "" >>$SUNDTEK_CONF_TMP + # remove empty lines at the end of file + sed -i '${/^$/d;}' $SUNDTEK_CONF_TMP + + ADDNEW=true + if [ -n "$DVBMODE" ]; then + [ $ADDNEW = true ] && ADDNEW=false && echo -e "\n[$SERIAL]" >>$SUNDTEK_CONF_TMP + echo "initial_dvb_mode=$DVBMODE" >>$SUNDTEK_CONF_TMP + fi + if [ -n "$IRPROT" ]; then + [ $ADDNEW = true ] && ADDNEW=false && echo -e "\n[$SERIAL]" >>$SUNDTEK_CONF_TMP + echo "ir_protocol=$IRPROT" >>$SUNDTEK_CONF_TMP + fi + if [ -n "$KEYMAP_FILE" ]; then + [ $ADDNEW = true ] && ADDNEW=false && echo -e "\n[$SERIAL]" >>$SUNDTEK_CONF_TMP + echo "rcmap=$KEYMAP_FILE" >>$SUNDTEK_CONF_TMP + fi + + echo "" >>$SUNDTEK_CONF_TMP + done + fi + md5_1=$(md5sum -b $SUNDTEK_CONF_TMP | awk '{print $1}') md5_2=$(md5sum -b $ADDON_HOME/sundtek.conf | awk '{print $1}') if [ "$md5_1" != "$md5_2" ]; then diff --git a/packages/addons/driver/sundtek-mediatv/source/bin/xmlpp.py b/packages/addons/driver/sundtek-mediatv/source/bin/xmlpp.py new file mode 100644 index 0000000000..342dcc01d7 --- /dev/null +++ b/packages/addons/driver/sundtek-mediatv/source/bin/xmlpp.py @@ -0,0 +1,161 @@ +"""Pretty print an XML document. + +LICENCE: +Copyright (c) 2008, Fredrik Ekholdt +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +* Neither the name of Fredrik Ekholdt nor the names of its contributors may be used to +endorse or promote products derived from this software without specific prior +written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE.""" + +import sys as _sys +import re as _re + +def _usage(this_file): + return """SYNOPSIS: pretty print an XML document +USAGE: python %s \n""" % this_file + +def _pprint_line(indent_level, line, width=100, output=_sys.stdout): + if line.strip(): + start = "" + number_chars = 0 + for l in range(indent_level): + start = start + " " + number_chars = number_chars + 1 + try: + elem_start = _re.findall("(\<\W{0,1}\w+:\w+) ?", line)[0] + elem_finished = _re.findall("([?|\]\]/]*\>)", line)[0] + #should not have * + attrs = _re.findall("(\S*?\=\".*?\")", line) + output.write(start + elem_start) + number_chars = len(start + elem_start) + for attr in attrs: + if (attrs.index(attr) + 1) == len(attrs): + number_chars = number_chars + len(elem_finished) + if (number_chars + len(attr) + 1) > width: + output.write("\n") + for i in range(len(start + elem_start) + 1): + output.write(" ") + number_chars = len(start + elem_start) + 1 + else: + output.write(" ") + number_chars = number_chars + 1 + output.write(attr) + number_chars = number_chars + len(attr) + output.write(elem_finished + "\n") + except IndexError: + #give up pretty print this line + output.write(start + line + "\n") + + +def _pprint_elem_content(indent_level, line, output=_sys.stdout): + if line.strip(): + for l in range(indent_level): + output.write(" ") + output.write(line + "\n") + +def _get_next_elem(data): + start_pos = data.find("<") + end_pos = data.find(">") + 1 + retval = data[start_pos:end_pos] + stopper = retval.rfind("/") + if stopper < retval.rfind("\""): + stopper = -1 + single = (stopper > -1 and ((retval.find(">") - stopper) < (stopper - retval.find("<")))) + + ignore_excl = retval.find(" -1 + ignore_question = retval.find(" -1 + + if ignore_excl: + cdata = retval.find(" -1 + if cdata: + end_pos = data.find("]]>") + if end_pos > -1: + end_pos = end_pos + len("]]>") + + elif ignore_question: + end_pos = data.find("?>") + len("?>") + ignore = ignore_excl or ignore_question + + no_indent = ignore or single + + #print retval, end_pos, start_pos, stopper > -1, no_indent + return start_pos, \ + end_pos, \ + stopper > -1, \ + no_indent + +def get_pprint(xml, indent=4, width=80): + """Returns the pretty printed xml """ + class out: + output = "" + + def write(self, string): + self.output += string + out = out() + pprint(xml, output=out, indent=indent, width=width) + + return out.output + + +def pprint(xml, output=_sys.stdout, indent=4, width=80): + """Pretty print xml. + Use output to select output stream. Default is sys.stdout + Use indent to select indentation level. Default is 4 """ + data = xml + indent_level = 0 + start_pos, end_pos, is_stop, no_indent = _get_next_elem(data) + while ((start_pos > -1 and end_pos > -1)): + _pprint_elem_content(indent_level, data[:start_pos].strip(), + output=output) + data = data[start_pos:] + if is_stop and not no_indent: + indent_level = indent_level - indent + _pprint_line(indent_level, + data[:end_pos - start_pos], + width=width, + output=output) + data = data[end_pos - start_pos:] + if not is_stop and not no_indent : + indent_level = indent_level + indent + + if not data: + break + else: + start_pos, end_pos, is_stop, no_indent = _get_next_elem(data) + + +if __name__ == "__main__": + if "-h" in _sys.argv or "--help" in _sys.argv: + _sys.stderr.write(_usage(_sys.argv[0])) + _sys.exit(1) + if len(_sys.argv) < 2: + _sys.stderr.write(_usage(_sys.argv[0])) + _sys.exit(1) + else: + filename = _sys.argv[1] + fh = open(filename) + + pprint(fh.read(), output=_sys.stdout, indent=4, width=80) diff --git a/packages/addons/driver/sundtek-mediatv/source/resources/language/English/strings.xml b/packages/addons/driver/sundtek-mediatv/source/resources/language/English/strings.xml index a76c6fd8d5..97d55aa426 100644 --- a/packages/addons/driver/sundtek-mediatv/source/resources/language/English/strings.xml +++ b/packages/addons/driver/sundtek-mediatv/source/resources/language/English/strings.xml @@ -3,11 +3,12 @@ General Auto update binary driver Enable analog TV - Extra settle time + Extra delay [sec] Run user script Enable hardware PID filter Enable IR receiver Lowest adapter number (/dev/dvb/adapterX/) + Networking Share local tuner over network Use network shared tuners @@ -21,4 +22,10 @@ # of tuners Server 5 IP address # of tuners + + Tuner settings + Enable modifying settings + Refresh... + IR protocol + keymap filename diff --git a/packages/addons/driver/sundtek-mediatv/source/resources/settings.xml b/packages/addons/driver/sundtek-mediatv/source/resources/settings.xml index 6b4940cfdc..24ffab9056 100644 --- a/packages/addons/driver/sundtek-mediatv/source/resources/settings.xml +++ b/packages/addons/driver/sundtek-mediatv/source/resources/settings.xml @@ -1,7 +1,6 @@ - @@ -12,7 +11,6 @@ - @@ -27,4 +25,9 @@ + + + + + From 6a9d95d16148be2255c91bda304f935157e5940e Mon Sep 17 00:00:00 2001 From: vpeter4 Date: Tue, 26 Feb 2013 20:57:10 +0100 Subject: [PATCH 3/4] hdhomerun: added addon settings for modifying tuner type (DVB-C, DVB-T, ATSC) and setting delays --- .../addons/driver/hdhomerun/changelog.txt | 4 + .../addons/driver/hdhomerun/icon/icon.png | Bin 4803 -> 36127 bytes packages/addons/driver/hdhomerun/meta | 4 +- .../driver/hdhomerun/settings-default.xml | 4 + .../hdhomerun/source/bin/hdhomerun.start | 28 +++ .../hdhomerun/source/bin/hdhomerun.stop | 26 +++ .../hdhomerun/source/bin/refresh-tuners.py | 125 ++++++++++++++ .../hdhomerun/source/bin/userspace-driver.sh | 88 ++++++++-- .../driver/hdhomerun/source/bin/xmlpp.py | 161 ++++++++++++++++++ .../addons/driver/hdhomerun/source/default.py | 0 .../resources/language/English/strings.xml | 12 ++ .../hdhomerun/source/resources/settings.xml | 13 ++ .../hdhomerun/source/sleep.d/hdhomerun.power | 8 +- 13 files changed, 452 insertions(+), 21 deletions(-) create mode 100644 packages/addons/driver/hdhomerun/settings-default.xml create mode 100644 packages/addons/driver/hdhomerun/source/bin/hdhomerun.start create mode 100644 packages/addons/driver/hdhomerun/source/bin/hdhomerun.stop create mode 100644 packages/addons/driver/hdhomerun/source/bin/refresh-tuners.py mode change 100755 => 100644 packages/addons/driver/hdhomerun/source/bin/userspace-driver.sh create mode 100644 packages/addons/driver/hdhomerun/source/bin/xmlpp.py mode change 100755 => 100644 packages/addons/driver/hdhomerun/source/default.py create mode 100644 packages/addons/driver/hdhomerun/source/resources/language/English/strings.xml create mode 100644 packages/addons/driver/hdhomerun/source/resources/settings.xml mode change 100755 => 100644 packages/addons/driver/hdhomerun/source/sleep.d/hdhomerun.power diff --git a/packages/addons/driver/hdhomerun/changelog.txt b/packages/addons/driver/hdhomerun/changelog.txt index 84281cae66..fb1539bfea 100644 --- a/packages/addons/driver/hdhomerun/changelog.txt +++ b/packages/addons/driver/hdhomerun/changelog.txt @@ -1,3 +1,7 @@ +3.0.2 +- added addon settings for + modifying tuner type (DVB-C, DVB-T, ATSC) + setting delays 3.0.1 - bump addon version - binary files are stored with OpenELEC image diff --git a/packages/addons/driver/hdhomerun/icon/icon.png b/packages/addons/driver/hdhomerun/icon/icon.png index 3e86018bdd7edf031d927c7500442805ed5c0c03..af1fddcd3e72641080b6401b33b26dd8243b9d92 100644 GIT binary patch literal 36127 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 literal 4803 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 diff --git a/packages/addons/driver/hdhomerun/meta b/packages/addons/driver/hdhomerun/meta index 5c5b7f5f8b..34b6e460a4 100644 --- a/packages/addons/driver/hdhomerun/meta +++ b/packages/addons/driver/hdhomerun/meta @@ -20,7 +20,7 @@ PKG_NAME="hdhomerun" PKG_VERSION="3.0" -PKG_REV="1" +PKG_REV="2" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="http://www.silicondust.com/products/hdhomerun/dvbt/" @@ -31,8 +31,6 @@ PKG_PRIORITY="optional" PKG_SECTION="driver/dvb" PKG_SHORTDESC="A linux DVB driver for the HDHomeRun (http://www.silicondust.com)." PKG_LONGDESC="A linux DVB driver for the HDHomeRun (http://www.silicondust.com)." - PKG_AUTORECONF="no" - PKG_IS_ADDON="yes" PKG_ADDON_TYPE="xbmc.python.script" diff --git a/packages/addons/driver/hdhomerun/settings-default.xml b/packages/addons/driver/hdhomerun/settings-default.xml new file mode 100644 index 0000000000..240d6ac22e --- /dev/null +++ b/packages/addons/driver/hdhomerun/settings-default.xml @@ -0,0 +1,4 @@ + + + + diff --git a/packages/addons/driver/hdhomerun/source/bin/hdhomerun.start b/packages/addons/driver/hdhomerun/source/bin/hdhomerun.start new file mode 100644 index 0000000000..3224d26d4d --- /dev/null +++ b/packages/addons/driver/hdhomerun/source/bin/hdhomerun.start @@ -0,0 +1,28 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +. /etc/profile + +ADDON_DIR="$HOME/.xbmc/addons/driver.dvb.hdhomerun" + +logger -t Hdhomerun "### Hdhomerun manual start ###" +. $ADDON_DIR/bin/userspace-driver.sh diff --git a/packages/addons/driver/hdhomerun/source/bin/hdhomerun.stop b/packages/addons/driver/hdhomerun/source/bin/hdhomerun.stop new file mode 100644 index 0000000000..94b1c5f60a --- /dev/null +++ b/packages/addons/driver/hdhomerun/source/bin/hdhomerun.stop @@ -0,0 +1,26 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +. /etc/profile + +logger -t Hdhomerun "### Hdhomerun manual stop ###" +killall userhdhomerun diff --git a/packages/addons/driver/hdhomerun/source/bin/refresh-tuners.py b/packages/addons/driver/hdhomerun/source/bin/refresh-tuners.py new file mode 100644 index 0000000000..bc382eeb01 --- /dev/null +++ b/packages/addons/driver/hdhomerun/source/bin/refresh-tuners.py @@ -0,0 +1,125 @@ +""" +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2013 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2013 ultraman/vpeter +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ +""" + +import os +import sys +import shutil +import xmlpp +import xbmcaddon + +from xml.dom import minidom +from array import array + +__settings__ = xbmcaddon.Addon(id='driver.dvb.hdhomerun') +__cwd__ = __settings__.getAddonInfo('path') +__settings_xml__ = xbmc.translatePath(os.path.join(__cwd__, 'resources', 'settings.xml')) + +__hdhomerun_log__ = '/var/log/dvbhdhomerun.log' + +# make backup settings only once +try: + with open(__settings_xml__ + '_orig') as f: pass +except IOError as e: + shutil.copyfile(__settings_xml__, __settings_xml__ + '_orig') + +###################################################################################################### + +# get supported devices on a system (name) +tuners = [] +try: + for line in open(__hdhomerun_log__, 'r'): + line = line.strip() + if line.startswith('Registered tuner'): + name = line.split(':'); + name = name[2].strip() + tuners.append(name) +except IOError: + print 'Error reading log file ', __hdhomerun_log__ + +""" +root ~ # grep "Registered tuner" /var/log/dvbhdhomerun.log +Registered tuner, id from kernel: 0 name: 101ADD2B-0 +Registered tuner, id from kernel: 1 name: 101ADD2B-1 +Registered tuner, id from kernel: 2 name: 1031D75A-0 +Registered tuner, id from kernel: 3 name: 1031D75A-1 +""" + +###################################################################################################### + +xmldoc = minidom.parse(__settings_xml__) +category = xmldoc.getElementsByTagName('category') + +# remove all nodes with id started with ATTACHED_TUNER_ +for node_cat in category: + setting = node_cat.getElementsByTagName('setting') + for node_set in setting : + if 'id' in node_set.attributes.keys() and not node_set.getAttribute('id').find('ATTACHED_TUNER_'): + node_set.parentNode.removeChild(node_set) + +# add new ATTACHED_TUNER_ nodes for available tuners +for node_cat in category: + setting = node_cat.getElementsByTagName('setting') + for node_set in setting : + if 'label' in node_set.attributes.keys() and '9010' in node_set.getAttribute('label'): + for ix, tuner_name in enumerate(tuners): + tuner_name_var = tuner_name.replace('-', '_') + + node1 = xmldoc.createElement("setting") + node1.setAttribute("id", 'ATTACHED_TUNER_' + tuner_name_var + '_DVBMODE') + node1.setAttribute("label", tuner_name) + node1.setAttribute("type", 'labelenum') + node1.setAttribute("default", 'auto') + node1.setAttribute("values", 'auto|ATSC|DVB-C|DVB-T') + node_cat.appendChild(node1) + + node2 = xmldoc.createElement("setting") + node2.setAttribute("id", 'ATTACHED_TUNER_' + tuner_name_var + '_FULLNAME') + node2.setAttribute("label", '9020') + node2.setAttribute("type", 'bool') + node2.setAttribute("default", 'false') + node_cat.appendChild(node2) + + node3 = xmldoc.createElement("setting") + node3.setAttribute("id", 'ATTACHED_TUNER_' + tuner_name_var + '_DISABLE') + node3.setAttribute("label", '9030') + node3.setAttribute("type", 'bool') + node3.setAttribute("default", 'false') + node_cat.appendChild(node3) + + # for tuner + break + +###################################################################################################### + +# save file back +try: + outputfile=open(__settings_xml__, 'w') + xmlpp.pprint(xmldoc.toxml(), output=outputfile, indent=2) + outputfile.close() +except IOError: + print 'Error writing file ', __settings_xml__ + +###################################################################################################### + +# dialog is closed already so just open settings again +xbmcaddon.Addon(id='driver.dvb.hdhomerun').openSettings() diff --git a/packages/addons/driver/hdhomerun/source/bin/userspace-driver.sh b/packages/addons/driver/hdhomerun/source/bin/userspace-driver.sh old mode 100755 new mode 100644 index 3f589962a8..393cc2a5c9 --- a/packages/addons/driver/hdhomerun/source/bin/userspace-driver.sh +++ b/packages/addons/driver/hdhomerun/source/bin/userspace-driver.sh @@ -24,6 +24,11 @@ ADDON_DIR="$HOME/.xbmc/addons/driver.dvb.hdhomerun" ADDON_HOME="$HOME/.xbmc/userdata/addon_data/driver.dvb.hdhomerun" +ADDON_SETTINGS="$ADDON_HOME/settings.xml" + +# modules are not automatically loaded +modprobe dvb_hdhomerun +modprobe dvb_hdhomerun_fe mkdir -p $ADDON_HOME @@ -31,31 +36,84 @@ if [ ! -f "$ADDON_HOME/dvbhdhomerun.sample" ]; then cp $ADDON_DIR/config/* $ADDON_HOME/ fi +if [ ! -f "$ADDON_SETTINGS" ]; then + cp $ADDON_DIR/settings-default.xml $ADDON_SETTINGS +fi + +mkdir -p /var/config +cat "$ADDON_SETTINGS" | awk -F\" '{print $2"=\""$4"\""}' | sed '/^=/d' > /var/config/hdhomerun-addon.conf +. /var/config/hdhomerun-addon.conf + if [ -z "$(pidof userhdhomerun)" ]; then + if [ "$ENABLE_TUNER_TYPES" = "true" ]; then + DVBHDHOMERUN_CONF_TMP=/tmp/dvbhdhomerun.conf + touch $ADDON_HOME/dvbhdhomerun.conf + cp $ADDON_HOME/dvbhdhomerun.conf $DVBHDHOMERUN_CONF_TMP + + # get tuner serial numbers + SERIALS=$(cat /var/config/hdhomerun-addon.conf | sed -n 's|^ATTACHED_TUNER_\(.*\)_\(.*\)_DVBMODE=.*|\1-\2|gp' | sort | uniq) + . /var/config/hdhomerun-addon.conf + + for SERIAL in ${SERIALS[@]}; do + SERIAL_VAR=$(echo $SERIAL | sed 's|-|_|') + DVBMODE=$(eval echo \$ATTACHED_TUNER_${SERIAL_VAR}_DVBMODE) + FULLNAME=$(eval echo \$ATTACHED_TUNER_${SERIAL_VAR}_FULLNAME) + DISABLE=$(eval echo \$ATTACHED_TUNER_${SERIAL_VAR}_DISABLE) + + [ "$DVBMODE" = "auto" ] && DVBMODE="" + + # remove setttings for this tuner + awk -v val="[$SERIAL]" '$0 == val {flag=1; next} /^tuner_type=|^use_full_name=|^disable=|^#|^$/{if (flag==1) next} /.*/{flag=0; print}' $DVBHDHOMERUN_CONF_TMP >${DVBHDHOMERUN_CONF_TMP}-types + mv ${DVBHDHOMERUN_CONF_TMP}-types $DVBHDHOMERUN_CONF_TMP + echo "" >>$DVBHDHOMERUN_CONF_TMP + # remove empty lines at the end of file + sed -i '${/^$/d;}' $DVBHDHOMERUN_CONF_TMP + + ADDNEW=true + if [ -n "$DVBMODE" ]; then + [ $ADDNEW = true ] && ADDNEW=false && echo "[$SERIAL]" >>$DVBHDHOMERUN_CONF_TMP + echo "tuner_type=$DVBMODE" >>$DVBHDHOMERUN_CONF_TMP + fi + if [ "$FULLNAME" = "true" ]; then + [ $ADDNEW = true ] && ADDNEW=false && echo "[$SERIAL]" >>$DVBHDHOMERUN_CONF_TMP + echo "use_full_name=true" >>$DVBHDHOMERUN_CONF_TMP + fi + if [ "$DISABLE" = "true" ]; then + [ $ADDNEW = true ] && ADDNEW=false && echo "[$SERIAL]" >>$DVBHDHOMERUN_CONF_TMP + echo "disable=true" >>$DVBHDHOMERUN_CONF_TMP + fi + + echo "" >>$DVBHDHOMERUN_CONF_TMP + done + + md5_1=$(md5sum -b $DVBHDHOMERUN_CONF_TMP | awk '{print $1}') + md5_2=$(md5sum -b $ADDON_HOME/dvbhdhomerun.conf | awk '{print $1}') + if [ "$md5_1" != "$md5_2" ]; then + # file changed - copy to addon home + cp $DVBHDHOMERUN_CONF_TMP $ADDON_HOME/dvbhdhomerun.conf + fi + fi + rm -f /tmp/dvbhdhomerun if [ -f $ADDON_HOME/dvbhdhomerun.conf ]; then ln -s $ADDON_HOME/dvbhdhomerun.conf /tmp/dvbhdhomerun fi - # modules are not automatically loaded - modprobe dvb_hdhomerun - modprobe dvb_hdhomerun_fe - usleep 2000000 + [ -z "$PRE_WAIT" ] && PRE_WAIT=0 + PRE_WAIT=$(( $PRE_WAIT *1 )) + [ -z "$POST_WAIT" ] && POST_WAIT=0 + POST_WAIT=$(( $POST_WAIT *1 )) - # could be useful - if [ -f $ADDON_HOME/pre-wait.sh ]; then - sh $ADDON_HOME/pre-wait.sh - fi + logger -t HDHomeRun "### Pre wait for $PRE_WAIT sec ###" + sleep $PRE_WAIT mkdir -p /var/log/ rm -f /var/log/dvbhdhomerun.log - + userhdhomerun -f - # how much time should we wait? - usleep 1000000 - if [ -f $ADDON_HOME/post-wait.sh ]; then - sh $ADDON_HOME/post-wait.sh - fi + + logger -t HDHomeRun "### Post wait for $POST_WAIT sec ###" + sleep $POST_WAIT # save adapter names in background ( @@ -67,3 +125,5 @@ if [ -z "$(pidof userhdhomerun)" ]; then fi )& fi + +logger -t HDHomeRun "### HDHomeRun ready ###" diff --git a/packages/addons/driver/hdhomerun/source/bin/xmlpp.py b/packages/addons/driver/hdhomerun/source/bin/xmlpp.py new file mode 100644 index 0000000000..342dcc01d7 --- /dev/null +++ b/packages/addons/driver/hdhomerun/source/bin/xmlpp.py @@ -0,0 +1,161 @@ +"""Pretty print an XML document. + +LICENCE: +Copyright (c) 2008, Fredrik Ekholdt +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +* Neither the name of Fredrik Ekholdt nor the names of its contributors may be used to +endorse or promote products derived from this software without specific prior +written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE.""" + +import sys as _sys +import re as _re + +def _usage(this_file): + return """SYNOPSIS: pretty print an XML document +USAGE: python %s \n""" % this_file + +def _pprint_line(indent_level, line, width=100, output=_sys.stdout): + if line.strip(): + start = "" + number_chars = 0 + for l in range(indent_level): + start = start + " " + number_chars = number_chars + 1 + try: + elem_start = _re.findall("(\<\W{0,1}\w+:\w+) ?", line)[0] + elem_finished = _re.findall("([?|\]\]/]*\>)", line)[0] + #should not have * + attrs = _re.findall("(\S*?\=\".*?\")", line) + output.write(start + elem_start) + number_chars = len(start + elem_start) + for attr in attrs: + if (attrs.index(attr) + 1) == len(attrs): + number_chars = number_chars + len(elem_finished) + if (number_chars + len(attr) + 1) > width: + output.write("\n") + for i in range(len(start + elem_start) + 1): + output.write(" ") + number_chars = len(start + elem_start) + 1 + else: + output.write(" ") + number_chars = number_chars + 1 + output.write(attr) + number_chars = number_chars + len(attr) + output.write(elem_finished + "\n") + except IndexError: + #give up pretty print this line + output.write(start + line + "\n") + + +def _pprint_elem_content(indent_level, line, output=_sys.stdout): + if line.strip(): + for l in range(indent_level): + output.write(" ") + output.write(line + "\n") + +def _get_next_elem(data): + start_pos = data.find("<") + end_pos = data.find(">") + 1 + retval = data[start_pos:end_pos] + stopper = retval.rfind("/") + if stopper < retval.rfind("\""): + stopper = -1 + single = (stopper > -1 and ((retval.find(">") - stopper) < (stopper - retval.find("<")))) + + ignore_excl = retval.find(" -1 + ignore_question = retval.find(" -1 + + if ignore_excl: + cdata = retval.find(" -1 + if cdata: + end_pos = data.find("]]>") + if end_pos > -1: + end_pos = end_pos + len("]]>") + + elif ignore_question: + end_pos = data.find("?>") + len("?>") + ignore = ignore_excl or ignore_question + + no_indent = ignore or single + + #print retval, end_pos, start_pos, stopper > -1, no_indent + return start_pos, \ + end_pos, \ + stopper > -1, \ + no_indent + +def get_pprint(xml, indent=4, width=80): + """Returns the pretty printed xml """ + class out: + output = "" + + def write(self, string): + self.output += string + out = out() + pprint(xml, output=out, indent=indent, width=width) + + return out.output + + +def pprint(xml, output=_sys.stdout, indent=4, width=80): + """Pretty print xml. + Use output to select output stream. Default is sys.stdout + Use indent to select indentation level. Default is 4 """ + data = xml + indent_level = 0 + start_pos, end_pos, is_stop, no_indent = _get_next_elem(data) + while ((start_pos > -1 and end_pos > -1)): + _pprint_elem_content(indent_level, data[:start_pos].strip(), + output=output) + data = data[start_pos:] + if is_stop and not no_indent: + indent_level = indent_level - indent + _pprint_line(indent_level, + data[:end_pos - start_pos], + width=width, + output=output) + data = data[end_pos - start_pos:] + if not is_stop and not no_indent : + indent_level = indent_level + indent + + if not data: + break + else: + start_pos, end_pos, is_stop, no_indent = _get_next_elem(data) + + +if __name__ == "__main__": + if "-h" in _sys.argv or "--help" in _sys.argv: + _sys.stderr.write(_usage(_sys.argv[0])) + _sys.exit(1) + if len(_sys.argv) < 2: + _sys.stderr.write(_usage(_sys.argv[0])) + _sys.exit(1) + else: + filename = _sys.argv[1] + fh = open(filename) + + pprint(fh.read(), output=_sys.stdout, indent=4, width=80) diff --git a/packages/addons/driver/hdhomerun/source/default.py b/packages/addons/driver/hdhomerun/source/default.py old mode 100755 new mode 100644 diff --git a/packages/addons/driver/hdhomerun/source/resources/language/English/strings.xml b/packages/addons/driver/hdhomerun/source/resources/language/English/strings.xml new file mode 100644 index 0000000000..143e077530 --- /dev/null +++ b/packages/addons/driver/hdhomerun/source/resources/language/English/strings.xml @@ -0,0 +1,12 @@ + + + General + Pre wait time [sec] + Post wait time [sec] + + Tuner settings + Enable modifying settings + Refresh... + use full name + disabled + diff --git a/packages/addons/driver/hdhomerun/source/resources/settings.xml b/packages/addons/driver/hdhomerun/source/resources/settings.xml new file mode 100644 index 0000000000..afaf8065f9 --- /dev/null +++ b/packages/addons/driver/hdhomerun/source/resources/settings.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/packages/addons/driver/hdhomerun/source/sleep.d/hdhomerun.power b/packages/addons/driver/hdhomerun/source/sleep.d/hdhomerun.power old mode 100755 new mode 100644 index c2c52fc1cd..02ac8750f3 --- a/packages/addons/driver/hdhomerun/source/sleep.d/hdhomerun.power +++ b/packages/addons/driver/hdhomerun/source/sleep.d/hdhomerun.power @@ -23,22 +23,22 @@ . /etc/profile LOCKDIR="/var/lock/" -LOCKFILE="hdhomerun" +LOCKFILE="$LOCKDIR/hdhomerun" case "$1" in hibernate|suspend) if [ -n "$(pidof userhdhomerun)" ]; then progress "Shutting down HDHomeRun driver for suspending..." mkdir -p "$LOCKDIR" - touch "$LOCKDIR/$LOCKFILE" + touch "$LOCKFILE" killall userhdhomerun fi ;; thaw|resume) - if [ -f "$LOCKDIR/$LOCKFILE" ]; then + if [ -f "$LOCKFILE" ]; then # driver started within Tvheadend/VDR - rm -rf "$LOCKDIR/$LOCKFILE" + rm -f "$LOCKFILE" fi ;; From 3d54e09252a4f34de4a2ee7198e02d36e39bf147 Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Tue, 26 Feb 2013 13:48:50 +0200 Subject: [PATCH 4/4] implement 'wait for network' --- .../config/default_settings.xml | 2 ++ .../resources/language/English/strings.xml | 3 ++ .../source/resources/settings.xml | 4 +++ packages/mediacenter/xbmc/init.d/93_xbmc | 3 ++ .../network/connman/profile.d/connman.conf | 36 +++++++++++++++++++ 5 files changed, 48 insertions(+) create mode 100644 packages/network/connman/profile.d/connman.conf diff --git a/packages/mediacenter/xbmc-addon-settings/config/default_settings.xml b/packages/mediacenter/xbmc-addon-settings/config/default_settings.xml index af1f23e09b..89f52ccede 100644 --- a/packages/mediacenter/xbmc-addon-settings/config/default_settings.xml +++ b/packages/mediacenter/xbmc-addon-settings/config/default_settings.xml @@ -2,6 +2,8 @@ + + diff --git a/packages/mediacenter/xbmc-addon-settings/source/resources/language/English/strings.xml b/packages/mediacenter/xbmc-addon-settings/source/resources/language/English/strings.xml index 21f01629a1..53c1d78040 100644 --- a/packages/mediacenter/xbmc-addon-settings/source/resources/language/English/strings.xml +++ b/packages/mediacenter/xbmc-addon-settings/source/resources/language/English/strings.xml @@ -13,6 +13,9 @@ HDD standby Enable HDD standby HDD standby timeout (minutes) + Other + Wait for network before starting xbmc + Wait time (seconds) Network diff --git a/packages/mediacenter/xbmc-addon-settings/source/resources/settings.xml b/packages/mediacenter/xbmc-addon-settings/source/resources/settings.xml index 3e906b7773..42f2ba0db9 100644 --- a/packages/mediacenter/xbmc-addon-settings/source/resources/settings.xml +++ b/packages/mediacenter/xbmc-addon-settings/source/resources/settings.xml @@ -17,6 +17,10 @@ + + + + diff --git a/packages/mediacenter/xbmc/init.d/93_xbmc b/packages/mediacenter/xbmc/init.d/93_xbmc index df8f7d9d05..fa4606486f 100644 --- a/packages/mediacenter/xbmc/init.d/93_xbmc +++ b/packages/mediacenter/xbmc/init.d/93_xbmc @@ -52,6 +52,9 @@ fi # waiting for Xorg to start wait_for_xorg +# wait for network + wait_for_inet_addr + # set cpu's to 'conservative' ( usleep 15000000 progress "set cpu's to 'ondemand'" diff --git a/packages/network/connman/profile.d/connman.conf b/packages/network/connman/profile.d/connman.conf new file mode 100644 index 0000000000..ec281cd8e6 --- /dev/null +++ b/packages/network/connman/profile.d/connman.conf @@ -0,0 +1,36 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +wait_for_inet_addr () { + if [ -f /var/config/settings.conf ]; then + . /var/config/settings.conf + fi + + if [ "$WAIT_NETWORK" = "true" ] ; then + progress "Wait for network" + [ -z "$WAIT_NETWORK_TIME" ] && WAIT_NETWORK_TIME=10 + LOOP_COUNT=$[$WAIT_NETWORK_TIME * 5] + for i in $(seq 1 $LOOP_COUNT) ; do + cnt=$(ifconfig | sed -e '/inet addr:/!d' -e '/127.0.0.1/d' |wc -l) + [ $cnt -gt 0 ] && break + usleep 200000 + done + fi +}