~ common/specific options parsing disptached into bot.py, signalcli.py and jabber.py

This commit is contained in:
nicobo 2020-05-22 09:15:50 +02:00
parent 646847e7ac
commit cb58f3f2a6
No known key found for this signature in database
GPG key ID: 2581E71C5FA5285F
4 changed files with 118 additions and 40 deletions

View file

@ -20,9 +20,12 @@ import urllib.request
# Own classes
from helpers import *
from bot import Bot
from bot import ArgHelper as BotArgHelper
from console import ConsoleChatter
from jabber import *
from jabber import JabberChatter
from jabber import arg_parser as jabber_arg_parser
from signalcli import SignalChatter
from signalcli import ArgHelper as SignalArgHelper
from stealth import StealthChatter
@ -37,12 +40,8 @@ class Config:
'input_file': sys.stdin,
'max_count': -1,
'patterns': [],
'recipient': None,
'signal_cli': shutil.which("signal-cli"),
'signal_stealth': False,
'stealth': False,
'timeout': None,
'username': None,
'verbosity': "INFO",
})
@ -130,6 +129,7 @@ class AskBot(Bot):
self.registerExitHandler()
self.chatter.connect()
# FIXME Sometimes the message is not received by the recipient (but the logs show it's sent ?)
if self.message:
self.chatter.send(self.message)
@ -156,35 +156,16 @@ if __name__ == '__main__':
# config is the final, merged configuration
config = Config()
parser = argparse.ArgumentParser( description='Sends a XMPP message and reads the answer', formatter_class=argparse.ArgumentDefaultsHelpFormatter )
# Bootstrap options
parser.add_argument("--config-file", "-c", "--config", dest="config_file", default=config.config_file, help="YAML configuration file.")
parser.add_argument("--config-dir", "-C", dest="config_dir", default=config.config_dir, help="Directory where to find configuration files by default.")
parser.add_argument('--verbosity', '-V', dest='verbosity', default=config.verbosity, help="Log level")
# Chatter-generic arguments
parser.add_argument("--backend", "-b", dest="backend", choices=['console','jabber','signal'], default=config.backend, help="Chat backend to use")
parser.add_argument("--input-file", "-i", dest="input_file", default=config.input_file, help="File to read messages from (one per line)")
parser.add_argument('--username', '-U', dest='username', help="Sender's ID (a phone number for Signal, a Jabber Identifier (JID) aka. username for Jabber/XMPP")
parser.add_argument('--recipient', '-r', '--receiver', dest='recipients', default=[], action='append', help="Recipient's ID (e.g. '+12345678901' for Signal / JabberID (Receiver address) to send the message to)")
parser.add_argument('--stealth', dest='stealth', action="store_true", default=config.stealth, help="Activate stealth mode on any chosen chatter")
# Other core options
parser = argparse.ArgumentParser(
parents=[ BotArgHelper().arg_parser(), jabber_arg_parser(), SignalArgHelper().arg_parser() ],
description='Sends a XMPP message and reads the answer',
formatter_class=argparse.ArgumentDefaultsHelpFormatter )
# Core options for this bot
parser.add_argument('--max-count', dest='max_count', type=int, default=config.max_count, help="Read this maximum number of responses before exiting")
parser.add_argument('--message', '-m', dest='message', help="Message to send. If missing, will read from --input-file")
parser.add_argument('--message-file', '-f', dest='message_file', type=argparse.FileType('r'), default=sys.stdin, help="File with the message to send. If missing, will be read from standard input")
parser.add_argument('--pattern', '-p', dest='patterns', action='append', nargs=2, help="Exits with status 0 whenever a message matches this pattern ; otherwise with status 1")
parser.add_argument('--timeout', '-t', dest='timeout', type=int, default=config.timeout, help="How much time t wait for an answer before quiting (in seconds)")
# Misc. options
parser.add_argument("--debug", "-d", action="store_true", dest='debug', default=False, help="Activate debug logs (overrides --verbosity)")
# Signal-specific arguments
parser.add_argument('--signal-cli', dest='signal_cli', default=config.signal_cli, help="Path to `signal-cli` if not in PATH")
parser.add_argument('--signal-username', dest='signal_username', help="Username when using the Signal backend (overrides --username)")
parser.add_argument('--signal-group', dest='group', help="Group's ID (for Signal : a base64 string (e.g. 'mPC9JNVoKDGz0YeZMsbL1Q==')")
parser.add_argument('--signal-recipient', dest='signal_recipients', action='append', default=[], help="Recipient when using the Signal backend (overrides --recipient)")
parser.add_argument('--signal-stealth', dest='signal_stealth', action="store_true", default=config.signal_stealth, help="Activate Signal chatter's specific stealth mode")
# Jabber-specific arguments
parser.add_argument('--jabber-username', '--jabberid', '--jid', dest='jabber_username', help="Username when using the Jabber/XMPP backend (overrides --username)")
parser.add_argument('--jabber-recipient', dest='jabber_recipients', action='append', default=[], help="Recipient when using the Jabber/XMPP backend (overrides --recipient)")
parser.add_argument('--jabber-password', dest='jabber_password', help="Senders's password")
#
# 1st pass only matters for 'bootstrap' options : configuration file and logging

