<commit_before># -*- coding: utf-8 -*-
"""
Created on Fri Dec 28 13:12:58 2012

@author: Preston
"""
import Player
import Pile
import socket
import threading
import pickle
import sys
import time
import random
import Queue
from OptionsParser import config_parser
from Card import Card

class Server(object):
    def __init__(self, rule_handler, player_handler, port = None,
                 ip_address = None):
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.bind((ip_address or socket.getfqdn(), int(port)))
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.listen(5)
        self.clients = {}
        self._server_running = threading.Event()
        threading.Thread(name = 'Connection Thread',
                         target = (self.get_connections),
                         args = (self.server,)).start()
        self.player_handler = player_handler
        self.rule_handler = rule_handler
        self.deck = Pile.Pile()
        self.pile = Pile.Pile()
        self.update_deck()
        self._main_event = threading.Event()

    def is_running(self):
        "Returns True if the server is running, or False if it is not"
        return not self._server_running.is_set()

    def get_connections(self, server):
        "Constantly get connections and adds them to clients"
        while self.is_running():
            try:
                server.settimeout(None)
                client, address = server.accept()
                if address in self.clients:
                    client.send('Same ip as other user! Connection aborted')
                    client.close()
                    continue
                client.send('Connection Established')
                print 'Connection Established with {}'.format(
                ':'.join((address[0], str(address[1]))))

                if client not in self.clients and (
                config_parser.getint('Players', 'max_players')
                or sys.maxint) > len(self.clients):
                    player = self.authorise_player(client)
                    self.clients.update({client: player})
                    self.player_handler.add_player(player)
                    Server.send(player, client)
                    self.receive(client) #Pile request
                    Server.send(self.pile.cards, client)
                    if not self.player_handler.current_player:
                        self.player_handler.next_player()
                    threading.Thread(name = 'Listening to {0} at {1}'.format(
                        player.name, address), target = self.listen,
                        args = (client, player)).start()
                else:
                    Server.send('', client)
                    client.close()
            except (socket.timeout, socket.error):
                try:
                    client.close()
                    if client in self.clients:
                        self.clients.pop(client)
                except (socket.error, UnboundLocalError):
                    pass

    def authorise_player(self, client):
        """Generates and then authorises the player with the information
        provided by the client (It has to send the name). It then returns
        the player if it succeeds, or raises socket.error"""
        player_name = self.receive(client)[0]
        if any(player.name == player_name for player in (
        self.player_handler.players)):
            print '{} is already taken!'.format(player_name)
            raise socket.error
        print player_name + ' Joined!'
        self.send_all('[{} Joined!]'.format(player_name))
        self.update_deck()
        return Player.Player(player_name, hand = self.deck.remove(0,
                               config_parser.getint('Cards', 'hand_size')))

    @staticmethod
    def send(data, client):
        "Send some data (pickled) to the client"
        pickled = pickle.dumps(data) +  ';'
        client.send(str(len(pickled)) + ':')

        total = 0
        while total < len(pickled):
            sent = client.send(pickled[total:])
            if sent == 0:
                raise socket.error("Connection Broken")
            else:
                total += sent

    def send_all(self, data):
        for client in self.clients:
            Server.send(data, client)

    def receive(self, client, timeout = 10):
        """Get a response from the server and de-pickles it. If the actual
        message takes too long (longer than 10 seconds or timeout if given)
        then socket.error is raised"""
        def get_message(client, timeout, message = None):
            if not message:
                received = client.recv(2048).split(':', 1)
            else:
                received = message.split(':', 1)
            length = received[0]
            if not length:
                raise socket.error
            data = received[1]
            client.settimeout(timeout)
            while len(data) < int(length):
                message = client.recv(2048)
                if not message:
                    raise socket.error
                data += message
            client.settimeout(None)
            first, second = data.rsplit(';', 1)
            first = pickle.loads(first)
            if first == '':
                raise socket.error('The Client closed the connection!')
            data = []
            data.append(first)
            if second:
                print "Message was too long!"
                data.extend(get_message(client, timeout = 10,
                                         message = second))
            return data
        return get_message(client, timeout)

    def constantly_receive(self, client, queue):
        """Constantly receives messages from the client and passes it into
        the given queue to be handled by the server"""
        while self.is_running() and client in self.clients:
            try:
                data = self.receive(client, timeout = 1)
                for item in data:
                    queue.put(item)
            except socket.timeout:
                continue
            except socket.error:
                if client in self.clients:
                    self.disconnect(client)
                break

    def disconnect(self, client):
        player = self.clients.pop(client)
        try:
            Server.send('', client)
        except (socket.error, socket.timeout):
            pass
        finally:
            client.close()
            self.deck.add(player.hand)
            self.deck.shuffle()
            if player is self.player_handler.current_player:
                self._main_event.set() #Stop the thread
            self.player_handler.remove_player(player)
            self.send_all('{} disconnected'.format(player.name))
            self.send_all(self.player_handler.players)
            #Just added this, hope it works aight
            print '{} disconnected'.format(player.name)

    def shutdown(self):
        "Turns off the server, closing all the connections in clients"
        self._server_running.set()
        clients = []
        clients.extend(self.clients.iterkeys())
        for client in clients:
            self.disconnect(client)
        self.server.shutdown(socket.SHUT_RDWR)
        self.server.close()

    def get_client(self, player):
        """Returns the client connected to the player instance"""
        reversed_map = {player: client for client, player in (
        self.clients.iteritems())}
        return reversed_map.get(player)

    def punish(self, player, penalty_num = config_parser.getint(
               'Punishment','penalty_num'), reason = None, cards = None):
        """The player is punished by being given penalty_num of cards.
        Raises a KeyError if the player is not in the list of players.
        If cards is given, then it appends that to the cards so that they are
        sent as one batch"""
        if cards is None:
            cards = ()
        if reason is None:
            reason = random.choice(config_parser.get(
                    'Punishment', 'default_phrases').split(';')).format(
                    name = player.name, random_card = (
                    random.choice(player.hand).rank + ' of ' + (
                    random.choice(player.hand).suit)))
        self.send_all('Penalty card for {} '.format(player.name) + reason)
        if player in self.player_handler.players:
            self.update_deck()
            cards = self.deck.remove(0, penalty_num) + cards
            Server.send(cards, self.get_client(player))
            for card in cards:
                player.add_card(card)
        else:
            raise KeyError, player.name + ' is not in players!'

    def constantly_punish(self, player, penalty_num, punish_timer, event):
        """Constantly punishes the player the number of cards in penalty_num
        until the event is set. If no event is given, uses the main_event
        (the one that is set when the current player finally plays a card)"""
        while (not event.wait(punish_timer) and
        player in self.player_handler.players):
            self.punish(player, penalty_num)
        event.clear()

    def update_deck(self):
        "Checks if the deck is getting low (<= 26), and adds card if it is"
        if len(self.deck.cards) <= 26:
            suits = []
            suits = "Spades Hearts Diamonds Clubs".split()
            ranks = "Ace 2 3 4 5 6 7 8 9 10 King Queen".split()
            new_deck = (Pile.Pile([Card(suit, rank) for rank in \
            ranks for suit in suits]))
            self.deck.add(new_deck.cards)
            self.deck.shuffle()
            self.deck.update_top_card()

    def main_loop(self, timer = config_parser.getint('Punishment', 'timer'),
                  penalty_num = config_parser.getint('Punishment',
                  'penalty_num')):
        """Main loop that should be called after initalisation. timer is the
        amount of time a player has to play before he is punished for taking
        too long and penalty num is the amount he is punished by"""
        while self.is_running():
            if self.player_handler.current_player:
                print 'Current Player: {}'.format(
                    self.player_handler.get_current_player())
                if self.constantly_punish(self.player_handler.current_player,
                                    penalty_num, timer,
                                    self._main_event):
                #Wait for a player to play
                    self.player_handler.next_player()
                    self.player_handler.update_order()
                    self.update_deck()
                    self.deck.update_top_card()
            else:
                time.sleep(1)
        self._main_event.set()

    def listen(self, client, player):
        """Constantly listens for messages from the respective client.
        Depending on the input, the player is either sent a card or nothing
        """
        message_queue = Queue.Queue()
        get_message_thread = threading.Thread(name = (
            'Getting messages from {}'.format(player.name)), target = (
            self.constantly_receive), args = (client, message_queue))
        get_message_thread.start()
        self.send(self.player_handler.players, client)#Added this too
        try:
            while self.is_running():
                try:
                    data = message_queue.get(timeout = 1)
                except Queue.Empty:
                    continue
                if not self.is_running():
                    #else it'd sent to a broken socket
                    break
                for code in (
                self.rule_handler.check_rules(data, config_parser.get(
                'Rules','allow_no_trigger'))):
                    threading.Thread(name = 'A Rule thread',
                                     target = code,
                                     args = (self,)).start()
                self.handle_data(data, player)
        except (socket.error):
            print "Socket error while listening to {}".format(player)
        except (socket.timeout):
            print "Timed out while listening for {}".format(player)
        finally:
            if self.is_running() and client in self.clients:
                self.disconnect(client)

    def handle_data(self, data, player):
        """Using data as in the player input and the current game conditions,
        this function responds to the player's action, usually by sending
        either a card or a message"""
        if type(data) == str:
            self.send_all('{player}: {message}'.format(
            player = player.name, message = data))
            print '{player}: {message}'.format(
            player = player.name, message = data)
        elif player == self.player_handler.current_player and (
        type(data) == Card):
            card_index = player.get_card_index(data)
            if card_index is not None:#Card index could be 0
                print '{player} attempted to play {card}'.format(
                        player = player.name,
                        card = data.rank + ' of ' + data.suit)
                card = player.get_card(card_index)
                if any((card.suit == self.pile.top_card.suit,
                card.rank == self.pile.top_card.rank,
                not self.pile.top_card.suit,
                not self.pile.top_card.rank)):
                    print ('{card} is now the top card'.format(
                    card = card.rank + ' of ' + card.suit))
                    self._main_event.set()
                    self.pile.add((card,))
                    self.send_all(card)
                else:
                    print (
                    '{card} was given back to {player}'.format(
                    player = player.name, card = card.rank + (
                    ' of ' + card.suit)))
                    assert type(data) == Card
                    if not data.rank and not data.suit:
                        data = None
                    else:
                        data = (data,)
                    self.punish(player, cards = data, reason = (
                    "for not playing a valid card"))
            elif not data.rank and not data.suit:
                self._main_event.set()
                self.punish(player)#They draw a card
            else:
                self._main_event.set()
                self.send_all(
                '{} was caught with a fake card!'.format(
                player.name))
                print '{} was caught with a fake card!'.format(
                player.name)
                raise socket.error

        else:
            assert type(data) == Card
            if not data.rank and not data.suit:
                data = None
            else:
                data = (data,)
            self.punish(player, cards = data, reason = (
            'for playing out of turn!'))

    def __enter__(self):
        threading.Thread(name = "Main Game loop",target = server.main_loop)
        return self

    def __exit__(self, type, value, traceback):
        self.shutdown()

