From e2f90ed9278105484c1b19cf92f3830981a41dd5 Mon Sep 17 00:00:00 2001
From: fragonib <devnull@localhost>
Date: Sat, 30 Apr 2011 16:26:49 +0200
Subject: NCryptIn: Improved support

---
 module/plugins/crypter/NCryptIn.py | 194 +++++++++++++++++++++++--------------
 1 file changed, 120 insertions(+), 74 deletions(-)

diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py
index 68456b7fe..12fc7fcef 100644
--- a/module/plugins/crypter/NCryptIn.py
+++ b/module/plugins/crypter/NCryptIn.py
@@ -2,6 +2,7 @@
 
 from Crypto.Cipher import AES
 from module.plugins.Crypter import Crypter
+from module.plugins.ReCaptcha import ReCaptcha
 import base64
 import binascii
 import re
@@ -10,7 +11,7 @@ class NCryptIn(Crypter):
     __name__ = "NCryptIn"
     __type__ = "crypter"
     __pattern__ = r"http://(?:www\.)?ncrypt.in/folder-([^/\?]+)"
-    __version__ = "1.1"
+    __version__ = "1.2"
     __description__ = """NCrypt.in Crypter Plugin"""
     __author_name__ = ("fragonib")
     __author_mail__ = ("fragonib[AT]yahoo[DOT]es")
@@ -21,111 +22,156 @@ class NCryptIn(Crypter):
         
     def setup(self):
         self.html = None
+        self.cleanedHtml = None
+        self.captcha = False
+        self.package = None
 
     def decrypt(self, pyfile):
         
         # Init
-        self.pyfile = pyfile
         self.package = pyfile.package()
         
         # Request package
-        self.html = self.requestPackage()
+        self.html = self.load(self.pyfile.url)
+        self.cleanedHtml = self.removeCrap(self.html)
         if not self.isOnline():
             self.offline()
         
-        # Check for password/captcha protection    
+        # Check for protection    
         if self.isProtected():
             self.html = self.unlockProtection()
+            self.cleanedHtml = self.removeCrap(self.html)
+            self.handleErrors()
 
         # Get package name and folder
         (package_name, folder_name) = self.getPackageInfo()
 
         # Extract package links
-        try:
-            package_links = []
-            (vcrypted, vjk) = self.getCipherParams()
-            for (crypted, jk) in zip(vcrypted, vjk):
-                package_links = package_links + self.getLinks(crypted, jk)
-        except:
-            self.fail("NCryptIn: Unable to decrypt package")
+        package_links = []
+        package_links.extend(self.handleWebLinks())
+        package_links.extend(self.handleContainer())
+        package_links.extend(self.handleCNL2())
+        package_links = set(package_links)
 
         # Pack
         self.packages = [(package_name, package_links, folder_name)]
         
-    def requestPackage(self):
-        return self.load(self.pyfile.url)
-
+    def removeCrap(self, content):
+        patterns = (r'(type="hidden".*?(name=".*?")?.*?value=".*?")',
+                    r'display:none;">(.*?)</(div|span)>',
+                    r'<div\s+class="jdownloader"(.*?)</div>',
+                    r'<iframe\s+style="display:none(.*?)</iframe>')
+        for pattern in patterns:
+            rexpr = re.compile(pattern, re.DOTALL)
+            content = re.sub(rexpr, "", content)
+        return content
+        
     def isOnline(self):        
-        if "Your folder does not exist" in self.html:
-            pattern = r'[^"]*(display\s*\:\s*none)[^"]*'
-            m = re.search(pattern, self.html)
-            if m is None:
-                self.log.debug("NCryptIn: File not found")
-                return False
+        if "Your folder does not exist" in self.cleanedHtml:
+            self.log.debug("%s: File not found" % self.__name__)
+            return False
         return True
     
     def isProtected(self):
-        pattern = r'''<form.*?name.*?protected.*?>'''
-        m = re.search(pattern, self.html)
-        if m is not None:
-            self.log.debug("NCryptIn: Links are protected")
+        if re.search(r'''<form.*?name.*?protected.*?>''', self.cleanedHtml):
+            self.log.debug("%s: Links are protected" % self.__name__)
             return True
         return False
     
-    def unlockProtection(self):
-
-        # Gather data
-        url = self.pyfile.url        
-        post = {'submit_protected' : 'Weiter zum Ordner '}
-        
-        # Resolve captcha
-        if "anicaptcha" in self.html:
-            self.log.debug("NCryptIn: Captcha protected, resolving captcha")
-            url = re.search(r'src="(/temp/anicaptcha/[^"]+)', self.html).group(1)
-            captcha = self.decryptCaptcha("http://ncrypt.in" + url)
-            self.log.debug("NCryptIn: Captcha resolved [%s]" % (captcha, ))
-            post.update({"captcha" : captcha})
-                   
-        # Submit package password
-        pattern = r'''<input.*?name.*?password.*?>'''
-        m = re.search(pattern, self.html)
-        if m is not None:
-            password = self.package.password
-            self.log.debug("NCryptIn: Submitting password [%s] for protected links" % (password,))
-            post.update({'password' : password })
-
-        # Unlock protection
-        html = self.load(url, {}, post)
-        
-        # Check for invalid password
-        pattern = r'''div\ id="main".*?This\ password\ is\ invalid!'''
-        m = re.search(pattern, html, re.DOTALL)
-        if m is not None:
-            self.log.debug("NCryptIn: Incorrect password, please set right password on 'Edit package' form and retry")
-            self.fail("Incorrect password, please set right password on 'Edit package' form and retry")
-            
-        if "The securitycheck was wrong!" in html:
-            self.log.debug("NCryptIn: Invalid captcha, retrying")
-            html = self.unlockProtection()
-
-        return html
-
     def getPackageInfo(self):
         title_re = r'<h2><span.*?class="arrow".*?>(?P<title>[^<]+).*?</span>.*?</h2>'
