Skip to content

Commit

Permalink
0.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmicc committed Jan 18, 2020
1 parent 82f20a1 commit b7ea83d
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 99 deletions.
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ name = "pypi"

[packages]
iso3166 = "*"
colorama = "*"

[dev-packages]
bump2version = "*"
Expand Down
10 changes: 9 additions & 1 deletion Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 10 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Command line & Python library for obtaining details about a radio frequency
* Free software: MIT license
* Documentation: https://rf-info.readthedocs.io.
* Python 3.6, 3.7, 3.8 & pypy3 tested
* Linux & Windows with color terminal support


Features
Expand Down Expand Up @@ -72,7 +73,7 @@ Usage
Command Line:
::

$ rf-info <frequency> [<suffix>] [<country>]
$ rf-info <frequency> [<units>] [<country>]


Frequency format examples:
Expand All @@ -93,10 +94,17 @@ $ rf-info 000.012.500

Suffix examples:
hz, khz, Mhz, Ghz (Case Insensitive)
::

$ rf-info 123.100 mhz
$ rf-info 4.5 ghz

Country examples (2 digit, 3 digit, number, or name):
Country examples (2 digit abbriviation, 3 digit abbriviation, 3 digit number, or full name):
US, USA, 040, JPN, es, Spain (Case Insensitive)
::

$ rf-info 144.400.000 hz US
$ rf-info 88 mhz JPN

Python:
::
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
iso3166>=1.0.1
colorama>=0.4.3
97 changes: 70 additions & 27 deletions rf_info/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import argparse
import sys
import json

from colorama import Fore, Style, init, deinit
import rf_info


Expand All @@ -11,38 +13,79 @@ def main(argv=None):
argv = sys.argv[1:]
sys.tracebacklimit = 0 # Disable showing tracebacks
parser = argparse.ArgumentParser()
parser.add_argument('--version', '-v', action='version', version='%(prog)s {}'.format(rf_info.__version__))
parser.add_argument('--version', action='version', version='%(prog)s {}'.format(rf_info.__version__))
parser.add_argument('frequency', action='store', help='radio frequency')
parser.add_argument('unit', nargs='?', default='hz', help='hz, khz, mhz, ghz')
parser.add_argument('country', nargs='?', default='us', help='us, ca, uk, jp, etc...')
parser.add_argument('--raw', '-r', action='store_true', help='includes raw output (for debugging)')
parser.add_argument('--nocolor', action='store_true', help='no color terminal output')
parser.add_argument('--raw', action='store_true', help='raw output for parsing')
parser.add_argument('--json', action='store_true', help='json output for parsing')
args = parser.parse_args(argv)

result = rf_info.Frequency(str(args.frequency), unit=str(args.unit).lower(), country=str(args.country)).__dict__
print(' ')
for key, value in result.items():
if key.lower() == 'band_use':
if len(value) == 0:
print('%s: %s' % (key.title(), 'Unknown'))
else:
newval = ''
loop = 0
for each in value:
if loop == 0:
loop += 1
newval = each
else:
newval = f'{newval}, {each}'
print('%s: %s' % (key.title(), newval))
else:
if value is not None:
print('%s: %s' % (key.title(), value))
print(' ')
if args.raw:
print('Raw:')
for key, value in result.items():
print(f'{key}: {value}')
if not args.nocolor:
KEYCOLOR = Style.BRIGHT + Fore.WHITE
VALUECOLOR = Style.BRIGHT + Fore.YELLOW
RESET = Style.RESET_ALL
TRUECOLOR = Fore.GREEN
FALSECOLOR = Style.BRIGHT + Fore.RED
NOTESCOLOR = Fore.CYAN
ALLOCATIONCOLOR = Style.BRIGHT + Fore.YELLOW
init()
else:
KEYCOLOR = ''
VALUECOLOR = ''
RESET = ''
TRUECOLOR = ''
FALSECOLOR = ''
NOTESCOLOR = ''
ALLOCATIONCOLOR = ''

frequency_object = rf_info.Frequency(str(args.frequency), unit=str(args.unit).lower(), country=str(args.country))
frequency_dict = frequency_object.__dict__
if not args.raw and not args.json:
print(' ')
print(result)
for key, value in frequency_dict.items():
if value is not None:

if key == 'primary_allocation':
if len(value) > 0:
print(f'\n{KEYCOLOR}{key.title()}{RESET}:')
for each in value:
print(f' {ALLOCATIONCOLOR}{each}{RESET}')

