Example #1
0
def proc_spot_mode(inmode):
    # valid modes
    modes = ["am", "cw", "data", "dv", "fm", "psk", "rtty", "ssb", "other"]
    valid = False

    mode = inmode.replace('\n', '')
    # check mode is valid string
    for validmode in range(len(modes)):
        if mode == modes[validmode]:
            valid = True
            break
    # mode is invalid, set it to other
    if valid == False:
        tstr = 'mode not valid ' + mode + ' using other instead'
        print(tstr)
        smslog.log(tstr)
        mode = 'other'

    return mode
Example #2
0
def proc_spot_SOTA_summit(tsummit):

    # only want 1st 2 chars for SOTA
    summit = tsummit[0:2]
    # if no - in the original then add one
    if tsummit[2:3] != '-':
        summit += '-'
        summit += tsummit[2:]
    else:
        summit = tsummit

    # check summit is right length
    if len(summit) != 6:
        tstr = 'SOTA summit len not 6 ' + summit + ' ' + tsummit
        smslog.log(tstr)
        print(tstr)
        return None

    return summit
Example #3
0
def proc_spot_freq(freq):
    # check we have a . or a : or a , in the string
    dotpos = freq.find('.')
    colpos = freq.find(':')
    commapos = freq.find(',')
    if dotpos == -1 and colpos == -1 and commapos == -1:
        tstr = 'no . or : or , in freq ' + freq
        smslog.log(tstr)
        print(tstr)
        return None

    if colpos != -1:
        dotpos = colpos
        freq = freq.replace(':', '.')
        tstr = 'replaced : with .'
        smslog.log(tstr)
        print(tstr)

    if commapos != -1:
        dotpos = commapos
        freq = freq.replace(',', '.')
        tstr = 'replaced , with .'
        smslog.log(tstr)
        print(tstr)

    # check digits before .
    if freq[0:dotpos].isdigit() == False:
        tstr = 'before . is not digit ' + freq
        print(tstr)
        smslog.log(tstr)
        return None

    #check digits after .
    if freq[dotpos + 1:].isdigit() == False:
        tstr = 'after . is not digit ' + freq
        print(tstr)
        smslog.log(tstr)
        return None

    # if here freq looks ok
    return freq
Example #4
0
def postwotaspot(param, spot, nowota):

    wotaparam = {}
    wotaparam['posted_by'] = 'mm0fmf'
    summit = param['summit'].split('-')
    if summit[0].find('LDW') != -1:
        wotaparam['summit'] = summit[1]
    else:
        wotaparam['summit'] = str(int(summit[1]) + 214)

    wotaparam['call'] = param['actCallsign']
    wotaparam['freqmode'] = param['freq'] + '+' + param['mode']
    wotaparam['comment'] = param['comments']

    # dont post if the nopost flag is set
    if nowota == True:
        partial_spotdata = urllib.parse.urlencode(wotaparam)
        print('**NOT** Posting a spot with: ')
        print(partial_spotdata)
        smslog.log(partial_spotdata)
        smslog.log('WOTA: posting disabled with nowota')
        retval = 303
        return retval

    if spot == True:
        spotdata = urllib.parse.urlencode(wotaparam)
        print('Posting a spot with: ')
        print(spotdata)
        smslog.log(spotdata)
        retval = 200
        try:
            smslog.log('WOTA: connect')
            if wota_connect() == False:
                tstr = "Cannot connect to wota.org.uk:80\n"
                print(tstr)
                smslog.log('WOTA: ' + tstr)
                retval = 404
                return retval
            smslog.log('WOTA: login')
            if wota_login("mm0fmf", "earlgrey100") == False:
                tstr = "Cannot login to wota.org.uk:80\n"
                print(tstr)
                smslog.log('WOTA: ' + tstr)
                retval = 404
                return retval

            #print "wotaconn.request..."


#            wotaconn.request("POST", "/index.php?page=mm_home/mm_sendspot.html", spotdata, wotahttpheaders)
            wotaconn.request("POST",
                             "/index.php?page=mm_home/mm_sendspotnoaprs.html",
                             spotdata, wotahttpheaders)
            #print "wotaconn.getresponse..."
            r1 = wotaconn.getresponse()
            #print "wotaconn.close..."
            wotaconn.close()
            #print "done"
            #print r1.status, r1.reason
            if r1.status == 200:
                #smslog.log( 'WOTA: '+str(r1.status) + ' is good')
                smslog.log('WOTA: {0:d} is good'.format(r1.status))
                return 200

        except IOError:
            print('HTTP IOError exception with www.wota.org.uk:80\n')
            smslog.log('WOTA: IOError, spot deleted')

    # not a spot, it's an alert and we support them yet
    else:
        print('Alerting with: ' + 'NOT YET')

    return retval
