# -*- coding: utf-8 -*-
#
# Software Update Check Plugin by gutemine
#
# Version 2.0.1
#

from Plugins.Plugin import PluginDescriptor
from Components.config import config, ConfigSubsection, ConfigEnableDisable, ConfigInteger, ConfigSelection
from enigma import eTimer
from Screens.Screen import Screen
from Components.ConfigList import ConfigListScreen
from Screens.Setup import SetupSummary
from Components.ActionMap import ActionMap
from Components.config import config, getConfigListEntry
from Components.Label import Label, MultiColorLabel
from Screens.Console import Console
from Screens.MessageBox import MessageBox
from Screens.InputBox import InputBox
from Screens.ChoiceBox import ChoiceBox
from enigma import eConsoleAppContainer
from enigma import quitMainloop
import Screens.Standby
import gettext
import os

updatelog_lines=15
global updatelog_topline
global freefilesystem
global freememory
updatelog_topline=0
updatecheck_options=""

updatecheck_plugindir="/usr/lib/enigma2/python/Plugins/Extensions/UpdateCheck"
# 1 hour (use smaller value for debugging)
updatecheck_period=3600000
# 15min (use smaller value for debugging)
updatecheck_dummyperiod=900000
updatecheck_testcommand="apt-get -s upgrade 0imageupdate"
updatecheck_logfile="/media/hdd/updatecheck.log"

# add local language file
sp=config.osd.language.value.split("_")
updatecheck_language = sp[0]
if os.path.exists("%s/locale/%s" % (updatecheck_plugindir,updatecheck_language)):
   os.environ["LANGUAGE"] = config.osd.language.value
   _=gettext.Catalog('updatecheck', '%s/locale' % updatecheck_plugindir).gettext

config.plugins.checksoftwareupdate = ConfigSubsection()
config.plugins.checksoftwareupdate.enabled = ConfigEnableDisable(default = False)
config.plugins.checksoftwareupdate.period = ConfigInteger(default = 0, limits = (0, 24))
config.plugins.checksoftwareupdate.timeout = ConfigInteger(default = 10, limits = (0, 60))
config.plugins.checksoftwareupdate.install = ConfigEnableDisable(default = False)
config.plugins.checksoftwareupdate.logfile = ConfigEnableDisable(default = False)
config.plugins.checksoftwareupdate.reboot = ConfigEnableDisable(default = True)
config.plugins.checksoftwareupdate.duringstandby = ConfigEnableDisable(default = False)
#feeds=[]
#for feed in os.listdir("/etc/dpkg"):  
#        if feed.startswith("dpkg."):
#	        feeds.append(( feed, feed.replace("dpkg.","") ))
#config.plugins.checksoftwareupdate.feed = ConfigSelection(default = "dpkg.1", choices = feeds)

def autostart(reason, **kwargs):
    global session
    if kwargs.has_key("session") and reason == 0:
        session = kwargs["session"]
        print "[CHECKSOFTWAREUPDATE] autostart check"
#    	if os.path.exists("/etc/dpkg/dpkg.conf"):
#    		feed=os.readlink("/etc/dpkg/dpkg.conf")
#    		if feed != config.plugins.checksoftwareupdate.feed.value:
#    			os.remove("/etc/dpkg/dpkg.conf")
#    			os.symlink("/etc/dpkg/%s" % config.plugins.checksoftwareupdate.feed.value, "/etc/dpkg/dpkg.conf")
#    	else:
#		os.symlink("/etc/dpkg/%s" % config.plugins.checksoftwareupdate.feed.value, "/etc/dpkg/dpkg.conf")
        session.open(SoftwareUpdateCheck)

def Plugins(**kwargs):
    return [PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc = autostart),
    		PluginDescriptor(name=_("Update Check"), description=_("check for Software Update"), where = PluginDescriptor.WHERE_PLUGINMENU, icon="updatecheck.png", fnc=main),
		PluginDescriptor(name=_("Update Check"), description=_("check for Software Update"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, icon="updatecheck.png", fnc=main)]

