From: Stephan Reichholf Date: Mon, 26 Jul 2010 23:05:24 +0000 (+0000) Subject: Initial checking of "Bonjour" plugin. It takes care of AVAHI/Zercoconf configuration. X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp-plugin;a=commitdiff_plain;h=2ea162e0a20f8dc1cfad96ed7463d37625bd4db2 Initial checking of "Bonjour" plugin. It takes care of AVAHI/Zercoconf configuration. Plugins providing network-services can register with this plugin, which will then take care of the proper avahi-configuration. THIS PLUGIN IS VERY BETA! --- diff --git a/Makefile.am b/Makefile.am index 0075c7c..c433c7e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,6 +7,7 @@ SUBDIRS = \ autoresolution \ autotimer \ babelzapper \ + bonjour \ cdinfo \ dreamirc \ dvdbackup \ diff --git a/bonjour/CONTROL/control b/bonjour/CONTROL/control new file mode 100644 index 0000000..acc5e0b --- /dev/null +++ b/bonjour/CONTROL/control @@ -0,0 +1,10 @@ +Package: enigma2-plugin-extensions-bonjour +Version: 0.1 +Description: Bonjour/avahi-daemon management for your Dreambox +Section: extra +Priority: optional +Maintainer: Stephan Reichholf +Architecture: noarch +Homepage: http://enigma2-plugins.schwerkraft.elitedvb.net/ +Depends: enigma2,avahi-daemon +Source: http://enigma2-plugins.schwerkraft.elitedvb.net/ \ No newline at end of file diff --git a/bonjour/Makefile.am b/bonjour/Makefile.am new file mode 100644 index 0000000..1e238b4 --- /dev/null +++ b/bonjour/Makefile.am @@ -0,0 +1,14 @@ +SUBDIRS = src meta + +PWD=$(shell pwd) + +ipkg: enigma2-plugin-extensions-bonjour.ipk + +enigma2-plugin-extensions-bonjour.ipk: + make install DESTDIR=${PWD}/ipkg/INSTALL + tar czf ipkg/data.tar.gz -C ipkg/INSTALL/ . + echo 2.0 > ipkg/debian-binary + tar czf ipkg/control.tar.gz -C CONTROL/ ./control + rm -f $@ + ar q $@ ipkg/control.tar.gz ipkg/debian-binary ipkg/data.tar.gz + rm -rf ipkg/ diff --git a/bonjour/meta/Makefile.am b/bonjour/meta/Makefile.am new file mode 100644 index 0000000..0a679fb --- /dev/null +++ b/bonjour/meta/Makefile.am @@ -0,0 +1,5 @@ +installdir = $(datadir)/meta/ + +dist_install_DATA = plugin_bonjour.xml + +EXTRA_DIST = bonjour.jpg \ No newline at end of file diff --git a/bonjour/meta/bonjour.jpg b/bonjour/meta/bonjour.jpg new file mode 100644 index 0000000..5113b66 Binary files /dev/null and b/bonjour/meta/bonjour.jpg differ diff --git a/bonjour/meta/plugin_bonjour.xml b/bonjour/meta/plugin_bonjour.xml new file mode 100644 index 0000000..87a6539 --- /dev/null +++ b/bonjour/meta/plugin_bonjour.xml @@ -0,0 +1,24 @@ + + + + + + Reichi + Bonjour + enigma2-plugin-extensions-bonjour + Bonjour/Avahi control plugin + Bonjour/Avahi control plugin + + + + Reichi + Bonjour + enigma2-plugin-extensions-bonjour + Bonjour/Avahi kontroll plugin + Bonjour/Avahi kontroll plugin + + + + + + diff --git a/bonjour/src/Bonjour.py b/bonjour/src/Bonjour.py new file mode 100644 index 0000000..55f60a5 --- /dev/null +++ b/bonjour/src/Bonjour.py @@ -0,0 +1,232 @@ +# -*- coding: utf-8 -*- +from enigma import eConsoleAppContainer, eTimer +from xml.etree.cElementTree import parse as cet_parse +from os import path, listdir +from os import remove as os_remove + +class Bonjour: + AVAHI_SERVICES_DIR = '/etc/avahi/services/' + AVAHI_START_SCRIPT = '/etc/init.d/avahi-daemon' + + def __init__(self): + self.services = [] + self.files = {} + + self.container = eConsoleAppContainer() + self.container.appClosed.append(self.cmdFinished) + + self._timer = eTimer() + self._timer.callback.append(self.restartDaemon) + self._timerRunning = False + + self.reloadConfig() + + def __createServiceConfig(self, service): + lines = [ + '\n', + '\n', + '\n', + '\n', + '\t%s\n' %(service['name']), + '\t\n', + '\t\t%s\n' %(service['type']), + '\t\t%s\n' %(service['port']) + ] + + if service['text'] is not None and service['text'] != "": + lines.add('\t\t%s\n' %(service['text']) ) + + lines.extend([ + '\t\n', + '\n' + ]) + + return lines + + def __writeService(self, service): + print "[Bonjour.__writeService] Creating service file '%s'" %(service['file']) + if 'type' in service and 'port' in service and 'file' in service: + filepath = "%s%s" %(self.AVAHI_SERVICES_DIR, service['file']) + file = open(filepath, 'w'); + file.writelines(self.__createServiceConfig(service)) + file.close() + return True + + print "[Bonjour.__writeService] Cannot create service file '%s'" %(service['file']) + return False + + def __deleteService(self, protocol): + filepath = "%s%s.service" %(self.AVAHI_SERVICES_DIR, protocol) + if path.exists(filepath): + + os_remove(filepath) + return True + + return False + + def __parse(self, file): + print "[Bonjour.__parse] parsing %s%s" %(self.AVAHI_SERVICES_DIR, file) + config = cet_parse(self.AVAHI_SERVICES_DIR + file).getroot() + + name = config.find('name').text + + service = config.find('service') + type = service.find('type').text + port = service.find('port').text + text = service.get('text-record') + if text is None: + text = "" + else: + text = text.text + + service = self.buildServiceFull(file, name, type, port, text) + self.registerService(service) + + def __removeServiceFromList(self, service): + oldservices = self.services + self.services = [] + + for s in oldservices: + if s['file'] != service['file']: + self.services.append(s) + self.files[s['file']] = len(self.services) - 1 + + self.files[service['file']] = None + + + def reloadConfig(self): + self.services = [] + self.files = {} + if path.exists(self.AVAHI_SERVICES_DIR): + print "[Bonjour.reloadConfig] reloading config" + service_files = filter( lambda x: x.endswith('.service'), listdir(self.AVAHI_SERVICES_DIR) ) + for file in service_files: + self.__parse(file) + + self.registerDefaultServices() + + + def registerService(self, service, replace = False): + print "[Bonjour.registerService] %s" %service + + if 'type' in service and 'port' in service and 'file' in service: + if (service['file'] not in self.files) or replace: + filepath = "%s%s" %(self.AVAHI_SERVICES_DIR, service['file']) + if not self.__writeService(service): + return False + + if replace and service['file'] in self.files: + self.__removeServiceFromList(service) + + + self.services.append(service) + self.files[service['file']] = len(self.services) - 1 + + if self._timerRunning: + self._timer.stop() + + #if no other service is being registered for 15 seconds restart the daemon + self._timer.start(15000) + self._timerRunning = True + + return True + + else: + print "[Bonjour.registerService] Missing port or type definition in %s%s" %(self.AVAHI_SERVICES_DIR, service['file']) + return False + + + def updateService(self, service): + if 'type' in service and 'port' in service and 'file' in service: + + filepath = "%s%s" %(self.AVAHI_SERVICES_DIR, service['file']) + if not path.exists(filepath): + print "[Bonjour.updateService] Cannot update non-existent service file '%s'" %(service['file']) + return False + + else: + if not self.__writeService(service): + print "[Bonjour.updateService] Cannot write service file '%s'" %(service['file']) + return False + + return True + + def unregisterService(self, protocol): + if self.__deleteService(protocol): + self.reloadConfig() + + + def buildService(self, protocol, port, text="", udp = False): + file = "%s.service" %protocol + + type = "_%s._tcp" %protocol + if udp: + type = "_%s._udp" %protocol + + name = "%h " + name += protocol.upper() + + return { + 'file' : file, + 'name' : name, + 'type' : type, + 'port' : port, + 'text' : text + } + + def buildServiceFull(self, file, name, type, port, text="", udp = False): + return { + 'file' : file, + 'name' : name, + 'type' : type, + 'port' : port, + 'text' : text + } + + def registerDefaultServices(self): + print "[Bonjour.registerDefaultServices] called" + service = self.buildService('ftp', '21') + filepath = "%s%s" %(self.AVAHI_SERVICES_DIR, service['file']) + if not path.exists(filepath): + self.registerService(service) + + service = self.buildService('ssh', '22') + filepath = "%s%s" %(self.AVAHI_SERVICES_DIR, service['file']) + if not path.exists(filepath): + self.registerService(service) + + service = self.buildService('sftp-ssh', '22') + filepath = "%s%s" %(self.AVAHI_SERVICES_DIR, service['file']) + if not path.exists(filepath): + self.registerService(service) + + service = self.buildService('smb', '139') + filepath = "%s%s" %(self.AVAHI_SERVICES_DIR, service['file']) + if not path.exists(filepath): + self.registerService(service) + + def stopTimer(self): + if self._timerRunning: + self._timer.stop() + + def startDaemon(self): + print "[Bonjour.startDaemon] called" + cmd = [self.AVAHI_START_SCRIPT, 'start'] + self.container.execute(*cmd) + + def stopDaemon(self): + print "[Bonjour.stopDaemon] called" + cmd = [self.AVAHI_START_SCRIPT, 'stop'] + self.container.execute(*cmd) + + def restartDaemon(self): + print "[Bonjour.restartDaemon] called" + self.stopTimer() + + cmd = [self.AVAHI_START_SCRIPT, 'restart'] + self.container.execute(*cmd) + + def cmdFinished(self, data): + print "[Bonjour.cmdFinished] %s" %(data) + +bonjour = Bonjour() \ No newline at end of file diff --git a/bonjour/src/Makefile.am b/bonjour/src/Makefile.am new file mode 100644 index 0000000..d5f4adb --- /dev/null +++ b/bonjour/src/Makefile.am @@ -0,0 +1,3 @@ +installdir = $(LIBDIR)/enigma2/python/Plugins/Extensions/Bonjour + +install_PYTHON = __init__.py plugin.py Bonjour.py diff --git a/bonjour/src/__init__.py b/bonjour/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bonjour/src/plugin.py b/bonjour/src/plugin.py new file mode 100644 index 0000000..e2fbc3c --- /dev/null +++ b/bonjour/src/plugin.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- + +from enigma import eListboxPythonMultiContent, gFont + +from Plugins.Plugin import PluginDescriptor +from Bonjour import bonjour + +from Screens.Screen import Screen +from Components.MenuList import MenuList +from Components.MultiContent import MultiContentEntryText +from Components.ActionMap import ActionMap + +class BonjourScreen(Screen): + skin = """ + + + """ + + def __init__(self, session, services, files): + Screen.__init__(self, session) + self.session = session + self.services = services + self.files = files + + self["menuList"] = MenuList([], content=eListboxPythonMultiContent) + self["menuList"].l.setItemHeight(75) + self["menuList"].l.setFont(0, gFont("Regular", 20) ) + self["menuList"].l.setFont(1, gFont("Regular", 16) ) + + self["actions"] = ActionMap(["OkCancelActions"], + { + "ok": self._ok, + "cancel": self._exit, + }, -1) + + self.onLayoutFinish.append(self.buildMenu) + self.onLayoutFinish.append(self.layoutFinished) + + def layoutFinished(self): + print "LAYOUT FINISHED!!" + self.setTitle(_("Bonjour: Overview")) + + def _ok(self): + print "OK OK OK OK" + pass + + def _exit(self): + self.close() + + def buildMenu(self): + list = [] + for key in sorted(self.files): + if self.files[key] != None: + list.append( self.__buildMenuEntry(self.services[self.files[key]]) ) + + self["menuList"].l.setList(list) + self["menuList"].setList(list) + + def __buildMenuEntry(self, service): + print "[Bonjour.__buildMenuEntry] service=%s" %service + + file = "%s" %(service['file']) + name = "Name: %s" %(service['name']) + type = "Type: %s" %(service['type'].split('.')[0].replace('_','')) + prot = "Protocol: %s" %(service['type'].split('.')[1].replace('_','')) + port = "Port: %s" %(service['port']) + text = "Text: %s" %(service['text']) + + return [ + service, + MultiContentEntryText(pos=(5, 0), size=(185, 30), font=0, text=file), + MultiContentEntryText(pos=(190, 0), size=(385, 30), font=0, text=name), + MultiContentEntryText(pos=(5, 25), size=(150, 30), font=1, text=type), + MultiContentEntryText(pos=(160, 25), size=(150, 30), font=1, text=prot), + MultiContentEntryText(pos=(315, 25), size=(150, 30), font=1, text=port), + MultiContentEntryText(pos=(5, 45), size=(570, 30), font=1, text=text) + ] + +def opencontrol(session): + bonjour.reloadConfig() + session.open(BonjourScreen, bonjour.services, bonjour.files) + print "[Bonjour.opencontrol] %s" %(bonjour.files) + #TODO GUI-Stuff + + +def Plugins(**kwargs): + return [ PluginDescriptor( + name=_("Bonjour"), description=_("Control Bonjour (avahi-daemon)"), + where=[PluginDescriptor.WHERE_PLUGINMENU], icon="plugin.png", fnc=opencontrol) + ] diff --git a/configure.ac b/configure.ac index 6fbcc96..76dff3d 100644 --- a/configure.ac +++ b/configure.ac @@ -63,6 +63,10 @@ babelzapper/etc/Makefile babelzapper/meta/Makefile babelzapper/src/Makefile +bonjour/Makefile +bonjour/meta/Makefile +bonjour/src/Makefile + cdinfo/Makefile cdinfo/meta/Makefile cdinfo/src/Makefile