Exemplo n.º 1
0
 def add_item(self, item):
     """Add menu item. Item will be passed into self.command.
     :param str item: The item to add.
     """
     maya.menu_option(label=item,
                      parent=self.menu,
                      command=lambda a: self.command(item))
Exemplo n.º 2
0
    def init_after_account_selected(self):
        try:
            if not hasattr(self, "submission"):
                self.submission = AzureBatchSubmission(
                    self.tab_index['SUBMIT'], self.frame, self.call)
            if not hasattr(self, "assets"):
                self.assets = AzureBatchAssets(self.tab_index['ASSETS'],
                                               self.frame, self.call)
            if not hasattr(self, "pools"):
                self.pools = AzureBatchPools(self.tab_index['POOLS'],
                                             self.frame, self.call)
            if not hasattr(self, "jobhistory"):
                self.jobhistory = AzureBatchJobHistory(
                    self.tab_index['JOBHISTORY'], self.frame, self.call)
            if not hasattr(self, "env"):
                self.env = AzureBatchEnvironment(self.tab_index['ENV'],
                                                 self.frame, self.call)

            self.config.auth = True
            self.start()
        except Exception as exp:
            if (maya.window("AzureBatch", q=1, exists=1)):
                maya.delete_ui("AzureBatch")
            message = "Batch Plugin Failed to Start: {0}".format(exp)
            maya.error(message)
            raise
Exemplo n.º 3
0
    def call(self, command, *args, **kwargs):
        """Wrap all Batch and Storage API calls in order to handle errors.
        Some errors we anticipate and raise without a dialog (e.g. PoolNotFound).
        Others we raise and display to the user.
        """
        try:
            result = command(*args, **kwargs)
            return self.ensure_iter_called(result)
        except BatchErrorException as exp:
            #if auth error (401) refresh tokens and recreate clients, before repeating the call
            if exp.response.status_code in [401]:
                self.config.refresh_auth_tokens(self.config.batch_auth_token,
                                                self.config.mgmt_auth_token)
                self.config.update_batch_and_storage_client_creds(
                    self.config.batch_auth_token, self.config.mgmt_auth_token)

                result = command(*args, **kwargs)
                try:
                    return self.ensure_iter_called(result)
                except BatchErrorException as exp:
                    self.handle_batch_exception(exp)
            else:
                self.handle_batch_exception(exp)

        except Exception as exp:
            if (maya.window("AzureBatch", q=1, exists=1)):
                maya.delete_ui("AzureBatch")
            exc_type, exc_value, exc_traceback = sys.exc_info()
            self._log.error("".join(
                traceback.format_exception(exc_type, exc_value,
                                           exc_traceback)))
            raise ValueError("Error: {0}".format(exp))
Exemplo n.º 4
0
    def set_thumbnail(self, thumb, height):
        """Set thumbnail image.

        :param str thumb: The path to the thumbnail image.
        :param int height: The height of the image in pixels.
        """
        maya.image(self._thumbnail, edit=True, image=thumb, height=height)
Exemplo n.º 5
0
 def start(self):
     """Place the button in a processing state."""
     maya.button(self._button,
                 edit=True,
                 enable=False,
                 label=self.prob_label)
     maya.refresh()
Exemplo n.º 6
0
    def __init__(self, base, index, layout):
        """Create a new pool reference.

        :param base: The base class for handling pools monitoring functionality.
        :type base: :class:`.AzureBatchPools`
        :param int index: The index of where this reference is displayed on
         the current page.
        :param layout: The layout on which the pool details will be displayed.
        :type layout: :class:`.utils.FrameLayout`
        """
        self.base = base
        self.index = index
        self.layout = layout
        maya.frame_layout(layout,
                          edit=True,
                          collapseCommand=self.on_collapse,
                          expandCommand=self.on_expand)
        self.listbox = maya.col_layout(numberOfColumns=2,
                                       columnWidth=((1, 100), (2, 200)),
                                       rowSpacing=((1, 5), ),
                                       rowOffset=(
                                           (1, "top", 5),
                                           (1, "bottom", 5),
                                       ),
                                       parent=self.layout)
        self.content = []
