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
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
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)
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
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
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
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
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
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
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
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
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"))
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
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
def test_key_value_pair_filter(input, expected): assert (key_value_pair_filter(input[0], input[1]) == expected)
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
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)