Skip to content

Commit

Permalink
Add filters, use poetry, better use of pyinstaller (#23)
Browse files Browse the repository at this point in the history
* Add more filters

* Use poetry for dependencies

* Best practices for pyinstaller (not working yet)

* Convert things to relative imports

* Add extra parameters to Chameleon.spec

* Move config dir creation to app initial run

* Remove unneeded hidden imports

* Fix caching
  • Loading branch information
dericke authored Sep 27, 2022
1 parent 9e47049 commit c781372
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 43 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ test/output_name.csv
main.spec
output_test.csv
pip-selfcheck.json
poetry.lock
7 changes: 4 additions & 3 deletions Chameleon.spec
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,13 @@ else:


a = Analysis(
["chameleon/qt/qt.py"],
["pyinstaller_entry.py"],
pathex=[],
binaries=[],
datas=added_files,
hiddenimports=[
"chameleon.qt.design",
"cmath",
"pandas._libs.tslibs.timedeltas",
"pytest",
],
hookspath=[],
runtime_hooks=[],
Expand Down Expand Up @@ -77,9 +75,11 @@ exe = EXE(
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
icon="chameleon/resources/chameleon.icns" if is_mac else None,
entitlements_file=None,
)
if is_mac:
coll = COLLECT(
Expand All @@ -89,6 +89,7 @@ if is_mac:
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name="Chameleon",
)
app = BUNDLE(
Expand Down
30 changes: 24 additions & 6 deletions chameleon/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import requests_cache
import yaml
from more_itertools import chunked as pager
from requests_cache.backends import sqlite

pd.options.mode.chained_assignment = None

Expand Down Expand Up @@ -153,7 +152,7 @@ def get_column_from_intermediate(column: str) -> None:
# If neither had one, we just won't include in the output
pass

for column in ("name", "highway"):
for column in ("name", "highway", "barrier"):
if self.chameleon_mode != column:
get_column_from_intermediate(column)

Expand Down Expand Up @@ -241,6 +240,8 @@ def group(self) -> ChameleonDataFrame:
new_column_order += ["name"]
if self.chameleon_mode != "highway":
new_column_order += ["highway"]
if self.chameleon_mode != "barrier":
new_column_order += ["barrier"]
new_column_order += [
f"old_{self.chameleon_mode_cleaned}",
f"new_{self.chameleon_mode_cleaned}",
Expand Down Expand Up @@ -282,6 +283,22 @@ def filter(self) -> ChameleonDataFrame:
)
]

# Drop access changes that don't affect routing
if self.chameleon_mode == "access":
self = self[self["highway"].notnull() | self["barrier"].notnull()]
self = self[
~(
self["old_access"].isin(["yes", np.nan])
& self["new_access"].isin(["yes", np.nan])
)
]

if self.chameleon_mode == "barrier":
self = self[self.index.str.startswith("n")]

if self.chameleon_mode in ["construction", "name"]:
self = self[self["highway"].notnull()]

# Drop rows with Kaart users tagged
if whitelist := self.config.get("user_whitelist", []):
self = self[~self["user"].isin(whitelist)]
Expand Down Expand Up @@ -378,11 +395,12 @@ def setup_cache(self) -> None:
CACHE_LOCATION.mkdir(exist_ok=True, parents=True)
expiry = timedelta(hours=12)
self.session = requests_cache.CachedSession(
backend=sqlite.DbCache(
use_cache_dir=str(CACHE_LOCATION / "cache"),
expire_after=expiry,
)
backend=requests_cache.backends.sqlite.SQLiteCache(
db_path=CACHE_LOCATION / "cache.sqlite",
),
expire_after=expiry,
)
self.session.remove_expired_responses()
logger.debug("Request caching enabled")
except (OSError, OperationalError):
logger.error(
Expand Down
26 changes: 15 additions & 11 deletions chameleon/qt/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@
from requests import HTTPError, Timeout

# Import generated UI file
from chameleon.core import (
from ..core import (
HIGH_DELETIONS_THRESHOLD,
OVERPASS_TIMEOUT,
ChameleonDataFrame,
ChameleonDataFrameSet,
)
from chameleon.qt import design, favorite_edit, filter_config
from . import design, favorite_edit, filter_config

# Differentiate sys settings between pre and post-bundling
RESOURCES_DIR = (
Expand Down Expand Up @@ -239,14 +239,6 @@ def run(self):
logger.debug("Worker thread successfully exposed to debugger.")
try: # Global exception catcher
# Saving paths to config for future loading
# Make directory if it doesn't exist
if not CONFIG_DIR.is_dir():
try:
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
except FileExistsError:
logger.debug("Config directory already exists")
except OSError:
logger.debug("Config directory could not be created.")
if self.files:
self.history_writer()
cdf_set = ChameleonDataFrameSet(
Expand Down Expand Up @@ -663,6 +655,14 @@ def __init__(self, parent=None):
self.work_thread = None
self.worker = None

# Make directory if it doesn't exist
try:
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
except FileExistsError:
logger.debug("Config directory already exists")
except OSError:
logger.debug("Config directory could not be created.")

# Set up application logo on main window
self.logo = str((RESOURCES_DIR / "chameleon.png").resolve())
self.setWindowIcon(QIcon(self.logo))
Expand Down Expand Up @@ -1943,8 +1943,12 @@ def tag_split(raw_label: str) -> list[str]:
return sorted(splitter)


if __name__ == "__main__":
def main():
app = QApplication(sys.argv)
form = MainApp()
form.show()
app.exec()


if __name__ == "__main__":
main()
9 changes: 0 additions & 9 deletions core-requirements.txt

This file was deleted.

3 changes: 3 additions & 0 deletions pyinstaller_entry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from chameleon.qt.qt import main

main()
45 changes: 45 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[tool.poetry]
name = "chameleon"
version = "3.6.2"
description = ""
authors = ["Evan Derickson <[email protected]>"]

[tool.poetry.dependencies]
python = ">=3.10,<3.11"
appdirs = "^1.4.4"
geojson = "^2.5.0"
more-itertools = "^8.14.0"
overpass = { git = "https://github.com/KaartGroup/overpass-api-python-wrapper", branch = "kaart_addons" }
pandas = "^1.4.3"
PyYAML = "^6.0"
requests = "^2.28.1"
requests-cache = "^1.0.0a2"
XlsxWriter = "^3.0.3"

[tool.poetry.group.qt.dependencies]
bidict = "^0.22.0"
pyinstaller = "^5.3"
PySide6 = "^6.3.1"


[tool.poetry.group.web.dependencies]
celery = "^5.2.7"
Flask = "^2.2.2"
gevent = "^21.12.0"
gunicorn = "^20.1.0"
redis = "^4.3.4"
SQLAlchemy = "^1.4.40"
Werkzeug = "^2.2.2"


[tool.poetry.group.dev.dependencies]
black = { version = "^22.6.0", allow-prereleases = true }
GitPython = "^3.1.27"
ptvsd = "^4.3.2"
pytest = "^7.1.2"
pytest-qt = "^4.1.0"
requests-mock = { extras = ["fixture"], version = "^1.9.3" }

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
3 changes: 0 additions & 3 deletions qt-requirements.txt

This file was deleted.

3 changes: 0 additions & 3 deletions test-requirements.txt

This file was deleted.

8 changes: 0 additions & 8 deletions web-requirements.txt

This file was deleted.

0 comments on commit c781372

Please sign in to comment.