Ejemplo n.º 1
0
def check_movies_gone():
    """Checks to see if the movies directory is gone.
    """

    # callback is what the frontend will call if the user asks us to continue
    callback = lambda: eventloop.add_urgent_call(fix_movies_gone, "fix movies gone")

    movies_dir = fileutil.expand_filename(app.config.get(prefs.MOVIES_DIRECTORY))

    # if the directory doesn't exist, create it.
    if not os.path.exists(movies_dir) and should_create_movies_directory(movies_dir):
        try:
            fileutil.makedirs(movies_dir)
        except OSError:
            logging.info("Movies directory can't be created -- calling handler")
            # FIXME - this isn't technically correct, but it's probably
            # close enough that a user can fix the issue and Miro can
            # run happily.
            _movies_directory_gone_handler(callback)
            return

    # make sure the directory is writeable
    if not os.access(movies_dir, os.W_OK):
        _movies_directory_gone_handler(callback)
        return

    # make sure that the directory is populated if we've downloaded stuff to
    # it
    if is_movies_directory_gone():
        logging.info("Movies directory is gone -- calling handler.")
        _movies_directory_gone_handler(callback)
        return

    eventloop.add_urgent_call(finish_backend_startup, "reconnect downloaders")
Ejemplo n.º 2
0
 def move_to_directory(self, directory):
     check_f(directory)
     if self.channelName:
         channel_name = filter_directory_name(self.channelName)
         # bug 10769: shutil and windows has problems with long
         # filenames, so we clip the directory name.
         if len(channel_name) > 80:
             channel_name = channel_name[:80]
         directory = os.path.join(directory, channel_name)
         if not os.path.exists(directory):
             try:
                 fileutil.makedirs(directory)
             except (SystemExit, KeyboardInterrupt):
                 raise
             except:
                 pass
     newfilename = os.path.join(directory, self.shortFilename)
     if newfilename == self.filename:
         return
     newfilename, fp = next_free_filename(newfilename)
     def callback():
         self.filename = newfilename
         self.update_client()
     fileutil.migrate_file(self.filename, newfilename, callback)
     fp.close()
Ejemplo n.º 3
0
 def image_directory(cls, subdir):
     dir_ = os.path.join(app.config.get(prefs.ICON_CACHE_DIRECTORY), subdir)
     try:
         fileutil.makedirs(dir_)
     except OSError:
         pass
     return dir_
Ejemplo n.º 4
0
def save_crash_report(report):
    """Save a crash report to the support directory.

    :returns: filename we saved to, or None if the save failed
    """
    try:
        crash_dir = app.config.get(prefs.CRASH_PATHNAME)

        if not os.path.exists(crash_dir):
            fileutil.makedirs(crash_dir)

        # we use a timestamp so that crash reports are easy to identify
        # for users.
        # we add a random bit at the end to reduce the likelihood that
        # if Miro is being crash-tastic that one report will stomp on
        # another one.  we don't kill ourselves for file-name uniqueness
        # though since we're in the middle of a crash and it's better
        # to be simple about it.
        timestamp = time.strftime("%Y-%m-%d-%H%M%S", time.localtime())
        fn = os.path.join(
            crash_dir,
            "crashreport-%s-%s.txt" % (timestamp, random.randint(0, 10000)))

        logging.info("saving crash report file to: %s", fn)

        f = open(fn, "w")
        f.write(report)
        f.close()
    except (OSError, IOError):
        logging.exception("exception while saving crash report")
        return None
    return fn
Ejemplo n.º 5
0
 def image_directory(cls, subdir):
     dir_ = os.path.join(app.config.get(prefs.ICON_CACHE_DIRECTORY), subdir)
     try:
         fileutil.makedirs(dir_)
     except OSError:
         pass
     return dir_
Ejemplo n.º 6
0
    def pick_initial_filename(self, suffix=".part", torrent=False):
        """Pick a path to download to based on self.shortFilename.

        This method sets self.filename, as well as creates any leading
        paths needed to start downloading there.

        If the torrent flag is true, then the filename we're working
        with is utf-8 and shouldn't be transformed in any way.

        If the torrent flag is false, then the filename we're working
        with is ascii and needs to be transformed into something sane.
        (default)
        """
        download_dir = os.path.join(app.config.get(prefs.MOVIES_DIRECTORY),
                                    'Incomplete Downloads')
        # Create the download directory if it doesn't already exist.
        if not os.path.exists(download_dir):
            fileutil.makedirs(download_dir)
        filename = self.shortFilename + suffix
        if not torrent:
            # this is an ascii filename and needs to be fixed
            filename = clean_filename(filename)
        self.filename, fp = next_free_filename(
                                os.path.join(download_dir, filename))
        # We can close this object now the file's been created, I guess.
        # This will linger in the filesystem namespace, caller is responsible
        # for cleaning this up (which I think it does).
        fp.close()
Ejemplo n.º 7
0
def save_crash_report(report):
    """Save a crash report to the support directory.

    :returns: filename we saved to, or None if the save failed
    """
    try:
        crash_dir = app.config.get(prefs.CRASH_PATHNAME)

        if not os.path.exists(crash_dir):
            fileutil.makedirs(crash_dir)

        # we use a timestamp so that crash reports are easy to identify
        # for users.
        # we add a random bit at the end to reduce the likelihood that
        # if Miro is being crash-tastic that one report will stomp on
        # another one.  we don't kill ourselves for file-name uniqueness
        # though since we're in the middle of a crash and it's better
        # to be simple about it.
        timestamp = time.strftime("%Y-%m-%d-%H%M%S", time.localtime())
        fn = os.path.join(
            crash_dir,
            "crashreport-%s-%s.txt" % (timestamp, random.randint(0, 10000)))

        logging.info("saving crash report file to: %s", fn)

        f = open(fn, "w")
        f.write(report)
        f.close()
    except (OSError, IOError):
        logging.exception("exception while saving crash report")
        return None
    return fn
Ejemplo n.º 8
0
    def migrate(self, directory):
        if app.download_state_manager.get_download(self.dlid):
            c = command.MigrateDownloadCommand(RemoteDownloader.dldaemon,
                                               self.dlid, directory)
            c.send()
        else:
            # downloader doesn't have our dlid.  Move the file ourself.
            short_filename = self.status.get("shortFilename")
            if not short_filename:
                logging.warning(
                    "can't migrate download; no shortfilename!  URL was %s",
                    self.url)
                return
            filename = self.status.get("filename")
            if not filename:
                logging.warning(
                    "can't migrate download; no filename!  URL was %s",
                    self.url)
                return
            if fileutil.exists(filename):
                if self.status.get('channelName', None) is not None:
                    channelName = filter_directory_name(
                        self.status['channelName'])
                    directory = os.path.join(directory, channelName)
                if not os.path.exists(directory):
                    try:
                        fileutil.makedirs(directory)
                    except OSError:
                        # FIXME - what about permission issues?
                        pass
                newfilename = os.path.join(directory, short_filename)
                if newfilename == filename:
                    return
                # create a file or directory to serve as a placeholder before
                # we start to migrate.  This helps ensure that the destination
                # we're migrating too is not already taken.
                try:
                    is_dir = fileutil.isdir(filename)
                    if is_dir:
                        newfilename = next_free_directory(newfilename)
                        fp = None
                    else:
                        newfilename, fp = next_free_filename(newfilename)
                        fp.close()
                except ValueError:
                    func = ('next_free_directory'
                            if is_dir else 'next_free_filename')
                    logging.warn('migrate: %s failed.  candidate = %r', func,
                                 newfilename)
                else:

                    def callback():
                        self.status['filename'] = newfilename
                        self.signal_change(needs_signal_item=False)
                        self._file_migrated(filename)

                    fileutil.migrate_file(filename, newfilename, callback)
        for i in self.item_list:
            i.migrate_children(directory)
Ejemplo n.º 9
0
def image_directory(subdir):
    dir_ = os.path.join(app.config.get(prefs.ICON_CACHE_DIRECTORY), subdir)
    try:
        fileutil.makedirs(dir_)
    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        pass
    return dir_
Ejemplo n.º 10
0
 def migrate(self, directory):
     if app.download_state_manager.get_download(self.dlid):
         c = command.MigrateDownloadCommand(RemoteDownloader.dldaemon,
                                            self.dlid, directory)
         c.send()
     else:
         # downloader doesn't have our dlid.  Move the file ourself.
         short_filename = self.short_filename
         if not short_filename:
             logging.warning(
                 "can't migrate download; no shortfilename!  URL was %s",
                 self.url)
             return
         filename = self.filename
         if not filename:
             logging.warning(
                 "can't migrate download; no filename!  URL was %s",
                 self.url)
             return
         if fileutil.exists(filename):
             if self.channel_name is not None:
                 channel_name = filter_directory_name(self.channel_name)
                 directory = os.path.join(directory, channel_name)
             if not os.path.exists(directory):
                 try:
                     fileutil.makedirs(directory)
                 except OSError:
                     # FIXME - what about permission issues?
                     pass
             newfilename = os.path.join(directory, short_filename)
             if newfilename == filename:
                 return
             # create a file or directory to serve as a placeholder before
             # we start to migrate.  This helps ensure that the destination
             # we're migrating too is not already taken.
             try:
                 is_dir = fileutil.isdir(filename)
                 if is_dir:
                     newfilename = next_free_directory(newfilename)
                     fp = None
                 else:
                     newfilename, fp = next_free_filename(newfilename)
                     fp.close()
             except ValueError:
                 func = ('next_free_directory' if is_dir
                         else 'next_free_filename')
                 logging.warn('migrate: %s failed.  candidate = %r',
                              func, newfilename)
             else:
                 def callback():
                     self.filename = newfilename
                     self.signal_change(needs_signal_item=False)
                     self._file_migrated(filename)
                 fileutil.migrate_file(filename, newfilename, callback)
     for i in self.item_list:
         i.migrate_children(directory)
Ejemplo n.º 11
0
 def _get_destination_path(extension, track_path):
     filename = "{0}.{1}.{2}".format(os.path.basename(track_path),
                util.random_string(5), extension)
     directory = app.config.get(prefs.COVER_ART_DIRECTORY)
     # make the directory if necessary:
     try:
         fileutil.makedirs(directory)
     except StandardError:
         pass
     return os.path.join(directory, filename)
Ejemplo n.º 12
0
def thumbnail_directory():
    dir_ = os.path.join(app.config.get(prefs.ICON_CACHE_DIRECTORY),
                        "extracted")
    try:
        fileutil.makedirs(dir_)
    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        pass
    return dir_
Ejemplo n.º 13
0
 def _get_destination_path(extension, track_path):
     filename = "{0}.{1}.{2}".format(os.path.basename(track_path),
                                     util.random_string(5), extension)
     directory = app.config.get(prefs.COVER_ART_DIRECTORY)
     # make the directory if necessary:
     try:
         fileutil.makedirs(directory)
     except StandardError:
         pass
     return os.path.join(directory, filename)
Ejemplo n.º 14
0
def _get_support_directory():
    if u3info.u3_active:
        path = u3info.APP_DATA_PREFIX
    else:
        # We don't get the publisher and long app name from the config so
        # changing the app name doesn't change the support directory
        path = os.path.join(specialfolders.app_data_directory, u"Participatory Culture Foundation", u"Miro", u"Support")

    try:
        fileutil.makedirs(path)
    except:
        pass
    return path
Ejemplo n.º 15
0
 def migrate(self, directory):
     if _downloads.has_key(self.dlid):
         c = command.MigrateDownloadCommand(RemoteDownloader.dldaemon,
                                            self.dlid, directory)
         c.send()
     else:
         # downloader doesn't have our dlid.  Move the file ourself.
         short_filename = self.status.get("shortFilename")
         if not short_filename:
             logging.warning(
                 "can't migrate download; no shortfilename!  URL was %s",
                 self.url)
             return
         filename = self.status.get("filename")
         if not filename:
             logging.warning(
                 "can't migrate download; no filename!  URL was %s",
                 self.url)
             return
         if fileutil.exists(filename):
             if self.status.get('channelName', None) is not None:
                 channelName = filter_directory_name(self.status['channelName'])
                 directory = os.path.join(directory, channelName)
             if not os.path.exists(directory):
                 try:
                     fileutil.makedirs(directory)
                 except OSError:
                     # FIXME - what about permission issues?
                     pass
             newfilename = os.path.join(directory, short_filename)
             if newfilename == filename:
                 return
             # create a file or directory to serve as a placeholder before
             # we start to migrate.  This helps ensure that the destination
             # we're migrating too is not already taken.
             if fileutil.isdir(filename):
                 newfilename = next_free_directory(newfilename)
                 fp = None
             else:
                 newfilename, fp = next_free_filename(newfilename)
             def callback():
                 self.status['filename'] = newfilename
                 self.signal_change(needs_signal_item=False)
                 self._file_migrated(filename)
             fileutil.migrate_file(filename, newfilename, callback)
             if fp is not None:
                 fp.close() # clean up if we called next_free_filename()
     for i in self.item_list:
         i.migrate_children(directory)
