diff --git a/docs/build/doctrees/Callinfo.doctree b/docs/build/doctrees/Callinfo.doctree index 13b3186..2cf8431 100644 Binary files a/docs/build/doctrees/Callinfo.doctree and b/docs/build/doctrees/Callinfo.doctree differ diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index 516b185..fc4a825 100644 Binary files a/docs/build/doctrees/environment.pickle and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/lookuplib.doctree b/docs/build/doctrees/lookuplib.doctree index c788d02..eea2d5b 100644 Binary files a/docs/build/doctrees/lookuplib.doctree and b/docs/build/doctrees/lookuplib.doctree differ diff --git a/docs/build/html/Callinfo.html b/docs/build/html/Callinfo.html index 43e6330..6107d45 100644 --- a/docs/build/html/Callinfo.html +++ b/docs/build/html/Callinfo.html @@ -60,12 +60,348 @@
-class pyhamtools.callinfo.Callinfo(lookuplib)
-

This is going to going to return information for a callsign

+class pyhamtools.callinfo.Callinfo(lookuplib, logger=None) +

The purpose of this class is to return data (country, latitude, longitude, CQ Zone...etc) for an +Amateur Radio callsign. The class can be used with any lookup database, +provided through an Instance of LookupLib. +An instance of Lookuplib has to be injected on object construction.

+ +++ + + + +
Parameters:
    +
  • lookuplib (LookupLib) – instance of LookupLib
  • +
  • logger (logging.getLogger(__name__), optional) – Python logger
  • +
+
-
-getHomeCall(callsign)
-

verify call and strip off any /ea1 vp5/ /qrp etc

+
+get_adif_id(callsign, timestamp=datetime.datetime(2014, 4, 29, 13, 22, 14, 671563, tzinfo=<UTC>))
+

Returns ADIF id of a callsign’s country

+ +++ + + + + + + + + + +
Parameters:
    +
  • callsign (str) – Amateur Radio callsign
  • +
  • timestamp (datetime, optional) – datetime in UTC (tzinfo=pytz.UTC)
  • +
+
Returns:

containing the country ADIF id

+
Return type:

int

+
Raises:

KeyError – +No Country found for callsign

+
+
+ +
+
+get_all(callsign, timestamp=datetime.datetime(2014, 4, 29, 13, 22, 14, 671563, tzinfo=<UTC>))
+

Lookup a callsign and return all data available from the underlying database

+ +++ + + + + + + + + + +
Parameters:
    +
  • callsign (str) – Amateur Radio callsign
  • +
  • timestamp (datetime, optional) – datetime in UTC (tzinfo=pytz.UTC)
  • +
+
Returns:

Dictionary containing the callsign specific data

+
Return type:

dict

+
Raises:

KeyError – +Callsign could not be identified

+
+

Example

+

The following code returns all available information from the country-files.com database for the +callsign “DH1TW”

+
>>> from pyhamtools import LookupLib, Callinfo
+>>> my_lookuplib = LookupLib(lookuptype="countryfile")
+>>> cic = Callinfo(my_lookuplib)
+>>> cic.get_all("DH1TW")
+{
+     'country': 'Fed. Rep. of Germany',
+     'adif': 230,
+     'continent': 'EU',
+     'latitude': 51.0,
+     'longitude': -10.0,
+     'cqz': 14,
+     'ituz': 28
+}
+
+
+
+

Note

+

The content of the returned data depends entirely on the injected +LookupLib (and the used database). While the country-files.com provides +for example the ITU Zone, Clublog doesn’t. Consequently, the item “ituz” +would be missing with Clublog (API or XML) LookupLib.

+
+
+ +
+
+get_continent(callsign, timestamp=datetime.datetime(2014, 4, 29, 13, 22, 14, 671563, tzinfo=<UTC>))
+

Returns the continent Identifier of a callsign

+ +++ + + + + + + + + + +
Parameters:
    +
  • callsign (str) – Amateur Radio callsign
  • +
  • timestamp (datetime, optional) – datetime in UTC (tzinfo=pytz.UTC)
  • +
+
Returns:

continent identified

+
Return type:

str

+
Raises:

KeyError – +No Continent found for callsign

+
+
+

Note

+

The following continent identifiers are used:

+
    +
  • EU: Europe
  • +
  • NA: North America
  • +
  • SA: South America
  • +
  • AS: Asia
  • +
  • AF: Africa
  • +
  • OC: Oceania
  • +
  • AN: Antarctica
  • +
+
+
+ +
+
+get_country_name(callsign, timestamp=datetime.datetime(2014, 4, 29, 13, 22, 14, 671563, tzinfo=<UTC>))
+

Returns the country name where the callsign is located

+ +++ + + + + + + + + + +
Parameters:
    +
  • callsign (str) – Amateur Radio callsign
  • +
  • timestamp (datetime, optional) – datetime in UTC (tzinfo=pytz.UTC)
  • +
+
Returns:

name of the Country

+
Return type:

str

+
Raises:

KeyError – +No Country found for callsign

+
+
+

Note

+

Don’t rely on the country name when working with several instances of +:Callinfo. Clublog and Country-files.org use slightly different names +for countrys. Example: +Country-files.com: “Fed. Rep. of Germany” +Clublog: “FEDERAL REPUBLIC OF GERMANY”

+
+
+ +
+
+get_cqz(callsign, timestamp=datetime.datetime(2014, 4, 29, 13, 22, 14, 671563, tzinfo=<UTC>))
+

Returns CQ Zone of a callsign

+ +++ + + + + + + + + + +
Parameters:
    +
  • callsign (str) – Amateur Radio callsign
  • +
  • timestamp (datetime, optional) – datetime in UTC (tzinfo=pytz.UTC)
  • +
+
Returns:

containing the callsign’s CQ Zone

+
Return type:

int

+
Raises:

KeyError – +no CQ Zone found for callsign

+
+
+ +
+
+get_homecall(callsign)
+

