Anonymous avatar Anonymous committed 30e4f4b

2010.07.14

Comments (0)

Files changed (2)

-2010.06.06
+2010.07.14
 	from cgi import parse_qs
 
 std_headers = {
-	'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6',
+	'User-Agent': 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100627 Firefox/3.6.6',
 	'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
-	'Accept': 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
+	'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
 	'Accept-Language': 'en-us,en;q=0.5',
 }
 
 	forcetitle:	Force printing title.
 	simulate:	Do not download the video files.
 	format:		Video format code.
+	format_limit:	Highest quality format to try.
 	outtmpl:	Template for output names.
 	ignoreerrors:	Do not stop on download errors.
 	ratelimit:	Download speed limit, in bytes/sec.
 			self.to_stdout(u'[download] Download completed')
 		else:
 			self.to_stdout(u'')
+	
+	def increment_downloads(self):
+		"""Increment the ordinal that assigns a number to each file."""
+		self._num_downloads += 1
 
 	def process_info(self, info_dict):
 		"""Process a single dictionary returned by an InfoExtractor."""
 				if content_length is not None and long(content_length) == resume_len:
 					# Because the file had already been fully downloaded
 					self.report_file_already_downloaded(filename)
-					self._num_downloads += 1
 					return True
 				else:
 					# Because the server didn't let us
 				try:
 					(stream, filename) = sanitize_open(filename, open_mode)
 					self.report_destination(filename)
-					self._num_downloads += 1
 				except (OSError, IOError), err:
 					self.trouble('ERROR: unable to open for writing: %s' % str(err))
 					return False
 class YoutubeIE(InfoExtractor):
 	"""Information extractor for youtube.com."""
 
-	_VALID_URL = r'^((?:http://)?(?:\w+\.)?youtube\.com/(?:(?:v/)|(?:(?:watch(?:\.php)?)?[\?#](?:.+&)?v=)))?([0-9A-Za-z_-]+)(?(1).+)?$'
+	_VALID_URL = r'^((?:http://)?(?:youtu\.be/|(?:\w+\.)?youtube\.com/(?:(?:v/)|(?:(?:watch(?:_popup)?(?:\.php)?)?[\?#](?:.+&)?v=))))?([0-9A-Za-z_-]+)(?(1).+)?$'
 	_LANG_URL = r'http://uk.youtube.com/?hl=en&persist_hl=1&gl=US&persist_gl=1&opt_out_ackd=1'
 	_LOGIN_URL = 'http://www.youtube.com/signup?next=/&gl=US&hl=en'
 	_AGE_URL = 'http://www.youtube.com/verify_age?next_url=/&gl=US&hl=en'
 	_NETRC_MACHINE = 'youtube'
 	# Listed in order of priority for the -b option
-	_available_formats = ['37', '22', '45', '35', '34', '43', '18', '6', '5', '17', '13', None]
+	_available_formats = ['38', '37', '22', '45', '35', '34', '43', '18', '6', '5', '17', '13', None]
 	_video_extensions = {
 		'13': '3gp',
 		'17': 'mp4',
 		'18': 'mp4',
 		'22': 'mp4',
 		'37': 'mp4',
+		'38': 'video', # You actually don't know if this will be MOV, AVI or whatever
 		'43': 'webm',
 		'45': 'webm',
 	}
 		if mobj is None:
 			self._downloader.trouble(u'ERROR: invalid URL: %s' % url)
 			return
+
+		# At this point we have a new video
+		if self._downloader is not None:
+			self._downloader.increment_downloads()
 		video_id = mobj.group(2)
 
 		# Downloader parameters
 			params = self._downloader.params
 			format_param = params.get('format', None)
 			if format_param == '0':
+				format_limit = params.get('format_limit', None)
+				if format_limit is not None:
+					try:
+						# Start at a different format if the user has limited the maximum quality
+						quality_index = self._available_formats.index(format_limit)
+					except ValueError:
+						pass
 				format_param = self._available_formats[quality_index]
 				best_quality = True
 			elif format_param == '-1':
 				return
 
 			# Attempt to extract SWF player URL
-			mobj = re.search(r'swfConfig.*"(http://.*?watch-.*?\.swf)"', video_webpage)
+			mobj = re.search(r'swfConfig.*"(http://.*?watch.*?-.*?\.swf)"', video_webpage)
 			if mobj is not None:
 				player_url = mobj.group(1)
 			else:
 			self._youtube_ie.extract('http://www.youtube.com/watch?v=%s' % mobj2.group(1))
 			return
 
+		# At this point we have a new video
+		if self._downloader is not None:
+			self._downloader.increment_downloads()
+
 		simple_title = mobj.group(2).decode('utf-8')
 		video_extension = 'flv'
 
 			self._downloader.trouble(u'ERROR: invalid URL: %s' % url)
 			return
 
