Compare commits
15 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e5b25853d | ||
|
|
bc03da935e | ||
|
|
0fd1e39356 | ||
|
|
71e490867f | ||
|
|
c5c9d4bcf7 | ||
|
|
12b6628c31 | ||
|
|
1e02ad4b8a | ||
|
|
cf33f09c37 | ||
|
|
e98c04ef0f | ||
|
|
c307c40e2c | ||
|
|
34bc5e69e2 | ||
|
|
c956583dc2 | ||
|
|
26d11c7309 | ||
|
|
789902c413 | ||
|
|
a9e0873869 |
5 changed files with 254 additions and 72 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -26,3 +26,9 @@
|
||||||
/OWSLib-0.20.0.tar.gz
|
/OWSLib-0.20.0.tar.gz
|
||||||
/OWSLib-0.21.0.tar.gz
|
/OWSLib-0.21.0.tar.gz
|
||||||
/OWSLib-0.25.0.tar.gz
|
/OWSLib-0.25.0.tar.gz
|
||||||
|
/OWSLib-0.26.0.tar.gz
|
||||||
|
/OWSLib-0.27.2.tar.gz
|
||||||
|
/OWSLib-0.28.0.tar.gz
|
||||||
|
/OWSLib-0.28.1.tar.gz
|
||||||
|
/OWSLib-0.28.1-filtered.tar.zst
|
||||||
|
/OWSLib-0.28.1-filtered.tar.xz
|
||||||
|
|
|
||||||
63
get_source
Executable file
63
get_source
Executable file
|
|
@ -0,0 +1,63 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -o nounset
|
||||||
|
set -o errexit
|
||||||
|
|
||||||
|
FORGEURL='https://github.com/geopython/OWSLib'
|
||||||
|
|
||||||
|
print_help()
|
||||||
|
{
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $1 VERSION
|
||||||
|
|
||||||
|
Generate a source archive for OWSLib with questionably-licensed XML files in
|
||||||
|
tests/resources/ removed. The result will be named
|
||||||
|
OWSLib-\${VERSION}-filtered.tar.xz and will be written into the current
|
||||||
|
working directory.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$#" != '1' ]
|
||||||
|
then
|
||||||
|
exec 1>&2
|
||||||
|
print_help "${0}"
|
||||||
|
exit 1
|
||||||
|
elif [ "${1-}" = '-h' ] || [ "${1-}" = '--help' ]
|
||||||
|
then
|
||||||
|
print_help "${0}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
VERSION="${1}"
|
||||||
|
SOURCE0="${FORGEURL}/archive/${VERSION}/OWSLib-${VERSION}.tar.gz"
|
||||||
|
TARNAME="$(basename "${SOURCE0}")"
|
||||||
|
TARDIR="$(basename "${SOURCE0}" '.tar.gz')"
|
||||||
|
NEWTAR="${TARDIR}-filtered.tar.xz"
|
||||||
|
|
||||||
|
SAVEDIR="${PWD}"
|
||||||
|
XDIR="$(mktemp -d)"
|
||||||
|
trap "rm -rf '${XDIR}'" INT TERM EXIT
|
||||||
|
|
||||||
|
cd "${XDIR}"
|
||||||
|
curl -L -O "${SOURCE0}"
|
||||||
|
echo "Extracting ${TARNAME}…" 1>&2
|
||||||
|
tar -xzf "${TARNAME}"
|
||||||
|
MTIME="$(stat -c '%Y' "${TARDIR}")"
|
||||||
|
rm -rvf "${TARDIR}/tests/resources"
|
||||||
|
echo "Re-compressing as ${NEWTAR}…" 1>&2
|
||||||
|
# https://www.gnu.org/software/tar/manual/html_section/Reproducibility.html
|
||||||
|
# We reset all mtimes to that of the top-level extracted directory; since git
|
||||||
|
# archives don’t have meaningful per-file mtimes, nothing useful is lost.
|
||||||
|
TZ=UTC LC_ALL=C tar \
|
||||||
|
--create \
|
||||||
|
--sort=name \
|
||||||
|
--format=posix \
|
||||||
|
--numeric-owner --owner=0 --group=0 \
|
||||||
|
--mode=go+u,go-w \
|
||||||
|
--pax-option='delete=atime,delete=ctime' \
|
||||||
|
--clamp-mtime --mtime="@${MTIME}" \
|
||||||
|
"${TARDIR}/" |
|
||||||
|
xz -9 -e > "${NEWTAR}"
|
||||||
|
touch -d @"${MTIME}" "${NEWTAR}"
|
||||||
|
|
||||||
|
cd "${SAVEDIR}"
|
||||||
|
mv -v "${XDIR}/${NEWTAR}" .
|
||||||
2
python-OWSLib.rpmlintrc
Normal file
2
python-OWSLib.rpmlintrc
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
# All documentation is in the -doc subpackage.
|
||||||
|
addFilter(r" no-documentation$")
|
||||||
|
|
@ -1,30 +1,79 @@
|
||||||
# Sphinx-generated HTML documentation is not suitable for packaging; see
|
# Sphinx-generated HTML documentation is not suitable for packaging; see
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2006555 for discussion.
|
# https://bugzilla.redhat.com/show_bug.cgi?id=2006555 for discussion.
|
||||||
#
|
#
|
||||||
# We can generate PDF documentation as a substitute.
|
# We can generate PDF documentation as a substitute. However, most of the
|
||||||
%bcond_without doc_pdf
|
# necessary dependencies are not packaged for EPEL8 and probably never will be.
|
||||||
|
%bcond_with doc_pdf
|
||||||
|
|
||||||
|
# Tests require pytest >= 3.8 but EPEL8 has 3.4.2.
|
||||||
|
%bcond_with tests
|
||||||
|
|
||||||
Name: python-OWSLib
|
Name: python-OWSLib
|
||||||
Version: 0.25.0
|
Version: 0.28.1
|
||||||
Release: %autorelease
|
Release: %autorelease
|
||||||
Summary: Client library for OGC web services
|
Summary: OGC Web Service utility library
|
||||||
|
|
||||||
License: BSD
|
License: BSD-3-Clause
|
||||||
URL: https://geopython.github.io/OWSLib
|
URL: https://geopython.github.io/OWSLib
|
||||||
Source0: https://github.com/geopython/OWSLib/archive/%{version}/OWSLib-%{version}.tar.gz
|
# A filtered source archive, obtained by (see Source1):
|
||||||
|
#
|
||||||
|
# ./get_source %%{version}
|
||||||
|
#
|
||||||
|
# is required because tests/resources/ contains XML data files that appear to
|
||||||
|
# have been pulled from various GIS databases, and the license terms for these
|
||||||
|
# files are unclear.
|
||||||
|
#
|
||||||
|
# The unfiltered base source URL would be:
|
||||||
|
#
|
||||||
|
# https://github.com/geopython/OWSLib/archive/%%{version}/OWSLib-%%{version}.tar.gz
|
||||||
|
#
|
||||||
|
# We *could* use the PyPI sdist, which does not contain tests/resources/, but
|
||||||
|
# it also does not contain any tests at all. We can still run some tests
|
||||||
|
# without the XML files, and we would like to do so.
|
||||||
|
Source0: OWSLib-%{version}-filtered.tar.xz
|
||||||
|
Source1: get_source
|
||||||
|
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
|
|
||||||
BuildRequires: python3-devel
|
BuildRequires: python%{python3_pkgversion}-devel
|
||||||
|
|
||||||
|
# requirements.txt:
|
||||||
|
BuildRequires: python%{python3_pkgversion}-dateutil >= 1.5
|
||||||
|
BuildRequires: python%{python3_pkgversion}-pytz
|
||||||
|
BuildRequires: python%{python3_pkgversion}-requests >= 1.0
|
||||||
|
BuildRequires: python%{python3_pkgversion}-pyproj >= 2
|
||||||
|
BuildRequires: python%{python3_pkgversion}-pyyaml
|
||||||
|
BuildRequires: python%{python3_pkgversion}-lxml
|
||||||
|
# python_version < '3.7':
|
||||||
|
BuildRequires: python%{python3_pkgversion}-dataclasses
|
||||||
|
|
||||||
|
# requirements-dev.txt
|
||||||
|
# flake8
|
||||||
|
# pytest-cov
|
||||||
|
# twine
|
||||||
|
# wheel
|
||||||
|
# coverage
|
||||||
|
# coveralls
|
||||||
|
# tox
|
||||||
|
%if %{with tests}
|
||||||
|
BuildRequires: python%{python3_pkgversion}-pytest >= 3.8
|
||||||
|
%endif
|
||||||
|
|
||||||
%if %{with doc_pdf}
|
%if %{with doc_pdf}
|
||||||
BuildRequires: make
|
BuildRequires: make
|
||||||
BuildRequires: python3-sphinx-latex
|
BuildRequires: python%{python3_pkgversion}-sphinx-latex
|
||||||
BuildRequires: latexmk
|
BuildRequires: latexmk
|
||||||
BuildRequires: pandoc
|
BuildRequires: pandoc
|
||||||
|
# requirements-dev.txt
|
||||||
|
BuildRequires: python%{python3_pkgversion}-sphinx
|
||||||
|
BuildRequires: python%{python3_pkgversion}-Pillow
|
||||||
|
BuildRequires: python%{python3_pkgversion}-nbsphinx
|
||||||
|
BuildRequires: python%{python3_pkgversion}-ipykernel
|
||||||
|
BuildRequires: python%{python3_pkgversion}-nbconvert
|
||||||
|
BuildRequires: python%{python3_pkgversion}-pandoc
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%global common_description %{expand: \
|
%global common_description %{expand:
|
||||||
OWSLib is a Python package for client programming with Open Geospatial
|
OWSLib is a Python package for client programming with Open Geospatial
|
||||||
Consortium (OGC) web service (hence OWS) interface standards, and their related
|
Consortium (OGC) web service (hence OWS) interface standards, and their related
|
||||||
content models.
|
content models.
|
||||||
|
|
@ -34,39 +83,33 @@ Full documentation is available at http://geopython.github.io/OWSLib
|
||||||
OWSLib provides a common API for accessing service metadata and wrappers for
|
OWSLib provides a common API for accessing service metadata and wrappers for
|
||||||
numerous OGC Web Service interfaces.}
|
numerous OGC Web Service interfaces.}
|
||||||
|
|
||||||
%description
|
%description %{common_description}
|
||||||
%{common_description}
|
|
||||||
|
|
||||||
|
|
||||||
%package -n python3-OWSLib
|
%package -n python%{python3_pkgversion}-OWSLib
|
||||||
Summary: %{summary}
|
Summary: %{summary}
|
||||||
|
|
||||||
%description -n python3-OWSLib
|
%py_provides python%{python3_pkgversion}-OWSLib
|
||||||
%{common_description}
|
%py_provides python%{python3_pkgversion}-owslib
|
||||||
|
|
||||||
|
%description -n python%{python3_pkgversion}-OWSLib %{common_description}
|
||||||
|
|
||||||
|
|
||||||
%package doc
|
%package doc
|
||||||
Summary: Documentation and examples for OWSLib
|
Summary: Documentation and examples for OWSLib
|
||||||
|
|
||||||
%description doc
|
%description doc %{common_description}
|
||||||
%{summary}.
|
|
||||||
|
This package contains documentation and examples for OWSLib.
|
||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -n OWSLib-%{version}
|
%autosetup -n OWSLib-%{version}
|
||||||
|
|
||||||
|
%if %{with tests}
|
||||||
# Don’t analyze/report test coverage
|
# Don’t analyze/report test coverage
|
||||||
sed -r -i 's/[-]-cov[^[:blank:]]*[[:blank:]][^[[:blank:]]+//g' tox.ini
|
sed -r -i 's/[-]-cov[^[:blank:]]*[[:blank:]][^[[:blank:]]+//g' tox.ini
|
||||||
# Don’t generate linting/coverage dependencies.
|
%endif
|
||||||
#
|
|
||||||
# We don’t have python3dist(pandoc) packaged, and besides, we don’t actually
|
|
||||||
# need python3dist(pandoc)—only the pandoc command-line tool, which we have
|
|
||||||
# manually BR’d.
|
|
||||||
#
|
|
||||||
# Don’t generate twine dependency, which is just for the upstream maintainer
|
|
||||||
# uploading to PyPI.
|
|
||||||
sed -r '/^(flake8|pytest-cov|pandoc|coverage|coveralls|twine)\b/d' \
|
|
||||||
requirements-dev.txt > requirements-dev-filtered.txt
|
|
||||||
|
|
||||||
# We don’t need shebangs in the examples. The pattern of selecting files
|
# We don’t need shebangs in the examples. The pattern of selecting files
|
||||||
# before modifying them with sed keeps us from unnecessarily discarding the
|
# before modifying them with sed keeps us from unnecessarily discarding the
|
||||||
|
|
@ -82,74 +125,142 @@ chmod -v a-x examples/*.py
|
||||||
echo 'nbsphinx_allow_errors = True' >> docs/conf.py
|
echo 'nbsphinx_allow_errors = True' >> docs/conf.py
|
||||||
|
|
||||||
|
|
||||||
%generate_buildrequires
|
|
||||||
%pyproject_buildrequires -r requirements-dev-filtered.txt
|
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%pyproject_wheel
|
%py3_build
|
||||||
|
|
||||||
%if %{with doc_pdf}
|
%if %{with doc_pdf}
|
||||||
PYTHONPATH="${PWD}" %make_build -C docs latex SPHINXOPTS='%{?_smp_mflags}'
|
PYTHONPATH="${PWD}" %make_build -C docs latex \
|
||||||
|
SPHINXOPTS='-j%{?_smp_build_ncpus}'
|
||||||
%make_build -C docs/build/latex/en LATEXMKOPTS='-quiet'
|
%make_build -C docs/build/latex/en LATEXMKOPTS='-quiet'
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|
||||||
%install
|
%install
|
||||||
%pyproject_install
|
%py3_install
|
||||||
%pyproject_save_files owslib
|
|
||||||
|
|
||||||
|
|
||||||
%check
|
%check
|
||||||
|
%if %{with tests}
|
||||||
# Otherwise, pytest finds the package twice in the Python path and complains.
|
# Otherwise, pytest finds the package twice in the Python path and complains.
|
||||||
rm -rf owslib
|
rm -rf owslib
|
||||||
|
|
||||||
# There is a convenient “online” mark for deselecting tests that require
|
# These require test data files from tests/resources/, which we have removed:
|
||||||
# Internet access, but we still have to manually deselect doctests that try to
|
ignore="${ignore-} --ignore-glob=tests/doctests/*.txt"
|
||||||
# make network requests.
|
k="${k-}${k+ and }not test_gm03"
|
||||||
k="${k-}${k+ and }not wms_geoserver_mass_gis.txt"
|
ignore="${ignore-} --ignore=tests/test_iso_parsing.py"
|
||||||
k="${k-}${k+ and }not wfs_MapServerWFSFeature.txt"
|
ignore="${ignore-} --ignore=tests/test_ows_interfaces.py"
|
||||||
k="${k-}${k+ and }not wfs_MapServerWFSCapabilities.txt"
|
ignore="${ignore-} --ignore=tests/test_owscontext_atomxml.py"
|
||||||
k="${k-}${k+ and }not wfs2_storedqueries.txt"
|
k="${k-}${k+ and }not test_decode_single_json"
|
||||||
k="${k-}${k+ and }not wfs1_generic.txt"
|
k="${k-}${k+ and }not test_load_parse"
|
||||||
k="${k-}${k+ and }not wcs_thredds.txt"
|
k="${k-}${k+ and }not test_decode_full_json"
|
||||||
|
k="${k-}${k+ and }not test_load_bulk"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_remote_metadata.py"
|
||||||
|
k="${k-}${k+ and }not TestOffline"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wfs_generic.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wms_datageo_130.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wms_jpl_capabilities.py"
|
||||||
|
k="${k-}${k+ and }not test_wps_getOperationByName"
|
||||||
|
k="${k-}${k+ and }not test_wps_checkStatus"
|
||||||
|
k="${k-}${k+ and }not test_wps_process_representation"
|
||||||
|
k="${k-}${k+ and }not test_wps_process_properties"
|
||||||
|
k="${k-}${k+ and }not test_wps_literal_data_input_parsing_references"
|
||||||
|
k="${k-}${k+ and }not test_wps_response_with_lineage"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wps_describeprocess_bbox.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wps_describeprocess_ceda.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wps_describeprocess_emu_all.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wps_describeprocess_usgs.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wps_execute.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wps_execute_invalid_request.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wps_getcapabilities_52n.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wps_getcapabilities_ceda.py"
|
||||||
|
ignore="${ignore-} --ignore=tests/test_wps_getcapabilities_usgs.py"
|
||||||
|
ignore="${ignore-} --ignore-glob=tests/test_wps_request*.py"
|
||||||
|
ignore="${ignore-} --ignore-glob=tests/test_wps_response*.py"
|
||||||
|
# Not in 0.30.0:
|
||||||
k="${k-}${k+ and }not test_wmts_example_informatievlaanderen"
|
k="${k-}${k+ and }not test_wmts_example_informatievlaanderen"
|
||||||
|
|
||||||
# This is a trivial error where the representation of the expected TypeEror has
|
PYTHONPATH='%{buildroot}%{python3_sitelib}' '%{python3}' -m pytest \
|
||||||
# changed over time:
|
-m 'not online' -k "${k-}" ${ignore-} -v -rs
|
||||||
# Differences (unified diff with -expected +actual):
|
%else
|
||||||
# @@ -1,3 +1,6 @@
|
%{py3_check_import owslib
|
||||||
# Traceback (most recent call last):
|
owslib
|
||||||
# -...
|
owslib.coverage
|
||||||
# -TypeError: get_namespace() ...
|
owslib.coverage.wcs100
|
||||||
# + File "/usr/lib64/python3.10/doctest.py", line 1346, in __run
|
owslib.coverage.wcs110
|
||||||
# + exec(compile(example.source, filename, "single",
|
owslib.coverage.wcs111
|
||||||
# + File "<doctest namespaces.txt[15]>", line 1, in <module>
|
owslib.coverage.wcs200
|
||||||
# + ns.get_namespace()
|
owslib.coverage.wcs201
|
||||||
# +TypeError: Namespaces.get_namespace() missing 1 required positional argument: 'key'
|
owslib.coverage.wcsBase
|
||||||
k="${k-}${k+ and }not namespaces.txt"
|
owslib.coverage.wcsdecoder
|
||||||
|
owslib.crs
|
||||||
# Unknown problem—check if it is fixed in a later version:
|
owslib.csw
|
||||||
k="${k-}${k+ and } not (TestOffline and test_wfs_110_remotemd_parse_all)"
|
owslib.dif
|
||||||
k="${k-}${k+ and } not (TestOffline and test_wfs_110_remotemd_parse_single)"
|
owslib.etree
|
||||||
k="${k-}${k+ and } not (TestOffline and test_wfs_200_remotemd_parse_all)"
|
owslib.feature
|
||||||
k="${k-}${k+ and } not (TestOffline and test_wfs_200_remotemd_parse_single)"
|
owslib.feature.common
|
||||||
k="${k-}${k+ and } not (TestOffline and test_wms_130_remotemd_parse_all)"
|
owslib.feature.postrequest
|
||||||
k="${k-}${k+ and } not (TestOffline and test_wms_130_remotemd_parse_single)"
|
owslib.feature.schema
|
||||||
|
owslib.feature.wfs100
|
||||||
%pytest -m 'not online' -k "${k-}"
|
owslib.feature.wfs110
|
||||||
|
owslib.feature.wfs200
|
||||||
|
owslib.fes
|
||||||
|
owslib.fgdc
|
||||||
|
owslib.gm03
|
||||||
|
owslib.interfaces
|
||||||
|
owslib.iso
|
||||||
|
owslib.iso_che
|
||||||
|
owslib.map
|
||||||
|
owslib.map.common
|
||||||
|
owslib.map.wms111
|
||||||
|
owslib.map.wms130
|
||||||
|
owslib.namespaces
|
||||||
|
owslib.ogcapi
|
||||||
|
owslib.ogcapi.coverages
|
||||||
|
owslib.ogcapi.features
|
||||||
|
owslib.ogcapi.records
|
||||||
|
owslib.ows
|
||||||
|
owslib.owscontext
|
||||||
|
owslib.owscontext.atom
|
||||||
|
owslib.owscontext.common
|
||||||
|
owslib.owscontext.core
|
||||||
|
owslib.owscontext.geojson
|
||||||
|
owslib.sos
|
||||||
|
owslib.swe
|
||||||
|
owslib.swe.common
|
||||||
|
owslib.swe.observation
|
||||||
|
owslib.swe.observation.om
|
||||||
|
owslib.swe.observation.sos100
|
||||||
|
owslib.swe.observation.sos200
|
||||||
|
owslib.swe.observation.waterml2
|
||||||
|
owslib.swe.sensor
|
||||||
|
owslib.swe.sensor.sml
|
||||||
|
owslib.tms
|
||||||
|
owslib.util
|
||||||
|
owslib.waterml
|
||||||
|
owslib.waterml.wml
|
||||||
|
owslib.waterml.wml10
|
||||||
|
owslib.waterml.wml11
|
||||||
|
owslib.wcs
|
||||||
|
owslib.wfs
|
||||||
|
owslib.wmc
|
||||||
|
owslib.wms
|
||||||
|
owslib.wmts
|
||||||
|
owslib.wps}
|
||||||
|
%endif
|
||||||
|
|
||||||
|
|
||||||
%files -n python3-OWSLib -f %{pyproject_files}
|
%files -n python%{python3_pkgversion}-OWSLib
|
||||||
# pyproject_files handles LICENSE; verify with “rpm -qL -p …”
|
%license LICENSE
|
||||||
|
|
||||||
%doc AUTHORS.rst
|
%{python3_sitelib}/owslib
|
||||||
%doc CHANGES.rst
|
%{python3_sitelib}/OWSLib-%{version}-py%{python3_version}.egg-info
|
||||||
%doc README.rst
|
|
||||||
|
|
||||||
|
|
||||||
%files doc
|
%files doc
|
||||||
%license LICENSE
|
%license LICENSE
|
||||||
|
%doc AUTHORS.rst
|
||||||
|
%doc CHANGES.rst
|
||||||
|
%doc README.rst
|
||||||
%doc examples
|
%doc examples
|
||||||
%if %{with doc_pdf}
|
%if %{with doc_pdf}
|
||||||
%doc docs/build/latex/en/OWSLib.pdf
|
%doc docs/build/latex/en/OWSLib.pdf
|
||||||
|
|
|
||||||
2
sources
2
sources
|
|
@ -1 +1 @@
|
||||||
SHA512 (OWSLib-0.25.0.tar.gz) = 058108cf77197ce24793608869d56bf0467230f5f231ac9ba48445f2e02d07ea1e26be03ad6967504a1e625008ae2768ed2a663f3b7a49dcea410ee4a8b40cec
|
SHA512 (OWSLib-0.28.1-filtered.tar.xz) = cc83e5973adb6d6bd5aa624017a6f7927957979f69a3dbdda1645c2ecb8b9b84bbb03b794440c7d66062d365400502a6176514f0fb8d51b8f06b1aea32c0284d
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue