Ejemplo n.º 1
0
class EntryLockResource(Resource):
    @marshal_with(fields.entry_lock, envelope="lock")
    def get(self, entry_id, logbook_id=None):
        "Check for a lock"
        entry = Entry.get(Entry.id == entry_id)
        lock = entry.get_lock(request.environ["REMOTE_ADDR"])
        if lock:
            return lock
        raise EntryLock.DoesNotExist

    @use_args({"steal": Boolean(missing=False)})
    @marshal_with(fields.entry_lock, envelope="lock")
    def post(self, args, entry_id, logbook_id=None):
        "Acquire (optionally stealing) a lock"
        entry = Entry.get(Entry.id == entry_id)
        return entry.get_lock(ip=request.environ["REMOTE_ADDR"],
                              acquire=True,
                              steal=args["steal"])

    @use_args({"lock_id": Integer()})
    @marshal_with(fields.entry_lock, envelope="lock")
    def delete(self, args, entry_id=None, logbook_id=None):
        "Cancel a lock"
        if "lock_id" in args:
            lock = EntryLock.get(EntryLock.id == args["lock_id"])
        else:
            entry = Entry.get(Entry.id == entry_id)
            lock = entry.get_lock()
        lock.cancel(request.environ["REMOTE_ADDR"])
        return lock
Ejemplo n.º 2
0
 def __init__(self) -> None:
     super().__init__()
     self.arg_schema = dict(
         page=Str(missing=None, description="Page"),
         per_page=Int(missing=20, description="Number to show"),
         all=Boolean(missing=False, description="Return all results."),
     )
     self.fields = {}
     self.basic_info = {}
     self.schema = None
