mirror of
https://github.com/dh1tw/pyhamtools.git
synced 2026-01-10 10:40:39 +01:00
added support for python 3.12
This commit is contained in:
parent
e549f416e8
commit
6a152760c5
129
.github/workflows/test.yml
vendored
129
.github/workflows/test.yml
vendored
|
|
@ -4,14 +4,59 @@ on: [push, pull_request]
|
|||
|
||||
jobs:
|
||||
test_linux:
|
||||
# Ubuntu 20.04 is still required for python 3.6; this doesn't work on Ubuntu 22.04 anymore
|
||||
runs-on: "ubuntu-20.04"
|
||||
name: "Ubuntu latest - Python ${{ matrix.python-version }}"
|
||||
name: "Ubuntu 20.04 - Python ${{ matrix.python-version }}"
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.6"]
|
||||
redis-version: [6]
|
||||
|
||||
steps:
|
||||
- uses: "actions/checkout@v3"
|
||||
- uses: "actions/setup-python@v4"
|
||||
with:
|
||||
python-version: "${{ matrix.python-version }}"
|
||||
cache: "pip"
|
||||
cache-dependency-path: |
|
||||
**/setup.py
|
||||
**/requirements*.txt
|
||||
|
||||
- name: "Install dependencies"
|
||||
run: |
|
||||
set -xe
|
||||
sudo apt-get install -y libxml2-dev libxslt-dev
|
||||
python -VV
|
||||
python -m pip install --upgrade pip setuptools
|
||||
python -m pip install -e .
|
||||
python -m pip install -r requirements-pytest.txt
|
||||
|
||||
- name: Start Redis
|
||||
uses: supercharge/redis-github-action@1.2.0
|
||||
with:
|
||||
redis-version: ${{ matrix.redis-version }}
|
||||
|
||||
- name: "Run tests for ${{ matrix.python-version }}"
|
||||
env:
|
||||
CLUBLOG_APIKEY: ${{ secrets.CLUBLOG_APIKEY }}
|
||||
QRZ_USERNAME: ${{ secrets.QRZ_USERNAME }}
|
||||
QRZ_PWD: ${{ secrets.QRZ_PWD }}
|
||||
PYTHON_VERSION: ${{ matrix.python-version }}
|
||||
# delay the execution randomly by a couple of seconds to reduce the amount
|
||||
# of concurrent API calls on Clublog and QRZ.com when all CI jobs execute simultaneously
|
||||
run: |
|
||||
sleep $[ ( $RANDOM % 10 ) + 1 ]s
|
||||
pytest ./test
|
||||
|
||||
test_linux_ubuntu_22:
|
||||
runs-on: "ubuntu-22.04"
|
||||
name: "Ubuntu 22.04 - Python ${{ matrix.python-version }}"
|
||||
env:
|
||||
USING_COVERAGE: '3.11'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "pypy2.7", "pypy3.7", "pypy3.8", "pypy3.9"]
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "pypy3.7", "pypy3.8", "pypy3.9", "pypy3.10"]
|
||||
redis-version: [6]
|
||||
|
||||
steps:
|
||||
|
|
@ -49,8 +94,13 @@ jobs:
|
|||
# of concurrent API calls on Clublog and QRZ.com when all CI jobs execute simultaneously
|
||||
run: |
|
||||
sleep $[ ( $RANDOM % 10 ) + 1 ]s
|
||||
pytest --cov=./
|
||||
if [[ $PYTHON_VERSION == 3.11 ]]; then codecov; fi
|
||||
if [[ $PYTHON_VERSION == 3.11 ]]
|
||||
then
|
||||
pytest --cov=test/
|
||||
codecov
|
||||
else
|
||||
pytest test/
|
||||
fi
|
||||
cd docs && make html
|
||||
|
||||
# publish_package:
|
||||
|
|
@ -64,18 +114,58 @@ jobs:
|
|||
# user: __token__
|
||||
# password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
|
||||
|
||||
test_macos:
|
||||
# Ubuntu 20.04 is still required for python 3.6; this doesn't work on Ubuntu 22.04 anymore
|
||||
runs-on: "macos-12"
|
||||
name: "MacOS 12 - Python ${{ matrix.python-version }}"
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "pypy3.8", "pypy3.9", "pypy3.10"]
|
||||
redis-version: [6]
|
||||
|
||||
steps:
|
||||
- uses: "actions/checkout@v3"
|
||||
- uses: "actions/setup-python@v4"
|
||||
with:
|
||||
python-version: "${{ matrix.python-version }}"
|
||||
cache: "pip"
|
||||
cache-dependency-path: |
|
||||
**/setup.py
|
||||
**/requirements*.txt
|
||||
|
||||
- name: "Install dependencies"
|
||||
run: |
|
||||
set -xe
|
||||
python -VV
|
||||
python -m pip install --upgrade pip setuptools
|
||||
python -m pip install -e .
|
||||
python -m pip install -r requirements-pytest.txt
|
||||
|
||||
- name: Start Redis
|
||||
uses: shogo82148/actions-setup-redis@v1.31.1
|
||||
with:
|
||||
redis-version: ${{ matrix.redis-version }}
|
||||
|
||||
- name: "Run tests for ${{ matrix.python-version }}"
|
||||
env:
|
||||
CLUBLOG_APIKEY: ${{ secrets.CLUBLOG_APIKEY }}
|
||||
QRZ_USERNAME: ${{ secrets.QRZ_USERNAME }}
|
||||
QRZ_PWD: ${{ secrets.QRZ_PWD }}
|
||||
PYTHON_VERSION: ${{ matrix.python-version }}
|
||||
# delay the execution randomly by a couple of seconds to reduce the amount
|
||||
# of concurrent API calls on Clublog and QRZ.com when all CI jobs execute simultaneously
|
||||
run: |
|
||||
sleep $[ ( $RANDOM % 10 ) + 1 ]
|
||||
pytest ./test
|
||||
|
||||
test_windows:
|
||||
runs-on: "windows-latest"
|
||||
name: "Windows latest - Python ${{ matrix.python-version }}"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
# lxml support for windows/python3.11 still missing (Dec 2022)
|
||||
# https://github.com/lxml/lxml/pull/360
|
||||
# python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
|
||||
# python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
|
||||
# disable python 3.6 on windows due to lxml / bs4 problems on Github Actions
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10"]
|
||||
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
|
||||
|
||||
steps:
|
||||
- uses: "actions/checkout@v3"
|
||||
|
|
@ -94,24 +184,27 @@ jobs:
|
|||
python -m pip install -r requirements-pytest.txt
|
||||
python -m pip install -r requirements-docs.txt
|
||||
- name: Setup redis
|
||||
# We have to download and install a non-official redis windows port
|
||||
# since there is no official redis version for windows.
|
||||
# 5.0 is good enough for our purposes. After installing the msi,
|
||||
# redis will startup as a service.
|
||||
# There are no github-actions supporting redis on windows.
|
||||
# Github Actions Container services are also not available for windows.
|
||||
# We have to download and install a non-official redis windows port
|
||||
# since there is no official redis version for windows.
|
||||
# Redis is then installed an run as a service
|
||||
run: |
|
||||
C:\msys64\usr\bin\wget.exe https://github.com/tporadowski/redis/releases/download/v5.0.14.1/Redis-x64-5.0.14.1.msi
|
||||
msiexec /quiet /i Redis-x64-5.0.14.1.msi
|
||||
C:\msys64\usr\bin\wget.exe https://github.com/redis-windows/redis-windows/releases/download/7.0.14/Redis-7.0.14-Windows-x64-with-Service.tar.gz
|
||||
C:\msys64\usr\bin\tar.exe -xvzf Redis-7.0.14-Windows-x64-with-Service.tar.gz
|
||||
sc.exe create Redis binpath=D:\a\pyhamtools\pyhamtools\Redis-7.0.14-Windows-x64-with-Service\RedisService.exe start= auto
|
||||
net start Redis
|
||||
|
||||
- name: "Run tests for ${{ matrix.python-version }}"
|
||||
env:
|
||||
CLUBLOG_APIKEY: ${{ secrets.CLUBLOG_APIKEY }}
|
||||
QRZ_USERNAME: ${{ secrets.QRZ_USERNAME }}
|
||||
QRZ_PWD: ${{ secrets.QRZ_PWD }}
|
||||
PYTHON_VERSION: ${{ matrix.python-version }}
|
||||
# delay the execution randomly by 1-20sec to reduce the
|
||||
# give redis service time to startup and
|
||||
# delay the execution randomly by 5-20sec to reduce the
|
||||
# amount of concurrent API calls on Clublog and QRZ.com
|
||||
# when all CI jobs execute simultaneously
|
||||
run: |
|
||||
start-sleep -Seconds (1..10 | get-random)
|
||||
start-sleep -Seconds (5..20 | get-random)
|
||||
pytest
|
||||
20
README.md
20
README.md
|
|
@ -4,7 +4,7 @@
|
|||
[](https://codecov.io/gh/dh1tw/pyhamtools)
|
||||
[](https://badge.fury.io/py/pyhamtools)
|
||||
|
||||
Pyhamtools is a set of functions and classes for Amateur Radio purpose.
|
||||
Pyhamtools is a set of functions and classes for Amateur Radio purposes.
|
||||
Currently, the core part is the Callsign Lookup which decodes any amateur radio
|
||||
callsign string and provides the corresponding information (Country, DXCC
|
||||
entity, CQ Zone...etc). This basic functionality is needed for Logbooks,
|
||||
|
|
@ -31,22 +31,22 @@ This Library is used in production at the [DXHeat.com DX Cluster](https://dxheat
|
|||
|
||||
## Compatibility
|
||||
|
||||
Pyhamtools is compatible with Python 2.7 and Python >=3.6.
|
||||
We check compatibility on OSX, Windows, and Linux with the following Python
|
||||
versions:
|
||||
Pyhamtools is compatible with Python >=3.6.
|
||||
We check compatibility on OSX, Windows, and Linux with the following Python versions:
|
||||
|
||||
* Python 2.7 (will be deprecated in 2023)
|
||||
* Python 3.5 (has been deprecated in 2022)
|
||||
* Python 3.6 (will be deprecated in 2023)
|
||||
* Python 3.7
|
||||
* Python 3.6 (will be deprecated in 2024)
|
||||
* Python 3.7 (will be deprecated in 2024)
|
||||
* Python 3.8
|
||||
* Python 3.9
|
||||
* Python 3.10
|
||||
* Python 3.11
|
||||
* [pypy2](https://pypy.org/) (Python 2)
|
||||
* [pypy3.7](https://pypy.org/)
|
||||
* Python 3.12
|
||||
* [pypy3.7](https://pypy.org/) (will be deprecated in 2024)
|
||||
* [pypy3.8](https://pypy.org/)
|
||||
* [pypy3.9](https://pypy.org/)
|
||||
* [pypy3.10](https://pypy.org/)
|
||||
|
||||
The support for Python 2.7 and 3.5 has been deprecated at the end of 2023. The last version which supports Python 2.7 and Python 3.5 is 0.8.7.
|
||||
|
||||
## Documentation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,18 @@
|
|||
Changelog
|
||||
---------
|
||||
|
||||
|
||||
PyHamtools 0.9.0
|
||||
================
|
||||
|
||||
28. December 2023
|
||||
|
||||
* Deprecated support for Python 2.7 and Python 3.5
|
||||
* Added Support for Python 3.12
|
||||
* Replaced pytz with datetime.timezone
|
||||
* Added Continous Integration Jobs for MacOS (now supported by Github Actions)
|
||||
|
||||
|
||||
PyHamtools 0.8.7
|
||||
================
|
||||
|
||||
|
|
|
|||
|
|
@ -12,19 +12,8 @@
|
|||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
from pyhamtools.version import __version__, __release__
|
||||
|
||||
sys.path.insert(0,"/Users/user/projects/pyhamtools/pyhamtools")
|
||||
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
|
|
@ -52,7 +41,7 @@ master_doc = 'index'
|
|||
|
||||
# General information about the project.
|
||||
project = u'pyhamtools'
|
||||
copyright = u'2019, Tobias Wellnitz, DH1TW'
|
||||
copyright = u'2024, Tobias Wellnitz, DH1TW'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
|
|
|
|||
|
|
@ -1,22 +1,11 @@
|
|||
import re
|
||||
import logging
|
||||
from datetime import datetime
|
||||
import sys
|
||||
|
||||
import pytz
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from pyhamtools.consts import LookupConventions as const
|
||||
|
||||
from pyhamtools.callsign_exceptions import callsign_exceptions
|
||||
|
||||
UTC = pytz.UTC
|
||||
|
||||
if sys.version_info < (2, 7, ):
|
||||
class NullHandler(logging.Handler):
|
||||
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
|
||||
|
|
@ -37,10 +26,7 @@ class Callinfo(object):
|
|||
self._logger = logger
|
||||
else:
|
||||
self._logger = logging.getLogger(__name__)
|
||||
if sys.version_info[:2] == (2, 6):
|
||||
self._logger.addHandler(NullHandler())
|
||||
else:
|
||||
self._logger.addHandler(logging.NullHandler())
|
||||
self._logger.addHandler(logging.NullHandler())
|
||||
|
||||
self._lookuplib = lookuplib
|
||||
self._callsign_info = None
|
||||
|
|
@ -81,10 +67,10 @@ class Callinfo(object):
|
|||
"""truncate call until it corresponds to a Prefix in the database"""
|
||||
prefix = callsign
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
if re.search('(VK|AX|VI)9[A-Z]{3}', callsign): #special rule for VK9 calls
|
||||
if timestamp > datetime(2006,1,1, tzinfo=UTC):
|
||||
if timestamp > datetime(2006,1,1, tzinfo=timezone.utc):
|
||||
prefix = callsign[0:3]+callsign[4:5]
|
||||
|
||||
while len(prefix) > 0:
|
||||
|
|
@ -115,7 +101,7 @@ class Callinfo(object):
|
|||
|
||||
Args:
|
||||
callsign (str): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Raises:
|
||||
KeyError: Callsign could not be identified
|
||||
|
|
@ -124,7 +110,7 @@ class Callinfo(object):
|
|||
"""
|
||||
entire_callsign = callsign.upper()
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
if re.search('[/A-Z0-9\\-]{3,15}', entire_callsign): # make sure the call has at least 3 characters
|
||||
|
||||
|
|
@ -230,7 +216,7 @@ class Callinfo(object):
|
|||
|
||||
def _lookup_callsign(self, callsign, timestamp=None):
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
# Check if operation is invalid
|
||||
invalid = False
|
||||
|
|
@ -278,7 +264,7 @@ class Callinfo(object):
|
|||
|
||||
Args:
|
||||
callsign (str): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
dict: Dictionary containing the callsign specific data
|
||||
|
|
@ -315,7 +301,7 @@ class Callinfo(object):
|
|||
callsign = callsign.upper()
|
||||
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
callsign_data = self._lookup_callsign(callsign, timestamp)
|
||||
|
||||
|
|
@ -332,7 +318,7 @@ class Callinfo(object):
|
|||
|
||||
Args:
|
||||
callsign (str): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
bool: True / False
|
||||
|
|
@ -348,7 +334,7 @@ class Callinfo(object):
|
|||
|
||||
"""
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
try:
|
||||
if self.get_all(callsign, timestamp):
|
||||
|
|
@ -361,7 +347,7 @@ class Callinfo(object):
|
|||
|
||||
Args:
|
||||
callsign (str): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
dict: Containing Latitude and Longitude
|
||||
|
|
@ -388,7 +374,7 @@ class Callinfo(object):
|
|||
|
||||
"""
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
callsign_data = self.get_all(callsign, timestamp=timestamp)
|
||||
return {
|
||||
|
|
@ -401,7 +387,7 @@ class Callinfo(object):
|
|||
|
||||
Args:
|
||||
callsign (str): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
int: containing the callsign's CQ Zone
|
||||
|
|
@ -411,7 +397,7 @@ class Callinfo(object):
|
|||
|
||||
"""
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
return self.get_all(callsign, timestamp)[const.CQZ]
|
||||
|
||||
|
|
@ -420,7 +406,7 @@ class Callinfo(object):
|
|||
|
||||
Args:
|
||||
callsign (str): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
int: containing the callsign's CQ Zone
|
||||
|
|
@ -433,7 +419,7 @@ class Callinfo(object):
|
|||
|
||||
"""
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
return self.get_all(callsign, timestamp)[const.ITUZ]
|
||||
|
||||
|
|
@ -442,7 +428,7 @@ class Callinfo(object):
|
|||
|
||||
Args:
|
||||
callsign (str): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
str: name of the Country
|
||||
|
|
@ -460,7 +446,7 @@ class Callinfo(object):
|
|||
|
||||
"""
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
return self.get_all(callsign, timestamp)[const.COUNTRY]
|
||||
|
||||
|
|
@ -469,7 +455,7 @@ class Callinfo(object):
|
|||
|
||||
Args:
|
||||
callsign (str): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
int: containing the country ADIF id
|
||||
|
|
@ -479,7 +465,7 @@ class Callinfo(object):
|
|||
|
||||
"""
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
return self.get_all(callsign, timestamp)[const.ADIF]
|
||||
|
||||
|
|
@ -488,7 +474,7 @@ class Callinfo(object):
|
|||
|
||||
Args:
|
||||
callsign (str): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
str: continent identified
|
||||
|
|
@ -508,6 +494,6 @@ class Callinfo(object):
|
|||
- AN: Antarctica
|
||||
"""
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
return self.get_all(callsign, timestamp)[const.CONTINENT]
|
||||
|
|
|
|||
|
|
@ -1,37 +1,30 @@
|
|||
__author__ = 'dh1tw'
|
||||
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from time import strptime, mktime
|
||||
import re
|
||||
|
||||
import pytz
|
||||
|
||||
from pyhamtools.consts import LookupConventions as const
|
||||
|
||||
|
||||
UTC = pytz.UTC
|
||||
|
||||
|
||||
|
||||
def decode_char_spot(raw_string):
|
||||
"""Chop Line from DX-Cluster into pieces and return a dict with the spot data"""
|
||||
|
||||
data = {}
|
||||
|
||||
# Spotter callsign
|
||||
if re.match('[A-Za-z0-9\/]+[:$]', raw_string[6:15]):
|
||||
data[const.SPOTTER] = re.sub(':', '', re.match('[A-Za-z0-9\/]+[:$]', raw_string[6:15]).group(0))
|
||||
if re.match(r'[A-Za-z0-9\/]+[:$]', raw_string[6:15]):
|
||||
data[const.SPOTTER] = re.sub(':', '', re.match(r'[A-Za-z0-9\/]+[:$]', raw_string[6:15]).group(0))
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
if re.search('[0-9\.]{5,12}', raw_string[10:25]):
|
||||
data[const.FREQUENCY] = float(re.search('[0-9\.]{5,12}', raw_string[10:25]).group(0))
|
||||
if re.search(r'[0-9\.]{5,12}', raw_string[10:25]):
|
||||
data[const.FREQUENCY] = float(re.search(r'[0-9\.]{5,12}', raw_string[10:25]).group(0))
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
data[const.DX] = re.sub('[^A-Za-z0-9\/]+', '', raw_string[26:38])
|
||||
data[const.COMMENT] = re.sub('[^\sA-Za-z0-9\.,;\#\+\-!\?\$\(\)@\/]+', ' ', raw_string[39:69]).strip()
|
||||
data[const.TIME] = datetime.now().replace(tzinfo=UTC)
|
||||
data[const.DX] = re.sub(r'[^A-Za-z0-9\/]+', '', raw_string[26:38])
|
||||
data[const.COMMENT] = re.sub(r'[^\sA-Za-z0-9\.,;\#\+\-!\?\$\(\)@\/]+', ' ', raw_string[39:69]).strip()
|
||||
data[const.TIME] = datetime.now(timezone.utc)
|
||||
|
||||
return data
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
from __future__ import division
|
||||
from math import pi, sin, cos, atan2, sqrt, radians, log, tan, degrees
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import pytz
|
||||
import ephem
|
||||
|
||||
UTC = pytz.UTC
|
||||
|
||||
def latlong_to_locator (latitude, longitude):
|
||||
"""converts WGS84 coordinates into the corresponding Maidenhead Locator
|
||||
|
||||
|
|
@ -283,16 +279,14 @@ def calculate_sunrise_sunset(locator, calc_date=None):
|
|||
The following calculates the next sunrise & sunset for JN48QM on the 1./Jan/2014
|
||||
|
||||
>>> from pyhamtools.locator import calculate_sunrise_sunset
|
||||
>>> from datetime import datetime
|
||||
>>> import pytz
|
||||
>>> UTC = pytz.UTC
|
||||
>>> myDate = datetime(year=2014, month=1, day=1, tzinfo=UTC)
|
||||
>>> from datetime import datetime, timezone
|
||||
>>> myDate = datetime(year=2014, month=1, day=1, tzinfo=timezone.utc)
|
||||
>>> calculate_sunrise_sunset("JN48QM", myDate)
|
||||
{
|
||||
'morning_dawn': datetime.datetime(2014, 1, 1, 6, 36, 51, 710524, tzinfo=<UTC>),
|
||||
'sunset': datetime.datetime(2014, 1, 1, 16, 15, 23, 31016, tzinfo=<UTC>),
|
||||
'evening_dawn': datetime.datetime(2014, 1, 1, 15, 38, 8, 355315, tzinfo=<UTC>),
|
||||
'sunrise': datetime.datetime(2014, 1, 1, 7, 14, 6, 162063, tzinfo=<UTC>)
|
||||
'morning_dawn': datetime.datetime(2014, 1, 1, 6, 36, 51, 710524, tzinfo=datetime.timezone.utc),
|
||||
'sunset': datetime.datetime(2014, 1, 1, 16, 15, 23, 31016, tzinfo=datetime.timezone.utc),
|
||||
'evening_dawn': datetime.datetime(2014, 1, 1, 15, 38, 8, 355315, tzinfo=datetime.timezone.utc),
|
||||
'sunrise': datetime.datetime(2014, 1, 1, 7, 14, 6, 162063, tzinfo=datetime.timezone.utc)
|
||||
}
|
||||
|
||||
"""
|
||||
|
|
@ -304,7 +298,7 @@ def calculate_sunrise_sunset(locator, calc_date=None):
|
|||
latitude, longitude = locator_to_latlong(locator)
|
||||
|
||||
if calc_date is None:
|
||||
calc_date = datetime.utcnow()
|
||||
calc_date = datetime.now(timezone.utc)
|
||||
if type(calc_date) != datetime:
|
||||
raise ValueError
|
||||
|
||||
|
|
@ -350,11 +344,11 @@ def calculate_sunrise_sunset(locator, calc_date=None):
|
|||
result['sunset'] = sunset
|
||||
|
||||
if morning_dawn:
|
||||
result['morning_dawn'] = morning_dawn.replace(tzinfo=UTC)
|
||||
result['morning_dawn'] = morning_dawn.replace(tzinfo=timezone.utc)
|
||||
if sunrise:
|
||||
result['sunrise'] = sunrise.replace(tzinfo=UTC)
|
||||
result['sunrise'] = sunrise.replace(tzinfo=timezone.utc)
|
||||
if evening_dawn:
|
||||
result['evening_dawn'] = evening_dawn.replace(tzinfo=UTC)
|
||||
result['evening_dawn'] = evening_dawn.replace(tzinfo=timezone.utc)
|
||||
if sunset:
|
||||
result['sunset'] = sunset.replace(tzinfo=UTC)
|
||||
result['sunset'] = sunset.replace(tzinfo=timezone.utc)
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -1,38 +1,24 @@
|
|||
from __future__ import unicode_literals
|
||||
import os
|
||||
import logging
|
||||
import logging.config
|
||||
import re
|
||||
import random, string
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
import xml.etree.ElementTree as ET
|
||||
import urllib
|
||||
import json
|
||||
import copy
|
||||
import sys
|
||||
import unicodedata
|
||||
|
||||
import requests
|
||||
from requests.exceptions import ConnectionError, HTTPError, Timeout
|
||||
from bs4 import BeautifulSoup
|
||||
import pytz
|
||||
|
||||
from . import version
|
||||
from .consts import LookupConventions as const
|
||||
from .exceptions import APIKeyMissingError
|
||||
|
||||
UTC = pytz.UTC
|
||||
|
||||
REDIS_LUA_DEL_SCRIPT = "local keys = redis.call('keys', ARGV[1]) \n for i=1,#keys,20000 do \n redis.call('del', unpack(keys, i, math.min(i+19999, #keys))) \n end \n return keys"
|
||||
|
||||
if sys.version_info < (2, 7,):
|
||||
class NullHandler(logging.Handler):
|
||||
def emit(self, record):
|
||||
pass
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
unicode = str
|
||||
|
||||
class LookupLib(object):
|
||||
"""
|
||||
|
||||
|
|
@ -80,10 +66,7 @@ class LookupLib(object):
|
|||
self._logger = logger
|
||||
else:
|
||||
self._logger = logging.getLogger(__name__)
|
||||
if sys.version_info[:2] == (2, 6):
|
||||
self._logger.addHandler(NullHandler())
|
||||
else:
|
||||
self._logger.addHandler(logging.NullHandler())
|
||||
self._logger.addHandler(logging.NullHandler())
|
||||
|
||||
self._apikey = apikey
|
||||
self._apiv = apiv
|
||||
|
|
@ -131,10 +114,7 @@ class LookupLib(object):
|
|||
"agent" : agent
|
||||
}
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
encodeurl = url + "?" + urllib.parse.urlencode(params)
|
||||
else:
|
||||
encodeurl = url + "?" + urllib.urlencode(params)
|
||||
encodeurl = url + "?" + urllib.parse.urlencode(params)
|
||||
response = requests.get(encodeurl, timeout=10)
|
||||
doc = BeautifulSoup(response.text, "xml")
|
||||
session_key = None
|
||||
|
|
@ -334,7 +314,7 @@ class LookupLib(object):
|
|||
|
||||
Args:
|
||||
callsign (string): Amateur radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
dict: Dictionary containing the country specific data of the callsign
|
||||
|
|
@ -347,10 +327,9 @@ class LookupLib(object):
|
|||
The following code queries the the online Clublog API for the callsign "VK9XO" on a specific date.
|
||||
|
||||
>>> from pyhamtools import LookupLib
|
||||
>>> from datetime import datetime
|
||||
>>> import pytz
|
||||
>>> from datetime import datetime, timezone
|
||||
>>> my_lookuplib = LookupLib(lookuptype="clublogapi", apikey="myapikey")
|
||||
>>> timestamp = datetime(year=1962, month=7, day=7, tzinfo=pytz.UTC)
|
||||
>>> timestamp = datetime(year=1962, month=7, day=7, tzinfo=timezone.utc)
|
||||
>>> print my_lookuplib.lookup_callsign("VK9XO", timestamp)
|
||||
{
|
||||
'country': u'CHRISTMAS ISLAND',
|
||||
|
|
@ -374,7 +353,7 @@ class LookupLib(object):
|
|||
"""
|
||||
callsign = callsign.strip().upper()
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
if self._lookuptype == "clublogapi":
|
||||
callsign_data = self._lookup_clublogAPI(callsign=callsign, timestamp=timestamp, apikey=self._apikey)
|
||||
|
|
@ -499,7 +478,7 @@ class LookupLib(object):
|
|||
|
||||
Args:
|
||||
prefix (string): Prefix of a Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
dict: Dictionary containing the country specific data of the Prefix
|
||||
|
|
@ -536,7 +515,7 @@ class LookupLib(object):
|
|||
|
||||
prefix = prefix.strip().upper()
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
if self._lookuptype == "clublogxml" or self._lookuptype == "countryfile":
|
||||
|
||||
|
|
@ -556,7 +535,7 @@ class LookupLib(object):
|
|||
|
||||
Args:
|
||||
callsign (string): Amateur Radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
bool: True if a record exists for this callsign (at the given time)
|
||||
|
|
@ -569,13 +548,12 @@ class LookupLib(object):
|
|||
The following code checks the Clublog XML database if the operation is valid for two dates.
|
||||
|
||||
>>> from pyhamtools import LookupLib
|
||||
>>> from datetime import datetime
|
||||
>>> import pytz
|
||||
>>> from datetime import datetime, timezone
|
||||
>>> my_lookuplib = LookupLib(lookuptype="clublogxml", apikey="myapikey")
|
||||
>>> print my_lookuplib.is_invalid_operation("5W1CFN")
|
||||
True
|
||||
>>> try:
|
||||
>>> timestamp = datetime(year=2012, month=1, day=31).replace(tzinfo=pytz.UTC)
|
||||
>>> timestamp = datetime(year=2012, month=1, day=31, tzinfo=timezone.utc)
|
||||
>>> my_lookuplib.is_invalid_operation("5W1CFN", timestamp)
|
||||
>>> except KeyError:
|
||||
>>> print "Seems to be invalid operation before 31.1.2012"
|
||||
|
|
@ -591,7 +569,7 @@ class LookupLib(object):
|
|||
|
||||
callsign = callsign.strip().upper()
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
if self._lookuptype == "clublogxml":
|
||||
|
||||
|
|
@ -645,7 +623,7 @@ class LookupLib(object):
|
|||
|
||||
Args:
|
||||
callsign (string): Amateur radio callsign
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=pytz.UTC)
|
||||
timestamp (datetime, optional): datetime in UTC (tzinfo=timezone.utc)
|
||||
|
||||
Returns:
|
||||
int: Value of the the CQ Zone exception which exists for this callsign (at the given time)
|
||||
|
|
@ -675,7 +653,7 @@ class LookupLib(object):
|
|||
|
||||
callsign = callsign.strip().upper()
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
if self._lookuptype == "clublogxml":
|
||||
|
||||
|
|
@ -704,12 +682,9 @@ class LookupLib(object):
|
|||
}
|
||||
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
encodeurl = url + "?" + urllib.parse.urlencode(params)
|
||||
else:
|
||||
encodeurl = url + "?" + urllib.urlencode(params)
|
||||
encodeurl = url + "?" + urllib.parse.urlencode(params)
|
||||
response = requests.get(encodeurl, timeout=5)
|
||||
|
||||
if not self._check_html_response(response):
|
||||
|
|
@ -740,10 +715,7 @@ class LookupLib(object):
|
|||
"callsign" : callsign,
|
||||
}
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
encodeurl = url + "?" + urllib.parse.urlencode(params)
|
||||
else:
|
||||
encodeurl = url + "?" + urllib.urlencode(params)
|
||||
encodeurl = url + "?" + urllib.parse.urlencode(params)
|
||||
response = requests.get(encodeurl, timeout=5)
|
||||
return response
|
||||
|
||||
|
|
@ -756,10 +728,7 @@ class LookupLib(object):
|
|||
"dxcc" : str(dxcc_or_callsign),
|
||||
}
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
encodeurl = url + "?" + urllib.parse.urlencode(params)
|
||||
else:
|
||||
encodeurl = url + "?" + urllib.urlencode(params)
|
||||
encodeurl = url + "?" + urllib.parse.urlencode(params)
|
||||
response = requests.get(encodeurl, timeout=5)
|
||||
return response
|
||||
|
||||
|
|
@ -890,12 +859,12 @@ class LookupLib(object):
|
|||
lookup[const.LAND] = root.Callsign.land.text
|
||||
if root.Callsign.efdate:
|
||||
try:
|
||||
lookup[const.EFDATE] = datetime.strptime(root.Callsign.efdate.text, '%Y-%m-%d').replace(tzinfo=UTC)
|
||||
lookup[const.EFDATE] = datetime.strptime(root.Callsign.efdate.text, '%Y-%m-%d').replace(tzinfo=timezone.utc)
|
||||
except ValueError:
|
||||
self._logger.debug("[QRZ.com] efdate: Invalid DateTime; " + callsign + " " + root.Callsign.efdate.text)
|
||||
if root.Callsign.expdate:
|
||||
try:
|
||||
lookup[const.EXPDATE] = datetime.strptime(root.Callsign.expdate.text, '%Y-%m-%d').replace(tzinfo=UTC)
|
||||
lookup[const.EXPDATE] = datetime.strptime(root.Callsign.expdate.text, '%Y-%m-%d').replace(tzinfo=timezone.utc)
|
||||
except ValueError:
|
||||
self._logger.debug("[QRZ.com] expdate: Invalid DateTime; " + callsign + " " + root.Callsign.expdate.text)
|
||||
if root.Callsign.p_call:
|
||||
|
|
@ -916,7 +885,7 @@ class LookupLib(object):
|
|||
lookup[const.BIO] = root.Callsign.bio.text
|
||||
if root.Callsign.biodate:
|
||||
try:
|
||||
lookup[const.BIODATE] = datetime.strptime(root.Callsign.biodate.text, '%Y-%m-%d %H:%M:%S').replace(tzinfo=UTC)
|
||||
lookup[const.BIODATE] = datetime.strptime(root.Callsign.biodate.text, '%Y-%m-%d %H:%M:%S').replace(tzinfo=timezone.utc)
|
||||
except ValueError:
|
||||
self._logger.warning("[QRZ.com] biodate: Invalid DateTime; " + callsign)
|
||||
if root.Callsign.image:
|
||||
|
|
@ -927,7 +896,7 @@ class LookupLib(object):
|
|||
lookup[const.SERIAL] = long(root.Callsign.serial.text)
|
||||
if root.Callsign.moddate:
|
||||
try:
|
||||
lookup[const.MODDATE] = datetime.strptime(root.Callsign.moddate.text, '%Y-%m-%d %H:%M:%S').replace(tzinfo=UTC)
|
||||
lookup[const.MODDATE] = datetime.strptime(root.Callsign.moddate.text, '%Y-%m-%d %H:%M:%S').replace(tzinfo=timezone.utc)
|
||||
except ValueError:
|
||||
self._logger.warning("[QRZ.com] moddate: Invalid DateTime; " + callsign)
|
||||
if root.Callsign.MSA:
|
||||
|
|
@ -971,10 +940,6 @@ class LookupLib(object):
|
|||
if root.Callsign.geoloc:
|
||||
lookup[const.GEOLOC] = root.Callsign.geoloc.text
|
||||
|
||||
# if sys.version_info >= (2,):
|
||||
# for item in lookup:
|
||||
# if isinstance(lookup[item], unicode):
|
||||
# print item, repr(lookup[item])
|
||||
return lookup
|
||||
|
||||
def _load_clublogXML(self,
|
||||
|
|
@ -1135,7 +1100,7 @@ class LookupLib(object):
|
|||
if cty_date:
|
||||
cty_date = cty_date.group(0).replace("date=", "").replace("'", "")
|
||||
cty_date = datetime.strptime(cty_date[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
cty_date.replace(tzinfo=UTC)
|
||||
cty_date.replace(tzinfo=timezone.utc)
|
||||
cty_header["Date"] = cty_date
|
||||
|
||||
cty_ns = re.search("xmlns='.+[']", raw_header)
|
||||
|
|
@ -1215,10 +1180,10 @@ class LookupLib(object):
|
|||
entity = {}
|
||||
for item in cty_entity:
|
||||
if item.tag == "name":
|
||||
entity[const.COUNTRY] = unicode(item.text)
|
||||
self._logger.debug(unicode(item.text))
|
||||
entity[const.COUNTRY] = str(item.text)
|
||||
self._logger.debug(str(item.text))
|
||||
elif item.tag == "prefix":
|
||||
entity[const.PREFIX] = unicode(item.text)
|
||||
entity[const.PREFIX] = str(item.text)
|
||||
elif item.tag == "deleted":
|
||||
if item.text == "TRUE":
|
||||
entity[const.DELETED] = True
|
||||
|
|
@ -1227,17 +1192,17 @@ class LookupLib(object):
|
|||
elif item.tag == "cqz":
|
||||
entity[const.CQZ] = int(item.text)
|
||||
elif item.tag == "cont":
|
||||
entity[const.CONTINENT] = unicode(item.text)
|
||||
entity[const.CONTINENT] = str(item.text)
|
||||
elif item.tag == "long":
|
||||
entity[const.LONGITUDE] = float(item.text)
|
||||
elif item.tag == "lat":
|
||||
entity[const.LATITUDE] = float(item.text)
|
||||
elif item.tag == "start":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
entity[const.START] = dt.replace(tzinfo=UTC)
|
||||
entity[const.START] = dt.replace(tzinfo=timezone.utc)
|
||||
elif item.tag == "end":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
entity[const.END] = dt.replace(tzinfo=UTC)
|
||||
entity[const.END] = dt.replace(tzinfo=timezone.utc)
|
||||
elif item.tag == "whitelist":
|
||||
if item.text == "TRUE":
|
||||
entity[const.WHITELIST] = True
|
||||
|
|
@ -1245,10 +1210,10 @@ class LookupLib(object):
|
|||
entity[const.WHITELIST] = False
|
||||
elif item.tag == "whitelist_start":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
entity[const.WHITELIST_START] = dt.replace(tzinfo=UTC)
|
||||
entity[const.WHITELIST_START] = dt.replace(tzinfo=timezone.utc)
|
||||
elif item.tag == "whitelist_end":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
entity[const.WHITELIST_END] = dt.replace(tzinfo=UTC)
|
||||
entity[const.WHITELIST_END] = dt.replace(tzinfo=timezone.utc)
|
||||
except AttributeError:
|
||||
self._logger.error("Error while processing: ")
|
||||
entities[int(cty_entity[0].text)] = entity
|
||||
|
|
@ -1269,23 +1234,23 @@ class LookupLib(object):
|
|||
else:
|
||||
call_exceptions_index[call] = [int(cty_exception.attrib["record"])]
|
||||
elif item.tag == "entity":
|
||||
call_exception[const.COUNTRY] = unicode(item.text)
|
||||
call_exception[const.COUNTRY] = str(item.text)
|
||||
elif item.tag == "adif":
|
||||
call_exception[const.ADIF] = int(item.text)
|
||||
elif item.tag == "cqz":
|
||||
call_exception[const.CQZ] = int(item.text)
|
||||
elif item.tag == "cont":
|
||||
call_exception[const.CONTINENT] = unicode(item.text)
|
||||
call_exception[const.CONTINENT] = str(item.text)
|
||||
elif item.tag == "long":
|
||||
call_exception[const.LONGITUDE] = float(item.text)
|
||||
elif item.tag == "lat":
|
||||
call_exception[const.LATITUDE] = float(item.text)
|
||||
elif item.tag == "start":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
call_exception[const.START] = dt.replace(tzinfo=UTC)
|
||||
call_exception[const.START] = dt.replace(tzinfo=timezone.utc)
|
||||
elif item.tag == "end":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
call_exception[const.END] = dt.replace(tzinfo=UTC)
|
||||
call_exception[const.END] = dt.replace(tzinfo=timezone.utc)
|
||||
call_exceptions[int(cty_exception.attrib["record"])] = call_exception
|
||||
|
||||
self._logger.debug(str(len(call_exceptions))+" Exceptions added")
|
||||
|
|
@ -1310,23 +1275,23 @@ class LookupLib(object):
|
|||
else:
|
||||
prefixes_index[call] = [int(cty_prefix.attrib["record"])]
|
||||
if item.tag == "entity":
|
||||
prefix[const.COUNTRY] = unicode(item.text)
|
||||
prefix[const.COUNTRY] = str(item.text)
|
||||
elif item.tag == "adif":
|
||||
prefix[const.ADIF] = int(item.text)
|
||||
elif item.tag == "cqz":
|
||||
prefix[const.CQZ] = int(item.text)
|
||||
elif item.tag == "cont":
|
||||
prefix[const.CONTINENT] = unicode(item.text)
|
||||
prefix[const.CONTINENT] = str(item.text)
|
||||
elif item.tag == "long":
|
||||
prefix[const.LONGITUDE] = float(item.text)
|
||||
elif item.tag == "lat":
|
||||
prefix[const.LATITUDE] = float(item.text)
|
||||
elif item.tag == "start":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
prefix[const.START] = dt.replace(tzinfo=UTC)
|
||||
prefix[const.START] = dt.replace(tzinfo=timezone.utc)
|
||||
elif item.tag == "end":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
prefix[const.END] = dt.replace(tzinfo=UTC)
|
||||
prefix[const.END] = dt.replace(tzinfo=timezone.utc)
|
||||
prefixes[int(cty_prefix.attrib["record"])] = prefix
|
||||
|
||||
self._logger.debug(str(len(prefixes))+" Prefixes added")
|
||||
|
|
@ -1349,10 +1314,10 @@ class LookupLib(object):
|
|||
|
||||
elif item.tag == "start":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
invalid_operation[const.START] = dt.replace(tzinfo=UTC)
|
||||
invalid_operation[const.START] = dt.replace(tzinfo=timezone.utc)
|
||||
elif item.tag == "end":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
invalid_operation[const.END] = dt.replace(tzinfo=UTC)
|
||||
invalid_operation[const.END] = dt.replace(tzinfo=timezone.utc)
|
||||
invalid_operations[int(cty_inv_operation.attrib["record"])] = invalid_operation
|
||||
|
||||
self._logger.debug(str(len(invalid_operations))+" Invalid Operations added")
|
||||
|
|
@ -1378,10 +1343,10 @@ class LookupLib(object):
|
|||
zoneException[const.CQZ] = int(item.text)
|
||||
elif item.tag == "start":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
zoneException[const.START] = dt.replace(tzinfo=UTC)
|
||||
zoneException[const.START] = dt.replace(tzinfo=timezone.utc)
|
||||
elif item.tag == "end":
|
||||
dt = datetime.strptime(item.text[:19], '%Y-%m-%dT%H:%M:%S')
|
||||
zoneException[const.END] = dt.replace(tzinfo=UTC)
|
||||
zoneException[const.END] = dt.replace(tzinfo=timezone.utc)
|
||||
zone_exceptions[int(cty_zone_exception.attrib["record"])] = zoneException
|
||||
|
||||
self._logger.debug(str(len(zone_exceptions))+" Zone Exceptions added")
|
||||
|
|
@ -1437,12 +1402,12 @@ class LookupLib(object):
|
|||
for item in cty_list:
|
||||
entry = {}
|
||||
call = str(item)
|
||||
entry[const.COUNTRY] = unicode(cty_list[item]["Country"])
|
||||
entry[const.COUNTRY] = str(cty_list[item]["Country"])
|
||||
if mapping:
|
||||
entry[const.ADIF] = int(mapping[cty_list[item]["Country"]])
|
||||
entry[const.CQZ] = int(cty_list[item]["CQZone"])
|
||||
entry[const.ITUZ] = int(cty_list[item]["ITUZone"])
|
||||
entry[const.CONTINENT] = unicode(cty_list[item]["Continent"])
|
||||
entry[const.CONTINENT] = str(cty_list[item]["Continent"])
|
||||
entry[const.LATITUDE] = float(cty_list[item]["Latitude"])
|
||||
entry[const.LONGITUDE] = float(cty_list[item]["Longitude"])*(-1)
|
||||
|
||||
|
|
@ -1534,17 +1499,17 @@ class LookupLib(object):
|
|||
elif item == const.LONGITUDE:
|
||||
my_dict[item] = float(my_dict[item])
|
||||
elif item == const.START:
|
||||
my_dict[item] = datetime.strptime(my_dict[item], '%Y-%m-%d%H:%M:%S').replace(tzinfo=UTC)
|
||||
my_dict[item] = datetime.strptime(my_dict[item], '%Y-%m-%d%H:%M:%S').replace(tzinfo=timezone.utc)
|
||||
elif item == const.END:
|
||||
my_dict[item] = datetime.strptime(my_dict[item], '%Y-%m-%d%H:%M:%S').replace(tzinfo=UTC)
|
||||
my_dict[item] = datetime.strptime(my_dict[item], '%Y-%m-%d%H:%M:%S').replace(tzinfo=timezone.utc)
|
||||
elif item == const.WHITELIST_START:
|
||||
my_dict[item] = datetime.strptime(my_dict[item], '%Y-%m-%d%H:%M:%S').replace(tzinfo=UTC)
|
||||
my_dict[item] = datetime.strptime(my_dict[item], '%Y-%m-%d%H:%M:%S').replace(tzinfo=timezone.utc)
|
||||
elif item == const.WHITELIST_END:
|
||||
my_dict[item] = datetime.strptime(my_dict[item], '%Y-%m-%d%H:%M:%S').replace(tzinfo=UTC)
|
||||
my_dict[item] = datetime.strptime(my_dict[item], '%Y-%m-%d%H:%M:%S').replace(tzinfo=timezone.utc)
|
||||
elif item == const.WHITELIST:
|
||||
my_dict[item] = self._str_to_bool(my_dict[item])
|
||||
else:
|
||||
my_dict[item] = unicode(my_dict[item])
|
||||
my_dict[item] = str(my_dict[item])
|
||||
|
||||
return my_dict
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
from future.utils import iteritems
|
||||
from datetime import datetime
|
||||
import re
|
||||
|
||||
|
|
@ -125,7 +124,7 @@ def get_clublog_users(**kwargs):
|
|||
|
||||
error_count = 0
|
||||
|
||||
for call, call_data in iteritems(cl_data):
|
||||
for call, call_data in cl_data.items():
|
||||
try:
|
||||
data = {}
|
||||
if "firstqso" in call_data:
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
VERSION = (0, 8, 7)
|
||||
VERSION = (0, 9, 0)
|
||||
__release__ = ''.join(['-.'[type(x) == int]+str(x) for x in VERSION])[1:]
|
||||
__version__ = '.'.join((str(VERSION[0]), str(VERSION[1])))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
pytest>=7.0.0; python_version>='3.7'
|
||||
pytest==4.6.11; python_version<='3.6' and python_version>='2.7'
|
||||
pytest==4.6.11; python_version=='3.6'
|
||||
pytest-blockage>=0.2.2
|
||||
pytest-localserver>=0.5
|
||||
pytest-cov>=2.12
|
||||
|
|
|
|||
3
setup.py
3
setup.py
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
import os
|
||||
from distutils.core import setup
|
||||
|
||||
|
|
@ -16,12 +15,10 @@ setup(name='pyhamtools',
|
|||
package_data={'': ['countryfilemapping.json']},
|
||||
packages=['pyhamtools'],
|
||||
install_requires=[
|
||||
"pytz>=2019.1",
|
||||
"requests>=2.21.0",
|
||||
"ephem>=4.1.3",
|
||||
"beautifulsoup4>=4.7.1",
|
||||
"lxml>=4.8.0",
|
||||
"future>=0.18.2",
|
||||
"redis>=2.10.6",
|
||||
],
|
||||
**kw
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pyhamtools.consts import LookupConventions as const
|
||||
|
||||
UTC = pytz.UTC
|
||||
|
||||
|
||||
response_prefix_DH_clublog = {
|
||||
'country': 'FEDERAL REPUBLIC OF GERMANY',
|
||||
'adif': 230,
|
||||
|
|
@ -198,8 +194,8 @@ response_Exception_VK9XO_with_start_date = {
|
|||
'adif': 35,
|
||||
'country': 'CHRISTMAS ISLAND',
|
||||
'continent': 'OC',
|
||||
'latitude': -10.50,
|
||||
'longitude': 105.70,
|
||||
'latitude': -10.48,
|
||||
'longitude': 105.71,
|
||||
'cqz': 29
|
||||
}
|
||||
|
||||
|
|
@ -389,7 +385,7 @@ class Test_callinfo_methods:
|
|||
if fix_callinfo._lookuplib._lookuptype == "clublogxml" or fix_callinfo._lookuplib._lookuptype == "clublogapi":
|
||||
assert fix_callinfo.get_all("DH1TW") == response_prefix_DH_clublog
|
||||
assert fix_callinfo.get_all("ci8aw") == response_zone_exception_ci8aw
|
||||
timestamp = datetime(year=2016, month=1, day=20, tzinfo=UTC)
|
||||
timestamp = datetime(year=2016, month=1, day=20, tzinfo=timezone.utc)
|
||||
assert fix_callinfo.get_all("VP8STI", timestamp) == response_Exception_VP8STI_with_start_and_stop_date
|
||||
|
||||
elif fix_callinfo._lookuplib._lookuptype == "countryfile":
|
||||
|
|
|
|||
|
|
@ -1,15 +1,9 @@
|
|||
import os
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
import pytest
|
||||
from future.utils import iteritems
|
||||
|
||||
from pyhamtools.qsl import get_clublog_users
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
unicode = str
|
||||
|
||||
test_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
fix_dir = os.path.join(test_dir, 'fixtures')
|
||||
|
||||
|
|
@ -26,8 +20,8 @@ class Test_clublog_methods:
|
|||
|
||||
data = get_clublog_users()
|
||||
assert isinstance(data, dict)
|
||||
for key, value in iteritems(data):
|
||||
assert isinstance(key, unicode)
|
||||
for key, value in data.items():
|
||||
assert isinstance(key, str)
|
||||
assert isinstance(value, dict)
|
||||
|
||||
def test_with_invalid_url(self):
|
||||
|
|
|
|||
|
|
@ -1,15 +1,9 @@
|
|||
import pytest
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
import pytz
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from pyhamtools.consts import LookupConventions as const
|
||||
from pyhamtools.dxcluster import decode_char_spot, decode_pc11_message, decode_pc61_message
|
||||
|
||||
UTC = pytz.UTC
|
||||
|
||||
fix_spot1 = "DX de CT3FW: 21004.8 HC2AO 599 TKS(CW)QSL READ,QRZ.COM 2132Z"
|
||||
fix_spot1_broken_spotter_call = "DX de $QRM: 21004.8 HC2AO 599 TKS(CW)QSL READ,QRZ.COM 2132Z"
|
||||
|
||||
|
|
@ -34,7 +28,7 @@ response_spot1 = {
|
|||
const.BAND: 15,
|
||||
const.MODE: "CW",
|
||||
const.COMMENT: "599 TKS(CW)QSL READ,QRZ.COM",
|
||||
const.TIME: datetime.utcnow().replace( hour=21, minute=32, second=0, microsecond = 0, tzinfo=UTC)
|
||||
const.TIME: datetime.now(timezone.utc).replace(hour=21, minute=32, second=0, microsecond = 0)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
from .execfile import execfile
|
||||
import os
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
import pytest
|
||||
|
||||
from pyhamtools.qsl import get_eqsl_users
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
unicode = str
|
||||
|
||||
test_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
fix_dir = os.path.join(test_dir, 'fixtures')
|
||||
class Test_eqsl_methods:
|
||||
|
|
@ -26,7 +21,7 @@ class Test_eqsl_methods:
|
|||
data = get_eqsl_users()
|
||||
assert isinstance(data, list)
|
||||
for el in data:
|
||||
assert isinstance(el, unicode)
|
||||
assert isinstance(el, str)
|
||||
assert len(data) > 1000
|
||||
|
||||
def test_with_invalid_url(self):
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pyhamtools.locator import calculate_sunrise_sunset
|
||||
|
||||
UTC = pytz.UTC
|
||||
|
||||
class Test_calculate_sunrise_sunset_normal_case():
|
||||
|
||||
def test_calculate_sunrise_sunset(self):
|
||||
|
|
@ -14,11 +11,11 @@ class Test_calculate_sunrise_sunset_normal_case():
|
|||
time_margin = timedelta(minutes=1)
|
||||
locator = "JN48QM"
|
||||
|
||||
test_time = datetime(year=2014, month=1, day=1, tzinfo=UTC)
|
||||
result_JN48QM_1_1_2014_evening_dawn = datetime(2014, 1, 1, 15, 38, tzinfo=UTC)
|
||||
result_JN48QM_1_1_2014_morning_dawn = datetime(2014, 1, 1, 6, 36, tzinfo=UTC)
|
||||
result_JN48QM_1_1_2014_sunrise = datetime(2014, 1, 1, 7, 14, tzinfo=UTC)
|
||||
result_JN48QM_1_1_2014_sunset = datetime(2014, 1, 1, 16, 15, 23, 31016, tzinfo=UTC)
|
||||
test_time = datetime(year=2014, month=1, day=1, tzinfo=timezone.utc)
|
||||
result_JN48QM_1_1_2014_evening_dawn = datetime(2014, 1, 1, 15, 38, tzinfo=timezone.utc)
|
||||
result_JN48QM_1_1_2014_morning_dawn = datetime(2014, 1, 1, 6, 36, tzinfo=timezone.utc)
|
||||
result_JN48QM_1_1_2014_sunrise = datetime(2014, 1, 1, 7, 14, tzinfo=timezone.utc)
|
||||
result_JN48QM_1_1_2014_sunset = datetime(2014, 1, 1, 16, 15, 23, 31016, tzinfo=timezone.utc)
|
||||
|
||||
assert calculate_sunrise_sunset(locator, test_time)['morning_dawn'] - result_JN48QM_1_1_2014_morning_dawn < time_margin
|
||||
assert calculate_sunrise_sunset(locator, test_time)['evening_dawn'] - result_JN48QM_1_1_2014_evening_dawn < time_margin
|
||||
|
|
@ -33,7 +30,7 @@ class Test_calculate_sunrise_sunset_normal_case():
|
|||
# The sun never rises in winter time close to the north pole (e.g. at Jan Mayen)
|
||||
# Therefore we expect no sunrise or sunset.
|
||||
|
||||
test_time = datetime(year=2021, month=12, day=15, tzinfo=UTC)
|
||||
test_time = datetime(year=2021, month=12, day=15, tzinfo=timezone.utc)
|
||||
|
||||
assert calculate_sunrise_sunset(locator, test_time)['morning_dawn'] == None
|
||||
assert calculate_sunrise_sunset(locator, test_time)['evening_dawn'] == None
|
||||
|
|
@ -48,7 +45,7 @@ class Test_calculate_sunrise_sunset_normal_case():
|
|||
# The sun never sets at the south pole during arctic summer
|
||||
# Therefore we expect no sunrise or sunset.
|
||||
|
||||
test_time = datetime(year=2014, month=1, day=1, tzinfo=UTC)
|
||||
test_time = datetime(year=2014, month=1, day=1, tzinfo=timezone.utc)
|
||||
|
||||
assert calculate_sunrise_sunset(locator, test_time)['morning_dawn'] == None
|
||||
assert calculate_sunrise_sunset(locator, test_time)['evening_dawn'] == None
|
||||
|
|
|
|||
|
|
@ -1,13 +1,8 @@
|
|||
from __future__ import unicode_literals
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
from pyhamtools.lookuplib import LookupLib
|
||||
from pyhamtools.exceptions import APIKeyMissingError
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
unicode = str
|
||||
|
||||
@pytest.fixture(scope="function", params=[5, -5, "", "foo bar", 11.5, {}, [], None, ("foo", "bar")])
|
||||
def fixAnyValue(request):
|
||||
return request.param
|
||||
|
|
@ -41,5 +36,5 @@ class TestlookupLibHelper:
|
|||
with pytest.raises(TypeError):
|
||||
fixClublogApi._generate_random_word()
|
||||
|
||||
assert type(fixClublogApi._generate_random_word(5)) is unicode
|
||||
assert type(fixClublogApi._generate_random_word(5)) is str
|
||||
assert len(fixClublogApi._generate_random_word(5)) == 5
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import pytest
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from pyhamtools.lookuplib import LookupLib
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ class TestclublogApi_Getters:
|
|||
def test_lookup_callsign(self, fixClublogApi):
|
||||
assert fixClublogApi.lookup_callsign("DH1TW") == response_Exception_DH1TW
|
||||
assert fixClublogApi.lookup_callsign("VU9KV") == response_Exception_VU9KV
|
||||
d = datetime.utcnow().replace(year=1971, month=4, day=14)
|
||||
d = datetime.now(timezone.utc).replace(year=1971, month=4, day=14)
|
||||
assert fixClublogApi.lookup_callsign("VU9KV", d) == response_Exception_VU9KV_with_Date
|
||||
assert fixClublogApi.lookup_callsign("DH1TW/MM") == response_Exception_DH1TW_MM
|
||||
assert fixClublogApi.lookup_callsign("DH1TW/AM") == response_Exception_DH1TW_AM
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
import pytest
|
||||
from datetime import datetime
|
||||
import pytz
|
||||
from datetime import datetime, timezone
|
||||
import os
|
||||
|
||||
from pyhamtools.lookuplib import LookupLib
|
||||
from pyhamtools.exceptions import APIKeyMissingError
|
||||
|
||||
UTC = pytz.UTC
|
||||
|
||||
|
||||
#Fixtures
|
||||
#===========================================================
|
||||
|
|
@ -55,8 +52,8 @@ response_Exception_VK9XO_with_start_date = {
|
|||
'adif': 35,
|
||||
'country': u'CHRISTMAS ISLAND',
|
||||
'continent': u'OC',
|
||||
'latitude': -10.50,
|
||||
'longitude': 105.70,
|
||||
'latitude': -10.48,
|
||||
'longitude': 105.71,
|
||||
'cqz': 29,
|
||||
}
|
||||
|
||||
|
|
@ -142,40 +139,40 @@ class TestclublogXML_Getters:
|
|||
#===============================
|
||||
|
||||
def test_lookup_callsign_same_callsign_different_exceptions(self, fixClublogXML):
|
||||
timestamp = datetime(year=1990, month=10, day=12, tzinfo=UTC)
|
||||
timestamp = datetime(year=1990, month=10, day=12, tzinfo=timezone.utc)
|
||||
assert fixClublogXML.lookup_callsign("kc6mm", timestamp) == response_Exception_KC6MM_1990
|
||||
|
||||
timestamp = datetime(year=1992, month=3, day=8, tzinfo=UTC)
|
||||
timestamp = datetime(year=1992, month=3, day=8, tzinfo=timezone.utc)
|
||||
assert fixClublogXML.lookup_callsign("kc6mm", timestamp) == response_Exception_KC6MM_1992
|
||||
|
||||
def test_lookup_callsign_exception_only_with_start_date(self, fixClublogXML):
|
||||
#timestamp > startdate
|
||||
timestamp = datetime(year=1962, month=7, day=7, tzinfo=UTC)
|
||||
timestamp = datetime(year=1962, month=7, day=7, tzinfo=timezone.utc)
|
||||
assert fixClublogXML.lookup_callsign("vk9xo", timestamp) == response_Exception_VK9XO_with_start_date
|
||||
assert fixClublogXML.lookup_callsign("vk9xo") == response_Exception_VK9XO_with_start_date
|
||||
|
||||
#timestamp < startdate
|
||||
timestamp = datetime(year=1962, month=7, day=5, tzinfo=UTC)
|
||||
timestamp = datetime(year=1962, month=7, day=5, tzinfo=timezone.utc)
|
||||
with pytest.raises(KeyError):
|
||||
fixClublogXML.lookup_callsign("vk9xo", timestamp)
|
||||
|
||||
def test_lookup_callsign_exception_only_with_end_date(self, fixClublogXML):
|
||||
|
||||
#timestamp < enddate
|
||||
timestamp = datetime(year=1975, month=9, day=14, tzinfo=UTC)
|
||||
timestamp = datetime(year=1975, month=9, day=14, tzinfo=timezone.utc)
|
||||
assert fixClublogXML.lookup_callsign("vk9xx", timestamp) == response_Exception_VK9XX_with_end_date
|
||||
|
||||
# timestamp > enddate
|
||||
with pytest.raises(KeyError):
|
||||
fixClublogXML.lookup_callsign("vk9xx")
|
||||
|
||||
timestamp = datetime(year=1975, month=9, day=16, tzinfo=UTC)
|
||||
timestamp = datetime(year=1975, month=9, day=16, tzinfo=timezone.utc)
|
||||
with pytest.raises(KeyError):
|
||||
fixClublogXML.lookup_callsign("vk9xx", timestamp)
|
||||
|
||||
def test_lookup_callsign_exception_no_start_nor_end_date(self, fixClublogXML):
|
||||
|
||||
timestamp = datetime(year=1975, month=9, day=14, tzinfo=UTC)
|
||||
timestamp = datetime(year=1975, month=9, day=14, tzinfo=timezone.utc)
|
||||
assert fixClublogXML.lookup_callsign("ax9nyg", timestamp) == response_Exception_AX9NYG
|
||||
assert fixClublogXML.lookup_callsign("ax9nyg" ) == response_Exception_AX9NYG
|
||||
|
||||
|
|
@ -196,29 +193,29 @@ class TestclublogXML_Getters:
|
|||
|
||||
def test_lookup_prefix_with_changing_entities(self, fixClublogXML):
|
||||
#return old entity (PAPUA TERR)
|
||||
timestamp = datetime(year=1975, month=9, day=14).replace(tzinfo=UTC)
|
||||
timestamp = datetime(year=1975, month=9, day=14, tzinfo=timezone.utc)
|
||||
assert fixClublogXML.lookup_prefix("VK9", timestamp) == response_Prefix_VK9_until_1975
|
||||
|
||||
#return empty dict - Prefix was not assigned at that time
|
||||
timestamp = datetime(year=1975, month=9, day=16).replace(tzinfo=UTC)
|
||||
timestamp = datetime(year=1975, month=9, day=16, tzinfo=timezone.utc)
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
fixClublogXML.lookup_prefix("VK9", timestamp)
|
||||
|
||||
#return new entity (Norfolk Island)
|
||||
timestamp = datetime.utcnow().replace(tzinfo=UTC)
|
||||
timestamp = datetime.now(timezone.utc)
|
||||
assert fixClublogXML.lookup_prefix("VK9", timestamp ) == response_Prefix_VK9_starting_1976
|
||||
|
||||
def test_lookup_prefix_with_entities_having_start_and_stop(self, fixClublogXML):
|
||||
|
||||
timestamp_before = datetime(year=1964, month=11, day=1).replace(tzinfo=UTC)
|
||||
timestamp_before = datetime(year=1964, month=11, day=1, tzinfo=timezone.utc)
|
||||
with pytest.raises(KeyError):
|
||||
fixClublogXML.lookup_prefix("ZD5", timestamp_before)
|
||||
|
||||
timestamp_valid = datetime(year=1964, month=12, day=2).replace(tzinfo=UTC)
|
||||
timestamp_valid = datetime(year=1964, month=12, day=2, tzinfo=timezone.utc)
|
||||
assert fixClublogXML.lookup_prefix("ZD5", timestamp_valid) == response_Prefix_ZD5_1964_to_1971
|
||||
|
||||
timestamp_after = datetime(year=1971, month=8, day=1).replace(tzinfo=UTC)
|
||||
timestamp_after = datetime(year=1971, month=8, day=1, tzinfo=timezone.utc)
|
||||
with pytest.raises(KeyError):
|
||||
fixClublogXML.lookup_prefix("ZD5", timestamp_after)
|
||||
|
||||
|
|
@ -234,8 +231,8 @@ class TestclublogXML_Getters:
|
|||
fixClublogXML.is_invalid_operation("dh1tw")
|
||||
|
||||
#Invalid Operation with start and end date
|
||||
timestamp_before = datetime(year=1993, month=12, day=30).replace(tzinfo=UTC)
|
||||
timestamp = datetime(year=1994, month=12, day=30).replace(tzinfo=UTC)
|
||||
timestamp_before = datetime(year=1993, month=12, day=30, tzinfo=timezone.utc)
|
||||
timestamp = datetime(year=1994, month=12, day=30, tzinfo=timezone.utc)
|
||||
with pytest.raises(KeyError):
|
||||
fixClublogXML.is_invalid_operation("vk0mc")
|
||||
|
||||
|
|
@ -246,7 +243,7 @@ class TestclublogXML_Getters:
|
|||
|
||||
#Invalid Operation with start date
|
||||
assert fixClublogXML.is_invalid_operation("5W1CFN")
|
||||
timestamp_before = datetime(year=2012, month=1, day=31).replace(tzinfo=UTC)
|
||||
timestamp_before = datetime(year=2012, month=1, day=31, tzinfo=timezone.utc)
|
||||
with pytest.raises(KeyError):
|
||||
fixClublogXML.is_invalid_operation("5W1CFN", timestamp_before)
|
||||
|
||||
|
|
@ -264,9 +261,9 @@ class TestclublogXML_Getters:
|
|||
assert fixClublogXML.lookup_zone_exception("dp0gvn") == 38
|
||||
|
||||
#zone exception with start and end date
|
||||
timestamp = datetime(year=1992, month=10, day=2).replace(tzinfo=UTC)
|
||||
timestamp_before = datetime(year=1992, month=9, day=30).replace(tzinfo=UTC)
|
||||
timestamp_after = datetime(year=1993, month=3, day=1).replace(tzinfo=UTC)
|
||||
timestamp = datetime(year=1992, month=10, day=2, tzinfo=timezone.utc)
|
||||
timestamp_before = datetime(year=1992, month=9, day=30, tzinfo=timezone.utc)
|
||||
timestamp_after = datetime(year=1993, month=3, day=1, tzinfo=timezone.utc)
|
||||
assert fixClublogXML.lookup_zone_exception("dl1kvc/p", timestamp) == 38
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
|
|
@ -276,6 +273,6 @@ class TestclublogXML_Getters:
|
|||
fixClublogXML.lookup_zone_exception("dl1kvc/p", timestamp_after)
|
||||
|
||||
#zone exception with start date
|
||||
timestamp_before = datetime(year=2013, month=12, day=26).replace(tzinfo=UTC)
|
||||
timestamp_before = datetime(year=2013, month=12, day=26,tzinfo=timezone.utc)
|
||||
with pytest.raises(KeyError):
|
||||
fixClublogXML.lookup_zone_exception("dh1hb/p", timestamp_before)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,4 @@
|
|||
from __future__ import unicode_literals
|
||||
import pytest
|
||||
import tempfile
|
||||
import os
|
||||
import sys
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
unicode = str
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
|
|
@ -58,13 +51,13 @@ class Test_Getter_Setter_Api_Types_for_all_sources:
|
|||
count = 0
|
||||
for attr in entity:
|
||||
if attr == "country":
|
||||
assert type(entity[attr] is unicode)
|
||||
assert type(entity[attr] is str)
|
||||
count +=1
|
||||
if attr == "continent":
|
||||
assert type(entity[attr] is unicode)
|
||||
assert type(entity[attr] is str)
|
||||
count +=1
|
||||
if attr == "prefix":
|
||||
assert type(entity[attr] is unicode)
|
||||
assert type(entity[attr] is str)
|
||||
count +=1
|
||||
if attr == "deleted":
|
||||
assert type(entity[attr] is bool)
|
||||
|
|
@ -114,10 +107,10 @@ class Test_Getter_Setter_Api_Types_for_all_sources:
|
|||
assert type(ex[attr]) is float
|
||||
count +=1
|
||||
elif attr == "country":
|
||||
assert type(ex[attr]) is unicode
|
||||
assert type(ex[attr]) is str
|
||||
count +=1
|
||||
elif attr == "continent":
|
||||
assert type(ex[attr]) is unicode
|
||||
assert type(ex[attr]) is str
|
||||
count +=1
|
||||
elif attr == "cqz":
|
||||
assert type(ex[attr]) is int
|
||||
|
|
@ -150,7 +143,7 @@ class Test_Getter_Setter_Api_Types_for_all_sources:
|
|||
count = 0
|
||||
for attr in prefix:
|
||||
if attr == "country":
|
||||
assert type(prefix[attr]) is unicode
|
||||
assert type(prefix[attr]) is str
|
||||
count +=1
|
||||
elif attr == "adif":
|
||||
assert type(prefix[attr]) is int
|
||||
|
|
@ -162,7 +155,7 @@ class Test_Getter_Setter_Api_Types_for_all_sources:
|
|||
assert type(prefix[attr]) is int
|
||||
count +=1
|
||||
elif attr == "continent":
|
||||
assert type(prefix[attr]) is unicode
|
||||
assert type(prefix[attr]) is str
|
||||
count +=1
|
||||
elif attr == "latitude":
|
||||
assert type(prefix[attr]) is float
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
import os
|
||||
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from pyhamtools.lookuplib import LookupLib
|
||||
from pyhamtools.exceptions import APIKeyMissingError
|
||||
from pyhamtools.consts import LookupConventions as const
|
||||
|
||||
import pytz
|
||||
UTC = pytz.UTC
|
||||
|
||||
|
||||
try:
|
||||
QRZ_USERNAME = str(os.environ['QRZ_USERNAME'])
|
||||
QRZ_PWD = str(os.environ['QRZ_PWD'])
|
||||
|
|
@ -21,10 +17,10 @@ except Exception:
|
|||
#===========================================================
|
||||
|
||||
response_1A1AB = {
|
||||
u'biodate': datetime(2018, 9, 7, 21, 17, 7, tzinfo=UTC),
|
||||
u'biodate': datetime(2018, 9, 7, 21, 17, 7, tzinfo=timezone.utc),
|
||||
u'bio': u'0',
|
||||
u'license_class': u'C',
|
||||
u'moddate': datetime(2008, 11, 2, 15, 0, 38, tzinfo=UTC),
|
||||
u'moddate': datetime(2008, 11, 2, 15, 0, 38, tzinfo=timezone.utc),
|
||||
u'locator': u'JN61fw',
|
||||
u'callsign': u'1A1AB',
|
||||
u'addr2': u'00187 Rome',
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
import pytest
|
||||
import json
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import pytz
|
||||
import redis
|
||||
|
||||
from pyhamtools import LookupLib, Callinfo
|
||||
|
||||
|
||||
UTC = pytz.UTC
|
||||
|
||||
r = redis.Redis()
|
||||
|
||||
|
||||
|
|
@ -44,7 +40,7 @@ class TestStoreDataInRedis:
|
|||
with pytest.raises(KeyError):
|
||||
fix_redis.is_invalid_operation("VK0MC")
|
||||
|
||||
timestamp = datetime(year=1994, month=12, day=30).replace(tzinfo=UTC)
|
||||
timestamp = datetime(year=1994, month=12, day=30, tzinfo=timezone.utc)
|
||||
assert fix_redis.is_invalid_operation("VK0MC", timestamp)
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
|
|
@ -61,7 +57,7 @@ class TestStoreDataInRedis:
|
|||
assert lib.lookup_prefix("DH") == fixCountryFile.lookup_prefix("DH")
|
||||
|
||||
def test_redis_lookup(self, fixClublogXML, fix_redis):
|
||||
timestamp = datetime(year=2016, month=1, day=20, tzinfo=UTC)
|
||||
timestamp = datetime(year=2016, month=1, day=20, tzinfo=timezone.utc)
|
||||
ci = Callinfo(fix_redis)
|
||||
assert ci.get_all("VP8STI", timestamp) == response_Exception_VP8STI_with_start_and_stop_date
|
||||
assert ci.get_all("tu5pct") == response_TU5PCT
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import os
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
from .execfile import execfile
|
||||
from future.utils import iteritems
|
||||
import pytest
|
||||
|
||||
def execfile(filepath, globals=None, locals=None):
|
||||
|
|
@ -19,9 +17,6 @@ def execfile(filepath, globals=None, locals=None):
|
|||
|
||||
from pyhamtools.qsl import get_lotw_users
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
unicode = str
|
||||
|
||||
test_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
fix_dir = os.path.join(test_dir, 'fixtures')
|
||||
|
||||
|
|
@ -38,8 +33,8 @@ class Test_lotw_methods:
|
|||
|
||||
data = get_lotw_users()
|
||||
assert isinstance(data, dict)
|
||||
for key, value in iteritems(data):
|
||||
assert isinstance(key, unicode)
|
||||
for key, value in data.items():
|
||||
assert isinstance(key, str)
|
||||
assert isinstance(value, datetime.datetime )
|
||||
assert len(data) > 1000
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue