def init_engine(uri, **kwargs): class AccountsTable(Base):
    """Represents a user's account to/from which to add/deduct monies"""

    __tablename__ = 'accounts'
    id = Column(Integer, primary_key=True)
    user = Column('user_id', Integer, ForeignKey('users.id'))
    name = Column(String(100))
    type = Column(String(100))
    balance = Column(Float(precision=2))
    slug = Column(String(100))

    def __init__(self, user=None, name=None, type=None, balance=None):
        self.user = user
        self.name = name
        self.type = type
        self.balance = balance
        # save slug on "normal" accounts
        self.slug = slugify(name) if type == 'asset' or type == 'liability' else None class AccountTransfersTable(Base):
    """A transfer to/from the account"""

    __tablename__ = 'account_transfers'
    id = Column(Integer, primary_key=True)
    user = Column('user_id', Integer, ForeignKey('users.id'))
    date = Column(Integer)
    from_account = Column('from_id', Integer, ForeignKey('accounts.id'))
    to_account = Column('to_id', Integer, ForeignKey('accounts.id'))
    amount = Column(Float(precision=2))

    def __init__(self, user=None, date=None, from_account=None, to_account=None, amount=None):
        self.user = user
        self.date = date
        self.from_account = from_account
        self.to_account = to_account
        self.amount = amount class Accounts(object):

    object = None

    def __init__(self, user_id, user_type=None):
        # determine user type
        if not user_type:
            user_type = 'private' if UsersTable.query\
            .filter(and_(UsersTable.id == user_id, UsersTable.is_private == True)).first() else 'normal'
        if user_type == 'normal':
            self.object = NormalUserAccounts(user_id)
        else:
            self.object = PrivateUserAccounts(user_id)

    def __getattr__(self, name):
        print "calling: ", name, ' on ', self.object
        return getattr(self.object, name) class ExpenseCategoriesTable(Base):
    """Expense category of a user"""

    __tablename__ = 'expense_categories'
    id = Column(Integer, primary_key=True)
    user = Column('user_id', Integer, ForeignKey('users.id'))
    name = Column(String(50))
    slug = Column(String(50))

    def __init__(self, user=None, name=None):
        self.user = user
        self.name = name
        self.slug = slugify(name) class ExpensesTable(Base):
    """Listing of expenses of various users"""

    __tablename__ = 'expenses'
    id = Column(Integer, primary_key=True)
    user = Column('user_id', Integer, ForeignKey('users.id'))
    date = Column(Integer)
    category = Column('category_id', Integer, ForeignKey('expense_categories.id'))
    description = Column(String(50))
    deduct_from = Column('account_id', Integer, ForeignKey('accounts.id'))
    amount = Column(Float(precision=2))
    pass_thru = Column(Boolean)

    def __init__(self, user=None, date=None, category=None, description=None, deduct_from=None, amount=None, pass_thru=None):
        self.user = user
        self.date = date
        self.category = category
        self.description = description
        self.deduct_from = deduct_from
        self.amount = amount
        self.pass_thru = pass_thru class ExpensesToLoansTable(Base):
    """Linking shared expenses together"""

    __tablename__ = 'expenses_to_loans'
    id = Column(Integer, primary_key=True)
    expense = Column('expense_id', Integer, ForeignKey('expenses.id'))
    loan = Column('loan_id', Integer, ForeignKey('loans.id'))
    shared_with = Column('shared_with_user_id', Integer, ForeignKey('users.id')) # shortcut
    percentage = Column(Float(precision=2))
    original_amount = Column(Float(precision=2))

    def __init__(self, expense=None, loan=None, shared_with=None, percentage=None, original_amount=None):
        self.expense = expense
        self.loan = loan
        self.shared_with = shared_with
        self.percentage = percentage
        self.original_amount = original_amount class Expenses(object):

    object = None

    def __init__(self, user_id, user_type=None):
        # determine user type
        if not user_type:
            user_type = 'private' if UsersTable.query\
            .filter(and_(UsersTable.id == user_id, UsersTable.is_private == True)).first() else 'normal'
        if user_type == 'normal':
            self.object = NormalUserExpenses(user_id)
        else:
            self.object = PrivateUserExpenses(user_id)

    def __getattr__(self, name):
        print "calling: ", name, ' on ', self.object
        return getattr(self.object, name) class IncomeTable(Base):
    """Listing of incomes of various users"""

    __tablename__ = 'income'
    id = Column(Integer, primary_key=True)
    user = Column('user_id', Integer, ForeignKey('users.id'))
    date = Column(Integer)
    category = Column('category_id', Integer, ForeignKey('income_categories.id'))
    description = Column(String(50))
    credit_to = Column('account_id', Integer, ForeignKey('accounts.id'))
    amount = Column(Float(precision=2))

    def __init__(self, user=None, date=None, category=None, description=None, credit_to=None, amount=None):
        self.user = user
        self.date = date
        self.category = category
        self.description = description
        self.credit_to = credit_to
        self.amount = amount class IncomeCategoriesTable(Base):
    """Income category of a user"""

    __tablename__ = 'income_categories'
    id = Column(Integer, primary_key=True)
    user = Column('user_id', Integer, ForeignKey('users.id'))
    name = Column(String(50))
    slug = Column(String(50))

    def __init__(self, user=None, name=None):
        self.user = user
        self.name = name
        self.slug = slugify(name) class LoansTable(Base):
    """A loan entry for the user
    A loan between two users will correspond to two loan entries where the direction of transfer
    is signified by the positive (user to other_user)/negative (other_user to user)
    """

    __tablename__ = 'loans'
    id = Column(Integer, primary_key=True)
    user = Column('user_id', Integer, ForeignKey('users.id'))
    other_user = Column('other_user_id', Integer, ForeignKey('users.id'))
    date = Column(Integer)
    account = Column('account_id', Integer, ForeignKey('accounts.id'))
    description = Column(String(50))
    amount = Column(Float(precision=2))

    def __init__(self, user=None, other_user=None, date=None, account=None, description=None, amount=None):
        self.user = user
        self.other_user = other_user
        self.date = date
        self.account = account
        self.description = description
        self.amount = amount class Totals():
    '''Totals for a given user'''

    user = None

    def __init__(self, user):
        self.user = user

    def get_totals(self, wayback=5):
        # generate today's month/year string
        m = MonthYear("today")

        # generate a list of month/year strings
        l = [m.substract(x) for x in range(wayback)]

        # pass it as an IS IN query to totals and return
        return TotalsTable.query\
        .filter(and_(TotalsTable.user == self.user, TotalsTable.month.in_(l)))\
        .order_by(asc(TotalsTable.id)).all()

    def update_expense(self, amount, date):
        # generate a month/year string
        m = MonthYear(date)

        # get the corresponding entry
        t = TotalsTable.query\
        .filter(and_(TotalsTable.user == self.user, TotalsTable.month == str(m))).first()

        if not t:
            # brand spanking new
            t = TotalsTable(self.user, str(m), amount, 0)
        else:
            # update the total
            t.expenses += float(amount)

        # save
        db_session.add(t)
        db_session.commit()

    def update_income(self, amount, date):
        # generate a month/year string
        m = MonthYear(date)

        # get the corresponding entry
        t = TotalsTable.query\
        .filter(and_(TotalsTable.user == self.user, TotalsTable.month == str(m))).first()

        if not t:
            # brand spanking new
            t = TotalsTable(self.user, str(m), 0, amount)
        else:
            # update the total
            t.income += float(amount)

        # save
        db_session.add(t)
        db_session.commit() class UsersTable(Base):
    """User account"""

    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    is_private = Column(Boolean)
    username = Column(String(20))
    password = Column(String(20))
    slug = Column(String(50))

    def __init__(self, name=None, is_private=None, username=None, password=None):
        self.name = name
        self.is_private = is_private
        self.username = username
        self.password = password
        self.slug = slugify(name) class UsersConnectionsTable(Base):
    """User connection"""

    __tablename__ = 'users_connections'
    id = Column(Integer, primary_key=True)
    from_user = Column('from_user_id', Integer, ForeignKey('users.id'))
    to_user = Column('to_user_id', Integer, ForeignKey('users.id'))

    def __init__(self, from_user=None, to_user=None):
        self.from_user = from_user
        self.to_user = to_user class UsersKeysTable(Base):
    """Key generated for a user to connect to"""

    __tablename__ = 'users_keys'
    id = Column(Integer, primary_key=True)
    user = Column('user_id', Integer, ForeignKey('users.id'))
    key = Column(String(50))
    expires = Column(Integer)

    def __init__(self, user=None):
        self.user = user
        # generate random key
        self.key = generate_random_key()
        # expire in 24 hours
        self.expires = tomorrow_timestamp() class Users():

    user_id = None
    connections = None

    def __init__(self, user_id):
        self.user_id = user_id

    def get_connections(self):
        if not self.connections:
            # fetch users from connections from us
            self.connections = UsersTable.query\
            .join((UsersConnectionsTable, (UsersTable.id == UsersConnectionsTable.to_user)))\
            .filter(UsersConnectionsTable.from_user == self.user_id)
        return self.connections

    def is_connection(self, name=None, user_id=None, slug=None):
        connections = self.get_connections()
        if name:
            for usr in connections:
                if usr.name == name:
                    return usr.id

        elif user_id:
            for usr in connections:
                if usr.id == int(user_id):
                    return usr.id

        elif slug:
            for usr in connections:
                if usr.slug == slug:
                    return usr.id

        return False

    def is_private(self, name=None, user_id=None, slug=None):
        connections = self.get_connections()
        if name:
            for usr in connections:
                if usr.name == name:
                    return True if usr.is_private else False

        elif user_id:
            for usr in connections:
                if usr.id == int(user_id):
                    return True if usr.is_private else False

        elif slug:
            for usr in connections:
                if usr.slug == slug:
                    return True if usr.is_private else False

        return False

    def add_private_user(self, name):
        u = UsersTable(name, True)
        db_session.add(u)
        db_session.commit()
        return u.id

    def add_connection(self, user_id):
        c = UsersConnectionsTable(self.user_id, user_id)
        db_session.add(c)
        c = UsersConnectionsTable(user_id, self.user_id)
        db_session.add(c)
        db_session.commit()

    def validate_key(self, key_value):
        k = UsersKeysTable.query\
        .filter(UsersKeysTable.key == key_value)\
        .filter(UsersKeysTable.expires > today_timestamp()).first()
        return k.user if k else None

    def get_key(self):
        k = UsersKeysTable.query\
        .filter(UsersKeysTable.user == self.user_id)\
        .filter(UsersKeysTable.expires > today_timestamp()).first()
        # generate key
        if not k:
            k = UsersKeysTable(self.user_id)
            db_session.add(k)
            db_session.commit()
        return k def slugify(value):
    import unicodedata, re

    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
    value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
    return re.sub('[-\s]+', '-', value)