Exemplo n.º 7
0
    def init_after_subscription_selected(self):
        self.account_status = "Loading"
        maya.refresh()
        if self.batch_account_row is not None:
            maya.delete_ui(self.batch_account_row)
        if self.account_ui_elements:
            maya.delete_ui(self.account_ui_elements)
        self.disable(False)
        self.account_ui_elements = []
        with utils.Row(
                2,
                2, (100, 200), ("left", "left"),
                parent=self.batch_account_framelayout) as batch_account_row:
            self.batch_account_row = batch_account_row
            maya.text(label="Batch Account:    ", align="right")
            with utils.Dropdown(
                    self.select_account_in_dropdown) as account_dropdown:
                self._account_dropdown = account_dropdown
                self._account_dropdown.add_item("")
                accounts = self.base.available_batch_accounts()
                self.accounts_by_name = dict([(account.name, account)
                                              for account in accounts])
                for account in accounts:
                    self._account_dropdown.add_item(account.name)
        self.account_status = "Please select Batch Account"

        self.draw_threads_and_logging_rows(self.frames_layout,
                                           self.account_ui_elements)
        self.disable(True)
        maya.refresh()
Exemplo n.º 8
0
 def load_tasks(self):
     """Get a list of tasks associated with the job."""
     try:
         job = self.jobs[self.selected_job.index]
     except (IndexError, AttributeError):
         self._log.warning("Selected job index does not match jobs list.")
         if not self.selected_job:
             return
         self.selected_job.set_status('unknown')
         self.selected_job.set_progress('unknown')
         self.selected_job.set_tasks('unknown')
         return
     try:
         tasks = list(self._call(self.batch.task.list, job.id))
         completed_tasks = [
             t for t in tasks if t.state == batch.models.TaskState.completed
         ]
         errored_tasks = [
             t for t in completed_tasks if t.execution_info.exit_code != 0
         ]
         state = job.state.value
         if len(tasks) == 0:
             percentage = 0
             state = "Pending"
         else:
             percentage = (100 * len(completed_tasks)) / (len(tasks))
         self.selected_job.set_status(state)
         self.selected_job.set_progress(str(percentage) + '%')
         self.selected_job.set_tasks(len(tasks))
         maya.refresh()
     except Exception as exp:
         self._log.warning("Failed to update job details {0}".format(exp))
         self.ui.refresh()
 def set_marketplace_image_mode(self, *args):
     """Set selected render node type to be a batch published VM image type.
     Displays the Batch VM image selection UI control.
     Command for select_rendernode_type radio buttons.
     """
     self.select_rendernode_type = PoolImageMode.MARKETPLACE_IMAGE.value
     if self.image_config != None:
         maya.delete_ui(self.image_config)
     self.image_config = []
     with utils.FrameLayout(label="Batch Provided Image Settings",
                            collapsable=True,
                            width=325,
                            collapse=False,
                            parent=self.rendernode_config) as framelayout:
         self.image_config.append(framelayout)
         with utils.ColumnLayout(2,
                                 col_width=((1, 80), (2, 160)),
                                 row_spacing=(1, 5),
                                 row_offset=((1, "top", 15), (5, "bottom",
                                                              15)),
                                 parent=framelayout) as os_image_layout:
             self.image_config.append(os_image_layout)
             maya.text(label="Use Image: ",
                       align='left',
                       parent=os_image_layout)
             with utils.Dropdown(self.set_os_image,
                                 parent=os_image_layout) as image_settings:
                 self._image = image_settings
                 for image in self.batch_images:
                     self._image.add_item(image)
Exemplo n.º 10
0
    def start(self, session, assets, pools, env):
        """Load submission tab after plug-in has been authenticated.

        :param session: Authenticated configuration handler.
        :type session: :class:`.AzureBatchConfig`
        :param assets: Asset handler.
        :type assets: :class:`.AzureBatchAssets`
        :param pools: Pool handler.
        :type pools: :class:`.AzureBatchPools`
        :param env: Render node environment handler.
        :type env: :class:`.AzureBatchEnvironment`
        """
        self._log.debug("Starting AzureBatchSubmission...")
        self.batch = session.batch
        self.asset_manager = assets
        self.pool_manager = pools
        self.env_manager = env
        self.data_path = session.path
        if self.renderer:
            self.renderer.delete()
        self._configure_renderer()
        self.renderer.display(self.ui.render_module)
        self.ui.submit_enabled(self.renderer.render_enabled())
        self.ui.is_logged_in()
        maya.refresh()
