def ping(redis, chat, session, chat_type): online_state = get_online_state(redis, chat, session.session_id) if online_state=='offline': # Check for Redis loading. if session.meta['counter'] == "Redis is loading the dataset in memory": abort(500) # Check IP bans. if redis.zscore('ip-bans', chat+'/'+request.headers['CF-Connecting-IP']) is not None: abort(403) # The user isn't online already. Add them to the chat. # Remove the chat from the delete queue. redis.zrem('delete-queue', chat) # Add to the archive queue, but only if it's saved. if chat_type!='unsaved' and redis.zscore('archive-queue', chat) is None: redis.zadd('archive-queue', chat, get_time(ARCHIVE_PERIOD)) # Log their IP address. redis.hset('session.'+session.session_id+'.meta', 'last_ip', request.headers['CF-Connecting-IP']) # Set user state. redis.sadd('chat.'+chat+'.online', session.session_id) if session.meta['group']=='silent': join_message = None elif session.meta['group']=='globalmod': join_message = '%s [%s] joined chat. ~~ %s ~~ [u]MSPARP STAFF[/u]' % (session.character['name'], session.character['acronym'], session.meta['counter']) else: join_message = '%s [%s] joined chat. ~~ %s ~~' % (session.character['name'], session.character['acronym'], session.meta['counter']) send_message(redis, chat, -1, 'user_change', join_message) redis.sadd('sessions-chatting', session.session_id) # Add character to chat character list. redis.sadd('chat.'+chat+'.characters', session.character['character']) redis.zadd('chats-alive', chat+'/'+session.session_id, get_time(PING_PERIOD*2)) return True redis.zadd('chats-alive', chat+'/'+session.session_id, get_time(PING_PERIOD*2)) return False
def ping(redis, chat, session, chat_type): online_state = get_online_state(redis, chat, session.session_id) if online_state=='offline': # Check IP bans. if redis.zrank('ip-bans', chat+'/'+request.environ['HTTP_X_REAL_IP']) is not None: abort(403) # The user isn't online already. Add them to the chat. # Remove the chat from the delete queue. redis.zrem('delete-queue', chat) # Add to the archive queue, but only if it's saved. if chat_type!='unsaved' and redis.zscore('archive-queue', chat) is None: redis.zadd('archive-queue', chat, get_time(ARCHIVE_PERIOD)) # Log their IP address. redis.hset('session.'+session.session_id+'.meta', 'last_ip', request.environ['HTTP_X_REAL_IP']) # Set user state. redis.sadd('chat.'+chat+'.online', session.session_id) if session.meta['group']=='silent': join_message = None else: join_message = '%s [%s] joined chat.' % (session.character['name'], session.character['acronym']) send_message(redis, chat, -1, 'user_change', join_message) redis.sadd('sessions-chatting', session.session_id) # Add character to chat character list. redis.sadd('chat.'+chat+'.characters', session.character['character']) redis.zadd('chats-alive', chat+'/'+session.session_id, get_time(PING_PERIOD*2)) return True redis.zadd('chats-alive', chat+'/'+session.session_id, get_time(PING_PERIOD*2)) return False
def ping(redis, chat, session, chat_type): online_state = get_online_state(redis, chat, session.session_id) if online_state == 'offline': # Don't let the user in if there are more than 30 people online already. # XXX SHOW THEM A PROPER ERROR MESSAGE FOR THIS if redis.sismember( "global-mods", session.session_id) is False and redis.scard('chat.' + chat + '.online') >= 30: abort(403) # Global bans if redis.hexists("global-bans", request.headers['CF-Connecting-IP']): abort(403) # Check for Redis loading. if session.meta['counter'] == "Redis is loading the dataset in memory": abort(500) # Check IP bans. if redis.zscore('ip-bans', chat + '/' + request.headers['CF-Connecting-IP']) is not None: abort(403) # The user isn't online already. Add them to the chat. # Remove the chat from the delete queue. redis.zrem('delete-queue', chat) # Add to the archive queue, but only if it's saved. if chat_type != 'unsaved' and redis.zscore('archive-queue', chat) is None: redis.zadd('archive-queue', chat, get_time(ARCHIVE_PERIOD)) # Log their IP address. redis.hset('session.' + session.session_id + '.meta', 'last_ip', request.headers['CF-Connecting-IP']) # Set user state. redis.sadd('chat.' + chat + '.online', session.session_id) if session.meta['group'] == 'silent': join_message = None elif session.meta['group'] == 'globalmod' and redis.hget( "session." + session.session_id + ".meta", "noglobal") != "1": join_message = '%s [%s] joined chat. ~~ %s ~~ [u]MSPARP STAFF[/u]' % ( session.character['name'], session.character['acronym'], session.meta['counter']) else: join_message = '%s [%s] joined chat. ~~ %s ~~' % ( session.character['name'], session.character['acronym'], session.meta['counter']) send_message(redis, chat, -1, 'user_change', join_message) redis.sadd('sessions-chatting', session.session_id) # Add character to chat character list. redis.sadd('chat.' + chat + '.characters', session.character['character']) redis.zadd('chats-alive', chat + '/' + session.session_id, get_time(PING_PERIOD * 2)) return True redis.zadd('chats-alive', chat + '/' + session.session_id, get_time(PING_PERIOD * 2)) return False
def __init__(self, redis, session_id=None, chat=None): self.redis = redis self.session_id = session_id or str(uuid4()) self.chat = chat original_prefix = 'session.'+self.session_id original_meta_prefix = original_prefix+'.meta' # Load metadata and character data. if chat is not None: self.prefix = original_prefix+'.chat.'+chat self.meta_prefix = original_meta_prefix+'.'+chat self.meta = get_or_create( redis, self.meta_prefix, lambda: new_chat_metadata(redis, chat, session_id) ) character = get_or_create( redis, self.prefix, lambda: get_or_create( redis, original_prefix, # Redis hashes can't be empty - if there are no keys they are auto-deleted. # So we store the character ID in this dict so it always has at least one. lambda: dict([('character', 'anonymous/other')]+CHARACTER_DETAILS['anonymous/other'].items()) ) ) else: self.prefix = original_prefix self.meta_prefix = original_meta_prefix self.meta = get_or_create(redis, original_meta_prefix, lambda: META_DEFAULTS) character = get_or_create( redis, self.prefix, lambda: dict([('character', 'anonymous/other')]+CHARACTER_DETAILS['anonymous/other'].items()) ) # Fill in missing fields from the characters dict. self.character = fill_in_data(character) # Character encodings are stupid. self.unicodify() redis.zadd('all-sessions', self.session_id, get_time(DELETE_SESSION_PERIOD)) if chat is not None: redis.zadd('chat-sessions', self.chat+'/'+self.session_id, get_time(DELETE_SESSION_PERIOD))
def save_one_measure(data, db=False): timeStamp = lib.get_time().replace(":", ".")[0:-3] filename = 'results/%s/%s/rawTrace_%s_%s.json' % (lib.get_date(), timeStamp[:2], lib.get_date(), timeStamp) if db: if 'OPENSHIFT_APP_NAME' in os.environ: app_name = os.environ['OPENSHIFT_APP_NAME'] mongo_url = os.environ['OPENSHIFT_MONGODB_DB_URL'] client = MongoClient(mongo_url) db = client[app_name] else: client = MongoClient("localhost", 27017) db = client["dev"] collection = db["raw_measures"] collection.insert_one(json.loads(json.dumps(data))) #collection2 = db["processed_measures"] #collection2.insert_one(json.loads(json.dumps(read_measure(data)))) else: if not os.path.exists(os.path.dirname(filename)): os.makedirs(os.path.dirname(filename)) with open(filename, 'w') as f: f.write(json.dumps(data, indent=2))
def save_one_measure(data, db=False): timeStamp = lib.get_time().replace(":", ".")[0:-3] filename = 'results/%s/%s/rawTrace_%s_%s.json' % ( lib.get_date(), timeStamp[:2], lib.get_date(), timeStamp) if db: if 'OPENSHIFT_APP_NAME' in os.environ: app_name = os.environ['OPENSHIFT_APP_NAME'] mongo_url = os.environ['OPENSHIFT_MONGODB_DB_URL'] client = MongoClient(mongo_url) db = client[app_name] else: client = MongoClient("localhost", 27017) db = client["dev"] collection = db["raw_measures"] collection.insert_one(json.loads(json.dumps(data))) #collection2 = db["processed_measures"] #collection2.insert_one(json.loads(json.dumps(read_measure(data)))) else: if not os.path.exists(os.path.dirname(filename)): os.makedirs(os.path.dirname(filename)) with open(filename, 'w') as f: f.write(json.dumps(data, indent=2))
def foundYet(): target=g.redis.get('session.'+g.user.session_id+'.match') if target: g.redis.delete('session.'+g.user.session_id+'.match') return jsonify(target=target) else: g.redis.zadd('searchers', g.user.session_id, get_time(SEARCH_PERIOD*2)) abort(404)
def __init__(self, redis, session_id=None, chat=None): self.redis = redis self.session_id = session_id or str(uuid4()) self.chat = chat original_prefix = 'session.'+self.session_id original_meta_prefix = original_prefix+'.meta' # Load metadata and character data. if chat is not None: self.prefix = original_prefix+'.chat.'+chat self.meta_prefix = original_meta_prefix+'.'+chat self.meta = get_or_create( redis, self.meta_prefix, lambda: new_chat_metadata(redis, chat, session_id) ) self.character = get_or_create( redis, self.prefix, lambda: get_or_create( redis, original_prefix, lambda: dict(CHARACTER_DEFAULTS) ) ) else: self.prefix = original_prefix self.meta_prefix = original_meta_prefix self.meta = get_or_create(redis, original_meta_prefix, lambda: META_DEFAULTS) self.character = get_or_create( redis, self.prefix, lambda: dict(CHARACTER_DEFAULTS) ) # Character encodings are stupid. self.unicodify() redis.zadd('all-sessions', self.session_id, get_time(DELETE_SESSION_PERIOD)) if chat is not None: redis.zadd('chat-sessions', self.chat+'/'+self.session_id, get_time(DELETE_SESSION_PERIOD))
def ping(redis, chat, session, chat_type): online_state = get_online_state(redis, chat, session.session_id) if online_state=='offline': # Don't let the user in if there are more than 30 people online already. # XXX SHOW THEM A PROPER ERROR MESSAGE FOR THIS if redis.scard('chat.'+chat+'.online')>=30: abort(403) # Global bans if redis.hexists("global-bans", request.headers['CF-Connecting-IP']): abort(403) # Check for Redis loading. if session.meta['counter'] == "Redis is loading the dataset in memory": abort(500) # Check IP bans. if redis.zscore('ip-bans', chat+'/'+request.headers['CF-Connecting-IP']) is not None: abort(403) # The user isn't online already. Add them to the chat. # Remove the chat from the delete queue. redis.zrem('delete-queue', chat) # Add to the archive queue, but only if it's saved. if chat_type!='unsaved' and redis.zscore('archive-queue', chat) is None: redis.zadd('archive-queue', chat, get_time(ARCHIVE_PERIOD)) # Log their IP address. redis.hset('session.'+session.session_id+'.meta', 'last_ip', request.headers['CF-Connecting-IP']) # Set user state. redis.sadd('chat.'+chat+'.online', session.session_id) if session.meta['group']=='silent': join_message = None elif session.meta['group']=='globalmod': join_message = '%s [%s] joined chat. ~~ %s ~~ [tshadow= 1px 1px 0px #000000, -1px 1px 0px #000000, 1px -1px 0px #000000, -1px -1px 0px #000000, 1px 0px 0px #000000, -1px 0px 0px #000000, 0px -1px 0px #000000, 0px 1px 0px #000000; color:#FFFFFF; background-image: url(//upload.wikimedia.org/wikipedia/commons/2/22/Animated_fire_by_nevit.gif); padding: 6px; border-radius: 5px; background-position: left bottom; line-height:0px; font-size:12px][u]MSPARP STAFF[/u][/tshadow]' % (session.character['name'], session.character['acronym'], session.meta['counter']) else: join_message = '%s [%s] joined chat. ~~ %s ~~' % (session.character['name'], session.character['acronym'], session.meta['counter']) send_message(redis, chat, -1, 'user_change', join_message) redis.sadd('sessions-chatting', session.session_id) # Add character to chat character list. redis.sadd('chat.'+chat+'.characters', session.character['character']) redis.zadd('chats-alive', chat+'/'+session.session_id, get_time(PING_PERIOD*2)) return True redis.zadd('chats-alive', chat+'/'+session.session_id, get_time(PING_PERIOD*2)) return False
def save_log(): if not validate_chat_url(request.form['chat']): abort(400) chat_type = g.redis.hget('chat.'+request.form['chat']+'.meta', 'type') if chat_type not in ['unsaved', 'saved']: abort(400) log_id = archive_chat(g.redis, g.mysql, request.form['chat']) g.redis.hset('chat.'+request.form['chat']+'.meta', 'type', 'saved') g.redis.zadd('archive-queue', request.form['chat'], get_time(ARCHIVE_PERIOD)) if 'tumblr' in request.form: # Set the character list as tags. tags = g.redis.smembers('chat.'+request.form['chat']+'.characters') tags.add('msparp') url_tags = urllib.quote_plus(','.join(tags)) return redirect('http://www.tumblr.com/new/link?post[one]=Check+out+this+chat+I+just+had+on+MSPARP!&post[two]=http%3A%2F%2Funsupported.msparp.com%2Flogs%2F'+str(log_id)+'&post[source_url]=http%3A%2F%2Fmsparp.com%2F&tags='+url_tags) return redirect(url_for('view_log', chat=request.form['chat']))
def scan_iperf_installations(slice_name, used_threads=200): print "get node list" nodes = getPlanetLabNodes(slice_name) print "start scanning on %d threads" % (used_threads) results = utils.thread_map(install_iperf, nodes, used_threads) # results = proc_map(install_iperf, nodes, used_threads) print "--------------------" c = Counter(results) print "Results:" stats = {"date": lib.get_date(), "time": lib.get_time()} for item in c.most_common(): stats[item[0]] = item[1] print json.dumps(stats, indent=2) filename = "results/installations.json" os.makedirs(os.path.dirname(filename)) with open(filename, "w") as f: f.write(json.dumps(stats, indent=2))
async def on_message(message): if message.author.bot or message.author == client.user: return if message.content.startswith('!weatherbot'): logging.info(f"Request: {message.content}") split_command = message.content.split(' ') second_command = safe_list_get(split_command, 1) if 'counter' in second_command: counter = get_counter() timestring = datetime.fromtimestamp( get_time()).strftime("%m/%d/%Y, %H:%M:%S") msg = f"The counter is currently at {counter} and will reset at {timestring}." logging.info(msg) await message.channel.send(content=msg) else: await message.channel.send(content="Hello from WeatherBot!") elif message.content.startswith('!weather'): gmap = MapSearch(key=GOOGLECLOUD) counter = get_counter() logging.info(f"Request: {message.content}") logging.info("Parsing command...") split_command = message.content.split(' ') second_command = safe_list_get(split_command, 1) location = ' '.join(safe_rest_of_list(split_command, 2)) if time.time() >= get_time(): set_time() set_counter() if not any(item in message.content.lower() for item in ['forecast', 'now', 'current'] + DAYS): await message.channel.send(content="Incorrect command Syntax.") return if second_command is None or location is None: await message.channel.send(content="Incorrect command Syntax.") return logging.info("Getting coordinates of location...") lat, lng = gmap.get_coordinates(location) weather = None if gmap.is_us: logging.info("Using NOAA Weather Data.") weather = USGovWeatherSearch() else: if counter < 1000: # this will change if I ever get a paid openweathermap membership. logging.info("Using OpenWeatherMap Data.") weather = WeatherSearch(key=WEATHERKEY) increment_counter() else: logging.warning( "Counter has reached 1000, cannot use OpenWeatherMap until tomorrow." ) await message.channel.send( content= "Sorry for the inconvenience, but the global weather request limit has been reached. This will be reset tonight at midnight EST." ) return try: weather.search(lat, lng) except requests.exceptions.RequestException as e: logging.error(e) logging.error(f"Given location: {location}") logging.error(f"Lat: {lat}, Lng: {lng}") await message.channel.send( content= "There was an error processing your request. If this persists, please report it here: https://github.com/chand1012/discord-weather-bot/issues" ) return if 'now' in second_command or 'current' in second_command: logging.info("Sending current weather...") await message.channel.send( content=get_short_forecast(weather.forecasts)) elif 'forecast' in second_command: logging.info("Sending forecast...") for forecast in get_7_day_forecast(weather.forecasts): await message.channel.send(content=forecast) elif any(day in second_command.lower() for day in DAYS): logging.info( f"Sending forecast for {second_command.capitalize()}...") for forecast in get_day_forecast(weather.forecasts, second_command): await message.channel.send(content=forecast) else: await message.channel.send(content='Incorrect command syntax.') elif message.content.startswith('!covid'): logging.info(f"Request: {message.content}") split_command = message.content.split(' ') location = ' '.join(safe_rest_of_list(split_command, 1)) state_codes = STATECODES.keys() covid = None test = None if location.upper() in STATES or location.upper( ) in state_codes or 'USA' in location.upper(): logging.info("Getting COVID-19 data for the US.") if 'USA' in location.upper(): location = '' covid = CovidUSData() test = covid.get_data(state=location) elif 'global' in location.lower() or 'globe' in location.lower( ) or not location: logging.info("Getting global COVID-19 data.") covid = CovidCountryData() test = covid.get_data() else: logging.info(f"Getting COVID-19 data for {location}.") covid = CovidCountryData() test = covid.get_data(country=location) logging.info("Generating message...") msg = generate_covid_message(covid, location) if not msg: logging.error("There was an error. Here is some debug info:") logging.error(location.upper()) logging.error(test) await message.channel.send( content="Error! Country not found in COVID-19 Statistics.") else: logging.info("Sending COVID-19 data....") await message.channel.send(content=msg) if not TOPGG is None: update_server_count(TOPGG, client.user.id, len(client.guilds)) logging.info('Done.') return
def send_message(redis, chat, counter, msg_type, text=None, color='000000', acronym='', audience=None): # Do this here because it's gotta be before userlist generation. redis.zadd('longpoll-timeout', chat, get_time(LONGPOLL_TIMEOUT_PERIOD)) # The JavaScript always expects the messages list, so if we don't have any then we need an empty list. json_message = {'messages': []} if text is not None: message_content = acronym + ': ' + text if acronym else text # Store the message if it's not private. if msg_type != 'private': message = ','.join([ str(get_time()), str(counter), msg_type, color, message_content ]) message_count = redis.rpush('chat.' + chat, message) # Send the chat for archiving early if the chat is getting too long. if message_count >= 500: try: chat_type = g.chat_type except RuntimeError: chat_type = redis.hget('chat.' + chat + '.meta', 'type') if chat_type != 'unsaved': redis.zadd('archive-queue', chat, get_time(-60)) else: # ...or just get message count if it is. message_count = redis.llen('chat.' + chat) # And add it to the pubsub data. json_message['messages'].append({ 'id': message_count - 1, 'timestamp': get_time(), 'counter': counter, 'type': msg_type, 'color': color, 'line': message_content }) if msg_type == 'user_change': # Generate user list. json_message['online'] = get_userlists(redis, chat) # g doesn't work in the reaper. try: chat_type = g.chat_type except RuntimeError: chat_type = redis.hget('chat.' + chat + '.meta', 'type') # If the last person just left, clean stuff up. if len(json_message['online']) == 0: # Mark the chat for deletion. if chat_type == 'unsaved': redis.zadd('delete-queue', chat, get_time(DELETE_UNSAVED_PERIOD)) else: redis.zadd('delete-queue', chat, get_time(DELETE_SAVED_PERIOD)) # Stop avoiding timeouts. redis.zrem('longpoll-timeout', chat) elif msg_type == 'meta_change': json_message['meta'] = redis.hgetall('chat.' + chat + '.meta') elif msg_type == 'private': # Just send it to the specified person. redis.publish('channel.' + chat + '.' + audience, json.dumps(json_message)) return None # Push to the publication channel to wake up longpolling listeners redis.publish('channel.' + chat, json.dumps(json_message))
def send_message(redis, chat, counter, msg_type, text=None, color='000000', acronym='', audience=None): # Do this here because it's gotta be before userlist generation. redis.zadd('longpoll-timeout', chat, get_time(LONGPOLL_TIMEOUT_PERIOD)) # The JavaScript always expects the messages list, so if we don't have any then we need an empty list. json_message = { 'messages': [] } if text is not None: message_content = acronym+': '+text if acronym else text # Store the message if it's not private. if msg_type!='private': message = ','.join([str(get_time()), str(counter), msg_type, color, message_content]) message_count = redis.rpush('chat.'+chat, message) # Send the chat for archiving early if the chat is getting too long. if message_count>=500: try: chat_type = g.chat_type except RuntimeError: chat_type = redis.hget('chat.'+chat+'.meta', 'type') if chat_type!='unsaved': redis.zadd('archive-queue', chat, get_time(-60)) else: # ...or just get message count if it is. message_count = redis.llen('chat.'+chat) # And add it to the pubsub data. json_message['messages'].append({ 'id': message_count - 1, 'timestamp': get_time(), 'counter': counter, 'type': msg_type, 'color': color, 'line': message_content }) if msg_type=='user_change': # Generate user list. json_message['online'], json_message['idle'] = get_userlists(redis, chat) # g doesn't work in the reaper. try: chat_type = g.chat_type except RuntimeError: chat_type = redis.hget('chat.'+chat+'.meta', 'type') # If the last person just left, clean stuff up. if len(json_message['online'])==0 and len(json_message['idle'])==0: # Mark the chat for deletion. if chat_type=='unsaved': redis.zadd('delete-queue', chat, get_time(DELETE_UNSAVED_PERIOD)) else: redis.zadd('delete-queue', chat, get_time(DELETE_SAVED_PERIOD)) # Stop avoiding timeouts. redis.zrem('longpoll-timeout', chat) elif msg_type=='meta_change': json_message['meta'] = redis.hgetall('chat.'+chat+'.meta') elif msg_type=='private': # Just send it to the specified person. redis.publish('channel.'+chat+'.'+audience, json.dumps(json_message)) return None # Push to the publication channel to wake up longpolling listeners redis.publish('channel.'+chat, json.dumps(json_message))
def get_default(redis, session, chat, key, defaultValue=""): v = redis.hget("session." + session + ".chat." + chat, key) if v is not None: return v return defaultValue if __name__ == "__main__": redis = Redis(unix_socket_path="/tmp/redis.sock") current_time = datetime.datetime.now() while True: for dead in redis.zrangebyscore("chats-alive", 0, get_time()): chat, session = dead.split("/") disconnect_message = None if redis.hget("session." + session + ".meta." + chat, "group") != "silent": session_name = redis.hget("session." + session + ".chat." + chat, "name") if session_name is None: session_name = CHARACTER_DETAILS[redis.hget("session." + session + ".chat." + chat, "character")][ "name" ] disconnect_message = ( "%s's connection timed out. Please don't quit straight away; they could be back." % (session_name) ) disconnect(redis, chat, session, disconnect_message) print "dead", dead for dead in redis.zrangebyscore("searchers", 0, get_time()):
if __name__=='__main__': redis = Redis(unix_socket_path='/tmp/redis.sock') current_time = datetime.datetime.now() while True: new_time = datetime.datetime.now() # Every minute if new_time.minute!=current_time.minute: mysql = sm() # Send blank messages to avoid socket timeouts. for chat in redis.zrangebyscore('longpoll-timeout', 0, get_time()): send_message(redis, chat, -1, "message") # Expire IP bans. redis.zremrangebyscore('ip-bans', 0, get_time()) # Archive chats. for chat in redis.zrangebyscore('archive-queue', 0, get_time()): try: archive_chat(redis, mysql, chat) except (sqlalchemy.exc.IntegrityError, sqlalchemy.exc.ProgrammingError): redis = redis = Redis(unix_socket_path='/tmp/redis.sock') mysql = sm() pass pipe = redis.pipeline() pipe.scard('chat.'+chat+'.online')
def postMessage(): chat = request.form['chat'] if 'line' in request.form and g.user.meta['group']!='silent': # Remove linebreaks and truncate to 1500 characters. line = request.form['line'].replace('\n', ' ')[:1500] send_message(g.redis, chat, g.user.meta['counter'], 'message', line, g.user.character['color'], g.user.character['acronym']) if 'state' in request.form and request.form['state'] in ['online', 'idle']: change_state(g.redis, chat, g.user.session_id, request.form['state']) # Mod options. if g.user.meta['group'] in MOD_GROUPS: if 'set_group' in request.form and 'counter' in request.form: set_group = request.form['set_group'] set_session_id = g.redis.hget('chat.'+chat+'.counters', request.form['counter']) or abort(400) ss_key = 'session.'+set_session_id+'.chat.'+chat ss_meta_key = 'session.'+set_session_id+'.meta.'+chat current_group = g.redis.hget(ss_meta_key, 'group') # You can't promote people to or demote people from a group higher than your own. if ( GROUP_RANKS[current_group]>GROUP_RANKS[g.user.meta['group']] or GROUP_RANKS[set_group]>GROUP_RANKS[g.user.meta['group']] ): return 'ok' if current_group!=set_group and set_group in GROUP_RANKS.keys(): g.redis.hset(ss_meta_key, 'group', set_group) set_message = None # XXX make a function for fetching name and acronym? # Convert the name and acronym to unicode. ss_character = g.redis.hget(ss_key, 'character') set_session_name = unicode( g.redis.hget(ss_key, 'name') or CHARACTER_DETAILS[ss_character]['name'], encoding='utf8' ) set_session_acronym = unicode( g.redis.hget(ss_key, 'acronym') or CHARACTER_DETAILS[ss_character]['acronym'], encoding='utf8' ) if set_group=='mod': set_message = '%s [%s] set %s [%s] to Professional Wet Blanket. They can now silence, kick and ban other users.' elif set_group=='mod2': set_message = '%s [%s] set %s [%s] to Bum\'s Rusher. They can now silence and kick other users.' elif set_group=='mod3': set_message = '%s [%s] set %s [%s] to Amateur Gavel-Slinger. They can now silence other users.' elif set_group=='user': if current_group in MOD_GROUPS: set_message = '%s [%s] removed moderator status from %s [%s].' else: set_message = '%s [%s] unsilenced %s [%s].' elif set_group=='silent': set_message = '%s [%s] silenced %s [%s].' if set_message is not None: set_message = set_message % ( g.user.character['name'], g.user.character['acronym'], set_session_name, set_session_acronym ) send_message(g.redis, chat, -1, 'user_change', set_message) if 'user_action' in request.form and 'counter' in request.form and request.form['user_action'] in MINIMUM_RANKS: # Check if we're high enough to perform this action. if GROUP_RANKS[g.user.meta['group']]<MINIMUM_RANKS[request.form['user_action']]: return 'ok' their_session_id = g.redis.hget('chat.'+chat+'.counters', request.form['counter']) or abort(400) their_group = g.redis.hget('session.'+their_session_id+'.meta.'+chat, 'group') # Check if we're high enough to affect the other user. if GROUP_RANKS[g.user.meta['group']]<GROUP_RANKS[their_group]: return 'ok' # XXX make a function for fetching name and acronym? # Fetch their name and convert to unicode. their_chat_key = 'session.'+their_session_id+'.chat.'+chat their_character = g.redis.hget(their_chat_key, 'character') their_session_name = unicode( g.redis.hget(their_chat_key, 'name') or CHARACTER_DETAILS[their_character]['name'], encoding='utf8' ) their_session_acronym = unicode( g.redis.hget(their_chat_key, 'acronym') or CHARACTER_DETAILS[their_character]['acronym'], encoding='utf8' ) if request.form['user_action']=='kick': g.redis.publish('channel.'+chat+'.'+their_session_id, '{"exit":"kick"}') disconnect(g.redis, chat, their_session_id, "%s [%s] kicked %s [%s] from the chat." % ( g.user.character['name'], g.user.character['acronym'], their_session_name, their_session_acronym )) # Don't ban people from the oubliette because that'll just put us in an infinite loop. elif request.form['user_action']=='ip_ban' and chat!='theoubliette': their_ip_address = g.redis.hget('session.'+their_session_id+'.meta', 'last_ip') ban_id = chat+'/'+their_ip_address if their_ip_address is not None: g.redis.zadd('ip-bans', ban_id, get_time(IP_BAN_PERIOD)) if 'reason' in request.form: g.redis.hset('ban-reasons', ban_id, request.form['reason']) g.redis.publish('channel.'+chat+'.'+their_session_id, '{"exit":"ban"}') disconnect(g.redis, chat, their_session_id, "%s [%s] IP banned %s [%s]." % ( g.user.character['name'], g.user.character['acronym'], their_session_name, their_session_acronym )) if 'meta_change' in request.form: for flag in CHAT_FLAGS: if flag in request.form: if request.form[flag]=='1': g.redis.hset('chat.'+chat+'.meta', flag, '1') else: g.redis.hdel('chat.'+chat+'.meta', flag) send_message(g.redis, chat, -1, 'meta_change') if 'topic' in request.form: if request.form['topic']!='': truncated_topic = request.form['topic'][:1500] g.redis.hset('chat.'+chat+'.meta', 'topic', truncated_topic) send_message(g.redis, chat, -1, 'meta_change', '%s changed the conversation topic to "%s".' % ( g.user.character['name'], truncated_topic )) else: g.redis.hdel('chat.'+chat+'.meta', 'topic') send_message(g.redis, chat, -1, 'meta_change', '%s removed the conversation topic.' % g.user.character['name']) return 'ok'
if __name__=='__main__': redis = Redis(host=os.environ['REDIS_HOST'], port=int(os.environ['REDIS_PORT']), db=int(os.environ['REDIS_DB'])) current_time = datetime.datetime.now() while True: new_time = datetime.datetime.now() # Every minute if new_time.minute!=current_time.minute: mysql = sm() # Expire IP bans. redis.zremrangebyscore('ip-bans', 0, get_time()) # Archive chats. for chat in redis.zrangebyscore('archive-queue', 0, get_time()): archive_chat(redis, mysql, chat, 0) online = redis.scard('chat.'+chat+'.online') # Stop archiving if no-one is online any more. if online == 0: redis.zrem('archive-queue', chat) else: redis.zadd('archive-queue', chat, get_time(ARCHIVE_PERIOD)) # Delete chat-sessions. for chat_session in redis.zrangebyscore('chat-sessions', 0, get_time()): delete_chat_session(redis, *chat_session.split('/'))
from lib.api import disconnect from lib.archive import archive_chat, delete_chat_session, delete_chat, delete_session from lib.messages import send_message from lib.model import sm def get_default(redis, session, chat, key, defaultValue=''): v = redis.hget("session."+session+".chat."+chat, key) if v is not None: return v return defaultValue if __name__=='__main__': redis = Redis(unix_socket_path='/tmp/redis.sock') while True: for dead in redis.zrangebyscore('chats-alive', 0, get_time()): chat, session = dead.split('/') disconnect_message = None if redis.hget('session.'+session+'.meta.'+chat, 'group')!='silent': session_name = redis.hget('session.'+session+'.chat.'+chat, 'name') disconnect_message = '%s\'s connection timed out. Please don\'t quit straight away; they could be back.' % (session_name) disconnect(redis, chat, session, disconnect_message) print 'dead', dead for dead in redis.zrangebyscore('searchers', 0, get_time()): print 'reaping searcher', dead redis.zrem('searchers', dead) time.sleep(1)