示例#1
0
class IssueSchema(Schema):
    id = Integer()

    user = Nested(UserSchema())
    user_id = Integer()
    user_url = Url(relative=True)

    bike = Nested(BikeSchema(), allow_none=True)
    bike_identifier = BytesField(as_string=True, allow_none=True)
    bike_url = Url(relative=True, allow_none=True)

    opened_at = DateTime()
    closed_at = DateTime()
    description = String(required=True)
    resolution = String(allow_none=True)
    status = EnumField(IssueStatus, default=IssueStatus.OPEN)

    @validates_schema
    def assert_url_included_with_foreign_key(self, data, **kwargs):
        """
        Asserts that when a user_id or bike_id is sent that a user_url or bike_url is sent with it.
        """
        if "user_id" in data and "user_url" not in data:
            raise ValidationError(
                "User ID was included, but User URL was not.")
        if "bike_id" in data and "bike_url" not in data:
            raise ValidationError(
                "Bike ID was included, but Bike URL was not.")
示例#2
0
class RecordIdentifier(StrictKeysMixin):
    nuslOAI = OAI()
    nrcrHandle = Url()
    nrcrOAI = OAI()
    originalRecord = Url()
    originalRecordOAI = OAI()
    catalogueSysNo = SanitizedUnicode()
示例#3
0
class CollectionCreateSchema(Schema):
    label = String(validate=Length(min=2, max=500), required=True)
    foreign_id = String(missing=None)
    casefile = Boolean(missing=None)
    summary = String(allow_none=True)
    publisher = String(allow_none=True)
    publisher_url = Url(allow_none=True)
    data_url = Url(allow_none=True)
    info_url = Url(allow_none=True)
    countries = List(Country())
    languages = List(Language())
    category = Category(missing=None)
示例#4
0
class RentalSchema(Schema):
    id = Integer(required=True)

    user = Nested(UserSchema())
    user_id = Integer()
    user_url = Url(relative=True)

    bike = Nested(BikeSchema())
    bike_identifier = BytesField(as_string=True)
    bike_url = Url(relative=True)

    events = Nested(RentalUpdateSchema(), many=True)
    start_time = DateTime(required=True)
    end_time = DateTime()
    cancel_time = DateTime()

    is_active = Boolean(required=True)
    price = Float()
    distance = Float()

    @validates_schema
    def assert_end_time_with_price(self, data, **kwargs):
        """
        Asserts that when a rental is complete both the price and end time are included.
        """
        if "price" in data and "end_time" not in data:
            raise ValidationError(
                "If the price is included, you must also include the end time."
            )
        elif "price" not in data and "end_time" in data:
            raise ValidationError(
                "If the end time is included, you must also include the price."
            )
        if "price" in data and "estimated_price" in data:
            raise ValidationError(
                "Rental should have one of either price or estimated_price.")

    @validates_schema
    def assert_url_included_with_foreign_key(self, data, **kwargs):
        """
        Asserts that when a user_id or bike_id is sent that a user_url or bike_url is sent with it.
        """
        if "user_id" in data and "user_url" not in data:
            raise ValidationError(
                "User ID was included, but User URL was not.")
        if "bike_id" in data and "bike_url" not in data:
            raise ValidationError(
                "Bike ID was included, but Bike URL was not.")
示例#5
0
class InstitutionsMixin:
    relatedID = Nested(RelatedIDSchema)
    aliases = List(SanitizedUnicode())
    ico = SanitizedUnicode()
    url = Url()
    provider = Boolean(missing=False)
    formerNames = List(SanitizedUnicode())
class WebPageSchema(Schema):
    url = Url(required=True, allow_none=False)
    html = String(required=True)

    @post_load()
    def make_web_page(self, data):
        return WebPage(**data)
