From f5258138c364ccb70f87fc4dd482d9ce5965e1bd Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Thu, 5 Sep 2019 18:12:14 -0400 Subject: [PATCH 1/7] Initial commit of links.py --- scripts/links.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 scripts/links.py diff --git a/scripts/links.py b/scripts/links.py new file mode 100644 index 0000000..2b56cae --- /dev/null +++ b/scripts/links.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import random +import sys +from response import Response + +from pb_logging import PBLogger +logger = PBLogger("Links") + +# flips a coin +def run(response): + response_obj = Response(sys.modules[__name__]) + res_message = "" + links = { + "Website":"pantherhackers.com", + "Slack":"pantherhackers.slack.com", + "Instagram":"instagram.com/pantherhackers", + "Twitter":"twitter.com/pantherhackers", + "GitHub":"github.com/PantherHackers" + } + for n, l in links: + res_message = res_message + n + ": " + l + "\n" + response_obj.messages_to_send.append(res_message) + logger.info(res_message) + return response_obj + +def return_alias(): + alias_list = ["links"] + return alias_list + +def is_admin_command(): + return False + +def help_preview(): + return "!links" + +def help_text(): + return "Lists links to revelant pages and social accounts." From 9f55719f274a03ca01a0bc214e8a4e689148e28f Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Thu, 5 Sep 2019 18:42:08 -0400 Subject: [PATCH 2/7] Added args to links.py, get specific link --- scripts/links.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/scripts/links.py b/scripts/links.py index 2b56cae..164dc38 100644 --- a/scripts/links.py +++ b/scripts/links.py @@ -8,7 +8,7 @@ logger = PBLogger("Links") # flips a coin -def run(response): +def run(response, args): response_obj = Response(sys.modules[__name__]) res_message = "" links = { @@ -18,8 +18,21 @@ def run(response): "Twitter":"twitter.com/pantherhackers", "GitHub":"github.com/PantherHackers" } - for n, l in links: - res_message = res_message + n + ": " + l + "\n" + specific_link = False + if args: + specific_link = True + if specific_link: + try: + for a in args: + res_message = res_message + a.lower().capitalize() + ": " + links[a.lower().capitalize()] + "\n" + except Exception as e: + logger.error(a.lower().capitalize() + " not found in links") + specific_link = False + break + if not specific_link: + res_message = "" + for n, l in links: + res_message = res_message + n + ": " + l + "\n" response_obj.messages_to_send.append(res_message) logger.info(res_message) return response_obj @@ -32,7 +45,7 @@ def is_admin_command(): return False def help_preview(): - return "!links" + return "!links " def help_text(): return "Lists links to revelant pages and social accounts." From 44f2caec1c9aa97787d039e26ae415800bcc2541 Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Thu, 5 Sep 2019 21:52:48 -0400 Subject: [PATCH 3/7] Initial commit of summary.py --- scripts/summary.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 scripts/summary.py diff --git a/scripts/summary.py b/scripts/summary.py new file mode 100644 index 0000000..4c34d5b --- /dev/null +++ b/scripts/summary.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import random +import sys +import urllib2, json +from response import Response + +from pb_logging import PBLogger +logger = PBLogger("Summary") + +# flips a coin +def run(response, args): + response_obj = Response(sys.modules[__name__]) + res_text = "" + if args: + smmry_url = "http://api.smmry.com/&SM_API_KEY=CFE8330DFD&SM_URL=" + args[0] + parsed_response = json.loads(urllib2.urlopen(smmry_url).read()) + if 'sm_api_content' in parsed_response: + res_text = parsed_response['sm_api_content'] + else: + res_text = "Whoops, something went wrong with the SMMRY API" + else: + res_text = "D'oh, you didn't include a link!" + response_obj.messages_to_send.append(res_text) + logger.info(res_text) + return response_obj + +def return_alias(): + alias_list = ["summary"] + return alias_list + +def is_admin_command(): + return False + +def help_preview(): + return "!summary " + +def help_text(): + return "Get a summary of an article or webpage" From ebe9188e90dcb74673d55182a1f56250c4a6b7e7 Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Thu, 5 Sep 2019 22:07:17 -0400 Subject: [PATCH 4/7] Initial commit of reddit.py --- scripts/reddit.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 scripts/reddit.py diff --git a/scripts/reddit.py b/scripts/reddit.py new file mode 100644 index 0000000..e836173 --- /dev/null +++ b/scripts/reddit.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import praw +import sys +from response import Response + +def run(response, pb_cooldown, args=None): + response_obj = Response(sys.modules[__name__]) + + if pb_cooldown is False: + response_obj.messages_to_send.append("Sorry, reddit is on cooldown.") + return response_obj + + reddit = praw.Reddit(client_id='aGpQJujCarDHWA', + client_secret='fkA9lp0NDx23B_qdFezTeGyGKu8', + user_agent='my user agent', + password='PHGSU2017', + username='Panther_Bot') + subreddit = "GaState" + + if args is not None: # Use specified subreddit. Else, default to r/GaState + subreddit = str(args[0]) + if subreddit.startswith("r/"): + subreddit = subreddit[2:] + + post_urls=[] + for submission in reddit.subreddit(subreddit).hot(limit=3): + post_urls.append(submission.url) + response_obj.messages_to_send = post_urls + response_obj.special_condition = True + return response_obj + +def return_alias(): + alias_list = ["reddit"] + return alias_list + +def error_cleanup(error_code): + response_obj = Response(sys.modules[__name__]) + response_obj.messages_to_send.append("An unknown error occured. Error code: " + str(error_code)) + return response_obj + +def set_cooldown(bot): + if bot.pb_cooldown is True: + bot.pb_cooldown = False + +def special_condition(bot): + set_cooldown(bot) + +def is_admin_command(): + return False + +def help_preview(): + return "!reddit" + +def help_text(): + return "Returns top 3 hot posts from a subreddit (Defaults to r/GaState if no subreddit provided)." From 558b9717107507a6bde97c16528ca555b565cd2c Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Sat, 7 Sep 2019 02:23:37 -0400 Subject: [PATCH 5/7] Initial commit of marta.py --- scripts/marta.py | 136 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 scripts/marta.py diff --git a/scripts/marta.py b/scripts/marta.py new file mode 100644 index 0000000..f85cbef --- /dev/null +++ b/scripts/marta.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import random +import sys +import requests +import json +from response import Response +from marta.api import get_buses, get_trains +from collections import defaultdict + +from pb_logging import PBLogger +logger = PBLogger("MARTA") + +stations = { + "AIRPORT STATION": ['airport','hartsfield','hartsfield-jackson'], + "ARTS CENTER STATION": ['arts center'], + "ASHBY STATION": ['ashby'], + "AVONDALE STATION": ['avondale'], + "BANKHEAD STATION": ['bankhead'], + "BROOKHAVEN STATION": ['brookhaven'], + "BUCKHEAD STATION": ['buckhead'], + "CHAMBLEE STATION": ['chamblee'], + "CIVIC CENTER STATION": ['civic center'], + "COLLEGE PARK STATION": ['college park'], + "DECATUR STATION": ['decatur'], + "OMNI DOME STATION": ['omni dome'], + "DORAVILLE STATION": ['doraville'], + "DUNWOODY STATION": ['dunwoody'], + "EAST LAKE STATION": ['east lake'], + "EAST POINT STATION": ['east point'], + "EDGEWOOD CANDLER PARK STATION": ['edgewood','candler park'], + "FIVE POINTS STATION": ['five points','5 points'], + "GARNETT STATION": ['garnett'], + "GEORGIA STATE STATION": ['georgia state','gsu','school'], + "HAMILTON E HOLMES STATION": ['hamilton e holmes','h.e. holmes','he holmes'], + "INDIAN CREEK STATION": ['indian creek'], + "INMAN PARK STATION": ['inman','inman park'], + "KENSINGTON STATION": ['kensington'], + "KING MEMORIAL STATION": ['king memorial','mlk'], + "LAKEWOOD STATION": ['lakewood'], + "LENOX STATION": ['lenox'], + "LINDBERGH STATION": ['lindbergh'], + "MEDICAL CENTER STATION": ['medical center'], + "MIDTOWN STATION": ['midtown'], + "NORTH AVE STATION": ['north ave','north avenue','gt','georgia tech', 'tech'], + "NORTH SPRINGS STATION": ['north springs'], + "OAKLAND CITY STATION": ['oakland','oakland city'], + "PEACHTREE CENTER STATION": ['peachtree center'], + "SANDY SPRINGS STATION": ['sandy springs'], + "VINE CITY STATION": ['vine city'], + "WEST END STATION": ['west end'], + "WEST LAKE STATION": ['west lake'] +} + +# flips a coin +def run(response, station=None, line=None, direction=None): + response_obj = Response(sys.modules[__name__]) + found=False + stationName = "GEORGIA STATE STATION" + if station != None: # Default to Georgia State Station if not specified + stationName = str(station) + for s in stations: + if stationName.upper() == s or stationName.lower() in stations[s][0]: + stationName = s + found=True + break + if not found: + response_obj.messages_to_send.append("Sorry, I don't know that station.") + logger.info("Sorry, I don't know that station.") + return response_obj + else: + trains = get_trains(station=stationName) + if trains: + if line is not None and line.lower() in ['g','r','b','gold','red','green','blue','y','yellow','o','orange'] and direction is not None and direction.lower() in ['n','s','e','w','north','south','east','west','northbound','southbound','eastbound','westbound']: + if line.lower().startswith('r'): + line = 'RED' + elif line.lower().startswith('y') or line.lower().startswith('o') or line.lower().startswith('go'): + line = 'GOLD' + elif line.lower().startswith('b'): + line = 'BLUE' + elif line.lower().startswith('g'): + line = 'GREEN' + if direction.lower().startswith('n'): + direction = 'N' + elif direction.lower().startswith('s'): + direction = 'S' + elif direction.lower().startswith('e'): + direction = 'E' + elif direction.lower().startswith('w'): + direction = 'W' + else: + line = None + direction = None + final_trains = [] + if line: + for t in trains: + if t.line == line and t.direction == direction: + final_trains.append(t) + else: + for t in trains: + final_trains.append(t) + if final_trains: + final_message = "" + attach = ("attachments:": []} + colors = {'Red':"#FF0000",'Gold':"#FFD700",'Blue':"#0000FF",'Green':"#3CB371"} + for t in final_trains: + #final_message = final_message + t.line.capitalize() + " line train to " + t.destination + " (" + t.direction + "): " + ("Arriving in " + t.waiting_time if t.waiting_time[0].isdigit() else t.waiting_time) + "\n" + message = t.line.capitalize() + " line train to " + t.destination + " (" + t.direction + "): " + ("Arriving in " + t.waiting_time if t.waiting_time[0].isdigit() else t.waiting_time) + attach['attachments'].append({'fallback': message, 'color': colors[t.line.capitalize()], 'text': message}) + #await ctx.send(final_message) + response_obj.messages_to_send.append(attach) + logger.info("Returning some MARTA data...") + return response_obj + else: + #await ctx.send("No trains in the near future.") + response_obj.messages_to_send.append("No trains arriving for that route.") + logger.info("No trains arriving for that route.") + return response_obj + else: + #print("No trains near that station.") + response_obj.messages_to_send.append("No trains near that station.") + logger.info("No trains near that station.") + return response_obj + +def return_alias(): + alias_list = ["marta"] + return alias_list + +def is_admin_command(): + return False + +def help_preview(): + return "!coin" + +def help_text(): + return "Flips a coin and returns the result... Sometimes you wonder if people even read these. Heads they don't." From 12d40378107b05b418ef5b3abad486dfb73c2c31 Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Sat, 7 Sep 2019 02:24:28 -0400 Subject: [PATCH 6/7] Modifications to bot files to handle attachments --- bot.py | 41 +++++++++++++++++++++++++++++++---------- reactbot.py | 2 +- requirements.txt | 1 + 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/bot.py b/bot.py index 143d29e..8483f03 100644 --- a/bot.py +++ b/bot.py @@ -79,13 +79,24 @@ def channels_to_ids(self, channel_names): # Send Message # Sends a message to the specified channel (looks up by channel name, unless is_id is True) - def send_msg(self, channel, text, is_id=False, thread_ts=None): + def send_msg(self, channel, text, is_id=False, thread_ts=None, attach=None): if is_id: channel_id = channel else: channel_id = self.channels_to_ids([channel])[0] if thread_ts is not None: - response_json = self.SLACK_CLIENT.api_call( + if attach is not None: + response_json = self.SLACK_CLIENT.api_call( + "chat.postMessage", + channel=channel_id, + text=text, + username=self.BOT_NAME, + icon_url=self.BOT_ICON_URL, + thread_ts=thread_ts, + attachments=attach + ) + else: + response_json = self.SLACK_CLIENT.api_call( "chat.postMessage", channel=channel_id, text=text, @@ -94,13 +105,23 @@ def send_msg(self, channel, text, is_id=False, thread_ts=None): thread_ts=thread_ts ) else: - response_json = self.SLACK_CLIENT.api_call( - "chat.postMessage", - channel=channel_id, - text=text, - username=self.BOT_NAME, - icon_url=self.BOT_ICON_URL - ) + if attach is not None: + response_json = self.SLACK_CLIENT.api_call( + "chat.postMessage", + channel=channel_id, + text=text, + username=self.BOT_NAME, + icon_url=self.BOT_ICON_URL, + attachments=attach + ) + else: + response_json = self.SLACK_CLIENT.api_call( + "chat.postMessage", + channel=channel_id, + text=text, + username=self.BOT_NAME, + icon_url=self.BOT_ICON_URL + ) logger.info("Message sent: ") return response_json @@ -115,4 +136,4 @@ def emoji_reaction(self, channel, ts, emoji): def close(self): self.WEBSOCKET.keep_running = False - logger.info("Closing Websocket...") \ No newline at end of file + logger.info("Closing Websocket...") diff --git a/reactbot.py b/reactbot.py index cae1524..4019b3e 100644 --- a/reactbot.py +++ b/reactbot.py @@ -152,7 +152,7 @@ def on_open(self, ws): # message_json Message # Sends a message to the same channel that message_json originates from # Provide a username and icon URL to override the default ones - def response_message(self, message_json, l, username=None, icon_url=None): + def response_message(self, message_json, l, username=None, icon_url=None, attach=None): for text in l: self.SLACK_CLIENT.api_call( "chat.postMessage", diff --git a/requirements.txt b/requirements.txt index aaa5fdf..058f5d3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ websocket-client chatterbot pyaml praw +git+https://github.com/itsmarta/marta-python.git From 086375b41bf1fe28164fb76266b74c3de3a1289a Mon Sep 17 00:00:00 2001 From: Nate Harris Date: Sun, 8 Sep 2019 01:25:37 -0400 Subject: [PATCH 7/7] Completed alpha of marta.py --- scripts/marta.py | 49 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/scripts/marta.py b/scripts/marta.py index f85cbef..936242d 100644 --- a/scripts/marta.py +++ b/scripts/marta.py @@ -11,48 +11,49 @@ from pb_logging import PBLogger logger = PBLogger("MARTA") +# Since Slack wouldn't know where the first arg ends and the second begins, the first arg (station name) has to be one word stations = { "AIRPORT STATION": ['airport','hartsfield','hartsfield-jackson'], - "ARTS CENTER STATION": ['arts center'], + "ARTS CENTER STATION": ['artscenter'], "ASHBY STATION": ['ashby'], "AVONDALE STATION": ['avondale'], "BANKHEAD STATION": ['bankhead'], "BROOKHAVEN STATION": ['brookhaven'], "BUCKHEAD STATION": ['buckhead'], "CHAMBLEE STATION": ['chamblee'], - "CIVIC CENTER STATION": ['civic center'], - "COLLEGE PARK STATION": ['college park'], + "CIVIC CENTER STATION": ['civiccenter'], + "COLLEGE PARK STATION": ['collegepark'], "DECATUR STATION": ['decatur'], - "OMNI DOME STATION": ['omni dome'], + "OMNI DOME STATION": ['omnidome','dome','mercedesbenz','cnn','statefarmarena','congresscenter','gwcc'], "DORAVILLE STATION": ['doraville'], "DUNWOODY STATION": ['dunwoody'], - "EAST LAKE STATION": ['east lake'], - "EAST POINT STATION": ['east point'], - "EDGEWOOD CANDLER PARK STATION": ['edgewood','candler park'], - "FIVE POINTS STATION": ['five points','5 points'], + "EAST LAKE STATION": ['eastlake'], + "EAST POINT STATION": ['eastpoint'], + "EDGEWOOD CANDLER PARK STATION": ['edgewood','candlerpark'], + "FIVE POINTS STATION": ['fivepoints','5points'], "GARNETT STATION": ['garnett'], - "GEORGIA STATE STATION": ['georgia state','gsu','school'], - "HAMILTON E HOLMES STATION": ['hamilton e holmes','h.e. holmes','he holmes'], - "INDIAN CREEK STATION": ['indian creek'], - "INMAN PARK STATION": ['inman','inman park'], + "GEORGIA STATE STATION": ['georgiastate','gsu','school'], + "HAMILTON E HOLMES STATION": ['hamiltoneholmes','h.e.holmes','heholmes'], + "INDIAN CREEK STATION": ['indiancreek'], + "INMAN PARK STATION": ['inman','inmanpark'], "KENSINGTON STATION": ['kensington'], "KING MEMORIAL STATION": ['king memorial','mlk'], "LAKEWOOD STATION": ['lakewood'], "LENOX STATION": ['lenox'], "LINDBERGH STATION": ['lindbergh'], - "MEDICAL CENTER STATION": ['medical center'], + "MEDICAL CENTER STATION": ['medicalcenter','medcenter'], "MIDTOWN STATION": ['midtown'], - "NORTH AVE STATION": ['north ave','north avenue','gt','georgia tech', 'tech'], - "NORTH SPRINGS STATION": ['north springs'], - "OAKLAND CITY STATION": ['oakland','oakland city'], - "PEACHTREE CENTER STATION": ['peachtree center'], - "SANDY SPRINGS STATION": ['sandy springs'], - "VINE CITY STATION": ['vine city'], - "WEST END STATION": ['west end'], - "WEST LAKE STATION": ['west lake'] + "NORTH AVE STATION": ['northave','northavenue','gt','georgiatech', 'tech'], + "NORTH SPRINGS STATION": ['northsprings'], + "OAKLAND CITY STATION": ['oakland','oaklandcity'], + "PEACHTREE CENTER STATION": ['peachtreecenter'], + "SANDY SPRINGS STATION": ['sandysprings'], + "VINE CITY STATION": ['vinecity'], + "WEST END STATION": ['westend'], + "WEST LAKE STATION": ['westlake'] } -# flips a coin +# MARTA times def run(response, station=None, line=None, direction=None): response_obj = Response(sys.modules[__name__]) found=False @@ -130,7 +131,7 @@ def is_admin_command(): return False def help_preview(): - return "!coin" + return "!marta " def help_text(): - return "Flips a coin and returns the result... Sometimes you wonder if people even read these. Heads they don't." + return "Check MARTA train times."