Skip to content

Commit

Permalink
Enhancements and updated README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
OJStuff committed Jun 23, 2024
1 parent d601827 commit ae11d1f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 43 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ All data from radioid.net (users.json) is in UTF-8 format, which is not very rad

pip install unidecode

## Basic use
## Getting started

### Example 1

This command shows how to get help using the prgram.
This command shows how to get help using the prgram:

>getdmrids.py -h
>python getdmrids.py -h
usage: getdmrids.py [-h] [-s] [-d] [-f {anytone,text}] [-r [REGION ...]]
[-c [COUNTRY ...]]

Expand All @@ -47,9 +47,9 @@ This command shows how to get help using the prgram.

### Example 2

This command specifies to download an updated raw DMR ID user database, and then create formatted export file for region 2 (Europe). File format will be for default traceiver type (AnyTone D878/D578) and the file will be named "users-anytone.csv".
This command specifies to download an updated raw DMR ID user database, and then create formatted export file for region 2 (Europe). File format will be for default traceiver type (AnyTone D878/D578) and the file will be named "users-anytone.csv":

>python3 getdmrids.py -d -r 2
>python getdmrids.py -d -r 2

Downloading DMR database users.json (42,597 kB downloaded)

Expand All @@ -59,9 +59,9 @@ This command specifies to download an updated raw DMR ID user database, and then

### Example 3

This command specifies to create formatted export file for region 2 (Europe). Country 302 (Canada) will also be added to the collection, but Norway (242) will ble excluded. File format will be for default traceiver type (AnyTone D878/D578) and the file will be named "users-anytone.csv".
This command specifies to create formatted export file for region 2 (Europe). Country 302 (Canada) will also be added to the collection, but Norway (242) will ble excluded. File format will be for default traceiver type (AnyTone D878/D578) and the file will be named "users-anytone.csv":

>python3 getdmrids.py -r 2 -c 302 -242
>python getdmrids.py -r 2 -c 302 -242

Options specified for export of formatted file:
-r 2 include region: Europe
Expand All @@ -71,9 +71,9 @@ This command specifies to create formatted export file for region 2 (Europe). Co

### Example 4

This command specifies to create formatted export file for region 1, 2 and 3 with statistics. File format will be for default traceiver type (AnyTone D878/D578) and the file will be named "users-anytone.csv".
This command specifies to create formatted export file for region 1, 2 and 3 with statistics. File format will be for default traceiver type (AnyTone D878/D578) and the file will be named "users-anytone.csv":

>python3 getdmrids.py -r 1 2 3 -s
>python getdmrids.py -r 1 2 3 -s