示例#7
0
class UserPaymentView(BaseView):
    """
    Allows a user to get or replace their payment details.
    """

    url = f"/users/{{id:{USER_IDENTIFIER_REGEX}}}/payment"
    with_user = match_getter(get_user, 'user', user_id='id')

    @with_user
    @docs(summary="Check For Existence Of Payment Details")
    @returns(None)
    async def get(self, user: User):
        if user.can_pay:
            raise web.HTTPOk
        else:
            raise web.HTTPNoContent

    @with_user
    @docs(summary="Add Or Replace Payment Details")
    @expects(PaymentSourceSchema())
    async def put(self, user: User):
        if user.can_pay:
            await self.payment_manager.update_customer(
                user, self.request["data"]["token"])
        else:
            await self.payment_manager.create_customer(
                user, self.request["data"]["token"])

        raise web.HTTPOk

    @with_user
    @docs(summary="Delete Payment Details")
    @returns(
        active_rental=JSendSchema.of(rental=RentalSchema(),
                                     message=String(),
                                     url=Url(relative=True)),
        no_details=(None, web.HTTPNotFound),
        deleted=(None, web.HTTPNoContent),
    )
    async def delete(self, user: User):

        rental = await self.rental_manager.active_rental(user)

        if rental is not None:
            return "active_rental", {
                "status": JSendStatus.FAIL,
                "data": {
                    "message":
                    "You cannot delete your payment details with an active rental.",
                    "url":
                    self.request.app.router["rental"].url_for(
                        id=str(rental.id)).path
                }
            }
        elif not user.can_pay:
            return "no_details", None
        else:
            await self.payment_manager.delete_customer(user)
            return "deleted", None
示例#8
0
class CollectionSchema(BaseSchema):
    EXPAND = [
        ('creator', Role, 'creator', RoleReferenceSchema, False),
    ]

    label = String(validate=Length(min=2, max=500), required=True)
    foreign_id = String(missing=None)
    kind = String(dump_only=True)
    casefile = Boolean(missing=None)
    summary = String(allow_none=True)
    publisher = String(allow_none=True)
    publisher_url = Url(allow_none=True)
    data_url = Url(allow_none=True)
    info_url = Url(allow_none=True)
    countries = List(Country())
    languages = List(Language())
    secret = Boolean(dump_only=True)
    category = Category(missing=Collection.DEFAULT)
    creator_id = String(allow_none=True)
    creator = Nested(RoleReferenceSchema(), dump_only=True)
    team = List(Nested(RoleReferenceSchema()), dump_only=True)
    count = Integer(dump_only=True)
    schemata = Dict(dump_only=True, default={})

    @pre_load
    def flatten_collection(self, data):
        flatten_id(data, 'creator_id', 'creator')

    @pre_dump
    def visibility(self, data):
        if not is_mapping(data):
            return
        roles = [int(r) for r in data.get('roles', [])]
        public = Role.public_roles()
        data['secret'] = len(public.intersection(roles)) == 0

    @post_dump
    def hypermedia(self, data):
        pk = str(data.get('id'))
        data['links'] = {
            'self': url_for('collections_api.view', id=pk),
            'ui': collection_url(pk)
        }
        data['writeable'] = request.authz.can_write(pk)
        return data
示例#9
0
class ReservationSchema(CreateReservationSchema):
    id = Integer()

    made_at = DateTime()
    ended_at = DateTime()
    status = EnumField(ReservationOutcome, default=ReservationOutcome.OPEN)

    user = Nested(UserSchema())
    user_id = Integer()
    user_url = Url(relative=True)

    pickup = Nested(PickupPointSchema())
    pickup_id = Integer()
    pickup_url = Url(relative=True)

    rental = Nested(RentalSchema())
    rental_io = Integer()
    rental_url = Url(relative=True)
示例#10
0
class NewInstanceRequest(SPSchema):
    """Validator for POST /rpc/client requests."""

    # Deserialization fields.
    chain_url = Url(required=True, load_only=True)
    privkey = BytesField(required=True, load_only=True)
    gas_price_strategy = String(required=False, load_only=True, missing="fast")

    # Serialization fields.
    rpc_client_id = String(required=True, dump_only=True)
