Test Failed
Pull Request — master (#86)
by Daniel
06:22 queued 03:08
created

irc2phpbb.__main__.parseOptions()   B

Complexity

Conditions 6

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 27
rs 8.5666
c 0
b 0
f 0
cc 6
nop 1
1
#! /usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
4
"""
5
An IRC bot that answers random questions, keeps a log from the IRC-chat,
6
easy to integrate in a webpage and montores a phpBB forum for latest topics
7
by loggin in to the forum and checking the RSS-feed.
8
9
You need to install additional modules.
10
11
# Install needed modules in local directory
12
pip3 install --target modules/ feedparser beautifulsoup4 chardet
13
14
Modules in modules/ will be loaded automatically. If you want to use a
15
different directory you can start the program like this instead:
16
17
PYTHONPATH=modules python3 main.py
18
19
# To get help
20
PYTHONPATH=modules python3 main.py --help
21
22
# Example of using options
23
--server=irc.bsnet.se --channel=#db-o-webb
24
--server=irc.bsnet.se --port=6667 --channel=#db-o-webb
25
--nick=marvin --ident=secret
26
27
# Configuration
28
Check out the file 'marvin_config_default.json' on how to configure, instead
29
of using cli-options. The default configfile is 'marvin_config.json' but you
30
can change that using cli-options.
31
32
# Make own actions
33
Check the file 'marvin_strings.json' for the file where most of the strings
34
are defined and check out 'marvin_actions.py' to see how to write your own
35
actions. Its just a small function.
36
37
# Read from incoming
38
Marvin reads messages from the incoming/ directory, if it exists, and writes
39
it out the the irc channel.
40
"""
41
42
import argparse
43
import json
44
import logging
45
import logging.config
46
import os
47
import sys
48
49
from importlib import resources as impresources
50
51
from irc2phpbb.discord_bot import DiscordBot
52
from irc2phpbb.irc_bot import IrcBot
53
54
from irc2phpbb import marvin_actions
55
from irc2phpbb import marvin_general_actions
56
57
from . import config as pkgconfig
58
59
60
#
61
# General stuff about this program
62
#
63
PROGRAM = "marvin"
64
VERSION = "0.3.0"
65
MSG_VERSION = f"{PROGRAM} version {VERSION}."
66
67
LOG = logging.getLogger("main")
68
69
70
def printVersion():
71
    """
72
    Print version information and exit.
73
    """
74
    print(MSG_VERSION)
75
    sys.exit(0)
76
77
78
def mergeOptionsWithConfigFile(options, configFile):
79
    """
80
    Read information from config file.
81
    """
82
    if os.path.isfile(configFile):
83
        with open(configFile, encoding="UTF-8") as f:
84
            data = json.load(f)
85
86
        options.update(data)
87
        res = json.dumps(options, sort_keys=True, indent=4, separators=(',', ': '))
88
        LOG.info("Read configuration from config file '%s'.", configFile)
89
        LOG.info("Current configuration is: %s", res)
90
    else:
91
        LOG.info("Config file '{%s}' is not readable, skipping.", configFile)
92
93
    return options
94
95
96
def parseOptions(options):
97
    """
98
    Merge default options with incoming options and arguments and return them as a dictionary.
99
    """
100
101
    parser = argparse.ArgumentParser()
102
    parser.add_argument("protocol", choices=["irc", "discord"], nargs="?", default="irc")
103
    parser.add_argument("-v", "--version", action="store_true")
104
    parser.add_argument("--config")
105
106
    for key, value in options.items():
107
        parser.add_argument(f"--{key}", type=type(value))
108
109
    args = vars(parser.parse_args())
110
    if args["version"]:
111
        printVersion()
112
    if args["config"]:
113
        mergeOptionsWithConfigFile(options, args["config"])
114
115
    for parameter in options:
116
        if args[parameter]:
117
            options[parameter] = args[parameter]
118
119
    res = json.dumps(options, sort_keys=True, indent=4, separators=(',', ': '))
120
    LOG.info("Configuration updated after cli options: %s", res)
121
122
    return options
123
124
125
def determineProtocol():
126
    """Parse the argument to determine what protocol to use"""
127
    parser = argparse.ArgumentParser()
128
    parser.add_argument("protocol", choices=["irc", "discord"], nargs="?", default="irc")
129
    arg, _ = parser.parse_known_args()
130
    return arg.protocol
131
132
133
def createBot(protocol):
134
    """Return an instance of a bot with the requested implementation"""
135
    if protocol == "irc":
136
        return IrcBot()
137
    if protocol == "discord":
138
        return DiscordBot()
139
    raise ValueError(f"Unsupported protocol: {protocol}")
140
141
142
def setupLogging():
143
    """Set up the logging config"""
144
    logConfig = impresources.files(pkgconfig) / "logging.json"
145
    with open(logConfig, encoding="UTF-8") as f:
146
        config = json.load(f)
147
    logging.config.dictConfig(config)
148
149
def main():
150
    """
151
    Main function to carry out the work.
152
    """
153
    setupLogging()
154
    protocol = determineProtocol()
155
    bot = createBot(protocol)
156
    options = bot.getConfig()
157
    options.update(mergeOptionsWithConfigFile(options, "marvin_config.json"))
158
    config = parseOptions(options)
159
    bot.setConfig(config)
160
    actions = marvin_actions.getAllActions()
161
    general_actions = marvin_general_actions.getAllGeneralActions()
162
    bot.registerActions(actions)
163
    bot.registerGeneralActions(general_actions)
164
    bot.begin()
165
166
    sys.exit(0)
167
168
169
if __name__ == "__main__":
170
    main()
171