class TestWebProfile(BaseTestStandardProfile):

    def setup_method(self, method):

        self.dialog = AlwaysApproveWebProfileDialog()
        t = threading.Thread(target=self.dialog.poll)
        t.start()

        self.tmpdir = tempfile.mkdtemp()
        lockfile = os.path.join(self.tmpdir, '.samp')

        self.hub = SAMPHubServer(web_profile_dialog=self.dialog,
                                 lockfile=lockfile,
                                 web_port=0, pool_size=1)
        self.hub.start()

        self.client1 = SAMPIntegratedClient()
        self.client1.connect(hub=self.hub, pool_size=1)
        self.client1_id = self.client1.get_public_id()
        self.client1_key = self.client1.get_private_key()

        self.client2 = SAMPIntegratedWebClient()
        self.client2.connect(web_port=self.hub._web_port, pool_size=2)
        self.client2_id = self.client2.get_public_id()
        self.client2_key = self.client2.get_private_key()

    def teardown_method(self, method):

        if self.client1.is_connected:
            self.client1.disconnect()
        if self.client2.is_connected:
            self.client2.disconnect()

        self.hub.stop()
        self.dialog.stop()

    # The full communication tests are run since TestWebProfile inherits
    # test_main from TestStandardProfile

    def test_web_profile(self):

        # Check some additional queries to the server

        with get_readable_fileobj('http://localhost:{0}/crossdomain.xml'.format(self.hub._web_port)) as f:
            assert f.read() == CROSS_DOMAIN

        with get_readable_fileobj('http://localhost:{0}/clientaccesspolicy.xml'.format(self.hub._web_port)) as f:
            assert f.read() == CLIENT_ACCESS_POLICY

        # Check headers

        req = Request('http://localhost:{0}/crossdomain.xml'.format(self.hub._web_port))
        req.add_header('Origin', 'test_web_profile')
        resp = urlopen(req)

        assert resp.getheader('Access-Control-Allow-Origin') == 'test_web_profile'
        assert resp.getheader('Access-Control-Allow-Headers') == 'Content-Type'
        assert resp.getheader('Access-Control-Allow-Credentials') == 'true'
Example #2
0
class HubMaster():
    def __init__(self,WPD):
        self.WPD = WPD
        self.isOpen=False
    def work(self):
        def runSampHub():
            self.h = SAMPHubServer(web_profile_dialog=self.WPD)
            self.isOpen=True
            self.h.start()
            say('samp hub started')
            while self.isOpen: 
#                say('samp hub running')
                time.sleep(1)
            self.h.stop()
            say('samp hub stopped')
        t=threading.Thread(target=runSampHub)
        t.daemon=True
        t.start()
Example #3
0
class SAMPManager():

    __client = None
    __received = False
    __params = {}
    __hub = None
    __server_name = "frastro server"
    __server_description = "frastro Web client"
    __server_description_html = "<h1>frastro Web client</h1>"
    __author = "Camilo E. Jimenez-Angel"
    __instritution = "IAC"
    __email_contact = "*****@*****.**"
    __url_icon = "http://localhost:8000/static/img/frastro_icon.jpg"

    def __init__(self, server_name=""):
        # Instantiate the client and connect to the hub
        self.__server_name = server_name if server_name != "" else self.__server_name
        self.connect()

    def starHubServer(self, web_profile=True):
        if self.__hub is None:
            self.__hub = SAMPHubServer(web_profile=web_profile,
                                       label=self.__server_name)
        self.__hub.start()

    def receive_call(self, private_key, sender_id, msg_id, mtype, params,
                     extra):
        self.__params = params
        self.__received = True
        self.__client.reply(msg_id, {
            "samp.status": "samp.ok",
            "samp.result": {}
        })

    def receive_notification(self, private_key, sender_id, mtype, params,
                             extra):
        self.__params = params
        self.__received = True

    def bind_to_server(self):
        # Listen for any instructions to load a table
        self.__client.bind_receive_call("table.load.votable",
                                        self.receive_call)
        self.__client.bind_receive_notification("table.load.votable",
                                                self.receive_notification)

    def sampMetadata(self):
        meta = {
            "samp.name": self.__server_name,
            "samp.description.text": self.__server_description,
            "samp.description.html": self.__server_description_html,
            "samp.icon.url": self.__url_icon,
            "author.affiliation": self.__instritution,
            "author.name": self.__author,
            "author.email": self.__email_contact
        }
        return meta

    def getRegisteredClients(self):
        clients = self.__client.get_registered_clients()
        run_clients = {}
        for client in clients:
            client_data = self.getMetadata(client)
            run_clients[client] = client_data
        return run_clients

    def getMetadata(self, client_id):
        return self.__client.get_metadata(client_id)

    def sendTable(self, message, recipient="all"):
        if recipient == "all":
            self.__client.notify_all(message)
        else:
            self.__client.notify(recipient, message)

    def connect(self):
        self.__client = SAMPIntegratedClient(name=self.__server_name,
                                             metadata=self.sampMetadata())
        self.__client.connect()
        self.bind_to_server()

    def sendImage(self, params, id=""):
        message = {}
        message["samp.mtype"] = "image.load.fits"
        message["samp.params"] = params
        if id == "" or id == "all":
            self.__client.notify_all(message)
        else:
            self.__client.notify(recipient_id=id, message=message)

    def sendMessage(self, params, id=""):
        message = {}
        message["samp.mtype"] = "table.load.votable"
        message["samp.params"] = params
        if id == "" or id == "all":
            self.__client.notify_all(message)
        else:
            self.__client.notify(recipient_id=id, message=message)

    def disconnect(self):
        self.__client.disconnect()

    def __del__(self):
        self.disconnect()
