Skip to content

Commit b0e20a4

Browse files
committed
Merge pull request #9 from CactusBot/v0.2.1
v0.2.1
2 parents 80433e0 + 1c957fa commit b0e20a4

File tree

6 files changed

+80
-65
lines changed

6 files changed

+80
-65
lines changed

Diff for: .travis.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@ language: python
22
python:
33
- "3.4"
44
- "3.5"
5-
5+
install:
6+
- pip install flake8
7+
before_script:
8+
- "flake8 ."
69
script: nosetests

Diff for: beam.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ class Beam:
1111
message_id = 0
1212

1313
def __init__(self, debug="WARNING", **kwargs):
14-
self._init_logger(debug, kwargs.get("log_to_file", False))
14+
self._init_logger(debug, kwargs.get("log_to_file", True))
1515
self.http_session = Session()
1616

17-
def _init_logger(self, level, log_to_file=False):
17+
def _init_logger(self, level, log_to_file=True):
1818
"""Initialize logger."""
1919

2020
self.logger = get_logger("CactusBot")
@@ -35,7 +35,8 @@ def _init_logger(self, level, log_to_file=False):
3535
if level in levels:
3636
level_num = __import__("logging").__getattribute__(level)
3737
self.logger.setLevel(level_num)
38-
get_logger("urllib3").setLevel(WARNING)
38+
get_logger("asyncio").setLevel(WARNING)
39+
get_logger("requests").setLevel(WARNING)
3940
get_logger("websockets").setLevel(WARNING)
4041
self.logger.info("Logger level set to: {}".format(level))
4142

@@ -128,7 +129,7 @@ def send_message(self, arguments, method="msg"):
128129
}
129130

130131
if method == "msg":
131-
self.logger.info("$[CactusBot] {message}".format(
132+
self.logger.info("$ [CactusBot] {message}".format(
132133
message=arguments[0]))
133134

134135
yield from self.websocket.send(dumps(message_packet))
@@ -144,9 +145,10 @@ def remove_message(self, channel_id, message_id):
144145
id=channel_id, message=message_id))
145146

146147
def read_chat(self, handle=None):
148+
"""Receive chat messages from Beam."""
147149
while True:
148150
response = loads((yield from self.websocket.recv()))
149151
self.logger.debug(response)
150152

151-
if handle:
153+
if callable(handle):
152154
handle(response)

Diff for: cactus.py

+32-32
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ class Cactus(MessageHandler, Beam):
4848
def __init__(self, autorestart=True, **kwargs):
4949
super(Cactus, self).__init__(**kwargs)
5050
self.debug = kwargs.get("DEBUG", False)
51-
self.autorestart = autorestart
5251
self.config_file = kwargs.get("config_file", "data/config.json")
5352
self.stats_file = kwargs.get("stats_file", "data/stats.json")
5453
self.database = kwargs.get("database", "data/data.db")
@@ -84,6 +83,9 @@ def load_config(self, filename):
8483
exit()
8584

8685
def load_stats(self, filename):
86+
self.logger.warning("Statistics are not yet implemented.")
87+
return dict()
88+
8789
if exists(filename):
8890
self.stats_file = filename
8991
self.logger.info("Statistics file was found. Loading...")
@@ -101,27 +103,43 @@ def update_config(self, keys, value):
101103
reduce(lambda d, k: d[k], keys.split('.')[:-1], config_data)[
102104
keys.split('.')[-1]] = value
103105
with open(self.config_file, 'w+') as config:
104-
dump(config_data, config, indent=4, sort_keys=True)
106+
dump(config_data, config, indent=2, sort_keys=True)
105107
self.config = config_data
108+
return self.config
106109

107110
def update_stats(self, keys, value):
111+
self.logger.warning("Statistics are not yet implemented.")
112+
return
113+
108114
with open(self.stats_file, 'r') as stats:
109115
stats_data = load(stats)
110116
reduce(lambda d, k: d[k], keys.split('.')[:-1], stats_data)[
111117
keys.split('.')[-1]] = value
112-
with open(self.config_file, 'w+') as config:
113-
dump(stats_data, config, indent=4, sort_keys=True)
114-
self.config = stats_data
118+
with open(self.stats_file, 'w+') as stats:
119+
dump(stats_data, stats, indent=2, sort_keys=True)
120+
self.stats = stats_data
121+
return self.stats
115122

116123
def run(self, *args, **kwargs):
117124
"""Run bot."""
118125

119126
self.logger.info(cactus_art)
120127
self._init_database(self.database)
128+
self.load_config(filename=self.config_file)
129+
self.load_stats(filename=self.stats_file)
121130

122-
while self.autorestart or not self.started:
131+
while self.config.get("autorestart") or not self.started:
123132
try:
124-
self._run(args, kwargs)
133+
self.bot_data = self.login(**self.config["auth"])
134+
self.logger.info("Authenticated as: {}.".format(
135+
self.bot_data["username"]))
136+
137+
self.started = True
138+
139+
self.channel = self.config["channel"]
140+
self.channel_data = self.get_channel(self.channel)
141+
142+
self._init_commands()
125143

126144
loop = get_event_loop()
127145

