Module ivao.server

Expand source code
import random
import threading
import time

from .parser import Parser


class Server:

    def __init__(self):
        self.handlers = {}
        self.clients = {}
        self.controllers = {}
        self.pilots = {}
        self.folme = {}
        self.update_stream = threading.currentThread()

    def call(self, name, *args):
        """
        Call a registed event by the name with arguments
        :param name: Event Name
        :param args: Argument to pass
        """
        if name in self.handlers:
            for h in self.handlers[name]:
                h(*args)

    def event(self, name):
        """
        Registering events by name
        :param name: Name of the event
        :return: event handler
        """

        def registerhandler(handler):
            if name in self.handlers:
                self.handlers[name].append(handler)
            else:
                self.handlers[name] = [handler]
            return handler

        return registerhandler

    def update_data(self, data=None):
        """
        Updating function that calls event triggers
        :param data: New data to compare
        """
        if not data:
            parser = Parser()
            data = parser.get_clients_object()
        first_run = True if len(self.clients) == 0 else False
        for client in data['atc']:
            if client.vid in self.controllers:  # If client was connected at previous update
                if self.controllers[client.vid].atis_time != client.atis_time:
                    self.call("atis_update", client)
            else:  # Client connected since last update
                self.call("connect", client, first_run)
            self.controllers[client.vid] = client
            self.clients[client.vid] = client
        for client in data['pilot']:
            if client.vid in self.pilots:  # If client was connected at previous update
                if self.pilots[client.vid].ground != client.ground:
                    if client.ground:
                        self.call("land", client)
                    else:
                        self.call("takeoff", client)
                if self.pilots[client.vid].latitude == client.latitude \
                        and self.pilots[client.vid].longitude == client.longitude \
                        and self.pilots[client.vid].altitude == client.altitude:
                    self.call("static", client)
                else:
                    if self.pilots[client.vid].altitude != client.altitude:
                        if self.pilots[client.vid].altitude > client.altitude + 1000:
                            self.call("descent", client)
                        elif self.pilots[client.vid].altitude < client.altitude - 1000:
                            self.call("climb", client)
                        else:
                            self.call("cruise", client)
                    self.call("moving", client)
            else:  # Client connected since last update
                self.call("connect", client, first_run)
            self.pilots[client.vid] = client
            self.clients[client.vid] = client
        for client in data['folme']:
            if client.vid in self.folme:  # If client was connected at previous update
                pass
            else:  # Client connected since last update
                self.call("connect", client, first_run)
            self.folme[client.vid] = client
            self.clients[client.vid] = client
        disconnects = []
        for vid in self.clients:
            still_connected = False
            for client in data['atc']:
                if client.vid == vid:
                    still_connected = True
                    break
            for client in data['pilot']:
                if client.vid == vid:
                    still_connected = True
                    break
            for client in data['folme']:
                if client.vid == vid:
                    still_connected = True
                    break
            if not still_connected:
                self.call("disconnect", self.clients[vid])
                if vid in self.pilots:
                    del self.pilots[vid]
                elif vid in self.controllers:
                    del self.controllers[vid]
                elif vid in self.folme:
                    del self.folme[vid]
                disconnects.append(vid)
        for vid in disconnects:
            del self.clients[vid]

        self.call('update', self.clients)

    def stop_update_stream(self):
        """
        Request updates stop, because it's running in a separate thread
        """
        self.update_stream.do_run = False

    def run_update_stream(self, delay=None):
        """
        Start updates runner
        :param delay: Delay, in minutes,
        """
        while getattr(self.update_stream, "do_run", True):
            self.update_data()
            if delay:
                time.sleep(delay * 60)
            else:
                time.sleep(random.randint(3, 5) * 60)

Classes

class Server
Expand source code
class Server:

    def __init__(self):
        self.handlers = {}
        self.clients = {}
        self.controllers = {}
        self.pilots = {}
        self.folme = {}
        self.update_stream = threading.currentThread()

    def call(self, name, *args):
        """
        Call a registed event by the name with arguments
        :param name: Event Name
        :param args: Argument to pass
        """
        if name in self.handlers:
            for h in self.handlers[name]:
                h(*args)

    def event(self, name):
        """
        Registering events by name
        :param name: Name of the event
        :return: event handler
        """

        def registerhandler(handler):
            if name in self.handlers:
                self.handlers[name].append(handler)
            else:
                self.handlers[name] = [handler]
            return handler

        return registerhandler

    def update_data(self, data=None):
        """
        Updating function that calls event triggers
        :param data: New data to compare
        """
        if not data:
            parser = Parser()
            data = parser.get_clients_object()
        first_run = True if len(self.clients) == 0 else False
        for client in data['atc']:
            if client.vid in self.controllers:  # If client was connected at previous update
                if self.controllers[client.vid].atis_time != client.atis_time:
                    self.call("atis_update", client)
            else:  # Client connected since last update
                self.call("connect", client, first_run)
            self.controllers[client.vid] = client
            self.clients[client.vid] = client
        for client in data['pilot']:
            if client.vid in self.pilots:  # If client was connected at previous update
                if self.pilots[client.vid].ground != client.ground:
                    if client.ground:
                        self.call("land", client)
                    else:
                        self.call("takeoff", client)
                if self.pilots[client.vid].latitude == client.latitude \
                        and self.pilots[client.vid].longitude == client.longitude \
                        and self.pilots[client.vid].altitude == client.altitude:
                    self.call("static", client)
                else:
                    if self.pilots[client.vid].altitude != client.altitude:
                        if self.pilots[client.vid].altitude > client.altitude + 1000:
                            self.call("descent", client)
                        elif self.pilots[client.vid].altitude < client.altitude - 1000:
                            self.call("climb", client)
                        else:
                            self.call("cruise", client)
                    self.call("moving", client)
            else:  # Client connected since last update
                self.call("connect", client, first_run)
            self.pilots[client.vid] = client
            self.clients[client.vid] = client
        for client in data['folme']:
            if client.vid in self.folme:  # If client was connected at previous update
                pass
            else:  # Client connected since last update
                self.call("connect", client, first_run)
            self.folme[client.vid] = client
            self.clients[client.vid] = client
        disconnects = []
        for vid in self.clients:
            still_connected = False
            for client in data['atc']:
                if client.vid == vid:
                    still_connected = True
                    break
            for client in data['pilot']:
                if client.vid == vid:
                    still_connected = True
                    break
            for client in data['folme']:
                if client.vid == vid:
                    still_connected = True
                    break
            if not still_connected:
                self.call("disconnect", self.clients[vid])
                if vid in self.pilots:
                    del self.pilots[vid]
                elif vid in self.controllers:
                    del self.controllers[vid]
                elif vid in self.folme:
                    del self.folme[vid]
                disconnects.append(vid)
        for vid in disconnects:
            del self.clients[vid]

        self.call('update', self.clients)

    def stop_update_stream(self):
        """
        Request updates stop, because it's running in a separate thread
        """
        self.update_stream.do_run = False

    def run_update_stream(self, delay=None):
        """
        Start updates runner
        :param delay: Delay, in minutes,
        """
        while getattr(self.update_stream, "do_run", True):
            self.update_data()
            if delay:
                time.sleep(delay * 60)
            else:
                time.sleep(random.randint(3, 5) * 60)

