<commit_before># coding: utf-8

import database
from data_structure import *

new_contest_list = ['agc001','agc002','agc003','agc004','agc005','agc006','agc007',
                    'arc058','arc059','arc060','arc061','arc062','arc063',
                    'abc042','abc043','abc044','abc045','abc046','abc047',
                    'tenka1-2016-quala','tenka1-2016-qualb','tenka1-2016-final-open',
                    'code-festival-2016-quala','code-festival-2016-qualb','code-festival-2016-qualc',
                    'ddcc2016-qual']

old_contest_list = ['arc001','arc002','arc003','arc004','arc005','arc006','arc007','arc008','arc009','arc010','arc011','arc012','arc013','arc014','arc015','arc016','arc017','arc018','arc019','arc020','arc021','arc022','arc023','arc024','arc025','arc026','arc027','arc028','arc029','arc030','arc031','arc032','arc033','arc034','arc035','arc036','arc037','arc038','arc039','arc040','arc041','arc042','arc043','arc044','arc045','arc046','arc047','arc048','arc049','arc050','arc051','arc052','arc053','arc054','arc055','arc056','arc057',
                    'abc001','abc002','abc003','abc004','abc005','abc006','abc007','abc008','abc009','abc010','abc011','abc012','abc013','abc014','abc015','abc016','abc017','abc018','abc019','abc020','abc021','abc022','abc023','abc024','abc025','abc026','abc027','abc028','abc029','abc030','abc031','abc032','abc033','abc034','abc035','abc036','abc037','abc038','abc039','abc040','abc041']

def get_user_list():
	sql = "SELECT DISTINCT user_id FROM results WHERE contest_id = '{0}'".format(new_contest_list[0])
	for contest_id in new_contest_list[1:-1]:
		sql += " OR contest_id = '{0}'".format(contest_id)
	sql += 'ORDER BY user_id;'
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return [e['user_id'] for e in cursor.fetchall()]

def get_task_list(contest_ids):
	sql =  "SELECT problem_id, symbol FROM tasks"
	sql += "  WHERE (contest_id = '{0}'".format(contest_ids[0])
	for contest_id in contest_ids[1:-1]:
		sql += "      OR contest_id = '{0}'".format(contest_id)
	sql += "  ) ORDER BY problem_id;"
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return cursor.fetchall()

def get_task_point_list(contest_ids):
	sql =  "SELECT tasks.problem_id, symbol, point FROM tasks, task_points"
	sql += "  WHERE tasks.contest_id = task_points.contest_id AND tasks.problem_id = task_points.problem_id"
	sql += "        AND (tasks.contest_id = '{0}'".format(contest_ids[0])
	for contest_id in contest_ids[1:-1]:
		sql += "      OR tasks.contest_id = '{0}'".format(contest_id)
	sql += "  ) ORDER BY tasks.problem_id;"
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return cursor.fetchall()

def get_result_list(problem_id):
	sql = "SELECT user_id, score, failure FROM results WHERE problem_id = '{0}'".format(problem_id)
	sql += '  ORDER BY user_id;'
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return cursor.fetchall()

def get_results(contest_ids):
	sql =  "SELECT problem_id, user_id, score FROM results"
	sql += "  WHERE (contest_id = '{0}'".format(contest_ids[0])
	for contest_id in contest_ids[1:-1]:
		sql += "      OR contest_id = '{0}'".format(contest_id)
	sql += "  );"
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return cursor.fetchall()

def output_train_csv():
	user_list = get_user_list()
	user_idx = {user_list[i] : i for i in range(len(user_list))}
	user_results = {user_id : {} for user_id in user_list}
	task_points = {tp['problem_id'] : tp['point'] for tp in get_task_point_list(new_contest_list)}
	for result in get_results(new_contest_list):
		uid = result['user_id']
		pid = result['problem_id']
		success = result['score'] == task_points[pid]
		user_results[uid][pid] = success
	for contest_id in new_contest_list:
		tasks = sorted(get_task_list([contest_id]), key = lambda x : x['symbol'])
		task_prob_ids = [x['problem_id'] for x in tasks]
		for user_id, results in user_results.items():
			results = user_results[user_id]
			tried = False
			for pid in task_prob_ids:
				if pid in results:
					tried = True
				elif tried:
					results[pid] = False   # tried and no submit

	print('source', end = '')
	for user in user_list:
		print(',{0}_T,{0}_F'.format(user), end = '')
	print(',point')
	for pid, point in task_points.items():
		print(pid, end='')
		for uid in user_list:
			results = user_results[uid]
			if pid not in results:
				print(',0,0', end='')
			elif results[pid]:
				print(',1,0', end='')
			else:
				print(',0,1', end='')
		print(',' + str(point))

def output_test_csv():
	user_list = get_user_list()
	user_idx = {user_list[i] : i for i in range(len(user_list))}
	print('source', end = '')
	for user in user_list:
		print(',{0}_T,{0}_F'.format(user), end = '')
	print()
	task_list = get_task_list(old_contest_list)
	for task in task_list:
		print(task['problem_id'], end = '')
		binary_list = [False] * (len(user_list) * 2)
		results = get_result_list(task['problem_id'])
		for result in results:
			user_id = result['user_id']
			if user_id in user_idx:
				idx = user_idx[user_id] * 2
				if result['score'] < 10000:
					idx += 1
				binary_list[idx] = True
		for b in binary_list:
			print(',', 1 if b else 0, sep = '', end = '')
		print()

def main():
	output_train_csv()

if __name__ == '__main__':
	main()

<commit_msg>add code festival 2016 final<commit_after># coding: utf-8

import database
from data_structure import *

new_contest_list = ['agc001','agc002','agc003','agc004','agc005','agc006','agc007',
                    'arc058','arc059','arc060','arc061','arc062','arc063',
                    'abc042','abc043','abc044','abc045','abc046','abc047',
                    'tenka1-2016-quala','tenka1-2016-qualb','tenka1-2016-final-open',
                    'code-festival-2016-quala','code-festival-2016-qualb','code-festival-2016-qualc', 'cf16-final', 'cf16-final-open'
                    'ddcc2016-qual']

old_contest_list = ['arc001','arc002','arc003','arc004','arc005','arc006','arc007','arc008','arc009','arc010','arc011','arc012','arc013','arc014','arc015','arc016','arc017','arc018','arc019','arc020','arc021','arc022','arc023','arc024','arc025','arc026','arc027','arc028','arc029','arc030','arc031','arc032','arc033','arc034','arc035','arc036','arc037','arc038','arc039','arc040','arc041','arc042','arc043','arc044','arc045','arc046','arc047','arc048','arc049','arc050','arc051','arc052','arc053','arc054','arc055','arc056','arc057',
                    'abc001','abc002','abc003','abc004','abc005','abc006','abc007','abc008','abc009','abc010','abc011','abc012','abc013','abc014','abc015','abc016','abc017','abc018','abc019','abc020','abc021','abc022','abc023','abc024','abc025','abc026','abc027','abc028','abc029','abc030','abc031','abc032','abc033','abc034','abc035','abc036','abc037','abc038','abc039','abc040','abc041']

def get_user_list():
	sql = "SELECT DISTINCT user_id FROM results WHERE contest_id = '{0}'".format(new_contest_list[0])
	for contest_id in new_contest_list[1:-1]:
		sql += " OR contest_id = '{0}'".format(contest_id)
	sql += 'ORDER BY user_id;'
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return [e['user_id'] for e in cursor.fetchall()]

def get_task_list(contest_ids):
	sql =  "SELECT problem_id, symbol FROM tasks"
	sql += "  WHERE (contest_id = '{0}'".format(contest_ids[0])
	for contest_id in contest_ids[1:-1]:
		sql += "      OR contest_id = '{0}'".format(contest_id)
	sql += "  ) ORDER BY problem_id;"
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return cursor.fetchall()

def get_task_point_list(contest_ids):
	sql =  "SELECT tasks.problem_id, symbol, point FROM tasks, task_points"
	sql += "  WHERE tasks.contest_id = task_points.contest_id AND tasks.problem_id = task_points.problem_id"
	sql += "        AND (tasks.contest_id = '{0}'".format(contest_ids[0])
	for contest_id in contest_ids[1:-1]:
		sql += "      OR tasks.contest_id = '{0}'".format(contest_id)
	sql += "  ) ORDER BY tasks.problem_id;"
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return cursor.fetchall()

def get_result_list(problem_id):
	sql = "SELECT user_id, score, failure FROM results WHERE problem_id = '{0}'".format(problem_id)
	sql += '  ORDER BY user_id;'
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return cursor.fetchall()

def get_results(contest_ids):
	sql =  "SELECT problem_id, user_id, score FROM results"
	sql += "  WHERE (contest_id = '{0}'".format(contest_ids[0])
	for contest_id in contest_ids[1:-1]:
		sql += "      OR contest_id = '{0}'".format(contest_id)
	sql += "  );"
	db = database.get_connection()
	with closing(db) as con:
		with closing(con.cursor()) as cursor:
			cursor.execute(sql)
			return cursor.fetchall()

def output_train_csv():
	user_list = get_user_list()
	user_idx = {user_list[i] : i for i in range(len(user_list))}
	user_results = {user_id : {} for user_id in user_list}
	task_points = {tp['problem_id'] : tp['point'] for tp in get_task_point_list(new_contest_list)}
	for result in get_results(new_contest_list):
		uid = result['user_id']
		pid = result['problem_id']
		success = result['score'] == task_points[pid]
		user_results[uid][pid] = success
	for contest_id in new_contest_list:
		tasks = sorted(get_task_list([contest_id]), key = lambda x : x['symbol'])
		task_prob_ids = [x['problem_id'] for x in tasks]
		for user_id, results in user_results.items():
			results = user_results[user_id]
			tried = False
			for pid in task_prob_ids:
				if pid in results:
					tried = True
				elif tried:
					results[pid] = False   # tried and no submit

	print('source', end = '')
	for user in user_list:
		print(',{0}_T,{0}_F'.format(user), end = '')
	print(',point')
	for pid, point in task_points.items():
		print(pid, end='')
		for uid in user_list:
			results = user_results[uid]
			if pid not in results:
				print(',0,0', end='')
			elif results[pid]:
				print(',1,0', end='')
			else:
				print(',0,1', end='')
		print(',' + str(point))

