MyProjects / ToGoodToGo / JsonHelper.py
JsonHelper.py
Raw
# This code parses date/times, so please
#
#     pip install python-dateutil
#
# To use this code, make sure you
#
#     import json
#
# and then, to convert JSON from a string, do
#
#     result = ToGoodToGo_from_dict(json.loads(json_string))

from dataclasses import dataclass
from typing import Any, List, Optional, TypeVar, Type, Callable, cast
from enum import Enum
from datetime import datetime
import dateutil.parser


T = TypeVar("T")
EnumT = TypeVar("EnumT", bound=Enum)


def from_str(x: Any) -> str:
    assert isinstance(x, str)
    return x


def from_int(x: Any) -> int:
    assert isinstance(x, int) and not isinstance(x, bool)
    return x


def to_enum(c: Type[EnumT], x: Any) -> EnumT:
    assert isinstance(x, c)
    return x.value


def from_bool(x: Any) -> bool:
    assert isinstance(x, bool)
    return x


def from_list(f: Callable[[Any], T], x: Any) -> List[T]:
    assert isinstance(x, list)
    return [f(y) for y in x]


def from_none(x: Any) -> Any:
    assert x is None
    return x


def from_union(fs, x):
    for f in fs:
        try:
            return f(x)
        except:
            pass
    assert False


def to_class(c: Type[T], x: Any) -> dict:
    assert isinstance(x, c)
    return cast(Any, x).to_dict()


def from_datetime(x: Any) -> datetime:
    return dateutil.parser.parse(x)


def from_float(x: Any) -> float:
    assert isinstance(x, (float, int)) and not isinstance(x, bool)
    return float(x)


def to_float(x: Any) -> float:
    assert isinstance(x, float)
    return x


@dataclass
class Picture:
    picture_id: int
    current_url: str

    @staticmethod
    def from_dict(obj: Any) -> 'Picture':
        assert isinstance(obj, dict)
        picture_id = int(from_str(obj.get("picture_id")))
        current_url = from_str(obj.get("current_url"))
        return Picture(picture_id, current_url)

    def to_dict(self) -> dict:
        result: dict = {}
        result["picture_id"] = from_str(str(self.picture_id))
        result["current_url"] = from_str(self.current_url)
        return result


class ItemCategory(Enum):
    BAKED_GOODS = "BAKED_GOODS"
    GROCERIES = "GROCERIES"
    MEAL = "MEAL"
    OTHER = "OTHER"


class ItemName(Enum):
    BELEG_JE_BROODJES_BOX = "Beleg Je Broodjes Box"
    EMPTY = ""
    MAGIC_BOX = "Magic Box"


class PackagingOption(Enum):
    BAG_ALLOWED = "BAG_ALLOWED"


class Code(Enum):
    EUR = "EUR"


@dataclass
class Price:
    code: Code
    minor_units: int
    decimals: int

    @staticmethod
    def from_dict(obj: Any) -> 'Price':
        assert isinstance(obj, dict)
        code = Code(obj.get("code"))
        minor_units = from_int(obj.get("minor_units"))
        decimals = from_int(obj.get("decimals"))
        return Price(code, minor_units, decimals)

    def to_dict(self) -> dict:
        result: dict = {}
        result["code"] = to_enum(Code, self.code)
        result["minor_units"] = from_int(self.minor_units)
        result["decimals"] = from_int(self.decimals)
        return result


@dataclass
class ItemItem:
    item_id: str
    price: Price
    value: Price
    cover_picture: Picture
    name: ItemName
    description: str
    can_user_supply_packaging: bool
    favorite_count: int
    diet_categories: List[Any]
    item_category: ItemCategory
    buffet: bool
    logo_picture: Optional[Picture] = None
    packaging_option: Optional[PackagingOption] = None
    collection_info: Optional[str] = None

    @staticmethod
    def from_dict(obj: Any) -> 'ItemItem':
        assert isinstance(obj, dict)
        item_id = from_str(obj.get("item_id"))
        price = Price.from_dict(obj.get("price"))
        value = Price.from_dict(obj.get("value"))
        cover_picture = Picture.from_dict(obj.get("cover_picture"))
        name = ItemName(obj.get("name"))
        description = from_str(obj.get("description"))
        can_user_supply_packaging = from_bool(obj.get("can_user_supply_packaging"))
        favorite_count = from_int(obj.get("favorite_count"))
        diet_categories = from_list(lambda x: x, obj.get("diet_categories"))
        item_category = ItemCategory(obj.get("item_category"))
        buffet = from_bool(obj.get("buffet"))
        logo_picture = from_union([Picture.from_dict, from_none], obj.get("logo_picture"))
        packaging_option = from_union([PackagingOption, from_none], obj.get("packaging_option"))
        collection_info = from_union([from_str, from_none], obj.get("collection_info"))
        return ItemItem(item_id, price, value, cover_picture, name, description, can_user_supply_packaging, favorite_count, diet_categories, item_category, buffet, logo_picture, packaging_option, collection_info)

    def to_dict(self) -> dict:
        result: dict = {}
        result["item_id"] = from_str(self.item_id)
        result["price"] = to_class(Price, self.price)
        result["value"] = to_class(Price, self.value)
        result["cover_picture"] = to_class(Picture, self.cover_picture)
        result["name"] = to_enum(ItemName, self.name)
        result["description"] = from_str(self.description)
        result["can_user_supply_packaging"] = from_bool(self.can_user_supply_packaging)
        result["favorite_count"] = from_int(self.favorite_count)
        result["diet_categories"] = from_list(lambda x: x, self.diet_categories)
        result["item_category"] = to_enum(ItemCategory, self.item_category)
        result["buffet"] = from_bool(self.buffet)
        result["logo_picture"] = from_union([lambda x: to_class(Picture, x), from_none], self.logo_picture)
        result["packaging_option"] = from_union([lambda x: to_enum(PackagingOption, x), from_none], self.packaging_option)
        result["collection_info"] = from_union([from_str, from_none], self.collection_info)
        return result


