-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimport.py
138 lines (110 loc) · 4.02 KB
/
import.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
import argparse
import asyncio
import os
import duckdb
from dotenv import load_dotenv
from rich.console import Console
from rich.table import Table
from Entities.Character import Character
from Services.BattleNet import BattleNet
def format_name(name: str) -> str:
return name.lower().replace(" ", "-").replace("'", '')
async def get_characters(service: BattleNet, realm: str, guild: str) -> list[Character] | None:
formatted_realm = format_name(realm)
formatted_guild = format_name(guild)
guild_data = await service.get_guild_data(formatted_realm, formatted_guild)
tasks = [
service.get_character_data(formatted_realm, char['character']['name'].lower())
for char in guild_data['members']
]
characters: list[Character] = [Character.from_nested_data(data) for data in
await asyncio.gather(*tasks, return_exceptions=True)
if not isinstance(data, Exception)]
return characters
def insert_character_data(con, character: Character):
con.execute("""
INSERT INTO characters (
id, race, gender, character_class, faction, level,
active_spec, realm, guild, achievement_points,
equipped_item_level, average_item_level
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT (id)
DO UPDATE SET
character_class = EXCLUDED.character_class
""", (character.id, character.race, character.gender, character.character_class,
character.faction, character.level, character.active_spec, character.realm,
character.guild, character.achievement_points, character.equipped_item_level,
character.average_item_level))
def create_table(con):
con.execute("""
CREATE TABLE IF NOT EXISTS characters (
id INTEGER PRIMARY KEY,
name TEXT,
race TEXT,
gender TEXT,
character_class TEXT,
faction TEXT,
level INTEGER,
active_spec TEXT,
realm TEXT,
guild TEXT,
achievement_points INTEGER,
equipped_item_level INTEGER,
average_item_level INTEGER
)
""")
def display_characters(characters):
console = Console()
table = Table(show_header=True, header_style="bold magenta")
table.add_column("Name")
table.add_column("Race")
table.add_column("Class")
table.add_column("Faction")
table.add_column("Level")
table.add_column("Spec")
table.add_column("Realm")
table.add_column("Guild")
for char in characters:
table.add_row(
char.name,
char.race,
char.character_class,
char.faction,
str(char.level),
char.active_spec,
char.realm,
char.guild
)
console.print(table)
async def main(arguments: argparse.Namespace):
load_dotenv()
# Access the variables and check if they are set
client_id = os.environ.get('CLIENT_ID')
client_secret = os.environ.get('CLIENT_SECRET')
con = duckdb.connect('characters.duckdb')
create_table(con)
if not client_id or not client_secret:
print("Error: CLIENT_ID and CLIENT_SECRET must be set")
else:
try:
service = await BattleNet.create(client_id, client_secret)
characters = await get_characters(service, arguments.realm, arguments.guild)
if characters:
for char in characters:
insert_character_data(con, char)
con.commit()
display_characters(characters)
except ValueError as e:
print(e)
finally:
if service is not None:
await service.close()
con.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Fetch character information for a given realm and guild.'
)
parser.add_argument('realm', type=str, help='The realm name.')
parser.add_argument('guild', type=str, help='The guild name.')
args = parser.parse_args()
asyncio.run(main(args))