Example #1
0
    def validate(self):

        try:
            self._sub_id = int(self._sub_id)
        except ValueError:
            raise ActionError("Invalid subscription id.")

        # make sure subscription exists
        matches = ProductSubscription.list(id=self._sub_id)
        if len(matches) != 1:
            raise ActionError(
                "Unable to identify subscription for id: " + str(self._sub_id)
            )

        self._subscription = matches[0]

        # make sure subsription is not locked
        if self._subscription.locked:
            raise ActionError("Can't remove locked subscription.")

        # make sure ptask version has no published products
        if self._subscription.ptask_version.published:
            raise ActionError(
                "Can't modify subscriptions. " + \
                "The ptask version has published products."
            )
Example #2
0
    def _create_ptask(self):

        parent = PTaskSpec.parent(self.spec)
        name = PTaskSpec.name(self.spec)

        # create
        if not self.ptask:
            try:
                self.logger.debug("Creating ptask: " + str(self.spec))
                self._ptask = PTask.create(
                    name,
                    self.ptask_type,
                    self.description,
                    creator_username=self.creator,
                    parent_spec=parent,
                    start_date=str(self.start_date),
                    due_date=str(self.due_date),
                )
            except PTaskError as e:
                raise ActionError("Failed to create ptask: " + str(e))
        # update
        else:
            try:
                self.logger.debug("Updating ptask: " + str(self.spec))
                self.ptask.update(
                    description=self.description,
                    start_date=str(self.start_date),
                    due_date=str(self.due_date),
                )
            except PTaskError as e:
                raise ActionError("Failed to update ptask: " + str(e))
Example #3
0
    def _ids_to_subs(self, sub_ids):

        subs = []

        if not sub_ids:
            return subs

        for sub_id in sub_ids:

            if isinstance(sub_id, ProductSubscription):
                subs.append(sub_id)
                continue

            try:
                sub = int(sub_id)
            except:
                raise ActionError("Could not determine sub from: {s}".\
                    format(s=sub_id))
            else:
                matches = ProductSubscription.list(id=sub_id)
                if len(matches) != 1:
                    raise ActionError("Unable to identify sub for id: " + \
                        str(sub_id))
                else:
                    subs.append(matches[0])

        return subs
Example #4
0
    def _create_version(self):

        new_version = self.ptask.next_version_number
        location_code = current_location_code()

        try:
            self._new_ptask_version = PTaskVersion.create(
                current_username(),
                "in progress...".format(n=new_version),
                location_code,
                ptask_spec=self.ptask.spec,
                number=new_version,
                parent_spec=self.source_version.spec,
            ) 
        except PTaskVersionError as e:
            raise ActionError("Failed to create ptask version: " + str(e))
        else:
            print "\nNew version successfully created in the database."

        # ---- provision a version directory in the ptask area

        try:
            self.ptask.area.provision(
                self.ptask.area.dir(version=new_version, verify=False)
            )
        except PTaskAreaError as e:
            raise ActionError("Unable to provision version directory.")
        else:
            print "\nSuccessfully provisioned directory for version: " + \
                str(new_version)
Example #5
0
    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)
Example #6
0
    def execute(self):

        try:
            ProductSubscription.delete(
                self.subscription.ptask_version_spec,
                self.subscription.product_version_spec,
            )
        except ProductSubscriptionError as e:
            raise ActionError("Subscription removal failed: " + str(e))
        else:
            if self.interactive:
                print "\nSubscription removed.\n"

        if self._no_refresh:
            return

        # refresh the subscriptions on disk
        refresh_action_cls = ActionRegistry().get_action('refresh', 'subs')
        if not refresh_action_cls:
            raise ActionError("Could not find sub refresh action.")

        try:
            refresh_action = refresh_action_cls(
                self.subscription.ptask_version.ptask)
            refresh_action.interactive = False
            refresh_action()
        except ActionError as e:
            raise ActionError("Failed to refresh subs on disk: " + str(e))
Example #7
0
    def __init__(self,
                 spec,
                 ptask_type=None,
                 description=None,
                 creator=None,
                 start_date=None,
                 due_date=None,
                 source=None,
                 force=True):
        super(PTaskCreateAction, self).__init__(
            spec,
            ptask_type=ptask_type,
            description=description,
            creator=creator,
            start_date=start_date,
            due_date=due_date,
            source=source,
            force=force,
        )

        # allow calling code to override the target to specify the ptask type
        # to create
        if ptask_type is None:
            if self.__class__.target_type is not 'ptask':
                ptask_type = self.__class__.target_type
            else:
                raise ActionError("PTask type is required.")

        # do some initial validation on the supplied spec
        parent = PTaskSpec.parent(spec)

        if parent != "":
            try:
                parent = PTask.get(parent)
            except PTaskError:
                raise ActionError("Parent ptask does not exist: " + parent)

        name = PTaskSpec.name(spec)
        try:
            name = validate_ptask_name(name)
        except PTaskError as e:
            raise ActionError("Invalid ptask name: " + str(e))

        # input
        self._spec = spec
        self._ptask_type = ptask_type
        self._description = description
        self._creator = creator
        self._start_date = start_date
        self._due_date = due_date
        self._source = source
        self._force = force

        # to create
        self._ptask = None
        self._ptask_area = None
        self._ptask_version = None
Example #8
0
    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,
        )
Example #9
0
    def _source_another_ptask(self):

        source_action_class = ActionRegistry().get_action('source', 'ptask')
        if not source_action_class:
            raise ActionError("Could not find ptask source action.")

        try:
            source_action = source_action_class(
                source=self.source,
                destination=self.ptask,
                force=True,
            )
            source_action.interactive = False
            source_action()

        except ActionError as e:
            raise ActionError("Failed to source ptask: " + str(e))

        exceptions = []

        # copy the subscriptions from the source ptask
        self._source_subs(self.source, self.ptask)

        # recursively create child ptasks from the source
        for source_child in self.source.children:

            try:
                child_spec = \
                    self.ptask.spec + PTaskSpec.SEPARATOR + source_child.name
                child_create = PTaskCreateAction(
                    child_spec,
                    ptask_type=source_child.type,
                    description="Sourced from: " + source_child.spec,
                    creator=self.creator,
                    start_date=self.start_date,
                    due_date=self.due_date,
                    source=source_child,
                    force=True,
                )
                child_create.interactive = False
                child_create()
            except ActionError as e:
                exceptions.append(e)

        if exceptions:
            msg = "\n".join([str(e) for e in exceptions])
            raise ActionError("Problem sourcing: " + self.source.spec +
                              "\n\n" + msg)
Example #10
0
    def _create_status(self):
        
        existing = ProductRepresentationStatus.list(
            product_representation=self._product_repr.spec,
            location=current_location_code(),
        )

        if len(existing) == 1:
            self._product_repr_status = existing.pop()
            if self.interactive:
                print "\nProduct representation status exists: " + \
                    Style.bright + self._product_repr_status.spec + Style.reset
        else:
            try:
                self._product_repr_status = ProductRepresentationStatus.create(
                    product_representation=self._product_repr.spec,
                    location=current_location_code(),
                    status=1,
                )
            except ProductRepresentationStatusError as e:
                raise ActionError(
                    "Unable to create product representation status: " + str(e))
            else:
                if self.interactive:
                    print "\nCreated product representation status: " + \
                        Style.bright + self._product_repr_status.spec + \
                        Style.reset
Example #11
0
 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))
Example #12
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
Example #13
0
    def _get_ptask_spec_from_history(self):

        # allow selection via history list
        try:
            self.spec = self._get_ptask_spec_history()[int(self.previous)]
        except Exception as e:
            raise ActionError("Invalid ptask history index.")
Example #14
0
    def _copy_subs(self):

        if self.interactive:
            print "\nCopying forward subscriptions:"

        ptask_version_spec = self.new_ptask_version
        exceptions = []
        
        for sub in self.source_version.subscriptions:
            try:
                new_sub = ProductSubscription.create(
                    ptask_version_spec,
                    sub.product_version_spec,
                )
            except ProductSubscriptionError as e:
                exceptions.append((sub, e))
            else:
                print "  " + Style.bright + \
                    str(sub.product_version_spec) + Style.normal

        if exceptions:
            msgs = []
            for (sub, e) in exceptions:
                msgs.append(sub.product_version_spec + ": " + str(e))
            
            raise ActionError(
                "Unable to copy forward some subscriptions:\n\n" + \
                    "\n".join(msgs)
            )
