tradedangerous 12.7.6__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.
- py.typed +1 -0
- trade.py +49 -0
- tradedangerous/__init__.py +43 -0
- tradedangerous/cache.py +1381 -0
- tradedangerous/cli.py +136 -0
- tradedangerous/commands/TEMPLATE.py +74 -0
- tradedangerous/commands/__init__.py +244 -0
- tradedangerous/commands/buildcache_cmd.py +102 -0
- tradedangerous/commands/buy_cmd.py +427 -0
- tradedangerous/commands/commandenv.py +372 -0
- tradedangerous/commands/exceptions.py +94 -0
- tradedangerous/commands/export_cmd.py +150 -0
- tradedangerous/commands/import_cmd.py +222 -0
- tradedangerous/commands/local_cmd.py +243 -0
- tradedangerous/commands/market_cmd.py +207 -0
- tradedangerous/commands/nav_cmd.py +252 -0
- tradedangerous/commands/olddata_cmd.py +270 -0
- tradedangerous/commands/parsing.py +221 -0
- tradedangerous/commands/rares_cmd.py +298 -0
- tradedangerous/commands/run_cmd.py +1521 -0
- tradedangerous/commands/sell_cmd.py +262 -0
- tradedangerous/commands/shipvendor_cmd.py +60 -0
- tradedangerous/commands/station_cmd.py +68 -0
- tradedangerous/commands/trade_cmd.py +181 -0
- tradedangerous/commands/update_cmd.py +67 -0
- tradedangerous/corrections.py +55 -0
- tradedangerous/csvexport.py +234 -0
- tradedangerous/db/__init__.py +27 -0
- tradedangerous/db/adapter.py +192 -0
- tradedangerous/db/config.py +107 -0
- tradedangerous/db/engine.py +259 -0
- tradedangerous/db/lifecycle.py +332 -0
- tradedangerous/db/locks.py +208 -0
- tradedangerous/db/orm_models.py +500 -0
- tradedangerous/db/paths.py +113 -0
- tradedangerous/db/utils.py +661 -0
- tradedangerous/edscupdate.py +565 -0
- tradedangerous/edsmupdate.py +474 -0
- tradedangerous/formatting.py +210 -0
- tradedangerous/fs.py +156 -0
- tradedangerous/gui.py +1146 -0
- tradedangerous/mapping.py +133 -0
- tradedangerous/mfd/__init__.py +103 -0
- tradedangerous/mfd/saitek/__init__.py +3 -0
- tradedangerous/mfd/saitek/directoutput.py +678 -0
- tradedangerous/mfd/saitek/x52pro.py +195 -0
- tradedangerous/misc/checkpricebounds.py +287 -0
- tradedangerous/misc/clipboard.py +49 -0
- tradedangerous/misc/coord64.py +83 -0
- tradedangerous/misc/csvdialect.py +57 -0
- tradedangerous/misc/derp-sentinel.py +35 -0
- tradedangerous/misc/diff-system-csvs.py +159 -0
- tradedangerous/misc/eddb.py +81 -0
- tradedangerous/misc/eddn.py +349 -0
- tradedangerous/misc/edsc.py +437 -0
- tradedangerous/misc/edsm.py +121 -0
- tradedangerous/misc/importeddbstats.py +54 -0
- tradedangerous/misc/prices-json-exp.py +179 -0
- tradedangerous/misc/progress.py +194 -0
- tradedangerous/plugins/__init__.py +249 -0
- tradedangerous/plugins/edcd_plug.py +371 -0
- tradedangerous/plugins/eddblink_plug.py +861 -0
- tradedangerous/plugins/edmc_batch_plug.py +133 -0
- tradedangerous/plugins/spansh_plug.py +2647 -0
- tradedangerous/prices.py +211 -0
- tradedangerous/submit-distances.py +422 -0
- tradedangerous/templates/Added.csv +37 -0
- tradedangerous/templates/Category.csv +17 -0
- tradedangerous/templates/RareItem.csv +143 -0
- tradedangerous/templates/TradeDangerous.sql +338 -0
- tradedangerous/tools.py +40 -0
- tradedangerous/tradecalc.py +1302 -0
- tradedangerous/tradedb.py +2320 -0
- tradedangerous/tradeenv.py +313 -0
- tradedangerous/tradeenv.pyi +109 -0
- tradedangerous/tradeexcept.py +131 -0
- tradedangerous/tradeorm.py +183 -0
- tradedangerous/transfers.py +192 -0
- tradedangerous/utils.py +243 -0
- tradedangerous/version.py +16 -0
- tradedangerous-12.7.6.dist-info/METADATA +106 -0
- tradedangerous-12.7.6.dist-info/RECORD +87 -0
- tradedangerous-12.7.6.dist-info/WHEEL +5 -0
- tradedangerous-12.7.6.dist-info/entry_points.txt +3 -0
- tradedangerous-12.7.6.dist-info/licenses/LICENSE +373 -0
- tradedangerous-12.7.6.dist-info/top_level.txt +2 -0
- tradegui.py +24 -0
tradedangerous/fs.py
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""This module should handle filesystem related operations
|
|
2
|
+
"""
|
|
3
|
+
from os import makedirs, PathLike
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from shutil import copy as shcopy
|
|
6
|
+
import typing
|
|
7
|
+
|
|
8
|
+
__all__ = ['copy', 'copyallfiles', 'touch', 'ensurefolder', 'file_line_count']
|
|
9
|
+
|
|
10
|
+
Pathlike: typing.TypeAlias = Path | str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def pathify(*args: str | Path) -> Path:
|
|
14
|
+
""" pathify will ensure a Path given input(s) that can be
|
|
15
|
+
either a single Path/str, or components to form one.
|
|
16
|
+
e.g.
|
|
17
|
+
pathify("C:/temp") -> Path("c:/temp")
|
|
18
|
+
pathify("C":", "temp") -> Path("C:/temp")
|
|
19
|
+
pathify("C:", Path("temp")) -> Path("C:/temp")
|
|
20
|
+
"""
|
|
21
|
+
if len(args) > 1 or not isinstance(args[0], Path):
|
|
22
|
+
return Path(*args)
|
|
23
|
+
return args[0]
|
|
24
|
+
|
|
25
|
+
def copy(src: PathLike, dst: PathLike) -> Path:
|
|
26
|
+
"""
|
|
27
|
+
copy src to dst
|
|
28
|
+
takes string or Path object as input
|
|
29
|
+
returns Path(dst) on success
|
|
30
|
+
raises FileNotFoundError if src does not exist
|
|
31
|
+
"""
|
|
32
|
+
srcPath = pathify(src).resolve()
|
|
33
|
+
dstPath = pathify(dst)
|
|
34
|
+
shcopy(str(srcPath), str(dstPath))
|
|
35
|
+
return dstPath
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def copy_if_newer(src: Pathlike, dst: Pathlike) -> Path:
|
|
39
|
+
"""
|
|
40
|
+
copy src to dst if src is newer
|
|
41
|
+
takes string or Path object as input
|
|
42
|
+
returns Path(dst) on success
|
|
43
|
+
returns Path(src) if not newer
|
|
44
|
+
raises FileNotFoundError if src does not exist
|
|
45
|
+
"""
|
|
46
|
+
srcPath = pathify(src).resolve()
|
|
47
|
+
dstPath = pathify(dst)
|
|
48
|
+
if dstPath.exists() and dstPath.stat().st_mtime >= srcPath.stat().st_mtime:
|
|
49
|
+
return srcPath
|
|
50
|
+
|
|
51
|
+
shcopy(srcPath, dstPath) # kfs: python 3.10 don't need us to strify these
|
|
52
|
+
return dstPath
|
|
53
|
+
|
|
54
|
+
def copy_if_missing(src: Pathlike, dst: Pathlike) -> Path:
|
|
55
|
+
"""
|
|
56
|
+
copy src to dst only if dst does not exist (or exists but is empty).
|
|
57
|
+
|
|
58
|
+
This is intended for bootstrap template files:
|
|
59
|
+
- never clobber an existing user/server CSV
|
|
60
|
+
- avoids "pip upgrade overwrote my downloaded files" behaviour
|
|
61
|
+
|
|
62
|
+
takes string or Path object as input
|
|
63
|
+
returns Path(dst) on success
|
|
64
|
+
returns Path(src) if dst already exists (and is non-empty)
|
|
65
|
+
raises FileNotFoundError if src does not exist
|
|
66
|
+
"""
|
|
67
|
+
srcPath = pathify(src).resolve()
|
|
68
|
+
dstPath = pathify(dst)
|
|
69
|
+
|
|
70
|
+
if dstPath.exists():
|
|
71
|
+
try:
|
|
72
|
+
if dstPath.stat().st_size > 0:
|
|
73
|
+
return srcPath
|
|
74
|
+
except OSError:
|
|
75
|
+
# If we can't stat it for some reason, play safe and don't overwrite.
|
|
76
|
+
return srcPath
|
|
77
|
+
|
|
78
|
+
shcopy(srcPath, dstPath)
|
|
79
|
+
return dstPath
|
|
80
|
+
|
|
81
|
+
def copyallfiles(srcdir: Pathlike, dstdir: Pathlike) -> None:
|
|
82
|
+
"""
|
|
83
|
+
Copies all files in srcdir to dstdir
|
|
84
|
+
"""
|
|
85
|
+
srcPath = pathify(srcdir)
|
|
86
|
+
dstPath = pathify(dstdir)
|
|
87
|
+
|
|
88
|
+
for p in srcPath.glob('*.*'):
|
|
89
|
+
if p.is_file():
|
|
90
|
+
copy(p, dstPath / p.name)
|
|
91
|
+
|
|
92
|
+
def touch(filename: Pathlike) -> Path:
|
|
93
|
+
"""
|
|
94
|
+
Creates file if it doesn't exist.
|
|
95
|
+
Always modifies utime.
|
|
96
|
+
Returns a Path(filename)
|
|
97
|
+
"""
|
|
98
|
+
path = pathify(filename)
|
|
99
|
+
path.touch(exist_ok=True)
|
|
100
|
+
return path
|
|
101
|
+
|
|
102
|
+
def ensurefolder(folder: Pathlike) -> Path:
|
|
103
|
+
"""Creates the folder if it doesn't exist
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
folder : string|pathlib.Path
|
|
108
|
+
path to the folder
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
pathlib.Path
|
|
113
|
+
Resolved path of the folder
|
|
114
|
+
"""
|
|
115
|
+
folderPath = pathify(folder)
|
|
116
|
+
try:
|
|
117
|
+
makedirs(str(folderPath))
|
|
118
|
+
except FileExistsError:
|
|
119
|
+
pass
|
|
120
|
+
return folderPath.resolve()
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def file_line_count(from_file: Pathlike, buf_size: int = 128 * 1024, *, missing_ok: bool = False) -> int:
|
|
124
|
+
""" counts the number of newline characters in a given file. """
|
|
125
|
+
if not isinstance(from_file, Path):
|
|
126
|
+
from_file = Path(from_file)
|
|
127
|
+
|
|
128
|
+
if missing_ok and not from_file.exists():
|
|
129
|
+
return 0
|
|
130
|
+
|
|
131
|
+
# Pre-allocate a buffer so that we aren't putting pressure on the garbage collector.
|
|
132
|
+
buf = bytearray(buf_size)
|
|
133
|
+
|
|
134
|
+
# Capture it's counting method, so we don't have to keep looking that up on
|
|
135
|
+
# large files.
|
|
136
|
+
counter = buf.count
|
|
137
|
+
|
|
138
|
+
total = 0
|
|
139
|
+
with from_file.open("rb") as fh:
|
|
140
|
+
# Capture the 'readinto' method to avoid lookups.
|
|
141
|
+
reader = fh.readinto
|
|
142
|
+
|
|
143
|
+
# read into the buffer and capture the number of bytes fetched,
|
|
144
|
+
# which will be 'size' until the last read from the file.
|
|
145
|
+
read = reader(buf)
|
|
146
|
+
while read == buf_size: # nominal case for large files
|
|
147
|
+
total += counter(b'\n')
|
|
148
|
+
read = reader(buf)
|
|
149
|
+
|
|
150
|
+
# when 0 <= read < buf_size we're on the last page of the
|
|
151
|
+
# file, so we need to take a slice of the buffer, which creates
|
|
152
|
+
# a new object, thus we also have to lookup count. it's trivial
|
|
153
|
+
# but if you have to do it 10,000x it's definitely not a rounding error.
|
|
154
|
+
return total + buf[:read].count(b'\n')
|
|
155
|
+
|
|
156
|
+
|