diff options
Diffstat (limited to 'module')
23 files changed, 547 insertions, 237 deletions
diff --git a/module/plugins/accounts/DebridItaliaCom.py b/module/plugins/accounts/DebridItaliaCom.py index d68f1c8a8..91dd3787f 100644 --- a/module/plugins/accounts/DebridItaliaCom.py +++ b/module/plugins/accounts/DebridItaliaCom.py @@ -1,5 +1,20 @@ # -*- coding: utf-8 -*- +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + import re import _strptime import time diff --git a/module/plugins/accounts/RarefileNet.py b/module/plugins/accounts/RarefileNet.py index 57f293c55..90ad02d43 100644 --- a/module/plugins/accounts/RarefileNet.py +++ b/module/plugins/accounts/RarefileNet.py @@ -3,10 +3,10 @@ from module.plugins.internal.XFSPAccount import XFSPAccount class RarefileNet(XFSPAccount): __name__ = "RarefileNet" - __version__ = "0.01" + __version__ = "0.02" __type__ = "account" __description__ = """RareFile.net account plugin""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") - MAIN_PAGE = "http://rarefile.in/"
\ No newline at end of file + MAIN_PAGE = "http://rarefile.net/" diff --git a/module/plugins/crypter/DataHuFolder.py b/module/plugins/crypter/DataHuFolder.py new file mode 100644 index 000000000..f710f60d7 --- /dev/null +++ b/module/plugins/crypter/DataHuFolder.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + +import re + +from module.plugins.internal.SimpleCrypter import SimpleCrypter + + +class DataHuFolder(SimpleCrypter): + __name__ = "DataHuFolder" + __type__ = "crypter" + __pattern__ = r"http://(www\.)?data.hu/dir/\w+" + __version__ = "0.03" + __description__ = """Data.hu Folder Plugin""" + __author_name__ = ("crash", "stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + LINK_PATTERN = r"<a href='(http://data\.hu/get/.+)' target='_blank'>\1</a>" + TITLE_PATTERN = ur'<title>(?P<title>.+) Let\xf6lt\xe9se</title>' + + def decrypt(self, pyfile): + self.html = self.load(pyfile.url, decode=True) + + if u'K\xe9rlek add meg a jelsz\xf3t' in self.html: # Password protected + password = self.getPassword() + if password is '': + self.fail("No password specified, please set right password on Add package form and retry") + self.logDebug('The folder is password protected', 'Using password: ' + password) + self.html = self.load(pyfile.url, post={'mappa_pass': password}, decode=True) + if u'Hib\xe1s jelsz\xf3' in self.html: # Wrong password + self.fail("Incorrect password, please set right password on Add package form and retry") + + package_name, folder_name = self.getPackageNameAndFolder() + + package_links = re.findall(self.LINK_PATTERN, self.html) + self.logDebug('Package has %d links' % len(package_links)) + + if package_links: + self.packages = [(package_name, package_links, folder_name)] + else: + self.fail('Could not extract any links') diff --git a/module/plugins/crypter/GooGl.py b/module/plugins/crypter/GooGl.py new file mode 100644 index 000000000..bcb1d7494 --- /dev/null +++ b/module/plugins/crypter/GooGl.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + +from module.plugins.Crypter import Crypter +from module.common.json_layer import json_loads + + +class GooGl(Crypter): + __name__ = "GooGl" + __type__ = "crypter" + __pattern__ = r"https?://(www\.)?goo\.gl/\w+" + __version__ = "0.01" + __description__ = """Goo.gl Crypter Plugin""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + API_URL = 'https://www.googleapis.com/urlshortener/v1/url' + + def decrypt(self, pyfile): + rep = self.load(self.API_URL, get={'shortUrl': pyfile.url}) + self.logDebug('JSON data: ' + rep) + rep = json_loads(rep) + + if 'longUrl' in rep: + self.core.files.addLinks([rep['longUrl']], self.pyfile.package().id) + else: + self.fail('Unable to expand shortened link') diff --git a/module/plugins/crypter/NetfolderIn.py b/module/plugins/crypter/NetfolderIn.py index d71a73d0a..c5c602c27 100644 --- a/module/plugins/crypter/NetfolderIn.py +++ b/module/plugins/crypter/NetfolderIn.py @@ -1,22 +1,25 @@ # -*- coding: utf-8 -*- -from module.plugins.Crypter import Crypter import re -class NetfolderIn(Crypter): +from module.plugins.internal.SimpleCrypter import SimpleCrypter + + +class NetfolderIn(SimpleCrypter): __name__ = "NetfolderIn" __type__ = "crypter" __pattern__ = r"http://(?:www\.)?netfolder.in/((?P<id1>\w+)/\w+|folder.php\?folder_id=(?P<id2>\w+))" - __version__ = "0.4" + __version__ = "0.6" __description__ = """NetFolder Crypter Plugin""" __author_name__ = ("RaNaN", "fragonib") __author_mail__ = ("RaNaN@pyload.org", "fragonib[AT]yahoo[DOT]es") + TITLE_PATTERN = r'<div class="Text">Inhalt des Ordners <span(.*)>(?P<title>.+)</span></div>' + def decrypt(self, pyfile): - # Request package self.html = self.load(pyfile.url) - + # Check for password protection if self.isPasswordProtected(): self.html = self.submitPassword() @@ -31,54 +34,37 @@ class NetfolderIn(Crypter): # Set package self.packages = [(package_name, package_links, folder_name)] - - + def isPasswordProtected(self): - + if '<input type="password" name="password"' in self.html: self.logDebug("Links are password protected") return True return False - def submitPassword(self): # Gather data try: m = re.match(self.__pattern__, self.pyfile.url) - id = max(m.group('id1'), m.group('id2')) + id = max(m.group('id1'), m.group('id2')) except AttributeError: self.logDebug("Unable to get package id from url [%s]" % self.pyfile.url) return url = "http://netfolder.in/folder.php?folder_id=" + id password = self.getPassword() - + # Submit package password - post = { 'password' : password, 'save' : 'Absenden' } + post = {'password': password, 'save': 'Absenden'} self.logDebug("Submitting password [%s] for protected links with id [%s]" % (password, id)) html = self.load(url, {}, post) - + # Check for invalid password if '<div class="InPage_Error">' in html: self.logDebug("Incorrect password, please set right password on Edit package form and retry") return None - - return html - - - def getPackageNameAndFolder(self): - title_re = r'<div class="Text">Inhalt des Ordners <span(.*)>(?P<title>.+)</span></div>' - m = re.search(title_re, self.html) - if m is not None: - name = folder = m.group('title') - self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder)) - return name, folder - else: - name = self.pyfile.package().name - folder = self.pyfile.package().folder - self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder)) - return name, folder - - + + return html + def getLinks(self): links = re.search(r'name="list" value="(.*?)"', self.html).group(1).split(",") self.logDebug("Package has %d links" % len(links)) diff --git a/module/plugins/crypter/SpeedLoadOrgFolder.py b/module/plugins/crypter/SpeedLoadOrgFolder.py index 5b350787f..f85ede6f3 100644 --- a/module/plugins/crypter/SpeedLoadOrgFolder.py +++ b/module/plugins/crypter/SpeedLoadOrgFolder.py @@ -1,5 +1,20 @@ # -*- coding: utf-8 -*- +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + from module.plugins.internal.SimpleCrypter import SimpleCrypter class SpeedLoadOrgFolder(SimpleCrypter): diff --git a/module/plugins/crypter/UlozToFolder.py b/module/plugins/crypter/UlozToFolder.py index c6672ea8c..814d5240d 100644 --- a/module/plugins/crypter/UlozToFolder.py +++ b/module/plugins/crypter/UlozToFolder.py @@ -7,7 +7,7 @@ class UlozToFolder(Crypter): __name__ = "UlozToFolder" __type__ = "crypter" __pattern__ = r"http://.*(uloz\.to|ulozto\.(cz|sk|net)|bagruj.cz|zachowajto.pl)/(m|soubory)/.*" - __version__ = "0.1a" + __version__ = "0.2" __description__ = """Uloz.to Folder Plugin""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") diff --git a/module/plugins/crypter/UploadedToFolder.py b/module/plugins/crypter/UploadedToFolder.py index d4534297e..c514f23d0 100644 --- a/module/plugins/crypter/UploadedToFolder.py +++ b/module/plugins/crypter/UploadedToFolder.py @@ -1,13 +1,30 @@ # -*- coding: utf-8 -*-
-from module.plugins.Crypter import Crypter
+############################################################################
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU Affero General Public License as #
+# published by the Free Software Foundation, either version 3 of the #
+# License, or (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU Affero General Public License for more details. #
+# #
+# You should have received a copy of the GNU Affero General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+############################################################################
+
import re
-class UploadedToFolder(Crypter):
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
+
+
+class UploadedToFolder(SimpleCrypter):
__name__ = "UploadedToFolder"
__type__ = "crypter"
- __pattern__ = r"http://(?:www\.)?(uploaded|ul)\.(to|net)/(f|list)/(?P<id>\w+)"
- __version__ = "0.1"
+ __pattern__ = r"http://(?:www\.)?(uploaded|ul)\.(to|net)/(f|folder|list)/(?P<id>\w+)"
+ __version__ = "0.3"
__description__ = """UploadedTo Crypter Plugin"""
__author_name__ = ("stickell")
__author_mail__ = ("l.stickell@yahoo.it")
@@ -31,15 +48,3 @@ class UploadedToFolder(Crypter): self.logDebug('Package has %d links' % len(package_links))
self.packages = [(package_name, package_links, folder_name)]
-
- def getPackageNameAndFolder(self):
- m = re.search(self.TITLE_PATTERN, self.html)
- if m:
- name = folder = m.group('title')
- self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder))
- return name, folder
- else:
- name = self.pyfile.package().name
- folder = self.pyfile.package().folder
- self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
- return name, folder
diff --git a/module/plugins/hooks/DebridItaliaCom.py b/module/plugins/hooks/DebridItaliaCom.py index 8cd997f4d..d570eebe3 100644 --- a/module/plugins/hooks/DebridItaliaCom.py +++ b/module/plugins/hooks/DebridItaliaCom.py @@ -1,11 +1,26 @@ # -*- coding: utf-8 -*- +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + from module.plugins.internal.MultiHoster import MultiHoster class DebridItaliaCom(MultiHoster): __name__ = "DebridItaliaCom" - __version__ = "0.01" + __version__ = "0.03" __type__ = "hook" __config__ = [("activated", "bool", "Activated", "False"), ("hosterListMode", "all;listed;unlisted", "Use for hosters (if supported)", "all"), @@ -22,4 +37,5 @@ class DebridItaliaCom(MultiHoster): "uploading.com", "megashares.com", "crocko.com", "filepost.com", "bitshare.com", "share-links.biz", "putlocker.com", "uploaded.to", "speedload.org", "rapidgator.net", "likeupload.net", "cyberlocker.ch", - "depositfiles.com", "extabit.com", "filefactory.com", "sharefiles.co"] + "depositfiles.com", "extabit.com", "filefactory.com", "sharefiles.co", + "ryushare.com", "tusfiles.net", "nowvideo.co"] diff --git a/module/plugins/hooks/LinkdecrypterCom.py b/module/plugins/hooks/LinkdecrypterCom.py index 2cb91d120..d3d6bce68 100644 --- a/module/plugins/hooks/LinkdecrypterCom.py +++ b/module/plugins/hooks/LinkdecrypterCom.py @@ -24,7 +24,7 @@ from module.utils import remove_chars class LinkdecrypterCom(Hook): __name__ = "LinkdecrypterCom" - __version__ = "0.16" + __version__ = "0.17" __description__ = """linkdecrypter.com - regexp loader""" __config__ = [ ("activated", "bool", "Activated" , "True") ] __author_name__ = ("zoidberg") @@ -50,7 +50,7 @@ class LinkdecrypterCom(Hook): self.logError(_("Crypter list is empty")) return - regexp = r"http://([^.]+\.)*?(%s)/.*" % "|".join(online) + regexp = r"https?://([^.]+\.)*?(%s)/.*" % "|".join(online) dict = self.core.pluginManager.crypterPlugins[self.__name__] dict["pattern"] = regexp diff --git a/module/plugins/hoster/AlldebridCom.py b/module/plugins/hoster/AlldebridCom.py index fe58ff0a7..efc96ff28 100644 --- a/module/plugins/hoster/AlldebridCom.py +++ b/module/plugins/hoster/AlldebridCom.py @@ -1,19 +1,16 @@ -#!/usr/nv python
# -*- coding: utf-8 -*-
import re
-from urllib import quote, unquote
+from urllib import unquote
from random import randrange
-from os import stat
-
from module.plugins.Hoster import Hoster
from module.common.json_layer import json_loads
-from module.utils import parseFileSize, fs_encode
+from module.utils import parseFileSize
class AlldebridCom(Hoster):
__name__ = "AlldebridCom"
- __version__ = "0.3"
+ __version__ = "0.31"
__type__ = "hoster"
__pattern__ = r"https?://.*alldebrid\..*"
@@ -27,7 +24,7 @@ class AlldebridCom(Hoster): except IndexError:
name = "Unknown_Filename..."
if name.endswith("..."): #incomplete filename, append random stuff
- name += "%s.tmp" % randrange(100,999)
+ name += "%s.tmp" % randrange(100, 999)
return name
def init(self):
@@ -35,10 +32,9 @@ class AlldebridCom(Hoster): self.chunkLimit = 3
self.resumeDownload = True
-
- def process(self, pyfile):
+ def process(self, pyfile):
if not self.account:
- self.logError(_("Please enter your AllDebrid account or deactivate this plugin"))
+ self.logError("Please enter your AllDebrid account or deactivate this plugin")
self.fail("No AllDebrid account provided")
self.log.debug("AllDebrid: Old URL: %s" % pyfile.url)
@@ -46,14 +42,13 @@ class AlldebridCom(Hoster): new_url = pyfile.url
else:
password = self.getPassword().splitlines()
- if not password: password = ""
- else: password = password[0]
+ password = "" if not password else password[0]
- url = "http://www.alldebrid.com/service.php?link=%s&json=true&pw=%s" %(pyfile.url, password)
+ url = "http://www.alldebrid.com/service.php?link=%s&json=true&pw=%s" % (pyfile.url, password)
page = self.load(url)
data = json_loads(page)
-
- self.log.debug("Json data: %s" % str(data))
+
+ self.logDebug("Json data: %s" % str(data))
if data["error"]:
if data["error"] == "This link isn't available on the hoster website.":
@@ -72,7 +67,7 @@ class AlldebridCom(Hoster): else:
new_url = new_url.replace("https://", "http://")
- self.log.debug("AllDebrid: New URL: %s" % new_url)
+ self.logDebug("AllDebrid: New URL: %s" % new_url)
if pyfile.name.startswith("http") or pyfile.name.startswith("Unknown"):
#only use when name wasnt already set
@@ -80,12 +75,10 @@ class AlldebridCom(Hoster): self.download(new_url, disposition=True)
- check = self.checkDownload(
- {"error": "<title>An error occured while processing your request</title>","empty": re.compile(r"^$")})
+ check = self.checkDownload({"error": "<title>An error occured while processing your request</title>",
+ "empty": re.compile(r"^$")})
if check == "error":
self.retry(reason="An error occured while generating link.", wait_time=60)
- else:
- if check == "empty":
- self.retry(reason="Downloaded File was empty.", wait_time=60)
-
+ elif check == "empty":
+ self.retry(reason="Downloaded File was empty.", wait_time=60)
diff --git a/module/plugins/hoster/DataHu.py b/module/plugins/hoster/DataHu.py new file mode 100644 index 000000000..7abd93d1f --- /dev/null +++ b/module/plugins/hoster/DataHu.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + +# Test links (random.bin): +# http://data.hu/get/6381232/random.bin + +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class DataHu(SimpleHoster): + __name__ = "DataHu" + __type__ = "hoster" + __pattern__ = r"http://(www\.)?data.hu/get/\w+" + __version__ = "0.01" + __description__ = """Data.hu Download Hoster""" + __author_name__ = ("crash", "stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_INFO_PATTERN = ur'<title>(?P<N>.*) \((?P<S>[^)]+)\) let\xf6lt\xe9se</title>' + FILE_OFFLINE_PATTERN = ur'Az adott f\xe1jl nem l\xe9tezik' + DIRECT_LINK_PATTERN = r'<div class="download_box_button"><a href="([^"]+)">' + + def handleFree(self): + self.resumeDownload = True + self.html = self.load(self.pyfile.url, decode=True) + + m = re.search(self.DIRECT_LINK_PATTERN, self.html) + if m: + url = m.group(1) + self.logDebug('Direct link: ' + url) + else: + self.parseError('Unable to get direct link') + + self.download(url, disposition=True) + + +getInfo = create_getInfo(DataHu) diff --git a/module/plugins/hoster/DebridItaliaCom.py b/module/plugins/hoster/DebridItaliaCom.py index 5142bbdf7..470c4ae5d 100644 --- a/module/plugins/hoster/DebridItaliaCom.py +++ b/module/plugins/hoster/DebridItaliaCom.py @@ -1,5 +1,20 @@ # -*- coding: utf-8 -*- +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + import re from module.plugins.Hoster import Hoster @@ -7,7 +22,7 @@ from module.plugins.Hoster import Hoster class DebridItaliaCom(Hoster): __name__ = "DebridItaliaCom" - __version__ = "0.01" + __version__ = "0.03" __type__ = "hoster" __pattern__ = r"https?://.*debriditalia\.com" __description__ = """Debriditalia.com hoster plugin""" @@ -31,8 +46,16 @@ class DebridItaliaCom(Hoster): page = self.load(url) self.logDebug("XML data: %s" % page) - new_url = re.search(r'<a href="(?:[^"]+)">(?P<direct>[^<]+)</a>', page).group('direct') + if 'File not available' in page: + self.fail('File not available') + else: + new_url = re.search(r'<a href="(?:[^"]+)">(?P<direct>[^<]+)</a>', page).group('direct') self.logDebug("New URL: %s" % new_url) - self.download(new_url, disposition=True)
\ No newline at end of file + self.download(new_url, disposition=True) + + check = self.checkDownload({"empty": re.compile(r"^$")}) + + if check == "empty": + self.retry(5, 120, 'Empty file downloaded') diff --git a/module/plugins/hoster/EgoFilesCom.py b/module/plugins/hoster/EgoFilesCom.py index b27abb416..ad278e60f 100644 --- a/module/plugins/hoster/EgoFilesCom.py +++ b/module/plugins/hoster/EgoFilesCom.py @@ -1,15 +1,34 @@ # -*- coding: utf-8 -*-
+############################################################################
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU Affero General Public License as #
+# published by the Free Software Foundation, either version 3 of the #
+# License, or (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU Affero General Public License for more details. #
+# #
+# You should have received a copy of the GNU Affero General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+############################################################################
+
+# Test link (random.bin):
+# http://egofiles.com/mOZfMI1WLZ6HBkGG/random.bin
+
+import re
+
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
from module.plugins.ReCaptcha import ReCaptcha
-import re
class EgoFilesCom(SimpleHoster):
__name__ = "EgoFilesCom"
__type__ = "hoster"
__pattern__ = r"https?://(www\.)?egofiles.com/(\w+)"
- __version__ = "0.10"
+ __version__ = "0.11"
__description__ = """Egofiles.com Download Hoster"""
__author_name__ = ("stickell")
__author_mail__ = ("l.stickell@yahoo.it")
@@ -25,8 +44,15 @@ class EgoFilesCom(SimpleHoster): # Set English language
self.load("https://egofiles.com/ajax/lang.php?lang=en", just_header=True)
+ def process(self, pyfile):
+ if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()):
+ self.handlePremium()
+ else:
+ self.handleFree()
+
def handleFree(self):
self.html = self.load(self.pyfile.url, decode=True)
+ self.getFileInfo()
# Wait time between free downloads
if 'For next free download you have to wait' in self.html:
@@ -56,7 +82,7 @@ class EgoFilesCom(SimpleHoster): if not downloadURL:
self.fail("No Download url retrieved/all captcha attempts failed")
- self.download(downloadURL)
+ self.download(downloadURL, disposition=True)
def handlePremium(self):
header = self.load(self.pyfile.url, just_header=True)
@@ -65,11 +91,13 @@ class EgoFilesCom(SimpleHoster): self.download(header['location'])
else:
self.html = self.load(self.pyfile.url, decode=True)
+ self.getFileInfo()
m = re.search(r'<a href="(?P<link>[^"]+)">Download ></a>', self.html)
if not m:
self.parseError('Unable to detect direct download url')
else:
self.logDebug('DIRECT URL from html: ' + m.group('link'))
- self.download(m.group('link'))
+ self.download(m.group('link'), disposition=True)
+
getInfo = create_getInfo(EgoFilesCom)
diff --git a/module/plugins/hoster/FilerNet.py b/module/plugins/hoster/FilerNet.py new file mode 100644 index 000000000..9693723f9 --- /dev/null +++ b/module/plugins/hoster/FilerNet.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- + +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + +# Test links (random.bin): +# http://filer.net/get/ivgf5ztw53et3ogd +# http://filer.net/get/hgo14gzcng3scbvv + +import pycurl +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.ReCaptcha import ReCaptcha + + +class FilerNet(SimpleHoster): + __name__ = "FilerNet" + __type__ = "hoster" + __pattern__ = r"https?://(www\.)?filer\.net/get/(\w+)" + __version__ = "0.01" + __description__ = """Filer.net Download Hoster""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_INFO_PATTERN = r'<h1 class="page-header">Free Download (?P<N>\S+) <small>(?P<S>[\w.]+) (?P<U>\w+)</small></h1>' + FILE_OFFLINE_PATTERN = r'Nicht gefunden' + RECAPTCHA_KEY = '6LcFctISAAAAAAgaeHgyqhNecGJJRnxV1m_vAz3V' + + def process(self, pyfile): + self.req.setOption("timeout", 120) + self.html = self.load(pyfile.url, decode=not self.SH_BROKEN_ENCODING, cookies=self.SH_COOKIES) + + # Wait between downloads + m = re.search(r'musst du <span id="time">(\d+)</span> Sekunden warten', self.html) + if m: + waittime = int(m.group(1)) + self.retry(3, waittime, 'Wait between free downloads') + + self.getFileInfo() + if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): + self.handlePremium() + else: + self.handleFree() + + def handleFree(self): + self.html = self.load(self.pyfile.url, decode=True) + + inputs = self.parseHtmlForm(input_names='token')[1] + if 'token' not in inputs: + self.parseError('Unable to detect token') + token = inputs['token'] + self.logDebug('Token: ' + token) + + self.html = self.load(self.pyfile.url, post={'token': token}, decode=True) + + inputs = self.parseHtmlForm(input_names='hash')[1] + if 'hash' not in inputs: + self.parseError('Unable to detect hash') + hash_data = inputs['hash'] + self.logDebug('Hash: ' + hash_data) + + downloadURL = '' + recaptcha = ReCaptcha(self) + for i in xrange(5): + challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY) + post_data = {'recaptcha_challenge_field': challenge, + 'recaptcha_response_field': response, + 'hash': hash_data} + + # Workaround for 0.4.9 just_header issue. In 0.5 clean the code using just_header + self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 0) + self.load(self.pyfile.url, post=post_data) + self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 1) + + if 'location' in self.req.http.header: + location = re.search(r'location: (\S+)', self.req.http.header).group(1) + downloadURL = 'http://filer.net' + location + self.correctCaptcha() + break + else: + self.logInfo('Wrong captcha') + self.invalidCaptcha() + + if not downloadURL: + self.fail("No Download url retrieved/all captcha attempts failed") + + self.download(downloadURL, disposition=True) + + +getInfo = create_getInfo(FilerNet) diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py index 46323d829..7b87bbe71 100644 --- a/module/plugins/hoster/OneFichierCom.py +++ b/module/plugins/hoster/OneFichierCom.py @@ -7,11 +7,10 @@ class OneFichierCom(SimpleHoster): __name__ = "OneFichierCom" __type__ = "hoster" __pattern__ = r"(http://(\w+)\.((1fichier|d(es)?fichiers|pjointe)\.(com|fr|net|org)|(cjoint|mesfichiers|piecejointe|oi)\.(org|net)|tenvoi\.(com|org|net)|dl4free\.com|alterupload\.com|megadl.fr))" - __version__ = "0.45" + __version__ = "0.46" __description__ = """1fichier.com download hoster""" __author_name__ = ("fragonib", "the-razer", "zoidberg","imclem") - __author_mail__ = ("fragonib[AT]yahoo[DOT]es", "daniel_ AT gmx DOT net", - "zoidberg@mujmail.cz","imclem on github") + __author_mail__ = ("fragonib[AT]yahoo[DOT]es", "daniel_ AT gmx DOT net", "zoidberg@mujmail.cz","imclem on github") FILE_NAME_PATTERN = r'">File name :</th>\s*<td>(?P<N>[^<]+)</td>' FILE_SIZE_PATTERN = r'<th>File size :</th>\s*<td>(?P<S>[^<]+)</td>' diff --git a/module/plugins/hoster/PutlockerCom.py b/module/plugins/hoster/PutlockerCom.py index ca5336231..9eff0dc2b 100644 --- a/module/plugins/hoster/PutlockerCom.py +++ b/module/plugins/hoster/PutlockerCom.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- + """ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,114 +17,60 @@ @author: jeix """ +# http://www.putlocker.com/file/83C174C844583CF7 + import re -from module.plugins.Hoster import Hoster -from module.network.RequestFactory import getURL - -def getInfo(urls): - result = [] - - for url in urls: - - html = getURL(url) - if re.search(PutlockerCom.PATTERN_OFFLINE, html): - result.append((url, 0, 1, url)) - else: - name = re.search(PutlockerCom.PATTERN_FILENAME_1, html) - if name is None: - name = re.search(PutlockerCom.PATTERN_FILENAME_2, html) - if name is None: - result.append((url, 0, 1, url)) - continue - - name = name.group(1) - - # size = re.search(PutlockerCom.PATTERN_FILESIZE, html) - # if size is None: - # result.append((url, 0, 1, url)) - # continue - - # size = size.group(1) - - result.append((name, 0, 2, url)) - yield result - -class PutlockerCom(Hoster): + +from module.plugins.internal.SimpleHoster import SimpleHoster + + +class PutlockerCom(SimpleHoster): __name__ = "PutlockerCom" __type__ = "hoster" __pattern__ = r'http://(www\.)?putlocker\.com/(file|embed)/[A-Z0-9]+' - __version__ = "0.21" + __version__ = "0.24" __description__ = """Putlocker.Com""" - __author_name__ = ("jeix") - - PATTERN_OFFLINE = r"This file doesn't exist, or has been removed." - PATTERN_FILENAME_1 = "site-content.*?<h1>(.*?)<strong" - PATTERN_FILENAME_2 = "<title>(.*?) \|" - PATTERN_FILESIZE = "site-content.*?<h1>.*?<strong>\\((.*?)\\)" - - - def process(self, pyfile): - - self.pyfile = pyfile - self.html = self.load(pyfile.url, decode=True) - - if not self._checkOnline(): - self.offline() - - self.pyfile.name = self._getName() - - self.link = self._getLink() - if not self.link.startswith('http://'): - self.link = "http://www.putlocker.com" + self.link - self.download( self.link ) - - def _checkOnline(self): - if re.search(self.PATTERN_OFFLINE, self.html): - return False - else: - return True - - def _getName(self): - name = re.search(self.PATTERN_FILENAME_1, self.html) - if name is None: - name = re.search(self.PATTERN_FILENAME_2, self.html) - # if name is None: - # self.fail("%s: Plugin broken." % self.__name__) - - return name.group(1) - + __author_name__ = ("jeix", "stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_OFFLINE_PATTERN = r"This file doesn't exist, or has been removed." + FILE_INFO_PATTERN = r'site-content">\s*<h1>(?P<N>.+)<strong>\( (?P<S>[^)]+) \)</strong></h1>' + + def handleFree(self): + self.html = self.load(self.pyfile.url, decode=True) + + link = self._getLink() + if not link.startswith('http://'): + link = "http://www.putlocker.com" + link + self.download(link, disposition=True) + def _getLink(self): - self.hash = re.search("<input type=\"hidden\" value=\"([a-z0-9]+)\" name=\"hash\">", self.html) - # if self.hash is None: - # self.fail("%s: Plugin broken." % self.__name__) - - self.param = "hash=" + self.hash.group(1) + "&confirm=Continue+as+Free+User" - self.html2 = self.load(self.pyfile.url, post=self.param) - if ">You have exceeded the daily stream limit for your country\\. You can wait until tomorrow" in self.html2 or "(>This content server has been temporarily disabled for upgrades|Try again soon\\. You can still download it below\\.<)" in self.html2: - self.waittime = 2 * 60 * 60 - self.retry(wait_time=self.waittime, reason="Waiting %s seconds" % self.waittime) - - self.link = re.search("<a href=\"/gopro\\.php\">Tired of ads and waiting\\? Go Pro\\!</a>[\t\n\rn ]+</div>[\t\n\rn ]+<a href=\"(/.*?)\"", self.html2) - if self.link is None: - self.link = re.search("\"(/get_file\\.php\\?download=[A-Z0-9]+\\&key=[a-z0-9]+)\"", self.html2) - - if self.link is None: - self.link = re.search("\"(/get_file\\.php\\?download=[A-Z0-9]+\\&key=[a-z0-9]+&original=1)\"", self.html2) - - if self.link is None: - self.link = re.search("\"(/get_file\\.php\\?id=[A-Z0-9]+\\&key=[A-Za-z0-9=]+\\&original=1)\"", self.html2) - - if self.link is None: - self.link = re.search("playlist: \\'(/get_file\\.php\\?stream=[A-Za-z0-9=]+)\\'", self.html2) - if not self.link is None: - self.html3 = self.load("http://www.putlocker.com" + self.link.group(1)) - self.link = re.search("media:content url=\"(http://.*?)\"", self.html3) - if self.link is None: - self.link = re.search("\"(http://media\\-b\\d+\\.putlocker\\.com/download/\\d+/.*?)\"", self.html3) - - # if link is None: - # self.fail("%s: Plugin broken." % self.__name__) - - return self.link.group(1).replace("&", "&") - - + hash_data = re.search(r'<input type="hidden" value="([a-z0-9]+)" name="hash">', self.html) + if not hash_data: + self.parseError('Unable to detect hash') + + post_data = {"hash": hash_data.group(1), "confirm": "Continue+as+Free+User"} + self.html = self.load(self.pyfile.url, post=post_data) + if ">You have exceeded the daily stream limit for your country\\. You can wait until tomorrow" in self.html or \ + "(>This content server has been temporarily disabled for upgrades|Try again soon\\. You can still download it below\\.<)" in self.html: + self.retry(wait_time=2 * 60 * 60, reason="Download limit exceeded or server disabled") + + patterns = (r'(/get_file\.php\?id=[A-Z0-9]+&key=[A-Za-z0-9=]+&original=1)', + r"(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+)", + r"(/get_file\.php\?download=[A-Z0-9]+&key=[a-z0-9]+&original=1)", + r'<a href="/gopro\.php">Tired of ads and waiting\? Go Pro!</a>[\t\n\rn ]+</div>[\t\n\rn ]+<a href="(/.*?)"') + for pattern in patterns: + link = re.search(pattern, self.html) + if link: + break + else: + link = re.search(r"playlist: '(/get_file\.php\?stream=[A-Za-z0-9=]+)'", self.html) + if link: + self.html = self.load("http://www.putlocker.com" + link.group(1)) + link = re.search(r'media:content url="(http://.*?)"', self.html) + if not link: + link = re.search("\"(http://media\\-b\\d+\\.putlocker\\.com/download/\\d+/.*?)\"", self.html) + else: + self.parseError('Unable to detect a download link') + + return link.group(1).replace("&", "&") diff --git a/module/plugins/hoster/RarefileNet.py b/module/plugins/hoster/RarefileNet.py index 7c5543cc8..a0f5930b5 100644 --- a/module/plugins/hoster/RarefileNet.py +++ b/module/plugins/hoster/RarefileNet.py @@ -1,30 +1,34 @@ # -*- coding: utf-8 -*- + import re + from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo from module.utils import html_unescape + class RarefileNet(XFileSharingPro): __name__ = "RarefileNet" __type__ = "hoster" __pattern__ = r"http://(?:\w*\.)*rarefile.net/\w{12}" - __version__ = "0.02" + __version__ = "0.03" __description__ = """Rarefile.net hoster plugin""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") - + FILE_NAME_PATTERN = r'<td><font color="red">(?P<N>.*?)</font></td>' FILE_SIZE_PATTERN = r'<td>Size : (?P<S>.+?) ' + DIRECT_LINK_PATTERN = r'<a href="(?P<link>[^"]+)">(?P=link)</a>' HOSTER_NAME = "rarefile.net" - + def setup(self): - self.resumeDownload = self.multiDL = self.premium - + self.resumeDownload = self.multiDL = self.premium + def handleCaptcha(self, inputs): captcha_div = re.search(r'<b>Enter code.*?<div.*?>(.*?)</div>', self.html, re.S).group(1) - self.logDebug(captcha_div) + self.logDebug(captcha_div) numerals = re.findall('<span.*?padding-left\s*:\s*(\d+).*?>(\d)</span>', html_unescape(captcha_div)) inputs['code'] = "".join([a[1] for a in sorted(numerals, key = lambda num: int(num[0]))]) - self.logDebug("CAPTCHA", inputs['code'], numerals) + self.logDebug("CAPTCHA", inputs['code'], numerals) return 3 -getInfo = create_getInfo(RarefileNet)
\ No newline at end of file +getInfo = create_getInfo(RarefileNet) diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py index a2134ecb5..5d8c9a5ac 100644 --- a/module/plugins/hoster/UploadedTo.py +++ b/module/plugins/hoster/UploadedTo.py @@ -11,34 +11,37 @@ from module.plugins.ReCaptcha import ReCaptcha key = "bGhGMkllZXByd2VEZnU5Y2NXbHhYVlZ5cEE1bkEzRUw=".decode('base64') + def getID(url): """ returns id from file url""" - m = re.match(r"http://[\w\.-]*?(uploaded\.(to|net)(/file/|/?\?id=|.*?&id=)|ul\.to/)(?P<ID>\w+)", url) + m = re.match(r"http://[\w\.-]*?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=)(?P<ID>\w+)", url) return m.group('ID') + def getAPIData(urls): - post = {"apikey" : key} + post = {"apikey": key} - idMap = {} + idMap = {} - for i, url in enumerate(urls): - id = getID(url) - post["id_%s" % i] = id - idMap[id] = url + for i, url in enumerate(urls): + id = getID(url) + post["id_%s" % i] = id + idMap[id] = url - api = unicode(getURL("http://uploaded.net/api/filemultiple", post=post, decode=False), 'iso-8859-1') + api = unicode(getURL("http://uploaded.net/api/filemultiple", post=post, decode=False), 'iso-8859-1') - result = {} + result = {} - if api: - for line in api.splitlines(): - data = line.split(",", 4) - if data[1] in idMap: - result[data[1]] = (data[0], data[2], data[4], data[3], idMap[data[1]]) + if api: + for line in api.splitlines(): + data = line.split(",", 4) + if data[1] in idMap: + result[data[1]] = (data[0], data[2], data[4], data[3], idMap[data[1]]) - return result + return result -def parseFileInfo(self, url = '', html = ''): + +def parseFileInfo(self, url='', html=''): if not html and hasattr(self, "html"): html = self.html name, size, status, found, fileid = url, 0, 3, None, None @@ -54,6 +57,7 @@ def parseFileInfo(self, url = '', html = ''): return name, size, status, fileid + def getInfo(urls): for chunk in chunks(urls, 80): result = [] @@ -74,7 +78,7 @@ class UploadedTo(Hoster): __name__ = "UploadedTo" __type__ = "hoster" __pattern__ = r"http://[\w\.-]*?(uploaded\.(to|net)(/file/|/?\?id=|.*?&id=)|ul\.to/)\w+" - __version__ = "0.64" + __version__ = "0.65" __description__ = """Uploaded.net Download Hoster""" __author_name__ = ("spoob", "mkaay", "zoidberg", "netpok", "stickell") __author_mail__ = ("spoob@pyload.org", "mkaay@mkaay.de", "zoidberg@mujmail.cz", "netpok@gmail.com", "l.stickell@yahoo.it") @@ -88,7 +92,7 @@ class UploadedTo(Hoster): self.multiDL = False self.resumeDownload = False self.url = False - self.chunkLimit = 1 # critical problems with more chunks + self.chunkLimit = 1 # critical problems with more chunks if self.account: self.premium = self.account.getAccountInfo(self.user)["premium"] if self.premium: @@ -108,7 +112,7 @@ class UploadedTo(Hoster): if not api: self.logWarning("No response for API call") - self.html = unicode(self.load(pyfile.url, decode = False), 'iso-8859-1') + self.html = unicode(self.load(pyfile.url, decode=False), 'iso-8859-1') name, size, status, self.fileID = parseFileInfo(self) self.logDebug(name, size, status, self.fileID) if status == 1: @@ -140,8 +144,9 @@ class UploadedTo(Hoster): def handlePremium(self): info = self.account.getAccountInfo(self.user, True) - self.log.debug("%(name)s: Use Premium Account (%(left)sGB left)" % {"name" :self.__name__, "left" : info["trafficleft"]/1024/1024}) - if int(self.data[1])/1024 > info["trafficleft"]: + self.log.debug("%(name)s: Use Premium Account (%(left)sGB left)" % {"name": self.__name__, + "left": info["trafficleft"] / 1024 / 1024}) + if int(self.data[1]) / 1024 > info["trafficleft"]: self.log.info(_("%s: Not enough traffic left" % self.__name__)) self.account.empty(self.user) self.resetAccount() @@ -185,7 +190,7 @@ class UploadedTo(Hoster): #self.req.lastURL = str(self.url) re_captcha = ReCaptcha(self) challenge, result = re_captcha.challenge(challengeId.group(1)) - options = {"recaptcha_challenge_field" : challenge, "recaptcha_response_field": result} + options = {"recaptcha_challenge_field": challenge, "recaptcha_response_field": result} self.wait() result = self.load(url, post=options) @@ -193,13 +198,13 @@ class UploadedTo(Hoster): if "limit-size" in result: self.fail("File too big for free download") - elif "limit-slot" in result: # Temporary restriction so just wait a bit + elif "limit-slot" in result: # Temporary restriction so just wait a bit self.setWait(30 * 60, True) self.wait() self.retry() elif "limit-parallel" in result: self.fail("Cannot download in parallel") - elif self.DL_LIMIT_PATTERN in result: # limit-dl + elif self.DL_LIMIT_PATTERN in result: # limit-dl self.setWait(60 * 60, True) self.wait() self.retry() diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py index 8b8764367..2fb1e5264 100644 --- a/module/plugins/hoster/YoutubeCom.py +++ b/module/plugins/hoster/YoutubeCom.py @@ -34,7 +34,7 @@ class YoutubeCom(Hoster): __name__ = "YoutubeCom" __type__ = "hoster" __pattern__ = r"(http|https)://(www\.)?(de\.)?\youtube\.com/watch\?v=.*" - __version__ = "0.29" + __version__ = "0.30" __config__ = [("quality", "sd;hd;fullhd;240p;360p;480p;720p;1080p;3072p", "Quality Setting", "hd"), ("fmt", "int", "FMT/ITAG Number (5-102, 0 for auto)", 0), (".mp4", "bool", "Allow .mp4", True), diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index b8942c724..c9e350e86 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -18,18 +18,20 @@ """ import re + from module.plugins.Crypter import Crypter + class SimpleCrypter(Crypter): __name__ = "SimpleCrypter" - __version__ = "0.03" + __version__ = "0.04" __pattern__ = None __type__ = "crypter" __description__ = """Base crypter plugin""" __author_name__ = ("stickell", "zoidberg") __author_mail__ = ("l.stickell@yahoo.it", "zoidberg@mujmail.cz") """ - These patterns should be defined by each hoster: + These patterns should be defined by each crypter: LINK_PATTERN: group(1) must be a download link example: <div class="link"><a href="(http://speedload.org/\w+) @@ -39,7 +41,7 @@ class SimpleCrypter(Crypter): """ def decrypt(self, pyfile): - self.html = self.load(pyfile.url) + self.html = self.load(pyfile.url, decode=True) package_name, folder_name = self.getPackageNameAndFolder() @@ -55,7 +57,7 @@ class SimpleCrypter(Crypter): if hasattr(self, 'TITLE_PATTERN'): m = re.search(self.TITLE_PATTERN, self.html) if m: - name = folder = m.group('title') + name = folder = m.group('title').strip() self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder)) return name, folder diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py index cfc9f2b43..69ed57ff8 100644 --- a/module/plugins/internal/SimpleHoster.py +++ b/module/plugins/internal/SimpleHoster.py @@ -155,8 +155,8 @@ class SimpleHoster(Hoster): """ These patterns should be defined by each hoster: FILE_INFO_PATTERN = r'(?P<N>file_name) (?P<S>file_size) (?P<U>units)' - or FILE_NAME_INFO = r'(?P<N>file_name)' - and FILE_SIZE_INFO = r'(?P<S>file_size) (?P<U>units)' + or FILE_NAME_PATTERN = r'(?P<N>file_name)' + and FILE_SIZE_PATTERN = r'(?P<S>file_size) (?P<U>units)' FILE_OFFLINE_PATTERN = r'File (deleted|not found)' TEMP_OFFLINE_PATTERN = r'Server maintainance' """ diff --git a/module/plugins/internal/UnRar.py b/module/plugins/internal/UnRar.py index 240dc0233..da8e7cf3d 100644 --- a/module/plugins/internal/UnRar.py +++ b/module/plugins/internal/UnRar.py @@ -22,18 +22,20 @@ import re from os.path import join from glob import glob from subprocess import Popen, PIPE +from string import digits from module.utils import save_join, decode from module.plugins.internal.AbstractExtractor import AbtractExtractor, WrongPassword, ArchiveError, CRCError class UnRar(AbtractExtractor): __name__ = "UnRar" - __version__ = "0.11" + __version__ = "0.13" # there are some more uncovered rar formats - re_splitfile = re.compile(r"(.*)\.part(\d+)\.rar$") + re_splitfile = re.compile(r"(.*)\.part(\d+)\.rar$", re.I) + re_partfiles = re.compile(r".*\.(rar|r[0-9]+)", re.I) re_filelist = re.compile(r"(.+)\s+(\d+)\s+(\d+)\s+") - re_wrongpwd = re.compile("(Corrupt file or wrong password|password incorrect)") + re_wrongpwd = re.compile("(Corrupt file or wrong password|password incorrect)", re.I) CMD = "unrar" @staticmethod @@ -113,15 +115,31 @@ class UnRar(AbtractExtractor): def extract(self, progress, password=None): command = "x" if self.fullpath else "e" - # popen thinks process is still alive (just like pexpect) - very strange behavior - # so for now progress can not be determined correctly p = self.call_unrar(command, self.file, self.out, password=password) renice(p.pid, self.renice) progress(0) - out, err = p.communicate() #wait for process + progressstring = "" + while True: + c = p.stdout.read(1) + # quit loop on eof + if not c: + break + # reading a percentage sign -> set progress and restart + if c == '%': + progress(int(progressstring)) + progressstring = "" + # not reading a digit -> therefore restart + elif c not in digits: + progressstring = "" + # add digit to progressstring + else: + progressstring = progressstring + c progress(100) + # retrieve stderr + err = p.stderr.read() + if "CRC failed" in err and not password and not self.passwordProtected: raise CRCError elif "CRC failed" in err: @@ -139,7 +157,9 @@ class UnRar(AbtractExtractor): def getDeleteFiles(self): if ".part" in self.file: return glob(re.sub("(?<=\.part)([01]+)", "*", self.file, re.IGNORECASE)) - return [self.file] + # get files which matches .r* and filter unsuited files out + parts = glob(re.sub(r"(?<=\.r)ar$", "*", self.file, re.IGNORECASE)) + return filter(lambda x: self.re_partfiles.match(x), parts) def listContent(self): command = "vb" if self.fullpath else "lb" |