コード例 #1
0
ファイル: l_membershelper.py プロジェクト: zthatch/regolith
    def sout(self):
        rc = self.rc
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["people"], rc.filter)
        else:
            collection = self.gtx["people"]
        bad_stati = ["finished", "cancelled", "paused", "back_burner"]
        people = []
        for person in collection:
            if rc.current and not person.get('active'):
                continue
            people.append(person)

        if rc.filter and not rc.verbose:
            results = (collection_str(people, rc.keys))
            print(results, end="")
            return

        for i in people:
            if rc.verbose:
                print("{}, {} | group_id: {}".format(i.get('name'), i.get('position'), i.get('_id')))
                print("    orcid: {} | github_id: {}".format(i.get('orcid_id'), i.get('github_id')))
            else:
                print("{}".format(i.get('name')))
        return
コード例 #2
0
    def sout(self):
        rc = self.rc
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["grants"], rc.filter)
        else:
            collection = self.gtx["grants"]
        grants = []
        if rc.date:
            desired_date = date_parser.parse(rc.date).date()
        else:
            desired_date = dt.date.today()
        for grant in collection:
            if rc.current and not is_current(grant, now=desired_date):
                continue
            if not rc.verbose:
                if grant.get("alias") not in BLACKLIST:
                    grants.append(grant)
            else:
                grants.append(grant)

        # Sort the grants by end date in reverse chronological order
        grants.sort(key=lambda k: get_dates(k).get('end_date'), reverse=True)
        if rc.keys:
            results = (collection_str(grants, rc.keys))
            print(results, end="")
            return
        for g in grants:
            print("{}, awardnr: {}, acctn: {}, {} to {}".format(
                g.get('alias', ''), g.get('awardnr', ''), g.get('account', ''),
                get_dates(g).get('begin_date'),
                get_dates(g).get('end_date')))
        return
コード例 #3
0
    def sout(self):
        rc = self.rc
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["projecta"], rc.filter)
        else:
            collection = self.gtx["projecta"]
        if not rc.date:
            now = datetime.date.today()
        else:
            now = date_parser.parse(rc.date).date()

        # remove checklist prums from the report
        collection = [
            prum for prum in collection
            if "checklist" not in prum.get('deliverable', {}).get('scope', [])
        ]

        title = f"\nProgress report for {rc.lead}, generated {now.isoformat()}"
        print(title)
        projecta = [
            valid_prum for valid_prum in collection
            if valid_prum.get("lead") == rc.lead
        ]

        finishedp, proposedp, startedp, otherp = [], [], [], []
        for prum in projecta:
            if prum.get('status') == "finished":
                finishedp.append(prum)
            elif prum.get('status') == "proposed":
                proposedp.append(prum)
            elif prum.get('status') == "started":
                startedp.append(prum)
            else:
                otherp.append(prum)
        print(
            f"*************************[Orphan Projecta]*************************"
        )
        for prum in otherp:
            print(f"{prum.get('_id')}, status: {prum.get('status')}")
        print(
            f"*************************[Finished Projecta]*************************"
        )
        for prum in finishedp:
            print(f"{prum.get('_id')}, grant: {prum.get('grants')}")
            print(f"  description: {prum.get('description')}")
            print(f"  finished: {prum.get('end_date')}")
        print(
            f"*************************[Proposed Projecta]*************************"
        )
        self.print_projectum(proposedp)
        print(
            f"*************************[In Progress Projecta]*************************"
        )
        self.print_projectum(startedp)
コード例 #4
0
    def sout(self):
        rc = self.rc
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["grants"], rc.filter)
        else:
            collection = self.gtx["grants"]
        grants = []
        if rc.date:
            desired_date = date_parser.parse(rc.date).date()
        else:
            desired_date = dt.date.today()
        for grant in collection:
            # fixme maybe change this logic and change the name of "year" in proposal to "submitted_year" or sthg
            if grant.get(
                    'year'
            ):  # year is used for prop submission but breaks get_dates
                del grant['year']
            if rc.current and not is_current(grant, now=desired_date):
                continue
            if not rc.verbose:
                if grant.get("alias") not in BLACKLIST:
                    grants.append(grant)
            else:
                grants.append(grant)

        # Sort the grants by end date in reverse chronological order
        grants.sort(key=lambda k: get_dates(k).get('end_date'), reverse=True)
        if rc.keys:
            results = (collection_str(grants, rc.keys))
            print(results, end="")
            return
        for g in grants:
            print("{}, awardnr: {}, acctn: {}, {} to {}".format(
                g.get('alias', ''), g.get('awardnr', ''), g.get('account', ''),
                get_dates(g).get('begin_date'),
                get_dates(g).get('end_date')))
        return
コード例 #5
0
ファイル: l_todohelper.py プロジェクト: sheneric88/regolith
    def sout(self):
        rc = self.rc
        if not rc.assigned_to:
            try:
                rc.assigned_to = rc.default_user_id
            except AttributeError:
                print(
                    "Please set default_user_id in '~/.config/regolith/user.json', or you need to enter your group id "
                    "in the command line")
                return
        try:
            person = document_by_value(
                all_docs_from_collection(rc.client, "todos"), "_id",
                rc.assigned_to)
            gather_todos = person.get("todos", [])
        except:
            print("The id you entered can't be found in todos.yml.")
            return
        if not rc.date:
            today = dt.date.today()
        else:
            today = date_parser.parse(rc.date).date()
        if rc.stati == ["started"]:
            rc.stati = PROJECTUM_ACTIVE_STATI
        running_index = 0
        for projectum in self.gtx["projecta"]:
            if projectum.get('lead') != rc.assigned_to:
                continue
            if "checklist" in projectum.get('deliverable').get('scope'):
                continue
            projectum["deliverable"].update({"name": "deliverable"})
            gather_miles = [projectum["deliverable"]]
            if projectum.get("kickoff"):
                projectum['kickoff'].update({"type": "meeting"})
                gather_miles = [projectum["kickoff"], projectum["deliverable"]]
            gather_miles.extend(projectum["milestones"])
            for ms in gather_miles:
                if projectum["status"] in PROJECTUM_ACTIVE_STATI:
                    if ms.get('status') in PROJECTUM_ACTIVE_STATI:
                        due_date = get_due_date(ms)
                        ms.update({
                            'status': "started",
                            'id': projectum.get('_id'),
                            'due_date': due_date,
                            'assigned_by': projectum.get('pi_id'),
                            'importance': 2,
                            'duration': 3600,
                            'running_index': 9900 + running_index
                        })
                        running_index += 1
                        ms.update({
                            'description':
                            f'milestone: {ms.get("name")} ({ms.get("id")})'
                        })
                        gather_todos.append(ms)
        if rc.filter:
            gather_todos = key_value_pair_filter(gather_todos, rc.filter)
        if rc.short:
            for todo in gather_todos[::-1]:
                if todo.get('duration') is None or float(
                        todo.get('duration')) > float(rc.short):
                    gather_todos.remove(todo)
        if rc.tags:
            for todo in gather_todos[::-1]:
                takeme = False
                for tag in rc.tags:
                    if tag in todo.get('tags', []):
                        takeme = True
                if not takeme:
                    gather_todos.remove(todo)
        if rc.assigned_by:
            if rc.assigned_by == "default_id":
                rc.assigned_by = rc.default_user_id
            for todo in gather_todos[::-1]:
                if todo.get('assigned_by') != rc.assigned_by:
                    gather_todos.remove(todo)
        len_of_started_tasks = 0
        milestones = 0
        for todo in gather_todos:
            if 'milestone: ' in todo['description']:
                milestones += 1
            elif todo["status"] == 'started':
                len_of_started_tasks += 1
        len_of_tasks = len(gather_todos)  #- milestones
        for todo in gather_todos:
            _format_todos(todo, today)
        gather_todos[:len_of_tasks] = sorted(
            gather_todos[:len_of_tasks],
            key=lambda k: (k['status'], k['importance'], k['order'], -k.get(
                'duration', 10000)))
        gather_todos[len_of_started_tasks:len_of_tasks] = sorted(
            gather_todos[len_of_started_tasks:len_of_tasks],
            key=lambda k: (-k["sort_finished"]))
        gather_todos[len_of_tasks:] = sorted(
            gather_todos[len_of_tasks:],
            key=lambda k: (k['status'], k['order'], -k.get('duration', 10000)))
        print(
            "If the indices are far from being in numerical order, please renumber them by running regolith helper u_todo -r"
        )
        print(
            "(index) action (days to due date|importance|expected duration (mins)|tags|assigned by)"
        )
        print("-" * 80)
        if len(gather_todos) != 0:
            print_task(gather_todos, stati=rc.stati)

        if rc.outstandingreview:
            prop = self.gtx['proposalReviews']
            man = self.gtx['refereeReports']
            outstanding_todo = []
            for manuscript in man:
                if manuscript.get("reviewer") != rc.assigned_to:
                    continue
                if manuscript.get("status") in STATI:
                    out = f"Manuscript by {manuscript.get('first_author_last_name')} in {manuscript.get('journal')} " \
                          f"is due on {manuscript.get('due_date')}"
                    outstanding_todo.append((out, manuscript.get('due_date'),
                                             manuscript.get("status")))
            for proposal in prop:
                if proposal.get("reviewer") != rc.assigned_to:
                    continue
                if proposal.get("status") in STATI:
                    if isinstance(proposal.get('names'), str):
                        name = HumanName(proposal.get('names'))
                    else:
                        name = HumanName(proposal.get('names')[0])
                    out = f"Proposal by {name.last} for {proposal.get('agency')} ({proposal.get('requester')})" \
                          f"is due on {proposal.get('due_date')}"
                    outstanding_todo.append((out, proposal.get('due_date'),
                                             proposal.get("status")))

            if len(outstanding_todo) != 0:
                print("-" * 30)
                print("Outstanding Reviews:")
                print("-" * 30)
            outstanding_todo = sorted(outstanding_todo,
                                      key=lambda k: str(k[1]))
            for stati in STATI:
                if stati in [output[2] for output in outstanding_todo]:
                    print(f'{stati}:')
                else:
                    continue
                for output in outstanding_todo:
                    if output[2] == stati:
                        print(output[0])

        return
コード例 #6
0
ファイル: l_projectahelper.py プロジェクト: zthatch/regolith
    def sout(self):
        rc = self.rc
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["projecta"], rc.filter)
        else:
            collection = self.gtx["projecta"]

        if (not rc.lead) and (not rc.person) and (not rc.ended) and (not rc.grant) and (not rc.verbose) and (not rc.grp_by_lead) and (not rc.filter) and (not rc.all):
            return
        if rc.date:
            desired_date = date_parser.parse(rc.date).date()
        else:
            desired_date = dt.date.today()

        if rc.range:
            num_of_days = int(rc.range)
        else:
            num_of_days = 7

        projecta = []
        end_projecta = []
        grouped_projecta = {}
        if rc.lead and rc.person:
            raise RuntimeError(f"please specify either lead or person, not both")
        for projectum in collection:
            if rc.all and projectum.get('status') != "finished":
                projecta.append(projectum)
                continue
            if isinstance(projectum.get('group_members'), str):
                projectum['group_members'] = [projectum.get('group_members')]
            if rc.lead and projectum.get('lead') != rc.lead:
                continue
            if rc.person:
                if isinstance(rc.person, str):
                    rc.person = [rc.person]
                good_p = []
                for i in rc.person:
                    if projectum.get('lead') == rc.person:
                        good_p.append(i)
                    if projectum.get('group_members') and i in projectum.get('group_members'):
                        good_p.append(i)
                if len(good_p) == 0:
                    continue
            if rc.grant and rc.grant not in projectum.get('grants'):
                continue
            if rc.ended and not projectum.get('end_date'):
                continue
            if rc.ended:
                end_date = projectum.get('end_date')
                if isinstance(end_date, str):
                    end_date = date_parser.parse(end_date).date()
                low_range = desired_date - dt.timedelta(days=num_of_days)
                high_range = desired_date + dt.timedelta(days=num_of_days)
                if low_range <= end_date <= high_range:
                    end_projecta.append(projectum)
                continue
            projecta.append(projectum)

        if rc.ended:
            for p in end_projecta:
                members, collaborators = None, None
                if p.get("group_members"):
                    members = ', '.join(p.get("group_members"))
                if p.get("collaborators"):
                    collaborators = ', '.join(p.get("collaborators"))
                print("{}    {}\n    Lead: {}    Members: {}    Collaborators: {}".format(p.get("_id"),
                                                                                          p.get("description"),
                                                                                          p.get("lead"), members,
                                                                                          collaborators))
            return

        if rc.verbose:
            for p in projecta:
                grants = None
                if p.get('grants'):
                    if isinstance(p.get('grants'), list):
                        grants = ' ,'.join(p.get('grants'))
                    else:
                        grants = p.get('grants')
                print(p.get('_id'))
                print(f"    status: {p.get('status')}, begin_date: {p.get('begin_date')}, due_date: {p.get('due_date')}, end_date: {p.get('end_date')}, grant: {grants}")
                print(f"    description: {p.get('description')}")
                print("    team:")
                print(f"        lead: {p.get('lead')}")
                grp_members = None
                if p.get('group_members'):
                    grp_members = ', '.join(p.get('group_members'))
                collaborators = None
                if p.get('collaborators'):
                    collaborators = ', '.join(p.get('collaborators'))
                print(f"        group_members: {grp_members}")
                print(f"        collaborators: {collaborators}")
            return

        if rc.grp_by_lead:
            for p in projecta:
                if p.get('lead') not in grouped_projecta:
                    grouped_projecta[p.get('lead')] = [p.get('_id')]
                else:
                    grouped_projecta[p.get('lead')].append(p.get('_id'))
            for key, values in grouped_projecta.items():
                print(f"{key}:")
                for v in values:
                    print(f"    {v}")
            return

        projecta.sort(key=lambda prum: prum.get("_id"))
        if rc.keys:
            results = (collection_str(projecta, rc.keys))
            print(results, end="")
            return

        for i in projecta:
            print(i.get("_id"))
        return
コード例 #7
0
    def sout(self):
        rc = self.rc
        # This if statement should be in all listers. Make sure to change self.gtx to get the database the lister needs
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["projecta"], rc.filter)
        else:
            collection = self.gtx["projecta"]

        if (not rc.lead) and (not rc.verbose) and (not rc.stati) and (
                not rc.current) and (not rc.person) and (not rc.all):
            return

        # fixme there must be a better way, but for now use magic to
        # to remove checklists
        # print(collection)
        collection = [
            prum for prum in collection
            if "checklist" not in prum.get('deliverable', {}).get('scope', [])
        ]

        if rc.lead:
            if rc.person:
                raise RuntimeError(
                    f"please specify either lead or person, not both")
            collection = [
                prum for prum in collection if prum.get('lead') == rc.lead
            ]
        if rc.person:
            if isinstance(rc.person, str):
                rc.person = [rc.person]
            collection = [
                prum for prum in collection
                if prum.get('lead') in rc.person or bool(
                    set(prum.get('group_members', [])).intersection(
                        set(rc.person))) or bool(
                            set(prum.get('collaborators', [])).intersection(
                                set(rc.person)))
            ]

        if not rc.all:
            collection = [
                prum for prum in collection
                if prum.get('status') not in INACTIVE_STATI
            ]

        all_milestones = []
        if not rc.stati and not rc.all and not rc.finished:
            rc.stati = PROJECTUM_ACTIVE_STATI
        elif rc.finished:
            rc.stati = PROJECTUM_FINISHED_STATI
        elif rc.all:
            rc.stati = PROJECTUM_STATI
        for projectum in collection:
            projectum["deliverable"].update({
                "name": "deliverable",
                "objective": "deliver"
            })
            milestones = [projectum["deliverable"]]
            if projectum.get("kickoff"):
                projectum["kickoff"].update({"type": "meeting"})
                milestones = [projectum["kickoff"], projectum["deliverable"]]
            milestones.extend(projectum["milestones"])
            milestones = [
                ms for ms in milestones if ms.get('status') in rc.stati
            ]

            for ms in milestones:
                due_date = get_due_date(ms)
                ms.update({
                    'lead': projectum.get('lead'),
                    'group_members': projectum.get('group_members'),
                    'collaborators': projectum.get('collaborators'),
                    'id': projectum.get('_id'),
                    'due_date': due_date,
                    'log_url': projectum.get('log_url'),
                    'pi': projectum.get('pi_id')
                })
            milestones.sort(key=lambda x: x['due_date'], reverse=True)
            all_milestones.extend(milestones)
        if rc.keys:
            results = (collection_str(all_milestones, rc.keys))
            print(results, end="")
            return
        if not rc.by_prum:
            all_milestones.sort(key=lambda x: x['due_date'], reverse=True)
        prum = ""
        for ms in all_milestones:
            if rc.by_prum:
                if prum != ms.get("id"):
                    print("-" * 50)
                    prum = ms.get("id")
            if rc.verbose:
                print(
                    f"{ms.get('due_date')}: lead: {ms.get('lead')}, {ms.get('id')}, status: {ms.get('status')}"
                )
                print(f"    Type: {ms.get('type', '')}")
                print(f"    Title: {ms.get('name')}")
                print(f"    log url: {ms.get('log_url')}")
                print(f"    Purpose: {ms.get('objective')}")
                audience = []
                for i in ms.get('audience', []):
                    if isinstance(ms.get(i, i), str):
                        audience.append(ms.get(i, i))
                    else:
                        if ms.get(i):
                            audience.extend(ms.get(i))
                out = ", ".join(audience)
                print(f"    Audience: {out}")
                if ms.get("notes"):
                    print(f"    Notes:")
                    for note in ms.get("notes"):
                        print(f"      - {note}")
            else:
                print(
                    f"{ms.get('due_date')}: lead: {ms.get('lead')}, {ms.get('id')}, {ms.get('name')}, status: {ms.get('status')}"
                )

        return
コード例 #8
0
    def db_updater(self):
        rc = self.rc
        if not rc.assigned_to:
            try:
                rc.assigned_to = rc.default_user_id
            except AttributeError:
                print(
                    "Please set default_user_id in '~/.config/regolith/user.json', or you need to enter your group id "
                    "in the command line")
                return
        filterid = {'_id': rc.assigned_to}
        if rc.reorder:
            index = 1
            for i in range(0, len(rc.databases)):
                db_name = rc.databases[i]["name"]
                person_idx = rc.client.find_one(db_name, rc.coll, filterid)
                if isinstance(person_idx, dict):
                    todolist_idx = person_idx.get("todos", [])
                else:
                    continue
                if len(todolist_idx) == 0:
                    continue
                else:
                    for todo in todolist_idx:
                        todo["running_index"] = index
                        index += 1
        person = document_by_value(
            all_docs_from_collection(rc.client, "people"), "_id",
            rc.assigned_to)
        if not person:
            raise TypeError(
                f"Id {rc.assigned_to} can't be found in people collection")
        todolist = person.get("todos", [])
        if len(todolist) == 0:
            print(f"{rc.assigned_to} doesn't have todos in people collection.")
            return
        if not rc.certain_date:
            today = dt.date.today()
        else:
            today = date_parser.parse(rc.certain_date).date()
        if not rc.index:
            started_todo = 0
            for todo in todolist:
                if todo["status"] == 'started':
                    started_todo += 1
                if not todo.get('importance'):
                    todo['importance'] = 1
                if type(todo["due_date"]) == str:
                    todo["due_date"] = date_parser.parse(
                        todo["due_date"]).date()
                if type(todo.get("end_date")) == str:
                    todo["end_date"] = date_parser.parse(
                        todo["end_date"]).date()
                todo["days_to_due"] = (todo.get('due_date') - today).days
                todo["sort_finished"] = (
                    todo.get("end_date", dt.date(1900, 1, 1)) -
                    dt.date(1900, 1, 1)).days
                todo["order"] = todo['importance'] + 1 / (
                    1 + math.exp(abs(todo["days_to_due"] - 0.5))) - (
                        todo["days_to_due"] < -7) * 10
            todolist = sorted(
                todolist,
                key=lambda k:
                (k['status'], k['order'], -k.get('duration', 10000)),
                reverse=True)
            todolist[started_todo:] = sorted(todolist[started_todo:],
                                             key=lambda k:
                                             (-k["sort_finished"]))
            index_match = {}
            if rc.reorder:
                new_index_started = 1
                new_index_finished = -1
                for todo in todolist[:started_todo]:
                    index_match[todo["running_index"]] = new_index_started
                    new_index_started += 1
                for todo in todolist[started_todo:]:
                    index_match[todo["running_index"]] = new_index_finished
                    new_index_finished += -1
                for i in range(0, len(rc.databases)):
                    db_name = rc.databases[i]["name"]
                    person_idx = rc.client.find_one(db_name, rc.coll, filterid)
                    if isinstance(person_idx, dict):
                        todolist_idx = person_idx.get("todos", [])
                    else:
                        continue
                    if len(todolist_idx) != 0:
                        for todo in todolist_idx:
                            index = index_match[todo["running_index"]]
                            todo["running_index"] = index
                        rc.client.update_one(db_name,
                                             rc.coll, {'_id': rc.assigned_to},
                                             {"todos": todolist_idx},
                                             upsert=True)
                        print(
                            f"Indices in {db_name} for {rc.assigned_to} have been updated."
                        )
                return
            if rc.assigned_by:
                if rc.assigned_by == "default_id":
                    rc.assigned_by = rc.default_user_id
                for todo in todolist[::-1]:
                    if todo.get('assigned_by') != rc.assigned_by:
                        print(todo.get('assigned_by'))
                        todolist.remove(todo)
                    elif rc.assigned_to == rc.assigned_by:
                        todolist.remove(todo)
            if rc.filter:
                todolist = key_value_pair_filter(todolist, rc.filter)
            if rc.stati == ["started"]:
                rc.stati = ACTIVE_STATI
            print(
                "If the indices are far from being in numerical order, please reorder them by running regolith helper u_todo -r"
            )
            print("Please choose from one of the following to update:")
            print(
                "(index) action (days to due date|importance|expected duration (mins)|assigned by)"
            )
            print("-" * 81)
            print_task(todolist, stati=rc.stati)
            print("-" * 81)
        else:
            match_todo = [
                i for i in todolist if i.get("running_index") == rc.index
            ]
            if len(match_todo) == 0:
                raise RuntimeError("Please enter a valid index.")
            else:
                todo = match_todo[0]
                if rc.description:
                    todo["description"] = rc.description
                if rc.due_date:
                    try:
                        relative_day = int(rc.due_date)
                        due_date = today + relativedelta(days=relative_day)
                    except ValueError:
                        due_date = date_parser.parse(rc.due_date).date()
                    todo["due_date"] = due_date
                if rc.estimated_duration:
                    todo["duration"] = rc.estimated_duration
                if rc.importance or rc.importance == 0:
                    if rc.importance in ALLOWED_IMPORTANCE:
                        todo["importance"] = rc.importance
                    else:
                        raise ValueError(
                            f"Importance should be chosen from{ALLOWED_IMPORTANCE}."
                        )
                if rc.status:
                    if rc.status in ALLOWED_STATI:
                        todo["status"] = rc.status
                    else:
                        raise ValueError(
                            f"Status should be chosen from {ALLOWED_STATI}.")
                if rc.notes:
                    try:
                        todo["notes"].extend(rc.notes)
                    except KeyError:
                        todo["notes"] = []
                        todo["notes"].extend(rc.notes)
                if rc.begin_date:
                    todo["begin_date"] = date_parser.parse(
                        rc.begin_date).date()
                if rc.end_date:
                    todo["end_date"] = date_parser.parse(rc.end_date).date()

                for i in range(0, len(rc.databases)):
                    db_name = rc.databases[i]["name"]
                    person_update = rc.client.find_one(db_name, rc.coll,
                                                       filterid)
                    todolist_update = person_update.get("todos", [])
                    if len(todolist_update) != 0:
                        for i, todo_u in enumerate(todolist_update):
                            if rc.index == todo_u.get("running_index"):
                                todolist_update[i] = todo
                                rc.client.update_one(
                                    db_name,
                                    rc.coll, {'_id': rc.assigned_to},
                                    {"todos": todolist_update},
                                    upsert=True)
                                print(
                                    f"The task \"({todo_u['running_index']}) {todo_u['description'].strip()}\" in {db_name} for {rc.assigned_to} has been updated."
                                )
                                return
        return
コード例 #9
0
    def sout(self):
        gtx = self.gtx
        rc = self.rc
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["people"], rc.filter)
        else:
            collection = self.gtx["people"]
        bad_stati = ["finished", "cancelled", "paused", "back_burner"]
        people = []
        group = fuzzy_retrieval(gtx['groups'], ["_id", "aka", "name"],
                                rc.groupname)
        group_id = group.get("_id")

        if rc.filter:
            if not rc.verbose:
                results = (collection_str(collection, rc.keys))
                print(results, end="")
                return
            else:
                for person in collection:
                    print("{}, {} | group_id: {}".format(
                        person.get('name'), person.get('position'),
                        person.get('_id')))
                    print("    orcid: {} | github_id: {}".format(
                        person.get('orcid_id'), person.get('github_id')))
                pass
            #code to print verbosely on filtering
        if not rc.filter:
            for person in gtx["people"]:
                if rc.current:
                    if not person.get('active'):
                        continue
                    people.append(person)
                elif rc.prior:
                    if person.get('active'):
                        continue
                    people.append(person)
                else:
                    people.append(person)

        cleaned_people = []
        for person in people:
            not_current_positions = [
                emp for emp in person.get('employment') if not is_current(emp)
            ]
            not_current_positions.sort(key=lambda x: get_dates(x)["end_date"])
            current_positions = [
                emp for emp in person.get('employment') if is_current(emp)
            ]
            current_positions.sort(key=lambda x: get_dates(x)["begin_date"])
            positions = not_current_positions + current_positions
            position_keys = [
                position_key(position) for position in positions
                if position.get("group", "") == group_id
            ]
            if position_keys:
                person["position_key"] = max(position_keys)[0]
                cleaned_people.append(person)
            else:
                print(
                    f"Person {person['name']} has no positions in group {group_id}"
                )
        cleaned_people.sort(key=lambda k: k['position_key'], reverse=True)
        position_names = {
            1: "Undergrads",
            2.5: "Masters Students",
            2: "Visiting Students",
            3: "Graduate Students",
            4: "Post Docs",
            5: "Visitors",
            8: "Assistant Scientists",
            9: "Associate Scientists",
            10: "Scientists",
            11: "PI"
        }
        accounting = 12
        for person in cleaned_people:
            if person.get('position_key') < accounting:
                accounting = person.get('position_key')
                print(
                    f"    -- {position_names.get(accounting,position_names.get(5))} --"
                )
            if rc.verbose:
                print("{}, {}".format(person.get('name'),
                                      person.get('position')))
                print("    email: {} | group_id: {}".format(
                    person.get('email'), person.get('_id')))
                print("    github_id: {} | orcid: {}".format(
                    person.get('github_id'), person.get('orcid_id')))
                for position in positions:
                    if is_current(position):
                        inst = fuzzy_retrieval(gtx["institutions"],
                                               ["aka", "name", "_id"],
                                               position.get("organization"))
                        if inst:
                            instname = inst.get("name")
                        else:
                            print(
                                f"WARNING: {position.get('organization')} not in institutions collection"
                            )
                        print("    current organization: {}".format(instname))
                        print("    current position: {}".format(
                            position.get('full_position',
                                         position.get('position').title())))
                    if not person.get('active'):
                        if position.get('group') == "bg":
                            print("    billinge group position: {}".format(
                                position.get('position')))
            else:
                print("{}".format(person.get('name')))
        return
コード例 #10
0
 def sout(self):
     rc = self.rc
     if not rc.assigned_to:
         try:
             rc.assigned_to = rc.default_user_id
         except AttributeError:
             print(
                 "Please set default_user_id in '~/.config/regolith/user.json', or you need to enter your group id "
                 "in the command line")
             return
     try:
         person = document_by_value(
             all_docs_from_collection(rc.client, "people"), "_id",
             rc.assigned_to)
         gather_todos = person.get("todos", [])
     except:
         print("The id you entered can't be found in people.yml.")
         return
     if not rc.certain_date:
         today = dt.date.today()
     else:
         today = date_parser.parse(rc.certain_date).date()
     if rc.stati == ["started"]:
         rc.stati = ACTIVE_STATI
     for projectum in self.gtx["projecta"]:
         if projectum.get('lead') != rc.assigned_to:
             continue
         projectum["deliverable"].update({"name": "deliverable"})
         gather_miles = [projectum["kickoff"], projectum["deliverable"]]
         gather_miles.extend(projectum["milestones"])
         for ms in gather_miles:
             if projectum["status"] not in ["finished", "cancelled"]:
                 if ms.get('status') not in \
                         ["finished", "cancelled"]:
                     due_date = get_due_date(ms)
                     ms.update({
                         'id': projectum.get('_id'),
                         'due_date': due_date,
                         'assigned_by': projectum.get('pi_id')
                     })
                     ms.update({
                         'description':
                         f'milestone: {ms.get("name")} ({ms.get("id")})'
                     })
                     gather_todos.append(ms)
     if rc.filter:
         gather_todos = key_value_pair_filter(gather_todos, rc.filter)
     if rc.short:
         for todo in gather_todos[::-1]:
             if todo.get('duration') is None or float(
                     todo.get('duration')) > float(rc.short):
                 gather_todos.remove(todo)
     if rc.assigned_by:
         if rc.assigned_by == "default_id":
             rc.assigned_by = rc.default_user_id
         for todo in gather_todos[::-1]:
             if todo.get('assigned_by') != rc.assigned_by:
                 gather_todos.remove(todo)
             elif rc.assigned_to == rc.assigned_by:
                 gather_todos.remove(todo)
     len_of_started_tasks = 0
     milestones = 0
     for todo in gather_todos:
         if 'milestone: ' in todo['description']:
             milestones += 1
         elif todo["status"] == 'started':
             len_of_started_tasks += 1
     len_of_tasks = len(gather_todos) - milestones
     for todo in gather_todos:
         if not todo.get('importance'):
             todo['importance'] = 1
         if type(todo["due_date"]) == str:
             todo["due_date"] = date_parser.parse(todo["due_date"]).date()
         if type(todo.get("end_date")) == str:
             todo["end_date"] = date_parser.parse(todo["end_date"]).date()
         todo["days_to_due"] = (todo.get('due_date') - today).days
         todo["sort_finished"] = (
             todo.get("end_date", dt.date(1900, 1, 1)) -
             dt.date(1900, 1, 1)).days
         try:
             todo["order"] = todo['importance'] + 1 / (
                 1 + math.exp(abs(todo["days_to_due"] - 0.5))) - (
                     todo["days_to_due"] < -7) * 10
         except OverflowError:
             todo["order"] = float('inf')
     gather_todos[:len_of_tasks] = sorted(
         gather_todos[:len_of_tasks],
         key=lambda k: (k['status'], k['order'], -k.get('duration', 10000)),
         reverse=True)
     gather_todos[len_of_started_tasks:len_of_tasks] = sorted(
         gather_todos[len_of_started_tasks:len_of_tasks],
         key=lambda k: (-k["sort_finished"]))
     gather_todos[len_of_tasks:] = sorted(
         gather_todos[len_of_tasks:],
         key=lambda k: (k['status'], k['order'], -k.get('duration', 10000)),
         reverse=True)
     print(
         "If the indices are far from being in numerical order, please reorder them by running regolith helper u_todo -r"
     )
     print(
         "(index) action (days to due date|importance|expected duration (mins)|assigned by)"
     )
     print("-" * 81)
     if len_of_tasks != 0:
         print("tasks from people collection:")
         print("-" * 30)
         print_task(gather_todos[:len_of_tasks], stati=rc.stati)
     if milestones != 0:
         print("-" * 42)
         print("tasks from projecta and other collections:")
         print("-" * 42)
         print_task(gather_todos[len_of_tasks:],
                    stati=rc.stati,
                    index=False)
     print("-" * 81)
     return