Example #15
0
    def _create_version(self):

        existing = ProductVersion.list(
            ptask_version=self._ptask_version.spec,
            product=self._product.spec,
        )

        if len(existing) == 1:
            self._product_version = existing.pop()
            self._product_version.update(release_note=self._note)
            if self.interactive:
                print "\nProduct version exists: " + \
                    Style.bright + self._product_version.spec + Style.reset
        else:
            try:
                self._product_version = ProductVersion.create(
                    ptask_version=self._ptask_version.spec,
                    product=self._product.spec,
                    release_note=self._note,
                    creator=current_username(),
                )
            except ProductVersionError as e:
                raise ActionError("Unable to create product version: " + str(e))
            else:
                if self.interactive:
                    print "\nCreated product version: " + \
                        Style.bright + self._product_version.spec + Style.reset
Example #16
0
    def _refresh_subs(self):

        if self.interactive:
            print "\nRefreshing subscriptions."
            
        # refresh the subscriptions on disk
        refresh_action_cls = ActionRegistry().get_action('refresh', 'subs')
        if not refresh_action_cls:
            raise ActionError("Could not find sub refresh action.")

        try:
            refresh_action = refresh_action_cls(self.ptask)
            refresh_action.interactive = False
            refresh_action()
        except ActionError as e:
            raise ActionError("Failed to refresh subs on disk: " + str(e))
Example #17
0
    def _create_representation(self):

        existing = ProductRepresentation.list(
            product_version=self._product_version.spec,
            resolution=self._resolution,
            representation_type=self._file_type,
        )

        if len(existing) == 1:
            self._product_repr = existing.pop()
            if self.interactive:
                print "\nProduct representation exists: " + \
                    Style.bright + self._product_repr.spec + Style.reset
        else:
            try:
                self._product_repr = ProductRepresentation.create(
                     product_version=self._product_version.spec,
                     resolution=self._resolution,
                     representation_type=self._file_type,
                     creation_location=current_location_code(),
                     creator=current_username(),
                )
            except ProductRepresentationError as e:
                raise ActionError(
                    "Unable to create product representation: " + str(e))
            else:
                if self.interactive:
                    print "\nCreated product representation: " + \
                        Style.bright + self._product_repr.spec + Style.reset
Example #18
0
    def execute(self):

        # ---- get the actions we need

        create_action_cls = ActionRegistry().get_action('create', 'sub')
        if not create_action_cls:
            raise ActionError("Could not find create sub action.")

        refresh_action_cls = ActionRegistry().get_action('refresh', 'subs')
        if not refresh_action_cls:
            raise ActionError("Could not find sub refresh action.")

        # ---- use the create sub action to create/replace the subs

        errors = []

        for sub in self.subs_to_source:

            product_version = sub.product_version
            product = product_version.product

            try:
                create_action = create_action_cls(
                    product=product,
                    ptask=self.current_ptask,
                    version=product_version,
                    ptask_version=self.current_ptask_version,
                    no_refresh=True)
                create_action.interactive = False
                create_action()
            except ActionError as e:
                errors.append(e)

        # ---- refresh the subs' import dirs

        try:
            refresh_action = refresh_action_cls(self.current_ptask)
            refresh_action.interactive = False
            refresh_action()
        except ActionError as e:
            raise ActionError("Failed to refresh subs on disk: " + str(e))

        # ---- spit some errors if need be

        if errors:
            raise ActionError("Errors occurred during source:\n" + \
                "\n    ".join([str(e) for e in errors]))
Example #19
0
    def _parse_product(self):

        # split the supplied product string to determine additional parts. 
        # this sets unknown values to None
        (name, cat, ver, file_type, res) = list(
            self._product.split(PTaskSpec.SEPARATOR, 5) + [None] * 5
        )[0:5]

        # name
        self._name = name

        # category
        if cat:
            if self._category and self._category != cat:
                raise ActionError(
                    "Different categories specified: {c1} & {c2}".format(
                        c1=self._category, c2=cat))
            self._category = cat

        # version 
        if ver:
            try:
                ver = int(ver)
            except ValueError:
                raise ActionError("Invalid version specified.")

            if self._version and self._version != ver:
                raise ActionError(
                    "Different versions specified: {v1} & {v2}".format(
                        v1=self._version, v2=ver))
            self._version = ver

        # file_type
        if file_type:
            if self._file_type and self._file_type != file_type:
                raise ActionError(
                    "Different file types specified: {t1} & {t2}".format(
                        t1=self._file_type, t2=file_type))
            self._file_type = file_type

        # resolution
        if res: 
            if self._resolution and self._resolution != res:
                raise ActionError(
                    "Different resolutions specified: {r1} & {r2}".format(
                        r1=self._resolution, c2=res))
            self._resolution = res
