Source code for vulyk.blueprints.gamification.models.foundations

# -*- coding: utf-8 -*-
"""
Contains all DB models related to foundations we donate or we rely on
"""
from enum import Enum
from typing import Iterator, Optional

from flask_mongoengine import Document
from mongoengine import (
    StringField, EmailField, ImageField, BooleanField, Q
)

from ..core.foundations import Fund

__all__ = [
    'FundFilterBy',
    'FundModel'
]


[docs]class FundFilterBy(Enum): """ The intent of this enum is to represent filtering policies. """ NO_FILTER = 0 DONATABLE = 1 NON_DONATABLE = 2
[docs]class FundModel(Document): """ Database-specific foundation representation """ id = StringField(required=True, max_length=50, primary_key=True) name = StringField(required=True) description = StringField(required=True) site = StringField(required=False) email = EmailField(required=False, allow_utf8_user=True) logo = ImageField(unique=True, thumbnail_size=(141, 106, True)) donatable = BooleanField(required=True) meta = { 'collection': 'gamification.funds', 'allow_inheritance': True, 'indexes': [ 'name', 'donatable' ] }
[docs] def to_fund(self) -> Fund: """ DB-specific model to Fund converter. :return: New Fund instance :rtype: Fund """ return Fund( fund_id=self.id, name=self.name, description=self.description, site=self.site, email=self.email, logo=self.logo.get(), donatable=self.donatable)
[docs] @classmethod def from_fund(cls, fund: Fund): """ Fund to DB-specific model converter. :param fund: Current Fund instance :type fund: Fund :return: New FundModel instance :rtype: FundModel """ result = cls( id=fund.id, name=fund.name, description=fund.description, site=fund.site, email=fund.email, donatable=fund.donatable) result.logo.put(fund.logo) return result
[docs] @classmethod def find_by_id(cls, fund_id: str) -> Optional[Fund]: """ Convenience method that returns an optional fund by its ID. :param fund_id: Fund's ID :type fund_id: str :return: Found instance or none. :rtype: Optional[Fund] """ result = None try: result = FundModel.objects.get(id=fund_id).to_fund() except cls.DoesNotExist: pass return result
[docs] @classmethod def get_funds( cls, filter_by: FundFilterBy = FundFilterBy.NO_FILTER ) -> Iterator[Fund]: """ Returns an enumeration of funds available using the filtering policy passed. :param filter_by: Filtering policy :type filter_by: FundFilterBy :return: Lazy enumeration of funds available. :rtype: Iterator[Fund] """ criteria = Q() if filter_by != FundFilterBy.NO_FILTER: if filter_by == FundFilterBy.DONATABLE: criteria = Q(donatable=True) elif filter_by == FundFilterBy.NON_DONATABLE: criteria = Q(donatable=False) yield from map(lambda f: f.to_fund(), cls.objects(criteria))
def __str__(self) -> str: return 'FundModel({model})'.format(model=str(self.to_fund())) def __repr__(self) -> str: return str(self)