added unrar functions. show in menu install-function if unrar is not installed, else...
authorNabil Hanna <ali@users.schwerkraft.elitedvb.net>
Sun, 8 Nov 2009 09:28:35 +0000 (09:28 +0000)
committerNabil Hanna <ali@users.schwerkraft.elitedvb.net>
Sun, 8 Nov 2009 09:28:35 +0000 (09:28 +0000)
rsdownloader/src/plugin.py

index a309397..aec38ec 100644 (file)
@@ -6,7 +6,8 @@
 from base64 import encodestring\r
 from Components.ActionMap import ActionMap\r
 from Components.config import config, ConfigInteger, ConfigText, ConfigYesNo, ConfigClock, ConfigSubsection, getConfigListEntry\r
-from Components.ConfigList import ConfigListScreen\r
+from Components.ConfigList import ConfigListScreen
+from Components.Console import Console as eConsole\r
 from Components.Label import Label\r
 from Components.Language import language\r
 from Components.MenuList import MenuList\r
@@ -16,19 +17,21 @@ from container.decrypt import decrypt
 from enigma import eListboxPythonMultiContent, eTimer, gFont, RT_HALIGN_CENTER, RT_HALIGN_RIGHT\r
 from os import environ, listdir, remove\r
 from Plugins.Plugin import PluginDescriptor\r
-from Screens.ChoiceBox import ChoiceBox\r
+from Screens.ChoiceBox import ChoiceBox
+from Screens.Console import Console as ConsoleScreen\r
 from Screens.MessageBox import MessageBox\r
 from Screens.Screen import Screen\r
 from Screens.VirtualKeyBoard import VirtualKeyBoard\r
 from time import localtime, sleep, strftime, time\r
-from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE, SCOPE_LANGUAGE, SCOPE_PLUGINS\r
+from Tools.Directories import fileExists, resolveFilename, SCOPE_SKIN_IMAGE, SCOPE_LANGUAGE, SCOPE_PLUGINS\r
 from Tools.Downloader import HTTPProgressDownloader\r
 from Tools.LoadPixmap import LoadPixmap\r
 from twisted.internet import reactor\r
 from twisted.python import failure\r
 from twisted.web.client import getPage
 from urllib2 import Request\r
-from urlparse import urlparse, urlunparse\r
+from urlparse import urlparse, urlunparse
+from xml.etree.cElementTree import parse\r
 import gettext, re, socket, urllib, urllib2\r
 \r
 ##############################################################################\r
@@ -886,7 +889,278 @@ class RSContainerSelector(ChangedScreen):
                cur = self["list"].getCurrent()\r
                self.close(cur)\r
 \r
