From 804aaf3e15d662b134ee7895ad84c17a24f84034 Mon Sep 17 00:00:00 2001 From: Steven Skoczen Date: Fri, 27 Feb 2015 15:23:32 +0700 Subject: [PATCH] Massive pep8 cleanup --- CONTRIBUTING.md | 2 +- config.py | 34 +++++++++--------- docs/improve.md | 3 +- fabfile.py | 24 +++++++------ requirements.dev.txt | 1 + setup.py | 6 ++-- tox.ini | 5 +++ will/__init__.py | 2 +- will/listener.py | 35 ++++++++++-------- will/mixins/email.py | 1 + will/mixins/errors.py | 3 +- will/mixins/room.py | 1 - will/mixins/schedule.py | 36 ++++++++++++------- will/mixins/storage.py | 4 +-- will/plugins/admin/__init__.py | 2 +- will/plugins/admin/keep_alive.py | 2 ++ will/plugins/admin/storage.py | 8 +++-- will/plugins/chat_room/__init__.py | 2 +- will/plugins/chat_room/rooms.py | 3 +- will/plugins/chat_room/roster.py | 2 +- will/plugins/devops/__init__.py | 2 +- will/plugins/devops/emergency_contacts.py | 3 +- will/plugins/devops/heroku_is_up.py | 8 +++-- will/plugins/friendly/__init__.py | 2 +- will/plugins/friendly/random_topic.py | 2 +- will/plugins/help/__init__.py | 2 +- will/plugins/help/help.py | 3 +- will/plugins/help/programmer_help.py | 1 - will/plugins/productivity/__init__.py | 2 +- will/plugins/productivity/hangout.py | 4 ++- will/plugins/productivity/world_time.py | 22 +++++++++--- will/plugins/web/__init__.py | 2 +- will/scheduler.py | 44 ++++++++++++++++------- will/scripts/generate_will_project.py | 40 ++++++++++----------- will/settings.py | 8 +++-- will/utils.py | 7 +++- 36 files changed, 201 insertions(+), 127 deletions(-) create mode 100644 tox.ini diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea5da571..16b2391a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ This is a first pass at a contribution doc, and will change, but for starters: -- Incoming code should follow PEP8 +- Incoming code should follow PEP8 ( run `flake8` ) - If you add new core-level features, write some quick docs in the README. If you're not sure if they're needed, just ask! - Add your name and attribution to the AUTHORS file. - Know you have our thanks for helping to make will even better! diff --git a/config.py b/config.py index ab061c16..c50d3e08 100644 --- a/config.py +++ b/config.py @@ -1,29 +1,27 @@ # Welcome to Will's settings. -# +# # Config and the environment: # --------------------------- # Will can use settings from the environment or this file, and sets reasonable defaults. -# -# Best practices: set keys and the like in the environment, and anything you'd be ok +# +# Best practices: set keys and the like in the environment, and anything you'd be ok # with other people knowing in this file. -# -# To specify in the environment, just prefix with WILL_ -# (i.e. WILL_DEFAULT_ROOM becomes DEFAULT_ROOM). +# +# To specify in the environment, just prefix with WILL_ +# (i.e. WILL_DEFAULT_ROOM becomes DEFAULT_ROOM). # In case of conflict, you will see a warning message, and the value in this file will win. - - # ------------------------------------------------------------------------------------ # Required settings # ------------------------------------------------------------------------------------ -# The list of plugin modules will should load. +# The list of plugin modules will should load. # Will recursively loads all plugins contained in each module. # This list can contain: -# +# # Built-in core plugins: # ---------------------- # All built-in modules: will.plugins @@ -35,7 +33,7 @@ # All modules: plugins # A specific module: plugins.module_name # Specific plugins: plugins.module_name.plugin -# +# # Plugins anywhere else on your PYTHONPATH: # ----------------------------------------- # All modules: someapp @@ -44,7 +42,7 @@ # By default, the list below includes all the core will plugins and -# all your project's plugins. +# all your project's plugins. PLUGINS = [ # Built-ins @@ -62,9 +60,9 @@ # Don't load any of the plugins in this list. Same options as above. PLUGIN_BLACKLIST = [ - # "will.plugins.friendly.cookies", # But who would deprive will of cookies?? - "will.plugins.productivity.hangout", # Because it requires a HANGOUT_URL - "will.plugins.productivity.world_time", # Because it requires a WORLD_WEATHER_ONLINE_V2_KEY key + # "will.plugins.friendly.cookies", # But who would deprive will of cookies?? + "will.plugins.productivity.hangout", # Because it requires a HANGOUT_URL + "will.plugins.productivity.world_time", # Because it requires a WORLD_WEATHER_ONLINE_V2_KEY key ] @@ -89,15 +87,15 @@ # ROOMS = ['Testing, Will Kahuna',] -# The room will will talk to if the trigger is a webhook and he isn't told a specific room. +# The room will will talk to if the trigger is a webhook and he isn't told a specific room. # Default is the first of ROOMS. # DEFAULT_ROOM = 'Testing, Will Kahuna' -# Fully-qualified folders to look for templates in, beyond the two that +# Fully-qualified folders to look for templates in, beyond the two that # are always included: core will's templates folder, your project's templates folder, and # all templates folders in included plugins, if they exist. -# +# # TEMPLATE_DIRS = [ # os.path.abspath("other_folder/templates") # ] diff --git a/docs/improve.md b/docs/improve.md index a5f1d5cf..7bf322a5 100644 --- a/docs/improve.md +++ b/docs/improve.md @@ -119,9 +119,8 @@ If you're looking for plugin inspiration, here are some wills that are open-sour ## Releases -#### 0.8 - February 27, 2015 +#### 0.7.2 - February 27, 2015 -* Big upgrade! Now only `WILL_USERNAME` and `WILL_PASSWORD` are needed. This solves the impending one-year V2 token expiry, and the need for a V1 token at all. * Improved handling when `.reply()` is called incorrectly, thanks to a report by [dothak](https://github.com/dothak) * Fixed the [annoying](https://github.com/skoczen/will/issues/78) "github's ok" on first launch. * Restored Python 2.6 compatability thanks to the report and patience of [JPerkster](https://github.com/JPerkster). diff --git a/fabfile.py b/fabfile.py index 6dcbe6e9..5140f2f6 100644 --- a/fabfile.py +++ b/fabfile.py @@ -4,61 +4,65 @@ from fabric.api import * SITE_DIR = "site" -WHITELIST_DIRS = [".git",] -WHITELIST_FILES = [ ".gitignore", ] +WHITELIST_DIRS = [".git", ] +WHITELIST_FILES = [".gitignore", ] SANITY_CHECK_PROJECT_FILES = ["fabfile.py", "setup.py", "mkdocs.yml"] SANITY_CHECK_BUILD_FILES = ["index.html", "js", "css"] + def _splitpath(path): path = os.path.normpath(path) return path.split(os.sep) + def tag_release(): # Tag the release: local("git tag %s" % VERSION) local("git push --tags") + def upload_release(): local("python setup.py sdist upload") + def release(): deploy_docs() upload_release() tag_release() + def deploy_docs(): # Sanity check dir. root_dir = os.getcwd() - assert all([os.path.exists(os.path.join(root_dir,f)) for f in SANITY_CHECK_PROJECT_FILES]) + assert all([os.path.exists(os.path.join(root_dir, f)) for f in SANITY_CHECK_PROJECT_FILES]) local("rm -rf %s" % SITE_DIR) local("mkdocs build") tempdir = tempfile.mkdtemp() local("mv %s/* %s" % (SITE_DIR, tempdir)) - + current_branch = local("git rev-parse --abbrev-ref HEAD", capture=True) last_commit = local("git log -1 --pretty=\%B", capture=True) # Add the new site to build local("git checkout gh-pages") - + # Sanity check dir. root_dir = os.getcwd() - assert all([os.path.exists(os.path.join(root_dir,f)) for f in SANITY_CHECK_BUILD_FILES]) - + assert all([os.path.exists(os.path.join(root_dir, f)) for f in SANITY_CHECK_BUILD_FILES]) for root, dirs, files in os.walk(root_dir, topdown=False): for name in files: - if not name in WHITELIST_FILES and not any([r in WHITELIST_DIRS for r in _splitpath(root)]): + if name not in WHITELIST_FILES and not any([r in WHITELIST_DIRS for r in _splitpath(root)]): # print "removing %s" % (os.path.join(root, name)) os.remove(os.path.join(root, name)) for name in dirs: - if not name in WHITELIST_DIRS and not any([r in WHITELIST_DIRS for r in _splitpath(root)]): + if name not in WHITELIST_DIRS and not any([r in WHITELIST_DIRS for r in _splitpath(root)]): # print "removing %s" % (os.path.join(root, name)) os.rmdir(os.path.join(root, name)) - + local("cp -rv %s/* ." % tempdir) with settings(warn_only=True): result = local("git diff --exit-code") diff --git a/requirements.dev.txt b/requirements.dev.txt index 388aac3e..f8bc8c0f 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -19,5 +19,6 @@ sleekxmpp>=1.2 pyandoc mkdocs fabric +flake8 mock nose \ No newline at end of file diff --git a/setup.py b/setup.py index be541933..ef88f9ba 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -#/usr/bin/env python +#!/usr/bin/env python import os from setuptools import setup, find_packages from will import __name__ as PACKAGE_NAME @@ -31,11 +31,11 @@ author_email="skoczen@gmail.com", url="https://github.com/skoczen/will", version=VERSION, - download_url = ['https://github.com/skoczen/will/tarball/%s' % VERSION, ], + download_url=['https://github.com/skoczen/will/tarball/%s' % VERSION, ], install_requires=reqs, packages=find_packages(), include_package_data=True, - keywords = ["hipchat", "bot"], + keywords=["hipchat", "bot"], classifiers=[ "Programming Language :: Python", "License :: OSI Approved :: BSD License", diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..44451dbc --- /dev/null +++ b/tox.ini @@ -0,0 +1,5 @@ +[flake8] +ignore = F401,N812,F403,E721,E713 +max-line-length = 120 +# exclude = tests/* +max-complexity = 12 \ No newline at end of file diff --git a/will/__init__.py b/will/__init__.py index fd9ee1c1..2400ae82 100644 --- a/will/__init__.py +++ b/will/__init__.py @@ -1 +1 @@ -VERSION = "0.8" +VERSION = "0.7.2" diff --git a/will/listener.py b/will/listener.py index 5364bb9b..f3522004 100644 --- a/will/listener.py +++ b/will/listener.py @@ -40,7 +40,7 @@ def start_xmpp_client(self): self.whitespace_keepalive = True self.whitespace_keepalive_interval = 30 - if settings.ALLOW_INSECURE_HIPCHAT_SERVER == True: + if settings.ALLOW_INSECURE_HIPCHAT_SERVER is True: self.add_event_handler('ssl_invalid_cert', lambda cert: True) self.add_event_handler("roster_update", self.join_rooms) @@ -48,7 +48,7 @@ def start_xmpp_client(self): self.add_event_handler("message", self.message_recieved) self.add_event_handler("groupchat_message", self.room_message) - self.register_plugin('xep_0045') # MUC + self.register_plugin('xep_0045') # MUC def session_start(self, event): self.send_presence() @@ -100,12 +100,10 @@ def update_will_roster_and_rooms(self): def room_message(self, msg): self._handle_message_listeners(msg) - def message_recieved(self, msg): if msg['type'] in ('chat', 'normal'): self._handle_message_listeners(msg) - def real_sender_jid(self, msg): # There's a bug in sleekXMPP where it doesn't set the "from_jid" properly. # Thus, this hideous hack. @@ -118,17 +116,21 @@ def real_sender_jid(self, msg): return msg["from"] - def _handle_message_listeners(self, msg): - if (self.some_listeners_include_me # I've been asked to listen to my own messages - or (msg['type'] in ('chat', 'normal') and self.real_sender_jid(msg) != self.me.jid) # or we're in a 1 on 1 chat and I didn't send it - or (msg["type"] == "groupchat" and msg['mucnick'] != self.nick) ): # we're in group chat and I didn't send it + if ( + # I've been asked to listen to my own messages + self.some_listeners_include_me + # or we're in a 1 on 1 chat and I didn't send it + or (msg['type'] in ('chat', 'normal') and self.real_sender_jid(msg) != self.me.jid) + # we're in group chat and I didn't send it + or (msg["type"] == "groupchat" and msg['mucnick'] != self.nick) + ): body = msg["body"] sent_directly_to_me = False # If it's sent directly to me, strip off "@will" from the start. if body[:len(self.handle) + 1].lower() == ("@%s" % self.handle).lower(): - body = body[len(self.handle)+1:].strip() + body = body[len(self.handle) + 1:].strip() msg["body"] = body sent_directly_to_me = True @@ -140,12 +142,17 @@ def _handle_message_listeners(self, msg): for l in self.message_listeners: search_matches = l["regex"].search(body) if (search_matches # The search regex matches and - and (msg['mucnick'] != self.nick or l["include_me"]) # It's not from me, or this search includes me, and - and (msg['type'] in ('chat', 'normal') or not l["direct_mentions_only"] or self.handle_regex.search(body) or sent_directly_to_me) # I'm mentioned, or this is an overheard, or we're in a 1-1 - and ((l['admin_only'] and self.message_is_from_admin(msg)) or (not l['admin_only'])) # It's from admins only and sender is an admin, or it's not from admins only - ): + # It's not from me, or this search includes me, and + and (msg['mucnick'] != self.nick or l["include_me"]) + # I'm mentioned, or this is an overheard, or we're in a 1-1 + and (msg['type'] in ('chat', 'normal') or not l["direct_mentions_only"] or + self.handle_regex.search(body) or sent_directly_to_me) + # It's from admins only and sender is an admin, or it's not from admins only + and ((l['admin_only'] and self.message_is_from_admin(msg)) or (not l['admin_only'])) + ): try: - thread_args = [msg,] + l["args"] + thread_args = [msg, ] + l["args"] + def fn(listener, args, kwargs): try: listener["fn"](*args, **kwargs) diff --git a/will/mixins/email.py b/will/mixins/email.py index 537c65d5..5891bc6a 100644 --- a/will/mixins/email.py +++ b/will/mixins/email.py @@ -3,6 +3,7 @@ from will import settings from will.decorators import require_settings + class EmailMixin(object): def send_email(self, from_email=None, email_list=[], subject="", message=""): diff --git a/will/mixins/errors.py b/will/mixins/errors.py index bd93f145..c5179dc2 100644 --- a/will/mixins/errors.py +++ b/will/mixins/errors.py @@ -1,6 +1,7 @@ import logging import traceback + class ErrorMixin(object): def get_startup_errors(self): if hasattr(self, "_startup_errors"): @@ -21,4 +22,4 @@ def startup_error(self, error_message, exception_instance): logging.critical(error_message) def runtime_error(self, error_message): - logging.critical(error_message) \ No newline at end of file + logging.critical(error_message) diff --git a/will/mixins/room.py b/will/mixins/room.py index cbd7e5ed..10018076 100644 --- a/will/mixins/room.py +++ b/will/mixins/room.py @@ -86,4 +86,3 @@ def get_room_from_name_or_id(self, name_or_id): if "room_id" in room and name_or_id == room["room_id"]: return room return None - diff --git a/will/mixins/schedule.py b/will/mixins/schedule.py index 8fb10cac..d5695f96 100644 --- a/will/mixins/schedule.py +++ b/will/mixins/schedule.py @@ -5,18 +5,17 @@ import traceback from apscheduler.triggers.cron import CronTrigger + class ScheduleMixin(object): def times_key(self, periodic_list=False): if periodic_list: return "will_periodic_times_list" - return "will_schedule_times_list" - + def schedule_key(self, periodic_list=False): if periodic_list: return "will_periodic_list" - return "will_schedule_list" def get_schedule_list(self, periodic_list=False): @@ -54,7 +53,10 @@ def add_room_message_to_schedule(self, when, content, room, *args, **kwargs): def add_to_schedule(self, when, item, periodic_list=False, ignore_scheduler_lock=False): try: - while (ignore_scheduler_lock == False and self.load("scheduler_lock", False)) or self.load("scheduler_add_lock", False): + while ( + (ignore_scheduler_lock is False and self.load("scheduler_lock", False)) or + self.load("scheduler_add_lock", False) + ): import sys sys.stdout.write("waiting for lock to clear\n") time.sleep(random.random()) @@ -69,9 +71,12 @@ def add_to_schedule(self, when, item, periodic_list=False, ignore_scheduler_lock times_list[item_hash] = when self.save_schedule_list(sched_list, periodic_list=periodic_list) self.save_times_list(times_list, periodic_list=periodic_list) - + except: - logging.critical("Error adding to schedule at %s. \n\n%s\nContinuing...\n" % (when, traceback.format_exc() )) + logging.critical( + "Error adding to schedule at %s. \n\n%s\nContinuing...\n" % + (when, traceback.format_exc()) + ) self.save("scheduler_add_lock", False) def remove_from_schedule(self, item_hash, periodic_list=False): @@ -83,7 +88,8 @@ def remove_from_schedule(self, item_hash, periodic_list=False): self.save_schedule_list(sched_list, periodic_list=periodic_list) self.save_times_list(times_list, periodic_list=periodic_list) - def add_periodic_task(self, module_name, cls_name, function_name, sched_args, sched_kwargs, ignore_scheduler_lock=False): + def add_periodic_task(self, module_name, cls_name, function_name, sched_args, + sched_kwargs, ignore_scheduler_lock=False): now = datetime.datetime.now() ct = CronTrigger(*sched_args, **sched_kwargs) when = ct.get_next_fire_time(now) @@ -97,7 +103,8 @@ def add_periodic_task(self, module_name, cls_name, function_name, sched_args, sc } self.add_to_schedule(when, item, periodic_list=True, ignore_scheduler_lock=ignore_scheduler_lock) - def add_single_random_task(self, when, module_name, cls_name, function_name, start_hour, end_hour, day_of_week, num_times_per_day, ignore_scheduler_lock=False): + def add_single_random_task(self, when, module_name, cls_name, function_name, start_hour, end_hour, + day_of_week, num_times_per_day, ignore_scheduler_lock=False): item = { "type": "random_task", "module_name": module_name, @@ -111,7 +118,8 @@ def add_single_random_task(self, when, module_name, cls_name, function_name, sta self.add_to_schedule(when, item, periodic_list=True, ignore_scheduler_lock=ignore_scheduler_lock) - def add_random_tasks(self, module_name, cls_name, function_name, start_hour, end_hour, day_of_week, num_times_per_day, ignore_scheduler_lock=False): + def add_random_tasks(self, module_name, cls_name, function_name, start_hour, end_hour, day_of_week, + num_times_per_day, ignore_scheduler_lock=False): # This function is fired at startup, and every day at midnight. if end_hour < start_hour: raise Exception("start_hour is after end_hour!") @@ -122,7 +130,7 @@ def add_random_tasks(self, module_name, cls_name, function_name, start_hour, end # Work around crontab bug where if the hour has started, it's skipped. adjusted_start_hour = start_hour if adjusted_start_hour != 23: - adjusted_start_hour += 1 + adjusted_start_hour += 1 adjusted_start_hour = "%s" % adjusted_start_hour ct = CronTrigger(hour=adjusted_start_hour, day_of_week=day_of_week) @@ -136,7 +144,7 @@ def add_random_tasks(self, module_name, cls_name, function_name, start_hour, end possible_times = [] for i in range(start_hour, end_hour): for j in range(60): - possible_times.append((i,j)) + possible_times.append((i, j)) times = random.sample(possible_times, num_times_per_day) for hour, minute in times: @@ -144,4 +152,8 @@ def add_random_tasks(self, module_name, cls_name, function_name, start_hour, end # If we're starting up mid-day, this may not be true. if when >= now: - self.add_single_random_task(when, module_name, cls_name, function_name, start_hour, end_hour, day_of_week, num_times_per_day, ignore_scheduler_lock=ignore_scheduler_lock) + self.add_single_random_task( + when, module_name, cls_name, function_name, + start_hour, end_hour, day_of_week, num_times_per_day, + ignore_scheduler_lock=ignore_scheduler_lock + ) diff --git a/will/mixins/storage.py b/will/mixins/storage.py index 3ec0621a..6c4f32e9 100644 --- a/will/mixins/storage.py +++ b/will/mixins/storage.py @@ -37,7 +37,7 @@ def save(self, key, value): ret = self.storage.set(key, pickle.dumps(value)) return ret except: - logging.critical("Unable to save %s: \n%s" % (key, traceback.format_exc()) ) + logging.critical("Unable to save %s: \n%s" % (key, traceback.format_exc())) def clear(self, key): if not hasattr(self, "storage"): @@ -57,7 +57,7 @@ def load(self, key, default=None): val = self.storage.get(key) if val is not None: return pickle.loads(val) - + except: logging.warn("Unable to load %s" % key) diff --git a/will/plugins/admin/__init__.py b/will/plugins/admin/__init__.py index fd4de13c..39525c69 100644 --- a/will/plugins/admin/__init__.py +++ b/will/plugins/admin/__init__.py @@ -1 +1 @@ -MODULE_DESCRIPTION = "Administrative actions" \ No newline at end of file +MODULE_DESCRIPTION = "Administrative actions" diff --git a/will/plugins/admin/keep_alive.py b/will/plugins/admin/keep_alive.py index 20c15f41..600cd0a4 100644 --- a/will/plugins/admin/keep_alive.py +++ b/will/plugins/admin/keep_alive.py @@ -4,6 +4,8 @@ from will import settings keep_alive_url = "/keep-alive" + + class KeepAlivePlugin(WillPlugin): @periodic(second=0) diff --git a/will/plugins/admin/storage.py b/will/plugins/admin/storage.py index 23959b87..0ecae5df 100644 --- a/will/plugins/admin/storage.py +++ b/will/plugins/admin/storage.py @@ -19,9 +19,11 @@ def clear_storage(self, message, key=None): @respond_to("^SERIOUSLY. REALLY. Clear all keys.", case_sensitive=True, admin_only=True) def clear_all_keys_listener(self, message): - self.say("Ok, I'm clearing them. You're probably going to want to restart me. I just forgot everything, including who I am and where the chat room is.", message=message) + self.say( + "Ok, I'm clearing them. You're probably going to want to restart me." + "I just forgot everything, including who I am and where the chat room is.", message=message + ) self.clear_all_keys() - @respond_to("^Show (?:me )?(?:the )?storage for (?P.*)", admin_only=True) def show_storage(self, message, key=None): @@ -29,4 +31,4 @@ def show_storage(self, message, key=None): self.say("Not sure what you're looking for.", message=message) else: val = self.load(key) - self.say("%s is %s" % (key, val), message=message) \ No newline at end of file + self.say("%s is %s" % (key, val), message=message) diff --git a/will/plugins/chat_room/__init__.py b/will/plugins/chat_room/__init__.py index cf8ba79d..32aff261 100644 --- a/will/plugins/chat_room/__init__.py +++ b/will/plugins/chat_room/__init__.py @@ -1 +1 @@ -MODULE_DESCRIPTION = "Hipchat actions" \ No newline at end of file +MODULE_DESCRIPTION = "Hipchat actions" diff --git a/will/plugins/chat_room/rooms.py b/will/plugins/chat_room/rooms.py index e28d9daa..ac38c6df 100644 --- a/will/plugins/chat_room/rooms.py +++ b/will/plugins/chat_room/rooms.py @@ -7,10 +7,9 @@ class RoomsPlugin(WillPlugin): @respond_to("what are the rooms\?") def list_rooms(self, message): """what are the rooms?: List all the rooms I know about.""" - context = {"rooms": self.available_rooms.values(),} + context = {"rooms": self.available_rooms.values(), } self.say(rendered_template("rooms.html", context), message=message, html=True) - @respond_to("^update the room list") def update_rooms(self, message): self.update_available_rooms() diff --git a/will/plugins/chat_room/roster.py b/will/plugins/chat_room/roster.py index 167fbdbf..66fabfe9 100644 --- a/will/plugins/chat_room/roster.py +++ b/will/plugins/chat_room/roster.py @@ -6,5 +6,5 @@ class RosterPlugin(WillPlugin): @respond_to("who do you know about?") def list_roster(self, message): - context = {"internal_roster": self.internal_roster.values(),} + context = {"internal_roster": self.internal_roster.values(), } self.say(rendered_template("roster.html", context), message=message, html=True) diff --git a/will/plugins/devops/__init__.py b/will/plugins/devops/__init__.py index e87f5ef2..ef3427cf 100644 --- a/will/plugins/devops/__init__.py +++ b/will/plugins/devops/__init__.py @@ -1 +1 @@ -MODULE_DESCRIPTION = "Devops, server stuff, and uptime" \ No newline at end of file +MODULE_DESCRIPTION = "Devops, server stuff, and uptime" diff --git a/will/plugins/devops/emergency_contacts.py b/will/plugins/devops/emergency_contacts.py index 7a978edd..b1a9ecad 100644 --- a/will/plugins/devops/emergency_contacts.py +++ b/will/plugins/devops/emergency_contacts.py @@ -2,6 +2,7 @@ from will.decorators import respond_to, periodic, hear, randomly, route, rendered_template, require_settings from will import settings + class EmergencyContactsPlugin(WillPlugin): @respond_to("^set my contact info to (?P.*)", multiline=True) @@ -24,5 +25,3 @@ def respond_to_contact_info(self, message): } contact_html = rendered_template("contact_info.html", context) self.say(contact_html, message=message) - - diff --git a/will/plugins/devops/heroku_is_up.py b/will/plugins/devops/heroku_is_up.py index df48ef41..fc7647d9 100644 --- a/will/plugins/devops/heroku_is_up.py +++ b/will/plugins/devops/heroku_is_up.py @@ -1,7 +1,8 @@ import requests from will.plugin import WillPlugin -from will.decorators import respond_to, periodic, hear, randomly, route, rendered_template, require_settings +from will.decorators import respond_to, periodic, hear, randomly,\ + route, rendered_template, require_settings class HerokuIsUpPlugin(WillPlugin): @@ -12,7 +13,10 @@ def heroku_is_up(self): last_status = self.load("last_heroku_status") if last_status and r.json()["status"] != last_status: if r.json()["status"]["Production"] != "green": - self.say("FYI everyone, heroku is having trouble: %s. \n http://status.heroku.com" % r.json()["issues"][0]["title"]) + self.say( + "FYI everyone, heroku is having trouble: %s. \n " + "http://status.heroku.com" % r.json()["issues"][0]["title"] + ) else: self.say("Looks like heroku's back up!") self.save("last_heroku_status", r.json()["status"]) diff --git a/will/plugins/friendly/__init__.py b/will/plugins/friendly/__init__.py index a6771fa6..c8dc7b3d 100644 --- a/will/plugins/friendly/__init__.py +++ b/will/plugins/friendly/__init__.py @@ -1 +1 @@ -MODULE_DESCRIPTION = "Old-fashioned friendliness" \ No newline at end of file +MODULE_DESCRIPTION = "Old-fashioned friendliness" diff --git a/will/plugins/friendly/random_topic.py b/will/plugins/friendly/random_topic.py index 2508372f..e1aa6691 100644 --- a/will/plugins/friendly/random_topic.py +++ b/will/plugins/friendly/random_topic.py @@ -11,4 +11,4 @@ def give_us_somethin_to_talk_about(self, message): """new topic: set the room topic to a random conversation starter.""" r = requests.get("http://chatoms.com/chatom.json?Normal=1&Fun=2&Philosophy=3&Out+There=4") data = r.json() - self.set_topic(data["text"], message=message) \ No newline at end of file + self.set_topic(data["text"], message=message) diff --git a/will/plugins/help/__init__.py b/will/plugins/help/__init__.py index bcbc2868..87441173 100644 --- a/will/plugins/help/__init__.py +++ b/will/plugins/help/__init__.py @@ -1 +1 @@ -MODULE_DESCRIPTION = "Help" \ No newline at end of file +MODULE_DESCRIPTION = "Help" diff --git a/will/plugins/help/help.py b/will/plugins/help/help.py index 88ef6359..4389f478 100644 --- a/will/plugins/help/help.py +++ b/will/plugins/help/help.py @@ -1,6 +1,5 @@ from will.plugin import WillPlugin -from will.decorators import respond_to, periodic, hear, randomly, route,\ - rendered_template +from will.decorators import respond_to, periodic, hear, randomly, route, rendered_template class HelpPlugin(WillPlugin): diff --git a/will/plugins/help/programmer_help.py b/will/plugins/help/programmer_help.py index ac8a3329..ce66659d 100644 --- a/will/plugins/help/programmer_help.py +++ b/will/plugins/help/programmer_help.py @@ -13,4 +13,3 @@ def help(self, message): help_text += "\n%s" % r self.say(help_text, message=message) - diff --git a/will/plugins/productivity/__init__.py b/will/plugins/productivity/__init__.py index 9c7f406e..af76d064 100644 --- a/will/plugins/productivity/__init__.py +++ b/will/plugins/productivity/__init__.py @@ -1 +1 @@ -MODULE_DESCRIPTION = "Productivity" \ No newline at end of file +MODULE_DESCRIPTION = "Productivity" diff --git a/will/plugins/productivity/hangout.py b/will/plugins/productivity/hangout.py index 48746e0d..c9322411 100644 --- a/will/plugins/productivity/hangout.py +++ b/will/plugins/productivity/hangout.py @@ -1,7 +1,9 @@ from will.plugin import WillPlugin -from will.decorators import respond_to, periodic, hear, randomly, route, rendered_template, require_settings, require_settings +from will.decorators import respond_to, periodic, hear, randomly, route,\ + rendered_template, require_settings from will import settings + class HangoutPlugin(WillPlugin): @require_settings("HANGOUT_URL",) diff --git a/will/plugins/productivity/world_time.py b/will/plugins/productivity/world_time.py index 4e0cf8b6..7d562f92 100644 --- a/will/plugins/productivity/world_time.py +++ b/will/plugins/productivity/world_time.py @@ -10,13 +10,27 @@ class TimePlugin(WillPlugin): @respond_to("what time is it in (?P.*)") def what_time_is_it_in(self, message, place): """what time is it in ___: Say the time in almost any city on earth.""" - if not hasattr(settings, "WORLD_WEATHER_ONLINE_KEY") and not hasattr(settings, "WORLD_WEATHER_ONLINE_V2_KEY"): - self.say("I need a world weather online key to do that.\n You can get one at http://developer.worldweatheronline.com, and then set the key as WORLD_WEATHER_ONLINE_V2_KEY", message=message) + if not ( + hasattr(settings, "WORLD_WEATHER_ONLINE_KEY") and + not hasattr(settings, "WORLD_WEATHER_ONLINE_V2_KEY") + ): + self.say( + "I need a world weather online key to do that.\n" + "You can get one at http://developer.worldweatheronline.com, " + "and then set the key as WORLD_WEATHER_ONLINE_V2_KEY", + message=message + ) else: if hasattr(settings, "WORLD_WEATHER_ONLINE_V2_KEY"): - r = requests.get("http://api.worldweatheronline.com/free/v2/tz.ashx?q=%s&format=json&key=%s" % (place, settings.WORLD_WEATHER_ONLINE_V2_KEY)) + r = requests.get( + "http://api.worldweatheronline.com/free/v2/tz.ashx?q=%s&format=json&key=%s" % + (place, settings.WORLD_WEATHER_ONLINE_V2_KEY) + ) elif hasattr(settings, "WORLD_WEATHER_ONLINE_KEY"): - r = requests.get("http://api.worldweatheronline.com/free/v1/tz.ashx?q=%s&format=json&key=%s" % (place, settings.WORLD_WEATHER_ONLINE_KEY)) + r = requests.get( + "http://api.worldweatheronline.com/free/v1/tz.ashx?q=%s&format=json&key=%s" % + (place, settings.WORLD_WEATHER_ONLINE_KEY) + ) resp = r.json() if "request" in resp["data"] and len(resp["data"]["request"]) > 0: place = resp["data"]["request"][0]["query"] diff --git a/will/plugins/web/__init__.py b/will/plugins/web/__init__.py index 5486a4e4..161b5efa 100644 --- a/will/plugins/web/__init__.py +++ b/will/plugins/web/__init__.py @@ -1 +1 @@ -MODULE_DESCRIPTION = "Web pages" \ No newline at end of file +MODULE_DESCRIPTION = "Web pages" diff --git a/will/scheduler.py b/will/scheduler.py index f5da736c..003c99cc 100644 --- a/will/scheduler.py +++ b/will/scheduler.py @@ -13,7 +13,7 @@ class Scheduler(ScheduleMixin, PluginModulesLibraryMixin): @classmethod def clear_locks(cls, bot): bot.save("scheduler_add_lock", False) - bot.save("scheduler_lock", False) + bot.save("scheduler_lock", False) bot.save("will_periodic_list", {}) bot.save("will_periodic_times_list", {}) @@ -36,24 +36,23 @@ def _clear_random_tasks(self): self.bot.save("scheduler_lock", True) periodic_list = self.bot.get_schedule_list(periodic_list=True) periodic_times_list = self.bot.get_times_list(periodic_list=True) - + new_periodic_list = {} new_periodic_times_list = {} - + for item_hash, item in periodic_list.items(): if not "random_task" in item: new_periodic_list[item_hash] = item new_periodic_times_list[item_hash] = periodic_times_list[item_hash] - + self.bot.save_schedule_list(new_periodic_list, periodic_list=True) self.bot.save_times_list(new_periodic_times_list, periodic_list=True) - - self.bot.save("scheduler_lock", False) + self.bot.save("scheduler_lock", False) def _run_applicable_actions_in_list(self, now, periodic_list=False): times_list = self.bot.get_times_list(periodic_list=periodic_list) - + # Iterate through times_list first, before loading the full schedule_list into memory (big pickled stuff, etc) a_task_needs_run = False for task_hash, task_time in times_list.items(): @@ -71,14 +70,18 @@ def _run_applicable_actions_in_list(self, now, periodic_list=False): running_task = True self.run_action(item) except: - logging.critical("Error running task %s. \n\n%s\nTrying to delete it and recover...\n" % (item, traceback.format_exc() )) - + logging.critical( + "Error running task %s. \n\n%s\n" + "Trying to delete it and recover...\n" % (item, traceback.format_exc()) + ) + if running_task: try: self.bot.remove_from_schedule(item["hash"], periodic_list=periodic_list) except: - logging.critical("Unable to remove task. Leaving it in, you'll have to clean it out by hand. Sorry! \n\n%s\nContinuing...\n" % (traceback.format_exc(), )) - + logging.critical( + "Unable to remove task. Leaving it in, you'll have to clean it out by hand." + "Sorry! \n\n%s\nContinuing...\n" % (traceback.format_exc(),)) def check_scheduled_actions(self): now = datetime.datetime.now() @@ -92,7 +95,15 @@ def check_scheduled_actions(self): self.last_random_schedule = now self._clear_random_tasks() for plugin_info, fn, function_name in self.bot.random_tasks: - self.add_random_tasks(plugin_info["full_module_name"], plugin_info["name"], function_name, fn.start_hour, fn.end_hour, fn.day_of_week, fn.num_times_per_day) + self.add_random_tasks( + plugin_info["full_module_name"], + plugin_info["name"], + function_name, + fn.start_hour, + fn.end_hour, + fn.day_of_week, + fn.num_times_per_day + ) try: if not self.bot.load("scheduler_add_lock", False) or not self.bot.load("scheduler_lock", False): self.bot.save("scheduler_lock", True) @@ -119,7 +130,14 @@ def run_action(self, task): thread.start() # Schedule the next one. - self.bot.add_periodic_task(task["module_name"], task["class_name"], task["function_name"], task["sched_args"], task["sched_kwargs"], ignore_scheduler_lock=True) + self.bot.add_periodic_task( + task["module_name"], + task["class_name"], + task["function_name"], + task["sched_args"], + task["sched_kwargs"], + ignore_scheduler_lock=True + ) elif task["type"] == "random_task": # Run the task module_info = self.plugin_modules_library[task["module_name"]] diff --git a/will/scripts/generate_will_project.py b/will/scripts/generate_will_project.py index 783013dd..192c5564 100644 --- a/will/scripts/generate_will_project.py +++ b/will/scripts/generate_will_project.py @@ -3,17 +3,18 @@ import stat import sys +from clint.textui import puts +from will.utils import print_head + PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__))) sys.path.append(PROJECT_ROOT) sys.path.append(os.getcwd()) -from clint.textui import colored -from clint.textui import puts, indent, columns -from will.utils import show_valid, error, warn, note, print_head class EmptyObj(object): pass + def main(): """ Creates the following structure: @@ -43,7 +44,7 @@ def main(): # Set up the directories if not os.path.exists(plugins_dir): os.makedirs(plugins_dir) - + print " __init__.py" # Create the plugins __init__.py with open(os.path.join(plugins_dir, "__init__.py"), 'w+') as f: @@ -68,7 +69,7 @@ def hello(self, message): print " /templates" if not os.path.exists(templates_dir): os.makedirs(templates_dir) - + print " blank.html" # Create the plugins __init__.py with open(os.path.join(templates_dir, "blank.html"), 'w+') as f: @@ -86,13 +87,12 @@ def hello(self, message): else: append_ignore = False with open(gitignore_path, "r+") as f: - if not "shelf.db" in f.read(): + if "shelf.db" not in f.read(): append_ignore = True if append_ignore: with open(gitignore_path, "a") as f: f.write("\nshelf.db\n") - # Create run_will.py print " run_will.py" run_will_path = os.path.join(current_dir, "run_will.py") @@ -115,17 +115,17 @@ def hello(self, message): if not os.path.exists(config_path): with open(config_path, 'w+') as f: f.write("""# Welcome to Will's settings. -# +# # Config and the environment: # --------------------------- # Will can use settings from the environment or this file, and sets reasonable defaults. -# -# Best practices: set keys and the like in the environment, and anything you'd be ok +# +# Best practices: set keys and the like in the environment, and anything you'd be ok # with other people knowing in this file. -# -# To specify in the environment, just prefix with WILL_ -# (i.e. WILL_DEFAULT_ROOM becomes DEFAULT_ROOM). +# +# To specify in the environment, just prefix with WILL_ +# (i.e. WILL_DEFAULT_ROOM becomes DEFAULT_ROOM). # In case of conflict, you will see a warning message, and the value in this file will win. @@ -134,12 +134,12 @@ def hello(self, message): # Required settings # ------------------------------------------------------------------------------------ -# The list of plugin modules will should load. +# The list of plugin modules will should load. # Will recursively loads all plugins contained in each module. # This list can contain: -# +# # Built-in core plugins: # ---------------------- # All built-in modules: will.plugins @@ -151,7 +151,7 @@ def hello(self, message): # All modules: plugins # A specific module: plugins.module_name # Specific plugins: plugins.module_name.plugin -# +# # Plugins anywhere else on your PYTHONPATH: # ----------------------------------------- # All modules: someapp @@ -160,7 +160,7 @@ def hello(self, message): # By default, the list below includes all the core will plugins and -# all your project's plugins. +# all your project's plugins. PLUGINS = [ # Built-ins @@ -205,15 +205,15 @@ def hello(self, message): # ROOMS = ['Testing, Will Kahuna',] -# The room will will talk to if the trigger is a webhook and he isn't told a specific room. +# The room will will talk to if the trigger is a webhook and he isn't told a specific room. # Default is the first of ROOMS. # DEFAULT_ROOM = 'Testing, Will Kahuna' -# Fully-qualified folders to look for templates in, beyond the two that +# Fully-qualified folders to look for templates in, beyond the two that # are always included: core will's templates folder, your project's templates folder, and # all templates folders in included plugins, if they exist. -# +# # TEMPLATE_DIRS = [ # os.path.abspath("other_folder/templates") # ] diff --git a/will/settings.py b/will/settings.py index 871e174e..aa0e5d06 100644 --- a/will/settings.py +++ b/will/settings.py @@ -111,9 +111,13 @@ def import_settings(quiet=True): if not quiet: warn("no PUBLIC_URL found in the environment or config. Defaulting to '%s'." % default_public) - if "V1_OKEN" not in settings: + if "V1_TOKEN" not in settings: if not quiet: - warn("no V1_TOKEN found in the environment or config. This is generally ok, but if you have more than 30 rooms, you may recieve rate-limit errors without one.") + warn( + "no V1_TOKEN found in the environment or config." + "This is generally ok, but if you have more than 30 rooms, " + "you may recieve rate-limit errors without one." + ) if "REDIS_MAX_CONNECTIONS" not in settings: settings["REDIS_MAX_CONNECTIONS"] = 4 diff --git a/will/utils.py b/will/utils.py index 360036f8..d18cc65f 100644 --- a/will/utils.py +++ b/will/utils.py @@ -22,11 +22,14 @@ class HTMLStripper(HTMLParser): def __init__(self): self.reset() self.fed = [] + def handle_data(self, d): self.fed.append(d) + def get_data(self): return ''.join(self.fed) + def html_to_text(html): # Do some light cleanup. html = html.replace("\n", "").replace("
", "\n").replace("
", "\n").replace('
  • ', "\n - ") @@ -35,6 +38,7 @@ def html_to_text(html): s.feed(html) return s.get_data() + def is_admin(nick): from . import settings return settings.ADMINS == '*' or nick.lower() in settings.ADMINS @@ -55,6 +59,7 @@ def error(err_string): def note(warn_string): puts(colored.cyan("- Note: %s" % warn_string)) + def print_head(): puts(""" ___/-\___ @@ -65,6 +70,6 @@ def print_head(): | | | \___/ | |_________| - + Will: Hi! """)