Skip to content

Commit

Permalink
Merge pull request #41 from unrealities/0325
Browse files Browse the repository at this point in the history
v3.25
  • Loading branch information
unrealities authored Jul 20, 2024
2 parents dde56a3 + e1a720b commit 7b96771
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 24 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Magic: The Gathering Arena draft tool that utilizes 17Lands data.
- This step isn't necessary if the application is installed in the main directory of a drive (i.e., `C:/` or `D:/`) or the `Users/<Username>/` directory
- **Step 4:** In Arena, go to Adjust Options, Account, and then check the Detailed Logs (Plugin Support) check box.
- **Step 5:** Double-click `MTGA_Draft_Tool.exe` to start the program.
- **Step 6:** Download the sets you plan to use (`Data->Add Sets`).
- **Step 6:** Download the sets you plan to use (`Data->Download Dataset`).
Event datasets can be used for different events (e.g., the premier draft dataset can be used for a sealed event).
- Quick draft players should consider using the premier draft dataset when quick draft initially becomes available.
- **Step 7:** Configure the tool through the [Settings window](#settings).
Expand Down Expand Up @@ -69,7 +69,7 @@ Magic: The Gathering Arena draft tool that utilizes 17Lands data.
- **Bottles (Linux):** /home/{username}/.var/app/com.usebottles.bottles/data/bottles/bottles/MTG-Arena/drive_c/users/{username}/AppData/LocalLow/Wizards Of The Coast/MTGA/Player.log
- **Lutris (Linux):** /home/{username}/Games/magic-the-gathering-arena/drive_c/users/{username}/AppData/LocalLow/Wizards Of The Coast/MTGA/Player.log
- **Step 10:** (Mac Only) Set Arena to window mode.
- **Step 11:** Download the sets you plan to use (`Data->Add Sets`).
- **Step 11:** Download the sets you plan to use (`Data->Download Dataset`).
- Event datasets can be used for different events (e.g., the premier draft dataset can be used for a sealed event).
- Select `Arena Cube` and adjust the start date to download the data from the most recent Arena Cube event.
- Quick draft players should consider using the premier draft dataset when quick draft initially becomes available.
Expand Down Expand Up @@ -127,7 +127,7 @@ Magic: The Gathering Arena draft tool that utilizes 17Lands data.
![Settings_Colors](https://github.com/unrealities/MTGA_Draft_17Lands/blob/main/assets/96687942/90c6b3df-0ade-4f32-a1be-b2ef40cedc32.png)

- **Read Draft Logs:** Read the log file from a draft by selecting `File->Open`. Select a file that has the following naming scheme `DraftLog_<Set>_<Draft Type>_<Draft_ID>.log` file to read the file.
- **Download Set Data:** Open the Add Sets window by selecting `Data->Add Sets`. Enter the set information and click the ADD SET button to begin downloading the set data.
- **Download Set Data:** Open the Download Dataset window by selecting `Data->Download Dataset`. Enter the set information and click the ADD SET button to begin downloading the set data.
- The download can take several minutes.
- 17Lands will timeout the request if too many requests are made within a short period.
- **List Taken Cards:** Get to the Taken Cards window by selecting `Cards->Taken Cards`.
Expand Down
4 changes: 2 additions & 2 deletions builder/Installer.iss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; -- MtgaDraft.iss --
[Setup]
AppName=MTGA Draft Tool
AppVersion=3.24
AppVersion=3.25
WizardStyle=modern
DefaultDirName={sd}\MtgaDraftTool
DefaultGroupName=MtgaDraftTool
Expand All @@ -11,7 +11,7 @@ Compression=lzma2
UsePreviousAppDir=yes
SolidCompression=yes
OutputDir={app}
OutputBaseFilename=MTGA_Draft_Tool_V0324
OutputBaseFilename=MTGA_Draft_Tool_V0325
InfoAfterFile=..\release_notes.txt
[Files]
Source: "..\dist\MTGA_Draft_Tool.exe"; DestDir: "{app}"
Expand Down
3 changes: 3 additions & 0 deletions release_notes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
===================== RELEASE NOTES 3.25 =====================
* FiYir released feature: Dataset Pre-Download Check #38

===================== RELEASE NOTES 3.24 =====================
* FiYir released feature: Card Popup Archetype Stats #32: Add archetype stats to card popup window

Expand Down
2 changes: 2 additions & 0 deletions src/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@
SCRYFALL_REQUEST_BACKOFF_DELAY_SECONDS = 5
SCRYFALL_REQUEST_ATTEMPT_MAX = 5

DATASET_DOWNLOAD_RATE_LIMIT_SEC = 60

PLATFORM_ID_OSX = "darwin"
PLATFORM_ID_WINDOWS = "win32"
PLATFORM_ID_LINUX = "linux"
Expand Down
12 changes: 10 additions & 2 deletions src/file_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,8 @@ def _assemble_set(self, matching_only):

def retrieve_17lands_color_ratings(self):
'''Use 17Lands endpoint to collect the data from the color_ratings page'''
result = True
game_count = 0
try:
if self.user_group == constants.LIMITED_USER_GROUP_ALL:
user_group = ""
Expand All @@ -771,11 +773,13 @@ def retrieve_17lands_color_ratings(self):
url_data = urllib.request.urlopen(url, context=self.context).read()

color_json_data = json.loads(url_data)
self._process_17lands_color_ratings(color_json_data)
game_count = self._process_17lands_color_ratings(color_json_data)

except Exception as error:
result = False
logger.error(url)
logger.error(error)
return result, game_count

def _process_17lands_data(self, colors, cards):
'''Parse the 17Lands json data to extract the card ratings'''
Expand Down Expand Up @@ -847,7 +851,7 @@ def _process_17lands_color_ratings(self, colors):
"(RGW)": "RGW",
"(GWU)": "GWU",
}

game_count = 0
try:
self.combined_data["color_ratings"] = {}
for color in colors:
Expand All @@ -866,9 +870,13 @@ def _process_17lands_color_ratings(self, colors):

if processed_colors not in self.combined_data["color_ratings"]:
self.combined_data["color_ratings"][processed_colors] = winrate
elif color["is_summary"] and color["color_name"] == "All Decks":
game_count = color["games"] if color["games"] else 0
self.combined_data["meta"]["game_count"] = game_count

except Exception as error:
logger.error(error)
return game_count

def _process_scryfall_data(self, data):
'''Parse json data from the Scryfall API to extract pertinent card data'''
Expand Down
82 changes: 71 additions & 11 deletions src/overlay.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import tkinter
from tkinter.ttk import Progressbar, Treeview, Style, OptionMenu, Button, Checkbutton, Label, Separator, Entry
from tkinter import filedialog, messagebox, font
from datetime import date
from datetime import date, datetime, UTC
import urllib
import sys
import io
Expand Down Expand Up @@ -40,7 +40,7 @@
except ImportError:
pass

APPLICATION_VERSION = 3.24
APPLICATION_VERSION = 3.25

HOTKEY_CTRL_G = '\x07'

Expand Down Expand Up @@ -419,6 +419,7 @@ def __init__(self, args):
self.root.title(f"Version {APPLICATION_VERSION:2.2f}")
self.configuration, _ = read_configuration()
self.root.resizable(False, False)
self.last_download = 0

self.__set_os_configuration()

Expand Down Expand Up @@ -464,7 +465,7 @@ def __init__(self, args):
self.filemenu.add_command(label="Open", command=self.__open_draft_log)
self.datamenu = tkinter.Menu(self.menubar, tearoff=0)
self.datamenu.add_command(
label="Add Sets", command=self.__open_set_view_window)
label="Download Dataset", command=self.__open_set_view_window)

