diff options
Diffstat (limited to 'module/plugins/hoster/SmuleCom.py')
| -rw-r--r-- | module/plugins/hoster/SmuleCom.py | 88 | 
1 files changed, 88 insertions, 0 deletions
| diff --git a/module/plugins/hoster/SmuleCom.py b/module/plugins/hoster/SmuleCom.py new file mode 100644 index 000000000..865b18698 --- /dev/null +++ b/module/plugins/hoster/SmuleCom.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +import re + +from module.common.JsEngine import JsEngine +from module.plugins.internal.SimpleHoster import SimpleHoster + + +class SmuleCom(SimpleHoster): +    __name__    = "SmuleCom" +    __type__    = "hoster" +    __version__ = "0.02" +    __status__  = "testing" + +    __pattern__ = r'https?://(?:www\.)?smule\.com/recording/.+' + +    __description__ = """SmuleCom hoster plugin""" +    __license__     = "GPLv3" +    __authors__     = [("igel"     , None                        ), +                       ("GammaC0de", "nitzo2001[AT]yahoo[DOT]com")] + + +    MEDIA_URL_PATTERN       = r'initPlayer\(.+?["\']video_media_url["\']:["\'](.+?)["\']' +    JS_HEADER_PATTERN       = r'(?P<decoder>function \w+\(\w+\){.+?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\+.+?}).+?;(?P<initvars>var r=.+?;)' +    JS_PROCESS_PATTERN      = r'processRecording\s*=\s*function.+?}' +    JS_SPLIT_WORD           = r'EXIF' # all interesting parts of the javascript function occur before the first occurance of this word +    NAME_PATTERN            = r'initPlayer\(.+?["\']title["\']:["\'](?P<N>.+?)["\']' +    COMMUNITY_JS_PATTERN    = r'<script.+?src=["\']/*(\w[^"\']*community.+?js)["\']' +    OFFLINE_PATTERN         = r'Page Not Found' + + +    @classmethod +    def get_info(cls, url="", html=""): +        info = super(SmuleCom, cls).get_info(url, html) +        # Unfortunately, NAME_PATTERN does not include file extension so we blindly add '.mp4' as an extension. +        # (hopefully all links are '.mp4' files) +        info['name'] += ".mp4" + +        return info + + +    def handle_free(self, pyfile): +        # step 1: get essential information: the media URL and the javascript translating the URL +        m = re.search(self.MEDIA_URL_PATTERN, self.data) +        if m is None: +            self.fail(_("Could not find any media URLs")) + +        encoded_media_url = m.group(1) +        self.log_debug(_("Found encoded media URL: %s") % encoded_media_url) +        +        m = re.search(self.COMMUNITY_JS_PATTERN, self.data) +        if m is None: +            self.fail(_("Could not find necessary javascript script to load")) + +        community_js_url = m.group(1) +        self.log_debug(_("Found community js at %s") % community_js_url) + +        community_js_code = self.load(community_js_url) +         +        # step 2: from the js code, parse the necessary parts: the decoder function and the headers +        # as the jscript is fairly long, we'll split it to make parsing easier +        if self.JS_SPLIT_WORD: +            community_js_code = community_js_code.partition(self.JS_SPLIT_WORD)[0] + +        m = re.search(self.JS_HEADER_PATTERN, community_js_code) +        if m is None: +            self.fail(_("Could not parse the necessary parts off the javascript")) + +        decoder_function = m.group('decoder') +        initialization = m.group('initvars') + +        m = re.search(self.JS_PROCESS_PATTERN, community_js_code) +        if m is None: +            self.fail(_("Could not parse the processing function off the javascript")) + +        process_function = m.group(0) + +        # step 3: assemble the new js code +        js = JsEngine() + +        new_js_code = decoder_function + '; ' + initialization + '; var ' + process_function + '; processRecording("' + encoded_media_url + '");' + +        self.log_debug(_("Running js script: %s") % new_js_code) +        js_result = js.eval(new_js_code) +        self.log_debug(_("Result is: %s") % js_result) + +        self.link = js_result + | 
