From 3c7b7eaa189dd030712290fea2b2655b69fd6c05 Mon Sep 17 00:00:00 2001
From: RaNaN <Mast3rRaNaN@hotmail.de>
Date: Sat, 4 Jun 2011 17:22:51 +0200
Subject: x7.to plugin, by ernieb

---
 module/plugins/Account.py       |  25 ++++++-
 module/plugins/accounts/X7To.py |  58 ++++++++++++++++
 module/plugins/hoster/X7To.py   | 144 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 224 insertions(+), 3 deletions(-)
 create mode 100644 module/plugins/accounts/X7To.py
 create mode 100644 module/plugins/hoster/X7To.py

(limited to 'module')

diff --git a/module/plugins/Account.py b/module/plugins/Account.py
index 557689fe9..732133d3a 100644
--- a/module/plugins/Account.py
+++ b/module/plugins/Account.py
@@ -35,9 +35,9 @@ class Account():
     __author_name__ = ("mkaay")
     __author_mail__ = ("mkaay@mkaay.de")
 
-    # after that time [in minutes] pyload will relogin the account
+    #: after that time [in minutes] pyload will relogin the account
     login_timeout = 600
-    # account data will be reloaded after this time
+    #: account data will be reloaded after this time
     info_threshold = 600
 
 
@@ -54,6 +54,12 @@ class Account():
         pass
 
     def login(self, user, data, req):
+        """login into account, the cookies will be saved so user can be recognized
+
+        :param user: loginname
+        :param data: data dictionary
+        :param req: `Request` instance
+        """
         pass
 
     def _login(self, user, data):
@@ -120,7 +126,13 @@ class Account():
             del self.timestamps[user]
 
     def getAccountInfo(self, name, force=False):
-        """ return dict with infos, do not overwrite this method! """
+        """retrieve account infos for an user, do **not** overwrite this method!\\
+        just use it to retrieve infos in hoster plugins. see `loadAccountInfo`
+
+        :param name: username
+        :param force: reloads cached account information
+        :return: dictionary with information
+        """
         data = Account.loadAccountInfo(self, name)
 
         if force or not self.infos.has_key(name):
@@ -152,6 +164,13 @@ class Account():
         return info["premium"]
 
     def loadAccountInfo(self, name, req=None):