self.cardmenu = tkinter.Menu(self.menubar, tearoff=0)
self.cardmenu.add_command(
Expand Down Expand Up @@ -1796,7 +1797,7 @@ def __open_set_view_window(self):
return

popup = tkinter.Toplevel()
popup.wm_title("Add Sets")
popup.wm_title("Download Dataset")
popup.protocol("WM_DELETE_WINDOW",
lambda window=popup: self.__close_set_view_window(window))
popup.resizable(width=False, height=True)
Expand Down Expand Up @@ -1905,7 +1906,7 @@ def __open_set_view_window(self):
list_box,
sets,
status_text,
constants.DATA_SET_VERSION_3), text="ADD SET")
constants.DATA_SET_VERSION_3), text="DOWNLOAD")

event_separator = Separator(popup, orient='vertical')
set_separator = Separator(popup, orient='vertical')
Expand Down Expand Up @@ -2820,15 +2821,27 @@ def __open_about_window(self):
logger.error(error)

def __add_set(self, popup, draft_set, draft, start, end, user_group, button, progress, list_box, sets, status, version):
'''Initiates the set download process when the Add Set button is clicked'''
'''Initiates the set download process when the Download Dataset button is clicked'''
result = True
result_string = ""
return_size = 0
current_time = datetime.now().timestamp()
while True:
try:
message_box = tkinter.messagebox.askyesno(
title="Download", message=f"17Lands updates their card data once a day at 03:00 UTC.\n\nAre you sure that you want to download the {draft_set.get()} {draft.get()} dataset?")
if not message_box:
time_difference = current_time - self.last_download
if time_difference >= constants.DATASET_DOWNLOAD_RATE_LIMIT_SEC:
message_box = tkinter.messagebox.askyesno(
title="Download",
message=f"Are you sure that you want to download the {draft_set.get()} {draft.get()} dataset?"
)
if not message_box:
break
else:
message_box = tkinter.messagebox.showinfo(
title="Download",
message="Rate limit reached.\n\n"
f"Please wait {int(constants.DATASET_DOWNLOAD_RATE_LIMIT_SEC - time_difference)} seconds before trying again."
)
break