Exemplo n.º 11
0
 def update_job(self, index):
     """Get the latest details on a specified job.
     Also attempts to find a latest thumbnail to display.
     :param int index: The index of the job displayed on the page
      that is currently selected.
     """
     try:
         self._log.info("Collecting job info...")
         job = self.jobs[index]
         self.selected_job.set_label("loading...")
         loading_thumb = os.path.join(os.environ["AZUREBATCH_ICONS"],
                                      "loading_preview.png")
         self.selected_job.set_thumbnail(loading_thumb, 24)
         maya.refresh()
         job = self._call(self.batch.job.get, job.id)
         self.selected_job.set_status('loading...')
         self.selected_job.set_progress('loading...')
         self.selected_job.set_tasks('loading...')
         self.selected_job.set_submission(job.creation_time.isoformat())
         self.selected_job.set_job(job.id)
         self.selected_job.set_pool(job.pool_info.pool_id)
         self.selected_job.set_label(job.display_name)
         maya.refresh()
         self._log.info("Updated {0}".format(job.display_name))
     except Exception as exp:
         self._log.warning("Failed to update job details {0}".format(exp))
         self.ui.refresh()
Exemplo n.º 12
0
 def refresh(self, *args):
     """Ensure settings are up to date with the current scene and renderer."""
     self.base.refresh()
     if self.select_rendernode_type == PoolImageMode.CONTAINER_IMAGE.value:
         self.set_container_image_mode()
     self.refresh_licenses()
     maya.refresh()
Exemplo n.º 13
0
    def _check_plugins(self):
        """Checks through all plug-ins that are currently in use (according to Maya)
        by the scene. We compile a list of those that we both support and should not
        ignore and return for inclusion in the pre-render script plug-in loading.

        TODO: This has been temporarily disabled because some of the plug-ins were
        causing errors in Maya on the render nodes. Need to investigate and add the
        culprits to the ignore list if necessary.
        """
        try:
            with open(
                    os.path.join(os.environ['AZUREBATCH_TOOLS'],
                                 "supported_plugins.json"), 'r') as plugins:
                supported_plugins = json.load(plugins)
            with open(
                    os.path.join(os.environ['AZUREBATCH_TOOLS'],
                                 "ignored_plugins.json"), 'r') as plugins:
                ignored_plugins = json.load(plugins)
        except EnvironmentError:
            self._log.warning("Unable to load supported plugins")
            return []
        loaded_plugins = maya.plugins(query=True, listPlugins=True)
        unsupported_plugins = [p for p in loaded_plugins \
            if p not in supported_plugins and p not in ignored_plugins]
        if unsupported_plugins:
            warning = (
                "The following plug-ins are used in the scene, but are not "
                "yet supported.\nRendering may be affected.\n")
            for plugin in unsupported_plugins:
                warning += plugin + "\n"
            options = ['Continue', 'Cancel']
            answer = maya.confirm(warning, options)
            if answer == options[-1]:
                raise CancellationException("Submission Aborted")
        return []
Exemplo n.º 14
0
    def display(self, ui, layout, scroll):
        """Create the UI elements that will display this asset depending
        on whether the file path has been resolved or not.
        """
        self.frame = ui
        self.scroll_layout = scroll

        if self.exists:
            self.check_box = maya.symbol_check_box(
                value=True,
                parent=layout,
                onCommand=lambda e: self.include(),
                offCommand=lambda e: self.exclude(),
                annotation="Click to remove asset from submission")
        else:
            self.check_box = maya.symbol_button(
                image="fpe_someBrokenPaths.png",
                parent=layout,
                command=lambda e: self.search(),
                height=17,
                annotation="Add search path")
        self.display_text = maya.text(self.label,
                                      parent=layout,
                                      enable=self.exists,
                                      annotation=self.note,
                                      align="left")
Exemplo n.º 15
0
    def __init__(self, base, frame):
        """Create 'Pools' tab and add to UI frame.

        :param base: The base class for handling pools monitoring functionality.
        :type base: :class:`.AzureBatchPools`
        :param frame: The shared plug-in UI frame.
        :type frame: :class:`.AzureBatchUI`
        """
        self.base = base
        self.label = "Pools "
        self.ready = False
        self.pools_displayed = []
        self.page = maya.form_layout(enableBackground=True)
        with utils.ScrollLayout(v_scrollbar=3, h_scrollbar=0,
                                height=520) as scroll:
            with utils.RowLayout(row_spacing=20) as sublayout:
                if not self.pools_displayed:
                    self.empty_pools = maya.text(label="Loading pool data...",
                                                 font="boldLabelFont",
                                                 parent=sublayout)
                self.pools_layout = sublayout
        with utils.Row(1, 1, 355, "center", (1, "bottom", 0)) as btn:
            self.refresh_button = utils.ProcButton("Refresh", "Refreshing...",
                                                   self.refresh)
        maya.form_layout(self.page,
                         edit=True,
                         attachForm=[(scroll, 'top', 5), (scroll, 'left', 5),
                                     (scroll, 'right', 5), (btn, 'bottom', 5),
                                     (btn, 'left', 0), (btn, 'right', 0)],
                         attachControl=(scroll, "bottom", 5, btn))
        frame.add_tab(self)
        self.is_logged_out()
