def is_there_clip(clip_id): url = "https://api.twitch.tv/helix/clips?id=" + clip_id req = urllib.request.Request(url, headers={ "Client-ID": config.CLIENT_ID, "Authorization": "Bearer " + access_token, }, data=None) try: response = urllib.request.urlopen(req) except (HTTPError, URLError) as err: debug.output_error(debug.lineno() + " - " + "HTTP Error: " + str(err)) utility.restart() data = json.load(response) # utility.print_toscreen(data) try: result = data["data"][0]["id"] except IndexError as err: debug.output_error(debug.lineno() + " - " + "Index Error: " + str(err)) return False # utility.print_toscreen("true") return True
def getStateList(order): global states global statekeys if not len(worldList): populateWorld() # else: # print len(worldList['c']) if order == 0: if not len(statekeys[0]): if config['debug'] > 3: printPretty([__name__,lineno(),worldList]) for state in worldList['s']: statename = None if len(state) > 0: statename = getStateName(state) if statename: if config['debug'] > 3: print "%s %s" % (lineno(),statename) statekeys[0][state] = statename pushLoc(state,statename) return statekeys[0] elif order == 1: if not len(statekeys[0]): getStateList(0) if not len(statekeys[1]): for state in statekeys[0]: statename = None if len(state) > 0: statename = getStateName(state) if statename: statekeys[1]["%s" % statename] = state return statekeys[1]
def get_access_token(): # url = "?grant_type=refresh_token&refresh_token=" + config.CLIENT_REFRESH_TOKEN + "&client_id=" + config.CLIENT_ID + "&client_secret=" + config.CLIENT_SECRET url = "https://id.twitch.tv/oauth2/token" data = urllib.parse.urlencode({ 'grant_type': 'refresh_token', 'refresh_token': config.CLIENT_REFRESH_TOKEN, 'client_id': config.CLIENT_ID, 'client_secret': config.CLIENT_SECRET }) data = data.encode('utf-8') # utility.print_toscreen(url) req = urllib.request.Request(url) try: response = urllib.request.urlopen(req, data=data) except (HTTPError, URLError) as err: debug.output_error(debug.lineno() + " - " + "HTTP Error: " + str(err)) utility.restart() data = json.load(response) global access_token access_token = data["access_token"] # utility.print_toscreen(data) # utility.print_toscreen(data["access_token"]) return data["access_token"]
def is_stream_live(channel_id): url = "https://api.twitch.tv/helix/streams?user_id=" + channel_id # utility.print_toscreen(url) req = urllib.request.Request(url, headers={ "Client-ID": config.CLIENT_ID, "Authorization": "Bearer " + access_token, }, data=None) response = urllib.request.urlopen(req) data = json.load(response) # utility.print_toscreen(data) try: result = data["data"][0]["type"] # utility.print_toscreen(resulqt) except IndexError as err: debug.output_error(debug.lineno() + " - " + "Index Error" + str(err)) # utility.print_toscreen("false") return False # utility.print_toscreen("true") return True
def create_clip(channel_id): url = "https://api.twitch.tv/helix/clips" data = urllib.parse.urlencode({ 'has_delay': 'false', 'broadcaster_id': channel_id, }) data = data.encode('utf-8') req = urllib.request.Request(url, headers={ "Client-ID": config.CLIENT_ID, "Authorization": "Bearer " + access_token, }, data=data) try: response = urllib.request.urlopen(req, data) except (HTTPError, URLError) as err: debug.output_error("HTTP Error: " + str(err) + debug.lineno()) return 0 data = json.load(response) # utility.print_toscreen(str(data)) return data["data"][0]["id"]
def loadRealm(fn = None,recursion = 0): """Returns a dict containing the config options in the Minette realm file.""" maxrecursion = 3 lines = [] realm = {} realm['realmloaded'] = False if fn is None or fn == "": print "Could not load realm information. No filename provided!" exit(-1) realm['realmfile'] = fn (found,fn) = findFile(lineno(),fn) if not found: print " [W] Realm %s not loaded." % fn return realm lines = readfile(fn) for line in lines: try: line = line.strip() if line: values = [x.strip() for x in line.split('=')] if values[0] != "likerealm": realm[values[0]] = values[1] # unlike config, existing realm options WILL be clobbered elif recursion < maxrecursion: # likerealm must be first option, or it may clobber options for the parent realm. rf = "realms/%s.rlm" % values[1] recursion += 1 realm.update(loadRealm(rf,recursion)) except Exception as e: print "There was an error in the realm file: %s" % e fn = realm.get("realmdir","") (found,fn) = findFile(lineno(),fn) if not found: print " [E] Fatal error. Realm directory %s not found!" % fn exit(-1) realm = validateRealm(realm) realm['realmloaded'] = True return realm
def loadConfig(fn = None,recursion = 0): """Returns a dict containing the config options in the Minette config file.""" maxrecursion = 3 lines = [] global config global defaults if fn is None: fn = "default.cfg" # using 3-letter extension for MSWin compatibility, I hope. (found,fn) = findFile(lineno(),fn) if not found: print " [W] Config %s not loaded." % fn if not defaults.get("set",False): setDefaults() config.update(defaults) return config lines = readfile(fn) for line in lines: try: line = line.strip() if line: values = [x.strip() for x in line.split('=')] if values[0] != "loadconfig": if not config.get(values[0]): config[values[0]] = values[1] # existing options will not be clobbered elif recursion < maxrecursion and os.path.exists(values[1]): # loadconfig must be first option, or its options may be ignored. recursion += 1 loadConfig(values[1],recursion) except Exception as e: print " [E] There was an error in the configuration file: %s" % e config['file'] = fn config = validateConfig(config) config['realmfile'] = "" if len(config.get("loadrealm","")) > 0 and recursion <= maxrecursion: rf = "realms/%s.rlm" % config['loadrealm'] realm = loadRealm(rf) config.update(realm) else: config['realmloaded'] = False config.update(criticalDefaults()) return config
def get_channel_id(channel_name): url = "https://api.twitch.tv/kraken/users/?api_version=5&client_id=" + config.CLIENT_ID + "&login="******"access_token"]) result = "0" try: result = data["users"][0]["_id"] except IndexError as err: debug.output_error(debug.lineno() + " - " + " Bad channel name: " + str(err)) return result return result
def bot_loop(): time.sleep(1) utility.print_toscreen("Starting Bot Loop") while connected: response = "" try: response = s.recv(1024).decode("utf-8") except Exception as e: debug.output_error(debug.lineno() + " - " + str(e)) utility.restart() # PING-PONG if re.search("PING :tmi.twitch.tv",response): try: s.send("PONG :tmi.twitch.tv\r\n".encode("utf-8")) # utility.print_toscreen("Pong") # debug.output_debug ("PONG") utility.print_usertoscreen("server", "twitch", "ping") except IOError as e: debug.output_error(debug.lineno() + " - " + "PONG error " + str(e)) utility.restart() find_all_twitch = re.findall(TWITCH_MSG, response) for found in find_all_twitch: username = "" channel = "" message = "" try: message = response[response.find(found) + len(found):] start = re.search(TWITCH_MSG, message) if start: message = message[0:start.start()] else: message = message if re.search("PRIVMSG",found): channel = re.search(r"#\w+", found).group(0) username = re.search(r"\w+", found).group(0) utility.print_usertoscreen(channel, username, message.rstrip()) else: utility.print_usertoscreen("server", "twitch", message.strip()) message = message.lower().rstrip() except Exception as e: debug.output_error(debug.lineno() + " - " + str(e)) # clip | !clip if message == "!clip" or message == "clip" or message == "clip it": channel_id = CHAT_NAMES_TO_ID[channel] debug.output_debug(channel + " | " + username + ": " + message) clip_thread = threading.Timer(5, create_clip, args=[channel, channel_id, username]) clip_thread.start() # !Hey # if message == "!hey" or message == "hi" or message == "hey" or message == "hello" or message == "heyguys": # utility.chat(s, channel, "Hey " + username + ", Welcome to the stream!") # utility.print_toscreen(CHAT_NAMES_TO_ID[channel]) # !help if message == "!help": utility.chat(s, channel, "Hi, I'm the clipping bot. type \"clip\" or \"!clip\" in chat, I'll clip the last 25 sec and post the link.") if re.search(config.TWITCH_NICK, message): debug.output_debug(channel + " | " + username + ": " + message)
for channel_name in config.CHANNEL_NAMES: time.sleep(0.2) # Getting channels id from channels names channel_id = twitch.get_channel_id(channel_name) channel_name = "#" + channel_name CHAT_NAMES_TO_ID[channel_name] = str(channel_id) s.send("JOIN {}\r\n".format(channel_name).encode("utf-8")) utility.print_toscreen(channel_name + " : " + channel_id) connected = True # Socket succefully connected except Exception as e: debug.output_error(debug.lineno() + " - " + str(e)) connected = False # Socket failed to connect utility.restart() # BOT LOOP # -------- def bot_loop(): time.sleep(1) utility.print_toscreen("Starting Bot Loop") while connected: response = ""
def populateWorld(): """Looks in the realmdir and makes a list of fileids the program can load. Makes worldList a tuple of lists. """ global config global worldList fn = os.path.join(config['realmdir'],"myrealm.cfg") persons = [] places = [] cities = [] states = [] orgs = [] # other data types. (found,fn) = common.findFile(lineno(),fn) if config['uselistfile'] and found: print " Loading worldList from file..." lines = [] try: with codecs.open(fn,'rU','utf-8') as conf: lines = conf.readlines() conf.close() except IOError as e: print " Could not open worldlist file: %s" % e exit(1) for line in lines: try: line = line.strip() if line: values = [x.strip() for x in line.split('=')] if values[0] == "persons": y = values[1] persons.extend(y.split(',')) elif values[0] == "places": y = values[1] places.extend(y.split(',')) elif values[0] == "cities": y = values[1] cities.extend(y.split(',')) elif values[0] == "states": y = values[1] states.extend(y.split(',')) elif values[0] == "orgs": y = values[1] orgs.extend(y.split(',')) elif values[0] == "person": persons.append(values[1]) elif values[0] == "place": places.append(values[1]) elif values[0] == "city": cities.append(values[1]) elif values[0] == "state": states.append(values[1]) elif values[0] == "org": orgs.append(values[1]) else: print "Unknown type %s found" % values[0] except Exception as e: print " There was an error in the configuration file: %s" % e # elif not found: # print " Fatal error. Realm directory %s does not exist! Exiting." % config['realmdir'] # exit(-1) else: print " Generating worldList from directory..." olist = os.listdir(config['realmdir']) nlist = [] ilist = [] for i in range(len(olist)): if re.search(r'.[Xx][Mm][Ll]$',olist[i]): ilist.append(os.path.splitext(olist[i])[0]) nlist.append(olist[i]) for i in range(len(nlist)): fn = os.path.join(config['realmdir'],nlist[i]) line = ""; match = -1; lno = 2 while match == -1 and lno < 6: line = getline(fn,lno) match = line.find("SYSTEM") lno += 1 match2 = line.find(".dtd") if match != -1 and match2 > match: match += 8 # trims 'SYSTEM "' line = line[match:match2] # trims '.dtd">\n' if "person" in line: persons.append(ilist[i]) elif "place" in line: places.append(ilist[i]) elif "city" in line: cities.append(ilist[i]) elif "state" in line: states.append(ilist[i]) elif "org" in line: orgs.append(ilist[i]) else: print "Unknown type %s found" % line if config['debug'] > 2: print "\nPersons: %s\nPlaces: %s\nCities: %s\nStates: %s\nOrgs: %s\n" % (persons,places,cities,states,orgs) worldList['p'] = persons worldList['l'] = places worldList['c'] = cities worldList['s'] = states worldList['o'] = orgs for key in worldList.keys(): if len(worldList[key]): if not len(worldList[key][0]): worldList[key] = [] for s in worldList['s']: pushLoc(s) getStateList(0) getCityList(0) if config['debug'] > 3: printPretty(worldList) printPretty(placeList)
def listRel(self,r,fileid,relid,scroll,psalts,target = None): if not r.get("related"): return name = r['related'][0] if not r.get("cat"): print "empty category! Attempting to find...", x = getCat(relid) if x is not None: r['cat'] = x print r else: print "Not found!\nTo repair, open %s manually, and then reload %s." % (relid,fileid) return print '\n', cat = r['cat'][0] displayFunc = None if cat == "person": displayFunc = displayPerson elif cat == "place": displayFunc = place.displayPlace else: print "Invalid category '%s' at listRel:%d!" % (cat,lineno()) return if not target: target = self.get_parent().get_parent().get_parent().get_parent() #Which is better? namebutton = gtk.Button(relid) namebutton.connect("clicked",displayFunc,relid,target) # passing the target or figuring it from parentage? ### TODO: displayPerson? what about places/orgs? row1 = gtk.HBox() self.pack_start(row1,0,0,2) row1.pack_start(namebutton,1,1,2) row1.show() namebutton.show() namebutton.set_alignment(0.75,0.05) namebutton.set_size_request(int(self.size_request()[0] * 0.20),10) namelabel = gtk.Label("Name: ") namelabel.show() row1.pack_start(namelabel,0,0,2) namelabel.set_width_chars(6) nameentry = gtk.Entry() nameentry.show() nameentry.set_text(name) activateRelEntry(nameentry,psalts,scroll,people.get(fileid),fileid,relid,"related") row1.pack_start(nameentry,1,1) txt = r.get("relation") if txt is None: r['relation'] = ["",False] txt = ["",False] relation = gtk.Label(txt[0]) relation.show() relation.set_width_chars(8) row1.pack_start(relation,1,1) relset = gtk.Button("Set") relset.show() relset.set_alignment(0.5,0.5) relset.set_size_request(36,24) data = people.get(relid,None) genderR = "" if data: genderR = getInf(data,["info","gender"]) if not genderR or genderR == "": p = loadPerson(relid) genderR = p[0].get("gender",['N',False]) genderR = genderR[0] genderP = getInf(people.get(fileid),["info","gender"]) relset.connect("clicked",selectConnectionP,relation,fileid,relid,name,cat,genderR,genderP) row1.pack_start(relset,0,0,5) row2 = gtk.HBox() self.pack_start(row2,0,0,2) row2.show() mileadd = gtk.Button("New Milestone") mileadd.show() mileadd.set_alignment(0.75,0.05) # mileadd.set_size_request(int(self.size_request()[0] * 0.30),24) row2.pack_start(mileadd,0,0,5) dhead = gtk.Label("Date") dhead.show() dhead.set_width_chars(8) row2.pack_start(dhead,1,1,2) ehead = gtk.Label("Event") ehead.show() ehead.set_width_chars(18) row2.pack_start(ehead,1,1,2) row2.show_all() row3 = gtk.VBox() row3.show() self.pack_start(row3,0,0,2) boxwidth = self.size_request()[0] mileadd.connect("clicked",addMilestone,scroll,row3,people.get(fileid),fileid,"relat",relid,boxwidth) if r.get("events"): for i in r['events']: # showMile(row3,r,i,fileid,relid) #def showMile(row3,r,i,fileid,relid): events = r['events'][i] # print str(events) if events.get("date") and events.get("event"): rowmile = gtk.HBox() rowmile.show() blank = gtk.Label() blank.show() blank.set_width_chars(12) rowmile.pack_start(blank,0,0,2) d = gtk.Entry() d.show() d.set_width_chars(12) d.set_text(events['date'][0]) data = people.get(fileid) activateRelEntry(d,psalts,scroll,data,fileid,relid,"date",i) rowmile.pack_start(d,1,1,2) placeCalendarButton(data,rowmile,d,[fileid,"relat",relid,"events",i,"date"],psalts,counter=ar) e = gtk.Entry() e.show() e.set_width_chars(18) e.set_text(events['event'][0]) activateRelEntry(e,psalts,scroll,data,fileid,relid,"event",i) rowmile.pack_start(e,1,1,2) row3.add(rowmile)