def _complete(self, spec, relative_to=None): in_spec = self.spec.strip().strip(PTaskSpec.SEPARATOR) full_spec = PTaskSpec.get(in_spec, relative_to=relative_to) ptask_area = None # is the supplied spec a ptask area? if so, print sub directories # if not, get the parent spec and print its sub directories try: ptask_area = PTaskArea(full_spec) except PTaskAreaError: in_spec = PTaskSpec.parent(in_spec) full_spec = PTaskSpec.parent(full_spec) try: ptask_area = PTaskArea(full_spec) except PTaskAreaError: pass if not ptask_area: return # append the child name to the input spec and print them out for completion match_specs = [] for area_dir in ptask_area.dirs(children=True, product_dirs=True): if in_spec: match_specs.append(in_spec + PTaskSpec.SEPARATOR + area_dir) else: match_specs.append(area_dir) return [m + PTaskSpec.SEPARATOR for m in match_specs]
def _link_sub(self, sub, app): area = PTaskArea(self.ptask.spec, version=self.version) product_ver = sub.product_version try: product_ver_area = PTaskArea(product_ver.spec) except PTaskAreaError as e: raise ActionError( "Unable to locate product directory for: " + product_ver.spec ) product_ver_path = product_ver_area.path product = product_ver.product product_ver_import_dir = os.path.join('import', app, product.name) try: area.provision(product_ver_import_dir) except PTaskAreaError as e: raise ActionError( "Failed to provision product import dir: " + str(e)) link_name = os.path.join(area.path, product_ver_import_dir, product.category) print "Creating subscription {a} link for: {pv}".format( a=app, pv=product_ver.spec) os.symlink(product_ver_path, link_name) product_ver_area = PTaskArea(product_ver.spec)
def import_path(self, app="global"): product = self.product_version.product area = PTaskArea(self.ptask_version.ptask.spec) import_dir = area.dir(dir_name="import", verify=False, path=True) path = os.path.join(import_dir, app, product.name, product.category) if not os.path.exists(path): raise ProductSubscriptionError("Import path does not exist.") return path
def import_path(self, app='global'): product = self.product_version.product area = PTaskArea(self.ptask_version.ptask.spec) import_dir = area.dir(dir_name="import", verify=False, path=True) path = os.path.join(import_dir, app, product.name, product.category) if not os.path.exists(path): raise ProductSubscriptionError("Import path does not exist.") return path
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 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 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 _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 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 area(self): """:returns: PTaskArea for this ptask.""" if not hasattr(self, '_area'): self._area = PTaskArea(self.spec) return self._area
def _create_area(self): try: self._product_area = PTaskArea.create(self.product_repr) except PTaskAreaError as e: raise ActionError( "Unable to create product area on disk: " + str(e))
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 _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 _create_ptask_area(self): # ---- create the directory path if it doesn't exist try: self._ptask_area = PTaskArea(self.ptask.spec) except PTaskAreaError: pass else: if not self.force: raise ActionError("PTask area already exists.") if not self.ptask_area: try: self._ptask_area = PTaskArea.create(self.ptask) except PTaskAreaError as e: raise ActionError("Failed to create ptask area: " + str(e))
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 _get_filter_rules(self, ptask): ptask_area = PTaskArea(ptask.spec, validate=False) filter_config = ptask_area.config( FILTER_RULES_CONFIG_PATH, composite_ancestors=True, ) includes = [] excludes = [] if 'includes' in filter_config: includes = filter_config.includes if 'excludes' in filter_config: excludes = filter_config.excludes return (includes, excludes)
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 _link_sub(self, sub, app): area = PTaskArea(self.ptask.spec, version=self.version) product_ver = sub.product_version try: product_ver_area = PTaskArea(product_ver.spec) except PTaskAreaError as e: raise ActionError("Unable to locate product directory for: " + product_ver.spec) product_ver_path = product_ver_area.path product = product_ver.product product_ver_import_dir = os.path.join('import', app, product.name) try: area.provision(product_ver_import_dir) except PTaskAreaError as e: raise ActionError("Failed to provision product import dir: " + str(e)) link_name = os.path.join(area.path, product_ver_import_dir, product.category) print "Creating subscription {a} link for: {pv}".format( a=app, pv=product_ver.spec) os.symlink(product_ver_path, link_name) product_ver_area = PTaskArea(product_ver.spec)
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(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 __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 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 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): 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 _prep_import_dir(self): area = PTaskArea(self.ptask.spec, version=self.version) import_dir = area.dir(dir_name="import", verify=False, path=True) if os.path.exists(import_dir): print "Cleaning up existing import directory." try: shutil.rmtree(import_dir) except Exception as e: raise ActionError("Failed to remove old import dir: " + str(e)) global_import_dir = os.path.join('import', 'global') try: print "Provisioning new import directory." area.provision('import') area.provision(global_import_dir) except PTaskAreaError as e: raise ActionError("Failed to provision global import directory: " + str(e)) return area.dir(dir_name=global_import_dir, path=True)
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): 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 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 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): 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