if __name__ == '__main__':
    start_time = time.time()
    from PlayerHandler import PlayerHandler
    from RuleHandler import RuleHandler
    from Rule import Rule
    def test_rule(server_object):
        global a
        a = exit
    rules = [Rule('Test Rule', None, test_rule)]
    RH = RuleHandler(rules)
    PH = PlayerHandler([])
    ip = config_parser.get('Misc.', 'ip')
    port = config_parser.getint('Misc.', 'port')
    players = PH.players
    server = Server(RH, PH, port, ip)
    clients = server.clients
    deck = server.deck
    pile = server.pile

    print 'Server at {}:{}'.format(ip or 'localhost', port)
    MAIN_THREAD = threading.Thread(target = server.main_loop)
    print "Type 'MAIN_THREAD.start()' to start the game!"

    def uptime():
        print "The server has been running for {} seconds".format(
        int(time.time() - start_time))

    def shutdown():
        server.shutdown()
        exit()

    print "Type 'shutdown()' to shutdown the server; DON'T exit the prompt"
<commit_msg>Updated docstring of , as the cards parameter was ambiguous<commit_after># -*- coding: utf-8 -*-
"""
Created on Fri Dec 28 13:12:58 2012

@author: Preston
"""
import Player
import Pile
import socket
import threading
import pickle
import sys
import time
import random
import Queue
from OptionsParser import config_parser
from Card import Card

class Server(object):
    def __init__(self, rule_handler, player_handler, port = None,
                 ip_address = None):
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.bind((ip_address or socket.getfqdn(), int(port)))
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.listen(5)
        self.clients = {}
        self._server_running = threading.Event()
        threading.Thread(name = 'Connection Thread',
                         target = (self.get_connections),
                         args = (self.server,)).start()
        self.player_handler = player_handler
        self.rule_handler = rule_handler
        self.deck = Pile.Pile()
        self.pile = Pile.Pile()
        self.update_deck()
        self._main_event = threading.Event()

    def is_running(self):
        "Returns True if the server is running, or False if it is not"
        return not self._server_running.is_set()

    def get_connections(self, server):
        "Constantly get connections and adds them to clients"
        while self.is_running():
            try:
                server.settimeout(None)
                client, address = server.accept()
                if address in self.clients:
                    client.send('Same ip as other user! Connection aborted')
                    client.close()
                    continue
                client.send('Connection Established')
                print 'Connection Established with {}'.format(
                ':'.join((address[0], str(address[1]))))

                if client not in self.clients and (
                config_parser.getint('Players', 'max_players')
                or sys.maxint) > len(self.clients):
                    player = self.authorise_player(client)
                    self.clients.update({client: player})
                    self.player_handler.add_player(player)
                    Server.send(player, client)
                    self.receive(client) #Pile request
                    Server.send(self.pile.cards, client)
                    if not self.player_handler.current_player:
                        self.player_handler.next_player()
                    threading.Thread(name = 'Listening to {0} at {1}'.format(
                        player.name, address), target = self.listen,
                        args = (client, player)).start()
                else:
                    Server.send('', client)
                    client.close()
            except (socket.timeout, socket.error):
                try:
                    client.close()
                    if client in self.clients:
                        self.clients.pop(client)
                except (socket.error, UnboundLocalError):
                    pass

    def authorise_player(self, client):
        """Generates and then authorises the player with the information
        provided by the client (It has to send the name). It then returns
        the player if it succeeds, or raises socket.error"""
        player_name = self.receive(client)[0]
        if any(player.name == player_name for player in (
        self.player_handler.players)):
            print '{} is already taken!'.format(player_name)
            raise socket.error
        print player_name + ' Joined!'
        self.send_all('[{} Joined!]'.format(player_name))
        self.update_deck()
        return Player.Player(player_name, hand = self.deck.remove(0,
                               config_parser.getint('Cards', 'hand_size')))

    @staticmethod
    def send(data, client):
        "Send some data (pickled) to the client"
        pickled = pickle.dumps(data) +  ';'
        client.send(str(len(pickled)) + ':')

        total = 0
        while total < len(pickled):
            sent = client.send(pickled[total:])
            if sent == 0:
                raise socket.error("Connection Broken")
            else:
                total += sent

    def send_all(self, data):
        for client in self.clients:
            Server.send(data, client)

    def receive(self, client, timeout = 10):
        """Get a response from the server and de-pickles it. If the actual
        message takes too long (longer than 10 seconds or timeout if given)
        then socket.error is raised"""
        def get_message(client, timeout, message = None):
            if not message:
                received = client.recv(2048).split(':', 1)
            else:
                received = message.split(':', 1)
            length = received[0]
            if not length:
                raise socket.error
            data = received[1]
            client.settimeout(timeout)
            while len(data) < int(length):
                message = client.recv(2048)
                if not message:
                    raise socket.error
                data += message
            client.settimeout(None)
            first, second = data.rsplit(';', 1)
            first = pickle.loads(first)
            if first == '':
                raise socket.error('The Client closed the connection!')
            data = []
            data.append(first)
            if second:
                print "Message was too long!"
                data.extend(get_message(client, timeout = 10,
                                         message = second))
            return data
        return get_message(client, timeout)

    def constantly_receive(self, client, queue):
        """Constantly receives messages from the client and passes it into
        the given queue to be handled by the server"""
        while self.is_running() and client in self.clients:
            try:
                data = self.receive(client, timeout = 1)
                for item in data:
                    queue.put(item)
            except socket.timeout:
                continue
            except socket.error:
                if client in self.clients:
                    self.disconnect(client)
                break

    def disconnect(self, client):
        player = self.clients.pop(client)
        try:
            Server.send('', client)
        except (socket.error, socket.timeout):
            pass
        finally:
            client.close()
            self.deck.add(player.hand)
            self.deck.shuffle()
            if player is self.player_handler.current_player:
                self._main_event.set() #Stop the thread
            self.player_handler.remove_player(player)
            self.send_all('{} disconnected'.format(player.name))
            self.send_all(self.player_handler.players)
            #Just added this, hope it works aight
            print '{} disconnected'.format(player.name)

    def shutdown(self):
        "Turns off the server, closing all the connections in clients"
        self._server_running.set()
        clients = []
        clients.extend(self.clients.iterkeys())
        for client in clients:
            self.disconnect(client)
        self.server.shutdown(socket.SHUT_RDWR)
        self.server.close()

    def get_client(self, player):
        """Returns the client connected to the player instance"""
        reversed_map = {player: client for client, player in (
        self.clients.iteritems())}
        return reversed_map.get(player)

    def punish(self, player, penalty_num = config_parser.getint(
               'Punishment','penalty_num'), reason = None, cards = None):
        """The player is punished by being given penalty_num of cards.
        Raises a KeyError if the player is not in the list of players.
        If cards is given, then it appends that to the cards. This option is
        available so that cards are sent as one batch, so as to fix hand syncing
        issues when sending back cards for playing out of turn while at the same
        time punishing the player."""
        if cards is None:
            cards = ()
        if reason is None:
            reason = random.choice(config_parser.get(
                    'Punishment', 'default_phrases').split(';')).format(
                    name = player.name, random_card = (
                    random.choice(player.hand).rank + ' of ' + (
                    random.choice(player.hand).suit)))
        self.send_all('Penalty card for {} '.format(player.name) + reason)
        if player in self.player_handler.players:
            self.update_deck()
            cards = self.deck.remove(0, penalty_num) + cards
            Server.send(cards, self.get_client(player))
            for card in cards:
                player.add_card(card)
        else:
            raise KeyError, player.name + ' is not in players!'

    def constantly_punish(self, player, penalty_num, punish_timer, event):
        """Constantly punishes the player the number of cards in penalty_num
        until the event is set. If no event is given, uses the main_event
        (the one that is set when the current player finally plays a card)"""
        while (not event.wait(punish_timer) and
        player in self.player_handler.players):
            self.punish(player, penalty_num)
        event.clear()

    def update_deck(self):
        "Checks if the deck is getting low (<= 26), and adds card if it is"
        if len(self.deck.cards) <= 26:
            suits = []
            suits = "Spades Hearts Diamonds Clubs".split()
            ranks = "Ace 2 3 4 5 6 7 8 9 10 King Queen".split()
            new_deck = (Pile.Pile([Card(suit, rank) for rank in \
            ranks for suit in suits]))
            self.deck.add(new_deck.cards)
            self.deck.shuffle()
            self.deck.update_top_card()

    def main_loop(self, timer = config_parser.getint('Punishment', 'timer'),
                  penalty_num = config_parser.getint('Punishment',
                  'penalty_num')):
        """Main loop that should be called after initalisation. timer is the
        amount of time a player has to play before he is punished for taking
        too long and penalty num is the amount he is punished by"""
        while self.is_running():
            if self.player_handler.current_player:
                print 'Current Player: {}'.format(
                    self.player_handler.get_current_player())
                if self.constantly_punish(self.player_handler.current_player,
                                    penalty_num, timer,
                                    self._main_event):
                #Wait for a player to play
                    self.player_handler.next_player()
                    self.player_handler.update_order()
                    self.update_deck()
                    self.deck.update_top_card()
            else:
                time.sleep(1)
        self._main_event.set()

    def listen(self, client, player):
        """Constantly listens for messages from the respective client.
        Depending on the input, the player is either sent a card or nothing
        """
        message_queue = Queue.Queue()
        get_message_thread = threading.Thread(name = (
            'Getting messages from {}'.format(player.name)), target = (
            self.constantly_receive), args = (client, message_queue))
        get_message_thread.start()
        self.send(self.player_handler.players, client)#Added this too
        try:
            while self.is_running():
                try:
                    data = message_queue.get(timeout = 1)
                except Queue.Empty:
                    continue
                if not self.is_running():
                    #else it'd sent to a broken socket
                    break
                for code in (
                self.rule_handler.check_rules(data, config_parser.get(
                'Rules','allow_no_trigger'))):
                    threading.Thread(name = 'A Rule thread',
                                     target = code,
                                     args = (self,)).start()
                self.handle_data(data, player)
        except (socket.error):
            print "Socket error while listening to {}".format(player)
        except (socket.timeout):
            print "Timed out while listening for {}".format(player)
        finally:
            if self.is_running() and client in self.clients:
                self.disconnect(client)

    def handle_data(self, data, player):
        """Using data as in the player input and the current game conditions,
        this function responds to the player's action, usually by sending
        either a card or a message"""
        if type(data) == str:
            self.send_all('{player}: {message}'.format(
            player = player.name, message = data))
            print '{player}: {message}'.format(
            player = player.name, message = data)
        elif player == self.player_handler.current_player and (
        type(data) == Card):
            card_index = player.get_card_index(data)
            if card_index is not None:#Card index could be 0
                print '{player} attempted to play {card}'.format(
                        player = player.name,
                        card = data.rank + ' of ' + data.suit)
                card = player.get_card(card_index)
                if any((card.suit == self.pile.top_card.suit,
                card.rank == self.pile.top_card.rank,
                not self.pile.top_card.suit,
                not self.pile.top_card.rank)):
                    print ('{card} is now the top card'.format(
                    card = card.rank + ' of ' + card.suit))
                    self._main_event.set()
                    self.pile.add((card,))
                    self.send_all(card)
                else:
                    print (
                    '{card} was given back to {player}'.format(
                    player = player.name, card = card.rank + (
                    ' of ' + card.suit)))
                    assert type(data) == Card
                    if not data.rank and not data.suit:
                        data = None
                    else:
                        data = (data,)
                    self.punish(player, cards = data, reason = (
                    "for not playing a valid card"))
            elif not data.rank and not data.suit:
                self._main_event.set()
                self.punish(player)#They draw a card
            else:
                self._main_event.set()
                self.send_all(
                '{} was caught with a fake card!'.format(
                player.name))
                print '{} was caught with a fake card!'.format(
                player.name)
                raise socket.error

        else:
            assert type(data) == Card
            if not data.rank and not data.suit:
                data = None
            else:
                data = (data,)
            self.punish(player, cards = data, reason = (
            'for playing out of turn!'))

    def __enter__(self):
        threading.Thread(name = "Main Game loop",target = server.main_loop)
        return self

    def __exit__(self, type, value, traceback):
        self.shutdown()

