Improved documentation

This commit is contained in:
dh1tw 2014-06-15 14:06:17 +07:00
parent 8216f488ef
commit 91c30879f1
12 changed files with 246 additions and 96 deletions

View file

@ -1,6 +1,39 @@
pyhamtools
==========
# pyhamtools
A Library with Amateur Radio specific Functions and Classes.
A Library with Amateur Radio specific Functions and Classes for any kind of Callsign Lookup Service, e.g. Logbooks
or DX-Clusters. Currently,
* [Country-Files.org](http://country-files.org),
* [Clublog Prefixes & Exceptions XML File](https://clublog.freshdesk.com/support/articles/54902-downloading-the-prefixes-and-exceptions-as)
* [Clublog DXCC Query API](http://clublog.freshdesk.com/support/articles/54904-how-to-query-club-log-for-dxcc)
* [Redis.io](http://redis.io)
are supported sources.
All services can be accessed through a unified interface.
The library is currently in Alpha state. Please do not use this library for operational code.
This Library is used in production at DxHeat.com.
# Installation
Easiest way to install pyhamtools is through the packet manager PIP:
`pip install pyhamtools'
# How to use pyhamtools
```
>>> 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
}
```
Check out the full documentation at:
[PyHamTools.readthedocs.org](pyhamtools.readthedocs.org/en/latest/index.html)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -25,7 +25,7 @@
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="pyhamtools 0.1 documentation" href="index.html" />
<link rel="next" title="LookupLib" href="LookupLib.html" />
<link rel="prev" title="PyHamTools" href="index.html" />
<link rel="prev" title="utils" href="utils.html" />
</head>
<body>
<div class="related">
@ -41,7 +41,7 @@
<a href="LookupLib.html" title="LookupLib"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="PyHamTools"
<a href="utils.html" title="utils"
accesskey="P">previous</a> |</li>
<li><a href="index.html">pyhamtools 0.1 documentation</a> &raquo;</li>
</ul>
@ -79,7 +79,7 @@ An instance of <tt class="xref py py-class docutils literal"><span class="pre">L
</table>
<dl class="method">
<dt id="pyhamtools.callinfo.Callinfo.get_adif_id">
<tt class="descname">get_adif_id</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>30</em>, <em>7</em>, <em>25</em>, <em>25</em>, <em>699031</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_adif_id" title="Permalink to this definition"></a></dt>
<tt class="descname">get_adif_id</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>717985</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_adif_id" title="Permalink to this definition"></a></dt>
<dd><p>Returns ADIF id of a callsign&#8217;s country</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -107,7 +107,7 @@ No Country found for callsign</p>
<dl class="method">
<dt id="pyhamtools.callinfo.Callinfo.get_all">
<tt class="descname">get_all</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>30</em>, <em>7</em>, <em>25</em>, <em>25</em>, <em>699031</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_all" title="Permalink to this definition"></a></dt>
<tt class="descname">get_all</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>717985</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_all" title="Permalink to this definition"></a></dt>
<dd><p>Lookup a callsign and return all data available from the underlying database</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -139,13 +139,13 @@ callsign &#8220;DH1TW&#8221;</p>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cic</span> <span class="o">=</span> <span class="n">Callinfo</span><span class="p">(</span><span class="n">my_lookuplib</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cic</span><span class="o">.</span><span class="n">get_all</span><span class="p">(</span><span class="s">&quot;DH1TW&quot;</span><span class="p">)</span>
<span class="go">{</span>
<span class="go"> &#39;country&#39;: &#39;Fed. Rep. of Germany&#39;,</span>
<span class="go"> &#39;adif&#39;: 230,</span>
<span class="go"> &#39;continent&#39;: &#39;EU&#39;,</span>
<span class="go"> &#39;latitude&#39;: 51.0,</span>
<span class="go"> &#39;longitude&#39;: -10.0,</span>
<span class="go"> &#39;cqz&#39;: 14,</span>
<span class="go"> &#39;ituz&#39;: 28</span>
<span class="go"> &#39;country&#39;: &#39;Fed. Rep. of Germany&#39;,</span>
<span class="go"> &#39;adif&#39;: 230,</span>
<span class="go"> &#39;continent&#39;: &#39;EU&#39;,</span>
<span class="go"> &#39;latitude&#39;: 51.0,</span>
<span class="go"> &#39;longitude&#39;: -10.0,</span>
<span class="go"> &#39;cqz&#39;: 14,</span>
<span class="go"> &#39;ituz&#39;: 28</span>
<span class="go">}</span>
</pre></div>
</div>
@ -160,7 +160,7 @@ would be missing with Clublog (API or XML) <tt class="xref py py-class docutils
<dl class="method">
<dt id="pyhamtools.callinfo.Callinfo.get_continent">
<tt class="descname">get_continent</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>30</em>, <em>7</em>, <em>25</em>, <em>25</em>, <em>699031</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_continent" title="Permalink to this definition"></a></dt>
<tt class="descname">get_continent</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>717985</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_continent" title="Permalink to this definition"></a></dt>
<dd><p>Returns the continent Identifier of a callsign</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -201,7 +201,7 @@ No Continent found for callsign</p>
<dl class="method">
<dt id="pyhamtools.callinfo.Callinfo.get_country_name">
<tt class="descname">get_country_name</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>30</em>, <em>7</em>, <em>25</em>, <em>25</em>, <em>699031</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_country_name" title="Permalink to this definition"></a></dt>
<tt class="descname">get_country_name</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>717985</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_country_name" title="Permalink to this definition"></a></dt>
<dd><p>Returns the country name where the callsign is located</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -229,7 +229,7 @@ No Country found for callsign</p>
<p class="first admonition-title">Note</p>
<p>Don&#8217;t rely on the country name when working with several instances of
py:class:<cite>Callinfo</cite>. Clublog and Country-files.org use slightly different names
for countrys. Example:</p>
for countries. Example:</p>
<ul class="last simple">
<li>Country-files.com: &#8220;Fed. Rep. of Germany&#8221;</li>
<li>Clublog: &#8220;FEDERAL REPUBLIC OF GERMANY&#8221;</li>
@ -239,7 +239,7 @@ for countrys. Example:</p>
<dl class="method">
<dt id="pyhamtools.callinfo.Callinfo.get_cqz">
<tt class="descname">get_cqz</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>30</em>, <em>7</em>, <em>25</em>, <em>25</em>, <em>699031</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_cqz" title="Permalink to this definition"></a></dt>
<tt class="descname">get_cqz</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>717985</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_cqz" title="Permalink to this definition"></a></dt>
<dd><p>Returns CQ Zone of a callsign</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -265,9 +265,9 @@ no CQ Zone found for callsign</p>
</table>
</dd></dl>
<dl class="method">
<dl class="staticmethod">
<dt id="pyhamtools.callinfo.Callinfo.get_homecall">
<tt class="descname">get_homecall</tt><big>(</big><em>callsign</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_homecall" title="Permalink to this definition"></a></dt>
<em class="property">static </em><tt class="descname">get_homecall</tt><big>(</big><em>callsign</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_homecall" title="Permalink to this definition"></a></dt>
<dd><p>Strips off country prefixes (<strong>HC2/**DH1TW) and activity suffixes (DH1TW</strong>/P**).</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -297,7 +297,7 @@ No callsign found in string</td>
<dl class="method">
<dt id="pyhamtools.callinfo.Callinfo.get_ituz">
<tt class="descname">get_ituz</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>30</em>, <em>7</em>, <em>25</em>, <em>25</em>, <em>699031</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_ituz" title="Permalink to this definition"></a></dt>
<tt class="descname">get_ituz</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>717985</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_ituz" title="Permalink to this definition"></a></dt>
<dd><p>Returns ITU Zone of a callsign</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -329,7 +329,7 @@ No ITU Zone found for callsign</p>
<dl class="method">
<dt id="pyhamtools.callinfo.Callinfo.get_lat_long">
<tt class="descname">get_lat_long</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>30</em>, <em>7</em>, <em>25</em>, <em>25</em>, <em>699031</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_lat_long" title="Permalink to this definition"></a></dt>
<tt class="descname">get_lat_long</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>717985</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.get_lat_long" title="Permalink to this definition"></a></dt>
<dd><p>Returns Latitude and Longitude for a callsign</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -360,8 +360,8 @@ No data found for callsign</p>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cic</span> <span class="o">=</span> <span class="n">Callinfo</span><span class="p">(</span><span class="n">my_lookuplib</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cic</span><span class="o">.</span><span class="n">get_lat_long</span><span class="p">(</span><span class="s">&quot;DH1TW&quot;</span><span class="p">)</span>
<span class="go">{</span>
<span class="go"> &#39;latitude&#39;: 51.0,</span>
<span class="go"> &#39;longitude&#39;: -10.0</span>
<span class="go"> &#39;latitude&#39;: 51.0,</span>
<span class="go"> &#39;longitude&#39;: -10.0</span>
<span class="go">}</span>
</pre></div>
</div>
@ -375,7 +375,7 @@ dedicated entry in the database exists.</p>
<dl class="method">
<dt id="pyhamtools.callinfo.Callinfo.is_valid_callsign">
<tt class="descname">is_valid_callsign</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>30</em>, <em>7</em>, <em>25</em>, <em>25</em>, <em>699031</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.is_valid_callsign" title="Permalink to this definition"></a></dt>
<tt class="descname">is_valid_callsign</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>717985</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.callinfo.Callinfo.is_valid_callsign" title="Permalink to this definition"></a></dt>
<dd><p>Checks if a callsign is valid</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -417,8 +417,8 @@ dedicated entry in the database exists.</p>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">PyHamTools</a></p>
<p class="topless"><a href="utils.html"
title="previous chapter">utils</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="LookupLib.html"
title="next chapter">LookupLib</a></p>
@ -457,7 +457,7 @@ dedicated entry in the database exists.</p>
<a href="LookupLib.html" title="LookupLib"
>next</a> |</li>
<li class="right" >
<a href="index.html" title="PyHamTools"
<a href="utils.html" title="utils"
>previous</a> |</li>
<li><a href="index.html">pyhamtools 0.1 documentation</a> &raquo;</li>
</ul>

View file

@ -64,6 +64,12 @@
<dt><a href="Callinfo.html#pyhamtools.callinfo.Callinfo">Callinfo (class in pyhamtools.callinfo)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="LookupLib.html#pyhamtools.lookuplib.LookupLib.copy_data_in_redis">copy_data_in_redis() (pyhamtools.lookuplib.LookupLib method)</a>
</dt>
</dl></td>
</tr></table>
@ -103,7 +109,7 @@
</dt>
<dt><a href="Callinfo.html#pyhamtools.callinfo.Callinfo.get_homecall">get_homecall() (pyhamtools.callinfo.Callinfo method)</a>
<dt><a href="Callinfo.html#pyhamtools.callinfo.Callinfo.get_homecall">get_homecall() (pyhamtools.callinfo.Callinfo static method)</a>
</dt>

View file

@ -56,7 +56,7 @@
</div>
<span class="target" id="module-pyhamtools.lookuplib"></span><dl class="class">
<dt id="pyhamtools.lookuplib.LookupLib">
<em class="property">class </em><tt class="descclassname">pyhamtools.lookuplib.</tt><tt class="descname">LookupLib</tt><big>(</big><em>lookuptype='countryfile'</em>, <em>apikey=None</em>, <em>filename=None</em>, <em>logger=None</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib" title="Permalink to this definition"></a></dt>
<em class="property">class </em><tt class="descclassname">pyhamtools.lookuplib.</tt><tt class="descname">LookupLib</tt><big>(</big><em>lookuptype='countryfile'</em>, <em>apikey=None</em>, <em>filename=None</em>, <em>logger=None</em>, <em>redis_instance=None</em>, <em>redis_prefix=None</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib" title="Permalink to this definition"></a></dt>
<dd><p>This class is a wrapper for the following three Amateur Radio databases:</p>
<ol class="arabic simple">
<li>Clublog.org (daily updated XML File)</li>
@ -64,28 +64,94 @@
<li>Country-files.com (infrequently updated PLIST File)</li>
</ol>
<p>It&#8217;s aim is to provide a homogeneous interface to different databases.</p>
<p>Typically an instance of this class is injected as a dependency in the <tt class="xref py py-class docutils literal"><span class="pre">Callinfo</span></tt> class, but it can also be used directly.</p>
<p>Typically an instance of this class is injected as a dependency in the <tt class="xref py py-class docutils literal"><span class="pre">Callinfo</span></tt> class, but it can also
be used directly.</p>
<p>Even the interface is the same for all lookup sources, the returning data can be different.
The documentation of the various methods provide more detail.</p>
<p>By default, LookupLib requires an Internet connection to download the libraries or perform the
lookup against the Clublog API.</p>
<p>The entire lookup data can also be copied into Redis, which an extremely fast in-memory Key/Value store.
A LookupLib object can be instanciated to perform then all lookups in Redis, instead processing and loading
the data from Internet / File. This saves some time and allows several instances of <a class="reference internal" href="#pyhamtools.lookuplib.LookupLib" title="pyhamtools.lookuplib.LookupLib"><tt class="xref py py-class docutils literal"><span class="pre">LookupLib</span></tt></a>
to query the same data concurrently.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>lookuptype</strong> (<em>str</em>) &#8211; &#8220;clublogxml&#8221; or &#8220;clublogapi&#8221; or &#8220;countryfile&#8221;</li>
<li><strong>lookuptype</strong> (<em>str</em>) &#8211; &#8220;clublogxml&#8221; or &#8220;clublogapi&#8221; or &#8220;countryfile&#8221; or &#8220;redis&#8221;</li>
<li><strong>apikey</strong> (<em>str</em>) &#8211; Clublog API Key</li>
<li><strong>filename</strong> (<em>str, optional</em>) &#8211; Filename for Clublog XML or Country-files.com cty.plist file. When a local file is used, no Internet connection not API Key is necessary.</li>
<li><strong>filename</strong> (<em>str, optional</em>) &#8211; Filename for Clublog XML or Country-files.com cty.plist file. When a local file is</li>
<li><strong>logger</strong> (<em>logging.getLogger(__name__), optional</em>) &#8211; Python logger</li>
<li><strong>redis_instance</strong> (<em>redis.Redis(), optional</em>) &#8211; Instance of Redis</li>
<li><strong>redis_prefix</strong> (<em>str, optional</em>) &#8211; Prefix to identify the lookup data set in Redis</li>
</ul>
</td>
</tr>
</tbody>
</table>
<dl class="method">
<dt id="pyhamtools.lookuplib.LookupLib.copy_data_in_redis">
<tt class="descname">copy_data_in_redis</tt><big>(</big><em>redis_prefix</em>, <em>redis_instance</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib.copy_data_in_redis" title="Permalink to this definition"></a></dt>
<dd><p>Copy the complete lookup data into redis. Old data will be overwritten.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>redis_prefix</strong> (<em>str</em>) &#8211; Prefix to distinguish the data in redis for the different looktypes</li>
<li><strong>redis_instance</strong> (<em>str</em>) &#8211; an Instance of Redis</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">returns True when the data has been copied successfully into Redis</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">bool</p>
</td>
</tr>
</tbody>
</table>
<p class="rubric">Example</p>
<p>Copy the entire lookup data from the Country-files.com PLIST File into Redis. This example requires a running
instance of Redis, as well the python Redis connector (pip install redis-py).</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pyhamtools</span> <span class="kn">import</span> <span class="n">LookupLib</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">redis</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">r</span> <span class="o">=</span> <span class="n">redis</span><span class="o">.</span><span class="n">Redis</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">my_lookuplib</span> <span class="o">=</span> <span class="n">LookupLib</span><span class="p">(</span><span class="n">lookuptype</span><span class="o">=</span><span class="s">&quot;countryfile&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">my_lookuplib</span><span class="o">.</span><span class="n">copy_data_in_redis</span><span class="p">(</span><span class="n">redis_prefix</span><span class="o">=</span><span class="s">&quot;CF&quot;</span><span class="p">,</span> <span class="n">redis_instance</span><span class="o">=</span><span class="n">r</span><span class="p">)</span>
<span class="go">True</span>
</pre></div>
</div>
<p>Now let&#8217;s create an instance of LookupLib, using Redis to query the data
&gt;&gt;&gt; from pyhamtools import LookupLib
&gt;&gt;&gt; import redis
&gt;&gt;&gt; r = redis.Redis()
&gt;&gt;&gt; my_lookuplib = LookupLib(lookuptype=&#8221;countryfile&#8221;, redis_instance=r, redis_prefix=&#8221;CF&#8221;)
&gt;&gt;&gt; my_lookuplib.lookup_callsign(&#8220;3D2RI&#8221;)
{</p>
<blockquote>
<div>u&#8217;adif&#8217;: 460,
u&#8217;continent&#8217;: &#8216;OC&#8217;,
u&#8217;country&#8217;: &#8216;Rotuma Island&#8217;,
u&#8217;cqz&#8217;: 32,
u&#8217;ituz&#8217;: 56,
u&#8217;latitude&#8217;: -12.48,
u&#8217;longitude&#8217;: -177.08</div></blockquote>
<p>}</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>This method is available for the following lookup type</p>
<ul class="last simple">
<li>clublogxml</li>
<li>countryfile</li>
</ul>
</div>
</dd></dl>
<dl class="method">
<dt id="pyhamtools.lookuplib.LookupLib.is_invalid_operation">
<tt class="descname">is_invalid_operation</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>29</em>, <em>13</em>, <em>1</em>, <em>27</em>, <em>518550</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib.is_invalid_operation" title="Permalink to this definition"></a></dt>
<tt class="descname">is_invalid_operation</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>706858</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib.is_invalid_operation" title="Permalink to this definition"></a></dt>
<dd><p>Returns True if an operations is known as invalid</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -134,13 +200,14 @@ API Key for Clublog missing or incorrect</li>
<p>This method is available for</p>
<ul class="last simple">
<li>clublogxml</li>
<li>redis</li>
</ul>
</div>
</dd></dl>
<dl class="method">
<dt id="pyhamtools.lookuplib.LookupLib.lookup_callsign">
<tt class="descname">lookup_callsign</tt><big>(</big><em>callsign=None</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>29</em>, <em>13</em>, <em>1</em>, <em>27</em>, <em>518519</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib.lookup_callsign" title="Permalink to this definition"></a></dt>
<tt class="descname">lookup_callsign</tt><big>(</big><em>callsign=None</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>706831</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib.lookup_callsign" title="Permalink to this definition"></a></dt>
<dd><p>Returns lookup data if an exception exists for a callsign</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -193,6 +260,7 @@ API Key for Clublog missing or incorrect</li>
<li>clublogxml</li>
<li>clublogapi</li>
<li>countryfile</li>
<li>redis</li>
</ul>
</div>
</dd></dl>
@ -238,13 +306,14 @@ the id 273.</p>
<p>This method is available for the following lookup type</p>
<ul class="last simple">
<li>clublogxml</li>
<li>redis</li>
</ul>
</div>
</dd></dl>
<dl class="method">
<dt id="pyhamtools.lookuplib.LookupLib.lookup_prefix">
<tt class="descname">lookup_prefix</tt><big>(</big><em>prefix</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>29</em>, <em>13</em>, <em>1</em>, <em>27</em>, <em>518519</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib.lookup_prefix" title="Permalink to this definition"></a></dt>
<tt class="descname">lookup_prefix</tt><big>(</big><em>prefix</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>706831</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib.lookup_prefix" title="Permalink to this definition"></a></dt>
<dd><p>Returns lookup data of a Prefix</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
@ -295,13 +364,14 @@ database (default database).</p>
<ul class="last simple">
<li>clublogxml</li>
<li>countryfile</li>
<li>redis</li>
</ul>
</div>
</dd></dl>
<dl class="method">
<dt id="pyhamtools.lookuplib.LookupLib.lookup_zone_exception">
<tt class="descname">lookup_zone_exception</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>4</em>, <em>29</em>, <em>13</em>, <em>1</em>, <em>27</em>, <em>518556</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib.lookup_zone_exception" title="Permalink to this definition"></a></dt>
<tt class="descname">lookup_zone_exception</tt><big>(</big><em>callsign</em>, <em>timestamp=datetime.datetime(2014</em>, <em>6</em>, <em>15</em>, <em>7</em>, <em>5</em>, <em>27</em>, <em>706866</em>, <em>tzinfo=&lt;UTC&gt;)</em><big>)</big><a class="headerlink" href="#pyhamtools.lookuplib.LookupLib.lookup_zone_exception" title="Permalink to this definition"></a></dt>
<dd><p>Returns a CQ Zone if an exception exists for the given callsign</p>
<p>Args:
callsign (string): Amateur radio callsign
@ -341,6 +411,7 @@ in CQ Zone 38</p>
<p>This method is available for</p>
<ul class="last simple">
<li>clublogxml</li>
<li>redis</li>
</ul>
</div>
</dd></dl>

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -3,11 +3,8 @@ import logging
from datetime import datetime
import sys
import pytz
from pyhamtools import LookupLib
from pyhamtools.consts import LookupConventions as const
@ -19,6 +16,7 @@ if sys.version_info < (2, 7, ):
def emit(self, record):
pass
class Callinfo(object):
"""
The purpose of this class is to return data (country, latitude, longitude, CQ Zone...etc) for an
@ -47,7 +45,8 @@ class Callinfo(object):
self._lookuplib = lookuplib
self._callsign_info = None
def get_homecall(self, callsign):
@staticmethod
def get_homecall(callsign):
"""Strips off country prefixes (**HC2/**DH1TW) and activity suffixes (DH1TW**/P**).
Args:
@ -60,13 +59,13 @@ class Callinfo(object):
ValueError: No callsign found in string
Example:
The following code retrieves the home call for "HC2/DH1TW/P"
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
>>> from pyhamtools import LookupLib, Callinfo
>>> my_lookuplib = LookupLib(lookuptype="countryfile")
>>> cic = Callinfo(my_lookuplib)
>>> cic.get_homecall("HC2/DH1TW/P")
DH1TW
"""
@ -78,12 +77,11 @@ class Callinfo(object):
else:
raise ValueError
def _iterate_prefix(self, callsign, timestamp=timestamp_now):
"""truncate call until it corresponds to a Prefix in the database"""
prefix = callsign
while(len(prefix) > 0):
while len(prefix) > 0:
try:
return self._lookuplib.lookup_prefix(prefix, timestamp)
except KeyError:
@ -91,19 +89,22 @@ class Callinfo(object):
continue
raise KeyError
def check_if_mm(self, callsign):
@staticmethod
def check_if_mm(callsign):
if re.search("/MM$", callsign.upper()):
return True
else:
return False
def check_if_am(self, callsign):
@staticmethod
def check_if_am(callsign):
if re.search("/AM$", callsign.upper()):
return True
else:
return False
def check_if_beacon(self, callsign):
@staticmethod
def check_if_beacon(callsign):
if re.search("/B$", callsign.upper()):
return True
elif re.search("/BCN$", callsign.upper()):
@ -111,7 +112,6 @@ class Callinfo(object):
else:
return False
def _dismantle_callsign(self, callsign, timestamp=timestamp_now):
""" try to identify the callsign's identity by analyzing it in the following order:
@ -142,7 +142,7 @@ class Callinfo(object):
if appendix == 'MM': # special case Martime Mobile
#self._mm = True
return {
return {
'adif': 999,
'continent': '',
'country': 'MARITIME MOBILE',
@ -151,7 +151,7 @@ class Callinfo(object):
'longitude': 0.0
}
elif appendix == 'AM': # special case Aeronautic Mobile
return {
return {
'adif': 998,
'continent': '',
'country': 'AIRCAFT MOBILE',
@ -165,16 +165,16 @@ class Callinfo(object):
elif appendix == 'QRPP': # special case QRPP
callsign = re.sub('/QRPP', '', callsign)
return self._iterate_prefix(callsign, timestamp)
elif appendix == 'BCN': #filter all beacons
elif appendix == 'BCN': # filter all beacons
callsign = re.sub('/BCN', '', callsign)
data = self._iterate_prefix(callsign, timestamp).copy()
data[const.BEACON] = True
return data
elif appendix == "LH": #Filter all Lighthouses
elif appendix == "LH": # Filter all Lighthouses
callsign = re.sub('/LH', '', callsign)
return self._iterate_prefix(callsign, timestamp)
else:
#check if the appendix is a valid country prefix
# check if the appendix is a valid country prefix
return self._iterate_prefix(re.sub('/', '', appendix), timestamp)
# Single character appendix (callsign/x)
@ -182,9 +182,9 @@ class Callinfo(object):
appendix = re.search('/[A-Z0-9]$', callsign)
appendix = re.sub('/', '', appendix.group(0))
if appendix == 'B': #special case Beacon
if appendix == 'B': # special case Beacon
callsign = re.sub('/B', '', callsign)
data = self._iterate_prefix(callsign, timestamp).copy()
data = self._iterate_prefix(callsign, timestamp).copy()
data[const.BEACON] = True
return data
@ -223,7 +223,7 @@ class Callinfo(object):
raise
if self.check_if_mm(callsign):
return {
return {
'adif': 999,
'continent': '',
'country': 'MARITIME MOBILE',
@ -232,7 +232,7 @@ class Callinfo(object):
'longitude': 0.0
}
elif self.check_if_am(callsign):
return {
return {
'adif': 998,
'continent': '',
'country': 'AIRCAFT MOBILE',
@ -253,7 +253,6 @@ class Callinfo(object):
# Dismantel the callsign and check if the prefix is known
return self._dismantle_callsign(callsign, timestamp)
def get_all(self, callsign, timestamp=timestamp_now):
""" Lookup a callsign and return all data available from the underlying database
@ -268,14 +267,14 @@ class Callinfo(object):
KeyError: Callsign could not be identified
Example:
The following code returns all available information from the country-files.com database for the
callsign "DH1TW"
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")
{
>>> 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',
@ -283,7 +282,7 @@ class Callinfo(object):
'longitude': -10.0,
'cqz': 14,
'ituz': 28
}
}
Note:
The content of the returned data depends entirely on the injected
@ -313,13 +312,13 @@ class Callinfo(object):
bool: True / False
Example:
The following checks if "DH1TW" is a valid callsign
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
>>> from pyhamtools import LookupLib, Callinfo
>>> my_lookuplib = LookupLib(lookuptype="countryfile")
>>> cic = Callinfo(my_lookuplib)
>>> cic.is_valid_callsign("DH1TW")
True
"""
try:
@ -342,16 +341,16 @@ class Callinfo(object):
KeyError: No data found for callsign
Example:
The following code returns Latitude & Longitude for "DH1TW"
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
}
>>> 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.
@ -361,8 +360,8 @@ class Callinfo(object):
"""
callsign_data = self.get_all(callsign, timestamp=timestamp)
return {
const.LATITUDE : callsign_data[const.LATITUDE],
const.LONGITUDE : callsign_data[const.LONGITUDE]
const.LATITUDE: callsign_data[const.LATITUDE],
const.LONGITUDE: callsign_data[const.LONGITUDE]
}
def get_cqz(self, callsign, timestamp=timestamp_now):
@ -416,7 +415,7 @@ class Callinfo(object):
Note:
Don't rely on the country name when working with several instances of
py:class:`Callinfo`. Clublog and Country-files.org use slightly different names
for countrys. Example:
for countries. Example:
- Country-files.com: "Fed. Rep. of Germany"
- Clublog: "FEDERAL REPUBLIC OF GERMANY"

View file

@ -7,7 +7,6 @@ from datetime import datetime
import xml.etree.ElementTree as ET
import urllib
import json
import pickle
import copy
import sys
@ -49,7 +48,7 @@ class LookupLib(object):
The entire lookup data can also be copied into Redis, which an extremely fast in-memory Key/Value store.
A LookupLib object can be instanciated to perform then all lookups in Redis, instead processing and loading
the data from Internet / File. This saves some time and allows several instances of :py:call:`LookupLib`
the data from Internet / File. This saves some time and allows several instances of :py:class:`LookupLib`
to query the same data concurrently.
Args:
@ -107,7 +106,7 @@ class LookupLib(object):
def copy_data_in_redis(self, redis_prefix, redis_instance):
"""
Copy the complete lookup data and indexes of the object into redis. Old data will be overwritten.
Copy the complete lookup data into redis. Old data will be overwritten.
Args:
redis_prefix (str): Prefix to distinguish the data in redis for the different looktypes
@ -117,8 +116,8 @@ class LookupLib(object):
bool: returns True when the data has been copied successfully into Redis
Example:
Copy the entire lookup data from the Country-files.com PLIST File into Redis. A Redis Instance
needs to be installed, as well as copy of the python Redis connector (pip install redis-py)
Copy the entire lookup data from the Country-files.com PLIST File into Redis. This example requires a running
instance of Redis, as well the python Redis connector (pip install redis-py).
>>> from pyhamtools import LookupLib
>>> import redis

View file

@ -0,0 +1,42 @@
import pytest
import json
from datetime import datetime
import pytz
import redis
from pyhamtools import LookupLib
UTC = pytz.UTC
r = redis.Redis()
class TestStoreDataInRedis:
def test_copy_data_in_redis(self, fixClublogXML, fix_redis):
fixClublogXML.copy_data_in_redis("clx", redis.Redis())
assert fix_redis.lookup_entity(280) == fixClublogXML.lookup_entity(280)
assert fix_redis.lookup_callsign("VK9XO") == fixClublogXML.lookup_callsign("VK9XO")
assert fix_redis.lookup_prefix("DH") == fixClublogXML.lookup_prefix("DH")
with pytest.raises(KeyError):
fix_redis.is_invalid_operation("VK0MC")
timestamp = datetime(year=1994, month=12, day=30).replace(tzinfo=UTC)
assert fix_redis.is_invalid_operation("VK0MC", timestamp)
with pytest.raises(KeyError):
fix_redis.lookup_zone_exception("DH1TW")
assert fix_redis.lookup_zone_exception("dp0gvn") == 38
def test_copy_data_in_redis_2(self, fixCountryFile):
lib = LookupLib(lookuptype="redis", redis_prefix="CF", redis_instance=r)
fixCountryFile.copy_data_in_redis("CF", r)
assert lib.lookup_callsign("3D2RI") == fixCountryFile.lookup_callsign("3D2RI")
assert lib.lookup_prefix("DH") == fixCountryFile.lookup_prefix("DH")