Skip to content

Commit e0248e9

Browse files
authored
Merge pull request #184 from TotallyNotRobots/update-config
Add missing default config keys
2 parents dbeedf4 + dd800ac commit e0248e9

File tree

7 files changed

+179
-99
lines changed

7 files changed

+179
-99
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
- Add Python 3.8 to testing matrix
1010
- Add support for channel keys (#95)
1111
- Officially support channel keys across the whole bot
12+
- Add missing default config keys
1213
### Changed
1314
- Refactor tests to remove dependency on mock library
1415
- Change link_announcer.py to only warn on connection errors

cloudbot/bot.py

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
from cloudbot import clients
1919
from cloudbot.client import Client
2020
from cloudbot.config import Config
21-
from cloudbot.event import Event, CommandEvent, RegexEvent, EventType
21+
from cloudbot.event import CommandEvent, Event, EventType, RegexEvent
2222
from cloudbot.hook import Action
2323
from cloudbot.plugin import PluginManager
24-
from cloudbot.reloader import PluginReloader, ConfigReloader
25-
from cloudbot.util import database, formatting, async_util
24+
from cloudbot.reloader import ConfigReloader, PluginReloader
25+
from cloudbot.util import async_util, database, formatting
2626
from cloudbot.util.mapping import KeyFoldDict
2727

2828
logger = logging.getLogger("cloudbot")
@@ -58,28 +58,34 @@ def clean_name(n):
5858
:type n: str
5959
:rtype: str
6060
"""
61-
return re.sub('[^A-Za-z0-9_]+', '', n.replace(" ", "_"))
61+
return re.sub("[^A-Za-z0-9_]+", "", n.replace(" ", "_"))
6262

6363

6464
def get_cmd_regex(event):
6565
conn = event.conn
6666
is_pm = event.chan.lower() == event.nick.lower()
67-
command_prefix = re.escape(conn.config.get('command_prefix', '.'))
67+
command_prefix = re.escape(conn.config.get("command_prefix", "."))
6868
conn_nick = re.escape(event.conn.nick)
6969
cmd_re = re.compile(
7070
r"""
7171
^
7272
# Prefix or nick
7373
(?:
74-
(?P<prefix>[""" + command_prefix + r"""])""" + ('?' if is_pm else '') + r"""
74+
(?P<prefix>["""
75+
+ command_prefix
76+
+ r"""])"""
77+
+ ("?" if is_pm else "")
78+
+ r"""
7579
|
76-
""" + conn_nick + r"""[,;:]+\s+
80+
"""
81+
+ conn_nick
82+
+ r"""[,;:]+\s+
7783
)
7884
(?P<command>\w+) # Command
7985
(?:$|\s+)
8086
(?P<text>.*) # Text
8187
""",
82-
re.IGNORECASE | re.VERBOSE
88+
re.IGNORECASE | re.VERBOSE,
8389
)
8490
return cmd_re
8591

@@ -126,7 +132,7 @@ def __init__(self, loop=asyncio.get_event_loop()):
126132
self.memory = collections.defaultdict()
127133

128134
# declare and create data folder
129-
self.data_dir = os.path.abspath('data')
135+
self.data_dir = os.path.abspath("data")
130136
if not os.path.exists(self.data_dir):
131137
logger.debug("Data folder not found, creating.")
132138
os.mkdir(self.data_dir)
@@ -141,11 +147,15 @@ def __init__(self, loop=asyncio.get_event_loop()):
141147
self.config_reloading_enabled = reloading_conf.get("config_reloading", True)
142148

143149
# this doesn't REALLY need to be here but it's nice
144-
self.user_agent = self.config.get('user_agent', 'CloudBot/3.0 - CloudBot Refresh '
145-
'<https://github.com/CloudBotIRC/CloudBot/>')
150+
self.repo_link = self.config.get(
151+
"repo_link", "https://github.com/TotallyNotRobots/CloudBot/"
152+
)
153+
self.user_agent = self.config.get(
154+
"user_agent", "CloudBot/3.0 - CloudBot Refresh <{repo_link}>"
155+
).format(repo_link=self.repo_link)
146156

147157
# setup db
148-
db_path = self.config.get('database', 'sqlite:///cloudbot.db')
158+
db_path = self.config.get("database", "sqlite:///cloudbot.db")
149159
self.db_engine = create_engine(db_path)
150160
self.db_factory = sessionmaker(bind=self.db_engine)
151161
self.db_session = scoped_session(self.db_factory)
@@ -201,15 +211,14 @@ def register_client(self, name, cls):
201211

202212
def create_connections(self):
203213
""" Create a BotConnection for all the networks defined in the config """
204-
for config in self.config['connections']:
214+
for config in self.config["connections"]:
205215
# strip all spaces and capitalization from the connection name
206-
name = clean_name(config['name'])
207-
nick = config['nick']
216+
name = clean_name(config["name"])
217+
nick = config["nick"]
208218
_type = config.get("type", "irc")
209219

210220
self.connections[name] = self.get_client(_type)(
211-
self, _type, name, nick, config=config,
212-
channels=config['channels']
221+
self, _type, name, nick, config=config, channels=config["channels"]
213222
)
214223
logger.debug("[%s] Created connection.", name)
215224

@@ -283,7 +292,9 @@ async def _init_routine(self):
283292
conn.active = True
284293

285294
# Connect to servers
286-
await asyncio.gather(*[conn.try_connect() for conn in self.connections.values()], loop=self.loop)
295+
await asyncio.gather(
296+
*[conn.try_connect() for conn in self.connections.values()], loop=self.loop
297+
)
287298
logger.debug("Connections created.")
288299

289300
# Run a manual garbage collection cycle, to clean up any unused objects created during initialization
@@ -294,7 +305,7 @@ def load_clients(self):
294305
Load all clients from the "clients" directory
295306
"""
296307
scanner = Scanner(bot=self)
297-
scanner.scan(clients, categories=['cloudbot.client'])
308+
scanner.scan(clients, categories=["cloudbot.client"])
298309

299310
async def process(self, event):
300311
"""
@@ -331,7 +342,9 @@ def add_hook(hook, _event, _run_before=False):
331342
for raw_hook in self.plugin_manager.catch_all_triggers:
332343
# run catch-all coroutine hooks before all others - TODO: Make this a plugin argument
333344
run_before = not raw_hook.threaded
334-
if not add_hook(raw_hook, Event(hook=raw_hook, base_event=event), _run_before=run_before):
345+
if not add_hook(
346+
raw_hook, Event(hook=raw_hook, base_event=event), _run_before=run_before
347+
):
335348
# The hook has an action of Action.HALT* so stop adding new tasks
336349
break
337350

@@ -355,12 +368,16 @@ def add_hook(hook, _event, _run_before=False):
355368
cmd_match = get_cmd_regex(event).match(event.content)
356369

357370
if cmd_match:
358-
command_prefix = event.conn.config.get('command_prefix', '.')
359-
prefix = cmd_match.group('prefix') or command_prefix[0]
360-
command = cmd_match.group('command').lower()
361-
text = cmd_match.group('text').strip()
371+
command_prefix = event.conn.config.get("command_prefix", ".")
372+
prefix = cmd_match.group("prefix") or command_prefix[0]
373+
command = cmd_match.group("command").lower()
374+
text = cmd_match.group("text").strip()
362375
cmd_event = partial(
363-
CommandEvent, text=text, triggered_command=command, base_event=event, cmd_prefix=prefix
376+
CommandEvent,
377+
text=text,
378+
triggered_command=command,
379+
base_event=event,
380+
cmd_prefix=prefix,
364381
)
365382
if command in self.plugin_manager.commands:
366383
command_hook = self.plugin_manager.commands[command]
@@ -380,7 +397,9 @@ def add_hook(hook, _event, _run_before=False):
380397
command_event = cmd_event(hook=command_hook)
381398
add_hook(command_hook, command_event)
382399
else:
383-
commands = sorted(command for command, plugin in potential_matches)
400+
commands = sorted(
401+
command for command, plugin in potential_matches
402+
)
384403
txt_list = formatting.get_text_list(commands)
385404
event.notice("Possible matches: {}".format(txt_list))
386405

@@ -397,7 +416,9 @@ def add_hook(hook, _event, _run_before=False):
397416
regex_match = regex.search(event.content)
398417
if regex_match:
399418
regex_matched = True
400-
regex_event = RegexEvent(hook=regex_hook, match=regex_match, base_event=event)
419+
regex_event = RegexEvent(
420+
hook=regex_hook, match=regex_match, base_event=event
421+
)
401422
if not add_hook(regex_hook, regex_event):
402423
# The hook has an action of Action.HALT* so stop adding new tasks
403424
break

config.default.json

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,39 @@
33
{
44
"name": "esper",
55
"type": "irc",
6+
"auto_rejoin": false,
7+
"invite_join": true,
8+
"join_throttle": 0.4,
9+
"require_registered_channels": false,
610
"connection": {
711
"server": "irc.esper.net",
812
"port": 6667,
913
"ssl": false,
1014
"ignore_cert": true,
1115
"password": "",
1216
"timeout": 300,
13-
"client_cert": "cloudbot.pem"
17+
"client_cert": "cloudbot.pem",
18+
"bind_addr": "",
19+
"bind_port": 0
1420
},
1521
"ping_settings": {
1622
"interval": 60,
1723
"warn": 120,
1824
"timeout": 300
1925
},
26+
"user_agent": "CloudBot/3.0 - CloudBot Refresh <https://github.com/TotallyNotRobots/CloudBot/>",
27+
"reply_ping": true,
2028
"nick": "MyCloudBot",
2129
"user": "cloudbot",
30+
"realname": "CloudBot - https://git.io/CloudBot",
2231
"avoid_notices": false,
2332
"channels": [
2433
"#cloudbot",
2534
"#cloudbot2"
2635
],
36+
"mode": null,
37+
"oper_user": null,
38+
"oper_pw": null,
2739
"log_channel": "#MyAdminChannel",
2840
"disabled_commands": [],
2941
"acls": {},
@@ -40,6 +52,12 @@
4052
"nickserv_name": "nickserv",
4153
"nickserv_command": "IDENTIFY"
4254
},
55+
"keep_alive": false,
56+
"strip_newlines": true,
57+
"max_line_length": 510,
58+
"encoding": "utf-8",
59+
"encoding_errors": "replace",
60+
"strip_cmd_chars": "!.@;$",
4361
"ratelimit": {
4462
"max_tokens": 17.5,
4563
"restore_rate": 2.5,
@@ -110,9 +128,11 @@
110128
"cleverbot": "",
111129
"brewerydb": "",
112130
"alphavantage": "",
113-
"coinmarketcap": ""
131+
"coinmarketcap": "",
132+
"giphy": ""
114133
},
115134
"database": "sqlite:///cloudbot.db",
135+
"location_bias_cc": null,
116136
"plugin_loading": {
117137
"use_whitelist": false,
118138
"blacklist": [

plugins/core/core_connect.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@ def conn_nick(conn):
1313

1414

1515
@hook.connect(priority=20, clients="irc")
16-
def conn_user(conn):
16+
def conn_user(conn, bot):
1717
conn.cmd(
18-
"USER", conn.config.get('user', 'cloudbot'), "3", "*",
19-
conn.config.get('realname', 'CloudBot - https://git.io/CloudBot')
18+
"USER",
19+
conn.config.get("user", "cloudbot"),
20+
"3",
21+
"*",
22+
conn.config.get("realname", "CloudBot - {repo_link}").format(
23+
repo_link=bot.repo_link
24+
),
2025
)

plugins/github.py

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,62 @@
1+
import re
2+
13
import requests
24

35
from cloudbot import hook
4-
from cloudbot.util import web, formatting
6+
from cloudbot.util import formatting, web
7+
8+
shortcuts = {}
9+
url_re = re.compile(r"(?:https?://github\.com/)?(?P<owner>[^/]+)/(?P<repo>[^/]+)")
10+
11+
12+
def parse_url(url):
13+
"""
14+
>>> parse_url("https://github.com/TotallyNotRobots/CloudBot/")
15+
('TotallyNotRobots', 'CloudBot')
16+
>>> parse_url("TotallyNotRobots/CloudBot/")
17+
('TotallyNotRobots', 'CloudBot')
18+
>>> parse_url("TotallyNotRobots/CloudBot")
19+
('TotallyNotRobots', 'CloudBot')
20+
"""
21+
match = url_re.match(url)
22+
return match.group("owner"), match.group("repo")
23+
524

6-
shortcuts = {
7-
'cloudbot': 'CloudBotIRC/CloudBot'
8-
}
25+
@hook.on_start()
26+
def load_shortcuts(bot):
27+
shortcuts["cloudbot"] = parse_url(bot.repo_link)
928

1029

1130
@hook.command("ghissue", "issue")
1231
def issue_cmd(text):
1332
"""<username|repo> [number] - gets issue [number]'s summary, or the open issue count if no issue is specified"""
1433
args = text.split()
15-
repo = args[0] if args[0] not in shortcuts else shortcuts[args[0]]
34+
owner, repo = parse_url(args[0] if args[0] not in shortcuts else shortcuts[args[0]])
1635
issue = args[1] if len(args) > 1 else None
1736

1837
if issue:
19-
r = requests.get('https://api.github.com/repos/{}/issues/{}'.format(repo, issue))
38+
r = requests.get(
39+
"https://api.github.com/repos/{}/{}/issues/{}".format(owner, repo, issue)
40+
)
2041
r.raise_for_status()
2142
j = r.json()
2243

23-
url = web.try_shorten(j['html_url'], service='git.io')
24-
number = j['number']
25-
title = j['title']
26-
summary = formatting.truncate(j['body'].split('\n')[0], 25)
27-
if j['state'] == 'open':
28-
state = '\x033\x02Opened\x02\x0f by {}'.format(j['user']['login'])
44+
url = web.try_shorten(j["html_url"], service="git.io")
45+
number = j["number"]
46+
title = j["title"]
47+
summary = formatting.truncate(j["body"].split("\n")[0], 25)
48+
if j["state"] == "open":
49+
state = "\x033\x02Opened\x02\x0f by {}".format(j["user"]["login"])
2950
else:
30-
state = '\x034\x02Closed\x02\x0f by {}'.format(j['closed_by']['login'])
51+
state = "\x034\x02Closed\x02\x0f by {}".format(j["closed_by"]["login"])
3152

32-
return 'Issue #{} ({}): {} | {}: {}'.format(number, state, url, title, summary)
33-
r = requests.get('https://api.github.com/repos/{}/issues'.format(repo))
53+
return "Issue #{} ({}): {} | {}: {}".format(number, state, url, title, summary)
54+
r = requests.get("https://api.github.com/repos/{}/{}/issues".format(owner, repo))
3455
r.raise_for_status()
3556
j = r.json()
3657

3758
count = len(j)
3859
if count == 0:
39-
return 'Repository has no open issues.'
60+
return "Repository has no open issues."
4061

41-
return 'Repository has {} open issues.'.format(count)
62+
return "Repository has {} open issues.".format(count)

0 commit comments

Comments
 (0)