Example #5
0
def postspot(param, nopost, api, spottingcall):

    spotdata = spotlite2api2(param)

    # dont post if the nopost flag is set
    if nopost == True:
        print('**NOT** Posting a spot with: ')
        print(spotdata)
        smslog.log(json.dumps(spotdata))
        smslog.log('SPOTLITE: posting disabled with nospot')
        thing = {}
        thing['statusCode'] = 0
        posted_spots[random.randint(1, 9999999)] = spotdata
        print("delete spot backtrace dictionary has " +
              str(len(posted_spots)) + " entries")
        print(posted_spots)
        return True, thing

    print('Posting a spot with: ')
    print(spotdata)
    smslog.log(json.dumps(spotdata))
    msg = "\nclient=sms&user="******"\n"
    smslog.log(msg)

    status, reply = api.postspot(spotdata, spottingcall)
    if status == False:
        msg = "api2 call failed"
        print(msg)
        smslog.log(msg + "\n")
        return status, reply

    posted_spots[reply['id']] = spotdata
    print("delete spot backtrace dictionary has " + str(len(posted_spots)) +
          " entries")
    msg = "api2 liked the spot"
    print(msg)
    smslog.log(msg + "\n")
    return status, reply
Example #6
0
def deletespot(param, nopost, api, spottingcall):

    spotdata = spotlite2api2(param)

    foundkey = False

    # dont post if the nopost flag is set

    if nopost == True:
        print('**NOT** Deleting a spot with: ')

        for key, value in posted_spots.items():
            oldspot = dict(value)
            if oldspot == spotdata:
                del posted_spots[key]
                print("delete spot backtrace dictionary has " +
                      str(len(posted_spots)) + " entries")
                message = ''.join("Deleted spot: " + str(key))
                print(message)
                print(spotdata)
                smslog.log(message)
                smslog.log(json.dumps(spotdata))
                foundkey = True
                break

        if foundkey == False:
            message = "No matching spot found"
            print(message)
            smslog.log(message + "\n")

        thing = {}
        thing['statusCode'] = 0
        return True, thing

    print('deleting a spot with: ')

    for key, value in posted_spots.items():
        oldspot = dict(value)
        if oldspot == spotdata:
            foundkey = True
            status, reply = api.deletespot(key)
            if status == False:
                print("api2 call failed")
                smslog.log("api2 call failed")
                return status, reply
            if reply['statusCode'] == 0:
                print("api2 liked the delete")
                smslog.log("api2 liked the delete")
                del posted_spots[key]
                print("delete spot backtrace dictionary has " +
                      str(len(posted_spots)) + " entries")
                message = ''.join("Deleted spot: " + str(key))
                print(message)
                print(spotdata)
                smslog.log(message)
                smslog.log(json.dumps(spotdata))
                return status, reply
            else:
                print("api2 did not like the delete")
                smslog.log("api2 did not like the delete")
                return status, reply

        if foundkey == False:
            message = "No matching spot found"
            print(message)
            smslog.log(message + "\n")
            return False, None
