예제 #1
0
class McastParams(object):
    """ Esta classe armazena e retorna alguns parametros e funcoes comuns ao
    cliente e servidor multicast. O objetivo principal eh evitar redundancia
    de codigo """
    def __init__(self,port,addr,sbound="",sport=None):

        self.__port = int(port)
        self.__addr = addr
        self.__serverbound = sbound
        self.__serverport = sport or int(port)-1
        self.__log = Log()
        self.__quit = False

    def quit(self):
        """ Mata threads, se existirem """
        if self.getThread():
            os.kill(self.getThreadPID(),signal.SIGKILL)
            self.closeSocket()

    def shouldQuit(self):
        return self.__quit

    def closeSocket(self):
        self.getSocket().close()

    def getSocket(self):
        return self.__socket

    def getPort(self):
        return self.__port

    def getAddr(self):
        return self.__addr

    def writeLog(self, v, msg):
        self.__log.log(v,"Mcast:%s"%msg)

    def getServerBound(self):
        return self.__serverbound

    def getServerPort(self):
        return self.__serverport

    def setThreadPID(self,pid):
        self.__threadPID = pid

    def getThreadPID(self):
        return self.__threadPID

    def read(self):
        while True:
            try:
                return self.getSocket().recvfrom(1024)
            except socket.error, errormsg:
                self.writeLog(LOGERROR,"read")
예제 #2
0
def waitrequest(*args):
    """ Executa funcao "handle" para cada mensagem recebida.
        Funcao executada em uma thread separada """

    obj, handle = args[0], args[1]
    obj.setThreadPID(os.getpid())
    log = Log()
    while not obj.shouldQuit():
        try:
            handle(obj.read())
        except socket.error,errormsg:
            log.log(LOGERROR,"watrequest:%s"%errormsg)
            pass
        time.sleep(0.01)
예제 #3
0
class GetLatestPriceController(object):
    """Gets the latest known price for a given symbol"""

    def __init__(self):
        self.log = Log(file_handler, self.__class__.__name__)

    def call(self, symbol):
        if symbol not in allowed_symbols or not buffer_dict:
            self.log.debug("Requested symbol %s is not allowed or has no data." % symbol)
            return json.dumps({"result": None})
        last_trade_time = max(buffer_dict)
        data = buffer_dict.get(last_trade_time)
        result = {"symbol": data.get("symbol"),
                  "price": data.get("price"),
                  "time": last_trade_time.strftime("%Y-%m-%d %H:%M:%S")}
        return json.dumps({"result": result})
예제 #4
0
    def __init__(self,port,addr,sbound="",sport=None):

        self.__port = int(port)
        self.__addr = addr
        self.__serverbound = sbound
        self.__serverport = sport or int(port)-1
        self.__log = Log()
        self.__quit = False
예제 #5
0
class GetChartDataController(object):
    """Gets chart data for a given symbol"""

    def __init__(self):
        self.log = Log(file_handler, self.__class__.__name__)

    def call(self, symbol):
        if symbol not in allowed_symbols or not buffer_dict:
            self.log.debug("Requested symbol %s is not allowed or has no data." % symbol)
            return json.dumps({"result": None})
        labels = [k.strftime("%H:%M:%S") for k in buffer_dict.keys()]
        data = [p.get("price") for p in buffer_dict.values()]
        result = {"symbol": symbol,
                  "labels": labels,
                  "data": data,
                  "min": float(min(data)) - 10,
                  "max": float(max(data)) + 10}
        return json.dumps({"result": result})
예제 #6
0
class IndexViewController(object):
    """Basic index view"""

    def __init__(self):
        self.log = Log(file_handler, self.__class__.__name__)

    def call(self):
        self.get_socket()

        return render_template("index.html", channel_href=config.channel_href)

    def get_socket(self):
        client = Client(config.api_key, config.api_secret)
        bm = BinanceSocketManager(client)
        bm.start_trade_socket("BTCUSDT", self.process_message)
        return bm.start()

    def process_message(self, msg):
        utime = str(msg.get("T"))[:10]
        ms = str(msg.get("T"))[-3:]
        dt = datetime.fromtimestamp(int(utime)).replace(microsecond=int(ms) * 1000)
        symbol = msg.get("s")
        price = "%.2f" % float(msg.get("p"))
        buffer_dict.update({dt: {"symbol": symbol, "price": price}})
        delete_keys = []
        for k in buffer_dict.keys():
            if (dt - k).seconds > config.timeframe or (datetime.now() - k).seconds > config.timeframe:
                delete_keys.append(k)
        if delete_keys:
            for k in delete_keys:
                del buffer_dict[k]
            self.log.info("Deleted keys: %s" % delete_keys)
        prices = [p.get("price") for p in buffer_dict.values()]
        if prices:
            max_price = max(prices)
            min_price = min(prices[prices.index(max_price):])
            drop_percent = (float(max_price) - float(min_price)) / float(max_price)
            if (drop_percent > config.percent_threshhold and drop_percent not in registered_drops.get("drops", [])
                and datetime.now() - dt).seconds < 5):
                self.send_notification(symbol, max_price, min_price, "{:.2%}".format(drop_percent))
                PriceLog.create(symbol=symbol, max_price=max_price,
                                min_price=min_price, drop_percent=round(drop_percent * 100, 2))
                registered_drops.get("drops", []).append(drop_percent)
