mirror of
https://github.com/rangermix/TwitchDropsMiner.git
synced 2026-05-28 16:09:39 +00:00
Add a way for the application to dump inventory data into a file
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -13,6 +13,7 @@ __pycache__
|
||||
/cache
|
||||
/*.jar
|
||||
log.txt
|
||||
/dump.dat
|
||||
/lock.file
|
||||
settings.json
|
||||
/lang/English.json
|
||||
|
||||
27
.vscode/launch.json
vendored
27
.vscode/launch.json
vendored
@@ -11,24 +11,6 @@
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Run App (INFO)",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "main.py",
|
||||
"args": ["-vv"],
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": false
|
||||
},
|
||||
{
|
||||
"name": "Run App (INFO+Tray)",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "main.py",
|
||||
"args": ["-vv", "--tray"],
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": false
|
||||
},
|
||||
{
|
||||
"name": "Run App (CALL)",
|
||||
"type": "python",
|
||||
@@ -38,6 +20,15 @@
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": false
|
||||
},
|
||||
{
|
||||
"name": "Run App (DUMP)",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "main.py",
|
||||
"args": ["--dump"],
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": false
|
||||
},
|
||||
{
|
||||
"name": "Run App (DEBUG+WS)",
|
||||
"type": "python",
|
||||
|
||||
@@ -23,7 +23,7 @@ if TYPE_CHECKING:
|
||||
IS_APPIMAGE = "APPIMAGE" in os.environ and os.path.exists(os.environ["APPIMAGE"])
|
||||
IS_PACKAGED = hasattr(sys, "_MEIPASS") or IS_APPIMAGE
|
||||
# logging special levels
|
||||
CALL = logging.INFO - 1
|
||||
CALL: int = logging.INFO - 1
|
||||
logging.addLevelName(CALL, "CALL")
|
||||
# site-packages venv path changes depending on the system platform
|
||||
if sys.platform == "win32":
|
||||
@@ -94,8 +94,9 @@ SITE_PACKAGES_PATH = Path(VENV_PATH, SYS_SITE_PACKAGES)
|
||||
LANG_PATH = _resource_path("lang")
|
||||
# Other Paths
|
||||
LOG_PATH = Path(WORKING_DIR, "log.txt")
|
||||
CACHE_PATH = Path(WORKING_DIR, "cache")
|
||||
DUMP_PATH = Path(WORKING_DIR, "dump.dat")
|
||||
LOCK_PATH = Path(WORKING_DIR, "lock.file")
|
||||
CACHE_PATH = Path(WORKING_DIR, "cache")
|
||||
CACHE_DB = Path(CACHE_PATH, "mapping.json")
|
||||
COOKIES_PATH = Path(WORKING_DIR, "cookies.jar")
|
||||
SETTINGS_PATH = Path(WORKING_DIR, "settings.json")
|
||||
|
||||
3
main.py
3
main.py
@@ -53,7 +53,7 @@ if __name__ == "__main__":
|
||||
_debug_gql: bool
|
||||
log: bool
|
||||
tray: bool
|
||||
no_run_check: bool
|
||||
dump: bool
|
||||
|
||||
# TODO: replace int with union of literal values once typeshed updates
|
||||
@property
|
||||
@@ -103,6 +103,7 @@ if __name__ == "__main__":
|
||||
parser.add_argument("-v", dest="_verbose", action="count", default=0)
|
||||
parser.add_argument("--tray", action="store_true")
|
||||
parser.add_argument("--log", action="store_true")
|
||||
parser.add_argument("--dump", action="store_true")
|
||||
# undocumented debug args
|
||||
parser.add_argument(
|
||||
"--debug-ws", dest="_debug_ws", action="store_true", help=argparse.SUPPRESS
|
||||
|
||||
@@ -5,15 +5,20 @@
|
||||
Available command line arguments:
|
||||
|
||||
• --tray
|
||||
Start application as minimised into tray.
|
||||
Start the application as minimised into tray.
|
||||
• -v
|
||||
Increase verbosity level. Can be stacked up several times (-vv, -vvv, etc.) to show
|
||||
increasingly more information during application runtime.
|
||||
• --log
|
||||
Enables logging of runtime information into a 'log.txt' file. Verbosity level of this logging
|
||||
matches the level set by `-v`.
|
||||
• --dump
|
||||
Start the application in a data-dump mode, where a 'dump.dat' file is created.
|
||||
The file contains anonymous raw Twitch API data, studying of which can help troubleshoot
|
||||
issues with the application. The application automatically closes shortly after launching,
|
||||
once dumping is finished.
|
||||
• --version
|
||||
Show application version information
|
||||
Show application version information.
|
||||
|
||||
Note: Additional settings are available within the application GUI.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class Settings:
|
||||
# from args
|
||||
log: bool
|
||||
tray: bool
|
||||
no_run_check: bool
|
||||
dump: bool
|
||||
# args properties
|
||||
debug_ws: int
|
||||
debug_gql: int
|
||||
|
||||
32
twitch.py
32
twitch.py
@@ -4,6 +4,7 @@ import json
|
||||
import asyncio
|
||||
import logging
|
||||
from time import time
|
||||
from copy import deepcopy
|
||||
from itertools import chain
|
||||
from functools import partial
|
||||
from collections import abc, deque, OrderedDict
|
||||
@@ -39,6 +40,7 @@ from utils import (
|
||||
)
|
||||
from constants import (
|
||||
CALL,
|
||||
DUMP_PATH,
|
||||
COOKIES_PATH,
|
||||
GQL_OPERATIONS,
|
||||
MAX_CHANNELS,
|
||||
@@ -559,6 +561,10 @@ class Twitch:
|
||||
return -1
|
||||
|
||||
async def run(self):
|
||||
if self.settings.dump:
|
||||
with open(DUMP_PATH, 'w', encoding="utf8"):
|
||||
# replace the existing file with an empty one
|
||||
pass
|
||||
while True:
|
||||
try:
|
||||
await self._run()
|
||||
@@ -599,6 +605,9 @@ class Twitch:
|
||||
self.change_state(State.INVENTORY_FETCH)
|
||||
while True:
|
||||
if self._state is State.IDLE:
|
||||
if self.settings.dump:
|
||||
self.gui.close()
|
||||
continue
|
||||
self.gui.status.update(_("gui", "status", "idle"))
|
||||
self.stop_watching()
|
||||
# clear the flag and wait until it's set again
|
||||
@@ -787,6 +796,9 @@ class Twitch:
|
||||
watching_channel,
|
||||
)
|
||||
elif self._state is State.CHANNEL_SWITCH:
|
||||
if self.settings.dump:
|
||||
self.gui.close()
|
||||
continue
|
||||
self.gui.status.update(_("gui", "status", "switching"))
|
||||
# Change into the selected channel, stay in the watching channel,
|
||||
# or select a new channel that meets the required conditions
|
||||
@@ -1412,6 +1424,26 @@ class Twitch:
|
||||
chunk_campaigns_data = await chunk_coro
|
||||
# merge the inventory and campaigns datas together
|
||||
inventory_data = self._merge_data(inventory_data, chunk_campaigns_data)
|
||||
|
||||
if self.settings.dump:
|
||||
# dump the campaigns data to the dump file
|
||||
with open(DUMP_PATH, 'a', encoding="utf8") as file:
|
||||
# pre-process a little, so the dump file isn't overly bloated
|
||||
dump_data: JsonType = deepcopy(inventory_data)
|
||||
for campaign_data in dump_data.values():
|
||||
if (
|
||||
campaign_data["allow"]
|
||||
and campaign_data["allow"].get("isEnabled", True)
|
||||
and campaign_data["allow"]["channels"]
|
||||
):
|
||||
# simply count the channels included in the ACL
|
||||
campaign_data["allow"]["channels"] = (
|
||||
f"{len(campaign_data['allow']['channels'])} channels"
|
||||
)
|
||||
json.dump(dump_data, file, indent=4, sort_keys=True)
|
||||
file.write("\n\n") # add a new line spacer
|
||||
json.dump(claimed_benefits, file, indent=4, sort_keys=True, default=str)
|
||||
|
||||
# use the merged data to create campaign objects
|
||||
campaigns: list[DropsCampaign] = [
|
||||
DropsCampaign(self, campaign_data, claimed_benefits)
|
||||
|
||||
Reference in New Issue
Block a user