コード例 #11
0
    def sout(self):
        gtx = self.gtx
        rc = self.rc
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["people"], rc.filter)
        else:
            collection = self.gtx["people"]
        bad_stati = ["finished", "cancelled", "paused", "back_burner"]
        people = []

        if rc.filter:
            if not rc.verbose:
                results = (collection_str(collection, rc.keys))
                # "scopatz"
                print(results, end="")
                return
            else:
                for person in collection:
                    print("{}, {} | group_id: {}".format(
                        person.get('name'), person.get('position'),
                        person.get('_id')))
                    print("    orcid: {} | github_id: {}".format(
                        person.get('orcid_id'), person.get('github_id')))
                pass
            #code to print verbosely on filtering
        if not rc.filter:
            for person in gtx["people"]:
                if rc.current:
                    if not person.get('active'):
                        continue
                    people.append(person)
                elif rc.prior:
                    if person.get('active'):
                        continue
                    people.append(person)
                else:
                    people.append(person)

        for i in people:
            if rc.verbose:
                print("{}, {}".format(i.get('name'), i.get('position')))
                print("    email: {} | group_id: {}".format(
                    i.get('email'), i.get('_id')))
                print("    github_id: {} | orcid: {}".format(
                    i.get('github_id'), i.get('orcid_id')))
                not_current_positions = [
                    emp for emp in i.get('employment') if not is_current(emp)
                ]
                not_current_positions.sort(
                    key=lambda x: get_dates(x)["end_date"])
                current_positions = [
                    emp for emp in i.get('employment') if is_current(emp)
                ]
                current_positions.sort(
                    key=lambda x: get_dates(x)["begin_date"])
                positions = not_current_positions + current_positions
                for position in positions:
                    if is_current(position):
                        inst = fuzzy_retrieval(gtx["institutions"],
                                               ["aka", "name", "_id"],
                                               position.get("organization"))
                        if inst:
                            instname = inst.get("name")
                        else:
                            print(
                                f"WARNING: {position.get('organization')} not in institutions collection"
                            )
                        print("    current organization: {}".format(instname))
                        print("    current position: {}".format(
                            position.get('full_position',
                                         position.get('position').title())))
                    if not i.get('active'):
                        if position.get('group') == "bg":
                            print("    billinge group position: {}".format(
                                position.get('position')))
            else:
                print("{}".format(i.get('name')))
        return
コード例 #12
0
ファイル: l_projectahelper.py プロジェクト: mwinitch/regolith
    def sout(self):
        rc = self.rc
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["projecta"], rc.filter)
        else:
            collection = self.gtx["projecta"]

        if (not rc.lead) and (not rc.person) and (not rc.ended) and (
                not rc.grant) and (not rc.verbose) and (
                    not rc.grp_by_lead) and (not rc.filter) and (
                        not rc.current) and (not rc.all):
            return
        if rc.date:
            now = date_parser.parse(rc.date).date()
        else:
            now = dt.date.today()
        if not rc.range:
            rc.range = 7
        since_date = now - dt.timedelta(days=int(rc.range))

        projecta, end_projecta, error_projecta = [], [], []
        grouped_projecta = {}
        if rc.grant:
            collection = [
                prum for prum in collection if rc.grant in prum.get('grants')
            ]
        if rc.lead:
            if rc.person:
                raise RuntimeError(
                    f"please specify either lead or person, not both")
            collection = [
                prum for prum in collection if prum.get('lead') == rc.lead
            ]
        if rc.person:
            if isinstance(rc.person, str):
                rc.person = [rc.person]
            collection = [
                prum for prum in collection
                if prum.get('lead') in rc.person or bool(
                    set(prum.get('group_members', [])).intersection(
                        set(rc.person)))
            ]
        if rc.current:
            collection = [
                prum for prum in collection
                if prum.get('status') in ACTIVE_STATI
            ]
        if not rc.all:
            collection = [
                prum for prum in collection
                if prum.get('status') not in INACTIVE_STATI
            ]

        for projectum in collection:
            if rc.ended:
                if projectum.get('status') not in ACTIVE_STATI:
                    if projectum.get('status') in INACTIVE_STATI:
                        continue
                    elif projectum.get('status') not in FINISHED_STATI \
                            or not isinstance(projectum.get('end_date'),
                                              dt.date):
                        error_projecta.append(projectum)
                    else:
                        end_date = projectum.get('end_date')
                        if isinstance(end_date, str):
                            end_date = date_parser.parse(end_date).date()
                        if since_date <= end_date <= now:
                            end_projecta.append(projectum)
                if end_projecta != []:
                    projecta = end_projecta
                continue
            projecta.append(projectum)

        if rc.verbose:
            for p in projecta:
                grants = None
                if p.get('grants'):
                    if isinstance(p.get('grants'), list):
                        grants = ' ,'.join(p.get('grants'))
                    else:
                        grants = p.get('grants')
                print(p.get('_id'))
                print(
                    f"    status: {p.get('status')}, begin_date: {p.get('begin_date')}, due_date: {p.get('due_date')}, end_date: {p.get('end_date')}, grant: {grants}"
                )
                print(f"    description: {p.get('description')}")
                print("    team:")
                print(f"        lead: {p.get('lead')}")
                grp_members = None
                if p.get('group_members'):
                    grp_members = ', '.join(p.get('group_members'))
                collaborators = None
                if p.get('collaborators'):
                    collaborators = ', '.join(p.get('collaborators'))
                print(f"        group_members: {grp_members}")
                print(f"        collaborators: {collaborators}")
            return

        if rc.grp_by_lead:
            for p in projecta:
                if p.get('lead') not in grouped_projecta:
                    grouped_projecta[p.get('lead')] = [p.get('_id')]
                else:
                    grouped_projecta[p.get('lead')].append(p.get('_id'))
            for key, values in grouped_projecta.items():
                print(f"{key}:")
                for v in values:
                    print(f"    {v}")
            return

        projecta.sort(key=lambda prum: prum.get("_id"))
        if rc.keys:
            results = (collection_str(projecta, rc.keys))
            print(results, end="")
            return

        if end_projecta != []:
            if now == dt.date.today() and rc.range == 7:
                print("\nProjecta finished this past week! o(*^v^*)o")
            else:
                print(
                    f"\nProjecta finished within the {rc.range} days leading up to {now}"
                )
        elif end_projecta == [] and rc.ended:
            if now == dt.date.today() and rc.range == 7:
                print("\nNo projecta finished this week")
            else:
                print(
                    f"\nNo projecta finished within the {rc.range} days leading up to {now}"
                )

        for i in projecta:
            print(i.get("_id"))

        if error_projecta:
            print(
                "\nWARNING: These projecta have an issue with the end date and/or status, "
                "please run f_prum to set status to finished and add an end date"
            )
            for i in error_projecta:
                print(i.get("_id"))
