michael@21: # -*- coding: UTF-8 -*- michael@21: # Mosaic by AliAbdul michael@21: from Components.ActionMap import NumberActionMap michael@21: from Components.config import config, ConfigSubsection, ConfigInteger michael@21: from Components.Console import Console michael@21: from Components.Label import Label michael@21: from Components.Language import language michael@21: from Components.Pixmap import Pixmap michael@21: from Components.VideoWindow import VideoWindow michael@21: from enigma import eServiceCenter, eServiceReference, eTimer, getDesktop, loadPNG michael@21: from os import environ michael@21: from Plugins.Plugin import PluginDescriptor michael@21: from Screens.ChannelSelection import BouquetSelector michael@21: from Screens.MessageBox import MessageBox michael@21: from Screens.Screen import Screen michael@21: from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE, SCOPE_LANGUAGE, SCOPE_PLUGINS michael@21: from Tools.LoadPixmap import LoadPixmap michael@21: import gettext michael@21: michael@21: ################################################ michael@21: michael@21: grab_binary = "/usr/bin/grab" michael@21: grab_picture = "/tmp/mosaic.jpg" michael@21: grab_errorlog = "/tmp/mosaic.log" michael@21: michael@21: config_limits = (3, 30) michael@21: config.plugins.Mosaic = ConfigSubsection() michael@21: config.plugins.Mosaic.countdown = ConfigInteger(default=5, limits=config_limits) michael@21: michael@21: playingIcon = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/ico_mp_play.png')) michael@21: pausedIcon = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/ico_mp_pause.png')) michael@21: michael@21: ################################################ michael@21: michael@21: lang = language.getLanguage() michael@21: environ["LANGUAGE"] = lang[:2] michael@21: gettext.bindtextdomain("enigma2", resolveFilename(SCOPE_LANGUAGE)) michael@21: gettext.textdomain("enigma2") michael@21: gettext.bindtextdomain("Mosaic", "%s%s" % (resolveFilename(SCOPE_PLUGINS), "Extensions/Mosaic/locale/")) michael@21: michael@21: def _(txt): michael@21: t = gettext.dgettext("Mosaic", txt) michael@21: if t == txt: michael@21: t = gettext.gettext(txt) michael@21: return t michael@21: michael@21: ################################################ michael@21: michael@21: class Mosaic(Screen): michael@21: PLAY = 0 michael@21: PAUSE = 1 michael@21: michael@21: desktop = getDesktop(0) michael@21: size = desktop.size() michael@21: width = size.width() michael@21: height = size.height() michael@21: windowWidth = width / 4 michael@21: windowHeight = height / 4 michael@21: michael@21: positions = [] michael@21: x = 80 michael@22: y = 40 michael@21: for i in range(1, 10): michael@21: positions.append([x, y]) michael@21: x += windowWidth michael@21: x += ((width - 160) - (windowWidth * 3)) / 2 michael@21: if (i == 3) or (i == 6): michael@22: y = y + windowHeight + 40 michael@21: x = 80 michael@21: michael@21: skin = "" michael@22: skin += """""" % (width, height) michael@21: skin += """""" michael@22: skin += """""" % (positions[0][0]-2, positions[0][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[1][0]-2, positions[1][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[2][0]-2, positions[2][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[3][0]-2, positions[3][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[4][0]-2, positions[4][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[5][0]-2, positions[5][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[6][0]-2, positions[6][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[7][0]-2, positions[7][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[8][0]-2, positions[8][1]+1, windowWidth, windowHeight) michael@21: michael@22: skin += """""" % (positions[0][0]-2, positions[0][1]-18, windowWidth-4) michael@22: skin += """""" % (positions[1][0]-2, positions[1][1]-18, windowWidth-4) michael@22: skin += """""" % (positions[2][0]-2, positions[2][1]-18, windowWidth-4) michael@22: skin += """""" % (positions[3][0]-2, positions[3][1]-18, windowWidth-4) michael@22: skin += """""" % (positions[4][0]-2, positions[4][1]-18, windowWidth-4) michael@22: skin += """""" % (positions[5][0]-2, positions[5][1]-18, windowWidth-4) michael@22: skin += """""" % (positions[6][0]-2, positions[6][1]-18, windowWidth-4) michael@22: skin += """""" % (positions[7][0]-2, positions[7][1]-18, windowWidth-4) michael@22: skin += """""" % (positions[8][0]-2, positions[8][1]-18, windowWidth-4) michael@22: michael@22: skin += """""" % (positions[0][0]-2, positions[0][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[1][0]-2, positions[1][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[2][0]-2, positions[2][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[3][0]-2, positions[3][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[4][0]-2, positions[4][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[5][0]-2, positions[5][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[6][0]-2, positions[6][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[7][0]-2, positions[7][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[8][0]-2, positions[8][1]+1, windowWidth, windowHeight) michael@22: michael@22: # Playing video moving pictures michael@22: skin += """""" % (positions[0][0]-2, positions[0][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[1][0]-2, positions[1][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[2][0]-2, positions[2][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[3][0]-2, positions[3][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[4][0]-2, positions[4][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[5][0]-2, positions[5][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[6][0]-2, positions[6][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[7][0]-2, positions[7][1]+1, windowWidth, windowHeight) michael@22: skin += """""" % (positions[8][0]-2, positions[8][1]+1, windowWidth, windowHeight) michael@22: michael@22: # Zweite Zeile Sendung michael@22: skin += """""" % (positions[0][0]-2, positions[0][1]-1, windowWidth) michael@22: skin += """""" % (positions[1][0]-2, positions[1][1]-1, windowWidth) michael@22: skin += """""" % (positions[2][0]-2, positions[2][1]-1, windowWidth) michael@22: skin += """""" % (positions[3][0]-2, positions[3][1]-1, windowWidth) michael@22: skin += """""" % (positions[4][0]-2, positions[4][1]-1, windowWidth) michael@22: skin += """""" % (positions[5][0]-2, positions[5][1]-1, windowWidth) michael@22: skin += """""" % (positions[6][0]-2, positions[6][1]-1, windowWidth) michael@22: skin += """""" % (positions[7][0]-2, positions[7][1]-1, windowWidth) michael@22: skin += """""" % (positions[8][0]-2, positions[8][1]-1, windowWidth) michael@22: michael@22: skin += """""" % (height-40, windowWidth) michael@22: skin += """ michael@22: """ % (positions[2][0] ,height-40, windowWidth) michael@21: michael@21: def __init__(self, session, services): michael@21: Screen.__init__(self, session) michael@21: michael@21: self.session = session michael@21: self.oldService = self.session.nav.getCurrentlyPlayingServiceReference() michael@21: self.consoleCmd = "" michael@21: self.Console = Console() michael@21: self.serviceHandler = eServiceCenter.getInstance() michael@21: self.ref_list = services michael@21: self.window_refs = [None, None, None, None, None, None, None, None, None] michael@21: self.current_refidx = 0 michael@21: self.current_window = 1 michael@21: self.countdown = config.plugins.Mosaic.countdown.value michael@21: self.working = False michael@21: self.state = self.PLAY michael@21: michael@21: self["playState"] = Pixmap() michael@21: for i in range(1, 10): michael@21: self["window" + str(i)] = Pixmap() michael@21: self["video" + str(i)] = VideoWindow(decoder=0, fb_width=self.width, fb_height=self.height) michael@21: self["video" + str(i)].hide() michael@21: self["channel" + str(i)] = Label("") michael@21: self["event" + str(i)] = Label("") michael@21: self["event" + str(i)].hide() michael@21: self["video1"].decoder = 0 michael@21: self["video1"].show() michael@21: self["countdown"] = Label() michael@21: self.updateCountdownLabel() michael@21: self["count"] = Label() michael@21: michael@21: self["actions"] = NumberActionMap(["MosaicActions"], michael@21: { michael@21: "ok": self.exit, michael@21: "cancel": self.closeWithOldService, michael@21: "green": self.play, michael@21: "yellow": self.pause, michael@21: "channelup": self.countdownPlus, michael@21: "channeldown": self.countdownMinus, michael@21: "1": self.numberPressed, michael@21: "2": self.numberPressed, michael@21: "3": self.numberPressed, michael@21: "4": self.numberPressed, michael@21: "5": self.numberPressed, michael@21: "6": self.numberPressed, michael@21: "7": self.numberPressed, michael@21: "8": self.numberPressed, michael@21: "9": self.numberPressed michael@21: }, prio=-1) michael@21: michael@21: self.updateTimer = eTimer() michael@21: self.updateTimer.callback.append(self.updateCountdown) michael@21: self.checkTimer = eTimer() michael@21: self.checkTimer.callback.append(self.checkGrab) michael@21: self.checkTimer.start(500, 1) michael@21: michael@21: def checkGrab(self): michael@21: # Start the first service in the bouquet and show the service-name michael@21: ref = self.ref_list[0] michael@21: self.window_refs[0] = ref michael@21: info = self.serviceHandler.info(ref) michael@21: name = info.getName(ref).replace('\xc2\x86', '').replace('\xc2\x87', '') michael@21: event_name = self.getEventName(info, ref) michael@21: self["channel1"].setText(name) michael@21: self["event1"].setText(event_name) michael@21: self.session.nav.playService(ref) michael@21: self["count"].setText(_("Channel: ") + "1 / " + str(len(self.ref_list))) michael@21: self["playState"].instance.setPixmap(playingIcon) michael@21: # Start updating the video-screenshots michael@21: self.updateTimer.start(1, 1) michael@21: michael@21: def exit(self, callback=None): michael@21: self.deleteConsoleCallbacks() michael@21: self.close() michael@21: michael@21: def deleteConsoleCallbacks(self): michael@21: if self.Console.appContainers.has_key(self.consoleCmd): michael@21: del self.Console.appContainers[self.consoleCmd].dataAvail[:] michael@21: del self.Console.appContainers[self.consoleCmd].appClosed[:] michael@21: del self.Console.appContainers[self.consoleCmd] michael@21: del self.Console.extra_args[self.consoleCmd] michael@21: del self.Console.callbacks[self.consoleCmd] michael@21: michael@21: def closeWithOldService(self): michael@21: self.session.nav.playService(self.oldService) michael@21: self.deleteConsoleCallbacks() michael@21: self.close() michael@21: michael@21: def numberPressed(self, number): michael@21: ref = self.window_refs[number-1] michael@21: if ref is not None: michael@21: self.session.nav.playService(ref) michael@21: self.deleteConsoleCallbacks() michael@21: self.close() michael@21: michael@21: def play(self): michael@21: if self.working == False and self.state == self.PAUSE: michael@21: self.state = self.PLAY michael@21: self.updateTimer.start(1000, 1) michael@21: self["playState"].instance.setPixmap(playingIcon) michael@21: michael@21: def pause(self): michael@21: if self.working == False and self.state == self.PLAY: michael@21: self.state = self.PAUSE michael@21: self.updateTimer.stop() michael@21: self["playState"].instance.setPixmap(pausedIcon) michael@21: michael@21: def countdownPlus(self): michael@21: self.changeCountdown(1) michael@21: michael@21: def countdownMinus(self): michael@21: self.changeCountdown(-1) michael@21: michael@21: def changeCountdown(self, direction): michael@21: if self.working == False: michael@21: configNow = config.plugins.Mosaic.countdown.value michael@21: configNow += direction michael@21: michael@21: if configNow < config_limits[0]: michael@21: configNow = config_limits[0] michael@21: elif configNow > config_limits[1]: michael@21: configNow = config_limits[1] michael@21: michael@21: config.plugins.Mosaic.countdown.value = configNow michael@21: config.plugins.Mosaic.countdown.save() michael@21: michael@21: self.updateCountdownLabel() michael@21: michael@21: def makeNextScreenshot(self): michael@21: # Grab video michael@21: if not self.Console: michael@21: self.Console = Console() michael@22: self.consoleCmd = "%s -v -r %d -j 100 %s" % (grab_binary, self.windowWidth, grab_picture) michael@21: self.Console.ePopen(self.consoleCmd, self.showNextScreenshot) michael@21: michael@21: def showNextScreenshot(self, result, retval, extra_args): michael@21: if retval == 0: michael@21: # Show screenshot in the current window michael@21: pic = LoadPixmap(grab_picture) michael@21: self["window" + str(self.current_window)].instance.setPixmap(pic) michael@21: michael@21: # Hide current video-window and show the running event-name michael@21: self["video" + str(self.current_window)].hide() michael@21: self["event" + str(self.current_window)].show() michael@21: michael@21: # Get next ref michael@21: self.current_refidx += 1 michael@21: if self.current_refidx > (len(self.ref_list) -1): michael@21: self.current_refidx = 0 michael@21: michael@21: # Play next ref michael@21: ref = self.ref_list[self.current_refidx] michael@21: info = self.serviceHandler.info(ref) michael@21: name = info.getName(ref).replace('\xc2\x86', '').replace('\xc2\x87', '') michael@21: event_name = self.getEventName(info, ref) michael@21: self.session.nav.playService(ref) michael@21: michael@21: # Get next window index michael@21: self.current_window += 1 michael@21: if self.current_window > 9: michael@21: self.current_window = 1 michael@21: michael@21: # Save the ref michael@21: self.window_refs[self.current_window-1] = ref michael@21: michael@21: # Save the event-name and hide the label michael@21: self["event" + str(self.current_window)].hide() michael@21: self["event" + str(self.current_window)].setText(event_name) michael@21: michael@21: # Show the new video-window michael@21: self["video" + str(self.current_window)].show() michael@21: self["video" + str(self.current_window)].decoder = 0 michael@21: michael@21: # Show the servicename michael@21: self["channel" + str(self.current_window)].setText(name) michael@21: self["count"].setText(_("Channel: ") + str(self.current_refidx + 1) + " / " + str(len(self.ref_list))) michael@21: michael@21: # Restart timer michael@21: self.working = False michael@21: self.updateTimer.start(1, 1) michael@21: else: michael@21: print "[Mosaic] retval: %d result: %s" % (retval, result) michael@21: michael@21: try: michael@21: f = open(grab_errorlog, "w") michael@21: f.write("retval: %d\nresult: %s" % (retval, result)) michael@21: f.close() michael@21: except: michael@21: pass michael@21: michael@21: self.session.openWithCallback(self.exit, MessageBox, _("Error while creating screenshot. You need grab version 0.8 or higher!"), MessageBox.TYPE_ERROR, timeout=5) michael@21: michael@21: def updateCountdown(self, callback=None): michael@21: self.countdown -= 1 michael@21: self.updateCountdownLabel() michael@21: if self.countdown == 0: michael@21: self.countdown = config.plugins.Mosaic.countdown.value michael@21: self.working = True michael@21: self.makeNextScreenshot() michael@21: else: michael@21: self.updateTimer.start(1000, 1) michael@21: michael@21: def updateCountdownLabel(self): michael@21: self["countdown"].setText("%s %s / %s" % (_("Countdown:"), str(self.countdown), str(config.plugins.Mosaic.countdown.value))) michael@21: michael@21: def getEventName(self, info, ref): michael@21: event = info.getEvent(ref) michael@21: if event is not None: michael@21: eventName = event.getEventName() michael@21: if eventName is None: michael@21: eventName = "" michael@21: else: michael@21: eventName = "" michael@21: return eventName michael@21: michael@21: ################################################ michael@21: # Most stuff stolen from the GraphMultiEPG michael@21: michael@21: Session = None michael@21: Servicelist = None michael@21: BouquetSelectorScreen = None michael@21: michael@21: def getBouquetServices(bouquet): michael@21: services = [] michael@21: Servicelist = eServiceCenter.getInstance().list(bouquet) michael@21: if Servicelist is not None: michael@21: while True: michael@21: service = Servicelist.getNext() michael@21: if not service.valid(): michael@21: break michael@21: if service.flags & (eServiceReference.isDirectory | eServiceReference.isMarker): michael@21: continue michael@21: services.append(service) michael@21: return services michael@21: michael@21: def closeBouquetSelectorScreen(ret=None): michael@21: if BouquetSelectorScreen is not None: michael@21: BouquetSelectorScreen.close() michael@21: michael@21: def openMosaic(bouquet): michael@21: if bouquet is not None: michael@21: services = getBouquetServices(bouquet) michael@21: if len(services): michael@21: Session.openWithCallback(closeBouquetSelectorScreen, Mosaic, services) michael@21: michael@21: def main(session, servicelist, **kwargs): michael@21: global Session michael@21: Session = session michael@21: global Servicelist michael@21: Servicelist = servicelist michael@21: global BouquetSelectorScreen michael@21: michael@21: bouquets = Servicelist.getBouquetList() michael@21: if bouquets is not None: michael@21: if len(bouquets) == 1: michael@21: openMosaic(bouquets[0][1]) michael@21: elif len(bouquets) > 1: michael@21: BouquetSelectorScreen = Session.open(BouquetSelector, bouquets, openMosaic, enableWrapAround=True) michael@21: michael@21: def Plugins(**kwargs): michael@21: return PluginDescriptor(name=_("Mosaic"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main)