def validate(self): # current ptask/version try: area = PTaskArea.current() self._current_ptask = PTask.get(area.spec) self._current_ptask_version = self._current_ptask.latest_version except PTaskError: raise ActionError("Unable to find ptask: " + str(self._ptask)) # source ptask if not isinstance(self._ptask, PTask): try: cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec) self._ptask = PTask.get(full_spec) except PTaskError: raise ActionError("Unable to find ptask: " + str(self._ptask)) # source ptask version if isinstance(self._version, PTaskVersion): pass elif self._version: matches = PTaskVersion.list( ptask=self._ptask.spec, number=self._version ) if len(matches) != 1: raise ActionError( "Unable to find ptask '{p}' at version '{v}'".format( p=self._ptask.spec, v=self._version ) ) else: self._version = matches[0] else: self._version = self._ptask.latest_version # source subs self._match_str = self._match_str.replace("%", ".*") all_subs = self._version.subscriptions self._subs_to_source = [] for sub in all_subs: if re.search(self._match_str, sub.product_version_spec): self._subs_to_source.append(sub) if not self._subs_to_source: raise ActionAborted("No subscriptions to source.")
def _import_mari_plugins(): from dpa.ptask.area import PTaskArea # first, get the context ptask_area = PTaskArea.current() # get a list of mari plugin directories plugin_dirs = ptask_area.ancestor_paths( 'plugins/mari', include_install=False) for plugin_dir in reversed(plugin_dirs): if not os.path.isdir(plugin_dir): continue file_names = os.listdir(plugin_dir) for file_name in file_names: # only python files if not file_name.endswith(".py"): continue full_path = os.path.join(plugin_dir, file_name) module_name = 'mari_plugin_' + file_name.replace(".", "_") try: module = imp.load_source(module_name, full_path) except Exception as e: print "Unable to load mari plugin: " + full_path traceback.print_exc()
def get_import_files(cls, session, name, category, representation, relative_to=None): ptask_area = PTaskArea.current() try: import_dir = ptask_area.dir(dir_name='import', path=True) except PTaskAreaError: raise EntityError("Could not find import directory!") import_dir = os.path.join( import_dir, 'global', name, category, representation.type, representation.resolution ) # get the file in the import_dir import_files = os.listdir(import_dir) import_files = [f for f in import_files if f.endswith('.' + representation.type)] # prepend the import directory to get the full path import_files = [os.path.join(import_dir, f) for f in import_files] if relative_to: import_files = [ os.path.relpath(f, relative_to) for f in import_files] return import_files
def _import_nuke_plugins(): from dpa.ptask.area import PTaskArea # first, get the context ptask_area = PTaskArea.current() # get a list of nuke plugin directories plugin_dirs = ptask_area.ancestor_paths('plugins/nuke', include_install=False) for plugin_dir in reversed(plugin_dirs): if not os.path.isdir(plugin_dir): continue file_names = os.listdir(plugin_dir) for file_name in file_names: # only python files if not file_name.endswith(".py"): continue full_path = os.path.join(plugin_dir, file_name) module_name = 'nuke_plugin_' + file_name.replace(".", "_") try: module = imp.load_source(module_name, full_path) except Exception as e: print "Unable to load nuke plugin: " + full_path traceback.print_exc()
def queue_submit_cmd(command, queue_name, output_file=None, id_extra=None, dt=None): """Create and submit a shell script with the given command.""" ptask_area = PTaskArea.current() ptask_area.provision(QUEUE) script_dir = ptask_area.dir(dir_name=QUEUE) unique_id = get_unique_id(ptask_area.spec, id_extra=id_extra, dt=dt) script_name = unique_id + '.sh' log_name = unique_id + '.log' script_path = os.path.join(script_dir, script_name) log_path = os.path.join(script_dir, log_name) with open(script_path, "w") as script_file: script_file.write("#!/bin/bash\n") script_file.write(command + "\n") script_file.write("chmod 660 " + output_file + "\n") os.chmod(script_path, 0770) create_queue_task(queue_name, script_path, unique_id, output_file=output_file, submit=True, log_path=log_path)
def setup_cl_args(cls, parser): parser.add_argument( "spec", nargs="?", default=PTaskArea.current().spec, help="The production task specification." ) parser.add_argument( "-s", "--shell", default=ShellFormatters.default().name, choices=sorted([f.name for f in ShellFormatters.all()]), help="Shell type env commands should target." ) parser.add_argument( "-p", "--previous", nargs="?", const="list", help="Choose a previous ptask env." ) parser.add_argument( "-v", "--version", type=int, help="The version of the ptask to print info for." )
def ptask_area(self): """Return the current ptask area for this session.""" if not hasattr(self, '_ptask_area'): self._ptask_area = PTaskArea.current() return self._ptask_area
def validate(self): # current ptask/version try: area = PTaskArea.current() self._current_ptask = PTask.get(area.spec) self._current_ptask_version = self._current_ptask.latest_version except PTaskError: raise ActionError("Unable to find ptask: " + str(self._ptask)) # source ptask if not isinstance(self._ptask, PTask): try: cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec) self._ptask = PTask.get(full_spec) except PTaskError: raise ActionError("Unable to find ptask: " + str(self._ptask)) # source ptask version if isinstance(self._version, PTaskVersion): pass elif self._version: matches = PTaskVersion.list(ptask=self._ptask.spec, number=self._version) if len(matches) != 1: raise ActionError( "Unable to find ptask '{p}' at version '{v}'".format( p=self._ptask.spec, v=self._version)) else: self._version = matches[0] else: self._version = self._ptask.latest_version # source subs self._match_str = self._match_str.replace("%", ".*") all_subs = self._version.subscriptions self._subs_to_source = [] for sub in all_subs: if re.search(self._match_str, sub.product_version_spec): self._subs_to_source.append(sub) if not self._subs_to_source: raise ActionAborted("No subscriptions to source.")
def execute(self): match_specs = self._complete( self.spec, relative_to=PTaskArea.current().spec, ) if match_specs: print " ".join([s for s in match_specs])
def get_default_product_name(): name = "Comp" ptask_area = PTaskArea.current() if ptask_area: name = PTaskSpec.name(ptask_area.spec) + name return name
def validate(self): if not isinstance(self._ptask, PTask): try: cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec) self._ptask = PTask.get(full_spec) except PTaskError: raise ActionError("Could not determine ptask from: {p}".format( p=self._ptask))
def log_action(self): if not self.__class__.logging: return # log the command msg = "({s})".format(s=PTaskArea.current().spec) msg += " " + " ".join(sys.argv) self.logger.info(msg)
def __call__(self, parser, namespace, in_spec, option_string=None): # assume the current ptask if not supplied if not in_spec: in_spec = "." cur_spec = PTaskArea.current().spec in_spec = in_spec.strip().strip(PTaskSpec.SEPARATOR) full_spec = PTaskSpec.get(in_spec, relative_to=cur_spec) setattr(namespace, self.dest, full_spec)
def validate(self): if not self._message: raise ActionError("Message can not be empty.") try: self._sender = User.current() except UserError: raise ActionError("Could not identify current user.") # get ooto notification recipients from the configs ptask_area = PTaskArea.current() ooto_config = ptask_area.config( OOTO_CONFIG_PATH, composite_ancestors=True, composite_method="append", ) ooto_notify = ooto_config.get('notify', []) self._to.extend(ooto_notify) # for all usernames specified, make sure they're a valid user, # get their email addresses. recipients = set() for recipient in self._to: # assume already a valid email address if "@" in recipient: recipients.add(recipient) else: try: recipient = User.get(recipient) except UserError: raise ActionError( "Could not identify user: "******"\n\nCurrent ptask: {p}".format(p=ptask_area.spec) self._message += "\n\n- {s}".format(s=self._sender.full_name) self._subject = "OOTO: {fn} ({un})".format( fn=self.sender.full_name, un=self.sender.username, )
def queue_submit_cmd(command, queue_name, output_file=None, id_extra=None): """Create and submit a shell script with the given command.""" ptask_area = PTaskArea.current() ptask_area.provision(QUEUE) script_dir = ptask_area.dir(dir_name=QUEUE) now = datetime.datetime.now() if not id_extra: id_extra = now.strftime("%f") unique_id = "{u}_{t}_{s}_{e}".format( u=current_username(), t=now.strftime("%Y_%m_%d_%H_%M_%S"), s=ptask_area.spec.replace('=', '_'), e=id_extra, ) script_name = unique_id + '.sh' log_name = unique_id + '.log' script_path = os.path.join(script_dir, script_name) log_path = os.path.join(script_dir, log_name) with open(script_path, "w") as script_file: script_file.write("#!/bin/bash\n") script_file.write(command + "\n") script_file.write("chmod 660 " + output_file + "\n") os.chmod(script_path, 0770) # ---- submit to the queue from cheesyq import DPACheesyQ, DPADataLibrary, DPACheesyQTasks data_lib = DPADataLibrary.DjangoLibrary(None) render_task = DPACheesyQ.RenderTask() render_task.taskid = unique_id render_task.logFileName = log_path render_task.outputFileName = output_file data_lib.set(render_task.taskid, render_task) render_task.addTask(script_path) os.system("cqresubmittask {qn} {tid}".format( qn=queue_name, tid=render_task.taskid )) print "Submitted task: " + str(render_task.taskid)
def __init__(self): ptask_area = PTaskArea.current() options_config = ptask_area.config(FAIL_OPTIONS_CONFIG, composite_ancestors=True) icon_path = IconFactory().disk_path(FAIL_ICON_URI) super(FailDialog, self).__init__( title='Failure Report', options_config=options_config, icon_path=icon_path, action_button_text='Submit', modal=False, )
def __init__(self): ptask_area = PTaskArea.current() options_config = ptask_area.config(OOTO_OPTIONS_CONFIG, composite_ancestors=True) icon_path = IconFactory().disk_path(OOTO_ICON_URI) super(OotoDialog, self).__init__( title='Out Of The Office (OOTO)', options_config=options_config, icon_path=icon_path, action_button_text='Submit', modal=False, )
def validate(self): cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec) # if we're listing the current ptask's subs, and no versions specified if cur_spec == full_spec and not self._versions: ptask_ver = DpaVars.ptask_version().get() if ptask_ver: self._versions = [ptask_ver] if not self._versions: self._versions = ["latest"] # try to get a ptask instance from the db try: ptask = PTask.get(full_spec) except PTaskError as e: # fall back to the input spec try: ptask = PTask.get(self.spec) except PTaskError: raise ActionError( 'Could not determine ptask from: "{s}"'.format( s=self.spec) ) self._ptask = ptask if self._versions == ['latest']: versions = [self.ptask.latest_version] elif self._versions == ['all']: versions = self.ptask.versions else: self._versions = map(int, self._versions) versions = [v for v in self.ptask.versions if v.number in self._versions] if len(versions) == 0: raise ActionError( "No matches found for {p} version: {v}".format( p=ptask.spec, v=Style.bright + str(self._versions) + Style.normal, ) ) self._versions = versions
def validate(self): cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec) # if we're listing the current ptask's subs, and no versions specified if cur_spec == full_spec and not self._versions: ptask_ver = DpaVars.ptask_version().get() if ptask_ver: self._versions = [ptask_ver] if not self._versions: self._versions = ["latest"] # try to get a ptask instance from the db try: ptask = PTask.get(full_spec) except PTaskError as e: # fall back to the input spec try: ptask = PTask.get(self.spec) except PTaskError: raise ActionError( 'Could not determine ptask from: "{s}"'.format( s=self.spec)) self._ptask = ptask if self._versions == ['latest']: versions = [self.ptask.latest_version] elif self._versions == ['all']: versions = self.ptask.versions else: self._versions = map(int, self._versions) versions = [ v for v in self.ptask.versions if v.number in self._versions ] if len(versions) == 0: raise ActionError("No matches found for {p} version: {v}".format( p=ptask.spec, v=Style.bright + str(self._versions) + Style.normal, )) self._versions = versions
def validate(self): cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec) if full_spec: try: product = Product.get(full_spec) except ProductError as e: # fall back to input spec try: product = Product.get(self.spec) except ProductError: raise ActionError('Could not determine product from: "{s}"'.format(s=self.spec)) else: product = None self._product = product
def initializePlugin(mobject): # read the config, get all the shelf definitions ptask_area = PTaskArea.current() maya_shelves_config = ptask_area.config( config_file=CONFIG_FILE, composite_ancestors=True) for (shelf_name, shelf_config) in maya_shelves_config.iteritems(): shelf = MayaShelf(shelf_name) if shelf.exists: shelf.delete() shelf.create() # add all the shelf buttons for (button_key, button_config) in shelf_config.iteritems(): shelf.add_button(**button_config) INITIALIZED_SHELVES.append(shelf)
def __init__(self): ptask_area = PTaskArea.current() options_config = ptask_area.config(IMPORT_OPTIONS_CONFIG, composite_ancestors=True) self.get_files() options_config['options']['products'].set('choices', self.sublist.keys()) options_config['options']['products'].set('default', self.sublist.keys()[0]) icon_path = IconFactory().disk_path(IMPORT_ICON_URI) super(ImportDialog, self).__init__( title='Import Product', options_config=options_config, icon_path=icon_path, action_button_text='Import', modal=False, )
def load_toolbars(): """Load all custom toolbars via config files.""" ptask_area = PTaskArea.current() nuke_toolbar_config = ptask_area.config(config_file=NUKE_TOOLBAR_CONFIG, composite_ancestors=True) for (toolbar_name, toolbar_config) in nuke_toolbar_config.iteritems(): toolbar = nuke.toolbar(toolbar_name) for (item_key, item_config) in toolbar_config.iteritems(): name = item_config.get("label", item_key) command = item_config.get("command", "print 'No op'") icon = item_config.get("image", None) tooltip = item_config.get("annotation", "") if icon: icon = IconFactory().disk_path(icon) toolbar.addCommand(name=name, command=command, icon=icon, tooltip=tooltip)
def validate(self): cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec) if full_spec: try: product = Product.get(full_spec) except ProductError as e: # fall back to input spec try: product = Product.get(self.spec) except ProductError: raise ActionError( 'Could not determine product from: "{s}"'.format( s=self.spec)) else: product = None self._product = product
def populate_sub_cache(ptask_version=None, refresh=False): if not ptask_version: ptask_area = PTaskArea.current() ptask = PTask.get(ptask_area.spec) if ptask_area.version: ptask_version = ptask.version(ptask_area.version) else: ptask_version = ptask.latest_version nuke_file = nuke.root().name() nuke_dir = os.path.dirname(nuke_file) if refresh or not SUBD_REPR_CACHE: for sub in ptask_version.subscriptions: for product_repr in sub.product_version.representations: product = product_repr.product_version.product if product.category != 'imgseq': continue product_repr_str = product.name_spec + ' @ ' + \ product_repr.type if product_repr.resolution != 'none': product_repr_str += PTaskSpec.SEPARATOR + \ product_repr.resolution sub_import_dir = get_import_dir(product_repr, product=product, area=ptask_area, relative_to=nuke_dir) # populate cache lookups SUBD_REPR_CACHE.append(product_repr) PRODUCT_REPR_STR_TO_PATH[product_repr_str] = \ sub_import_dir
def validate(self): cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec) # try to get a ptask instance from the db if full_spec: try: ptask = PTask.get(full_spec) except PTaskError as e: # fall back to the input spec try: ptask = PTask.get(self.spec) except PTaskError: raise ActionError( 'Could not determine ptask from: "{s}"'.format( s=self.spec)) else: ptask = None self._ptask = ptask
def get_import_dir(product_repr, product=None, area=None, relative_to=None): if not area: area = PTaskArea.current() if not product: product = product_repr.product_version.product try: import_dir = area.dir(dir_name='import', path=True) except PTaskAreaError: raise Exception("Could not find import directory!") import_dir = os.path.join(import_dir, 'global', product.name, product.category, product_repr.type, product_repr.resolution) if relative_to: import_dir = os.path.relpath(import_dir, relative_to) return import_dir
def log_action(self): if not self.__class__.logging: return # try to format the args/kwargs to be readable in the log args_str = "" if len(self.args): args_str += ", ".join([str(a) for a in self.args]) args_str = "args(" + args_str + ")" if len(self.kwargs.keys()): kwargs_str = ", ".join( sorted([k + '="' + str(v) + '"' for (k, v) in self.kwargs.items() if v]) ) args_str = args_str + " kwargs(" + kwargs_str + ")" msg = "({s})".format(s=PTaskArea.current().spec) msg += " " + args_str # log the action and its args self.logger.info(msg)
def validate(self): cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec) # try to get a ptask instance from the db if full_spec: try: ptask = PTask.get(full_spec) except PTaskError as e: # fall back to the input spec try: ptask = PTask.get(self.spec) except PTaskError: raise ActionError( 'Could not determine ptask from: "{s}"'.format( s=self.spec) ) else: ptask = None self._ptask = ptask
def get_import_dir(product_repr, product=None, area=None, relative_to=None): if not area: area = PTaskArea.current() if not product: product = product_repr.product_version.product try: import_dir = area.dir(dir_name='import', path=True) except PTaskAreaError: raise Exception("Could not find import directory!") import_dir = os.path.join( import_dir, 'global', product.name, product.category, product_repr.type, product_repr.resolution ) if relative_to: import_dir = os.path.relpath(import_dir, relative_to) return import_dir
def validate(self): use_cur_version = False if not isinstance(self.ptask, PTask): if not self.ptask or self.ptask == '.': use_cur_version = True cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self.ptask, relative_to=cur_spec) # try to get a ptask instance from the db try: ptask = PTask.get(full_spec) except PTaskError as e: # fall back to the input spec try: ptask = PTask.get(self.spec) except PTaskError: raise ActionError( 'Could not determine ptask from: "{s}"'.format( s=self.spec) ) self._ptask = ptask latest_ver = self.ptask.latest_version if use_cur_version: cur_ptask_ver = DpaVars.ptask_version().get() if cur_ptask_ver and cur_ptask_ver != latest_ver.number: self._ptask_version = self.ptask.version(cur_ptask_ver) self._version = cur_ptask_ver else: self._ptask_version = self.ptask.latest_version else: self._ptask_version = self.ptask.latest_version
def log_action(self): if not self.__class__.logging: return # try to format the args/kwargs to be readable in the log args_str = "" if len(self.args): args_str += ", ".join([str(a) for a in self.args]) args_str = "args(" + args_str + ")" if len(self.kwargs.keys()): kwargs_str = ", ".join( sorted([ k + '="' + str(v) + '"' for (k, v) in self.kwargs.items() if v ])) args_str = args_str + " kwargs(" + kwargs_str + ")" msg = "({s})".format(s=PTaskArea.current().spec) msg += " " + args_str # log the action and its args self.logger.info(msg)
def __init__(self): self._ptask_area = PTaskArea.current() options_config = self._ptask_area.config(VERSION_OPTIONS_CONFIG, composite_ancestors=True) try: self._ptask = PTask.get(self._ptask_area.spec) except PTaskError as e: error_dialog = QtGui.QErrorMessage(self) error_dialog.setWindowTitle('Version Failure') error_dialog.showMessage("Unable to determine current ptask.") return icon_path = IconFactory().disk_path(VERSION_ICON_URI) super(PTaskVersionDialog, self).__init__( title='Version up', options_config=options_config, icon_path=icon_path, action_button_text='Submit', modal=False, )
def validate(self): use_cur_version = False if not isinstance(self.ptask, PTask): if not self.ptask or self.ptask == '.': use_cur_version = True cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self.ptask, relative_to=cur_spec) # try to get a ptask instance from the db try: ptask = PTask.get(full_spec) except PTaskError as e: # fall back to the input spec try: ptask = PTask.get(self.spec) except PTaskError: raise ActionError( 'Could not determine ptask from: "{s}"'.format( s=self.spec)) self._ptask = ptask latest_ver = self.ptask.latest_version if use_cur_version: cur_ptask_ver = DpaVars.ptask_version().get() if cur_ptask_ver and cur_ptask_ver != latest_ver.number: self._ptask_version = self.ptask.version(cur_ptask_ver) self._version = cur_ptask_ver else: self._ptask_version = self.ptask.latest_version else: self._ptask_version = self.ptask.latest_version
def _get_products(wild_spec): ptask_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(wild_spec, relative_to=ptask_spec) if PTaskSpec.WILDCARD in full_spec: search_str = ",".join( filter(None, full_spec.strip().split(PTaskSpec.WILDCARD))) # no wildcard, match all products under current location else: search_str = full_spec # XXX this is inefficient. need better filtering on the backend products = Product.list(search=search_str) matching_products = [] # the rest api's search filter isn't that great. it doesn't maintain any # knowledge of order for the supplied filters. So, it will return products # that match all of the search terms, but not necessarily in the order # supplied. Do one more match against the returned products specs keeping # the order of the supplied wildcard spec. regex_spec = "^" + \ full_spec.replace(PTaskSpec.WILDCARD, "([\w=]+)?") + "$" regex_spec = re.compile(regex_spec) for product in products: if regex_spec.match(product.spec): matching_products.append(product) return matching_products
def _get_products(wild_spec): ptask_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(wild_spec, relative_to=ptask_spec) if PTaskSpec.WILDCARD in full_spec: search_str = ",".join( filter(None, full_spec.strip().split(PTaskSpec.WILDCARD)) ) # no wildcard, match all products under current location else: search_str = full_spec # XXX this is inefficient. need better filtering on the backend products = Product.list(search=search_str) matching_products = [] # the rest api's search filter isn't that great. it doesn't maintain any # knowledge of order for the supplied filters. So, it will return products # that match all of the search terms, but not necessarily in the order # supplied. Do one more match against the returned products specs keeping # the order of the supplied wildcard spec. regex_spec = "^" + \ full_spec.replace(PTaskSpec.WILDCARD, "([\w:]+)?") + "$" regex_spec = re.compile(regex_spec) for product in products: if regex_spec.match(product.spec): matching_products.append(product) return matching_products
def load_toolbars(): """Load all custom toolbars via config files.""" ptask_area = PTaskArea.current() nuke_toolbar_config = ptask_area.config(config_file=NUKE_TOOLBAR_CONFIG, composite_ancestors=True) for (toolbar_name, toolbar_config) in nuke_toolbar_config.iteritems(): toolbar = nuke.toolbar(toolbar_name) for (item_key, item_config) in toolbar_config.iteritems(): name = item_config.get('label', item_key) command = item_config.get('command', "print 'No op'") icon = item_config.get('image', None) tooltip = item_config.get('annotation', "") if icon: icon = IconFactory().disk_path(icon) toolbar.addCommand(name=name, command=command, icon=icon, tooltip=tooltip)
def setup_cl_args(cls, parser): parser.add_argument("spec", nargs="?", default=PTaskArea.current().spec, help="The production task specification.") parser.add_argument("-s", "--shell", default=ShellFormatters.default().name, choices=sorted( [f.name for f in ShellFormatters.all()]), help="Shell type env commands should target.") parser.add_argument("-p", "--previous", nargs="?", const="list", help="Choose a previous ptask env.") parser.add_argument("-v", "--version", type=int, help="The version of the ptask to print info for.")
def validate(self): # validate the ptask if not isinstance(self._ptask, PTask): try: cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec) self._ptask = PTask.get(full_spec) except PTaskError: raise ActionError("Could not determine ptask from: {p}".format( p=self._ptask)) # find the version of the ptask to update if isinstance(self._ptask_version, PTaskVersion): if not self._ptask_version.ptask_spec == self._ptask_spec: raise ActionError( "Supplied ptask version doesn't match supplied ptask.") elif self._ptask_version: matches = PTaskVersion.list( ptask=self._ptask.spec, number=self._ptask_version ) if len(matches) != 1: raise ActionError( "Unable to find ptask '{p}' at version '{v}'".format( p=self._ptask.spec, v=self._ptask_version ) ) else: self._ptask_version = matches[0] else: self._ptask_version = self._ptask.latest_version # XXX rule # don't allow if ptask_version already has published products if self._ptask_version.published: raise ActionError( "Subscriptions can not be modified." + \ "Version {v} of {p} has published products.".format( v=self._ptask_version.number_padded, p=self._ptask.spec )) # XXX subs = [] # valdiate the subscriptions to update if self._subs: # get explicit subs for sub in self._subs: if isinstance(sub, ProductSubscription): subs_to_udpate.append(sub) continue try: sub = int(sub) except: raise ActionError("Could not determine sub from: {s}".\ format(s=sub)) else: matches = ProductSubscription.list(id=sub) if len(matches) != 1: raise ActionError("Unable to identify sub for id: " + \ str(sub)) else: subs.append(matches[0]) else: # all subs for ptask version subs.extend(self._ptask_version.subscriptions) self._subs = subs update_map = defaultdict(dict) for sub in subs: sub_product_ver = sub.product_version update_map[sub.id]['old'] = sub_product_ver if sub.locked: update_map[sub.id]['new'] = None update_map[sub.id]['note'] = 'Subscription locked' continue if sub_product_ver.is_official: update_map[sub.id]['new'] = None update_map[sub.id]['note'] = 'Already subscribed to official' continue sub_product = sub_product_ver.product official_ver = sub_product.official_version if official_ver and official_ver.number > sub_product_ver.number: update_map[sub.id]['new'] = official_ver update_map[sub.id]['note'] = 'Official version' continue if sub.product_version.product.ptask.spec == self.ptask.spec: all_vers = [v for v in sub_product.versions] else: all_vers = [v for v in sub_product.versions if v.published] all_vers.sort(key=lambda v: v.number_padded) if all_vers: latest = all_vers[-1] if latest.number > sub_product_ver.number: update_map[sub.id]['new'] = latest if latest.published: update_map[sub.id]['note'] = 'Latest published version' else: update_map[sub.id]['note'] = 'Latest version' continue else: update_map[sub.id]['new'] = None if sub_product_ver.published: update_map[sub.id]['note'] = \ 'Already using latest published' else: update_map[sub.id]['note'] = 'Already using latest' continue else: update_map[sub.id]['new'] = None update_map[sub.id]['note'] = 'No new versions' continue self._update_map = update_map
def ptask_area(self): if not hasattr(self, '_ptask_area'): self._ptask_area = PTaskArea.current() return self._ptask_area
def _print_ptask_env(self): # remove any whitespace on the head/tail of the spec spec = self.spec.strip() ptask_area = None if self.version: spec = PTaskSpec.VERSION.join([spec, str(self.version)]) replace_match = re.match("\.?/([=\w]+)/([=\w]+)/", spec) # handle 'none' as a valid spec - unset current ptask (set it to root) if spec.lower() == 'none': spec = "" full_spec = PTaskSpec.get(spec) try: ptask_area = PTaskArea(full_spec) except: pass # special character '-' indicates use the last set ptask spec elif spec == "-": ptask_area = PTaskArea.previous() # set to a similar ptask with text replacement elif replace_match: cur_area_spec = PTaskArea.current().spec repl_spec = cur_area_spec.replace( replace_match.group(1), replace_match.group(2)) try: ptask_area = PTaskArea(repl_spec) except: pass # use the supplied spec relative to the current ptask else: relative_to = PTaskArea.current().spec while ptask_area is None: try: full_spec = PTaskSpec.get(spec, relative_to=relative_to) except PTaskSpecError as e: raise ActionError(str(e)) try: # if this is successful, we'll break out of the while ptask_area = PTaskArea(full_spec) except PTaskAreaError as e: # no match, check the parent relative spec relative_to = PTaskSpec.parent(relative_to) # there is no parent, break out of the while if relative_to is None: break # dump out commands used for setting the environment for the supplied # spec. if not ptask_area: raise ActionError( "Could not determine ptask area from: " + str(spec), ) ptask = None # delay the db query to this point to prevent multiple, unnecessary db # queries. if we're at this point, we know there's at least a # corresponding directory on disk. if ptask_area.base_spec: try: ptask = PTask.get(ptask_area.base_spec) except PTaskError as e: pass if not ptask and ptask_area.spec != "": raise ActionError("Could not determine ptask from: " + str(spec)) ptask_area.set(shell=self.shell, ptask=ptask)
def playblaster(quality, sequence, autoReview): #Does some error checking to ensure the fspattern is correct area = PTaskArea.current() spec = None if area: spec = area.spec else: print "You need to dpaset into a ptask to use this tool." return False currentCam = cmds.modelPanel(cmds.getPanel(wf=True), q=True, cam=True) currentCamMunged = currentCam.replace('|', '_') focalLength = cmds.camera(currentCam, q=True, fl=True) cameraName = currentCamMunged.title() + "Fov" + str(focalLength) print "Camera Name: " + cameraName specName = spec.name(spec).title() if not autoReview: playblastdir = "/scratch" + area.dir() #listing = os.listdir(playblastdir) print "Making directory " + playblastdir os.system("mkdir -p " + playblastdir) #get a listing of the version numbers in the directory nbversions = len(os.listdir(playblastdir)) versionFrame = "%04d" % (nbversions + 1) fileName = "%s/playblast%s%s-%s" % (playblastdir, specName, cameraName, versionFrame) print "writing playblast to file " + fileName + ".mov" xVal = cmds.getAttr('defaultResolution.width') yVal = cmds.getAttr('defaultResolution.height') if sequence: sqMgr = cmds.listConnections('sequenceManager1', s=True, d=False)[0] seqEnd = cmds.getAttr(str(sqMgr) + ".maxFrame") seqStart = cmds.getAttr(str(sqMgr) + ".minFrame") print "SqStart: " + str(seqStart) print "SqEnd: " + str(seqEnd) cmds.playblast(startTime=seqStart, endTime=seqEnd, sequenceTime=sequence, f=fileName, percent=quality, offScreen=True, format="qt", width=xVal, height=yVal) else: cmds.playblast(f=fileName, percent=quality, offScreen=True, format="qt", width=xVal, height=yVal) cmds.deleteUI("PBQuality") os.chmod(fileName + ".mov", 0777) os.system("vlc " + fileName + ".mov &") return True if autoReview: #create a product to put this in xVal = cmds.getAttr('defaultResolution.width') yVal = cmds.getAttr('defaultResolution.height') product_spec = "playblast=movie" product_type = "mov" product_resolution = str(xVal) + "x" + str(yVal) product_description = "auto generated in dpa playblast tool" from dpa.action.registry import ActionRegistry create_action_cls = ActionRegistry().get_action('create', 'product') create_action = create_action_cls(product=product_spec, ptask=spec, description=product_description, file_type=product_type, resolution=product_resolution) try: create_action() except ActionError as e: raise EntityError("Unable to create a product: " + str(e)) #use product to get the directory path area = create_action.product_repr.area playblastdir = area.dir() versionFrame = create_action.product_version.number_padded baseFileName = "playblast%s%s-%s" % (specName, cameraName, versionFrame) fileName = playblastdir + "/" + baseFileName print "writing playblast to file " + fileName + ".mov" if sequence: sqMgr = cmds.listConnections('sequenceManager1', s=True, d=False)[0] seqEnd = cmds.getAttr(str(sqMgr) + ".maxFrame") seqStart = cmds.getAttr(str(sqMgr) + ".minFrame") print "SqStart: " + str(seqStart) print "SqEnd: " + str(seqEnd) cmds.playblast(startTime=seqStart, endTime=seqEnd, sequenceTime=sequence, f=fileName, percent=quality, offScreen=True, format="qt", width=xVal, height=yVal) else: cmds.playblast(f=fileName, percent=quality, offScreen=True, format="qt", width=xVal, height=yVal) cmds.deleteUI("PBQuality") os.chmod(fileName + ".mov", 0777) reviewcmd = "cd " + playblastdir + "; dpacreatereview " + baseFileName + ".mov " + str( create_action.product_repr.spec) print "creating review: " + reviewcmd os.system(reviewcmd) os.system("vlc " + fileName + ".mov &") return True cmds.error("Invalid selections.") return False
def _get_url_config(): from dpa.ptask.area import PTaskArea return PTaskArea.current().config( URL_CONFIG_PATH, composite_ancestors=True, )
def validate(self): cur_spec = PTaskArea.current().spec full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec) product = None if full_spec: try: product = Product.get(full_spec) except ProductError as e: # fall back to input spec try: product = Product.get(self.spec) except ProductError: raise ActionError( 'Could not determine product from: "{s}"'.format( s=self.spec ) ) if product: self._product = product else: raise ActionError( 'Could not determine product from: "{s}"'.format( s=self.spec ) ) if self.publish: vers = self._nums_to_versions(self.publish) self._publish = [v for v in vers if not v.published] if self.unpublish: vers = self._nums_to_versions(self.unpublish) self._unpublish = [v for v in vers if v.unpublish] if self.deprecate: vers = self._nums_to_versions(self.deprecate) self._deprecate = [v for v in vers if not v.deprecated] if self.undeprecate: vers = self._nums_to_versions(self.undeprecate) self._undeprecate = [v for v in vers if v.deprecated] if self.official: vers = self._nums_to_versions(self.official) if len(vers) > 1: raise ActionError("Can't official more than one version.") to_official = vers[0] if to_official.number == self.product.official_version_number: raise ActionError( "Version {v} of '{p}' is already official.".format( v=to_official.number, p=self.product.spec, ) ) if not to_official.published: if not self.publish: self._publish = [to_official] else: self._publish.append(to_official) self._official = to_official if self.publish and self.unpublish: overlap = set([v.spec for v in self.publish]).intersection( set([v.spec for v in self.unpublish])) if len(overlap) > 0: raise ActionError( "Can't publish and unpublish the same versions.") if self.deprecate and self.undeprecate: overlap = set([v.spec for v in self.deprecate]).intersection( set([v.spec for v in self.undeprecate])) if len(overlap) > 0: raise ActionError( "Can't deprecate and undeprecate the same versions.") # XXX publish if not already when officialing # XXX can't official a deprecated version # XXX can't deprecate the official version # XXX can't unpublish something that has subscribers # XXX add active to subscription model if (self.publish is None and self.unpublish is None and self.deprecate is None and self.undeprecate is None and self.official is None and self.noofficial is False): raise ActionError("No actions to perform.")
def _output_options(self): output_type_lbl = QtGui.QLabel("Output:") output_type = QtGui.QComboBox() output_type.addItems(['Automatic', 'Manual']) header_layout = QtGui.QHBoxLayout() header_layout.addStretch() header_layout.addWidget(output_type_lbl) header_layout.addWidget(output_type) header_layout.addStretch() # ---- auto cur_area = PTaskArea.current() self._cur_ptask = PTask.get(cur_area.spec) if self._cur_ptask: self._version = \ cur_area.version or self._cur_ptask.latest_version.number else: self._cur_ptask = None self._version = "None" ptask_lbl = QtGui.QLabel("PTask:") ptask_edit = QtGui.QLineEdit(str(self._cur_ptask)) ptask_edit.setReadOnly(True) version_num = QtGui.QLabel("<B>v" + str(self._version) + "</B>") auto_layout = QtGui.QGridLayout() auto_layout.addWidget(ptask_lbl, 0, 0, QtCore.Qt.AlignRight) auto_layout.addWidget(ptask_edit, 0, 1) auto_layout.addWidget(version_num, 0, 2, QtCore.Qt.AlignLeft) auto_layout.setColumnStretch(0, 0) auto_layout.setColumnStretch(1, 1000) auto_widgets = QtGui.QWidget() auto_widgets.setLayout(auto_layout) # ---- manual dir_lbl = QtGui.QLabel("Directory:") self._dir_edit = QtGui.QLineEdit(os.getcwd()) dir_btn = QtGui.QPushButton() dir_btn.setFlat(True) dir_btn_size = QtCore.QSize(22, 22) dir_btn.setFixedSize(dir_btn_size) dir_btn.setIcon(QtGui.QIcon(self.__class__._dir_path)) dir_btn.setIconSize(dir_btn_size) dir_dialog = QtGui.QFileDialog(self, 'Output directory', os.getcwd()) dir_dialog.setFileMode(QtGui.QFileDialog.Directory) dir_dialog.setOption(QtGui.QFileDialog.ShowDirsOnly, True) dir_dialog.setOption(QtGui.QFileDialog.DontResolveSymlinks, True) dir_dialog.setOption(QtGui.QFileDialog.HideNameFilterDetails, True) dir_dialog.fileSelected.connect(self._dir_edit.setText) dir_btn.clicked.connect(dir_dialog.show) manual_layout = QtGui.QGridLayout() manual_layout.setContentsMargins(0, 0, 0, 0) manual_layout.addWidget(dir_lbl, 0, 0, QtCore.Qt.AlignRight) manual_layout.addWidget(self._dir_edit, 0, 1) manual_layout.addWidget(dir_btn, 0, 2) manual_layout.setColumnStretch(0, 0) manual_layout.setColumnStretch(1, 1000) manual_layout.setColumnStretch(2, 0) manual_widgets = QtGui.QWidget() manual_widgets.setLayout(manual_layout) self._output_stack = QtGui.QStackedWidget() self._output_stack.addWidget(auto_widgets) self._output_stack.addWidget(manual_widgets) output_type.activated.connect(self._output_stack.setCurrentIndex) # ---- layout output_layout = QtGui.QVBoxLayout() output_layout.addLayout(header_layout) output_layout.addWidget(self._output_stack) return output_layout