Strips off country prefixes (HC2/**DH1TW) and activity suffixes (DH1TW/P**).

+ +++ + + + + + + + + + +
Parameters:callsign (str) – Amateur Radio callsign
Returns:callsign without country/activity pre/suffixes
Return type:str
Raises:ValueError – +No callsign found in string
+

Example

+

The following code retrieves the home call for “HC2/DH1TW/P”

+
>>> from pyhamtools import LookupLib, Callinfo
+>>> my_lookuplib = LookupLib(lookuptype="countryfile")
+>>> cic = Callinfo(my_lookuplib)
+>>> cic.get_homecall("HC2/DH1TW/P")
+DH1TW
+
+
+
+ +
+
+get_ituz(callsign, timestamp=datetime.datetime(2014, 4, 29, 13, 22, 14, 671563, tzinfo=<UTC>))
+

Returns ITU Zone of a callsign

+ +++ + + + + + + + + + +
Parameters:
    +
  • callsign (str) – Amateur Radio callsign
  • +
  • timestamp (datetime, optional) – datetime in UTC (tzinfo=pytz.UTC)
  • +
+
Returns:

containing the callsign’s CQ Zone

+
Return type:

int

+
Raises:

KeyError – +No ITU Zone found for callsign

+
+
+

Note

+

Currently, only Country-files.com lookup database contains ITU Zones

+
+
+ +
+
+get_lat_long(callsign)
+

Returns Latitude and Longitude for a callsign

+ +++ + + + + + + + + + +
Parameters:
    +
  • callsign (str) – Amateur Radio callsign
  • +
  • timestamp (datetime, optional) – datetime in UTC (tzinfo=pytz.UTC)
  • +
+
Returns:

Containing Latitude and Longitude

+
Return type:

dict

+
Raises:

KeyError – +No data found for callsign

+
+

Example

+

The following code returns Latitude & Longitude for “DH1TW”

+
>>> from pyhamtools import LookupLib, Callinfo
+>>> my_lookuplib = LookupLib(lookuptype="countryfile")
+>>> cic = Callinfo(my_lookuplib)
+>>> cic.get_lat_long("DH1TW")
+{
+   'latitude': 51.0,
+   'longitude': -10.0
+}
+
+
+
+

Note

+

Unfortunately, in most cases the returned Latitude and Longitude are not very precise. +Clublog and Country-files.com use the country’s capital coordinates in most cases, if no +dedicated entry in the database exists.

+
+
+ +
+
+is_valid_callsign(callsign, timestamp=datetime.datetime(2014, 4, 29, 13, 22, 14, 671563, tzinfo=<UTC>))
+

Checks if a callsign is valid

+ +++ + + + + + + + +
Parameters:
    +
  • callsign (str) – Amateur Radio callsign
  • +
  • timestamp (datetime, optional) – datetime in UTC (tzinfo=pytz.UTC)
  • +
+
Returns:

True / False

+
Return type:

bool

+
+

Example

+

The following checks if “DH1TW” is a valid callsign

+
>>> from pyhamtools import LookupLib, Callinfo
+>>> my_lookuplib = LookupLib(lookuptype="countryfile")
+>>> cic = Callinfo(my_lookuplib)
+>>> cic.is_valid_callsign("DH1TW")
+True
+
+
diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html index c353f6e..3dc6e40 100644 --- a/docs/build/html/genindex.html +++ b/docs/build/html/genindex.html @@ -70,7 +70,37 @@ + @@ -83,6 +113,12 @@
is_invalid_operation() (pyhamtools.lookuplib.LookupLib method)
+ +
-
getHomeCall() (pyhamtools.callinfo.Callinfo method) +
get_adif_id() (pyhamtools.callinfo.Callinfo method) +
+ + +
get_all() (pyhamtools.callinfo.Callinfo method) +
+ + +
get_continent() (pyhamtools.callinfo.Callinfo method) +
+ + +
get_country_name() (pyhamtools.callinfo.Callinfo method) +
+ +
+ +
get_cqz() (pyhamtools.callinfo.Callinfo method) +
+ + +
get_homecall() (pyhamtools.callinfo.Callinfo method) +
+ + +
get_ituz() (pyhamtools.callinfo.Callinfo method) +
+ + +
get_lat_long() (pyhamtools.callinfo.Callinfo method)
+ +
is_valid_callsign() (pyhamtools.callinfo.Callinfo method) +
+
diff --git a/docs/build/html/lookuplib.html b/docs/build/html/lookuplib.html index 8bf869a..1fd8fd5 100644 --- a/docs/build/html/lookuplib.html +++ b/docs/build/html/lookuplib.html @@ -85,7 +85,7 @@ lookup against the Clublog API.

-is_invalid_operation(callsign, timestamp=datetime.datetime(2014, 4, 25, 22, 19, 33, 219680, tzinfo=<UTC>))
+is_invalid_operation(callsign, timestamp=datetime.datetime(2014, 4, 29, 13, 1, 27, 518550, tzinfo=<UTC>))

Returns True if an operations is known as invalid

@@ -140,7 +140,7 @@ API Key for Clublog missing or incorrect
-lookup_callsign(callsign=None, timestamp=datetime.datetime(2014, 4, 25, 22, 19, 33, 219601, tzinfo=<UTC>))
+lookup_callsign(callsign=None, timestamp=datetime.datetime(2014, 4, 29, 13, 1, 27, 518519, tzinfo=<UTC>))

Returns lookup data if an exception exists for a callsign

@@ -244,7 +244,7 @@ the id 273.

-lookup_prefix(prefix, timestamp=datetime.datetime(2014, 4, 25, 22, 19, 33, 219601, tzinfo=<UTC>))
+lookup_prefix(prefix, timestamp=datetime.datetime(2014, 4, 29, 13, 1, 27, 518519, tzinfo=<UTC>))

Returns lookup data of a Prefix

@@ -301,7 +301,7 @@ database (default database).

-lookup_zone_exception(callsign, timestamp=datetime.datetime(2014, 4, 25, 22, 19, 33, 219687, tzinfo=<UTC>))
+lookup_zone_exception(callsign, timestamp=datetime.datetime(2014, 4, 29, 13, 1, 27, 518556, tzinfo=<UTC>))

Returns a CQ Zone if an exception exists for the given callsign

Args: callsign (string): Amateur radio callsign diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv index 122f8d0..479e5aa 100644 --- a/docs/build/html/objects.inv +++ b/docs/build/html/objects.inv @@ -2,5 +2,7 @@ # Project: pyhamtools # Version: 0.1 # The remainder of this file is compressed using zlib. -xڭn0D|rU\PJoU^+6UCpBVpxZNפ - 33^&ze5+ФDzPm٤ƨhxS5,\(Kb;emg;;,"l)9Z*"'fok"9;hU@` k^Qˇ $=El!r-T#kZt~#e asg1 \ No newline at end of file +xڭSAj0j\sBJZՒW4qj f43VZA(@l\ T Ц{E􃎊D YO i&*ظ&iki,bI?c Yv.Bk%M#8GNjRl{4ˢ&.9/QqrЈd'̊EVˢ%Wx +K +Kj +ER ocYIpJӮ%ysmKKBcV+<d \ No newline at end of file diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js index 53333c6..c8bb064 100644 --- a/docs/build/html/searchindex.js +++ b/docs/build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{oper:4,all:[4,3],code:[0,4],identifi:4,show:4,illustr:[],text:[],obtain:[4,3],myapikei:4,prefix:4,radio:[0,4],invalid:4,permiss:3,follow:[0,4,3],lookup:4,apikeymissingerror:4,entiti:4,xml:4,content:[],clublogxml:4,depend:4,copyright:3,also:4,"true":4,explain:[],tobia:3,except:4,should:[],tort:3,other:3,dict:4,ituz:4,queri:4,tzinfo:4,aris:3,logger:4,therefor:4,local:4,match:4,merchant:3,applic:0,lookup_ent:4,sourc:4,"return":[1,4],string:4,variou:4,countryfil:4,python:[0,4],timestamp:4,express:3,dai:4,"import":4,veri:[],liabl:3,month:4,associ:3,requir:4,warranti:3,like:0,specif:4,complic:[],"try":4,provid:[4,3],stuff:[],necessari:[0,4],contain:[0,4],found:4,readthedoc:0,page:0,impli:3,right:3,deal:3,example_gener:[],replac:4,some:0,see:0,callsign:[0,1,4],connect:[4,3],arg:4,download:4,germani:4,event:3,librari:[0,4],out:3,even:4,index:0,lookuptyp:4,turkmenistan:4,lookup_prefix:4,databas:4,rep:4,publish:3,lookup_zone_except:4,current:0,delet:4,written:[],version:0,inject:4,action:3,internet:4,print:4,condit:3,irc:0,bla:[],method:4,str:4,kei:4,longitud:4,given:4,free:3,dictionari:4,locat:4,come:0,lookup_callsign:4,valu:4,christma:4,search:0,fit:3,island:4,cty:4,against:4,datetim:4,instanc:4,doctest:[],permit:3,fals:4,countri:4,typic:4,dh1tw:[0,2,3],com:[0,4],assign:4,frequent:0,"default":4,vp5:1,softwar:3,adif:4,directli:4,modul:[],damag:3,three:4,qrp:1,filenam:4,api:4,strip:1,ea1:1,noresult:[],miss:4,merg:3,liabil:3,differ:4,from:[4,3],log:4,wai:[],cqz:4,modifi:3,etc:1,contact:[],two:4,wrapper:4,github:0,avail:4,whom:3,station:4,interfac:4,includ:3,paramet:4,call:1,daili:4,type:4,more:4,"function":[],amateur:[0,4],option:4,copi:3,keyerror:4,notic:3,is_invalid_oper:4,pytz:4,pars:0,callinfo:[],particular:3,known:4,herebi:3,holder:3,utc:4,kind:3,whether:3,access:[],structur:[],exampl:4,aim:4,record:4,contin:4,limit:3,can:4,abov:3,webirc:0,otherwis:3,hamtest:0,purpos:3,latitud:4,claim:3,file:[0,4,3],creat:0,"int":4,descript:[],year:4,my_lookuplib:4,ani:[1,3],dp0gvn:4,antarctica:4,inform:[1,4],exist:4,contract:3,substanti:3,onlin:4,seem:4,deltaxrai:0,plist:4,sell:3,vk9xo:4,mylookuplib:4,date:4,author:3,perform:4,apikei:4,when:4,detail:4,same:4,check:4,note:[],how:4,valid:4,bool:4,which:[0,4],none:4,verifi:1,you:0,subject:3,mit:[0,3],lookuplib:[],updat:4,incorrect:4,"5w1cfn":4,http:[0,4],clublog:4,shall:3,org:[0,4],fed:4,restrict:3,befor:4,zone:4,rais:4,distribut:3,sublicens:3,bsd:[],data:4,"class":[0,1,4],charg:3,homogen:4,noninfring:3,infrequ:4,off:1,faster:0,"__name__":4,grant:3,clublogapi:4,wellnitz:3,without:3,issu:0,person:3,portion:3,getter:[],gethomecal:1,getlogg:4,thi:[1,4,3],time:4,format:[],hello:[],furnish:3},objtypes:{"0":"py:module","1":"py:method","2":"py:class"},objnames:{"0":["py","module","Python module"],"1":["py","method","Python method"],"2":["py","class","Python class"]},filenames:["index","Callinfo","help","license","LookupLib"],titles:["PyHamTools","Callinfo","help","license","LookupLib"],objects:{pyhamtools:{callinfo:[1,0,0,"-"],lookuplib:[4,0,0,"-"]},"pyhamtools.callinfo.Callinfo":{getHomeCall:[1,1,1,""]},"pyhamtools.lookuplib":{LookupLib:[4,2,1,""]},"pyhamtools.lookuplib.LookupLib":{lookup_prefix:[4,1,1,""],lookup_entity:[4,1,1,""],lookup_zone_exception:[4,1,1,""],lookup_callsign:[4,1,1,""],is_invalid_operation:[4,1,1,""]},"pyhamtools.callinfo":{Callinfo:[1,2,1,""]}},titleterms:{help:2,anoth:[],licens:3,clase:0,simpl:[],indic:0,content:[],header:[],contact:3,tabl:0,pyhamtool:0,document:[],callinfo:1,modul:0,lookuplib:4,welcom:[]}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{vp5:[],all:[1,4,3],code:[0,1,4],identifi:[1,4],show:4,illustr:[],text:[],obtain:[4,3],damag:3,myapikei:4,prefix:[1,4],get_contin:1,publish:3,permiss:3,follow:[0,1,4,3],itu:1,apikeymissingerror:4,entiti:4,xml:[1,4],content:[],onli:1,clublogxml:4,depend:[1,4],copyright:3,also:4,adif:[1,4],"true":[1,4],explain:[],tobia:3,except:4,should:[],tort:3,other:3,dict:[1,4],ituz:[1,4],queri:4,tzinfo:[1,4],aris:3,logger:[1,4],therefor:4,local:4,match:4,merchant:3,applic:0,lookup_ent:4,sourc:4,"return":[1,4],string:[1,4],variou:4,format:[],python:[0,1,4],timestamp:[1,4],express:3,dai:4,feder:1,"import":[1,4],veri:1,liabl:3,month:4,geo:[],requir:4,name:1,warranti:3,like:0,specif:[1,4],descript:[],complic:[],"try":4,whether:3,republ:1,stuff:[],necessari:[0,4],contain:[0,1,4],found:[1,4],readthedoc:0,where:1,page:0,get_cqz:1,impli:3,right:3,deal:3,replac:4,some:0,consequ:1,see:0,callsign:[0,1,4],connect:[4,3],arg:4,download:4,home:1,event:3,librari:[0,4],out:3,even:4,index:0,oceania:1,lookuptyp:[1,4],turkmenistan:4,item:1,lookup_prefix:4,databas:[1,4],rep:[1,4],asia:1,lookup_zone_except:4,current:[0,1],delet:4,written:[],version:0,inject:[1,4],internet:4,print:4,condit:3,irc:0,bla:[],method:4,provid:[1,4,3],str:[1,4],kei:4,longitud:[1,4],differ:[1,4],free:3,entir:1,dictionari:[1,4],europ:1,come:0,lookup_callsign:4,valu:4,christma:4,hc2:1,sell:3,search:0,perform:4,fit:3,most:1,germani:[1,4],island:4,could:1,slightli:1,cty:4,against:4,unfortun:1,precis:1,datetim:[1,4],instanc:[1,4],doctest:[],permit:3,fals:[1,4],countri:[1,4],typic:4,dh1tw:[0,1,2,3],com:[0,1,4],assign:4,frequent:0,oper:4,softwar:3,get_ituz:1,suffix:1,directli:4,activ:1,modul:[],africa:1,three:4,qrp:[],filenam:4,api:[1,4],wrapper:4,strip:1,ea1:[],noresult:[],miss:[1,4],fed:[1,4],merg:3,liabil:3,given:4,latitud:[1,4],from:[1,4,3],log:[1,4],wai:[],cqz:[1,4],modifi:3,daili:4,etc:1,contact:[],two:4,construct:1,github:0,avail:[1,4],whom:3,reli:1,station:4,interfac:4,includ:3,paramet:[1,4],call:1,underli:1,locat:[1,4],type:[1,4],valueerror:1,more:4,"function":[],plist:4,capit:1,through:1,option:[1,4],copi:3,keyerror:[1,4],notic:3,lookup:[1,4],is_invalid_oper:4,pytz:[1,4],pars:0,callinfo:[],particular:3,known:4,off:1,herebi:3,holder:3,cic:1,utc:[1,4],kind:3,dedic:1,retriev:1,"default":4,access:[],none:[1,4],structur:[],exampl:[1,4],aim:4,record:4,"while":1,contin:[1,4],limit:3,can:[1,4],abov:3,webirc:0,otherwis:3,hamtest:0,purpos:[1,3],radio:[0,1,4],associ:3,pre:1,claim:3,would:1,file:[0,1,4,3],creat:0,"int":[1,4],get_homecal:1,year:4,my_lookuplib:[1,4],ani:[1,3],doesn:1,dp0gvn:4,"case":1,antarctica:[1,4],inform:[1,4],exist:[1,4],contract:3,substanti:3,onlin:4,seem:4,deltaxrai:0,action:3,sever:1,incorrect:4,vk9xo:4,mylookuplib:4,date:4,author:3,check:[1,4],get_country_nam:1,apikei:4,when:[1,4],detail:4,same:4,get_lat_long:1,note:[],how:4,amateur:[0,1,4],valid:[1,4],bool:[1,4],which:[0,4],get_adif_id:1,verifi:[],you:0,subject:3,mit:[0,3],lookuplib:[],updat:4,furnish:3,example_gener:[],"5w1cfn":4,http:[0,4],clublog:[1,4],shall:3,org:[0,1,4],object:1,restrict:3,invalid:4,befor:4,zone:[1,4],rais:[1,4],countryfil:[1,4],work:1,distribut:3,sublicens:3,bsd:[],america:1,data:[1,4],"class":[0,1,4],charg:3,is_valid_callsign:1,homogen:4,noninfring:3,infrequ:4,don:1,faster:0,coordin:1,entri:1,"__name__":[1,4],grant:3,clublogapi:4,wellnitz:3,without:[1,3],issu:0,person:3,portion:3,getter:[],gethomecal:[],south:1,thi:[1,4,3],time:4,north:1,get_al:1,hello:[],getlogg:[1,4]},objtypes:{"0":"py:module","1":"py:method","2":"py:class"},objnames:{"0":["py","module","Python module"],"1":["py","method","Python method"],"2":["py","class","Python class"]},filenames:["index","Callinfo","help","license","LookupLib"],titles:["PyHamTools","Callinfo","help","license","LookupLib"],objects:{pyhamtools:{callinfo:[1,0,0,"-"],lookuplib:[4,0,0,"-"]},"pyhamtools.callinfo.Callinfo":{get_continent:[1,1,1,""],get_cqz:[1,1,1,""],get_homecall:[1,1,1,""],get_country_name:[1,1,1,""],get_all:[1,1,1,""],get_lat_long:[1,1,1,""],is_valid_callsign:[1,1,1,""],get_adif_id:[1,1,1,""],get_ituz:[1,1,1,""]},"pyhamtools.lookuplib":{LookupLib:[4,2,1,""]},"pyhamtools.lookuplib.LookupLib":{lookup_prefix:[4,1,1,""],lookup_entity:[4,1,1,""],lookup_zone_exception:[4,1,1,""],lookup_callsign:[4,1,1,""],is_invalid_operation:[4,1,1,""]},"pyhamtools.callinfo":{Callinfo:[1,2,1,""]}},titleterms:{help:2,anoth:[],licens:3,clase:0,simpl:[],indic:0,content:[],header:[],contact:3,tabl:0,pyhamtool:0,document:[],callinfo:1,modul:0,lookuplib:4,welcom:[]}}) \ No newline at end of file diff --git a/pyhamtools/__init__.py b/pyhamtools/__init__.py index ce01da8..10baab5 100644 --- a/pyhamtools/__init__.py +++ b/pyhamtools/__init__.py @@ -1,4 +1,3 @@ from pyhamtools.lookuplib import LookupLib from pyhamtools.callinfo import Callinfo - diff --git a/pyhamtools/callinfo.py b/pyhamtools/callinfo.py index 90542ea..02abd69 100644 --- a/pyhamtools/callinfo.py +++ b/pyhamtools/callinfo.py @@ -1,6 +1,7 @@ import re import logging from datetime import datetime +import sys import pytz @@ -13,26 +14,61 @@ from pyhamtools.consts import LookupConventions as const UTC = pytz.UTC timestamp_now = datetime.utcnow().replace(tzinfo=UTC) +if sys.version_info < (2, 7, ): + class NullHandler(logging.Handler): + def emit(self, record): + pass class Callinfo(object): """ - This is going to going to return information for a callsign + The purpose of this class is to return data (country, latitude, longitude, CQ Zone...etc) for an + Amateur Radio callsign. The class can be used with any lookup database, + provided through an Instance of :py:class:`LookupLib`. + An instance of :py:class:`Lookuplib` has to be injected on object construction. + + Args: + lookuplib (:py:class:`LookupLib`) : instance of :py:class:`LookupLib` + logger (logging.getLogger(__name__), optional): Python logger + """ - def __init__(self, lookuplib=LookupLib(), logger=None): + def __init__(self, lookuplib, logger=None): self._logger = None if logger: self._logger = logger else: self._logger = logging.getLogger(__name__) - self._logger.addHandler(logging.NullHandler()) + if sys.version_info[:2] == (2, 6): + self._logger.addHandler(NullHandler()) + else: + self._logger.addHandler(logging.NullHandler()) self._lookuplib = lookuplib self._callsign_info = None def get_homecall(self, callsign): - """verify call and strip off any /ea1 vp5/ /qrp etc""" + """Strips off country prefixes (**HC2/**DH1TW) and activity suffixes (DH1TW**/P**). + + Args: + callsign (str): Amateur Radio callsign + + Returns: + str: callsign without country/activity pre/suffixes + + Raises: + ValueError: No callsign found in string + + Example: + The following code retrieves the home call for "HC2/DH1TW/P" + + >>> from pyhamtools import LookupLib, Callinfo + >>> my_lookuplib = LookupLib(lookuptype="countryfile") + >>> cic = Callinfo(my_lookuplib) + >>> cic.get_homecall("HC2/DH1TW/P") + DH1TW + + """ callsign = callsign.upper() homecall = re.search('[\d]{0,1}[A-Z]{1,2}\d([A-Z]{1,4}|\d{3,3}|\d{1,3}[A-Z])[A-Z]{0,5}', callsign) @@ -40,7 +76,8 @@ class Callinfo(object): homecall = homecall.group(0) return homecall else: - return + raise ValueError + def _iterate_prefix(self, callsign, timestamp=timestamp_now): """truncate call until it corresponds to a Prefix in the database""" @@ -55,7 +92,17 @@ class Callinfo(object): raise KeyError def _dismantle_callsign(self, callsign, timestamp=timestamp_now): + """ try to identify the callsign's identity by analyzing it in the following order: + Args: + callsign (str): Amateur Radio callsign + timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC) + + Raises: + KeyError: Callsign could not be identified + + + """ entire_callsign = callsign.upper() if re.search('[/A-Z0-9\-]{3,15}', entire_callsign): # make sure the call has at least 3 characters @@ -150,7 +197,43 @@ class Callinfo(object): def get_all(self, callsign, timestamp=timestamp_now): + """ Lookup a callsign and return all data available from the underlying database + Args: + callsign (str): Amateur Radio callsign + timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC) + + Returns: + dict: Dictionary containing the callsign specific data + + Raises: + KeyError: Callsign could not be identified + + Example: + The following code returns all available information from the country-files.com database for the + callsign "DH1TW" + + >>> from pyhamtools import LookupLib, Callinfo + >>> my_lookuplib = LookupLib(lookuptype="countryfile") + >>> cic = Callinfo(my_lookuplib) + >>> cic.get_all("DH1TW") + { + 'country': 'Fed. Rep. of Germany', + 'adif': 230, + 'continent': 'EU', + 'latitude': 51.0, + 'longitude': -10.0, + 'cqz': 14, + 'ituz': 28 + } + + Note: + The content of the returned data depends entirely on the injected + :py:class:`LookupLib` (and the used database). While the country-files.com provides + for example the ITU Zone, Clublog doesn't. Consequently, the item "ituz" + would be missing with Clublog (API or XML) :py:class:`LookupLib`. + + """ callsign_data = self._lookup_callsign(callsign, timestamp_now) try: @@ -159,18 +242,65 @@ class Callinfo(object): except KeyError: pass - print callsign_data - return callsign_data def is_valid_callsign(self, callsign, timestamp=timestamp_now): + """ Checks if a callsign is valid + + Args: + callsign (str): Amateur Radio callsign + timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC) + + Returns: + bool: True / False + + Example: + The following checks if "DH1TW" is a valid callsign + + >>> from pyhamtools import LookupLib, Callinfo + >>> my_lookuplib = LookupLib(lookuptype="countryfile") + >>> cic = Callinfo(my_lookuplib) + >>> cic.is_valid_callsign("DH1TW") + True + + """ try: if self.get_all(callsign, timestamp): return True - except: + except KeyError: return False def get_lat_long(self, callsign): + """ Returns Latitude and Longitude for a callsign + + Args: + callsign (str): Amateur Radio callsign + timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC) + + Returns: + dict: Containing Latitude and Longitude + + Raises: + KeyError: No data found for callsign + + Example: + The following code returns Latitude & Longitude for "DH1TW" + + >>> from pyhamtools import LookupLib, Callinfo + >>> my_lookuplib = LookupLib(lookuptype="countryfile") + >>> cic = Callinfo(my_lookuplib) + >>> cic.get_lat_long("DH1TW") + { + 'latitude': 51.0, + 'longitude': -10.0 + } + + Note: + Unfortunately, in most cases the returned Latitude and Longitude are not very precise. + Clublog and Country-files.com use the country's capital coordinates in most cases, if no + dedicated entry in the database exists. + + """ callsign_data = self.get_all(callsign, timestamp=timestamp_now) return { const.LATITUDE : callsign_data[const.LATITUDE], @@ -178,30 +308,101 @@ class Callinfo(object): } def get_cqz(self, callsign, timestamp=timestamp_now): + """ Returns CQ Zone of a callsign + + Args: + callsign (str): Amateur Radio callsign + timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC) + + Returns: + int: containing the callsign's CQ Zone + + Raises: + KeyError: no CQ Zone found for callsign + + """ return self.get_all(callsign, timestamp)[const.CQZ] def get_ituz(self, callsign, timestamp=timestamp_now): + """ Returns ITU Zone of a callsign + + Args: + callsign (str): Amateur Radio callsign + timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC) + + Returns: + int: containing the callsign's CQ Zone + + Raises: + KeyError: No ITU Zone found for callsign + + Note: + Currently, only Country-files.com lookup database contains ITU Zones + + """ return self.get_all(callsign, timestamp)[const.ITUZ] def get_country_name(self, callsign, timestamp=timestamp_now): + """ Returns the country name where the callsign is located + + Args: + callsign (str): Amateur Radio callsign + timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC) + + Returns: + str: name of the Country + + Raises: + KeyError: No Country found for callsign + + Note: + Don't rely on the country name when working with several instances of + :Callinfo. Clublog and Country-files.org use slightly different names + for countrys. Example: + Country-files.com: "Fed. Rep. of Germany" + Clublog: "FEDERAL REPUBLIC OF GERMANY" + + """ return self.get_all(callsign, timestamp)[const.COUNTRY] def get_adif_id(self, callsign, timestamp=timestamp_now): + """ Returns ADIF id of a callsign's country + + Args: + callsign (str): Amateur Radio callsign + timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC) + + Returns: + int: containing the country ADIF id + + Raises: + KeyError: No Country found for callsign + + """ return self.get_all(callsign, timestamp)[const.ADIF] def get_continent(self, callsign, timestamp=timestamp_now): - return self.get_all(callsign, timestamp)[const.CONTINENT] + """ Returns the continent Identifier of a callsign -if __name__ == "__main__": - import logging.config - logging.config.fileConfig("logging.ini") - logger = logging.getLogger(__name__) + Args: + callsign (str): Amateur Radio callsign + timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC) + Returns: + str: continent identified - from pyhamtools import LookupLib - apikey = "67547d6ce7a37276373b0568e3e52c1d3e2cb0e5" - l = LookupLib("clublogxml", apikey=apikey) - c = Callinfo(l) - print c._iterate_prefix("DH1TW") - print c._iterate_prefix("QRM") + Raises: + KeyError: No Continent found for callsign + Note: + The following continent identifiers are used: + + - EU: Europe + - NA: North America + - SA: South America + - AS: Asia + - AF: Africa + - OC: Oceania + - AN: Antarctica + """ + return self.get_all(callsign, timestamp)[const.CONTINENT] \ No newline at end of file diff --git a/pyhamtools/consts.py b/pyhamtools/consts.py index 9210ada..965497d 100644 --- a/pyhamtools/consts.py +++ b/pyhamtools/consts.py @@ -17,4 +17,24 @@ class LookupConventions: WHITELIST = "whitelist" WHITELIST_START = "whitelist_start" WHITELIST_END = "whitelist_end" - DELETED = "deleted" \ No newline at end of file + DELETED = "deleted" + +class Modes: + """ Constants for Operating modes """ + + CW = "CW" + USB = "USB" + LSB = "LSB" + DIGITAL = "DIGITAL" + FM = "FM" + +class DXSpot: + """ Constants used for DX Spots """ + + SPOTTER = "spotter" + DX = "dx" + FREQUENCY = "frequency" + COMMENT = "comment" + TIME = "time" + BAND = "band" + MODE = "mode" \ No newline at end of file diff --git a/pyhamtools/dxcluster.py b/pyhamtools/dxcluster.py new file mode 100644 index 0000000..9e35737 --- /dev/null +++ b/pyhamtools/dxcluster.py @@ -0,0 +1,60 @@ +__author__ = 'dh1tw' + +from datetime import datetime +import re + + +import pytz + +UTC = pytz.UTC + +from pyhamtools.utils import freq_to_band +from pyhamtools.consts import Modes as mode +from pyhamtools.consts import DXSpot as dxspot + + +def decode_spot(raw_string): + """Chop Line from DX-Cluster into pieces and return a dict with the spot data""" + + spotter_call = None + dx_call = None + frequency = None + comment = None + spot_time = None + band = None + mode = None + bandmode = None + + # Spotter callsign + if re.match('[A-Za-z0-9\/]+[:$]', raw_string[6:15]): + spotter_call = re.sub(':', '', re.match('[A-Za-z0-9\/]+[:$]', raw_string[6:15]).group(0)) + else: + raise ValueError + + if re.search('[0-9\.]{5,12}', raw_string[10:25]): + frequency = float(re.search('[0-9\.]{5,12}', raw_string[10:25]).group(0)) + else: + raise ValueError + + dx_call = re.sub('[^A-Za-z0-9\/]+', '', raw_string[26:38]) + comment = re.sub('[^\sA-Za-z0-9\.,;\#\+\-!\?\$\(\)@\/]+', ' ', raw_string[39:69]) + spot_time_ = re.sub('[^0-9]+', '', raw_string[70:74]) + spot_time = datetime(hour=int(spot_time_[0:2]), minute=int(spot_time_[2:4]), second=0, microsecond = 0, tzinfo=UTC) + + try: + bandmode = freq_to_band(frequency) + band = bandmode["band"] + mode = bandmode["mode"] + except KeyError: + raise ValueError + + data = { + dxspot.SPOTTER: spotter_call, + dxspot.DX: dx_call, + dxspot.BAND: band, + dxspot.MODE: mode, + dxspot.COMMENT: comment, + dxspot.TIME: spot_time + } + + return data diff --git a/pyhamtools/logging.ini b/pyhamtools/logging.ini new file mode 100644 index 0000000..4c8fca4 --- /dev/null +++ b/pyhamtools/logging.ini @@ -0,0 +1,22 @@ +[loggers] +keys=root + +[handlers] +keys=consoleHandler + +[formatters] +keys=simpleFormatter + +[logger_root] +level=DEBUG +handlers=consoleHandler + +[handler_consoleHandler] +class=StreamHandler +level=DEBUG +formatter=simpleFormatter +args=(sys.stdout,) + +[formatter_simpleFormatter] +format=%(asctime)s - %(name)s - %(levelname)s - %(message)s +datefmt= \ No newline at end of file diff --git a/pyhamtools/lookuplib.py b/pyhamtools/lookuplib.py index dc514e0..408064f 100644 --- a/pyhamtools/lookuplib.py +++ b/pyhamtools/lookuplib.py @@ -8,7 +8,7 @@ import xml.etree.ElementTree as ET import urllib import json import copy - +import sys import requests from requests.exceptions import ConnectionError, HTTPError, Timeout @@ -21,6 +21,10 @@ from exceptions import APIKeyMissingError UTC = pytz.UTC timestamp_now = datetime.utcnow().replace(tzinfo=UTC) +if sys.version_info < (2, 7,): + class NullHandler(logging.Handler): + def emit(self, record): + pass class LookupLib(object): """ @@ -55,7 +59,10 @@ class LookupLib(object): self._logger = logger else: self._logger = logging.getLogger(__name__) - self._logger.addHandler(logging.NullHandler()) + if sys.version_info[:2] == (2, 6): + self._logger.addHandler(NullHandler()) + else: + self._logger.addHandler(logging.NullHandler()) self._apikey = apikey self._download = True @@ -201,7 +208,6 @@ class LookupLib(object): if self._callsign_exceptions[item][const.START] < timestamp: callsign_data = copy.deepcopy(self._callsign_exceptions[item]) del callsign_data[const.START] - print callsign + ": " + "here1" return callsign_data # enddate > timestamp @@ -209,7 +215,6 @@ class LookupLib(object): if self._callsign_exceptions[item][const.END] > timestamp: callsign_data = copy.deepcopy(self._callsign_exceptions[item]) del callsign_data[const.END] - print callsign + ": " + "here2" return callsign_data # startdate > timestamp > enddate @@ -219,15 +224,12 @@ class LookupLib(object): callsign_data = copy.deepcopy(self._callsign_exceptions[item]) del callsign_data[const.START] del callsign_data[const.END] - print callsign + ": " + "here3" return callsign_data # no startdate or enddate available elif not const.START in self._callsign_exceptions[item] and not const.END in self._callsign_exceptions[item]: - print callsign + ": " + "here4" return self._callsign_exceptions[item] - print callsign + ": " + "here5" # no matching case raise KeyError @@ -588,11 +590,15 @@ class LookupLib(object): # unzip file, if gz if os.path.splitext(download_file_path)[1][1:] == "gz": - with gzip.open(download_file_path, "r") as download_file: + + download_file = gzip.open(download_file_path, "r") + try: cty_file_path = os.path.join(os.path.splitext(download_file_path)[0]) with open(cty_file_path, "w") as cty_file: cty_file.write(download_file.read()) - self._logger.debug(str(cty_file_path) + " successfully extracted") + self._logger.debug(str(cty_file_path) + " successfully extracted") + finally: + download_file.close() else: cty_file_path = download_file_path diff --git a/pyhamtools/utils.py b/pyhamtools/utils.py new file mode 100644 index 0000000..b2e8f14 --- /dev/null +++ b/pyhamtools/utils.py @@ -0,0 +1,135 @@ +from pyhamtools.consts import Modes as const + + +def freq_to_band(freq): + """converts a frequency [kHz] into the band and looks up the mode""" + band = None + mode = None + if ((freq >= 135) and (freq <= 138)): + band = 2190 + mode = const.CW + elif ((freq >= 1800) and (freq <= 2000)): + band = 160 + if ((freq >= 1800) and (freq < 1838)): + mode = const.CW + elif ((freq >= 1838) and (freq < 1840)): + mode = const.DIGITAL + elif ((freq >= 1840) and (freq < 2000)): + mode = const.LSB + elif ((freq >= 3500) and (freq <= 4000)): + band = 80 + if ((freq >= 3500) and (freq < 3580)): + mode = const.CW + elif ((freq >= 3580) and (freq < 3600)): + mode = const.DIGITAL + elif ((freq >= 3600) and (freq < 4000)): + mode = const.LSB + elif ((freq >= 5000) and (freq <= 5500)): + band = 60 + elif ((freq >= 7000) and (freq <= 7300)): + band = 40 + if ((freq >= 7000) and (freq < 7040)): + mode = const.CW + elif ((freq >= 7040) and (freq < 7050)): + mode = const.DIGITAL + elif ((freq >= 7050) and (freq < 7300)): + mode = const.LSB + elif ((freq >= 10100) and (freq <= 10150)): + band = 30 + if ((freq >= 10100) and (freq < 10140)): + mode = const.CW + elif ((freq >= 10140) and (freq < 10150)): + mode = const.DIGITAL + elif ((freq >= 14000) and (freq <= 14350)): + band = 20 + if ((freq >= 14000) and (freq < 14070)): + mode = const.CW + elif ((freq >= 14070) and (freq < 14099)): + mode = const.DIGITAL + elif ((freq >= 14100) and (freq < 14350)): + mode = const.USB + elif ((freq >= 18068) and (freq <= 18268)): + band = 17 + if ((freq >= 18068) and (freq < 18095)): + mode = const.CW + elif ((freq >= 18095) and (freq < 18110)): + mode = const.DIGITAL + elif ((freq >= 18110) and (freq < 18268)): + mode = const.USB + elif ((freq >= 21000) and (freq <= 21450)): + band = 15 + if ((freq >= 21000) and (freq < 21070)): + mode = const.CW + elif ((freq >= 21070) and (freq < 21150)): + mode = const.DIGITAL + elif ((freq >= 21150) and (freq < 21450)): + mode = const.USB + elif ((freq >= 24890) and (freq <= 24990)): + band = 12 + if ((freq >= 24890) and (freq < 24915)): + mode = const.CW + elif ((freq >= 24915) and (freq < 24930)): + mode = const.DIGITAL + elif ((freq >= 24930) and (freq < 24990)): + mode = const.USB + elif ((freq >= 28000) and (freq <= 29700)): + band = 10 + if ((freq >= 28000) and (freq < 28070)): + mode = const.CW + elif ((freq >= 28070) and (freq < 28190)): + mode = const.DIGITAL + elif ((freq >= 28300) and (freq < 29700)): + mode = const.USB + elif ((freq >= 50000) and (freq <= 54000)): + band = 6 + if ((freq >= 50000) and (freq < 50100)): + mode = const.CW + elif ((freq >= 50100) and (freq < 50500)): + mode = const.USB + elif ((freq >= 50500) and (freq < 51000)): + mode = const.DIGITAL + elif ((freq >= 70000) and (freq <= 71000)): + band = 4 + mode = None + elif ((freq >= 144000) and (freq <= 148000)): + band = 2 + if ((freq >= 144000) and (freq < 144150)): + mode = const.CW + elif ((freq >= 144150) and (freq < 144400)): + mode = const.USB + elif ((freq >= 144400) and (freq < 148000)): + mode = None + elif ((freq >= 220000) and (freq <= 226000)): + band = 1.25 #1.25m + mode = None + elif ((freq >= 420000) and (freq <= 470000)): + band = 0.7 #70cm + mode = None + elif ((freq >= 902000) and (freq <= 928000)): + band = 0.33 #33cm US + mode = None + elif ((freq >= 1200000) and (freq <= 1300000)): + band = 0.23 #23cm + mode = None + elif ((freq >= 2390000) and (freq <= 2450000)): + band = 0.13 #13cm + mode = None + elif ((freq >= 3300000) and (freq <= 3500000)): + band = 0.09 #9cm + mode = None + elif ((freq >= 5650000) and (freq <= 5850000)): + band = 0.053 #5.3cm + mode = None + elif ((freq >= 10000000) and (freq <= 10500000)): + band = 0.03 #3cm + mode = None + elif ((freq >= 24000000) and (freq <= 24050000)): + band = 0.0125 #1,25cm + mode = None + elif ((freq >= 47000000) and (freq <= 47200000)): + band = 0.0063 #6,3mm + mode = None + else: + raise KeyError + + return {"band": band, "mode": mode} \ No newline at end of file diff --git a/setup.py b/setup.py index a49a534..e012857 100755 --- a/setup.py +++ b/setup.py @@ -1,16 +1,22 @@ #!/usr/bin/env python - +import sys from distutils.core import setup +kw = {} + +if sys.version_info >= (3,): + kw['use_2to3'] = True + setup(name='pyhamtools', - version='0.1', - description='Amateur Radio Callsign Lookup', + version='0.1.1', + description='Collection of Tools for Amateur Radio developers', author='Tobias Wellnitz, DH1TW', author_email='Tobias@dh1tw.de', - url='http://github.com/dh1tw', + url='http://github.com/dh1tw/pyhamtools', packages=['pyhamtools'], install_requires=[ "pytz", "requests", - ] + ], + **kw ) diff --git a/test/conftest.py b/test/conftest.py index bfaecf2..0452e52 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -4,13 +4,6 @@ import os from apikey import APIKEY -# -# @pytest.fixture() -# def cleandir(): -# newpath = tempfile.mkdtemp() -# os.chdir(newpath) -# - from pyhamtools import LookupLib from pyhamtools import Callinfo diff --git a/test/test_utils_freq_to_band.py b/test/test_utils_freq_to_band.py new file mode 100644 index 0000000..74885a4 --- /dev/null +++ b/test/test_utils_freq_to_band.py @@ -0,0 +1,81 @@ +import pytest +from pyhamtools.utils import freq_to_band +from pyhamtools.consts import Modes as mode + +class Test_utils_freq_to_band(): + + def test_hf_frequencies(self): + assert freq_to_band(137) == {"band" : 2190, "mode":mode.CW} + + assert freq_to_band(1805) == {"band" : 160, "mode":mode.CW} + assert freq_to_band(1838) == {"band" : 160, "mode":mode.DIGITAL} + assert freq_to_band(1870) == {"band" : 160, "mode":mode.LSB} + + assert freq_to_band(3500) == {"band" : 80, "mode":mode.CW} + assert freq_to_band(3580) == {"band" : 80, "mode":mode.DIGITAL} + assert freq_to_band(3799) == {"band" : 80, "mode":mode.LSB} + + assert freq_to_band(5200) == {"band" : 60, "mode":None} + + assert freq_to_band(7000) == {"band" : 40, "mode":mode.CW} + assert freq_to_band(7044) == {"band" : 40, "mode":mode.DIGITAL} + assert freq_to_band(7139) == {"band" : 40, "mode":mode.LSB} + + assert freq_to_band(10100) == {"band" : 30, "mode":mode.CW} + assert freq_to_band(10141) == {"band" : 30, "mode":mode.DIGITAL} + + assert freq_to_band(14000) == {"band" : 20, "mode":mode.CW} + assert freq_to_band(14070) == {"band" : 20, "mode":mode.DIGITAL} + assert freq_to_band(14349) == {"band" : 20, "mode":mode.USB} + + assert freq_to_band(18068) == {"band" : 17, "mode":mode.CW} + assert freq_to_band(18096) == {"band" : 17, "mode":mode.DIGITAL} + assert freq_to_band(18250) == {"band" : 17, "mode":mode.USB} + + assert freq_to_band(21000) == {"band" : 15, "mode":mode.CW} + assert freq_to_band(21070) == {"band" : 15, "mode":mode.DIGITAL} + assert freq_to_band(21449) == {"band" : 15, "mode":mode.USB} + + assert freq_to_band(24890) == {"band" : 12, "mode":mode.CW} + assert freq_to_band(24916) == {"band" : 12, "mode":mode.DIGITAL} + assert freq_to_band(24965) == {"band" : 12, "mode":mode.USB} + + assert freq_to_band(28000) == {"band" : 10, "mode":mode.CW} + assert freq_to_band(28070) == {"band" : 10, "mode":mode.DIGITAL} + assert freq_to_band(28500) == {"band" : 10, "mode":mode.USB} + + assert freq_to_band(50000) == {"band" : 6, "mode":mode.CW} + assert freq_to_band(50100) == {"band" : 6, "mode":mode.USB} + assert freq_to_band(50500) == {"band" : 6, "mode":mode.DIGITAL} + + def test_vhf_frequencies(self): + assert freq_to_band(70001) == {"band" : 4, "mode":None} + + assert freq_to_band(144000) == {"band" : 2, "mode":mode.CW} + assert freq_to_band(144150) == {"band" : 2, "mode":mode.USB} + assert freq_to_band(144400) == {"band" : 2, "mode":None} + + assert freq_to_band(220000) == {"band" : 1.25, "mode":None} + + def test_uhf_frequencies(self): + assert freq_to_band(420000) == {"band" : 0.7, "mode":None} + + assert freq_to_band(902000) == {"band" : 0.33, "mode":None} + + assert freq_to_band(1200000) == {"band" : 0.23, "mode":None} + + def test_shf_frequencies(self): + assert freq_to_band(2390000) == {"band" : 0.13, "mode":None} + + assert freq_to_band(3300000) == {"band" : 0.09, "mode":None} + + assert freq_to_band(5650000) == {"band" : 0.053, "mode":None} + + assert freq_to_band(10000000) == {"band" : 0.03, "mode":None} + + assert freq_to_band(24000000) == {"band" : 0.0125, "mode":None} + + assert freq_to_band(47000000) == {"band" : 0.0063, "mode":None} + + with pytest.raises(KeyError): + freq_to_band(16304) \ No newline at end of file diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..8f93aa7 --- /dev/null +++ b/tox.ini @@ -0,0 +1,13 @@ +# Tox (http://tox.testrun.org/) is a tool for running tests +# in multiple virtualenvs. This configuration file will run the +# test suite on all supported python versions. To use it, "pip install tox" +# and then run "tox" from this directory. + +[tox] +envlist = py26,py27,pypy + +[testenv] +deps=pytest +commands = + py.test \ + {posargs}