-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate_frontend_doc.py
149 lines (131 loc) · 6.35 KB
/
generate_frontend_doc.py
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"""
Generates files to build the frontend.
"""
import json
from backend.aggregator import get_all_scores, get_card_color_identities
from backend.database import MongoDatabase
from backend.moxfield import MoxfieldDeckSource
from backend.archidekt import ArchidektDeckSource
from backend.prices import save_price_dictionary
from backend.utils import normalize_cardnames
from backend.update import perform_update, get_latest_bulk_file
import tqdm
if __name__ == '__main__':
# Create a connection to the database
with open('server-token.json') as server_token_file:
connection_string = json.load(server_token_file)['connection']
database = MongoDatabase(connection_string)
sources = [ArchidektDeckSource(), MoxfieldDeckSource()]
# Commit updates to the database
print('Updating database')
perform_update(database, sources)
# Load all cards from bulk json in database
bulk_filepath = get_latest_bulk_file(directory='scryfall_data')
with open(bulk_filepath, 'r') as bulk_file:
all_card_data = json.load(bulk_file)
# Create lookup of card images by name, alongside sets of lands and DFCs
image_lookup = {}
image_pipeline = [{'$match': {'$or': [{'legal_in_mainboard': True},
{'legal_as_commander': True}]}},
{'$project': {'_id': 0, 'image_urls': 1, 'name': 1}}]
for card in database.cards.aggregate(image_pipeline):
image_lookup[card['name']] = card['image_urls']
lands = set()
double_faced = set()
for card in tqdm.tqdm(all_card_data):
if 'type_line' not in card:
continue
if 'Land' in card['type_line']:
lands.add(card['name'])
# Skip tokens
if 'set_type' in card and card['set_type'] == 'token':
continue
# Double-faced cards
if 'image_uris' not in card and 'card_faces' in card:
double_faced.add(card['name'])
# Generate a list of the commanders / commander pairs, along with their
# image urls and cleaned names
commander_pipeline = [{'$match': {'isLegal': True}},
{'$project': {'_id': 0, 'commanders': 1}}]
commanders_list = {tuple(deck['commanders'])
for deck in database.decks.aggregate(commander_pipeline)}
# Ensure commanders are unique (sort pairs)
commanders_list = list(set(tuple(sorted(commanders))
for commanders in commanders_list))
# Store all updated commander data
commander_data = []
# Record commander names and image URLs
for commanders in tqdm.tqdm(commanders_list):
urls = []
for card in commanders:
urls.extend(database.cards.find_one({'name': card})['image_urls'])
commander_data.append({'commanders': commanders, 'urls': urls})
# Record all other commander statistics
all_synergy_scores, popularity_scores, commander_counts, \
color_popularity, commander_card_counts = get_all_scores(database)
# Get color identities for commander filtering by color
card_color_identities = get_card_color_identities(database)
processed = 0 # Number of commanders processed
commander_names = []
for commander in tqdm.tqdm(commander_data):
tqdm.tqdm.write(f'Updating: {commander}')
# Store commander name
commander_names.append(" ".join(commander['commanders']))
# Store count of decks with commander
commander['count'] = commander_counts[tuple(commander['commanders'])]
# Store synergy scores
commander['carddata'] = []
synergy_scores = all_synergy_scores[tuple(commander['commanders'])]
for card in synergy_scores:
if card in image_lookup:
card_image = image_lookup[card]
else:
raise Exception(f'{card} not in image_lookup')
card_popularity = commander_card_counts[tuple(commander[
'commanders'])][
card]
card_info = [card, synergy_scores[card], card_image,
card_popularity]
commander['carddata'].append(card_info)
# Sort cards by decreasing synergy scores
commander['carddata'].sort(key=lambda info: -info[1])
if len(commander['commanders']) == 1:
commander['coloridentity'] = card_color_identities[commander[
'commanders'][0]]
else:
commander['coloridentity'] = "".join(sorted(set(
card_color_identities[commander['commanders'][0]] +
card_color_identities[commander['commanders'][1]])))
# Parse commanders and commanderstring (for database use)
# Double faced commanders separated by '--'
if (len(commander['commanders']) == 1
and commander['commanders'][0] in double_faced): # Handle DFCs
print(commander['commanders'][0])
commander['urls'] = image_lookup[commander['commanders'][0]]
commander['commanders'] = commander['commanders'][0].split(" // ")
commander['commanderstring'] = \
"--".join(normalize_cardnames(commander['commanders']))
else:
commander['commanderstring'] = \
"-".join(sorted(normalize_cardnames(commander['commanders'])))
# Update user on processing status
tqdm.tqdm.write(commander['commanderstring'])
processed += 1
tqdm.tqdm.write(f"{processed} / {len(commander_data)}")
# Save commander names to file
with open('frontend/commandernames.json', 'w') as commandernames_file:
json.dump(commander_names, commandernames_file)
# Sort commanders by decreasing count and save to file
commander_data.sort(key=lambda commander: -commander['count'])
with open('frontend/_data/commanders.json', 'w') as commanders_file:
json.dump(commander_data, commanders_file)
# Store color popularity (staple) information
staples = []
for card in color_popularity:
if card not in lands: # Skip lands
staples.append([card, color_popularity[card][0],
image_lookup[card], color_popularity[card][1]])
# Save color popularity to file
with open('frontend/_data/staples.json', 'w') as staples_file:
json.dump(staples, staples_file)
save_price_dictionary("frontend/_data/prices.json")