surplus v2.2.0 (#38)
* build(deps-dev): bump black from 23.7.0 to 23.9.1 (#33) Bumps [black](https://github.com/psf/black) from 23.7.0 to 23.9.1. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.7.0...23.9.1) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * meta: update devbox files * ctt: type analyse * ci: update devbox-install-action (#35) * import protocol from typing straight (#36) * ctt: update uq and np tests * s+,docs: add termux-location json support (#37) docs: update api accordingly * meta: bump ver * s+,ctt: fix italian addressing + add test (#34) * st: fix regression in last commit + add per-line settings dict * ctt: update modena test * docs: update api docs for the new st constants * ci,devbox: fix for ci * ctt: update modena test --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
533cdb2ce4
commit
fdf3a86d84
8
.github/workflows/checks.yml
vendored
8
.github/workflows/checks.yml
vendored
|
@ -15,7 +15,7 @@ jobs:
|
|||
uses: actions/checkout@v3
|
||||
|
||||
- name: install devbox
|
||||
uses: jetpack-io/devbox-install-action@v0.3.0
|
||||
uses: jetpack-io/devbox-install-action@v0.7.0
|
||||
|
||||
- name: install dependencies
|
||||
run: devbox run poetry install
|
||||
|
@ -28,10 +28,10 @@ jobs:
|
|||
run: devbox run poetry run mypy .
|
||||
|
||||
- name: check for black formatting compliance
|
||||
run: devbox run poetry run "black --check ."
|
||||
run: devbox run poetry run black --check .
|
||||
|
||||
- name: analyse isort compliance
|
||||
run: devbox run poetry run "isort --check *.py **/*.py"
|
||||
run: devbox run poetry run isort --check *.py **/*.py
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -40,7 +40,7 @@ jobs:
|
|||
uses: actions/checkout@v3
|
||||
|
||||
- name: install devbox
|
||||
uses: jetpack-io/devbox-install-action@v0.3.0
|
||||
uses: jetpack-io/devbox-install-action@v0.7.0
|
||||
|
||||
- name: install dependencies
|
||||
run: devbox run poetry install
|
||||
|
|
2
.github/workflows/publish-slsa3-auto.yml
vendored
2
.github/workflows/publish-slsa3-auto.yml
vendored
|
@ -24,7 +24,7 @@ jobs:
|
|||
uses: tj-actions/branch-names@v7
|
||||
|
||||
- name: install devbox
|
||||
uses: jetpack-io/devbox-install-action@v0.6.1
|
||||
uses: jetpack-io/devbox-install-action@v0.7.0
|
||||
|
||||
- name: install dependencies
|
||||
run: devbox run poetry install
|
||||
|
|
2
.github/workflows/publish-slsa3-manual.yml
vendored
2
.github/workflows/publish-slsa3-manual.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
|||
uses: tj-actions/branch-names@v7
|
||||
|
||||
- name: install devbox
|
||||
uses: jetpack-io/devbox-install-action@v0.6.1
|
||||
uses: jetpack-io/devbox-install-action@v0.7.0
|
||||
|
||||
- name: install dependencies
|
||||
run: devbox run poetry install
|
||||
|
|
77
README.md
77
README.md
|
@ -20,7 +20,7 @@ to iOS Shortcuts-like shareable text.
|
|||
|
||||
```text
|
||||
$ surplus 9R3J+R9 Singapore
|
||||
surplus version 2.1.1
|
||||
surplus version 2.2.0
|
||||
Thomson Plaza
|
||||
301 Upper Thomson Road
|
||||
Sin Ming, Bishan
|
||||
|
@ -57,7 +57,7 @@ see [licence](#licence) for licensing information.
|
|||
|
||||
```text
|
||||
usage: surplus [-h] [-d] [-v] [-c {pluscode,localcode,latlong,sharetext}]
|
||||
[-u USER_AGENT]
|
||||
[-u USER_AGENT] [-t]
|
||||
[query ...]
|
||||
|
||||
Google Maps Plus Code to iOS Shortcuts-like shareable text
|
||||
|
@ -79,6 +79,9 @@ options:
|
|||
-u USER_AGENT, --user-agent USER_AGENT
|
||||
user agent string to use for geocoding service,
|
||||
defaults to fingerprinted user agent string
|
||||
-t, --using-termux-location
|
||||
treats input as a termux-location output json
|
||||
string, and parses it accordingly
|
||||
```
|
||||
|
||||
### example api usage
|
||||
|
@ -260,7 +263,7 @@ of incorrect outputs.
|
|||
|
||||
```text
|
||||
$ s+ --debug 8QJF+RP Singapore
|
||||
surplus version 2.1.1, debug mode (latest@future, Tue 05 Sep 2023 23:38:59 +0800)
|
||||
surplus version 2.2.0, debug mode (latest@future, Tue 05 Sep 2023 23:38:59 +0800)
|
||||
debug: parse_query: behaviour.query=['8QJF+RP', 'Singapore']
|
||||
debug: _match_plus_code: portion_plus_code='8QJF+RP', portion_locality='Singapore'
|
||||
debug: cli: query=Result(value=LocalCodeQuery(code='8QJF+RP', locality='Singapore'), error=None)
|
||||
|
@ -602,24 +605,62 @@ line breakdown of shareable text output, accompanied by their Nominatim keys:
|
|||
> this constant only affects the default surplus Nominatim geocoding functions. custom
|
||||
> functions do not read from this, unless deliberately programmed to do so
|
||||
|
||||
- `SHAREABLE_TEXT_LINE_0_KEYS: typing.Final[tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_1_KEYS: typing.Final[tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_2_KEYS: typing.Final[tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_3_KEYS: typing.Final[tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_4_KEYS: typing.Final[tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_5_KEYS: typing.Final[tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_6_KEYS: typing.Final[tuple[str, ...]]`
|
||||
- `SHAREABLE_TEXT_LINE_0_KEYS: dict[str, tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_1_KEYS: dict[str, tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_2_KEYS: dict[str, tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_3_KEYS: dict[str, tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_4_KEYS: dict[str, tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_5_KEYS: dict[str, tuple[str, ...]]`
|
||||
`SHAREABLE_TEXT_LINE_6_KEYS: dict[str, tuple[str, ...]]`
|
||||
|
||||
a tuple of strings containing Nominatim keys used in shareable text line 0-6
|
||||
a dictionary of iso3166-2 country-portion string keys with a tuple of Nominatim keys
|
||||
used in shareable text line 0-6 as their values
|
||||
|
||||
- `SHAREABLE_TEXT_NAMES: typing.Final[tuple[str, ...]]`
|
||||
```python
|
||||
{
|
||||
"default": (...),
|
||||
"SG": (...,),
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
- `SHAREABLE_TEXT_LINE_SETTINGS: dict[str, dict[int, tuple[str, bool]]]`
|
||||
|
||||
a dictionary of iso3166-2 country-portion string keys with a dictionary as their values
|
||||
|
||||
the dictionary values are dictionaries with integers as keys, and a tuple of two strings
|
||||
|
||||
the first string is the separator string to use, and the second string is a boolean flag
|
||||
that if `True` will check the line for seen names
|
||||
|
||||
```python
|
||||
{
|
||||
"default": {
|
||||
0: (", ", False),
|
||||
...
|
||||
6: (", ", False),
|
||||
},
|
||||
"IT": {
|
||||
0: (", ", False),
|
||||
...
|
||||
6: (", ", False),
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
- `SHAREABLE_TEXT_NAMES: dict[str, tuple[str, ...]]`
|
||||
|
||||
a dictionary of iso3166-2 country-portion string keys with a tuple of strings as their
|
||||
values
|
||||
a tuple of strings containing Nominatim keys used in shareable text line 0-2 and
|
||||
special keys in line 3
|
||||
|
||||
used for seen name checks
|
||||
|
||||
- `SHAREABLE_TEXT_LOCALITY: dict[str, tuple[str, ...]]`
|
||||
|
||||
a dictionary of iso3166-2 country-portion strings with a tuples of strings as their
|
||||
a dictionary of iso3166-2 country-portion string keys with a tuple of strings as their
|
||||
values
|
||||
|
||||
used when generating the locality portions of shortened Plus Codes/local codes
|
||||
|
@ -632,6 +673,9 @@ line breakdown of shareable text output, accompanied by their Nominatim keys:
|
|||
}
|
||||
```
|
||||
|
||||
- `SHAREABLE_TEXT_DEFAULT: typing.Final[str]`
|
||||
constant for what is the "default" key in the `SHAREABLE*` constants
|
||||
|
||||
- `EMPTY_LATLONG: typing.Final[Latlong]`
|
||||
a constant for an empty latlong coordinate, with latitude and longitude set to 0.0
|
||||
|
||||
|
@ -793,6 +837,9 @@ attributes
|
|||
- `convert_to_type: ConversionResultTypeEnum = ConversionResultTypeEnum.SHAREABLE_TEXT`
|
||||
what type to convert the query to
|
||||
|
||||
- `using_termux_location: bool = False`
|
||||
treats query as a termux-location output json string, and parses it accordingly
|
||||
|
||||
### `class SurplusDefaultGeocoding`
|
||||
|
||||
> [!IMPORTANT]
|
||||
|
@ -1288,7 +1335,7 @@ it contains the following, in order, alongside an example:
|
|||
1. `version` - the surplus version alongside a suffix, if any
|
||||
|
||||
```text
|
||||
2.1.1-local
|
||||
2.2.0-local
|
||||
```
|
||||
|
||||
2. `system_info` - generic machine and operating system information
|
||||
|
@ -1312,7 +1359,7 @@ it contains the following, in order, alongside an example:
|
|||
after hashing, this string becomes a 12 character hexadecimal string, as shown below:
|
||||
|
||||
```text
|
||||
surplus/2.1.1-local (1fdbfa0b0cfb)
|
||||
surplus/2.2.0-local (1fdbfa0b0cfb)
|
||||
^^^^^^^^^^^^
|
||||
this is the hashed result of unique_info
|
||||
```
|
||||
|
|
11
devbox.json
11
devbox.json
|
@ -1,14 +1,11 @@
|
|||
{
|
||||
"packages": [
|
||||
"python311",
|
||||
"python311Packages.ipykernel",
|
||||
"poetry"
|
||||
"python311@latest",
|
||||
"python311Packages.ipykernel@latest",
|
||||
"poetry@latest"
|
||||
],
|
||||
"shell": {
|
||||
"init_hook": [
|
||||
"poetry env use $(which python)",
|
||||
"poetry shell"
|
||||
]
|
||||
"init_hook": ["poetry install"]
|
||||
},
|
||||
"nixpkgs": {
|
||||
"commit": "f80ac848e3d6f0c12c52758c0f25c10c97ca3b62"
|
||||
|
|
64
devbox.lock
64
devbox.lock
|
@ -1,15 +1,67 @@
|
|||
{
|
||||
"lockfile_version": "1",
|
||||
"packages": {
|
||||
"poetry": {
|
||||
"resolved": "github:NixOS/nixpkgs/f80ac848e3d6f0c12c52758c0f25c10c97ca3b62#poetry"
|
||||
"poetry@latest": {
|
||||
"last_modified": "2023-10-04T02:19:08Z",
|
||||
"plugin_version": "0.0.3",
|
||||
"resolved": "github:NixOS/nixpkgs/d1c9180c6d1f8fce9469436f48c1cb8180d7087d#poetry",
|
||||
"source": "devbox-search",
|
||||
"version": "1.6.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"store_path": "/nix/store/i7q6kxa3ac7c57zalr4vwa04c1bll3xd-python3.10-poetry-1.6.1"
|
||||
},
|
||||
"python311": {
|
||||
"aarch64-linux": {
|
||||
"store_path": "/nix/store/b0gmqd0y5pich25mk5p649g1bbbyxp0v-python3.10-poetry-1.6.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"store_path": "/nix/store/q5zqqp3k58z46q4imgmj5pxbinmzjyqf-python3.10-poetry-1.6.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"store_path": "/nix/store/6v2zvmag2il359sbd8j1q7b3c20gs6yd-python3.10-poetry-1.6.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"python311@latest": {
|
||||
"last_modified": "2023-09-27T18:02:17Z",
|
||||
"plugin_version": "0.0.1",
|
||||
"resolved": "github:NixOS/nixpkgs/f80ac848e3d6f0c12c52758c0f25c10c97ca3b62#python311"
|
||||
"resolved": "github:NixOS/nixpkgs/517501bcf14ae6ec47efd6a17dda0ca8e6d866f9#python311",
|
||||
"source": "devbox-search",
|
||||
"version": "3.11.4",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"store_path": "/nix/store/rycxjkclx801wrhwrgllak0302xzjdvx-python3-3.11.4"
|
||||
},
|
||||
"python311Packages.ipykernel": {
|
||||
"resolved": "github:NixOS/nixpkgs/f80ac848e3d6f0c12c52758c0f25c10c97ca3b62#python311Packages.ipykernel"
|
||||
"aarch64-linux": {
|
||||
"store_path": "/nix/store/h4xi1djsmhk7bjdipz58xkfnf8lc9mpm-python3-3.11.4"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"store_path": "/nix/store/yqs2zxkxn61xzimdaz1pbgawk2lnm0d8-python3-3.11.4"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"store_path": "/nix/store/3k7is7nc2xbav8a48vx7arad522d8czx-python3-3.11.4"
|
||||
}
|
||||
}
|
||||
},
|
||||
"python311Packages.ipykernel@latest": {
|
||||
"last_modified": "2023-09-29T09:08:59Z",
|
||||
"resolved": "github:NixOS/nixpkgs/bd9b686c0168041aea600222be0805a0de6e6ab8#python311Packages.ipykernel",
|
||||
"source": "devbox-search",
|
||||
"version": "6.21.2",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"store_path": "/nix/store/78gi0qk9lmrb4rk5ignww29p5j0l79gs-python3.11-ipykernel-6.21.2"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"store_path": "/nix/store/74m55prblwmsyx1ylv135iqw2wqj4c6a-python3.11-ipykernel-6.21.2"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"store_path": "/nix/store/j0wpnwkdcqfp2bmp2b9pgzdngnmxzjj9-python3.11-ipykernel-6.21.2"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"store_path": "/nix/store/3kqcf56q2q46hj0g5n4rxzzy1c9vdiqa-python3.11-ipykernel-6.21.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
83
poetry.lock
generated
83
poetry.lock
generated
|
@ -1,10 +1,9 @@
|
|||
# This file is automatically @generated by Poetry and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "appnope"
|
||||
version = "0.1.3"
|
||||
description = "Disable App Nap on macOS >= 10.9"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -16,7 +15,6 @@ files = [
|
|||
name = "asttokens"
|
||||
version = "2.4.0"
|
||||
description = "Annotate AST trees with source code positions"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -34,7 +32,6 @@ test = ["astroid", "pytest"]
|
|||
name = "backcall"
|
||||
version = "0.2.0"
|
||||
description = "Specifications for callback functions passed in to an API"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -44,34 +41,33 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "23.7.0"
|
||||
version = "23.9.1"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"},
|
||||
{file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"},
|
||||
{file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"},
|
||||
{file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"},
|
||||
{file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"},
|
||||
{file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"},
|
||||
{file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"},
|
||||
{file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"},
|
||||
{file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"},
|
||||
{file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"},
|
||||
{file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"},
|
||||
{file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"},
|
||||
{file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"},
|
||||
{file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"},
|
||||
{file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"},
|
||||
{file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"},
|
||||
{file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"},
|
||||
{file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"},
|
||||
{file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"},
|
||||
{file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"},
|
||||
{file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"},
|
||||
{file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"},
|
||||
{file = "black-23.9.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:d6bc09188020c9ac2555a498949401ab35bb6bf76d4e0f8ee251694664df6301"},
|
||||
{file = "black-23.9.1-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:13ef033794029b85dfea8032c9d3b92b42b526f1ff4bf13b2182ce4e917f5100"},
|
||||
{file = "black-23.9.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:75a2dc41b183d4872d3a500d2b9c9016e67ed95738a3624f4751a0cb4818fe71"},
|
||||
{file = "black-23.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a2e4a93bb8ca74a749b6974925c27219bb3df4d42fc45e948a5d9feb5122b7"},
|
||||
{file = "black-23.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:adc3e4442eef57f99b5590b245a328aad19c99552e0bdc7f0b04db6656debd80"},
|
||||
{file = "black-23.9.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:8431445bf62d2a914b541da7ab3e2b4f3bc052d2ccbf157ebad18ea126efb91f"},
|
||||
{file = "black-23.9.1-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:8fc1ddcf83f996247505db6b715294eba56ea9372e107fd54963c7553f2b6dfe"},
|
||||
{file = "black-23.9.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:7d30ec46de88091e4316b17ae58bbbfc12b2de05e069030f6b747dfc649ad186"},
|
||||
{file = "black-23.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031e8c69f3d3b09e1aa471a926a1eeb0b9071f80b17689a655f7885ac9325a6f"},
|
||||
{file = "black-23.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:538efb451cd50f43aba394e9ec7ad55a37598faae3348d723b59ea8e91616300"},
|
||||
{file = "black-23.9.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:638619a559280de0c2aa4d76f504891c9860bb8fa214267358f0a20f27c12948"},
|
||||
{file = "black-23.9.1-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:a732b82747235e0542c03bf352c126052c0fbc458d8a239a94701175b17d4855"},
|
||||
{file = "black-23.9.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:cf3a4d00e4cdb6734b64bf23cd4341421e8953615cba6b3670453737a72ec204"},
|
||||
{file = "black-23.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf99f3de8b3273a8317681d8194ea222f10e0133a24a7548c73ce44ea1679377"},
|
||||
{file = "black-23.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:14f04c990259576acd093871e7e9b14918eb28f1866f91968ff5524293f9c573"},
|
||||
{file = "black-23.9.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:c619f063c2d68f19b2d7270f4cf3192cb81c9ec5bc5ba02df91471d0b88c4c5c"},
|
||||
{file = "black-23.9.1-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:6a3b50e4b93f43b34a9d3ef00d9b6728b4a722c997c99ab09102fd5efdb88325"},
|
||||
{file = "black-23.9.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c46767e8df1b7beefb0899c4a95fb43058fa8500b6db144f4ff3ca38eb2f6393"},
|
||||
{file = "black-23.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50254ebfa56aa46a9fdd5d651f9637485068a1adf42270148cd101cdf56e0ad9"},
|
||||
{file = "black-23.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:403397c033adbc45c2bd41747da1f7fc7eaa44efbee256b53842470d4ac5a70f"},
|
||||
{file = "black-23.9.1-py3-none-any.whl", hash = "sha256:6ccd59584cc834b6d127628713e4b6b968e5f79572da66284532525a042549f9"},
|
||||
{file = "black-23.9.1.tar.gz", hash = "sha256:24b6b3ff5c6d9ea08a8888f6977eae858e1f340d7260cf56d70a49823236b62d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -93,7 +89,6 @@ uvloop = ["uvloop (>=0.15.2)"]
|
|||
name = "click"
|
||||
version = "8.1.7"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -108,7 +103,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
|||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
|
@ -120,7 +114,6 @@ files = [
|
|||
name = "decorator"
|
||||
version = "5.1.1"
|
||||
description = "Decorators for Humans"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -132,7 +125,6 @@ files = [
|
|||
name = "executing"
|
||||
version = "1.2.0"
|
||||
description = "Get the currently executing AST node of a frame, and other information"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -147,7 +139,6 @@ tests = ["asttokens", "littleutils", "pytest", "rich"]
|
|||
name = "geographiclib"
|
||||
version = "2.0"
|
||||
description = "The geodesic routines from GeographicLib"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -159,7 +150,6 @@ files = [
|
|||
name = "geopy"
|
||||
version = "2.4.0"
|
||||
description = "Python Geocoding Toolbox"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -183,7 +173,6 @@ timezone = ["pytz"]
|
|||
name = "ipython"
|
||||
version = "8.15.0"
|
||||
description = "IPython: Productive Interactive Computing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
|
@ -222,7 +211,6 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa
|
|||
name = "isort"
|
||||
version = "5.12.0"
|
||||
description = "A Python utility / library to sort Python imports."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
|
@ -240,7 +228,6 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"]
|
|||
name = "jedi"
|
||||
version = "0.19.0"
|
||||
description = "An autocompletion tool for Python that can be used for text editors."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -260,7 +247,6 @@ testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"]
|
|||
name = "matplotlib-inline"
|
||||
version = "0.1.6"
|
||||
description = "Inline Matplotlib backend for Jupyter"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -275,7 +261,6 @@ traitlets = "*"
|
|||
name = "mypy"
|
||||
version = "1.5.1"
|
||||
description = "Optional static typing for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -321,7 +306,6 @@ reports = ["lxml"]
|
|||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -333,7 +317,6 @@ files = [
|
|||
name = "packaging"
|
||||
version = "23.1"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -345,7 +328,6 @@ files = [
|
|||
name = "parso"
|
||||
version = "0.8.3"
|
||||
description = "A Python Parser"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -361,7 +343,6 @@ testing = ["docopt", "pytest (<6.0.0)"]
|
|||
name = "pathspec"
|
||||
version = "0.11.2"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -373,7 +354,6 @@ files = [
|
|||
name = "pexpect"
|
||||
version = "4.8.0"
|
||||
description = "Pexpect allows easy control of interactive console applications."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -388,7 +368,6 @@ ptyprocess = ">=0.5"
|
|||
name = "pickleshare"
|
||||
version = "0.7.5"
|
||||
description = "Tiny 'shelve'-like database with concurrency support"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -400,7 +379,6 @@ files = [
|
|||
name = "platformdirs"
|
||||
version = "3.10.0"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -416,7 +394,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co
|
|||
name = "pluscodes"
|
||||
version = "2022.1.3"
|
||||
description = "Compute Plus Codes (Open Location Codes)."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
files = [
|
||||
|
@ -430,7 +407,6 @@ dev = ["black (==22.3.0)", "build (==0.8.0)", "coverage (==6.4)", "isort (==5.8.
|
|||
name = "prompt-toolkit"
|
||||
version = "3.0.39"
|
||||
description = "Library for building powerful interactive command lines in Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
|
@ -445,7 +421,6 @@ wcwidth = "*"
|
|||
name = "ptyprocess"
|
||||
version = "0.7.0"
|
||||
description = "Run a subprocess in a pseudo terminal"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -457,7 +432,6 @@ files = [
|
|||
name = "pure-eval"
|
||||
version = "0.2.2"
|
||||
description = "Safely evaluate AST nodes without side effects"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -472,7 +446,6 @@ tests = ["pytest"]
|
|||
name = "pygments"
|
||||
version = "2.16.1"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -487,7 +460,6 @@ plugins = ["importlib-metadata"]
|
|||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
files = [
|
||||
|
@ -499,7 +471,6 @@ files = [
|
|||
name = "stack-data"
|
||||
version = "0.6.2"
|
||||
description = "Extract data from python stack frames and tracebacks for informative displays"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -519,7 +490,6 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
|
|||
name = "tokenize-rt"
|
||||
version = "5.2.0"
|
||||
description = "A wrapper around the stdlib `tokenize` which roundtrips."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -531,7 +501,6 @@ files = [
|
|||
name = "traitlets"
|
||||
version = "5.9.0"
|
||||
description = "Traitlets Python configuration system"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -547,7 +516,6 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"]
|
|||
name = "typing-extensions"
|
||||
version = "4.7.1"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -559,7 +527,6 @@ files = [
|
|||
name = "wcwidth"
|
||||
version = "0.2.6"
|
||||
description = "Measures the displayed width of unicode strings in a terminal"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -570,4 +537,4 @@ files = [
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "f9270d7fb45c708e923f4afe041b26f77becb8e4adfcd517742e67f6b8f9d6b9"
|
||||
content-hash = "3f2847d76a104121389f12d4f82841153b114d479c8ddba0c5a78994b544d0d6"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "surplus"
|
||||
version = "2.1.1"
|
||||
version = "2.2.0"
|
||||
description = "Python script to convert Google Maps Plus Codes to iOS Shortcuts-like shareable text."
|
||||
authors = ["Mark Joshwel <mark@joshwel.co>"]
|
||||
license = "Unlicense"
|
||||
|
@ -17,7 +17,7 @@ pluscodes = "^2022.1.3"
|
|||
geopy = "^2.3.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
black = {extras = ["jupyter"], version = "^23.7.0"}
|
||||
black = {extras = ["jupyter"], version = "^23.9.1"}
|
||||
mypy = "^1.5.1"
|
||||
isort = "^5.12.0"
|
||||
|
||||
|
|
|
@ -31,11 +31,14 @@ For more information, please refer to <http://unlicense.org/>
|
|||
|
||||
from argparse import ArgumentParser
|
||||
from collections import OrderedDict
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from enum import Enum
|
||||
from functools import lru_cache
|
||||
from hashlib import shake_256
|
||||
from json import loads as json_loads
|
||||
from json.decoder import JSONDecodeError
|
||||
from platform import platform
|
||||
from socket import gethostname
|
||||
from sys import stderr, stdin, stdout
|
||||
|
@ -45,6 +48,7 @@ from typing import (
|
|||
Final,
|
||||
Generic,
|
||||
NamedTuple,
|
||||
Protocol,
|
||||
Sequence,
|
||||
TextIO,
|
||||
TypeAlias,
|
||||
|
@ -55,12 +59,9 @@ from uuid import getnode
|
|||
from geopy import Location as _geopy_Location # type: ignore
|
||||
from geopy.extra.rate_limiter import RateLimiter as _geopy_RateLimiter # type: ignore
|
||||
from geopy.geocoders import Nominatim as _geopy_Nominatim # type: ignore
|
||||
from pluscodes import Area as _PlusCode_Area # type: ignore
|
||||
from pluscodes import PlusCode as _PlusCode # type: ignore
|
||||
from pluscodes import decode as _PlusCode_decode # type: ignore
|
||||
from pluscodes import encode as _PlusCode_encode # type: ignore
|
||||
from pluscodes.validator import Validator as _PlusCode_Validator # type: ignore
|
||||
from typing_extensions import Protocol
|
||||
|
||||
from pluscodes.openlocationcode import ( # type: ignore # isort: skip
|
||||
recoverNearest as _PlusCode_recoverNearest,
|
||||
|
@ -68,14 +69,19 @@ from pluscodes.openlocationcode import ( # type: ignore # isort: skip
|
|||
|
||||
# constants
|
||||
|
||||
VERSION: Final[tuple[int, int, int]] = (2, 1, 1)
|
||||
VERSION: Final[tuple[int, int, int]] = (2, 2, 0)
|
||||
VERSION_SUFFIX: Final[str] = "-local"
|
||||
BUILD_BRANCH: Final[str] = "future"
|
||||
BUILD_COMMIT: Final[str] = "latest"
|
||||
BUILD_DATETIME: Final[datetime] = datetime.now(timezone(timedelta(hours=8))) # using SGT
|
||||
CONNECTION_MAX_RETRIES: int = 9
|
||||
CONNECTION_WAIT_SECONDS: int = 10
|
||||
SHAREABLE_TEXT_LINE_0_KEYS: Final[tuple[str, ...]] = (
|
||||
LOCALITY_GEOCODER_LEVEL: int = 13 # adjusts geocoder zoom level when
|
||||
# geocoding latlong into an address
|
||||
|
||||
# default shareable text line keys
|
||||
SHAREABLE_TEXT_LINE_0_KEYS: dict[str, tuple[str, ...]] = {
|
||||
"default": (
|
||||
"emergency",
|
||||
"historic",
|
||||
"military",
|
||||
|
@ -98,23 +104,23 @@ SHAREABLE_TEXT_LINE_0_KEYS: Final[tuple[str, ...]] = (
|
|||
"bridge",
|
||||
"tunnel",
|
||||
"waterway",
|
||||
)
|
||||
SHAREABLE_TEXT_LINE_1_KEYS: Final[tuple[str, ...]] = ("building",)
|
||||
SHAREABLE_TEXT_LINE_2_KEYS: Final[tuple[str, ...]] = ("highway",)
|
||||
|
||||
SHAREABLE_TEXT_LINE_3_KEYS: Final[tuple[str, ...]] = (
|
||||
),
|
||||
}
|
||||
SHAREABLE_TEXT_LINE_1_KEYS: dict[str, tuple[str, ...]] = {
|
||||
"default": ("building",),
|
||||
}
|
||||
SHAREABLE_TEXT_LINE_2_KEYS: dict[str, tuple[str, ...]] = {
|
||||
"default": ("highway",),
|
||||
}
|
||||
SHAREABLE_TEXT_LINE_3_KEYS: dict[str, tuple[str, ...]] = {
|
||||
"default": (
|
||||
"house_number",
|
||||
"house_name",
|
||||
"road",
|
||||
)
|
||||
# special line 3 keys for Italian addresses (IT)
|
||||
SHAREABLE_TEXT_LINE_3_KEYS_IT: Final[tuple[str, ...]] = (
|
||||
"road",
|
||||
"house_number",
|
||||
"house_name",
|
||||
)
|
||||
|
||||
SHAREABLE_TEXT_LINE_4_KEYS: Final[tuple[str, ...]] = (
|
||||
),
|
||||
}
|
||||
SHAREABLE_TEXT_LINE_4_KEYS: dict[str, tuple[str, ...]] = {
|
||||
"default": (
|
||||
"residential",
|
||||
"neighbourhood",
|
||||
"allotments",
|
||||
|
@ -128,29 +134,112 @@ SHAREABLE_TEXT_LINE_4_KEYS: Final[tuple[str, ...]] = (
|
|||
"city",
|
||||
"town",
|
||||
"village",
|
||||
)
|
||||
SHAREABLE_TEXT_LINE_5_KEYS: Final[tuple[str, ...]] = ("postcode",)
|
||||
SHAREABLE_TEXT_LINE_6_KEYS: Final[tuple[str, ...]] = (
|
||||
),
|
||||
}
|
||||
SHAREABLE_TEXT_LINE_5_KEYS: dict[str, tuple[str, ...]] = {
|
||||
"default": ("postcode",),
|
||||
}
|
||||
SHAREABLE_TEXT_LINE_6_KEYS: dict[str, tuple[str, ...]] = {
|
||||
"default": (
|
||||
"region",
|
||||
"county",
|
||||
"state",
|
||||
"state_district",
|
||||
"country",
|
||||
"continent",
|
||||
)
|
||||
SHAREABLE_TEXT_NAMES: Final[tuple[str, ...]] = (
|
||||
SHAREABLE_TEXT_LINE_0_KEYS
|
||||
+ SHAREABLE_TEXT_LINE_1_KEYS
|
||||
+ SHAREABLE_TEXT_LINE_2_KEYS
|
||||
),
|
||||
}
|
||||
SHAREABLE_TEXT_LINE_SETTINGS: dict[str, dict[int, tuple[str, bool]]] = {
|
||||
# line number: (string separator to use, whether to check for seen names)
|
||||
"default": {
|
||||
0: (", ", False),
|
||||
1: (", ", False),
|
||||
2: (", ", False),
|
||||
3: (" ", False),
|
||||
4: (", ", True),
|
||||
5: (", ", False),
|
||||
6: (", ", False),
|
||||
},
|
||||
}
|
||||
SHAREABLE_TEXT_NAMES: dict[str, tuple[str, ...]] = {
|
||||
"default": (
|
||||
SHAREABLE_TEXT_LINE_0_KEYS["default"]
|
||||
+ SHAREABLE_TEXT_LINE_1_KEYS["default"]
|
||||
+ SHAREABLE_TEXT_LINE_2_KEYS["default"]
|
||||
+ ("house_name", "road")
|
||||
)
|
||||
),
|
||||
}
|
||||
SHAREABLE_TEXT_LOCALITY: dict[str, tuple[str, ...]] = {
|
||||
"default": ("city_district", "district", "city", *SHAREABLE_TEXT_LINE_6_KEYS),
|
||||
"default": (
|
||||
"city_district",
|
||||
"district",
|
||||
"city",
|
||||
*SHAREABLE_TEXT_LINE_6_KEYS["default"],
|
||||
),
|
||||
}
|
||||
SHAREABLE_TEXT_DEFAULT: Final[str] = "default"
|
||||
|
||||
# special per-country key arrangements for SG/Singapore
|
||||
SHAREABLE_TEXT_LOCALITY.update(
|
||||
{
|
||||
"SG": ("country",),
|
||||
}
|
||||
)
|
||||
|
||||
# special per-country key arrangements for IT/Italy
|
||||
SHAREABLE_TEXT_LINE_3_KEYS.update(
|
||||
{
|
||||
"IT": (
|
||||
"road",
|
||||
"house_number",
|
||||
"house_name",
|
||||
),
|
||||
}
|
||||
)
|
||||
SHAREABLE_TEXT_LINE_5_KEYS.update(
|
||||
{
|
||||
"IT": (
|
||||
"postcode",
|
||||
"region",
|
||||
"county",
|
||||
"state",
|
||||
"state_district",
|
||||
),
|
||||
},
|
||||
)
|
||||
SHAREABLE_TEXT_LINE_6_KEYS.update(
|
||||
{
|
||||
"IT": (
|
||||
"country",
|
||||
"continent",
|
||||
),
|
||||
}
|
||||
)
|
||||
SHAREABLE_TEXT_LINE_SETTINGS.update(
|
||||
{"IT": deepcopy(SHAREABLE_TEXT_LINE_SETTINGS)["default"]}
|
||||
)
|
||||
SHAREABLE_TEXT_LINE_SETTINGS["IT"][5] = (" ", False)
|
||||
|
||||
# special per-country key arrangements for MY/Malaysia
|
||||
SHAREABLE_TEXT_LINE_4_KEYS.update(
|
||||
{
|
||||
"MY": tuple(),
|
||||
},
|
||||
)
|
||||
SHAREABLE_TEXT_LINE_5_KEYS.update(
|
||||
{
|
||||
"MY": (
|
||||
"postcode",
|
||||
*SHAREABLE_TEXT_LINE_4_KEYS["default"],
|
||||
),
|
||||
},
|
||||
)
|
||||
SHAREABLE_TEXT_LINE_SETTINGS.update(
|
||||
{"MY": deepcopy(SHAREABLE_TEXT_LINE_SETTINGS)["default"]}
|
||||
)
|
||||
SHAREABLE_TEXT_LINE_SETTINGS["MY"][4] = (" ", False)
|
||||
SHAREABLE_TEXT_LINE_SETTINGS["MY"][5] = (" ", True)
|
||||
|
||||
# adjusts geocoder zoom level when geocoding latlong into an address
|
||||
LOCALITY_GEOCODER_LEVEL: int = 13
|
||||
|
||||
# exceptions
|
||||
|
||||
|
@ -819,6 +908,8 @@ class Behaviour(NamedTuple):
|
|||
whether to print version information and exit
|
||||
convert_to_type: ConversionResultTypeEnum = ConversionResultTypeEnum.SHAREABLE_TEXT
|
||||
what type to convert query to
|
||||
using_termux_location: bool = False
|
||||
treats query as a termux-location output json string, and parses it accordingly
|
||||
"""
|
||||
|
||||
query: str | list[str] = ""
|
||||
|
@ -829,6 +920,7 @@ class Behaviour(NamedTuple):
|
|||
debug: bool = False
|
||||
version_header: bool = False
|
||||
convert_to_type: ConversionResultTypeEnum = ConversionResultTypeEnum.SHAREABLE_TEXT
|
||||
using_termux_location: bool = False
|
||||
|
||||
|
||||
# functions
|
||||
|
@ -967,7 +1059,46 @@ def parse_query(behaviour: Behaviour) -> Result[Query]:
|
|||
file=behaviour.stderr,
|
||||
)
|
||||
|
||||
# not a plus/local code, try to match for latlong or string query
|
||||
# check if termux-location json
|
||||
if behaviour.using_termux_location:
|
||||
try:
|
||||
termux_location_json = json_loads(original_query)
|
||||
if not isinstance(termux_location_json, dict):
|
||||
raise ValueError("parsed termux-location json is not a dict")
|
||||
|
||||
return Result[Query](
|
||||
LatlongQuery(
|
||||
Latlong(
|
||||
latitude=termux_location_json["latitude"],
|
||||
longitude=termux_location_json["longitude"],
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
except (JSONDecodeError, TypeError) as exc:
|
||||
return Result[Query](
|
||||
LatlongQuery(EMPTY_LATLONG),
|
||||
error=ValueError("could not parse termux-location json"),
|
||||
)
|
||||
|
||||
except KeyError as exc:
|
||||
return Result[Query](
|
||||
LatlongQuery(EMPTY_LATLONG),
|
||||
error=ValueError(
|
||||
"could not get 'latitude' or 'longitude' keys from termux-location json"
|
||||
),
|
||||
)
|
||||
|
||||
except Exception as exc:
|
||||
return Result[Query](
|
||||
LatlongQuery(EMPTY_LATLONG),
|
||||
error=exc,
|
||||
)
|
||||
|
||||
# unreachable
|
||||
|
||||
# not a plus/local code/termux-location json,
|
||||
# try to match for latlong or string query
|
||||
match split_query:
|
||||
case [single]:
|
||||
# possibly a:
|
||||
|
@ -1081,11 +1212,19 @@ def handle_args() -> Behaviour:
|
|||
help=f"user agent string to use for geocoding service, defaults to fingerprinted user agent string",
|
||||
default=default_fingerprint,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--using-termux-location",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="treats input as a termux-location output json string, and parses it accordingly",
|
||||
)
|
||||
|
||||
# initialisation
|
||||
args = parser.parse_args()
|
||||
|
||||
query: str | list[str] = ""
|
||||
|
||||
# "-" stdin check
|
||||
if args.query == ["-"]:
|
||||
stdin_query: list[str] = []
|
||||
|
||||
|
@ -1097,8 +1236,8 @@ def handle_args() -> Behaviour:
|
|||
else:
|
||||
query = args.query
|
||||
|
||||
# setup structures and return
|
||||
geocoding = SurplusDefaultGeocoding(args.user_agent)
|
||||
|
||||
behaviour = Behaviour(
|
||||
query=query,
|
||||
geocoder=geocoding.geocoder,
|
||||
|
@ -1108,8 +1247,8 @@ def handle_args() -> Behaviour:
|
|||
debug=args.debug,
|
||||
version_header=args.version,
|
||||
convert_to_type=ConversionResultTypeEnum(args.convert_to),
|
||||
using_termux_location=args.using_termux_location,
|
||||
)
|
||||
|
||||
return behaviour
|
||||
|
||||
|
||||
|
@ -1147,7 +1286,7 @@ def _generate_text(
|
|||
def _generate_text_line(
|
||||
line_number: int,
|
||||
line_keys: Sequence[str],
|
||||
seperator: str = ", ",
|
||||
separator: str = ", ",
|
||||
filter: Callable[[str], list[bool]] = lambda e: [True],
|
||||
) -> str:
|
||||
"""
|
||||
|
@ -1158,8 +1297,8 @@ def _generate_text(
|
|||
line number to prefix with
|
||||
line_keys: Sequence[str]
|
||||
list of keys to .get() from location dict
|
||||
seperator: str = ", "
|
||||
seperator to join elements with
|
||||
separator: str = ", "
|
||||
separator to join elements with
|
||||
filter: Callable[[str], list[bool]] = lambda e: True
|
||||
function that takes in a string and returns a list of bools, used to
|
||||
filter elements from line_keys. list will be passed to all(). if all
|
||||
|
@ -1199,9 +1338,37 @@ def _generate_text(
|
|||
)
|
||||
continue
|
||||
|
||||
line = line_prefix + seperator.join(basket)
|
||||
line = line_prefix + separator.join(basket)
|
||||
return (line + "\n") if (line != "") else ""
|
||||
|
||||
C = TypeVar("C")
|
||||
|
||||
def stget(split_iso3166_2: list[str], line_keys: dict[str, C]) -> tuple[bool, C]:
|
||||
"""
|
||||
(internal function)
|
||||
|
||||
arguments:
|
||||
split_iso3166_2: list[str]
|
||||
the dash-split iso 3166-2 country code
|
||||
|
||||
line_keys:
|
||||
the shareable text line keys dict to use
|
||||
|
||||
returns tuple[bool, C]
|
||||
bool: whether the a special key arrangement was used
|
||||
C: dict content
|
||||
"""
|
||||
|
||||
DEFAULT = "default"
|
||||
country: str = DEFAULT
|
||||
if len(iso3166_2) >= 1:
|
||||
country = split_iso3166_2[0]
|
||||
|
||||
if country not in line_keys:
|
||||
return False, line_keys[DEFAULT]
|
||||
else:
|
||||
return True, line_keys[country]
|
||||
|
||||
# iso3166-2 handling: this allows surplus to have special key arrangements for a
|
||||
# specific iso3166-2 code for edge cases
|
||||
# (https://en.wikipedia.org/wiki/ISO_3166-2)
|
||||
|
@ -1220,49 +1387,46 @@ def _generate_text(
|
|||
file=behaviour.stderr,
|
||||
)
|
||||
|
||||
# skeleton code to allow for changing keys based on iso3166-2 code
|
||||
st_line0_keys = SHAREABLE_TEXT_LINE_0_KEYS
|
||||
st_line1_keys = SHAREABLE_TEXT_LINE_1_KEYS
|
||||
st_line2_keys = SHAREABLE_TEXT_LINE_2_KEYS
|
||||
st_line3_keys = SHAREABLE_TEXT_LINE_3_KEYS
|
||||
st_line4_keys = SHAREABLE_TEXT_LINE_4_KEYS
|
||||
st_line5_keys = SHAREABLE_TEXT_LINE_5_KEYS
|
||||
st_line6_keys = SHAREABLE_TEXT_LINE_6_KEYS
|
||||
st_names = SHAREABLE_TEXT_NAMES
|
||||
st_locality: tuple[str, ...] = ()
|
||||
n_used_special: int = 0 # number of special key arrangements used
|
||||
|
||||
# special key arrangements for edge cases in local/regional address formats
|
||||
match split_iso3166_2:
|
||||
case ["SG", *_]: # Singapore
|
||||
if debug:
|
||||
# skeleton code to allow for changing keys based on iso3166-2 code
|
||||
used_special, st_line0_keys = stget(split_iso3166_2, SHAREABLE_TEXT_LINE_0_KEYS)
|
||||
n_used_special += used_special
|
||||
|
||||
used_special, st_line1_keys = stget(split_iso3166_2, SHAREABLE_TEXT_LINE_1_KEYS)
|
||||
n_used_special += used_special
|
||||
|
||||
used_special, st_line2_keys = stget(split_iso3166_2, SHAREABLE_TEXT_LINE_2_KEYS)
|
||||
n_used_special += used_special
|
||||
|
||||
used_special, st_line3_keys = stget(split_iso3166_2, SHAREABLE_TEXT_LINE_3_KEYS)
|
||||
n_used_special += used_special
|
||||
|
||||
used_special, st_line4_keys = stget(split_iso3166_2, SHAREABLE_TEXT_LINE_4_KEYS)
|
||||
n_used_special += used_special
|
||||
|
||||
used_special, st_line5_keys = stget(split_iso3166_2, SHAREABLE_TEXT_LINE_5_KEYS)
|
||||
n_used_special += used_special
|
||||
|
||||
used_special, st_line6_keys = stget(split_iso3166_2, SHAREABLE_TEXT_LINE_6_KEYS)
|
||||
n_used_special += used_special
|
||||
|
||||
used_special, st_names = stget(split_iso3166_2, SHAREABLE_TEXT_NAMES)
|
||||
n_used_special += used_special
|
||||
|
||||
used_special, st_locality = stget(split_iso3166_2, SHAREABLE_TEXT_LOCALITY)
|
||||
n_used_special += used_special
|
||||
|
||||
used_special, st_line_settings = stget(split_iso3166_2, SHAREABLE_TEXT_LINE_SETTINGS)
|
||||
n_used_special += used_special
|
||||
|
||||
if n_used_special and debug:
|
||||
print(
|
||||
"debug: _generate_text: "
|
||||
f"using special key arrangements for '{iso3166_2}' (Singapore)",
|
||||
file=behaviour.stderr,
|
||||
)
|
||||
|
||||
st_locality = SHAREABLE_TEXT_LOCALITY[split_iso3166_2[0]]
|
||||
|
||||
case ["IT", *_]: # Italy
|
||||
if debug:
|
||||
print(
|
||||
"debug: _generate_text: "
|
||||
f"using special key arrangements for '{iso3166_2}' (Italy)",
|
||||
file=behaviour.stderr,
|
||||
)
|
||||
|
||||
st_line3_keys = SHAREABLE_TEXT_LINE_3_KEYS_IT
|
||||
|
||||
case _: # default
|
||||
if debug:
|
||||
print(
|
||||
"debug: _generate_text: "
|
||||
f"using default key arrangements for '{iso3166_2}'",
|
||||
file=behaviour.stderr,
|
||||
)
|
||||
|
||||
st_locality = SHAREABLE_TEXT_LOCALITY["default"]
|
||||
|
||||
# start generating text
|
||||
match mode:
|
||||
case TextGenerationEnum.SHAREABLE_TEXT:
|
||||
|
@ -1283,52 +1447,37 @@ def _generate_text(
|
|||
str(location.get(detail, "")) for detail in st_line6_keys
|
||||
]
|
||||
|
||||
text.append(
|
||||
_generate_text_line(
|
||||
line_number=0,
|
||||
line_keys=st_line0_keys,
|
||||
)
|
||||
)
|
||||
text.append(
|
||||
_generate_text_line(
|
||||
line_number=1,
|
||||
line_keys=st_line1_keys,
|
||||
)
|
||||
)
|
||||
text.append(
|
||||
_generate_text_line(
|
||||
line_number=2,
|
||||
line_keys=st_line2_keys,
|
||||
)
|
||||
)
|
||||
text.append(
|
||||
_generate_text_line(
|
||||
line_number=3,
|
||||
line_keys=st_line3_keys,
|
||||
seperator=" ",
|
||||
)
|
||||
)
|
||||
text.append(
|
||||
_generate_text_line(
|
||||
line_number=4,
|
||||
line_keys=st_line4_keys,
|
||||
filter=lambda ak: [
|
||||
# everything here should be True if the element is to be kept
|
||||
for (
|
||||
line_number,
|
||||
line_keys,
|
||||
) in enumerate(
|
||||
[
|
||||
st_line0_keys,
|
||||
st_line1_keys,
|
||||
st_line2_keys,
|
||||
st_line3_keys,
|
||||
st_line4_keys,
|
||||
st_line5_keys,
|
||||
st_line6_keys,
|
||||
]
|
||||
):
|
||||
line_separator, line_filter = st_line_settings[line_number]
|
||||
|
||||
# filter: everything here should be True if the element is to be kept
|
||||
if line_filter is False:
|
||||
_filter = lambda e: [True]
|
||||
else:
|
||||
_filter = lambda ak: [
|
||||
ak not in general_global_info,
|
||||
not any(True if (ak in sn) else False for sn in seen_names),
|
||||
],
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
text.append(
|
||||
_generate_text_line(
|
||||
line_number=5,
|
||||
line_keys=st_line5_keys,
|
||||
)
|
||||
)
|
||||
text.append(
|
||||
_generate_text_line(
|
||||
line_number=6,
|
||||
line_keys=st_line6_keys,
|
||||
line_number=line_number,
|
||||
line_keys=line_keys,
|
||||
separator=line_separator,
|
||||
filter=_filter,
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -1602,9 +1751,9 @@ def surplus(query: Query | str, behaviour: Behaviour) -> Result[str]:
|
|||
def cli() -> int:
|
||||
"""command-line entry point, returns an exit code int"""
|
||||
|
||||
# handle arguments and print version header
|
||||
behaviour = handle_args()
|
||||
|
||||
# handle arguments and print version header
|
||||
print(
|
||||
f"surplus version {'.'.join([str(v) for v in VERSION])}{VERSION_SUFFIX}"
|
||||
+ (f", debug mode" if behaviour.debug else "")
|
||||
|
|
42
test.py
42
test.py
|
@ -1,5 +1,3 @@
|
|||
# type: ignore
|
||||
|
||||
"""
|
||||
surplus test runner
|
||||
-------------------
|
||||
|
@ -58,7 +56,7 @@ class TestFailure(NamedTuple):
|
|||
tests: list[ContinuityTest] = [
|
||||
ContinuityTest(
|
||||
query="8R3M+F8 Singapore",
|
||||
expected=("Wisma Atria\n" "435 Orchard Road\n" "238877\n" "Central, Singapore"),
|
||||
expected=[("Wisma Atria\n" "435 Orchard Road\n" "238877\n" "Central, Singapore")],
|
||||
),
|
||||
ContinuityTest(
|
||||
query="9R3J+R9 Singapore",
|
||||
|
@ -96,6 +94,13 @@ tests: list[ContinuityTest] = [
|
|||
"4072\n"
|
||||
"Queensland, Australia"
|
||||
),
|
||||
(
|
||||
"The University of Queensland\n"
|
||||
"Hawken Drive\n"
|
||||
"St Lucia, Greater Brisbane\n"
|
||||
"4072\n"
|
||||
"Queensland, Australia"
|
||||
),
|
||||
],
|
||||
),
|
||||
ContinuityTest(
|
||||
|
@ -107,7 +112,14 @@ tests: list[ContinuityTest] = [
|
|||
"Bukit Timah\n"
|
||||
"599489\n"
|
||||
"Northwest, Singapore"
|
||||
)
|
||||
),
|
||||
(
|
||||
"Ngee Ann Polytechnic\n"
|
||||
"535 Clementi Road\n"
|
||||
"Ewart Park, Bukit Timah\n"
|
||||
"599489\n"
|
||||
"Northwest, Singapore"
|
||||
),
|
||||
],
|
||||
),
|
||||
ContinuityTest(
|
||||
|
@ -139,6 +151,28 @@ tests: list[ContinuityTest] = [
|
|||
),
|
||||
],
|
||||
),
|
||||
ContinuityTest(
|
||||
query="J286+WV San Cesario sul Panaro, Modena, Italy",
|
||||
expected=[
|
||||
(
|
||||
"Via Emilia 1193a\n"
|
||||
"Unione dei comuni del Sorbara, Sant'Anna\n"
|
||||
"41018 Modena Emilia-Romagna\n"
|
||||
"Italia"
|
||||
),
|
||||
],
|
||||
),
|
||||
ContinuityTest(
|
||||
query="GQ2G+GX Johor Bahru, Johor, Malaysia",
|
||||
expected=[
|
||||
(
|
||||
"The Mall, Mid Valley Southkey\n"
|
||||
"Jalan Bakar Batu\n"
|
||||
"81100 Taman Sentosa Johor Bahru\n"
|
||||
"Iskandar Malaysia, Johor, Malaysia"
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue