firefly-exporter/xmppbot.py

110 lines
3.6 KiB
Python

import os
import signal
import asyncio
import aioxmpp
import firefly.budgets
class BudgetBot(object):
def message_received(self, msg):
if msg.type_ != aioxmpp.MessageType.CHAT:
return
if not msg.body:
return
if str(msg.from_).split('/')[0] not in self.controller:
print("Ignored message from: {}".format(msg.from_))
return
print("msg from: {}".format(msg.from_))
print("got: {}".format(list(msg.body.values())[0]))
budget_data = firefly.budgets._collect_budget_data()
command = list(msg.body.values())[0]
if command.lower() == "budgets":
reply = "Budgets:\n"
for budget in budget_data:
reply += "- *{}*\n".format(budget.get('name'))
elif command.lower().startswith("budget "):
cmd_budget = command.split(' ')[1].lower()
budget = [b for b in budget_data if b['name'].lower() == cmd_budget]
if len(budget) != 1:
reply = "Invalid budget name"
else:
reply = "Budget *{}*\n".format(budget[0]['name'])
reply += " Available current month: {:.2f}\n".format(budget[0].get('limit'))
reply += " Average per day: {:.2f}\n".format(budget[0].get('average_per_day'))
reply += " Spent: {:.2f}\n".format(budget[0].get('spent'))
reply += " Spent per day: {:.2f}\n".format(budget[0].get('spent_per_day'))
reply += " Remaining: {:.2f}\n".format(budget[0].get('remaining'))
reply += " Remaining per day: {:.2f}".format(budget[0].get('remaining_per_day'))
else:
reply = "Please send command:\n"
reply += "- *budgets* list all budgets"
reply_msg = aioxmpp.Message(
type_=msg.type_,
to=msg.from_,
)
reply_msg.body[None] = reply
self.client.enqueue(reply_msg)
async def run_simple_example(self):
stop_event = self.make_sigint_event()
self.client.stream.register_message_callback(
aioxmpp.MessageType.CHAT,
None,
self.message_received,
)
print("listening... (press Ctrl-C or send SIGTERM to stop)")
await stop_event.wait()
async def run_example(self):
self.client = self.make_simple_client()
async with self.client.connected():
await self.run_simple_example()
def make_simple_client(self):
client = aioxmpp.PresenceManagedClient(
aioxmpp.JID.fromstr(os.environ.get('FIREFLY_JABBER_ID')),
aioxmpp.make_security_layer(os.environ.get('FIREFLY_JABBER_PASSWORD')),
)
self.roster = client.summon(aioxmpp.RosterClient)
self.roster.on_initial_roster_received.connect(
self._read_roster,
)
return client
def _read_roster(self):
self.controller = []
for item in self.roster.items.values():
self.controller.append(str(item.jid))
print("Roster entry: {}".format(item.jid))
print("Subscription: {}".format(item.subscription))
print("Approved: {}".format(item.approved))
print("Allowed controllers: {}".format(self.controller))
def make_sigint_event(self):
event = asyncio.Event()
loop = asyncio.get_event_loop()
loop.add_signal_handler(
signal.SIGINT,
event.set,
)
return event
def main():
bot = BudgetBot()
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(bot.run_example())
finally:
loop.close()
if __name__ == "__main__":
main()