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")
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()
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_
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
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()
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)
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_
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)
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)
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_
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
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)
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
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
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")
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()
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
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)
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
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")
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()
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()
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()