-##############################################################################\r
+##############################################################################
+
+class UnrarEntry:
+       def __init__(self, name, password):
+               self.name = name
+               self.password = password
+               self.working = False
+               self.finishCallback = None
+               self.console = None
+               self.command = None
+               self.list = ("%s/%s"%(config.plugins.RSDownloader.lists_directory.value, self.name)).replace("//", "/")
+               package = None
+               try:
+                       f = open(self.list, "r")
+                       while True:\r
+                               line = f.readline()\r
+                               if line == '':\r
+                                       break
+                               elif line.startswith("http://") and (line.__contains__("part1.rar") or line.__contains__("part01.rar") or line.__contains__("part001.rar")):
+                                       package = line.split("/")[-1]
+                                       package = package.replace("\n", "").replace("\r", "")
+                                       package = ("%s/%s"%(config.plugins.RSDownloader.downloads_directory.value, package)).replace("//", "/")
+                                       break
+                       f.close()
+               except:
+                       pass
+               if package:
+                       if self.password:
+                               self.command = "unrar -p%s -o+ x %s %s"%(self.password, package, config.plugins.RSDownloader.downloads_directory.value)
+                       else:
+                               self.command = "unrar -o+ x %s %s"%(package, config.plugins.RSDownloader.downloads_directory.value)
+               else:
+                       writeLog("Error finding rar-archives in list: %s"%self.name)
+
+       def startUnrar(self):
+               self.working = True
+               if not self.console:
+                       self.console = eConsole()
+               self.console.ePopen(self.command, self.unrarDataAvailable)
+
+       def unrarDataAvailable(self, result, retval, extra_args):
+               self.working = False
+               try:
+                       fileName = ("%s/%s_unrar.txt"%(config.plugins.RSDownloader.downloads_directory.value, self.name)).replace("//", "/")
+                       f = open(fileName, "w")
+                       f.write(result)
+                       f.close()
+               except:
+                       print "[RS Downloader] Result of unrar:",result
+               self.finishCallback(self.name)
+
+       def allDownloaded(self):
+               try:
+                       f = open(self.list, "r")
+                       content = f.read()
+                       f.close()
+               except:
+                       content = ""
+               if content.__contains__("http://"):
+                       return False
+               else:
+                       return True
+
+##############################################################################
+
+class Unrar:
+       def __init__(self):
+               self.list = []
+               self.timer = eTimer()
+               self.timer.callback.append(self.checkUnrar)
+               self.timer.start(30000, 1)
+               self.xmlFile = ("%s/unrar.xml"%config.plugins.RSDownloader.lists_directory.value).replace("//", "/")
+               
+       def addToList(self, name, password):
+               entry = UnrarEntry(name, password)
+               self.list.append(entry)
+
+       def deleteEntry(self, name):
+               idx = 0
+               ret = True
+               for x in self.list:
+                       if x.name == name:
+                               if x.working:
+                                       ret = False
+                               else:
+                                       del self.list[idx]
+                                       break
+                       idx += 1
+               return ret
+
+       def checkUnrar(self):
+               if len(self.list) > 0:
+                       self.startUnrar()
+               else:
+                       self.timer.start(30000, 1)
+
+       def isWorking(self):
+               ret = False
+               for x in self.list:
+                       if x.working:
+                               ret = True
+                               break
+               return ret
+
+       def getFirstEmptyList(self):
+               entry = None
+               for x in self.list:
+                       if (x.allDownloaded() == True):
+                               entry = x
+                               break
+               return entry
+
+       def startUnrar(self):
+               ret = self.isWorking()
+               if ret == False:
+                       entry = self.getFirstEmptyList()
+                       if entry:
+                               if entry.command:
+                                       writeLog("Start unpacking: %s"%entry.name)
+                                       entry.finishCallback = self.cleanFinishedEntry
+                                       entry.startUnrar()
+                               else:
+                                       self.deleteEntry(entry.name)
+                                       self.timer.start(30000, 1)
+                       else:
+                               self.timer.start(30000, 1)
+               else:
+                       self.timer.start(30000, 1)
+
+       def cleanFinishedEntry(self, name):
+               writeLog("Unpacking finished: %s"%name)
+               self.deleteEntry(name)
+               self.checkUnrar()
+
+       def decode_charset(self, str, charset):
+               try:
+                       uni = unicode(str, charset, 'strict')
+               except:
+                       uni = str
+               return uni
+
+       def loadXml(self):
+               if fileExists(self.xmlFile):
+                       menu = parse(self.xmlFile).getroot()
+                       for item in menu.findall("entry"):
+                               name = item.get("name") or None
+                               password = item.get("password") or None
+                               if name and password:
+                                       name = self.decode_charset(name, "utf-8")
+                                       password = self.decode_charset(password, "utf-8")
+                                       self.addToList(str(name), str(password))
+
+       def writeXml(self):
+               xml = '<unrar>\n'
+               for x in self.list:
+                       name = self.decode_charset(x.name, "utf-8")
+                       password = self.decode_charset(x.password, "utf-8")
+                       xml += '\t<entry name="%s" password="%s" />\n'%(name.encode("utf-8"), password.encode("utf-8"))
+               xml += '</unrar>\n'
+               try:
+                       f = open(self.xmlFile, "w")
+                       f.write(xml)
+                       f.close()
+               except:
+                       writeLog("Error writing unrar xml file: %s"%self.xmlFile)
+unrar = Unrar()
+
+##############################################################################
+
+class UnrarPackageSelector(ChangedScreen):\r
+       skin = """\r
+               <screen position="center,center" size="560,450" title="RS Downloader">\r
+                       <widget name="list" position="0,0" size="560,450" />\r
+               </screen>"""\r
+\r
+       def __init__(self, session):\r
+               ChangedScreen.__init__(self, session)
+               \r
+               self["list"] = MenuList([])
+               \r
+               self["actions"] = ActionMap(["OkCancelActions"],
+                       {
+                               "ok": self.okClicked,
+                               "cancel": self.close
+                       }, -1)
+               
+               self.onLayoutFinish.append(self.updateList)
+
+       def updateList(self):\r
+               try:\r
+                       names = listdir(config.plugins.RSDownloader.lists_directory.value)\r
+               except:\r
+                       names = []\r
+               list = []\r
+               for name in names:\r
+                       if name.lower().endswith(".txt"):
+                               added = False
+                               for x in unrar.list:
+                                       if x.name == name:
+                                               added = True
+                               if added == False:\r
+                                       list.append(name)\r
+               list.sort()
+               self["list"].setList(list)\r
+\r
+       def okClicked(self):\r
+               cur = self["list"].getCurrent()
+               if cur:
+                       self.name = cur
+                       self.session.openWithCallback(self.okClickedCallback, VirtualKeyBoard, title=_("Enter unrar password:"))
+
+       def okClickedCallback(self, callback=None):
+               if callback is None:
+                       callback = ""\r
+               self.close([self.name, callback])
+
+##############################################################################
+
+class UnrarManager(ChangedScreen):\r
+       skin = """\r
+               <screen position="center,center" size="560,450" title="RS Downloader">\r
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />\r
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />\r
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />\r
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />\r
+                       <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
+                       <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
+                       <widget name="list" position="0,40" size="560,375" scrollbarMode="showNever" />\r
+               </screen>"""\r
+\r
+       def __init__(self, session):\r
+               ChangedScreen.__init__(self, session)\r
+               self.session = session
+               \r
+               self["key_red"] = Label(_("Delete"))\r
+               self["key_green"] = Label(_("Add"))\r
+               self["list"] = MenuList([])
+               \r
+               self["actions"] = ActionMap(["ColorActions", "OkCancelActions"],
+                       {
+                               "red": self.delete,
+                               "green": self.add,
+                               "cancel": self.close
+                       }, prio=-1)
+               \r
+               self.onLayoutFinish.append(self.updateList)
+
+       def updateList(self):
+               list = []
+               for x in unrar.list:
+                       list.append(x.name)
+               list.sort()
+               self["list"].setList(list)
+
+       def delete(self):
+               cur = self["list"].getCurrent()
+               if cur:
+                       ret = unrar.deleteEntry(cur)
+                       if ret:
+                               self.updateList()
+                       else:
+                               self.session.open(MessageBox, _("Unrar is already working!"), MessageBox.TYPE_ERROR)
+
+       def add(self):
+               self.session.openWithCallback(self.addCallback, UnrarPackageSelector)
+
+       def addCallback(self, callback=None):
+               if callback:
+                       unrar.addToList(callback[0], callback[1])
+                       self.updateList()\r
+
+##############################################################################
 \r
 class RSList(MenuList):\r
        def __init__(self, list):\r
