def dateobj_to_int(dateobj):
    return int(dateobj.strftime(date_fmtstr)) def int_to_dateobj(dateint):
    return datetime.strptime(str(dateint), date_fmtstr).date() ONE_DAY = timedelta(days=1) class RawSQL(object):
    def __init__(self, sql):
    def sql(self):
def _parse_cond(conds):
def __parse_cond(cond):
def ___parse_cond(cond):
def expand_cond(cond):
def _parse_comp_cond(cond, forcelimit=None):
def _strify(st):
def _encode(obj):
def _encode_name(identifier):
def _parse_extras(kwargs):
def _mk_multi_return(row, cols, coldict):
def _execute(sql, write=False, ret='fetch'):
def _done(commit=True):
def fetch_info(info):
def fetch_onerow(table, coldict, conds, **kwargs):
def fetch_oneentry(table, col, conds, **kwargs):
def fetch_onecol(table, col, conds, **kwargs):
def fetch_multirow(table, coldict, conds, **kwargs):
def insert_row(table, insert):
def insert_or_update_row(table, insert, update):
def update_row(table, update, conds):
def delete_rows(table, conds): class BaseObject(object):
    __metaclass__ = _BaseMetaclass

    @property
    def id(self):
        """ID of the object."""
        if not self.is_real:
            raise NotImplementedError
        return self._id

    @property
    def is_real(self):
        """
        Whether the object is temporary object (False) or permanent (True).
        """
        return self._id > 0

    @classmethod
    def new(cls):
        """Returns a new temporary object for creation."""
        return cls(0)

    def __eq__(self, other):
        if not isinstance(other, BaseObject):
            return NotImplemented
        try:
            return self.id == other.id
        except NotImplementedError:
            return NotImplemented

    def __ne__(self, other):
        if not isinstance(other, BaseObject):
            return NotImplemented
        try:
            return self.id != other.id
        except NotImplementedError:
            return NotImplemented

    def __hash__(self):
        return hash(self.id) class Property(object):
    """
    Represent a value in the specified column of the current table.

    Selection is done by the id of the owner object match the value in the
    identifier column in the current table.

    :param basestring dbname: column name in relational database
    :param ie: import/export method
    :type ie: a single value of, or a tuple with two values of,
        None, NotImplemented, basestring, a serializer module, BaseObject,
        Enum, or callable
    :param bool search: whether the column should be searchable
    :param bool rediscached: whether the column should be cached on Redis
    :param bool search_require_true: if True, the object will only be
        searchable if this column evaluates to True
    :param error_default: if not Ellipsis, when the importing fails,
        import this value as a fallback; else raise the error
    """
    def __init__(prop, dbname, ie=None, search=False, rediscached=False,
                 search_require_true=False, error_default=Ellipsis):
        super(Property, prop).__init__()
        prop.dbname = dbname
        prop.imp, prop.exp = _get_ie(ie)
        prop.search = _get_search(search, ie)
        prop.rediscached = rediscached
        prop.search_require_true = search_require_true
        prop.error_default = error_default

    def __get__(prop, self, owner=None):
        if self is None:
            return prop
        if prop.name not in self._cache:
            if prop.rediscached:
                cache = redis.RedisCache(
                    prop._get_redis_key(self), REDIS_CACHE_TIME)
                if not cache.new:
                    data = cache.get()
                else:
                    data = self._data[prop.name]
                    cache.set(data)
            else:
                data = self._data[prop.name]

            try:
                value = prop.imp(data)
            except Exception:
                if prop.error_default is not Ellipsis:
                    value = prop.imp(prop.error_default)
                else:
                    raise
            self._cache[prop.name] = value
        return self._cache[prop.name]

    def __set__(prop, self, value):
        # Proxies can't pass isinstance check
        try:
            value = value._get_current_object()
        except AttributeError:
            pass

        # Make strings simple
        try:
            value = value.strip()
        except AttributeError:
            pass

        self._cache[prop.name] = value

        dbvalue = prop.exp(value)
        if self.is_real:
            if self._dbdata is None:
                self._data
            if dbvalue == self._dbdata[prop.name]:
                return

            self._dbdata[prop.name] = dbvalue

            database.update_row(
                self.table,
                {prop.dbname: dbvalue},
                {self.identifier: self.id}
            )

            # multiple search_require_true support is done in _escreate
            if prop.search_require_true:
                if value:
                    self._escreate()
                else:
                    elasticsearch.delete(self.table, self.id)

            if prop.search and self._es_requirement_good():
                elasticsearch.update(
                    self.table,
                    self.id,
                    {prop.name: prop.search(value)}
                )

            if prop.rediscached:
                cache = redis.RedisCache(
                    prop._get_redis_key(self), REDIS_CACHE_TIME)
                cache.set(dbvalue)
        else:
            self._dbdata = self._dbdata or {}
            self._dbdata[prop.name] = dbvalue

    def __delete__(prop, self):
        if prop.name in self._cache:
            del self._cache[prop.name]

        if self.is_real:
            self._dbdata = None
        else:
            if prop.name in self._dbdata:
                del self._dbdata[prop.name]

    def _get_redis_key(prop, self):
        return ':'.join(['cache', self.table, str(self.id), prop.name]) def paged_db_read(func):
    """Decorator function to have a database read with paging abilities."""
    def get_pager(limit):
        tempstorage = type(b'tempstorage', (object,), {})

        def pager_fetch(*args, **kwargs):
            f, table, cols, conds = args
            conds = database.expand_cond(conds)
            if limit:
                conds['limit'] = limit

            ret = f(table, cols, conds, _calc_found=True, **kwargs)

            tempstorage.count = database.fetch_info(
                database.RawSQL('FOUND_ROWS()'))

            return ret

        def pager_return(data):
            if limit:
                return tempstorage.count, data

            return data

        return pager_fetch, pager_return

    @wraps(func)
    def decorated_function(*args, **kwargs):
        return func(pager=get_pager(kwargs.pop('limit', None)),
                    *args, **kwargs)

    return decorated_function class Building(Enum):
    """Enum for buildings for classroom reservation."""
    XMT = 1
    ZTB = 2

    @property
    def format_name(self):
        """Formats the value of the enum for display."""
        return ['', 'XMT', 'ZTB'][self.value] class ActivityTime(Enum):
    """Enum regarding the time of an activity."""
    UNKNOWN = 0
    NOON = 1
    AFTERSCHOOL = 2
    HONGMEI = 3
    OTHERS = 4

    @property
    def format_name(self):
        """Formats the value of the enum for display."""
        return ['N/A', 'Lunch', 'Afterschool', 'HongMei',
                'Other'][self.value] class SBAppStatus(Enum):
    """Enum for smartboard application statuses"""
    PENDING = 0
    APPROVED = 1
    REJECTED = 2
    NA = 3

    @property
    def format_name(self):
        return ['Pending', 'Approved', 'Rejected', 'N/A'][self.value] class ResStatus(Enum):
    """Enum for status of reservations."""
    UNPAIRED = 1
    PAIRED = 2
    TEACHER = 3
from datetime import date, timedelta
from oclubs.utils.dates import dateobj_to_int, int_to_dateobj, ONE_DAY
from oclubs.access import database
from oclubs.objs.base import BaseObject, Property, paged_db_read
from oclubs.enums import Building, ActivityTime, SBAppStatus, ResStatus
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#

from __future__ import absolute_import, unicode_literals, division




class Reservation(BaseObject):
    table = 'reservation'
    identifier = 'res_id'
    activity = Property('res_activity', 'Activity')  # for club reservations
    # the date for when the reservation is effective
    date = Property('res_date', (int_to_dateobj, dateobj_to_int))
    # the date for when the reservation was created
    date_of_reservation = Property('res_date_of_res',
                                   (int_to_dateobj, dateobj_to_int))

    timeslot = Property('res_timeslot', ActivityTime)