elif key == 'secondary_allocation':
if len(value) > 0:
print(f'\n{KEYCOLOR}{key.title()}{RESET}:')
for each in value:
print(f' {ALLOCATIONCOLOR}{each}{RESET}')

elif key == 'allocation_notes':
if len(value) > 0:
print(f'\n{KEYCOLOR}{key.title()}{RESET}:')
for each in value:
print(f' {NOTESCOLOR}{each}{RESET}\n')

elif key == 'amateur_details':
if len(value) > 0:
print(f'{KEYCOLOR}{key.title()}{RESET}:')
for each in value:
print(f' {VALUECOLOR}{each}{RESET}')
else:
if not value:
print(f'{KEYCOLOR}{key.title()}{RESET}: {FALSECOLOR}{value}{RESET}')
elif isinstance(value, bool):
print(f'{KEYCOLOR}{key.title()}{RESET}: {TRUECOLOR}{value}{RESET}')
else:
print(f'{KEYCOLOR}{key.title()}{RESET}: {VALUECOLOR}{value}{RESET}')
print(' ')

elif not args.json:
for key, value in frequency_dict.items():
print(f'{key}={value}')
else:
print(json.dumps(frequency_dict, indent=4, sort_keys=False))

if not args.nocolor:
deinit()

return 0
102 changes: 51 additions & 51 deletions rf_info/data/us_extras.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,57 @@
from .rangekeydict import RangeKeyDict