if __name__ == '__main__':
    start_time = time.time()
    from PlayerHandler import PlayerHandler
    from RuleHandler import RuleHandler
    from Rule import Rule
    def test_rule(server_object):
        global a
        a = exit
    rules = [Rule('Test Rule', None, test_rule)]
    RH = RuleHandler(rules)
    PH = PlayerHandler([])
    ip = config_parser.get('Misc.', 'ip')
    port = config_parser.getint('Misc.', 'port')
    players = PH.players
    server = Server(RH, PH, port, ip)
    clients = server.clients
    deck = server.deck
    pile = server.pile

    print 'Server at {}:{}'.format(ip or 'localhost', port)
    MAIN_THREAD = threading.Thread(target = server.main_loop)
    print "Type 'MAIN_THREAD.start()' to start the game!"

    def uptime():
        print "The server has been running for {} seconds".format(
        int(time.time() - start_time))

    def shutdown():
        server.shutdown()
        exit()

    print "Type 'shutdown()' to shutdown the server; DON'T exit the prompt"
<|endoftext|>


<commit_before>import django.http
import MySQLdb
import cStringIO

import empaths
import zindex
import emcarest
import emcaproj
import dbconfig

# Errors we are going to catch
from emcaerror import ANNError

def emcaget (request, webargs):
  """Restful URL for all read services to annotation projects"""

  [ token , sym, cutoutargs ] = webargs.partition ('/')
  [ service, sym, rest ] = cutoutargs.partition ('/')

  try:
    if service=='xy' or service=='yz' or service=='xz':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="image/png" )
    elif service=='hdf5':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="product/hdf5" )
    elif service=='npz':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="product/npz" )
    elif service=='zip':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="product/zip" )
    elif service=='xyanno' or service=='yzanno' or service=='xzanno':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="image/png" )
    elif service=='id':
      return django.http.HttpResponse(emcarest.emcaget(webargs))
    elif service=='ids':
      return django.http.HttpResponse(emcarest.emcaget(webargs))
    else:
      return django.http.HttpResponseBadRequest ("Could not find service %s" % dataset )
  except (ANNError,MySQLdb.Error), e:
    return django.http.HttpResponseNotFound(e.value)

def annopost (request, webargs):
  """Restful URL for all write/post services to annotation projects"""

  # All handling done by emcarest
  try:
    return django.http.HttpResponse(emcarest.annopost(webargs,request.body))
  except ANNError, e:
    return django.http.HttpResponseNotFound(e.value)

def annotation (request, webargs):
  """Get put object interface for RAMON objects"""

  try:
    if request.method == 'GET':
      return django.http.HttpResponse(emcarest.getAnnotation(webargs), mimetype="product/hdf5" )
    elif request.method == 'POST':
      return django.http.HttpResponse(emcarest.putAnnotation(webargs,request.body))
    elif request.method == 'DELETE':
      emcarest.deleteAnnotation(webargs)
      return django.http.HttpResponse ("Success", mimetype='text/html')
  except ANNError, e:
    if hasattr(e,'value'):
      return django.http.HttpResponseNotFound(e.value)
    else:
      return django.http.HttpResponseNotFound(e)

def csv (request, webargs):
  """Get (not yet put) csv interface for RAMON objects"""

  try:
    if request.method == 'GET':
      return django.http.HttpResponse(emcarest.getCSV(webargs), mimetype="text/html" )
  except ANNError, e:
    if hasattr(e,'value'):
      return django.http.HttpResponseNotFound(e.value)
    else:
      return django.http.HttpResponseNotFound(e)

def getObjects ( request, webargs ):
  """Batch fetch of RAMON objects"""

  try:
    if request.method == 'GET':
      raise ANNError ( "GET requested. objects Web service requires a POST of a list of identifiers.")
    elif request.method == 'POST':
      return django.http.HttpResponse(emcarest.getAnnotations(webargs,request.body), mimetype="product/hdf5")

  except ANNError, e:
    return django.http.HttpResponseNotFound(e.value)

def listObjects ( request, webargs ):
  """Return a list of objects matching predicates and cutout"""

  try:
    if request.method == 'GET':
      return django.http.HttpResponse(emcarest.listAnnoObjects(webargs), mimetype="product/hdf5")
    elif request.method == 'POST':
      return django.http.HttpResponse(emcarest.listAnnoObjects(webargs,request.body), mimetype="product/hdf5")

  except ANNError, e:
    return django.http.HttpResponseNotFound(e.value)

def catmaid (request, webargs):
  """Convert a CATMAID request into an cutout."""

  try:
    catmaidimg = emcarest.emcacatmaid(webargs)

    fobj = cStringIO.StringIO ( )
    catmaidimg.save ( fobj, "PNG" )
    fobj.seek(0)
    return django.http.HttpResponse(fobj.read(), mimetype="image/png")

  except Exception, e:
    return django.http.HttpResponseNotFound(e)