예제 #7
0
class ClearRegisteredDropsController(object):
    """Clears registered drops list"""

    def __init__(self):
        self.log = Log(file_handler, self.__class__.__name__)

    def call(self):
        now = datetime.now()
        delete_keys = []
        for k in buffer_dict.keys():
            if (now - k).seconds > config.timeframe:
                delete_keys.append(k)
        if delete_keys:
            for k in delete_keys:
                del buffer_dict[k]
            self.log.info("Deleted keys: %s" % delete_keys)
        if (now - registered_drops.get("last_clear_time")).seconds > config.timeframe + 2:
            self.log.info("Clearing registered drops %s" % registered_drops)
            registered_drops.get("drops", []).clear()
            registered_drops["last_clear_time"] = now
            return "Drops cleared."
        return "Drops clearing skipped."
예제 #8
0
    def __init__(self, serverID, mcastPort, mcastAddr, serverFile):

        Thread.__init__(self)
        McastServiceServer.__init__(self,mcastPort,mcastAddr)
        self.__serverDict = self.readServerFile(serverFile)
        self.__server = int(serverID)
        self.__requestList = []
        self.__timeoutList = []
        self.__log = Log("server%d.log"%self.__server)
        self.writeLog(LOGCONTROL,"Iniciando...")

        self.getServer().setAlive()

        # Sinaliza quando a thread tera que ser fechada
        self.__quit = False
예제 #9
0
 def __init__(self):
     self.log = Log(file_handler, self.__class__.__name__)
예제 #10
0
# -*- coding:utf-8 -*-

import os
import logging
import config
from flask import Flask
from misc import Log

app = Flask(__name__)

if not os.path.exists("logs"):
    os.mkdir("logs")

file_handler = logging.FileHandler(config.log_config.get("filename"))
file_handler.setLevel(config.log_config.get("level"))
file_handler.setFormatter(config.log_config.get("format"))

log = Log(file_handler, "Binance")
log.info("Binance service started.")