def main(session, **kwargs):
	global freefilesystem
	global freememory
        st = os.statvfs("/")                                                                           
        free = st.f_bavail * st.f_frsize/1024/1024                                                               
        total = st.f_blocks * st.f_frsize/1024/1024                                                
        used = (st.f_blocks - st.f_bfree) * st.f_frsize/1024/1024 
	freefilesystem=_("Root Filesystem\n\ntotal: %s MB\nused:  %s MB\nfree:  %s MB") % (total,used,free)		
      	memfree=0
      	memtotal=0
      	memused=0
	fm=open("/proc/meminfo")
      	line = fm.readline()
      	sp=line.split()
      	memtotal=int(sp[1])/1024
      	line = fm.readline()
      	sp=line.split()
      	memfree=int(sp[1])/1024
	fm.close()
	memused=memtotal-memfree
	freememory=_("Memory\n\ntotal: %i MB\nused: %i MB\nfree: %i MB") % (memtotal,memused,memfree)		
        print "[CHECKSOFTWAREUPDATE] Open Config Screen"
        session.open(CheckSoftwareUpdateConfiguration)

class CheckSoftwareUpdateConfiguration(Screen, ConfigListScreen):
    skin = """
        <screen position="center,center" size="610,450" title="Configuration for Softwareupdate Check" >
        <widget name="config" position="0,0" size="600,220" scrollbarMode="showOnDemand" />
        <widget name="buttonred" position="10,400" size="140,40" backgroundColor="red" valign="center" halign="center" zPosition="2"  foregroundColor="white" font="Regular;18"/>
        <widget name="buttongreen" position="160,400" size="140,40" backgroundColor="green" valign="center" halign="center" zPosition="2"  foregroundColor="white" font="Regular;18"/>
        <widget name="buttonyellow" position="310,400" size="140,40" backgroundColor="yellow" valign="center" halign="center" zPosition="2"  foregroundColor="white" font="Regular;18"/>
        <widget name="buttonblue" position="460,400" size="140,40" backgroundColor="blue" valign="center" halign="center" zPosition="2"  foregroundColor="white" font="Regular;18"/>
        <widget name="freefilesystem" position="130,220" size="140,180" valign="center" halign="center" zPosition="2"  foregroundColor="white" font="Regular;18"/>
        <widget name="freememory" position="330,220" size="140,180" valign="center" halign="center" zPosition="2"  foregroundColor="white" font="Regular;18"/>
        </screen>"""

    def __init__(self, session, args = 0):
	Screen.__init__(self, session)
       	self.list = []
        self.list.append(getConfigListEntry(_("Updatecheck on enigma2 startup"), config.plugins.checksoftwareupdate.enabled))
        self.list.append(getConfigListEntry(_("Updatecheck periodically in hours"), config.plugins.checksoftwareupdate.period))
        self.list.append(getConfigListEntry(_("Confirmation timeout in seconds (0=none)"), config.plugins.checksoftwareupdate.timeout))
        self.list.append(getConfigListEntry(_("Installation confirmation default answer"), config.plugins.checksoftwareupdate.install))
        self.list.append(getConfigListEntry(_("Logfile view default answer"), config.plugins.checksoftwareupdate.logfile))
        self.list.append(getConfigListEntry(_("Reboot confirmation default answer"), config.plugins.checksoftwareupdate.reboot))
        self.list.append(getConfigListEntry(_("Output also during Standby"), config.plugins.checksoftwareupdate.duringstandby))
#       self.list.append(getConfigListEntry(_("Std. Feeds"), config.plugins.checksoftwareupdate.feed))
        self.onShown.append(self.setWindowTitle)
       	ConfigListScreen.__init__(self, self.list)

        # explizit check on every entry
	self.onChangedEntry = []
	global freefilesystem
	global freememory

       	self["buttonred"] = Label(_("Cancel"))
       	self["buttongreen"] = Label(_("OK"))
       	self["buttonyellow"] = Label(_("Check"))
       	self["buttonblue"] = Label(_("Logfile"))
       	self["freefilesystem"] = Label(freefilesystem)
       	self["freememory"] = Label(freememory)
        self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
       	{
       		"green": self.save,
        	"red": self.cancel,
        	"yellow": self.Check4Update,
        	"blue": self.ShowLogfile,
            	"save": self.save,
            	"cancel": self.cancel,
            	"ok": self.save,
       	})
    def setWindowTitle(self):
        self.setTitle(_("Configuration for Softwareupdate Check"))

    def save(self):
