Esempio n. 1
0
    def _create_product(self):

        existing = Product.list(
            name=self._name,
            category=self._category,
            ptask=self._ptask.spec,
        )
        
        if len(existing) == 1:
            self._product = existing.pop()
            self._product.update(description=self._description)
            if self.interactive:
                print "\nBase product exists: " + \
                    Style.bright + self._product.spec + Style.reset
        else:
            try:
                self._product = Product.create(
                    ptask=self._ptask.spec,
                    name=self._name,
                    category=self._category,
                    description=self._description,
                    creator=current_username(),
                )
            except ProductError as e:
                raise ActionError("Unable to create product: " + str(e))
            else:
                if self.interactive:
                    print "\nCreated base product: " + \
                        Style.bright + self._product.spec + Style.reset
Esempio n. 2
0
    def _query_products(self):
        # find all available published products based on input
        products = Product.list(category=self.query_values['category'],
                                search=self.query_values['spec'],
                                name=self.query_values['name'])

        self._importable_products = []

        for product in products:
            print product.spec
            print self.query_values['official']
            print self.query_values['published']
            print self.query_values['deprecated']

            if self.query_values['published']:
                if self.query_values['official']:
                    if not self.query_values['deprecated']:
                        product_versions = ProductVersion.list(
                            product=product.spec,
                            published=self.query_values['published'],
                            is_official=self.query_values['official'],
                            deprecated=self.query_values['deprecated'])

            print product_versions
            for pv in product_versions:
                print pv
                self._importable_products.append(pv)

        print self.importable_products
        self._product_widget = EntityTreeWidget(self.importable_products)
        self._product_widget.setFocusPolicy(QtCore.Qt.NoFocus)
Esempio n. 3
0
    def _query_products(self):
        # find all available published products based on input
        products = Product.list(category=self.query_values['category'],
            search=self.query_values['spec'],
            name=self.query_values['name'])

        self._importable_products = []

        for product in products:
            print product.spec
            print self.query_values['official']
            print self.query_values['published']
            print self.query_values['deprecated']

            if self.query_values['published']:
                if self.query_values['official']:
                    if not self.query_values['deprecated']:
                        product_versions = ProductVersion.list(
                            product=product.spec,
                            published=self.query_values['published'],
                            is_official=self.query_values['official'],
                            deprecated=self.query_values['deprecated'])

            print product_versions
            for pv in product_versions:
                print pv
                self._importable_products.append(pv)

        print self.importable_products
        self._product_widget = EntityTreeWidget(self.importable_products)
        self._product_widget.setFocusPolicy(QtCore.Qt.NoFocus)
Esempio n. 4
0
    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
Esempio n. 5
0
    def _process_ptask(self, ptask):

        print " PTASK: " + ptask.spec + " ..."

        ptask_type = ptask.type

        self._data.ptasks[ptask_type] += 1

        for ptask_ver in ptask.versions:

            #if ptask_ver.number > 2: continue  # speed up testing XXX

            print "  VER: " + ptask_ver.spec

            self._data.ptask_versions[ptask_type] += 1

            for sub in ptask_ver.subscriptions:

                print "   SUB: " + sub.product_version_spec

                sub_product = sub.product_version.product
                self._data.ptask_subscriptions[ptask_type] += 1

        for product in Product.list(ptask=ptask.spec):

            print "  PRODUCT: " + product.name_spec

            category = product.category
            self._data.ptask_products[ptask_type] += 1
            self._data.products[category] += 1

            for product_ver in product.versions:

                print "   PRODUCT VER: " + product_ver.spec

                self._data.ptask_product_versions[ptask_type] += 1
                self._data.product_versions[category] += 1

                for product_repr in product_ver.representations:

                    print "    PRODUCT REPR: " + product_repr.spec

                    file_type = product_repr.type
                    self._data.product_representations[category] += 1

                    if os.path.exists(product_repr.area.path):
                        for file_name in os.listdir(product_repr.area.path):
                            if file_name.endswith(file_type):
                                print "          FILE: " + file_name
                                self._data.product_repr_files[category] += 1
                                self._data.product_repr_files_by_type[
                                    file_type] += 1

        # recursively iterate over all children
        for child_ptask in ptask.children:
            self._process_ptask(child_ptask)