Ejemplo n.º 3
0
class OpenSearchEndpoint(HTTPEndpoint):

    args_schema = dict(
        page=Str(missing=None, description="Page"),
        per_page=Int(missing=20, description="Number to show"),
        all=Boolean(missing=False, description="Return all results."),
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    async def get(self, request):

        db = app_context().database
        query_params = request.query_params
        if "query" not in query_params or "model" not in query_params:
            return JSONResponse({
                "Status":
                "Success",
                "Message":
                "Provide a string as a query parameter or model",
                "example":
                "/api/v2/search?query=lava&model=sample",
            })

        params = {"query": query_params["query"]}
        model = query_params["model"]

        models = {
            "sample": search_sample,
            "project": search_project,
            "session": search_session,
        }
        if model == "all":
            sql_fn = search_total
            query_res = db.exec_sql_query(fn=sql_fn, params=params)

            json_res = [dict(model=x, data=y) for x, y in query_res]
            json_res.reverse()

            return JSONResponse(json_res)
        else:
            for key, value in models.items():
                if model == key:
                    sql_fn = value
                    schema = getattr(db.interface, key)(many=True)

        query_res = db.exec_sql_query(fn=sql_fn, params=params)

        json_res = [dict(r) for r in query_res]

        return APIResponse(json_res, total_count=len(json_res), schema=schema)
Ejemplo n.º 4
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.meta = self.Meta()
        if getattr(self.meta, "table") is None:
            raise ValueError(
                f"Meta value '{k}' must be provided for ViewAPIEndpoint")

        self._model_name = classname_for_table(self.meta.table)
        log.info(self._model_name)

        self.args_schema = dict(page=Str(missing=None),
                                per_page=Int(missing=20),
                                all=Boolean(missing=False))
Ejemplo n.º 5
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.meta = self.Meta()
        for k in ("database", "schema"):
            if getattr(self.meta, k) is None:
                raise ValueError(
                    f"Meta value '{k}' must be provided for ModelAPIEndpoint")

        schema = self.meta.schema
        self._model_name = classname_for_table(schema.opts.model.__table__)
        log.info(self._model_name)

        d = "related models to nest within response [allowed_nests]"
        e = "?nest=session,project"
        des = create_params(d, e)
        self.instance_schema = dict(
            nest=NestedModelField(Str(), missing=[], description=des))

        des_page = create_params("number of results per page", "?page=>i:5039")
        des_per_page = create_params("number of results per page",
                                     "?per_page=15")
        des_all = create_params("return all results", "?all=true")

        self.args_schema = dict(
            **self.instance_schema,
            page=Str(missing=None, description=des_page),
            per_page=Int(missing=20, description=des_per_page),
            all=Boolean(missing=False, description=des_all),
        )

        self._filters = []
        self.register_filter(OpenSearchFilter)
        self.register_filter(AuthorityFilter)
        self.register_filter(FieldExistsFilter)
        self.register_filter(FieldNotExistsFilter)
        self.register_filter(EmbargoFilter)
        self.register_filter(DateFilter)
        self.register_filter(DOIFilter)
        self.register_filter(CoordinateFilter)
        self.register_filter(GeometryFilter)
        self.register_filter(TextSearchFilter)
        self.register_filter(AgeRangeFilter)
        self.register_filter(IdListFilter)
        self.register_filter(TagsFilter)
Ejemplo n.º 6
0
class DataFileListEndpoint(HTTPEndpoint):
    """A simple demonstration endpoint for paginating a select statement. Extremely quick, but somewhat hand-constructed."""

    args_schema = dict(
        page=Str(missing=None, description="Page"),
        per_page=Int(missing=20, description="Number to show"),
        all=Boolean(missing=False, description="Return all results."),
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        db = get_database()
        self.schema = db.interface.data_file
        self.model = db.model.data_file

        self._filters = []
        self.register_filter(OpenSearchFilter)
        self.register_filter(AuthorityFilter)
        self.register_filter(FieldExistsFilter)
        self.register_filter(FieldNotExistsFilter)
        self.register_filter(EmbargoFilter)
        self.register_filter(DateFilter)
        self.register_filter(TextSearchFilter)
        self.register_filter(AgeRangeFilter)
        self.register_filter(IdListFilter)
        self.register_filter(TagsFilter)

    def register_filter(self, _filter: BaseFilter):
        """Register a filter specification to control parametrization of the
        model query"""
        f = _filter(self.model, schema=self.schema)
        if not f.should_apply():
            return
        if params := getattr(f, "params"):
            self.args_schema.update(**params)
        self._filters.append(f)
Ejemplo n.º 7
0
@advantage_checks(check_list=["need_user"])
@use_kwargs(post_payment_method, location="json")
def post_payment_method(**kwargs):
    api_url = kwargs.get("api_url")
    token = kwargs.get("token")
    account_id = kwargs.get("account_id")
    payment_method_id = kwargs.get("payment_method_id")

    advantage = UAContractsAPI(session, token, api_url=api_url)

    return advantage.put_payment_method(account_id, payment_method_id)


@advantage_checks(check_list=["need_user"])
@use_kwargs({"should_auto_renew": Boolean()}, location="json")
def post_auto_renewal_settings(**kwargs):
    api_url = kwargs.get("api_url")
    token = kwargs.get("token")
    should_auto_renew = kwargs.get("should_auto_renew", False)

    advantage = UAContractsAPI(session, token, api_url=api_url)
    accounts = advantage.get_accounts()

    for account in accounts:
        monthly_subscriptions = advantage.get_account_subscriptions(
            account_id=account["id"],
            marketplace="canonical-ua",
            filters={"status": "active", "period": "monthly"},
        )
Ejemplo n.º 8
0
class EntryResource(Resource):

    "Handle requests for a single entry"

    @use_args({"thread": Boolean(missing=False)})
    @marshal_with(fields.entry_full, envelope="entry")
    def get(self, args, entry_id, logbook_id=None, revision_n=None):
        entry = Entry.get(Entry.id == entry_id)
        if revision_n is not None:
            return entry.get_revision(revision_n)
        if args["thread"]:
            return entry._thread
        return entry

    @send_signal(new_entry)
    @use_args(entry_args)
    @marshal_with(fields.entry_full, envelope="entry")
    def post(self, args, logbook_id, entry_id=None):
        "Creating a new entry"
        logbook = Logbook.get(Logbook.id == logbook_id)
        # TODO: clean up
        if entry_id is not None:
            # we're creating a followup to an existing entry
            args["follows"] = entry_id
        if args.get("content"):
            content_type = args["content_type"]
            if content_type.startswith("text/html"):
                # extract any inline images as attachments
                args["content"], inline_attachments = handle_img_tags(
                    args["content"], timestamp=args.get("created_at"))
            else:
                inline_attachments = []
        else:
            inline_attachments = []
        args["logbook"] = logbook
        # make sure the attributes are of proper types
        try:
            args["attributes"] = logbook.check_attributes(
                args.get("attributes", {}))
        except ValueError as e:
            abort(422, messages={"attributes": [str(e)]})
        if args.get("follows_id"):
            # don't allow pinning followups, that makes no sense
            args["pinned"] = False
        entry = Entry.create(**args)
        for attachment in inline_attachments:
            attachment.entry = entry
            attachment.save()
        return entry

    @send_signal(edit_entry)
    @use_args(entry_args)
    @marshal_with(fields.entry_full, envelope="entry")
    def put(self, args, entry_id, logbook_id=None):
        "update entry"
        entry_id = entry_id or args["id"]
        entry = Entry.get(Entry.id == entry_id)
        # to prevent overwiting someone else's changes we require the
        # client to supply the "revision_n" field of the entry they
        # are editing. If this does not match the current entry in the
        # db, it means someone has changed it inbetween and we abort.
        if "revision_n" not in args:
            abort(400, message="Missing 'revision_n' field!")
        if args["revision_n"] != entry.revision_n:
            abort(
                409,
                message=
                ("Conflict: Entry {} has been edited since you last loaded it!"
                 .format(entry_id)))
        # check for a lock on the entry
        if entry.lock:
            if entry.lock.owned_by_ip == request.remote_addr:
                entry.lock.cancel(request.remote_addr)
            else:
                abort(
                    409,
                    message=("Conflict: Entry {} is locked by IP {} since {}".
                             format(entry_id, entry.lock.owned_by_ip,
                                    entry.lock.created_at)))
        if args.get("content"):
            content_type = args.get("content_type", entry.content_type)
            if content_type.startswith("text/html"):
                args["content"], inline_attachments = handle_img_tags(
                    args["content"])
            else:
                inline_attachments = []
        else:
            inline_attachments = []

        entry = Entry.get(Entry.id == entry_id)
        change = entry.make_change(**args)
        entry.save()
        change.save()
        for attachment in inline_attachments:
            attachment.entry = entry
            attachment.save()
        return entry
Ejemplo n.º 9
0
    "name":
    Str(),
    "description":
    Str(allow_none=True),
    "template":
    Str(allow_none=True),
    "attributes":
    List(
        Nested({
            "name":
            Str(),
            "type":
            Str(validate=lambda t: t in
                ["text", "number", "boolean", "option", "multioption"]),
            "required":
            Boolean(),
            "options":
            List(Str())
        })),
    "metadata":
    Dict(),
    "archived":
    Boolean(missing=False)
}


class LogbooksResource(Resource):

    "Handle requests for logbooks"

    @use_args({"parent": Integer()})
Ejemplo n.º 10
0
    List(Nested({
        "name": Str(),
        "login": Str(allow_none=True),
        "email": Email(allow_none=True)
    }),
         validate=lambda a: len(a) > 0),
    "created_at":
    LocalDateTime(),
    "last_changed_at":
    LocalDateTime(allow_none=True),
    "follows_id":
    Integer(allow_none=True),
    "attributes":
    Dict(),
    "archived":
    Boolean(),
    "metadata":
    Dict(),
    "priority":
    Integer(missing=0),
    "revision_n":
    Integer()
}