def projinfo (request, webargs):
  """Return project and dataset configuration information"""

  return django.http.HttpResponse(emcarest.projInfo(webargs), mimetype="product/hdf5" )
<commit_msg>Add no cache directives.<commit_after>import django.http
from django.views.decorators.cache import cache_control
import MySQLdb
import cStringIO

import empaths
import zindex
import emcarest
import emcaproj
import dbconfig

# Errors we are going to catch
from emcaerror import ANNError

def emcaget (request, webargs):
  """Restful URL for all read services to annotation projects"""

  [ token , sym, cutoutargs ] = webargs.partition ('/')
  [ service, sym, rest ] = cutoutargs.partition ('/')

  try:
    if service=='xy' or service=='yz' or service=='xz':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="image/png" )
    elif service=='hdf5':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="product/hdf5" )
    elif service=='npz':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="product/npz" )
    elif service=='zip':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="product/zip" )
    elif service=='xyanno' or service=='yzanno' or service=='xzanno':
      return django.http.HttpResponse(emcarest.emcaget(webargs), mimetype="image/png" )
    elif service=='id':
      return django.http.HttpResponse(emcarest.emcaget(webargs))
    elif service=='ids':
      return django.http.HttpResponse(emcarest.emcaget(webargs))
    else:
      return django.http.HttpResponseBadRequest ("Could not find service %s" % dataset )
  except (ANNError,MySQLdb.Error), e:
    return django.http.HttpResponseNotFound(e.value)

@cache_control(no_cache=True)
def annopost (request, webargs):
  """Restful URL for all write/post services to annotation projects"""

  # All handling done by emcarest
  try:
    return django.http.HttpResponse(emcarest.annopost(webargs,request.body))
  except ANNError, e:
    return django.http.HttpResponseNotFound(e.value)

@cache_control(no_cache=True)
def annotation (request, webargs):
  """Get put object interface for RAMON objects"""

  try:
    if request.method == 'GET':
      return django.http.HttpResponse(emcarest.getAnnotation(webargs), mimetype="product/hdf5" )
    elif request.method == 'POST':
      return django.http.HttpResponse(emcarest.putAnnotation(webargs,request.body))
    elif request.method == 'DELETE':
      emcarest.deleteAnnotation(webargs)
      return django.http.HttpResponse ("Success", mimetype='text/html')
  except ANNError, e:
    if hasattr(e,'value'):
      return django.http.HttpResponseNotFound(e.value)
    else:
      return django.http.HttpResponseNotFound(e)

@cache_control(no_cache=True)
def csv (request, webargs):
  """Get (not yet put) csv interface for RAMON objects"""

  try:
    if request.method == 'GET':
      return django.http.HttpResponse(emcarest.getCSV(webargs), mimetype="text/html" )
  except ANNError, e:
    if hasattr(e,'value'):
      return django.http.HttpResponseNotFound(e.value)
    else:
      return django.http.HttpResponseNotFound(e)

@cache_control(no_cache=True)
def getObjects ( request, webargs ):
  """Batch fetch of RAMON objects"""

  try:
    if request.method == 'GET':
      raise ANNError ( "GET requested. objects Web service requires a POST of a list of identifiers.")
    elif request.method == 'POST':
      return django.http.HttpResponse(emcarest.getAnnotations(webargs,request.body), mimetype="product/hdf5")

  except ANNError, e:
    return django.http.HttpResponseNotFound(e.value)

@cache_control(no_cache=True)
def listObjects ( request, webargs ):
  """Return a list of objects matching predicates and cutout"""

  try:
    if request.method == 'GET':
      return django.http.HttpResponse(emcarest.listAnnoObjects(webargs), mimetype="product/hdf5")
    elif request.method == 'POST':
      return django.http.HttpResponse(emcarest.listAnnoObjects(webargs,request.body), mimetype="product/hdf5")

  except ANNError, e:
    return django.http.HttpResponseNotFound(e.value)

def catmaid (request, webargs):
  """Convert a CATMAID request into an cutout."""

  try:
    catmaidimg = emcarest.emcacatmaid(webargs)

    fobj = cStringIO.StringIO ( )
    catmaidimg.save ( fobj, "PNG" )
    fobj.seek(0)
    return django.http.HttpResponse(fobj.read(), mimetype="image/png")

  except Exception, e:
    return django.http.HttpResponseNotFound(e)

@cache_control(no_cache=True)
def projinfo (request, webargs):
  """Return project and dataset configuration information"""

  return django.http.HttpResponse(emcarest.projInfo(webargs), mimetype="product/hdf5" )
<|endoftext|>


<commit_before>import sublime_plugin
import sublime
import json
import socketserver
from threading import Thread
from collections import defaultdict
from EditorConnect.Utils import ignore
from EditorConnect.Settings import Settings

END_OF_MESSAGE_BYTE = b'\n'[0]
END_OF_MESSAGE_STR = '\n'
HANDSHAKE = {
	"name": 'Sublime Text 3',
	"handshake": True
}
HOST = '127.0.0.1'

port = None
server = None
server_thread = None

on_received_callbacks = []
on_disconnect_callbacks = []

def on_received(callback):
	""" Add a callback to the server's on_receive event """
	on_received_callbacks.append(callback)

def off_received(callback):
	""" Removes the callback from the server's receive event """
	global on_received_callbacks
	on_received_callbacks = [cb for cb in on_received_callbacks if cb != cb]

def on_disconnect(callback):
	on_disconnect_callbacks.append(callback)

def off_disconnect(callback):
	""" Removes the callback from the server's receive event """
	global on_disconnect_callbacks
	on_disconnect_callbacks = [cb for cb in on_disconnect_callbacks if cb != cb]

class Parser():
	""" Parses and encodes incoming and outgoing data from the server """
	def encode(self, data):
		return json.dumps(data) + END_OF_MESSAGE_STR

	def decode(self, data):
		return [json.loads(item) for item in str(data, encoding='utf8').split(END_OF_MESSAGE_STR) if item]

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
	def __init__(self, server_address, RequestHandlerClass):
		socketserver.TCPServer.__init__(self, server_address, RequestHandlerClass)
		self.clients = []

	def add_client(self, client):
		server.clients.append(client)

	def remove_client(self, client):
		if client in self.clients:
			self.clients.remove(client)

	def send_all(self, data):
		""" Send data to all clients """
		for client in self.clients:
			client.send(data)

	def send(self, data, id_name):
		""" Send data to a specific client """
		for client in self.clients:
			if client.id == id_name:
				client.send(data)

	def close_requests(self):
		""" Close all requests of the server """
		for client in self.clients:
			client.finish()
		self.clients = []

class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
	""" Server request handler """

	def is_valid_handshake(self):
		self.parser = Parser();

		try:
			handshake = self.parser.decode(self.recvall())[0]
		except Exception as ex:
			print('Parsing error', ex)
			return False

		plugin_id = handshake.get('pluginId')

		if plugin_id:
			self.id = plugin_id
			self.server.add_client(self)
			self.send(HANDSHAKE)
			print('"{0}"'.format(self.id), 'connected', '- Total number connections:', len(self.server.clients))

			return True
		else:
			return False

	def handle(self):
		self.should_receive = True
		self.closed = False

		with ignore(Exception, origin="ThreadedTCPRequestHandler.handle"):
			if not self.is_valid_handshake():
				return self.finish()

			while self.should_receive:
				data_bytes = self.recvall()

				if not data_bytes:
					break

				messages = self.parser.decode(data_bytes)

				with ignore(Exception, origin="ThreadedTCPRequestHandler.handle"):
					for message in messages:
						for callback in on_received_callbacks:
							callback(message)

	def finish(self):
		""" Tie up any loose ends with the request """
		# If the client has not already been closed then close it
		if not self.closed:
			self.request.close()

		# Remove self from list of server clients
		self.server.remove_client(self)
		self.closed = True

		for callback in on_disconnect_callbacks:
			callback(self.id)

		print('"{0}"'.format(getattr(self, 'id', 'Unknown')), 'disconnected', '- Total number of connections', len(self.server.clients))

	def send(self, data):
		# Send data to the client
		with ignore(Exception, origin='ThreadedTCPRequestHandler.send'):
			data = sublime.encode_value(data)
			self.request.sendall((data).encode('utf8'))
			return

		self.finish()
		print('finish after send')

	# Keep receiving until an END_OF_MESSAGE is hit.
	def recvall(self, buffer_size=4096):
		try:
			data_bytes = self.request.recv(buffer_size)

			if not data_bytes:
				return data_bytes

			# Keep receiving until the end of message is hit
			while data_bytes[-1] != END_OF_MESSAGE_BYTE:
				data_bytes += self.request.recv(buffer_size)

		except Exception as ex:
			print('Receiving error', ex)
			return b''

		return data_bytes

def start_server():
	""" Start the server """
	global server, server_thread

	if server != None:
		return print('Server is already running')

	# FIXME: Need to catch the error where previous server didn't shut down
	server = ThreadedTCPServer((HOST, port), ThreadedTCPRequestHandler)

	server_thread = Thread(target=server.serve_forever, daemon=True)
	server_thread.deamon = True
	server_thread.start()
	print('Server started on port {0}'.format(port))

def stop_server():
	""" Stop the server """
	global server

	if server == None:
		return print('Server is already shutdown')

	server.close_requests()
	server.shutdown()
	server = None
	server_thread = None
	print('Server stopped')