def output_test_csv():
	user_list = get_user_list()
	user_idx = {user_list[i] : i for i in range(len(user_list))}
	print('source', end = '')
	for user in user_list:
		print(',{0}_T,{0}_F'.format(user), end = '')
	print()
	task_list = get_task_list(old_contest_list)
	for task in task_list:
		print(task['problem_id'], end = '')
		binary_list = [False] * (len(user_list) * 2)
		results = get_result_list(task['problem_id'])
		for result in results:
			user_id = result['user_id']
			if user_id in user_idx:
				idx = user_idx[user_id] * 2
				if result['score'] < 10000:
					idx += 1
				binary_list[idx] = True
		for b in binary_list:
			print(',', 1 if b else 0, sep = '', end = '')
		print()

def main():
	output_train_csv()

if __name__ == '__main__':
	main()

<|endoftext|>


<commit_before>from functools import partial

from fabric.contrib import files
from fabric.decorators import task

from refabric.api import info
from refabric.context_managers import sudo
from refabric.contrib import blueprints, debian

blueprint = blueprints.get(__name__)

start = task(partial(debian.service, 'elasticsearch', 'start', check_status=False))
stop = task(partial(debian.service, 'elasticsearch', 'stop', check_status=False))
restart = task(partial(debian.service, 'elasticsearch', 'restart', check_status=False))
reload = task(partial(debian.service, 'elasticsearch', 'force-reload', check_status=False))

@task
def setup():
    install()
    upgrade()

def install():
    with sudo():
        debian.add_apt_ppa('webupd8team/java')
        debian.debconf_set_selections('shared/accepted-oracle-license-v1-1 select true',
                                      'shared/accepted-oracle-license-v1-1 seen true')
        # Install elastic search
        version = blueprint.get('version', '1.0')
        repository = 'deb http://packages.elasticsearch.org/elasticsearch/{0}/debian stable main'.format(version)
        info('Adding key for {0}'.format(repository))
        debian.add_apt_key('http://packages.elasticsearch.org/GPG-KEY-elasticsearch')
        files.append('/etc/apt/sources.list', repository, shell=True)
        debian.apt_get('update')
        debian.apt_get('install', 'oracle-java7-installer', 'elasticsearch')

        # Enable on boot
        debian.add_service('elasticsearch', priorities='defaults 95 10')

@task
def upgrade():
    context = {
        'cluster_name': blueprint.get('cluster_name', 'elasticsearch'),
        'number_of_shards': blueprint.get('number_of_shards', '5'),
        'number_of_replicas': blueprint.get('number_of_replicas', '0')
    }
    uploads = blueprint.upload('./', '/etc/elasticsearch/', context)
    if uploads:
        restart()
<commit_msg>Refactor rc.d helper<commit_after>from functools import partial

from fabric.contrib import files
from fabric.decorators import task

from refabric.api import info
from refabric.context_managers import sudo
from refabric.contrib import blueprints, debian

blueprint = blueprints.get(__name__)

start = task(partial(debian.service, 'elasticsearch', 'start', check_status=False))
stop = task(partial(debian.service, 'elasticsearch', 'stop', check_status=False))
restart = task(partial(debian.service, 'elasticsearch', 'restart', check_status=False))
reload = task(partial(debian.service, 'elasticsearch', 'force-reload', check_status=False))

@task
def setup():
    install()
    upgrade()

def install():
    with sudo():
        debian.add_apt_ppa('webupd8team/java')
        debian.debconf_set_selections('shared/accepted-oracle-license-v1-1 select true',
                                      'shared/accepted-oracle-license-v1-1 seen true')
        # Install elastic search
        version = blueprint.get('version', '1.0')
        repository = 'deb http://packages.elasticsearch.org/elasticsearch/{0}/debian stable main'.format(version)
        info('Adding key for {0}'.format(repository))
        debian.add_apt_key('http://packages.elasticsearch.org/GPG-KEY-elasticsearch')
        files.append('/etc/apt/sources.list', repository, shell=True)
        debian.apt_get('update')
        debian.apt_get('install', 'oracle-java7-installer', 'elasticsearch')

        # Enable on boot
        debian.add_rc_service('elasticsearch', priorities='defaults 95 10')

@task
def upgrade():
    context = {
        'cluster_name': blueprint.get('cluster_name', 'elasticsearch'),
        'number_of_shards': blueprint.get('number_of_shards', '5'),
        'number_of_replicas': blueprint.get('number_of_replicas', '0')
    }
    uploads = blueprint.upload('./', '/etc/elasticsearch/', context)
    if uploads:
        restart()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
    BobSwitch
    ~~~~~~~~~~~~~~

    Online HTML5 version of the backpackers card game switch, also known as
    crazy eights and a lot of different names.  This version follows the rules
    that I know.

    :copyright: (c) Copyright 2013 by Bob
    :license: BSD, see LICENSE for more details.
"""

import sys
import argparse

import tornado.ioloop
import sockjs.tornado

from json_convert import convert_hand, convert_state_start, convert_play_response, \
        convert_state_watch
from engine import create_deck, Game, MoveType, GameMove, GameState
from models import Player, Card, Suit, Rank
from sockjs_ext import EventSocketConnection, event

import logging
log = logging.getLogger()

def wrap_chat_message(name, message):
    return {
        "name": name,
        "text": message
    }

def create_game(players):
    deck = create_deck()
    deck.shuffle()

    game = Game(players, 7, deck)

    return game

def convert_move_type(move_type):
    if move_type == "pick":
        return MoveType.pick
    elif move_type == "play":
        return MoveType.play

    return MoveType.wait

def convert_card(rankId, suitId):
    rank = next(x for x in Rank if int(x) == rankId)
    suit = next(x for x in Suit if int(x) == suitId)

    return Card(suit, rank)

def convert_suit(suitId):
    return next(x for x in Suit if int(x) == suitId)

class Room(object):
    def __init__(self):
        self.active_game = None
        self.active_players = {}
        self.players = {}
        self.participants = set()

class RoomPlayer(object):
    def __init__(self, name, socket, player):
        self.name = name
        self.socket = socket
        self.player = player
        self.ready = False

class SocketConnection(EventSocketConnection):
    participants = set()
    room = Room()

    rooms = {}

    def on_open(self, info):
        #user remains annonymous until they register, so they get no name
        self.name = None

        self.participants.add(self)

    def on_close(self):
        log.debug("Player disconnected: %s", self.name)

        if hasattr(self, "active_room"):
            if self.name in self.active_room.players:
                self.broadcast_event(self.active_room.participants, "players:disconnected", self.name)
                self.active_room.players[self.name].socket = None

            self.active_room.participants.remove(self)

        self.participants.remove(self)

    ########
    # chat functions
    ########

    @event("chat:message")
    def chat_message(self, room_name, message):
        log.debug("Chat message recieved for room '%s': %s: %s", room_name, self.name, message)

        room = self.active_room

        wrapped_message = wrap_chat_message(self.name, message)
        self.broadcast_event(room.participants, "chat:message", wrapped_message)

    def check_room(self, room):
        if room not in self.rooms:
            log.debug("creating room - '%s'", room)
            self.rooms[room] = Room()

    ########
    # account functions
    ########

    @event("account:login")
    def login(self, room_name, name):
        log.debug("user '%s' logged in to room '%s'", name, room_name)

        room = self.active_room

        self.name = name

        if name in room.players:
            room.players[name].socket = self
            self.broadcast_event(room.participants, "players:reconnected", self.name)

            game = room.active_game
            if game:
                hand = game.player_hand(name)
                self.send_event("game:state:start",
                    convert_state_start(game.state, game.players, game.player_hands,
                    game.current_player, game.played_cards.top_card, hand))
        else:
            player = Player(name)
            room_player = RoomPlayer(name, self, player)
            room.players[name] = room_player
            self.broadcast_event(self.active_room.participants, "players:added", name)

    @event("account:listing")
    def listing(self, room_name, message):
        log.debug("request for registered users")

        self.check_room(room_name)
        room = self.rooms[room_name]
        room.participants.add(self)
        self.active_room = room

        names = [{"name":s.name, "ready":s.ready, "disconnected": s.socket==None}
                for s in room.players.values()]

        self.send_event("players:listing", names)

    #######
    # game functions
    #######

    @event("game:player:ready")
    def player_ready(self, room_name, message):
        log.debug("%s ready to start game", self.name)

        room = self.active_room

        player = room.players[self.name]
        player.ready = True

        self.broadcast_event(room.participants, "game:player:ready", self.name)

        all_ready = all([s.ready
                            for s in room.players.values()])

        player_count = len(room.players)
        enough_players = player_count > 1 and player_count < 5
        if not all_ready or not enough_players:
            return

        room.active_players = room.players.copy()
        #start the game
        #send the game initial state to all players
        players = [s.player for s in room.players.values()]

        game = create_game(players)

        for participant in room.active_players.values():
            socket = participant.socket
            if socket == None:
                #player is currently disconnected, just ignore him he will
                #pick up state on reconnection
                continue
            hand = game.player_hand(socket.name)
            socket.send_event("game:state:start",
                convert_state_start(game.state, game.players, game.player_hands,
                game.current_player, game.played_cards.top_card, hand))

        for participant in room.participants:
            if participant.name not in room.active_players:
                participant.send_event("game:state:watch",
                    convert_state_watch(game.state, game.players, game.player_hands,
                        game.current_player, game.played_cards.top_card))

        room.active_game = game

        for participant in room.active_players.values():
            participant.ready = False

    @event("game:player:move")
    def player_move(self, room_name, message):
        log.debug("%s plays move", self.name)

        #parse message (wait, pick, play)
        #format
        """
            "type": "play",
            "card": { rank: 4, suit: 4 }
        """

        room = self.active_room

        move_type = convert_move_type(message["type"])
        move = None
        if move_type == MoveType.play:
            card = message["card"]
            move = GameMove(MoveType.play,
                    convert_card(card["rank"], card["suit"]))
            if "suit" in message:
                move.suit = convert_suit(message["suit"])
        else:
            move = GameMove(move_type)

        game = room.active_game

        play_response = game.play(self.name, move)

        self.send_event("game:player:response",
                convert_play_response(play_response))

        if play_response.success:
            for participant in room.active_players.values():
                socket = participant.socket
                if socket == None:
                    continue
                hand = game.player_hand(socket.name)
                socket.send_event("game:state:update",
                    convert_state_start(game.state, game.players,
                        game.player_hands,
                        game.current_player,
                        game.played_cards.top_card, hand))

            for participant in room.participants:
                if participant.name not in room.active_players:
                    participant.send_event("game:state:watch",
                        convert_state_watch(game.state, game.players, game.player_hands,
                            game.current_player, game.played_cards.top_card))

        if game.state == GameState.FINISHED:
            room.active_game = None
            room.active_players = None
            for participant in room.players.values():
                participant.ready = False

class ClearHandler(tornado.web.RequestHandler):
    def get(self):
        SocketConnection.participants.clear()
        SocketConnection.room = Room()

def parse_args(argv=sys.argv[1:]):
    description = """
    Python server for playing bobswitch
    """
    parser = argparse.ArgumentParser(description=description)
    parser.add_argument("-d", "--debug", help="enable debug mode",
                    action="store_true")

    return parser.parse_args(argv)

if __name__ == "__main__":
    import logging
    logging.getLogger().setLevel(logging.DEBUG)

    arguments = parse_args()

    BobSwitchRouter = sockjs.tornado.SockJSRouter(SocketConnection,
            '/bobswitch')

    app = tornado.web.Application(
            BobSwitchRouter.urls,
            debug=arguments.debug
    )

    app.listen(4500)

    if arguments.debug:
        debug_application = tornado.web.Application([
            (r"/clear", ClearHandler),
        ])
        debug_application.listen(9433)

    tornado.ioloop.IOLoop.instance().start()
<commit_msg>updated clear for debug mode to clear old sockets properly<commit_after># -*- coding: utf-8 -*-
"""
    BobSwitch
    ~~~~~~~~~~~~~~

    Online HTML5 version of the backpackers card game switch, also known as
    crazy eights and a lot of different names.  This version follows the rules
    that I know.

    :copyright: (c) Copyright 2013 by Bob
    :license: BSD, see LICENSE for more details.
