From 991ba7fae38498b1066c7f6821d1d8681ef87f1b Mon Sep 17 00:00:00 2001 From: Jeff Crouse Date: Sat, 5 Jan 2013 15:42:35 -0500 Subject: [PATCH] Added extractors for 3 porn sites --- LATEST_VERSION | 2 +- README.md | 14 +- youtube-dl | Bin 45792 -> 3447 bytes youtube_dl/InfoExtractors.py | 328 +++++++++++++++++++++++++++++++++++ 4 files changed, 336 insertions(+), 8 deletions(-) mode change 100644 => 100755 LATEST_VERSION mode change 100644 => 100755 README.md diff --git a/LATEST_VERSION b/LATEST_VERSION old mode 100644 new mode 100755 index d070c6ea3..275de03d9 --- a/LATEST_VERSION +++ b/LATEST_VERSION @@ -1 +1 @@ -2012.10.09 +9999.99.99 \ No newline at end of file diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 4b0de1b88..b3cd9a38c --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ which means you can modify it, redistribute it or use it however you like. --list-extractors List all supported extractors and the URLs they would handle - Video Selection: +## Video Selection: --playlist-start NUMBER playlist video to start at (default is 1) --playlist-end NUMBER playlist video to end at (default is last) --match-title REGEX download only matching titles (regex or caseless @@ -39,7 +39,7 @@ which means you can modify it, redistribute it or use it however you like. caseless sub-string) --max-downloads NUMBER Abort after downloading NUMBER files - Filesystem Options: +## Filesystem Options: -t, --title use title in file name --id use video ID in file name -l, --literal [deprecated] alias of --title @@ -70,7 +70,7 @@ which means you can modify it, redistribute it or use it however you like. --write-description write video description to a .description file --write-info-json write video metadata to a .info.json file - Verbosity / Simulation Options: +## Verbosity / Simulation Options: -q, --quiet activates quiet mode -s, --simulate do not download the video and do not write anything to disk @@ -85,7 +85,7 @@ which means you can modify it, redistribute it or use it however you like. --console-title display progress in console titlebar -v, --verbose print various debugging information - Video Format Options: +## Video Format Options: -f, --format FORMAT video format code --all-formats download all available video formats --prefer-free-formats prefer free video formats unless a specific one is @@ -97,12 +97,12 @@ which means you can modify it, redistribute it or use it however you like. --srt-lang LANG language of the closed captions to download (optional) use IETF language tags like 'en' - Authentication Options: +## Authentication Options: -u, --username USERNAME account username -p, --password PASSWORD account password -n, --netrc use .netrc authentication data - Post-processing Options: +## Post-processing Options: -x, --extract-audio convert video files to audio-only files (requires ffmpeg or avconv and ffprobe or avprobe) --audio-format FORMAT "best", "aac", "vorbis", "mp3", "m4a", or "wav"; @@ -172,7 +172,7 @@ youtube requires an additional signature since September 2012 which is not suppo The error File "youtube-dl", line 2 - SyntaxError: Non-ASCII character '“' ... + SyntaxError: Non-ASCII character '\x93' ... means you're using an outdated version of Python. Please update to Python 2.6 or 2.7. diff --git a/youtube-dl b/youtube-dl index 6ba864a14c87e41cc8c836754d5a8932ae8967a2..e6f05c17327ed58f8db66e6dc7d2a38380355d61 100755 GIT binary patch literal 3447 zcmbVOdvDt|5dVAr6qgpAq}5eK$&%#&DbS%Q)@^8tq+Ky2fk8qkP9-o{xN}eW#I7RUp>b+i9VlpWt%Pb>@Oy`OR?7Qy47(ZWhKwxF}!V6ga5Te z|6x&+40Di*FF&I!^1Z!5rT7Y`po*2?x{*siG3gLgZCTU<^s@U9YK)N)E?VH{KnbpM!q}63H+DyOz&TVyWW2AKp(R%Am!6e9j^z);ml){hT?Owg={WT7ZvK}zlKJxGxlql>` zmE*uqlsM~l=XsU`PtDqL+>cdpOw@*;$PbEcyfgm}PR<8bVy8@vNqogArC-HuH1ozk z>q0>yMWqKJq`wdc9sgO{D3{`v;m#i2ah|d-6&)y*=2EL|q1PRG;N9*5Mj!opFX@Zu zTios<+Q+n>#l}V2hx8lJH>1z*&OCEw_~^{1DE{|2u*Jc?(KZv-?&*z{?qvSick}@BtxRbFsn(9{{%2!&Qy=1>WQO(hX@u|fA%(Chq$%6IER!L}$%qA&M^n01YU z)+xGhO=wAHwIrwl6dI+`va0BsE-NYbkXLlJCLOYBk`hlIQuE5-nX%iz@(Oj!L{QFU zLGP_YG_C8i(^I($+!f`zNnFC@(}SOAL%vF`mv4H;BPmb8`kf?RzgzYs*5udg2MBwNR<7x8R&UGo^6L7< z^0$jW$spU?Ewac%oMmwydtt!*JWE)}BR`Ml$s$a$C}MM3u`FlvXdZ`EJ7Z80YetDERKS7vGC^@ zc(ZUGC28zM3!i?_Tg>7`l&3jkNfhM)`U~`C81Om61!pV_WBTVQau&}#j%hH@(||aV zC?N~em~ocQ*ldPgkYp_N7|Ss7G04gIc@p^Z%!_A!l;a|pLKKF<+@Zms1FVX&m!?#~ z_K;IEC%7M$m%sHL&?Fdlg|@AWtE7U3#5bo2mxhaqUY9*2*r5T0XSU;J*tO9{=g;E4i{2M$a_*Y)SN0cILrHhNY4oKT zoJqO3wKP#vt{V-Wz8*kS$=xJ@fUd7(*y5!9DwI~=t8 zw5${!K-7MH*<$DvF0b2#W5!=Jg@g3{c+I8x7#SMN|TlgB43N7I+Q8j4cF=V%Yr=w z-i#;EzU~1ZreJLonv*Cb)T{GOuNeW&u5bBAz6_n|{|B`qUpw4N8!1g1kHY$m*8h?w VgcEqv4HG~(0kRQCgGDzp`~&H2U`7A{ literal 45792 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 diff --git a/youtube_dl/InfoExtractors.py b/youtube_dl/InfoExtractors.py index e380f62a1..72ad25ad3 100755 --- a/youtube_dl/InfoExtractors.py +++ b/youtube_dl/InfoExtractors.py @@ -14,6 +14,10 @@ import email.utils import xml.etree.ElementTree import random import math +import urllib +import urllib2 +import httplib +from urlparse import parse_qs, urlparse from .utils import * @@ -3735,6 +3739,327 @@ class UstreamIE(InfoExtractor): return [info] + +class YouPornIE(InfoExtractor): + """Information extractor for youporn.com.""" + + _VALID_URL = r'^(?:https?://)?(?:\w+\.)?youporn\.com/watch/(?P[0-9]+)/(?P[^/]+)' + IE_NAME = u'youporn' + VIDEO_TITLE_RE = r'videoTitleArea">(?P<title>.*)</h1>' + VIDEO_DATE_RE = r'Date:</b>(?P<date>.*)</li>' + VIDEO_UPLOADER_RE = r'Submitted:</b>(?P<uploader>.*)</li>' + DOWNLOAD_LIST_RE = r'(?s)<ul class="downloadList">(?P<download_list>.*?)</ul>' + LINK_RE = r'(?s)<a href="(?P<url>[^"]+)">' + + def __init__(self, downloader=None): + InfoExtractor.__init__(self, downloader) + + def report_id(self, video_id): + """Report finding video ID""" + self._downloader.to_screen(u'[youporn] Video ID: %s' % video_id) + + def report_webpage(self, url): + """Report downloading page""" + self._downloader.to_screen(u'[youporn] Downloaded page: %s' % url) + + def report_title(self, video_title): + """Report dfinding title""" + self._downloader.to_screen(u'[youporn] Title: %s' % video_title) + + def report_uploader(self, uploader): + """Report dfinding title""" + self._downloader.to_screen(u'[youporn] Uploader: %s' % uploader) + + def report_upload_date(self, video_date): + """Report finding date""" + self._downloader.to_screen(u'[youporn] Date: %s' % video_date) + + def _print_formats(self, formats): + """Print all available formats""" + print 'Available formats:' + print u'ext\t\tformat' + print u'---------------------------------' + for format in formats: + print u'%s\t\t%s' % (format['ext'], format['format']) + + def _specific(self, req_format, formats): + for x in formats: + if(x["format"]==req_format): + return x + return None + + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + if mobj is None: + self._downloader.trouble(u'ERROR: invalid URL: %s' % url) + return + + video_id = mobj.group('videoid').decode('utf-8') + self.report_id(video_id) + + # Get webpage content + try: + webpage = urllib2.urlopen(url).read() + except (urllib2.URLError, httplib.HTTPException, socket.error), err: + self._downloader.trouble(u'ERROR: unable to download video webpage: %s' % err) + return + self.report_webpage(url) + + # Get the video title + result = re.search(self.VIDEO_TITLE_RE, webpage) + if result is None: + self._downloader.trouble(u'ERROR: unable to extract video title') + return + video_title = result.group('title').decode('utf-8').strip() + self.report_title(video_title) + + # Get the video date + result = re.search(self.VIDEO_DATE_RE, webpage) + if result is None: + self._downloader.trouble(u'ERROR: unable to extract video date') + return + upload_date = result.group('date').decode('utf-8').strip() + self.report_upload_date(upload_date) + + # Get the video uploader + result = re.search(self.VIDEO_UPLOADER_RE, webpage) + if result is None: + self._downloader.trouble(u'ERROR: unable to extract uploader') + return + video_uploader = result.group('uploader').decode('utf-8').strip() + video_uploader = clean_html( video_uploader ) + self.report_uploader(video_uploader) + + # Get all of the formats available + result = re.search(self.DOWNLOAD_LIST_RE, webpage) + if result is None: + self._downloader.trouble(u'ERROR: unable to extract download list') + return + download_list_html = result.group('download_list').decode('utf-8').strip() + + # Get all of the links from the page + links = re.findall(self.LINK_RE, download_list_html) + if(len(links) == 0): + self._downloader.trouble(u'ERROR: no known formats available for video') + return + + self._downloader.to_screen(u'[youporn] Links found: %d' % len(links)) + + formats = [] + for link in links: + + # A link looks like this: + # http://cdn1.download.youporn.phncdn.com/201210/31/8004515/480p_370k_8004515/YouPorn%20-%20Nubile%20Films%20The%20Pillow%20Fight.mp4?nvb=20121113051249&nva=20121114051249&ir=1200&sr=1200&hash=014b882080310e95fb6a0 + # A path looks like this: + # /201210/31/8004515/480p_370k_8004515/YouPorn%20-%20Nubile%20Films%20The%20Pillow%20Fight.mp4 + video_url = unescapeHTML( link.decode('utf-8') ) + path = urlparse( video_url ).path + extension = os.path.splitext( path )[1][1:] + format = path.split('/')[4].split('_')[:2] + size = format[0] + bitrate = format[1] + format = "-".join( format ) + title = u'%s-%s-%s' % (video_title, size, bitrate) + + formats.append({ + 'id': video_id, + 'url': video_url, + 'uploader': video_uploader, + 'upload_date': upload_date, + 'title': title, + 'ext': extension, + 'format': format, + 'thumbnail': None, + 'description': None, + 'player_url': None + }) + + if self._downloader.params.get('listformats', None): + self._print_formats(formats) + return + + req_format = self._downloader.params.get('format', None) + #format_limit = self._downloader.params.get('format_limit', None) + self._downloader.to_screen(u'[youporn] Format: %s' % req_format) + + + if req_format is None or req_format == 'best': + return [formats[0]] + elif req_format == 'worst': + return [formats[-1]] + elif req_format in ('-1', 'all'): + return formats + else: + format = self._specific( req_format, formats ) + if result is None: + self._downloader.trouble(u'ERROR: requested format not available') + return + return [format] + + + +class PornotubeIE(InfoExtractor): + """Information extractor for pornotube.com.""" + + _VALID_URL = r'^(?:https?://)?(?:\w+\.)?pornotube\.com(/c/(?P<channel>[0-9]+))?(/m/(?P<videoid>[0-9]+))(/(?P<title>.+))$' + IE_NAME = u'pornotube' + VIDEO_URL_RE = r'url: "(?P<url>http://video[0-9].pornotube.com/.+\.flv)",' + VIDEO_UPLOADED_RE = r'<div class="video_added_by">Added (?P<date>[0-9\/]+) by' + + + def __init__(self, downloader=None): + InfoExtractor.__init__(self, downloader) + + def report_extract_entry(self, url): + """Report downloading extry""" + self._downloader.to_screen(u'[pornotube] Downloading entry: %s' % url.decode('utf-8')) + + def report_date(self, upload_date): + """Report finding uploaded date""" + self._downloader.to_screen(u'[pornotube] Entry date: %s' % upload_date) + + def report_webpage(self, url): + """Report downloading page""" + self._downloader.to_screen(u'[pornotube] Downloaded page: %s' % url) + + def report_title(self, video_title): + """Report downloading extry""" + self._downloader.to_screen(u'[pornotube] Title: %s' % video_title.decode('utf-8')) + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + if mobj is None: + self._downloader.trouble(u'ERROR: invalid URL: %s' % url) + return + + video_id = mobj.group('videoid').decode('utf-8') + video_title = mobj.group('title').decode('utf-8') + self.report_title(video_title); + + # Get webpage content + try: + webpage = urllib2.urlopen(url).read() + except (urllib2.URLError, httplib.HTTPException, socket.error), err: + self._downloader.trouble(u'ERROR: unable to download video webpage: %s' % err) + return + self.report_webpage(url) + + # Get the video URL + result = re.search(self.VIDEO_URL_RE, webpage) + if result is None: + self._downloader.trouble(u'ERROR: unable to extract video url') + return + video_url = urllib.unquote(result.group('url').decode('utf-8')) + self.report_extract_entry(video_url) + + #Get the uploaded date + result = re.search(self.VIDEO_UPLOADED_RE, webpage) + if result is None: + self._downloader.trouble(u'ERROR: unable to extract video title') + return + upload_date = result.group('date').decode('utf-8') + self.report_date(upload_date); + + + info = {'id': video_id, + 'url': video_url, + 'uploader': None, + 'upload_date': upload_date, + 'title': video_title, + 'ext': 'flv', + 'format': 'flv', + 'thumbnail': None, + 'description': None, + 'player_url': None} + + return [info] + + + +class YouJizzIE(InfoExtractor): + """Information extractor for youjizz.com.""" + + _VALID_URL = r'^(?:https?://)?(?:\w+\.)?youjizz\.com/videos/([^.]+).html$' + IE_NAME = u'youjizz' + VIDEO_TITLE_RE = r'<title>(?P<title>.*)' + EMBED_PAGE_RE = r'http://www.youjizz.com/videos/embed/(?P[0-9]+)' + SOURCE_RE = r'so.addVariable\("file",encodeURIComponent\("(?P[^"]+)"\)\);' + + def __init__(self, downloader=None): + InfoExtractor.__init__(self, downloader) + + def report_extract_entry(self, url): + """Report downloading extry""" + self._downloader.to_screen(u'[youjizz] Downloading entry: %s' % url.decode('utf-8')) + + def report_webpage(self, url): + """Report downloading page""" + self._downloader.to_screen(u'[youjizz] Downloaded page: %s' % url) + + def report_title(self, video_title): + """Report downloading extry""" + self._downloader.to_screen(u'[youjizz] Title: %s' % video_title.decode('utf-8')) + + def report_embed_page(self, embed_page): + """Report downloading extry""" + self._downloader.to_screen(u'[youjizz] Embed Page: %s' % embed_page.decode('utf-8')) + + def _real_extract(self, url): + # Get webpage content + try: + webpage = urllib2.urlopen(url).read() + except (urllib2.URLError, httplib.HTTPException, socket.error), err: + self._downloader.trouble(u'ERROR: unable to download video webpage: %s' % err) + return + self.report_webpage(url) + + # Get the video title + result = re.search(self.VIDEO_TITLE_RE, webpage) + if result is None: + self._downloader.trouble(u'ERROR: unable to extract video title') + return + video_title = result.group('title').decode('utf-8').strip() + self.report_title(video_title) + + # Get the embed page + result = re.search(self.EMBED_PAGE_RE, webpage) + if result is None: + self._downloader.trouble(u'ERROR: unable to extract embed page') + return + + embed_page_url = result.group(0).decode('utf-8').strip() + video_id = result.group('videoid').decode('utf-8') + self.report_embed_page(embed_page_url) + + try: + webpage = urllib2.urlopen(embed_page_url).read() + except (urllib2.URLError, httplib.HTTPException, socket.error), err: + self._downloader.trouble(u'ERROR: unable to download video embed page: %s' % err) + return + + # Get the video URL + result = re.search(self.SOURCE_RE, webpage) + if result is None: + self._downloader.trouble(u'ERROR: unable to extract video url') + return + video_url = result.group('source').decode('utf-8') + self.report_extract_entry(video_url) + + info = {'id': video_id, + 'url': video_url, + 'uploader': None, + 'upload_date': None, + 'title': video_title, + 'ext': 'flv', + 'format': 'flv', + 'thumbnail': None, + 'description': None, + 'player_url': embed_page_url} + + return [info] + + def gen_extractors(): """ Return a list of an instance of every supported extractor. The order does matter; the first extractor matched is the one handling the URL. @@ -3768,6 +4093,9 @@ def gen_extractors(): MTVIE(), YoukuIE(), XNXXIE(), + YouJizzIE(), + PornotubeIE(), + YouPornIE(), GooglePlusIE(), ArteTvIE(), NBAIE(),