@dataclass
class PickupInterval:
    start: datetime
    end: datetime

    @staticmethod
    def from_dict(obj: Any) -> 'PickupInterval':
        assert isinstance(obj, dict)
        start = from_datetime(obj.get("start"))
        end = from_datetime(obj.get("end"))
        return PickupInterval(start, end)

    def to_dict(self) -> dict:
        result: dict = {}
        result["start"] = self.start.isoformat()
        result["end"] = self.end.isoformat()
        return result


class ISOCode(Enum):
    NL = "NL"


class CountryName(Enum):
    NETHERLANDS = "Netherlands"


@dataclass
class Country:
    iso_code: ISOCode
    name: CountryName

    @staticmethod
    def from_dict(obj: Any) -> 'Country':
        assert isinstance(obj, dict)
        iso_code = ISOCode(obj.get("iso_code"))
        name = CountryName(obj.get("name"))
        return Country(iso_code, name)

    def to_dict(self) -> dict:
        result: dict = {}
        result["iso_code"] = to_enum(ISOCode, self.iso_code)
        result["name"] = to_enum(CountryName, self.name)
        return result


@dataclass
class Address:
    country: Country
    address_line: str
    city: str
    postal_code: str

    @staticmethod
    def from_dict(obj: Any) -> 'Address':
        assert isinstance(obj, dict)
        country = Country.from_dict(obj.get("country"))
        address_line = from_str(obj.get("address_line"))
        city = from_str(obj.get("city"))
        postal_code = from_str(obj.get("postal_code"))
        return Address(country, address_line, city, postal_code)

    def to_dict(self) -> dict:
        result: dict = {}
        result["country"] = to_class(Country, self.country)
        result["address_line"] = from_str(self.address_line)
        result["city"] = from_str(self.city)
        result["postal_code"] = from_str(self.postal_code)
        return result


@dataclass
class LocationClass:
    longitude: float
    latitude: float

    @staticmethod
    def from_dict(obj: Any) -> 'LocationClass':
        assert isinstance(obj, dict)
        longitude = from_float(obj.get("longitude"))
        latitude = from_float(obj.get("latitude"))
        return LocationClass(longitude, latitude)

    def to_dict(self) -> dict:
        result: dict = {}
        result["longitude"] = to_float(self.longitude)
        result["latitude"] = to_float(self.latitude)
        return result


@dataclass
class Location:
    address: Address
    location: LocationClass

    @staticmethod
    def from_dict(obj: Any) -> 'Location':
        assert isinstance(obj, dict)
        address = Address.from_dict(obj.get("address"))
        location = LocationClass.from_dict(obj.get("location"))
        return Location(address, location)

    def to_dict(self) -> dict:
        result: dict = {}
        result["address"] = to_class(Address, self.address)
        result["location"] = to_class(LocationClass, self.location)
        return result


class StoreTimeZone(Enum):
    EUROPE_AMSTERDAM = "Europe/Amsterdam"


@dataclass
class Store:
    store_id: str
    store_name: str
    description: str
    website: str
    store_location: Location
    store_time_zone: StoreTimeZone
    hidden: bool
    favorite_count: int
    we_care: bool
    logo_picture: Optional[Picture] = None
    branch: Optional[str] = None

    @staticmethod
    def from_dict(obj: Any) -> 'Store':
        assert isinstance(obj, dict)
        store_id = from_str(obj.get("store_id"))
        store_name = from_str(obj.get("store_name"))
        description = from_str(obj.get("description"))
        website = from_str(obj.get("website"))
        store_location = Location.from_dict(obj.get("store_location"))
        store_time_zone = StoreTimeZone(obj.get("store_time_zone"))
        hidden = from_bool(obj.get("hidden"))
        favorite_count = from_int(obj.get("favorite_count"))
        we_care = from_bool(obj.get("we_care"))
        logo_picture = from_union([Picture.from_dict, from_none], obj.get("logo_picture"))
        branch = from_union([from_str, from_none], obj.get("branch"))
        return Store(store_id, store_name, description, website, store_location, store_time_zone, hidden, favorite_count, we_care, logo_picture, branch)

    def to_dict(self) -> dict:
        result: dict = {}
        result["store_id"] = from_str(self.store_id)
        result["store_name"] = from_str(self.store_name)
        result["description"] = from_str(self.description)
        result["website"] = from_str(self.website)
        result["store_location"] = to_class(Location, self.store_location)
        result["store_time_zone"] = to_enum(StoreTimeZone, self.store_time_zone)
        result["hidden"] = from_bool(self.hidden)
        result["favorite_count"] = from_int(self.favorite_count)
        result["we_care"] = from_bool(self.we_care)
        result["logo_picture"] = from_union([lambda x: to_class(Picture, x), from_none], self.logo_picture)
        result["branch"] = from_union([from_str, from_none], self.branch)
        return result