Methods

def call(self, name, *args)

Call a registed event by the name with arguments :param name: Event Name :param args: Argument to pass

Expand source code
def call(self, name, *args):
    """
    Call a registed event by the name with arguments
    :param name: Event Name
    :param args: Argument to pass
    """
    if name in self.handlers:
        for h in self.handlers[name]:
            h(*args)
def event(self, name)

Registering events by name :param name: Name of the event :return: event handler

Expand source code
def event(self, name):
    """
    Registering events by name
    :param name: Name of the event
    :return: event handler
    """

    def registerhandler(handler):
        if name in self.handlers:
            self.handlers[name].append(handler)
        else:
            self.handlers[name] = [handler]
        return handler

    return registerhandler
def run_update_stream(self, delay=None)

Start updates runner :param delay: Delay, in minutes,

Expand source code
def run_update_stream(self, delay=None):
    """
    Start updates runner
    :param delay: Delay, in minutes,
    """
    while getattr(self.update_stream, "do_run", True):
        self.update_data()
        if delay:
            time.sleep(delay * 60)
        else:
            time.sleep(random.randint(3, 5) * 60)
def stop_update_stream(self)

Request updates stop, because it's running in a separate thread

Expand source code
def stop_update_stream(self):
    """
    Request updates stop, because it's running in a separate thread
    """
    self.update_stream.do_run = False
def update_data(self, data=None)

Updating function that calls event triggers :param data: New data to compare

Expand source code
def update_data(self, data=None):
    """
    Updating function that calls event triggers
    :param data: New data to compare
    """
    if not data:
        parser = Parser()
        data = parser.get_clients_object()
    first_run = True if len(self.clients) == 0 else False
    for client in data['atc']:
        if client.vid in self.controllers:  # If client was connected at previous update
            if self.controllers[client.vid].atis_time != client.atis_time:
                self.call("atis_update", client)
        else:  # Client connected since last update
            self.call("connect", client, first_run)
        self.controllers[client.vid] = client
        self.clients[client.vid] = client
    for client in data['pilot']:
        if client.vid in self.pilots:  # If client was connected at previous update
            if self.pilots[client.vid].ground != client.ground:
                if client.ground:
                    self.call("land", client)
                else:
                    self.call("takeoff", client)
            if self.pilots[client.vid].latitude == client.latitude \
                    and self.pilots[client.vid].longitude == client.longitude \
                    and self.pilots[client.vid].altitude == client.altitude:
                self.call("static", client)
            else:
                if self.pilots[client.vid].altitude != client.altitude:
                    if self.pilots[client.vid].altitude > client.altitude + 1000:
                        self.call("descent", client)
                    elif self.pilots[client.vid].altitude < client.altitude - 1000:
                        self.call("climb", client)
                    else:
                        self.call("cruise", client)
                self.call("moving", client)
        else:  # Client connected since last update
            self.call("connect", client, first_run)
        self.pilots[client.vid] = client
        self.clients[client.vid] = client
    for client in data['folme']:
        if client.vid in self.folme:  # If client was connected at previous update
            pass
        else:  # Client connected since last update
            self.call("connect", client, first_run)
        self.folme[client.vid] = client
        self.clients[client.vid] = client
    disconnects = []
    for vid in self.clients:
        still_connected = False
        for client in data['atc']:
            if client.vid == vid:
                still_connected = True
                break
        for client in data['pilot']:
            if client.vid == vid:
                still_connected = True
                break
        for client in data['folme']:
            if client.vid == vid:
                still_connected = True
                break
        if not still_connected:
            self.call("disconnect", self.clients[vid])
            if vid in self.pilots:
                del self.pilots[vid]
            elif vid in self.controllers:
                del self.controllers[vid]
            elif vid in self.folme:
                del self.folme[vid]
            disconnects.append(vid)
    for vid in disconnects:
        del self.clients[vid]

    self.call('update', self.clients)