From fc4b726d1aeb44a4e0314485627a9c485fcacf42 Mon Sep 17 00:00:00 2001 From: dgw Date: Sat, 27 Oct 2018 18:49:31 -0500 Subject: [PATCH 01/42] version: remove unused regex The `log_line` regex was orphaned in ab05f11 and hasn't been used since. That was almost five years ago. No `re` stuff needed in the module now. --- sopel/modules/version.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sopel/modules/version.py b/sopel/modules/version.py index 79aaeebb48..867662c696 100644 --- a/sopel/modules/version.py +++ b/sopel/modules/version.py @@ -12,14 +12,10 @@ from datetime import datetime from sopel import __version__ as release from sopel.module import commands, intent, rate -import re from os import path import platform -log_line = re.compile(r'\S+ (\S+) (.*? <.*?>) (\d+) (\S+)\tcommit[^:]*: (.+)') - - def git_info(): repo = path.join(path.dirname(path.dirname(path.dirname(__file__))), '.git') head = path.join(repo, 'HEAD') From 51b3b2c14583a7ba75fd115bc1b1a6b74d617741 Mon Sep 17 00:00:00 2001 From: Sujeet Akula Date: Fri, 4 May 2018 12:03:20 +1000 Subject: [PATCH 02/42] reload: old_callables is orphaned code from 5 years ago MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Actually, it's from 6 years ago now. — dgw, rebasing onto current master Co-Authored-By: dgw --- sopel/modules/reload.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sopel/modules/reload.py b/sopel/modules/reload.py index 9b4592880a..caa4a286db 100644 --- a/sopel/modules/reload.py +++ b/sopel/modules/reload.py @@ -11,7 +11,7 @@ import collections import sys import time -from sopel.tools import stderr, iteritems +from sopel.tools import stderr, itervalues import sopel.loader import sopel.module import subprocess @@ -62,8 +62,7 @@ def reload_module_tree(bot, name, seen=None, silent=False): if name not in seen: seen[name] = [] - old_callables = {} - for obj_name, obj in iteritems(vars(old_module)): + for obj in itervalues(vars(old_module)): if callable(obj): if (getattr(obj, '__name__', None) == 'shutdown' and obj in bot.shutdown_methods): @@ -95,12 +94,6 @@ def reload_module_tree(bot, name, seen=None, silent=False): if name not in modules: return # Only reload the top-level module, once recursion is finished - # Also remove all references to sopel callables from top level of the - # module, so that they will not get loaded again if reloading the - # module does not override them. - for obj_name in old_callables.keys(): - delattr(old_module, obj_name) - # Also delete the setup function # Sub-modules shouldn't have setup functions, so do after the recursion check if hasattr(old_module, "setup"): From 4bde7a46295e0111a90fc9397a63515b7411e84d Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:56:49 -0500 Subject: [PATCH 03/42] admin: Operation Cruft Cleanup --- sopel/modules/admin.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sopel/modules/admin.py b/sopel/modules/admin.py index 5838cec19b..668f8be682 100644 --- a/sopel/modules/admin.py +++ b/sopel/modules/admin.py @@ -5,7 +5,7 @@ (yanovich.net) Copyright © 2012, Elad Alfassa, Copyright 2013, Ari Koivula - +Copyright 2019, Florian Strzelecki, https://github.com/Exirel Licensed under the Eiffel Forum License 2. https://sopel.chat @@ -212,9 +212,7 @@ def me(bot, trigger): @sopel.module.rule('.*') @sopel.module.priority('low') def invite_join(bot, trigger): - """ - Join a channel Sopel is invited to, if the inviter is an admin. - """ + """Join a channel Sopel is invited to, if the inviter is an admin.""" if trigger.admin or bot.config.admin.auto_accept_invite: bot.join(trigger.args[1]) return From a970772cbef81f01d46467de0fe655022a1029fe Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:54:13 -0500 Subject: [PATCH 04/42] adminchannel: Operation Cruft Cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Really did a number on the docstrings here. Will probably have to update a pending PR or two based on these changes… --- sopel/modules/adminchannel.py | 66 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/sopel/modules/adminchannel.py b/sopel/modules/adminchannel.py index cd7784897e..99024ca027 100644 --- a/sopel/modules/adminchannel.py +++ b/sopel/modules/adminchannel.py @@ -1,12 +1,20 @@ # coding=utf-8 -# Copyright 2010-2011, Michael Yanovich, Alek Rollyson, and Elsie Powell -# Copyright © 2012, Elad Alfassa -# Licensed under the Eiffel Forum License 2. +""" +adminchannel.py - Sopel Channel Admin Module +Copyright 2010-2011, Michael Yanovich, Alek Rollyson, and Elsie Powell +Copyright © 2012, Elad Alfassa +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division import re + from sopel import formatting -from sopel.module import commands, priority, OP, HALFOP, require_privilege, require_chanmsg +from sopel.module import ( + commands, example, priority, OP, HALFOP, require_privilege, require_chanmsg +) from sopel.tools import Identifier @@ -24,9 +32,7 @@ def default_mask(trigger): @commands('kick') @priority('high') def kick(bot, trigger): - """ - Kick a user from the channel. - """ + """Kick a user from the channel.""" if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP: return bot.reply("I'm not a channel operator!") text = trigger.group().split() @@ -75,9 +81,9 @@ def configureHostMask(mask): @commands('ban') @priority('high') def ban(bot, trigger): - """ - This give admins the ability to ban a user. - The bot must be a Channel Operator for this command to work. + """Ban a user from the channel + + The bot must be a channel operator for this command to work. """ if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP: return bot.reply("I'm not a channel operator!") @@ -103,9 +109,9 @@ def ban(bot, trigger): @require_privilege(OP, 'You are not a channel operator.') @commands('unban') def unban(bot, trigger): - """ - This give admins the ability to unban a user. - The bot must be a Channel Operator for this command to work. + """Unban a user from the channel + + The bot must be a channel operator for this command to work. """ if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP: return bot.reply("I'm not a channel operator!") @@ -131,9 +137,9 @@ def unban(bot, trigger): @require_privilege(OP, 'You are not a channel operator.') @commands('quiet') def quiet(bot, trigger): - """ - This gives admins the ability to quiet a user. - The bot must be a Channel Operator for this command to work. + """Quiet a user + + The bot must be a channel operator for this command to work. """ if bot.channels[trigger.sender].privileges[bot.nick] < OP: return bot.reply("I'm not a channel operator!") @@ -159,9 +165,9 @@ def quiet(bot, trigger): @require_privilege(OP, 'You are not a channel operator.') @commands('unquiet') def unquiet(bot, trigger): - """ - This gives admins the ability to unquiet a user. - The bot must be a Channel Operator for this command to work. + """Unquiet a user + + The bot must be a channel operator for this command to work. """ if bot.channels[trigger.sender].privileges[bot.nick] < OP: return bot.reply("I'm not a channel operator!") @@ -186,12 +192,12 @@ def unquiet(bot, trigger): @require_chanmsg @require_privilege(OP, 'You are not a channel operator.') @commands('kickban', 'kb') +@example('.kickban [#chan] user1 user!*@* get out of here') @priority('high') def kickban(bot, trigger): - """ - This gives admins the ability to kickban a user. - The bot must be a Channel Operator for this command to work. - .kickban [#chan] user1 user!*@* get out of here + """Kick and ban a user from the channel + + The bot must be a channel operator for this command to work. """ if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP: return bot.reply("I'm not a channel operator!") @@ -223,9 +229,9 @@ def kickban(bot, trigger): @require_privilege(OP, 'You are not a channel operator.') @commands('topic') def topic(bot, trigger): - """ - This gives ops the ability to change the topic. - The bot must be a Channel Operator for this command to work. + """Change the channel topic + + The bot must be a channel operator for this command to work. """ if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP: return bot.reply("I'm not a channel operator!") @@ -258,9 +264,11 @@ def topic(bot, trigger): @require_privilege(OP, 'You are not a channel operator.') @commands('tmask') def set_mask(bot, trigger): - """ - Set the mask to use for .topic in the current channel. {} is used to allow - substituting in chunks of text. + """Set the topic mask to use for the current channel + + Within the topic mask, {} is used to allow substituting in chunks of text. + + This mask is used when running the 'topic' command. """ bot.db.set_channel_value(trigger.sender, 'topic_mask', trigger.group(2)) bot.say("Gotcha, " + trigger.nick) From 9cc961eb0b17d9f0877bfbcefd03c2dc80ab4455 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:48:53 -0500 Subject: [PATCH 05/42] announce: Operation Cruft Cleanup --- sopel/modules/announce.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sopel/modules/announce.py b/sopel/modules/announce.py index 80f68a1fd0..9de9f2d4b4 100644 --- a/sopel/modules/announce.py +++ b/sopel/modules/announce.py @@ -1,9 +1,11 @@ # coding=utf-8 """ -announce.py - Send a message to all channels +announce.py - Sopel Announcement Module +Sends announcements to all channels the bot has joined. Copyright © 2013, Elad Alfassa, Licensed under the Eiffel Forum License 2. +https://sopel.chat """ from __future__ import unicode_literals, absolute_import, print_function, division @@ -14,9 +16,7 @@ @example('.announce Some important message here') @require_admin('Sorry, I can\'t let you do that', reply=True) def announce(bot, trigger): - """ - Send an announcement to all channels the bot is in - """ + """Send an announcement to all channels the bot is in""" for channel in bot.channels: bot.msg(channel, '[ANNOUNCEMENT] %s' % trigger.group(2)) bot.reply('Announce complete.') From 537d73cbc2748391efcc8d5fa61fd5c54ca6e656 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:48:46 -0500 Subject: [PATCH 06/42] bugzilla: Operation Cruft Cleanup --- sopel/modules/bugzilla.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sopel/modules/bugzilla.py b/sopel/modules/bugzilla.py index 42e9e66545..dbddce375c 100644 --- a/sopel/modules/bugzilla.py +++ b/sopel/modules/bugzilla.py @@ -1,14 +1,16 @@ # coding=utf-8 -"""Bugzilla issue reporting module - +""" +bugzilla.py - Sopel Bugzilla Module Copyright 2013-2015, Embolalia, embolalia.com Licensed under the Eiffel Forum License 2. + +https://sopel.chat """ from __future__ import unicode_literals, absolute_import, print_function, division import re -import requests +import requests import xmltodict from sopel.config.types import StaticSection, ListAttribute From 0092a8dfe4c8b6a07fd156413a515495c65ef41f Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:46:55 -0500 Subject: [PATCH 07/42] calc: Operation Cruft Cleanup --- sopel/modules/calc.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sopel/modules/calc.py b/sopel/modules/calc.py index 9cec9dc917..c1dade8a3a 100644 --- a/sopel/modules/calc.py +++ b/sopel/modules/calc.py @@ -8,10 +8,12 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division +import sys + +from requests import get + from sopel.module import commands, example from sopel.tools.calculation import eval_equation -from requests import get -import sys if sys.version_info.major < 3: from urllib import quote as _quote From b10b3a783f46229986c9fb45f9047da586b87a4e Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:46:03 -0500 Subject: [PATCH 08/42] clock: Operation Cruft Cleanup --- sopel/modules/clock.py | 45 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/sopel/modules/clock.py b/sopel/modules/clock.py index 7fcee2c5ec..e9032f6572 100644 --- a/sopel/modules/clock.py +++ b/sopel/modules/clock.py @@ -1,20 +1,25 @@ # coding=utf-8 -# Copyright 2008-9, Sean B. Palmer, inamidst.com -# Copyright 2012, Elsie Powell, embolalia.com -# Licensed under the Eiffel Forum License 2. +""" +clock.py - Sopel Clock Module +Copyright 2008-9, Sean B. Palmer, inamidst.com +Copyright 2012, Elsie Powell, embolalia.com +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division -try: - import pytz -except ImportError: - pytz = None - from sopel.module import commands, example, OP from sopel.tools.time import ( get_timezone, format_time, validate_format, validate_timezone ) from sopel.config.types import StaticSection, ValidatedAttribute +try: + import pytz +except ImportError: + pytz = None + class TimeSection(StaticSection): tz = ValidatedAttribute( @@ -97,9 +102,7 @@ def update_user(bot, trigger): @commands('gettz', 'gettimezone') @example('.gettz [nick]') def get_user_tz(bot, trigger): - """ - Gets a user's preferred time zone; will show yours if no user specified. - """ + """Gets a user's preferred time zone; will show yours if no user specified.""" if not pytz: bot.reply("Sorry, I don't have timezone support installed.") else: @@ -125,8 +128,8 @@ def update_user_format(bot, trigger): """ tformat = trigger.group(2) if not tformat: - bot.reply("What format do you want me to use? Try using" - " http://strftime.net to make one.") + bot.reply("What format do you want me to use? Try using " + "http://strftime.net to make one.") return tz = get_timezone(bot.db, bot.config, None, trigger.nick, trigger.sender) @@ -140,8 +143,8 @@ def update_user_format(bot, trigger): try: timef = format_time(db=bot.db, zone=tz, nick=trigger.nick) except Exception: # TODO: Be specific - bot.reply("That format doesn't work. Try using" - " http://strftime.net to make one.") + bot.reply("That format doesn't work. Try using " + "http://strftime.net to make one.") # New format doesn't work. Revert save in database. bot.db.set_nick_value(trigger.nick, 'time_format', old_format) return @@ -153,9 +156,7 @@ def update_user_format(bot, trigger): @commands('gettimeformat', 'gettf') @example('.gettf [nick]') def get_user_format(bot, trigger): - """ - Gets a user's preferred time format; will show yours if no user specified. - """ + """Gets a user's preferred time format; will show yours if no user specified.""" nick = trigger.group(2) if not nick: nick = trigger.nick @@ -174,9 +175,7 @@ def get_user_format(bot, trigger): @commands('setchanneltz', 'setctz') @example('.setctz America/New_York') def update_channel(bot, trigger): - """ - Set the preferred timezone for the channel. - """ + """Set the preferred timezone for the channel.""" if bot.channels[trigger.sender].privileges[trigger.nick] < OP: return elif not pytz: @@ -236,8 +235,8 @@ def update_channel_format(bot, trigger): tformat = trigger.group(2) if not tformat: - bot.reply("What format do you want me to use? Try using" - " http://strftime.net to make one.") + bot.reply("What format do you want me to use? Try using " + "http://strftime.net to make one.") tz = get_timezone(bot.db, bot.config, None, None, trigger.sender) From 07dcdbcc034b5a0fe40da11c89cb24cc78d5f29e Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:42:45 -0500 Subject: [PATCH 09/42] countdown: Operation Cruft Cleanup Also added `help_prefix` to usage outputs. --- sopel/modules/countdown.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sopel/modules/countdown.py b/sopel/modules/countdown.py index 12bb99dd88..d2a9146fde 100644 --- a/sopel/modules/countdown.py +++ b/sopel/modules/countdown.py @@ -8,18 +8,18 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -from sopel.module import commands, NOLIMIT import datetime +from sopel.module import commands, NOLIMIT + @commands('countdown') def generic_countdown(bot, trigger): - """ - .countdown - displays a countdown to a given date. - """ + """.countdown - displays a countdown to a given date.""" text = trigger.group(2) if not text: - bot.say("Please use correct format: .countdown 2012 12 21") + bot.say("Please use correct format: {}countdown 2012 12 21" + .format(bot.config.core.help_prefix)) return NOLIMIT text = trigger.group(2).split() if text and (len(text) == 3 and text[0].isdigit() and @@ -28,11 +28,13 @@ def generic_countdown(bot, trigger): diff = (datetime.datetime(int(text[0]), int(text[1]), int(text[2])) - datetime.datetime.today()) except Exception: # TODO: Be specific - bot.say("Please use correct format: .countdown 2012 12 21") + bot.say("Please use correct format: {}countdown 2012 12 21" + .format(bot.config.core.help_prefix)) return NOLIMIT bot.say(str(diff.days) + " days, " + str(diff.seconds // 3600) + " hours and " + str(diff.seconds % 3600 // 60) + " minutes until " + text[0] + " " + text[1] + " " + text[2]) else: - bot.say("Please use correct format: .countdown 2012 12 21") + bot.say("Please use correct format: {}countdown 2012 12 21" + .format(bot.config.core.help_prefix)) return NOLIMIT From 1cfe818dfba5bd84abe0bb7d5bb65ff44f0738ab Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:40:37 -0500 Subject: [PATCH 10/42] currency: Operation Cruft Cleanup Added a missing command docstring, too. --- sopel/modules/currency.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sopel/modules/currency.py b/sopel/modules/currency.py index 0bb89de9de..5d7488c25b 100644 --- a/sopel/modules/currency.py +++ b/sopel/modules/currency.py @@ -1,13 +1,20 @@ # coding=utf-8 -# Copyright 2013 Elsie Powell, embolalia.com -# Licensed under the Eiffel Forum License 2 +""" +currency.py - Sopel Currency Conversion Module +Copyright 2013, Elsie Powell, embolalia.com +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division import re from requests import get + from sopel.module import commands, example, NOLIMIT + # The Canadian central bank has better exchange rate data than the Fed, the # Bank of England, or the European Central Bank. Who knew? base_url = 'https://www.bankofcanada.ca/valet/observations/FX{}CAD/json' @@ -83,6 +90,7 @@ def display(bot, amount, of, to): @commands('btc', 'bitcoin') @example('.btc 20 EUR') def bitcoin(bot, trigger): + """Convert between Bitcoin and a fiat currency""" # if 2 args, 1st is number and 2nd is currency. If 1 arg, it's either the number or the currency. to = trigger.group(4) amount = trigger.group(3) From fc97d3ffa5b86c6341dac86d115689b229423b04 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:38:56 -0500 Subject: [PATCH 11/42] dice: Operation Cruft Cleanup --- sopel/modules/dice.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sopel/modules/dice.py b/sopel/modules/dice.py index 8b741aca45..56bfd99f81 100644 --- a/sopel/modules/dice.py +++ b/sopel/modules/dice.py @@ -1,17 +1,17 @@ # coding=utf-8 """ -dice.py - Dice Module +dice.py - Sopel Dice Module Copyright 2010-2013, Dimitri "Tyrope" Molenaars, TyRope.nl Copyright 2013, Ari Koivula, Licensed under the Eiffel Forum License 2. -https://sopel.chat/ +https://sopel.chat """ from __future__ import unicode_literals, absolute_import, print_function, division +import operator import random import re -import operator import sopel.module from sopel.tools.calculation import eval_equation @@ -183,7 +183,7 @@ def roll(bot, trigger): number of lowest dice to be dropped from the result. N is the constant to be applied to the end result. """ - # This regexp is only allowed to have one captured group, because having + # This regexp is only allowed to have one capture group, because having # more would alter the output of re.findall. dice_regexp = r"-?\d*[dD]-?\d+(?:[vV]-?\d+)?" @@ -254,9 +254,7 @@ def _get_pretty_str(dice): re=True) @sopel.module.example(".choose a", 'Your options: a. My choice: a') def choose(bot, trigger): - """ - .choice option1|option2|option3 - Makes a difficult choice easy. - """ + """.choice option1|option2|option3 - Makes a difficult choice easy.""" if not trigger.group(2): return bot.reply('I\'d choose an option, but you didn\'t give me any.') choices = [trigger.group(2)] From 3961045f8b7fc9e2585590b41dfc839cc68cc913 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:37:46 -0500 Subject: [PATCH 12/42] emoticons: Operation Cruft Cleanup --- sopel/modules/emoticons.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sopel/modules/emoticons.py b/sopel/modules/emoticons.py index ee1ea9174d..99af5ff9e1 100644 --- a/sopel/modules/emoticons.py +++ b/sopel/modules/emoticons.py @@ -7,6 +7,7 @@ https://sopel.chat """ from __future__ import unicode_literals, absolute_import, print_function, division + from sopel.module import commands, example From 9e7e4b01bcfd4ae99d69879a0611b819a73125f4 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:37:11 -0500 Subject: [PATCH 13/42] etymology: Operation Cruft Cleanup --- sopel/modules/etymology.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sopel/modules/etymology.py b/sopel/modules/etymology.py index 503f8fe6a4..81b95cbc4f 100644 --- a/sopel/modules/etymology.py +++ b/sopel/modules/etymology.py @@ -10,9 +10,12 @@ from __future__ import unicode_literals, absolute_import, print_function, division from re import sub + from requests import get + from sopel import web from sopel.module import commands, example, NOLIMIT + try: # Python 2.7 from HTMLParser import HTMLParser From be184648c295f03705df66fdb6f33f9e16fbbc1a Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:36:05 -0500 Subject: [PATCH 14/42] find: Operation Cruft Cleanup It felt good to address that TODO comment from years ago. --- sopel/modules/find.py | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/sopel/modules/find.py b/sopel/modules/find.py index c89bd57b89..c8e1ea62ea 100644 --- a/sopel/modules/find.py +++ b/sopel/modules/find.py @@ -1,13 +1,16 @@ # coding=utf-8 -"""Sopel Spelling correction module - +""" +find.py - Sopel Spelling Correction Module This module will fix spelling errors if someone corrects them using the sed notation (s///) commonly found in vi/vim. + +Copyright 2011, Michael Yanovich, yanovich.net +Copyright 2013, Elsie Powell, embolalia.com +Includes contributions from: dgw, Matt Meinwald, and Morgan Goose +Licensed under the Eiffel Forum License 2. + +https://sopel.chat """ -# Copyright 2011, Michael Yanovich, yanovich.net -# Copyright 2013, Elsie Powell, embolalia.com -# Licensed under the Eiffel Forum License 2. -# Contributions from: Matt Meinwald and Morgan Goose from __future__ import unicode_literals, absolute_import, print_function, division import re @@ -25,10 +28,8 @@ def setup(bot): @priority('low') def collectlines(bot, trigger): """Create a temporary log of what people say""" - - # Don't log things in PM if trigger.is_privmsg: - return + return # Don't log things in PM # Add a log for the channel and nick, if there isn't already one if trigger.sender not in bot.memory['find_lines']: @@ -84,11 +85,8 @@ def findandreplace(bot, trigger): if Identifier(rnick) not in search_dict[trigger.sender]: return - # TODO rest[0] is find, rest[1] is replace. These should be made variables of - # their own at some point. - rest = [trigger.group(2), trigger.group(3)] - rest[0] = rest[0].replace(r'\/', '/') - rest[1] = rest[1].replace(r'\/', '/') + old = trigger.group(2).replace(r'\/', '/') + new = trigger.group(3).replace(r'\/', '/') me = False # /me command flags = (trigger.group(4) or '') @@ -98,16 +96,16 @@ def findandreplace(bot, trigger): else: count = 1 - # repl is a lambda function which performs the substitution. i flag turns - # off case sensitivity. re.U turns on unicode replacement. + # repl is a dynamically defined function which performs the substitution. + # i flag turns off case sensitivity. re.U turns on unicode replacement. if 'i' in flags: - regex = re.compile(re.escape(rest[0]), re.U | re.I) + regex = re.compile(re.escape(old), re.U | re.I) def repl(s): - return re.sub(regex, rest[1], s, count == 1) + return re.sub(regex, new, s, count == 1) else: def repl(s): - return s.replace(rest[0], rest[1], count) + return s.replace(old, new, count) # Look back through the user's lines in the channel until you find a line # where the replacement works From df348be2a0c57c64cb65678c0e940edacd04cddf Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:29:40 -0500 Subject: [PATCH 15/42] find_updates: Operation Cruft Cleanup --- sopel/modules/find_updates.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sopel/modules/find_updates.py b/sopel/modules/find_updates.py index 300571d343..8038a5e9da 100644 --- a/sopel/modules/find_updates.py +++ b/sopel/modules/find_updates.py @@ -1,19 +1,23 @@ # coding=utf-8 -"""Update checking module for Sopel. - +""" +find_updates.py - Sopel Update Check Module This is separated from version.py, so that it can be easily overridden by distribution packagers, and they can check their repositories rather than the Sopel website. +Copyright 2014, Elsie Powell, embolalia.com +Licensed under the Eiffel Forum License 2. + +https://sopel.chat """ -# Copyright 2014, Elsie Powell, embolalia.com -# Licensed under the Eiffel Forum License 2. from __future__ import unicode_literals, absolute_import, print_function, division +import requests + import sopel import sopel.module -import requests import sopel.tools + wait_time = 24 * 60 * 60 # check once per day startup_check_run = False version_url = 'https://sopel.chat/latest.json' From b5bb441c92296fcf2e3d660c9681b447750226ec Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:27:12 -0500 Subject: [PATCH 16/42] help: Operation Cruft Cleanup Minimal changes, but we are NOT storing stuff in the config. That's what the DB is for. Updated the offending comment so nobody actually tries to implement storing things they shouldn't in the config file. --- sopel/modules/help.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sopel/modules/help.py b/sopel/modules/help.py index f1cc6faeb0..c04db6c9e5 100644 --- a/sopel/modules/help.py +++ b/sopel/modules/help.py @@ -10,14 +10,15 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -import textwrap import collections import requests +import textwrap from sopel.logger import get_logger from sopel.module import commands, rule, example, priority -logger = get_logger(__name__) + +LOGGER = get_logger(__name__) def setup(bot): @@ -55,7 +56,7 @@ def msgfun(l): else: # This'll probably catch most cases, without having to spend the time # actually creating the list first. Maybe worth storing the link and a - # heuristic in config, too, so it persists across restarts. Would need a + # heuristic in the DB, too, so it persists across restarts. Would need a # command to regenerate, too... if 'command-list' in bot.memory and bot.memory['command-list'][0] == len(bot.command_groups): url = bot.memory['command-list'][1] @@ -89,14 +90,14 @@ def create_list(bot, msg): result = requests.post('https://clbin.com/', data={'clbin': msg}) except requests.RequestException: bot.say("Sorry! Something went wrong.") - logger.exception("Error posting commands") + LOGGER.exception("Error posting commands") return result = result.text if "https://clbin.com/" in result: return result else: bot.say("Sorry! Something went wrong.") - logger.error("Invalid result %s", result) + LOGGER.error("Invalid result %s", result) return From 4fac19064acb326c939a58e8af65e01c82df2c37 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:26:03 -0500 Subject: [PATCH 17/42] instagram: Operation Cruft Cleanup --- sopel/modules/instagram.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sopel/modules/instagram.py b/sopel/modules/instagram.py index a525115f9f..25cd134200 100644 --- a/sopel/modules/instagram.py +++ b/sopel/modules/instagram.py @@ -1,6 +1,6 @@ # coding=utf-8 """ -instagram.py - API-key-less Instagram module for Sopel +instagram.py - Sopel Instagram Module Copyright 2018, Sopel contributors Licensed under the Eiffel Forum License 2. @@ -8,8 +8,8 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -import re from datetime import datetime +import re from requests import get From b8f946152aac7abae741847beba2bcc9ec098059 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:24:49 -0500 Subject: [PATCH 18/42] ip: Operation Cruft Cleanup --- sopel/modules/ip.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/sopel/modules/ip.py b/sopel/modules/ip.py index 7c807a401f..0024b3fbbd 100644 --- a/sopel/modules/ip.py +++ b/sopel/modules/ip.py @@ -1,8 +1,12 @@ # coding=utf-8 -"""GeoIP lookup module""" -# Copyright 2011, Dimitri Molenaars, TyRope.nl, -# Copyright © 2013, Elad Alfassa -# Licensed under the Eiffel Forum License 2. +""" +ip.py - Sopel GeoIP Lookup Module +Copyright 2011, Dimitri Molenaars, TyRope.nl, +Copyright © 2013, Elad Alfassa +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division @@ -28,6 +32,7 @@ except ImportError: pass + LOGGER = get_logger(__name__) @@ -52,7 +57,7 @@ def setup(bot): def _decompress(source, target, delete_after_decompression=True): - """ Decompress just the database from the archive """ + """Decompress just the database from the archive""" # https://stackoverflow.com/a/16452962 tar = tarfile.open(source) for member in tar.getmembers(): @@ -64,7 +69,7 @@ def _decompress(source, target, delete_after_decompression=True): def _find_geoip_db(bot): - """ Find the GeoIP database """ + """Find the GeoIP database""" config = bot.config if config.ip.GeoIP_db_path: cities_db = os.path.join(config.ip.GeoIP_db_path, 'GeoLite2-City.mmdb') From afc694fd7eb8c8a9dbe27318c5214a7d0d30a103 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:22:08 -0500 Subject: [PATCH 19/42] ipython: Operation Cruft Cleanup The usual header/docstring cleanup aside, this also tweaks the code style a bit to take advantage of `dict.get()` semantics instead of first checking `bot.memory` for a key, then reading it. --- sopel/modules/ipython.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sopel/modules/ipython.py b/sopel/modules/ipython.py index e9cc0aac1b..51fb266c2f 100644 --- a/sopel/modules/ipython.py +++ b/sopel/modules/ipython.py @@ -1,16 +1,18 @@ # coding=utf-8 """ -ipython.py - sopel ipython console! +ipython.py - Sopel IPython Console Module Copyright © 2014, Elad Alfassa Licensed under the Eiffel Forum License 2. -Sopel: https://sopel.chat/ +https://sopel.chat """ from __future__ import unicode_literals, absolute_import, print_function, division +import sys + import sopel import sopel.module -import sys + if sys.version_info.major >= 3: # Backup stderr/stdout wrappers old_stdout = sys.stdout @@ -33,17 +35,16 @@ sys.stdout = old_stdout sys.stderr = old_stderr + console = None @sopel.module.commands('console') @sopel.module.require_admin('Only admins can start the interactive console') def interactive_shell(bot, trigger): - """ - Starts an interactive IPython console - """ + """Starts an interactive IPython console""" global console - if 'iconsole_running' in bot.memory and bot.memory['iconsole_running']: + if bot.memory.get('iconsole_running', False): bot.say('Console already running') return if not sys.__stdout__.isatty(): From 99486f7094cff73ae4baba4fdc7ac4c7e32d725a Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:17:40 -0500 Subject: [PATCH 20/42] isup: Operation Cruft Cleanup Guessed copyright date by tracing back to when this module was added to Embolalia's Phenny fork: https://github.com/embolalia/phenny/commit/79f21eb416b030b0047496f353f785b1ef7a741c --- sopel/modules/isup.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sopel/modules/isup.py b/sopel/modules/isup.py index 33679cb776..11171ba975 100644 --- a/sopel/modules/isup.py +++ b/sopel/modules/isup.py @@ -1,13 +1,18 @@ # coding=utf-8 -"""Simple website status check with isup.me""" -# Author: Elsie Powell http://embolalia.com +""" +isup.py - Sopel Website Status Check Module +Copyright 2011, Elsie Powell http://embolalia.com +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division import requests -from sopel.module import commands - from requests.exceptions import SSLError +from sopel.module import commands + @commands('isup', 'isupinsecure') def isup(bot, trigger): From e4b4aa4110dcf5837c50461b25ca62b9dc8ab8ff Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:14:37 -0500 Subject: [PATCH 21/42] lmgtfy: Operation Cruft Cleanup --- sopel/modules/lmgtfy.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sopel/modules/lmgtfy.py b/sopel/modules/lmgtfy.py index 3e5e960cb1..e1a4a37097 100644 --- a/sopel/modules/lmgtfy.py +++ b/sopel/modules/lmgtfy.py @@ -1,6 +1,6 @@ # coding=utf-8 """ -lmgtfy.py - Sopel Let me Google that for you module +lmgtfy.py - Sopel Let Me Google That For You Module Copyright 2013, Dimitri Molenaars http://tyrope.nl/ Licensed under the Eiffel Forum License 2. @@ -17,8 +17,7 @@ @example('.lmgtfy sopel bot', 'https://lmgtfy.com/?q=sopel+bot') @example('.lmgtfy', 'https://www.google.com/') def googleit(bot, trigger): - """Let me just... google that for you.""" - # No input - if not trigger.group(2): + """Let me just… Google that for you.""" + if not trigger.group(2): # No input return bot.say('https://www.google.com/') bot.say('https://lmgtfy.com/?q=' + quote(trigger.group(2).replace(' ', '+'), '+')) From db2f0138c1dedc31f70d9333d1b6aae61a05eb15 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:12:59 -0500 Subject: [PATCH 22/42] meetbot: Operation Cruft Cleanup --- sopel/modules/meetbot.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sopel/modules/meetbot.py b/sopel/modules/meetbot.py index b5160f1947..552937e501 100644 --- a/sopel/modules/meetbot.py +++ b/sopel/modules/meetbot.py @@ -1,24 +1,26 @@ # coding=utf-8 """ -meetbot.py - Sopel meeting logger module +meetbot.py - Sopel Meeting Logger Module +This module is an attempt to implement at least some of the functionality of Debian's meetbot Copyright © 2012, Elad Alfassa, Licensed under the Eiffel Forum License 2. -This module is an attempt to implement at least some of the functionallity of Debian's meetbot +https://sopel.chat """ from __future__ import unicode_literals, absolute_import, print_function, division -import time +import codecs import os +import time + from sopel.config.types import ( StaticSection, FilenameAttribute, ValidatedAttribute ) from sopel.formatting import bold -from sopel.web import quote -from sopel.modules.url import find_title from sopel.module import example, commands, rule, priority +from sopel.modules.url import find_title from sopel.tools import Ddict, Identifier -import codecs +from sopel.web import quote class MeetbotSection(StaticSection): From a7550d4f70541e8fd38448db1901b7e23a96c7d2 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:08:17 -0500 Subject: [PATCH 23/42] ping: Operation Cruft Cleanup Unified style of header with the other modules. Had to guess at year of authorship by browsing to the Phenny repo (but the module might be older even than that). Also added a couple more punctuation options for `hello()` to use. --- sopel/modules/ping.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sopel/modules/ping.py b/sopel/modules/ping.py index 87a136913a..3de2e2ddae 100644 --- a/sopel/modules/ping.py +++ b/sopel/modules/ping.py @@ -1,19 +1,21 @@ # coding=utf-8 """ ping.py - Sopel Ping Module -Author: Sean B. Palmer, inamidst.com -About: https://sopel.chat +Copyright 2008 (?), Sean B. Palmer, inamidst.com + +https://sopel.chat """ from __future__ import unicode_literals, absolute_import, print_function, division import random + from sopel.module import rule, priority, thread @rule(r'(?i)(hi|hello|hey),? $nickname[ \t]*$') def hello(bot, trigger): greeting = random.choice(('Hi', 'Hey', 'Hello')) - punctuation = random.choice(('', '!')) + punctuation = random.choice(('', '.', '…', '!')) bot.say(greeting + ' ' + trigger.nick + punctuation) From 95054e9e318a40431ec46814f56ee0bb31f8d2c5 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:04:52 -0500 Subject: [PATCH 24/42] pronouns: Operation Cruft Cleanup On top of updating the comment pointing to the pronoun.is JSON API pull request we'd like to see merged (the old one was merged into a feature branch), this also fixes some typos and handles the example commands properly using the help prefix set in the bot's config. Oh, and it also removed an unused global logger. You know, actual cruft. --- sopel/modules/pronouns.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sopel/modules/pronouns.py b/sopel/modules/pronouns.py index 7df6604858..825765fa0a 100644 --- a/sopel/modules/pronouns.py +++ b/sopel/modules/pronouns.py @@ -8,12 +8,11 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -from sopel.logger import get_logger from sopel.module import commands, example -logger = get_logger(__name__) + # Copied from pronoun.is, leaving a *lot* out. If -# https://github.com/witch-house/pronoun.is/pull/40 gets merged, using that +# https://github.com/witch-house/pronoun.is/pull/96 gets merged, using that # would be a lot easier. KNOWN_SETS = { 'ze': 'ze/hir/hir/hirs/hirself', @@ -40,7 +39,7 @@ def pronouns(bot, trigger): say_pronouns(bot, trigger.nick, pronouns) else: bot.reply("I don't know your pronouns! You can set them with " - ".setpronouns") + "{}setpronouns".format(bot.config.core.help_prefix)) else: pronouns = bot.db.get_nick_value(trigger.group(3), 'pronouns') if pronouns: @@ -54,7 +53,8 @@ def pronouns(bot, trigger): ) else: bot.say("I don't know {}'s pronouns. They can set them with " - ".setpronouns".format(trigger.group(3))) + "{}setpronouns".format(trigger.group(3), + bot.config.core.help_prefix)) def say_pronouns(bot, nick, pronouns): @@ -85,8 +85,8 @@ def set_pronouns(bot, trigger): bot.say( "I'm sorry, I don't know those pronouns. You can give me a set " "I don't know by formatting it " - "subject/object/possessive-determiner/posessive-pronoun/" - "reflexive, as in they/them/their/theirs/themselves" + "subject/object/possessive-determiner/possessive-pronoun/" + "reflexive, as in: they/them/their/theirs/themselves" ) return bot.db.set_nick_value(trigger.nick, 'pronouns', pronouns) From bc36c153cb89c04ccb3e7e4197ecc79521f902c4 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 04:00:27 -0500 Subject: [PATCH 25/42] rand: Operation Cruft Cleanup --- sopel/modules/rand.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sopel/modules/rand.py b/sopel/modules/rand.py index 9f5fb2f7f6..3a07e10a94 100644 --- a/sopel/modules/rand.py +++ b/sopel/modules/rand.py @@ -8,10 +8,11 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -from sopel.module import commands, example import random import sys +from sopel.module import commands, example + @commands('rand') @example('.rand 2', r'random\(0, 2\) = (0|1|2)', re=True, repeat=10) @@ -35,7 +36,7 @@ def rand(bot, trigger): low = 0 high = sys.maxsize except (ValueError, TypeError): - return bot.reply("Arguments must be of integer type") + return bot.reply("Arguments must be integers.") if low > high: low, high = high, low From d5506b718d9b295da0c5544f0e579c149f07e48f Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:57:02 -0500 Subject: [PATCH 26/42] reddit: Operation Cruft Cleanup --- sopel/modules/reddit.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/sopel/modules/reddit.py b/sopel/modules/reddit.py index 52ae240fcb..184932b5d8 100644 --- a/sopel/modules/reddit.py +++ b/sopel/modules/reddit.py @@ -1,15 +1,25 @@ # coding=utf-8 -# Author: Elsie Powell, embolalia.com +""" +reddit.py - Sopel Reddit Module +Copyright 2012, Elsie Powell, embolalia.com +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division -from sopel.module import commands, rule, example, require_chanmsg, NOLIMIT, OP -from sopel.formatting import bold, color, colors -from sopel.web import USER_AGENT -from sopel.tools import time import datetime as dt -import praw import re import sys + +import praw + +from sopel.formatting import bold, color, colors +from sopel.module import commands, rule, example, require_chanmsg, NOLIMIT, OP +from sopel.tools import time +from sopel.web import USER_AGENT + +# clean up all of this when dropping py2/old py3 versions if sys.version_info.major >= 3: unicode = str if sys.version_info.minor >= 4: @@ -111,7 +121,7 @@ def rpost_info(bot, trigger, match=None): @commands('redditor') @example('.redditor poem_for_your_sprog') def redditor_info(bot, trigger, match=None): - """Show information about the given Redditor""" + """Shows information about the given Redditor""" commanded = re.match(bot.config.core.prefix + 'redditor', trigger) r = praw.Reddit( user_agent=USER_AGENT, From 832b9444263741931f2a8f654861658f69d1ab2d Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:31:58 -0500 Subject: [PATCH 27/42] reload: Operation Cruft Cleanup --- sopel/modules/reload.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sopel/modules/reload.py b/sopel/modules/reload.py index caa4a286db..3780b39e72 100644 --- a/sopel/modules/reload.py +++ b/sopel/modules/reload.py @@ -9,12 +9,13 @@ from __future__ import unicode_literals, absolute_import, print_function, division import collections +import subprocess import sys import time + from sopel.tools import stderr, itervalues import sopel.loader import sopel.module -import subprocess try: from importlib import reload @@ -30,7 +31,7 @@ @sopel.module.thread(False) @sopel.module.require_admin def f_reload(bot, trigger): - """Reloads a module, for use by admins only.""" + """Reloads a module (for use by admins only).""" name = trigger.group(2) if not name or name == '*' or name.upper() == 'ALL THE THINGS': @@ -122,7 +123,7 @@ def load_module(bot, name, path, type_, silent=False): @sopel.module.nickname_commands('update') @sopel.module.require_admin def f_update(bot, trigger): - """Pulls the latest versions of all modules from Git""" + """Pulls the latest versions of all modules from Git (for use by admins only).""" proc = subprocess.Popen('/usr/bin/git pull', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) @@ -136,7 +137,7 @@ def f_update(bot, trigger): @sopel.module.thread(False) @sopel.module.require_admin def f_load(bot, trigger): - """Loads a module, for use by admins only.""" + """Loads a module (for use by admins only).""" name = trigger.group(2) path = '' if not name: @@ -152,7 +153,7 @@ def f_load(bot, trigger): load_module(bot, name, path, type_) -# Catch PM based messages +# Catch private messages @sopel.module.commands("reload") @sopel.module.priority("low") @sopel.module.thread(False) From 44d08a493f5a1ff39c159a4297c2779a6b129895 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:54:35 -0500 Subject: [PATCH 28/42] safety: Operation Cruft Cleanup --- sopel/modules/safety.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/sopel/modules/safety.py b/sopel/modules/safety.py index 64a5727325..09c4337cea 100644 --- a/sopel/modules/safety.py +++ b/sopel/modules/safety.py @@ -8,20 +8,23 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -from sopel.config.types import StaticSection, ValidatedAttribute, ListAttribute -from sopel.formatting import color, bold -from sopel.logger import get_logger -from sopel.module import OP -import sopel.tools import sys import time import os.path import re + import requests +from sopel.config.types import StaticSection, ValidatedAttribute, ListAttribute +from sopel.formatting import color, bold +from sopel.logger import get_logger +from sopel.module import OP +import sopel.tools + try: # This is done separately from the below version if/else because JSONDecodeError # didn't appear until Python 3.5, but Sopel claims support for 3.3+ + # Redo this whole block of nonsense when dropping py2/old py3 support from json import JSONDecodeError as InvalidJSONResponse except ImportError: InvalidJSONResponse = ValueError @@ -34,6 +37,7 @@ from urllib import urlretrieve from urlparse import urlparse + LOGGER = get_logger(__name__) vt_base_api_url = 'https://www.virustotal.com/vtapi/v2/url/' @@ -84,7 +88,7 @@ def setup(bot): loc = os.path.join(bot.config.homedir, 'malwaredomains.txt') if os.path.isfile(loc): if os.path.getmtime(loc) < time.time() - 24 * 60 * 60 * 7: - # File exists but older than one week, update + # File exists but older than one week — update it _download_malwaredomains_db(loc) else: _download_malwaredomains_db(loc) @@ -103,7 +107,7 @@ def _download_malwaredomains_db(path): @sopel.module.rule(r'(?u).*(https?://\S+).*') @sopel.module.priority('high') def url_handler(bot, trigger): - """ Check for malicious URLs """ + """Checks for malicious URLs""" check = True # Enable URL checking strict = False # Strict mode: kick on malicious URL positives = 0 # Number of engines saying it's malicious @@ -126,7 +130,7 @@ def url_handler(bot, trigger): use_vt = False if not check: - return # Not overriden by DB, configured default off + return # Not overridden by DB, configured default off try: netloc = urlparse(trigger.group(1)).netloc @@ -168,7 +172,7 @@ def url_handler(bot, trigger): if unicode(netloc).lower() in malware_domains: # malwaredomains is more trustworthy than some VT engines - # therefor it gets a weight of 10 engines when calculating confidence + # therefore it gets a weight of 10 engines when calculating confidence positives += 10 total += 10 @@ -185,7 +189,7 @@ def url_handler(bot, trigger): @sopel.module.commands('safety') def toggle_safety(bot, trigger): - """ Set safety setting for channel """ + """Set safety setting for channel""" if not trigger.admin and bot.channels[trigger.sender].privileges[trigger.nick] < OP: bot.reply('Only channel operators can change safety settings') return @@ -200,12 +204,12 @@ def toggle_safety(bot, trigger): bot.reply('Safety is now set to "%s" on this channel' % trigger.group(2)) -# Clean the cache every day, also when > 1024 entries +# Clean the cache every day +# Code above also calls this if there are too many cache entries @sopel.module.interval(24 * 60 * 60) def _clean_cache(bot): - """ Cleanup old entries in URL cache """ - # TODO probably should be using locks here, to make sure stuff doesn't - # explode + """Cleans up old entries in URL cache""" + # TODO: probably should use locks here, to make sure stuff doesn't explode oldest_key_age = 0 oldest_key = '' for key, data in sopel.tools.iteritems(bot.memory['safety_cache']): From 4b4dde93ef82b551e92c98e0c068cc400a3faa51 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:49:43 -0500 Subject: [PATCH 29/42] search: Operation Cruft Cleanup --- sopel/modules/search.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/sopel/modules/search.py b/sopel/modules/search.py index ef0d6af412..0e0730e767 100644 --- a/sopel/modules/search.py +++ b/sopel/modules/search.py @@ -1,7 +1,12 @@ # coding=utf-8 -# Copyright 2008-9, Sean B. Palmer, inamidst.com -# Copyright 2012, Elsie Powell, embolalia.com -# Licensed under the Eiffel Forum License 2. +""" +search.py - Sopel Search Engine Module +Copyright 2008-9, Sean B. Palmer, inamidst.com +Copyright 2012, Elsie Powell, embolalia.com +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division import re @@ -95,10 +100,10 @@ def duck_api(query): @commands('duck', 'ddg', 'g') # test for bad Unicode handling in py2 @example('.duck grandorder.wiki chulainn alter', 'https://grandorder.wiki/Cú_Chulainn_(Alter)') -# the last example is what .help displays +# the last example (in source line order) is what .help displays @example('.duck sopel irc bot', r'https?:\/\/sopel\.chat\/?', re=True) def duck(bot, trigger): - """Queries Duck Duck Go for the specified input.""" + """Queries DuckDuckGo for the specified input.""" query = trigger.group(2) if not query: return bot.reply('.ddg what?') @@ -109,7 +114,7 @@ def duck(bot, trigger): bot.reply(result) return - # Otherwise, look it up on the HTMl version + # Otherwise, look it up on the HTML version uri = duck_search(query) if uri: @@ -142,7 +147,7 @@ def bing(bot, trigger): @commands('search') @example('.search sopel irc bot') def search(bot, trigger): - """Searches Bing and Duck Duck Go.""" + """Searches both Bing and DuckDuckGo.""" if not trigger.group(2): return bot.reply('.search for what?') query = trigger.group(2) @@ -166,7 +171,7 @@ def search(bot, trigger): @example('.suggest ', 'No query term.') @example('.suggest lkashdfiauwgeaef', 'Sorry, no result.') def suggest(bot, trigger): - """Suggest terms starting with given input""" + """Suggests terms starting with given input""" if not trigger.group(2): return bot.reply("No query term.") query = trigger.group(2) From cb391affe5fdeb1ffd6891931a77be501c02d2d3 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:45:50 -0500 Subject: [PATCH 30/42] seen: Operation Cruft Cleanup --- sopel/modules/seen.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sopel/modules/seen.py b/sopel/modules/seen.py index 8c09ec1a92..3ce07cb9d6 100644 --- a/sopel/modules/seen.py +++ b/sopel/modules/seen.py @@ -9,11 +9,12 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -import time import datetime +import time + +from sopel.module import commands, rule, priority, thread from sopel.tools import Identifier from sopel.tools.time import get_timezone, format_time -from sopel.module import commands, rule, priority, thread @commands('seen') From 91211a4ce1e296698c527da0144bb65eca81b619 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:45:05 -0500 Subject: [PATCH 31/42] spellcheck: Operation Cruft Cleanup --- sopel/modules/spellcheck.py | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/sopel/modules/spellcheck.py b/sopel/modules/spellcheck.py index ce6ccfa285..482b611af4 100644 --- a/sopel/modules/spellcheck.py +++ b/sopel/modules/spellcheck.py @@ -1,14 +1,16 @@ # coding=utf-8 - """ spellcheck.py - Sopel spelling checker module Copyright © 2016, Alan Huang Copyright © 2019, dgw Licensed under the Eiffel Forum License 2. + https://sopel.chat """ from __future__ import unicode_literals, absolute_import, print_function, division + import aspell + from sopel.module import commands, example, require_admin @@ -26,9 +28,7 @@ def shutdown(bot): @commands('scadd') @require_admin('I only trust admins to add words.') def add_command(bot, trigger): - """ - Stage a word to be added to the bot's personal dictionary. - """ + """Stage a word to be added to the bot's personal dictionary.""" bot.memory['spellcheck_pending_adds'].append(trigger.group(2)) bot.say('Added "{0}". (To review pending words, use {1}scpending. ' 'To commit changes, use {1}scsave.)' @@ -37,9 +37,7 @@ def add_command(bot, trigger): @commands('scpending') def pending_command(bot, trigger): - """ - List words that are waiting to be saved to the bot's personal dictionary. - """ + """List words that are waiting to be saved to the bot's personal dictionary.""" bot.say('Ready to save: "{0}". (To remove a word before saving, use {1}scdel ' 'word, or clear the list with {1}scclear.)' .format('", "'.join(bot.memory['spellcheck_pending_adds']), @@ -49,9 +47,7 @@ def pending_command(bot, trigger): @commands('scdel') @require_admin('Only admins may cancel a word-list addition.') def del_command(bot, trigger): - """ - Remove a word from the list of pending personal dictionary additions. - """ + """Remove a word from the list of pending personal dictionary additions.""" try: bot.memory['spellcheck_pending_adds'].remove(trigger.group(2)) except ValueError: @@ -71,9 +67,7 @@ def del_command(bot, trigger): @commands('scclear') @require_admin('Only admins may clear the pending word list.') def clear_command(bot, trigger): - """ - Clear the list of words pending addition to the bot's personal dictionary. - """ + """Clear the list of words pending addition to the bot's personal dictionary.""" count = len(bot.memory['spellcheck_pending_adds']) del bot.memory['spellcheck_pending_adds'][:] # list.clear() is py3.3+ only :( bot.say('Cleared pending word list ({0} items).'.format(count)) @@ -82,9 +76,10 @@ def clear_command(bot, trigger): @commands('scsave') @require_admin('Only admins may commit word-list changes.') def save_command(bot, trigger): - """ - Commit pending changes to the bot's personal dictionary. This action cannot be undone, - except by manually editing the aspell dictionary file. + """Commit pending changes to the bot's personal dictionary. + + This action cannot be undone, except by manually editing the aspell + dictionary file. """ for word in bot.memory['spellcheck_pending_adds']: if word != word.strip() and trigger.group(2) != 'force': @@ -112,7 +107,8 @@ def check_multiple(bot, words): if len(mistakes) == 0: bot.say("Nothing seems to be misspelled.") else: - bot.say('The following word(s) seem to be misspelled: {0}'.format(', '.join(['"{0}"'.format(w) for w in mistakes]))) + bot.say('The following word(s) seem to be misspelled: {0}' + .format(', '.join(['"{0}"'.format(w) for w in mistakes]))) def check_one(bot, word): @@ -126,15 +122,14 @@ def check_one(bot, word): if len(suggestions) == 0: bot.say("That doesn't seem to be correct.") else: - bot.say("That doesn't seem to be correct. Try {0}.".format(', '.join(['"{0}"'.format(s) for s in suggestions]))) + bot.say("That doesn't seem to be correct. Try {0}.".format(', '.join(['"{0}"' + .format(s) for s in suggestions]))) @commands('spellcheck', 'spell', 'sc') @example('.spellcheck wrod') def spellchecker(bot, trigger): - """ - Checks if the given word is spelled correctly, and suggests corrections. - """ + """Checks if the given word is spelled correctly, and suggests corrections.""" if not trigger.group(2): bot.say('What word am I checking?') return From 236f15eca757c84321b26cfee089250119a8f09b Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:39:19 -0500 Subject: [PATCH 32/42] tell: Operation Cruft Cleanup Use myself (current maintainer) as example, instead of old maintainer who probably doesn't want to be bothered (or highlighted in case someone happens to get that help output in a channel where they are). Sort imports, rename global constant to UPPERCASE, and add a bit of future-thinking documentation for in-progress work. --- sopel/modules/tell.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/sopel/modules/tell.py b/sopel/modules/tell.py index e6fad218ef..43171f90a4 100644 --- a/sopel/modules/tell.py +++ b/sopel/modules/tell.py @@ -12,11 +12,13 @@ import time import threading import sys + +from sopel.module import commands, nickname_commands, rule, priority, example from sopel.tools import Identifier, iterkeys from sopel.tools.time import get_timezone, format_time -from sopel.module import commands, nickname_commands, rule, priority, example -maximum = 4 + +MAXIMUM = 4 def loadReminders(fn, lock): @@ -80,7 +82,7 @@ def setup(self): @commands('tell', 'ask') @nickname_commands('tell', 'ask') -@example('$nickname, tell Embolalia he broke something again.') +@example('$nickname, tell dgw he broke something again.') def f_remind(bot, trigger): """Give someone a message the next time they're seen""" teller = trigger.nick @@ -102,10 +104,10 @@ def f_remind(bot, trigger): if not os.path.exists(bot.tell_filename): return - if len(tellee) > 30: + if len(tellee) > 30: # TODO: use server NICKLEN here when available return bot.reply('That nickname is too long.') if tellee == bot.nick: - return bot.reply("I'm here now, you can tell me whatever you want!") + return bot.reply("I'm here now; you can tell me whatever you want!") if tellee not in (Identifier(teller), bot.nick, 'me'): tz = get_timezone(bot.db, bot.config, None, tellee) @@ -145,7 +147,7 @@ def getReminders(bot, channel, key, tellee): try: del bot.memory['reminders'][key] except KeyError: - bot.msg(channel, 'Er...') + bot.msg(channel, 'Er…') finally: bot.memory['tell_lock'].release() return lines @@ -171,12 +173,12 @@ def message(bot, trigger): elif tellee.lower().startswith(remkey.lower().rstrip('*:')): reminders.extend(getReminders(bot, channel, remkey, tellee)) - for line in reminders[:maximum]: + for line in reminders[:MAXIMUM]: bot.say(line) - if reminders[maximum:]: + if reminders[MAXIMUM:]: bot.say('Further messages sent privately') - for line in reminders[maximum:]: + for line in reminders[MAXIMUM:]: bot.msg(tellee, line) if len(bot.memory['reminders'].keys()) != remkeys: From dac2db95f28f2e96d9db966af9e30e0f3792b8aa Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:29:34 -0500 Subject: [PATCH 33/42] tld: Operation Cruft Cleanup --- sopel/modules/tld.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sopel/modules/tld.py b/sopel/modules/tld.py index 2d10e6a94f..a96421b59a 100644 --- a/sopel/modules/tld.py +++ b/sopel/modules/tld.py @@ -8,13 +8,17 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -from sopel.module import commands, example -import requests import re import sys + +import requests + +from sopel.module import commands, example + if sys.version_info.major >= 3: unicode = str + uri = 'https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains' r_tag = re.compile(r'<(?!!)[^>]+>') From e35d29c5303338bbbc04d3d65720206dada81741 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:23:36 -0500 Subject: [PATCH 34/42] translate: Operation Cruft Cleanup --- sopel/modules/translate.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sopel/modules/translate.py b/sopel/modules/translate.py index 4084827093..93bbc11f00 100644 --- a/sopel/modules/translate.py +++ b/sopel/modules/translate.py @@ -2,7 +2,7 @@ """ translate.py - Sopel Translation Module Copyright 2008, Sean B. Palmer, inamidst.com -Copyright © 2013-2014, Elad Alfassa +Copyright 2013-2014, Elad Alfassa Licensed under the Eiffel Forum License 2. https://sopel.chat @@ -12,17 +12,19 @@ import json import random import sys -import requests +import requests from sopel import web from sopel.module import rule, commands, priority, example -mangle_lines = {} if sys.version_info.major >= 3: unicode = str +mangle_lines = {} + + def translate(text, in_lang='auto', out_lang='en', verify_ssl=True): raw = False if unicode(out_lang).endswith('-raw'): @@ -93,7 +95,7 @@ def tr(bot, trigger): if sys.version_info.major < 3 and isinstance(msg, str): msg = msg.decode('utf-8') if msg: - msg = web.decode(msg) # msg.replace(''', "'") + msg = web.decode(msg) msg = '"%s" (%s to %s, translate.google.com)' % (msg, in_lang, out_lang) else: msg = 'The %s to %s translation failed, are you sure you specified valid language abbreviations?' % (in_lang, out_lang) From 2afd7a57af92d0026ee616a81e2b9cdca1f00a4d Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:15:00 -0500 Subject: [PATCH 35/42] units: Operation Cruft Cleanup --- sopel/modules/units.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/sopel/modules/units.py b/sopel/modules/units.py index 551774ef7a..5f9e2fc82d 100644 --- a/sopel/modules/units.py +++ b/sopel/modules/units.py @@ -5,12 +5,15 @@ Copyright © 2013, Dimitri Molenaars, Licensed under the Eiffel Forum License 2. +https://sopel.chat """ from __future__ import unicode_literals, absolute_import, print_function, division -from sopel.module import commands, example, NOLIMIT import re +from sopel.module import commands, example, NOLIMIT + + find_temp = re.compile(r'(-?[0-9]*\.?[0-9]*)[ °]*(K|C|F)', re.IGNORECASE) find_length = re.compile(r'([0-9]*\.?[0-9]*)[ ]*(mile[s]?|mi|inch|in|foot|feet|ft|yard[s]?|yd|(?:milli|centi|kilo|)meter[s]?|[mkc]?m|ly|light-year[s]?|au|astronomical unit[s]?|parsec[s]?|pc)', re.IGNORECASE) find_mass = re.compile(r'([0-9]*\.?[0-9]*)[ ]*(lb|lbm|pound[s]?|ounce|oz|(?:kilo|)gram(?:me|)[s]?|[k]?g)', re.IGNORECASE) @@ -37,9 +40,7 @@ def k_to_c(temp): @example('.temp 100C', '100.00°C = 212.00°F = 373.15K') @example('.temp 100K', '-173.15°C = -279.67°F = 100.00K') def temperature(bot, trigger): - """ - Convert temperatures - """ + """Convert temperatures""" try: source = find_temp.match(trigger.group(2)).groups() except (AttributeError, TypeError): @@ -76,9 +77,7 @@ def temperature(bot, trigger): @example('.length 3 au', '448793612.10km = 278867421.71 miles') @example('.length 3 parsec', '92570329129020.20km = 57520535754731.61 miles') def distance(bot, trigger): - """ - Convert distances - """ + """Convert distances""" try: source = find_length.match(trigger.group(2)).groups() except (AttributeError, TypeError): @@ -148,9 +147,7 @@ def distance(bot, trigger): @commands('weight', 'mass') def mass(bot, trigger): - """ - Convert mass - """ + """Convert mass""" try: source = find_mass.match(trigger.group(2)).groups() except (AttributeError, TypeError): From 64219fc6cd31dd7afabf5ca832f700fe89e066e5 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:11:28 -0500 Subject: [PATCH 36/42] uptime: Operation Cruft Cleanup Renamed memory key from "uptime" to "start_time", since it's actually storing the bot's start time and not its uptime. Tweaked some other code/docstring style, too. --- sopel/modules/uptime.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sopel/modules/uptime.py b/sopel/modules/uptime.py index 467b654903..162c86db7c 100644 --- a/sopel/modules/uptime.py +++ b/sopel/modules/uptime.py @@ -1,6 +1,6 @@ # coding=utf-8 """ -uptime.py - Uptime module +uptime.py - Sopel Uptime Module Copyright 2014, Fabian Neundorf Licensed under the Eiffel Forum License 2. @@ -8,20 +8,20 @@ """ from __future__ import unicode_literals, absolute_import, print_function, division -from sopel.module import commands import datetime +from sopel.module import commands + def setup(bot): - if "uptime" not in bot.memory: - bot.memory["uptime"] = datetime.datetime.utcnow() + if "start_time" not in bot.memory: + bot.memory["start_time"] = datetime.datetime.utcnow() @commands('uptime') def uptime(bot, trigger): """.uptime - Returns the uptime of Sopel.""" delta = datetime.timedelta(seconds=round((datetime.datetime.utcnow() - - bot.memory["uptime"]) + bot.memory["start_time"]) .total_seconds())) - bot.say("I've been sitting here for {} and I keep " - "going!".format(delta)) + bot.say("I've been sitting here for {} and I keep going!".format(delta)) From 538a3c35a90207e29de36128c5990a9538bc1e68 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:17:42 -0500 Subject: [PATCH 37/42] unicode_info: Operation Cruft Cleanup Prettified file header, added missing docstring(s), etc. --- sopel/modules/unicode_info.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/sopel/modules/unicode_info.py b/sopel/modules/unicode_info.py index f56cc446bf..f92eb448af 100644 --- a/sopel/modules/unicode_info.py +++ b/sopel/modules/unicode_info.py @@ -1,8 +1,12 @@ # coding=utf-8 -"""Codepoints Module""" -# Copyright 2013, Elsie Powell, embolalia.com -# Copyright 2008, Sean B. Palmer, inamidst.com -# Licensed under the Eiffel Forum License 2. +""" +unicode_info.py - Sopel Codepoints Module +Copyright 2013, Elsie Powell, embolalia.com +Copyright 2008, Sean B. Palmer, inamidst.com +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division import sys @@ -22,7 +26,7 @@ def get_codepoint_name(char): - """Retrieve the codepoint and name if possible from a character""" + """Retrieve the code point (and name, if possible) for a given character""" # Get the hex value for the code point, and drop the 0x from the front point = unicode(hex(ord(char)))[2:] @@ -43,6 +47,7 @@ def get_codepoint_name(char): @module.example('.u ‽', 'U+203D INTERROBANG (‽)') @module.example('.u 203D', 'U+203D INTERROBANG (‽)') def codepoint(bot, trigger): + """Look up a Unicode character or a hexadecimal code point.""" arg = trigger.group(2) if not arg: bot.reply('What code point do you want me to look up?') From afe4d7c6e7d0af6b68b8f4e22df36cab63748606 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:08:36 -0500 Subject: [PATCH 38/42] url: Operation Cruft Cleanup Overhauled docstrings and sorted imports while looking for unused code. --- sopel/modules/url.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/sopel/modules/url.py b/sopel/modules/url.py index fc45a75b29..26337e1c54 100644 --- a/sopel/modules/url.py +++ b/sopel/modules/url.py @@ -1,18 +1,24 @@ # coding=utf-8 -"""URL title module""" -# Copyright 2010-2011, Michael Yanovich, yanovich.net, Kenneth Sham -# Copyright 2012-2013 Elsie Powell -# Copyright 2013 Lior Ramati (firerogue517@gmail.com) -# Copyright © 2014 Elad Alfassa -# Licensed under the Eiffel Forum License 2. +""" +url.py - Sopel URL Title Module +Copyright 2010-2011, Michael Yanovich (yanovich.net) & Kenneth Sham +Copyright 2012-2013, Elsie Powell +Copyright 2013, Lior Ramati +Copyright 2014, Elad Alfassa +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division import re + +import requests + from sopel import web, tools, __version__ -from sopel.module import commands, rule, example from sopel.config.types import ValidatedAttribute, ListAttribute, StaticSection +from sopel.module import commands, rule, example -import requests USER_AGENT = 'Sopel/{} (https://sopel.chat)'.format(__version__) default_headers = {'User-Agent': USER_AGENT} @@ -188,8 +194,8 @@ def process_urls(bot, trigger, urls): For each URL in the list, ensure that it isn't handled by another module. If not, find where it redirects to, if anywhere. If that redirected URL should be handled by another module, dispatch the callback for it. - Return a list of (title, hostname) tuples for each URL which is not handled by - another module. + Return a list of (title, hostname) tuples for each URL which is not handled + by another module. """ results = [] @@ -230,7 +236,7 @@ def check_callbacks(bot, trigger, url, run=True): """ Check the given URL against the callbacks list. If it matches, and ``run`` is given as ``True``, run the callback function, otherwise pass. Returns - ``True`` if the url matched anything in the callbacks list. + ``True`` if the URL matched anything in the callbacks list. """ # Check if it matches the exclusion list first matched = any(regex.search(url) for regex in bot.memory['url_exclude']) From 4b5815d846bd56d221a55be1aa5181ef575f929b Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 02:52:51 -0500 Subject: [PATCH 39/42] version: pre-emptively fix import order At some point in the future, we want to enforce good import order. Standard imports before modules, and external packages before our own, that kind of thing. Since I'm going through all the modules anyway, sorting the imports makes sense to reduce the workload later. --- sopel/modules/version.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sopel/modules/version.py b/sopel/modules/version.py index 867662c696..14b5b3857b 100644 --- a/sopel/modules/version.py +++ b/sopel/modules/version.py @@ -10,11 +10,12 @@ from __future__ import unicode_literals, absolute_import, print_function, division from datetime import datetime -from sopel import __version__ as release -from sopel.module import commands, intent, rate from os import path import platform +from sopel import __version__ as release +from sopel.module import commands, intent, rate + def git_info(): repo = path.join(path.dirname(path.dirname(path.dirname(__file__))), '.git') From e9159a5c61352acc90675506f1237d37635a8423 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 03:04:46 -0500 Subject: [PATCH 40/42] wikipedia: Operation Cruft Cleanup Overhauled import order and docstrings while looking for unused code. --- sopel/modules/wikipedia.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/sopel/modules/wikipedia.py b/sopel/modules/wikipedia.py index 044595d728..fa4a45b34c 100644 --- a/sopel/modules/wikipedia.py +++ b/sopel/modules/wikipedia.py @@ -1,14 +1,21 @@ # coding=utf-8 -# Copyright 2013 Elsie Powell - embolalia.com -# Licensed under the Eiffel Forum License 2. +""" +wikipedia.py - Sopel Wikipedia Module +Copyright 2013 Elsie Powell - embolalia.com +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division +import re +import sys + +from requests import get + from sopel.config.types import StaticSection, ValidatedAttribute from sopel.module import NOLIMIT, commands, example, rule -from requests import get -import re -import sys if sys.version_info.major < 3: from urllib import quote as _quote from urlparse import unquote as _unquote @@ -21,6 +28,7 @@ def unquote(s): else: from urllib.parse import quote, unquote + REDIRECT = re.compile(r'^REDIRECT (.*)') WIKIPEDIA_REGEX = re.compile('([a-z]+).(wikipedia.org/wiki/)([^ ]+)') @@ -56,7 +64,8 @@ def configure(config): def mw_search(server, query, num): - """ + """Search a MediaWiki site + Searches the specified MediaWiki server for the given query, and returns the specified number of results. """ @@ -91,10 +100,7 @@ def say_snippet(bot, trigger, server, query, show_url=True): def mw_snippet(server, query): - """ - Retrives a snippet of the specified length from the given page on the given - server. - """ + """Retrieves a snippet of the given page from the given MediaWiki server.""" snippet_url = ('https://' + server + '/w/api.php?format=json' '&action=query&prop=extracts&exintro&explaintext' '&exchars=300&redirects&titles=') @@ -111,10 +117,7 @@ def mw_snippet(server, query): @rule(r'.*\/([a-z]+\.wikipedia\.org)\/wiki\/((?!File\:)[^ ]+).*') def mw_info(bot, trigger, found_match=None): - """ - Retrives a snippet of the specified length from the given page on the given - server. - """ + """Retrieves and outputs a snippet from the linked page.""" match = found_match or trigger say_snippet(bot, trigger, match.group(1), unquote(match.group(2)), show_url=False) From 12c6744835973dcd99f26aa91907401929af1788 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 02:58:07 -0500 Subject: [PATCH 41/42] wiktionary: Operation Cruft Cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A blank line between standard and module imports is nice. Not enforced (yet), but nice to have. Also, since we're using UTF-8 for this source file, why did we not output a Unicode '…' ellipsis instead of '...' three periods? We do now. --- sopel/modules/wiktionary.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sopel/modules/wiktionary.py b/sopel/modules/wiktionary.py index 2f33844665..af9de2f2a7 100644 --- a/sopel/modules/wiktionary.py +++ b/sopel/modules/wiktionary.py @@ -9,10 +9,13 @@ from __future__ import unicode_literals, absolute_import, print_function, division import re + import requests + from sopel import web from sopel.module import commands, example + uri = 'https://en.wiktionary.org/w/index.php?title=%s&printable=yes' r_sup = re.compile(r']+>.+') # Superscripts that are references only, not ordinal indicators, etc... r_tag = re.compile(r'<[^>]+>') @@ -112,5 +115,5 @@ def wiktionary(bot, trigger): result = format(word, definitions, 5) if len(result) > 300: - result = result[:295] + '[...]' + result = result[:295] + '[…]' bot.say(result) From 0de6224f91bec3e7a1e88e1e205ffa6bf4d68bb0 Mon Sep 17 00:00:00 2001 From: dgw Date: Tue, 16 Apr 2019 02:46:13 -0500 Subject: [PATCH 42/42] xkcd: Operation Cruft Cleanup I came looking for cruft, but the closest thing I found was outdated comments referencing "google" even though we haven't used Google for years. (It was DuckDuckGo for a while, but now it's Bing, because DDG broke using multiple `site:` queries and never fixed the bug.) So, now we just talk vaguely about searching the web, instead of Google. We also have a nicer module-level docstring, which is part of the cruft-cleaning project as well. --- sopel/modules/xkcd.py | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/sopel/modules/xkcd.py b/sopel/modules/xkcd.py index 718db790a3..7e36efa116 100644 --- a/sopel/modules/xkcd.py +++ b/sopel/modules/xkcd.py @@ -1,18 +1,26 @@ # coding=utf-8 -# Copyright 2010, Michael Yanovich (yanovich.net), and Morgan Goose -# Copyright 2012, Lior Ramati -# Copyright 2013, Elsie Powell (embolalia.com) -# Licensed under the Eiffel Forum License 2. +""" +xkcd.py - Sopel xkcd Module +Copyright 2010, Michael Yanovich (yanovich.net), and Morgan Goose +Copyright 2012, Lior Ramati +Copyright 2013, Elsie Powell (embolalia.com) +Licensed under the Eiffel Forum License 2. + +https://sopel.chat +""" from __future__ import unicode_literals, absolute_import, print_function, division import random import re + import requests + from sopel.modules.search import bing_search from sopel.module import commands, url + ignored_sites = [ - # For google searching + # For searching the web 'almamater.xkcd.com', 'blog.xkcd.com', 'blag.xkcd.com', @@ -36,7 +44,7 @@ def get_info(number=None, verify_ssl=True): return data -def google(query): +def web_search(query): url = bing_search(query + sites_query) if not url: return None @@ -47,12 +55,15 @@ def google(query): @commands('xkcd') def xkcd(bot, trigger): - """ - .xkcd - Finds an xkcd comic strip. Takes one of 3 inputs: - If no input is provided it will return a random comic - If numeric input is provided it will return that comic, or the nth-latest - comic if the number is non-positive - If non-numeric input is provided it will return the first google result for those keywords on the xkcd.com site + """.xkcd - Finds an xkcd comic strip. + + Takes one of 3 inputs: + + * If no input is provided it will return a random comic + * If numeric input is provided it will return that comic, or the + nth-latest comic if the number is non-positive + * If non-numeric input is provided it will return the first search result + for those keywords on the xkcd.com site """ verify_ssl = bot.config.core.verify_ssl # get latest comic for rand function and numeric input @@ -74,11 +85,11 @@ def xkcd(bot, trigger): query = -query return numbered_result(bot, query, latest) else: - # Non-number: google. + # Non-number: search the web. if (query.lower() == "latest" or query.lower() == "newest"): requested = latest else: - number = google(query) + number = web_search(query) if not number: bot.say('Could not find any comics for that query.') return