def post_delete(cls, sender, document, **kwargs): admin_email = current_app.config["MAIL_DEFAULT_SENDER"] admin_topic = current_app.config["MAIL_TOPIC"] subject = f'Your project "{document.name}" has been deleted' html = render_template("owner_email.html", approved=False, admin_email=admin_email) topic_arn = ":".join( admin_topic.split(":")[:-1] + ["mpcontribs_" + document.name]) send_email(topic_arn, subject, html) sns_client.delete_topic(TopicArn=topic_arn)
def post_save(cls, sender, document, **kwargs): admin_email = current_app.config["MAIL_DEFAULT_SENDER"] admin_topic = current_app.config["MAIL_TOPIC"] if kwargs.get("created"): ts = current_app.config["USTS"] email_project = [document.owner, document.project] token = ts.dumps(email_project) scheme = "http" if current_app.config["DEBUG"] else "https" link = url_for("projects.applications", token=token, _scheme=scheme, _external=True) subject = f'New project "{document.project}"' hours = int(current_app.config["USTS_MAX_AGE"] / 3600) html = render_template("admin_email.html", doc=document, link=link, hours=hours) send_email(admin_topic, subject, html) resp = sns_client.create_topic( Name=f"mpcontribs_{document.project}", Attributes={"DisplayName": f"MPContribs {document.title}"}, ) sns_client.subscribe(TopicArn=resp["TopicArn"], Protocol="email", Endpoint=document.owner) else: set_keys = document._delta()[0].keys() if "is_approved" in set_keys and document.is_approved: subject = f'Your project "{document.project}" has been approved' if current_app.config["DEBUG"]: portal = "http://localhost:" + os.environ["PORTAL_PORT"] else: portal = "https://" + os.environ["PORTAL_CNAME"] html = render_template( "owner_email.html", approved=True, admin_email=admin_email, host=portal, ) topic_arn = ":".join( admin_topic.split(":")[:-1] + ["mpcontribs_" + document.project]) send_email(topic_arn, subject, html) if set_keys: # import here to avoid circular from mpcontribs.api.contributions.document import Contributions from mpcontribs.api.notebooks.document import Notebooks from mpcontribs.api.cards.document import Cards contributions = Contributions.objects.only("pk").filter( project=document.project) Notebooks.objects(contribution__in=contributions).delete() Cards.objects(contribution__in=contributions).delete()
def post_save(cls, sender, document, **kwargs): admin_email = current_app.config["MAIL_DEFAULT_SENDER"] admin_topic = current_app.config["MAIL_TOPIC"] if kwargs.get("created"): ts = current_app.config["USTS"] email_project = [document.owner, document.name] token = ts.dumps(email_project) scheme = "http" if current_app.config["DEBUG"] else "https" link = url_for("projects.applications", token=token, _scheme=scheme, _external=True) subject = f'New project "{document.name}"' hours = int(current_app.config["USTS_MAX_AGE"] / 3600) doc_yaml = yaml.dump(document.to_mongo().to_dict(), indent=4, sort_keys=False) html = render_template("admin_email.html", doc=doc_yaml, link=link, hours=hours) send_email(admin_topic, subject, html) resp = sns_client.create_topic( Name=f"mpcontribs_{document.name}", Attributes={"DisplayName": f"MPContribs {document.title}"}, ) sns_client.subscribe(TopicArn=resp["TopicArn"], Protocol="email", Endpoint=document.owner) else: set_keys = document._delta()[0].keys() if "is_approved" in set_keys and document.is_approved: subject = f'Your project "{document.name}" has been approved' if current_app.config["DEBUG"]: portal = "http://localhost:" + os.environ["PORTAL_PORT"] else: portal = "https://" + os.environ["PORTAL_CNAME"] html = render_template( "owner_email.html", approved=True, admin_email=admin_email, host=portal, ) topic_arn = ":".join( admin_topic.split(":")[:-1] + ["mpcontribs_" + document.name]) send_email(topic_arn, subject, html)
def post_save(cls, sender, document, **kwargs): admin_email = current_app.config["MAIL_DEFAULT_SENDER"] admin_topic = current_app.config["MAIL_TOPIC"] scheme = "http" if current_app.config["DEBUG"] else "https" if kwargs.get("created"): ts = current_app.config["USTS"] email_project = [document.owner, document.name] token = ts.dumps(email_project) link = url_for("projects.applications", token=token, _scheme=scheme, _external=True) subject = f'New project "{document.name}"' hours = int(current_app.config["USTS_MAX_AGE"] / 3600) doc_yaml = yaml.dump(document.to_mongo().to_dict(), indent=4, sort_keys=False) html = render_template("admin_email.html", doc=doc_yaml, link=link, hours=hours) send_email(admin_topic, subject, html) resp = sns_client.create_topic( Name=f"mpcontribs_{document.name}", Attributes={"DisplayName": f"MPContribs {document.title}"}, ) endpoint = document.owner.split(":", 1)[1] sns_client.subscribe(TopicArn=resp["TopicArn"], Protocol="email", Endpoint=endpoint) else: delta_set, delta_unset = document._delta() if "is_approved" in delta_set and document.is_approved: subject = f'Your project "{document.name}" has been approved' netloc = urllib.parse.urlparse(request.url).netloc.replace( "-api", "") portal = f"{scheme}://{netloc}" html = render_template("owner_email.html", approved=True, admin_email=admin_email, host=portal, project=document.name) topic_arn = ":".join( admin_topic.split(":")[:-1] + ["mpcontribs_" + document.name]) send_email(topic_arn, subject, html) if "columns" in delta_set or "columns" in delta_unset or ( not delta_set and not delta_unset): from mpcontribs.api.contributions.document import Contributions, COMPONENTS columns = {} ncontribs = Contributions.objects(project=document.id).count() if "columns" in delta_set: # document.columns updated by the user as intended for col in document.columns: columns[col.path] = col elif "columns" in delta_unset or ncontribs: # document.columns unset by user to reinit all columns from DB # -> get paths and units across all contributions from DB group = { "_id": "$project", "merged": { "$mergeObjects": "$data" } } pipeline = [{ "$match": { "project": document.id } }, { "$group": group }] result = list(Contributions.objects.aggregate(pipeline)) merged = {} if not result else result[0]["merged"] flat = flatten(remap(merged, visit=visit, enter=enter), reducer="dot") for k, v in flat.items(): path = f"data.{k}" columns[path] = Column(path=path) if v is not None: columns[path].unit = v # set min/max for all number columns min_max_paths = [ path for path, col in columns.items() if col["unit"] != "NaN" ] group = {"_id": None} for path in min_max_paths: field = f"{path}{delimiter}value" for k in ["min", "max"]: clean_path = path.replace(delimiter, "__") key = f"{clean_path}__{k}" group[key] = {f"${k}": f"${field}"} pipeline = [{ "$match": { "project": document.id } }, { "$group": group }] result = list(Contributions.objects.aggregate(pipeline)) min_max = {} if not result else result[0] for clean_path in min_max_paths: for k in ["min", "max"]: path = clean_path.replace(delimiter, "__") m = min_max.get(f"{path}__{k}") if m is not None: setattr(columns[clean_path], k, m) # update stats stats_kwargs = { "columns": len(columns), "contributions": ncontribs } for component in COMPONENTS.keys(): pipeline = [{ "$match": { "project": document.id, component: { "$exists": True, "$not": { "$size": 0 } } } }, { "$count": "count" }] result = list(Contributions.objects.aggregate(pipeline)) if result: stats_kwargs[component] = result[0]["count"] columns[component] = Column(path=component) else: stats_kwargs[component] = 0 stats = Stats(**stats_kwargs) document.update(stats=stats, columns=columns.values())