class StartServerCommand(sublime_plugin.ApplicationCommand):
	""" Start the server """
	def run(self):
		sublime.set_timeout_async(start_server, 3000)

	def is_enabled(self):
		return server == None and server_thread != None and not server_thread.is_alive()

class StopServerCommand(sublime_plugin.ApplicationCommand):
	""" Stop the server """
	def run(self):
		stop_server()

	def is_enabled(self):
		return server != None and server_thread != None and server_thread.is_alive()

def plugin_loaded():
	global user_settings, port
	user_settings = Settings()
	port = user_settings.get('port')
	# Setting a timeout will ensure the port is clear for reuse
	sublime.set_timeout_async(start_server, 3000)

def plugin_unloaded():
	stop_server()<commit_msg>Fix whitespace<commit_after>import sublime_plugin
import sublime
import json
import socketserver
from threading import Thread
from collections import defaultdict
from EditorConnect.Utils import ignore
from EditorConnect.Settings import Settings

END_OF_MESSAGE_BYTE = b'\n'[0]
END_OF_MESSAGE_STR = '\n'
HANDSHAKE = {
	"name": 'Sublime Text 3',
	"handshake": True
}
HOST = '127.0.0.1'

port = None
server = None
server_thread = None

on_received_callbacks = []
on_disconnect_callbacks = []

def on_received(callback):
	""" Add a callback to the server's on_receive event """
	on_received_callbacks.append(callback)

def off_received(callback):
	""" Removes the callback from the server's receive event """
	global on_received_callbacks
	on_received_callbacks = [cb for cb in on_received_callbacks if cb != cb]

def on_disconnect(callback):
	on_disconnect_callbacks.append(callback)

def off_disconnect(callback):
	""" Removes the callback from the server's receive event """
	global on_disconnect_callbacks
	on_disconnect_callbacks = [cb for cb in on_disconnect_callbacks if cb != cb]

class Parser():
	""" Parses and encodes incoming and outgoing data from the server """
	def encode(self, data):
		return json.dumps(data) + END_OF_MESSAGE_STR

	def decode(self, data):
		return [json.loads(item) for item in str(data, encoding='utf8').split(END_OF_MESSAGE_STR) if item]

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
	def __init__(self, server_address, RequestHandlerClass):
		socketserver.TCPServer.__init__(self, server_address, RequestHandlerClass)
		self.clients = []

	def add_client(self, client):
		server.clients.append(client)

	def remove_client(self, client):
		if client in self.clients:
			self.clients.remove(client)

	def send_all(self, data):
		""" Send data to all clients """
		for client in self.clients:
			client.send(data)

	def send(self, data, id_name):
		""" Send data to a specific client """
		for client in self.clients:
			if client.id == id_name:
				client.send(data)

	def close_requests(self):
		""" Close all requests of the server """
		for client in self.clients:
			client.finish()
		self.clients = []

class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
	""" Server request handler """

	def is_valid_handshake(self):
		self.parser = Parser();

		try:
			handshake = self.parser.decode(self.recvall())[0]
		except Exception as ex:
			print('Parsing error', ex)
			return False

		plugin_id = handshake.get('pluginId')

		if plugin_id:
			self.id = plugin_id
			self.server.add_client(self)
			self.send(HANDSHAKE)
			print('"{0}"'.format(self.id), 'connected', '- Total number connections:', len(self.server.clients))

			return True
		else:
			return False

	def handle(self):
		self.should_receive = True
		self.closed = False

		with ignore(Exception, origin="ThreadedTCPRequestHandler.handle"):
			if not self.is_valid_handshake():
				return self.finish()

			while self.should_receive:
				data_bytes = self.recvall()

				if not data_bytes:
					break

				messages = self.parser.decode(data_bytes)

				with ignore(Exception, origin="ThreadedTCPRequestHandler.handle"):
					for message in messages:
						for callback in on_received_callbacks:
							callback(message)

	def finish(self):
		""" Tie up any loose ends with the request """
		# If the client has not already been closed then close it
		if not self.closed:
			self.request.close()

		# Remove self from list of server clients
		self.server.remove_client(self)
		self.closed = True

		for callback in on_disconnect_callbacks:
			callback(self.id)

		print('"{0}"'.format(getattr(self, 'id', 'Unknown')), 'disconnected', '- Total number of connections', len(self.server.clients))

	def send(self, data):
		# Send data to the client
		with ignore(Exception, origin='ThreadedTCPRequestHandler.send'):
			data = sublime.encode_value(data)
			self.request.sendall((data).encode('utf8'))
			return

		self.finish()
		print('finish after send')

	# Keep receiving until an END_OF_MESSAGE is hit.
	def recvall(self, buffer_size=4096):
		try:
			data_bytes = self.request.recv(buffer_size)

			if not data_bytes:
				return data_bytes

			# Keep receiving until the end of message is hit
			while data_bytes[-1] != END_OF_MESSAGE_BYTE:
				data_bytes += self.request.recv(buffer_size)

		except Exception as ex:
			print('Receiving error', ex)
			return b''

		return data_bytes

def start_server():
	""" Start the server """
	global server, server_thread

	if server != None:
		return print('Server is already running')

	# FIXME: Need to catch the error where previous server didn't shut down
	server = ThreadedTCPServer((HOST, port), ThreadedTCPRequestHandler)

	server_thread = Thread(target=server.serve_forever, daemon=True)
	server_thread.deamon = True
	server_thread.start()
	print('Server started on port {0}'.format(port))

def stop_server():
	""" Stop the server """
	global server

	if server == None:
		return print('Server is already shutdown')

	server.close_requests()
	server.shutdown()
	server = None
	server_thread = None
	print('Server stopped')

class StartServerCommand(sublime_plugin.ApplicationCommand):
	""" Start the server """
	def run(self):
		sublime.set_timeout_async(start_server, 3000)

	def is_enabled(self):
		return server == None and server_thread != None and not server_thread.is_alive()

class StopServerCommand(sublime_plugin.ApplicationCommand):
	""" Stop the server """
	def run(self):
		stop_server()

	def is_enabled(self):
		return server != None and server_thread != None and server_thread.is_alive()

def plugin_loaded():
	global user_settings, port
	user_settings = Settings()
	port = user_settings.get('port')
	# Setting a timeout will ensure the port is clear for reuse
	sublime.set_timeout_async(start_server, 3000)

def plugin_unloaded():
	stop_server()<|endoftext|>


<commit_before># Si7005.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# mar 2014 python port of Si7005 arduino library
# AKA
from __future__ import division
from Adafruit_I2C import Adafruit_I2C
import Adafruit_BBIO.GPIO as GPIO
import time

class si7005():
    # /* Si7005 Registers */
    REG_STATUS         = 0x00
    REG_DATA           = 0x01
    REG_CONFIG         = 0x03
    REG_ID             = 0x11

    # /* Status Register */
    STATUS_NOT_READY   = 0x01

    # /* Config Register */
    CONFIG_START       = 0x01
    CONFIG_HEAT        = 0x02
    CONFIG_HUMIDITY    = 0x00
    CONFIG_TEMPERATURE = 0x10
    CONFIG_FAST        = 0x20

    # /* ID Register */
    ID_SAMPLE          = 0xF0
    ID_SI7005          = 0x50

    # /* Coefficients */
    TEMPERATURE_OFFSET  =  50
    TEMPERATURE_SLOPE   =  32
    HUMIDITY_OFFSET     =  24
    HUMIDITY_SLOPE      =  16
    a0 = (-4.7844)
    a1 =  0.4008
    a2 = (-0.00393)
    q0 =  0.1973
    q1 =  0.00237

    WAKE_UP_TIME = 0.15 # AKA thinks this was 15ms, so changing it to 0.015sec
    # address
    SI7005_ADR = 0x40

    def __init__(self,pin):
    	self.i2c = Adafruit_I2C(self.SI7005_ADR)
    	GPIO.setup(pin, GPIO.OUT)
    	GPIO.output(pin,GPIO.HIGH)
    	self._cs_pin = pin

    	self._last_temperature = 25.0
    	self._config_reg = 0

    def detectSensor(self):
        # byte deviceID
        GPIO.output(self._cs_pin, GPIO.LOW)
        time.sleep(self.WAKE_UP_TIME)
        # i2c.beginTransmission(self.SI7005_ADR)
        self.i2c.write8(self.SI7005_ADR, self.REG_ID)
        # i2c.endTransmission(false)
        # i2c.requestFrom(SI7005_ADR,1)
        deviceID = self.i2c.readU8(self.SI7005_ADR)
        GPIO.output(self._cs_pin, GPIO.HIGH)
        if (deviceID & self.ID_SAMPLE) == self.ID_SI7005:
            return True
        else:
            return False

    def doMeasurement(self,configValue):
        GPIO.output(self._cs_pin, GPIO.LOW) # enable sensor
        time.sleep(self.WAKE_UP_TIME) # wait for wakeup

        self.i2c.write8(self.SI7005_ADR, self.REG_CONFIG) # select config register
        self.i2c.write8(self.SI7005_ADR, (self.CONFIG_START | configValue | self._config_reg)) # Start measurement of the selected type (Temperature / humidity)
        measurementStatus = self.STATUS_NOT_READY

        while (measurementStatus & self.STATUS_NOT_READY):
            self.i2c.write8(self.SI7005_ADR, self.REG_STATUS)
            measurementStatus = self.i2c.readU8(self.SI7005_ADR)

        self.i2c.write8(self.SI7005_ADR, REG_DATA)
        rawData = self.i2c.readU8(self.SI7005_ADR) << 8 # MSB
        rawData |= self.i2c.readU8(self.SI7005_ADR) # LSB

        GPIO.output(self._cs_pin, GPIO.HIGH) # disable sensor

        return rawData

    def getTemperature(self):
    	rawTemperature = self.doMeasurement(self.CONFIG_TEMPERATURE) >> 2
        _last_temperature = ( rawTemperature / self.TEMPERATURE_SLOPE ) - self.TEMPERATURE_OFFSET
        return _last_temperature

    def getHumidity( self):
    	rawHumidity = doMeasurement(self.CONFIG_HUMIDITY) >> 4
        curve = (rawHumidity / self.HUMIDITY_SLOPE) - self.HUMIDITY_OFFSET
        linearHumidity = curve - ( (curve*curve)*a2 + curve*a1 +  a0)
        linearHumidity = linearHumidity + ( _last_temperature - 30 ) * ( linearHumidity * q1 + q0 )
        return linearHumidity

    def enableHeater(self ):
    	_config_reg |= CONFIG_HEAT

    def disableHeater(self ):
    	_config_reg ^= CONFIG_HEAT

    def enableFastMeasurements(self ):
    	_config_reg |= CONFIG_FAST

    def disableFastMeasurements(self ):
    	_config_reg ^= CONFIG_FAST<commit_msg>debugging<commit_after># Si7005.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# mar 2014 python port of Si7005 arduino library