コード例 #13
0
    def sout(self):
        rc = self.rc
        # This if statement should be in all listers. Make sure to change self.gtx to get the database the lister needs
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["projecta"], rc.filter)
        else:
            collection = self.gtx["projecta"]
        all_milestones = []
        if not rc.stati:
            rc.stati = ['started']
        for projectum in collection:
            if rc.lead and projectum.get('lead') != rc.lead:
                continue
            projectum["deliverable"].update({
                "name": "deliverable",
                "objective": "deliver"
            })
            projectum["kickoff"].update({"type": "meeting"})
            gather_miles = [projectum["kickoff"], projectum["deliverable"]]
            gather_miles.extend(projectum["milestones"])
            for ms in gather_miles:
                if projectum["status"] in rc.stati or \
                        'all' in rc.stati:
                    if ms.get('status') not in \
                            ["finished", "cancelled"]:
                        due_date = get_due_date(ms)
                        ms.update({
                            'lead':
                            projectum.get('lead'),
                            'group_members':
                            projectum.get('group_members'),
                            'collaborators':
                            projectum.get('collaborators'),
                            'id':
                            projectum.get('_id'),
                            'due_date':
                            due_date,
                            'log_url':
                            projectum.get('log_url'),
                            'pi':
                            projectum.get('pi_id')
                        })
                        all_milestones.append(ms)
        all_milestones.sort(key=lambda x: x['due_date'], reverse=True)
        if rc.keys:
            results = (collection_str(all_milestones, rc.keys))
            print(results, end="")
            return
        for ms in all_milestones:
            if rc.verbose:
                print(
                    f"{ms.get('due_date')}: lead: {ms.get('lead')}, {ms.get('id')}, status: {ms.get('status')}"
                )
                print(f"    Type: {ms.get('type', '')}")
                print(f"    Title: {ms.get('name')}")
                print(f"    log url: {ms.get('log_url')}")
                print(f"    Purpose: {ms.get('objective')}")
                audience = []
                for i in ms.get('audience'):
                    if isinstance(ms.get(i, i), str):
                        audience.append(ms.get(i, i))
                    else:
                        if ms.get(i):
                            audience.extend(ms.get(i))
                out = ", ".join(audience)
                print(f"    Audience: {out}")
            else:
                print(
                    f"{ms.get('due_date')}: lead: {ms.get('lead')}, {ms.get('id')}, {ms.get('name')}, status: {ms.get('status')}"
                )

        return
コード例 #14
0
    def sout(self):
        rc = self.rc
        # This if statement should be in all listers. Make sure to change self.gtx to get the database the lister needs
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["projecta"], rc.filter)
        else:
            collection = self.gtx["projecta"]

        if (not rc.lead) and (not rc.verbose) and (not rc.stati) and (
                not rc.current) and (not rc.person) and (not rc.all):
            return

        if rc.lead:
            if rc.person:
                raise RuntimeError(
                    f"please specify either lead or person, not both")
            collection = [
                prum for prum in collection if prum.get('lead') == rc.lead
            ]
        if rc.person:
            if isinstance(rc.person, str):
                rc.person = [rc.person]
            collection = [
                prum for prum in collection
                if prum.get('lead') in rc.person or bool(
                    set(prum.get('group_members', [])).intersection(
                        set(rc.person)))
            ]
