def ddtest_valid_syslog_publishing(self, host=None, pname=None, time=None, native=None): # Dealing with syslog-ng oddity documented in #161 if not host: host = 'nohost' time = datetime.now().isoformat() # Syslog-ng only uses 3 decimal places time = time[:-3] result = self.rsyslog_client.send( priority=6, timestamp=time, app_name=pname, host_name=host, msg=native) # Sockets return None when they successfully deliver message self.assertIsNone(result) # Make sure the index exists before we continue self.assertTrue(self.es_client.has_index(self.tenant_id)) msgs = self.publish_behaviors.get_messages_by_timestamp( timestamp=time, num_messages=1) self.assertEqual(len(msgs), 1) # This will work for now, but we need to write a model for this soon. msg = msgs[0] msg_time = parse_iso8601(msg.get('time')) expected_time = parse_iso8601('{0}+0'.format(time)) self.assertEqual(msg.get('pri'), 'info') self.assertEqual(msg_time, expected_time) self.assertEqual(msg.get('pname'), pname or '-') self.assertEqual(msg.get('host'), host)
def maybe_iso8601(dt): """``Either datetime | str -> datetime or None -> None``""" if not dt: return if isinstance(dt, datetime): return dt return parse_iso8601(dt)
def maybe_iso8601(dt): """`Either datetime | str -> datetime or None -> None`""" if not dt: return if isinstance(dt, datetime): return dt return parse_iso8601(dt)
def ddtest_valid_syslog_publishing(self, host=None, pname=None, time=None, native=None): # Dealing with syslog-ng oddity documented in #161 if not host: host = 'nohost' time = datetime.now().isoformat() # Syslog-ng only uses 3 decimal places time = time[:-3] result = self.rsyslog_client.send(priority=6, timestamp=time, app_name=pname, host_name=host, msg=native) # Sockets return None when they successfully deliver message self.assertIsNone(result) # Make sure the index exists before we continue self.assertTrue(self.es_client.has_index(self.tenant_id)) msgs = self.publish_behaviors.get_messages_by_timestamp(timestamp=time, num_messages=1) self.assertEqual(len(msgs), 1) # This will work for now, but we need to write a model for this soon. msg = msgs[0] msg_time = parse_iso8601(msg.get('time')) expected_time = parse_iso8601('{0}+0'.format(time)) self.assertEqual(msg.get('pri'), 'info') self.assertEqual(msg_time, expected_time) self.assertEqual(msg.get('pname'), pname or '-') self.assertEqual(msg.get('host'), host)
def _parse_iso8601(text): """ Maybe parse an ISO8601 datetime string into a datetime. :param text: Either a ``unicode`` string to parse or any other object (ideally a ``datetime`` instance) to pass through. :return: A ``datetime.datetime`` representing ``text``. Or ``text`` if it was anything but a ``unicode`` string. """ if isinstance(text, unicode): try: return parse_iso8601(text) except ValueError: raise CheckedValueTypeError( None, (datetime, ), unicode, text, ) # Let pyrsistent reject it down the line. return text
def validate_game_submission(headers, body_json): #required data = { 'server_id': body_json.get('server_id'), 'black_id': body_json.get('black_id'), 'white_id': body_json.get('white_id'), 'result': body_json.get('result'), 'handicap': body_json.get('handicap'), 'komi': body_json.get('komi'), 'date_played': body_json.get('date_played'), } if None in data.values(): missing_fields = ", ".join(k for k,v in data.items() if v is None) raise ApiException('Missing required parameters: %s' % missing_fields) #optional data.update({ 'game_record': body_json.get('game_record'), 'game_url': body_json.get('game_url') }) server_token = headers.get('X-Auth-Server-Token') black_token = headers.get('X-Auth-Black-Player-Token') white_token = headers.get('X-Auth-White-Player-Token') if any(token is None for token in (server_token, black_token, white_token)): raise ApiException('Did not submit required X-Auth-(Server-Token|Black-Player-Token|White-Player-Token) headers.', 403) gs = GoServer.query.filter_by(id=data['server_id'], token=server_token).first() if gs is None: raise ApiException('server access token unknown or expired: %s' % server_token, status_code=404) b = Player.query.filter_by(id=data['black_id'], token=black_token).first() if b is None or b.user_id is None: raise ApiException('black player access token unknown or expired: %s' % black_token, status_code=404) w = Player.query.filter_by(id=data['white_id'], token=white_token).first() if w is None or w.user_id is None: raise ApiException('white player token unknown or expired: %s' % white_token, status_code=404) if not _result_str_valid(data['result']): raise ApiException('format of result is incorrect') if data['game_record'] is None and data['game_url'] is None: raise ApiException('One of game_record or game_url must be present') if data['game_record'] is not None: game_record = data['game_record'].encode() else: try: timeout = current_app.config['GAME_FETCH_HTTP_TIMEOUT'] response = requests.get(data['game_url'], verify=False, timeout=timeout) game_record = response.content except requests.exceptions.Timeout as e: current_app.logger.warn('Request to %s timed out' % data.get('game_url', '')) current_app.logger.warn(e) raise ApiException('game_url provided (%s) timed out upon fetch' % data.get('game_url', '')) except Exception as e: current_app.logger.warn('Got invalid game_url %s' % data.get('game_url', '')) current_app.logger.warn(e) raise ApiException('game_url provided (%s) was invalid!' % data.get('game_url', '')) try: date_played = parse_iso8601(data['date_played']) except TypeError: raise ApiException(error='date_played must be in ISO 8601 format') try: handicap = int(data['handicap']) komi = float(data['komi']) except ValueError: raise ApiException('invalid handicap or komi') current_app.logger.info("Creating game, White: %s, Black: %s " % (w,b)) game = Game(server_id=gs.id, white_id=w.id, black_id=b.id, rated=False, date_played=date_played, date_reported=datetime.now(), result=data['result'], handicap=handicap, komi=komi, game_url=data['game_url'], game_record=game_record ) return game
def postresult(): """Post a new game result to the database. TODO: Check for duplicates. """ #required data = { 'server_tok': request.args.get('server_tok'), 'b_tok': request.args.get('b_tok'), 'w_tok': request.args.get('w_tok'), 'rated': request.args.get('rated'), 'result': request.args.get('result'), 'date': request.args.get('date'), } if None in data.values(): raise ApiException('malformed request') #optional data.update({ 'sgf_data': request.args.get('sgf_data'), 'sgf_link': request.args.get('sgf_link') }) gs = GoServer.query.filter_by(token=data['server_tok']).first() if gs is None: raise ApiException('server access token unknown or expired: %s' % data['server_tok'], status_code=404) b = Player.query.filter_by(token=data['b_tok']).first() if b is None or b.user_id is None: raise ApiException('user access token unknown or expired: %s' % data['b_tok'], status_code=404) w = Player.query.filter_by(token=data['w_tok']).first() if w is None or w.user_id is None: raise ApiException('user access token unknown or expired: %s' % data['w_tok'], status_code=404) if data['rated'] not in ['True', 'False']: raise ApiException('rated must be set to True or False') if not _result_str_valid(data['result']): raise ApiException('format of result is incorrect') if data['sgf_data'] is None and data['sgf_link'] is None: raise ApiException('One of sgf_data or sgf_link must be present') elif data['sgf_data'] is not None: #TODO: some kind of validation pass else: #TODO: enqueue the URL for later fetching and storage, e.g. Celery pass try: date_played = parse_iso8601(data['date']) except TypeError: raise ApiException(error='date must be in ISO 8601 format') rated = data['rated'] == 'True' logging.info(" White: %s, Black: %s " % (w,b)) game = Game(white=w, white_id = w.id, black=b, black_id = b.id, rated=rated, date_played=date_played, date_reported=datetime.now(), result=data['result'], game_record=data['sgf_data'].encode() ) logging.info("saving game: %s " % str(game)) db.session.add(game) db.session.commit() return jsonify(message='OK')
def validate_game_submission(headers, body_json): #required data = { 'server_id': body_json.get('server_id'), 'black_id': body_json.get('black_id'), 'white_id': body_json.get('white_id'), 'result': body_json.get('result'), 'handicap': body_json.get('handicap'), 'komi': body_json.get('komi'), 'date_played': body_json.get('date_played'), } if None in data.values(): missing_fields = ", ".join(k for k,v in data.items() if v is None) raise ApiException('Missing required parameters: %s' % missing_fields) #optional data.update({ 'game_record': body_json.get('game_record'), 'game_url': body_json.get('game_url'), 'server_url': body_json.get('server_url') }) server_token = headers.get('X-Auth-Server-Token') black_token = headers.get('X-Auth-Black-Player-Token') white_token = headers.get('X-Auth-White-Player-Token') if any(token is None for token in (server_token, black_token, white_token)): raise ApiException('Did not submit required X-Auth-(Server-Token|Black-Player-Token|White-Player-Token) headers.', 403) gs = GoServer.query.filter_by(id=data['server_id'], token=server_token).first() if gs is None: raise ApiException('server access token unknown or expired: %s' % server_token, status_code=404) b = Player.query.filter_by(id=data['black_id'], token=black_token).first() if b is None or b.user_id is None: raise ApiException('black player access token unknown or expired: %s' % black_token, status_code=404) w = Player.query.filter_by(id=data['white_id'], token=white_token).first() if w is None or w.user_id is None: raise ApiException('white player token unknown or expired: %s' % white_token, status_code=404) if not _result_str_valid(data['result']): raise ApiException('format of result is incorrect') if data['game_record'] is None and data['game_url'] is None: raise ApiException('One of game_record or game_url must be present') if data['game_record'] is not None: game_record = data['game_record'].encode() else: try: timeout = current_app.config['GAME_FETCH_HTTP_TIMEOUT'] response = requests.get(data['game_url'], verify=False, timeout=timeout) game_record = response.content except requests.exceptions.Timeout as e: current_app.logger.warn('Request to %s timed out' % data.get('game_url', '')) current_app.logger.warn(e) raise ApiException('game_url provided (%s) timed out upon fetch' % data.get('game_url', '')) except Exception as e: current_app.logger.warn('Got invalid game_url %s' % data.get('game_url', '')) current_app.logger.warn(e) raise ApiException('game_url provided (%s) was invalid!' % data.get('game_url', '')) try: date_played = parse_iso8601(data['date_played']) except TypeError: raise ApiException(error='date_played must be in ISO 8601 format') try: handicap = int(data['handicap']) komi = float(data['komi']) except ValueError: raise ApiException('invalid handicap or komi') current_app.logger.info("Creating game, White: %s, Black: %s " % (w,b)) game = Game(server_id=gs.id, white_id=w.id, black_id=b.id, rated=False, date_played=date_played, date_reported=datetime.now(), result=data['result'], handicap=handicap, komi=komi, game_url=data['game_url'], game_record=game_record ) return game
def validate_game_submission(queryparams, body_json): #required data = { 'server_tok': queryparams.get('server_tok'), 'b_tok': queryparams.get('b_tok'), 'w_tok': queryparams.get('w_tok'), 'game_server': body_json.get('game_server'), 'black_id': body_json.get('black_id'), 'white_id': body_json.get('white_id'), 'rated': body_json.get('rated'), 'result': body_json.get('result'), 'date_played': body_json.get('date_played'), } if None in data.values(): missing_fields = ", ".join(k for k,v in data.items() if v is None) raise ApiException('Missing required parameters: %s' % missing_fields) #optional data.update({ 'game_record': body_json.get('game_record'), 'game_url': body_json.get('game_url') }) gs = GoServer.query.filter_by(name=data['game_server'], token=data['server_tok']).first() if gs is None: raise ApiException('server access token unknown or expired: %s' % data['server_tok'], status_code=404) b = Player.query.filter_by(id=data['black_id'], token=data['b_tok']).first() if b is None or b.user_id is None: raise ApiException('user access token unknown or expired: %s' % data['b_tok'], status_code=404) w = Player.query.filter_by(id=data['white_id'], token=data['w_tok']).first() if w is None or w.user_id is None: raise ApiException('user access token unknown or expired: %s' % data['w_tok'], status_code=404) if type(data['rated']) != bool: raise ApiException('rated must be set to True or False') if not _result_str_valid(data['result']): raise ApiException('format of result is incorrect') if data['game_record'] is None and data['game_url'] is None: raise ApiException('One of game_record or game_url must be present') if data['game_record'] is not None: game_record = data['game_record'].encode() else: try: response = requests.get(data['game_url'], verify=False) game_record = response.content except Exception as e: logging.info("Got invalid game_url %s" % data.get("game_url", "")) logging.info(e) raise ApiException('game_url provided (%s) was invalid!' % data.get('game_url', '<None>')) try: date_played = parse_iso8601(data['date_played']) except TypeError: raise ApiException(error='date_played must be in ISO 8601 format') rated = data['rated'] logging.info(" White: %s, Black: %s " % (w,b)) game = Game(server_id=gs.id, white_id=w.id, black_id=b.id, rated=rated, date_played=date_played, date_reported=datetime.now(), result=data['result'], game_record=game_record ) return game