"""

import sys
import argparse

import tornado.ioloop
import sockjs.tornado

from json_convert import convert_hand, convert_state_start, convert_play_response, \
        convert_state_watch
from engine import create_deck, Game, MoveType, GameMove, GameState
from models import Player, Card, Suit, Rank
from sockjs_ext import EventSocketConnection, event

import logging
log = logging.getLogger()

def wrap_chat_message(name, message):
    return {
        "name": name,
        "text": message
    }

def create_game(players):
    deck = create_deck()
    deck.shuffle()

    game = Game(players, 7, deck)

    return game

def convert_move_type(move_type):
    if move_type == "pick":
        return MoveType.pick
    elif move_type == "play":
        return MoveType.play

    return MoveType.wait

def convert_card(rankId, suitId):
    rank = next(x for x in Rank if int(x) == rankId)
    suit = next(x for x in Suit if int(x) == suitId)

    return Card(suit, rank)

def convert_suit(suitId):
    return next(x for x in Suit if int(x) == suitId)

class Room(object):
    def __init__(self):
        self.active_game = None
        self.active_players = {}
        self.players = {}
        self.participants = set()

class RoomPlayer(object):
    def __init__(self, name, socket, player):
        self.name = name
        self.socket = socket
        self.player = player
        self.ready = False

class SocketConnection(EventSocketConnection):
    participants = set()
    room = Room()

    rooms = {}

    def on_open(self, info):
        #user remains annonymous until they register, so they get no name
        self.name = None

        self.participants.add(self)

    def on_close(self):
        log.debug("Player disconnected: %s", self.name)

        if hasattr(self, "active_room"):
            if self.name in self.active_room.players:
                self.broadcast_event(self.active_room.participants, "players:disconnected", self.name)
                self.active_room.players[self.name].socket = None

            self.active_room.participants.remove(self)

        self.participants.remove(self)

    ########
    # chat functions
    ########

    @event("chat:message")
    def chat_message(self, room_name, message):
        log.debug("Chat message recieved for room '%s': %s: %s", room_name, self.name, message)

        room = self.active_room

        wrapped_message = wrap_chat_message(self.name, message)
        self.broadcast_event(room.participants, "chat:message", wrapped_message)

    def check_room(self, room):
        if room not in self.rooms:
            log.debug("creating room - '%s'", room)
            self.rooms[room] = Room()

    ########
    # account functions
    ########

    @event("account:login")
    def login(self, room_name, name):
        log.debug("user '%s' logged in to room '%s'", name, room_name)

        room = self.active_room

        self.name = name

        if name in room.players:
            room.players[name].socket = self
            self.broadcast_event(room.participants, "players:reconnected", self.name)

            game = room.active_game
            if game:
                hand = game.player_hand(name)
                self.send_event("game:state:start",
                    convert_state_start(game.state, game.players, game.player_hands,
                    game.current_player, game.played_cards.top_card, hand))
        else:
            player = Player(name)
            room_player = RoomPlayer(name, self, player)
            room.players[name] = room_player
            self.broadcast_event(self.active_room.participants, "players:added", name)

    @event("account:listing")
    def listing(self, room_name, message):
        log.debug("request for registered users")

        self.check_room(room_name)
        room = self.rooms[room_name]
        room.participants.add(self)
        self.active_room = room

        names = [{"name":s.name, "ready":s.ready, "disconnected": s.socket==None}
                for s in room.players.values()]

        self.send_event("players:listing", names)

    #######
    # game functions
    #######

    @event("game:player:ready")
    def player_ready(self, room_name, message):
        log.debug("%s ready to start game", self.name)

        room = self.active_room

        player = room.players[self.name]
        player.ready = True

        self.broadcast_event(room.participants, "game:player:ready", self.name)

        all_ready = all([s.ready
                            for s in room.players.values()])

        player_count = len(room.players)
        enough_players = player_count > 1 and player_count < 5
        if not all_ready or not enough_players:
            return

        room.active_players = room.players.copy()
        #start the game
        #send the game initial state to all players
        players = [s.player for s in room.players.values()]

        game = create_game(players)

        for participant in room.active_players.values():
            socket = participant.socket
            if socket == None:
                #player is currently disconnected, just ignore him he will
                #pick up state on reconnection
                continue
            hand = game.player_hand(socket.name)
            socket.send_event("game:state:start",
                convert_state_start(game.state, game.players, game.player_hands,
                game.current_player, game.played_cards.top_card, hand))

        for participant in room.participants:
            if participant.name not in room.active_players:
                participant.send_event("game:state:watch",
                    convert_state_watch(game.state, game.players, game.player_hands,
                        game.current_player, game.played_cards.top_card))

        room.active_game = game

        for participant in room.active_players.values():
            participant.ready = False

    @event("game:player:move")
    def player_move(self, room_name, message):
        log.debug("%s plays move", self.name)

        #parse message (wait, pick, play)
        #format
        """
            "type": "play",
            "card": { rank: 4, suit: 4 }
        """

        room = self.active_room

        move_type = convert_move_type(message["type"])
        move = None
        if move_type == MoveType.play:
            card = message["card"]
            move = GameMove(MoveType.play,
                    convert_card(card["rank"], card["suit"]))
            if "suit" in message:
                move.suit = convert_suit(message["suit"])
        else:
            move = GameMove(move_type)

        game = room.active_game

        play_response = game.play(self.name, move)

        self.send_event("game:player:response",
                convert_play_response(play_response))

        if play_response.success:
            for participant in room.active_players.values():
                socket = participant.socket
                if socket == None:
                    continue
                hand = game.player_hand(socket.name)
                socket.send_event("game:state:update",
                    convert_state_start(game.state, game.players,
                        game.player_hands,
                        game.current_player,
                        game.played_cards.top_card, hand))

            for participant in room.participants:
                if participant.name not in room.active_players:
                    participant.send_event("game:state:watch",
                        convert_state_watch(game.state, game.players, game.player_hands,
                            game.current_player, game.played_cards.top_card))

        if game.state == GameState.FINISHED:
            room.active_game = None
            room.active_players = None
            for participant in room.players.values():
                participant.ready = False

class ClearHandler(tornado.web.RequestHandler):
    def get(self):
        SocketConnection.participants.clear()
        SocketConnection.rooms = {}

def parse_args(argv=sys.argv[1:]):
    description = """
    Python server for playing bobswitch
    """
    parser = argparse.ArgumentParser(description=description)
    parser.add_argument("-d", "--debug", help="enable debug mode",
                    action="store_true")

    return parser.parse_args(argv)

if __name__ == "__main__":
    import logging
    logging.getLogger().setLevel(logging.DEBUG)

    arguments = parse_args()

    BobSwitchRouter = sockjs.tornado.SockJSRouter(SocketConnection,
            '/bobswitch')

    app = tornado.web.Application(
            BobSwitchRouter.urls,
            debug=arguments.debug
    )

    app.listen(4500)

    if arguments.debug:
        debug_application = tornado.web.Application([
            (r"/clear", ClearHandler),
        ])
        debug_application.listen(9433)

    tornado.ioloop.IOLoop.instance().start()
<|endoftext|>


<commit_before>from .plotobject import PlotObject
from .properties import (HasProps, Dict, Enum,
                         Either, Float, Instance, Int,
                         List, String, Color, Include, Bool,
                         Tuple, Any, lookup_descriptor)
import copy
import logging
logger = logging.getLogger(__name__)

class HBox(PlotObject):
    children = List(Instance(PlotObject, has_ref=True), has_ref=True)
class VBox(PlotObject):
    children = List(Instance(PlotObject, has_ref=True), has_ref=True)

#parent class only, you need to set the fields you want
class VBoxModelForm(PlotObject):
    _children  = List(Instance(PlotObject, has_ref=True), has_ref=True)
    _field_defs = Dict(String, Any)
    input_specs = None
    jsmodel = "VBoxModelForm"
    def __init__(self, *args, **kwargs):
        super(VBoxModelForm, self).__init__(*args, **kwargs)
        for prop in self.__properties__:
            propobj = lookup_descriptor(self.__class__, prop)
            if isinstance(propobj, Float):
                self._field_defs[prop] = "Float"
            elif isinstance(propobj, Int):
                self._field_defs[prop] = "Int"
            else:
                self._field_defs[prop] = "String"
    def create_inputs(self, session):
        session.add(self)
        if self.input_specs:
            for input_spec in self.input_specs:
                input_spec = copy.copy(input_spec)
                widget = input_spec.pop('widget')
                widget = widget.create(**input_spec)
                session.add(widget)
                self._children.append(widget)

class InputWidget(PlotObject):
    title = String()
    name = String()
    value = String()
    @classmethod
    def coerce_value(cls, val):
        prop_obj = lookup_descriptor(cls, 'value')
        if isinstance(prop_obj, Float):
            return float(val)
        if isinstance(prop_obj, Int):
            return int(val)
        if isinstance(prop_obj, String):
            return str(val)

    @classmethod
    def create(cls, *args, **kwargs):
        """Only called the first time we make an object,
        whereas __init__ is called every time it's loaded
        """
        if kwargs.get('title') is None:
            kwargs['title'] = kwargs['name']
        if kwargs.get('value') is not None:
            kwargs['value'] = cls.coerce_value(kwargs.get('value'))
        return cls(**kwargs)

class TextInput(InputWidget):
    value = String()

class BokehApplet(PlotObject):
    modelform = Instance(VBoxModelForm, has_ref=True)
    children = List(Instance(PlotObject, has_ref=True), has_ref=True)
    jsmodel = "HBox"
    extra_generated_classes = List(Tuple(String, String, String))

    def update(self, **kwargs):
        super(BokehApplet, self).update(**kwargs)
        self.setup_events()

    def setup_events(self):
        if self.modelform:
            self.bind_modelform()

    def bind_modelform(self):
        for prop in self.modelform.__properties__:
            if not prop.startswith("_"):
                self.modelform.on_change(prop, self,
                                         'input_change')

    def input_change(self, obj, attrname, old, new):
        pass

    def create(self):
        pass
    def add_all(self, session):
        objs = self.references()
        for obj in objs:
            session.add(obj)

    @classmethod
    def add_route(cls, route, bokeh_url):
        from bokeh.server.app import bokeh_app
        from bokeh.pluginutils import app_document
        from bokeh.plotting import session
        from flask import render_template
        @app_document(cls.__view_model__, bokeh_url)
        def make_app():
            app = cls()
            app.create(session())
            return app

        def exampleapp():
            app = make_app()
            docname = session().docname
            docid = session().docid
            extra_generated_classes = app.extra_generated_classes
            if len(extra_generated_classes) == 0:
                extra_generated_classes.append((
                    app.__view_model__,
                    app.__view_model__,
                    app.jsmodel))
                extra_generated_classes.append((
                    app.modelform.__view_model__,
                    app.modelform.__view_model__,
                    app.modelform.jsmodel))
            return render_template(
                'applet.html',
                extra_generated_classes=extra_generated_classes,
                title=app.__class__.__view_model__,
                docname=docname,
                docid=docid,
                splitjs=bokeh_app.splitjs)
        exampleapp.__name__ = cls.__view_model__
        bokeh_app.route(route)(exampleapp)

class Paragraph(PlotObject):
    text = String()

class PreText(Paragraph):
    pass

class Select(InputWidget):
    options = List(Any)
    value = String()

    @classmethod
    def create(self, *args, **kwargs):
        options = kwargs.pop('options', [])
        new_options = []
        for opt in options:
            if isinstance(opt, basestring):
                opt = {'name' : opt, 'value' : opt}
            new_options.append(opt)
        kwargs['options'] = new_options
        return super(Select, self).create(*args, **kwargs)

class Slider(InputWidget):
    value = Float()
    start = Float()
    end = Float()
    steps = Int(default=50)
    orientation = String(default="horizontal")
<commit_msg>changed orientation of slider to enum<commit_after>from .plotobject import PlotObject
from .properties import (HasProps, Dict, Enum,
                         Either, Float, Instance, Int,
                         List, String, Color, Include, Bool,
                         Tuple, Any, lookup_descriptor)
import copy
import logging
logger = logging.getLogger(__name__)

class HBox(PlotObject):
    children = List(Instance(PlotObject, has_ref=True), has_ref=True)
class VBox(PlotObject):
    children = List(Instance(PlotObject, has_ref=True), has_ref=True)

#parent class only, you need to set the fields you want
class VBoxModelForm(PlotObject):
    _children  = List(Instance(PlotObject, has_ref=True), has_ref=True)
    _field_defs = Dict(String, Any)
    input_specs = None
    jsmodel = "VBoxModelForm"
    def __init__(self, *args, **kwargs):
        super(VBoxModelForm, self).__init__(*args, **kwargs)
        for prop in self.__properties__:
            propobj = lookup_descriptor(self.__class__, prop)
            if isinstance(propobj, Float):
                self._field_defs[prop] = "Float"
            elif isinstance(propobj, Int):
                self._field_defs[prop] = "Int"
            else:
                self._field_defs[prop] = "String"
    def create_inputs(self, session):
        session.add(self)
        if self.input_specs:
            for input_spec in self.input_specs:
                input_spec = copy.copy(input_spec)
                widget = input_spec.pop('widget')
                widget = widget.create(**input_spec)
                session.add(widget)
                self._children.append(widget)

class InputWidget(PlotObject):
    title = String()
    name = String()
    value = String()
    @classmethod
    def coerce_value(cls, val):
        prop_obj = lookup_descriptor(cls, 'value')
        if isinstance(prop_obj, Float):
            return float(val)
        if isinstance(prop_obj, Int):
            return int(val)
        if isinstance(prop_obj, String):
            return str(val)

    @classmethod
    def create(cls, *args, **kwargs):
        """Only called the first time we make an object,
        whereas __init__ is called every time it's loaded
        """
        if kwargs.get('title') is None:
            kwargs['title'] = kwargs['name']
        if kwargs.get('value') is not None:
            kwargs['value'] = cls.coerce_value(kwargs.get('value'))
        return cls(**kwargs)

class TextInput(InputWidget):
    value = String()

class BokehApplet(PlotObject):
    modelform = Instance(VBoxModelForm, has_ref=True)
    children = List(Instance(PlotObject, has_ref=True), has_ref=True)
    jsmodel = "HBox"
    extra_generated_classes = List(Tuple(String, String, String))

    def update(self, **kwargs):
        super(BokehApplet, self).update(**kwargs)
        self.setup_events()

    def setup_events(self):
        if self.modelform:
            self.bind_modelform()

    def bind_modelform(self):
        for prop in self.modelform.__properties__:
            if not prop.startswith("_"):
                self.modelform.on_change(prop, self,
                                         'input_change')

    def input_change(self, obj, attrname, old, new):
        pass

    def create(self):
        pass
    def add_all(self, session):
        objs = self.references()
        for obj in objs:
            session.add(obj)

    @classmethod
    def add_route(cls, route, bokeh_url):
        from bokeh.server.app import bokeh_app
        from bokeh.pluginutils import app_document
        from bokeh.plotting import session
        from flask import render_template
        @app_document(cls.__view_model__, bokeh_url)
        def make_app():
            app = cls()
            app.create(session())
            return app

        def exampleapp():
            app = make_app()
            docname = session().docname
            docid = session().docid
            extra_generated_classes = app.extra_generated_classes
            if len(extra_generated_classes) == 0:
                extra_generated_classes.append((
                    app.__view_model__,
                    app.__view_model__,
                    app.jsmodel))
                extra_generated_classes.append((
                    app.modelform.__view_model__,
                    app.modelform.__view_model__,
                    app.modelform.jsmodel))
            return render_template(
                'applet.html',
                extra_generated_classes=extra_generated_classes,
                title=app.__class__.__view_model__,
                docname=docname,
                docid=docid,
                splitjs=bokeh_app.splitjs)
        exampleapp.__name__ = cls.__view_model__
        bokeh_app.route(route)(exampleapp)

class Paragraph(PlotObject):
    text = String()

class PreText(Paragraph):
    pass

class Select(InputWidget):
    options = List(Any)
    value = String()

    @classmethod
    def create(self, *args, **kwargs):
        options = kwargs.pop('options', [])
        new_options = []
        for opt in options:
            if isinstance(opt, basestring):
                opt = {'name' : opt, 'value' : opt}
            new_options.append(opt)
        kwargs['options'] = new_options
        return super(Select, self).create(*args, **kwargs)

class Slider(InputWidget):
    value = Float()
    start = Float()
    end = Float()
    steps = Int(default=50)
    orientation = Enum("horizontal", "vertical")
<|endoftext|>


<commit_before>import json
import logging
import re

import aiohttp
import discord
from discord.ext import commands

log = logging.getLogger(__name__)
err_regex = re.compile(r"^error(\[.*\])*:", re.MULTILINE)

class CodeBlock:
    missing_error = "Missing code block. Please use the following markdown\n\\`\\`\\`rust\ncode here\n\\`\\`\\`"

    def __init__(self, argument):
        try:
            block, code = argument.split("\n", 1)
        except ValueError:
            raise commands.BadArgument(self.missing_error)

        if not block.startswith("```") and not code.endswith("```"):
            raise commands.BadArgument(self.missing_error)

        self.source = code.rstrip("`")

class CodeSection:
    missing_error = "Missing code section. Please use the following markdown\n\\`code here\\`\nor\n\\`\\`\\`rust\ncode here\n\\`\\`\\`"

    def __init__(self, code):
        codeblock = code.startswith("```") and code.endswith("```")
        codesection = code.startswith("`") and code.endswith("`")
        if not codesection and not codeblock:
            raise commands.BadArgument(self.missing_error)

        if codeblock:
            self.source = "\n".join(code.split("\n")[1:]).rstrip("`")
        else:
            self.source = code.strip("`")

class Playground:
    """Evaluates Rust code with an optional compilation mode.
    Defaults to debug.

    Usage:

    ?play (--release|--debug) ```rs
    <your Rust code here>
    ```

    """

    def __init__(self, bot: commands.Bot):
        self.bot = bot
        self.session = aiohttp.ClientSession(loop=self.bot.loop)

    def __unload(self):
        self.session.close()

    @commands.command()
    async def play(self, ctx: commands.Context, *, arg):
        """Evaluates Rust code. Exactly equal to https://play.integer32.com/"""
        (mode, code) = self.parse_args(arg)
        await self.query_playground(ctx, mode, code.source)

    @commands.command()
    async def playwarn(self, ctx: commands.Context, *, arg):
        """Evaluates Rust code and outputs generated warnings. Exactly equal to https://play.integer32.com/"""
        (mode, code) = self.parse_args(arg)
        await self.query_playground(ctx, mode, code.source, warnings=True)

    @commands.command()
    async def eval(self, ctx: commands.Context, *, arg):
        """Evaluates Rust code and debug prints the results. Exactly equal to https://play.integer32.com/"""
        (mode, code) = self.parse_args(arg)
        comment_index = code.source.find("//")
        end_idx = comment_index if comment_index != -1 else len(code.source)
        await self.query_playground(
            ctx, mode, 'fn main(){println!("{:?}",{' + code.source[:end_idx] + "});}"
        )

    def parse_args(self, args):
        args = args.replace("\n`", " `").split(" ")
        if args[0].startswith("--"):
            mode = args[0][2:]
            mode.strip()
            print("aaaaaa", mode)
            code = " ".join(args[1:])
            if mode != "release" and mode != "debug":
                raise commands.BadArgument(
                    "Bad compile mode. Valid options are `--release` and `--debug`"
                )

            return (mode, CodeSection(code))
        else:
            code = " ".join(args[0:])
            return (None, CodeSection(code))

    async def query_playground(
        self, ctx: commands.Context, mode, source, warnings=None
    ):
        async with ctx.typing():
            payload = json.dumps(
                {
                    "channel": "nightly",
                    "code": source,
                    "crateType": "bin",
                    "mode": mode if mode is not None else "debug",
                    "tests": False,
                }
            )

            async with self.session.post(
                "https://play.integer32.com/execute", data=payload
            ) as r:
                if r.status != 200:
                    raise commands.CommandError(
                        "Rust i32 Playground didn't respond in time."
                    )

                response = await r.json()
                if "error" in response:
                    raise commands.CommandError(response["error"])

                stderr = response["stderr"]
                stdout = response["stdout"]

                full_response = (
                    stdout
                    if err_regex.search(stderr) is None
                    and not (warnings is not None and len(stderr) >= 4)
                    and not "panicked" in stderr
                    else "\n".join(stderr.split("\n")[1:]) + "\n\n" + stdout
                )
                len_response = len(full_response)
                if len_response == 0:
                    msg = "``` ```"
                elif len_response < 1990:
                    full_response = full_response.replace("```", "  ̀  ̀  ̀")
                    msg = f"```rs\n{full_response}```"
                elif 1990 <= len_response <= 5000:
                    msg = await self.get_gist(full_response)
                else:
                    raise commands.CommandError("Output too big!")

                await ctx.send(msg)

    async def get_gist(self, msg):
        data = json.dumps({"public": True, "files": {"main.rs": {"content": msg}}})

        headers = {"Accept": "application/vnd.github.v3+json"}

        async with self.session.post(
            "https://api.github.com/gists", data=data, headers=headers
        ) as r:
            response = await r.json()

        return "https://gist.github.com/anonymous/" + response["id"]

    async def __error(self, ctx: commands.Context, error):
        log.error("Playground error: %s", error)
        if isinstance(error, (discord.HTTPException, discord.Forbidden)):
            await ctx.send("Error while sending the output.")
        if isinstance(error, commands.MissingRequiredArgument):
            await ctx.send(CodeBlock.missing_error)
        if isinstance(error, commands.CommandError):
            await ctx.send(str(error))

