summaryrefslogtreecommitdiffstats
path: root/module/plugins/crypter
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins/crypter')
-rw-r--r--module/plugins/crypter/DownloadVimeoCom.py30
-rw-r--r--module/plugins/crypter/EasybytezComFolder.py60
-rw-r--r--module/plugins/crypter/GooGl.py15
-rw-r--r--module/plugins/crypter/MBLinkInfo.py27
-rw-r--r--module/plugins/crypter/Movie2kTo.py54
-rw-r--r--module/plugins/crypter/NCryptIn.py33
-rw-r--r--module/plugins/crypter/NetfolderIn.py48
-rw-r--r--module/plugins/crypter/SerienjunkiesOrg.py6
-rw-r--r--module/plugins/crypter/SpeedLoadOrgFolder.py15
-rw-r--r--module/plugins/crypter/UploadedToFolder.py37
-rw-r--r--module/plugins/crypter/YoutubeBatch.py37
11 files changed, 277 insertions, 85 deletions
diff --git a/module/plugins/crypter/DownloadVimeoCom.py b/module/plugins/crypter/DownloadVimeoCom.py
new file mode 100644
index 000000000..88310915b
--- /dev/null
+++ b/module/plugins/crypter/DownloadVimeoCom.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import re
+import HTMLParser
+from module.plugins.Crypter import Crypter
+
+class DownloadVimeoCom(Crypter):
+ __name__ = 'DownloadVimeoCom'
+ __type__ = 'crypter'
+ __pattern__ = r'(?:http://vimeo\.com/\d*|http://smotri\.com/video/view/\?id=.*)'
+ ## The download from dailymotion failed with a 403
+ __version__ = '0.1'
+ __description__ = """Video Download Plugin based on downloadvimeo.com"""
+ __author_name__ = ('4Christopher')
+ __author_mail__ = ('4Christopher@gmx.de')
+ BASE_URL = 'http://downloadvimeo.com'
+
+ def decrypt(self, pyfile):
+ self.package = pyfile.package()
+ html = self.load('%s/generate?url=%s' % (self.BASE_URL, pyfile.url))
+ h = HTMLParser.HTMLParser()
+ try:
+ f = re.search(r'cmd quality="(?P<quality>[^"]+?)">\s*?(?P<URL>[^<]*?)</cmd>', html)
+ except:
+ self.logDebug('Failed to find the URL')
+ else:
+ url = h.unescape(f.group('URL'))
+ self.logDebug('Quality: %s, URL: %s' % (f.group('quality'), url))
+ self.packages.append((self.package.name, [url], self.package.folder))
diff --git a/module/plugins/crypter/EasybytezComFolder.py b/module/plugins/crypter/EasybytezComFolder.py
new file mode 100644
index 000000000..1b887e421
--- /dev/null
+++ b/module/plugins/crypter/EasybytezComFolder.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+
+############################################################################
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU Affero 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 Affero General Public License for more details. #
+# #
+# You should have received a copy of the GNU Affero General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+############################################################################
+
+import re
+
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
+
+
+class EasybytezComFolder(SimpleCrypter):
+ __name__ = "EasybytezComFolder"
+ __type__ = "crypter"
+ __pattern__ = r"https?://(www\.)?easybytez\.com/users/\w+/\w+"
+ __version__ = "0.01"
+ __description__ = """Easybytez Crypter Plugin"""
+ __author_name__ = ("stickell")
+ __author_mail__ = ("l.stickell@yahoo.it")
+
+ LINK_PATTERN = r'<div class="link"><a href="(http://www\.easybytez\.com/\w+)" target="_blank">.+</a></div>'
+ TITLE_PATTERN = r'<Title>Files of (?P<title>.+) folder</Title>'
+ PAGES_PATTERN = r"<a href='[^']+'>(\d+)</a><a href='[^']+'>Next &#187;</a><br><small>\(\d+ total\)</small></div>"
+
+ def decrypt(self, pyfile):
+ self.html = self.load(pyfile.url, decode=True)
+
+ package_name, folder_name = self.getPackageNameAndFolder()
+
+ package_links = re.findall(self.LINK_PATTERN, self.html)
+
+ pages = re.search(self.PAGES_PATTERN, self.html)
+ if pages:
+ pages = int(pages.group(1))
+ else:
+ pages = 1
+
+ p = 2
+ while p <= pages:
+ self.html = self.load(pyfile.url, get={'page': p}, decode=True)
+ package_links += re.findall(self.LINK_PATTERN, self.html)
+ p += 1
+
+ self.logDebug('Package has %d links' % len(package_links))
+
+ if package_links:
+ self.packages = [(package_name, package_links, folder_name)]
+ else:
+ self.fail('Could not extract any links') \ No newline at end of file
diff --git a/module/plugins/crypter/GooGl.py b/module/plugins/crypter/GooGl.py
index 07de5e008..bcb1d7494 100644
--- a/module/plugins/crypter/GooGl.py
+++ b/module/plugins/crypter/GooGl.py
@@ -1,5 +1,20 @@
# -*- coding: utf-8 -*-
+############################################################################
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU Affero 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 Affero General Public License for more details. #
+# #
+# You should have received a copy of the GNU Affero General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+############################################################################
+
from module.plugins.Crypter import Crypter
from module.common.json_layer import json_loads
diff --git a/module/plugins/crypter/MBLinkInfo.py b/module/plugins/crypter/MBLinkInfo.py
new file mode 100644
index 000000000..e266c7722
--- /dev/null
+++ b/module/plugins/crypter/MBLinkInfo.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.Crypter import Crypter
+
+
+class MBLinkInfo(Crypter):
+ __name__ = "MBLinkInfo"
+ __type__ = "container"
+ __pattern__ = r"http://(?:www\.)?mblink\.info/?\?id=(\d+)"
+ __version__ = "0.02"
+ __description__ = """MBLink.Info Container Plugin"""
+ __author_name__ = ("Gummibaer", "stickell")
+ __author_mail__ = ("Gummibaer@wiki-bierkiste.de", "l.stickell@yahoo.it")
+
+ URL_PATTERN = r'<meta[^;]+; URL=(.*)["\']>'
+
+ def decrypt(self, pyfile):
+ src = self.load(pyfile.url)
+ found = re.search(self.URL_PATTERN, src)
+ if found:
+ link = found.group(1)
+ self.logDebug("Redirected to " + link)
+ self.core.files.addLinks([link], self.pyfile.package().id)
+ else:
+ self.fail('Unable to detect valid link')
diff --git a/module/plugins/crypter/Movie2kTo.py b/module/plugins/crypter/Movie2kTo.py
index f5800b498..097cb702e 100644
--- a/module/plugins/crypter/Movie2kTo.py
+++ b/module/plugins/crypter/Movie2kTo.py
@@ -9,11 +9,12 @@ class Movie2kTo(Crypter):
__name__ = 'Movie2kTo'
__type__ = 'container'
__pattern__ = r'http://(?:www\.)?movie2k\.to/(.*)\.html'
- __version__ = '0.3'
- __config__ = [('accepted_hosters', 'str', 'List of accepted hosters', 'Xvidstage, '),
+ __version__ = '0.5'
+ __config__ = [('accepted_hosters', 'str', 'List of accepted hosters', 'Xvidstage, Putlocker, '),
+ ('dir_quality', 'bool', 'Show the quality of the footage in the folder name', 'True'),
('whole_season', 'bool', 'Download whole season', 'False'),
('everything', 'bool', 'Download everything', 'False'),
- ('firstN', 'int', 'Download the first N files for each episode. The first file is probably all you will need.', '1')]
+ ('firstN', 'int', 'Download the first N files for each episode (the first file is probably all you will need)', '1')]
__description__ = """Movie2k.to Container Plugin"""
__author_name__ = ('4Christopher')
__author_mail__ = ('4Christopher@gmx.de')
@@ -47,21 +48,26 @@ class Movie2kTo(Crypter):
season_links += self.getInfoAndLinks('%s/%s' % (self.BASE_URL, url_path))
self.logDebug(season_links)
- self.packages.append(('%s: Season %s (%s)'
- % (self.name, season, self.qStat()), season_links, 'Season %s' % season))
+ folder = '%s: Season %s' % (self.name, season)
+ name = '%s%s' % (folder, self.qStat())
+ self.packages.append((name, season_links, folder))
self.qStatReset()
else:
links = self.getLinks()
- self.package.name = '%s%s' % (self.package.name, self.qStat())
- self.packages.append((self.package.name, links , self.package.folder))
+ name = '%s%s' % (self.package.name, self.qStat())
+ self.packages.append((name, links , self.package.folder))
def qStat(self):
if len(self.q) == 0: return ''
+ if not self.getConfig('dir_quality'): return ''
+ if len(self.q) == 1: return (' (Quality: %d, max (all hosters): %d)' % (self.q[0], self.max_q))
return (' (Average quality: %d, min: %d, max: %d, %s, max (all hosters): %d)'
% (sum(self.q) / float(len(self.q)), min(self.q), max(self.q), self.q, self.max_q))
+
def qStatReset(self):
- self.q = [] ## to calculate the average, min and max of the quality
- self.max_q = None
+ self.q = [] ## to calculate the average, min and max of the quality
+ self.max_q = None ## maximum quality of all hosters
+
def tvshow_number(self, number):
if int(number) < 10:
return '0%s' % number
@@ -81,8 +87,6 @@ class Movie2kTo(Crypter):
elif re.search(self.FILM_URL_PATH_PATTERN, self.url_path):
self.format = 'film'
pattern_re = re.search(self.FILM_URL_PATH_PATTERN, self.url_path)
-
-
self.name = pattern_re.group('name')
self.id = pattern_re.group('id')
self.logDebug('URL Path: %s (ID: %s, Name: %s, Format: %s)'
@@ -100,8 +104,8 @@ class Movie2kTo(Crypter):
re_quality = re.compile(r'.+?Quality:.+?smileys/(\d)\.gif')
## The quality is one digit. 0 is the worst and 5 is the best.
## Is not always there …
- re_hoster_id_html = re.compile(r'(?:<td height|<tr id).+?<a href=".*?(\d{7}).*?".+?&nbsp;([^<>]+?)</a>(.+?)</tr>')
re_hoster_id_js = re.compile(r'links\[(\d+?)\].+&nbsp;(.+?)</a>(.+?)</tr>')
+ re_hoster_id_html = re.compile(r'(?:<td height|<tr id).+?<a href=".*?(\d{7}).*?".+?&nbsp;([^<>]+?)</a>(.+?)</tr>')
## I assume that the ID is 7 digits longs
count = defaultdict(int)
matches = re_hoster_id_html.findall(self.html)
@@ -112,10 +116,10 @@ class Movie2kTo(Crypter):
match_q = re_quality.search(q_html)
if match_q:
quality = int(match_q.group(1))
- if self.max_q:
- if self.max_q < quality: self.max_q = quality
- else: ## was None before
+ if self.max_q == None:
self.max_q = quality
+ else:
+ if self.max_q < quality: self.max_q = quality
q_s = ', Quality: %d' % quality
else:
q_s = ', unknown quality'
@@ -128,14 +132,20 @@ class Movie2kTo(Crypter):
self.html = self.load('%s/tvshows-%s-%s.html' % (self.BASE_URL, h_id, self.name))
else:
self.logDebug('This is already the right ID')
- try:
- url = re.search(r'<a target="_blank" href="(http://.*?)"', self.html).group(1)
- self.logDebug('id: %s, %s: %s' % (h_id, hoster, url))
- links.append(url)
- except:
- self.logDebug('Failed to find the URL')
+ # The iframe tag must continue with a width. There where
+ # two iframes in the site and I try to make sure that it
+ # matches the right one. This is not (yet) nessesary
+ # because the right iframe happens to be the first iframe.
+ for pattern in (r'<a target="_blank" href="(http://[^"]*?)"', r'<iframe src="(http://[^"]*?)" width'):
+ try:
+ url = re.search(pattern, self.html).group(1)
+ except:
+ self.logDebug('Failed to find the URL (pattern %s)' % pattern)
+ else:
+ self.logDebug('id: %s, %s: %s' % (h_id, hoster, url))
+ links.append(url)
+ break
else:
self.logDebug('Not accepted: %s, ID: %s%s' % (hoster, h_id, q_s))
-
# self.logDebug(links)
return links
diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py
index a8eaac631..5e1ea347c 100644
--- a/module/plugins/crypter/NCryptIn.py
+++ b/module/plugins/crypter/NCryptIn.py
@@ -50,7 +50,8 @@ class NCryptIn(Crypter):
package_links = []
package_links.extend(self.handleWebLinks())
package_links.extend(self.handleContainers())
- package_links.extend(self.handleCNL2())
+ package_links.extend(self.handleCNL2())
+ package_links = self.removeContainers(package_links)
package_links = set(package_links)
# Pack
@@ -65,7 +66,20 @@ class NCryptIn(Crypter):
rexpr = re.compile(pattern, re.DOTALL)
content = re.sub(rexpr, "", content)
return content
-
+
+ def removeContainers(self,package_links):
+ tmp_package_links = package_links[:]
+ for link in tmp_package_links:
+ self.logDebug(link)
+ if ".dlc" in link or ".ccf" in link or ".rsdf" in link:
+ self.logDebug("Removing [%s] from package_links" % link)
+ package_links.remove(link)
+
+ if len(package_links) > 0:
+ return package_links
+ else:
+ return tmp_package_links
+
def isOnline(self):
if "Your folder does not exist" in self.cleanedHtml:
self.logDebug("File not found")
@@ -121,6 +135,19 @@ class NCryptIn(Crypter):
challenge, code = recaptcha.challenge(id)
postData['recaptcha_challenge_field'] = challenge
postData['recaptcha_response_field'] = code
+
+ # Resolve circlecaptcha
+ if "circlecaptcha" in form:
+ self.captcha = True
+ self.logDebug("Captcha protected")
+ captcha_img_url = "http://ncrypt.in/classes/captcha/circlecaptcha.php"
+ coords = self.decryptCaptcha(captcha_img_url, forceUser=True, imgtype="png", result_type='positional')
+ self.logDebug("Captcha resolved, coords [%s]" % str(coords))
+ self.captcha_post_url = self.pyfile.url
+
+ postData['circle.x'] = coords[0]
+ postData['circle.y'] = coords[1]
+
# Unlock protection
postData['submit_protected'] = 'Continue to folder '
@@ -221,4 +248,4 @@ class NCryptIn(Crypter):
# Log and return
self.logDebug("Block has %d links" % len(links))
- return links \ No newline at end of file
+ return links
diff --git a/module/plugins/crypter/NetfolderIn.py b/module/plugins/crypter/NetfolderIn.py
index d71a73d0a..c5c602c27 100644
--- a/module/plugins/crypter/NetfolderIn.py
+++ b/module/plugins/crypter/NetfolderIn.py
@@ -1,22 +1,25 @@
# -*- coding: utf-8 -*-
-from module.plugins.Crypter import Crypter
import re
-class NetfolderIn(Crypter):
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
+
+
+class NetfolderIn(SimpleCrypter):
__name__ = "NetfolderIn"
__type__ = "crypter"
__pattern__ = r"http://(?:www\.)?netfolder.in/((?P<id1>\w+)/\w+|folder.php\?folder_id=(?P<id2>\w+))"
- __version__ = "0.4"
+ __version__ = "0.6"
__description__ = """NetFolder Crypter Plugin"""
__author_name__ = ("RaNaN", "fragonib")
__author_mail__ = ("RaNaN@pyload.org", "fragonib[AT]yahoo[DOT]es")
+ TITLE_PATTERN = r'<div class="Text">Inhalt des Ordners <span(.*)>(?P<title>.+)</span></div>'
+
def decrypt(self, pyfile):
-
# Request package
self.html = self.load(pyfile.url)
-
+
# Check for password protection
if self.isPasswordProtected():
self.html = self.submitPassword()
@@ -31,54 +34,37 @@ class NetfolderIn(Crypter):
# Set package
self.packages = [(package_name, package_links, folder_name)]
-
-
+
def isPasswordProtected(self):
-
+
if '<input type="password" name="password"' in self.html:
self.logDebug("Links are password protected")
return True
return False
-
def submitPassword(self):
# Gather data
try:
m = re.match(self.__pattern__, self.pyfile.url)
- id = max(m.group('id1'), m.group('id2'))
+ id = max(m.group('id1'), m.group('id2'))
except AttributeError:
self.logDebug("Unable to get package id from url [%s]" % self.pyfile.url)
return
url = "http://netfolder.in/folder.php?folder_id=" + id
password = self.getPassword()
-
+
# Submit package password
- post = { 'password' : password, 'save' : 'Absenden' }
+ post = {'password': password, 'save': 'Absenden'}
self.logDebug("Submitting password [%s] for protected links with id [%s]" % (password, id))
html = self.load(url, {}, post)
-
+
# Check for invalid password
if '<div class="InPage_Error">' in html:
self.logDebug("Incorrect password, please set right password on Edit package form and retry")
return None
-
- return html
-
-
- def getPackageNameAndFolder(self):
- title_re = r'<div class="Text">Inhalt des Ordners <span(.*)>(?P<title>.+)</span></div>'
- m = re.search(title_re, self.html)
- if m is not None:
- name = folder = m.group('title')
- self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder))
- return name, folder
- else:
- name = self.pyfile.package().name
- folder = self.pyfile.package().folder
- self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
- return name, folder
-
-
+
+ return html
+
def getLinks(self):
links = re.search(r'name="list" value="(.*?)"', self.html).group(1).split(",")
self.logDebug("Package has %d links" % len(links))
diff --git a/module/plugins/crypter/SerienjunkiesOrg.py b/module/plugins/crypter/SerienjunkiesOrg.py
index dfe34ff6e..3fcc12e36 100644
--- a/module/plugins/crypter/SerienjunkiesOrg.py
+++ b/module/plugins/crypter/SerienjunkiesOrg.py
@@ -11,13 +11,13 @@ class SerienjunkiesOrg(Crypter):
__name__ = "SerienjunkiesOrg"
__type__ = "container"
__pattern__ = r"http://.*?(serienjunkies.org|dokujunkies.org)/.*?"
- __version__ = "0.36"
+ __version__ = "0.38"
__config__ = [
("changeNameSJ", "Packagename;Show;Season;Format;Episode", "Take SJ.org name", "Show"),
("changeNameDJ", "Packagename;Show;Format;Episode", "Take DJ.org name", "Show"),
("randomPreferred", "bool", "Randomize Preferred-List", False),
("hosterListMode", "OnlyOne;OnlyPreferred(One);OnlyPreferred(All);All", "Use for hosters (if supported)", "All"),
- ("hosterList", "str", "Preferred Hoster list (comma separated)", "RapidshareCom,UploadedTo,NetloadIn,FilefactoryCom,FreakshareNet,FilebaseTo,MegauploadCom,HotfileCom,DepositfilesCom,EasyshareCom,KickloadCom"),
+ ("hosterList", "str", "Preferred Hoster list (comma separated)", "RapidshareCom,UploadedTo,NetloadIn,FilefactoryCom,FreakshareNet,FilebaseTo,HotfileCom,DepositfilesCom,EasyshareCom,KickloadCom"),
("ignoreList", "str", "Ignored Hoster list (comma separated)", "MegauploadCom")
]
__description__ = """serienjunkies.org Container Plugin"""
@@ -30,6 +30,8 @@ class SerienjunkiesOrg(Crypter):
def getSJSrc(self, url):
src = self.req.load(str(url))
+ if "This website is not available in your country" in src:
+ self.fail("Not available in your country")
if not src.find("Enter Serienjunkies") == -1:
sleep(1)
src = self.req.load(str(url))
diff --git a/module/plugins/crypter/SpeedLoadOrgFolder.py b/module/plugins/crypter/SpeedLoadOrgFolder.py
index 5b350787f..f85ede6f3 100644
--- a/module/plugins/crypter/SpeedLoadOrgFolder.py
+++ b/module/plugins/crypter/SpeedLoadOrgFolder.py
@@ -1,5 +1,20 @@
# -*- coding: utf-8 -*-
+############################################################################
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU Affero 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 Affero General Public License for more details. #
+# #
+# You should have received a copy of the GNU Affero General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+############################################################################
+
from module.plugins.internal.SimpleCrypter import SimpleCrypter
class SpeedLoadOrgFolder(SimpleCrypter):
diff --git a/module/plugins/crypter/UploadedToFolder.py b/module/plugins/crypter/UploadedToFolder.py
index d4534297e..c514f23d0 100644
--- a/module/plugins/crypter/UploadedToFolder.py
+++ b/module/plugins/crypter/UploadedToFolder.py
@@ -1,13 +1,30 @@
# -*- coding: utf-8 -*-
-from module.plugins.Crypter import Crypter
+############################################################################
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU Affero 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 Affero General Public License for more details. #
+# #
+# You should have received a copy of the GNU Affero General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+############################################################################
+
import re
-class UploadedToFolder(Crypter):
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
+
+
+class UploadedToFolder(SimpleCrypter):
__name__ = "UploadedToFolder"
__type__ = "crypter"
- __pattern__ = r"http://(?:www\.)?(uploaded|ul)\.(to|net)/(f|list)/(?P<id>\w+)"
- __version__ = "0.1"
+ __pattern__ = r"http://(?:www\.)?(uploaded|ul)\.(to|net)/(f|folder|list)/(?P<id>\w+)"
+ __version__ = "0.3"
__description__ = """UploadedTo Crypter Plugin"""
__author_name__ = ("stickell")
__author_mail__ = ("l.stickell@yahoo.it")
@@ -31,15 +48,3 @@ class UploadedToFolder(Crypter):
self.logDebug('Package has %d links' % len(package_links))
self.packages = [(package_name, package_links, folder_name)]
-
- def getPackageNameAndFolder(self):
- m = re.search(self.TITLE_PATTERN, self.html)
- if m:
- name = folder = m.group('title')
- self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder))
- return name, folder
- else:
- name = self.pyfile.package().name
- folder = self.pyfile.package().folder
- self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
- return name, folder
diff --git a/module/plugins/crypter/YoutubeBatch.py b/module/plugins/crypter/YoutubeBatch.py
index 2e68dfe02..72b72aab7 100644
--- a/module/plugins/crypter/YoutubeBatch.py
+++ b/module/plugins/crypter/YoutubeBatch.py
@@ -2,26 +2,41 @@
# -*- coding: utf-8 -*-
import re
+import json
from module.plugins.Crypter import Crypter
+API_KEY = "AIzaSyCKnWLNlkX-L4oD1aEzqqhRw1zczeD6_k0"
+
class YoutubeBatch(Crypter):
__name__ = "YoutubeBatch"
__type__ = "container"
- __pattern__ = r"http://(?:[^/]*?)youtube\.com/((?:view_play_list|playlist|.*?feature=PlayList).*?[\?&](?:list|p)=|user/)(\w+)"
- __version__ = "0.92"
+ __pattern__ = r"https?://(?:[^/]*?)youtube\.com/(?:(?:view_play_list|playlist|.*?feature=PlayList).*?[?&](?:list|p)=)([a-zA-Z0-9-_]+)"
+ __version__ = "0.93"
__description__ = """Youtube.com Channel Download Plugin"""
- __author_name__ = ("RaNaN", "Spoob", "zoidberg")
- __author_mail__ = ("RaNaN@pyload.org", "spoob@pyload.org", "zoidberg@mujmail.cz")
+ __author_name__ = ("RaNaN", "Spoob", "zoidberg", "roland")
+ __author_mail__ = ("RaNaN@pyload.org", "spoob@pyload.org", "zoidberg@mujmail.cz", "roland@enkore.de")
+
+ def get_videos(self, playlist_id, token=None):
+ url = "https://www.googleapis.com/youtube/v3/playlistItems?playlistId=%s&part=snippet&key=%s&maxResults=50" % (playlist_id, API_KEY)
+ if token:
+ url += "&pageToken=" + token
+
+ response = json.loads(self.load(url))
+
+ for item in response["items"]:
+ if item["kind"] == "youtube#playlistItem" and item["snippet"]["resourceId"]["kind"] == "youtube#video":
+ yield "http://youtube.com/watch?v=" + item["snippet"]["resourceId"]["videoId"]
+
+ if "nextPageToken" in response:
+ for item in self.get_videos(playlist_id, response["nextPageToken"]):
+ yield item
def decrypt(self, pyfile):
match_id = re.match(self.__pattern__, self.pyfile.url)
- if match_id.group(1) == "user/":
- url = "http://gdata.youtube.com/feeds/api/users/%s/uploads?v=2" % match_id.group(2)
- else:
- url = "http://gdata.youtube.com/feeds/api/playlists/%s?v=2" % match_id.group(2)
-
- rep = self.load(url)
new_links = []
- new_links.extend(re.findall(r"href\='(http:\/\/www.youtube.com\/watch\?v\=[^']+)&", rep))
+ playlist_id = match_id.group(1)
+
+ new_links.extend(self.get_videos(playlist_id))
+
self.packages.append((self.pyfile.package().name, new_links, self.pyfile.package().name))