View file

@ -1,9 +1,13 @@
# -*- coding: utf-8 -*-
import argparse
import atexit
import logging
import os
import signal
import sys
import logging
class Bot:
"""
@ -46,3 +50,45 @@ class Bot:
Starts the bot
"""
pass
class ArgHelper:
"""
Command-line parsing helper for bot-generic options
"""
def __init__(self):
# Default configuration (some defaults still need to be set up after command line has been parsed)
self.__dict__.update({
'backend': "console",
'config_file': "config.yml",
'config_dir': os.getcwd(),
'input_file': sys.stdin,
'stealth': False,
'verbosity': "INFO",
})
def arg_parser(self):
"""
Returns a parent parser for common bot arguments
"""
parser = argparse.ArgumentParser(add_help=False)
# Bootstrap options
parser.add_argument("--config-file", "-c", "--config", dest="config_file", default=self.config_file, help="YAML configuration file.")
parser.add_argument("--config-dir", "-C", dest="config_dir", default=self.config_dir, help="Directory where to find configuration files by default.")
parser.add_argument('--verbosity', '-V', dest='verbosity', default=self.verbosity, help="Log level")
# Chatter-generic arguments
parser.add_argument("--backend", "-b", dest="backend", choices=['console','jabber','signal'], default=self.backend, help="Chat backend to use")
parser.add_argument("--input-file", "-i", dest="input_file", default=self.input_file, help="File to read messages from (one per line)")
parser.add_argument('--username', '-U', dest='username', help="Sender's ID (a phone number for Signal, a Jabber Identifier (JID) aka. username for Jabber/XMPP")
parser.add_argument('--recipient', '-r', '--receiver', dest='recipients', default=[], action='append', help="Recipient's ID (e.g. '+12345678901' for Signal / JabberID (Receiver address) to send the message to)")
parser.add_argument('--stealth', dest='stealth', action="store_true", default=self.stealth, help="Activate stealth mode on any chosen chatter")
# Misc. options
parser.add_argument("--debug", "-d", action="store_true", dest='debug', default=False, help="Activate debug logs (overrides --verbosity)")
return parser

View file

@ -1,6 +1,10 @@
# -*- coding: utf-8 -*-
import argparse
import asyncio
import logging
import time
import os
import time
from slixmpp import ClientXMPP, JID
from slixmpp.exceptions import IqTimeout, IqError
@ -9,7 +13,6 @@ import slixmpp_omemo
from slixmpp_omemo import PluginCouldNotLoad, MissingOwnKey, EncryptionPrepareException
from slixmpp_omemo import UndecidedException, UntrustedException, NoAvailableSession
from omemo.exceptions import MissingBundleException
import asyncio
# Own classes
from chatter import Chatter
@ -316,3 +319,19 @@ class JabberChatter(Chatter):
Stops waiting for messages and exits the engine
"""
self.xmpp.disconnect()
def arg_parser():
"""
Returns a parent parser for jabber-specific arguments
"""
parser = argparse.ArgumentParser(add_help=False)
# Jabber-specific arguments
parser.add_argument('--jabber-username', '--jabberid', '--jid', dest='jabber_username', help="Username when using the Jabber/XMPP backend (overrides --username)")
parser.add_argument('--jabber-recipient', dest='jabber_recipients', action='append', default=[], help="Recipient when using the Jabber/XMPP backend (overrides --recipient)")
parser.add_argument('--jabber-password', dest='jabber_password', help="Senders's password")
return parser

View file

@ -2,17 +2,17 @@
# -*- coding: utf-8 -*-
import argparse
import logging
import sys
import os
import shutil
import subprocess
import atexit
import signal
import json
import i18n
import re
import json
import locale
import logging
import os
import re
import shutil
import signal
import subprocess
import sys
import time
from chatter import Chatter
@ -159,3 +159,35 @@ class SignalChatter(Chatter):
logging.debug("Discarding message without data")
else:
logging.debug("Discarding message that was sent before I started")
class ArgHelper:
"""
Command-line parsing helper for Signal-specific options
"""
def __init__(self):
# Default configuration (some defaults still need to be set up after command line has been parsed)
self.__dict__.update({
'signal_cli': shutil.which("signal-cli"),
'signal_stealth': False,
})
def arg_parser(self):
"""
Returns a parent parser for Signal-specific arguments
"""
parser = argparse.ArgumentParser(add_help=False)
# Signal-specific arguments
parser.add_argument('--signal-cli', dest='signal_cli', default=self.signal_cli, help="Path to `signal-cli` if not in PATH")
parser.add_argument('--signal-username', dest='signal_username', help="Username when using the Signal backend (overrides --username)")
parser.add_argument('--signal-group', dest='signal_group', help="Group's ID (for Signal : a base64 string (e.g. 'mPC9JNVoKDGz0YeZMsbL1Q==')")
parser.add_argument('--signal-recipient', dest='signal_recipients', action='append', default=[], help="Recipient when using the Signal backend (overrides --recipient)")
parser.add_argument('--signal-stealth', dest='signal_stealth', action="store_true", default=self.signal_stealth, help="Activate Signal chatter's specific stealth mode")
return parser