]> gitweb @ CieloNegro.org - youtube-dl.git/blobdiff - youtube-dl
Add self-updating code
[youtube-dl.git] / youtube-dl
index 5afff4e61879526235ff5f262ce4be188c122725..d3e8cf4f642b212ebcd01817596aff5a9f905f5a 100755 (executable)
@@ -33,15 +33,15 @@ def preferredencoding():
        Returns the best encoding scheme for the system, based on
        locale.getpreferredencoding() and some further tweaks.
        """
        Returns the best encoding scheme for the system, based on
        locale.getpreferredencoding() and some further tweaks.
        """
-       try:
-               pref = locale.getpreferredencoding()
-               # Mac OSX systems have this problem sometimes
-               if pref == '':
-                       return 'UTF-8'
-               return pref
-       except:
-               sys.stderr.write('WARNING: problem obtaining preferred encoding. Falling back to UTF-8.\n')
-               return 'UTF-8'
+       def yield_preferredencoding():
+               try:
+                       pref = locale.getpreferredencoding()
+                       u'TEST'.encode(pref)
+               except:
+                       pref = 'UTF-8'
+               while True:
+                       yield pref
+       return yield_preferredencoding().next()
 
 class DownloadError(Exception):
        """Download Error exception.
 
 class DownloadError(Exception):
        """Download Error exception.
@@ -309,7 +309,7 @@ class FileDownloader(object):
                # Do nothing else if in simulate mode
                if self.params.get('simulate', False):
                        try:
                # Do nothing else if in simulate mode
                if self.params.get('simulate', False):
                        try:
-                               info_dict['url'] = self.verify_url(info_dict['url'])
+                               info_dict['url'] = self.verify_url(info_dict['url'].encode('utf-8')).decode('utf-8')
                        except (OSError, IOError, urllib2.URLError, httplib.HTTPException, socket.error), err:
                                raise UnavailableFormatError
 
                        except (OSError, IOError, urllib2.URLError, httplib.HTTPException, socket.error), err:
                                raise UnavailableFormatError
 
@@ -327,7 +327,7 @@ class FileDownloader(object):
                        filename = self.params['outtmpl'] % template_dict
                except (ValueError, KeyError), err:
                        self.trouble('ERROR: invalid output template or system charset: %s' % str(err))
                        filename = self.params['outtmpl'] % template_dict
                except (ValueError, KeyError), err:
                        self.trouble('ERROR: invalid output template or system charset: %s' % str(err))
-               if self.params['nooverwrites'] and os.path.exists(filename):
+               if self.params.get('nooverwrites', False) and os.path.exists(filename):
                        self.to_stderr(u'WARNING: file exists: %s; skipping' % filename)
                        return
 
                        self.to_stderr(u'WARNING: file exists: %s; skipping' % filename)
                        return
 
@@ -338,7 +338,7 @@ class FileDownloader(object):
                        return
 
                try:
                        return
 
                try:
-                       success = self._do_download(filename, info_dict['url'])
+                       success = self._do_download(filename, info_dict['url'].encode('utf-8'))
                except (OSError, IOError), err:
                        raise UnavailableFormatError
                except (urllib2.URLError, httplib.HTTPException, socket.error), err:
                except (OSError, IOError), err:
                        raise UnavailableFormatError
                except (urllib2.URLError, httplib.HTTPException, socket.error), err:
@@ -402,7 +402,7 @@ class FileDownloader(object):
                        resume_len = os.path.getsize(filename)
                else:
                        resume_len = 0
                        resume_len = os.path.getsize(filename)
                else:
                        resume_len = 0
-               if self.params['continuedl'] and resume_len != 0:
+               if self.params.get('continuedl', False) and resume_len != 0:
                        self.report_resuming_byte(resume_len)
                        request.add_header('Range','bytes=%d-' % resume_len)
 
                        self.report_resuming_byte(resume_len)
                        request.add_header('Range','bytes=%d-' % resume_len)
 
@@ -719,11 +719,11 @@ class YoutubeIE(InfoExtractor):
                        video_uploader = urllib.unquote(mobj.group(1))
 
                        # title
                        video_uploader = urllib.unquote(mobj.group(1))
 
                        # title
-                       mobj = re.search(r'(?m)&title=([^&]+)(?:&|$)', video_info_webpage)
+                       mobj = re.search(r'(?m)&title=([^&]*)(?:&|$)', video_info_webpage)
                        if mobj is None:
                                self._downloader.trouble(u'ERROR: unable to extract video title')
                                return
                        if mobj is None:
                                self._downloader.trouble(u'ERROR: unable to extract video title')
                                return