Example #7
0
def posthumpspot(param, spot, nopost):

    summitReference = ""
    summitReference = param['assoc']
    summitReference = summitReference + '/'
    summitReference = summitReference + param['summit']
    summitReference = summitReference.upper()

    spotparams = {'submitSpotButton': 'Submit spot'}
    spotparams['activationCallsign'] = param['actCallsign']
    spotparams['summitReference'] = summitReference
    spotparams['frequency'] = param['freq']
    spotparams['mode'] = param['mode']
    spotparams['comments'] = param['comments']
    encspotparams = urllib.parse.urlencode(spotparams)

    httpheaders = {
        "Content-type": "application/x-www-form-urlencoded",
        "Accept": "text/plain",
        "User-Agent": "humps-spotter-mm0fmf/0.1"
    }

    if nopost == True:
        print('**NOT** Posting a hump spot with: ')
        print(encspotparams)
        smslog.log(encspotparams)
        smslog.log('HUMPS: posting disabled with nohump')
        retval = 303
        return retval

        retval = 200
    try:
        conn = http.client.HTTPConnection("www.summitswatch.org.uk")
        conn.request("GET", "/sb/login.php")
        r1 = conn.getresponse()

        #print r1.status, r1.reason
        if r1.status != 200:
            return 200

        headers = r1.getheaders()
        for header in headers:
            if header[0] == 'set-cookie':
                cookie = header[1].split(';')
                #print cookie[0]

        httpheaders['Cookie'] = cookie[0]

        body = r1.read()
        #print loginparams
        #print httpheaders

        loginparams = {
            'submitted': 'TRUE',
            'submit': 'Login',
        }
        loginparams['email'] = '*****@*****.**'
        loginparams['pass'] = '******'

        encparams = urllib.parse.urlencode(loginparams)

        conn.request("POST", "/sb/login.php", encparams, httpheaders)
        r1 = conn.getresponse()
        body = r1.read()
        if r1.status != 302:
            conn.close()
            return 200

        print('posting a hump spot with:')
        print(encspotparams)
        smslog.log(encspotparams)
        conn.request("POST", "/sb/submitSpot.php", encspotparams, httpheaders)
        r1 = conn.getresponse()
        body = r1.read()
        #print r1.status, r1.reason
        #smslog.log( 'HUMPS: '+str(r1.status) )
        smslog.log('HUMPS: {0:d}'.format(r1.status))

        if r1.status == 302:
            conn.close()
            return 303
    except IOError:
        print('HTTP exception with www.summitswatch.org.uk:80\n')
        smslog.log('HUMPS: IOError, spot deleted')
        return 200
Example #8
0
def postspotlite(param, spot, nopost, spotter):

    # dont post if the nopost flag is set
    if nopost == True:
        headers = {
            "Content-type": "application/x-www-form-urlencoded",
            "Accept": "text/plain"
        }
        partial_spotdata = urllib.parse.urlencode(param)
        print('**NOT** Posting a spot with: ')
        print(partial_spotdata)
        smslog.log(partial_spotdata)
        smslog.log('SPOTLITE: posting disabled with nospot')
        retval = 303
        return retval

    if spot == True:
        headers = {
            "Content-type": "application/x-www-form-urlencoded",
            "Accept": "text/plain"
        }
        partial_spotdata = urllib.parse.urlencode(param)
        print('Posting a spot with: ')
        print(partial_spotdata)
        smslog.log(partial_spotdata)

        if spotter == 'VK':  #'SMS_AUS':
            param['callsign'] = 'SMS_AUS'
            param['password'] = '******'
        elif spotter == 'GB':  #'SMS':
            param['callsign'] = 'SMS'
            param['password'] = '******'
        elif spotter == 'SAT':  #'Iridium':
            param['callsign'] = 'Iridium'
            param['password'] = '******'
        elif spotter == 'NA':  #'SMS_NA':
            param['callsign'] = 'SMS_NA'
            param['password'] = '******'
        elif spotter == 'OE':  #'SMS_OE':
            param['callsign'] = 'SMS_OE'
            param['password'] = '******'

        param['submit'] = 'SPOT!'
        spotdata = urllib.parse.urlencode(param)

        retval = 200
        try:
            #            conn = http.client.HTTPConnection("www.sota.org.uk:80")
            conn = http.client.HTTPConnection("old.sota.org.uk:80")
            conn.request("POST", "/Spotlite/postSpot", spotdata, headers)
            response = conn.getresponse()
            data = response.read()
            conn.close()
            #smslog.log( 'SPOTLITE: '+str(response.status) + '\n' + data)
            smslog.log('SPOTLITE: {0:d}\n{1}'.format(response.status,
                                                     data.decode('utf-8')))
            retval = response.status

        except IOError:
            #            print('HTTP IOError exception with www.sota.org.uk:80\n')
            print('HTTP IOError exception with old.sota.org.uk:80\n')
            smslog.log('SPOTLITE: IOError, spot deleted')

    # not a spot, it's an alert and we support them yet
    else:
        print('Alerting with: ' + 'NOT YET')

    return retval
