Last active 1731167344

call.py Raw
1#!/usr/bin/env python3
2
3"""Lookup DMR users on radioid.net
4
5This script fetches user information from radioid.net API and
6prints them to stdout.
7
8Author: Dominic Reich <quick.hat4396@qtztsjosmprqmgtunjyf.com>
9Created: maybe back in 2021
10Last modified: 2023-01-02 00:07:34+0100
11
12Usage:
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
21Examples:
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
38import re # regex
39import sys
40import requests
41
42
43def 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
56def 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
67def 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
127if __name__ == "__main__":
128 main()
129