-                       video_title = urllib.unquote(mobj.group(1))
+                       video_title = urllib.unquote_plus(mobj.group(1))
                        video_title = video_title.decode('utf-8')
                        video_title = re.sub(ur'(?u)&(.+?);', self.htmlentity_transform, video_title)
                        video_title = video_title.replace(os.sep, u'%')
                        video_title = video_title.decode('utf-8')
                        video_title = re.sub(ur'(?u)&(.+?);', self.htmlentity_transform, video_title)
                        video_title = video_title.replace(os.sep, u'%')
@@ -1089,6 +1089,22 @@ if __name__ == '__main__':
                import getpass
                import optparse
 
                import getpass
                import optparse
 
+               # 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)
+
+                       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('Updated to version %s' % latest_version)
+
                # General configuration
                urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()))
                urllib2.install_opener(urllib2.build_opener(urllib2.HTTPCookieProcessor()))
                # General configuration
                urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()))
                urllib2.install_opener(urllib2.build_opener(urllib2.HTTPCookieProcessor()))
@@ -1097,7 +1113,7 @@ if __name__ == '__main__':
                # Parse command line
                parser = optparse.OptionParser(
                        usage='Usage: %prog [options] url...',
                # Parse command line
                parser = optparse.OptionParser(
                        usage='Usage: %prog [options] url...',
-                       version='2009.09.13',
+                       version='INTERNAL',
                        conflict_handler='resolve',
                )
 
                        conflict_handler='resolve',
                )
 
@@ -1105,6 +1121,8 @@ if __name__ == '__main__':
                                action='help', help='print this help text and exit')
                parser.add_option('-v', '--version',
                                action='version', help='print program version and exit')
                                action='help', help='print this help text and exit')
                parser.add_option('-v', '--version',
                                action='version', help='print program version and exit')
+               parser.add_option('-U', '--update',
+                               action='store_true', dest='update_self', help='update this program to latest stable version')
                parser.add_option('-i', '--ignore-errors',
                                action='store_true', dest='ignoreerrors', help='continue on download errors', default=False)
                parser.add_option('-r', '--rate-limit',
                parser.add_option('-i', '--ignore-errors',
                                action='store_true', dest='ignoreerrors', help='continue on download errors', default=False)
                parser.add_option('-r', '--rate-limit',
@@ -1157,7 +1175,7 @@ if __name__ == '__main__':
                parser.add_option_group(filesystem)
 
                (opts, args) = parser.parse_args()
                parser.add_option_group(filesystem)
 
                (opts, args) = parser.parse_args()
-
+        
                # Batch file verification
                batchurls = []
                if opts.batchfile is not None:
                # Batch file verification
                batchurls = []
                if opts.batchfile is not None:
@@ -1170,8 +1188,6 @@ if __name__ == '__main__':
                all_urls = batchurls + args
 
                # Conflicting, missing and erroneous options
                all_urls = batchurls + args
 
                # Conflicting, missing and erroneous options
-               if len(all_urls) < 1:
-                       parser.error(u'you must provide at least one URL')
                if opts.usenetrc and (opts.username is not None or opts.password is not None):
                        parser.error(u'using .netrc conflicts with giving username/password')
                if opts.password is not None and opts.username is None:
                if opts.usenetrc and (opts.username is not None or opts.password is not None):
                        parser.error(u'using .netrc conflicts with giving username/password')
                if opts.password is not None and opts.username is None:
@@ -1217,6 +1233,17 @@ if __name__ == '__main__':
                fd.add_info_extractor(youtube_pl_ie)
                fd.add_info_extractor(metacafe_ie)
                fd.add_info_extractor(youtube_ie)
                fd.add_info_extractor(youtube_pl_ie)
                fd.add_info_extractor(metacafe_ie)
                fd.add_info_extractor(youtube_ie)
+
+               # Update version
+               if opts.update_self:
+                       update_self(fd, sys.argv[0])
+
+               # Maybe do nothing
+               if len(all_urls) < 1:
+                       if not opts.update_self:
+                               parser.error(u'you must provide at least one URL')
+                       else:
+                               sys.exit()
                retcode = fd.download(all_urls)
                sys.exit(retcode)
 
                retcode = fd.download(all_urls)
                sys.exit(retcode)