From cd7a0f2255d41643fd2a04c762e2e4b2a7445da3 Mon Sep 17 00:00:00 2001 From: Reilly Tucker Siemens Date: Sat, 25 Jun 2016 02:32:28 -0700 Subject: [PATCH] Change how topic functions are defined. Instead of requiring a topic_ prefix functions are now decorated with the @topic decorator. Additionally, topics now cite their topic source when posting a link to Slack. --- CONTRIBUTING.md | 18 +++++++++++++++--- setup.py | 2 +- tb2k.py | 13 +++++++++---- topics/functions.py | 13 ++++++++----- topics/utils.py | 6 ++++++ 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0874832..5cc45df 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,17 +5,29 @@ you'd like to contribute a topic source of your own you can submit a pull request to this repository adding a function to that module. Topic functions **MUST** conform to the following specification: -1. Begin with the `topic_` prefix. +1. Be decorated with the `@topic` decorator from [`topics.utils`][topic utils]. 2. Take no arguments. 3. Return a `topic` string and a `link` string as a tuple. - The `link` _can_ be the empty string. An example topic function might look like this: ```python -def topic_wwucs(): - topic = 'WWU CS rules!' +@topic +def wwu_cs_rules(): + topic = 'WWU CS is the best!' link = 'https://wwucs.slack.com' return topic, link ``` +## Note +The `@topic` decorator sets a special attribute, `__topic__`, on the topic +function to signal that it is a topic, but also for naming purposes. The +`__topic__` attribute is used to provide source for links. For example, +the above function would show up in a Slack message like +> WWU CS Rules: https://wwucs.slack.com + +Therefore, it behooves contributors to pick descriptive names for new topic +functions. + [topic functions]: https://github.com/solus-impar/tb2k/blob/master/topics/functions.py +[topic utils]: https://github.com/solus-impar/tb2k/blob/master/topics/utils.py diff --git a/setup.py b/setup.py index 905bed5..c981982 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ setup( name='tb2k', - version='0.3.0', + version='0.4.0', description='A python3 slack topic bot.', author='Mike Canoy', author_email='canoym@students.wwu.edu', diff --git a/tb2k.py b/tb2k.py index b2e3855..0ef1589 100644 --- a/tb2k.py +++ b/tb2k.py @@ -51,9 +51,12 @@ def main(): bot = SlackClient(token) if bot.rtm_connect(): - # Get all attributes in the topics.functions module that begin with - # 'topic', randomly choose one, and then execute it. - topic_funcs = [getattr(tf, f) for f in dir(tf) if f.startswith('topic')] + # Get all attributes in the topics.functions module that are callable + # and possess the custom __topic__ attribute. + topic_funcs = [] + for attr in (getattr(tf, a) for a in dir(tf)): + if hasattr(attr, '__call__') and hasattr(attr, '__topic__'): + topic_funcs.append(attr) topic_func = random.choice(topic_funcs) topic, link = topic_func() @@ -71,8 +74,10 @@ def main(): try: response = requests.head(link) if response.ok: + source = "{}: {}".format(topic_func.__topic__, link) response = bot.api_call("chat.postMessage", token=token, - channel=channel_id, text=link, as_user=True) + channel=channel_id, text=source, + as_user=True) if not response['ok']: sys.exit("tb2k: error: failed to post link in #{}".format( channel)) diff --git a/topics/functions.py b/topics/functions.py index 42a555e..7304e70 100644 --- a/topics/functions.py +++ b/topics/functions.py @@ -4,10 +4,11 @@ import wikipedia -from topics.utils import fetch_json +from topics.utils import topic, fetch_json -def topic_man_page(): +@topic +def random_man_page(): """Randomly select a man page from /usr/share/man/.""" sec = random.randrange(1, 9) man_dir = "/usr/share/man/man{}/".format(sec) @@ -26,16 +27,18 @@ def topic_man_page(): return "{}({})".format(page.split('.')[0], sec), man_url -def topic_wikipedia_programming_language(): +@topic +def random_wikipedia_programming_language(): """Randomly select a programming language from Wikipedia.""" title = 'List of programming languages' page = wikipedia.page(title=title) lang = random.choice(page.links) - lang_url = "https://en.wikipedia.org/wiki/{}".format(lang.replace(' ','_')) + lang_url = "https://en.wikipedia.org/wiki/{}".format(lang.replace(' ', '_')) return lang, lang_url -def topic_top_hacker_news_story(): +@topic +def top_hacker_news_story(): """Select the current top Hacker News story.""" hn_api = 'https://hacker-news.firebaseio.com/v0' diff --git a/topics/utils.py b/topics/utils.py index 046db23..da470c8 100644 --- a/topics/utils.py +++ b/topics/utils.py @@ -2,6 +2,12 @@ import requests +def topic(func): + name = " ".join(w.title() for w in func.__name__.split('_')) + func.__topic__ = name + return func + + def fetch_json(url): """Fetch data from a URL and attempt to parse it as JSON.""" try: