Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
 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
Пример #4
0
    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
Пример #5
0
    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
Пример #6
0
 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)
Пример #7
0
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
Пример #8
0
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)
Пример #9
0
 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)
Пример #10
0
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
Пример #11
0
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)