class EntryResource(Resource):

    "Handle requests for a single entry"

    @use_args({"thread": Boolean(missing=False)})
    @marshal_with(fields.entry_full, envelope="entry")
Ejemplo n.º 11
0

logbook_args = {
    "parent_id": Integer(allow_none=True),
    "name": Str(),
    "description": Str(allow_none=True),
    "template": Str(allow_none=True),
    "attributes": List(Nested({
        "name": Str(),
        "type": Str(
            validate=lambda t: t in ["text",
                                     "number",
                                     "boolean",
                                     "option",
                                     "multioption"]),
        "required": Boolean(),
        "options": List(Str(), missing=None)
    })),
    "metadata": Dict(),
    "archived": Boolean(missing=False)
}


class LogbooksResource(Resource):

    "Handle requests for logbooks"

    @use_args({"parent": Integer()})
    @marshal_with(fields.logbook, envelope="logbook")
    def get(self, args, logbook_id=None, revision_n=None):
Ejemplo n.º 12
0
class EntitlementSchema(Schema):
    type = String(required=True)
    is_enabled = Boolean(required=True)
Ejemplo n.º 13
0
    line1 = String()
    postal_code = String()
    state = String()


class TaxIdSchema(Schema):
    type = String()
    value = String()


post_advantage_subscriptions = {
    "account_id": String(required=True),
    "period": String(enum=["monthly", "yearly"], required=True),
    "previous_purchase_id": String(required=True),
    "products": List(Nested(ProductSchema), required=True),
    "resizing": Boolean(),
    "trialling": Boolean(),
}