+		# At this point we have a new video
+		if self._downloader is not None:
+			self._downloader.increment_downloads()
 		video_id = mobj.group(1)
 
 		simple_title = mobj.group(2).decode('utf-8')
 			self._downloader.trouble(u'ERROR: Invalid URL: %s' % url)
 			return
 
+		# At this point we have a new video
+		if self._downloader is not None:
+			self._downloader.increment_downloads()
 		video_id = mobj.group(1)
 
 		video_extension = 'mp4'
 			self._downloader.trouble(u'ERROR: Invalid URL: %s' % url)
 			return
 
+		# At this point we have a new video
+		if self._downloader is not None:
+			self._downloader.increment_downloads()
 		video_id = mobj.group(1)
 
 		video_extension = 'flv'
 	def _real_initialize(self):
 		return
 
-	def _real_extract(self, url):
+	def _real_extract(self, url, new_video=True):
 		# Extract ID from URL
 		mobj = re.match(self._VALID_URL, url)
 		if mobj is None:
 			self._downloader.trouble(u'ERROR: Invalid URL: %s' % url)
 			return
 
+		# At this point we have a new video
+		if self._downloader is not None and new_video:
+			self._downloader.increment_downloads()
 		video_id = mobj.group(2)
 		video_extension = 'flv'
 
 			yahoo_vid = mobj.group(1)
 
 			url = 'http://video.yahoo.com/watch/%s/%s' % (yahoo_vid, yahoo_id)
-			return self._real_extract(url)
+			return self._real_extract(url, new_video=False)
 
 		# Retrieve video webpage to extract further information
 		request = urllib2.Request(url)
 		return
 
 	def _real_extract(self, url):
+		# At this point we have a new video
+		if self._downloader is not None:
+			self._downloader.increment_downloads()
+
 		video_id = url.split('/')[-1]
 		request = urllib2.Request(url)
 		try:
 		# Function to update the program file with the latest version from bitbucket.org
 		def update_self(downloader, filename):
 			# Note: downloader only used for options
-			#if not os.access (filename, os.W_OK):
-			#	sys.exit('ERROR: no write permissions on %s' % filename)
+			if not os.access (filename, os.W_OK):
+				sys.exit('ERROR: no write permissions on %s' % filename)
 
-			downloader.to_stdout('Checking for latest stable version...')
-			version_current = '2010.06.06'
+			downloader.to_stdout('Updating to latest stable version...')
 			latest_url = 'http://bitbucket.org/rg3/youtube-dl/raw/tip/LATEST_VERSION'
 			latest_version = urllib.urlopen(latest_url).read().strip()
-			#prog_url = 'http://bitbucket.org/rg3/youtube-dl/raw/%s/youtube-dl' % latest_version
-			#newcontent = urllib.urlopen(prog_url).read()
-			#stream = open(filename, 'w')
-			#stream.write(newcontent)
-			#stream.close()
-			downloader.to_stdout('Latest available version is %s' % latest_version)
-			downloader.to_stdout('Installed version is %s' % version_current)
-			if latest_version == version_current:
-				downloader.to_stdout('Installed version is latest, no need to update')
-			else:
-				downloader.to_stdout('Please visit "http://go.himili.com/youtube-dl" to download latest version')
+			prog_url = 'http://bitbucket.org/rg3/youtube-dl/raw/%s/youtube-dl' % latest_version
+			newcontent = urllib.urlopen(prog_url).read()
+			stream = open(filename, 'w')
+			stream.write(newcontent)
+			stream.close()
+			downloader.to_stdout('Updated to version %s' % latest_version)
 
 		# General configuration
 		urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()))
 		# Parse command line
 		parser = optparse.OptionParser(
 			usage='Usage: %prog [options] url...',
-			version='2010.06.06',
+			version='2010.07.14',
 			conflict_handler='resolve',
 		)
 
 				action='store_const', dest='format', help='alias for -f 22', const='22')
 		video_format.add_option('--all-formats',
 				action='store_const', dest='format', help='download all available video formats', const='-1')
+		video_format.add_option('--max-quality',
+				action='store', dest='format_limit', metavar='FORMAT', help='highest quality format limit for -b')
 		parser.add_option_group(video_format)
 
 		verbosity = optparse.OptionGroup(parser, 'Verbosity / Simulation Options')
 			'forcedescription': opts.getdescription,
 			'simulate': (opts.simulate or opts.geturl or opts.gettitle or opts.getthumbnail or opts.getdescription),
 			'format': opts.format,
+			'format_limit': opts.format_limit,
 			'outtmpl': ((opts.outtmpl is not None and opts.outtmpl.decode(preferredencoding()))
 				or (opts.format == '-1' and opts.usetitle and u'%(stitle)s-%(id)s-%(format)s.%(ext)s')
 				or (opts.format == '-1' and opts.useliteral and u'%(title)s-%(id)s-%(format)s.%(ext)s')
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.