@dataclass
class ItemElement:
    item: ItemItem
    store: Store
    display_name: str
    pickup_location: Location
    items_available: int
    distance: float
    favorite: bool
    in_sales_window: bool
    new_item: bool
    pickup_interval: Optional[PickupInterval] = None
    purchase_end: Optional[datetime] = None
    sold_out_at: Optional[datetime] = None

    @staticmethod
    def from_dict(obj: Any) -> 'ItemElement':
        assert isinstance(obj, dict)
        item = ItemItem.from_dict(obj.get("item"))
        store = Store.from_dict(obj.get("store"))
        display_name = from_str(obj.get("display_name"))
        pickup_location = Location.from_dict(obj.get("pickup_location"))
        items_available = from_int(obj.get("items_available"))
        distance = from_float(obj.get("distance"))
        favorite = from_bool(obj.get("favorite"))
        in_sales_window = from_bool(obj.get("in_sales_window"))
        new_item = from_bool(obj.get("new_item"))
        pickup_interval = from_union([PickupInterval.from_dict, from_none], obj.get("pickup_interval"))
        purchase_end = from_union([from_datetime, from_none], obj.get("purchase_end"))
        sold_out_at = from_union([from_datetime, from_none], obj.get("sold_out_at"))
        return ItemElement(item, store, display_name, pickup_location, items_available, distance, favorite, in_sales_window, new_item, pickup_interval, purchase_end, sold_out_at)

    def to_dict(self) -> dict:
        result: dict = {}
        result["item"] = to_class(ItemItem, self.item)
        result["store"] = to_class(Store, self.store)
        result["display_name"] = from_str(self.display_name)
        result["pickup_location"] = to_class(Location, self.pickup_location)
        result["items_available"] = from_int(self.items_available)
        result["distance"] = to_float(self.distance)
        result["favorite"] = from_bool(self.favorite)
        result["in_sales_window"] = from_bool(self.in_sales_window)
        result["new_item"] = from_bool(self.new_item)
        result["pickup_interval"] = from_union([lambda x: to_class(PickupInterval, x), from_none], self.pickup_interval)
        result["purchase_end"] = from_union([lambda x: x.isoformat(), from_none], self.purchase_end)
        result["sold_out_at"] = from_union([lambda x: x.isoformat(), from_none], self.sold_out_at)
        return result


@dataclass
class DiscoverBucket:
    bucket_identifier: str
    items: List[ItemElement]

    @staticmethod
    def from_dict(obj: Any) -> 'DiscoverBucket':
        assert isinstance(obj, dict)
        bucket_identifier = from_str(obj.get("bucket_identifier"))
        items = from_list(ItemElement.from_dict, obj.get("items"))
        return DiscoverBucket(bucket_identifier, items)

    def to_dict(self) -> dict:
        result: dict = {}
        result["bucket_identifier"] = from_str(self.bucket_identifier)
        result["items"] = from_list(lambda x: to_class(ItemElement, x), self.items)
        return result


@dataclass
class Grouping:
    type: str
    discover_bucket: Optional[DiscoverBucket] = None

    @staticmethod
    def from_dict(obj: Any) -> 'Grouping':
        assert isinstance(obj, dict)
        type = from_str(obj.get("type"))
        discover_bucket = from_union([DiscoverBucket.from_dict, from_none], obj.get("discover_bucket"))
        return Grouping(type, discover_bucket)

    def to_dict(self) -> dict:
        result: dict = {}
        result["type"] = from_str(self.type)
        result["discover_bucket"] = from_union([lambda x: to_class(DiscoverBucket, x), from_none], self.discover_bucket)
        return result


@dataclass
class ToGoodToGo:
    item_availability_status: str
    groupings: List[Grouping]

    @staticmethod
    def from_dict(obj: Any) -> 'ToGoodToGo':
        assert isinstance(obj, dict)
        item_availability_status = from_str(obj.get("item_availability_status"))
        groupings = from_list(Grouping.from_dict, obj.get("groupings"))
        return ToGoodToGo(item_availability_status, groupings)

    def to_dict(self) -> dict:
        result: dict = {}
        result["item_availability_status"] = from_str(self.item_availability_status)
        result["groupings"] = from_list(lambda x: to_class(Grouping, x), self.groupings)
        return result


def ToGoodToGo_from_dict(s: Any) -> ToGoodToGo:
    return ToGoodToGo.from_dict(s)


def ToGoodToGo_to_dict(x: ToGoodToGo) -> Any:
    return to_class(ToGoodToGo, x)