do not crash if container can not get encrypted
[enigma2-plugins.git] / rsdownloader / src / plugin.py
1 ##\r
2 ## RS Downloader\r
3 ## by AliAbdul\r
4 ##\r
5 ##\r
6 from base64 import encodestring\r
7 from Components.ActionMap import ActionMap\r
8 from Components.config import config, ConfigInteger, ConfigText, ConfigYesNo, ConfigClock, ConfigSubsection, getConfigListEntry\r
9 from Components.ConfigList import ConfigListScreen
10 from Components.Console import Console as eConsole\r
11 from Components.Label import Label\r
12 from Components.Language import language\r
13 from Components.MenuList import MenuList\r
14 from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest\r
15 from Components.ScrollLabel import ScrollLabel\r
16 from container.decrypt import decrypt\r
17 from enigma import eListboxPythonMultiContent, eTimer, gFont, RT_HALIGN_CENTER, RT_HALIGN_RIGHT\r
18 from os import environ, listdir, remove\r
19 from Plugins.Plugin import PluginDescriptor\r
20 from Screens.ChoiceBox import ChoiceBox
21 from Screens.Console import Console as ConsoleScreen\r
22 from Screens.MessageBox import MessageBox\r
23 from Screens.Screen import Screen\r
24 from Screens.VirtualKeyBoard import VirtualKeyBoard\r
25 from time import localtime, sleep, strftime, time\r
26 from Tools.Directories import fileExists, resolveFilename, SCOPE_SKIN_IMAGE, SCOPE_LANGUAGE, SCOPE_PLUGINS\r
27 from Tools.Downloader import HTTPProgressDownloader\r
28 from Tools.LoadPixmap import LoadPixmap\r
29 from twisted.internet import reactor\r
30 from twisted.python import failure\r
31 from twisted.web.client import getPage
32 from urllib2 import Request\r
33 from urlparse import urlparse, urlunparse
34 from xml.etree.cElementTree import parse\r
35 import gettext, re, socket, urllib, urllib2\r
36 \r
37 ##############################################################################\r
38 \r
39 config.plugins.RSDownloader = ConfigSubsection()\r
40 config.plugins.RSDownloader.onoff = ConfigYesNo(default=True)\r
41 config.plugins.RSDownloader.username = ConfigText(default="", fixed_size=False)\r
42 config.plugins.RSDownloader.password = ConfigText(default="", fixed_size=False)\r
43 config.plugins.RSDownloader.lists_directory = ConfigText(default="/media/hdd/rs/lists/", fixed_size=False)\r
44 config.plugins.RSDownloader.downloads_directory = ConfigText(default="/media/hdd/rs/downloads", fixed_size=False)\r
45 config.plugins.RSDownloader.ignore_time = ConfigYesNo(default=False)\r
46 config.plugins.RSDownloader.start_time = ConfigClock(default=time())\r
47 config.plugins.RSDownloader.end_time = ConfigClock(default=time())\r
48 config.plugins.RSDownloader.download_monday = ConfigYesNo(default=True)\r
49 config.plugins.RSDownloader.download_tuesday = ConfigYesNo(default=True)\r
50 config.plugins.RSDownloader.download_wednesday = ConfigYesNo(default=True)\r
51 config.plugins.RSDownloader.download_thursday = ConfigYesNo(default=True)\r
52 config.plugins.RSDownloader.download_friday = ConfigYesNo(default=True)\r
53 config.plugins.RSDownloader.download_saturday = ConfigYesNo(default=True)\r
54 config.plugins.RSDownloader.download_sunday = ConfigYesNo(default=True)\r
55 config.plugins.RSDownloader.count_downloads = ConfigInteger(default=3, limits=(1, 10))\r
56 config.plugins.RSDownloader.count_maximal_downloads = ConfigInteger(default=40, limits=(1, 1000))\r
57 config.plugins.RSDownloader.write_log = ConfigYesNo(default=True)\r
58 config.plugins.RSDownloader.reconnect_fritz = ConfigYesNo(default=False)\r
59 config.plugins.RSDownloader.autorestart_failed = ConfigYesNo(default=False)\r
60 config.plugins.RSDownloader.mark_small_as_failed = ConfigYesNo(default=True)\r
61 \r
62 ##############################################################################\r
63 \r
64 def localeInit():\r
65         lang = language.getLanguage()\r
66         environ["LANGUAGE"] = lang[:2]\r
67         gettext.bindtextdomain("enigma2", resolveFilename(SCOPE_LANGUAGE))\r
68         gettext.textdomain("enigma2")\r
69         gettext.bindtextdomain("RSDownloader", "%s%s"%(resolveFilename(SCOPE_PLUGINS), "Extensions/RSDownloader/locale/"))\r
70 \r
71 def _(txt):\r
72         t = gettext.dgettext("RSDownloader", txt)\r
73         if t == txt:\r
74                 t = gettext.gettext(txt)\r
75         return t\r
76 \r
77 localeInit()\r
78 language.addCallback(localeInit)\r
79 \r
80 ##############################################################################\r
81 \r
82 def writeLog(message):\r
83         if config.plugins.RSDownloader.write_log.value:\r
84                 try:\r
85                         f = open("/tmp/rapidshare.log", "a")\r
86                         f.write(strftime("%c", localtime(time())) + " - " + message + "\n")\r
87                         f.close()\r
88                 except:\r
89                         pass\r
90 \r
91 ##############################################################################\r
92 \r
93 def _parse(url):\r
94         url = url.strip()\r
95         parsed = urlparse(url)\r
96         scheme = parsed[0]\r
97         path = urlunparse(('','') + parsed[2:])\r
98         host, port = parsed[1], 80\r
99         if '@' in host:\r
100                 username, host = host.split('@')\r
101                 if ':' in username:\r
102                         username, password = username.split(':')\r
103                 else:\r
104                         password = ""\r
105         else:\r
106                 username = ""\r
107                 password = ""\r
108         if ':' in host:\r
109                 host, port = host.split(':')\r
110                 port = int(port)\r
111         if path == "":\r
112                 path = "/"\r
113         return scheme, host, port, path, username, password\r
114 \r
115 class ProgressDownload:\r
116         def __init__(self, url, outputfile, contextFactory=None, *args, **kwargs):\r
117                 scheme, host, port, path, username, password = _parse(url)\r
118                 if username and password:\r
119                         url = scheme + '://' + host + ':' + str(port) + path\r
120                         basicAuth = encodestring("%s:%s"%(username, password))\r
121                         authHeader = "Basic " + basicAuth.strip()\r
122                         AuthHeaders = {"Authorization": authHeader}\r
123                         if kwargs.has_key("headers"):\r
124                                 kwargs["headers"].update(AuthHeaders)\r
125                         else:\r
126                                 kwargs["headers"] = AuthHeaders\r
127                 self.factory = HTTPProgressDownloader(url, outputfile, *args, **kwargs)\r
128                 self.connection = reactor.connectTCP(host, port, self.factory)\r
129 \r
130         def start(self):\r
131                 return self.factory.deferred\r
132 \r
133         def stop(self):\r
134                 self.connection.disconnect()\r
135 \r
136         def addProgress(self, progress_callback):\r
137                 self.factory.progress_callback = progress_callback\r
138 \r
139 ##############################################################################\r
140 \r
141 def get(url):\r
142         try:\r
143                 data = urllib2.urlopen(url)\r
144                 return data.read()\r
145         except:\r
146                 return ""\r
147    \r
148 def post(url, data):\r
149         try:\r
150                 return urllib2.urlopen(url, data).read()\r
151         except:\r
152                 return ""\r
153 \r
154 def matchGet(rex, string):\r
155         match = re.search(rex, string)\r
156         if match:\r
157                 if len(match.groups()) == 0:\r
158                         return string[match.span()[0]:match.span()[1]]\r
159                 if len(match.groups()) == 1:\r
160                         return match.groups()[0]\r
161         else:\r
162                 return False\r
163 \r
164 ##############################################################################\r
165 \r
166 def reconnect(host='fritz.box', port=49000):\r
167         http_body = '\r\n'.join((\r
168                 '<?xml version="1.0" encoding="utf-8"?>',\r
169                 '<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">',\r
170                 '  <s:Body>',\r
171                 '    <u:ForceTermination xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"/>',\r
172                 '  </s:Body>',\r
173                 '</s:Envelope>'))\r
174         http_data = '\r\n'.join((\r
175                 'POST /upnp/control/WANIPConn1 HTTP/1.1',\r
176                 'Host: %s:%d'%(host, port),\r
177                 'SoapAction: urn:schemas-upnp-org:service:WANIPConnection:1#ForceTermination',\r
178                 'Content-Type: text/xml; charset="utf-8"',\r
179                 'Content-Length: %d'%len(http_body),\r
180                 '',\r
181                 http_body))\r
182         try:\r
183                 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r
184                 s.connect((host, port))\r
185                 s.send(http_data)\r
186                 s.close()\r
187         except:\r
188                 pass\r
189 \r
190 ##############################################################################
191
192 std_headers = {
193         'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2',
194         'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
195         'Accept': 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
196         'Accept-Language': 'en-us,en;q=0.5',
197 }\r
198 \r
199 class RSDownload:\r
200         def __init__(self, url):\r
201                 writeLog("Adding: %s"%url)\r
202                 self.url = url\r
203                 self.download = None\r
204                 self.downloading = False\r
205                 self.progress = 0\r
206                 self.size = 0\r
207                 self.status = _("Waiting")\r
208                 self.name = self.url.split("/")[-1]\r
209                 self.finishCallbacks = []\r
210 \r
211         def start(self):\r
212                 writeLog("Downloading: %s"%self.url)\r
213                 self.downloading = True\r
214                 self.progress = 0\r
215                 self.size = 0\r
216                 username = config.plugins.RSDownloader.username.value\r
217                 password = config.plugins.RSDownloader.password.value\r
218                 if self.url.__contains__("rapidshare.com") and username == "" and password == "":\r
219                         writeLog("Free RS-Download: %s"%self.url)\r
220                         self.status = _("Checking")\r
221                         if config.plugins.RSDownloader.reconnect_fritz.value:\r
222                                 reconnect()\r
223                                 sleep(3)\r
224                         data = get(self.url)\r
225                         url = matchGet('<form[^>]+action="([^"]+)', data)\r
226                         if not url:\r
227                                 writeLog("Failed: %s"%self.url)\r
228                                 self.httpFailed(True, "Failed to get download page url: %s"%self.url)\r
229                         else:\r
230                                 data = post(url, "dl.start=Free")\r
231                                 seconds = matchGet('var c=([0-9]+)', data)\r
232                                 if not seconds:\r
233                                         self.httpFailed(True, "Failed to get download page url: %s"%self.url)\r
234                                 else:\r
235                                         writeLog("Free RS-Download... must wait %s seconds: %s"%(seconds, self.url))\r
236                                         self.status = "%s %s"%(_("Waiting"), seconds)\r
237                                         url = matchGet('"dlf" action="([^"]+)', data)\r
238                                         if not url:\r
239                                                 self.httpFailed(True, "Failed to get download page url: %s"%self.url)\r
240                                         else:\r
241                                                 self.freeDownloadUrl = url\r
242                                                 self.freeDownloadTimer = eTimer()\r
243                                                 self.freeDownloadTimer.callback.append(self.freeDownloadStart)\r
244                                                 self.freeDownloadTimer.start((int(seconds) + 2) * 1000, 1)
245                 elif self.url.__contains__("uploaded.to") or self.url.__contains__("ul.to"):
246                         writeLog("Free Uploaded.to-Download: %s"%self.url)\r
247                         self.status = _("Checking")\r
248                         if config.plugins.RSDownloader.reconnect_fritz.value:\r
249                                 reconnect()\r
250                                 sleep(3)\r
251                         data = get(self.url)
252                         tmp = re.search(r"Or wait (\d+) minutes", data)
253                         if tmp:
254                                 minutes = tmp.group(1)
255                                 writeLog("Free Uploaded.to-Download... must wait %s minutes: %s"%(minutes, self.url))
256                                 self.status = "%s %s"%(_("Waiting"), minutes)\r
257                                 self.freeDownloadTimer = eTimer()\r
258                                 self.freeDownloadTimer.callback.append(self.start)\r
259                                 self.freeDownloadTimer.start((int(minutes) + 1) * 60000, 1)
260                         else:
261                                 url = re.search(r".*<form name=\"download_form\" method=\"post\" action=\"(.*)\">", data).group(1)
262                                 self.name = re.search(r"<td><b>\s+(.+)\s", data).group(1) + re.search(r"</td><td>(\..+)</td></tr>", data).group(1)\r
263                                 self.status = _("Downloading")\r
264                                 self.download = ProgressDownload(url, ("%s/%s"%(config.plugins.RSDownloader.downloads_directory.value, self.name)).replace("//", "/"))\r
265                                 self.download.addProgress(self.httpProgress)\r
266                                 self.download.start().addCallback(self.httpFinished).addErrback(self.httpFailed)\r
267                 elif self.url.__contains__("youtube.com"):\r
268                         writeLog("Getting youtube video link: %s"%self.url)\r
269                         self.status = _("Checking")\r
270                         downloadLink = self.getYoutubeDownloadLink()\r
271                         if downloadLink:\r
272                                 self.status = _("Downloading")\r
273                                 writeLog("Downloading video: %s"%downloadLink)\r
274                                 req = urllib2.Request(downloadLink)\r
275                                 url_handle = urllib2.urlopen(req)\r
276                                 headers = url_handle.info()\r
277                                 if headers.getheader("content-type") == "video/mp4":\r
278                                         ext = "mp4"\r
279                                 else:\r
280                                         ext = "flv"\r
281                                 self.download = ProgressDownload(downloadLink, ("%s/%s.%s"%(config.plugins.RSDownloader.downloads_directory.value, self.name, ext)).replace("//", "/"))\r
282                                 self.download.addProgress(self.httpProgress)\r
283                                 self.download.start().addCallback(self.httpFinished).addErrback(self.httpFailed)\r
284                         else:\r
285                                 self.httpFailed(True, "Failed to get video url: %s"%self.url)\r
286                 else:\r
287                         if self.url.__contains__("rapidshare.com"):\r
288                                 url = self.url.replace("http://", "http://" + username + ":" + password + "@")\r
289                         else:\r
290                                 url = self.url\r
291                         self.status = _("Downloading")\r
292                         self.download = ProgressDownload(url, ("%s/%s"%(config.plugins.RSDownloader.downloads_directory.value, self.name)).replace("//", "/").replace(".html", ""))\r
293                         self.download.addProgress(self.httpProgress)\r
294                         self.download.start().addCallback(self.httpFinished).addErrback(self.httpFailed)\r
295 \r
296         def freeDownloadStart(self):\r
297                 self.status = _("Downloading")\r
298                 self.download = ProgressDownload(self.freeDownloadUrl, ("%s/%s"%(config.plugins.RSDownloader.downloads_directory.value, self.name)).replace("//", "/").replace(".html", ""))\r
299                 self.download.addProgress(self.httpProgress)\r
300                 self.download.start().addCallback(self.httpFinished).addErrback(self.httpFailed)\r
301 \r
302         def stop(self):\r
303                 self.progress = 0\r
304                 self.downloading = False\r
305                 self.status = _("Waiting")\r
306                 if self.download:\r
307                         writeLog("Stopping download: %s"%self.url)\r
308                         self.download.stop()\r
309 \r
310         def httpProgress(self, recvbytes, totalbytes):\r
311                 if self.size == 0:\r
312                         self.size = int((totalbytes / 1024) / 1024)\r
313                 self.progress = int(100.0 * float(recvbytes) / float(totalbytes))\r
314 \r
315         def httpFinished(self, string=None):\r
316                 if string is not None:\r
317                         writeLog("Failed: %s"%self.url)\r
318                         writeLog("Error: %s"%string)\r
319                 self.status = _("Checking")\r
320                 self.checkTimer = eTimer()\r
321                 self.checkTimer.callback.append(self.doCheckTimer)\r
322                 self.checkTimer.start(10000, 1)\r
323 \r
324         def doCheckTimer(self):\r
325                 if (self.size == 0) or (self.progress < 100) or ((config.plugins.RSDownloader.mark_small_as_failed.value == True) and (self.size < 1)):\r
326                         self.status = _("Failed")\r
327                         if config.plugins.RSDownloader.autorestart_failed.value:\r
328                                 self.restartFailedTimer = eTimer()\r
329                                 self.restartFailedTimer.callback.append(self.restartFailedCheck)\r
330                                 self.restartFailedTimer.start(10000*60, 1)\r
331                 elif self.progress == 100:\r
332                         self.status = _("Finished")
333                         writeLog("Finished: %s"%self.url)\r
334                 self.downloading = False\r
335                 self.execFinishCallbacks()\r
336 \r
337         def restartFailedCheck(self):\r
338                 if self.status == _("Failed"): # check if user didn't restart already\r
339                         self.download = None\r
340                         self.status = _("Waiting")\r
341 \r
342         def execFinishCallbacks(self):\r
343                 for x in self.finishCallbacks:\r
344                         x()\r
345 \r
346         def httpFailed(self, failure=None, error=""):\r
347                 if failure:\r
348                         if error == "":\r
349                                 error = failure.getErrorMessage()\r
350                         if error != "" and not error.startswith("[Errno 2]"):\r
351                                 writeLog("Failed: %s"%self.url)\r
352                                 writeLog("Error: %s"%error)\r
353                                 self.status = _("Checking")\r
354                 self.checkTimer = eTimer()\r
355                 self.checkTimer.callback.append(self.doCheckTimer)\r
356                 self.checkTimer.start(10000, 1)
357
358         def getTubeId(self):
359                 url = self.url
360                 if url.__contains__("&feature="):
361                         idx = url.index("&feature=")
362                         url = url[:idx]
363                 split = url.split("=")
364                 ret = split.pop()
365                 if ret == 'youtube_gdata':
366                         tmpval = split.pop()
367                         if tmpval.endswith("&feature"):
368                                 tmp = tmpval.split("&")
369                                 ret = tmp.pop(0)
370                 return ret\r
371 \r
372         def getYoutubeDownloadLink(self):
373                 html = get(self.url)\r
374                 if html != "":\r
375                         reonecat = re.compile(r'<title>(.+?)</title>', re.DOTALL)\r
376                         titles = reonecat.findall(html)\r
377                         if titles:\r
378                                 self.name = titles[0]
379                                 if self.name.__contains__("\t- "):\r
380                                         idx = self.name.index("\t- ")\r
381                                         self.name = (self.name[idx+3:]).replace("&amp;", "&").replace("\t", "").replace("\n", "")
382                 mrl = None
383                 isHDAvailable = False
384                 video_id = str(self.getTubeId())
385                 watch_url = "http://www.youtube.com/watch?v="+video_id
386                 watchrequest = Request(watch_url, None, std_headers)
387                 try:
388                         watchvideopage = urllib2.urlopen(watchrequest).read()
389                 except:
390                         watchvideopage = ""
391                 if "isHDAvailable = true" in watchvideopage:
392                         isHDAvailable = True
393                 info_url = 'http://www.youtube.com/get_video_info?&video_id=%s&el=detailpage&ps=default&eurl=&gl=US&hl=en'%video_id
394                 inforequest = Request(info_url, None, std_headers)
395                 try:
396                         infopage = urllib2.urlopen(inforequest).read()
397                 except:
398                         infopage = ""
399                 mobj = re.search(r'(?m)&token=([^&]+)(?:&|$)', infopage)
400                 if mobj:
401                         token = urllib.unquote(mobj.group(1))
402                         myurl = 'http://www.youtube.com/get_video?video_id=%s&t=%s&eurl=&el=detailpage&ps=default&gl=US&hl=en'%(video_id, token)
403                         if isHDAvailable is True:
404                                 mrl = '%s&fmt=%s'%(myurl, '22')
405                         else:
406                                 mrl = '%s&fmt=%s'%(myurl, '18')\r
407                 return mrl\r
408 \r
409 ##############################################################################\r
410 \r
411 class RS:\r
412         def __init__(self):\r
413                 self.downloads = []\r
414                 self.checkTimer = eTimer()\r
415                 self.checkTimer.callback.append(self.startDownloading)\r
416                 self.checkTimer.start(5000*60, False)\r
417 \r
418         def mayDownload(self):\r
419                 if config.plugins.RSDownloader.onoff.value == False:\r
420                         writeLog("RS Downloader is turned off...")\r
421                         return False\r
422                 elif config.plugins.RSDownloader.ignore_time.value:\r
423                         return True\r
424                 else:\r
425                         start = config.plugins.RSDownloader.start_time.value\r
426                         end = config.plugins.RSDownloader.end_time.value\r
427                         t = localtime()\r
428                         weekday = t[6]\r
429                         if weekday == 0 and config.plugins.RSDownloader.download_monday.value == False:\r
430                                 return False\r
431                         elif weekday == 1 and config.plugins.RSDownloader.download_tuesday.value == False:\r
432                                 return False\r
433                         elif weekday == 2 and config.plugins.RSDownloader.download_wednesday.value == False:\r
434                                 return False\r
435                         elif weekday == 3 and config.plugins.RSDownloader.download_thursday.value == False:\r
436                                 return False\r
437                         elif weekday == 4 and config.plugins.RSDownloader.download_friday.value == False:\r
438                                 return False\r
439                         elif weekday == 5 and config.plugins.RSDownloader.download_saturday.value == False:\r
440                                 return False\r
441                         elif weekday == 6 and config.plugins.RSDownloader.download_sunday.value == False:\r
442                                 return False\r
443                         else:\r
444                                 hour_now = t[3]\r
445                                 minute_now = t[4]\r
446                                 hour_start = start[0]\r
447                                 minute_start = start[1]\r
448                                 hour_end = end[0]\r
449                                 minute_end = end[1]\r
450                                 if start == end: # Same start and end-time\r
451                                         return True\r
452                                 elif hour_end < hour_start: # Different days!!!\r
453                                         if hour_now > hour_start or hour_now < hour_end:\r
454                                                 return True\r
455                                         elif hour_now == hour_start and minute_now > minute_start:\r
456                                                 return True\r
457                                         elif hour_now == hour_end and minute_now < minute_end:\r
458                                                 return True\r
459                                         else:\r
460                                                 return False\r
461                                 elif hour_now > hour_start and hour_now < hour_end: # Same day...\r
462                                         return True\r
463                                 elif hour_now == hour_start and minute_now > minute_start: # Same day, same start-hour...\r
464                                         return True\r
465                                 elif hour_now == hour_end and minute_now < minute_end: # Same day, same end-hour...\r
466                                         return True\r
467                                 else:\r
468                                         return False\r
469 \r
470         def allDownloadsFinished(self):\r
471                 allDone = True\r
472                 for download in self.downloads:\r
473                         if (download.status != _("Failed")) and (download.status != _("Finished")):\r
474                                 allDone = False
475                                 break\r
476                 return allDone\r
477 \r
478         def startDownloading(self):\r
479                 if self.mayDownload() == True:\r
480                         if self.allDownloadsFinished() == True:\r
481                                 self.readLists()\r
482                         downloadCount = 0\r
483                         for download in self.downloads:\r
484                                 if download.downloading == True:\r
485                                         downloadCount += 1 # Count the downloaded files\r
486                         if config.plugins.RSDownloader.username.value == "" and config.plugins.RSDownloader.password.value == "":\r
487                                 if downloadCount < 1: # Allow one download if without account\r
488                                         for download in self.downloads:\r
489                                                 if download.downloading == False and download.status.startswith(_("Waiting")):\r
490                                                         download.start() # Start first download in the list\r
491                                                         break\r
492                         else:\r
493                                 mayDownloadCount = config.plugins.RSDownloader.count_downloads.value - downloadCount\r
494                                 for download in self.downloads:\r
495                                         if download.downloading == False:\r
496                                                 if mayDownloadCount > 0 and download.status == _("Waiting"):\r
497                                                         download.start()\r
498                                                         mayDownloadCount -= 1\r
499 \r
500         def addDownload(self, url):\r
501                 error = False\r
502                 for download in self.downloads:\r
503                         if download.url == url:\r
504                                 error = True\r
505                 if error:\r
506                         return False\r
507                 else:\r
508                         download = RSDownload(url)\r
509                         download.finishCallbacks.append(self.cleanLists)\r
510                         self.downloads.append(download)\r
511                         return True\r
512 \r
513         def readLists(self):\r
514                 writeLog("Reading all lists...")\r
515                 path = config.plugins.RSDownloader.lists_directory.value\r
516                 if not path.endswith("/"):\r
517                         path = path + "/"\r
518                 writeLog("Directory: " + path)\r
519                 try:\r
520                         file_list = listdir(path)
521                         file_list.sort()\r
522                         writeLog("Count of lists: " + str(len(file_list)))\r
523                 except:\r
524                         file_list = []\r
525                         writeLog("Could not find any list!")
526                 added_downloads = 0\r
527                 for x in file_list:\r
528                         list = path + x\r
529                         if list.endswith(".txt"):\r
530                                 try:\r
531                                         writeLog("Reading list %s..."%list)\r
532                                         f = open(list, "r")\r
533                                         count = 0\r
534                                         for l in f:\r
535                                                 if l.startswith("http://"):
536                                                         if added_downloads < config.plugins.RSDownloader.count_maximal_downloads.value:\r
537                                                                 if (self.addDownload(l.replace("\n", "").replace("\r", ""))) == True:\r
538                                                                         count += 1
539                                                                         added_downloads += 1
540                                                         else:
541                                                                 break\r
542                                         f.close()\r
543                                         if count == 0:\r
544                                                 writeLog("Empty list or downloads already in download list: %s"%list)\r
545                                         else:\r
546                                                 writeLog("Added %d files from list %s..."%(count, list))\r
547                                 except:\r
548                                         writeLog("Error while reading list %s!"%list)\r
549                         else:\r
550                                 writeLog("No *.txt file: %s!"%list)\r
551 \r
552         def cleanLists(self):\r
553                 writeLog("Cleaning lists...")\r
554                 path = config.plugins.RSDownloader.lists_directory.value\r
555                 if not path.endswith("/"):\r
556                         path = path + "/"\r
557                 try:\r
558                         file_list = listdir(path)\r
559                 except:\r
560                         file_list = []
561                 
562                 finished_downloads = []
563                 for download in self.downloads:\r
564                         if download.status == _("Finished"):
565                                 finished_downloads.append(download)\r
566                 for x in file_list:\r
567                         list = path + x
568                         if list.endswith(".txt"):\r
569                                 try:\r
570                                         f = open(list, "r")\r
571                                         content = f.read()\r
572                                         f.close()
573                                         for finished in finished_downloads:\r
574                                                 if content.__contains__(finished.url):\r
575                                                         content = content.replace(finished.url, "")\r
576                                                         content = content.replace("\n\n", "\n").replace("\r\r", "\r")\r
577                                         f = open(list, "w")\r
578                                         f.write(content)\r
579                                         f.close()\r
580                                 except:\r
581                                         writeLog("Error while cleaning list %s!"%list)\r
582                 self.startDownloading()\r
583 \r
584         def removeDownload(self, url):\r
585                 tmp = []\r
586                 for download in self.downloads:\r
587                         if download.url == url:\r
588                                 download.stop()\r
589                         else:\r
590                                 tmp.append(download)\r
591                 del self.downloads\r
592                 self.downloads = tmp\r
593                 self.removeFromLists(url)\r
594 \r
595         def removeFromLists(self, url):\r
596                 path = config.plugins.RSDownloader.lists_directory.value\r
597                 if not path.endswith("/"):\r
598                         path = path + "/"\r
599                 try:\r
600                         file_list = listdir(path)\r
601                 except:\r
602                         file_list = []\r
603                 for x in file_list:\r
604                         list = path + x\r
605                         try:\r
606                                 f = open(list, "r")\r
607                                 content = f.read()\r
608                                 f.close()\r
609                                 if content.__contains__(url):\r
610                                         content = content.replace(url, "")\r
611                                         content = content.replace("\n\n", "\n").replace("\r\r", "\r")\r
612                                 f = open(list, "w")\r
613                                 f.write(content)\r
614                                 f.close()\r
615                         except:\r
616                                 pass\r
617 \r
618         def clearFinishedDownload(self, url):\r
619                 idx = 0\r
620                 for x in self.downloads:\r
621                         if x.url == url:\r
622                                 del self.downloads[idx]\r
623                                 break\r
624                         else:\r
625                                 idx += 1\r
626 \r
627         def clearFinishedDownloads(self):\r
628                 tmp = []\r
629                 for download in self.downloads:\r
630                         if download.status != _("Finished"):\r
631                                 tmp.append(download)\r
632                 del self.downloads\r
633                 self.downloads = tmp\r
634 \r
635         def deleteFailedDownloads(self):\r
636                 tmp = []\r
637                 for download in self.downloads:\r
638                         if download.status == _("Failed"):\r
639                                 self.removeFromLists(download.url)\r
640                         else:\r
641                                 tmp.append(download)\r
642                 del self.downloads\r
643                 self.downloads = tmp
644
645         def abortAllDownloads(self):\r
646                 tmp = []\r
647                 for download in self.downloads:\r
648                         if download.status == _("Downloading"):\r
649                                 download.stop()\r
650                                 download.download = None\r
651                                 download.downloading = False\r
652                                 download.progress = 0\r
653                                 download.size = 0\r
654                                 download.status = _("Waiting")\r
655                         tmp.append(download)\r
656                 del self.downloads\r
657                 self.downloads = tmp\r
658                 self.startDownloading()\r
659 \r
660         def restartFailedDownloads(self):\r
661                 tmp = []\r
662                 for download in self.downloads:\r
663                         if download.status == _("Failed"):\r
664                                 download.download = None\r
665                                 download.downloading = False\r
666                                 download.progress = 0\r
667                                 download.size = 0\r
668                                 download.status = _("Waiting")\r
669                         tmp.append(download)\r
670                 del self.downloads\r
671                 self.downloads = tmp\r
672                 self.startDownloading()\r
673 \r
674 rapidshare = RS()\r
675 \r
676 ##############################################################################\r
677 \r
678 class ChangedScreen(Screen):\r
679         def __init__(self, session, parent=None):\r
680                 Screen.__init__(self, session, parent)\r
681                 self.onLayoutFinish.append(self.setScreenTitle)\r
682 \r
683         def setScreenTitle(self):\r
684                 self.setTitle(_("RS Downloader"))\r
685 \r
686 ##############################################################################\r
687 \r
688 class RSConfig(ConfigListScreen, ChangedScreen):\r
689         skin = """\r
690                 <screen position="center,center" size="560,450" title="RS Downloader">\r
691                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />\r
692                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />\r
693                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />\r
694                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />\r
695                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
696                         <widget name="config" position="0,45" size="560,400" scrollbarMode="showOnDemand" />\r
697                 </screen>"""\r
698 \r
699         def __init__(self, session):\r
700                 ChangedScreen.__init__(self, session)\r
701                 \r
702                 self["key_green"] = Label(_("Save"))\r
703                 \r
704                 ConfigListScreen.__init__(self, [\r
705                         getConfigListEntry(_("Download in the background:"), config.plugins.RSDownloader.onoff),\r
706                         getConfigListEntry(_("Username:"), config.plugins.RSDownloader.username),\r
707                         getConfigListEntry(_("Password:"), config.plugins.RSDownloader.password),\r
708                         getConfigListEntry(_("Lists directory:"), config.plugins.RSDownloader.lists_directory),\r
709                         getConfigListEntry(_("Downloads directory:"), config.plugins.RSDownloader.downloads_directory),\r
710                         getConfigListEntry(_("Ignore download times:"), config.plugins.RSDownloader.ignore_time),\r
711                         getConfigListEntry(_("Allow downloading on monday:"), config.plugins.RSDownloader.download_monday),\r
712                         getConfigListEntry(_("Allow downloading on tuesday:"), config.plugins.RSDownloader.download_tuesday),\r
713                         getConfigListEntry(_("Allow downloading on wednesday:"), config.plugins.RSDownloader.download_wednesday),\r
714                         getConfigListEntry(_("Allow downloading on thursday:"), config.plugins.RSDownloader.download_thursday),\r
715                         getConfigListEntry(_("Allow downloading on friday:"), config.plugins.RSDownloader.download_friday),\r
716                         getConfigListEntry(_("Allow downloading on saturday:"), config.plugins.RSDownloader.download_saturday),\r
717                         getConfigListEntry(_("Allow downloading on sunday:"), config.plugins.RSDownloader.download_sunday),\r
718                         getConfigListEntry(_("Don't download before:"), config.plugins.RSDownloader.start_time),\r
719                         getConfigListEntry(_("Don't download after:"), config.plugins.RSDownloader.end_time),\r
720                         getConfigListEntry(_("Maximal downloads:"), config.plugins.RSDownloader.count_downloads),\r
721                         getConfigListEntry(_("Take x downloads to list:"), config.plugins.RSDownloader.count_maximal_downloads),\r
722                         getConfigListEntry(_("Write log:"), config.plugins.RSDownloader.write_log),\r
723                         getConfigListEntry(_("Reconnect fritz.Box before downloading:"), config.plugins.RSDownloader.reconnect_fritz),\r
724                         getConfigListEntry(_("Restart failed after 10 minutes:"), config.plugins.RSDownloader.autorestart_failed),
725                         getConfigListEntry(_("Mark files < 1 MB as failed:"), config.plugins.RSDownloader.mark_small_as_failed)])\r
726                 \r
727                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"], {"green": self.save, "cancel": self.exit}, -1)\r
728 \r
729         def save(self):\r
730                 for x in self["config"].list:\r
731                         x[1].save()\r
732                 self.close()\r
733 \r
734         def exit(self):\r
735                 for x in self["config"].list:\r
736                         x[1].cancel()\r
737                 self.close()\r
738 \r
739 ##############################################################################\r
740 \r
741 class RSSearch(Screen):\r
742         skin = """\r
743                 <screen position="center,center" size="560,450" title="Searching... please wait!">\r
744                         <widget name="list" position="0,0" size="570,450" scrollbarMode="showOnDemand" />\r
745                 </screen>"""\r
746 \r
747         def __init__(self, session, searchFor):\r
748                 Screen.__init__(self, session)\r
749                 self.session = session\r
750                 \r
751                 self.searchFor = searchFor.replace(" ", "%2B")\r
752                 self.maxPage = 1\r
753                 self.curPage = 1\r
754                 self.files = []\r
755                 \r
756                 self["list"] = MenuList([])\r
757                 \r
758                 self["actions"] = ActionMap(["OkCancelActions", "InfobarChannelSelection"],\r
759                         {\r
760                                 "historyBack": self.previousPage,\r
761                                 "historyNext": self.nextPage,\r
762                                 "ok": self.okClicked,\r
763                                 "cancel": self.close\r
764                         }, -1)\r
765                 \r
766                 self.onLayoutFinish.append(self.search)\r
767 \r
768         def okClicked(self):\r
769                 if len(self.files) > 0:\r
770                         idx = self["list"].getSelectedIndex()\r
771                         url = self.files[idx]\r
772                         try:\r
773                                 f = open(("%s/search.txt" % config.plugins.RSDownloader.lists_directory.value).replace("//", "/"), "a")\r
774                                 f.write("%s\n"%url)\r
775                                 f.close()\r
776                                 self.session.open(MessageBox, (_("Added %s to the download-list.") % url), MessageBox.TYPE_INFO)\r
777                         except:\r
778                                 self.session.open(MessageBox, (_("Error while adding %s to the download-list!") % url), MessageBox.TYPE_ERROR)\r
779 \r
780         def search(self):\r
781                 getPage("http://rapidshare-search-engine.com/index-s_submit=Search&sformval=1&s_type=0&what=1&s=%s&start=%d.html"%(self.searchFor, self.curPage)).addCallback(self.searchCallback).addErrback(self.searchError)\r
782 \r
783         def searchCallback(self, html=""):\r
784                 list = []\r
785                 files = []\r
786                 \r
787                 if html.__contains__("Nothing found, sorry."):\r
788                         self.session.open(MessageBox, (_("Error while searching http://rapidshare-search-engine.com!\n\nError: Nothing found, sorry.")), MessageBox.TYPE_ERROR)\r
789                         self.instance.setTitle(_("Nothing found, sorry."))\r
790                 else:\r
791                         tmp = html\r
792                         while tmp.__contains__("goPg('"):\r
793                                 idx = tmp.index("goPg('")\r
794                                 tmp = tmp[idx+6:]\r
795                                 idx = tmp.index("'")\r
796                                 pageNumber = tmp[:idx]\r
797                                 \r
798                                 try:\r
799                                         pageNumber = int(pageNumber)\r
800                                         if pageNumber > self.maxPage:\r
801                                                 self.maxPage = pageNumber\r
802                                 except:\r
803                                         pass\r
804                                 \r
805                                 self.instance.setTitle(_("Page %d / %d. Push < > to switch the page...")%(self.curPage, self.maxPage))\r
806                         \r
807                         while html.__contains__('title="Download"'):\r
808                                 idx = html.index('title="Download"')\r
809                                 html = html[idx:]\r
810                                 idx = html.index('value="')\r
811                                 html = html[idx+7:]\r
812                                 idx = html.index('"')\r
813                                 size = html[:idx]\r
814                                 idx = html.index('http://rapidshare.com/')\r
815                                 html = html[idx:]\r
816                                 idx = html.index('"')\r
817                                 url = html[:idx]\r
818                                 \r
819                                 files.append(url) \r
820                                 try:\r
821                                         urllist = url.split("/")\r
822                                         idx = len(urllist) - 1\r
823                                         name = urllist[idx]\r
824                                         list.append("%s - %s"%(size, name))\r
825                                 except:\r
826                                         list.append("%s - %s"%(size, url))\r
827                 \r
828                 self.files = files\r
829                 self["list"].setList(list)\r
830 \r
831         def searchError(self, error=""):\r
832                 self.session.open(MessageBox, (_("Error while searching http://rapidshare-search-engine.com!\n\nError: %s")%str(error)), MessageBox.TYPE_ERROR)\r
833 \r
834         def previousPage(self):\r
835                 if self.curPage > 1:\r
836                         self.curPage -= 1\r
837                         self.instance.setTitle(_("Loading previous page... please wait!"))\r
838                         self.search()\r
839 \r
840         def nextPage(self):\r
841                 if self.curPage < self.maxPage:\r
842                         self.curPage += 1\r
843                         self.instance.setTitle(_("Loading next page... please wait!"))\r
844                         self.search()\r
845 \r
846 ##############################################################################\r
847 \r
848 class RSLogScreen(ChangedScreen):\r
849         skin = """\r
850                 <screen position="center,center" size="560,450" title="RS Downloader">\r
851                         <widget name="label" position="0,0" size="560,450" font="Regular;20" />\r
852                 </screen>"""\r
853 \r
854         def __init__(self, session):\r
855                 ChangedScreen.__init__(self, session)\r
856                 \r
857                 try:\r
858                         f = open("/tmp/rapidshare.log")\r
859                         log = f.read()\r
860                         f.close()\r
861                 except:\r
862                         log = ""\r
863                 self["label"] = ScrollLabel(log)\r
864                 \r
865                 self["actions"] = ActionMap(["WizardActions"],\r
866                         {\r
867                                 "ok": self.close,\r
868                                 "back": self.close,\r
869                                 "up": self["label"].pageUp,\r
870                                 "down": self["label"].pageDown,\r
871                                 "left": self["label"].pageUp,\r
872                                 "right": self["label"].pageDown\r
873                         }, -1)\r
874 \r
875 ##############################################################################\r
876 \r
877 class RSContainerSelector(ChangedScreen):\r
878         skin = """\r
879                 <screen position="center,center" size="560,450" title="RS Downloader">\r
880                         <widget name="list" position="0,0" size="560,450" />\r
881                 </screen>"""\r
882 \r
883         def __init__(self, session, list):\r
884                 ChangedScreen.__init__(self, session)\r
885                 self["list"] = MenuList(list)\r
886                 self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.okClicked, "cancel": self.close}, -1)\r
887 \r
888         def okClicked(self):\r
889                 cur = self["list"].getCurrent()\r
890                 self.close(cur)\r
891 \r
892 ##############################################################################
893
894 class UnrarEntry:
895         def __init__(self, name, password):
896                 self.name = name
897                 self.password = password
898                 self.working = False
899                 self.finishCallback = None
900                 self.console = None
901                 self.command = None
902                 self.list = ("%s/%s"%(config.plugins.RSDownloader.lists_directory.value, self.name)).replace("//", "/")
903                 package = None
904                 try:
905                         f = open(self.list, "r")
906                         while True:\r
907                                 line = f.readline()\r
908                                 if line == '':\r
909                                         break
910                                 elif line.startswith("http://") and (line.__contains__("part1.rar") or line.__contains__("part01.rar") or line.__contains__("part001.rar")):
911                                         package = line.split("/")[-1]
912                                         package = package.replace("\n", "").replace("\r", "")
913                                         package = ("%s/%s"%(config.plugins.RSDownloader.downloads_directory.value, package)).replace("//", "/")
914                                         break
915                         f.close()
916                 except:
917                         pass
918                 if package:
919                         if self.password:
920                                 self.command = "unrar -p%s -o+ x %s %s"%(self.password, package, config.plugins.RSDownloader.downloads_directory.value)
921                         else:
922                                 self.command = "unrar -o+ x %s %s"%(package, config.plugins.RSDownloader.downloads_directory.value)
923                 else:
924                         writeLog("Error finding rar-archives in list: %s"%self.name)
925
926         def startUnrar(self):
927                 self.working = True
928                 if not self.console:
929                         self.console = eConsole()
930                 self.console.ePopen(self.command, self.unrarDataAvailable)
931
932         def unrarDataAvailable(self, result, retval, extra_args):
933                 self.working = False
934                 try:
935                         fileName = ("%s/%s_unrar.txt"%(config.plugins.RSDownloader.downloads_directory.value, self.name)).replace("//", "/")
936                         f = open(fileName, "w")
937                         f.write(result)
938                         f.close()
939                 except:
940                         print "[RS Downloader] Result of unrar:",result
941                 self.finishCallback(self.name)
942
943         def allDownloaded(self):
944                 try:
945                         f = open(self.list, "r")
946                         content = f.read()
947                         f.close()
948                 except:
949                         content = ""
950                 if content.__contains__("http://"):
951                         return False
952                 else:
953                         return True
954
955 ##############################################################################
956
957 class Unrar:
958         def __init__(self):
959                 self.list = []
960                 self.timer = eTimer()
961                 self.timer.callback.append(self.checkUnrar)
962                 self.timer.start(30000, 1)
963                 self.xmlFile = ("%s/unrar.xml"%config.plugins.RSDownloader.lists_directory.value).replace("//", "/")
964                 
965         def addToList(self, name, password):
966                 entry = UnrarEntry(name, password)
967                 self.list.append(entry)
968
969         def deleteEntry(self, name):
970                 idx = 0
971                 ret = True
972                 for x in self.list:
973                         if x.name == name:
974                                 if x.working:
975                                         ret = False
976                                 else:
977                                         del self.list[idx]
978                                         break
979                         idx += 1
980                 return ret
981
982         def checkUnrar(self):
983                 if len(self.list) > 0:
984                         self.startUnrar()
985                 else:
986                         self.timer.start(30000, 1)
987
988         def isWorking(self):
989                 ret = False
990                 for x in self.list:
991                         if x.working:
992                                 ret = True
993                                 break
994                 return ret
995
996         def getFirstEmptyList(self):
997                 entry = None
998                 for x in self.list:
999                         if (x.allDownloaded() == True):
1000                                 entry = x
1001                                 break
1002                 return entry
1003
1004         def startUnrar(self):
1005                 ret = self.isWorking()
1006                 if ret == False:
1007                         entry = self.getFirstEmptyList()
1008                         if entry:
1009                                 if entry.command:
1010                                         writeLog("Start unpacking: %s"%entry.name)
1011                                         entry.finishCallback = self.cleanFinishedEntry
1012                                         entry.startUnrar()
1013                                 else:
1014                                         self.deleteEntry(entry.name)
1015                                         self.timer.start(30000, 1)
1016                         else:
1017                                 self.timer.start(30000, 1)
1018                 else:
1019                         self.timer.start(30000, 1)
1020
1021         def cleanFinishedEntry(self, name):
1022                 writeLog("Unpacking finished: %s"%name)
1023                 self.deleteEntry(name)
1024                 self.checkUnrar()
1025
1026         def decode_charset(self, str, charset):
1027                 try:
1028                         uni = unicode(str, charset, 'strict')
1029                 except:
1030                         uni = str
1031                 return uni
1032
1033         def loadXml(self):
1034                 if fileExists(self.xmlFile):
1035                         menu = parse(self.xmlFile).getroot()
1036                         for item in menu.findall("entry"):
1037                                 name = item.get("name") or None
1038                                 password = item.get("password") or None
1039                                 if name and password:
1040                                         name = self.decode_charset(name, "utf-8")
1041                                         password = self.decode_charset(password, "utf-8")
1042                                         self.addToList(str(name), str(password))
1043
1044         def writeXml(self):
1045                 xml = '<unrar>\n'
1046                 for x in self.list:
1047                         name = self.decode_charset(x.name, "utf-8")
1048                         password = self.decode_charset(x.password, "utf-8")
1049                         xml += '\t<entry name="%s" password="%s" />\n'%(name.encode("utf-8"), password.encode("utf-8"))
1050                 xml += '</unrar>\n'
1051                 try:
1052                         f = open(self.xmlFile, "w")
1053                         f.write(xml)
1054                         f.close()
1055                 except:
1056                         writeLog("Error writing unrar xml file: %s"%self.xmlFile)
1057 unrar = Unrar()
1058
1059 ##############################################################################
1060
1061 class UnrarPackageSelector(ChangedScreen):\r
1062         skin = """\r
1063                 <screen position="center,center" size="560,450" title="RS Downloader">\r
1064                         <widget name="list" position="0,0" size="560,450" />\r
1065                 </screen>"""\r
1066 \r
1067         def __init__(self, session):\r
1068                 ChangedScreen.__init__(self, session)
1069                 \r
1070                 self["list"] = MenuList([])
1071                 \r
1072                 self["actions"] = ActionMap(["OkCancelActions"],
1073                         {
1074                                 "ok": self.okClicked,
1075                                 "cancel": self.close
1076                         }, -1)
1077                 
1078                 self.onLayoutFinish.append(self.updateList)
1079
1080         def updateList(self):\r
1081                 try:\r
1082                         names = listdir(config.plugins.RSDownloader.lists_directory.value)\r
1083                 except:\r
1084                         names = []\r
1085                 list = []\r
1086                 for name in names:\r
1087                         if name.lower().endswith(".txt"):
1088                                 added = False
1089                                 for x in unrar.list:
1090                                         if x.name == name:
1091                                                 added = True
1092                                 if added == False:\r
1093                                         list.append(name)\r
1094                 list.sort()
1095                 self["list"].setList(list)\r
1096 \r
1097         def okClicked(self):\r
1098                 cur = self["list"].getCurrent()
1099                 if cur:
1100                         self.name = cur
1101                         self.session.openWithCallback(self.okClickedCallback, VirtualKeyBoard, title=_("Enter unrar password:"))
1102
1103         def okClickedCallback(self, callback=None):
1104                 if callback is None:
1105                         callback = ""\r
1106                 self.close([self.name, callback])
1107
1108 ##############################################################################
1109
1110 class UnrarManager(ChangedScreen):\r
1111         skin = """\r
1112                 <screen position="center,center" size="560,450" title="RS Downloader">\r
1113                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />\r
1114                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />\r
1115                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />\r
1116                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />\r
1117                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
1118                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
1119                         <widget name="list" position="0,40" size="560,375" scrollbarMode="showNever" />\r
1120                 </screen>"""\r
1121 \r
1122         def __init__(self, session):\r
1123                 ChangedScreen.__init__(self, session)\r
1124                 self.session = session
1125                 \r
1126                 self["key_red"] = Label(_("Delete"))\r
1127                 self["key_green"] = Label(_("Add"))\r
1128                 self["list"] = MenuList([])
1129                 \r
1130                 self["actions"] = ActionMap(["ColorActions", "OkCancelActions"],
1131                         {
1132                                 "red": self.delete,
1133                                 "green": self.add,
1134                                 "cancel": self.close
1135                         }, prio=-1)
1136                 \r
1137                 self.onLayoutFinish.append(self.updateList)
1138
1139         def updateList(self):
1140                 list = []
1141                 for x in unrar.list:
1142                         list.append(x.name)
1143                 list.sort()
1144                 self["list"].setList(list)
1145
1146         def delete(self):
1147                 cur = self["list"].getCurrent()
1148                 if cur:
1149                         ret = unrar.deleteEntry(cur)
1150                         if ret:
1151                                 self.updateList()
1152                         else:
1153                                 self.session.open(MessageBox, _("Unrar is already working!"), MessageBox.TYPE_ERROR)
1154
1155         def add(self):
1156                 self.session.openWithCallback(self.addCallback, UnrarPackageSelector)
1157
1158         def addCallback(self, callback=None):
1159                 if callback:
1160                         unrar.addToList(callback[0], callback[1])
1161                         self.updateList()\r
1162
1163 ##############################################################################
1164 \r
1165 class RSList(MenuList):\r
1166         def __init__(self, list):\r
1167                 MenuList.__init__(self, list, False, eListboxPythonMultiContent)\r
1168                 self.l.setItemHeight(25)\r
1169                 self.l.setFont(0, gFont("Regular", 20))\r
1170 \r
1171 ##############################################################################\r
1172 \r
1173 def RSListEntry(download):\r
1174         res = [(download)]\r
1175         res.append(MultiContentEntryText(pos=(0, 0), size=(170, 25), font=0, text=download.name))\r
1176         res.append(MultiContentEntryText(pos=(175, 0), size=(75, 25), font=0, text="%d%s"%(download.size, "MB"), flags=RT_HALIGN_CENTER))\r
1177         res.append(MultiContentEntryPixmapAlphaTest(pos=(260, 9), size=(84, 7), png=LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/progress_bg.png"))))\r
1178         res.append(MultiContentEntryPixmapAlphaTest(pos=(260, 10), size=(int(0.84 * download.progress), 5), png=LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/progress_small.png"))))\r
1179         res.append(MultiContentEntryText(pos=(360, 0), size=(60, 25), font=0, text="%d%s"%(download.progress, "%"), flags=RT_HALIGN_CENTER))\r
1180         res.append(MultiContentEntryText(pos=(420, 0), size=(140, 25), font=0, text=download.status, flags=RT_HALIGN_RIGHT))\r
1181         return res\r
1182 \r
1183 ##############################################################################\r
1184 \r
1185 class RSMain(ChangedScreen):\r
1186         skin = """\r
1187                 <screen position="center,center" size="560,450" title="RS Downloader">\r
1188                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />\r
1189                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />\r
1190                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />\r
1191                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />\r
1192                         <ePixmap pixmap="skin_default/buttons/key_menu.png" position="10,420" size="35,25" transparent="1" alphatest="on" />\r
1193                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
1194                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
1195                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
1196                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />\r
1197                         <widget name="key_menu" position="50,422" size="300,25" font="Regular;20" transparent="1" />\r
1198                         <widget name="list" position="0,40" size="560,375" scrollbarMode="showNever" />\r
1199                 </screen>"""\r
1200 \r
1201         def __init__(self, session):\r
1202                 ChangedScreen.__init__(self, session)\r
1203                 self.session = session\r
1204                 \r
1205                 self["key_red"] = Label(_("Delete"))\r
1206                 self["key_green"] = Label(_("Search"))\r
1207                 self["key_yellow"] = Label(_("Add"))\r
1208                 self["key_blue"] = Label(_("Config"))\r
1209                 self["key_menu"] = Label(_("Menu"))\r
1210                 self["list"] = RSList([])\r
1211                 \r
1212                 self.refreshTimer = eTimer()\r
1213                 self.refreshTimer.callback.append(self.updateList)\r
1214                 \r
1215                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "InfobarMenuActions"],\r
1216                         {\r
1217                                 "mainMenu": self.menu,\r
1218                                 "cancel": self.close,\r
1219                                 "red": self.delete,\r
1220                                 "green": self.search,\r
1221                                 "yellow": self.add,\r
1222                                 "blue": self.config\r
1223                         }, prio=-1)\r
1224                 \r
1225                 self.onLayoutFinish.append(self.updateList)\r
1226 \r
1227         def menu(self):\r
1228                 list = []\r
1229                 list.append((_("Delete download"), self.delete))\r
1230                 list.append((_("Use search engine"), self.search))\r
1231                 list.append((_("Add downloads from txt files"), self.add))\r
1232                 list.append((_("Add files from container"), self.addContainer))\r
1233                 list.append((_("Delete failed downloads"), self.deleteFailed))\r
1234                 list.append((_("Abort all downloads"), self.abortDownloads))\r
1235                 list.append((_("Restart failed downloads"), self.restartFailed))\r
1236                 list.append((_("Clear finished downloads"), self.clearFinished))\r
1237                 list.append((_("Show log"), self.showLog))\r
1238                 list.append((_("Delete log"), self.deleteLog))
1239                 if fileExists("/usr/bin/unrar"):
1240                         list.append((_("Open unrar Manager"), self.openUnrarManager))
1241                 else:
1242                         list.append((_("Install unrar"), self.installUnrar))\r
1243                 list.append((_("Close plugin"), self.close))\r
1244                 self.session.openWithCallback(self.menuCallback, ChoiceBox, title=_("Please choose a function..."), list=list)\r
1245 \r
1246         def menuCallback(self, callback=None):\r
1247                 if callback is not None:\r
1248                         callback[1]()\r
1249 \r
1250         def deleteFailed(self):\r
1251                 rapidshare.deleteFailedDownloads()
1252
1253         def abortDownloads(self):
1254                 rapidshare.abortAllDownloads()\r
1255 \r
1256         def restartFailed(self):\r
1257                 rapidshare.restartFailedDownloads()\r
1258 \r
1259         def clearFinished(self):\r
1260                 rapidshare.clearFinishedDownloads()\r
1261 \r
1262         def showLog(self):\r
1263                 self.session.open(RSLogScreen)\r
1264 \r
1265         def deleteLog(self):\r
1266                 try:\r
1267                         remove("/tmp/rapidshare.log")\r
1268                 except:\r
1269                         pass
1270
1271         def openUnrarManager(self):
1272                 self.session.open(UnrarManager)
1273
1274         def installUnrar(self):
1275                 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
1276 \r
1277         def updateList(self):\r
1278                 list = []\r
1279                 for download in rapidshare.downloads:\r
1280                         list.append(RSListEntry(download))\r
1281                 self["list"].setList(list)\r
1282                 self.refreshTimer.start(2000, 1)\r
1283 \r
1284         def delete(self):\r
1285                 cur = self["list"].getCurrent()\r
1286                 if cur:\r
1287                         cur = cur[0]\r
1288                         if cur.status == _("Finished"):\r
1289                                 rapidshare.clearFinishedDownload(cur.url)\r
1290                         else:\r
1291                                 self.session.openWithCallback(self.deleteCallback, MessageBox, (_("Delete %s?")%cur.name))\r
1292 \r
1293         def deleteCallback(self, callback):\r
1294                 if callback:\r
1295                         rapidshare.removeDownload(self["list"].getCurrent()[0].url)\r
1296                         self.refreshTimer.stop()\r
1297                         self.updateList()\r
1298 \r
1299         def search(self):\r
1300                 self.session.openWithCallback(self.searchCallback, VirtualKeyBoard, title=_("Search http://rapidshare-search-engine.com for:"))\r
1301 \r
1302         def searchCallback(self, callback):\r
1303                 if callback is not None and callback != "":\r
1304                         self.session.openWithCallback(self.searchScreenCallback, RSSearch, callback)\r
1305 \r
1306 \r
1307         def searchScreenCallback(self):\r
1308                 self.refreshTimer.stop()\r
1309                 rapidshare.startDownloading()\r
1310                 self.updateList()\r
1311 \r
1312         def add(self):\r
1313                 self.refreshTimer.stop()\r
1314                 rapidshare.startDownloading()\r
1315                 self.updateList()\r
1316 \r
1317         def config(self):\r
1318                 self.session.openWithCallback(self.configCallback, RSConfig)\r
1319 \r
1320         def configCallback(self):\r
1321                 if config.plugins.RSDownloader.onoff.value:\r
1322                         rapidshare.startDownloading()\r
1323                 else:\r
1324                         for download in rapidshare.downloads:\r
1325                                 if download.downloading:\r
1326                                         download.stop()\r
1327                 self.updateList()\r
1328 \r
1329         def addContainer(self):\r
1330                 try:\r
1331                         file_list = listdir(config.plugins.RSDownloader.lists_directory.value)\r
1332                 except:\r
1333                         file_list = []\r
1334                 list = []\r
1335                 for file in file_list:\r
1336                         if file.lower().endswith(".ccf") or file.lower().endswith(".dlc") or file.lower().endswith(".rsdf"):\r
1337                                 list.append(file)\r
1338                 list.sort()\r
1339                 self.session.openWithCallback(self.addContainerCallback, RSContainerSelector, list)\r
1340 \r
1341         def addContainerCallback(self, callback=None):\r
1342                 if callback:\r
1343                         file = "%s/%s"%(config.plugins.RSDownloader.lists_directory.value, callback)\r
1344                         file = file.replace("//", "/")\r
1345                         links = decrypt(file)
1346                         if links:\r
1347                                 try:\r
1348                                         f = open(("%s/%s.txt" % (config.plugins.RSDownloader.lists_directory.value, callback)).replace("//", "/"), "w")\r
1349                                         for link in links:\r
1350                                                 if link.endswith(".html"):\r
1351                                                         link = link[:-5]\r
1352                                                 elif link.endswith(".htm"):\r
1353                                                         link = link[:-4]\r
1354                                                 f.write("%s\n"%link)\r
1355                                         f.close()
1356                                         remove(file)\r
1357                                 except:\r
1358                                         pass\r
1359                                 self.refreshTimer.stop()\r
1360                                 rapidshare.startDownloading()\r
1361                                 self.updateList()
1362                         else:
1363                                 self.session.open(MessageBox, (_("Error while decrypting %s!") % callback), MessageBox.TYPE_ERROR)\r
1364 \r
1365 ##############################################################################\r
1366 \r
1367 def autostart(reason, **kwargs):\r
1368         if reason == 0:\r
1369                 rapidshare.startDownloading()
1370                 unrar.loadXml()
1371         elif reason == 1:
1372                 unrar.writeXml()\r
1373 \r
1374 ##############################################################################\r
1375 \r
1376 def main(session, **kwargs):\r
1377         session.open(RSMain)\r
1378 \r
1379 ##############################################################################\r
1380 \r
1381 def Plugins(**kwargs):\r
1382         return [\r
1383                 PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=autostart),\r
1384                 PluginDescriptor(name=_("RS Downloader"), description=_("Download files from rapidshare"), where=[PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_PLUGINMENU], icon="rs.png", fnc=main)]\r
1385 \r