# AKA
from __future__ import division
from Adafruit_I2C import Adafruit_I2C
import Adafruit_BBIO.GPIO as GPIO
import time

class si7005():
    # /* Si7005 Registers */
    REG_STATUS         = 0x00
    REG_DATA           = 0x01
    REG_CONFIG         = 0x03
    REG_ID             = 0x11

    # /* Status Register */
    STATUS_NOT_READY   = 0x01

    # /* Config Register */
    CONFIG_START       = 0x01
    CONFIG_HEAT        = 0x02
    CONFIG_HUMIDITY    = 0x00
    CONFIG_TEMPERATURE = 0x10
    CONFIG_FAST        = 0x20

    # /* ID Register */
    ID_SAMPLE          = 0xF0
    ID_SI7005          = 0x50

    # /* Coefficients */
    TEMPERATURE_OFFSET  =  50
    TEMPERATURE_SLOPE   =  32
    HUMIDITY_OFFSET     =  24
    HUMIDITY_SLOPE      =  16
    a0 = (-4.7844)
    a1 =  0.4008
    a2 = (-0.00393)
    q0 =  0.1973
    q1 =  0.00237

    WAKE_UP_TIME = 0.15 # AKA thinks this was 15ms, so changing it to 0.015sec
    # address
    SI7005_ADR = 0x34

    def __init__(self,pin):
    	self.i2c = Adafruit_I2C(self.SI7005_ADR)
    	GPIO.setup(pin, GPIO.OUT)
    	GPIO.output(pin,GPIO.HIGH)
    	self._cs_pin = pin

    	self._last_temperature = 25.0
    	self._config_reg = 0

    def detectSensor(self):
        # byte deviceID
        GPIO.output(self._cs_pin, GPIO.LOW)
        time.sleep(self.WAKE_UP_TIME)
        # i2c.beginTransmission(self.SI7005_ADR)
        self.i2c.write8(self.SI7005_ADR, self.REG_ID)
        # i2c.endTransmission(false)
        # i2c.requestFrom(SI7005_ADR,1)
        deviceID = self.i2c.readU8(self.SI7005_ADR)
        GPIO.output(self._cs_pin, GPIO.HIGH)
        if (deviceID & self.ID_SAMPLE) == self.ID_SI7005:
            return True
        else:
            return False

    def doMeasurement(self,configValue):
        GPIO.output(self._cs_pin, GPIO.LOW) # enable sensor
        time.sleep(self.WAKE_UP_TIME) # wait for wakeup

        self.i2c.write8(self.SI7005_ADR, self.REG_CONFIG) # select config register
        self.i2c.write8(self.SI7005_ADR, (self.CONFIG_START | configValue | self._config_reg)) # Start measurement of the selected type (Temperature / humidity)
        measurementStatus = self.STATUS_NOT_READY

        while (measurementStatus & self.STATUS_NOT_READY):
            self.i2c.write8(self.SI7005_ADR, self.REG_STATUS)
            measurementStatus = self.i2c.readU8(self.SI7005_ADR)

        self.i2c.write8(self.SI7005_ADR, REG_DATA)
        rawData = self.i2c.readU8(self.SI7005_ADR) << 8 # MSB
        rawData |= self.i2c.readU8(self.SI7005_ADR) # LSB

        GPIO.output(self._cs_pin, GPIO.HIGH) # disable sensor

        return rawData

    def getTemperature(self):
    	rawTemperature = self.doMeasurement(self.CONFIG_TEMPERATURE) >> 2
        _last_temperature = ( rawTemperature / self.TEMPERATURE_SLOPE ) - self.TEMPERATURE_OFFSET
        return _last_temperature

    def getHumidity( self):
    	rawHumidity = doMeasurement(self.CONFIG_HUMIDITY) >> 4
        curve = (rawHumidity / self.HUMIDITY_SLOPE) - self.HUMIDITY_OFFSET
        linearHumidity = curve - ( (curve*curve)*a2 + curve*a1 +  a0)
        linearHumidity = linearHumidity + ( _last_temperature - 30 ) * ( linearHumidity * q1 + q0 )
        return linearHumidity

    def enableHeater(self ):
    	_config_reg |= CONFIG_HEAT

    def disableHeater(self ):
    	_config_reg ^= CONFIG_HEAT

    def enableFastMeasurements(self ):
    	_config_reg |= CONFIG_FAST

    def disableFastMeasurements(self ):
    	_config_reg ^= CONFIG_FAST<|endoftext|>


<commit_before># encoding: utf-8

"""Session handling extension utilizing pluggable session data storage engines."""

from __future__ import unicode_literals

from os import urandom
from binascii import hexlify
from datetime import timedelta
from functools import partial
from itsdangerous import Signer, TimestampSigner, BadSignature

from web.core.util import lazy
from web.core.context import ContextGroup
from web.session.memory import MemorySession

log = __import__('logging').getLogger(__name__)

try:
	from bson import ObjectId
except:
	def ObjectId():
		return hexlify(urandom(32)).decode('ascii')

