Passed
Pull Request — master (#74)
by
unknown
05:42 queued 02:29
created

main   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Test Coverage

Coverage 80%

Importance

Changes 0
Metric Value
eloc 72
dl 0
loc 159
ccs 56
cts 70
cp 0.8
rs 10
c 0
b 0
f 0
wmc 15

6 Functions

Rating   Name   Duplication   Size   Complexity  
A mergeOptionsWithConfigFile() 0 18 3
A printVersion() 0 6 1
A determineProtocol() 0 6 1
B parseOptions() 0 27 6
A createBot() 0 7 3
A main() 0 17 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 1
import argparse
43 1
import json
44 1
import os
45 1
import sys
46
47 1
from discord_bot import DiscordBot
48 1
from irc_bot import IrcBot
49
50 1
import marvin_actions
51 1
import marvin_general_actions
52
53
#
54
# General stuff about this program
55
#
56 1
PROGRAM = "marvin"
57 1
AUTHOR = "Mikael Roos"
58 1
EMAIL = "[email protected]"
59 1
VERSION = "0.3.0"
60 1
MSG_VERSION = "{program} version {version}.".format(program=PROGRAM, version=VERSION)
61
62
63
64 1
def printVersion():
65
    """
66
    Print version information and exit.
67
    """
68 1
    print(MSG_VERSION)
69 1
    sys.exit(0)
70
71
72 1
def mergeOptionsWithConfigFile(options, configFile):
73
    """
74
    Read information from config file.
75
    """
76 1
    if os.path.isfile(configFile):
77 1
        with open(configFile, encoding="UTF-8") as f:
78 1
            data = json.load(f)
79
80 1
        options.update(data)
81 1
        res = json.dumps(options, sort_keys=True, indent=4, separators=(',', ': '))
82
83 1
        msg = "Read configuration from config file '{file}'. Current configuration is:\n{config}"
84 1
        print(msg.format(config=res, file=configFile))
85
86
    else:
87
        print("Config file '{file}' is not readable, skipping.".format(file=configFile))
88
89 1
    return options
90
91
92 1
def parseOptions(options):
93
    """
94
    Merge default options with incoming options and arguments and return them as a dictionary.
95
    """
96
97 1
    parser = argparse.ArgumentParser()
98 1
    parser.add_argument("protocol", choices=["irc", "discord"], nargs="?", default="irc")
99 1
    parser.add_argument("-v", "--version", action="store_true")
100 1
    parser.add_argument("--config")
101
102 1
    for key, value in options.items():
103 1
        parser.add_argument(f"--{key}", type=type(value))
104
105 1
    args = vars(parser.parse_args())
106 1
    if args["version"]:
107 1
        printVersion()
108 1
    if args["config"]:
109 1
        mergeOptionsWithConfigFile(options, args["config"])
110
111 1
    for parameter in options:
112 1
        if args[parameter]:
113 1
            options[parameter] = args[parameter]
114
115 1
    res = json.dumps(options, sort_keys=True, indent=4, separators=(',', ': '))
116 1
    print("Configuration updated after cli options:\n{config}".format(config=res))
117
118 1
    return options
119
120
121 1
def determineProtocol():
122
    """Parse the argument to determine what protocol to use"""
123 1
    parser = argparse.ArgumentParser()
124 1
    parser.add_argument("protocol", choices=["irc", "discord"], nargs="?", default="irc")
125 1
    arg, _ = parser.parse_known_args()
126 1
    return arg.protocol
127
128
129 1
def createBot(protocol):
130
    """Return an instance of a bot with the requested implementation"""
131 1
    if protocol == "irc":
132 1
        return IrcBot()
133 1
    if protocol == "discord":
134 1
        return DiscordBot()
135 1
    raise ValueError(f"Unsupported protocol: {protocol}")
136
137
138 1
def main():
139
    """
140
    Main function to carry out the work.
141
    """
142
    protocol = determineProtocol()
143
    bot = createBot(protocol)
144
    options = bot.getConfig()
145
    options.update(mergeOptionsWithConfigFile(options, "marvin_config.json"))
146
    config = parseOptions(options)
147
    bot.setConfig(config)
148
    actions = marvin_actions.getAllActions()
149
    general_actions = marvin_general_actions.getAllGeneralActions()
150
    bot.registerActions(actions)
151
    bot.registerGeneralActions(general_actions)
152
    bot.begin()
153
154
    sys.exit(0)
155
156
157 1
if __name__ == "__main__":
158
    main()
159