AMATEUR = RangeKeyDict({
(1800000, 1831000): ('Class', 'Use', 'CW, RTTY, and other narrowband modes'),
(1830000, 1841000): ('Class', 'Use', 'CW, RTTY, and other narrowband modes, Intercontinental QSOs only'),
(1840000, 1851000): ('Class', 'Use', 'CW, SSB, SSTV, and other wideband modes, Intercontinental QSOs only'),
(1850000, 2000000): ('Class', 'Use', 'CW, Phone, SSTV and other wideband modes'),
(3590000, 3591000): ('Class', 'Use', 'RTTY DX'),
(3580000, 3621000): ('Class', 'Use', 'RTTY'),
(3620000, 3636000): ('Class', 'Use', 'Packet'),
(3790000, 3801000): ('Class', 'Use', 'DX Window'),
(3845000, 3846000): ('Class', 'Use', 'SSTV'),
(3885000, 3886000): ('Class', 'Use', 'AM calling frequency'),
(5332000, 5333000): ('Class', 'Use', '5330.5 kHz Amateur Tuning Frequency'),
(5348000, 5349000): ('Class', 'Use', '5346.5 kHz Amateur Tuning Frequency'),
(5368000, 5369000): ('Class', 'Use', '5366.5 kHz Amateur Tuning Frequency'),
(5373000, 5374000): ('Class', 'Use', '5371.5 kHz Amateur Tuning Frequency'),
(5405000, 5406000): ('Class', 'Use', '5403.5 kHz Amateur Tuning Frequency'),
(7040000, 7041000): ('Class', 'Use', 'RTTY DX'),
(7080000, 7101000): ('Class', 'Use', 'RTTY'),
(7171000, 7172000): ('Class', 'Use', 'SSTV'),
(7290000, 7291000): ('Class', 'Use', 'AM calling frequency'),
(10130000, 10141000): ('Class', 'Use', 'RTTY'),
(10140000, 10151000): ('Class', 'Use', 'Packet'),
(14070000, 14095000): ('Class', 'Use', 'RTTY'),
(14095000, 14100000): ('Class', 'Use', 'Packet'),
(14100000, 14101000): ('Class', 'Use', 'NCDXF Beacons'),
(14100000, 14113000): ('Class', 'Use', 'Packet'),
(14230000, 14231000): ('Class', 'Use', 'SSTV'),
(14286000, 14287000): ('Class', 'Use', 'AM calling frequency'),
(18100000, 18105000): ('Class', 'Use', 'RTTY'),
(18105000, 18110000): ('Class', 'Use', 'Packet'),
(21070000, 21101000): ('Class', 'Use', 'RTTY'),
(21100000, 21111000): ('Class', 'Use', 'Packet'),
(21340000, 21341000): ('Class', 'Use', 'SSTV'),
(24920000, 24926000): ('Class', 'Use', 'RTTY'),
(24925000, 24931000): ('Class', 'Use', 'Packet'),
(28000000, 28071000): ('Class', 'Use', 'CW'),
(28070000, 28151000): ('Class', 'Use', 'RTTY'),
(28150000, 28191000): ('Class', 'Use', 'CW'),
(28200000, 28301000): ('Class', 'Use', 'Beacons'),
(28300000, 29300000): ('Class', 'Use', 'Phone'),
(28680000, 28681000): ('Class', 'Use', 'SSTV'),
(29000000, 29201000): ('Class', 'Use', 'AM'),
(29300000, 29511000): ('Class', 'Use', 'Satellite Downlinks'),
(29520000, 29591000): ('Class', 'Use', 'Repeater Inputs'),
(29600000, 29601000): ('Class', 'Use', 'FM Simplex'),
(29610000, 29701000): ('Class', 'Use', 'Repeater Outputs'),
(144000000, 144051000): ('Class', 'Use', 'EME (CW)'),
(144050000, 144101000): ('Class', 'Use', 'General CW and weak signals'),
(144100000, 144201000): ('Class', 'Use', 'EME and weak signal SSB'),
(144200000, 144201000): ('Class', 'Use', 'National Calling Frequency'),
(144200000, 144275000): ('Class', 'Use', 'General SSB Operation'),
(144275000, 144301000): ('Class', 'Use', 'Propagation'),
(1800000, 1831000): (['Class', 'Use', 'CW, RTTY, and other narrowband modes']),
(1830000, 1841000): (['Class', 'Use', 'CW, RTTY, and other narrowband modes, Intercontinental QSOs only']),
(1840000, 1851000): (['Class', 'Use', 'CW, SSB, SSTV, and other wideband modes, Intercontinental QSOs only']),
(1850000, 2000000): (['Class', 'Use', 'CW, Phone, SSTV and other wideband modes']),
(3590000, 3591000): (['Class', 'Use', 'RTTY DX']),
(3580000, 3621000): (['Class', 'Use', 'RTTY']),
(3620000, 3636000): (['Class', 'Use', 'Packet']),
(3790000, 3801000): (['Class', 'Use', 'DX Window']),
(3845000, 3846000): (['Class', 'Use', 'SSTV']),
(3885000, 3886000): (['Class', 'Use', 'AM calling frequency']),
(5332000, 5333000): (['Class', 'Use', '5330.5 kHz Amateur Tuning Frequency']),
(5348000, 5349000): (['Class', 'Use', '5346.5 kHz Amateur Tuning Frequency']),
(5368000, 5369000): (['Class', 'Use', '5366.5 kHz Amateur Tuning Frequency']),
(5373000, 5374000): (['Class', 'Use', '5371.5 kHz Amateur Tuning Frequency']),
(5405000, 5406000): (['Class', 'Use', '5403.5 kHz Amateur Tuning Frequency']),
(7040000, 7041000): (['Class', 'Use', 'RTTY DX']),
(7080000, 7101000): (['Class', 'Use', 'RTTY']),
(7171000, 7172000): (['Class', 'Use', 'SSTV']),
(7290000, 7291000): (['Class', 'Use', 'AM calling frequency']),
(10130000, 10141000): (['Class', 'Use', 'RTTY']),
(10140000, 10151000): (['Class', 'Use', 'Packet']),
(14070000, 14095000): (['Class', 'Use', 'RTTY']),
(14095000, 14100000): (['Class', 'Use', 'Packet']),
(14100000, 14101000): (['Class', 'Use', 'NCDXF Beacons']),
(14100000, 14113000): (['Class', 'Use', 'Packet']),
(14230000, 14231000): (['Class', 'Use', 'SSTV']),
(14286000, 14287000): (['Class', 'Use', 'AM calling frequency']),
(18100000, 18105000): (['Class', 'Use', 'RTTY']),
(18105000, 18110000): (['Class', 'Use', 'Packet']),
(21070000, 21101000): (['Class', 'Use', 'RTTY']),
(21100000, 21111000): (['Class', 'Use', 'Packet']),
(21340000, 21341000): (['Class', 'Use', 'SSTV']),
(24920000, 24926000): (['Class', 'Use', 'RTTY']),
(24925000, 24931000): (['Class', 'Use', 'Packet']),
(28000000, 28071000): (['Class', 'Use', 'CW']),
(28070000, 28151000): (['Class', 'Use', 'RTTY']),
(28150000, 28191000): (['Class', 'Use', 'CW']),
(28200000, 28301000): (['Class', 'Use', 'Beacons']),
(28300000, 29300000): (['Class', 'Use', 'Phone']),
(28680000, 28681000): (['Class', 'Use', 'SSTV']),
(29000000, 29201000): (['Class', 'Use', 'AM']),
(29300000, 29511000): (['Class', 'Use', 'Satellite Downlinks']),
(29520000, 29591000): (['Class', 'Use', 'Repeater Inputs']),
(29600000, 29601000): (['Class', 'Use', 'FM Simplex']),
(29610000, 29701000): (['Class', 'Use', 'Repeater Outputs']),
(144000000, 144051000): (['Class', 'Use', 'EME (CW)']),
(144050000, 144101000): (['Class', 'Use', 'General CW and weak signals']),
(144100000, 144201000): (['Class', 'Use', 'EME and weak signal SSB']),
(144200000, 144201000): (['Class', 'Use', 'National Calling Frequency']),
(144200000, 144275000): (['Class', 'Use', 'General SSB Operation']),
(144275000, 144301000): (['Class', 'Use', 'Propagation']),
# (144050, 144101): ('Class', 'Use', 'New OSCAR sub-band'),
# (144050, 144101): ('Class', 'Use', 'Linear Translator Inputs'),
# (144050, 144101): ('Class', 'Use', 'FM Repeater Inputs'),
Expand Down
20 changes: 12 additions & 8 deletions rf_info/rf_info.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python3

from iso3166 import countries
from .data.international import COUNTRY_MAP

Expand All @@ -8,7 +9,6 @@ def remove_all_butfirst(s, substr):
return s[:first_occurrence] + s[first_occurrence:].replace(substr, "")



def parse_freq(freq, unit):
argfreq = freq.replace('.', '').replace(',', '').replace('_', '').replace(' ', '')
if unit.lower() == 'khz':
Expand Down Expand Up @@ -118,6 +118,16 @@ def __init__(self, freq, unit='hz', country='us'):

# Set Allocations
self.amateur = ALLOCATIONS[intfreq][0]
# Create Amateur Band Use
if 'AMATEUR' in locals():
am = AMATEUR[intfreq]
if am is None:
self.amateur_details = []
else:
self.amateur_details = am
else:
self.amateur_details = []

self.fixed_station = ALLOCATIONS[intfreq][1]
self.mobile_station = ALLOCATIONS[intfreq][2]
self.broadcast = ALLOCATIONS[intfreq][3]
Expand All @@ -135,15 +145,9 @@ def __init__(self, freq, unit='hz', country='us'):
self.band_use = tuple()
else:
self.band_use = tuple(self.band_use)
# Create Amateur Band Use
am = AMATEUR[intfreq]
if am is None:
self.amateur_band = ((False, ))
else:
self.amateur_band = ((True, )) + am
'''


def info(self):
return self.__dict__

Expand Down
28 changes: 18 additions & 10 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
import pytest
from rf_info import cli

MAX = 999999999999


MAX = 999_999_999_999
RAND_TESTS = 500
TEST_UNITS = (
('132.158.000', 'Hz', 'us', '132.158.000'),
('144.100.000', 'Hz', 'us', '144.100.000'),
('1,000,000', '', '', '1.000.000'),
('1000', 'HZ', 'GB', '1.000'),
('142.233', 'khz', 'JP', '142.233'),
Expand All @@ -22,9 +21,6 @@
)


RAND_TESTS = 500


def test_out_of_range():
with pytest.raises(Exception) as e:
freq = MAX + 1
Expand Down Expand Up @@ -57,13 +53,25 @@ def test_invalids():
def test_cli():
template = '{0:20s} | {1:20s} | {2:2s}'
print(' ')
print(template.format('FREQUENCY', 'suffix', '=='))
print(template.format('FREQUENCY', 'units', '=='))
for (freq, unit, country, expected) in TEST_UNITS:
exit_status = cli.main([str(freq), unit])
ok = 'OK' if exit_status == 0 else f'XX ({exit_status})'
print(template.format(str(freq), unit, ok))
assert exit_status == 0
exit_status = cli.main(['123', '-r'])

exit_status = cli.main(['123', '--raw'])
ok = 'OK' if exit_status == 0 else f'XX ({exit_status})'
print(template.format(str(freq), '-r', ok))
print(template.format(str(freq), '--raw', ok))
assert exit_status == 0

exit_status = cli.main(['144.100.000', '--json'])
ok = 'OK' if exit_status == 0 else f'XX ({exit_status})'
print(template.format(str(freq), '--json', ok))
assert exit_status == 0

exit_status = cli.main(['123', '--nocolor'])
ok = 'OK' if exit_status == 0 else f'XX ({exit_status})'
print(template.format(str(freq), '--nocolor', ok))
assert exit_status == 0

0 comments on commit b7ea83d

Please sign in to comment.