Add a way for the application to dump inventory data into a file
This commit is contained in:
1 parent
6d258efe41
commit
f5d5fc3a05
7 files changed
+55
-24
No files matched your search
@@ -13,6 +13,7 @@ __pycache__
|
|||||||
/cache
|
/cache
|
||||||
/*.jar
|
/*.jar
|
||||||
log.txt
|
log.txt
|
||||||
|
/dump.dat
|
||||||
/lock.file
|
/lock.file
|
||||||
settings.json
|
settings.json
|
||||||
/lang/English.json
|
/lang/English.json
|
||||||
|
|||||||
Vendored
+9
-18
@@ -11,24 +11,6 @@
|
|||||||
"program": "${file}",
|
"program": "${file}",
|
||||||
"console": "integratedTerminal"
|
"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)",
|
"name": "Run App (CALL)",
|
||||||
"type": "python",
|
"type": "python",
|
||||||
@@ -38,6 +20,15 @@
|
|||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"justMyCode": false
|
"justMyCode": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Run App (DUMP)",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "main.py",
|
||||||
|
"args": ["--dump"],
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"justMyCode": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Run App (DEBUG+WS)",
|
"name": "Run App (DEBUG+WS)",
|
||||||
"type": "python",
|
"type": "python",
|
||||||
|
|||||||
+3
-2
@@ -23,7 +23,7 @@ if TYPE_CHECKING:
|
|||||||
IS_APPIMAGE = "APPIMAGE" in os.environ and os.path.exists(os.environ["APPIMAGE"])
|
IS_APPIMAGE = "APPIMAGE" in os.environ and os.path.exists(os.environ["APPIMAGE"])
|
||||||
IS_PACKAGED = hasattr(sys, "_MEIPASS") or IS_APPIMAGE
|
IS_PACKAGED = hasattr(sys, "_MEIPASS") or IS_APPIMAGE
|
||||||
# logging special levels
|
# logging special levels
|
||||||
CALL = logging.INFO - 1
|
CALL: int = logging.INFO - 1
|
||||||
logging.addLevelName(CALL, "CALL")
|
logging.addLevelName(CALL, "CALL")
|
||||||
# site-packages venv path changes depending on the system platform
|
# site-packages venv path changes depending on the system platform
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
@@ -94,8 +94,9 @@ SITE_PACKAGES_PATH = Path(VENV_PATH, SYS_SITE_PACKAGES)
|
|||||||
LANG_PATH = _resource_path("lang")
|
LANG_PATH = _resource_path("lang")
|
||||||
# Other Paths
|
# Other Paths
|
||||||
LOG_PATH = Path(WORKING_DIR, "log.txt")
|
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")
|
LOCK_PATH = Path(WORKING_DIR, "lock.file")
|
||||||
|
CACHE_PATH = Path(WORKING_DIR, "cache")
|
||||||
CACHE_DB = Path(CACHE_PATH, "mapping.json")
|
CACHE_DB = Path(CACHE_PATH, "mapping.json")
|
||||||
COOKIES_PATH = Path(WORKING_DIR, "cookies.jar")
|
COOKIES_PATH = Path(WORKING_DIR, "cookies.jar")
|
||||||
SETTINGS_PATH = Path(WORKING_DIR, "settings.json")
|
SETTINGS_PATH = Path(WORKING_DIR, "settings.json")
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ if __name__ == "__main__":
|
|||||||
_debug_gql: bool
|
_debug_gql: bool
|
||||||
log: bool
|
log: bool
|
||||||
tray: bool
|
tray: bool
|
||||||
no_run_check: bool
|
dump: bool
|
||||||
|
|
||||||
# TODO: replace int with union of literal values once typeshed updates
|
# TODO: replace int with union of literal values once typeshed updates
|
||||||
@property
|
@property
|
||||||
@@ -103,6 +103,7 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument("-v", dest="_verbose", action="count", default=0)
|
parser.add_argument("-v", dest="_verbose", action="count", default=0)
|
||||||
parser.add_argument("--tray", action="store_true")
|
parser.add_argument("--tray", action="store_true")
|
||||||
parser.add_argument("--log", action="store_true")
|
parser.add_argument("--log", action="store_true")
|
||||||
|
parser.add_argument("--dump", action="store_true")
|
||||||
# undocumented debug args
|
# undocumented debug args
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--debug-ws", dest="_debug_ws", action="store_true", help=argparse.SUPPRESS
|
"--debug-ws", dest="_debug_ws", action="store_true", help=argparse.SUPPRESS
|
||||||
|
|||||||
+7
-2
@@ -5,15 +5,20 @@
|
|||||||
Available command line arguments:
|
Available command line arguments:
|
||||||
|
|
||||||
• --tray
|
• --tray
|
||||||
Start application as minimised into tray.
|
Start the application as minimised into tray.
|
||||||
• -v
|
• -v
|
||||||
Increase verbosity level. Can be stacked up several times (-vv, -vvv, etc.) to show
|
Increase verbosity level. Can be stacked up several times (-vv, -vvv, etc.) to show
|
||||||
increasingly more information during application runtime.
|
increasingly more information during application runtime.
|
||||||
• --log
|
• --log
|
||||||
Enables logging of runtime information into a 'log.txt' file. Verbosity level of this logging
|
Enables logging of runtime information into a 'log.txt' file. Verbosity level of this logging
|
||||||
matches the level set by `-v`.
|
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
|
• --version
|
||||||
Show application version information
|
Show application version information.
|
||||||
|
|
||||||
Note: Additional settings are available within the application GUI.
|
Note: Additional settings are available within the application GUI.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ class Settings:
|
|||||||
# from args
|
# from args
|
||||||
log: bool
|
log: bool
|
||||||
tray: bool
|
tray: bool
|
||||||
no_run_check: bool
|
dump: bool
|
||||||
# args properties
|
# args properties
|
||||||
debug_ws: int
|
debug_ws: int
|
||||||
debug_gql: int
|
debug_gql: int
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import json
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from time import time
|
from time import time
|
||||||
|
from copy import deepcopy
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from collections import abc, deque, OrderedDict
|
from collections import abc, deque, OrderedDict
|
||||||
@@ -39,6 +40,7 @@ from utils import (
|
|||||||
)
|
)
|
||||||
from constants import (
|
from constants import (
|
||||||
CALL,
|
CALL,
|
||||||
|
DUMP_PATH,
|
||||||
COOKIES_PATH,
|
COOKIES_PATH,
|
||||||
GQL_OPERATIONS,
|
GQL_OPERATIONS,
|
||||||
MAX_CHANNELS,
|
MAX_CHANNELS,
|
||||||
@@ -559,6 +561,10 @@ class Twitch:
|
|||||||
return -1
|
return -1
|
||||||
|
|
||||||
async def run(self):
|
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:
|
while True:
|
||||||
try:
|
try:
|
||||||
await self._run()
|
await self._run()
|
||||||
@@ -599,6 +605,9 @@ class Twitch:
|
|||||||
self.change_state(State.INVENTORY_FETCH)
|
self.change_state(State.INVENTORY_FETCH)
|
||||||
while True:
|
while True:
|
||||||
if self._state is State.IDLE:
|
if self._state is State.IDLE:
|
||||||
|
if self.settings.dump:
|
||||||
|
self.gui.close()
|
||||||
|
continue
|
||||||
self.gui.status.update(_("gui", "status", "idle"))
|
self.gui.status.update(_("gui", "status", "idle"))
|
||||||
self.stop_watching()
|
self.stop_watching()
|
||||||
# clear the flag and wait until it's set again
|
# clear the flag and wait until it's set again
|
||||||
@@ -787,6 +796,9 @@ class Twitch:
|
|||||||
watching_channel,
|
watching_channel,
|
||||||
)
|
)
|
||||||
elif self._state is State.CHANNEL_SWITCH:
|
elif self._state is State.CHANNEL_SWITCH:
|
||||||
|
if self.settings.dump:
|
||||||
|
self.gui.close()
|
||||||
|
continue
|
||||||
self.gui.status.update(_("gui", "status", "switching"))
|
self.gui.status.update(_("gui", "status", "switching"))
|
||||||
# Change into the selected channel, stay in the watching channel,
|
# Change into the selected channel, stay in the watching channel,
|
||||||
# or select a new channel that meets the required conditions
|
# or select a new channel that meets the required conditions
|
||||||
@@ -1412,6 +1424,26 @@ class Twitch:
|
|||||||
chunk_campaigns_data = await chunk_coro
|
chunk_campaigns_data = await chunk_coro
|
||||||
# merge the inventory and campaigns datas together
|
# merge the inventory and campaigns datas together
|
||||||
inventory_data = self._merge_data(inventory_data, chunk_campaigns_data)
|
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
|
# use the merged data to create campaign objects
|
||||||
campaigns: list[DropsCampaign] = [
|
campaigns: list[DropsCampaign] = [
|
||||||
DropsCampaign(self, campaign_data, claimed_benefits)
|
DropsCampaign(self, campaign_data, claimed_benefits)
|
||||||
|
|||||||
Reference in new issue
Block a user