-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrove.py
More file actions
68 lines (58 loc) · 3.28 KB
/
Copy pathtrove.py
File metadata and controls
68 lines (58 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/env python3
"""trove - personal price/listing intelligence over many sources, one shared core.
python trove.py <source> <command> [args]
Examples:
python trove.py steam search "elden ring"
python trove.py discogs release 249504 # 'item' alias per source below
python trove.py itunes watch add 1713845538
python trove.py steam poll
Run `python trove.py` to list sources, or `python trove.py <source> -h` for its commands.
Each source keeps its own history in data/<source>.db.
"""
from __future__ import annotations
import importlib
import os
import sys
ROOT = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(ROOT, "data")
# Sources grouped by genre. This grouping is the single source of truth: it drives
# the `--help` listing, and the flat SOURCES tuple (membership + dispatch) is derived
# from it. Adding a source = drop its name into the right group below.
SOURCE_GROUPS = {
"games / media / collectibles": ("steam", "discogs", "itunes", "scryfall", "pokemontcg", "ygoprodeck", "epic", "steammarket"),
"fuel & electricity": ("spainfuel", "petrolspy", "em6", "octopus", "aemo", "fuelwatch", "awattar", "carbonintensity", "nyiso", "francefuel", "energinet"),
"currency & macro": ("frankfurter", "paralelobo"),
"deals, fares & listings": ("grabone", "grabaseat", "bookme", "turners", "eventcinemas", "reverb"),
"attention & rank": ("hackernews", "appcharts", "melbped"),
"weather, environment & geohazard": ("geonet", "metno", "volcano", "nzski", "gwrivers", "avalanche", "mdcrivers", "nswrfs", "beachwatch", "vicemergency", "horizonsrivers", "northlandrivers", "westcoastrivers", "sacfs", "safeswim", "eafloods", "usgs", "wildfire", "airquality", "usgsquakes", "hkweather", "ipma", "luchtmeetnet"),
"space": ("spaceweather", "sentry", "spacelaunch"),
"aviation": ("chcflights", "zqnflights", "opensky", "adsblol"),
"roads & transport": ("nzroads", "tfl", "mbta", "swisstransport", "bcferries"),
"shared mobility": ("bikeshare", "sgtaxi"),
"sports & recreation": ("squiggle",),
"parking": ("chcparking", "sgcarpark"),
"utilities & outages": ("outages",),
"marine & coastal": ("noaatides", "ndbc"),
"civic & government": ("civic311",),
"jobs & labour": ("arbeitnow",),
}
SOURCES = tuple(name for group in SOURCE_GROUPS.values() for name in group)
def main(argv=None):
argv = list(sys.argv[1:] if argv is None else argv)
if not argv or argv[0] in ("-h", "--help"):
print(__doc__)
print("sources:")
w = max(len(label) for label in SOURCE_GROUPS)
for label, names in SOURCE_GROUPS.items():
print(f" {label:<{w}} {', '.join(names)}")
return 0
name = argv[0]
if name not in SOURCES:
print(f"unknown source '{name}'. available: {', '.join(SOURCES)}", file=sys.stderr)
return 2
sys.path.insert(0, ROOT)
mod = importlib.import_module(f"sources.{name}")
from trove.tracker import run_cli
return run_cli(mod.SOURCE, argv[1:], DATA_DIR)
if __name__ == "__main__":
raise SystemExit(main())