def __init__(self, client, local_path_u, db, name, clock, delay=0): self._client = client self._local_path_u = local_path_u self._local_filepath = to_filepath(local_path_u) self._db = db self._name = name self._clock = clock self._hooks = { 'processed': None, 'started': None, 'iteration': None, } self.started_d = self.set_hook('started') if not self._local_filepath.exists(): raise AssertionError("The '[magic_folder] local.directory' parameter was %s " "but there is no directory at that location." % quote_local_unicode_path(self._local_path_u)) if not self._local_filepath.isdir(): raise AssertionError("The '[magic_folder] local.directory' parameter was %s " "but the thing at that location is not a directory." % quote_local_unicode_path(self._local_path_u)) self._deque = deque() # do we also want to bound on "maximum age"? self._process_history = deque(maxlen=20) self._stopped = False # XXX pass in an initial value for this; it seems like .10 broke this and it's always 0 self._turn_delay = delay self._log('delay is %f' % self._turn_delay) # a Deferred to wait for the _do_processing() loop to exit # (gets set to the return from _do_processing() if we get that # far) self._processing = defer.succeed(None)
def test_to_filepath(self): foo_u = win32_other(u'C:\\foo', u'/foo') nosep_fp = to_filepath(foo_u) sep_fp = to_filepath(foo_u + os.path.sep) for fp in (nosep_fp, sep_fp): self.failUnlessReallyEqual(fp, FilePath(foo_u)) if encodingutil.use_unicode_filepath: self.failUnlessReallyEqual(fp.path, foo_u) if sys.platform == "win32": long_u = u'\\\\?\\C:\\foo' longfp = to_filepath(long_u + u'\\') self.failUnlessReallyEqual(longfp, FilePath(long_u)) self.failUnlessReallyEqual(longfp.path, long_u)
def __init__(self, client, local_path_u, db, name, clock): self._client = client self._local_path_u = local_path_u self._local_filepath = to_filepath(local_path_u) self._db = db self._name = name self._clock = clock self._debug_log = False self._logger = None self._hooks = { 'processed': None, 'started': None, 'iteration': None, 'inotify': None, } self.started_d = self.set_hook('started') if not self._local_filepath.exists(): raise AssertionError("The '[magic_folder] local.directory' parameter was %s " "but there is no directory at that location." % quote_local_unicode_path(self._local_path_u)) if not self._local_filepath.isdir(): raise AssertionError("The '[magic_folder] local.directory' parameter was %s " "but the thing at that location is not a directory." % quote_local_unicode_path(self._local_path_u)) self._deque = deque() # do we also want to bound on "maximum age"? self._process_history = deque(maxlen=20) self._stopped = False # a Deferred to wait for the _do_processing() loop to exit # (gets set to the return from _do_processing() if we get that # far) self._processing = defer.succeed(None)
def __init__(self, client, local_path_u, db, name, clock): self._client = client self._local_path_u = local_path_u self._local_filepath = to_filepath(local_path_u) self._db = db self._name = name self._clock = clock self._debug_log = False self._logger = None self._hooks = { 'processed': None, 'started': None, 'iteration': None, 'inotify': None, } self.started_d = self.set_hook('started') # we should have gotten nice errors already while loading the # config, but just to be safe: assert self._local_filepath.exists() assert self._local_filepath.isdir() self._deque = deque() # do we also want to bound on "maximum age"? self._process_history = deque(maxlen=20) self._stopped = False # a Deferred to wait for the _do_processing() loop to exit # (gets set to the return from _do_processing() if we get that # far) self._processing = defer.succeed(None)
def load_magic_folders(node_directory): """ Loads existing magic-folder configuration and returns it as a dict mapping name -> dict of config. This will NOT upgrade from old-style to new-style config (but WILL read old-style config and return in the same way as if it was new-style). :returns: dict mapping magic-folder-name to its config (also a dict) """ yaml_fname = os.path.join(node_directory, u"private", u"magic_folders.yaml") folders = dict() config_fname = os.path.join(node_directory, "tahoe.cfg") config = configutil.get_config(config_fname) if not os.path.exists(yaml_fname): # there will still be a magic_folder section in a "new" # config, but it won't have local.directory nor poll_interval # in it. if config.has_option("magic_folder", "local.directory"): up_fname = os.path.join(node_directory, "private", "magic_folder_dircap") coll_fname = os.path.join(node_directory, "private", "collective_dircap") directory = config.get("magic_folder", "local.directory").decode('utf8') try: interval = int(config.get("magic_folder", "poll_interval")) except ConfigParser.NoOptionError: interval = 60 dir_fp = to_filepath(directory) if not dir_fp.exists(): raise Exception( "The '[magic_folder] local.directory' parameter is {} " "but there is no directory at that location.".format( quote_local_unicode_path(directory), ) ) if not dir_fp.isdir(): raise Exception( "The '[magic_folder] local.directory' parameter is {} " "but the thing at that location is not a directory.".format( quote_local_unicode_path(directory) ) ) folders[u"default"] = { u"directory": directory, u"upload_dircap": fileutil.read(up_fname), u"collective_dircap": fileutil.read(coll_fname), u"poll_interval": interval, } else: # without any YAML file AND no local.directory option it's # an error if magic-folder is "enabled" because we don't # actually have enough config for any magic-folders at all if config.has_section("magic_folder") \ and config.getboolean("magic_folder", "enabled") \ and not folders: raise Exception( "[magic_folder] is enabled but has no YAML file and no " "'local.directory' option." ) elif os.path.exists(yaml_fname): # yaml config-file exists if config.has_option("magic_folder", "local.directory"): raise Exception( "magic-folder config has both old-style configuration" " and new-style configuration; please remove the " "'local.directory' key from tahoe.cfg or remove " "'magic_folders.yaml' from {}".format(node_directory) ) with open(yaml_fname, "r") as f: magic_folders = yamlutil.safe_load(f.read()) if not isinstance(magic_folders, dict): raise Exception( "'{}' should contain a dict".format(yaml_fname) ) folders = magic_folders['magic-folders'] if not isinstance(folders, dict): raise Exception( "'magic-folders' in '{}' should be a dict".format(yaml_fname) ) # check configuration for (name, mf_config) in folders.items(): if not isinstance(mf_config, dict): raise Exception( "Each item in '{}' must itself be a dict".format(yaml_fname) ) for k in ['collective_dircap', 'upload_dircap', 'directory', 'poll_interval']: if k not in mf_config: raise Exception( "Config for magic folder '{}' is missing '{}'".format( name, k ) ) for k in ['collective_dircap', 'upload_dircap']: if isinstance(mf_config[k], unicode): mf_config[k] = mf_config[k].encode('ascii') return folders
def _maybe_notify(self, fname, mask): if self._fake_inotify: self._uploader._notifier.event(to_filepath(fname), mask)