def send_email(self): if not authorized(ValidAuthKitUser()): return { "failure" : Messages.invalidSession() } try: to_address = request.params['to_address'] subject = request.params['subject'] body = request.params['body'] except: return { "failure" : Messages.invalidArguments() } if to_address == "" or subject == "" or body == "": return { "failure" : Messages.invalidArguments() } from email.MIMEText import MIMEText message = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') message['Subject'] = subject message['From'] = config['from_address'] message['To'] = to_address try: from fivecents.lib.mail import EmailSender ms = EmailSender(to_addresses = to_address) ms.send_mime(message) except Exception, e: return { "failure" : Messages.failedToSendEmail(exception=e) }
def category(self): dbFacade = self.dbFacade() result = {} category = dbFacade.balances.categoryDao.find_by_name(request.params.get('category')) if category is None: return { "failure": Messages.invalidArguments() } for id in request.params.getall('id'): try: item = dbFacade.balances.changeDao.find_by_uid(id, options=[eagerload('balance')]) if item is None: result[id] = { "deleted" : False, "message": Messages.elementNotFound(key=id) } continue if not item.balance or not item.balance.can_modify_balance(h.authenticated_user().uid): result[id] = { "deleted" : False, "message": Messages.permissionDenied() } continue item.category = category.name dbFacade.db.commit() result[id] = { "modified" : True } except Exception, e: result[id] = { "deleted" : False, "message" : Messages.failedToDelete(exception=e), }
def send_email(self): """ Will send an e-mail with to a given address. Only authenticated users can use it. """ if not authorized(ValidAuthKitUser()): return { "failure" : Messages.invalidSession() } to_address = request.params.get('to_address') subject = request.params.get('subject') body = request.params.get('body') if not to_address or not subject or not body: return { "failure" : Messages.invalidArguments() } from email.MIMEText import MIMEText message = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') message['Subject'] = subject message['From'] = config['from_address'] message['To'] = to_address try: self.emailSender().send_mime(to_address, config['from_address'], message) except Exception, e: return { "failure" : Messages.failedToSendEmail(exception=e) }
def send_invitation(self): model = self.get_sa_model() db = self.get_sa_session() if not authorized(ValidAuthKitUser()): return { "failure" : Messages.invalidSession() } to_address = request.params.get('to_address') body = request.params.get('body') if not to_address or not body: return { "failure" : Messages.invalidArguments() } invitation = db.query(model.Invitation).filter_by(to_address = to_address).filter_by(sender_uid=h.authenticated_user().uid).first() if invitation: invitation.message = body invitation.sent = False invitation.sent_on = datetime.today() else: invitation = model.Invitation( sender_uid = h.authenticated_user().uid, to_address = to_address, message = body ) db.save(invitation) db.commit() return { "success" : Messages.messageWasSent() }
def delete(self): model = self.get_sa_model() db = self.get_sa_session() result = {} for id in request.params.getall('id'): try: if not Operations(db, model).can_modify_balance(h.authenticated_user().uid, id): result[id] = { "deleted": False, "message": Messages.permissionDenied() } continue item = db.query(model.Balance).filter_by(uid=id).one() except InvalidRequestError: result[id] = { "deleted" : False, "message": Messages.elementNotFound(key=id) } continue try: db.delete(item) db.commit() result[item.uid] = { "deleted" : True, } except Exception, e: result[item.uid] = { "deleted" : False, "message" : Messages.failedToDelete(exception=e) }
def delete(self, balance_uid): model = request.environ['sqlalchemy.model'] db = request.environ['sqlalchemy.session'] if not Operations(db, model).can_modify_balance(h.authenticated_user().uid, balance_uid): return { "failure": Messages.permissionDenied() } result = {} for id in request.params.getall('id'): try: item = db.query(model.BalanceChange).filter_by(uid=id).filter_by(balance_uid=balance_uid).one() except InvalidRequestError: result[id] = { "deleted" : False, "message": Messages.elementNotFound(key=id) } continue else: try: Operations(db, model).delete_balance_change(item) result[item.uid] = { "deleted" : True, } except Exception, e: result[item.uid] = { "deleted" : False, "message" : Messages.failedToDelete(exception=e), }
def delete(self): dbFacade = self.dbFacade() result = {} for id in request.params.getall('id'): try: item = dbFacade.balances.balanceDao.find_by_uid(id) if not item or not item.can_modify_balance(h.authenticated_user().uid): result[id] = { "deleted": False, "message": Messages.permissionDenied() } continue except InvalidRequestError: result[id] = { "deleted" : False, "message": Messages.elementNotFound(key=id) } continue try: dbFacade.db.delete(item) dbFacade.db.commit() result[item.uid] = { "deleted" : True, } except Exception, e: result[item.uid] = { "deleted" : False, "message" : Messages.failedToDelete(exception=e) }
def delete(self): result = {} for id in request.params.getall('id'): try: item = self.dbFacade().balances.changeDao.find_by_uid(id, options=[eagerload('balance'), eagerload('transfer')]) if item is None: result[id] = { "deleted" : False, "message": Messages.elementNotFound(key=id) } continue if not item.balance or not item.balance.can_modify_balance(h.authenticated_user().uid) \ or (item.transfer and not item.transfer.balance) \ or (item.transfer and not item.transfer.balance.can_modify_balance(h.authenticated_user().uid)): result[id] = { "deleted" : False, "message": Messages.permissionDenied() } continue if item.transfer: self.dbFacade().db.delete(item.transfer) self.dbFacade().db.delete(item) self.dbFacade().db.commit() result[id] = { "deleted" : True } except Exception, e: result[id] = { "deleted" : False, "message" : Messages.failedToDelete(exception=e), }
def delete(self): db = self.get_sa_session() model = self.get_sa_model() result = {} for id in request.params.getall('id'): try: item = db.query(model.ChangeCategory).filter_by(uid=id).one() except InvalidRequestError: result[id] = { "deleted" : False, "message": Messages.elementNotFound(key=id) } continue if (db.query(model.BalanceChange).filter_by(change_category_uid=item.uid).count() > 0): result[item.uid] = { "deleted" : False, "message" : Messages.changeCategoryInUse(id=item.uid) } else: try: db.delete(item) db.commit() result[item.uid] = { "deleted" : True, } except Exception, e: result[item.uid] = { "deleted" : False, "message" : Messages.failedToDelete(exception=e), }
def delete(self): model = request.environ["sqlalchemy.model"] db = request.environ["sqlalchemy.session"] result = {} for id in request.params.getall('id'): try: item = db.query(model.IncomeCategory).filter_by(uid=id).one() except InvalidRequestError: result[id] = { "deleted" : False, "message": Messages.elementNotFound(key=id) } continue if (db.query(model.BalanceChange).filter_by(income_category_uid=item.uid).count() > 0): result[item.uid] = { "deleted" : False, "message" : Messages.incomeCategoryIsInUse(id=item.uid) } else: try: db.delete(item) db.commit() result[item.uid] = { "deleted" : True, } except Exception, e: result[item.uid] = { "deleted" : False, "message" : Messages.failedToDelete(exception=e) }
def add(self): model = request.environ["sqlalchemy.model"] db = request.environ["sqlalchemy.session"] try: name = request.params['name'] except: return { "failure": Messages.invalidArguments() } if name == "": return { "failure": Messages.invalidArguments() } try: user = db.query(model.AuthenticatedUser).filter_by(uid = h.authenticated_user().uid).one() balance = model.Balance(name = name,) user_balance = model.UserBalance(user_uid=h.authenticated_user().uid, writable=True) balance.users.append(user_balance) user.balances.append(user_balance) db.save(balance) # ensure we set writable to true (needed only with sqlite3) #ub = db.query(model.UserBalance).filter_by(user_uid=session[BaseController.AUTHENTICATED_USER], balance_uid=balance.uid).one() #ub.writable = True #db.save(ub) db.commit() except IntegrityError, e: return { "failure": Messages.primaryKeyViolation() }
def _list_by_category(self, balance_uid, expenses = True, incomes = True): model = request.environ['sqlalchemy.model'] db = request.environ['sqlalchemy.session'] try: user_uid = h.authenticated_user().uid except: return { "failure": Messages.pemissionDenied() } if not Operations(db, model).can_see_balance(user_uid, balance_uid): return { "failure": Messages.permissionDenied() } now = date.today() select_expenses = select( [model.ExpenseCategory.c.uid.label('uid'), model.ExpenseCategory.c.name.label('name'), func.sum(model.BalanceChange.c.amount).label('summary')], and_(model.BalanceChange.is_income==False, model.ExpenseCategory.uid==model.BalanceChange.expense_category_uid, model.BalanceChange.balance_uid==balance_uid, model.BalanceChange.occurred_on >= date(now.year, now.month, 1)), from_obj=[model.expense_categories_table, model.balance_changes_table], group_by=[model.ExpenseCategory.c.uid, model.ExpenseCategory.c.name]) select_incomes = select( [model.IncomeCategory.c.uid.label('uid'), model.IncomeCategory.c.name.label('name'), func.sum(model.BalanceChange.c.amount).label('summary')], and_(model.BalanceChange.is_income==True, model.IncomeCategory.uid==model.BalanceChange.income_category_uid, model.BalanceChange.balance_uid==balance_uid, model.BalanceChange.occurred_on >= date(now.year, now.month, 1)), from_obj=[model.income_categories_table, model.balance_changes_table], group_by=[model.IncomeCategory.c.uid, model.IncomeCategory.c.name]) if expenses and incomes: query = union(select_expenses, select_incomes) else: query = expenses and select_expenses or select_incomes balance_changes = db.execute(query.order_by('name')).fetchall() total = len(balance_changes) try: page_nr = request.params['page_nr'] except: page_nr = 1 try: items_per_page = int(request.params['items_per_page']) except: items_per_page = 15 subset = Page(balance_changes, item_count=total, current_page=page_nr, items_per_page=items_per_page) return { "totalItems" : total, "itemsFound" : len(subset), "items" : [{ "uid" : item.uid, "name" : item.name, "summary" : h.format_decimal(Decimal(item.summary))} for item in subset ] }
def delete(self): result = {} try: category_name = request.params.get('name') category_tc = self.dbFacade().balances.categoryDao.find_by_name(category_name, h.authenticated_user().uid) if category_tc is None: return { "failure" : Messages.elementNotFound(key=category_name) } parent = self.dbFacade().balances.categoryDao.find_by_key(category_tc.parent, h.authenticated_user().uid) self.dbFacade().db.delete(category_tc) self._change_changes_category(category_name, parent.name) self.dbFacade().db.commit() except Exception, e: return { "failure" : Messages.failedToDelete(exception=e) }
def add(self, balance_uid): model = request.environ['sqlalchemy.model'] db = request.environ['sqlalchemy.session'] balance = db.query(model.Balance).filter_by(uid = balance_uid).first() if not balance or not balance.can_modify_balance(h.authenticated_user().uid): return { "failure": Messages.permissionDenied() } try: with localcontext() as ctx: ctx.prec = 2 try: amount = h.parse_decimal(request.params['amount']) except: log.error("Invalid number: %s" % request.params.get('amount'), exc_info=1) return { "failure": Messages.invalidCurrencyFormat() } expense_date = h.parse_date(request.params['occurred_on']) income_category_uid = None expense_category_uid = None if (int(request.params['is_income']) >= 0): income_category_uid = int(request.params['income_category_uid']) is_income = True else: expense_category_uid = int(request.params['expense_category_uid']) is_income = False except: log.error("Failed to parse arguments %s" % str(request.params), exc_info=1) return { "failure": Messages.invalidArguments() } tags = request.params.get('tags', '') description = request.params.get('description', '') bc = model.BalanceChange( amount = amount, description = description, user_uid = h.authenticated_user().uid, expense_category_uid = expense_category_uid, occurred_on = expense_date, is_income = is_income, income_category_uid = income_category_uid ) balance.changes.append(bc) db.flush() ops = Operations(db, model) ops.change_tags_from_string(bc, tags) ops.save_balance_change(bc) return { "id" : bc.uid }
def add(self): model = request.environ["sqlalchemy.model"] db = request.environ["sqlalchemy.session"] name = request.params.get('name') if not name: return { "failure": Messages.invalidArguments() } try: ec = model.IncomeCategory(name = name,) db.save(ec) db.commit() except IntegrityError, e: return { "failure": Messages.primaryKeyViolation() }
def add(self, balance_uid): model = request.environ['sqlalchemy.model'] db = request.environ['sqlalchemy.session'] if not Operations(db, model).can_modify_balance(h.authenticated_user().uid, balance_uid): return { "failure": Messages.permissionDenied() } try: with localcontext() as ctx: ctx.prec = 2 try: amount = h.parse_decimal(request.params['amount']) except NumberFormatError: return { "failure": Messages.invalidCurrencyFormat() } expense_date = parser.parse(request.params['occurred_on']) income_category_uid = None expense_category_uid = None if (int(request.params['is_income']) >= 0): income_category_uid = int(request.params['income_category_uid']) is_income = True else: expense_category_uid = int(request.params['expense_category_uid']) is_income = False except: return { "failure": Messages.invalidArguments() } tags = request.params.get('tags', '') try: description = request.params['description'] except: description = "" try: bc = model.BalanceChange( amount = amount, description = description, balance_uid = balance_uid, user_uid = h.authenticated_user().uid, expense_category_uid = expense_category_uid, occurred_on = expense_date, is_income = is_income, income_category_uid = income_category_uid ) ops = Operations(db, model) ops.change_tags_from_string(bc, tags) ops.save_balance_change(bc) except IntegrityError, e: return { "failure": Messages.primaryKeyViolation() }
def add(self, balance_uid): dbFacade = DbFacade(request.environ['sqlalchemy.session'], request.environ['sqlalchemy.model']) balance = dbFacade.balances.balanceDao.find_by_uid(balance_uid) if not balance or not balance.can_modify_balance(h.authenticated_user().uid): return { "failure": Messages.permissionDenied() } try: with localcontext() as ctx: ctx.prec = 2 try: amount = h.parse_decimal(request.params['amount']) except: log.error("Invalid number: %s" % request.params.get('amount'), exc_info=1) return { "failure": Messages.invalidCurrencyFormat() } expense_date = h.parse_date(request.params['occurred_on']) income_category_uid = None expense_category_uid = None if (int(request.params['is_income']) >= 0): income_category_uid = int(request.params['income_category_uid']) is_income = True else: expense_category_uid = int(request.params['expense_category_uid']) is_income = False except: log.error("Failed to parse arguments %s" % str(request.params), exc_info=1) return { "failure": Messages.invalidArguments() } tags = request.params.get('tags', '') description = request.params.get('description', '') bc = dbFacade.model.BalanceChange( amount = amount, description = description, user_uid = h.authenticated_user().uid, expense_category_uid = expense_category_uid, occurred_on = expense_date, is_income = is_income, income_category_uid = income_category_uid ) bc.tags = dbFacade.balances.find_or_create_tags(balance, dbFacade.balances.elements_from_string(tags)) dbFacade.balances.add_balance_change(balance, bc) dbFacade.db.commit() return { "id" : bc.uid }
def list_tags(self, id): dbFacade = DbFacade(request.environ["sqlalchemy.session"], request.environ["sqlalchemy.model"]) balance = dbFacade.balances.balanceDao.find_by_uid(id) if not balance or not balance.can_modify_balance(h.authenticated_user().uid): return {"failure": Messages.permissionDenied()} query = request.params.get("query", None) if query: tags = balance.get_tags_starting_with(query) else: tags = balance.tags.order_by(dbFacade.model.BalanceTag.tag).all() total = len(tags) try: page_nr = int(request.params["page_nr"]) except: page_nr = 1 try: items_per_page = int(request.params["items_per_page"]) except: items_per_page = 15 subset = Page(tags, item_count=total, current_page=page_nr, items_per_page=items_per_page) return { "totalItems": total, "itemsFound": len(subset), "items": [{"uid": item.uid, "tag": item.tag} for item in subset], }
def _by_day(self, balance_uid, is_income): db = request.environ['sqlalchemy.session'] model = request.environ['sqlalchemy.model'] balance = db.query(model.Balance).filter_by(uid = balance_uid).first() if not balance or not balance.can_see_balance(h.authenticated_user().uid): return { "failure": Messages.permissionDenied() } conditions = [model.BalanceChange.c.balance_uid == balance_uid, model.BalanceChange.c.is_income == is_income] (start_date, end_date) = self._get_dates() if start_date: conditions.append(model.BalanceChange.c.occurred_on >= start_date) if end_date: conditions.append(model.BalanceChange.c.occurred_on <= end_date) dates = db.execute(select([func.sum(model.BalanceChange.c.amount).label('summary'), model.BalanceChange.c.occurred_on.label('date')], and_(*conditions), from_obj=[model.balance_changes_table], order_by=['date'], group_by=['date'])).fetchall() return { "totalItems" : len(dates), "itemsFound": len(dates), "items" : [{ "date" : item.date, "summary": item.summary} for item in dates ] }
def edit_many(self): model = request.environ["sqlalchemy.model"] db = request.environ["sqlalchemy.session"] modified = [] if not request.params.has_key("uids"): return {"failure": Messages.invalidArguments()} for uid in request.params.getall("uids"): try: if not Operations(db, model).can_modify_balance(h.authenticated_user().uid, uid): continue balance = db.query(model.Balance).filter_by(uid=uid).one() name = request.params["name_%s" % (uid)] if name == "": continue balance.name = name db.commit() modified.append({"uid": uid}) except: # if it fails just skip it and go for next continue return modified
def send_feedback(self): from_address = request.params.get('from_address') subject = _("Feedback about %s ") % h.site_name() body = request.params.get('body') if not from_address or not subject or not body: return { "failure" : Messages.invalidArguments() } from email.MIMEText import MIMEText message = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') message['Subject'] = subject message['From'] = from_address message['To'] = config['email_to'] try: self.emailSender().send_mime(config['email_to'], from_address, message) except Exception, e: return { "failure" : Messages.failedToSendEmail(exception=e) }
def add(self): db = self.get_sa_session() model = self.get_sa_model() try: name = request.params['name'] except: return { "failure": Messages.invalidArguments() } if name == "": return { "failure": Messages.invalidArguments() } try: ec = model.ChangeCategory(name = name,) db.save(ec) db.commit() except IntegrityError, e: return { "failure": Messages.primaryKeyViolation() }
def add(self): db = request.environ['sqlalchemy.session'] model = request.environ['sqlalchemy.model'] try: name = request.params['name'] except: return { "failure": Messages.invalidArguments() } if name == "": return { "failure": Messages.invalidArguments() } try: ec = model.ExpenseCategory(name = name,) db.save(ec) db.commit() except IntegrityError, e: return { "failure": Messages.primaryKeyViolation() }
def add(self): model = request.environ["sqlalchemy.model"] db = request.environ["sqlalchemy.session"] name = request.params.get("name") if not name: return {"failure": Messages.invalidArguments()} try: user = db.query(model.AuthenticatedUser).filter_by(uid=h.authenticated_user().uid).one() balance = model.Balance(name=name) user_balance = model.UserBalance(user_uid=h.authenticated_user().uid, writable=True) balance.users.append(user_balance) user.balances.append(user_balance) db.save(balance) db.commit() except IntegrityError, e: return {"failure": Messages.primaryKeyViolation()}
def list(self, balance_uid): model = request.environ['sqlalchemy.model'] db = request.environ['sqlalchemy.session'] balance = db.query(model.Balance).filter_by(uid = balance_uid).first() if not balance or not balance.can_see_balance(h.authenticated_user().uid): return { "failure": Messages.permissionDenied() } qr = balance.changes \ .options(eagerload('expense_category'), eagerload('income_category'), eagerload('tags')) \ .order_by(model.BalanceChange.occurred_on) (start_date, end_date) = self._get_dates() if start_date: qr = qr.filter(model.BalanceChange.occurred_on >= start_date) if end_date: qr = qr.filter(model.BalanceChange.occurred_on <= end_date) balance_changes = qr.all() total = len(balance_changes) try: page_nr = int(request.params['page_nr']) except: page_nr = 1 try: items_per_page = int(request.params['items_per_page']) except: items_per_page = 15 subset = Page(balance_changes, item_count=total, current_page=page_nr, items_per_page=items_per_page) return { "summary" : { "total" : self._total(balance_uid), "date_range" : { "expenses" : self._expenses_for_date_range(balance_uid, start_date, end_date), "incomes" : self._incomes_for_date_range(balance_uid, start_date, end_date), }, }, "changes": { "totalItems" : total, "itemsFound" : len(subset), "items" : [{ "uid" : item.uid, "category_uid" : item.is_income and item.income_category_uid or item.expense_category_uid, "category" : (item.is_income and item.income_category or item.expense_category).name, "amount" : Decimal(item.amount), "description" : item.description, "occurred_on": str(item.occurred_on), "is_income": item.is_income, "tags_as_string": item.tags_as_string()} for item in subset ] } }
def _edit_balance(self, balance): if balance.uid is not None: if not balance.can_modify_balance(h.authenticated_user().uid): return { "failure": Messages.permissionDenied() } try: balance.name = request.params['name'][0:25] except: return { "failure": Messages.invalidArguments() } if len(balance.users.all()) == 0: user_balance = self.dbFacade().model.UserBalance(user_uid=h.authenticated_user().uid, writable=True) balance.users.append(user_balance) h.authenticated_user().balances.append(user_balance) self.dbFacade().balances.balanceDao.save(balance) self.dbFacade().db.commit() return { "id" : balance.uid }
def edit(self, balance_uid): model = request.environ['sqlalchemy.model'] db = request.environ['sqlalchemy.session'] balance = db.query(model.Balance).filter_by(uid = balance_uid).first() if not balance or not balance.can_modify_balance(h.authenticated_user().uid): return { "failure": Messages.permissionDenied() } uid = int(request.params['uid']) bc = balance.changes.filter_by(uid=uid).first() if not bc: abort(404) try: with localcontext() as ctx: ctx.prec = 2 bc.amount = h.parse_decimal(request.params['amount']) except: log.error("Invalid number: %s" % request.params.get('amount'), exc_info=1) pass try: if int(request.params['is_income']) >= 0: bc.income_category_uid = int(request.params['income_category_uid']) bc.expense_category_uid = None bc.is_income = True else: bc.expense_category_uid = int(request.params['expense_category_uid']) bc.income_category_uid = None bc.is_income = False except: pass try: bc.description = request.params['description'] except: pass try: bc.occurred_on = h.parse_date(request.params['occurred_on']) except: log.error("Invalid date: %s" % request.params.get('occurred_on'), exc_info=1) pass ops = Operations(db, model) try: ops.change_tags_from_string(bc, request.params['tags']) except: pass ops.save_balance_change(bc) return { "id" : bc.uid }
def send_invitation(self): model = request.environ["sqlalchemy.model"] db = request.environ["sqlalchemy.session"] if not authorized(ValidAuthKitUser()): return { "failure" : Messages.invalidSession() } try: to_address = request.params['to_address'] subject = _("You have been invited to %s " % h.site_name()) body = request.params['body'] except: return { "failure" : Messages.invalidArguments() } if to_address == "" or subject == "" or body == "": return { "failure" : Messages.invalidArguments() } invitation = model.Invitation( sender_uid = h.authenticated_user().uid, to_address = to_address, ) db.save(invitation) db.commit() c.invitation_link = h.site_url() + h.url_for(controller='signup', action='invitation', id=invitation.token) from email.MIMEText import MIMEText body = body + render_jinja('messages/invitation_footer.jinja') message = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') message['Subject'] = subject message['From'] = config['from_address'] message['To'] = to_address try: from fivecents.lib.mail import EmailSender ms = EmailSender(to_addresses = to_address) ms.send_mime(message) except Exception, e: return { "failure" : Messages.failedToSendEmail(exception=e) }
def send_feedback(self): try: from_address = request.params['from_address'] subject = _("Feedback about %s " % h.site_name()) body = request.params['body'] except: return { "failure" : Messages.invalidArguments() } if from_address == "" or subject == "" or body == "": return { "failure" : Messages.invalidArguments() } from email.MIMEText import MIMEText message = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') message['Subject'] = subject message['From'] = from_address message['To'] = config['email_to'] try: from fivecents.lib.mail import EmailSender ms = EmailSender(to_addresses = message['To']) ms.send_mime(message) except Exception, e: return { "failure" : Messages.failedToSendEmail(exception=e) }
def list(self, balance_uid): model = request.environ['sqlalchemy.model'] db = request.environ['sqlalchemy.session'] try: user_uid = h.authenticated_user().uid except: return { "failure": Messages.pemissionDenied() } if not Operations(db, model).can_see_balance(user_uid, balance_uid): return { "failure": Messages.permissionDenied() } balance_changes = db.query(model.BalanceChange) \ .options(eagerload('expense_category'), eagerload('income_category')) \ .filter_by(balance_uid = balance_uid).order_by(model.BalanceChange.occurred_on).all() total = len(balance_changes) try: page_nr = request.params['page_nr'] except: page_nr = 1 try: items_per_page = int(request.params['items_per_page']) except: items_per_page = 15 subset = Page(balance_changes, item_count=total, current_page=page_nr, items_per_page=items_per_page) return { "totalItems" : total, "itemsFound" : len(subset), "items" : [{ "uid" : item.uid, "category_uid" : item.is_income and item.income_category_uid or item.expense_category_uid, "category" : (item.is_income and item.income_category or item.expense_category).name, "amount" : h.format_decimal(Decimal(item.amount)), "description" : item.description, "occurred_on": str(item.occurred_on), "is_income": item.is_income, "tags_as_string": item.tags_as_string()} for item in subset ] }