#        if rc.current:
#            collection = [prum for prum in collection if
#                          prum.get('status') in ACTIVE_STATI]
#        if rc.finished:
#            collection = [prum for prum in collection if
#                          prum.get('status') in FINISHED_STATI]
        if not rc.all:
            collection = [
                prum for prum in collection
                if prum.get('status') not in INACTIVE_STATI
            ]

        all_milestones = []
        if not rc.stati:
            rc.stati = ['started']
        for projectum in collection:
            projectum["deliverable"].update({
                "name": "deliverable",
                "objective": "deliver"
            })
            projectum["kickoff"].update({"type": "meeting"})
            milestones = [projectum["kickoff"], projectum["deliverable"]]
            milestones.extend(projectum["milestones"])
            if rc.current:
                milestones = [
                    ms for ms in milestones if ms.get('status') in ACTIVE_STATI
                ]
            if rc.finished:
                milestones = [
                    ms for ms in milestones
                    if ms.get('status') in FINISHED_STATI
                ]
            if not rc.all:
                milestones = [
                    ms for ms in milestones
                    if ms.get('status') not in INACTIVE_STATI
                ]
            for ms in milestones:
                due_date = get_due_date(ms)
                ms.update({
                    'lead': projectum.get('lead'),
                    'group_members': projectum.get('group_members'),
                    'collaborators': projectum.get('collaborators'),
                    'id': projectum.get('_id'),
                    'due_date': due_date,
                    'log_url': projectum.get('log_url'),
                    'pi': projectum.get('pi_id')
                })
                all_milestones.append(ms)
        all_milestones.sort(key=lambda x: x['due_date'], reverse=True)
        if rc.keys:
            results = (collection_str(all_milestones, rc.keys))
            print(results, end="")
            return
        for ms in all_milestones:
            if rc.verbose:
                print(
                    f"{ms.get('due_date')}: lead: {ms.get('lead')}, {ms.get('id')}, status: {ms.get('status')}"
                )
                print(f"    Type: {ms.get('type', '')}")
                print(f"    Title: {ms.get('name')}")
                print(f"    log url: {ms.get('log_url')}")
                print(f"    Purpose: {ms.get('objective')}")
                audience = []
                for i in ms.get('audience'):
                    if isinstance(ms.get(i, i), str):
                        audience.append(ms.get(i, i))
                    else:
                        if ms.get(i):
                            audience.extend(ms.get(i))
                out = ", ".join(audience)
                print(f"    Audience: {out}")
            else:
                print(
                    f"{ms.get('due_date')}: lead: {ms.get('lead')}, {ms.get('id')}, {ms.get('name')}, status: {ms.get('status')}"
                )

        return
コード例 #15
0
def test_key_value_pair_filter(input, expected):
    assert (key_value_pair_filter(input[0], input[1]) == expected)
コード例 #16
0
 def db_updater(self):
     rc = self.rc
     if rc.index:
         if rc.index >= 9900:
             print("WARNING: indices >= 9900 are used for milestones which "
                   "should be finished using u_milestone and not f_todo")
             return
     if not rc.assigned_to:
         try:
             rc.assigned_to = rc.default_user_id
         except AttributeError:
             print(
                 "Please set default_user_id in '~/.config/regolith/user.json', or you need to enter your group id "
                 "in the command line")
             return
     person = document_by_value(
         all_docs_from_collection(rc.client, "todos"), "_id",
         rc.assigned_to)
     filterid = {'_id': rc.assigned_to}
     if not person:
         raise TypeError(
             f"Id {rc.assigned_to} can't be found in todos collection")
     todolist = person.get("todos", [])
     if len(todolist) == 0:
         print(f"{rc.assigned_to} doesn't have todos in todos collection.")
         return
     now = dt.date.today()
     if not rc.index:
         if not rc.date:
             today = now
         else:
             today = date_parser.parse(rc.date).date()
         if rc.filter:
             todolist = key_value_pair_filter(todolist, rc.filter)
         for todo in todolist:
             if type(todo["due_date"]) == str:
                 todo["due_date"] = date_parser.parse(
                     todo["due_date"]).date()
             todo["days_to_due"] = (todo.get('due_date') - today).days
             todo["order"] = 1 / (1 +
                                  math.exp(abs(todo["days_to_due"] - 0.5)))
         todolist = sorted(todolist,
                           key=lambda k: (k['status'], k['importance'], k[
                               'order'], -k.get('duration', 10000)))
         print(
             "If the indices are far from being in numerical order, please renumber them by running regolith helper u_todo -r"
         )
         print("Please choose from one of the following to update:")
         print(
             "(index) action (days to due date|importance|expected duration (mins)|tags|assigned by)"
         )
         print("-" * 80)
         print_task(todolist, stati=['started'])
     else:
         match_todo = [
             i for i in todolist if i.get("running_index") == rc.index
         ]
         if len(match_todo) == 0:
             raise RuntimeError("Please enter a valid index.")
         else:
             todo = match_todo[0]
             todo["status"] = "finished"
             if not rc.end_date:
                 end_date = now
             else:
                 end_date = date_parser.parse(rc.end_date).date()
             todo["end_date"] = end_date
             for i in range(0, len(rc.databases)):
                 db_name = rc.databases[i]["name"]
                 person_update = rc.client.find_one(db_name, rc.coll,
                                                    filterid)
                 if person_update:
                     todolist_update = person_update.get("todos", [])
                 else:
                     continue
                 if len(todolist_update) != 0:
                     for i, todo_u in enumerate(todolist_update):
                         if rc.index == todo_u.get("running_index"):
                             todolist_update[i] = todo
                             rc.client.update_one(
                                 db_name,
                                 rc.coll, {'_id': rc.assigned_to},
                                 {"todos": todolist_update},
                                 upsert=True)
                             print(
                                 f"The task \"({todo_u['running_index']}) {todo_u['description'].strip()}\" in {db_name} for {rc.assigned_to} has been marked as finished."
                             )
                             return
     return
コード例 #17
0
    def sout(self):
        rc = self.rc
        if rc.filter:
            collection = key_value_pair_filter(self.gtx["projecta"], rc.filter)
        else:
            collection = self.gtx["projecta"]

        projecta = []
        for projectum in collection:
            if (not rc.lead) and (not rc.stati):
                projecta.append(projectum)
                continue
            if rc.lead and projectum.get('lead') != rc.lead:
                continue
            if rc.stati and projectum.get('status') not in rc.stati:
                continue
            projecta.append(projectum)

        selected_projecta = []
        for p in projecta:
            if p.get('status') != "proposed":
                continue
            selected_projecta.append(p)
        if selected_projecta:
            print(
                f"*************************[Proposed Projecta]*************************"
            )
            print_projectum(selected_projecta, rc)

        selected_projecta = []
        for p in projecta:
            if p.get('status') != "started":
                continue
            selected_projecta.append(p)
        if selected_projecta:
            print(
                f"*************************[Started Projecta]**************************"
            )
            print_projectum(selected_projecta, rc)

        selected_projecta = []
        for p in projecta:
            if p.get('status') != "finished":
                continue
            selected_projecta.append(p)
        if selected_projecta:
            print(
                f"*************************[Finished Projecta]*************************"
            )
            print_projectum(selected_projecta, rc)

        selected_projecta = []
        for p in projecta:
            if p.get('status') not in ["back_burner", "paused", "cancelled"]:
                continue
            selected_projecta.append(p)
        if selected_projecta:
            print(
                f"*************************[Others]************************************"
            )
            print_projectum(selected_projecta, rc)