| 1 | #!/usr/bin/env python3
|
| 2 |
|
| 3 | """Lookup DMR users on radioid.net
|
| 4 |
|
| 5 | This script fetches user information from radioid.net API and
|
| 6 | prints them to stdout.
|
| 7 |
|
| 8 | Author: Dominic Reich <quick.hat4396@qtztsjosmprqmgtunjyf.com>
|
| 9 | Created: maybe back in 2021
|
| 10 | Last modified: 2023-01-02 00:07:34+0100
|
| 11 |
|
| 12 | Usage:
|
| 13 | ------
|
| 14 | With arguments
|
| 15 | ./call.py [callsign]|[dmrid]....
|
| 16 |
|
| 17 | Without arguments - but enter them when the script asks you for them
|
| 18 | ./call.py
|
| 19 |
|
| 20 |
|
| 21 | Examples:
|
| 22 | ---------
|
| 23 | ❯ ./call.py oe7drt oe%kbc
|
| 24 | DMRID CALLSIGN FIRSTNAME CITY COUNTRY
|
| 25 | 2327180 OE7DRT Dominic Laengenfeld Austria
|
| 26 | 2327212 OE7DRT Dominic Laengenfeld Austria
|
| 27 | 2321001 OE1KBC Kurt Wien Austria
|
| 28 | 2321002 OE1KBC Kurt Wien Austria
|
| 29 | 2321003 OE1KBC Kurt Wien Austria
|
| 30 | 2328023 OE8KBC Kurt Saurachberg Austria
|
| 31 |
|
| 32 | ❯ ./call.py 2327212
|
| 33 | DMRID CALLSIGN FIRSTNAME CITY COUNTRY
|
| 34 | 2327180 OE7DRT Dominic Laengenfeld Austria
|
| 35 | 2327212 OE7DRT Dominic Laengenfeld Austria
|
| 36 | """
|
| 37 |
|
| 38 | import re # regex
|
| 39 | import sys
|
| 40 | import requests
|
| 41 |
|
| 42 |
|
| 43 | def printFormatted(data: dict) -> None:
|
| 44 | """Formats and prints to stdout.
|
| 45 |
|
| 46 | Expects data coming in as dict, returns nothing but
|
| 47 | the text printed out to stdout."""
|
| 48 | print("{:>7.8} {:<8.8} {:12.12} {:12.12} {:13.13}".format(
|
| 49 | str(data['id']),
|
| 50 | data['callsign'],
|
| 51 | data['fname'],
|
| 52 | data['city'],
|
| 53 | data['country']))
|
| 54 |
|
| 55 |
|
| 56 | def getFromCallsign(url: str, call: str) -> None:
|
| 57 | """Maps the given callsign to a DMRID
|
| 58 |
|
| 59 | Uses the given base-url and callsign and fetches the
|
| 60 | connected DMRIDs. Loops over the result and executes
|
| 61 | printFormatted to print the results to stdout."""
|
| 62 | r = requests.get(url + "/api/dmr/user/?callsign={}".format(call))
|
| 63 | for ids in range(0, r.json()['count']):
|
| 64 | printFormatted(r.json()['results'][ids])
|
| 65 |
|
| 66 |
|
| 67 | def main():
|
| 68 | """main function
|
| 69 |
|
| 70 | Runs if script is run by itself."""
|
| 71 | if len(sys.argv) <= 1:
|
| 72 | # Check if arguments were given, if not, let the user
|
| 73 | # input some here
|
| 74 | arguments = []
|
| 75 |
|
| 76 | userinput = input("No arguments found, enter them now: ")
|
| 77 | words = userinput.split()
|
| 78 | for word in words:
|
| 79 | arguments.append(word)
|
| 80 | else:
|
| 81 | # If arguments were given, take them and move on
|
| 82 | arguments = sys.argv[1:]
|
| 83 |
|
| 84 | # Using these regex pattern to match agains valid DMRIDs
|
| 85 | # and callsigns. The callsign pattern was taken from
|
| 86 | # <https://gist.github.com/JoshuaCarroll/f6b2c64992dfe23feed49a117f5d1a43>
|
| 87 | # and slighty modifed to also allow the percent sign (%) used by
|
| 88 | # used by radioid.net as wildmask.
|
| 89 | dmrid_userid_patt = re.compile("^[0-9]{7}$")
|
| 90 | dmrid_rep_patt = re.compile("^[0-9]{6}$")
|
| 91 | # dmrid_other_patt = re.compile("^[0-9]{0,5}$")
|
| 92 | call_patt = re.compile("^[a-zA-Z0-9%]{1,3}[0123456789%][a-zA-Z0-9%]{0,2}[a-zA-Z%]$")
|
| 93 |
|
| 94 | baseurl = 'https://www.radioid.net'
|
| 95 |
|
| 96 | print(" DMRID CALLSIGN FIRSTNAME CITY COUNTRY")
|
| 97 |
|
| 98 | for arg in arguments:
|
| 99 | if dmrid_userid_patt.match(arg):
|
| 100 | # A valid DMRID was found, so we have to lookup the
|
| 101 | # callsign and we may get more DMRIDs for this OM
|
| 102 | # Valid means 7 chars long, all numbers. We do not know
|
| 103 | # yet if the id really exists.
|
| 104 | r = requests.get(baseurl + '/api/dmr/user/?id={}'.format(arg))
|
| 105 | if r.status_code == 200:
|
| 106 | # Only fetch more DMRIDs if the first one exists,
|
| 107 | # otherwise we would try to run code on an non
|
| 108 | # existing variable
|
| 109 | getFromCallsign(baseurl, r.json()['results'][0]['callsign'])
|
| 110 |
|
| 111 | elif dmrid_rep_patt.match(arg):
|
| 112 | # A valid repeater ID was found. Valid means, technically
|
| 113 | # correct -> 6 characters long, all numbers
|
| 114 | print("{} looks like a repeater. Skipping for now.".format(arg))
|
| 115 |
|
| 116 | # elif dmrid_other_patt.match(arg):
|
| 117 | # # Print a warning for numbers less than 6 characters
|
| 118 | # print("{} is not a valid dmr id!".format(arg))
|
| 119 |
|
| 120 | elif call_patt.match(arg):
|
| 121 | getFromCallsign(baseurl, arg)
|
| 122 |
|
| 123 | else:
|
| 124 | print('{} is an invalid value'.format(arg))
|
| 125 |
|
| 126 |
|
| 127 | if __name__ == "__main__":
|
| 128 | main()
|
| 129 |
|