import views
예제 #11
0
class OnlineCalcServer(McastServiceServer,Thread):
    def __init__(self, serverID, mcastPort, mcastAddr, serverFile):

        Thread.__init__(self)
        McastServiceServer.__init__(self,mcastPort,mcastAddr)
        self.__serverDict = self.readServerFile(serverFile)
        self.__server = int(serverID)
        self.__requestList = []
        self.__timeoutList = []
        self.__log = Log("server%d.log"%self.__server)
        self.writeLog(LOGCONTROL,"Iniciando...")

        self.getServer().setAlive()

        # Sinaliza quando a thread tera que ser fechada
        self.__quit = False

    def run(self):
        """ Este metodo recebe as mensagens e endereca para o metodo
        correto """

        # Criando timeout para o heartbeat
        self.__createTimeout(self.sendHeartBeat,TOUT_HEARTBEAT)
        # Criando timeout para o atualizar status dos servidores
        self.__createTimeout(self.updateHeartBeat,TOUT_DEAD)

        while not self.__quit:
            (data,(ip,port)) = self.getRequest()
            Thread(target=self.parserRequest,args=(data,ip,port)).start()

    def parserRequest(self, data, ip, port):
        """ Recebe uma requisicao e faz o parser executando os metodos
        necessarios. """

        # Expressoes regulares de possiveis mensagens
        reID = "(?P<id>[0-9]+)"
        rePORT = "(?P<port>[0-9]{4,5})"
        reREQCONF = "(?P<request>.*)"
        reREQ = "(?P<request>[0-9()\.\+\-\/\*]*)"

        reALIVE = re.compile("^%s:ALIVE$" % reID)
        reCONFIRM = re.compile("%s:CONFIRM:%s$" % (reID,reREQCONF))
        reREQUEST = re.compile("^%s:%s$"%(rePORT,reREQ))
        reQUIT = re.compile("^%s:QUIT$"% reID)

        if reALIVE.match(data):
            data = reALIVE.search(data)
            sid = int(data.group("id"))
            self.heartBeatReceived(sid)
        elif reCONFIRM.match(data):
            data = reCONFIRM.search(data)
            serverID = data.group("id")
            request = Request(data.group("request"))
            self.requestSentby(serverID,request)
        elif reREQUEST.match(data):
            data = reREQUEST.search(data)
            port = data.group("port")
            data = "%s:%s:%s" %(ip,port,data.group("request"))
            request = Request(data)
            self.addRequest(request)
            self.sendReply(request)
        elif reQUIT.match(data):
            data = reQUIT.search(data)
            serverID = int(data.group("id"))
            self.serverQuiting(serverID)
        else:
            msg = "Request invalido (%s,%d):%s"%(ip,port,data)
            self.writeLog(LOGWARNING,msg)

    def __createTimeout(self,method,tout):
        tout = Timeout(method,tout)
        tout.start()
        self.addTimeout(tout)

    def serverQuiting(self, serverID):
        """ Quando um servidor vai sair seta ele como morto """
        if self.getServer() != self.getServerDict()[serverID]:
            msg = "Servidor %d desconectou"%( serverID )
            self.writeLog(LOGCONTROL,msg)
            self.missingHeartBeat(serverID)

    def readServerFile(self,serverFile):
        """ Le um arquivo contendo os servidores que serao utilizados e
        retorna um dicionario {id:Server} """

        serverList = {}
        for line in open(serverFile):
            # Se a linha nao eh um comentario nem vazia
            if not re.match("^(#|$)",line):
                sid,shostname,sport = line.split()
                serverList[int(sid)] = Server(sid,shostname,sport)

        return serverList

    def writeLog(self,verbose,msg):
        """ Escreve uma mensagem no log """
        msg = "Server-%d %s"%( self.getServer().getID(),msg )
        self.__log.log(verbose,msg)

    def addTimeout(self,obj):
        self.__timeoutList.append(obj)

    def addRequest(self, request):
        """ Adiciona uma nova requisicao a lista e a trata """

        self.writeLog(LOGMESSAGE,"Request:%s"%request)
        self.__requestList.append(request)

    def removeRequest(self, request):
        """ Remove request da lista """
        if request in self.__requestList:
            self.__requestList.remove(request)

    def requestSentby(self, serverID, request):
        """ Confirmacao de que o servidor serverID respondeu a requisicao
        request, que deve ser removida da lista """
        if int(serverID) != self.getServer().getID():
            msg = "Servidor %s Respondeu %s"%(serverID,request)
        else:
            msg = "Respondi %s"%(request)
        self.writeLog(LOGMESSAGE,msg)
        self.removeRequest(request)

    def heartBeatReceived(self,serverID):
        """ Marca servidor serverID como vivo """
        if serverID != self.getServer().getID():
            self.writeLog(LOGCONTROL,"HeartBeatReceived:%d"%serverID)
        self.getServerDict()[int(serverID)].setAlive()

    def updateHeartBeat(self):
        """ Verifica se algum servidor nao responde a mais de TOUT_DEAD
        segundos """
        for server in self.getServerDict().values():
            if server != self.getServer():
                if time.time() - server.getLastContact() > TOUT_DEAD:
                    self.missingHeartBeat(server.getID())

    def missingHeartBeat(self,serverID):
        """ Marca servidor serverID como morto """
        self.writeLog(LOGCONTROL,"MissingHeartBeat:%d"%serverID)
        self.getServerDict()[int(serverID)].setNotAlive()

    def sendHeartBeat(self):
        """ Envia mensagem ao multicast informando que esta vivo """
        self.getMcast().send("%d:ALIVE"%self.getServer().getID())

    def whoAnswers(self):
        """ Retorna o menor servidor ativo """
        for idx in sorted(self.getServerDict().keys()):
            server = self.getServerDict()[idx]
            if server.imalive():
                return self.getServerDict()[idx]

    def sendReply(self,request,force=False):
        """ Computa request e (se sou o servidor com menor ID vivo)
        envia resposta para o cliente, ao mesmo tempo
        que comunica os outros servidores do grupo multicast que a
        requisicao request foi respondida. """
        willAnswer = self.whoAnswers()
        if force or willAnswer == self.getServer():
            reply = "Server%d "%(self.getServer().getID())
            reply += str((self.getServer().getAddr()))+": "
            try:
                reply += str(eval(request.getRequest()))
            except (SyntaxError,TypeError),error:
                reply += "ERRO: "+str(error)
            except ZeroDivisionError:
                reply = "ERRO: Ocorreu uma divisao por zero."
            self.writeLog(LOGCONTROL,"Respondendo %s = %s"%(request,reply))
            host,port = request.getIP(),request.getPort()
            McastServiceServer.sendReply(self,host,port,reply)
            self.sendReplyConfirm(request)