summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nitzo <nitzo2001@yahoo.com> 2016-08-01 23:34:45 +0200
committerGravatar Nitzo <nitzo2001@yahoo.com> 2016-08-01 23:34:45 +0200
commit020df65923233fcf1af1b6f2bf92fccde966b946 (patch)
treec22b3c2b1583beb9f91070b422ba0a7036870e0e
parent[UploadedTo] Fix #2554 (2) (diff)
downloadpyload-020df65923233fcf1af1b6f2bf92fccde966b946.tar.xz
[New Hoster] SmuleCom (fix #2562, fix #2402)
-rw-r--r--module/plugins/hoster/SmuleCom.py88
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
+