-        regex = re.compile(title_re, re.DOTALL)
-        m = regex.findall(self.html)
+        m = re.findall(title_re, self.html, re.DOTALL)
         if m is not None:
             title = m[-1].strip()
             name = folder = title
-            self.log.debug("NCryptIn: Found name [%s] and folder [%s] in package info" % (name, folder))
-            return (name, folder)
+            self.log.debug("%s: Found name [%s] and folder [%s] in package info" % (self.__name__, name, folder))
         else:
             name = self.package.name
             folder = self.package.folder
-            self.log.debug("NCryptIn: Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
-            return (name, folder)
-
-    def getCipherParams(self):
+            self.log.debug("%s: Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (self.__name__, name, folder))
+        return (name, folder)
+    
+    def unlockProtection(self):
+        
+        postData = {}
+                
+        form = re.search(r'''<form\ name="protected"(.*?)</form>''', self.cleanedHtml, re.DOTALL).group(1)
+        
+        # Submit package password
+        if "password" in form:
+            password = self.package.password
+            self.log.debug("%s: Submitting password [%s] for protected links" % (self.__name__, password))
+            postData['password'] = password
+        
+        # Resolve anicaptcha
+        if "anicaptcha" in form:
+            self.captcha = True
+            self.log.debug("%s: Captcha protected, resolving captcha" % self.__name__)
+            captchaUri = re.search(r'src="(/temp/anicaptcha/[^"]+)', form).group(1)
+            captcha = self.decryptCaptcha("http://ncrypt.in" + captchaUri)
+            self.log.debug("%s: Captcha resolved [%s]" % (self.__name__, captcha))
+            postData['captcha'] = captcha
+        
+        # Resolve recaptcha           
+        if "recaptcha" in form:
+            self.captcha = True    
+            id = re.search(r'\?k=(.*?)"', form).group(1)
+            self.log.debug("%s: Resolving ReCaptcha with key [%s]" % (self.__name__, id))
+            recaptcha = ReCaptcha(self)
+            challenge, code = recaptcha.challenge(id)
+            postData['recaptcha_challenge_field'] = challenge
+            postData['recaptcha_response_field'] = code
+                   
+        # Unlock protection
+        postData['submit_protected'] = 'Continue to folder '
+        return self.load(self.pyfile.url, post=postData)
+        
+    def handleErrors(self):
+                   
+        if "This password is invalid!" in self.cleanedHtml:
+            self.log.debug("%s: Incorrect password, please set right password on 'Edit package' form and retry" % self.__name__)
+            self.fail("Incorrect password, please set right password on 'Edit package' form and retry")  
+
+        if self.captcha:          
+            if "The securitycheck was wrong!" in self.cleanedHtml:
+                self.log.debug("%s: Invalid captcha, retrying" % self.__name__)
+                self.invalidCaptcha()
+                self.retry()
+            else:
+                self.correctCaptcha()
+
+    def handleWebLinks(self):
+        package_links = []
+        pattern = r"(http://ncrypt\.in/link-.*?=)"
+        links = re.findall(pattern, self.html)
+        for link in links:
+            link = link.replace("link-", "frame-")
+            # Wait for "redirect location" function
+            # link = self.req.getRedirectLocation(link)
+            # package_links.append(link)
+        return package_links
+    
+    def handleContainer(self):
+        package_links = []
+        pattern = r"/container/(rsdf|dlc|ccf)/([a-z0-9]+)"
+        containersLinks = re.findall(pattern, self.html)
+        for containerLink in containersLinks:
+            link = "http://ncrypt.in/container/%s/%s.%s" % (containerLink[0], containerLink[1], containerLink[0])
+            package_links.append(link)
+        return package_links
+                
+    def handleCNL2(self):
+        package_links = []
+        if 'cnl2_output' in self.cleanedHtml:
+            try:
+                (vcrypted, vjk) = self._getCipherParams()
+                for (crypted, jk) in zip(vcrypted, vjk):
+                    package_links = package_links + self._getLinks(crypted, jk)
+            except:
+                self.fail("Unable to decrypt package")            
+        return package_links
+    
+    def _getCipherParams(self):
             
         pattern = r'<input.*?name="%s".*?value="(.*?)"'    
             
@@ -138,14 +184,14 @@ class NCryptIn(Crypter):
         vcrypted = re.findall(crypted_re, self.html)
 
         # Log and return
-        self.log.debug("NCryptIn: Detected crypted blocks [%d]" % len(vcrypted))
+        self.log.debug("%s: Detected crypted blocks [%d]" % (self.__name__, len(vcrypted)))
         return (vcrypted, vjk)
 
-    def getLinks(self, crypted, jk):
+    def _getLinks(self, crypted, jk):
 
         # Get key
         jreturn = self.js.eval("%s f()" % jk)
-        self.log.debug("NCryptIn: JsEngine returns value [%s]" % jreturn)
+        self.log.debug("%s: JsEngine returns value [%s]" % (self.__name__, jreturn))
         key = binascii.unhexlify(jreturn)
 
         # Decode crypted
@@ -163,5 +209,5 @@ class NCryptIn(Crypter):
         links = filter(lambda x: x != "", links)
 
         # Log and return
-        self.log.debug("NCryptIn: Package has %d links" % len(links))
+        self.log.debug("%s: Package has %d links" % (self.__name__, len(links)))
         return links
\ No newline at end of file
-- 
cgit v1.2.3