Example #9
0
def uk_localise(callsign, assoc):
    assocs = ['GM', 'GW', 'GI', 'GD', 'G']
    region = ['M', 'W', 'I', 'D', 'E']
    clubregion = ['S', 'C', 'N', 'T', 'X']
    bclub = False
    bgcall = False
    b2call = False

    # IL call?
    if callsign[0:1] == '2':
        b2call = True
    # G or M call?
    elif callsign[0:1] == 'G' or callsign[0:1] == 'M':
        bgcall = True
    else:
        # this is not a UK callsign
        return callsign

    for clubsecondary in clubregion:
        if clubsecondary == callsign[1:2]:
            bclub = True
            print('Club call')
            clubindex = clubregion.index(clubsecondary)
            break
    # check if uk call in uk region
    for tassoc in assocs:
        if tassoc == assoc:
            # we are in a localisable region
            index = assocs.index(tassoc)
            # copy 1st char
            localised = callsign[0:1]

            if bclub == True:
                #print 'uk club callsign in ',tassoc
                # club call, 2nd char is clubregion
                localised += clubregion[index]
                # club call always has a secondary locator
                # so rest of call starts at 2: not 1:
                localised += callsign[2:]
            else:
                # england has no secondary locator
                if index == 4:
                    # IL call?
                    if b2call == True:
                        #print 'uk IL callsign in ',tassoc
                        # but england does have secondary if IL call
                        localised += region[index]
                        # IL call always has a secondary locator
                        # so rest of call starts at 2:
                        localised += callsign[2:]
                    else:
                        #print 'uk callsign in ',tassoc
                        # english call in england
                        if callsign[1:2].isdigit() == True:
                            # just copy whats left
                            localised += callsign[1:]
                        else:
                            # uk regional, number starts at 2:
                            localised += callsign[2:]
                else:
                    # in a region with secondary
                    localised += region[index]
                    # english call in england
                    if callsign[1:2].isdigit() == True:
                        # just copy whats left
                        localised += callsign[1:]
                    else:
                        # uk regional, number starts at 2:
                        localised += callsign[2:]

            break
        else:
            #print 'uk callsign but not in ',tassoc
            localised = callsign

    smslog.log('callsign: ' + callsign + ' assoc: ' + assoc + ' localised: ' +
               localised)
    return localised
Example #10
0
def parse_SOTA_spot(message, spottercall, isAPI2, spotsource):

    message.strip()

    pepperspot = message.find('-DS09a)')
    if pepperspot != -1:
        pepperspot = pepperspot * -1
        message = message[1:-pepperspot]

    pepperspot = message.find('-DS1f)')
    if pepperspot != -1:
        pepperspot = pepperspot * -1
        message = message[1:-pepperspot]

    if spottercall == 'MM0FMF':
        pepperspot = message.find('via DroidSpot')
        if pepperspot != -1:
            pepperspot = pepperspot * -1
            message = message[0:-pepperspot]
            print('DroidSpot removed:\n' + message)

        pepperspot = message.find('#DroidSpot')
        if pepperspot != -1:
            pepperspot = pepperspot * -1
            message = message[0:-pepperspot]
            print('DroidSpot removed:\n' + message)

    fields = message.split(' ')
    # user may have entered multiple spaces, use list comprehension to remove any
    # null entries in the list of keywords after we split on space
    fields = [i for i in fields if i != '']

    # create dict with all bad entries
    spot = allbadspot()

    # check we have at least 6 fields of data
    # well we should have 6 fields but we dont need a comment field
    # so we accept 5

    if len(fields) < NUM_SOTA_FIELDS - 1:
        #tstr = 'Bad format: only '+str(len(fields))+' fields in message'
        tstr = 'Bad format: only {0:d} fields in message'.format(len(fields))
        smslog.log(tstr)
        spot['actCallsign'] = spottercall
        smslog.badspot(spot, 'data')
        print(tstr)
        return None

    # create some vars (because we are a C programmer at heart)
    callsign = ''
    assoc = ''
    summit = ''
    freq = ''
    mode = ''
    comment = ''
    isfullcall = False
    status = False

    # cleanup call, add /p etc.
    callsign, isfullcall, eraseme = proc_spot_callsign(
        fields[sota_CALL].upper(), spottercall)

    # extract association
    assoc = fields[sota_ASSOC].upper()

    if isfullcall == False:
        # uk regionalise the callsign
        callsign = uk_localise(callsign, assoc)

    # fill in dict with parsed data
    spot['actCallsign'] = callsign
    spot['assoc'] = assoc

    # extract summit and check is SOTA format
    summit = proc_spot_SOTA_summit(fields[sota_REF].upper())

    if summit == None:
        # log it for status
        smslog.badspot(spot, 'summit')
        return False, None, False

    # fill in dict with parsed data
    spot['summit'] = summit

    # extract freq
    freq = proc_spot_freq(fields[sota_FREQ].upper())

    # if freq is bogus, fail now
    if freq == None:
        smslog.badspot(spot, 'freq')
        return False, None, False

    # fill in dict with parsed data
    spot['freq'] = freq

    # extract mode and cleanup
    mode = proc_spot_mode(fields[sota_MODE].lower())

    # build comment
    if isAPI2 == True:
        comment = proc_spot_api2comment(spottercall, fields, sota_COMMENT,
                                        spotsource)
    else:
        comment = proc_spot_comment(spottercall, fields, sota_COMMENT)

    # finally assemble all components into a spot string