cancel_advantage_subscriptions = {
    "account_id": String(required=True),
    "previous_purchase_id": String(required=True),
    "product_listing_id": String(required=True),
}

post_anonymised_customer_info = {
    "account_id": String(required=True),
    "name": String(required=True),
    "address": Nested(AddressSchema, required=True),
    "tax_id": Nested(TaxIdSchema, allow_none=True),
}
Ejemplo n.º 14
0
    String(),
    "marketplace":
    String(
        validate=validate.OneOf(["canonical-ua", "canonical-cube", "blender"]),
        required=True,
    ),
    "action":
    String(validate=validate.OneOf(["purchase", "resize", "trial", "offer"])),
}

post_advantage_subscriptions = {
    "account_id": String(required=True),
    "period": String(enum=["monthly", "yearly"], required=True),
    "previous_purchase_id": String(required=True),
    "products": List(Nested(ProductSchema), required=True),
    "resizing": Boolean(),
    "marketplace": String(),
    "trialling": Boolean(),
}

cancel_advantage_subscriptions = {
    "account_id":
    String(required=True),
    "previous_purchase_id":
    String(required=True),
    "product_listing_id":
    String(required=True),
    "marketplace":
    String(
        validate=validate.OneOf(["canonical-ua", "canonical-cube", "blender"]),
        required=True,
Ejemplo n.º 15
0
class SubscriptionRenewalSchema(Schema):
    subscription_id = String()
    should_auto_renew = Boolean()
Ejemplo n.º 16
0
    List(Nested({
        "name": Str(),
        "login": Str(allow_none=True),
        "email": Email(allow_none=True)
    }),
         validate=lambda a: len(a) > 0),
    "created_at":
    LocalDateTime(),
    "last_changed_at":
    LocalDateTime(allow_none=True),
    "follows_id":
    Integer(allow_none=True),
    "attributes":
    Dict(),
    "archived":
    Boolean(),
    "no_change_time":
    Boolean(),
    "metadata":
    Dict(),
    "priority":
    Integer(missing=0),
    "revision_n":
    Integer(),
}


class EntryResource(Resource):

    "Handle requests for a single entry"
Ejemplo n.º 17
0
    line1 = String()
    postal_code = String()
    state = String()


class TaxIdSchema(Schema):
    type = String()
    value = String()


post_advantage_subscriptions = {
    "account_id": String(required=True),
    "period": String(enum=["monthly", "yearly"], required=True),
    "previous_purchase_id": String(required=True),
    "products": List(Nested(ProductSchema), required=True),
    "resizing": Boolean(),
}

cancel_advantage_subscriptions = {
    "account_id": String(required=True),
    "previous_purchase_id": String(required=True),
    "product_listing_id": String(required=True),
}

post_anonymised_customer_info = {
    "account_id": String(required=True),
    "address": Nested(AddressSchema, required=True),
    "tax_id": Nested(TaxIdSchema, allow_none=True),
}

post_payment_method = {
Ejemplo n.º 18
0
 def params(self):
     d = "filter by embargoed or not, (false = private data, true = public data, empty = all data)"
     e = ["?public=true", "?public=false"]
     des = create_params(d, e)
     return {self.key: Boolean(description=des)}