Esempio n. 6
0
    def _process_ptask(self, ptask):

        print " PTASK: " + ptask.spec + " ..."

        ptask_type = ptask.type

        self._data.ptasks[ptask_type] += 1

        for ptask_ver in ptask.versions:

            #if ptask_ver.number > 2: continue  # speed up testing XXX

            print "  VER: " + ptask_ver.spec

            self._data.ptask_versions[ptask_type] += 1
            
            for sub in ptask_ver.subscriptions:

                print "   SUB: " + sub.product_version_spec

                sub_product = sub.product_version.product
                self._data.ptask_subscriptions[ptask_type] += 1 

        for product in Product.list(ptask=ptask.spec):

            print "  PRODUCT: " + product.name_spec

            category = product.category
            self._data.ptask_products[ptask_type] += 1
            self._data.products[category] += 1

            for product_ver in product.versions:

                print "   PRODUCT VER: " + product_ver.spec

                self._data.ptask_product_versions[ptask_type] += 1
                self._data.product_versions[category] += 1
        
                for product_repr in product_ver.representations:

                    print "    PRODUCT REPR: " + product_repr.spec
                    
                    file_type = product_repr.type
                    self._data.product_representations[category] += 1

                    if os.path.exists(product_repr.area.path):
                        for file_name in os.listdir(product_repr.area.path):
                            if file_name.endswith(file_type):
                                print "          FILE: " + file_name
                                self._data.product_repr_files[category] += 1
                                self._data.product_repr_files_by_type[file_type] += 1

        # recursively iterate over all children
        for child_ptask in ptask.children:
            self._process_ptask(child_ptask)
Esempio n. 7
0
    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
Esempio n. 8
0
    def _process_ptask(self, ptask):

        ptask_type = ptask.type

        self._data.ptasks[ptask_type] += 1

        for ptask_ver in ptask.versions:

            #if ptask_ver.number > 2: continue  # speed up testing XXX

            self._data.ptask_versions[ptask_type] += 1
            
            for sub in ptask_ver.subscriptions:

                sub_product = sub.product_version.product
                self._data.ptask_subscriptions[ptask_type] += 1 

        for product in Product.list(ptask=ptask.spec):

            category = product.category
            self._data.ptask_products[ptask_type] += 1
            self._data.products[category] += 1

            for product_ver in product.versions:

                self._data.ptask_product_versions[ptask_type] += 1
                self._data.product_versions[category] += 1
        
                for product_repr in product_ver.representations:

                    file_type = product_repr.type
                    self._data.product_representations[category] += 1

                    if os.path.exists(product_repr.area.path):
                        for file_name in os.listdir(product_repr.area.path):
                            if file_name.endswith(file_type):
                                self._data.product_repr_files[category] += 1
                                self._data.product_repr_files_by_type[file_type] += 1

        # recursively iterate over all children
        for child_ptask in ptask.children:
            self._process_ptask(child_ptask)
Esempio n. 9
0
    def prompt(self):

        print ""

        product_display = " [{b}{p}{r}]".format(
            b=Style.bright,
            p=self._product,
            r=Style.reset,
        )

        # category menu
        if not self._category:
            self._category = Output.prompt_menu(
                "Product categories",
                "{pd} category".format(pd=product_display),
                zip(*[Product.category_names()] * 2),
            )
       
        # description
        if not self._description:
            self._description = Output.prompt(
                '{pd} description'.format(pd=product_display),
                blank=False,
            )
        
        # file type
        if not self._file_type:
            if not self._file_type:
                self._file_type = Output.prompt(
                    "{pd} file type".format(pd=product_display),
                    blank=False,
                )

        # resolution
        if not self._resolution:
            self._resolution = Output.prompt(
                "{pd} resolution (Return if none)".format(pd=product_display),
                blank=True,
            )
            if not self._resolution:
                self._resolution = 'none'