示例#11
0
class CollectionSchema(BaseSchema):
    EXPAND = [
        ('creator', Role, 'creator', RoleReferenceSchema, False),
    ]

    label = String(validate=Length(min=2, max=500), required=True)
    foreign_id = String(missing=None)
    kind = String(dump_only=True)
    casefile = Boolean(missing=None)
    summary = String(allow_none=True)
    publisher = String(allow_none=True)
    publisher_url = Url(allow_none=True)
    data_url = Url(allow_none=True)
    info_url = Url(allow_none=True)
    countries = List(Country())
    languages = List(Language())
    secret = Boolean(dump_only=True)
    category = Category(missing=Collection.DEFAULT)
    creator_id = String(allow_none=True)
    creator = Nested(RoleReferenceSchema(), dump_only=True)
    team = List(Nested(RoleReferenceSchema()), dump_only=True)
    count = Integer(dump_only=True)
    schemata = Dict(dump_only=True)

    @pre_load
    def flatten_collection(self, data):
        flatten_id(data, 'creator_id', 'creator')

    @post_dump
    def hypermedia(self, data):
        pk = str(data.get('id'))
        data['links'] = {
            'self': url_for('collections_api.view', id=pk),
            'xref': url_for('xref_api.index', id=pk),
            'xref_csv': url_for('xref_api.csv_export', id=pk, _authorize=True),
            'ui': collection_url(pk)
        }
        data['writeable'] = request.authz.can(pk, request.authz.WRITE)
        return data
示例#12
0
class CreateClientSchema(SPSchema):
    """POST /rpc/client

    load-only parameters:

        - chain_url (:class:`Url`)
        - privkey (:class:`BytesField`)
        - gas_price (str)

    dump-only parameters:

        - client_id (:class:`RPCClientID`)
    """

    # Deserialization fields.
    chain_url = Url(required=True, load_only=True)
    privkey = BytesField(required=True, load_only=True)
    gas_price = GasPrice(required=False, load_only=True, missing="FAST")

    # Serialization fields.
    client_id = RPCClientID(required=True, dump_only=True)
示例#13
0
class RightsMixin:
    icon = Url()
    related = Nested(RightsRelated)
示例#14
0
class UserEndCurrentRentalView(BaseView):
    """"""

    url = f"/users/{{id:{USER_IDENTIFIER_REGEX}}}/rentals/current/{{action}}"
    name = "user_end_current_rental"
    with_user = match_getter(get_user, 'user', user_id='id')
    actions = ("cancel", "complete")

    @with_user
    @docs(summary="End Rental For User")
    @requires(UserMatchesToken() | UserIsAdmin())
    @returns(
        no_rental=(JSendSchema(), web.HTTPNotFound),
        invalid_action=(JSendSchema(), web.HTTPNotFound),
        rental_completed=JSendSchema.of(rental=RentalSchema(),
                                        action=String(),
                                        receipt_url=Url(allow_none=True)),
    )
    async def patch(self, user: User):
        """
        Ends a rental for a user, in one of two ways:

        - ``PATCH /users/me/rentals/current/cancel`` cancels the rental
        - ``PATCH /users/me/rentals/current/complete`` completes the rental
        """

        if not self.rental_manager.has_active_rental(user):
            return "no_rental", {
                "status": JSendStatus.FAIL,
                "data": {
                    "message": "You have no current rental."
                }
            }

        end_type = self.request.match_info["action"]
        if end_type not in self.actions:
            return "invalid_action", {
                "status": JSendStatus.FAIL,
                "data": {
                    "message":
                    f"Invalid action. Pick between {', '.join(self.actions)}",
                    "actions": self.actions
                }
            }

        if end_type == "complete":
            rental, receipt_url = await self.rental_manager.finish(user)
        elif end_type == "cancel":
            rental = await self.rental_manager.cancel(user)
            receipt_url = None
        else:
            raise Exception

        return "rental_completed", {
            "status": JSendStatus.SUCCESS,
            "data": {
                "rental":
                await rental.serialize(self.rental_manager,
                                       self.bike_connection_manager,
                                       self.reservation_manager,
                                       self.request.app.router),
                "action":
                "canceled" if end_type == "cancel" else "completed",
                "receipt_url":
                receipt_url,
            }
        }