Ejemplo n.º 16
0
def _get_support_directory():
    if u3info.u3_active:
        path = u3info.APP_DATA_PREFIX
    else:
        # We don't get the publisher and long app name from the config so
        # changing the app name doesn't change the support directory
        path = os.path.join(specialfolders.app_data_directory,
                            u'Participatory Culture Foundation', u'Miro',
                            u'Support')

    try:
        fileutil.makedirs(path)
    except:
        pass
    return path
Ejemplo n.º 17
0
    def get_backup_directory(self):
        """This returns the backup directory path.

        It has the side effect of creating the directory, too, if it
        doesn't already exist.  If the dbbackups directory doesn't exist
        and it can't build a new one, then it returns the directory the
        database is in.
        """
        path = os.path.join(os.path.dirname(self.path), "dbbackups")
        if not os.path.exists(path):
            try:
                fileutil.makedirs(path)
            except OSError:
                # if we can't make the backups dir, we just stick it in
                # the same directory
                path = os.path.dirname(self.path)
        return path
Ejemplo n.º 18
0
def check_movies_gone(check_unmounted=True):
    """Checks to see if the movies directory is gone.
    """

    movies_dir = fileutil.expand_filename(
        app.config.get(prefs.MOVIES_DIRECTORY))
    movies_dir = filename_to_unicode(movies_dir)

    # if the directory doesn't exist, create it.
    if (not os.path.exists(movies_dir)
            and should_create_movies_directory(movies_dir)):
        try:
            fileutil.makedirs(movies_dir)
        except OSError:
            logging.info(
                "Movies directory can't be created -- calling handler")
            # FIXME - this isn't technically correct, but it's probably
            # close enough that a user can fix the issue and Miro can
            # run happily.
            msg = _(
                "Permissions error: %(appname)s couldn't "
                "create the folder.",
                {"appname": app.config.get(prefs.SHORT_APP_NAME)})
            _movies_directory_gone_handler(msg, movies_dir)
            return

    # make sure the directory is writeable
    if not os.access(movies_dir, os.W_OK):
        logging.info("Can't write to movies directory -- calling handler")
        msg = _("Permissions error: %(appname)s can't "
                "write to the folder.",
                {"appname": app.config.get(prefs.SHORT_APP_NAME)})
        _movies_directory_gone_handler(msg, movies_dir)
        return

    # make sure that the directory is populated if we've downloaded stuff to
    # it
    if check_unmounted and check_movies_directory_unmounted():
        logging.info("Movies directory is gone -- calling handler.")
        msg = _("The folder contains no files: "
                "is it on a drive that's disconnected?")
        _movies_directory_gone_handler(msg, movies_dir, allow_continue=True)
        return

    eventloop.add_urgent_call(finish_backend_startup, "reconnect downloaders")
Ejemplo n.º 19
0
Archivo: startup.py Proyecto: ndim/miro
    def check_movies_gone(self, check_unmounted=True):
        """Checks to see if the movies directory is gone.
        """

        movies_dir = fileutil.expand_filename(app.config.get(
            prefs.MOVIES_DIRECTORY))
        movies_dir = filename_to_unicode(movies_dir)

        # if the directory doesn't exist, create it.
        if (not os.path.exists(movies_dir) and
                should_create_movies_directory(movies_dir)):
            try:
                fileutil.makedirs(movies_dir)
            except OSError:
                logging.info("Movies directory can't be created -- calling handler")
                # FIXME - this isn't technically correct, but it's probably
                # close enough that a user can fix the issue and Miro can
                # run happily.
                msg = _("Permissions error: %(appname)s couldn't "
                        "create the folder.",
                        {"appname": app.config.get(prefs.SHORT_APP_NAME)})
                self.movies_directory_gone_handler(msg, movies_dir)
                return

        # make sure the directory is writeable
        if not os.access(movies_dir, os.W_OK):
            logging.info("Can't write to movies directory -- calling handler")
            msg = _("Permissions error: %(appname)s can't "
                    "write to the folder.",
                    {"appname": app.config.get(prefs.SHORT_APP_NAME)})
            self.movies_directory_gone_handler(msg, movies_dir)
            return

        # make sure that the directory is populated if we've downloaded stuff to
        # it
        if check_unmounted and check_movies_directory_unmounted():
            logging.info("Movies directory is gone -- calling handler.")
            msg = _("The folder contains no files: "
                    "is it on a drive that's disconnected?")
            self.movies_directory_gone_handler(msg, movies_dir,
                                               allow_continue=True)
            return

        self.all_checks_done()