#    	if os.path.exists("/etc/dpkg/dpkg.conf"):
#    		feed=os.readlink("/etc/dpkg/dpkg.conf")
#    		if feed != config.plugins.checksoftwareupdate.feed.value:
#    			os.remove("/etc/dpkg/dpkg.conf")
#    			os.symlink("/etc/dpkg/%s" % config.plugins.checksoftwareupdate.feed.value, "/etc/dpkg/dpkg.conf")
#    	else:
#		os.symlink("/etc/dpkg/%s" % config.plugins.checksoftwareupdate.feed.value, "/etc/dpkg/dpkg.conf")
        for x in self["config"].list:
           x[1].save()
        self.close(True)

    def cancel(self):
        for x in self["config"].list:
           x[1].cancel()
        self.close(False)

    def ShowLogfile(self):
	if os.path.exists(updatecheck_logfile):
       		session.open(ShowUpdateLog)
	else:
        	self.session.open(MessageBox,_("no update logfile found at:\n%s") % updatecheck_logfile ,type = MessageBox.TYPE_ERROR,timeout =  config.plugins.checksoftwareupdate.timeout.value)		

    def Check4Update(self):
        global softwareupdatefound
        softwareupdatefound=False
        for x in self["config"].list:
           x[1].save()
        self.container = eConsoleAppContainer()
        self.appClosed_conn = self.container.appClosed.connect(self.runFinished)
        self.container.execute("opkg update")

    def runFinished(self, retval):
        self.container = eConsoleAppContainer()
        self.appClosed_conn = self.container.appClosed.connect(self.runFinished)
        self.dataAvail_conn = self.container.dataAvail.connect(self.dataAvail)
        self.appClosed_conn = self.container.appClosed.connect(self.runFinished2)
        self.container.execute(updatecheck_testcommand)

    def runFinished2(self, retval):
        global softwareupdatefound
        if softwareupdatefound is True:
           softwareupdatefound=False
        else:
           self.session.open(MessageBox,_("no Softwareupdate available") ,type = MessageBox.TYPE_INFO,timeout =  config.plugins.checksoftwareupdate.timeout.value)		

    def dataAvail(self, str):
        global softwareupdatefound
        global softwareupdatefrom
        global softwareupdateto
	print "[UPDATECHECK] %s" % str
        if str.find(" upgraded, 0") is not -1 and not softwareupdatefound and not str.startswith("0"):
		str2 = str.replace("[","").replace("]","").replace("(","").replace(",","")
		print str2
		parts = str2.split(" ")
 		print parts
       		softwareupdatefound=True 
        	softwareupdatefrom=parts[13]
        	softwareupdateto=parts[14]
          	SoftwareUpdateCheckExecution(self.session)

class SoftwareUpdateCheck(Screen):
#    skin = """
#        <screen position="150,100" size="400,300" title="Softwareupdate Check" >
#        </screen>"""
    def __init__(self,session):