@@ -918,7 +1192,7 @@ class RSMain(ChangedScreen):
                        <ePixmap pixmap="skin_default/buttons/key_menu.png" position="10,420" size="35,25" transparent="1" alphatest="on" />\r
                        <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
                        <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
-                       <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
+                       <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
                        <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
                        <widget name="key_menu" position="50,422" size="300,25" font="Regular;20" transparent="1" />\r
                        <widget name="list" position="0,40" size="560,375" scrollbarMode="showNever" />\r
@@ -952,7 +1226,6 @@ class RSMain(ChangedScreen):
 \r
        def menu(self):\r
                list = []\r
-               #TODO: Add sort list functions\r
                list.append((_("Delete download"), self.delete))\r
                list.append((_("Use search engine"), self.search))\r
                list.append((_("Add downloads from txt files"), self.add))\r
@@ -962,7 +1235,11 @@ class RSMain(ChangedScreen):
                list.append((_("Restart failed downloads"), self.restartFailed))\r
                list.append((_("Clear finished downloads"), self.clearFinished))\r
                list.append((_("Show log"), self.showLog))\r
-               list.append((_("Delete log"), self.deleteLog))\r
+               list.append((_("Delete log"), self.deleteLog))
+               if fileExists("/usr/bin/unrar"):
+                       list.append((_("Open unrar Manager"), self.openUnrarManager))
+               else:
+                       list.append((_("Install unrar"), self.installUnrar))\r
                list.append((_("Close plugin"), self.close))\r
                self.session.openWithCallback(self.menuCallback, ChoiceBox, title=_("Please choose a function..."), list=list)\r
 \r
@@ -989,7 +1266,13 @@ class RSMain(ChangedScreen):
                try:\r
                        remove("/tmp/rapidshare.log")\r
                except:\r
-                       pass\r
+                       pass
+
+       def openUnrarManager(self):
+               self.session.open(UnrarManager)
+
+       def installUnrar(self):
+               self.session.open(ConsoleScreen, title=_("Installing unrar..."), cmdlist=["ipkg install http://www.lt-forums.org/ali/downloads/unrar_3.4.3-r0_mipsel.ipk"])\r
 \r
        def updateList(self):\r
                list = []\r
@@ -1080,7 +1363,10 @@ class RSMain(ChangedScreen):
 \r
 def autostart(reason, **kwargs):\r
        if reason == 0:\r
-               rapidshare.startDownloading()\r
+               rapidshare.startDownloading()
+               unrar.loadXml()
+       elif reason == 1:
+               unrar.writeXml()\r
 \r
 ##############################################################################\r
 \r