-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbank.py
139 lines (108 loc) · 4.09 KB
/
bank.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import logging
from datetime import datetime
from typing import Union
import dataset
import discord
from tools import database
log = logging.getLogger(__name__)
class Bank:
def __init__(self, user: Union[discord.User, discord.Member, discord.ClientUser]):
# Note: discord.ClientUser is the bot itself.
if not isinstance(user, (discord.User, discord.Member, discord.ClientUser)):
raise TypeError(
f"Object given was not a User nor Member object.\n\tType given: {type(user)}"
)
self.user = user
self.balance = self.__balance__()
def __str__(self) -> str:
"""<name>'s balance is $<balance>."""
return f"{self.user.name}'s balance is **$`{self.balance:,.2f}`**."
def __format__(self, format_spec: str) -> str:
"""Returns balance's value as to the specified format."""
return format(self.balance, format_spec)
def __get__(self) -> float:
"""Returns balance's value as a float."""
return float(self.balance)
def __lt__(self, other) -> bool:
"""Less than"""
if isinstance(other, int) or isinstance(other, float):
return self.balance < other
else:
raise TypeError
def __le__(self, other) -> bool:
"""Less than or equal to"""
if isinstance(other, int) or isinstance(other, float):
return self.balance <= other
else:
raise TypeError
def __gt__(self, other) -> bool:
"""Greater than"""
if isinstance(other, int) or isinstance(other, float):
return self.balance > other
else:
raise TypeError
def __ge__(self, other) -> bool:
"""Greater than or equal to"""
if isinstance(other, int) or isinstance(other, float):
return self.balance >= other
else:
raise TypeError
def __float__(self) -> bool:
return self.balance
def __balance__(self) -> float:
"""Get the balance of a user."""
with dataset.connect(database.get_db()) as db:
# Find last bank transaction.
statement = statement = f"""
SELECT opening_balance, transaction_amount
FROM bank
WHERE author_id = {self.user.id}
ORDER BY id DESC
LIMIT 1
"""
result = db.query(statement)
for row in result:
balance = row["opening_balance"] + row["transaction_amount"]
break
else:
# If there was no result for the user, default balance is given.
balance = 500
return float(balance)
def add(self, amount: float, reason: str = "") -> "Bank":
"""Add to a user's balance."""
if amount == 0: # Pointless, do nothing.
return 0
self.__record_ledger__(amount, reason)
self.balance += amount
return self
def subtract(self, amount: float, reason: str = "") -> "Bank":
"""Subtract from a user's balance."""
if amount == 0: # Pointless, do nothing.
return 0
self.__record_ledger__(-amount, reason)
self.balance -= amount
return self
def set(self, amount: float, reason: str = "") -> "Bank":
"""Set a user's balance."""
self.__record_ledger__(amount - self.balance, reason) # Because math
self.balance = amount
return self
def __record_ledger__(self, amount: float, reason: str = "") -> None:
with dataset.connect(database.get_db()) as db:
# Find last bank transaction
db["bank"].insert(
dict(
author_id=self.user.id,
opening_balance=self.balance,
transaction_amount=amount,
reason=reason,
timestamp=datetime.now(),
)
)
db.commit()
def name(self) -> str:
"""Return bank owner's name."""
return self.user.name
def id(self) -> int:
"""Return bank owner's ID."""
return self.user.id