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