def findUser(self, username, email, firstName, lastName, numOfResults, shift, sessionId): extendSessionOrFail(sessionId) searchDict = {} def addToDict(fieldName, value): if len(value) > 0: searchDict[fieldName] = value addToDict('username', username) addToDict('email', email) addToDict('firstName', firstName) addToDict('lastName', lastName) return User.objects.filter(**searchDict)
def modifyMoneyChange(self, changeId, amount, sessionId): userId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=userId) user_node = user.get_profile().node edge = getEdgeOrFail(changeId) if edge.creator.id != user_node.id: raise InvalidArguments(\ description={ Argument.ChangeID : "This change can't be modified by you." }) if edge.is_confirmed: raise InvalidArguments(\ description={ Argument.ChangeID : "Change is already confirmed." }) try: money_debt_object = MoneyDebtObject.objects.get(edge=edge) except ObjectDoesNotExist: raise InvalidArguments(\ description={ Argument.ChangeID : "Change is not a money change." }) if amount >= 0: money_debt_object.amount = amount else: money_debt_object.amount = -amount tmp = edge.borrower edge.borrower = edge.creditor edge.creditor = tmp edge.save() money_debt_object.save() money_debt = MoneyDebt.objects.get(id=edge.debt.id) return self.createMoneyDebtDescription(money_debt)
def addMoneyContribution(self, eventId, userId, amount, currency, sessionId): callerId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=callerId) event = getEventOrFail(eventId) if not event.participants.filter(id=user.id).exists(): raise InvalidArguments( description={ Argument.EventID : "Your're not a member of this event." }) user_node = user.get_profile().node event_node = event.node if callerId != userId and not event.admins.filter(id=user.id).exists(): raise InvalidArguments( description={ Argument.EventID : "Not enough rights." }) if amount == 0: raise InvalidArguments( description={ Argument.Amount : "Empty contribution." }) if amount < 0: raise InvalidArguments( description={ Argument.Amount : "Negative contribution is not allowed." }) debt = findOrCreateMoneyDebt(user_node, event_node, event, currency) debt.save() self.appendEdgeToMoneyDebt(debt, event_node, user_node, amount, user_node) return self.createMoneyDebtDescription(debt)
def listFriendRequests(self, sessionId): userId, refTime = extendSessionOrFail(sessionId) user = getUserOrFail(userId) result = [] for friendship in Friendship.objects.filter(user_b=user): if friendship.is_confirmed == False: result.append(friendship.user_a.id) return result
def getEventMoneyDebts(self, eventId, sessionId): userId, _ = extendSessionOrFail(sessionId) event = getEventOrFail(eventId) debts_a = MoneyDebt.objects.filter(node_a=event.node) debts_b = MoneyDebt.objects.filter(node_b=event.node) return [self.createMoneyDebtDescription(debt) for debt in chain(debts_a.all(), debts_b.all())]
def acceptFriendRequest(self, friendId, sessionId): userId, refTime = extendSessionOrFail(sessionId) user = getUserOrFail(userId) friend = getUserOrFail(friendId) friendship = getFriendshipOrFail(user, friend) if friendship.is_confirmed: raise InvalidArguments(\ description={ Argument.FriendID : 'Friend already accepted' }) friendship.is_confirmed = True friendship.save()
def modifyMoneyDebt(self, debtId, amount, sessionId): userId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=userId) user_node = user.get_profile().node debt = self.getMoneyDebtOrFail(debtId) self.appendEdgeToDebt(debt, debt.borrower(), debt.creditor(), amount, user_node) return self.createMoneyDebtDescription(debt)
def getUsersMoneyDebts(self, sessionId): userId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=userId) user_node = user.get_profile().node debts_a = MoneyDebt.objects.filter(node_a=user_node) debts_b = MoneyDebt.objects.filter(node_b=user_node) return [self.createMoneyDebtDescription(debt) for debt in chain(debts_a.all(), debts_b.all())]
def sendFriendRequest(self, friendId, sessionId): userId, refTime = extendSessionOrFail(sessionId) if userId == friendId: raise InvalidArguments(\ description={ Argument.FriendID : 'Can\'t friend yourself' }) user = getUserOrFail(userId) friend = getUserOrFail(friendId) res = user.get_profile().send_friend_request(friend) if res is None: raise InvalidArguments(\ description={ Argument.FriendID : 'Friend request already sent' }) return res
def getMoneyDebtsWith(self, friendId, sessionId): userId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=userId) friend = getFriendOrFail(friendId, user) user_node = user.get_profile().node friend_node = friend.get_profile().node debts_a = MoneyDebt.objects.filter(node_a=user_node, node_b=friend_node) debts_b = MoneyDebt.objects.filter(node_a=friend_node, node_b=user_node) return [self.createMoneyDebtDescription(debt) for debt in chain(debts_a.all(), debts_b.all())]
def modifyMoneyContribution(self, debtId, userId, amount, sessionId): callerId, _ = extendSessionOrFail(sessionId) caller = User.objects.get(id=callerId) user = getUserOrFail(userId) user_node = user.get_profile().node debt = self.getMoneyDebtOrFail(debtId) if debt.node_a != user_node and debt.node_b != user_node: raise InvalidArguments( description={ Argument.DebtID : "Debt and user don't match" }) self.appendEdgeToDebt(debt, debt.borrower(), debt.creditor(), amount, user_node) return self.createMoneyDebtDescription(debt)
def redeemEventMoneyDebtTo(self, eventId, participantId, amount, currency, sessionId): userId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=userId) user_node = user.get_profile().node event = getEventOrFail(eventId) if userId == participantId: raise InvalidArguments( description={ Argument.UserID : "Participant id can't be the same as user's id" }) participant = getUserOrFail(participantId) participant_node = participant.get_profile().node user_debt = findMoneyDebt(event.node, user_node, currency) if user_debt is None: raise InvalidArguments( description={ Argument.EventID : "No obligations in this event." }) participant_debt = findMoneyDebt(event.node, participant_node, currency) if participant_debt is None: raise InvalidArguments( description={ Argument.UserID : "Wrong participant." }) user_obligation = 0 if user_debt.borrower() != user_node else \ abs(user_debt.total_confirmed_amount()) participant_obligation = 0 if participant_debt.borrower() != event.node else \ abs(participant_debt.total_confirmed_amount()) if amount <= 0 or amount > user_obligation or amount > participant_obligation: raise InvalidArguments( description={ Argument.Amount : "Wrong amount." }) user_participant_debt = findOrCreateMoneyDebt(user_node, participant_node, event, currency) user_participant_debt.save() user_edge = self.appendEdgeToMoneyDebt(user_debt, event.node, user_node, amount, event.node) participant_edge = self.appendEdgeToMoneyDebt(participant_debt, participant_node, event.node, amount, event.node) user_participant_edge = self.appendEdgeToMoneyDebt(user_participant_debt, user_node, participant_node, amount, event.node) user_edge.is_confirmed = True user_edge.save() participant_edge.is_confirmed = True participant_edge.save() user_participant_edge.is_confirmed = True user_participant_edge.save() return self.createMoneyDebtDescription(user_participant_debt)
def addMoneyDebt(self, friendId, amount, currency, sessionId): userId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=userId) friend = getFriendOrFail(friendId, user) user_node = user.get_profile().node friend_node = friend.get_profile().node if amount == 0: raise InvalidArguments(\ description={ Argument.Amount : "Empty debt" }) debt = MoneyDebt.objects.create(node_a=friend_node, node_b=user_node, currency=currency) debt.save() self.appendEdgeToMoneyDebt(debt, friend_node, user_node, amount, user_node) return self.createMoneyDebtDescription(debt)
def confirmMoneyChange(self, changeId, amount, borrowerId, sessionId): userId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=userId) edge, money_debt_object = getMoneyEdgeOrFail(changeId) if money_debt_object.amount != amount: raise InvalidArguments( description={ Argument.Amount : "Wrong amount." }) if edge.borrower.id != borrowerId: raise InvalidArguments( description={ Argument.GraphID : "Wrong borrower." }) if edge.is_confirmed: raise InvalidArguments( description={ Argument.ChangeID : "Change already confirmed" }) if not edge.can_be_confirmed_by(user): raise InvalidArguments( description={ Argument.ChangeID : "Change can't be confirmed by this user." }) edge.is_confirmed = True edge.save()
def generatePreciseEventMoneyDebts(self, eventId, obligations, sessionId): userId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=userId) event = getEventOrFail(eventId) if not event.admins.filter(id=user.id).exists(): raise InvalidArguments( description={ Argument.EventID : "Your're not an admin of this event." }) participants = event.participants.all() pnodes = { participant : participant.get_profile().node for participant in participants } all_debts = { pnode : [debt for debt in MoneyDebt.objects.filter(node_a=event.node, node_b=pnode).all()] + \ [debt for debt in MoneyDebt.objects.filter(node_a=pnode, node_b=event.node).all()] \ for pnode in pnodes.values() } currencies = set() for pnode in pnodes.values(): for debt in all_debts[pnode]: currencies.add(debt.currency) for currency in currencies: for participant in pnodes.keys(): if participant.id not in obligations or currency not in obligations[participant.id]: raise InvalidArguments( description={ Argument.Obligations : "Description incomplete. You need to specify amount for each currency and each participant." }) def norm_total(amount, debt): amount = abs(amount) if debt.borrower() == event.node: return amount return -amount for currency in currencies: tdebts = { pnode : filter(lambda d: d.currency == currency, all_debts[pnode]) \ for pnode in pnodes.values() } debts = { pnode : (None if len(tdebts[pnode]) == 0 else tdebts[pnode][0]) \ for pnode in pnodes.values() } contributions = { pnode : 0 if debts[pnode] is None else \ norm_total(debts[pnode].total_confirmed_amount_created_by(pnode), debts[pnode]) \ for pnode in pnodes.values() } total_contribution = sum(contributions.values()) total_obligation = sum([sum([0 if curr != currency else amount for curr, amount in obligation.items()]) for obligation in obligations.values()]) if total_contribution != total_obligation: raise InvalidArguments( description={ Argument.Obligations : "Total contribution and total obligation are not equal." }) result = [] for currency in currencies: tdebts = { pnode : filter(lambda d: d.currency == currency, all_debts[pnode]) \ for pnode in pnodes.values() } debts = { pnode : (None if len(tdebts[pnode]) == 0 else tdebts[pnode][0]) \ for pnode in pnodes.values() } contributions = { pnode : 0 if debts[pnode] is None else \ norm_total(debts[pnode].total_confirmed_amount_created_by(pnode), debts[pnode]) \ for pnode in pnodes.values() } total_contribution = sum(contributions.values()) current = { pnode : (0 if debts[pnode] is None else \ norm_total(debts[pnode].total_confirmed_amount(), debts[pnode]) ) \ for pnode in pnodes.values() } for debt in debts.values(): if debt is not None: debt.remove_edges([rdebt.id for rdebt in\ debt.edges.filter(is_confirmed=False, creator=event.node).all()]) for participant, pnode in pnodes.items(): amount = -current[pnode] + contributions[pnode] - obligations[participant.id][currency] if amount != 0: debt = debts[pnode] if debts[pnode] is not None else MoneyDebt.objects.create(\ node_a=event.node, node_b=pnode, currency=currency) self.appendEdgeToMoneyDebt(debt, event.node, pnode, amount, event.node) result.append(self.createMoneyDebtDescription(debt)) elif debts[pnode] is not None: result.append(self.createMoneyDebtDescription(debts[pnode])) return result
def generateWeightedEventMoneyDebts(self, eventId, weights, sessionId): userId, _ = extendSessionOrFail(sessionId) user = User.objects.get(id=userId) event = getEventOrFail(eventId) if not event.admins.filter(id=user.id).exists(): raise InvalidArguments( description={ Argument.EventID : "Your're not an admin of this event." }) participants = event.participants.all() if set([participant.id for participant in participants]) != set(weights.keys()): raise InvalidArguments( description={ Argument.EventID : "Not all participants included." }) total_weight = sum(weights.values()) if total_weight <= 0 or filter(lambda x: x < 0, weights.values()) != []: raise InvalidArguments( description={ Argument.Weights : "Invalid weights." }) pnodes = { participant : participant.get_profile().node for participant in participants } all_debts = { pnode : [debt for debt in MoneyDebt.objects.filter(node_a=event.node, node_b=pnode).all()] + \ [debt for debt in MoneyDebt.objects.filter(node_a=pnode, node_b=event.node).all()] \ for pnode in pnodes.values() } currencies = set() for pnode in pnodes.values(): for debt in all_debts[pnode]: currencies.add(debt.currency) result = [] def norm_total(amount, debt): amount = abs(amount) if debt.borrower() == event.node: return amount return -amount for currency in currencies: tdebts = { pnode : filter(lambda d: d.currency == currency, all_debts[pnode]) \ for pnode in pnodes.values() } debts = { pnode : (None if len(tdebts[pnode]) == 0 else tdebts[pnode][0]) \ for pnode in pnodes.values() } contributions = { pnode : 0 if debts[pnode] is None else \ norm_total(debts[pnode].total_confirmed_amount_created_by(pnode), debts[pnode]) \ for pnode in pnodes.values() } total_contribution = sum(contributions.values()) current = { pnode : (0 if debts[pnode] is None else \ norm_total(debts[pnode].total_confirmed_amount(), debts[pnode]) ) \ for pnode in pnodes.values() } obligations = { pnode : weights[participant.id] * total_contribution / total_weight \ for participant, pnode in pnodes.items() } for debt in debts.values(): if debt is not None: debt.remove_edges([rdebt.id for rdebt in\ debt.edges.filter(is_confirmed=False, creator=event.node).all()]) for participant, pnode in pnodes.items(): amount = -current[pnode] + contributions[pnode] - obligations[pnode] if amount != 0: debt = debts[pnode] if debts[pnode] is not None else MoneyDebt.objects.create(\ node_a=event.node, node_b=pnode, currency=currency) self.appendEdgeToMoneyDebt(debt, event.node, pnode, amount, event.node) result.append(self.createMoneyDebtDescription(debt)) elif debts[pnode] is not None: result.append(self.createMoneyDebtDescription(debts[pnode])) return result
def removeFriend(self, friendId, sessionId): userId, refTime = extendSessionOrFail(sessionId) user = getUserOrFail(userId) friend = getFriendOrFail(friendId, user) getConfirmedFriendshipOrFail(user, friend).delete()
def denyFriendRequest(self, friendId, sessionId): userId, refTime = extendSessionOrFail(sessionId) user = getUserOrFail(userId) friend = getUserOrFail(friendId) getFriendshipOrFail(user, friend).delete()
def getUsersGraphId(self, userId, sessionId): callerId, refTime = extendSessionOrFail(sessionId) user = getUserOrFail(userId) return user.get_profile().node.id
def listFriends(self, sessionId): userId, refTime = extendSessionOrFail(sessionId) user = getUserOrFail(userId) return [friend.id for friend in user.get_profile().friends()]