Skip to content

Commit

Permalink
add a default::quiet option to allow for silent bots
Browse files Browse the repository at this point in the history
  • Loading branch information
scarlehoff committed Jul 10, 2024
1 parent 5e837fc commit afc954c
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 26 deletions.
3 changes: 2 additions & 1 deletion src/pybliotecario/argument_parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Wrapper for the argument parser and the initialization
"""

from argparse import Action, ArgumentParser, ArgumentTypeError
import configparser
import glob
Expand Down Expand Up @@ -93,7 +94,7 @@ def configure_telegram():
token = input("Authorization token: ")

# Try to fire up the bot with the given token
telegram_API = TelegramUtil(token, timeout=20)
telegram_API = TelegramUtil(token=token, timeout=20)
print("Thanks, let's test this out. Say something (anything!) to your bot in telegram")

for _ in range(20): # Allow for 20 tries
Expand Down
16 changes: 15 additions & 1 deletion src/pybliotecario/backend/basic_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"""

from abc import ABC, abstractmethod
from configparser import ConfigParser
import json
import logging
import urllib
Expand Down Expand Up @@ -160,7 +161,14 @@ class Backend(ABC):
"""

_max_size = 99999
def __init__(self, config=None, debug=False, **kwargs):
if config is None:
# If no config is passed, generate and empty one
config = ConfigParser()
self._max_size = 99999
self._quiet = config.getboolean("DEFAULT", "quiet", fallback=False)
self._config = config
self._debug = debug

@abstractmethod
def _get_updates(self, not_empty=False):
Expand All @@ -175,6 +183,12 @@ def raw_updates(self):
def send_message(self, text, chat, **kwargs):
"""Sends a message to the chat"""

def send_quiet_message(self, text, chat, **kwargs):
"""Like ``send_message`` but only sends the message if quiet is set to False
otherwise, do nothing"""
if not self._quiet:
return self.send_message(text, chat, **kwargs)

@property
@abstractmethod
def _message_class(self):
Expand Down
31 changes: 24 additions & 7 deletions src/pybliotecario/backend/facebook_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,31 @@ class FacebookUtil(Backend):
_message_class = FacebookMessage
_max_size = MAX_SIZE

def __init__(self, PAGE_TOKEN, VERIFY_TOKEN, host="0.0.0.0", port=3000, debug=False):
def __init__(self, config=None, host="0.0.0.0", port=3000, **kwargs):
super().__init__(config, **kwargs)
if config is None:
raise ValueError("A configuration with a FACEBOOK section must be given")

try:
fb_config = config["FACEBOOK"]
except KeyError:
raise ValueError("No facebook section found for facebook in pybliotecario.ini")

if not _HAS_FLASK:
# Raise the error now
raise ModuleNotFoundError("No module named 'flask'")
raise ModuleNotFoundError("No module named 'flask', needed for Facebook backend")

verify_token = fb_config.get("verify")
page_token = fb_config.get("app_token")

self.page_access_token = PAGE_TOKEN
self.verify_token = VERIFY_TOKEN
self.page_access_token = page_token
self.verify_token = verify_token
self.port = port
self.host = host
app = Flask(__name__)
# Load the listener into the webhook endpoint
app.add_url_rule("/webhook", "webhook", self.listener, methods=["POST", "GET"])
self.flask_app = app
self.debug = debug
self.action_function = None
self.auth = {"access_token": self.page_access_token}

Expand Down Expand Up @@ -121,7 +132,7 @@ def act_on_updates(self, action_function, not_empty=False):
opens the webhook to wait ofr updates and act on them
"""
self.action_function = action_function
self.flask_app.run(host=self.host, port=self.port, debug=self.debug)
self.flask_app.run(host=self.host, port=self.port, debug=self._debug)

def _get_updates(self, not_empty=False):
"""This class skips get_updates and uses act_on_updates directly"""
Expand Down Expand Up @@ -184,8 +195,14 @@ def send_file(self, filepath, chat):


if __name__ == "__main__":
from configparser import ConfigParser
logger.info("Testing FB Util")
verify = "your_verify_token"
app_token = "your_app_key"
fb_util = FacebookUtil(app_token, verify, debug=True)
config = ConfigParser()
config["FACEBOOK"] = {
"verify": verify,
"app_token": app_token
}
fb_util = FacebookUtil(config, debug=True)
fb_util.act_on_updates(lambda x: print(x))
17 changes: 11 additions & 6 deletions src/pybliotecario/backend/telegram_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,18 @@ class TelegramUtil(Backend):

