From e396c646c1c7399cbd6048be0773c1ad9d3df1e0 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 3 Jan 2020 08:08:27 -0500 Subject: [PATCH 01/27] initial commit of recent-collabs builder --- regolith/builder.py | 2 + regolith/builders/recentcollabsbuilder.py | 91 +++++++++++++++++++++++ regolith/templates/recentcollabs.csv | 3 + tests/test_builders.py | 2 + 4 files changed, 98 insertions(+) create mode 100644 regolith/builders/recentcollabsbuilder.py create mode 100644 regolith/templates/recentcollabs.csv diff --git a/regolith/builder.py b/regolith/builder.py index 90d7b750c..5075893ae 100644 --- a/regolith/builder.py +++ b/regolith/builder.py @@ -12,6 +12,7 @@ from regolith.builders.resumebuilder import ResumeBuilder from regolith.builders.cpbuilder import CPBuilder from regolith.builders.figurebuilder import FigureBuilder +from regolith.builders.recentcollabsbuilder import RecentCollabsBuilder BUILDERS = { @@ -28,6 +29,7 @@ "preslist": PresListBuilder, "reimb": ReimbursementBuilder, "figure": FigureBuilder, + "recent-collabs": RecentCollabsBuilder, } diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py new file mode 100644 index 000000000..01e656b53 --- /dev/null +++ b/regolith/builders/recentcollabsbuilder.py @@ -0,0 +1,91 @@ +"""Builder for publication lists.""" +import os + +try: + from bibtexparser.bwriter import BibTexWriter + from bibtexparser.bibdatabase import BibDatabase + + HAVE_BIBTEX_PARSER = True +except ImportError: + HAVE_BIBTEX_PARSER = False + +from regolith.tools import all_docs_from_collection +from regolith.sorters import doc_date_key, ene_date_key, position_key +from regolith.builders.basebuilder import LatexBuilderBase, latex_safe + +LATEX_OPTS = ["-halt-on-error", "-file-line-error"] + + +class RecentCollabsBuilder(LatexBuilderBase): + + btype = "recent-collabs" + + def construct_global_ctx(self): + super().construct_global_ctx() + gtx = self.gtx + rc = self.rc + + gtx["people"] = sorted( + all_docs_from_collection(rc.client, "people"), + key=position_key, + reverse=True, + ) + gtx["all_docs_from_collection"] = all_docs_from_collection + + def latex(self): + rc = self.rc + for p in self.gtx["people"]: + names = frozenset(p.get("aka", []) + [p["name"]]) + pubs = self.filter_publications(names, reverse=True) + bibfile = self.make_bibtex_file( + pubs, pid=p["_id"], person_dir=self.bldir + ) + emp = p.get("employment", []) + emp.sort(key=ene_date_key, reverse=True) + self.render( + "recentcollabslist.tex", + p["_id"] + ".tex", + p=p, + title=p.get("name", ""), + pubs=pubs, + names=names, + bibfile=bibfile, + employment=emp, + ) + self.pdf(p["_id"]) + + def filter_publications(self, authors, reverse=False): + rc = self.rc + pubs = [] + for pub in all_docs_from_collection(rc.client, "citations"): + if len(set(pub["author"]) & authors) == 0: + continue + bold_self = [] + for a in pub["author"]: + if a in authors: + bold_self.append("\\textbf{" + a + "}") + else: + bold_self.append(a) + pub["author"] = bold_self + pubs.append(pub) + pubs.sort(key=doc_date_key, reverse=reverse) + return pubs + + def make_bibtex_file(self, pubs, pid, person_dir="."): + if not HAVE_BIBTEX_PARSER: + return None + skip_keys = set(["ID", "ENTRYTYPE", "author"]) + self.bibdb.entries = ents = [] + for pub in pubs: + ent = dict(pub) + ent["ID"] = ent.pop("_id") + ent["ENTRYTYPE"] = ent.pop("entrytype") + ent["author"] = " and ".join(ent["author"]) + for key in ent.keys(): + if key in skip_keys: + continue + ents.append(ent) + fname = os.path.join(person_dir, pid) + ".bib" + with open(fname, "w", encoding='utf-8') as f: + f.write(self.bibwriter.write(self.bibdb)) + return fname diff --git a/regolith/templates/recentcollabs.csv b/regolith/templates/recentcollabs.csv new file mode 100644 index 000000000..4d6ec217e --- /dev/null +++ b/regolith/templates/recentcollabs.csv @@ -0,0 +1,3 @@ +%person collaborated with +{{p['title']}} {{p['name']}} + diff --git a/tests/test_builders.py b/tests/test_builders.py index faa1a11b4..3f040c211 100644 --- a/tests/test_builders.py +++ b/tests/test_builders.py @@ -19,6 +19,8 @@ "preslist", "reimb", "figure", + "review-man", + "recent-collabs" ] xls_check = ("B17", "B20", "B36") From a6b98511e3da519df80c90fdb96f1b341bb99d2e Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 3 Jan 2020 09:48:21 -0500 Subject: [PATCH 02/27] now extracts people it finds in author list, but only if in people collection --- regolith/builders/recentcollabsbuilder.py | 56 +++++++++++------------ regolith/templates/recentcollabs.csv | 1 + 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index 01e656b53..dc02ab445 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -1,5 +1,7 @@ """Builder for publication lists.""" import os +import datetime as dt +from dateutil.relativedelta import relativedelta try: from bibtexparser.bwriter import BibTexWriter @@ -9,7 +11,8 @@ except ImportError: HAVE_BIBTEX_PARSER = False -from regolith.tools import all_docs_from_collection +from regolith.tools import all_docs_from_collection, filter_publications, \ + is_since, fuzzy_retrieval from regolith.sorters import doc_date_key, ene_date_key, position_key from regolith.builders.basebuilder import LatexBuilderBase, latex_safe @@ -17,7 +20,6 @@ class RecentCollabsBuilder(LatexBuilderBase): - btype = "recent-collabs" def construct_global_ctx(self): @@ -30,46 +32,42 @@ def construct_global_ctx(self): key=position_key, reverse=True, ) + gtx["citations"] = all_docs_from_collection(rc.client, "citations") gtx["all_docs_from_collection"] = all_docs_from_collection def latex(self): rc = self.rc + since_date = dt.date.today() - relativedelta(months=48) for p in self.gtx["people"]: - names = frozenset(p.get("aka", []) + [p["name"]]) - pubs = self.filter_publications(names, reverse=True) - bibfile = self.make_bibtex_file( - pubs, pid=p["_id"], person_dir=self.bldir - ) + if p["_id"] == "sbillinge": + my_names = frozenset(p.get("aka", []) + [p["name"]]) + pubs = filter_publications(self.gtx["citations"], my_names, + reverse=True, bold=False) + my_collabs = [] + for pub in pubs: + if is_since(pub.get("year"), since_date.year, pub.get("month", 1), since_date.month): + if not pub.get("month"): + print("WARNING: {} is missing month".format( + pub["_id"])) + my_collabs.extend([collabs for collabs in + [names for names in + pub.get('author', [])]]) + people = [] + for collab in my_collabs: + people.append(fuzzy_retrieval(self.gtx["people"], + ["name", "aka", "_id"], collab)) + print(set([person["name"] for person in people if person])) emp = p.get("employment", []) emp.sort(key=ene_date_key, reverse=True) self.render( - "recentcollabslist.tex", - p["_id"] + ".tex", + "recentcollabs.csv", + p["_id"] + ".csv", p=p, title=p.get("name", ""), pubs=pubs, - names=names, - bibfile=bibfile, employment=emp, + collabs=my_collabs ) - self.pdf(p["_id"]) - - def filter_publications(self, authors, reverse=False): - rc = self.rc - pubs = [] - for pub in all_docs_from_collection(rc.client, "citations"): - if len(set(pub["author"]) & authors) == 0: - continue - bold_self = [] - for a in pub["author"]: - if a in authors: - bold_self.append("\\textbf{" + a + "}") - else: - bold_self.append(a) - pub["author"] = bold_self - pubs.append(pub) - pubs.sort(key=doc_date_key, reverse=reverse) - return pubs def make_bibtex_file(self, pubs, pid, person_dir="."): if not HAVE_BIBTEX_PARSER: diff --git a/regolith/templates/recentcollabs.csv b/regolith/templates/recentcollabs.csv index 4d6ec217e..5f8ca09ae 100644 --- a/regolith/templates/recentcollabs.csv +++ b/regolith/templates/recentcollabs.csv @@ -1,3 +1,4 @@ %person collaborated with {{p['title']}} {{p['name']}} +{{ my_collabs }} \ No newline at end of file From dd4d779b66cc62dff47b38ea25b12c7877b22b47 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 3 Jan 2020 10:01:48 -0500 Subject: [PATCH 03/27] WIP working and returns set of folks in people coll --- regolith/builders/recentcollabsbuilder.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index dc02ab445..9d161ba31 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -56,7 +56,11 @@ def latex(self): for collab in my_collabs: people.append(fuzzy_retrieval(self.gtx["people"], ["name", "aka", "_id"], collab)) - print(set([person["name"] for person in people if person])) + institutions = [places[0]["institution"] for places in + [person["education"] for person in people if person]] + ppl_names = [person["name"] for person in people if person] +# print(set([person["name"] for person in people if person])) + print(set([(person,institution) for person, institution in zip(ppl_names, institutions)])) emp = p.get("employment", []) emp.sort(key=ene_date_key, reverse=True) self.render( From 54e3ee131dbc05816b134e6a74955225896c464d Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Sun, 5 Jan 2020 06:49:43 -0500 Subject: [PATCH 04/27] proper name parsing in recentcollabs builder --- regolith/builders/recentcollabsbuilder.py | 66 +++++++++++++++++++---- regolith/dates.py | 2 +- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index 9d161ba31..c25b46563 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -1,6 +1,7 @@ """Builder for publication lists.""" import os import datetime as dt +from copy import copy from dateutil.relativedelta import relativedelta try: @@ -32,6 +33,13 @@ def construct_global_ctx(self): key=position_key, reverse=True, ) + gtx["contacts"] = sorted( + all_docs_from_collection(rc.client, "contacts"), + key=position_key, + reverse=True, + ) + gtx["institutions"] = all_docs_from_collection(rc.client, + "institutions") gtx["citations"] = all_docs_from_collection(rc.client, "citations") gtx["all_docs_from_collection"] = all_docs_from_collection @@ -45,22 +53,62 @@ def latex(self): reverse=True, bold=False) my_collabs = [] for pub in pubs: - if is_since(pub.get("year"), since_date.year, pub.get("month", 1), since_date.month): + if is_since(pub.get("year"), since_date.year, + pub.get("month", 1), since_date.month): if not pub.get("month"): print("WARNING: {} is missing month".format( pub["_id"])) my_collabs.extend([collabs for collabs in [names for names in pub.get('author', [])]]) - people = [] + people, institutions = [], [] for collab in my_collabs: - people.append(fuzzy_retrieval(self.gtx["people"], - ["name", "aka", "_id"], collab)) - institutions = [places[0]["institution"] for places in - [person["education"] for person in people if person]] - ppl_names = [person["name"] for person in people if person] -# print(set([person["name"] for person in people if person])) - print(set([(person,institution) for person, institution in zip(ppl_names, institutions)])) + person = fuzzy_retrieval(all_docs_from_collection( + rc.client, "people"), + ["name", "aka", "_id"], + collab) + if not person: + person = fuzzy_retrieval(all_docs_from_collection( + rc.client, "contacts"), + ["name", "aka", "_id"], collab) + if not person: + print( + "WARNING: {} not found in contacts. Check aka".format( + collab)) + else: + people.append(person) + inst = fuzzy_retrieval(all_docs_from_collection( + rc.client, "institutions"), + ["name", "aka", "_id"], + person["institution"]) + if inst: + institutions.append(inst["name"]) + else: + institutions.append( + person.get("institution", "missing")) + print( + "WARNING: {} missing from institutions".format( + person["institution"])) + else: + people.append(person) + pinst = person.get("employment", + [{"organization": "missing"}])[ + 0]["organization"] + inst = fuzzy_retrieval(all_docs_from_collection( + rc.client, "institutions"), ["name", "aka", "_id"], + pinst) + if inst: + institutions.append(inst["name"]) + else: + institutions.append(pinst) + print( + "WARNING: {} missing from institutions".format( + pinst)) + ppl_names = [(person["name"], i) for + person, i in zip(people, institutions) if + person] + # print(set([person["name"] for person in people if person])) + print(set([person for person in ppl_names])) emp = p.get("employment", []) emp.sort(key=ene_date_key, reverse=True) self.render( diff --git a/regolith/dates.py b/regolith/dates.py index 7d13fc026..616555e17 100644 --- a/regolith/dates.py +++ b/regolith/dates.py @@ -40,7 +40,7 @@ "dec.": 12, "december": 12, "": 1, - "tbd": 1, + "tbd": 1 } From 49a105b8901b202f9b674b5a69ccf470f2f31fa9 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Sun, 5 Jan 2020 16:16:10 -0500 Subject: [PATCH 05/27] tweaking error handling in recent_collabs --- regolith/builders/recentcollabsbuilder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index c25b46563..afa3f5f94 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -109,7 +109,8 @@ def latex(self): person] # print(set([person["name"] for person in people if person])) print(set([person for person in ppl_names])) - emp = p.get("employment", []) + emp = p.get("employment", [{"organization": "missing", + "begin_year": 2019}]) emp.sort(key=ene_date_key, reverse=True) self.render( "recentcollabs.csv", From 87993078a3ad064219379f48bbc2071899112150 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 10 Jan 2020 16:34:08 -0500 Subject: [PATCH 06/27] adding dateutil to requirements --- requirements/run.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements/run.txt b/requirements/run.txt index 52eac1ac9..02eb6e04b 100644 --- a/requirements/run.txt +++ b/requirements/run.txt @@ -7,3 +7,4 @@ xonsh rever openpyxl nameparser +dateutil From 95eff79bea7e964b010d1f656349b41f224bf03a Mon Sep 17 00:00:00 2001 From: Long Yang Date: Wed, 5 Feb 2020 16:52:09 -0500 Subject: [PATCH 07/27] ENH: add needed_dbs --- regolith/builders/recentcollabsbuilder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index afa3f5f94..bafaf517c 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -22,6 +22,7 @@ class RecentCollabsBuilder(LatexBuilderBase): btype = "recent-collabs" + needed_dbs = ['citations','people','contacts','institutions'] def construct_global_ctx(self): super().construct_global_ctx() From 2e164af15063903715e52350660b2ae23cb30a9c Mon Sep 17 00:00:00 2001 From: Long Yang Date: Wed, 5 Feb 2020 17:03:55 -0500 Subject: [PATCH 08/27] MAINT: replace sbillinge with people argument --- regolith/builders/recentcollabsbuilder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index bafaf517c..e06845268 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -47,8 +47,9 @@ def construct_global_ctx(self): def latex(self): rc = self.rc since_date = dt.date.today() - relativedelta(months=48) + person = fuzzy_retrieval(all_docs_from_collection(rc.client, "people"), ['aka', 'name', '_id'], self.rc.people, case_sensitive = False) for p in self.gtx["people"]: - if p["_id"] == "sbillinge": + if p["_id"] == person["_id"]: my_names = frozenset(p.get("aka", []) + [p["name"]]) pubs = filter_publications(self.gtx["citations"], my_names, reverse=True, bold=False) From 68145d17653b9ad8aae752d2f986acf973dc8fd8 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Sat, 15 Feb 2020 08:12:46 -0500 Subject: [PATCH 09/27] catch tbd months --- regolith/builders/recentcollabsbuilder.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index e06845268..1c90fcac6 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -60,6 +60,10 @@ def latex(self): if not pub.get("month"): print("WARNING: {} is missing month".format( pub["_id"])) + if pub.get("month") == "tbd".casefold(): + print("WARNING: month in {} is tbd".format( + pub["_id"])) + my_collabs.extend([collabs for collabs in [names for names in pub.get('author', [])]]) From 484abe54c46cab4afff0ff0bd28564447c8a421a Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Sun, 16 Feb 2020 17:29:53 -0500 Subject: [PATCH 10/27] more friendly fail when no person is specified --- .travis.yml | 2 +- regolith/builders/recentcollabsbuilder.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4bd94bfe3..645d45a8d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ env: matrix: include: - - python: 3.6 + - python: 3.8 install: # Install conda diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index 1c90fcac6..ab0497d5b 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -1,6 +1,7 @@ """Builder for publication lists.""" import os import datetime as dt +import sys from copy import copy from dateutil.relativedelta import relativedelta @@ -48,6 +49,8 @@ def latex(self): rc = self.rc since_date = dt.date.today() - relativedelta(months=48) person = fuzzy_retrieval(all_docs_from_collection(rc.client, "people"), ['aka', 'name', '_id'], self.rc.people, case_sensitive = False) + if not person: + sys.exit("please rerun specifying --people PERSON") for p in self.gtx["people"]: if p["_id"] == person["_id"]: my_names = frozenset(p.get("aka", []) + [p["name"]]) From 5db5ea00e094a1ad3d0026355a72fead4d255292 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 3 Jan 2020 09:48:21 -0500 Subject: [PATCH 11/27] now extracts people it finds in author list, but only if in people collection --- regolith/builders/recentcollabsbuilder.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index ab0497d5b..232f7aecb 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -127,9 +127,29 @@ def latex(self): p=p, title=p.get("name", ""), pubs=pubs, + names=names, + bibfile=bibfile, employment=emp, collabs=my_collabs ) + self.pdf(p["_id"]) + + def filter_publications(self, authors, reverse=False): + rc = self.rc + pubs = [] + for pub in all_docs_from_collection(rc.client, "citations"): + if len(set(pub["author"]) & authors) == 0: + continue + bold_self = [] + for a in pub["author"]: + if a in authors: + bold_self.append("\\textbf{" + a + "}") + else: + bold_self.append(a) + pub["author"] = bold_self + pubs.append(pub) + pubs.sort(key=doc_date_key, reverse=reverse) + return pubs def make_bibtex_file(self, pubs, pid, person_dir="."): if not HAVE_BIBTEX_PARSER: From a6bc4ba3141c155c7898109a59f6c3216fc132b0 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 17 Feb 2020 06:38:29 -0500 Subject: [PATCH 12/27] people seems to be enforced as list in p3.8] --- regolith/builders/recentcollabsbuilder.py | 28 +++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py index 232f7aecb..adccd0c10 100644 --- a/regolith/builders/recentcollabsbuilder.py +++ b/regolith/builders/recentcollabsbuilder.py @@ -23,7 +23,7 @@ class RecentCollabsBuilder(LatexBuilderBase): btype = "recent-collabs" - needed_dbs = ['citations','people','contacts','institutions'] + needed_dbs = ['citations', 'people', 'contacts', 'institutions'] def construct_global_ctx(self): super().construct_global_ctx() @@ -48,7 +48,11 @@ def construct_global_ctx(self): def latex(self): rc = self.rc since_date = dt.date.today() - relativedelta(months=48) - person = fuzzy_retrieval(all_docs_from_collection(rc.client, "people"), ['aka', 'name', '_id'], self.rc.people, case_sensitive = False) + if isinstance(self.rc.people, str): + self.rc.people = [self.rc.people] + person = fuzzy_retrieval(all_docs_from_collection(rc.client, "people"), + ['aka', 'name', '_id'], self.rc.people[0], + case_sensitive=False) if not person: sys.exit("please rerun specifying --people PERSON") for p in self.gtx["people"]: @@ -73,13 +77,13 @@ def latex(self): people, institutions = [], [] for collab in my_collabs: person = fuzzy_retrieval(all_docs_from_collection( - rc.client, "people"), - ["name", "aka", "_id"], - collab) + rc.client, "people"), + ["name", "aka", "_id"], + collab) if not person: person = fuzzy_retrieval(all_docs_from_collection( rc.client, "contacts"), - ["name", "aka", "_id"], collab) + ["name", "aka", "_id"], collab) if not person: print( "WARNING: {} not found in contacts. Check aka".format( @@ -87,9 +91,9 @@ def latex(self): else: people.append(person) inst = fuzzy_retrieval(all_docs_from_collection( - rc.client, "institutions"), - ["name", "aka", "_id"], - person["institution"]) + rc.client, "institutions"), + ["name", "aka", "_id"], + person["institution"]) if inst: institutions.append(inst["name"]) else: @@ -101,11 +105,11 @@ def latex(self): else: people.append(person) pinst = person.get("employment", - [{"organization": "missing"}])[ - 0]["organization"] + [{"organization": "missing"}])[ + 0]["organization"] inst = fuzzy_retrieval(all_docs_from_collection( rc.client, "institutions"), ["name", "aka", "_id"], - pinst) + pinst) if inst: institutions.append(inst["name"]) else: From 71e55dcb04ccc37a9ddb1f35a8009c85d2d22d09 Mon Sep 17 00:00:00 2001 From: Hung Vuong Date: Wed, 19 Feb 2020 14:22:59 -0500 Subject: [PATCH 13/27] test file --- news/test.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 news/test.rst diff --git a/news/test.rst b/news/test.rst new file mode 100644 index 000000000..e69de29bb From f2afba35b07ec6e6b7e1ae913aa9239eeaeef030 Mon Sep 17 00:00:00 2001 From: Hung Vuong Date: Wed, 19 Feb 2020 14:28:22 -0500 Subject: [PATCH 14/27] added coa_template.xlsx --- regolith/templates/coa_template.xlsx | Bin 0 -> 18984 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 regolith/templates/coa_template.xlsx diff --git a/regolith/templates/coa_template.xlsx b/regolith/templates/coa_template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..72b2ed8464d1cd34ae67fcc4fa7ae0c0b3866d9c GIT binary patch literal 18984 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 literal 0 HcmV?d00001 From b6fbe30f56ea89c6f63ae7ad33b2f24a9e5f79f5 Mon Sep 17 00:00:00 2001 From: Hung Vuong Date: Thu, 20 Feb 2020 15:38:57 -0500 Subject: [PATCH 15/27] - added script coabuilder.py filling in excel template - working on fixing cells with data validation --- regolith/builder.py | 4 +- regolith/builders/coabuilder.py | 173 ++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 regolith/builders/coabuilder.py diff --git a/regolith/builder.py b/regolith/builder.py index 5075893ae..8d9099d1b 100644 --- a/regolith/builder.py +++ b/regolith/builder.py @@ -12,7 +12,7 @@ from regolith.builders.resumebuilder import ResumeBuilder from regolith.builders.cpbuilder import CPBuilder from regolith.builders.figurebuilder import FigureBuilder -from regolith.builders.recentcollabsbuilder import RecentCollabsBuilder +from regolith.builders.coabuilder import RecentCollaboratorsBuilder BUILDERS = { @@ -29,7 +29,7 @@ "preslist": PresListBuilder, "reimb": ReimbursementBuilder, "figure": FigureBuilder, - "recent-collabs": RecentCollabsBuilder, + "recent-collabs": RecentCollaboratorsBuilder, } diff --git a/regolith/builders/coabuilder.py b/regolith/builders/coabuilder.py new file mode 100644 index 000000000..a1ca05091 --- /dev/null +++ b/regolith/builders/coabuilder.py @@ -0,0 +1,173 @@ +"""Builder for Resumes.""" + +import datetime as dt +import os +import sys +import openpyxl + +from regolith.builders.basebuilder import BuilderBase +from regolith.dates import month_to_int +from regolith.sorters import doc_date_key, ene_date_key, position_key +from regolith.tools import all_docs_from_collection, filter_publications, \ + month_and_year, fuzzy_retrieval, is_since +from copy import copy +from dateutil.relativedelta import relativedelta + + + +def mdy_date(month, day, year, **kwargs): + if isinstance(month, str): + month = month_to_int(month) + return dt.date(year, month, day) + + +def mdy(month, day, year, **kwargs): + return "{}/{}/{}".format( + str(month_to_int(month)).zfill(2), str(day).zfill(2), str(year)[-2:] + ) + + +class RecentCollaboratorsBuilder(BuilderBase): + """Build recent collaborators from database entries""" + + btype = "recent-collabs" + needed_dbs = ['citations', 'people', 'contacts', 'institutions'] + + def __init__(self, rc): + super().__init__(rc) + self.template = os.path.join( + os.path.dirname(os.path.dirname(__file__)), "templates", "coa_template.xlsx" + ) + self.cmds = ["excel"] + + def construct_global_ctx(self): + super().construct_global_ctx() + gtx = self.gtx + rc = self.rc + + gtx["people"] = sorted( + all_docs_from_collection(rc.client, "people"), + key=position_key, + reverse=True, + ) + gtx["contacts"] = sorted( + all_docs_from_collection(rc.client, "contacts"), + key=position_key, + reverse=True, + ) + gtx["institutions"] = all_docs_from_collection(rc.client, + "institutions") + gtx["citations"] = all_docs_from_collection(rc.client, "citations") + gtx["all_docs_from_collection"] = all_docs_from_collection + + def excel(self): + rc = self.rc + gtx = self.gtx + since_date = dt.date.today() - relativedelta(months=48) + if isinstance(self.rc.people, str): + self.rc.people = [self.rc.people] + person = fuzzy_retrieval(all_docs_from_collection(rc.client, "people"), + ['aka', 'name', '_id'], self.rc.people[0], + case_sensitive=False) + if not person: + sys.exit("please rerun specifying --people PERSON") + for p in self.gtx["people"]: + if p["_id"] == person["_id"]: + my_names = frozenset(p.get("aka", []) + [p["name"]]) + pubs = filter_publications(self.gtx["citations"], my_names, + reverse=True, bold=False) + my_collabs = [] + for pub in pubs: + if is_since(pub.get("year"), since_date.year, + pub.get("month", 1), since_date.month): + if not pub.get("month"): + print("WARNING: {} is missing month".format( + pub["_id"])) + if pub.get("month") == "tbd".casefold(): + print("WARNING: month in {} is tbd".format( + pub["_id"])) + + my_collabs.extend([collabs for collabs in + [names for names in + pub.get('author', [])]]) + people, institutions = [], [] + for collab in my_collabs: + person = fuzzy_retrieval(all_docs_from_collection( + rc.client, "people"), + ["name", "aka", "_id"], + collab) + if not person: + person = fuzzy_retrieval(all_docs_from_collection( + rc.client, "contacts"), + ["name", "aka", "_id"], collab) + if not person: + print( + "WARNING: {} not found in contacts. Check aka".format( + collab)) + else: + people.append(person) + inst = fuzzy_retrieval(all_docs_from_collection( + rc.client, "institutions"), + ["name", "aka", "_id"], + person["institution"]) + if inst: + institutions.append(inst["name"]) + else: + institutions.append( + person.get("institution", "missing")) + print( + "WARNING: {} missing from institutions".format( + person["institution"])) + else: + people.append(person) + pinst = person.get("employment", + [{"organization": "missing"}])[ + 0]["organization"] + inst = fuzzy_retrieval(all_docs_from_collection( + rc.client, "institutions"), ["name", "aka", "_id"], + pinst) + if inst: + institutions.append(inst["name"]) + else: + institutions.append(pinst) + print( + "WARNING: {} missing from institutions".format( + pinst)) + ppl_names = [(person["name"], i) for + person, i in zip(people, institutions) if + person] + # print(set([person["name"] for person in people if person])) + print(set([person for person in ppl_names])) + emp = p.get("employment", [{"organization": "missing", + "begin_year": 2019}]) + emp.sort(key=ene_date_key, reverse=True) + + def apply_cell_style(cell, style): + cell.font = style["font"] + cell.border = style["border"] + cell.fill = style["fill"] + cell.alignment = style["alignment"] + template = self.template + num_rows = len(ppl_names) # number of rows to add to the excel file + wb = openpyxl.load_workbook(template) + ws = wb.worksheets[0] + ws.move_range("A52:E66", rows=num_rows, cols=0, translate=True) + style_ref_cell = ws["B51"] + template_cell_style = {} + template_cell_style["font"] = copy(style_ref_cell.font) + template_cell_style["border"] = copy(style_ref_cell.border) + template_cell_style["fill"] = copy(style_ref_cell.fill) + template_cell_style["alignment"] = copy(style_ref_cell.alignment) + col_idx = ["A", "B", "C", "D", "E"] + for row in range(1, num_rows + 1): + try: + ws.unmerge_cells("A{}:E{}".format(row + 51, row + 51)) + except: + pass + for idx in range(len(col_idx)): + apply_cell_style(ws["{}{}".format(col_idx[idx], row + 51)], template_cell_style) + ws["A{}".format(row + 51)].value = "A" + ws["B{}".format(row + 51)].value = ppl_names[row - 1][0] + ws["C{}".format((row + 51))].value = ppl_names[row - 1][1] + ws.delete_rows(51) # deleting the reference row + wb.save(os.path.join(self.bldir, "coa_table.xlsx")) \ No newline at end of file From 900f02f6341be23c2148fe5a04f1e4af883f9161 Mon Sep 17 00:00:00 2001 From: Hung Vuong Date: Fri, 21 Feb 2020 10:31:28 -0500 Subject: [PATCH 16/27] - removed the duplicate entries - reformatted the names into Last, First format - sorted the names by alphabetical order (by last name) --- regolith/builders/coabuilder.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/regolith/builders/coabuilder.py b/regolith/builders/coabuilder.py index a1ca05091..3e2478f52 100644 --- a/regolith/builders/coabuilder.py +++ b/regolith/builders/coabuilder.py @@ -12,6 +12,8 @@ month_and_year, fuzzy_retrieval, is_since from copy import copy from dateutil.relativedelta import relativedelta +from operator import itemgetter +from openpyxl.worksheet.datavalidation import DataValidation @@ -136,8 +138,19 @@ def excel(self): ppl_names = [(person["name"], i) for person, i in zip(people, institutions) if person] + ppl = [] + # reformatting the name in last name, first name + for idx in range(len(ppl_names)): + names = ppl_names[idx][0].split() + last_name = names[-1] + first_name = ' '.join(names[:-1]) + name_reformatted = ', '.join([last_name, first_name]) + ppl.append((name_reformatted, ppl_names[idx][1])) + ppl = list(set(ppl)) + # sorting the ppl list + ppl_sorted = sorted(ppl, key=itemgetter(0)) # print(set([person["name"] for person in people if person])) - print(set([person for person in ppl_names])) + #print(set([person for person in ppl_names])) emp = p.get("employment", [{"organization": "missing", "begin_year": 2019}]) emp.sort(key=ene_date_key, reverse=True) @@ -148,9 +161,10 @@ def apply_cell_style(cell, style): cell.fill = style["fill"] cell.alignment = style["alignment"] template = self.template - num_rows = len(ppl_names) # number of rows to add to the excel file + num_rows = len(ppl) # number of rows to add to the excel file wb = openpyxl.load_workbook(template) ws = wb.worksheets[0] + ws.delete_rows(52, amount=3) # removing the example rows ws.move_range("A52:E66", rows=num_rows, cols=0, translate=True) style_ref_cell = ws["B51"] template_cell_style = {} @@ -166,8 +180,8 @@ def apply_cell_style(cell, style): pass for idx in range(len(col_idx)): apply_cell_style(ws["{}{}".format(col_idx[idx], row + 51)], template_cell_style) - ws["A{}".format(row + 51)].value = "A" - ws["B{}".format(row + 51)].value = ppl_names[row - 1][0] - ws["C{}".format((row + 51))].value = ppl_names[row - 1][1] + ws["A{}".format(row + 51)].value = "A:" + ws["B{}".format(row + 51)].value = ppl_sorted[row - 1][0] + ws["C{}".format((row + 51))].value = ppl_sorted[row - 1][1] ws.delete_rows(51) # deleting the reference row wb.save(os.path.join(self.bldir, "coa_table.xlsx")) \ No newline at end of file From 4ca5487faa8c0ca10ebeb35230e746c0d9eed81a Mon Sep 17 00:00:00 2001 From: Hung Vuong Date: Fri, 21 Feb 2020 10:34:28 -0500 Subject: [PATCH 17/27] added global variable NUM_MONTHS --- regolith/builders/coabuilder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/regolith/builders/coabuilder.py b/regolith/builders/coabuilder.py index 3e2478f52..fda98043c 100644 --- a/regolith/builders/coabuilder.py +++ b/regolith/builders/coabuilder.py @@ -13,9 +13,9 @@ from copy import copy from dateutil.relativedelta import relativedelta from operator import itemgetter -from openpyxl.worksheet.datavalidation import DataValidation +NUM_MONTHS = 48 def mdy_date(month, day, year, **kwargs): if isinstance(month, str): @@ -65,7 +65,7 @@ def construct_global_ctx(self): def excel(self): rc = self.rc gtx = self.gtx - since_date = dt.date.today() - relativedelta(months=48) + since_date = dt.date.today() - relativedelta(months=NUM_MONTHS) if isinstance(self.rc.people, str): self.rc.people = [self.rc.people] person = fuzzy_retrieval(all_docs_from_collection(rc.client, "people"), From abeadf0271d72b17424407404ce2aa7232189c82 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Wed, 4 Mar 2020 11:14:40 -0500 Subject: [PATCH 18/27] requirements should have python-dateutil not just dateutil --- requirements/run.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/run.txt b/requirements/run.txt index 02eb6e04b..68892a44d 100644 --- a/requirements/run.txt +++ b/requirements/run.txt @@ -7,4 +7,4 @@ xonsh rever openpyxl nameparser -dateutil +python-dateutil From 0b5677d000e997ec44adf3dc47cb3f97fbc5fa89 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Wed, 4 Mar 2020 11:43:23 -0500 Subject: [PATCH 19/27] remove missing review-man test for test_builders. This should be in a different pr. --- tests/test_builders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_builders.py b/tests/test_builders.py index 3f040c211..25abae21f 100644 --- a/tests/test_builders.py +++ b/tests/test_builders.py @@ -19,7 +19,7 @@ "preslist", "reimb", "figure", - "review-man", +# "review-man", "recent-collabs" ] From 232b17aa2f5f16f0a59817c19eca953f14e74cd1 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Wed, 4 Mar 2020 12:08:36 -0500 Subject: [PATCH 20/27] changing tests so that recent collabs will run with scopatz as person --- tests/test_builders.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_builders.py b/tests/test_builders.py index 25abae21f..a879aae1c 100644 --- a/tests/test_builders.py +++ b/tests/test_builders.py @@ -51,7 +51,7 @@ def test_builder(bm, make_db): prep_figure() if bm == "html": os.makedirs("templates/static", exist_ok=True) - if bm == "reimb": + if bm == "reimb" or bm == "recent-collabs": subprocess.run(["regolith", "build", bm, "--no-pdf", "--people", "scopatz"], check=True, cwd=repo ) else: @@ -95,7 +95,7 @@ def test_builder_python(bm, make_db): prep_figure() if bm == "html": os.makedirs("templates/static", exist_ok=True) - if bm == "reimb": + if bm == "reimb" or bm == "recent-collabs": main(["build", bm, "--no-pdf", "--people", "scopatz"]) else: main(["build", bm, "--no-pdf"]) From c20819550e29728bb0c0846e4f54125c2a5986dc Mon Sep 17 00:00:00 2001 From: Sani Harouna-Mayer Date: Wed, 4 Mar 2020 17:36:10 -0500 Subject: [PATCH 21/27] added function filter for advisors and positions, status of last commit of PR to wrong branch --- regolith/tools.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/regolith/tools.py b/regolith/tools.py index c64abc75f..c3152c248 100644 --- a/regolith/tools.py +++ b/regolith/tools.py @@ -425,6 +425,78 @@ def filter_grants(input_grants, names, pi=True, reverse=True, multi_pi=False): return grants, total_amount, subaward_amount +def filter_grants(input_grants, names, pi=True, reverse=True): + """Filter grants by those involved + + Parameters + ---------- + input_grants : list of dict + The grants to filter + names : set of str + The authors to be filtered against + pi : bool, optional + If True add the grant amount to that person's total amount + reverse : bool, optional + If True reverse the order, defaults to False + """ + grants = [] + total_amount = 0.0 + subaward_amount = 0.0 + for grant in input_grants: + team_names = set(gets(grant['team'], 'name')) + if len(team_names & names) == 0: + continue + grant = deepcopy(grant) + person = [x for x in grant['team'] if x['name'] in names][0] + if pi: + if person['position'].lower() == 'pi': + total_amount += grant['amount'] + else: + continue + else: + if person['position'].lower() == 'pi': + continue + else: + total_amount += grant['amount'] + subaward_amount += person.get('subaward_amount', 0.0) + grant['subaward_amount'] = person.get('subaward_amount', + 0.0) + grant['pi'] = [x for x in grant['team'] if + x['position'].lower() == 'pi'][0] + grant['me'] = person + grants.append(grant) + grants.sort(key=ene_date_key, reverse=reverse) + return grants, total_amount, subaward_amount + + +def filter_advisors(input_contacts, advisors, positions=["PhD", "post-doc"]): + """Filter for PhD and post-docs advisors. + + Parameters + ---------- + input_contacts : list of dict + The contacts information + advisors : list of str + The advisors to be filtered for + positions : list of str, optional + The positions to be filtered for + + Return + ------ + filtered_contacts: list of dicts + """ + output_contacts = [] + for contacts in input_contacts: + filtered_contacts = {} + for advisor in advisors: + for position in positions: + for person, info in contacts.items(): + if advisor == info['advisor'] and position == info['position']: + filtered_contacts[person] = info + output_contacts.append(filtered_contacts) + return output_contacts + + def awards_grants_honors(p): """Make sorted awards grants and honors list. From d29c162ad5527f75de3e926680a30b0c4b952bec Mon Sep 17 00:00:00 2001 From: Sani Harouna-Mayer Date: Wed, 4 Mar 2020 17:39:44 -0500 Subject: [PATCH 22/27] add advisor to schema @ education and employment --- regolith/schemas.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/regolith/schemas.py b/regolith/schemas.py index ffc51f4a3..85f1f1b6d 100644 --- a/regolith/schemas.py +++ b/regolith/schemas.py @@ -1366,6 +1366,7 @@ "schema": { "type": "dict", "schema": { + "advisor": {"required": False, "type": "string"}, "begin_day": {"required": False, "type": "integer"}, "begin_month": {"required": False, @@ -1411,6 +1412,7 @@ "schema": { "type": "dict", "schema": { + "advisor": {"required": False, "type": "string"}, "begin_day": {"required": False, "type": "integer"}, "begin_month": {"required": False, "anyof_type": ["string", "integer"], From 73f33730d557f7e3a8a4333339501ca30f0255e2 Mon Sep 17 00:00:00 2001 From: Sani Harouna-Mayer Date: Wed, 4 Mar 2020 21:29:18 -0500 Subject: [PATCH 23/27] deleted duplicated function filter grants @tools.py --- regolith/tools.py | 52 ++++++----------------------------------------- 1 file changed, 6 insertions(+), 46 deletions(-) diff --git a/regolith/tools.py b/regolith/tools.py index c3152c248..a08722f4c 100644 --- a/regolith/tools.py +++ b/regolith/tools.py @@ -425,50 +425,6 @@ def filter_grants(input_grants, names, pi=True, reverse=True, multi_pi=False): return grants, total_amount, subaward_amount -def filter_grants(input_grants, names, pi=True, reverse=True): - """Filter grants by those involved - - Parameters - ---------- - input_grants : list of dict - The grants to filter - names : set of str - The authors to be filtered against - pi : bool, optional - If True add the grant amount to that person's total amount - reverse : bool, optional - If True reverse the order, defaults to False - """ - grants = [] - total_amount = 0.0 - subaward_amount = 0.0 - for grant in input_grants: - team_names = set(gets(grant['team'], 'name')) - if len(team_names & names) == 0: - continue - grant = deepcopy(grant) - person = [x for x in grant['team'] if x['name'] in names][0] - if pi: - if person['position'].lower() == 'pi': - total_amount += grant['amount'] - else: - continue - else: - if person['position'].lower() == 'pi': - continue - else: - total_amount += grant['amount'] - subaward_amount += person.get('subaward_amount', 0.0) - grant['subaward_amount'] = person.get('subaward_amount', - 0.0) - grant['pi'] = [x for x in grant['team'] if - x['position'].lower() == 'pi'][0] - grant['me'] = person - grants.append(grant) - grants.sort(key=ene_date_key, reverse=reverse) - return grants, total_amount, subaward_amount - - def filter_advisors(input_contacts, advisors, positions=["PhD", "post-doc"]): """Filter for PhD and post-docs advisors. @@ -491,8 +447,12 @@ def filter_advisors(input_contacts, advisors, positions=["PhD", "post-doc"]): for advisor in advisors: for position in positions: for person, info in contacts.items(): - if advisor == info['advisor'] and position == info['position']: - filtered_contacts[person] = info + if info['education']['advisor']: + if advisor == info['education']['advisor'] and position == info['position']: + filtered_contacts[person] = info + if info['employment']['advisor']: + if advisor == info['employment']['advisor'] and position == info['position']: + filtered_contacts[person] = info output_contacts.append(filtered_contacts) return output_contacts From 4f25ea58586fb23e4071bf7e6400c2ebb5a7f09f Mon Sep 17 00:00:00 2001 From: Sani Harouna-Mayer Date: Thu, 5 Mar 2020 11:53:22 -0500 Subject: [PATCH 24/27] in EXEMPLARS - add an advisor entry for one entry in employment and one entry in education --- regolith/schemas.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/regolith/schemas.py b/regolith/schemas.py index 85f1f1b6d..ae3a45539 100644 --- a/regolith/schemas.py +++ b/regolith/schemas.py @@ -309,6 +309,7 @@ "bio": "Anthony Scopatz is currently an Assistant Professor", "education": [ { + "advisor": "sbillinge", "begin_year": 2008, "degree": "Ph.D. Mechanical Engineering, " "Nuclear and Radiation Engineering " @@ -363,6 +364,7 @@ "email": "scopatz@cec.sc.edu", "employment": [ { + "advisor": "sbillinge", "begin_year": 2015, "group": "ergs", "location": "Columbia, SC", @@ -376,7 +378,7 @@ "position": "Assistant Professor, Mechanical Engineering " "Department", }, { - "begin_year": 2013, + "advisor": "sbillinge","begin_year": 2013, "begin_month": "Jun", "begin_day": 1, "end_year": 2015, From 1fe7cd2da7ea8bb560f31f8b17cfb6968aa56cfa Mon Sep 17 00:00:00 2001 From: Sani Harouna-Mayer Date: Thu, 5 Mar 2020 12:02:30 -0500 Subject: [PATCH 25/27] add descripotion to advisor @employment & @education schema. description clear enough?? --- regolith/schemas.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/regolith/schemas.py b/regolith/schemas.py index ae3a45539..79e49677b 100644 --- a/regolith/schemas.py +++ b/regolith/schemas.py @@ -1368,7 +1368,10 @@ "schema": { "type": "dict", "schema": { - "advisor": {"required": False, "type": "string"}, + "advisor": {"required": False, "type": "string", + "description": "advisor/PI of the" + "education entry" + }, "begin_day": {"required": False, "type": "integer"}, "begin_month": {"required": False, @@ -1414,7 +1417,10 @@ "schema": { "type": "dict", "schema": { - "advisor": {"required": False, "type": "string"}, + "advisor": {"required": False, "type": "string", + "description": "advisor/PI of the" + "employment entry" + }, "begin_day": {"required": False, "type": "integer"}, "begin_month": {"required": False, "anyof_type": ["string", "integer"], From c1b527b004687509da36213350ee5026fd54fe8c Mon Sep 17 00:00:00 2001 From: Sani Harouna-Mayer Date: Mon, 16 Mar 2020 16:34:23 -0400 Subject: [PATCH 26/27] update schema.py -> education and employment -> advisor -> description: mentor --- regolith/schemas.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/regolith/schemas.py b/regolith/schemas.py index 79e49677b..44b893584 100644 --- a/regolith/schemas.py +++ b/regolith/schemas.py @@ -1369,7 +1369,7 @@ "type": "dict", "schema": { "advisor": {"required": False, "type": "string", - "description": "advisor/PI of the" + "description": "advisor/mentor of the" "education entry" }, "begin_day": {"required": False, @@ -1418,7 +1418,7 @@ "type": "dict", "schema": { "advisor": {"required": False, "type": "string", - "description": "advisor/PI of the" + "description": "advisor/mentor of the" "employment entry" }, "begin_day": {"required": False, "type": "integer"}, From 100c5eaf1e237eafd72b174685d52fbf0c7f4e6b Mon Sep 17 00:00:00 2001 From: Sani Harouna-Mayer Date: Mon, 16 Mar 2020 17:11:11 -0400 Subject: [PATCH 27/27] update schema.py -> change key name advisor to mentor --- regolith/schemas.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/regolith/schemas.py b/regolith/schemas.py index 44b893584..3a4ccf691 100644 --- a/regolith/schemas.py +++ b/regolith/schemas.py @@ -364,7 +364,7 @@ "email": "scopatz@cec.sc.edu", "employment": [ { - "advisor": "sbillinge", + "mentor": "sbillinge", "begin_year": 2015, "group": "ergs", "location": "Columbia, SC", @@ -378,7 +378,7 @@ "position": "Assistant Professor, Mechanical Engineering " "Department", }, { - "advisor": "sbillinge","begin_year": 2013, + "mentor": "sbillinge","begin_year": 2013, "begin_month": "Jun", "begin_day": 1, "end_year": 2015, @@ -1368,7 +1368,7 @@ "schema": { "type": "dict", "schema": { - "advisor": {"required": False, "type": "string", + "mentor": {"required": False, "type": "string", "description": "advisor/mentor of the" "education entry" }, @@ -1417,7 +1417,7 @@ "schema": { "type": "dict", "schema": { - "advisor": {"required": False, "type": "string", + "mentor": {"required": False, "type": "string", "description": "advisor/mentor of the" "employment entry" },