def __init__(self, username, password, sk_key): self.reply_string = "" self.username = username self.password = password self.query = "" self.db = SQLManager() self.r = praw.Reddit(USERAGENT) self.sk = Songkick(sk_key)
class ConcertBot(object): """A Reddit bot that scans for mentions and delivers information on concerts. A ConcertBot has the following properties: Attributes: username: The username of the Reddit account being logged into. password: The password of the Reddit account being logged into. sk_key: A valid Songkick API. reply_string: The string containing the response to a found comment. query: The string containing the payload for a Songkick API request. db: An instance of SQLManager to manage a database of posts already replied to. r: An instance of the PRAW wrapper to manage Reddit API actions. sk: An instance of Songkick to manage Songkick API actions. Constants: USERAGENT: A short description of what the bot does SUBREDDIT: The sub or list of subs to be scanned for new posts. PARENTSTRING: The keywords we're looking for MAXPOSTS: The maximum number of posts responded to per run. WAIT: The time (in seconds) to wait in between runs. BAD_INPUT: A premade error message to reply. SIGNATURE: A line of text found at the end of every post Methods: init: Class takes username and password values and initializes a sql database and reddit client using PRAW. login: Logs into Reddit using the credentials stored in the instance variables. """ def __init__(self, username, password, sk_key): self.reply_string = "" self.username = username self.password = password self.query = "" self.db = SQLManager() self.r = praw.Reddit(USERAGENT) self.sk = Songkick(sk_key) def login(self): logging.info('BOT: Logging in...') self.r.login(self.username, self.password) def search_for_posts(self): logging.info('BOT: Searching /r/'+ SUBREDDIT + '.') subreddit = self.r.get_subreddit(SUBREDDIT) posts = subreddit.get_comments(limit=MAXPOSTS) for post in posts: pid = post.id try: pauthor = post.author.name logging.info("Looking at post %s", pid) self.db.select_by_postID(pid) if not self.db.fetch_selection(): #If the current post isn't found in the database of old posts pbody = post.body if any(key in pbody for key in PARENTSTRING): logging.info('BOT: Found a key match.') if pauthor.lower() != self.username.lower(): #Split comment text by quotes to catch payload catch = pbody.split('"') if not catch: #Empty payload self.send_reply(BAD_INPUT, post) else: #Send payload to Songkick self.call_Songkick(catch[1], post) else: #Current post author account matches bot username. logging.info('BOT: Will not reply to self account.') self.db.insert_oldpost(pid) else: pass except AttributeError: #Author is deleted. We don't care about this. logging.info("Post %s deleted.", pid) pass def send_reply(self,content,recipient): logging.info('BOT: Replying to ' + recipient.id + ' by ' + recipient.author.name + '.') logging.info("BOT: ********") logging.info("%s",content) logging.info("BOT: ********") recipient.reply(content + SIGNATURE) self.db.insert_oldpost(recipient.id) self.reply_string = "" def call_Songkick(self, payload, current_post): try: artist = self.sk.get_artist_info_by_name(payload) except ValueError: self.send_reply(BAD_INPUT, current_post) return None if not artist: self.send_reply(NO_RESULTS, current_post) return None #Find upcoming events try: calendar = self.sk.get_events_by_artistID(artist.id) except ValueError: self.send_reply(BAD_INPUT, current_post) return None if not calendar: self.send_reply("Couldn't find any upcoming tour dates for ["+artist.name+"](" + artist.url + "). Laaaame.\n\n", current_post) return None else: #begin building reply self.reply_string = "Hey there! Here's where " + artist.name + " will be performing soon:" #list the events and their dates for i in calendar.list_events[:6]: datesplit = i["start"]["date"].split('-') self.reply_string += "\n\n* " + datesplit[1] +"/"+ datesplit[2] + " @ " + i["location"]["city"] #append with link to songkick page if calendar.num_events > 6: self.reply_string += "\n\n" + str((calendar.num_events - 6)) + " events not shown. Click [here](" + artist.url + ") to view or buy tickets." self.send_reply(self.reply_string,current_post) return None else: self.reply_string += "\n\nClick [here](" + artist.url + ") to view more information or buy tickets." self.send_reply(self.reply_string,current_post) return None def run_bot(self): while True: try: self.search_for_posts() except Exception as e: traceback.print_exc() print('Running again in %d seconds \n' % WAIT) time.sleep(WAIT)
def __init__(self): self.bandsintown = Bandsintown(settings.BANDSINTOWN_APP_ID) self.songkick = Songkick(settings.SONGKICK_API_KEY)
def check_concerts(self, widget): self.textview.get_buffer().set_text("") #pixbuf = GdkPixbuf.Pixbuf.new_from_file('SK_badge.png') bad_names = [] dev_key = "yBb9DilAbXqZ0MCH" try: songkick = Songkick(api_key=dev_key) except: self.textview.get_buffer().set_text( "ERROR: Unable to access SongKick!\n") return None infile = open("name_setting.txt", "r") temp = infile.read().split("\n") temp = filter(None, temp) artist_names = list(set(temp)) #self.url_lib = Gtk.Label() #self.url_lib.set_markup('<a href="http://www.w3schools.com/html/">Visit our HTML tutorial</a>') self.ebox = Gtk.Button("PLEASE") self.ebox.show() #anchor = Gtk.TextChildAnchor() #buffer1 = self.textview.get_buffer() #iter1 = buffer1.get_end_iter() #anchor = buffer1.create_child_anchor(iter1) #self.textview.add_child_at_anchor(self.url_lib, anchor) #self.textview.show_all() #self.textview.get_buffer().insert_with_tags(self.textview.get_buffer().get_end_iter(), self.url_lib) # anchor = self.textview.create_child_anchor(self.textview.get_buffer().get_end_iter()) if not artist_names: self.textview.get_buffer().set_text( "Your List of Artists is Empty!\n") return file_setting.write_new_file(artist_names, "name_setting.txt") new_city = file_setting.parse_file("city_setting.txt") try: search = new_city[0] except: search = "" pass if search == "": error_mess = "you currently do not have a location set!" self.textview.get_buffer().insert( self.textview.get_buffer().get_end_iter(), "\n" + error_mess) return None #search = search.lower() search = search.title() user_city = search for name in artist_names: events = songkick.events.query(artist_name=name) try: for event in events: city = event.location.city.encode('ascii', 'ignore').split(",") if city[0] == user_city: url1 = "<a href=" url2 = event.uri.encode('ascii', 'ignore') url3 = ">Check Tickets</a>" final_url = url1 + "\"" + url2 + "\"" + url3 index = final_url.find('utm_medium') tickets_url = final_url[:index] + "amp;" + final_url[ index:] event_name = event.display_name.encode( 'ascii', 'ignore') event_loc = event.location.city.encode( 'ascii', 'ignore') event_venue = event.venue.display_name.encode( 'ascii', 'ignore') self.textview.get_buffer().insert( self.textview.get_buffer().get_end_iter(), "\n" + "--------------------------------------------------------------------------------------------------" ) self.textview.get_buffer().insert( self.textview.get_buffer().get_end_iter(), "\n" + "*") self.textview.get_buffer().insert( self.textview.get_buffer().get_end_iter(), "\n" + name) self.textview.get_buffer().insert( self.textview.get_buffer().get_end_iter(), "\n" + "*") self.textview.get_buffer().insert( self.textview.get_buffer().get_end_iter(), "\n" + event_name) self.textview.get_buffer().insert( self.textview.get_buffer().get_end_iter(), "\n" + event_loc) self.textview.get_buffer().insert( self.textview.get_buffer().get_end_iter(), ", " + event_venue) #self.textview.get_buffer().insert_pixbuf(self.textview.get_buffer().get_end_iter(), pixbuf) self.textview.get_buffer().insert( self.textview.get_buffer().get_end_iter(), "\n") test_url = '<a href="http://www.w3schools.com/html/">Check Tickets</a>' #print test_url #print tickets_url #print final_url self.url_lib = Gtk.Label() self.url_lib.set_markup(tickets_url) buffer1 = self.textview.get_buffer() iter1 = buffer1.get_end_iter() anchor = buffer1.create_child_anchor(iter1) self.textview.add_child_at_anchor(self.url_lib, anchor) self.textview.show_all() except: bad_names.append(name) continue if bad_names: for name in bad_names: file_setting.delete_data(name, "name_setting.txt")
def check_concerts(self, widget): self.textview.get_buffer().set_text("") bad_names = [] global dev_key #global key try: songkick = Songkick(api_key = dev_key) except: self.textview.get_buffer().set_text("ERROR: Unable to access SongKick!\n") return None infile = open("data/settings/name_setting.txt", "r") temp = infile.read().split("\n") temp = filter(None, temp) artist_names = list(set(temp)) if not artist_names: self.textview.get_buffer().set_text("Your List of Artists is Empty!\n") return file_setting.write_new_file(artist_names, "data/settings/name_setting.txt") new_city = file_setting.parse_file("data/settings/city_setting.txt") try: search = new_city[0] except: search = "" pass if search == "": error_mess = "you currently do not have a location set!" self.textview.get_buffer().insert(self.textview.get_buffer().get_end_iter(), "\n" + error_mess) return None search = search.title() user_city = search for name in artist_names: events = songkick.events.query(artist_name = name ) try: for event in events: city = event.location.city.encode('ascii', 'ignore').split(",") if city[0] == user_city: url1 = "<a href=" url2 = event.uri.encode('ascii','ignore') url3 = ">Check Tickets</a>" final_url = url1 + "\"" + url2 + "\"" + url3 index = final_url.find('utm_medium') tickets_url = final_url[:index] + "amp;" + final_url[index:] event_info = ( "\n--------------------------------------------------------------------------------------------------\n" "*\n" "{artist_name}\n" "*\n" "{event_name}\n" "{event_location}, {venue_name}\n" ).format( artist_name = name, event_name = event.display_name.encode('ascii','ignore'), event_location = event.location.city.encode('ascii','ignore'), venue_name = event.venue.display_name.encode('ascii','ignore') ) self.textview.get_buffer().insert(self.textview.get_buffer().get_end_iter(), event_info) self.url_lib = Gtk.Label() self.url_lib.set_markup(tickets_url) buffer1 = self.textview.get_buffer() iter1 = buffer1.get_end_iter() anchor = buffer1.create_child_anchor(iter1) self.textview.add_child_at_anchor(self.url_lib, anchor) self.textview.show_all() except: bad_names.append(name) continue if bad_names: for name in bad_names: file_setting.delete_data(name , "data/settings/name_setting.txt")