Skip to content

Commit

Permalink
Merge pull request #2 from solus-impar/plugins
Browse files Browse the repository at this point in the history
Plugins
  • Loading branch information
solus-impar committed Jun 22, 2016
2 parents 98448e3 + 3899cbb commit 498dfe7
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 77 deletions.
21 changes: 21 additions & 0 deletions CONTRIBUTING.md
@@ -0,0 +1,21 @@
# Contributing to `tb2k`

`tb2k` keeps plugins in the [`topics.functions`][topic functions] module. If
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.
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!'
link = 'https://wwucs.slack.com'
return topic, link
```

[topic functions]: https://github.com/solus-impar/tb2k/blob/master/topics/functions.py
16 changes: 11 additions & 5 deletions README.md
Expand Up @@ -20,18 +20,24 @@ that `tb2k` depends on the following environment variables:
If you want `tb2k` to run regularly you can add it to your `crontab` with
```
crontab -e
0 6 * * * \path\to\python3 \path\to\tb2k.py
0 6 * * * tb2k
```

Every day at 06:00, `tb2k` will update the channel's topic
to one of thse pages.
* Monday, Tuesday, & Wednesday: Random man-page
* Thursday & Friday: Random programming language
* Saturday & Sunday: Top HN story
to one of these pages.
* Random man-page
* Random programming language
* Top HN story

## New Topics
Don't like the topics that `tb2k` currently supports? Follow the
[contribution guidelines] to add one!

## Resources
Slack API: [api.slack.com](https://api.slack.com/)

You should also check out [wb2k].

[wb2k]: https://www.github.com/reillysiemens/wb2k/
[virtualenv]: https://virtualenv.pypa.io/en/stable/
[contribution guidelines]: https://github.com/solus-impar/tb2k/blob/master/CONTRIBUTING.md
7 changes: 4 additions & 3 deletions setup.py
@@ -1,5 +1,5 @@
import os.path
from setuptools import setup
from setuptools import setup, find_packages
from pip.req import parse_requirements

here = os.path.abspath(os.path.dirname(__file__))
Expand All @@ -10,11 +10,12 @@

setup(
name='tb2k',
version='0.2.0',
version='0.3.0',
description='A python3 slack topic bot.',
author='Mike Canoy',
author_email='canoym@students.wwu.edu',
url='https://github.com/solus-impar/tb2k',
packages=find_packages(),
install_requires=requirements,
license='MIT',
keywords='topic bot Slack',
Expand All @@ -23,7 +24,7 @@
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
],
py_modules=['tb2k'],
py_modules=['tb2k', 'topics'],
entry_points={
'console_scripts': [
'tb2k=tb2k:main',
Expand Down
77 changes: 8 additions & 69 deletions tb2k.py
Expand Up @@ -5,12 +5,12 @@
import os
import sys
import random
from datetime import date

import requests
import wikipedia
from slackclient import SlackClient

import topics.functions as tf


def find_id(channel, bot):
"""Find the ID of a channel and whether it is public or private."""
Expand All @@ -34,63 +34,6 @@ def find_id(channel, bot):
sys.exit("tb2k: error: couldn't find #{}".format(channel))


def fetch_json(url):
"""Fetch data from a URL and attempt to parse it as JSON."""
try:
response = requests.get(url)
except requests.ConnectionError:
sys.exit("tb2k: error: cannot connect to {}".format(url))

status_code = response.status_code
if status_code == 200:
try:
return response.json()
except ValueError:
sys.exit("tb2k: error: invalid JSON at {}".format(url))
else:
sys.exit("tb2k: error: {} fetching {}".format(status_code, url))


def man_page():
"""Randomly select a man page from /usr/share/man/."""
sec = random.randrange(1, 9)
man_dir = "/usr/share/man/man{}/".format(sec)
man_url = "http://man7.org/linux/man-pages/man{}/".format(sec)

try:
page = random.choice(os.listdir(man_dir))
except IndexError:
sys.exit("tb2k: error: no man pages in section {}".format(sec))
except FileNotFoundError:
sys.exit("tb2k: error: {} does not exist".format(man_dir))
except PermissionError:
sys.exit("tb2k: error: {}: permission denied".format(man_dir))

man_url = "{}{}.{}.html".format(man_url, page.split('.')[0], sec)
return "{}({})".format(page.split('.')[0], sec), man_url


def 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(' ','_'))
return lang, lang_url


def top_hacker_news_story():
"""Select the current top Hacker News story."""
hn_api = 'https://hacker-news.firebaseio.com/v0'

stories_url = "{}/topstories.json".format(hn_api)
stories = fetch_json(stories_url)

story_url = "{}/item/{}.json".format(hn_api, stories[0])
story = fetch_json(story_url)

return story['title'], story['url']

def main():
"""
Set a channel topic to one of:
Expand All @@ -107,16 +50,12 @@ def main():

bot = SlackClient(token)
if bot.rtm_connect():
day = date.today().weekday()
# Mon Tue Wed
if day < 3:
topic, link = man_page()
# Thur Fri
elif day < 5:
topic, link = wikipedia_programming_language()
# Sat Sun
else:
topic, link = top_hacker_news_story()

# 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')]
topic_func = random.choice(topic_funcs)
topic, link = topic_func()

channel_id, channel_type = find_id(channel, bot)

Expand Down
Empty file added topics/__init__.py
Empty file.
48 changes: 48 additions & 0 deletions topics/functions.py
@@ -0,0 +1,48 @@
import os
import sys
import random

import wikipedia

from topics.utils import fetch_json


def topic_man_page():
"""Randomly select a man page from /usr/share/man/."""
sec = random.randrange(1, 9)
man_dir = "/usr/share/man/man{}/".format(sec)
man_url = "http://man7.org/linux/man-pages/man{}/".format(sec)

try:
page = random.choice(os.listdir(man_dir))
except IndexError:
sys.exit("tb2k: error: no man pages in section {}".format(sec))
except FileNotFoundError:
sys.exit("tb2k: error: {} does not exist".format(man_dir))
except PermissionError:
sys.exit("tb2k: error: {}: permission denied".format(man_dir))

man_url = "{}{}.{}.html".format(man_url, page.split('.')[0], sec)
return "{}({})".format(page.split('.')[0], sec), man_url


def topic_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(' ','_'))
return lang, lang_url


def topic_top_hacker_news_story():
"""Select the current top Hacker News story."""
hn_api = 'https://hacker-news.firebaseio.com/v0'

stories_url = "{}/topstories.json".format(hn_api)
stories = fetch_json(stories_url)

story_url = "{}/item/{}.json".format(hn_api, stories[0])
story = fetch_json(story_url)

return story['title'], story['url']
19 changes: 19 additions & 0 deletions topics/utils.py
@@ -0,0 +1,19 @@
import sys
import requests


def fetch_json(url):
"""Fetch data from a URL and attempt to parse it as JSON."""
try:
response = requests.get(url)
except requests.ConnectionError:
sys.exit("tb2k: error: cannot connect to {}".format(url))

status_code = response.status_code
if status_code == 200:
try:
return response.json()
except ValueError:
sys.exit("tb2k: error: invalid JSON at {}".format(url))
else:
sys.exit("tb2k: error: {} fetching {}".format(status_code, url))

0 comments on commit 498dfe7

Please sign in to comment.