def setup(bot):
    bot.add_cog(Playground(bot))
<commit_msg>Cleanup code style<commit_after>import json
import logging
import re

import aiohttp
import discord
from discord.ext import commands

log = logging.getLogger(__name__)
err_regex = re.compile(r"^error(\[.*\])*:", re.MULTILINE)

class CodeBlock:
    missing_error = "Missing code block. Please use the following markdown\n\\`\\`\\`rust\ncode here\n\\`\\`\\`"

    def __init__(self, argument):
        try:
            block, code = argument.split("\n", 1)
        except ValueError:
            raise commands.BadArgument(self.missing_error)

        if not block.startswith("```") and not code.endswith("```"):
            raise commands.BadArgument(self.missing_error)

        self.source = code.rstrip("`")

class CodeSection:
    missing_error = "Missing code section. Please use the following markdown\n\\`code here\\`\nor\n\\`\\`\\`rust\ncode here\n\\`\\`\\`"

    def __init__(self, code):
        codeblock = code.startswith("```") and code.endswith("```")
        codesection = code.startswith("`") and code.endswith("`")
        if not codesection and not codeblock:
            raise commands.BadArgument(self.missing_error)

        if codeblock:
            self.source = "\n".join(code.split("\n")[1:]).rstrip("`")
        else:
            self.source = code.strip("`")

class Playground:
    """Evaluates Rust code with an optional compilation mode.
    Defaults to debug.

    Usage:

    ?play (--release|--debug) ```rs
    <your Rust code here>
    ```

    """

    def __init__(self, bot: commands.Bot):
        self.bot = bot
        self.session = aiohttp.ClientSession(loop=self.bot.loop)

    def __unload(self):
        self.session.close()

    @commands.command()
    async def play(self, ctx: commands.Context, *, arg):
        """Evaluates Rust code. Exactly equal to https://play.integer32.com/"""
        (mode, code) = self.parse_args(arg)
        await self.query_playground(ctx, mode, code.source)

    @commands.command()
    async def playwarn(self, ctx: commands.Context, *, arg):
        """Evaluates Rust code and outputs generated warnings. Exactly equal to https://play.integer32.com/"""
        (mode, code) = self.parse_args(arg)
        await self.query_playground(ctx, mode, code.source, warnings=True)

    @commands.command()
    async def eval(self, ctx: commands.Context, *, arg):
        """Evaluates Rust code and debug prints the results. Exactly equal to https://play.integer32.com/"""
        (mode, code) = self.parse_args(arg)
        comment_index = code.source.find("//")
        end_idx = comment_index if comment_index != -1 else len(code.source)
        await self.query_playground(
            ctx, mode, 'fn main(){println!("{:?}",{' + code.source[:end_idx] + "});}"
        )

    def parse_args(self, args):
        args = args.replace("\n`", " `").split(" ")
        if args[0].startswith("--"):
            mode = args[0][2:]
            mode.strip()
            code = " ".join(args[1:])
            if mode != "release" and mode != "debug":
                raise commands.BadArgument(
                    "Bad compile mode. Valid options are `--release` and `--debug`"
                )

            return mode, CodeSection(code)
        else:
            code = " ".join(args[0:])
            return None, CodeSection(code)

    async def query_playground(
        self, ctx: commands.Context, mode, source, warnings=None
    ):
        async with ctx.typing():
            payload = json.dumps(
                {
                    "channel": "nightly",
                    "code": source,
                    "crateType": "bin",
                    "mode": mode if mode is not None else "debug",
                    "tests": False,
                }
            )

            async with self.session.post(
                "https://play.integer32.com/execute", data=payload
            ) as r:
                if r.status != 200:
                    raise commands.CommandError(
                        "Rust i32 Playground didn't respond in time."
                    )

                response = await r.json()
                if "error" in response:
                    raise commands.CommandError(response["error"])

                stderr = response["stderr"]
                stdout = response["stdout"]

                full_response = (
                    stdout
                    if err_regex.search(stderr) is None
                    and not (warnings is not None and len(stderr) >= 4)
                    and "panicked" not in stderr
                    else "\n".join(stderr.split("\n")[1:]) + "\n\n" + stdout
                )
                len_response = len(full_response)
                if len_response == 0:
                    msg = "``` ```"
                elif len_response < 1990:
                    full_response = full_response.replace("```", "  ̀  ̀  ̀")
                    msg = f"```rs\n{full_response}```"
                elif 1990 <= len_response <= 5000:
                    msg = await self.get_gist(full_response)
                else:
                    raise commands.CommandError("Output too big!")

                await ctx.send(msg)

    async def get_gist(self, msg):
        data = json.dumps({"public": True, "files": {"main.rs": {"content": msg}}})

        headers = {"Accept": "application/vnd.github.v3+json"}

        async with self.session.post(
            "https://api.github.com/gists", data=data, headers=headers
        ) as r:
            response = await r.json()

        return "https://gist.github.com/anonymous/" + response["id"]

    async def __error(self, ctx: commands.Context, error):
        log.error("Playground error: %s", error)
        if isinstance(error, (discord.HTTPException, discord.Forbidden)):
            await ctx.send("Error while sending the output.")
        if isinstance(error, commands.MissingRequiredArgument):
            await ctx.send(CodeBlock.missing_error)
        if isinstance(error, commands.CommandError):
            await ctx.send(str(error))