Esempio n. 10
0
    def validate(self):

        if self.interactive:
            print "\nValidating product arguments ..."

        # should have a valid product name, 
        self._name = validate_product_name(self._name)

        if self._category:
            if not self._category in Product.category_names():
                raise ActionError("Unrecognized category.")
        else:
            raise ActionError("Category is required.")

        if not self._description:
            raise ActionError("Description is required.")

        # ptask
        if not isinstance(self._ptask, PTask):
            try:
                self._ptask = PTask.get(self._ptask)
            except PTaskError:
                raise ActionError("Could not determine ptask.")
                
        if self._version:
            self._ptask_version = self._ptask.version(self._version)
        else:
            self._ptask_version = self._ptask.latest_version

        if not self._ptask_version:
            raise ActionError("Could not determine ptask version.")

        if not self._note:
            self._note = "None"

        if self._path:
            if not os.path.exists(self._path):
                raise ActionError("Supplied path does not exist.")
            if (os.path.isdir(self._path) and 
                not self._path.endswith(os.path.sep)):
                self._path += os.path.sep
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
    def validate(self):

        # need to identify the product version being subscribed to and the
        # ptask version subscribing to it.

        # get the product
        if not isinstance(self._product, Product):
            try:
                self._product = Product.get(self._product)
            except ProductError:
                raise ActionError("Unable to find product: " +
                                  str(self._product))

        # get 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))

        # find the version to subscribe to
        if isinstance(self._product_version, ProductVersion):
            pass
        elif self._product_version:
            matches = ProductVersion.list(product=self.product.spec,
                                          number=int(self._product_version))
            if len(matches) != 1:
                raise ActionError(
                    "Unable to find product '{p}' at version '{v}'".format(
                        p=self.product.spec, v=self._product_version))
            else:
                self._product_version = matches[0]
        else:
            # get the official version
            official_version = self._product.official_version
            if official_version:
                self._product_version = official_version
            else:
                # get the latest, non-deprecated version
                latest_published = self._product.latest_published()
                if latest_published:
                    self._product_version = latest_published
                else:
                    raise ActionError(
                        "No available versions of product '{p}'".format(
                            p=self._product.spec))

        # find the version of the ptask doing the subscribing
        if isinstance(self._ptask_version, PTaskVersion):
            pass
        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 the rules below need to be exposed outside of just the create
        # code. UIs, for example, should be able to check these cases before
        # allowing the user to perform actions...

        # if this ptask has any existing published versions, error out
        published = ProductVersion.list(ptask_version=self._ptask_version,
                                        published=True)
        if len(published) > 0:
            raise ActionError(
                "Unable to create new subscription. This ptask version " + \
                "already has published product versions.\n" + \
                "You need to version up to modify subscriptions."
            )

        # see if there is an existing subscription:
        self._existing_sub = self._ptask_version.is_subscribed(self._product)
        if self._existing_sub:

            if (self._existing_sub.product_version_spec == \
                self._product_version.spec):
                raise ActionError("Subscription already exists!")

        if self._product_version.deprecated:
            raise ActionError(
                "Product version is deprecated. Specify an alternate version.")

        # make sure product is published or from same ptask
        if (not self._product_version.published
                and not self._product.ptask_spec == self._ptask.spec):
            raise ActionError(
                "Product version is not published. Specify a published version."
            )