#       self.skin = SoftwareUpdateCheck.skin
	self.session = session
	Screen.__init__(self,session)

        print "[CHECKSOFTWAREUPDATE] doing check"
        self.TimerSoftwareUpdateCheck = eTimer()
        self.TimerSoftwareUpdateCheck.stop()
        self.TimerSoftwareUpdateCheck_conn = self.TimerSoftwareUpdateCheck.timeout.connect(self.CheckSoftwareUpdate)
        if config.plugins.checksoftwareupdate.period.value > 0:
           print "[CHECKSOFTWAREUPDATE] planning periodic check"
           self.TimerSoftwareUpdateCheck.start(config.plugins.checksoftwareupdate.period.value*updatecheck_period,True) 
        else:
           # just for catching if period value changes
           print "[CHECKSOFTWAREUPDATE] planning dummy check"
           self.TimerSoftwareUpdateCheck.start(updatecheck_dummyperiod,True) 
        if config.plugins.checksoftwareupdate.enabled.value:
           self.TimerStartupSoftwareUpdateCheck = eTimer()
           self.TimerStartupSoftwareUpdateCheck.stop()
           self.TimerStartupSoftwareUpdateCheck_conn = self.TimerStartupSoftwareUpdateCheck.timeout.connect(self.StartupCheckSoftwareUpdate)
           self.TimerStartupSoftwareUpdateCheck.start(30000,True) 

    def StartupCheckSoftwareUpdate(self):
        self.TimerStartupSoftwareUpdateCheck.stop()
        self.container = eConsoleAppContainer()
        self.appClosed_conn = self.container.appClosed.connect(self.runFinished)
        self.container.execute("opkg update")

    def CheckSoftwareUpdate(self):
        self.TimerSoftwareUpdateCheck.stop()
        global softwareupdatefound
        softwareupdatefound=False
        if config.plugins.checksoftwareupdate.period.value > 0:
           self.container = eConsoleAppContainer()
           self.appClosed_conn = self.container.appClosed.connect(self.runFinished)
           self.container.execute("opkg update")
           print "[CHECKSOFTWAREUPDATE] planning periodic check"
           self.TimerSoftwareUpdateCheck.start(config.plugins.checksoftwareupdate.period.value*updatecheck_period,True) 
        else:
           # just for catching if period value changes
           print "[CHECKSOFTWAREUPDATE] planning dummy check"
           self.TimerSoftwareUpdateCheck.start(updatecheck_dummyperiod,True) 

    def runFinished(self, retval):
        global softwareupdatefound
        softwareupdatefound=False
        self.container = eConsoleAppContainer()
        self.dataAvail_conn = self.container.dataAvail.connect(self.dataAvail)
        self.container.execute(updatecheck_testcommand)

    def dataAvail(self, str):
        global softwareupdatefrom
        global softwareupdateto
        global softwareupdatefound
	print "[UPDATECHECK] %s" % str
        if str.find(" upgraded, 0") is not -1 and not softwareupdatefound and not str.startswith("0"):
		str2 = str.replace("[","").replace("]","").replace("(","").replace(",","")
		print str2
		parts = str2.split(" ")
		print parts
		softwareupdatefound=True
		softwareupdatefrom=parts[13]
		softwareupdateto=parts[14]
		SoftwareUpdateCheckExecution(self.session)

class SoftwareUpdateCheckExecution(Screen):
    skin = """
        <screen position="150,100" size="400,300" title="Softwareupdate Check" >
        </screen>"""
        
    def __init__(self,session):
        self.skin = SoftwareUpdateCheckExecution.skin
	self.session = session
	Screen.__init__(self,session)
        global softwareupdatefrom
        global softwareupdateto
        if len(config.tv.lastservice.value) == 0:
		print "[CHECKSOFTWAREUPDATE] first run, don't check this time"
		return
        if config.plugins.checksoftwareupdate.duringstandby.value:
           self.session.openWithCallback(self.CheckPreSoftwareUpdate,MessageBox,_("Softwareupdate available from %s to %s,\ndo you want to update now ?") % (softwareupdatefrom,softwareupdateto),type = MessageBox.TYPE_YESNO,timeout = config.plugins.checksoftwareupdate.timeout.value, default = config.plugins.checksoftwareupdate.install.value)		
        else:
           if not Screens.Standby.inStandby:
              self.session.openWithCallback(self.CheckPreSoftwareUpdate,MessageBox,_("Softwareupdate available from %s to %s,\ndo you want to update now ?") % (softwareupdatefrom,softwareupdateto),type = MessageBox.TYPE_YESNO,timeout = config.plugins.checksoftwareupdate.timeout.value, default = config.plugins.checksoftwareupdate.install.value)		
           else:
              print "[CHECKSOFTWAREUPDATE] found something to upgrade, but output in standby is disabled"

    def CheckPreSoftwareUpdate(self,retval):
	if (retval):
           if os.path.exists("/usr/script/updatecheck.sh") is True:
              self.session.openWithCallback(self.DoSoftwareUpdate,Console,_("updatecheck.sh start"),["/usr/script/updatecheck.sh start"])
           else:
              self.DoSoftwareUpdate()

    def DoSoftwareUpdate(self):
        self.container = eConsoleAppContainer()
        self.appClosed_conn = self.container.appClosed.connect(self.runFinished)
        self.container.execute("opkg %s upgrade > %s" % (updatecheck_options,updatecheck_logfile))
           
    def runFinished(self, retval):
        self.session.openWithCallback(self.CheckPostSoftwareUpdate,MessageBox,_("Softwareupdate done!"),type=MessageBox.TYPE_INFO, timeout= config.plugins.checksoftwareupdate.timeout.value)

    def CheckPostSoftwareUpdate(self,retval):
           if os.path.exists("/usr/script/updatecheck.sh") is True:
              self.session.openWithCallback(self.AskShowLogfile,Console,_("updatecheck.sh stop"),["/usr/script/updatecheck.sh stop"])
           else:
              self.AskShowLogfile()

    def AskShowLogfile(self):
        self.session.openWithCallback(self.DoShowLogfile,MessageBox,_("do you want to see update logfile?"), type = MessageBox.TYPE_YESNO,timeout = config.plugins.checksoftwareupdate.timeout.value, default = config.plugins.checksoftwareupdate.logfile.value)		

    def DoShowLogfile(self,retval):
	if (retval):
              self.session.openWithCallback(self.AskRebootSoftwareUpdate,ShowUpdateLog)
	else:
              self.AskRebootSoftwareUpdate(True)

    def AskRebootSoftwareUpdate(self,retval):
        self.session.openWithCallback(self.DoRebootSoftwareUpdate,MessageBox,_("do you want to reboot now after the Softwareupdate ?"), type = MessageBox.TYPE_YESNO,timeout = config.plugins.checksoftwareupdate.timeout.value, default = config.plugins.checksoftwareupdate.reboot.value)		

    def DoRebootSoftwareUpdate(self,retval):
	if (retval):
           quitMainloop(2)