示例#15
0
class CurrentReservationSchema(ReservationSchema):
    url = Url(relative=True, required=True)
示例#16
0
class Links(Schema):
    self = Url()
示例#17
0
class CommonMetadataSchemaV2(InvenioRecordMetadataSchemaV1Mixin, FSMRecordSchemaMixin,
                             OARepoCommunitiesMixin, StrictKeysMixin):
    """Schema for the record metadata."""

    abstract = MultilingualStringV2()
    accessibility = MultilingualStringV2()
    accessRights = TaxonomyField(mixins=[TitledMixin, AccessRightsMixin], required=True)
    creator = List(Nested(PersonSchema), required=True)
    contributor = List(Nested(ContributorSchema))
    dateIssued = NRDate(required=True)
    dateModified = NRDate()
    resourceType = TaxonomyField(mixins=[TitledMixin], required=True)
    extent = List(SanitizedUnicode())  # TODO: pokud nemáme extent, spočítat z PDF - asi nepůjde
    externalLocation = Url()
    control_number = SanitizedUnicode(required=True)
    recordIdentifiers = Nested(RecordIdentifier)
    workIdentifiers = Nested(WorkIdentifersSchema)
    isGL = Boolean()
    language = TaxonomyField(mixins=[TitledMixin], required=True)
    note = List(SanitizedUnicode())
    fundingReference = List(Nested(FundingReferenceSchema))
    provider = TaxonomyField(mixins=[TitledMixin, InstitutionsMixin], required=True)
    entities = TaxonomyField(mixins=[TitledMixin, InstitutionsMixin], many=True)
    publicationPlace = Nested(PublicationPlaceSchema)
    publisher = List(SanitizedUnicode())
    relatedItem = List(Nested(RelatedItemSchema))
    rights = TaxonomyField(mixins=[TitledMixin, RightsMixin], many=True)
    series = List(Nested(SeriesSchema))
    subject = TaxonomyField(mixins=[TitledMixin, SubjectMixin, PSHMixin, CZMeshMixin, MedvikMixin],
                            many=True)
    keywords = List(MultilingualStringV2())
    title = List(MultilingualStringV2(required=True), required=True, validate=Length(min=1))
    titleAlternate = List(MultilingualStringV2())
    rulesExceptions = List(Nested(RulesExceptionsSchema))

    @pre_load
    def check_keyword(self, data, **kwargs):
        keywords = data.get("keywords", [])
        if isinstance(keywords, dict):
            if "error" in keywords:
                raise ValidationError(keywords["error"])
        return data

    @post_load
    def check_language(self, data, **kwargs):
        language = data.get("language")
        if not language:
            raise ValidationError("Language is required field", field_name="language")
        return data

    @post_load
    def validate_keywords_subjects(self, data, **kwargs):
        subject = [x for x in data.get("subject", []) if not x["is_ancestor"]]
        keywords = data.get("keywords", [])
        if len(keywords) + len(subject) < 3:
            raise ValidationError("At least three subjects or keyword are required",
                                  field_name="keywords")
        return data

    @post_load
    def copy_to_entities(self, data, **kwargs):
        entities = data.get("entities")
        if not entities:
            data["entities"] = data["provider"]
        return data

    @post_load
    def rules_exceptions(self, data, **kwargs):
        if "rulesExceptions" in data:
            raise ValidationError(f"Some rules raises exception: {data['rulesExceptions']}")
        return data