#    spot = {}
#    spot[ 'actCallsign' ] = callsign
#    spot[ 'assoc' ] = assoc
#    spot[ 'summit' ] = summit
#    spot[ 'freq' ] = freq
    spot['mode'] = mode
    spot['comments'] = comment

    return True, spot, eraseme
Example #11
0
def processloop(sender, msg, nospot, spotsource, sotapi2):

    #isAPI2 = False
    isAPI2 = True

    callsign, features = usercheck.find(sender)

    if len(msg) == 0:
        print('Bad format, no data!')
        smslog.log('Bad message format, no data')

        return

    fstr = 'SOTA'
    if callsign != '':
        # yes, the user is registered
        print('Found: ', callsign)
        if features & 1:
            fstr += '+Hump'
        if features & 2:
            fstr += '+WOTA'
        print('Features:', fstr)
        print('Message: ', msg)

    else:

        index1 = msg.find('dlor.me/')
        index2 = msg.find('inr.ch')
        index3 = msg.find('garmin.com')

        # not Delorme Inreach
        if index1 == -1 and index2 == -1 and index3 == -1:
            # unknown sender
            smslog.log('Unknown sender: ' + sender)
            # skip the processing
            return

        # we have a Delorme Inreach message, find the user
        delorme = 1
        if index1 != -1:
            delorme = index1
        if index2 != -1:
            delorme = index2
        if index3 != -1:
            delorme = index3

        # we have a Delorme Inreach message, find the user
        delormemsg = msg[delorme:]
        if delormemsg.find(' - ') == -1:
            # delorme message looks buggered
            smslog.log('Delorme InReach message looks corrupt\n')
            smslog.log(msg)
            # skip further processing
            return

        delormefields = delormemsg.split(' - ')
        sender = delormefields[1].strip()
        callsign, features = usercheck.find(sender)
        if callsign == '':
            # unknown delorme user
            smslog.log('Unknown Delorme InReach sender: ' + sender)
            # skip further processing
            return
        else:
            # trim Delorme trash off our spot message
            msg = msg[:delorme]
            # check extra features support
            if features & 1:
                fstr += '+Hump'
            if features & 2:
                fstr += '+WOTA'
            print('(Delorme) Found: ' + callsign)
            print('(Delorme) Features:', fstr)
            print('(Delorme) Message: ', msg)
            # overide default spotsource as all Delorme message are from Iridium
            spotsource = 'Iridium'

    # by now we have a valid SMS or Delorm user identified

    formatvalid = False

    print("processing message: ")

    status, httpspot, eraseme = parsemsg.parse_SOTA_spot(
        msg, callsign, isAPI2, spotsource)

    # check we got some data
    if status == False:
        # log bum data and do next
        smslog.log('Invalid message: ' + msg)

    # data seems good
    else:
        # handle spots

        if isAPI2 == False and eraseme == False:
            # post spot, log results
            httpresp = http_sota.postspotlite(httpspot, True, nospot,
                                              spotsource)
            # log badness if spot failed
            if httpresp == 200:
                smslog.log('Spotlite does not like the message')

        else:
            if eraseme == True:
                # post spot using API2
                status, httpresp = api_sota.deletespot(httpspot, nospot,
                                                       sotapi2, callsign)
            else:
                # post spot using API2
                status, httpresp = api_sota.postspot(httpspot, nospot, sotapi2,
                                                     callsign)

            # log badness if spot failed
            if status == False:
                smslog.log('Posting/deleting the spot failed, api fail')

            else:
                smslog.log('api2 likes the message')

    return