forked from crawl/dcss_tourney
/
teams.py
184 lines (163 loc) · 7.25 KB
/
teams.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#This script assumes the following format:
#A team member should have the following as the first line of her rcfile:
# TEAMCAPTAIN <captain's name>
#The space serves as separator.
#The team captain should have the following as the first line of her rcfile:
# TEAMNAME <team name>
#The space serves as separator, spaces in the team name will be removed.
#Further, the team captain should have the following as the second line of her
#rcfile:
# TEAMMEMBERS <member1> <member2> ...
#A player is considered part of a team, if both she "volunteered" to the team's
#captain by putting the captain's name in her rcfile AND the captain "drafted"
#her by listing her as a member of the team, that she's also named.
import os
import fnmatch
import re
import datetime
import loaddb
import query
import crawl_utils
from query import say_points, get_points, log_temp_clan_points
import banner
import outline
import logging
from loaddb import query_first_col
from logging import debug, info, warn, error
# Register listener and timer.
class TeamListener (loaddb.CrawlEventListener):
def cleanup(self, db):
cursor = db.cursor()
try:
insert_teams(cursor, get_teams(loaddb.CRAWLRC_DIRECTORY_LIST))
update_clan_scores(cursor)
finally:
cursor.close()
class TeamTimer (loaddb.CrawlTimerListener):
def run(self, cursor, elapsed):
insert_teams(cursor, get_teams(loaddb.CRAWLRC_DIRECTORY_LIST))
update_clan_scores(cursor)
LISTENER = [ TeamListener() ]
# Run the timer every so often to refresh team stats.
TIMER = [ ( crawl_utils.UPDATE_INTERVAL , TeamTimer() ) ]
DEADLINE = loaddb.CLAN_DEADLINE
def get_teams(directory_list):
'''Searches all *.rc files in the given directories for team information
and returns a dictorary, indexed by team captains, of tuples of
the team name and the set of members. If there are multiple .rc files belonging to the same player with team information, use the first one.'''
existing_directory_list = [directory for directory in directory_list if os.path.exists(directory)]
if len(existing_directory_list) == 0:
return { }
teams = {}
teamname = {}
draftees = {}
volunteers = {}
players = []
for directory in existing_directory_list:
for filename in os.listdir(directory):
if fnmatch.fnmatch(filename, '*.rc'):
player = filename[:-3].lower()
if player in players:
continue
rcfile = open(os.path.join(directory, filename))
line = rcfile.readline()
offset = line.find('TEAM')
if offset != -1:
elements = re.sub('[^\w -]', '', line[offset:]).split(' ')
if elements[0] == 'TEAMCAPTAIN':
players.append(player)
if len(elements) < 2:
elements.append(player)
volunteers.setdefault(elements[1].lower(), []).append(player)
line = rcfile.readline()
offset = line.find('TEAM')
elements = re.sub('[^\w -]', '', line[offset:]).split(' ')
elif elements[0] == 'TEAMNAME':
players.append(player)
teamname[player] = ''.join(elements[1:]) or ('Team_' + player)
volunteers.setdefault(player, []).append(player)
line = rcfile.readline()
offset = line.find('TEAM')
elements = re.sub('[^\w -]', '', line[offset:]).split(' ')
if elements[0] == 'TEAMMEMBERS':
draftedones = [name.lower() for name in elements[1:7]]
if player in draftedones:
draftees[player] = draftedones
else:
draftees[player] = draftedones[:5]
draftees[player].append(player)
else:
draftees[player] = [player]
rcfile.close()
for captain in teamname.iterkeys():
vset = set(volunteers.get(captain, []))
dset = set(draftees.get(captain, []))
members = vset.intersection(dset)
# for name in members:
# players.remove(name)
teams[captain] = (teamname[captain], members)
# for name in players:
# teams[name] = ('Team_' + name, set([name]))
return teams
def insert_teams(cursor, teams):
now = datetime.datetime.utcnow()
if (now < DEADLINE):
info("Updating team information.")
query.drop_teams(cursor)
for captain in teams.iterkeys():
loaddb.check_add_player(cursor, captain)
canon_cap = query.canonicalize_player_name(cursor, captain)
if canon_cap:
query.create_team(cursor, teams[captain][0], canon_cap)
for player in teams[captain][1]:
query.add_player_to_team(cursor, canon_cap, player)
else:
info("Team information frozen.")
# Team scoring. Putting it here because this we know the teams have
# been created in the db at this point.
def clan_additional_score(c, owner):
additional = 0
query.audit_flush_clan(c, owner)
combo_pos = query.clan_combo_pos(c, owner)
additional += log_temp_clan_points( c, owner,
'clan_combo_scores_Nth:%d' % (combo_pos + 1),
get_points(
combo_pos,
200, 100, 50 ) )
uscore_pos = query.clan_unique_pos(c, owner)
additional += log_temp_clan_points( c, owner,
'clan_top_unique_killer:%d' % (uscore_pos + 1),
get_points(
uscore_pos,
100, 50, 20 ) )
zig_depth = int((query.clan_zig_depth(c, owner) + 1)/2)
additional += log_temp_clan_points( c, owner,
'zig_dive:%d' % zig_depth,
5 * zig_depth)
# Now we give race/class points to clans.
for g in query.clan_race_wins(c, owner):
key = 'species_win:' + g[0]
points = query.clan_max_points(c, owner, key)
additional += log_temp_clan_points(c, owner, key, points)
for g in query.clan_class_wins(c, owner):
key = 'class_win:' + g[0]
points = query.clan_max_points(c, owner, key)
additional += log_temp_clan_points(c, owner, key, points)
for g in query.clan_god_wins(c, owner):
banner_god = g[0].lower().replace(' ', '_')
key = 'god_win:' + banner_god
points = query.clan_max_points(c, owner, key)
additional += log_temp_clan_points(c, owner, key, points)
query.set_clan_points(c, owner, additional)
# A clan-based banner.
for player in query.get_saints(c, owner):
banner.award_banner(c, player, 'beogh', 1, temp=True)
def update_clan_scores(c):
banner.flush_clan_banners(c)
for clan in query.get_clans(c):
info("Updating full score for clan %s" % clan)
clan_additional_score(c, clan)
banner.assign_top_clan_banners(c)
top_clan_player_banners = query.clan_player_banners(c)
for banner_name, prestige, player in top_clan_player_banners:
banner.award_banner(c, player, banner_name, prestige, temp=True)