def get_downloader_for_item(item): existing = get_existing_downloader(item) if existing: return existing url = item.get_url() existing = get_existing_downloader_by_url(url) if existing: return existing channel_name = unicode_to_filename(item.get_channel_title(True)) if not channel_name: channel_name = None if url.startswith(u'file://'): path = get_file_url_path(url) try: get_torrent_info_hash(path) except ValueError: raise ValueError("Don't know how to handle %s" % url) except (OSError, IOError): return None else: return RemoteDownloader(url, item, u'application/x-bittorrent', channel_name=channel_name) elif is_magnet_uri(url): return RemoteDownloader(url, item, u'application/x-magnet') else: return RemoteDownloader(url, item, channel_name=channel_name)
def calc_torrent_title(self): if self.metainfo is not None: # if we have metainfo, then we should use that return util.get_name_from_torrent_metadata( self.metainfo) elif is_magnet_uri(self.url): # as a fallback, we can try the title from the magnet URI return title_from_magnet(self.url) else: return None
def should_load_url(self, url): """Returns True if the Miro browser should handle the url and False otherwise. Situations which should return false: * if the url is something that Miro should download instead * other things? """ logging.debug("got %s", url) if url in self.seen_cache: del self.seen_cache[url] return True url = util.to_uni(url) if subscription.is_subscribe_link(url): self.emit('download-started') messages.SubscriptionLinkClicked(url).send_to_backend() return False if filetypes.is_maybe_rss_url(url): logging.debug("miro wants to handle %s", url) self.emit('download-started') messages.DownloadURL(url, self.unknown_callback).send_to_backend() return False # parse the path out of the url and run that through the filetypes # code to see if it might be a video, audio or torrent file. # if so, try downloading it. ret = urlparse(url) if filetypes.is_allowed_filename(ret[2]): logging.debug("miro wants to handle %s", url) self.emit('download-started') messages.DownloadURL(url, self.unknown_callback).send_to_backend() return False if util.is_magnet_uri(url): logging.debug("miro wants to handle %s", url) self.emit('download-started') messages.DownloadURL(url, self.unknown_callback).send_to_backend() return False return True
def get_content_type(self): if is_magnet_uri(self.url): self.content_type = u'application/x-magnet' return httpclient.grab_headers(self.url, self.on_content_type, self.on_content_type_error)
def parse_command_line_args(args): """ This goes through a list of files which could be arguments passed in on the command line or a list of files from other source. """ if not _started_up: _command_line_args.extend(args) return for i in xrange(len(args)): if args[i].startswith('file://'): args[i] = args[i][len('file://'):] reset_command_line_view() added_videos = False added_downloads = False for arg in args: if arg.startswith('file://'): arg = download_utils.get_file_url_path(arg) elif arg.startswith('miro:'): add_subscription_url('miro:', 'application/x-miro', arg) elif arg.startswith('democracy:'): add_subscription_url('democracy:', 'application/x-democracy', arg) elif (arg.startswith('http:') or arg.startswith('https:') or arg.startswith('feed:') or arg.startswith('feeds:') or is_magnet_uri(arg)): singleclick.add_download(filename_to_unicode(arg)) elif os.path.exists(arg): ext = os.path.splitext(arg)[1].lower() if ext in ('.torrent', '.tor'): try: torrent_infohash = get_torrent_info_hash(arg) except ValueError: title = _("Invalid Torrent") msg = _( "The torrent file %(filename)s appears to be corrupt " "and cannot be opened.", {"filename": os.path.basename(arg)} ) dialogs.MessageBoxDialog(title, msg).run() continue except (IOError, OSError): title = _("File Error") msg = _( "The torrent file %(filename)s could not be opened. " "Please ensure it exists and you have permission to " "access this file.", {"filename": os.path.basename(arg)} ) dialogs.MessageBoxDialog(title, msg).run() continue add_torrent(arg, torrent_infohash) added_downloads = True elif ext in ('.rss', '.rdf', '.atom', '.ato'): feed.add_feed_from_file(arg) elif ext in ('.miro', '.democracy', '.dem', '.opml'): opml.Importer().import_subscriptions(arg, show_summary=False) else: add_video(arg) added_videos = True else: logging.warning("parse_command_line_args: %s doesn't exist", arg) # if the user has Miro set up to play all videos externally, then # we don't want to play videos added by the command line. # # this fixes bug 12362 where if the user has his/her system set up # to use Miro to play videos and Miro goes to play a video # externally, then it causes an infinite loop and dies. if added_videos and app.config.get(prefs.PLAY_IN_MIRO): item_infos = [itemsource.DatabaseItemSource._item_info_for(i) for i in _command_line_videos] messages.PlayMovie(item_infos).send_to_frontend() if added_downloads: # FIXME - switch to downloads tab? pass
def add_download(url, handle_unknown_callback=None, metadata=None): """Given a url, this tries to figure out what it is (video, audio, torrent, rss feed, flash file that Miro can scrape) and handles it accordingly. If it can't figure out what it is, then it calls ``handle_unknown_callback`` with the url of the thing it can't identify and thus doesn't know what to do with. :param url: The url to download. :param handle_unknown_callback: The function to call if Miro can't figure out what kind of thing is at the url. If this is None, then it uses the default ``download_unknown_mime_type`` handler. :param metadata: dict holding additional metadata like title, description, ... """ if handle_unknown_callback == None: handle_unknown_callback = download_unknown_mime_type if url.startswith('feed:') or url.startswith('feeds:'): # hack so feed(s): acts as http(s): url = "http" + url[4:] if check_url_exists(url): return def errback(error): title = _("Download Error") text = _( "%(appname)s is not able to download a file at this URL:\n" "\n" "URL: %(url)s\n" "\n" "Error: %(error)s (%(errordesc)s)", { "url": url, "appname": app.config.get(prefs.SHORT_APP_NAME), "error": error.getFriendlyDescription(), "errordesc": error.getLongDescription() }) logging.info("can't download '%s'", url) if not isinstance(error, httpclient.PossiblyTemporaryError): dialogs.MessageBoxDialog(title, text).run() else: def callback(dialog): if dialog.choice == dialogs.BUTTON_RETRY: httpclient.grab_headers(url, callback, errback) dialogs.ChoiceDialog(title, text, dialogs.BUTTON_RETRY, dialogs.BUTTON_CANCEL).run(callback) def callback_peek(data): """Takes the data returned from a GET and peeks at it to see if it's a feed despite the fact that it has the wrong content-type. """ if data["body"]: if filetypes.is_maybe_rss(data["body"]): # FIXME - this is silly since we just did a GET and we # do another one in add_feeds logging.info("%s is a feed--adding it." % url) add_feeds([url]) return handle_unknown_callback(url) def callback(headers, content_type=None): """We need to figure out if the URL is a external video link, or a link to a feed. """ print 'callback for', url, headers, content_type if check_url_exists(url): return if content_type is None: content_type = headers.get("content-type") if content_type: if filetypes.is_feed_content_type(content_type): add_feeds([url]) return if flashscraper.is_maybe_flashscrapable(url): entry = _build_entry(url, 'video/x-flv', additional=metadata) download_video(entry) return if amazon.is_amazon_content_type(content_type): amazon.download_file(url, handle_unknown_callback) return if filetypes.is_maybe_feed_content_type(content_type): logging.info( "%s content type is %s. " "going to peek to see if it's a feed....", url, content_type) httpclient.grab_url(url, callback_peek, errback) return entry = _build_entry(url, content_type) if filetypes.is_video_enclosure(entry['enclosures'][0]): download_video(entry) else: handle_unknown_callback(url) if metadata and metadata.get('mime_type'): # we've already got the mime type, don't do another call callback(None, metadata['mime_type']) elif is_magnet_uri(url): callback(None, 'application/x-magnet') elif amazon.is_amazon_url(url): amazon.download_file(url, handle_unknown_callback) elif emusic.is_emusic_url(url): emusic.download_file(url, handle_unknown_callback) else: httpclient.grab_headers(url, callback, errback)
def parse_command_line_args(args): """ This goes through a list of files which could be arguments passed in on the command line or a list of files from other source. """ if not _started_up: _command_line_args.extend(args) return for i in xrange(len(args)): if args[i].startswith('file://'): args[i] = args[i][len('file://'):] reset_command_line_view() added_videos = False added_downloads = False for arg in args: if arg.startswith('file://'): arg = download_utils.get_file_url_path(arg) elif arg.startswith('miro:'): add_subscription_url('miro:', 'application/x-miro', arg) elif arg.startswith('democracy:'): add_subscription_url('democracy:', 'application/x-democracy', arg) elif (arg.startswith('http:') or arg.startswith('https:') or arg.startswith('feed:') or arg.startswith('feeds:') or is_magnet_uri(arg)): singleclick.add_download(filename_to_unicode(arg)) elif os.path.exists(arg): ext = os.path.splitext(arg)[1].lower() if ext in ('.torrent', '.tor'): try: torrent_infohash = get_torrent_info_hash(arg) except ValueError: title = _("Invalid Torrent") msg = _( "The torrent file %(filename)s appears to be corrupt " "and cannot be opened.", {"filename": os.path.basename(arg)}) dialogs.MessageBoxDialog(title, msg).run() continue except (IOError, OSError): title = _("File Error") msg = _( "The torrent file %(filename)s could not be opened. " "Please ensure it exists and you have permission to " "access this file.", {"filename": os.path.basename(arg)}) dialogs.MessageBoxDialog(title, msg).run() continue add_torrent(arg, torrent_infohash) added_downloads = True elif ext in ('.rss', '.rdf', '.atom', '.ato'): feed.add_feed_from_file(arg) elif ext in ('.miro', '.democracy', '.dem', '.opml'): opml.Importer().import_subscriptions(arg, show_summary=False) else: add_video(arg) added_videos = True else: logging.warning("parse_command_line_args: %s doesn't exist", arg) # if the user has Miro set up to play all videos externally, then # we don't want to play videos added by the command line. # # this fixes bug 12362 where if the user has his/her system set up # to use Miro to play videos and Miro goes to play a video # externally, then it causes an infinite loop and dies. if added_videos and app.config.get(prefs.PLAY_IN_MIRO): item_ids = [i.id for i in _command_line_videos] item_infos = app.db.fetch_item_infos(item_ids) messages.PlayMovies(item_infos).send_to_frontend() if added_downloads: # FIXME - switch to downloads tab? pass
def add_download(url, handle_unknown_callback=None, metadata=None): """Given a url, this tries to figure out what it is (video, audio, torrent, rss feed, flash file that Miro can scrape) and handles it accordingly. If it can't figure out what it is, then it calls ``handle_unknown_callback`` with the url of the thing it can't identify and thus doesn't know what to do with. :param url: The url to download. :param handle_unknown_callback: The function to call if Miro can't figure out what kind of thing is at the url. If this is None, then it uses the default ``download_unknown_mime_type`` handler. :param metadata: dict holding additional metadata like title, description, ... """ if handle_unknown_callback == None: handle_unknown_callback = download_unknown_mime_type if url.startswith('feed:') or url.startswith('feeds:'): # hack so feed(s): acts as http(s): url = "http" + url[4:] if check_url_exists(url): return def errback(error): title = _("Download Error") text = _( "%(appname)s is not able to download a file at this URL:\n" "\n" "URL: %(url)s\n" "\n" "Error: %(error)s (%(errordesc)s)", {"url": url, "appname": app.config.get(prefs.SHORT_APP_NAME), "error": error.getFriendlyDescription(), "errordesc": error.getLongDescription()} ) logging.info("can't download '%s'", url) if not isinstance(error, httpclient.PossiblyTemporaryError): dialogs.MessageBoxDialog(title, text).run() else: def callback(dialog): if dialog.choice == dialogs.BUTTON_RETRY: httpclient.grab_headers(url, callback, errback) dialogs.ChoiceDialog(title, text, dialogs.BUTTON_RETRY, dialogs.BUTTON_CANCEL).run(callback) def callback_peek(data): """Takes the data returned from a GET and peeks at it to see if it's a feed despite the fact that it has the wrong content-type. """ if data["body"]: if filetypes.is_maybe_rss(data["body"]): # FIXME - this is silly since we just did a GET and we # do another one in add_feeds logging.info("%s is a feed--adding it." % url) add_feeds([url]) return handle_unknown_callback(url) def callback(headers, content_type=None): """We need to figure out if the URL is a external video link, or a link to a feed. """ print 'callback for', url, headers, content_type if check_url_exists(url): return if content_type is None: content_type = headers.get("content-type") if content_type: if filetypes.is_feed_content_type(content_type): add_feeds([url]) return if flashscraper.is_maybe_flashscrapable(url): entry = _build_entry(url, 'video/x-flv', additional=metadata) download_video(entry) return if amazon.is_amazon_content_type(content_type): amazon.download_file(url, handle_unknown_callback) return if filetypes.is_maybe_feed_content_type(content_type): logging.info("%s content type is %s. " "going to peek to see if it's a feed....", url, content_type) httpclient.grab_url(url, callback_peek, errback) return entry = _build_entry(url, content_type) if filetypes.is_video_enclosure(entry['enclosures'][0]): download_video(entry) else: handle_unknown_callback(url) if metadata and metadata.get('mime_type'): # we've already got the mime type, don't do another call callback(None, metadata['mime_type']) elif is_magnet_uri(url): callback(None, 'application/x-magnet') elif amazon.is_amazon_url(url): amazon.download_file(url, handle_unknown_callback) elif emusic.is_emusic_url(url): emusic.download_file(url, handle_unknown_callback) else: httpclient.grab_headers(url, callback, errback)