Esempio n. 14
0
    def export_confirm_page(self):

        if hasattr(self, '_export_confirm_page'):
            return self._export_confirm_page

        self._descriptions = defaultdict(dict)

        ptask_version = self.session.ptask_version
        ptask = ptask_version.ptask

        layout = QtGui.QVBoxLayout()

        note_lbl = QtGui.QLabel(
            "Describe the work you did on the entities being exported:   (required)"
        )
        self._note_edit = QtGui.QLineEdit()
        self._note_edit.setFocus()

        self._note_edit.textChanged.connect(
            lambda t: self._check_descriptions())

        layout.addWidget(note_lbl)
        layout.addWidget(self._note_edit)
        layout.addSpacing(5)

        products_layout = QtGui.QFormLayout()

        # get this ptask's products
        products = Product.list(ptask=ptask.spec)

        for entity_item in self.entity_widget.entity_items:

            entity = entity_item.entity

            existing_products = [
                p for p in products if p.name == entity.display_name
                and p.category == entity.category
            ]

            product_desc = QtGui.QLineEdit()
            if existing_products:
                product_desc.setText(existing_products[0].description)

            product_lbl = QtGui.QLabel(
                "<b>{n}</b>".format(n=entity.product_name))

            products_layout.addRow(product_lbl, product_desc)

            self._descriptions[entity]['label'] = product_lbl
            self._descriptions[entity]['widget'] = product_desc

            product_desc.textChanged.connect(
                lambda t: self._check_descriptions())

        products_widget = QtGui.QWidget()
        products_widget.setLayout(products_layout)

        scroll_area = QtGui.QScrollArea()
        scroll_area.setFocusPolicy(QtCore.Qt.NoFocus)
        scroll_area.setWidgetResizable(True)
        scroll_area.setWidget(products_widget)

        product_lbl = QtGui.QLabel(
            "Enter/update descriptions for the products:   (required)")
        product_lbl.setWordWrap(True)

        layout.addWidget(product_lbl)
        layout.addWidget(scroll_area)
        layout.addSpacing(5)

        self._publish_check = QtGui.QCheckBox("Publish all after Export")
        self._publish_check.setChecked(True)

        self._version_check = QtGui.QCheckBox("Version up after Publish")
        self._version_check.setChecked(True)

        # if publish gets toggled, update the version check accordingly
        self._publish_check.toggled.connect(
            lambda s: self._version_check.setEnabled(
                s) or self._version_check.setChecked(s))

        layout.addWidget(self._publish_check)
        layout.addWidget(self._version_check)
        layout.addSpacing(5)

        confirm_lbl = QtGui.QLabel("<b>Export to {p} v{v}?</b>".\
            format(p=ptask.spec, v=ptask_version.number))
        confirm_lbl.setAlignment(QtCore.Qt.AlignCenter)
        layout.addWidget(confirm_lbl)

        self._export_confirm_page = QtGui.QWizardPage()
        self._export_confirm_page.setTitle("Confirm")
        self._export_confirm_page.setSubTitle(
            "Describe and confirm the folowing exports :")
        self._export_confirm_page.setLayout(layout)

        return self._export_confirm_page
Esempio n. 15
0
    def export_confirm_page(self):

        if hasattr(self, '_export_confirm_page'):
            return self._export_confirm_page

        self._descriptions = defaultdict(dict)

        ptask_version = self.session.ptask_version
        ptask = ptask_version.ptask

        layout = QtGui.QVBoxLayout()

        note_lbl = QtGui.QLabel(
            "Describe the work you did on the entities being exported:   (required)")
        self._note_edit = QtGui.QLineEdit()
        self._note_edit.setFocus()

        self._note_edit.textChanged.connect(
            lambda t: self._check_descriptions())

        layout.addWidget(note_lbl)
        layout.addWidget(self._note_edit)
        layout.addSpacing(5)

        products_layout = QtGui.QFormLayout()

        # get this ptask's products
        products = Product.list(ptask=ptask.spec)

        for entity_item in self.entity_widget.entity_items:

            entity = entity_item.entity

            existing_products = [p for p in products 
                if p.name == entity.display_name and 
                   p.category == entity.category]

            product_desc = QtGui.QLineEdit()
            if existing_products:
                product_desc.setText(existing_products[0].description)

            product_lbl = QtGui.QLabel("<b>{n}</b>".format(n=entity.product_name))
                
            products_layout.addRow(product_lbl, product_desc)

            self._descriptions[entity]['label'] = product_lbl
            self._descriptions[entity]['widget'] = product_desc

            product_desc.textChanged.connect(
                lambda t: self._check_descriptions())

        products_widget = QtGui.QWidget()
        products_widget.setLayout(products_layout)

        scroll_area = QtGui.QScrollArea()
        scroll_area.setFocusPolicy(QtCore.Qt.NoFocus)
        scroll_area.setWidgetResizable(True)
        scroll_area.setWidget(products_widget)

        product_lbl = QtGui.QLabel(
            "Enter/update descriptions for the products:   (required)")
        product_lbl.setWordWrap(True)

        layout.addWidget(product_lbl)
        layout.addWidget(scroll_area)
        layout.addSpacing(5)

        self._publish_check = QtGui.QCheckBox("Publish all after Export")
        self._publish_check.setChecked(True)

        self._version_check = QtGui.QCheckBox("Version up after Publish")
        self._version_check.setChecked(True)
        
        # if publish gets toggled, update the version check accordingly
        self._publish_check.toggled.connect(
            lambda s: self._version_check.setEnabled(s) or 
                      self._version_check.setChecked(s)
        )

        layout.addWidget(self._publish_check)
        layout.addWidget(self._version_check)
        layout.addSpacing(5)

        confirm_lbl = QtGui.QLabel("<b>Export to {p} v{v}?</b>".\
            format(p=ptask.spec, v=ptask_version.number))
        confirm_lbl.setAlignment(QtCore.Qt.AlignCenter)
        layout.addWidget(confirm_lbl)

        self._export_confirm_page = QtGui.QWizardPage()
        self._export_confirm_page.setTitle("Confirm")
        self._export_confirm_page.setSubTitle(
            "Describe and confirm the folowing exports :")
        self._export_confirm_page.setLayout(layout)

        return self._export_confirm_page
