aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2023-08-11 14:07:32 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2023-08-11 14:07:32 +0200
commitb17559d8ede422a0b91bcc1a2a01e71cd9b905b3 (patch)
tree426ef44932c343fae9a426ca6267342826b80ffc
parenta16f0be99ea25e9102c9863db6c32dd4cb96c0a7 (diff)
downloadgeldschieberbot-b17559d8ede422a0b91bcc1a2a01e71cd9b905b3.tar.gz
geldschieberbot-b17559d8ede422a0b91bcc1a2a01e71cd9b905b3.zip
extract the models and utility function into separate source files
-rw-r--r--geldschieberbot.py90
-rw-r--r--models.py71
-rw-r--r--utils.py28
3 files changed, 101 insertions, 88 deletions
diff --git a/geldschieberbot.py b/geldschieberbot.py
index f876461..0b766c0 100644
--- a/geldschieberbot.py
+++ b/geldschieberbot.py
@@ -3,100 +3,14 @@
import argparse
from datetime import date, datetime, timedelta
-from dataclasses import dataclass, field
import json
import os
import subprocess
import sys
import typing as T
-
-@dataclass
-class MessageContext:
- """Class representing the context of a message passed to a command function"""
- sender_number: str
- sender: T.Optional[str]
- args: list[str]
- body: list[str]
- timestamp: str
-
-
-@dataclass
-class Modification:
- """Class representing a single modification to the balance
-
- Amount is transfered from donor to the recipient.
- """
- recipient: str
- donor: str
- amount: int
-
- def in_string(self) -> str:
- """Format the change using the recipient as initiator"""
- return f'{self.recipient} {"->" if self.amount < 0 else "<-"} {to_euro(abs(self.amount))} {self.donor}'
-
- def out_string(self) -> str:
- """Format the change using the donor as initiator"""
- return f'{self.donor} {"->" if self.amount < 0 else "<-"} {to_euro(abs(self.amount))} {self.recipient}'
-
-
-@dataclass
-class Change:
- """Class representing a change to the state caused by a single command"""
- cmd: list[str]
- modifications: list[Modification]
- timestamp: str
- rewind_cmds: list[list[str]] = field(default_factory=lambda: [])
-
-
-@dataclass
-class Quote:
- """Class representing a message to quote"""
- timestamp: str
- author: str
-
-
-class GeldschieberbotJSONEncoder(json.JSONEncoder):
- """Custom JSONEncoder supporting our dataclasses"""
-
- def default(self, o):
- if isinstance(o, (Modification, Change)):
- return o.__dict__
- return json.JSONEncoder.default(self, o)
-
-
-@dataclass
-class Reply:
- """Class representing a reply from the bot"""
- msg: str
- attachment: T.Optional[str] = None
-
-
-def to_cent(euro) -> int:
- """Parse string containing euros into a cent value"""
- if '.' in euro:
- euro = euro.split('.')
- else:
- euro = euro.split(',')
- if len(euro) > 2:
- raise TypeError
- euro[0] = int(euro[0])
- if len(euro) < 2:
- euro.append(0)
- else:
- if len(euro[1]) == 1:
- euro[1] = int(euro[1]) * 10
- else:
- euro[1] = int(euro[1])
- amount = euro[0] * 100 + euro[1]
- if amount < 0:
- raise ValueError
- return amount
-
-
-def to_euro(cents) -> str:
- """Format cents as euro"""
- return f"{cents/100:.2f}"
+from models import MessageContext, Modification, Change, Quote, GeldschieberbotJSONEncoder, Reply
+from utils import to_euro, to_cent
class Geldschieberbot:
diff --git a/models.py b/models.py
new file mode 100644
index 0000000..5cee04a
--- /dev/null
+++ b/models.py
@@ -0,0 +1,71 @@
+"""Models used by geldschieberbot"""
+
+import json
+import typing as T
+
+from dataclasses import dataclass, field
+
+from utils import to_euro
+
+
+@dataclass
+class MessageContext:
+ """Class representing the context of a message passed to a command function"""
+ sender_number: str
+ sender: T.Optional[str]
+ args: list[str]
+ body: list[str]
+ timestamp: str
+
+
+@dataclass
+class Modification:
+ """Class representing a single modification to the balance
+
+ Amount is transfered from donor to the recipient.
+ """
+ recipient: str
+ donor: str
+ amount: int
+
+ def in_string(self) -> str:
+ """Format the change using the recipient as initiator"""
+ return (f'{self.recipient} {"->" if self.amount < 0 else "<-"}'
+ f' {to_euro(abs(self.amount))} {self.donor}')
+
+ def out_string(self) -> str:
+ """Format the change using the donor as initiator"""
+ return (f'{self.donor} {"->" if self.amount < 0 else "<-"}'
+ f' {to_euro(abs(self.amount))} {self.recipient}')
+
+
+@dataclass
+class Change:
+ """Class representing a change to the state caused by a single command"""
+ cmd: list[str]
+ modifications: list[Modification]
+ timestamp: str
+ rewind_cmds: list[list[str]] = field(default_factory=lambda: [])
+
+
+@dataclass
+class Quote:
+ """Class representing a message to quote"""
+ timestamp: str
+ author: str
+
+
+class GeldschieberbotJSONEncoder(json.JSONEncoder):
+ """Custom JSONEncoder supporting our dataclasses"""
+
+ def default(self, o):
+ if isinstance(o, (Modification, Change)):
+ return o.__dict__
+ return json.JSONEncoder.default(self, o)
+
+
+@dataclass
+class Reply:
+ """Class representing a reply from the bot"""
+ msg: str
+ attachment: T.Optional[str] = None
diff --git a/utils.py b/utils.py
new file mode 100644
index 0000000..353e562
--- /dev/null
+++ b/utils.py
@@ -0,0 +1,28 @@
+"""Utility functions used by the geldschieberbot"""
+
+
+def to_cent(euro) -> int:
+ """Parse string containing euros into a cent value"""
+ if '.' in euro:
+ euro = euro.split('.')
+ else:
+ euro = euro.split(',')
+ if len(euro) > 2:
+ raise TypeError
+ euro[0] = int(euro[0])
+ if len(euro) < 2:
+ euro.append(0)
+ else:
+ if len(euro[1]) == 1:
+ euro[1] = int(euro[1]) * 10
+ else:
+ euro[1] = int(euro[1])
+ amount = euro[0] * 100 + euro[1]
+ if amount < 0:
+ raise ValueError
+ return amount
+
+
+def to_euro(cents) -> str:
+ """Format cents as euro"""
+ return f"{cents/100:.2f}"