tradedangerous 11.5.3__py3-none-any.whl → 12.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tradedangerous might be problematic. Click here for more details.
- tradedangerous/cache.py +567 -395
- tradedangerous/cli.py +2 -2
- tradedangerous/commands/TEMPLATE.py +25 -26
- tradedangerous/commands/__init__.py +8 -16
- tradedangerous/commands/buildcache_cmd.py +40 -10
- tradedangerous/commands/buy_cmd.py +57 -46
- tradedangerous/commands/commandenv.py +0 -2
- tradedangerous/commands/export_cmd.py +78 -50
- tradedangerous/commands/import_cmd.py +67 -31
- tradedangerous/commands/market_cmd.py +52 -19
- tradedangerous/commands/olddata_cmd.py +120 -107
- tradedangerous/commands/rares_cmd.py +122 -110
- tradedangerous/commands/run_cmd.py +118 -66
- tradedangerous/commands/sell_cmd.py +52 -45
- tradedangerous/commands/shipvendor_cmd.py +49 -234
- tradedangerous/commands/station_cmd.py +55 -485
- tradedangerous/commands/update_cmd.py +56 -420
- tradedangerous/csvexport.py +173 -162
- tradedangerous/db/__init__.py +27 -0
- tradedangerous/db/adapter.py +191 -0
- tradedangerous/db/config.py +95 -0
- tradedangerous/db/engine.py +246 -0
- tradedangerous/db/lifecycle.py +332 -0
- tradedangerous/db/locks.py +208 -0
- tradedangerous/db/orm_models.py +455 -0
- tradedangerous/db/paths.py +112 -0
- tradedangerous/db/utils.py +661 -0
- tradedangerous/gui.py +2 -2
- tradedangerous/plugins/eddblink_plug.py +387 -251
- tradedangerous/plugins/spansh_plug.py +2488 -821
- tradedangerous/prices.py +124 -142
- tradedangerous/templates/TradeDangerous.sql +6 -6
- tradedangerous/tradecalc.py +1227 -1109
- tradedangerous/tradedb.py +533 -384
- tradedangerous/tradeenv.py +12 -1
- tradedangerous/version.py +1 -1
- {tradedangerous-11.5.3.dist-info → tradedangerous-12.0.1.dist-info}/METADATA +11 -7
- {tradedangerous-11.5.3.dist-info → tradedangerous-12.0.1.dist-info}/RECORD +42 -38
- {tradedangerous-11.5.3.dist-info → tradedangerous-12.0.1.dist-info}/WHEEL +1 -1
- tradedangerous/commands/update_gui.py +0 -721
- tradedangerous/jsonprices.py +0 -254
- tradedangerous/plugins/edapi_plug.py +0 -1071
- tradedangerous/plugins/journal_plug.py +0 -537
- tradedangerous/plugins/netlog_plug.py +0 -316
- {tradedangerous-11.5.3.dist-info → tradedangerous-12.0.1.dist-info}/entry_points.txt +0 -0
- {tradedangerous-11.5.3.dist-info → tradedangerous-12.0.1.dist-info/licenses}/LICENSE +0 -0
- {tradedangerous-11.5.3.dist-info → tradedangerous-12.0.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# tradedangerous/db/paths.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import os
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
import configparser
|
|
10
|
+
except Exception: # pragma: no cover
|
|
11
|
+
configparser = None # type: ignore
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"ensure_dir",
|
|
15
|
+
"resolve_data_dir",
|
|
16
|
+
"resolve_tmp_dir",
|
|
17
|
+
"resolve_db_config_path",
|
|
18
|
+
"get_sqlite_db_path",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
# --------------------------
|
|
22
|
+
# Helpers that tolerate either ConfigParser or dict
|
|
23
|
+
# --------------------------
|
|
24
|
+
|
|
25
|
+
def _is_cfg(obj: Any) -> bool:
|
|
26
|
+
return hasattr(obj, "has_option") and hasattr(obj, "get")
|
|
27
|
+
|
|
28
|
+
def _get_opt(cfg: Any, section: str, key: str, default: str | None = None) -> str | None:
|
|
29
|
+
"""Return option from either a ConfigParser-like object or a nested dict.
|
|
30
|
+
Falls back to [database] overlay for convenience, matching legacy behaviour.
|
|
31
|
+
Safe even if cfg is None.
|
|
32
|
+
"""
|
|
33
|
+
if cfg is None:
|
|
34
|
+
return default
|
|
35
|
+
# ConfigParser branch
|
|
36
|
+
if _is_cfg(cfg):
|
|
37
|
+
try:
|
|
38
|
+
if cfg.has_option(section, key):
|
|
39
|
+
return cfg.get(section, key) # type: ignore[arg-type]
|
|
40
|
+
if cfg.has_option("database", key):
|
|
41
|
+
return cfg.get("database", key) # type: ignore[arg-type]
|
|
42
|
+
except Exception:
|
|
43
|
+
return default
|
|
44
|
+
return default
|
|
45
|
+
# Mapping/dict branch
|
|
46
|
+
try:
|
|
47
|
+
sec = (cfg or {}).get(section, {}) or {}
|
|
48
|
+
if key in sec and sec[key] not in (None, ""):
|
|
49
|
+
return sec[key]
|
|
50
|
+
db = (cfg or {}).get("database", {}) or {}
|
|
51
|
+
if key in db and db[key] not in (None, ""):
|
|
52
|
+
return db[key]
|
|
53
|
+
except Exception:
|
|
54
|
+
pass
|
|
55
|
+
return default
|
|
56
|
+
|
|
57
|
+
def _resolve_dir(default_rel: str, env_key: str, cfg_value: str | None) -> Path:
|
|
58
|
+
cand = os.getenv(env_key) or (cfg_value or default_rel)
|
|
59
|
+
p = Path(cand).expanduser()
|
|
60
|
+
return p if p.is_absolute() else (Path.cwd() / p)
|
|
61
|
+
|
|
62
|
+
# --------------------------
|
|
63
|
+
# Public API
|
|
64
|
+
# --------------------------
|
|
65
|
+
|
|
66
|
+
def ensure_dir(pathlike: os.PathLike | str) -> Path:
|
|
67
|
+
"""Create directory if missing (idempotent) and return the Path."""
|
|
68
|
+
p = Path(pathlike)
|
|
69
|
+
p.mkdir(parents=True, exist_ok=True)
|
|
70
|
+
return p
|
|
71
|
+
|
|
72
|
+
def resolve_data_dir(cfg: Any = None) -> Path:
|
|
73
|
+
"""Resolve the persistent data directory.
|
|
74
|
+
|
|
75
|
+
Precedence: TD_DATA env > cfg[paths|database].data_dir > ./data
|
|
76
|
+
Always creates the directory.
|
|
77
|
+
"""
|
|
78
|
+
val = _get_opt(cfg, "paths", "data_dir") or _get_opt(cfg, "database", "data_dir")
|
|
79
|
+
p = _resolve_dir("./data", "TD_DATA", val)
|
|
80
|
+
return ensure_dir(p)
|
|
81
|
+
|
|
82
|
+
def resolve_tmp_dir(cfg: Any = None) -> Path:
|
|
83
|
+
"""Resolve the temporary directory.
|
|
84
|
+
|
|
85
|
+
Precedence: TD_TMP env > cfg[paths|database].tmp_dir > ./tmp
|
|
86
|
+
Always creates the directory.
|
|
87
|
+
"""
|
|
88
|
+
val = _get_opt(cfg, "paths", "tmp_dir") or _get_opt(cfg, "database", "tmp_dir")
|
|
89
|
+
p = _resolve_dir("./tmp", "TD_TMP", val)
|
|
90
|
+
return ensure_dir(p)
|
|
91
|
+
|
|
92
|
+
def get_sqlite_db_path(cfg: Any = None) -> Path:
|
|
93
|
+
"""Return full path to the SQLite DB file (does not create the file).
|
|
94
|
+
|
|
95
|
+
Data dir is resolved via resolve_data_dir(cfg). Filename comes from:
|
|
96
|
+
cfg[sqlite].sqlite_filename or cfg[database].sqlite_filename or legacy default 'TradeDangerous.db'.
|
|
97
|
+
"""
|
|
98
|
+
data_dir = resolve_data_dir(cfg)
|
|
99
|
+
filename = (
|
|
100
|
+
_get_opt(cfg, "sqlite", "sqlite_filename")
|
|
101
|
+
or _get_opt(cfg, "database", "sqlite_filename")
|
|
102
|
+
or "TradeDangerous.db" # legacy default matches shipped tests/fixtures
|
|
103
|
+
)
|
|
104
|
+
return (data_dir / filename).resolve()
|
|
105
|
+
|
|
106
|
+
def resolve_db_config_path(default_name: str = "db_config.ini") -> Path:
|
|
107
|
+
"""Honor TD_DB_CONFIG env var for config file path, else default_name in CWD.
|
|
108
|
+
Does not read or validate contents; just returns a Path.
|
|
109
|
+
"""
|
|
110
|
+
cand = os.getenv("TD_DB_CONFIG") or default_name
|
|
111
|
+
p = Path(cand).expanduser()
|
|
112
|
+
return p if p.is_absolute() else (Path.cwd() / p)
|