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 zcmeHvgLh?Hvu|wMw(X9Mj&0kvla8Hq$L`p+?T&5R&dWLH-Fv>Tzw_QdaPJypuRYe7 ztA1uM3D^u^m+gP9{+BSVQ9=EViJTRY}oip?uoohYxqsm(;RUF85%+fh8@NT7U5_w6EBj``hj= zSvp}L66)m^riAF0{EV3R_)#X7@Zas~`n8mV-!&v@sLW7ICIa^|f}x{`d|(T1OVmn` zc8~PzD4|UuX$od7zFi%np&b_#?%MQc@uiPNp$?A^Hlrm$?|EB8iC8IhXuQG3xAga* zWNTl|R5^w4`pu{T$|;)iVvvPUBG?;H?0z-z!)g^^S2xDNjM6ve$+SD>Ls-tps$K5; za_tO~N9eBLkEhhzJgQ8)p`|vFp=t6W(vnP;OktT=t-0a(c*QW%1mnpzvyUDO|48sY z$Uks!K`Zv)K=38JHrDlfFF!E?Y6??L1H)V=EN!|!yM}tt|5}y z=@kwD;Nt@rKFNGB|F8Z24>sC=>3UhbjO?HG zEB+cf^f0#;iy$cFDj?oUsN~}(u?k-wl}CcT)=7?opoA3&Eauzp^E$G!#uIfsM0mf= zQWk-P!cE-ZS{{<}Z0`(CMdpw!YG1b1hv+hQH+TO-Owyggr9FnKw5cdZYIuWK^w*Ve zHNqsFDi$Pi0Zs_ommmHb12XFC29FhhbApOz(C9SrOhnVJRz`ahg{dWIAvWx$7EPb=?T3bt1oc(SA)IQXpbMdSsdu8zjxX z^VO(hxf;!I?_-DTEgiZX4v4@nTK{xu|7j%tyoo6{pCi)pX(U(x5P)u0^ncljtF42j zfvv6OAMWnIYzFYt=Y695&pyf&WTg5S5Za;NLm6DtTu>30oal*8l~3RyhU+L-$OxHz zZa1*0TC~;XrRafeL)9xN-s9e?@;6HvODh? zW)G)S3a^Cqi&uyfLFkYezAt6G<6iEMR^^K=C&8By%FdN*n$g<}lilILxsA_%`ae}> zau%ME^;2EgK>z^YKkxWdnSWK5vIK40GzOHA3-U8QwGMJWV9F@L5-$YWnOPCdd7ajM z618rOr9#4z`wdsWf|J=aozoFrv6zj8i>uQLWm0!A!-5J0tY{#~Y$UFfImQCM2W-yg$A!{LI8pCE+r;S{UN)4^m+z z$~2-}D+pD{?Q`-htJ{(#UAF0clpHwXu8Z$6D}}cSqVPp{ny|%q)aOvkoP?_h3f)?Q ztUU3oXwj6El(f-KmI8N|ByXBEeKhT5xvPmI%?y$613I46&0E9_Py;tH-DO5cr^x}S z4f5}x&-Z>!z#?t4_XzHQRclS?Vdao8pFA<}jonDKti>Vp8Yc3^9VZU+ge4}tw z%}*qi@H^;TM~@xs$$>+QQYWAD?LFrPyf_q7xTClGFcebRKr@0b8BhXDt2{}uHcdfd zPU2u(;W<@T_1i4qzgU|>AE1GIfihcDJ=tf*kuWrp)a{{ATLo#1LpR!4jEL9VC#4wI z6tPV1XJ6vd9O!(vomr&+bz*v?gtpq$zO@~sd&-TIylQYANI3hXaw;=6px%b(NwXf= zE|Lza!y!9a1PGiRd~pD_wLrp0{j$7jX4tClcH4BMIeZt}EBtV}+_?_palS=wud>Kp_RS zNtFr6^+O)*-Fi*mxbPAS<@;hnxh7?pG@;vg&poL@aw9%SmDOgmww`|4ZV~596eCjN z_|(Fh)NrTh>v=MzA?C*3Sg9H2*e}p%nI~-0Y)HwnhzGv4A%qAVxx}=od7nl)s00Br>A>NLK#} zPvsI;z)cD55LUAb8>;84^et@n;95+yht5%&4ulB&C1V3(b;gyXS=E2G#pb{v@Q2QUYpF{N-I7KON*gl}k^NLC1xold7%7AHx^>N%jv z2SZg5y8N!rTSN{-;$1EN{7q8a$F=!^BN>ytm{Fn42f&Iu`>Z?$|6PO~L&?1?R!cI@ z=k?N6Dn;U;Nr;Fa9R0&zRJ zWQtiIou6o&ta(1G81;@)qM(2%+A@I1w>W1}f_tH!U5lXxQJ@Sn;3A-I2;@denA5Ei`P|*bz@Oq5 z!TQ+w+iS^ZcKUpe-$n)fk{M+?)J*7U5|S&54rmjK1bTJLwxDslsxcg0JHCY2G z_csad0(hCIhOQr@F>QE~vXt8=uOD!Y@Rt|MYyi*`A}8W!u9ax-uv>AC6`GrSgLXE=;(@ymW*%} zGIA!d% z5>xyxl>thmwa#q;Fh9t`g77%}Fg+ez%UbCY!0{j=i4vU-uqfKY7LXdS8)>{N1kxntS?*R&iz~PlV9k$P zFMi5Ua)0R(;d^S>7o|(wr5{`BU?zCq&Uwqzw>&I#4j31)C4MN48KBFTxjhFmxXl~Xh znYH^*J?zLiQX7c8Aw4iPnA?O0SXs2exnZ@$dTP&Z8j}1QrxDW!rmY)j4xuI_Y%pxA zf}eVgYJ9dd-K5$u(L_bV#nM2Js)hTiK`6kejHTsQRa0mxnkOQ$)O zw&F>!liwo4gZfBtp0Kn-w+wSdN2ZUCbYdpMM!ZBRcWxs{t1bM804If6*>zzDI7FR~ zPin|PH_vEUguNg~_uB`R@Xv$?3OolhzfA-+2LjLv!l#PGSGE?#%P%}*AXG2Ss>7@r zKVl3gF8&D8Z(%K}W_3{o6@(e(b#{dLulzc_@VZ)Lj<_2;^% z{%$}s858Z{>vNE%u3=(w4^tYh6bIRmr4s>Ca7!zldGGC)WKeU`3;80?^0Hs}2?!r% zc(*&DzR!7deB0AY_NK4?IK-lE9;tKDv6V}+O`^0>SBQlJ$mMJ_Hif~elgd$=p7D?b z&jLy`6^yNEdznEO?ZJBIh8J!UL;|951JzbJThI_(nMK#7d4X4Bg+sC%M_aItc}NIX1(g<1aXV@ z$vug#-3aF=_Tesi(XE6cjw9vLd?21SYyIm>1($^SqD@G6Zo)x>-)vR(!`=J3&XwDw z>6&qex&mN3@V=TnwG#zy@q|t9k*IHkYMdu}`$w;O;Dn!|Fkvz&uL;?QHtQU}UyWnA z;RwLY+2>b@YE?x;n zoZy5XxzOjFgFRL4${VMbL1eARdz;tSw8T++0o|Sbg^z>3EPE#R&gS;|?=E-mBf$;^ zZx;wNbf=d3pH{X|wP8OTJUv*;_A|4zwBC4{INLdXra^l!_w9^El%^3r!w8EV(hyVA zT}6&%10l>yBEz*Q+cOZWQ)f?*!>u_JKoO9GL;9zJB@1w?{{-^JH$vM4c@OuqMNmfY zP`MkE=U|t{I=$_=BV+(5;LJEz_mLLWJW}-Z(7RarFrUjP*%(d}{L*sjQW7lt-L^7SbX$w0>>3bf``ckCr#rpHZ_8%9#`G!1SnLe3y-Y2E{ zT=V`HrE)YgHgTJ;Ym;Iq5@nZ{Yu;;ntaqh1! zAXCW}>yk!i6?fHq-ufz&hOJg+hq1n3OZ^ZxmL(Bi-VYg(_M*`_#}n=mkgu?i`W}W` z^IgW)mdsYI6d|ICDLSD@Fg=V40qrAM^74vx|U>I56r;84m=vQjB*>f&x-^TXoX zQJe|WB=gq66F*5rMnuNPLW77t3$Oay96>NMEkTiSl)T&%k`P(`>c-`}xN#7wUFJ>) zceFgV*hebP1UA&+24j#J2foZc2{^euRZ0jQEOk4X5$f4Pea;;H`Xrs5R^7M>aTv7v zGAj)^|Nre9vA z@iXi{vDiy6xQWou;qLyVu*iQ6xs#c(wK4sl=Re1JOjXl1j|0U=*Zd=}pBvUyaMnqf zzzpA{ex{+++of3+R(R1IJL-AkV3Eu(!HN6VnRr5*-;>vCMntEfuCIp;gvXethU=LI zb0rMyp7pY^vt~uT?>UlpG2w_^n*L1vlLq&$(u>p0i|vA2e@WXg;+X9bRAqg5^_oR> zHYJRq$K2U9S_i83h8|d@ck__PD~JnrO%+V9CQFkI>+Ckz*t;@{b7~&9jY2CY)&`QB zHRc{L<&kakk=75ws-?hT#9MyinLIJ+d91PoXIa-L=3fZiiQS>~Cf~9enwoVs=NQ7O zRQD(LNw?X@u*rgWN2GIko?=T|)Pz5sTaLuE?RIi{VHE%u%J zW%%#zfUZ>IuM`GkEj3PZgwlOby8*`EXE1xk3nPet((@x-=zI&a6^RZ&CkT6(xa>e2 zh_2iOEh2J$u?u0-nv9NKkB-eH_SFgkuSj^D*Ygq-V2zyXPoZc@rmROhqddVf3b(Ml zOsS9s==o&JEh48?qtNMsxMJUDAH1V@7mWKK1>KT%mRva#XA%hYvcFp&-;cBUj6EA6 z%%|d@oU@fQI?zMuMx@4Sx)3~>Qmq!?7T1D+iIDZV;FS8RcJCl)f~wxDjR|-UzL%>z zYi{8NNs89y2Oh=eYK!S7ga-$Q?~*r&bUln`X_K)xn_t7y?(j3F4ZynMgx)fQ-M<#w ziQNc7NfI)M0ePLr#D1qOjIW}Py^INr4gMe^jp)WvU&erVu&^<2T;#QT@{6} zU*6@M??#kr5O2yOs~{G$v^V@TCEbZ8%~S~h%rz_rs8|R*ai{#yO5=pval?#rgcxet&46m7HN5xV`i4}ni(Ht}w8Tk3 z-n>AL&MA_u)7pg@1hd6211Q#sN3D=%6Zkx;dUzg$F`}(@q{eD7t;jx4ZoV<@a*cI@ z=mW`W*gk7}pPZBPPCvIkJG*sc(LMR6A9omV-q)A3#=s3@%-9WJJUQOFmGzY&*j#aY zqAk@gG>eb^_USkR?dzmnMJK-gJ1VIGtjeOyefkLxbXRI5ts zEYUKW66iqe?M+$B7cR<*z^0#$)g|=6v1Q>;8KyJbYG(t7Rt~GtpX`yu&Y8q@SZ*o0 zzM6?eH)|_6HPh10s^TKMBG|yLs&V7LHQhpSv3@%-z_#vLX5z zO#v@S%45K6i9}>&p()0~0pb9Iq#WGc&*Fv7_gK~CgMs1OO<~7P`5O)@T+Zp6$+I20 z4;Ane5aP)$`brjFx(ZW(Uhy1qE@CBgU4Orn(io!MY6B8W==e%*S0`?S4Tr-bMj$Pa zToYpT%`Hglj*|u_QELux7i3%Ou7CG_lD2!qpMiebRY7ke^3VaGUDVfDZ9GC@Gbe)X zQng>kkz#DlP{!2nv1xAtfW+hik->h~JtngJW2XY5w3+%yBD<9-XF!SUGvrL^gEAw~ z)+MJN^*y=1J1@8)?Tn2$on@Ov#UtieBs3>~JgP;B#0<@*Ovj z)f-2mQA>+O_yE`+AJdb@o%(^BXpq+4`;<`(DRNz-&;_SPodKgazoO=0oxm3sNh^%! zpHBfxW2Z$4maJ9d0G!I>a71I7;(br;bGCWE`~6LcLT6E?8}Q|XfY%u-I<-ExYHt+6 zy}}VEok~TY&!kgJkG6)y@u`>s`Z``g9?tq++t`)vvOoR?C;Om0-4pW3<;*t25xrhW z)$J=<=c!WSfl+zC!-0w&tq%4FJth4JX+&uYea-z7n02{E5nX>CNmz1yUP^3=rI=J~ z+T0fa;{cs^z$*MhQ z>wHdRO~;JvBUaT#9eaHCfYQe z`vmunY-abts*Q?*iJurleg)2+UF5KO3p$>=c%K?isz;7B8RRl+$H7Jdhljo zdtLHNn|PcymDSed3OOuCxAPNUKWK-;txZlwBcMj?@hUOrl^1(h!<(*-hBz$nR& z%l261G&$$6!itF+`vhPj#pXl#xk@6%Y?S_&syxn^3Mz$umBjAGNEcu}B~QId$%dFm zR|Fdp$EX>Z`OOg!cNQ62y3=gDr#NY%9yJV8fjyTE)81|Odgj!f>-V{=^wVIvU`{FtkR`Y)jflUve-~>m`Qi#)oZO2aYVr4>p_IJiV5@tFn6%UUq<5d zX(TFjov6}GO`anIX7nkf;%i8hiR~kDXB&l!30^qBm6Az}B}$I1t7=HDf($+dq%e71 ze_$q(hLK0eCFhgeS)tzL?bt9uRpF7ceZ`=v*XW6;p`!f--`UW5d%RIXnY)(7qA5=+ zwWC2MBOza&yL?;#rlRzsQrr+ZUx=)@Q~dTrg{M=*;S8Pnx%%BRx*~}kYVy#BanO5- zc~1l?%TALW^jD?+c1io)^9 zKJD`TJtX4}0*OZc{E*Nqapx#bY%JlFKn3f~;jin#j!fQ@}=|UYwHUd^*5VdxD#1_=xtv75KF!4!pj{t%mV3##~)DMF-@OCkoAvws+mU?gU@Mq@As;BCXzJ zrKNbSu2QpJf7EKVF|83_vo{&U^Mqq@yhT5i^0J(+pLdeE8R|Vj3n~JnlABDQgj!$t zw00r}MltZ?A9tjs^UIdcKUX$}yZ`_g|G|a-X2E6ZD>f^l2;THlz6g(al5OHOFrxxv z#>)T#2z?SS(o%II!br+-4Ld&GrWdWuECN{LLPq$op{8`)rmo(1?+f~T?o^X9%J>Tc zC=&q^?yIva$B$KTK3*S>=S1IGtnF9PUY^w|0#j-r*L6SMSLPhO-@Sw=3WsMMfIqGJ?i$Hf~;unq|X`yLeP3iMRnb!8-$|()<7~143VqQJn(NEv^mb09GQrKZDWXGN)Y(7?cWC4{~Q7Meqkx3qVdM#z|=em0B zBziel>_%ZbdOrx+(NVd4ai3#8LH+}x%Mj-NYf8v)9Wh~}%j z=eYCAWA1WygMVQ0(#(}CM@QkLxw@A8;_xe3^W5v&RvX`j9Tc8ja?|tX1zo4_izw*Y zWWUtg;&n>*0`mjm#L^2}1~~FMtE=-{0^cR%I@eAZ0*)I_e_?s%NZD#{D{tSF+sDw* z_9#z7^^K`B-YNxOxJqE6_2|pC{f5ci`-R2Ixo{cOiwfU|x(a-2GB~oJZG?i3jjq~~ zRd!AnoAhHT+Z|pF_=hYUsxHP9d_Vow6ODJFetcgoNjPCip*NxgG+EkUVLAM9eXh;` zXdkgw*G~t;K|^nn5pXXmdwbUuU&9}v#j?aQuGO>%^` z@F20q5BiXhUT-0eSVZKBSD;`+D`^f8eGq^70-l?arme0LT#N|=OtPbqCvaSb3XNB7 ziZ&L}Elg}=JOK;=2lT5R;Ar4p&4I1eC>vHTo_9JFof^S^ZQcQPQDdh26&v%ptFUu! z-+g(_#70K+=g-*|0U_2i6OOQR;$P*4qYxzhY$5oo1r$Wk4=7wu%NZ^bV%OIz?h%@R zOl`}>ET4kR(9nPgf>`{VNJrZ1BWmD*2(H^p%hR6yyL-TQZ0z22f=Ghq2)8kP667rj zA&mQ-?~d%>-0OtLqN4P_B8bMWity~WS!x|;qzUImtYRQ*>FKkGs$fF)^?3$UTPJzO z$|6B}@<|j_+Z>3hof8=vNg#cbFI^4vidX6xClElw8yE5s#Av3JH-OGHQr*QN*TpO_ zFr;rJ1u;PMcYwd%!K&Chq5_#D?o}W)EP&52pFJIWB8-Zd6T>kRBA3b4& zBCnalx8RCNK#_34#*9Qf=7mzqTDspmo@01T7-WQHHP?&=* z`EGThNKVH47LG*r_fGUJi@K0Og`76P^zBc#Q)6m>laARnOZ7m&=cf-ozwV4Ar7fj( z)s?1b%p6K+2BsRYJz5qAD~c;(o#Z$<0uNTK&u2-gz5P|0&c@yv{Mp=997G?=f7t4v zvXZWu2{CZ)C;MsH(xk=+_D1_6&vv^`S>$S5kVx*RNp#6TOC-^4gBEskL6nvG8;YFz zY0LPrtbd{iuYwGec&h|9Z;w@KEQpDH3L+Y|rBO67R=jWc<@s@uTr|9F33epTTThyr z0P{~~RHMB#`BE(*TDM{6NsT5l8gE z-jFEf^Psnn)4>p|gXGFwArl_rW)c;7tMGY8)*Z%?Ox>-<%&taeYQEWMIwpHE)BLU0 zk{sh#(R7|43_9T6C6&@#&nOZ)zF(3W+^?fAc#w>DN4SS&LS=$lQq09-SzFVpGq%t% zBs6_76f$_i$gItU$B%&e7&9-yUxVgMB|hNz)5I`Aw08ThESj%0V5 z2tg{z&Up%pOzUk);dpl@9svegu`iKdT1e2~jR>w4^6V$6tblAFoRHV?5wWe6oDLwnJ(^WjKC046(DSt=`2Ny4nId3bSaC{bCCQm)}eXLFe zx^&=R4(J_&m0uB~xP~~AOTJ63!hH8<$Yw9O7CsXYaA9>QK6=qvS7nh~HUtb0w@3ERSRT(9xdgWvb)S%<}2!?a!?Qwj0(>KAyzPMG{n&c`D%nGk|$4XWU7B>` zN7wrztQ!QRSuuwzv8#+jA(tz71cAj(X3n0nuL>0;>L#?8rX~`ZWE(e*JYb-@ccSeNQ8vMKPCDVoj4uJa_B6 zhqohh3FsDg5nGy&g0*`Dh(U>=f7vCqdc0OE{1W68bi+ELs`GPqGqiOZZBr1I>l%z5e2jif-T&> zT461PZOV#BAf)GPRa0d$G>@K3^_lp`d-C4_8*)j1m!skPxkeq zFUL6}6wsio3FAC$f#UK-DxjhKxLA}wu96{&8Ouw&<6^?|lgYlrO2biGovt|V@;irJ zh)_r=NNfuSC(d-~16SQ-6V~?K>3+`i@rFpri$dqfyE8^Bps7r9lUJ?l;Gm1FlF4ra z?(owyCjzT9+sK|c;c@Ejbx~FG1}jI?6yLj0SMQ?VwIf!b@{7cR$J{Ltl&Yn{0+P^3 zer%(x-63uTx43_NeNxL9g0)CJ1vFE#0F*w#S|GlZP0l#!3Y(vbtweK5NFNzf|8a6i z6+IR_M+j|c)%{@^#~n3~HD_r|snY;tv*VQx_7z!D4}|U4W07 zt6q2S%_^PZC@xuIQokr1Pu7~AhDy(y@|b0*(lyba)5p3O+Wr$o647!H#0fKBvs#O%5($eSY+c(j7R zRc&=SAb+#PZ&agUBgF)?MbQ-W^k_mtMFk=$eWi>nFMcZLOImqpw>sn8W?77P5^zp?PUI5uF{diy@LhaOevck?1m^WX(fPu>w$6J!UtWXeE=ZycPP5 zDD1Z2LqP^#Zox#e{=g64k9n{RbD}nAwwcZ`wUfvbv3bU__kZMw+cY~{^q(oHjGr5L z|2ILQdI8FY z#GcJ0<2o2SG*iq z)mc#)OB7;*Lc$`>%pLA%AG}YwuiQjUVd5q@4gVr+#+Bj$lfD2n0p4uoWFYln=1=)S zVlEFs+0w}v;TyAeJfXUV5!70wdtJ7Nl{f9z5DJ@e4LX7J_Ucg494GkJG8jSoP;v1c zG@fV+8y``WcBCEiM>|ZFp|47ChjtoW6LKgLk(RnvSUCgQv%2f(^uV&hNANNz5V1wH zXQWG=y7vIIQB?m6%9M1feYB5+n}MB&Zqj z)VAul^t&A-LJmY`Aq5_U4%2zwFLDhB6uEfAVrqwZ*upKkS{Smm%{cr)zT35zs`t+- zum8+(W)#aB;`$6etbTsT{|Z9beWso|89OK%J30N4gG&F~H6xvYxs8EdHVi`z1H~#J zR`*Az|BpETxGhvwUNNXx6Vq>c1_pXS2`C!=irmCYxRpVJ+rv?$Pdo)SZst}?PRvOSMidHYmx zbD@jOuF>;THxspuEDg}f9xijIfgbfP{=*q11$?G^>&`nB7#s&}d*iyHMRg9BtWMuX z(RU%pZ1Xdwc>i`E)MT36;@kTSX!hMLh%b>JJ$DwiXyf_kN|6cEWiqXi}erIECl zX6s1L9pJPWN;A&kS$wkLDzli>J;p6zf?#H`)DLrQJgob{MaWknY!FffmG_AN-6!ar5+}xou;W7vi%hgOPT_SH zSxzk7?tnq}7jm?U$>{>ow+IGEv~?H60Ua%ROWXRE)|;M3!c_DKBVJvU&LxcQTao)h2SX6k)-*p0DwV2kRT_EZKZO`7RV! zZuXHMj$_m0U81W^h1K?ft3i^vy0+XUS^pd)b6U}eW&fN2IsbVAWcq6Y{0xvWz zK-bS;;WFH^>*GIMMNzn5x_>ce{?2GORNzaIfzouz?Rc? z5%p7#_2ekyZx$QMb()*=D$Iqg|p;Q=>u%w7#%`$1fh$;JQ^r5-o12^jXk24WelfzTO=S+nCITIm#)(08c z8p=7?+Bwqe+u8l0WS^CE|63LGIdbXo0ZazwB}s-s$wY9VD$D$n z70gR&91X_s({!Dg5=6-~XT^;_-1815CzDfNCaUoi8oE=wnkhJdZ3V60Dt2S$#+TqH zm@ITH(RmVI0e-MCH2xy33wo3wUsVqgX6^e zAq?=>Vb6@RdvUei<=M#k2+V|M+!;q3Kn5uR=wEg;2dy{DKB}Yk{^7s+yY+www@|8U z4hi^Jurn_4`$jphh8V8Cay+bHH~2IepgK*P=Tq>;MW_5^=F6yo)1H0j@2P$^eslDR zRBj^6deD;%byztDVQueceB9w*S125YB|A}h!JWO}_J!_ccT0V5(a@m@w*_s#v?A*t ztW^2u6gwa&7YBz=Mb7@5H4*<+kqvDfjQ>}Y|5%6ob$G?=%JveV^l!+#!Ua7f&v0hs zpKNE1q5qUp$-9c`TANp+0IXYSOli=}2)l~&gzNO247O@eM12N28PSksj6#m&kI+c= zVD6{y=SkJuXlavc6bPRqaqjEEnr03&{5UJ6G5>JNotb^#GZ`E=z` zHS*@3qxdzwS(TPoOO%-DYm;U#ese)`Oit7l z*P^DIh)bgrq}?;#*!Lod>4J+De_=xSlVA8r3)5@fjDzln_Ndb=xpmp9G#LzB?zW*X z&Yj~6=(9Ojoqa4}@hp-9pt!YHpsh{3gm{2&tDPT8@Bf&XC=g2~7Wt{9_5bYJS^sqH zO8@5CC2+~V{sOTNrxB?F>Silj17~2vwM-xticd4@efPdCu#CJPMi9A{JHYX9_oPDM ziF2MgR0~oi2FyoJko5l6A2WD%De8Aqq^KmSNHek9cXs^NS}@p7v}ti>5a+2&7tlq@ ziF#NeEs<)=WC(rhRTtWol+57F8Aq?gfEQH}2vmSZ@Jo#$WFVlGZ(fESNa08__<+7W zyMPAmWZ23cT?DA@s%X{K(Q9ZtPVAuDQIudbr&ZBqqd{ic(6yyQ{LzTU)CHZ{MrG$d z;1_hzx(JDiR9V}SvI`y4{TT!qJ97Bu ztXfR<^YXfhMkBVKg=*XmsJZ=1mE=A+fB5Y92%SocOI~2GqP2US^6g%03pk2mf z03piCO08M_V4#a9ct}pE$yqrEEpxH5nzfSUW)*-w5RjA$U_`^k^rV2UPdM%*X5y?2 z5lsT3uFK?3zR&S}P8a`4oC-l6RhU1um*$_fm-(-SseViF3{)c{T*0L}Niqbc? z9F1R6()345_*LK$RxPLTYge%Z}so4dXW|*c0p>BWXvGt1}iLU<5kC^oySo-P?nWo zE*EgLG_fZfG#%iQoX9iT9jVDsNQq?4gu@I_Yc8;7U`d;+>Wxw^fTu2ra?B6=b$erx zrn>Uqa%3k9c=b;f-NI0t1k4=i@ZwyUI=ef}0%P7rVIWgAgl>~v9+9Tz;&BCRgF$SD zvQb^|75EPfOaM$6E9|FNRh=J!DnG1yC+1zHp*_rx!gNECK%(E_y z;H1OY!OW-$HRVn3ZKk0rm$qdvPBYS@v(k#3TyuZDiI zbFQ_OakHwzd0)BOFM7h`_QBJsWF--gp&l~$uQ1%uXDK*Q;)fUi%Fb(h)M@q|2jS-v z%&|m&nSX!JS#$0){bc8af3b7>KiIjzCp#yO!**7!(IApo&A>^h8jP+O6lD8k=Sp!0 zKy`>_4-qD0_}YL(DBYzf{oghbcWk({vq{MTNjZ~Rh|sv4)V~A#`^zEz76kwp`dsP$%c~-O7yS2v`F|BW z1N$=@^Z!vk|2xj_Rn&hY5kUTT0l_&H{d?{pMbw-*Z&Uidt&R~0GT*{_36LUTz?n+J!Rx?QD4&EJM(t} z$?qt?2NnND$z%Sj2fv3He@FN|YV=bw?G z-w}Qf7W|En&+#7}`!jU#JHo%Sz`x}`Q;@j<0Dk9$zf1r7()(Yf=fC`m^nWeHe;5CK yLG(9(FaLl1{6CjRza#wal>SEeBJ>{!f4V3+DbP=A{(~tX0@!`JvRsiruKo|PzT-&% 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 c7879e48672b2d3d57cea871a51f78e3ca3daffc Mon Sep 17 00:00:00 2001 From: Hung Vuong Date: Wed, 11 Mar 2020 17:04:52 -0400 Subject: [PATCH 21/27] - added example outputs for testing - added .idea to .gitignore - modified coabuilder.py: added option for finding collaborators within 48 months from a provided "to date" --- .gitignore | 1 + regolith/builders/coabuilder.py | 44 ++++++++++---------- tests/outputs/recent-collabs/coa_table.xlsx | Bin 0 -> 12063 bytes 3 files changed, 23 insertions(+), 22 deletions(-) create mode 100644 tests/outputs/recent-collabs/coa_table.xlsx diff --git a/.gitignore b/.gitignore index 9c5f714dd..26b1a9b73 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ var/ *.egg-info/ .installed.cfg *.egg +.idea # PyInstaller # Usually these files are written by a python script from a template diff --git a/regolith/builders/coabuilder.py b/regolith/builders/coabuilder.py index fda98043c..25c67ad51 100644 --- a/regolith/builders/coabuilder.py +++ b/regolith/builders/coabuilder.py @@ -1,4 +1,4 @@ -"""Builder for Resumes.""" +"""Builder for Recent Collaborators.""" import datetime as dt import os @@ -65,14 +65,18 @@ def construct_global_ctx(self): def excel(self): rc = self.rc gtx = self.gtx - since_date = dt.date.today() - relativedelta(months=NUM_MONTHS) + if isinstance(self.rc.to_date, str): + since_date = dt.datetime.strptime(self.rc.to_date, '%Y-%m-%d').date() - relativedelta(months=NUM_MONTHS) + else: + since_date = dt.date.today() - relativedelta(months=NUM_MONTHS) if isinstance(self.rc.people, str): - self.rc.people = [self.rc.people] + self.rc.peopythple = [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"]]) @@ -94,35 +98,33 @@ def excel(self): pub.get('author', [])]]) people, institutions = [], [] for collab in my_collabs: - person = fuzzy_retrieval(all_docs_from_collection( + collab_person = fuzzy_retrieval(all_docs_from_collection( rc.client, "people"), ["name", "aka", "_id"], collab) - if not person: - person = fuzzy_retrieval(all_docs_from_collection( + if not collab_person: + collab_person = fuzzy_retrieval(all_docs_from_collection( rc.client, "contacts"), ["name", "aka", "_id"], collab) - if not person: + if not collab_person: print( "WARNING: {} not found in contacts. Check aka".format( - collab)) + collab)) else: - people.append(person) + people.append(collab_person) inst = fuzzy_retrieval(all_docs_from_collection( rc.client, "institutions"), ["name", "aka", "_id"], - person["institution"]) + collab_person["institution"]) if inst: institutions.append(inst["name"]) else: - institutions.append( - person.get("institution", "missing")) - print( - "WARNING: {} missing from institutions".format( - person["institution"])) + institutions.append(collab_person.get("institution", "missing")) + print("WARNING: {} missing from institutions".format( + collab_person["institution"])) else: - people.append(person) - pinst = person.get("employment", + people.append(collab_person) + pinst = collab_person.get("employment", [{"organization": "missing"}])[ 0]["organization"] inst = fuzzy_retrieval(all_docs_from_collection( @@ -135,9 +137,9 @@ def excel(self): print( "WARNING: {} missing from institutions".format( pinst)) - ppl_names = [(person["name"], i) for - person, i in zip(people, institutions) if - person] + ppl_names = [(collab_person["name"], i) for + collab_person, i in zip(people, institutions) if + collab_person] ppl = [] # reformatting the name in last name, first name for idx in range(len(ppl_names)): @@ -149,8 +151,6 @@ def excel(self): 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])) emp = p.get("employment", [{"organization": "missing", "begin_year": 2019}]) emp.sort(key=ene_date_key, reverse=True) diff --git a/tests/outputs/recent-collabs/coa_table.xlsx b/tests/outputs/recent-collabs/coa_table.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6e6eaa9eef64580f4e559c5e23dd570650dbc976 GIT binary patch literal 12063 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 literal 0 HcmV?d00001 From b618f8113167d18ec4ebced188e63b02d035fd38 Mon Sep 17 00:00:00 2001 From: Hung Vuong Date: Thu, 12 Mar 2020 17:10:00 -0400 Subject: [PATCH 22/27] Fixed typo and added comments about the to_date option --- regolith/builders/coabuilder.py | 6 +++++- tests/outputs/recent-collabs/coa_table.xlsx | Bin 12063 -> 12083 bytes 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/regolith/builders/coabuilder.py b/regolith/builders/coabuilder.py index 25c67ad51..33c1e3c5a 100644 --- a/regolith/builders/coabuilder.py +++ b/regolith/builders/coabuilder.py @@ -65,12 +65,16 @@ def construct_global_ctx(self): def excel(self): rc = self.rc gtx = self.gtx + # if --to is provided: + # use self.rc.to_date as the endpoint and find every publications within + # NUM_MONTHS months of the to_date date + # Otherwise: find every publication within NUM_MONTHS months from today. if isinstance(self.rc.to_date, str): since_date = dt.datetime.strptime(self.rc.to_date, '%Y-%m-%d').date() - relativedelta(months=NUM_MONTHS) else: since_date = dt.date.today() - relativedelta(months=NUM_MONTHS) if isinstance(self.rc.people, str): - self.rc.peopythple = [self.rc.people] + 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) diff --git a/tests/outputs/recent-collabs/coa_table.xlsx b/tests/outputs/recent-collabs/coa_table.xlsx index 6e6eaa9eef64580f4e559c5e23dd570650dbc976..e99ee56460e1fc8271b5440332811d4c8c8d9978 100644 GIT binary patch delta 9789 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 DjcV*v delta 9814 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 Date: Thu, 12 Mar 2020 17:46:58 -0400 Subject: [PATCH 23/27] Added options to test for the recent-collabs builder (comparing excel files). Test passed for now." --- tests/outputs/recent-collabs/coa_table.xlsx | Bin 12083 -> 12063 bytes tests/test_builders.py | 13 +++++++++++++ 2 files changed, 13 insertions(+) diff --git a/tests/outputs/recent-collabs/coa_table.xlsx b/tests/outputs/recent-collabs/coa_table.xlsx index e99ee56460e1fc8271b5440332811d4c8c8d9978..62d55c7953bf5d821c6c0009844a74cf060efc22 100644 GIT binary patch delta 9808 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 delta 9783 zcmZX41yEhfvi8O$Sa1vO?(XjH5G=U6!^Q&}-y3)L-~oaKcL^3;f&~li1o+80|9S78 z`_@#gshaAV)$@Hl-95b~&$!VTMNJU~78?KnAOe~rlTbcEH%HdD%Rs$$jWEz`ut?33 z4r-`N4VCo}A$UsQn$dy#3SYy^$yewS-D`#l4XR5p^?+*%6TSYam4m3@(h(7r1THOh z0X4l~=GSM>?R+1Az}E5jcNJw!BxSA#iQ8InP#UYyQz|pT*vPGRwng8SqK;us93n_&k-Aa!8Bg;0=j8tu!k1;F!D=VlJ+|&Wu3XLGDa5* zQJoegQ&fh)i!@bR>>zk`v4ugJFuRTVm#f=- zqt0cK3$~u43@6Xt`9>j|Ns!I8A(h3Ow&=^XMPGK{O}EK&fAW2&iU||vPgj~}noH%> z%alx58iVQ6iw(M@=dl)>EGT?c<85!DDdAgU-f!9CLPi69+-ELplo>vtXlv80`y8?} z|ECxjp@4xtUL+1ajYKhaBorm$mhH!Q;JRRcaasD65|}GlU&d@04Ax|syNbE+81su8 z3H$||>2f`f#34k1&+O^03)nu)U0Cq)p0dYk<9LvgQngX3Wzl>tm+S^igonwF;*p|8WllmxN1z<0vyUN3zb>_L=oVhAjr=2ESw1 zSf8g>Yd#Z4Foj!c^zH{BRfWGrakNniPTZNMfaaJm)xqqMX4}>sMzffhiKRt~5e(1I zu9J|K=+vv1=u*1hvz6x|pbUUADN<4zU9v;{k_VO7*!Y+(UI{2Mjono;E~zDR*82&p zn5CILb;oTPp`FY#myyC8Ti$W!Qe4WRV|HGlDw;wmISEK;JcZpEM0YgHn-JLJqB2Vk zB{79*1%VT|#y(^Qlc4&qBl*XV-i&u&u!Fv=gA=F3uaIbwrnpZh1&lnr4gql51^gp- zpn2l^TGTPJAANL-$jrY{QgNyf8QFnuqHSMaq`J|NXxUYB#nR1j313us6JVdezC5@9 zZ~30?t~m+TRE9T7cW&YXy4s((0?E*4UmpD~*|ZndgF5{0EU$L=PErHDP%dbaZEOe! zWT*ra5j1jrgjQgHBj7P6F5=Z}-m3uX4C>P;!u9LTnQam$^M$xE_M2QXAv^+u>B+P6 zL6_;hvD`-SgAvfJ(UN8@m`6MzZNuG&RN#j+3OBrCvd}u?K^tWCN6cNt4nBq38v1_4 zvsz|sU89a_2x9m}kl)JNg7-JNR8}8K;>D$ZBpbED6e5{t$2^r><)8b>TQeo(f0xJ( zv5y!rE<_1^YRHnb>zUZd=_3Wo(eHLpFqX+t4oY$2M=@=KiW?L;F8ndF(=9X>8P2Ss zK6lBXS)c)h&$+<4Oe>p~1R*0oh2Tg`bqjb1rNS9{^-0+8L zsb62cJgaVavaDNEMF!GuRiGZvZe1c{`ov-t3KiC`E&vd0F`sBGU>AUCnE9zPZ0<%4 zTk>7w#z$f6(nFUBB`@KM9hr(9oh)BC^!l}NliH(59AT7xuqt+ilBJI5qs(YyJFnme zG%82RaaK7ventg#hZFbjozqy@@tP%y$)xyGT22L@=q>x^{9pkHp%6x1+DBfh@?_tJ zMfPo~TiU5&h+hYXUoiuJutqm|8rMupx<#@d-KDNsu>tq9+R5SzP1zQ_s`u^p#>Ey@aro`+w_uu!ba z3)R*b9%W}@g@~ezHwZ;|A@Gi7_C6<3Tk4`7+V-DTaY?LK^ELwU-8x#Sq~28T;~oJF zC<6_zJ#dWAq_*kR=vKsZ;3S!OkhV(7l485J_oGLhrt{M#Wn2$S zw@WjQX2F=8w6(?wDF_}h6UMAd!8<=Sk-ogHMe1tHEfHrWd}@&<%Fjou_KeOyg8c^h zVf+o%BS<(LW1cD;c9rREmYlvO4Sp1920Sdi^@jVB{xO3Ol*0$H-ntp(cs`sFlypgp zPh_3bM#0>`Y37V;WA=IqBwuM@<)pcg^j)e%SM$GiS2Latq7xSz7kOl*8(> z=JO>oJ)riIX0}~^4t82Xt`6IUvHrG%a?4u26e-uk!fUo4m>K#cHF!r;1S3W?015P$ zjly;D!gUEM#&nC~yhF*QZA_=xKxC6yq`kmK*%BDB;+8c1IO8h!tpLzUANejr^7)1ZRUBvJOpGxj2GTPcZDm+URi0ych2Abs42>)$uE|xb6kTb)g@od8t7}dU{N`Fh zeW=_?$mjYdn1;E2Np`ClIYZ2%Ib3uM*vI@?kz-nMIJ@T7nJCjI0yUM%7_u^yKsDCG z5k8Ib5U_Zan59b=Cs15L!o8KlKKUP?R^}l!_R~})aG2Cn z=QAt&wU^y6+CcRH7`>UCf6~&GV3E56M&QOXUsNa8 zm*O|osh4J&b32gF%z2_S7_rJfO^OvVFH|j12{(MD`678?;@$$7Q2UCS4$7}y33a_36ky=ae>UfxrA#@=mJ2KFGP-b>Wj!xmYMx#uZ zR5&J!Tkyf%qLbQwA}hQn@Q%NocSJ0Zc#FhJY&iQkl5RU+-OVu;1oNx44C&^bv7g}h z5ACzC9we(JAo{r96BY`C&8PiAg$%#PU%I{sUA7bQa;<`KoHXo!Ka{l zQc!so>sk_5#Z&Sg2IV7ET!p#4Q!@gTikO_X`?dGp;pq@Z>N}l^DKDmNigc)NPF(Xr zB(;Jd^>N`9{qK`1JExB*+M^X=Pmv7{KSNM|>(OIL1JC1~5q}Ffslg~Lx)Eq%hl#yn zpe}Ul6LPpOhMErRRt>#Ghb7G~o$ptm3quoPL}XO2L6bQnXq@jiq4PQ*R3*mqikb>W z`MFWPGtO`evPF>+*Dh=bNI*-jn6$ti(SkhIF+4hsO*>o{no|{;^Xr0Ifj0`r<%^gF zj}Wkpn}?B=wD*jaFw^AtqZ{Ri=eYotP`4L)bjlML&~pv!Ic z(u(p!rdw+&;hNeH{dFsvQ7FxMGYH`sVfwLwW~TI_LWUl_rZWF?I%_#hrFlMiMFd;( zTN<9;IWaym%XgL)Auz#YYQdYLhvz4d8>8(7bc9L%nhAfW7bZ?(89Csg2YD{EY)x{gw`j0_z&JjQian|Pe62Id@iNHO{QUR2Lr9h zjU*>2d6<09ITTv0Acr7T?gf+xklKQ)E3<~t>vAdoN#|s~ppMYRQPyWqYoRgM*;e7w zsmOCuOEdl>d8a_D7EB~jQRYlQz^kR&C|t&aOS8%B-mO+ZLCS0X*(hre=}%#T+?zb7 zJa!6~E~9@W8#(8bx5?dADTO+;u4_B(dUwf$eERRO0o^ zwot`T1%oAkGTQIe=2I%Yyj?v#qeZ*!7~_i6o{UxC2-oYX!H5Gz-Sz>=Mjfn(8+lyH znz_%RUk}urEqZ&hEILOR!wx@7hj3y8L^o8!+OV{QHg=06KS4r*i?^fYV`QhZWi zVA6a0UN-E=7lq+@_z$*K!!$Z{qhg7udrn@y-%Du{6Trk}Ckw2$3)9GcX&tA&lRu$< zD7tDu^*(4hS7xhlDli-n!Tr?zCR9esUYIZCQr_y{GL#~WKW;0K=;tL7U2QNHt2cC% zjeFqGH5vL5SNuNsSGaIyHcfJN6Ng9{5V}5tb5F5{`%ZSn1uJ`502RN>X)0h_LYV)Se1lg_7y_UKW_m9dl zi&-mSNut3sglfg*_7xV7?U%RcQX#TnE2)*NioCYDS&?fVbLr@dEC@H5vl-8-^r%VA zyIh=&^kuY!IgsHOJbZ&23S)i_L63$XU7hM$CdHSF`Y#4d0ptTKHx>dm7WZ%djbwef zsk1F4nBWyj4WMc-8^#lZ^2FBNK&wB%BkRv!Mq?|3t@$>neeSkQ%bKzunmUJcA+gY1oJq zyOhgLTzMIWx;KxVy0XlkT=js7B+dj=wVK$I5d|nznIwN(<~0Ly_##r79GRSrTw$cZ zUr2xuvf@gY-o5~zoUpTui}Eyk0%Kj>a=-_`<%sHY!Nyji6UeE9IV?#;Y_?`iS7G?* z&Ws-6W})jXRQ#@kbGr3J$W9>Pks;@}oVV-(Z%~)OY(kC&B1}XkKueT}5}_0S=CZb% zxEQ#)rSCUc^;3_24$o0>NcHnoeo_!`2^l1O^)3V1R~FYaeE=GJ-I$X=^t(czjO_$5 zcnNKQSF0mmc-|yqbVXset&;<%71uw0J$rk1G9{bYz^q&Q#iUTt?A`Z*H#*;s#dp`a z#>*`&9{$Ui>q^wIEubKTL?o{qIR4?_nNeBP)_nC13Z)qpBBp#4%@!%2{t)3~>J7%( z!ir<;D+d+7+`XqRSFdRh^Foti1t~YLkijKaMd7%~*eD!U8`nSN4T1W^m)fZ_K69Y) zYhyEoBHX!RVYS{T{(LDAf|J2e>sQjZpAaDL&bpUJ36hn{i-v-k+!I4BMvdY zv$Q?M{hO^b|AwCjr**F#TDXL9w3E@E$L5P!&2lK_d$*%HwD)xyjR+|#vsyCDl(Q!P z-T^EtymY2e001To0MbHC@XEn2l`uB!z?4#SQ!}FSF+C1mJZoI#Y*v?dmRzZ+O?WN$ zSGanpn?tPoUw&r$J2_h;I)fqD7&>JR5E`yndie-u>g>GyO{Bn21XWSsY{}7y7?E|` z?I59-HckCQg@QhT#IiLtidAok=))DlTxyTEA7>vIKRaDq5%Hnf0by-{O}QQn?M9^9 z5-1O+Z@_Kbs+8+RR?|2l6F4M01^BH4l+6cp4MOP2y*yr^-(5yl_#rq`ZF8u$_%g0EwR{j z%=u^?mc=vNzwxJ!{4V<875^h>0N}O64^bq+0S1EYU-!WuuRg1qi7&V)MI8$(8$~6B zb&js(HAv{MzZ@3)b^SyJnNZX-aLPZ|U7vPXlqxZsGLIBwnLG2A`io1-&JbP=S;^^V z@}gqc+^|5-N7@fhvOl}fp);0jl@7=f1r}aC5vh0bK4)nJMM>jbkdP{-LZ;5-z6cZ$ z)$M>~j7Hq_eP*YMt<;FP{4Wgy3Y`ywtEI35Yo98_9_7rcxAtqj#*8cjKi0sCQ7^H9 zWRzSB4m^6jZEz(h7Gw4nJ!Y=b2)<}8Cn*a$NK9S1B)JM+<&z3@g@^B%*^}Jt=|59v z*H`mH$vv?SzCghKUKFL~ zW#4Jb(&z?_NvtRGYpoVS$1Nx$;ht1gEhg(7_J*Suywx=~+@hqesV3FPX_R4Pa8W)m zc#n8ghnmxb^Flq(S~x`v8>a*W{F{c=4Bob_*FP-ZU|u;`A*BU&&UQNWkzsV7>(=`K zSX@OS877m_2->s)L*9ru5TZmCeZIVrj;k!yNEB$w#mK(9G+Y#h3|Mq*ufx`q_6Rsh z!2@nYYV*yp$h z5z8LvjZJ>-lcxkW!4rhG$h;TxO|B*GViCSiB|PV&2BA5MbizKM&e}U-zw7WL8ZHqu z*mtKl*q$s5eY|)uM1w?x(<%nMPv!V}o0d6cr{2Jzc<4)g)L_9~YoVE1{WHa33_S57 zzd3}k{@(~Jp!ww3!T|u{{r~_f00;p1IIy~V_&Qj=dMHPSU+>rAw|KCFQs~gXVc@1O z;eK<{HTbMy7{}#4Z74}xHyEusG~O!`_#_!DhA)8_opU~si2oAsGkfaiT|XM9$`X9v zPwMb-eOW#g+7od7j_#D=PeuHYD?D&_IuHw!5Ngo*pjQzKSv(OW^Y-SU6SzJc0|2cZ z@EJ>QP^JpFH-MJhRo=a&{RPX4nJ2^k4C76*adrw%+rD~rS|0QXK^H&OT z>(QL8)>)*M-vrx*WItQ@IZNdAdu_INw889h+o!)}xWOf58;-RmJV?6Rp`mdbq-_Yy zI|!s!GB$t%5xtw$Y6pQqHj6?e>6nrZQ>vtfw}Wz2HPEoQRPe|O-+@dEMl6^#EQX_G zwXrc{e>QD?LGk+dpEHn$PLCGJ=6P8!LZJ` zbhVt;a$G;`!xSY+?DLNk1DNZGhV=`{f-6O6E_GXV#{{Zlk0AuZJB?6*b=S&0r76zhYy=rr_3eiHUY zX!F#F+HnD``o1~eT7*a$aSczDH|$~_G0H97=8)-5hwR)x@RIp`QmH8lAaY_`qmf3r|9*+mZFN~M!fW;! zH~3vIPc}dov?jRwTV5odO79f?92LHX$>$|IXq3)xEtL`5V&IPMOQ8o6^u>0ag$nG3 zW;!cY86~g>l!QW5h8G)VqGY=XKN&Z)`D*HV`v=8XNi z%6*G5Dz||lt0u{PSS<0b-?*LXkbh~4{TIC2T5YN7u}t0PD7lz7C6%tlD@UYRW-X9l zYJ6bhsMX>xq6w=-0V%0Q4u=m7hwrL7h&7e;QEhXay;)U=CUM^vb(F;X)f8bo&P6Ct z4Mt}-{PEp3va5fci^{1i4sL&Iyf2UunW;9KIEf4zJ{~`@Y??&x)K&UNb1z=4Bc`gp zSA7}Ui7KJ(QGJ4Z6vHcqm7L*&v|#5;5bn(MICyHVA)_9 z$8-BxD})#oPHJB;f8WTq8?d&s(40I!IOFGQH$7Dl%iG_pHkSSO0Z-^hNksQ+G{SvN z3f{c-CT^Av?yM|--k-p#z?fb!l!31b8IOdzJ$>fFz6Xx_zoA`eo+Je!BH1@+IbG9n;o6g9~R+zKmeYNw2Ysx(U<}W&7s$~`ov)I# z{|>w!E3^)lulbMH>r&BQm--rYyq(?b&7Ga?|HPd*^%WIpc8sT#Qqs*{hH#A3elay5 zCZ$Z2P}(mh!Gbhp!QtH_$M%}7ELC^@9L_Rp8rmZ?L3{M$>Xh>jx@Vc?1lAd>_TPFp zmf)4T8IGFr)!G8Bs*n}aS1!tX)KYK#`o=>r!@u7V5=|L4zqs5Fh9q{ulYKH^VE%S? zP^@{gr)Nvufs6{bF}L5c0kB^3z=WU!!yzy4qNuT`f6zMg*K7(;_9q=f@;nhr(6kk>MbEdM%&kD-lA`E!v4Yz-_30KmHHH)TFXXk(C`j1 z{A=pD2su@$xX8Y&YJ$RqgtMh_wGFRS>WSDa>%U1UVCM0xeI?`Zl^DXmN%`9Z|Dpzh zN{<5klr)7L#)k6Iq~r<;*R!rqO|{+UoqtH-IeK$57r|_c$pM;xOI=u6Wa8PQ$jt9} zgL6~bLj+lK9=}3~oADE5G0y~<=@EhK-r~>ebZDPWyDR*(-btiV;hn9Z=h>&;xo$x6Vip^LBcd0iMzGWpm zu!>RDJf{b>gI}8j-=-H$aad-e0 z${|ghbu9vEN$bUyGWFbrk|0F|EL!M51El@jmY?)Nv;_g->QS*WGr|ZKs_ruCO>ua_ zR895TYB|M|b9gu}1Se$)RafiYKM^pb8LW+e=gG*i@F)S#n1kOFtae-2z<5g%wURD( z_u-%x8|YQ6Ip_8DKF;?9%Za8e;i)M?L1V-Ga|sC|!YK55{Rk4kDEy~uXB7R9OGq$G z!lZw$B>h#UdbJ>zzmGPrcJ%iX421zPVWRv?=C1AoUn1P=gU{Ui0-2SaT`E?H>cr5OJV F{y!S@>Bay6 diff --git a/tests/test_builders.py b/tests/test_builders.py index a879aae1c..51cddf441 100644 --- a/tests/test_builders.py +++ b/tests/test_builders.py @@ -24,6 +24,7 @@ ] xls_check = ("B17", "B20", "B36") +recent_collabs_xlsx_check = ["A51", "B51", "C51"] def prep_figure(): @@ -65,6 +66,9 @@ def test_builder(bm, make_db): if bm == "reimb": actual = openpyxl.load_workbook(fn1)["T&B"] actual = [str(actual[b]) for b in xls_check] + elif bm == "recent-collabs": + actual = openpyxl.load_workbook(fn1)["NSF COA Template"] + actual = [str(actual[cell]) for cell in recent_collabs_xlsx_check] else: with open(fn1, "r") as f: actual = f.read() @@ -72,6 +76,9 @@ def test_builder(bm, make_db): if bm == "reimb": expected = openpyxl.load_workbook(fn2)["T&B"] expected = [str(expected[b]) for b in xls_check] + elif bm == "recent-collabs": + expected = openpyxl.load_workbook(fn2)["NSF COA Template"] + expected = [str(expected[cell]) for cell in recent_collabs_xlsx_check] else: with open(fn2, "r") as f: expected = f.read() @@ -108,6 +115,9 @@ def test_builder_python(bm, make_db): if bm == "reimb": actual = openpyxl.load_workbook(fn1)["T&B"] actual = [str(actual[b]) for b in xls_check] + elif bm == "recent-collabs": + actual = openpyxl.load_workbook(fn1)["NSF COA Template"] + actual = [str(actual[cell]) for cell in recent_collabs_xlsx_check] else: with open(fn1, "r") as f: actual = f.read() @@ -115,6 +125,9 @@ def test_builder_python(bm, make_db): if bm == "reimb": expected = openpyxl.load_workbook(fn2)["T&B"] expected = [str(expected[b]) for b in xls_check] + elif bm == "recent-collabs": + expected = openpyxl.load_workbook(fn2)["NSF COA Template"] + expected = [str(expected[cell]) for cell in recent_collabs_xlsx_check] else: with open(fn2, "r") as f: expected = f.read() From 47849a7b61458ff193997eae6bf02f1cbad9c6c8 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 16 Mar 2020 16:34:38 -0400 Subject: [PATCH 24/27] adding doe template and renaming nsf template --- regolith/templates/coa_template_doe.xlsx | Bin 0 -> 16499 bytes ...{coa_template.xlsx => coa_template_nsf.xlsx} | Bin 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 regolith/templates/coa_template_doe.xlsx rename regolith/templates/{coa_template.xlsx => coa_template_nsf.xlsx} (100%) diff --git a/regolith/templates/coa_template_doe.xlsx b/regolith/templates/coa_template_doe.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..5151931c37eb8f617743f375e4d5a159f83328ac GIT binary patch literal 16499 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 Date: Mon, 16 Mar 2020 16:39:04 -0400 Subject: [PATCH 25/27] removing old recentcollabsbuilder and changing template name in coabuilder --- regolith/builders/coabuilder.py | 2 +- regolith/builders/recentcollabsbuilder.py | 175 ---------------------- 2 files changed, 1 insertion(+), 176 deletions(-) delete mode 100644 regolith/builders/recentcollabsbuilder.py diff --git a/regolith/builders/coabuilder.py b/regolith/builders/coabuilder.py index 33c1e3c5a..cc87e64e6 100644 --- a/regolith/builders/coabuilder.py +++ b/regolith/builders/coabuilder.py @@ -38,7 +38,7 @@ class RecentCollaboratorsBuilder(BuilderBase): def __init__(self, rc): super().__init__(rc) self.template = os.path.join( - os.path.dirname(os.path.dirname(__file__)), "templates", "coa_template.xlsx" + os.path.dirname(os.path.dirname(__file__)), "templates", "coa_template_nsf.xlsx" ) self.cmds = ["excel"] diff --git a/regolith/builders/recentcollabsbuilder.py b/regolith/builders/recentcollabsbuilder.py deleted file mode 100644 index adccd0c10..000000000 --- a/regolith/builders/recentcollabsbuilder.py +++ /dev/null @@ -1,175 +0,0 @@ -"""Builder for publication lists.""" -import os -import datetime as dt -import sys -from copy import copy -from dateutil.relativedelta import relativedelta - -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, 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 - -LATEX_OPTS = ["-halt-on-error", "-file-line-error"] - - -class RecentCollabsBuilder(LatexBuilderBase): - btype = "recent-collabs" - needed_dbs = ['citations', 'people', 'contacts', 'institutions'] - - 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 latex(self): - rc = self.rc - 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) - self.render( - "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: - 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 From e39d6f72d0bfc9182f7f5132986f54ca235cbb33 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 16 Mar 2020 19:27:52 -0400 Subject: [PATCH 26/27] version of the builder that builds the DOE template --- regolith/builders/coabuilder.py | 44 ++++++++++++++++++++--- regolith/templates/coa_template_doe.xlsx | Bin 16499 -> 15962 bytes 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/regolith/builders/coabuilder.py b/regolith/builders/coabuilder.py index cc87e64e6..b291bcad9 100644 --- a/regolith/builders/coabuilder.py +++ b/regolith/builders/coabuilder.py @@ -4,15 +4,16 @@ import os import sys import openpyxl +from copy import copy +from operator import itemgetter +from dateutil.relativedelta import relativedelta +from nameparser import HumanName 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 -from operator import itemgetter NUM_MONTHS = 48 @@ -40,6 +41,9 @@ def __init__(self, rc): self.template = os.path.join( os.path.dirname(os.path.dirname(__file__)), "templates", "coa_template_nsf.xlsx" ) + self.template2 = os.path.join( + os.path.dirname(os.path.dirname(__file__)), "templates", "coa_template_doe.xlsx" + ) self.cmds = ["excel"] def construct_global_ctx(self): @@ -80,6 +84,11 @@ def excel(self): case_sensitive=False) if not person: sys.exit("please rerun specifying --people PERSON") + person_inst = person.get("employment")[0]["organization"] + person_inst = fuzzy_retrieval(all_docs_from_collection( + rc.client, "institutions"), ["name", "aka", "_id"], + person_inst) + person_inst_name = person_inst.get("name") for p in self.gtx["people"]: if p["_id"] == person["_id"]: @@ -164,6 +173,7 @@ def apply_cell_style(cell, style): cell.border = style["border"] cell.fill = style["fill"] cell.alignment = style["alignment"] + template = self.template num_rows = len(ppl) # number of rows to add to the excel file wb = openpyxl.load_workbook(template) @@ -188,4 +198,30 @@ def apply_cell_style(cell, style): 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 + wb.save(os.path.join(self.bldir, "{}_nsf.xlsx".format(person["_id"]))) + + template2 = self.template2 + ppl = [] + for t in ppl_names: + inst = fuzzy_retrieval( + all_docs_from_collection(rc.client, "institutions"), + ['aka', 'name', '_id'], t[1], + case_sensitive=False) + if inst: + inst_name = inst.get("name","") + else: + inst_name = t[1] + # remove all people who are in the institution of the person + if inst_name != person_inst_name: + name = HumanName(t[0]) + ppl.append((name.last, name.first, t[1])) + ppl = list(set(ppl)) + ppl.sort(key = lambda x: x[0]) + num_rows = len(ppl) # number of rows to add to the excel file + wb = openpyxl.load_workbook(template2) + ws = wb.worksheets[0] + for row in range(num_rows): + ws["A{}".format(row + 8)].value = ppl[row][0] + ws["B{}".format(row + 8)].value = ppl[row][1] + ws["C{}".format((row + 8))].value = ppl[row][2] + wb.save(os.path.join(self.bldir, "{}_doe.xlsx".format(person["_id"]))) \ No newline at end of file diff --git a/regolith/templates/coa_template_doe.xlsx b/regolith/templates/coa_template_doe.xlsx index 5151931c37eb8f617743f375e4d5a159f83328ac..9c87bef469d63976f90c580fd17ae480310c8923 100644 GIT binary patch delta 7952 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 delta 8436 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 JTKG@te*i>9zAgX& From 0d62d682ed24eabbab2b98b44188586894fca6f1 Mon Sep 17 00:00:00 2001 From: Long Yang Date: Wed, 18 Mar 2020 14:40:01 -0400 Subject: [PATCH 27/27] ENH: filter grants collection for co-PIs of person --- regolith/tools.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/regolith/tools.py b/regolith/tools.py index c64abc75f..409236da5 100644 --- a/regolith/tools.py +++ b/regolith/tools.py @@ -393,6 +393,7 @@ def filter_grants(input_grants, names, pi=True, reverse=True, multi_pi=False): If True compute sub-awards for multi PI grants, defaults to False """ grants = [] + co_pis = {} total_amount = 0.0 subaward_amount = 0.0 for grant in input_grants: @@ -409,6 +410,11 @@ def filter_grants(input_grants, names, pi=True, reverse=True, multi_pi=False): elif multi_pi: grant["subaward_amount"] = person.get("subaward_amount", 0.0) grant["multi_pi"] = any(gets(grant["team"], "subaward_amount")) + if co_pis.get(person.get("name")): + current_amount = co_pis[person.get("name")] + co_pis[person.get("name")] = current_amount + person.get("subaward_amount", 0.0) + else: + co_pis[person.get("name")] = person.get("subaward_amount", 0.0) else: if person["position"].lower() == "pi": continue @@ -422,7 +428,7 @@ def filter_grants(input_grants, names, pi=True, reverse=True, multi_pi=False): grant["me"] = person grants.append(grant) grants.sort(key=ene_date_key, reverse=reverse) - return grants, total_amount, subaward_amount + return grants, total_amount, subaward_amount, co_pis def awards_grants_honors(p):