+        """this should be overwritten in account plugin,\
+        and retrieving account information for user
+
+        :param name:
+        :param req: `Request` instance
+        :return:
+        """
         return {
             "validuntil": None, # -1 for unlimited
             "login": name,
diff --git a/module/plugins/accounts/X7To.py b/module/plugins/accounts/X7To.py
new file mode 100644
index 000000000..1e3ef782e
--- /dev/null
+++ b/module/plugins/accounts/X7To.py
@@ -0,0 +1,58 @@
+# -*- 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
+    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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+    @author: ernieb
+"""
+
+import re
+from time import strptime, mktime
+
+from module.plugins.Account import Account
+
+class X7To(Account):
+    __name__ = "X7To"
+    __version__ = "0.1"
+    __type__ = "account"
+    __description__ = """X7.To account plugin"""
+    __author_name__ = ("ernieb")
+    __author_mail__ = ("ernieb")
+
+    def loadAccountInfo(self, user, req):
+        page = req.load("http://www.x7.to/my")
+
+        valid = re.search("Premium-Mitglied bis ([0-9]*-[0-9]*-[0-9]*)", page, re.IGNORECASE).group(1)
+        valid = int(mktime(strptime(valid, "%Y-%m-%d")))
+
+        trafficleft = re.search('<em style="white-space:nowrap">([\d]*)[,]?[\d]?[\d]? (KB|MB|GB)</em>', page,
+                                re.IGNORECASE)
+        if trafficleft:
+            units = float(trafficleft.group(1))
+            pow = {'KB': 0, 'MB': 1, 'GB': 2}[trafficleft.group(2)]
+            trafficleft = int(units * 1024 ** pow)
+        else:
+            trafficleft = -1
+
+        return {"trafficleft": trafficleft, "validuntil": valid}
+
+
+    def login(self, user, data, req):
+        #req.cj.setCookie("share.cx", "lang", "english")
+        page = req.load("http://x7.to/lang/en", None, {})
+        page = req.load("http://x7.to/james/login", None,
+                {"redirect": "http://www.x7.to/", "id": user, "pw": data['password'], "submit": "submit"})
+
+        if "Username and password are not matching." in page:
+            self.wrongPassword()
\ No newline at end of file
diff --git a/module/plugins/hoster/X7To.py b/module/plugins/hoster/X7To.py
new file mode 100644
index 000000000..39441d091
--- /dev/null
+++ b/module/plugins/hoster/X7To.py
@@ -0,0 +1,144 @@
+# -*- coding: utf-8 -*-
+from __future__ import with_statement
+
+import re
+
+from module.plugins.Hoster import Hoster
+
+from module.network.RequestFactory import getURL
+
+def getInfo(urls):
+    result = []
+
+    for url in urls:
+        #print "X7To: getinfo for "+url
+        # Get html
+        html = getURL(url)
+
+        if re.search(r"var page = '404';", html):
+            #print "x7html: 404"
+            result.append((url, 0, 1, url))
+            continue
+
+        # Name
+        fileInfo = re.search('<meta name="description" content="Download: (.*) ([0-9,.]*) (KB|MB|GB) at ', html)
+        if fileInfo:
+            name = fileInfo.group(1)
+            #print "X7To: filename "+name
+            # Size
+            units = float(fileInfo.group(1).replace(",", "."))
+            pow = {'KB': 1, 'MB': 2, 'GB': 3}[fileInfo.group(2)]
+            size = int(units * 1024 ** pow)
+        else:
+            # fallback: name could not be extracted.. most likely change on x7.to side ... needs to be checked then
+            #print "X7To: file information not found"
+            name = url
+            size = 0
+
+        # Return info
+        result.append((name, size, 2, url))
+
+    yield result
+
+
+class X7To(Hoster):
+    __name__ = "X7To"
+    __type__ = "hoster"
+    __pattern__ = r"http://(?:www.)?x7.to/"
+    __version__ = "0.1"
+    __description__ = """X7.To File Download Hoster"""
+    __author_name__ = ("ernieb")
+    __author_mail__ = ("ernieb")
+
+    def setup(self):
+        if self.premium:
+            self.multiDL = False
+            self.resumeDownload = False
+            self.chunkLimit = 1
+        else:
+            self.multiDL = False
+
+        self.file_id = re.search(r"http://x7.to/([a-zA-Z0-9]+)", self.pyfile.url).group(1)
+        self.pyfile.url = "http://x7.to/" + self.file_id
+
+    def process(self, pyfile):
+        self.html = self.load(self.pyfile.url, ref=False, decode=True)
+
+        if re.search(r"var page = '404';", self.html) is not None:
+            self.offline()
+
+        fileInfo = re.search(r'<meta name="description" content="Download: (.*) \(([0-9,.]*) (KB|MB|GB)\) at ',
+                             self.html, re.IGNORECASE)
+        size = 0
+        trafficLeft = 100000000000
+        if fileInfo:
+            self.pyfile.name = fileInfo.group(1)
+            if self.account:
+                trafficLeft = self.account.getAccountInfo(self.user)["trafficleft"]
+                # Size
+                units = float(fileInfo.group(2).replace(",", "."))
+                pow = {'KB': 1, 'MB': 2, 'GB': 3}[fileInfo.group(3)]
+                size = int(units * 1024 ** pow)
+                self.logDebug("filesize: %s    trafficleft: %s" % (size, trafficLeft))
+
+        else:
+            #self.log.debug( self.html )
+            self.logDebug("name and size not found")
+
+        if self.account and self.premium and trafficLeft > size:
+            self.handlePremium()
+        else:
+            self.handleFree()
+
+    def handlePremium(self):
+        # check if over limit first
+        overLimit = re.search(r'<a onClick="cUser.buyTraffic\(\)" id="DL">', self.html)
+        if overLimit:
+            self.logDebug("over limit")
+        else:
+            realurl = re.search(r'<a href="http://stor(\d*).x7.to/dl/([^"]*)" id="DL">', self.html)
+            if realurl:
+                realurl = 'http://stor' + realurl.group(1) + '.x7.to/dl/' + realurl.group(2)
+            else:
+                self.logDebug("premium link not found")
+            self.download(realurl)
+
+    def handleFree(self):
+        # find file id
+        file_id = re.search(r"var dlID = '([^']*)'", self.html)
+        if file_id:
+            file_url = "http://x7.to/james/ticket/dl/" + file_id.group(1)
+            #getDownloadXml = getURL(file_url)
+            self.html = self.load(file_url, ref=False, decode=True)
+
+            # find download limit in xml
+            haveToWait = re.search("limit-dl", self.html)
+            if haveToWait:
+                self.logDebug("Limit reached ... waiting")
+                self.setWait(900)
+                self.wait()
+                return True
+
+            # no waiting required, go to download
+            waitCheck = re.search(r"wait:(\d*),", self.html)
+            if waitCheck:
+                waitCheck = int(waitCheck.group(1))
+                self.setWait(waitCheck, True)
+                self.wait()
+
+            urlCheck = re.search(r"url:'(.*)',", self.html)
+            url = None
+            if urlCheck:
+                url = urlCheck.group(1)
+                self.logDebug("url found " + url)
+
+            if url:
+                try:
+                    self.download(url)
+                except:
+                    self.logDebug("downloading url failed:" + url)
+
+
+            else:
+                #print self.html
+                self.fail("no download url found")
\ No newline at end of file
-- 
cgit v1.2.3