Example #20
0
    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))
Example #21
0
    def validate(self):

        if not self._lock and not self._unlock:
            raise ActionError(
                "Must supply an action to perform (lock, unlock, etc.)")

        self._lock = self._ids_to_subs(self._lock)
        self._unlock = self._ids_to_subs(self._unlock)
Example #22
0
    def _get_path(self, ptask, version=None, latest_version=None, 
        directory=None, location_override=None):

        cur_loc_code = current_location_code()

        if version:
            version_num = version.number 
        else:
            if not latest_version:
                latest_version = ptask.latest_version
            version = latest_version
            version_num = None

        if location_override:
            loc_code = location_override.code
        else:
            loc_code = version.location_code

        if loc_code == cur_loc_code:
            try:
                path = ptask.area.dir(
                    version=version_num, 
                    dir_name=directory,
                )
            except PTaskAreaError:
                raise ActionError(
                    "Path for 's' does not exist.".format(s=ptask.spec),
                )
            path += "/"
        else:
            location = version.location
            if not location.host:
                raise ActionError(
                    "Unable to sync with location '{l}'. Unknown host.".\
                        format(l=location.name)
                )
            path = ptask.area.dir(
                version=version_num, 
                dir_name=directory,
                root=location.filesystem_root,
                verify=False,
            )
            path = current_username() + "@" + location.host + ":" + path + "/"

        return path
Example #23
0
    def _source_subs(self, source_ptask, dest_ptask):

        if self.interactive:
            print "\nSourcing subscriptions:"

        dest_ptask_version_spec = dest_ptask.latest_version.spec
        exceptions = []

        for sub in source_ptask.latest_version.subscriptions:
            try:
                new_sub = ProductSubscription.create(
                    dest_ptask_version_spec,
                    sub.product_version_spec,
                )
            except ProductSubscriptionError as e:
                exceptions.append((sub, e))
            else:
                print "  " + Style.bright + \
                    str(sub.product_version_spec) + Style.normal

        if exceptions:
            msgs = []
            for (sub, e) in exceptions:
                msgs.append(sub.product_version_spec + ": " + str(e))

            raise ActionError(
                "Unable to copy forward some subscriptions:\n\n" + \
                    "\n".join(msgs)
            )
        else:
            # build the import directory...
            if self.interactive:
                print "\nRefreshing subscriptions."

            # refresh the subscriptions on disk
            refresh_action_cls = ActionRegistry().get_action('refresh', 'subs')
            if not refresh_action_cls:
                raise ActionError("Could not find sub refresh action.")

            try:
                refresh_action = refresh_action_cls(dest_ptask)
                refresh_action.interactive = False
                refresh_action()
            except ActionError as e:
                raise ActionError("Failed to refresh subs on disk: " + str(e))
Example #24
0
    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
Example #25
0
    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.")
Example #26
0
    def validate(self):

        if self.source:
            try:
                self._source = PTask.get(self.source)
            except PTaskError:
                raise ActionError(
                    "Unable to retrieve ptask from source argument: " + \
                        str(self.source),
                )
Example #27
0
    def _sync_path(self):

        if self._product_version.published:
            raise ActionError(
                "Product version is already published at this version. Can " + \
                "not overwrite: " + self._product_version.spec)
        
        if not self._path:
            return

        sync = SyncAction(
            source=self._path,
            destination=self._product_area.path,
        )

        try:
            sync()
        except ActionError as e:
            raise ActionError("Failed to sync product source: " + str(e))
Example #28
0
    def _sync_latest_remote(self):

        # sync the local work directory with the contents of the remote work
        # directory (excluding products and child directories)

        source_action_class = ActionRegistry().get_action('sync', 'ptask')
        if not source_action_class:
            raise ActionError("Could not find ptask source action.")

        try:
            source_action = source_action_class(
                ptask=self.ptask,
                version="latest",
                force=True,
            )
            source_action.interactive = False
            source_action()
        except ActionError as e:
            raise ActionError("Failed to sync the remote work directory.")
Example #29
0
    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))
Example #30
0
    def validate(self):

        try:
            location = Location.get(self.code)
        except LocationError as e:
            raise ActionError(
                'Could not determine location from code: "{c}"'.\
                    format(c=self.code)
            )

        self._location = location