status.set("Starting Download Process")
Expand All @@ -2848,8 +2861,55 @@ def __add_set(self, popup, draft_set, draft, start, end, user_group, button, pro
break
self.extractor.set_user_group(user_group.get())
self.extractor.set_version(version)

set_codes = [v.seventeenlands[0] for v in sets.values()]
file_list, error_list = retrieve_local_set_list(set_codes)

# Log all of errors generated by retrieve_local_set_list
for error_string in error_list:
logger.error(error_string)

self.last_download = current_time

status.set("Downloading Color Ratings")
self.extractor.retrieve_17lands_color_ratings()
result, game_count = self.extractor.retrieve_17lands_color_ratings()

if result and file_list:
if game_count == 0:
message_box = tkinter.messagebox.askyesno(
title="Download",
message=f"17Lands doesn't have data for {draft_set.get()} {draft.get()} {start.get()} to {end.get()}.\n\n"
"Would you still like to continue with the download?"
)
if not message_box:
status.set("Download Cancelled")
break
else:
notify = False
set_code = sets[draft_set.get()].seventeenlands[0]
for file in file_list:
if(
set_code == file[0] and
draft.get() == file[1] and
user_group.get() == file[2] and
start.get() == file[3] and
(end.get() == file[4] or end.get() > file[4]) and
game_count == file[6]
):
notify = True
break

if notify:
current_time_utc = datetime.now(UTC).strftime('%H:%M:%S')
message_box = tkinter.messagebox.askyesno(
title="Download",
message="Your dataset is already up-to-date.\n\n"
f"It's currently {current_time_utc} UTC, and 17Lands updates their card data once a day around 03:00:00 UTC.\n\n"
"Would you still like to continue with the download?"
)
if not message_box:
status.set("Download Cancelled")
break

result, result_string, temp_size = self.extractor.download_card_data(
popup, progress, status, self.configuration.card_data.database_size)
Expand All @@ -2862,7 +2922,6 @@ def __add_set(self, popup, draft_set, draft, start, end, user_group, button, pro
result_string = "File Write Failure"
break
progress['value'] = 100
button['state'] = 'normal'
return_size = temp_size
popup.update()
status.set("Updating Set List")
Expand All @@ -2886,6 +2945,7 @@ def __add_set(self, popup, draft_set, draft, start, end, user_group, button, pro
message_box = tkinter.messagebox.showwarning(
title="Error", message=message_string)
else:
button['state'] = 'normal'
self.configuration.card_data.database_size = return_size
write_configuration(self.configuration)
popup.update()
Expand Down
9 changes: 8 additions & 1 deletion src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,20 @@ def retrieve_local_set_list(codes, names = None):
else:
start_date = json_data["meta"]["start_date"]
end_date = json_data["meta"]["end_date"]

if "game_count" in json_data["meta"]:
game_count = json_data["meta"]["game_count"]
else:
game_count = 0

file_list.append((
set_name,
event_type,
user_group,
start_date,
end_date,
file_location
file_location,
game_count
))
except Exception as error:
error_list.append(error)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_app_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def invalid_input_url():

@pytest.fixture
def valid_input_url_zip():
return "https://github.com/unrealities/MTGA_Draft_17Lands/releases/download/MTGA_Draft_Tool_V0323/MTGA_Draft_Tool_V0323.zip"
return "https://github.com/unrealities/MTGA_Draft_17Lands/releases/download/MTGA_Draft_Tool_V0324/MTGA_Draft_Tool_V0324.zip"

@pytest.fixture
def output_filename():
Expand Down
8 changes: 4 additions & 4 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
"OTJ_FakeDraft_All_Data.json",
]
MOCKED_DATASETS_LIST_VALID = [
("MH3", "PremierDraft", "All", "2019-01-01", "2024-07-11", os.path.join(SETS_FOLDER, "MH3_PremierDraft_All_Data.json")),
("MH3", "PremierDraft", "Top", "2019-01-01", "2024-07-11", os.path.join(SETS_FOLDER, "MH3_PremierDraft_Top_Data.json")),
("OTJ", "TradDraft", "Middle", "2019-01-01", "2024-07-11", os.path.join(SETS_FOLDER, "OTJ_TradDraft_Middle_Data.json")),
("OTJ", "QuickDraft", "Bottom", "2019-01-01", "2024-07-11", os.path.join(SETS_FOLDER, "OTJ_QuickDraft_Bottom_Data.json"))
("MH3", "PremierDraft", "All", "2019-01-01", "2024-07-11", os.path.join(SETS_FOLDER, "MH3_PremierDraft_All_Data.json"), 0),
("MH3", "PremierDraft", "Top", "2019-01-01", "2024-07-11", os.path.join(SETS_FOLDER, "MH3_PremierDraft_Top_Data.json"), 0),
("OTJ", "TradDraft", "Middle", "2019-01-01", "2024-07-11", os.path.join(SETS_FOLDER, "OTJ_TradDraft_Middle_Data.json"), 0),
("OTJ", "QuickDraft", "Bottom", "2019-01-01", "2024-07-11", os.path.join(SETS_FOLDER, "OTJ_QuickDraft_Bottom_Data.json"), 0)
]
MOCKED_DATASET_JSON = {
"meta" : {
Expand Down

0 comments on commit 7b96771

Please sign in to comment.