Exemplo n.º 16
0
 def update_pool(self, index):
     """Update the display for the currently selected pool. This is called
     when a specific pool is selected or refreshed in the UI.
     """
     try:
         pool = self.pools[index]
         self.selected_pool.set_label("loading...")
         maya.refresh()
         pool = self._call(self.batch.pool.get, pool.id)
         _nodes = self._call(self.batch.compute_node.list, pool.id)
         nodes = [n for n in _nodes]
         self.selected_pool.set_id(pool.id)
         self.selected_pool.set_label(
             pool.display_name if pool.display_name else pool.id)
         self.selected_pool.set_dedicated_size(pool)
         self.selected_pool.set_low_pri_size(pool)
         self.selected_pool.set_type("Auto" if pool.id.startswith(
             "Maya_Auto_Pool") else "Provisioned")
         self.selected_pool.set_state(pool.state.value, nodes)
         self.selected_pool.set_allocation(pool.allocation_state.value)
         self.selected_pool.set_created(pool.creation_time)
         self.selected_pool.set_licenses(pool.application_licenses)
         self.selected_pool.set_vm_sku(pool.vm_size)
         self.selected_pool.set_image(
             self.environment.get_image_label(
                 pool.virtual_machine_configuration.image_reference))
         maya.refresh()
     except Exception as exp:
         self._log.warning(str(exp))
         self.ui.refresh()
Exemplo n.º 17
0
 def disable(self, enabled):
     """Disable the tab from user interaction. Used during long running
     processes like upload, and when plug-in is unauthenticated.
     :param bool enabled: Whether to enable the display. False will
      disable the display.
     """
     maya.form_layout(self.page, edit=True, enable=enabled)
Exemplo n.º 18
0
    def __init__(self, id, data_path, dir):
        """Create a new job watcher.

        :param str id: The ID of the job to watch.
        :param str data_path: The path of the AzureBatch config dir.
        :param str dir: The path of directory where outputs will be 
         downloaded.
        """
        self.job_id = id
        self.data_path = data_path
        self.selected_dir = dir
        self._log = logging.getLogger('AzureBatchMaya')
        self.job_watcher = os.path.join(
            os.path.dirname(__file__), "tools", "job_watcher.py")
        platform = get_os()
        if platform == OperatingSystem.windows.value:
            self.proc_cmd = 'system("WMIC PROCESS where (Name=\'mayapy.exe\') get Commandline")'
            self.start_cmd = 'system("start mayapy {0}")'
            self.quotes = '\\"'
            self.splitter = 'mayapy'
        elif platform == OperatingSystem.darwin.value:
            self.proc_cmd = 'system("ps -ef")'
            self.start_cmd = 'system("osascript -e \'tell application \\"Terminal\\" to do script \\"python {0}\\"\'")'
            self.quotes = '\\\\\\"'
            self.splitter = '\n'
        else:
            maya.warning("Cannot launch job watcher: OS not supported.")
            return
        self.start_job_watcher() 
Exemplo n.º 19
0
 def update(self, update):
     """Update the button label with process status.
     :param str update: The status to display on the label.
     """
     update = "{0} [Press ESC to cancel]".format(update)
     maya.button(self._button, edit=True, enable=False, label=update)
     maya.refresh()
Exemplo n.º 20
0
 def __init__(self, log):
     """Create and start new progress bar."""
     self.done = False
     self._log = log
     self._progress = maya.mel('$tmp = $gMainProgressBar')
     maya.progress_bar(self._progress, edit=True,
                       beginProgress=True, isInterruptable=True)
Exemplo n.º 21
0
 def add_row(self, *args):
     """Add new user environment variable from contents of custom_env text
     fields.
     """
     env_var = maya.text_field(self.custom_env_var, query=True, text=True)
     env_val = maya.text_field(self.custom_env_val, query=True, text=True)
     if env_var and env_val:
         maya.table(self.env_vars, edit=True, insertRow=1)
Exemplo n.º 22
0
 def select(self, value):
     """Select a specific option in the menu.
     :param int value: The index of the option to select.
     """
     try:
         maya.menu(self.menu, edit=True, select=int(value))
     except ValueError:
         maya.menu(self.menu, edit=True, value=value)
Exemplo n.º 23
0
 def update(update):
     # Update the % complete in the asset label
     if self.display_text:
         maya.text(self.display_text,
                   edit=True,
                   label="    Uploading {0}% {1}".format(
                       int(update), name))
         maya.refresh()
Exemplo n.º 24
0
 def include(self):
     """Include this asset in the list for files to be uploaded for submission."""
     if self not in self.parent_list:
         self.parent_list.append(self)
     maya.symbol_check_box(
         self.check_box,
         edit=True,
         annotation="Click to remove asset from submission")
Exemplo n.º 25
0
 def enable_watcher(self, opt):
     """Enable whether job watcher will be launched after submission.
     Command for watch_job check box.
     :param bool opt: True if watcher enabled.
     """
     maya.symbol_button(self.dir_button, edit=True, enable=opt)
     maya.text_field(
         self.dir, edit=True, enable=opt, text=self.selected_dir)
Exemplo n.º 26
0
 def set_job(self, value):
     """Set the label for the job ID, and format the portal URL reference
     for the job with this ID.
     Except that with the current portal we have no way to directly link to a job.
     :param str value: The job ID.
     """
     maya.text_field(self._job, edit=True, text=value)
     self.url = "https://portal.azure.com"
Exemplo n.º 27
0
 def set_submission(self, value):
     """Set the label for date/time submitted.
     :param str value: The datetime string to format.
     """
     datetime = value.split('T')
     datetime[1] = datetime[1].split('.')[0]
     label = ' '.join(datetime)
     maya.text(self._submission, edit=True, label=" {0}".format(label))
Exemplo n.º 28
0
    def __init__(self, base, frame):
        """Create 'Jobs' tab and add to UI frame.

        :param base: The base class for handling jobs monitoring functionality.
        :type base: :class:`.AzureBatchJobHistory`
        :param frame: The shared plug-in UI frame.
        :type frame: :class:`.AzureBatchUI`
        """
        self.base = base
        self.label = " Jobs "
        self.ready = False
        self.jobs_displayed = []
        self.page = maya.form_layout(enableBackground=True)

        with utils.Row(1, 1, 360, "center") as lbl:
            self.total = maya.text(label="", font="boldLabelFont")
        self.paging_display()
        with utils.ScrollLayout(v_scrollbar=3, h_scrollbar=0,
                                height=478) as scroll:
            with utils.RowLayout(row_spacing=20) as sublayout:
                if not self.jobs_displayed:
                    self.empty_jobs = maya.text(label="Loading job data...",
                                                align='left',
                                                font="boldLabelFont")
                self.jobs_layout = sublayout

        with utils.Row(1, 1, 355, "center", (1, "bottom", 0)) as btn:
            self.refresh_button = utils.ProcButton("Refresh", "Refreshing...",
                                                   self.refresh)
        maya.form_layout(self.page,
                         edit=True,
                         attachForm=[(lbl, 'top', 0), (lbl, 'left', 5),
                                     (lbl, 'right', 5),
                                     (self.first_btn, 'left', 5),
                                     (self.last_btn, 'right', 5),
                                     (scroll, 'left', 5), (scroll, 'right', 5),
                                     (btn, 'bottom', 5), (btn, 'left', 0),
                                     (btn, 'right', 0)],
                         attachControl=[(self.first_btn, "top", 5, lbl),
                                        (self.prev_btn, "top", 5, lbl),
                                        (self.last_btn, "top", 5, lbl),
                                        (self.next_btn, "top", 5, lbl),
                                        (scroll, "top", 5, self.first_btn),
                                        (scroll, "top", 5, self.next_btn),
                                        (scroll, "top", 5, self.prev_btn),
                                        (scroll, "top", 5, self.last_btn),
                                        (scroll, "bottom", 5, btn)],
                         attachPosition=[
                             (lbl, 'top', 5, 0),
                             (self.first_btn, 'right', 5, 25),
                             (self.prev_btn, 'left', 5, 25),
                             (self.prev_btn, 'right', 5, 50),
                             (self.next_btn, 'right', 5, 75),
                             (self.next_btn, 'left', 5, 50),
                             (self.last_btn, 'left', 5, 75),
                         ])
        frame.add_tab(self)
        self.is_logged_out()
Exemplo n.º 29
0
 def delete(self):
     """Remove this asset from the UI display. This is usually done on
     a refresh of the asset tab in order to wipe the UI for repopulating.
     """
     try:
         self.parent_list.remove(self)
     except ValueError:
         pass
     maya.delete_ui(self.check_box, control=True)
Exemplo n.º 30
0
 def clear_ui(self):
     """Wipe all UI elements in the Assets tab."""
     children = maya.col_layout(self.asset_display,
                                query=True,
                                childArray=True)
     if not children:
         return
     for child in children:
         maya.delete_ui(child, control=True)