def yield_all_perms(): class ABase(with_metaclass(ABaseMeta, object)):
    """abstract base class which introduces a nice constructor for the model classes."""

    def __init__(self, *args, **kw):
        """ create a model object.

        pass attributes by using named parameters, e.g. name="foo", value=123
        """

        for k, v in kw.items():
            setattr(self, k, v)

    def __str__(self):
        if hasattr(self, "__unicode__"):
            return self.__unicode__()

    def __getitem__(self, key):
        return getattr(self,key)

    def __setitem__(self, key, item):
        return setattr(self,key,item) def exists_by_expr(t, expr):
    # TODO: use exists instead of count
    q = select([func.count("*").label("c")], from_obj=t).where(expr)
    r = meta.DBSession.execute(q).fetchone()
    if r.c > 0:
        return True
    else:
        return False def calc_distance(latlong1, latlong2):
    """generates a sqlalchemy expression for distance query in km

       :param latlong1: the location from which we look for rows, as tuple (lat,lng)

       :param latlong2: the columns containing the latitude and longitude, as tuple (lat,lng)
    """

    # explain: http://geokoder.com/distances

    # return func.sqrt(func.pow(69.1 * (latlong1[0] - latlong2[0]),2)
    #               + func.pow(53.0 * (latlong1[1] - latlong2[1]),2))

    return func.sqrt(func.pow(111.2 * (latlong1[0] - latlong2[0]), 2)
                     + func.pow(111.2 * (latlong1[1] - latlong2[1]) * func.cos(latlong2[0]), 2)) def coords(row):
    return (row["lat"], row["lng"]) def update_connection():
    session = meta.DBSession() if callable(meta.DBSession) else meta.DBSession
    mark_changed(session)
    return session def init_caches():
def clear_all_caches(): def get_settings():
    global _settings
    return _settings def dt_now():
    return datetime.datetime.utcnow().replace(tzinfo=pytz.utc) def dt_ago(**kw):
    return datetime.datetime.utcnow().replace(tzinfo=pytz.utc) - datetime.timedelta(**kw) def dt_in(**kw):
    return datetime.datetime.utcnow().replace(tzinfo=pytz.utc) + datetime.timedelta(**kw) def normalize_key(key):
    return '' if key is None else str(key) def rowproxy2dict(rp):
    return {k: v for k, v in dict(rp).items() if not str(k).startswith("_")} def seconds_until_end_of_day(timezone):
    tzobj = pytz.timezone(timezone)
    now = datetime.datetime.now(tzobj)
    today = now.replace(hour=0, minute=0, second=0, microsecond=0)
    tomorrow = today + datetime.timedelta(days=1)
    return int((tomorrow - today).total_seconds()) class MySession(Session):
    def commit(self,*args,**kw):
    def rollback(self, *args, **kw):
def get_sessionmaker(bind=None):
def init_session(override_session=None, replace=False):
def init_declarative_base(override_base=None):
def init_db(engine): def evaluate_condition(inst, column_variable=None, column_key=None):
    try:
        if isinstance(inst,str):
            inst = json.loads(inst)
        from gengine.app.model import t_values, t_variables
        if column_variable is None:
            column_variable = t_variables.c.name.label("variable_name")
        if column_key is None:
            column_key = t_variables.c.name.label("variable_name")

        jsonschema.validate(inst, TermDocument.get_schema())
        return _term_eval(inst["term"], column_variable, column_key)
    except:
       raise FormularEvaluationException(json.dumps(inst)) def evaluate_value_expression(expression, params={}):
    if expression is None:
        return None
    try:
        nsp = NumericStringParser(extra_literals=params.keys())
        return nsp.eval(expression,key_value_map=params)
    except:
        raise FormularEvaluationException(expression) def evaluate_string(inst, params=None):
    try:
        if inst is None:
            return None
        if params is not None:
            formatted = render_string(inst, params)
        else:
            formatted = inst

        try:
            if str(int(formatted)) == str(formatted):
                return int(formatted)
        except:
            pass

        try:
            if str(int(float)) == str(float):
                return float(formatted)
        except:
            pass

        return formatted
    except:
        raise FormularEvaluationException(inst)
import datetime
import logging
import hashlib
import pytz
import sqlalchemy.types as ty
import sys
            import argon2
            import crypt
            import base64
        import argon2
        import base64
        import crypt
from collections import defaultdict
from datetime import timedelta
from dateutil import relativedelta
from sqlalchemy.dialects.postgresql import JSON
from pyramid.settings import asbool
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.sql.ddl import DDL
from sqlalchemy.sql.schema import UniqueConstraint, Index
from sqlalchemy.sql.sqltypes import Integer, String
from gengine.app.permissions import perm_global_increase_value
from gengine.base.model import ABase, exists_by_expr, calc_distance, coords, update_connection
from gengine.app.cache import cache_general, cache_achievements_subjects_levels, \
    cache_achievements_by_subject_for_today, cache_translations
from sqlalchemy import (
    Table,
    ForeignKey,
    func,
    select,
    and_,
    or_,
    text,
    Column
, event)
from sqlalchemy.dialects.postgresql import TIMESTAMP
from sqlalchemy.orm import (
    mapper,
    relationship as sa_relationship,
    backref as sa_backref
)
from sqlalchemy.sql import bindparam
from gengine.base.settings import get_settings
from gengine.base.util import dt_now, dt_ago, dt_in, normalize_key, rowproxy2dict, seconds_until_end_of_day
from gengine.metadata import Base, DBSession
from gengine.app.formular import evaluate_condition, evaluate_value_expression, evaluate_string
        from gengine.app.leaderboard import RelationsLeaderBoardSubjectSet, GlobalLeaderBoardSubjectSet, \
            ContextSubjectLeaderBoardSubjectSet
        from gengine.app.push import send_push_message

class AchievementDate:
    def __init__(self, from_date, to_date):
        self.from_date = from_date
        self.to_date = to_date

    def __repr__(self):
        return "AchievementDate(%s, %s)" % (str(self.from_date), str(self.to_date))

    def __str__(self):
        return self.from_date.isoformat()

    def __json__(self, *args, **kw):
        return self.from_date.isoformat()

    def __lt__(self, other):
        return AchievementDate.db_format(self) < AchievementDate.db_format(other)

    @classmethod
    def db_format(cls, instance):
        return instance.from_date if instance else None

    @classmethod
    def compute(cls, evaluation_timezone, evaluation_type, evaluation_shift, context_datetime):
        """
            This computes the datetime to identify the time of the achievement.
            Only relevant for repeating achievements (monthly, yearly, weekly, daily)
            Returns None for all other achievement types
        """

        if evaluation_type and not evaluation_timezone:
            evaluation_timezone = "UTC"

        tzobj = pytz.timezone(evaluation_timezone)
        if not context_datetime:
            dt = datetime.datetime.now(tzobj)
        else:
            dt = context_datetime.astimezone(tzobj)

        from_date = dt
        to_date = dt
        if evaluation_type == "yearly":
            if evaluation_shift:
                from_date = tzobj.localize((from_date.replace(tzinfo=None) - datetime.timedelta(seconds=evaluation_shift)))
            from_date = from_date.replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0)
            if evaluation_shift:
                from_date = tzobj.localize((from_date.replace(tzinfo=None) + datetime.timedelta(seconds=evaluation_shift)))
            to_date = from_date + relativedelta.relativedelta(years=1)
        elif evaluation_type == "monthly":
            if evaluation_shift:
                from_date = tzobj.localize((from_date.replace(tzinfo=None) - datetime.timedelta(seconds=evaluation_shift)))
            from_date = from_date.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
            if evaluation_shift:
                from_date = tzobj.localize((from_date.replace(tzinfo=None) + datetime.timedelta(seconds=evaluation_shift)))
            to_date = from_date + relativedelta.relativedelta(months=1)
        elif evaluation_type == "weekly":
            if evaluation_shift:
                from_date = tzobj.localize((from_date.replace(tzinfo=None) - datetime.timedelta(seconds=evaluation_shift)))
            from_date = from_date - datetime.timedelta(days=from_date.weekday())
            from_date = from_date.replace(hour=0, minute=0, second=0, microsecond=0)
            if evaluation_shift:
                from_date = tzobj.localize((from_date.replace(tzinfo=None) + datetime.timedelta(seconds=evaluation_shift)))
            to_date = from_date + relativedelta.relativedelta(weeks=1)
        elif evaluation_type == "daily":
            if evaluation_shift:
                from_date = tzobj.localize((from_date.replace(tzinfo=None) - datetime.timedelta(seconds=evaluation_shift)))
            from_date = from_date.replace(hour=0, minute=0, second=0, microsecond=0)
            if evaluation_shift:
                from_date = tzobj.localize((from_date.replace(tzinfo=None) + datetime.timedelta(seconds=evaluation_shift)))
            to_date = from_date + relativedelta.relativedelta(days=1)
        elif evaluation_type == "immediately":
            return None
        elif evaluation_type == "end":
            return None

        return AchievementDate(
            from_date = from_date.astimezone(tzobj),
            to_date = to_date.astimezone(tzobj)
        )



class Achievement(ABase):
    """A collection of goals which has multiple :class:`AchievementProperty` and :class:`Reward`."""

    def __unicode__(self, *args, **kwargs):
        return self.name + " (ID: %s)" % (self.id,)

    @classmethod
    def is_leaderboard(cls, achievement):
        return achievement["goal"] is None

    @classmethod
    @cache_general.cache_on_arguments()
    def get_achievement(cls,achievement_id):
        achievement = rowproxy2dict(DBSession.execute(t_achievements.select().where(t_achievements.c.id == achievement_id)).fetchone())
        compared_subjecttypes = [x["id"] for x in DBSession.execute(t_achievement_compared_subjecttypes.select().where(t_achievement_compared_subjecttypes.c.achievement_id == achievement_id)).fetchall()]
        domain_subjects = [x["id"] for x in DBSession.execute(t_achievement_compared_subjecttypes.select().where(t_achievement_compared_subjecttypes.c.achievement_id == achievement_id)).fetchall()]

        achievement['compared_subjecttypes'] = compared_subjecttypes
        achievement['domain_subjects'] = domain_subjects

        return achievement

    @classmethod
    def get_achievements_by_subject_for_today(cls,subject):
        """Returns all achievements that are relevant for the subject today.

        This is needed as achievements may be limited to a specific time (e.g. only during holidays)
        """

        def generate_achievements_by_subject_for_today():
            today = datetime.date.today()

            by_loc =  cls.get_achievements_by_location(coords(subject))
            by_date = cls.get_achievements_by_date(today)

            return {x["id"]: x for x in by_loc+by_date}.values()

        key = str(subject["id"])

        expiration_time = seconds_until_end_of_day(subject["timezone"])