Python

DX Cluster client in Python

Condivido il codice sorgente in Python 3 per la realizzazione di un DX cluster client, con annessa serie di video in cui spiego il l’implementazione. Lo stesso programma che ho chiamato DX Fighter cluster, è stato da me scritto anche in Java.

Main Class

import socket, _thread
from termcolor import colored
from time import sleep
from Spot import Spot
from Entities import Entities, LOTW

MYCALL = 'IZ0KBA'
#host, port = 'clx.noantri.org', 23
host, port = 'dxfun.com', 8000
server = (host, port)

clxsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
entities = Entities()
lotw = LOTW()

def sendCmd(txt):
    ''' Send a string to server. Carry self included'''
    txt = txt + '\n'
    clxsock.send(txt.encode())
    
def connection():
    ''' Make connetion to server'''
    global clxsock
    connected = False
    while not connected:
        print(colored(f'Connection to: {host} {port}', 'blue'))
        try:
            clxsock.connect( server )
        except:
            print('Impossibile to connect')
            sleep(5)     
        else:       
            print('Connected!!!')
            connected = True
        
def run():
    connection()
    while True:
        try:
            clxmsg = clxsock.recv(2048).decode('latin-1')
            for line in clxmsg.splitlines():
                if line.upper().startswith('DX DE '):
                    #SPOT
                    spot = Spot(line)
                    print(spot.toString())
                else:
                    print(colored(line, 'yellow'))
                    if 'login' in line.lower() or 'enter your call' in line.lower():
                        sendCmd(MYCALL)
                        
        except KeyboardInterrupt:
            print('Disconnected')
            
if __name__ == '__main__':
    _thread.start_new_thread(run, ())
    while True:
        comando = input('>')
        sendCmd(comando)

Class Spot

import __main__

class Spot(): 
    
    lunghezzaMaxSpot = 0
    
    @staticmethod    
    def getBand(frequency):
        '''Accept frequency as string, return Band and Mode'''
        banda, modo = None, None
        frequency = float(frequency)
        if frequency < 2000:
            if frequency <= 1838:
                modo = 'CW'
            elif frequency <= 1843:
                modo = 'DATA'
            else:
                modo = 'PHONE'
            banda = '160M'
        elif frequency < 4000:
            if frequency <= 3580:
                modo ='CW'
            elif frequency <= 3600:
                modo ='DATA'
            else:
                modo ='PHONE'
            banda = '80M'
        elif frequency < 6000:
            if frequency <= 5354:
                modo ='CW'
            else:
                modo ='PHONE'
            banda = '60M'
        elif frequency < 7500:
            if frequency <= 7040:
                modo = 'CW'
            elif frequency <= 7050:
                modo = 'DATA'
            else:
                modo = 'PHONE'
            banda = '40M'
        elif frequency < 10200:
            if frequency <= 10130:
                modo = 'CW'
            else:
            	 modo = 'DATA'
            banda = '30M'
        elif frequency < 14500:
            if frequency <= 14070:
                modo = 'CW'
            elif frequency <= 14100:
                modo = 'DATA'
            else:
                modo = 'PHONE'
            banda = '20M'
        elif frequency < 18300: 
            if frequency < 18095:
                modo = 'CW'
            elif frequency < 18109:
                modo = 'DATA'
            else:
                modo = 'PHONE'
            banda = '17M'
        elif frequency < 21500:
            if frequency <= 21070:
                modo = 'CW'
            elif frequency <= 21110:
                modo ='DATA'
            else:
                modo ='PHONE'
            banda = '15M'
        elif frequency < 25000:
            if frequency < 24915:
                modo ='CW'
            elif frequency <= 24929:
                modo ='DATA'
            else:
                modo ='PHONE'
            banda = '12M'
        elif frequency < 30000:
            if frequency < 28070:
                modo ='CW'
            elif frequency <= 28190:
                modo ='DATA'
            else:
                modo ='PHONE'
            banda = '10M'
        elif frequency < 55000:
            if frequency < 50100:
                modo = 'CW'
            elif frequency < 50300:
                modo = 'PHONE'
            else:
                modo = 'DATA'
            banda = '6M'
        elif frequency < 71000:
            banda = '4M'
        elif frequency < 150000:
            banda = '2M'
        else:
            banda = 'UHF'
            
        return (banda, modo)
    
    def __init__(self, line):
        self.txt = line
        duepunti, punto = line.find(":"), line.find(".")
        self.spotter = line[6 : duepunti]
        self.qrg = line[duepunti + 1 : punto + 2].strip()
        self.callsign = line[punto + 3 : 39].strip()
        bm = self.getBand(self.qrg)
        self.band = bm[0]
        self.mode = bm[1]
        info = __main__.entities.getEntities(self.callsign)
        self.entities = info.name
        self.lotw = __main__.lotw.getLotw(self.callsign)
        if Spot.lunghezzaMaxSpot < len(line):
            Spot.lunghezzaMaxSpot = len(line)
        
    
    def toString(self):
        return f'{self.txt.ljust(Spot.lunghezzaMaxSpot)} {self.lotw[0]} {self.entities} {self.lotw[1]}'

Class Entities

import os
from datetime import datetime

class Entita():
    def __init__(self, line):
        self.name = line[0]
        self.continet = line[1]
        self.dxccn = line[4]        

class Entities():
    def __init__(self, file = 'entities.ini'):
        self.entities = {}
        if os.path.exists(file):
            with open(file, 'r') as inifile:
                for line in inifile.read().splitlines():
                    if '=' in line:
                        k, v = line.split('=')
                        self.entities[k] = v
                        
    def getEntities(self, callsign):
        """Metodo ricorsivo - Recursive method"""
        if callsign:
            if callsign in self.entities:
                return Entita(self.entities[callsign].split(';'))
            return self.getEntita(callsign[:-1])
        return Entita(['Sconosciuto'.ljust(35),'','0','0','-1'])
        
class LOTW():
    def __init__(self, file = 'lotw-user-activity.csv'):
        self.users = {}
        with open(file, 'r') as f:
            for line in f.read().splitlines():
                callsign, data = line.split(',')[:-1]
                self.users[callsign] = data
                
    def getLotw(self, callsign):
        if callsign in self.users:
            data = self.users[callsign]
            diff = (datetime.now() - datetime.strptime(data, '%Y-%m-%d')).days
            data = ('{0} {1}'.format(data, diff)) if diff <= 365 else ('{0} {1}y'.format(data, diff//365))
            return '< LOTW <', data
        else:
            return '<      <',''
                        
if __name__ == '__main__':
    e = Entities()

2 commenti

Lascia una risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *