-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathev-tracker.py
executable file
·249 lines (186 loc) · 7.48 KB
/
ev-tracker.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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/usr/local/bin/python
# coding=utf-8
import os
import argparse
import json
from shutil import copyfile
from pokemon import Pokemon, EvSet
import pokedex
TRACKER_FILENAME = '.ev-tracker'
TRACKER_PATH = os.path.expanduser(os.path.join('~', TRACKER_FILENAME))
class Tracker(object):
@classmethod
def from_json(cls, filename):
tracker = cls()
tracker.filename = filename
try:
fp = open(filename, 'r')
data = json.load(fp)
for spec in data['pokemon']:
pokemon = Pokemon.from_dict(spec)
tracker.track(pokemon)
if 'active' in data and int(data['active']) == pokemon.id:
tracker.active = pokemon
except IOError:
pass # Ignore missing tracking file.
return tracker
@staticmethod
def to_json(tracker, filename=None):
filename = tracker.filename if filename is None else filename
fp = open(filename, 'w')
data = {}
if tracker.has_active():
data['active'] = tracker.active.id
data['pokemon'] = [pokemon.to_dict() for pokemon in tracker.pokemon.values()]
json.dump(data, fp)
fp.close()
pokemon = {}
def __init__(self):
self._active = None
self.counter = 1
active = property(lambda self: self.get_active(),
lambda self, pokemon: self.set_active(pokemon))
def has_active(self):
return self._active is not None
def get_active(self):
if self._active is None:
raise NoActivePokemon()
return self._active
def set_active(self, pokemon):
self._active = pokemon
def get_pokemon(self, id):
if id not in self.pokemon:
raise NoTrackedPokemon(id)
return self.pokemon[id]
def unique_id(self):
while self.counter in self.pokemon:
self.counter += 1
return self.counter
def track(self, pokemon):
self.pokemon[pokemon.id] = pokemon
def untrack(self, pokemon):
del self.pokemon[pokemon.id]
pokemon.id = None
if self._active is pokemon:
self._active = None
def __str__(self):
if len(self.pokemon):
return '\n'.join([pokemon.listing(self._active) for pokemon in self.pokemon.values()])
else:
return 'No tracked Pokemon'
class NoActivePokemon(Exception):
"""
Raised when an operation that assumes the existence of an active Pokemon
is carried out.
"""
pass
class NoTrackedPokemon(Exception):
"""
Raised when an id is requested from a Tracker but the Tracker does not
have a Pokemon with the provided id.
"""
def __init__(self, id):
super(NoTrackedPokemon, self).__init__()
self.id = id
_tracker = None
def _save_tracker():
if os.path.exists(_tracker.filename):
copyfile(_tracker.filename, _tracker.filename + '.bak') # Create backup
Tracker.to_json(_tracker)
def _cmd_ev(args):
print pokedex.search(args.species)
def _cmd_list(args):
print _tracker
def _cmd_track(args):
species = pokedex.search(args.species)
pokemon = Pokemon(id=_tracker.unique_id(), species=species,
name=args.name, item=args.item, pokerus=args.pokerus)
_tracker.track(pokemon)
print pokemon
_save_tracker()
def _cmd_active(args):
if args.switch:
_tracker.active = _tracker.get_pokemon(args.switch)
_save_tracker()
print _tracker.active
def _cmd_status(args):
if args.id is None:
pokemon = _tracker.active
else:
pokemon = _tracker.get_pokemon(args.id)
print pokemon.status()
def _cmd_update(args):
raise NotImplementedError('update command is not yet implemented.')
def _cmd_battle(args):
species = pokedex.search(args.species)
if args.id is None:
pokemon = _tracker.active
else:
pokemon = _tracker.get_pokemon(args.id)
pokemon.battle(species)
print evs
print pokemon
def _cmd_release(args):
pokemon = _tracker.get_pokemon(args.id)
_tracker.untrack(pokemon)
print 'No longer tracking %s' % pokemon
_save_tracker()
def _build_parser():
parser = argparse.ArgumentParser(prog='ev',
description='''
A small utility for keeping
track of Effort Values while
training Pokemon.
''')
parser.add_argument('--infile', '-i',
dest='filename',
default=TRACKER_PATH,
help='''
Optional location of the file to save tracking
information to. This defaults to %s in your
home directory
''' % TRACKER_FILENAME)
subparsers = parser.add_subparsers()
ev_parser = subparsers.add_parser('ev', help='List Effort Values for a Pokemon')
ev_parser.add_argument('species', help='Name or number of Pokemon species to search for')
ev_parser.set_defaults(func=_cmd_ev)
list_parser = subparsers.add_parser('list', help='List tracked Pokemon')
list_parser.set_defaults(func=_cmd_list)
track_parser = subparsers.add_parser('track', help='Add a Pokemon to track')
track_parser.add_argument('species', help='Name of number of Pokemon species to track')
track_parser.add_argument('--name', '-n', help='Nickname of Pokemon')
track_parser.add_argument('--pokerus', '-p', action='store_true', default=False, help='Indicates the given Pokemon has Pokerus')
track_parser.add_argument('--item', '-i')
track_parser.set_defaults(func=_cmd_track)
active_parser = subparsers.add_parser('active', help='List the active Pokemon')
active_parser.add_argument('--switch', '-s', type=int, help='Switch the active Pokemon')
active_parser.set_defaults(func=_cmd_active)
status_parser = subparsers.add_parser('status', help='Show the status of the active Pokemon')
status_parser.add_argument('--id', '-i', type=int)
status_parser.set_defaults(func=_cmd_status)
update_parser = subparsers.add_parser('update', help='Update a tracked Pokemon\'s details')
update_parser.set_defaults(func=_cmd_update)
battle_parser = subparsers.add_parser('battle', help='Record a battle for a tracked Pokemon')
battle_parser.add_argument('species', help='Name of number of Pokemon species to battle')
battle_parser.add_argument('--id', '-i', type=int)
battle_parser.set_defaults(func=_cmd_battle)
release_parser = subparsers.add_parser('release', help='Stop tracking a Pokemon')
release_parser.add_argument('id', type=int)
release_parser.set_defaults(func=_cmd_release)
return parser
if __name__ == '__main__':
try:
args = _build_parser().parse_args()
_tracker = Tracker.from_json(args.filename)
args.func(args)
except pokedex.NoSuchSpecies as e:
print "No match found for '%s'." % e.identifier
if isinstance(e, pokedex.AmbiguousSpecies):
print "Did you mean:"
for match in e.matches:
print " %s" % match
except NoActivePokemon:
print "No tracked Pokemon is marked as active."
print "Set an active pokemon using the 'active --switch' command."
except NoTrackedPokemon as e:
print "No tracked Pokemon with id '%d' was found." % e.id