class SessionExtension(object):
	"""Client session management extension.

	This extension provides a modular approach to managing sessions, with the concept of a "default" engine handling
	most requests, and optional additional engines accessible by their prefix. It populates (lazily) a
	`context.session` object whose attributes are (lazily) loaded on access, and persists .
	"""

	provides = {'session'}
	needs = {'request'}

	def __init__(self, secret=None, default=None, expires=None, cookie=None, refresh=True, **engines):
		"""Configure session management extension and prepare engines.

		The first positional argument is `secret`, the application-secret value used as the cryptographic basis for
		cookie validation. Make sure to set this to a reasonably large random value in production environments. In
		development, if not provided, a different pseudo-random value will be generated on each start.

		The next positional argument, `default`, represents the target of otherwise unknown attribute access to the
		`context.session` object. If one is not given, a `MemorySession` instance will be utilized.

		An optional `expires` time may be given (either a `timedelta` object or an integer representing a number of
		hours) to indicate the lifetime of abandoned sessions; this will be used as the default cookie `max_age` if
		set.

		Cookie settings, to be passed through to the `context.response.set_cookie` WebOb helper, may be passed as a
		dictionary or dictionary-alike named `cookie`.

		If `refresh` is truthy, the cookie will be refreshed to have an updated expiry time on each access. Set this
		value falsy if you want your sessions to have a fixed lifespan from initial creation, otherwise it will
		expire only after it has been abandoned for that duration.

		Additional keyword arguments are used as session engines assigned as lazily loaded attributes of the
		`context.session` object. Individual engines may have their own expiry controls in addition to the global
		setting made here. (There is never a point in setting a specific engine's expiry time to be longer than the
		global.)
		"""

		if not secret:
			if not __debug__:
				raise ValueError("A secret must be defined in production environments.")

			log.warn("Generating temporary session secret; sessions will not persist between restarts.")
			secret = hexlify(urandom(32)).decode('ascii')

		if expires and (hasattr(expires, 'isdigit') or isinstance(expires, (int, float))):
			expires = timedelta(hours=int(expires))

		self._refresh = refresh
		self._expires = expires
		self._signer = TimestampSigner(secret) if expires else Signer(secret)

		engines['default'] = default if default else MemorySession()
		self.engines = engines
		self._cookie = cookie = cookie if cookie else dict()

		cookie.setdefault('name', 'session')
		cookie.setdefault('httponly', True)
		cookie.setdefault('path', '/')

		if expires:
			cookie.setdefault('max_age',
					expires.days * 24 * 60 * 60 + \
					expires.hours * 60 * 60 + \
					expires.minutes * 60 + \
					expires.seconds)

		self.uses = set()
		self.needs = set(self.needs)
		self.provides = set(self.provides)

		# Gather all the dependency information from Session Engines
		for name, engine in self.engines.items():
			if engine is None: continue  # Handle no-default case.
			engine.__name__ = name  # Inform the engine what its name is.
			self.uses.update(getattr(engine, 'uses', ()))
			self.needs.update(getattr(engine, 'needs', ()))
			self.provides.update(getattr(engine, 'provides', ()))

	def get_session_id(self, session):
		"""Lazily get the session id for the current request.

		The `session` passed to this function is the bound SessionGroup instance containing the lazy engines.
		"""
		# TODO: check if any session engines have this key, if not generate a new one
		# otherwise use this key

		cookies = session._ctx.request.cookies
		identifier = None
		token = cookies.get(self._cookie['name'], None)

		if isinstance(token, bytes):
			token = token.decode('ascii')

		if token:
			try:
				if self._expires:
					expires = self._expires
					identifier = self._signer.unsign(token,
							expires.days * 24 * 60 * 60 + \
							expires.hours * 60 * 60 + \
							expires.minutes * 60 + \
							expires.seconds)
				else:
					identifier = self._signer.unsign(token).decode('ascii')

			except BadSignature:
				log.info("Signature failed to validate.", extra=dict(request=id(session._ctx)))

			else:
				if __debug__:
					log.debug("Retreived valid session token from cookie.", extra=dict(
							request=id(session._ctx), identifier=identifier))

		if not identifier:
			# TODO: if token: notify to nuke old session
			identifier = str(ObjectId())
			session['_new'] = True

			if __debug__:
				log.debug("No existing session identifier; generated new.", extra=dict(
					request=id(session._ctx), session=identifier))

		return identifier

	def start(self, context):
		"""Called to prepare attributes on the ApplicationContext."""

		# Construct lazy bindings for each configured session extension.
		context.session = ContextGroup(**{
				name: lazy(lambda s: engine.load(s._ctx, s._id), name) \
				for name, engine in self.engines.items()
			})

		# Also lazily construct the session ID on first request.
		context.session['_id'] = lazy(self.get_session_id, '_id')

		# Notify the engines.
		self._handle_event(True, 'start', context=context)

	def prepare(self, context):
		"""Called to prepare attributes on the RequestContext.

		We additionally promote our DBGroup of extensions here and "bind" the group to this request.
		"""

		if __debug__:
			log.debug("Preparing session group.", extra=dict(request=id(context)))

		context.session = context.session._promote('SessionGroup')  # Allow the lazy descriptor to run from the class.
		context.session['_ctx'] = context  # Bind this promoted SessionGroup to the current context.

		self._handle_event(True, 'prepare', context)

	def after(self, context):
		"""Called after the view has prepared a response, prior to details being sent to the client.

		Determine if the session cookie needs to be set, if so, set it.
		"""

		# engines could have made a new storage even if the id is old
		self._handle_event(True, 'after', context)

		# if the session was accessed at all during this request
		if '_id' not in context.session.__dict__:
			return

		# if the session id has just been generated this request, we need to set the cookie
		if not self._refresh and '_new' not in context.session.__dict__:
			return

		# Sign the token.
		token = self._signer.sign(context.session._id.encode('ascii'))

		# see WebOb request / response
		context.response.set_cookie(value=token, **self._cookie)

	def done(self, context):
		"""Called after the response has been fully sent to the client.

		This helps us defer the overhead of writing session data out until after the client is already served.
		"""

		self._handle_event(True, 'done', context)

		if '_id' not in context.session.__dict__:
			return  # Bail early if the session was never accessed.

		# Inform session engines that had their data touched to persist any changes.
		for ext in set(context.session.__dict__) & set(self.engines):
			self.engines[ext].persist(context, context.session._id, context.session[ext])

	def _handle_event(self, all, event, context, *args, **kw):
		"""Send a signal to all, or only accessed session engines.

		The required positional argument `all` controls if the message is broadcast to all available engines or only
		those that have been accessed during the current request.

		The `event` argument is the string name of the method ("event") to call, if present on the engine.

		A WebCore context must also be passed in as `context`. Any additional arguments (positional or keyword) will
		be passed through to the callbacks themselves.
		"""

		# Determine the set of engines we're sending signals to.
		engines = self.engines.items() if all else {i: self.engines[i] for i \
				in set(context.session.__dict__) & set(self.engines)}

		# Call the event callback, if present in the engine.
		for name, engine in engines:
			if not hasattr(engine, event): continue
			getattr(engine, event)(context, *args, **kw)

	def __getattr__(self, name):
		"""Pass any signals SessionExtension doesn't use on to SessionEngines"""

		# Only allow signals defined in `web.ext.extensions.WebExtensions`
		if name not in ('stop', 'graceful', 'dispatch', 'before', 'interactive', 'inspect'):
			raise AttributeError()

		return partial(self._handle_event, True, name)
<commit_msg>Fix for silly timedeltas.<commit_after># encoding: utf-8

"""Session handling extension utilizing pluggable session data storage engines."""

from __future__ import unicode_literals

from os import urandom
from binascii import hexlify
from datetime import timedelta
from functools import partial
from itsdangerous import Signer, TimestampSigner, BadSignature

from web.core.util import lazy
from web.core.context import ContextGroup
from web.session.memory import MemorySession

log = __import__('logging').getLogger(__name__)

try:
	from bson import ObjectId
except:
	def ObjectId():
		return hexlify(urandom(32)).decode('ascii')

class SessionExtension(object):
	"""Client session management extension.

	This extension provides a modular approach to managing sessions, with the concept of a "default" engine handling
	most requests, and optional additional engines accessible by their prefix. It populates (lazily) a
	`context.session` object whose attributes are (lazily) loaded on access, and persists .
	"""

	provides = {'session'}
	needs = {'request'}

	def __init__(self, secret=None, default=None, expires=None, cookie=None, refresh=True, **engines):
		"""Configure session management extension and prepare engines.

		The first positional argument is `secret`, the application-secret value used as the cryptographic basis for
		cookie validation. Make sure to set this to a reasonably large random value in production environments. In
		development, if not provided, a different pseudo-random value will be generated on each start.

		The next positional argument, `default`, represents the target of otherwise unknown attribute access to the
		`context.session` object. If one is not given, a `MemorySession` instance will be utilized.

		An optional `expires` time may be given (either a `timedelta` object or an integer representing a number of
		hours) to indicate the lifetime of abandoned sessions; this will be used as the default cookie `max_age` if
		set.

		Cookie settings, to be passed through to the `context.response.set_cookie` WebOb helper, may be passed as a
		dictionary or dictionary-alike named `cookie`.

		If `refresh` is truthy, the cookie will be refreshed to have an updated expiry time on each access. Set this
		value falsy if you want your sessions to have a fixed lifespan from initial creation, otherwise it will
		expire only after it has been abandoned for that duration.

		Additional keyword arguments are used as session engines assigned as lazily loaded attributes of the
		`context.session` object. Individual engines may have their own expiry controls in addition to the global
		setting made here. (There is never a point in setting a specific engine's expiry time to be longer than the
		global.)
		"""

		if not secret:
			if not __debug__:
				raise ValueError("A secret must be defined in production environments.")

			log.warn("Generating temporary session secret; sessions will not persist between restarts.")
			secret = hexlify(urandom(32)).decode('ascii')

		if expires and (hasattr(expires, 'isdigit') or isinstance(expires, (int, float))):
			expires = timedelta(hours=int(expires))

		self._refresh = refresh
		self._expires = expires
		self._signer = TimestampSigner(secret) if expires else Signer(secret)

		engines['default'] = default if default else MemorySession()
		self.engines = engines
		self._cookie = cookie = cookie if cookie else dict()

		cookie.setdefault('name', 'session')
		cookie.setdefault('httponly', True)
		cookie.setdefault('path', '/')

		if expires:
			cookie.setdefault('max_age',
					expires.days * 24 * 60 * 60 + \
					expires.seconds)

		self.uses = set()
		self.needs = set(self.needs)
		self.provides = set(self.provides)

		# Gather all the dependency information from Session Engines
		for name, engine in self.engines.items():
			if engine is None: continue  # Handle no-default case.
			engine.__name__ = name  # Inform the engine what its name is.
			self.uses.update(getattr(engine, 'uses', ()))
			self.needs.update(getattr(engine, 'needs', ()))
			self.provides.update(getattr(engine, 'provides', ()))

	def get_session_id(self, session):
		"""Lazily get the session id for the current request.

		The `session` passed to this function is the bound SessionGroup instance containing the lazy engines.
		"""
		# TODO: check if any session engines have this key, if not generate a new one
		# otherwise use this key

		cookies = session._ctx.request.cookies
		identifier = None
		token = cookies.get(self._cookie['name'], None)

		if isinstance(token, bytes):
			token = token.decode('ascii')

		if token:
			try:
				if self._expires:
					expires = self._expires
					identifier = self._signer.unsign(token,
							expires.days * 24 * 60 * 60 + \
							expires.hours * 60 * 60 + \
							expires.minutes * 60 + \
							expires.seconds)
				else:
					identifier = self._signer.unsign(token).decode('ascii')

			except BadSignature:
				log.info("Signature failed to validate.", extra=dict(request=id(session._ctx)))

			else:
				if __debug__:
					log.debug("Retreived valid session token from cookie.", extra=dict(
							request=id(session._ctx), identifier=identifier))

		if not identifier:
			# TODO: if token: notify to nuke old session
			identifier = str(ObjectId())
			session['_new'] = True

			if __debug__:
				log.debug("No existing session identifier; generated new.", extra=dict(
					request=id(session._ctx), session=identifier))

		return identifier

	def start(self, context):
		"""Called to prepare attributes on the ApplicationContext."""

		# Construct lazy bindings for each configured session extension.
		context.session = ContextGroup(**{
				name: lazy(lambda s: engine.load(s._ctx, s._id), name) \
				for name, engine in self.engines.items()
			})

		# Also lazily construct the session ID on first request.
		context.session['_id'] = lazy(self.get_session_id, '_id')

		# Notify the engines.
		self._handle_event(True, 'start', context=context)

	def prepare(self, context):
		"""Called to prepare attributes on the RequestContext.

		We additionally promote our DBGroup of extensions here and "bind" the group to this request.
		"""

		if __debug__:
			log.debug("Preparing session group.", extra=dict(request=id(context)))

		context.session = context.session._promote('SessionGroup')  # Allow the lazy descriptor to run from the class.
		context.session['_ctx'] = context  # Bind this promoted SessionGroup to the current context.

		self._handle_event(True, 'prepare', context)

	def after(self, context):
		"""Called after the view has prepared a response, prior to details being sent to the client.

		Determine if the session cookie needs to be set, if so, set it.
		"""

		# engines could have made a new storage even if the id is old
		self._handle_event(True, 'after', context)

		# if the session was accessed at all during this request
		if '_id' not in context.session.__dict__:
			return

		# if the session id has just been generated this request, we need to set the cookie
		if not self._refresh and '_new' not in context.session.__dict__:
			return

		# Sign the token.
		token = self._signer.sign(context.session._id.encode('ascii'))

		# see WebOb request / response
		context.response.set_cookie(value=token, **self._cookie)

	def done(self, context):
		"""Called after the response has been fully sent to the client.

		This helps us defer the overhead of writing session data out until after the client is already served.
		"""

		self._handle_event(True, 'done', context)

		if '_id' not in context.session.__dict__:
			return  # Bail early if the session was never accessed.

		# Inform session engines that had their data touched to persist any changes.
		for ext in set(context.session.__dict__) & set(self.engines):
			self.engines[ext].persist(context, context.session._id, context.session[ext])

	def _handle_event(self, all, event, context, *args, **kw):
		"""Send a signal to all, or only accessed session engines.

		The required positional argument `all` controls if the message is broadcast to all available engines or only
		those that have been accessed during the current request.

		The `event` argument is the string name of the method ("event") to call, if present on the engine.

		A WebCore context must also be passed in as `context`. Any additional arguments (positional or keyword) will
		be passed through to the callbacks themselves.
		"""

		# Determine the set of engines we're sending signals to.
		engines = self.engines.items() if all else {i: self.engines[i] for i \
				in set(context.session.__dict__) & set(self.engines)}

		# Call the event callback, if present in the engine.
		for name, engine in engines:
			if not hasattr(engine, event): continue
			getattr(engine, event)(context, *args, **kw)

	def __getattr__(self, name):
		"""Pass any signals SessionExtension doesn't use on to SessionEngines"""

		# Only allow signals defined in `web.ext.extensions.WebExtensions`
		if name not in ('stop', 'graceful', 'dispatch', 'before', 'interactive', 'inspect'):
			raise AttributeError()

		return partial(self._handle_event, True, name)
