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