Ejemplo n.º 1
0
    def test_plugins(self, rw_dir):
        """load all known plugins and dispatch some events"""
        def raiser(py_file, mod_name):
            raise AssertionError("loading of plugin '%s' failed")
        # end 

        prev_dir = os.getcwd()
        bapp.main().context().push('example plugins')

        plugin_path = Path(__file__).dirname().dirname() / 'plugins'
        examples_path = plugin_path.dirname().dirname().dirname() / 'examples'

        for path in (plugin_path, examples_path):
            assert path.isdir()
            assert load_files(path, on_error=raiser)
        # end for each path to load plugins from

        try:
            os.chdir(rw_dir)
            sg = EventsReadOnlyTestSQLProxyShotgunConnection()
            engine = EventEngine(sg)

            for eid in range(1, 1000, 100):
                sg.next_event_id = sg.first_event_id + eid
                engine._process_events()
            # end 
        finally:
            os.chdir(prev_dir)
Ejemplo n.º 2
0
 def test_delegate(self):
     dlg_type = ProcessControllerDelegate
     for path in ('C:\\foo\\bar\\file.ext', '/mnt/share/subdir/file.ext'):
         path = Path(path)
         for p in (path, path.dirname()):
             # can happen with windows paths dirname on posix
             if not p:
                 continue
             m = dlg_type.re_find_path.match(p)
             assert m and m.group(0) == p, "should have found a path in '%s'" % p
             p = p.replace('/', '-').replace('\\', '-')
             assert not dlg_type.re_find_path.match(p), "This should be no path '%s'" % p
Ejemplo n.º 3
0
    def pre_start(self, executable, env, args, cwd, resolve):
        executable, env, new_args, cwd = super(TankCommandDelegate, self).pre_start(executable, env, args, cwd, resolve)
        # and the second argument must be the tank install root ... lets make it happy
        if len(new_args) > 2 and not os.path.isabs(new_args[1]):
            install_root = Path(new_args[0]).dirname().dirname().dirname()
            assert install_root.basename() == 'install', "Expected first argument '%s' to be tank_cmd.py right in the install root" % new_args[0]
            new_args.insert(1, install_root.dirname())
        # end handle install root

        last_arg = new_args[-1]
        if not last_arg.startswith(self.tank_pc_arg):
            # we assume to be in the right spot, but a check can't hurt until
            # we are able to do more ourselves
            actual_executable = self._actual_executable()
            base = actual_executable.dirname()
            assert (base / 'tank').exists(), "Currently '%s' must be right next to the 'tank' executable" % executable
            new_args.append(str(self.tank_pc_arg + base))
        # end setup context

        #######################
        # Process Arguments ##
        #####################
        if len(new_args) > 6 and new_args[3].startswith(self.launch_prefix):
            # now we could go crazy and try to find asset paths in order to provide context to bprocess
            # We could also use the shotgun context in some way, to feed data to our own asset management
            # However, for now using the project itself should just be fine, but this is certainly 
            # to be improved

            # Additinally, what we really want is to start any supported program, and enforce tank support by
            # fixing up delegates. For that, we will create a new process controller, which uses our Application 
            # instance, and the delegate that it defined so far.
            # However, we are currently unable to truly provide the information we have to a new process controller, 
            # unless it's communicated via the context.

            # It should be one of ours (e.g. TankEngineDelegate derivative) if there is tank support, which 
            # requires proper configuration.
            
            # For that to work, we will override the entire start procedure, as in pre-start we can't and should not
            # swap in the entire delegate
            def set_overrides(schema, value):
                value.host_app_name = new_args[3][len(self.launch_prefix):]
                value.entity_type = new_args[4]
                value.entity_id = int(new_args[5])
            # end overrides setter

            # This call will also push the context onto the stack, nothing more to be done here
            self.ApplyChangeContextType('tank-engine-information').setup(self._app.context(),
                                                                         set_overrides, 
                                                                         tank_engine_schema)
        #end handle particular command mode

        return (executable, env, new_args, cwd)
Ejemplo n.º 4
0
    def prepare_context(self, executable, env, args, cwd):
        """We will parse paths from the given commandline and use them in the context we build.
        Additionaly, we will provide a per-arg handler with the opportunity to inject kvstore overrides
        """
        # Will be a kvstore if there have been overrides
        kvstore_overrides = KeyValueStoreModifier(dict())
        for arg in args:
            # by default, we use paths as as context provider (configurable)
            path = self._extract_path(arg)
            if path:
                # ignore args that are not paths
                path = Path(path)
                if path.dirname().isdir():
                    self._app.context().push(self.StackAwareHierarchicalContextType(path.dirname()))
                # end handle valid directory
            # end handle path
            self.handle_argument(arg, kvstore_overrides)
        # end for each arg to check

        # set overrides
        if list(kvstore_overrides.keys()):
            self._app.context().push(Context('delegate overrides', kvstore_overrides))
        # end handle overrides
        return super(ProcessControllerDelegate, self).prepare_context(executable, env, args, cwd)
Ejemplo n.º 5
0
    def __init__(self, *args, **kwargs):
        """Initialize this instance with the required operations and verify configuration
        @throw ValueError if our configuration seems invalid"""
        super(TransferDropboxTransaction, self).__init__(*args, **kwargs)

        # Prepare the kvstore with data for resolving values
        now = datetime.utcnow()
        store = self._kvstore
        store.set_value('Y', now.year)
        store.set_value('M', now.month)
        store.set_value('D', now.day)
        store.set_value('H', now.hour)
        store.set_value('MIN', now.minute)

        config = self._config()

        if config.mode not in self.valid_modes:
            raise ValueError("Invalid transfer mode '%s' - must be one of %s" % (config.mode, ','.join(self.valid_modes)))
        # end check mode

        if not config.destination_dir.isdir():
            raise ValueError("Destination dropbox was not accessible: '%s'" % config.destination_dir)
        # prepare and resolve destination
        
        # handle subdir and create it if needed
        if config.subdir:
            raise NotImplementedError("implement unique identifier and subdir creation")
        # end 

        source = self._sql_instance.in_package.root()
        destination = config.destination_dir
        is_sync_mode = config.mode == self.MODE_SYNC
        if config.keep_package_subdir:
            # NOTE: rsync will duplicate our first directory unless we truncate it here
            root_relative = Path(self._package.root_relative())
            if root_relative.dirname():
                destination /= root_relative.dirname()
            # end handle modification of destination

            if is_sync_mode:
                if not source.isdir():
                    log.warn("Using copy instead of sync as it would be dangerous to use if there is no package subdirectory - source is file")
                    is_sync_mode = False
                else:
                    # In case of sync, we want to use the most destination path. This is possibly by instructing
                    # rsync to copy only the directory contents, into a destination which carries the additional
                    # base name of the source directory 
                    destination = destination / source.basename()
                    source += '/'
                # end put in sync mode safety
            # end adjust source-destination for sync mode

            # Make sure the directory exists
            if not destination.isdir():
                destination.makedirs()
            # end handle dir creation
        elif is_sync_mode:
            log.warn("Deactivating sync-mode as it is dangerous to use if keep_package_subdir is disabled")
            is_sync_mode = False
        # end handle subdir
        rsync_args = is_sync_mode and ['--delete'] or list()

        TransferRsyncOperation(self, source, destination, move=config.mode==self.MODE_MOVE, additional_rsync_args=rsync_args)
        self._sql_instance.comment = "%sing package from '%s' to '%s'" % (config.mode, source, destination)