<|endoftext|>


<commit_before>from django.contrib.gis.geos import Point
from busstops.models import Service
from ...models import VehicleLocation, VehicleJourney
from ..import_live_vehicles import ImportLiveVehiclesCommand

class Command(ImportLiveVehiclesCommand):
    source_name = 'transdevblazefield'
    url = 'https://transdevblazefield.arcticapi.com/network/vehicles'
    operators = {
        'YCD': 'YCST',
        'LUI': 'LNUD',
        'BPT': 'BPTR',
        'HDT': 'HRGT',
        'KDT': 'KDTR',
        'ROS': 'ROST'
    }

    def get_items(self):
        return super().get_items()['features']

    def get_vehicle(self, item):
        code = item['properties']['vehicle']
        if '-' in code and code[0].isalpha():
            operator, code = code.split('-', 1)
        else:
            operator = item['_embedded']['transmodel:line']['id'].split(':')[0]

        if len(self.operators) == 1:
            operator = list(self.operators.values())[0]
        else:
            operator = self.operators[operator]

        if operator == 'NCTR' and len(code) == 6:
            if code[:2] == '21':
                operator = 'KBUS'
            elif code[:2] == '20':
                operator = 'TBTN'
            code = code[2:]

        fleet_number = code

        if '_-_' in code:
            parts = code.split('_-_')
            if parts[0].isdigit():
                fleet_number = parts[0]

        defaults = {
            'source': self.source,
            'operator_id': operator,
            'code': code
        }

        if fleet_number.isdigit():
            vehicle = self.vehicles.get_or_create(
                defaults,
                fleet_number=fleet_number,
                operator__in=self.operators.values()
            )
        else:
            vehicle = self.vehicles.get_or_create(
                defaults,
                code=code,
                operator__in=self.operators.values()
            )

        if vehicle[0].code.isdigit() and not code.isdigit():
            vehicle[0].code = code
            vehicle[0].save()

        return vehicle

    def get_journey(self, item, vehicle):
        journey = VehicleJourney(
            route_name=item['properties']['line'],
            direction=item['properties']['direction'][:8]
        )

        if len(self.operators) == 1:
            operator = list(self.operators.values())[0]
        else:
            operator = item['_embedded']['transmodel:line']['id'].split(':')[0]
            try:
                operator = self.operators[operator]
            except KeyError as e:
                print(e, item)
                return journey

        line_name = item['properties']['line']
        if operator == 'BLAC' and line_name == 'PRM':
            line_name = '1'
        if vehicle.latest_location and vehicle.latest_location.journey.route_name == journey.route_name:
            journey.service = vehicle.latest_location.journey.service
        else:
            services = Service.objects.filter(current=True, line_name=line_name)
            if operator == 'BORD':
                services = services.filter(operator__in=('BORD', 'PERY'))
            else:
                services = services.filter(operator=operator)

            if vehicle.operator_id != operator:
                vehicle.operator_id = operator
                vehicle.save()

            try:
                journey.service = self.get_service(services, Point(item['geometry']['coordinates']))
            except Service.DoesNotExist:
                pass
            if not journey.service:
                print(operator, line_name)

        return journey

    def create_vehicle_location(self, item):
        return VehicleLocation(
            latlong=Point(item['geometry']['coordinates']),
            heading=item['properties'].get('bearing')
        )
<commit_msg>just ignore bogus NCTR vehicles<commit_after>from django.contrib.gis.geos import Point
from busstops.models import Service
from ...models import VehicleLocation, VehicleJourney
from ..import_live_vehicles import ImportLiveVehiclesCommand

class Command(ImportLiveVehiclesCommand):
    source_name = 'transdevblazefield'
    url = 'https://transdevblazefield.arcticapi.com/network/vehicles'
    operators = {
        'YCD': 'YCST',
        'LUI': 'LNUD',
        'BPT': 'BPTR',
        'HDT': 'HRGT',
        'KDT': 'KDTR',
        'ROS': 'ROST'
    }

    def get_items(self):
        return super().get_items()['features']

    def get_vehicle(self, item):
        code = item['properties']['vehicle']
        if '-' in code and code[0].isalpha():
            operator, code = code.split('-', 1)
        else:
            operator = item['_embedded']['transmodel:line']['id'].split(':')[0]

        if len(self.operators) == 1:
            operator = list(self.operators.values())[0]
        else:
            operator = self.operators[operator]

        if operator == 'NCTR' and len(code) == 6:
            # Trent Barton vehicles
            return None, None

        fleet_number = code

        if '_-_' in code:
            parts = code.split('_-_')
            if parts[0].isdigit():
                fleet_number = parts[0]

        defaults = {
            'source': self.source,
            'operator_id': operator,
            'code': code
        }

        if fleet_number.isdigit():
            vehicle = self.vehicles.get_or_create(
                defaults,
                fleet_number=fleet_number,
                operator__in=self.operators.values()
            )
        else:
            vehicle = self.vehicles.get_or_create(
                defaults,
                code=code,
                operator__in=self.operators.values()
            )

        if vehicle[0].code.isdigit() and not code.isdigit():
            vehicle[0].code = code
            vehicle[0].save()

        return vehicle

    def get_journey(self, item, vehicle):
        journey = VehicleJourney(
            route_name=item['properties']['line'],
            direction=item['properties']['direction'][:8]
        )

        if len(self.operators) == 1:
            operator = list(self.operators.values())[0]
        else:
            operator = item['_embedded']['transmodel:line']['id'].split(':')[0]
            try:
                operator = self.operators[operator]
            except KeyError as e:
                print(e, item)
                return journey

        line_name = item['properties']['line']
        if operator == 'BLAC' and line_name == 'PRM':
            line_name = '1'
        if vehicle.latest_location and vehicle.latest_location.journey.route_name == journey.route_name:
            journey.service = vehicle.latest_location.journey.service
        else:
            services = Service.objects.filter(current=True, line_name=line_name)
            if operator == 'BORD':
                services = services.filter(operator__in=('BORD', 'PERY'))
            else:
                services = services.filter(operator=operator)

            if vehicle.operator_id != operator:
                vehicle.operator_id = operator
                vehicle.save()

            try:
                journey.service = self.get_service(services, Point(item['geometry']['coordinates']))
            except Service.DoesNotExist:
                pass
            if not journey.service:
                print(operator, line_name)

        return journey

    def create_vehicle_location(self, item):
        return VehicleLocation(
            latlong=Point(item['geometry']['coordinates']),
            heading=item['properties'].get('bearing')
        )
<|endoftext|>