Ejemplo n.º 20
0
def write_database(database, mount):
    """
    Writes the given dictionary to the device.

    The database lives at [MOUNT]/.miro/json
    """
    confirm_db_thread()
    if not os.path.exists(mount):
        # device disappeared, so we can't write to it
        return
    try:
        fileutil.makedirs(os.path.join(mount, '.miro'))
    except OSError:
        pass
    try:
        json.dump(database, file(os.path.join(mount, '.miro', 'json'), 'wb'))
    except IOError:
        # couldn't write to the device
        # XXX throw up an error?
        pass
Ejemplo n.º 21
0
def write_database(database, mount):
    """
    Writes the given dictionary to the device.

    The database lives at [MOUNT]/.miro/json
    """
    confirm_db_thread()
    if not os.path.exists(mount):
        # device disappeared, so we can't write to it
        return
    try:
        fileutil.makedirs(os.path.join(mount, '.miro'))
    except OSError:
        pass
    try:
        json.dump(database, file(os.path.join(mount, '.miro', 'json'), 'wb'))
    except IOError:
        # couldn't write to the device
        # XXX throw up an error?
        pass
Ejemplo n.º 22
0
 def migrate(self, directory):
     if _downloads.has_key(self.dlid):
         c = command.MigrateDownloadCommand(RemoteDownloader.dldaemon,
                                            self.dlid, directory)
         c.send()
     else:
         # downloader doesn't have our dlid.  Move the file ourself.
         short_filename = self.status.get("shortFilename")
         if not short_filename:
             logging.warning(
                 "can't migrate download; no shortfilename!  URL was %s",
                 self.url)
             return
         filename = self.status.get("filename")
         if not filename:
             logging.warning(
                 "can't migrate download; no filename!  URL was %s",
                 self.url)
             return
         if fileutil.exists(filename):
             if self.status.get('channelName', None) is not None:
                 channelName = filter_directory_name(self.status['channelName'])
                 directory = os.path.join(directory, channelName)
             if not os.path.exists(directory):
                 try:
                     fileutil.makedirs(directory)
                 except OSError:
                     # FIXME - what about permission issues?
                     pass
             newfilename = os.path.join(directory, short_filename)
             if newfilename == filename:
                 return
             newfilename, fp = next_free_filename(newfilename)
             def callback():
                 self.status['filename'] = newfilename
                 self.signal_change(needs_signal_item=False)
                 self._file_migrated(filename)
             fileutil.migrate_file(filename, newfilename, callback)
             fp.close()
     for i in self.item_list:
         i.migrate_children(directory)
Ejemplo n.º 23
0
def write_database(db, mount):
    """
    Writes the given dictionary to the device.

    The database lives at [MOUNT]/.miro/json
    """
    database.confirm_db_thread()
    if not os.path.exists(mount):
        # device disappeared, so we can't write to it
        return
    try:
        fileutil.makedirs(os.path.join(mount, '.miro'))
    except OSError:
        pass
    try:
        with file(os.path.join(mount, '.miro', 'json'), 'wb') as output:
            iterable = json._default_encoder.iterencode(db)
            output.writelines(iterable)
    except IOError:
        # couldn't write to the device
        # XXX throw up an error?
        pass