@@ -150,14 +168,18 @@ def run(self, *args, **kwargs):
150168
loop.run_until_complete(
151169
self.send_message("CactusBot deactivated! :cactus")
152170
)
153-
pass
154171
self.logger.info("CactusBot deactivated.")
155172
exit()
156173
except Exception:
157174
self.logger.critical("Oh no, I crashed!")
175+
try:
176+
loop.run_until_complete(gather(
177+
self.send_message("Oh no, I crashed! :127")))
178+
except Exception:
179+
pass
158180
self.logger.error("\n\n" + format_exc())
159181

160-
if self.autorestart:
182+
if self.config.get("autorestart"):
161183
self.logger.info("Restarting in 10 seconds...")
162184
try:
163185
sleep(10)
@@ -168,29 +190,7 @@ def run(self, *args, **kwargs):
168190
self.logger.info("CactusBot deactivated.")
169191
exit()
170192

171-
def _run(self, *args, **kwargs):
172-
"""Bot execution code."""
173-
174-
if self.load_config(filename=self.config_file):
175-
self.load_stats(filename=self.stats_file)
176-
self.bot_data = self.login(**self.config["auth"])
177-
self.username = self.bot_data["username"]
178-
self.bot_id = self.bot_data["id"]
179-
self.logger.info("Authenticated as: {}.".format(self.username))
180-
181-
self.started = True
182-
183-
self.channel = self.config["channel"]
184-
self.channel_data = self.get_channel(self.channel)
185-
186-
self.logger.info("Channel {ch} (id {id}) is {status}.".format(
187-
ch=self.channel_data["token"], id=self.channel_data["id"],
188-
status=["offline", "online"][self.channel_data["online"]]
189-
))
190-
191-
self._init_commands()
192-
193193

194194
if __name__ == "__main__":
195-
cactus = Cactus(debug="debug", autorestart=False, log_to_file=True)
195+
cactus = Cactus(debug="info")
196196
cactus.run()

Diff for: data/config-template.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"channel": "CHANNEL",
3+
"autorestart": true,
34
"auth": {
45
"username": "USERNAME",
56
"password": "PASSWORD"

Diff for: data/stats-template.json

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
11
{
2-
"total-messages": 0,
3-
"unique-views": 0,
4-
"total-views": 0,
5-
"total-followers": 0,
6-
"total-subs": 0,
7-
"total-resubs": 0,
8-
"total-deleted-messages": 0,
9-
"total-banned-users": 0
2+
"status": "Not yet implemented."
103
}

Diff for: models.py

+35-19
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ def __call__(self, args, data):
129129
elif args[1] == "remove":
130130
if len(args) > 2:
131131
command = session.query(Command).filter_by(
132-
command=args[2]).first()
133-
if command:
132+
command=args[2])
133+
if command.first():
134134
command.delete()
135135
session.commit()
136136
return "Removed command !{}.".format(args[2])
@@ -177,7 +177,7 @@ def __call__(self, args, data):
177177
session.commit()
178178
return "Removed quote with ID {}.".format(args[2])
179179
return "Quote {} does not exist!".format(args[2])
180-
return "Invalid argument: '{}'".format(args[1])
180+
return "Invalid argument: '{}'.".format(args[1])
181181
return "Not enough arguments."
182182
else:
183183
if not session.query(Quote).count():
@@ -289,24 +289,40 @@ def __init__(self, update_config):
289289
def __call__(self, args, data=None):
290290
if len(args) >= 3:
291291
if args[1] == "length":
292-
self.update_config("spam_protection.maximum_message_length",
293-
int(args[2]))
294-
return "Maximum message length set to {}.".format(args[2])
292+
if args[2].isdigit():
293+
self.update_config(
294+
"spam_protection.maximum_message_length",
295+
int(args[2]))
296+
return "Maximum message length set to {}.".format(
297+
args[2])
298+
return "Invalid number: '{}'.".format(args[2])
295299
elif args[1] == "caps":
296-
self.update_config("spam_protection.maximum_message_capitals",
297-
int(args[2]))
298-
return "Maximum capitals per message set to {}.".format(
299-
args[2])
300+
if args[2].isdigit():
301+
self.update_config(
302+
"spam_protection.maximum_message_capitals",
303+
int(args[2]))
304+
return "Maximum capitals per message set to {}.".format(
305+
args[2])
306+
return "Invalid number: '{}'.".format(args[2])
300307
elif args[1] == "emotes":
301-
self.update_config("spam_protection.maximum_message_emotes",
302-
int(args[2]))
303-
return "Maximum emotes per message set to {}.".format(args[2])
304-
elif args[1] == "link":
305-
self.update_config("spam_protection.allow_links",
306-
bool(args[2]))
307-
return "Links are now {}allowed.".format("dis"*bool(args[2]))
308-
else:
309-
return "Not enough arguments"
308+
if args[2].isdigit():
309+
self.update_config(
310+
"spam_protection.maximum_message_emotes",
311+
int(args[2]))
312+
return "Maximum emotes per message set to {}.".format(
313+
args[2])
314+
return "Invalid number: '{}'.".format(args[2])
315+
elif args[1] == "links":
316+
if args[2].lower() in ("true", "false"):
317+
links_allowed = args[2].lower() == "true"
318+
self.update_config(
319+
"spam_protection.allow_links",
320+
links_allowed)
321+
return "Links are now {dis}allowed.".format(
322+
dis="dis"*(not links_allowed))
323+
return "Invalid true/false: '{}'.".format(args[2])
324+
return "Invalid argument: '{}'.".format(args[1])
325+
return "Not enough arguments."
310326

311327

312328
class ProCommand(Command):

0 commit comments

Comments
 (0)