summaryrefslogtreecommitdiffstats
path: root/module/plugins/internal/SimpleHoster.py
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins/internal/SimpleHoster.py')
-rw-r--r--module/plugins/internal/SimpleHoster.py110
1 files changed, 69 insertions, 41 deletions
diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py
index 5a32ac943..c1982ee67 100644
--- a/module/plugins/internal/SimpleHoster.py
+++ b/module/plugins/internal/SimpleHoster.py
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
+import mimetypes
+import os
import re
+from datetime import datetime, timedelta
from inspect import isclass
-from os.path import exists
from time import time
from urllib import unquote
from urlparse import urljoin, urlparse
@@ -106,7 +108,13 @@ def parseFileInfo(plugin, url="", html=""):
info = plugin.getInfo(url, html)
res = info['name'], info['size'], info['status'], info['url']
else:
- res = urlparse(unquote(url)).path.split('/')[-1] or _("Unknown"), 0, 3, url
+ url = unquote(url)
+ res = ((urlparse(url).path.split('/')[-1]
+ or urlparse(url).query.split('=', 1)[::-1][0].split('&', 1)[0]
+ or _("Unknown")),
+ 0,
+ 3 if url else 8,
+ url)
return res
@@ -114,10 +122,15 @@ def parseFileInfo(plugin, url="", html=""):
#@TODO: Remove in 0.4.10
#@NOTE: Every plugin must have own parseInfos classmethod to work with 0.4.10
def create_getInfo(plugin):
+
+ def generator(list):
+ for x in list:
+ yield x
+
if hasattr(plugin, "parseInfos"):
- fn = lambda urls: [(info['name'], info['size'], info['status'], info['url']) for info in plugin.parseInfos(urls)]
+ fn = lambda urls: generator((info['name'], info['size'], info['status'], info['url']) for info in plugin.parseInfos(urls))
else:
- fn = lambda urls: [parseFileInfo(url) for url in urls]
+ fn = lambda urls: generator(parseFileInfo(url) for url in urls)
return fn
@@ -127,35 +140,58 @@ def timestamp():
#@TODO: Move to hoster class in 0.4.10
-def directLink(self, url, resumable=False):
- link = ""
+def fileUrl(self, url, follow_location=False):
+ link = ""
+ redirect = 1
+
+ if isinstance(follow_location, int):
+ redirect = max(follow_location, 1)
+
+ elif follow_location:
+ redirect = 5
+
+ for i in xrange(redirect):
+ self.logDebug("Redirect #%d to: %s" % (i, url))
- for i in xrange(5 if resumable else 1):
header = self.load(url, ref=True, cookies=True, just_header=True, decode=True)
if 'content-disposition' in header:
link = url
- elif 'location' in header and header['location']:
+ elif 'location' in header and header['location'].strip():
location = header['location']
if not urlparse(location).scheme:
- p = urlparse(url)
- base = "%s://%s" % (p.scheme, p.netloc)
- location = urljoin(base, location)
+ url_p = urlparse(url)
+ baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
+ location = urljoin(baseurl, location)
+
+ if 'code' in header and header['code'] == 302:
+ link = location
- if resumable:
+ if follow_location:
url = location
- self.logDebug("Redirect #%d to: %s" % (++i, location))
continue
- elif 'code' in header and header['code'] == 302:
- link = location
+ else:
+ extension = os.path.splitext(urlparse(url).path.split('/')[-1])[-1]
- elif 'content-type' in header and header['content-type'] and "html" not in header['content-type']:
- link = url
+ if 'content-type' in header and header['content-type'].strip():
+ mimetype = header['content-type'].split(';')[0].strip()
+
+ elif extension:
+ mimetype = mimetypes.guess_extension(extension, False)[0] or "application/octet-stream"
+
+ else:
+ mimetype = ""
+
+ if mimetype and (link or 'html' not in mimetype):
+ link = url
+ else:
+ link = ""
break
+
else:
self.logError(_("Too many redirects"))
@@ -183,7 +219,7 @@ def secondsToMidnight(gmt=0):
class SimpleHoster(Hoster):
__name__ = "SimpleHoster"
__type__ = "hoster"
- __version__ = "0.94"
+ __version__ = "1.01"
__pattern__ = r'^unmatchable$'
@@ -247,7 +283,7 @@ class SimpleHoster(Hoster):
MULTI_HOSTER = False #: Set to True to leech other hoster link (as defined in handleMulti method)
LOGIN_ACCOUNT = False #: Set to True to require account login
- directLink = directLink #@TODO: Remove in 0.4.10
+ directLink = fileUrl #@TODO: Remove in 0.4.10
@classmethod
@@ -328,9 +364,6 @@ class SimpleHoster(Hoster):
else:
online = True
- if not info['pattern']:
- info.pop('pattern', None)
-
if online:
info['status'] = 2
@@ -351,6 +384,9 @@ class SimpleHoster(Hoster):
hashtype = info['pattern']['T'] if 'T' in info['pattern'] else "hash"
info[hashtype] = info['pattern']['H']
+ if not info['pattern']:
+ info.pop('pattern', None)
+
return info
@@ -439,9 +475,9 @@ class SimpleHoster(Hoster):
self.invalidCaptcha()
self.retry(10, reason=_("Wrong captcha"))
- elif not self.lastDownload or not exists(fs_encode(self.lastDownload)):
+ elif not self.lastDownload or not os.path.exists(fs_encode(self.lastDownload)):
self.lastDownload = ""
- self.fail(self.pyfile.error or _("No file downloaded"))
+ self.error(self.pyfile.error or _("No file downloaded"))
else:
rules = {'empty file': re.compile(r'\A\Z'),
@@ -553,7 +589,7 @@ class SimpleHoster(Hoster):
def handleDirect(self, pyfile):
- link = self.directLink(pyfile.url, self.resumeDownload)
+ link = self.fileUrl(pyfile.url, self.resumeDownload)
if link:
self.logInfo(_("Direct download link detected"))
@@ -571,16 +607,12 @@ class SimpleHoster(Hoster):
if not hasattr(self, 'LINK_FREE_PATTERN'):
self.logError(_("Free download not implemented"))
- try:
- m = re.search(self.LINK_FREE_PATTERN, self.html)
- if m is None:
- self.error(_("Free download link not found"))
-
+ m = re.search(self.LINK_FREE_PATTERN, self.html)
+ if m is None:
+ self.error(_("Free download link not found"))
+ else:
self.link = m.group(1)
- except Exception, e:
- self.fail(e)
-
def handlePremium(self, pyfile):
if not hasattr(self, 'LINK_PREMIUM_PATTERN'):
@@ -588,16 +620,12 @@ class SimpleHoster(Hoster):
self.logDebug("Handled as free download")
self.handleFree(pyfile)
- try:
- m = re.search(self.LINK_PREMIUM_PATTERN, self.html)
- if m is None:
- self.error(_("Premium download link not found"))
-
+ m = re.search(self.LINK_PREMIUM_PATTERN, self.html)
+ if m is None:
+ self.error(_("Premium download link not found"))
+ else:
self.link = m.group(1)
- except Exception, e:
- self.fail(e)
-
def longWait(self, wait_time=None, max_tries=3):
if wait_time and isinstance(wait_time, (int, long, float)):