Ejemplo n.º 24
0
def check_movies_gone():
    """Checks to see if the movies directory is gone.
    """

    # callback is what the frontend will call if the user asks us to continue
    callback = lambda: eventloop.add_urgent_call(fix_movies_gone,
                                                 "fix movies gone")

    movies_dir = fileutil.expand_filename(
        app.config.get(prefs.MOVIES_DIRECTORY))

    # if the directory doesn't exist, create it.
    if (not os.path.exists(movies_dir)
            and should_create_movies_directory(movies_dir)):
        try:
            fileutil.makedirs(movies_dir)
        except OSError:
            logging.info(
                "Movies directory can't be created -- calling handler")
            # FIXME - this isn't technically correct, but it's probably
            # close enough that a user can fix the issue and Miro can
            # run happily.
            _movies_directory_gone_handler(callback)
            return

    # make sure the directory is writeable
    if not os.access(movies_dir, os.W_OK):
        _movies_directory_gone_handler(callback)
        return

    # make sure that the directory is populated if we've downloaded stuff to
    # it
    if is_movies_directory_gone():
        logging.info("Movies directory is gone -- calling handler.")
        _movies_directory_gone_handler(callback)
        return

    eventloop.add_urgent_call(finish_backend_startup, "reconnect downloaders")
Ejemplo n.º 25
0
    def update_icon_cache(self, url, info):
        self.dbItem.confirm_db_thread()

        if self.removed:
            iconCacheUpdater.update_finished()
            return

        needs_save = False
        needsChange = False

        if info == None or (info['status'] != 304 and info['status'] != 200):
            self.error_callback(url, "bad response")
            return
        try:
            # Our cache is good.  Hooray!
            if info['status'] == 304:
                return

            needsChange = True

            # We have to update it, and if we can't write to the file, we
            # should pick a new filename.
            if self.filename and not fileutil.access(self.filename, os.R_OK | os.W_OK):
                self.filename = None

            cachedir = app.config.get(prefs.ICON_CACHE_DIRECTORY)
            try:
                fileutil.makedirs(cachedir)
            except OSError:
                pass

            try:
                # Write to a temp file.
                if self.filename:
                    tmp_filename = self.filename + ".part"
                else:
                    tmp_filename = os.path.join(cachedir, info["filename"]) + ".part"

                tmp_filename, output = next_free_filename(tmp_filename)
                output.write(info["body"])
                output.close()
            except IOError:
                self.remove_file(tmp_filename)
                return

            if self.filename:
                self.remove_file(self.filename)

            # Create a new filename always to avoid browser caching in case a
            # file changes.
            # Add a random unique id
            parts = unicodify(info["filename"]).split('.')
            uid = u"%08d" % random.randint(0, 99999999)
            if len(parts) == 1:
                parts.append(uid)
            else:
                parts[-1:-1] = [uid]
            self.filename = u'.'.join(parts)
            self.filename = unicode_to_filename(self.filename, cachedir)
            self.filename = os.path.join(cachedir, self.filename)
            self.filename, fp = next_free_filename(self.filename)
            needs_save = True

            try:
                fileutil.rename(tmp_filename, self.filename)
            except OSError:
                self.filename = None
                needs_save = True
            fp.close()

            etag = unicodify(info.get("etag"))
            modified = unicodify(info.get("modified"))

            if self.etag != etag:
                needs_save = True
                self.etag = etag
            if self.modified != modified:
                needs_save = True
                self.modified = modified
            if self.url != url:
                needs_save = True
                self.url = url
        finally:
            if needsChange:
                self.icon_changed(needs_save=needs_save)
            self.updating = False
            if self.needsUpdate:
                self.needsUpdate = False
                self.request_update(True)
            iconCacheUpdater.update_finished()