Example #4
0
class SAMPState(State):

    status = CallbackProperty('Not connected to SAMP Hub')
    connected = CallbackProperty(False)
    clients = CallbackProperty([])
    highlight_is_selection = CallbackProperty(False)

    def __init__(self):
        super(SAMPState, self).__init__()
        self.hub = SAMPHubServer()
        self.client = SAMPIntegratedClient()
        self.add_callback('connected', self.on_connected)

    def start_samp(self):
        if not self.client.is_connected:
            try:
                self.client.connect()
            except SAMPHubError:
                try:
                    self.hub.start()
                    self.client.connect()
                except Exception:
                    self.connected = False
                    self.status = 'Could not connect to Hub'
                else:
                    self.connected = True
                    self.status = 'Connected to (glue) SAMP Hub'
            except:
                self.connected = False
                self.status = 'Could not connect to Hub'
            else:
                self.connected = True
                self.status = 'Connected to SAMP Hub'

    def stop_samp(self):
        if self.client.is_connected:
            self.client.disconnect()
        if self.hub.is_running:
            self.hub.stop()
        self.connected = False
        self.status = 'Not connected to SAMP Hub'

    def on_connected(self, *args):
        if self.connected:
            metadata = {
                'author.email': '*****@*****.**',
                'author.name': 'Thomas Robitaille',
                'home.page': 'http://www.glueviz.org',
                'samp.description.text':
                'Multi-dimensional linked data exploration',
                'samp.documentation.url': 'http://www.glueviz.org',
                'samp.icon.url': 'file://' + ICON_PATH,
                'samp.name': 'glueviz',
                'glue.version': glue_version
            }
            self.client.declare_metadata(metadata)
            self.on_client_change()

    def on_client_change(self):
        clients = []
        for client in self.client.get_registered_clients():
            metadata = self.client.get_metadata(client)
            clients.append((client, metadata.get('samp.name', client)))
        self.clients = clients

    def send_data(self, layer=None, client=None):

        filename = tempfile.mktemp()

        message = {}
        message["samp.params"] = {}

        if isinstance(layer, Data):

            if layer.ndim == 1:
                table = data_to_astropy_table(layer)
                table.write(filename, format='votable')
                message["samp.mtype"] = "table.load.votable"
                if 'samp-table-id' not in layer.meta:
                    layer.meta['samp-table-id'] = layer.label
                message["samp.params"]['table-id'] = layer.meta[
                    'samp-table-id']
            elif layer.ndim == 2:
                fits_writer(filename, layer)
                message["samp.mtype"] = "image.load.fits"
                if 'samp-image-id' not in layer.meta:
                    layer.meta['samp-image-id'] = layer.label
                message["samp.params"]['image-id'] = layer.meta[
                    'samp-image-id']
            else:
                return

            message["samp.params"]['name'] = layer.label
            message["samp.params"]['url'] = 'file://' + os.path.abspath(
                filename)

        else:

            message['samp.mtype'] = 'table.select.rowList'

            if layer.ndim == 1:
                message["samp.params"]['table-id'] = layer.data.meta[
                    'samp-table-id']
                message["samp.params"]['row-list'] = np.nonzero(
                    layer.to_mask())[0].astype(str).tolist()
            else:
                return

        if client is None:
            self.client.notify_all(message)
        else:
            # Make sure client is subscribed otherwise an exception is raised
            subscriptions = self.client.get_subscriptions(client)
            for mtype in subscriptions:
                if fnmatch(message['samp.mtype'], mtype):
                    self.client.notify(client, message)
                    return
            else:
                return