from flask import Blueprint, session
from flask.helpers import make_response
from flask.templating import render_template
from db.database import db_session
from models.accounts import AccountsTable, AccountTransfersTable, Accounts
from models.expenses import ExpenseCategoriesTable, ExpensesTable, ExpensesToLoansTable, Expenses
from models.income import IncomeTable, IncomeCategoriesTable
from models.loans import LoansTable
from models.totals import Totals
from models.users import UsersTable, UsersConnectionsTable, UsersKeysTable, Users
from utils import slugify
#!/usr/bin/python
# -*- coding: utf -*-

# framework

# db

# models

# utils

tests = Blueprint('tests', __name__)

@tests.route('/test/create-user/<name>')
def create_user(name):
    '''A test module for creating users in the system'''

    name = name.lower()
    slug = slugify(name)
    u = UsersTable(name.capitalize(), False, slug, slug)
    db_session.add(u)
    db_session.commit()

    return make_response("User created", 200)

@tests.route('/test/get-key')
def get_key():
    '''Get a user key for a logged in user'''

    u = Users(session.get('logged_in_user'))
    # fetch/generate key
    key = u.get_key()

    return make_response(key.key, 200)

@tests.route('/test/wipe-tables')
def wipe_tables():
    '''Make a table cleanup in a database'''

    UsersTable.query.delete()
    UsersConnectionsTable.query.delete()
    UsersKeysTable.query.delete()
    LoansTable.query.delete()
    IncomeCategoriesTable.query.delete()
    IncomeTable.query.delete()
    ExpenseCategoriesTable.query.delete()
    ExpensesTable.query.delete()
    ExpensesToLoansTable.query.delete()

    AccountsTable.query.delete()