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
                WHERE ss.subject_id = :subject_id AND """+(datestr % {'ss': 'ss'})+"""
            UNION ALL
                SELECT g2.id, g2.name, ss2.part_of_id, p.depth + 1 AS depth,
                    (p.path || '->' || g2.id ::TEXT)
                FROM nodes_cte AS p
                LEFT JOIN subjects_subjects AS ss2 ON ss2.subject_id=p.subject_id
                LEFT JOIN subjects AS g2 ON ss2.part_of_id = g2.id
                WHERE """+(datestr % {'ss': 'ss2'})+"""
            ) SELECT * FROM nodes_cte
        """).bindparams(subject_id=subject_id, from_date=from_date, to_date=to_date).columns(subject_id=Integer, name=String, part_of_id=Integer, depth=Integer, path=String).alias()

        j = t_subjects.join(sq, sq.c.subject_id == t_subjects.c.id)

        q = select([
            sq.c.path.label("subject_path"),
            sq.c.subject_id.label("subject_id"),
            sq.c.part_of_id.label("part_of_id"),
            sq.c.name.label("subject_name"),
            t_subjects.c.subjecttype_id.label("subjecttype_id")
        ], from_obj=j)

        if of_type_id is not None:
            q = q.where(t_subjects.c.subjecttype_id == of_type_id)

        rows = DBSession.execute(q).fetchall()
        groups = {r["part_of_id"]: r for r in rows if r["part_of_id"]}
        return groups

    @classmethod
    def get_descendent_subjects(cls, subject_id, of_type_id, from_date, to_date, whole_time_required):
        if whole_time_required:
            datestr = "(%(ss)s.joined_at<=:from_date AND (%(ss)s.left_at IS NULL OR %(ss)s.left_at >= :to_date))"
        else:
            datestr = "((%(ss)s.joined_at<=:from_date AND (%(ss)s.left_at IS NULL OR %(ss)s.left_at >= :from_date))" \
                      "OR (%(ss)s.joined_at >= :from_date AND %(ss)s.joined_at <= :to_date)" \
                      "OR (%(ss)s.left_at >= :from_date AND %(ss)s.left_at <= :to_date))"

        sq = text("""
            WITH RECURSIVE nodes_cte(subject_id, name, part_of_id, depth, path) AS (
                SELECT g1.id, g1.name, NULL::bigint as part_of_id, 1::INT as depth, g1.id::TEXT as path
                FROM subjects as g1
                LEFT JOIN subjects_subjects ss ON ss.subject_id=g1.id
                WHERE ss.part_of_id = :subject_id AND """+(datestr % {'ss': 'ss'})+"""
            UNION ALL
                SELECT c.subject_id, g2.name, c.part_of_id, p.depth + 1 AS depth,
                    (p.path || '->' || g2.id ::TEXT)
                FROM nodes_cte AS p, subjects_subjects AS c
                JOIN subjects AS g2 ON g2.id=c.subject_id
                WHERE c.part_of_id = p.subject_id AND """+(datestr % {'ss': 'c'})+"""
            ) SELECT * FROM nodes_cte
        """).bindparams(subject_id=subject_id, from_date=from_date, to_date=to_date).columns(subject_id=Integer, name=String, part_of_id=Integer, depth=Integer, path=String).alias()

        j = t_subjects.join(sq, sq.c.subject_id == t_subjects.c.id)

        q = select([
            sq.c.path.label("subject_path"),
            sq.c.subject_id.label("subject_id"),
            sq.c.name.label("subject_name"),
            t_subjects.c.subjecttype_id.label("subjecttype_id")
        ], from_obj=j)

        if of_type_id is not None:
            q = q.where(t_subjects.c.subjecttype_id == of_type_id)

        rows = DBSession.execute(q).fetchall()
        subjects = {r["subject_id"]: r for r in rows if r["subject_id"]}
        return subjects

    @classmethod
    def join_subject(cls,
                     subject_id,
                     part_of_id,
                     join_date):

        q = t_subjects_subjects.insert().values({
            'subject_id': subject_id,
            'part_of_id': part_of_id,
            'joined_at': join_date
        })

        update_connection().execute(q)

    @classmethod
    def leave_subject(cls,
                      subject_id,
                      part_of_id,
                      leave_date):

        q = t_subjects_subjects.update().values({
            'left_at': leave_date
        }).where(and_(
            t_subjects_subjects.c.subject_id == subject_id,
            t_subjects_subjects.c.part_of_id == part_of_id,
        ))

        update_connection().execute(q)


class SubjectType(ABase):
    def __unicode__(self, *args, **kwargs):
        return "(ID: %s; Name: %s)" % (self.id, self.name)

    @classmethod
    def basic_output(cls, subjecttype):
        return {
            "id": subjecttype["id"],
            "name": subjecttype["name"],
        }

class Variable(ABase):
    """A Variable is anything that should be meassured in your application and be used in :class:`.Goal`.

       To save database rows, variables may be grouped by time:
       group needs to be set to "year","month","day","timeslot" or "none" (default)
    """

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

    @classmethod

    @cache_general.cache_on_arguments()