Example #1
0
 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)
Example #2
0
    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()
Example #3
0
 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)
Example #4
0
    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())