class ShowUpdateLog(Screen):
 	skin = """
		<screen position="center,center" size="620,500">
		<widget name="showupdatelog" position="0,0" size="620,500" font="Regular;16" valign="left" halign="left">
		</widget>
		</screen>"""
	def __init__(self, session):
		Screen.__init__(self, session)
		self.skin = ShowUpdateLog.skin
		global updatelog_topline
		updatelog_topline=0
		i=0
		if os.path.exists(updatecheck_logfile) == True:
	   			f = open(updatecheck_logfile)               
				i=0
				for line in f:
    					i=i+1
				f.close()
		if i>updatelog_lines:
    			updatelog_topline=i-updatelog_lines
 		self["showupdatelog"] = MultiColorLabel("\n")
		self.showUpdateLogPage()
                self["setupActions"] = ActionMap([ "ColorActions", "SetupActions", "InfobarMovieListActions" ],                         
                        {                                                                                    
                        "red": self.cancel,                                                                  
                        "cancel": self.cancel,                                                               
                        "ok": self.cancel,                                                                     
		        "left": self.pagebackward,                                                                           
			"right": self.pageforward,                                                                       
		        "up": self.backward,                                                                           
			"down": self.forward,                                                                       
                        })                                                                                   

	def setWindowTitle(self):
		self.setTitle(_("Display Last Update Log"))

	def showUpdateLogPage(self):                                                                     
			global updatelog_topline
			if os.path.exists(updatecheck_logfile) == True:
	   			f = open(updatecheck_logfile)               
				updatelogtext = ""                            
				i=0
#				print updatelog_topline
				while i<(updatelog_topline+updatelog_lines):
					if i>(updatelog_topline-1):
						text=f.readline()
   						updatelogtext = updatelogtext+text                           
					else:
						text=f.readline()
					i=i+1

   				f.close
   	     			self["showupdatelog"].setText(updatelogtext)    
			else:
   	     			self["showupdatelog"].setText(_("%s not found") % updatecheck_logfile   )    

	def cancel(self):
		self.close(False)

        def backward(self):      
		global updatelog_topline
		updatelog_topline=updatelog_topline-1
		if updatelog_topline<0:
			updatelog_topline=0
		self.showUpdateLogPage()

        def forward(self):      
		global updatelog_topline
		updatelog_topline=updatelog_topline+1
		self.showUpdateLogPage()

        def pagebackward(self):      
		global updatelog_topline
		global updatelog_lines
		updatelog_topline=updatelog_topline-updatelog_lines
		if updatelog_topline<0:
			updatelog_topline=0
		self.showUpdateLogPage()

        def pageforward(self):      
		global updatelog_topline
		global updatelog_lines
		updatelog_topline=updatelog_topline+updatelog_lines
		self.showUpdateLogPage()