def setup(bot):
    bot.add_cog(Playground(bot))
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Copyright 2014 Universitatea de Vest din Timișoara

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@author: Marian Neagul <marian@info.uvt.ro>
@contact: marian@info.uvt.ro
@copyright: 2014 Universitatea de Vest din Timișoara
"""

import sys

import cherrypy
import pkg_resources
from sct.webapi import get_app

class CloudToolkitWebServer(object):
    @cherrypy.expose
    def index(self):
        index_content = pkg_resources.resource_string(__name__, "resources/web/index.html")
        return index_content

def handle_server_cli(args):
    static_content_dir = pkg_resources.resource_filename(__name__, "resources/web/static/")

    config = {
        '/': {
            'tools.staticdir.debug': True,
        },
        '/static': {
            'tools.staticdir.dir': static_content_dir,
            'tools.staticdir.on': True,
        }
    }

    webapp = CloudToolkitWebServer()
    cherrypy.tree.mount(webapp, "/", config=config)
    cherrypy.tree.graft(get_app(), "/api")
    cherrypy.config.update(config)
    print >>sys.stderr, "Starting server..."
    cherrypy.engine.start()

<commit_msg>[...]<commit_after># -*- coding: utf-8 -*-
"""
Copyright 2014 Universitatea de Vest din Timișoara

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@author: Marian Neagul <marian@info.uvt.ro>
@contact: marian@info.uvt.ro
@copyright: 2014 Universitatea de Vest din Timișoara
"""

import sys

import logging
import cherrypy
import pkg_resources
from sct.webapi import get_app

class CloudToolkitWebServer(object):
    @cherrypy.expose
    def index(self):
        index_content = pkg_resources.resource_string(__name__, "resources/web/index.html")
        return index_content

def handle_server_cli(args):
    static_content_dir = pkg_resources.resource_filename(__name__, "resources/web/static/")

    config = {
        '/': {
            'tools.staticdir.debug': True,
        },
        '/static': {
            'tools.staticdir.dir': static_content_dir,
            'tools.staticdir.on': True,
        }
    }

    webapp = CloudToolkitWebServer()
    cherrypy.tree.mount(webapp, "/", config=config)
    cherrypy.tree.graft(get_app(), "/api")
    cherrypy.config.update(config)
    logging.info("Satrating server...")
    cherrypy.engine.start()

<|endoftext|>


<commit_before># This file is part of cclib (http://cclib.sf.net), a library for parsing
# and interpreting the results of computational chemistry packages.
#
# Copyright (C) 2006-2014, the cclib development team
#
# The library is free software, distributed under the terms of
# the GNU Lesser General Public version 2.1 or later. You should have
# received a copy of the license along with cclib. You can also access
# the full license online at http://www.gnu.org/copyleft/lgpl.html.

from __future__ import print_function
import os
import sys
import unittest

from cclib.parser import ADF, GAMESS, GAMESSUK, Gaussian, Jaguar, Molpro, ORCA

# All supported parsers.
parsers = [ "ADF", "GAMESS", "GAMESSUK", "Gaussian", "Jaguar", "Molpro", "ORCA" ]

# The modules to be included in the global test testall().
test_modules = [ "SP", "SPun", "GeoOpt", "Basis", "Core",   # Basic calculations.
                 "MP", "CC", "CI", "TD", "TDun",            # Post-SCF calculations.
                 "vib" ]                                    # Other property calculations.

def get_program_dir(parser_name):
    """In one case the directory is names differently than the parser."""
    if parser_name == "GAMESSUK":
        return "GAMESS-UK"
    else:
        return parser_name

def getfile(parser, *location):
    """Returns a parsed logfile.

    Inputs:
        parser - a logfile parser class (subclass of LogFile)
        *location - subdirectory and data filename(s)

    Outputs:
        data - the resulting data object
        logfile - the parser object used for parsing
    """

    location = os.path.join(("..", "data", get_program_dir(parser.__name__)) + location)

    # Now construct the proper full path(s).
    # Multiple paths will be in a list only if more than one data file given.
    # Presently, location contains only one subdirectory (basic*),
    #   so this is easy since there are normally 5 elements in location.
    if len(location) == 5:
        filename = os.path.join(*location)
    else:
        filename = [os.path.join(*(location[:4]+location[n:n+1])) for n in range(4,len(location))]

    logfile = parser(filename)
    logfile.logger.setLevel(0)
    data = logfile.parse()

    return data, logfile

def gettestdata(module=None):
    """Returns a dict of test files for a given module."""

    testdatadir = os.path.dirname(os.path.realpath(sys.argv[0]))
    lines = open(testdatadir+'/testdata').readlines()

    # Remove blank lines and those starting with '#'.
    lines = [line.split() for line in lines if (line.strip() and line[0] != '#')]

    # Filter for lines only for the given module.
    if module:
        lines = [line for line in lines if line[0] == module]

    # This dictionary contains information needed to run unit tests, with one entry
    # for each unit test class used. Since there may in principle be multiple tests
    # for a test class (files from different program versions, for example), the values
    # in this dictionary are themselves lists of dictionaries.
    testdata = {}
    for line in lines:
        test = {}
        test["module"] = line[0]
        test["parser"] = line[1]
        test["location"] = line[3:]
        testclass = line[2]
        if testclass not in testdata:
            testdata[testclass] = []
        testdata[testclass].append(test)

    return testdata

def visualtests():
    """These are not formal tests -- but they should be eyeballed."""

    output = [ getfile(Gaussian,"basicGaussian03","dvb_gopt.out")[0],
               getfile(GAMESS,"basicPCGAMESS","dvb_gopt_a.out")[0],
               getfile(GAMESS,"basicGAMESS-US2012","dvb_gopt_a.out")[0],
               getfile(ADF,"basicADF2007.01","dvb_gopt.adfout")[0],
               getfile(Jaguar,"basicJaguar7.0", "dvb_gopt.out")[0],
               getfile(Molpro,"basicMolpro2006", "dvb_gopt.out", "dvb_gopt.out")[0],
             ]

    print("\n\nMO energies of optimised dvb")
    print("      ", "".join(["%-12s" % x for x in ['Gaussian03','PC-GAMESS','GAMESS-US','ADF2007.01','Jaguar7.0','Molpro2006']]))
    print("HOMO", "   ".join(["%+9.4f" % x.moenergies[0][x.homos[0]] for x in output]))
    print("LUMO", "   ".join(["%+9.4f" % x.moenergies[0][x.homos[0]+1] for x in output]))
    print("H-L ", "   ".join(["%9.4f" % (x.moenergies[0][x.homos[0]+1]-x.moenergies[0][x.homos[0]],) for x in output]))

def importName(modulename, name):
    """Import from a module whose name is determined at run-time.

    Taken from Python Cookbook 2nd ed O'Reilly Recipe 16.3.
    Additionally, also returns None if module does not habe attribute name.

    Inputs:
        modulename - name of the module
        name - name to be imported
    """

    try:
        module = __import__(modulename, globals(), locals(), [name])
    except ImportError:
        return None

    return getattr(module, name, None)

def testall(parserchoice=parsers, modules=test_modules):
    """Run all unittests in all modules."""

    # Make sure we are in the test directory of this script,
    #   so that getfile() can access the data files.
    curdir = os.path.abspath(os.curdir)
    destdir = os.path.dirname(__file__)
    if destdir:
        os.chdir(destdir)

    perpackage = {}
    errors = []

    alltests = []
    for module in modules:

        testdata = gettestdata(module)

        # Filter the test data to use if a list of requested parsers is passed
        # to this function, assuming that all unit tests for a given test class
        # use the same parser (use the first unit test to check).
        if parserchoice:
            testdata = dict([(x,y) for x,y in testdata.items() if y[0]['parser'] in parserchoice ])

        testnames = sorted(testdata.keys())
        for name in testnames:

            for test_instance in testdata[name]:

                path = '/'.join(test_instance["location"])
                program = test_instance["location"][0][5:]

                try:
                    test = importName("test%s" %module, name)
                except:
                    errors.append("ERROR: could not import %s from %s." %(name, module))
                else:
                    print("\n**** test%s (%s): %s ****" %(module, program, test.__doc__))
                    parser = test_instance["parser"]
                    location = test_instance["location"]
                    test.data, test.logfile = getfile(eval(parser), *location)
                    myunittest = unittest.makeSuite(test)
                    a = unittest.TextTestRunner(verbosity=2).run(myunittest)
                    l = perpackage.setdefault(program, [0, 0, 0, 0])
                    l[0] += a.testsRun
                    l[1] += len(a.errors)
                    l[2] += len(a.failures)
                    if hasattr(a, "skipped"):
                        l[3] += len(a.skipped)
                    alltests.append(test)

    print("\n\n********* SUMMARY PER PACKAGE ****************")
    names = sorted(perpackage.keys())
    total = [0, 0, 0, 0]
    print(" "*14, "\t".join(["Total", "Passed", "Failed", "Errors", "Skipped"]))
    for name in names:
        l = perpackage[name]
        print(name.ljust(15), "%3d\t%3d\t%3d\t%3d\t%3d" % (l[0], l[0]-l[1]-l[2]-l[3], l[2], l[1], l[3]))
        for i in range(4):
            total[i] += l[i]

    print("\n\n********* SUMMARY OF EVERYTHING **************")
    print("TOTAL: %d\tPASSED: %d\tFAILED: %d\tERRORS: %d\tSKIPPED: %d" \
            %(total[0], total[0]-(total[1]+total[2]+total[3]), total[2], total[1], total[3]))

    if errors:
        print("\n".join(errors))

    print("\n\n*** Visual tests ***")
    visualtests()

    # Return to the directory we started from.
    if destdir:
        os.chdir(curdir)

    return alltests

if __name__ == "__main__":
    chosen_parsers = [p for p in parsers if p in sys.argv] or parsers
    chosen_modules = [m for m in test_modules if m in sys.argv] or test_modules
    tests = testall(chosen_parsers, chosen_modules)
<commit_msg>Tests: allow custom stream when running tests<commit_after># This file is part of cclib (http://cclib.sf.net), a library for parsing
# and interpreting the results of computational chemistry packages.
#
# Copyright (C) 2006-2014, the cclib development team
#
# The library is free software, distributed under the terms of
# the GNU Lesser General Public version 2.1 or later. You should have
# received a copy of the license along with cclib. You can also access
# the full license online at http://www.gnu.org/copyleft/lgpl.html.

from __future__ import print_function
import os
import sys
import unittest

from cclib.parser import ADF, GAMESS, GAMESSUK, Gaussian, Jaguar, Molpro, ORCA

# All supported parsers.
parsers = [ "ADF", "GAMESS", "GAMESSUK", "Gaussian", "Jaguar", "Molpro", "ORCA" ]

# The modules to be included in the global test testall().
test_modules = [ "SP", "SPun", "GeoOpt", "Basis", "Core",   # Basic calculations.
                 "MP", "CC", "CI", "TD", "TDun",            # Post-SCF calculations.
                 "vib" ]                                    # Other property calculations.

def get_program_dir(parser_name):
    """In one case the directory is names differently than the parser."""
    if parser_name == "GAMESSUK":
        return "GAMESS-UK"
    else:
        return parser_name

def getfile(parser, *location, stream=sys.stdout):
    """Returns a parsed logfile.

    Inputs:
        parser - a logfile parser class (subclass of LogFile)
        *location - subdirectory and data filename(s)

    Outputs:
        data - the resulting data object
        logfile - the parser object used for parsing
    """

    location = os.path.join(("..", "data", get_program_dir(parser.__name__)) + location)

    # Now construct the proper full path(s).
    # Multiple paths will be in a list only if more than one data file given.
    # Presently, location contains only one subdirectory (basic*),
    #   so this is easy since there are normally 5 elements in location.
    if len(location) == 5:
        filename = os.path.join(*location)
    else:
        filename = [os.path.join(*(location[:4]+location[n:n+1])) for n in range(4,len(location))]

    logfile = parser(filename, logstream=stream)
    logfile.logger.setLevel(0)
    data = logfile.parse()

    return data, logfile

def gettestdata(module=None):
    """Returns a dict of test files for a given module."""

    testdatadir = os.path.dirname(os.path.realpath(sys.argv[0]))
    lines = open(testdatadir+'/testdata').readlines()

    # Remove blank lines and those starting with '#'.
    lines = [line.split() for line in lines if (line.strip() and line[0] != '#')]

    # Filter for lines only for the given module.
    if module:
        lines = [line for line in lines if line[0] == module]

    # This dictionary contains information needed to run unit tests, with one entry
    # for each unit test class used. Since there may in principle be multiple tests
    # for a test class (files from different program versions, for example), the values
    # in this dictionary are themselves lists of dictionaries.
    testdata = {}
    for line in lines:
        test = {}
        test["module"] = line[0]
        test["parser"] = line[1]
        test["location"] = line[3:]
        testclass = line[2]
        if testclass not in testdata:
            testdata[testclass] = []
        testdata[testclass].append(test)

    return testdata

def visualtests(stream=sys.stdout):
    """These are not formal tests -- but they should be eyeballed."""

    output = [ getfile(Gaussian,"basicGaussian03","dvb_gopt.out")[0],
               getfile(GAMESS,"basicPCGAMESS","dvb_gopt_a.out")[0],
               getfile(GAMESS,"basicGAMESS-US2012","dvb_gopt_a.out")[0],
               getfile(ADF,"basicADF2007.01","dvb_gopt.adfout")[0],
               getfile(Jaguar,"basicJaguar7.0", "dvb_gopt.out")[0],
               getfile(Molpro,"basicMolpro2006", "dvb_gopt.out", "dvb_gopt.out")[0],
             ]

    print("\n\nMO energies of optimised dvb", file=stream)
    print("      ", "".join(["%-12s" % x for x in ['Gaussian03','PC-GAMESS','GAMESS-US','ADF2007.01','Jaguar7.0','Molpro2006']]), file=stream)
    print("HOMO", "   ".join(["%+9.4f" % x.moenergies[0][x.homos[0]] for x in output]), file=stream)
    print("LUMO", "   ".join(["%+9.4f" % x.moenergies[0][x.homos[0]+1] for x in output]), file=stream)
    print("H-L ", "   ".join(["%9.4f" % (x.moenergies[0][x.homos[0]+1]-x.moenergies[0][x.homos[0]],) for x in output]), file=stream)

def importName(modulename, name):
    """Import from a module whose name is determined at run-time.

    Taken from Python Cookbook 2nd ed O'Reilly Recipe 16.3.
    Additionally, also returns None if module does not habe attribute name.

    Inputs:
        modulename - name of the module
        name - name to be imported
    """

    try:
        module = __import__(modulename, globals(), locals(), [name])
    except ImportError:
        return None

    return getattr(module, name, None)

def testall(parserchoice=parsers, modules=test_modules, stream=sys.stdout):
    """Run all unittests in all modules."""

    # Make sure we are in the test directory of this script,
    #   so that getfile() can access the data files.
    curdir = os.path.abspath(os.curdir)
    destdir = os.path.dirname(__file__)
    if destdir:
        os.chdir(destdir)

    perpackage = {}
    errors = []

    alltests = []
    for module in modules:

        testdata = gettestdata(module)

        # Filter the test data to use if a list of requested parsers is passed
        # to this function, assuming that all unit tests for a given test class
        # use the same parser (use the first unit test to check).
        if parserchoice:
            testdata = dict([(x,y) for x,y in testdata.items() if y[0]['parser'] in parserchoice ])

        testnames = sorted(testdata.keys())
        for name in testnames:

            for test_instance in testdata[name]:

                path = '/'.join(test_instance["location"])
                program = test_instance["location"][0][5:]

                try:
                    test = importName("test%s" %module, name)
                except:
                    errors.append("ERROR: could not import %s from %s." %(name, module))
                else:
                    print("\n**** test%s (%s): %s ****" %(module, program, test.__doc__), file=stream)
                    parser = test_instance["parser"]
                    location = test_instance["location"]
                    test.data, test.logfile = getfile(eval(parser), *location, stream=stream)
                    myunittest = unittest.makeSuite(test)
                    a = unittest.TextTestRunner(stream=stream, verbosity=2).run(myunittest)
                    l = perpackage.setdefault(program, [0, 0, 0, 0])
                    l[0] += a.testsRun
                    l[1] += len(a.errors)
                    l[2] += len(a.failures)
                    if hasattr(a, "skipped"):
                        l[3] += len(a.skipped)
                    alltests.append(test)

    print("\n\n********* SUMMARY PER PACKAGE ****************", file=stream)
    names = sorted(perpackage.keys())
    total = [0, 0, 0, 0]
    print(" "*14, "\t".join(["Total", "Passed", "Failed", "Errors", "Skipped"]), file=stream)
    for name in names:
        l = perpackage[name]
        print(name.ljust(15), "%3d\t%3d\t%3d\t%3d\t%3d" % (l[0], l[0]-l[1]-l[2]-l[3], l[2], l[1], l[3]), file=stream)
        for i in range(4):
            total[i] += l[i]

    print("\n\n********* SUMMARY OF EVERYTHING **************", file=stream)
    print("TOTAL: %d\tPASSED: %d\tFAILED: %d\tERRORS: %d\tSKIPPED: %d" \
            %(total[0], total[0]-(total[1]+total[2]+total[3]), total[2], total[1], total[3]), file=stream)

    if errors:
        print("\n".join(errors))

    print("\n\n*** Visual tests ***", file=stream)
    visualtests(stream=stream)

    # Return to the directory we started from.
    if destdir:
        os.chdir(curdir)

    return alltests

if __name__ == "__main__":
    chosen_parsers = [p for p in parsers if p in sys.argv] or parsers
    chosen_modules = [m for m in test_modules if m in sys.argv] or test_modules
    tests = testall(chosen_parsers, chosen_modules)
<|endoftext|>


<commit_before>from geoserver.support import ResourceInfo, DimensionInfo, xml_property, write_string, bbox, metadata, \
    write_metadata, write_bbox, string_list, write_string_list, attribute_list, write_bool, url

def md_link(node):
    """Extract a metadata link tuple from an xml node"""
    mimetype = node.find("type")
    mdtype = node.find("metadataType")
    content = node.find("content")
    if None in [mimetype, mdtype, content]:
        return None
    else:
        return (mimetype.text, mdtype.text, content.text)

def metadata_link_list(node):
    if node is not None:
        return [md_link(n) for n in node.findall("metadataLink")]

def write_metadata_link_list(name):
    def write(builder, md_links):
        builder.start(name, dict())
        for (mime, md_type, content_url) in md_links:
            # geoserver supports only three mime
            if mime not in ['ISO19115:2003', 'FGDC', 'TC211']:
                mime = 'other'
            builder.start("metadataLink", dict())
            builder.start("type", dict())
            builder.data(md_type)
            builder.end("type")
            builder.start("metadataType", dict())
            builder.data(mime)
            builder.end("metadataType")
            builder.start("content", dict())
            builder.data(content_url)
            builder.end("content")
            builder.end("metadataLink")
        builder.end("metadataLinks")
    return write

def featuretype_from_index(catalog, workspace, store, node):
    name = node.find("name")
    return FeatureType(catalog, workspace, store, name.text)

def coverage_from_index(catalog, workspace, store, node):
    name = node.find("name")
    return Coverage(catalog, workspace, store, name.text)

def wmslayer_from_index(catalog, workspace, store, node):
    name = node.find("name")
    return WmsLayer(catalog, workspace, store, name.text)

class _ResourceBase(ResourceInfo):
    save_method = 'PUT'

    def __init__(self, catalog, workspace, store, name, href=None):
        super(_ResourceBase, self).__init__()

        if not href:
            assert isinstance(store, ResourceInfo)
            assert isinstance(name, basestring)
            assert workspace is not None
        else:
            parts = href.split('/')
            self._workspace_name = parts[parts.index('workspaces') + 1]
            self._store_name = parts[parts.index(self.url_part_stores) + 1]
            name = parts[-1].replace('.xml','')

        self._href = href
        self.catalog = catalog
        self._workspace = workspace
        self._store = store
        self.name = name

    @property
    def workspace(self):
        if not self._workspace:
            self._workspace = self.catalog.get_workspace(self._workspace_name)
        return self._workspace

    @property
    def store(self):
        if not self._store:
            self._store = self.catalog.get_store(self._store_name, self._workspace_name)
        return self._store

    @property
    def href(self):
        return self._href or url(self.catalog.service_url,
            ["workspaces", self.workspace.name,
             self.url_part_stores, self.store.name,
             self.url_part_types, self.name + ".xml"])

class FeatureType(_ResourceBase):

    resource_type = "featureType"
    url_part_stores = 'datastores'
    url_part_types = 'featuretypes'

    title = xml_property("title")
    abstract = xml_property("abstract")
    enabled = xml_property("enabled")
    advertised = xml_property("advertised", default="true")
    native_bbox = xml_property("nativeBoundingBox", bbox)
    latlon_bbox = xml_property("latLonBoundingBox", bbox)
    projection = xml_property("srs")
    projection_policy = xml_property("projectionPolicy")
    keywords = xml_property("keywords", string_list)
    attributes = xml_property("attributes", attribute_list)
    metadata_links = xml_property("metadataLinks", metadata_link_list)

    writers = dict(
                name = write_string("name"),
                title = write_string("title"),
                abstract = write_string("abstract"),
                enabled = write_bool("enabled"),
                advertised = write_bool("advertised"),
                nativeBoundingBox = write_bbox("nativeBoundingBox"),
                latLonBoundingBox = write_bbox("latLonBoundingBox"),
                srs = write_string("srs"),
                nativeCRS = write_string("nativeCRS"),
                projectionPolicy = write_string("projectionPolicy"),
                keywords = write_string_list("keywords"),
                metadataLinks = write_metadata_link_list("metadataLinks")
            )

class CoverageDimension(object):
    def __init__(self, name, description, dimension_range):
        self.name = name
        self.description = description
        self.dimension_range = dimension_range

def coverage_dimension(node):
    name = node.find("name")
    name = name.text if name is not None else None
    description = node.find("description")
    description = description.text if description is not None else None
    range_min = node.find("range/min")
    range_max = node.find("range/max")
    dimension_range = None
    if None not in [min, max]:
        dimension_range = float(range_min.text), float(range_max.text)
    if None not in [name, description]:
        return CoverageDimension(name, description, dimension_range)
    else:
        return None # should we bomb out more spectacularly here?

def coverage_dimension_xml(builder, dimension):
    builder.start("coverageDimension", dict())
    builder.start("name", dict())
    builder.data(dimension.name)
    builder.end("name")

    builder.start("description", dict())
    builder.data(dimension.description)
    builder.end("description")

    if dimension.range is not None:
        builder.start("range", dict())
        builder.start("min", dict())
        builder.data(str(dimension.range[0]))
        builder.end("min")
        builder.start("max", dict())
        builder.data(str(dimension.range[1]))
        builder.end("max")
        builder.end("range")

    builder.end("coverageDimension")

class Coverage(_ResourceBase):

    resource_type = "coverage"
    url_part_stores = 'coveragestores'
    url_part_types = 'coverages'

    title = xml_property("title")
    abstract = xml_property("abstract")
    enabled = xml_property("enabled")
    advertised = xml_property("advertised", default="true")
    native_bbox = xml_property("nativeBoundingBox", bbox)
    latlon_bbox = xml_property("latLonBoundingBox", bbox)
    projection = xml_property("srs")
    projection_policy = xml_property("projectionPolicy")
    keywords = xml_property("keywords", string_list)
    request_srs_list = xml_property("requestSRS", string_list)
    response_srs_list = xml_property("responseSRS", string_list)
    supported_formats = xml_property("supportedFormats", string_list)
    metadata_links = xml_property("metadataLinks", metadata_link_list)
    metadata = xml_property("metadata", metadata)

    writers = dict(
                title = write_string("title"),
                abstract = write_string("abstract"),
                enabled = write_bool("enabled"),
                advertised = write_bool("advertised"),
                nativeBoundingBox = write_bbox("nativeBoundingBox"),
                latLonBoundingBox = write_bbox("latLonBoundingBox"),
                srs = write_string("srs"),
                projection_policy = write_string("projectionPolicy"),
                keywords = write_string_list("keywords"),
                metadataLinks = write_metadata_link_list("metadataLinks"),
                requestSRS = write_string_list("requestSRS"),
                responseSRS = write_string_list("responseSRS"),
                supportedFormats = write_string_list("supportedFormats"),
                metadata = write_metadata("metadata")
            )

class WmsLayer(ResourceInfo):
    resource_type = "wmsLayer"
    save_method = "PUT"

    def __init__(self, catalog, workspace, store, name):
        super(WmsLayer, self).__init__()
        self.catalog = catalog
        self.workspace = workspace
        self.store = store
        self.name = name

    @property
    def href(self):
        return "%s/workspaces/%s/wmsstores/%s/wmslayers/%s.xml" % (
                self.catalog.service_url,
                self.workspace.name,
                self.store.name,
                self.name
                )

    title = xml_property("title")
    description = xml_property("description")
    abstract = xml_property("abstract")
    keywords = xml_property("keywords", string_list)
    # nativeCRS
    projection = xml_property("srs")
    native_bbox = xml_property("nativeBoundingBox", bbox)
    latlon_bbox = xml_property("latLonBoundingBox", bbox)
    projection_policy = xml_property("projectionPolicy")
    enabled = xml_property("enabled")
    metadata_links = xml_property("metadataLinks", metadata_link_list)

    writers = dict(
                title = write_string("title"),
                description = write_string("description"),
                abstract = write_string("abstract"),
                keywords = write_string_list("keywords"),
                # nativeCRS
                projection = write_string("srs"),
                nativeBoundingBox = write_bbox("nativeBoundingBox"),
                latLonBoundingBox = write_bbox("latLonBoundingBox"),
                projection_policy = write_string("projectionPolicy"),
                enabled = write_bool("enabled"),
                metadataLinks = write_metadata_link_list("metadataLinks")
           )
<commit_msg>fix metadata related test failures, see #53<commit_after>from geoserver.support import ResourceInfo, DimensionInfo, xml_property, write_string, bbox, metadata, \
    write_metadata, write_bbox, string_list, write_string_list, attribute_list, write_bool, url

def md_link(node):
    """Extract a metadata link tuple from an xml node"""
    mimetype = node.find("type")
    mdtype = node.find("metadataType")
    content = node.find("content")
    if None in [mimetype, mdtype, content]:
        return None
    else:
        return (mimetype.text, mdtype.text, content.text)

def metadata_link_list(node):
    if node is not None:
        return [md_link(n) for n in node.findall("metadataLink")]

def write_metadata_link_list(name):
    def write(builder, md_links):
        builder.start(name, dict())
        for (mime, md_type, content_url) in md_links:
            # geoserver supports only three mime
            if md_type not in ['ISO19115:2003', 'FGDC', 'TC211']:
                mime = 'other'
            builder.start("metadataLink", dict())
            builder.start("type", dict())
            builder.data(mime)
            builder.end("type")
            builder.start("metadataType", dict())
            builder.data(md_type)
            builder.end("metadataType")
            builder.start("content", dict())
            builder.data(content_url)
            builder.end("content")
            builder.end("metadataLink")
        builder.end("metadataLinks")
    return write

def featuretype_from_index(catalog, workspace, store, node):
    name = node.find("name")
    return FeatureType(catalog, workspace, store, name.text)

def coverage_from_index(catalog, workspace, store, node):
    name = node.find("name")
    return Coverage(catalog, workspace, store, name.text)

def wmslayer_from_index(catalog, workspace, store, node):
    name = node.find("name")
    return WmsLayer(catalog, workspace, store, name.text)

class _ResourceBase(ResourceInfo):
    save_method = 'PUT'

    def __init__(self, catalog, workspace, store, name, href=None):
        super(_ResourceBase, self).__init__()

        if not href:
            assert isinstance(store, ResourceInfo)
            assert isinstance(name, basestring)
            assert workspace is not None
        else:
            parts = href.split('/')
            self._workspace_name = parts[parts.index('workspaces') + 1]
            self._store_name = parts[parts.index(self.url_part_stores) + 1]
            name = parts[-1].replace('.xml','')

        self._href = href
        self.catalog = catalog
        self._workspace = workspace
        self._store = store
        self.name = name

    @property
    def workspace(self):
        if not self._workspace:
            self._workspace = self.catalog.get_workspace(self._workspace_name)
        return self._workspace

    @property
    def store(self):
        if not self._store:
            self._store = self.catalog.get_store(self._store_name, self._workspace_name)
        return self._store

    @property
    def href(self):
        return self._href or url(self.catalog.service_url,
            ["workspaces", self.workspace.name,
             self.url_part_stores, self.store.name,
             self.url_part_types, self.name + ".xml"])

class FeatureType(_ResourceBase):

    resource_type = "featureType"
    url_part_stores = 'datastores'
    url_part_types = 'featuretypes'

    title = xml_property("title")
    abstract = xml_property("abstract")
    enabled = xml_property("enabled")
    advertised = xml_property("advertised", default="true")
    native_bbox = xml_property("nativeBoundingBox", bbox)
    latlon_bbox = xml_property("latLonBoundingBox", bbox)
    projection = xml_property("srs")
    projection_policy = xml_property("projectionPolicy")
    keywords = xml_property("keywords", string_list)
    attributes = xml_property("attributes", attribute_list)
    metadata_links = xml_property("metadataLinks", metadata_link_list)

    writers = dict(
                name = write_string("name"),
                title = write_string("title"),
                abstract = write_string("abstract"),
                enabled = write_bool("enabled"),
                advertised = write_bool("advertised"),
                nativeBoundingBox = write_bbox("nativeBoundingBox"),
                latLonBoundingBox = write_bbox("latLonBoundingBox"),
                srs = write_string("srs"),
                nativeCRS = write_string("nativeCRS"),
                projectionPolicy = write_string("projectionPolicy"),
                keywords = write_string_list("keywords"),
                metadataLinks = write_metadata_link_list("metadataLinks")
            )

class CoverageDimension(object):
    def __init__(self, name, description, dimension_range):
        self.name = name
        self.description = description
        self.dimension_range = dimension_range

def coverage_dimension(node):
    name = node.find("name")
    name = name.text if name is not None else None
    description = node.find("description")
    description = description.text if description is not None else None
    range_min = node.find("range/min")
    range_max = node.find("range/max")
    dimension_range = None
    if None not in [min, max]:
        dimension_range = float(range_min.text), float(range_max.text)
    if None not in [name, description]:
        return CoverageDimension(name, description, dimension_range)
    else:
        return None # should we bomb out more spectacularly here?

def coverage_dimension_xml(builder, dimension):
    builder.start("coverageDimension", dict())
    builder.start("name", dict())
    builder.data(dimension.name)
    builder.end("name")

    builder.start("description", dict())
    builder.data(dimension.description)
    builder.end("description")

    if dimension.range is not None:
        builder.start("range", dict())
        builder.start("min", dict())
        builder.data(str(dimension.range[0]))
        builder.end("min")
        builder.start("max", dict())
        builder.data(str(dimension.range[1]))
        builder.end("max")
        builder.end("range")

    builder.end("coverageDimension")

class Coverage(_ResourceBase):

    resource_type = "coverage"
    url_part_stores = 'coveragestores'
    url_part_types = 'coverages'

    title = xml_property("title")
    abstract = xml_property("abstract")
    enabled = xml_property("enabled")
    advertised = xml_property("advertised", default="true")
    native_bbox = xml_property("nativeBoundingBox", bbox)
    latlon_bbox = xml_property("latLonBoundingBox", bbox)
    projection = xml_property("srs")
    projection_policy = xml_property("projectionPolicy")
    keywords = xml_property("keywords", string_list)
    request_srs_list = xml_property("requestSRS", string_list)
    response_srs_list = xml_property("responseSRS", string_list)
    supported_formats = xml_property("supportedFormats", string_list)
    metadata_links = xml_property("metadataLinks", metadata_link_list)
    metadata = xml_property("metadata", metadata)

    writers = dict(
                title = write_string("title"),
                abstract = write_string("abstract"),
                enabled = write_bool("enabled"),
                advertised = write_bool("advertised"),
                nativeBoundingBox = write_bbox("nativeBoundingBox"),
                latLonBoundingBox = write_bbox("latLonBoundingBox"),
                srs = write_string("srs"),
                projection_policy = write_string("projectionPolicy"),
                keywords = write_string_list("keywords"),
                metadataLinks = write_metadata_link_list("metadataLinks"),
                requestSRS = write_string_list("requestSRS"),
                responseSRS = write_string_list("responseSRS"),
                supportedFormats = write_string_list("supportedFormats"),
                metadata = write_metadata("metadata")
            )

class WmsLayer(ResourceInfo):
    resource_type = "wmsLayer"
    save_method = "PUT"

    def __init__(self, catalog, workspace, store, name):
        super(WmsLayer, self).__init__()
        self.catalog = catalog
        self.workspace = workspace
        self.store = store
        self.name = name

    @property
    def href(self):
        return "%s/workspaces/%s/wmsstores/%s/wmslayers/%s.xml" % (
                self.catalog.service_url,
                self.workspace.name,
                self.store.name,
                self.name
                )

    title = xml_property("title")
    description = xml_property("description")
    abstract = xml_property("abstract")
    keywords = xml_property("keywords", string_list)
    # nativeCRS
    projection = xml_property("srs")
    native_bbox = xml_property("nativeBoundingBox", bbox)
    latlon_bbox = xml_property("latLonBoundingBox", bbox)
    projection_policy = xml_property("projectionPolicy")
    enabled = xml_property("enabled")
    metadata_links = xml_property("metadataLinks", metadata_link_list)

    writers = dict(
                title = write_string("title"),
                description = write_string("description"),
                abstract = write_string("abstract"),
                keywords = write_string_list("keywords"),
                # nativeCRS
                projection = write_string("srs"),
                nativeBoundingBox = write_bbox("nativeBoundingBox"),
                latLonBoundingBox = write_bbox("latLonBoundingBox"),
                projection_policy = write_string("projectionPolicy"),
                enabled = write_bool("enabled"),
                metadataLinks = write_metadata_link_list("metadataLinks")
           )
<|endoftext|>