Esempio n. 16
0
 def product(self):
     from dpa.product import Product
     return Product.get(self.product_spec)
Esempio n. 17
0
 def product(self):
     from dpa.product import Product
     return Product.get(self.product_spec)
Esempio n. 18
0
    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.")
Esempio n. 19
0
    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.")
Esempio n. 20
0
    def validate(self):

        # need to identify the product version being subscribed to and the
        # ptask version subscribing to it.

        # get the product
        if not isinstance(self._product, Product):
            try:
                self._product = Product.get(self._product)
            except ProductError:
                raise ActionError("Unable to find product: " + str(self._product))

        # get 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))

        # find the version to subscribe to
        if isinstance(self._product_version, ProductVersion):
            pass
        elif self._product_version:
            matches = ProductVersion.list(product=self.product.spec, number=int(self._product_version))
            if len(matches) != 1:
                raise ActionError(
                    "Unable to find product '{p}' at version '{v}'".format(p=self.product.spec, v=self._product_version)
                )
            else:
                self._product_version = matches[0]
        else:
            # get the official version
            official_version = self._product.official_version
            if official_version:
                self._product_version = official_version
            else:
                # get the latest, non-deprecated version
                latest_published = self._product.latest_published()
                if latest_published:
                    self._product_version = latest_published
                else:
                    raise ActionError("No available versions of product '{p}'".format(p=self._product.spec))

        # find the version of the ptask doing the subscribing
        if isinstance(self._ptask_version, PTaskVersion):
            pass
        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 the rules below need to be exposed outside of just the create
        # code. UIs, for example, should be able to check these cases before
        # allowing the user to perform actions...

        # if this ptask has any existing published versions, error out
        published = ProductVersion.list(ptask_version=self._ptask_version, published=True)
        if len(published) > 0:
            raise ActionError(
                "Unable to create new subscription. This ptask version "
                + "already has published product versions.\n"
                + "You need to version up to modify subscriptions."
            )

        # see if there is an existing subscription:
        self._existing_sub = self._ptask_version.is_subscribed(self._product)
        if self._existing_sub:

            if self._existing_sub.product_version_spec == self._product_version.spec:
                raise ActionError("Subscription already exists!")

        if self._product_version.deprecated:
            raise ActionError("Product version is deprecated. Specify an alternate version.")

        # make sure product is published or from same ptask
        if not self._product_version.published and not self._product.ptask_spec == self._ptask.spec:
            raise ActionError("Product version is not published. Specify a published version.")