Skip to content
Snippets Groups Projects
schemas.py 4.01 KiB
Newer Older
  • Learn to ignore specific revisions
  • import marshmallow
    import semver
    import re
    
    
    class VersionField(marshmallow.fields.Str):
        def deserialize(self, value, *args, **kwargs):
            value = super().deserialize(value, *args, **kwargs)
            try:
                return semver.parse(value)
            except ValueError:
                # funkwhale does not always include the patch version, so we add the 0 ourself and
                # try again
                try:
                    v_regex = r"(\d+\.\d+)"
                    match = re.match(v_regex, value)
                    if match and match[0]:
                        new_version = f"{match[0]}.0"
                        return semver.parse(value.replace(match[0], new_version, 1))
                    raise ValueError()
                except (ValueError, IndexError):
                    raise marshmallow.ValidationError(
                        f"{value} is not a semver version number"
                    )
            return value
    
    
    class SoftwareSchema(marshmallow.Schema):
        name = marshmallow.fields.String(
            required=True, validate=[marshmallow.validate.OneOf(["funkwhale", "Funkwhale"])]
        )
        version = VersionField(required=True)
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        class Meta:
            unknown = marshmallow.EXCLUDE
    
    
    
    """
    "openRegistrations": False,
            "usage": {"users": {"total": 78}},
            "metadata": {
                "private": False,
                "nodeName": "Funkwhale 101",
                "library": {
                    "federationEnabled": True,
                    "federationNeedsApproval": True,
                    "anonymousCanListen": True,
                    "tracks": {"total": 98552},
                    "artists": {"total": 9831},
                    "albums": {"total": 10872},
                    "music": {"hours": 7650.678055555555},
                },
                "usage": {
                    "favorites": {"tracks": {"total": 1683}},
                    "listenings": {"total": 50294},
                },
            },
        }
    """
    
    
    class StatisticsSchema(marshmallow.Schema):
    
        total = marshmallow.fields.Integer(required=True)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        class Meta:
            unknown = marshmallow.EXCLUDE
    
    
    class UsageStatisticsSchema(StatisticsSchema):
        activeHalfyear = marshmallow.fields.Integer(required=False)
        activeMonth = marshmallow.fields.Integer(required=False)
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        class Meta:
            unknown = marshmallow.EXCLUDE
    
    
    class UsageSchema(marshmallow.Schema):
    
        users = marshmallow.fields.Nested(UsageStatisticsSchema, required=True)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        class Meta:
            unknown = marshmallow.EXCLUDE
    
    
    
    class MusicSchema(marshmallow.Schema):
        hours = marshmallow.fields.Integer(required=False)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        class Meta:
            unknown = marshmallow.EXCLUDE
    
    
    
    class LibraryMetadataSchema(marshmallow.Schema):
        anonymousCanListen = marshmallow.fields.Boolean(required=True)
        federationEnabled = marshmallow.fields.Boolean(required=True)
    
        tracks = marshmallow.fields.Nested(StatisticsSchema, required=False)
        albums = marshmallow.fields.Nested(StatisticsSchema, required=False)
        artists = marshmallow.fields.Nested(StatisticsSchema, required=False)
        music = marshmallow.fields.Nested(MusicSchema, required=False)
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        class Meta:
            unknown = marshmallow.EXCLUDE
    
    
    
    class MetadataUsageSchema(marshmallow.Schema):
        listenings = marshmallow.fields.Nested(StatisticsSchema, required=False)
    
        downloads = marshmallow.fields.Nested(StatisticsSchema, required=False)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        class Meta:
            unknown = marshmallow.EXCLUDE
    
    
    
    class MetadataSchema(marshmallow.Schema):
        nodeName = marshmallow.fields.String(required=True)
        private = marshmallow.fields.Boolean(required=True)
    
        library = marshmallow.fields.Nested(LibraryMetadataSchema, required=True)
        usage = marshmallow.fields.Nested(MetadataUsageSchema, required=True)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        class Meta:
            unknown = marshmallow.EXCLUDE
    
    
    
    class NodeInfo2Schema(marshmallow.Schema):
    
        software = marshmallow.fields.Nested(SoftwareSchema, required=True)
    
        openRegistrations = marshmallow.fields.Boolean(required=True)
    
        usage = marshmallow.fields.Nested(UsageSchema, required=True)
        metadata = marshmallow.fields.Nested(MetadataSchema, required=True)
    
        class Meta:
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            unknown = marshmallow.EXCLUDE