Options specified for export of formatted file:
-r 1 include region: North America and Canada
Expand Down
91 changes: 57 additions & 34 deletions getdmrids.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Environment: Thonny IDE v4.1.4 and builtin Python v3.10.11.
Copyright: Released under CC BY-SA 4.0
Author: GitHub/OJStuff, June 10, 2024, v1.1
Author: GitHub/OJStuff, June 23, 2024, v1.2
"""

import sys
Expand Down Expand Up @@ -92,26 +92,26 @@ def urlExist(url: str) -> bool:

def urlLoad(file: str, url: str, info: bool) -> bool:
"""
Download file from url in blocks of 1024 bytes
Download file from url in chunks of 1024 bytes
Args:
file: Local filname
url: Url to download
info: True if info about downloaded kB will be shown
info: True if info about downloaded size be shown
Returns:
None
"""
try:
status: bool = True
count: int = 0
r = requests.get(url, timeout=5)
with open(file, "wb") as f:
for block in r.iter_content(1024):
count: int = 0
chunk_size: int = 1024
for block in r.iter_content(chunk_size=chunk_size):
f.write(block)
count += 1
f.close()
if info:
sep = ","
print(f" ({count:{sep}} kB downloaded)")
print(f" > {count/chunk_size:.2f} MB downloaded")
except:
status = False
return status
Expand Down Expand Up @@ -142,7 +142,7 @@ def argsHandle() -> tuple[bool, bool, str, list, list]:
Args:
None
Returns:
status: Returns True ig args are OK
status: Returns True if args are OK
fFormat: Returns a string with selected file format
cList: Returns a list of selected country codes
rList: Returns a list of selected region codes
Expand All @@ -154,7 +154,7 @@ def argsHandle() -> tuple[bool, bool, str, list, list]:

parser = argparse.ArgumentParser(
prog=sys.argv[0],
description="""Program exports a formatted file with dmr-id's
description="""Program exports a formatted file with DMR IDs
based on users criteria. This file can be imported into a radio,
like AnyTone D878/D578, as digital contact list""",
epilog="""Updated version and resources may be found at
Expand All @@ -171,7 +171,7 @@ def argsHandle() -> tuple[bool, bool, str, list, list]:
parser.add_argument(
"-d",
"--download",
help="download raw dmr database from https://radioid.net",
help="download DMR database from https://radioid.net",
action="store_true",
)

Expand Down Expand Up @@ -203,17 +203,19 @@ def argsHandle() -> tuple[bool, bool, str, list, list]:
args = parser.parse_args()

if len(sys.argv) == 1:
print(f"\nPlease try {sys.argv[0]} -h if you need help")
print(f"Please try {sys.argv[0]} -h if you need help")

statActive = args.statistics
downActive = args.download

if downActive:
if urlExist(DMR_URL):
print(f"\nDownloading DMR database {os.path.basename(DMR_URL)}", end="")
print(f'Downloading DMR database "{os.path.basename(DMR_URL)}"', end="")
if not urlLoad(os.path.basename(DMR_URL), DMR_URL, True):
print(f"\nProblem downloading {DMR_URL} -> network problems !")
sys.exit(1)
else:
print(f"\n{DMR_URL} unreachable -> network problems !")
print(f"{DMR_URL} unreachable -> network problems !")
sys.exit(1)

fFormat = args.format
Expand All @@ -227,11 +229,13 @@ def argsHandle() -> tuple[bool, bool, str, list, list]:
cList = removeConjugate(list(set(args.country)))

if (not regionActive) and (not countryActive):
print("\nNo options specified to do anything...")
print("No options specified to do anything...")
status = False

if regionActive or countryActive:
print("Options specified for export of formatted file:")

if regionActive:
print("\nOptions specified for export of formatted file:")
for n in rList:
if n in DMR_RC.keys():
print("-r", n, "include region:", DMR_RC[n])
Expand Down Expand Up @@ -262,9 +266,10 @@ def argsHandle() -> tuple[bool, bool, str, list, list]:
cList.remove(r)

if not fileExist(os.path.basename(DMR_URL)):
print(f"\nCan't find local DMR database {os.path.basename(DMR_URL)}")
print(f"\nUse -d option to download {os.path.basename(DMR_URL)}")
print(f'\nCan\'t find local DMR database "{os.path.basename(DMR_URL)}"')
print(f'Use -d option to download "{os.path.basename(DMR_URL)}"')
status = False

return statActive, status, fFormat, cList, rList


Expand Down Expand Up @@ -317,6 +322,7 @@ def dmrSelection(cList: list, rList: list) -> list[dict]:
"""
selection: list = []
dmrDB = jsonLoad(os.path.basename(DMR_URL))
print(f'Getting DMR IDs from "{os.path.basename(DMR_URL)}"')
for i in dmrDB["users"]:
if regionInclude(i["radio_id"], rList) and not countryExclude(
i["radio_id"], cList
Expand All @@ -341,18 +347,12 @@ def dmrTouchup(data: list) -> list[dict]:
"""
dataToucup: list = []
for x in data:
x["fname"] = unidecode(x["fname"])
x["fname"] = x["fname"].title()
x["name"] = unidecode(x["name"])
x["name"] = x["name"].title()
x["country"] = unidecode(x["country"])
x["country"] = x["country"].title()
x["callsign"] = x["callsign"].upper()
x["city"] = unidecode(x["city"])
x["city"] = x["city"].title()
x["surname"] = unidecode(x["surname"])
x["surname"] = x["surname"].title()
x["state"] = unidecode(x["state"])
x["state"] = x["state"].title()
dataToucup.append(x)
return dataToucup
Expand All @@ -369,6 +369,28 @@ def dmrStat(data: list):
return None


def csvLoad(file: str, mode: str, newl: str, enc: str, delim: str) -> list:
"""
Import csv file rows
Args:
file: CSV filename
mode: CSV file mode
newl: CSV newline char
enc: CSV file encoding
delim: CSV delimiter
Returns:
List of rows
"""
fileRows = []
with open(file, mode, newline=newl, encoding=enc) as csvfile:
csvreader = csv.reader(csvfile, delimiter=delim)
next(csvreader) # Skip the header
for row in csvreader:
fileRows.append(row) # Get all the rows
csvfile.close()
return fileRows


def dmrExportAnytone(data: list, file: str) -> None:
"""
Creates csv file formatted for AnyTone D878/D578 for export
Expand All @@ -395,22 +417,22 @@ def dmrExportAnytone(data: list, file: str) -> None:

for x in data:
csvRow: list = [
x["radio_id"],
x["callsign"],
x["fname"],
x["city"],
x["state"],
x["country"],
"",
"Private Call",
"None",
unidecode(str(x["radio_id"])),
unidecode(x["callsign"]),
unidecode(x["fname"]),
unidecode(x["city"]),
unidecode(x["state"]),
unidecode(x["country"]),
unidecode(""),
unidecode("Private Call"),
unidecode("None"),
]
csvRows.append(csvRow)

with open(file, "wt", newline="", encoding="utf-8") as csvfile:
cswriter = csv.writer(csvfile)
cswriter.writerows(csvRows)
print(f"DMR ID file ({file}) was exported with {len(data):,} IDs")
print(f'DMR ID file "{file}" was exported with {len(data):,} IDs')
return None


Expand Down Expand Up @@ -461,7 +483,7 @@ def dmrExportText(data: list, file: str) -> None:
txtFile.writelines(txtRows)
txtFile.close()

print(f"DMRID file ({file}) exported with {len(data):,} IDs")
print(f'DMR ID file "{file}" was exported with {len(data):,} IDs')
return None


Expand All @@ -475,6 +497,7 @@ def main() -> None:

if argsOK and fileExist(os.path.basename(DMR_URL)):
dmrData = dmrSelection(countryList, regionList)

dmrData = dmrTouchup(dmrData)

if fileFormat[0] == "anytone":
Expand Down

0 comments on commit ae11d1f

Please sign in to comment.