_message_class = TelegramMessage

def __init__(self, TOKEN, debug=False, timeout=300):
def __init__(self, config=None, token=None, timeout=300, **kwargs):
super().__init__(config, **kwargs)
if token is None:
if config is None:
raise ValueError("Either a config or a token must be provided for Telegram")
token = config.defaults().get("token")

self.offset = None
self.debug = debug
self.timeout = timeout
# Build app the API urls
base_URL = TELEGRAM_URL + f"bot{TOKEN}/"
self.base_fileURL = TELEGRAM_URL + f"file/bot{TOKEN}/"
base_URL = TELEGRAM_URL + f"bot{token}/"
self.base_fileURL = TELEGRAM_URL + f"file/bot{token}/"
self.send_msg = base_URL + "sendMessage"
self.send_img = base_URL + "sendPhoto"
self.send_doc = base_URL + "sendDocument"
Expand Down Expand Up @@ -185,7 +190,7 @@ def _get_updates(self, not_empty=False):
if not updates and not_empty:
return self._get_updates(not_empty=True)

if self.debug:
if self._debug:
logger.info("Request url: %s", url)
logger.info("Obtained updates: %s", updates)

Expand Down Expand Up @@ -254,7 +259,7 @@ def download_file(self, file_id, file_path):
if __name__ == "__main__":
logger.info("Testing TelegramUtil")
token = "must put a token here to test"
ut = TelegramUtil(token, debug=True)
ut = TelegramUtil(token=token, debug=True)
# noinspection PyProtectedMember
results = ut._get_updates()
for res in results:
Expand Down
3 changes: 2 additions & 1 deletion src/pybliotecario/core_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This module manages the core loop of the pybliotecario
when it is called with daemon mode -d
"""

from datetime import datetime
import logging
from pathlib import Path
Expand Down Expand Up @@ -119,7 +120,7 @@ def act_on_message(message):
# Otherwise just save the msg to the log and send a funny reply
_write_to_daily_log(main_folder, message.text)
random_msg = still_alive()
tele_api.send_message(random_msg, chat_id)
tele_api.send_quiet_message(random_msg, chat_id)
except_counter = 0
except Exception as e:
logger.error(f"This message produced an exception: {e}")
Expand Down
1 change: 1 addition & 0 deletions src/pybliotecario/customconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Define custom parsers for the config reader
and default data/config locations
"""

from configparser import ConfigParser
from copy import copy
from os import environ
Expand Down
1 change: 1 addition & 0 deletions src/pybliotecario/on_cmd_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
This is a design choice as this way it is not necessary to have all dependencies
if you want to run only some submodules of the pybliotecario.
"""

import importlib
import logging

Expand Down
14 changes: 4 additions & 10 deletions src/pybliotecario/pybliotecario.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@


def read_config(config_file=None):
"""Reads the pybliotecario config file and uploads the global configuration
"""Reads the pybliotecario config file and updates the global configuration
By default looks always in the default file path (in XDG_CONFIG_HOME) and the current folder
"""
default_file_path = default_config_path()
Expand Down Expand Up @@ -107,19 +107,13 @@ def main(cmdline_arg=None, tele_api=None, config=None):
)
sys.exit(-1)

tele_api = TelegramUtil(api_token, debug=args.debug)
tele_api = TelegramUtil(config=config, debug=args.debug)
elif args.backend.lower() == "test":
tele_api = TestUtil("/tmp/test_file.txt")
elif args.backend.lower() == "facebook":
try:
fb_config = config["FACEBOOK"]
except KeyError:
raise ValueError("No facebook section found for facebook in pybliotecario.ini")
verify_token = fb_config.get("verify")
app_token = fb_config.get("app_token")
tele_api = FacebookUtil(app_token, verify_token, debug=args.debug)
tele_api = FacebookUtil(config=config, debug=args.debug)
# Check whether we have chat id
chat_id = fb_config.get("chat_id")
chat_id = config["FACEBOOK"].get("chat_id")
if chat_id is not None:
config.set("DEFAULT", "chat_id", chat_id)

Expand Down

0 comments on commit afc954c

Please sign in to comment.