Ejemplo n.º 26
0
    def update_icon_cache(self, url, info):
        self.dbItem.confirm_db_thread()

        if self.removed:
            app.icon_cache_updater.update_finished()
            return

        needs_save = False
        needsChange = False

        if info == None or (info['status'] != 304 and info['status'] != 200):
            self.error_callback(url, "bad response")
            return
        try:
            # Our cache is good.  Hooray!
            if info['status'] == 304:
                return

            needsChange = True

            # We have to update it, and if we can't write to the file, we
            # should pick a new filename.
            if ((self.filename and
                 not fileutil.access(self.filename, os.R_OK | os.W_OK))):
                self.filename = None

            cachedir = app.config.get(prefs.ICON_CACHE_DIRECTORY)
            try:
                fileutil.makedirs(cachedir)
            except OSError:
                pass

            try:
                # Write to a temp file.
                if self.filename:
                    tmp_filename = self.filename + ".part"
                else:
                    tmp_filename = os.path.join(cachedir, info["filename"]) + ".part"
                tmp_filename, output = next_free_filename(tmp_filename)
                output.write(info["body"])
                output.close()
            except IOError:
                self.remove_file(tmp_filename)
                return
            except ValueError:
                logging.warn('update_icon_cache: next_free_filename failed '
                             '#1, candidate = %r', tmp_filename)
                return

            filename = unicode(info["filename"])
            filename = unicode_to_filename(filename, cachedir)
            filename = os.path.join(cachedir, filename)
            needs_save = True
            try:
                filename, fp = next_free_filename(filename)
            except ValueError:
                logging.warn('update_icon_cache: next_free_filename failed '
                             '#2, candidate = %r', filename)
                return

            if self.filename:
                filename = self.filename
                self.filename = None
                self.remove_file(filename)

            # we need to move the file here--so we close the file
            # pointer and then move the file.
            fp.close()
            try:
                self.remove_file(filename)
                fileutil.rename(tmp_filename, filename)
            except (IOError, OSError):
                logging.exception("iconcache: fileutil.move failed")
                filename = None

            self.filename = filename

            etag = unicodify(info.get("etag"))
            modified = unicodify(info.get("modified"))

            if self.etag != etag:
                needs_save = True
                self.etag = etag
            if self.modified != modified:
                needs_save = True
                self.modified = modified
            if self.url != url:
                needs_save = True
                self.url = url
        finally:
            if needsChange:
                self.icon_changed(needs_save=needs_save)
            self.updating = False
            if self.needsUpdate:
                self.needsUpdate = False
                self.request_update(True)
            app.icon_cache_updater.update_finished()
Ejemplo n.º 27
0
    def update_icon_cache(self, url, info):
        self.dbItem.confirm_db_thread()

        if self.removed:
            icon_cache_updater.update_finished()
            return

        needs_save = False
        needsChange = False

        if info == None or (info['status'] != 304 and info['status'] != 200):
            self.error_callback(url, "bad response")
            return
        try:
            # Our cache is good.  Hooray!
            if info['status'] == 304:
                return

            needsChange = True

            # We have to update it, and if we can't write to the file, we
            # should pick a new filename.
            if ((self.filename and
                 not fileutil.access(self.filename, os.R_OK | os.W_OK))):
                self.filename = None

            cachedir = app.config.get(prefs.ICON_CACHE_DIRECTORY)
            try:
                fileutil.makedirs(cachedir)
            except OSError:
                pass

            try:
                # Write to a temp file.
                if self.filename:
                    tmp_filename = self.filename + ".part"
                else:
                    tmp_filename = os.path.join(cachedir, info["filename"]) + ".part"
                tmp_filename, output = next_free_filename(tmp_filename)
                output.write(info["body"])
                output.close()
            except IOError:
                self.remove_file(tmp_filename)
                return
            except ValueError:
                logging.warn('update_icon_cache: next_free_filename failed '
                             '#1, candidate = %r', tmp_filename)
                return

            filename = unicode(info["filename"])
            filename = unicode_to_filename(filename, cachedir)
            filename = os.path.join(cachedir, filename)
            needs_save = True
            try:
                filename, fp = next_free_filename(filename)
            except ValueError:
                logging.warn('update_icon_cache: next_free_filename failed '
                             '#2, candidate = %r', filename)
                return

            if self.filename:
                filename = self.filename
                self.filename = None
                self.remove_file(filename)

            # we need to move the file here--so we close the file
            # pointer and then move the file.
            fp.close()
            try:
                self.remove_file(filename)
                fileutil.rename(tmp_filename, filename)
            except (IOError, OSError):
                logging.exception("iconcache: fileutil.move failed")
                filename = None

            self.filename = filename

            etag = unicodify(info.get("etag"))
            modified = unicodify(info.get("modified"))

            if self.etag != etag:
                needs_save = True
                self.etag = etag
            if self.modified != modified:
                needs_save = True
                self.modified = modified
            if self.url != url:
                needs_save = True
                self.url = url
        finally:
            if needsChange:
                self.icon_changed(needs_save=needs_save)
            self.updating = False
            if self.needsUpdate:
                self.needsUpdate = False
                self.request_update(True)
            icon_cache_updater.update_finished()