3 # mEveMon - A character monitor for EVE Online
4 # Copyright (c) 2010 Ryan and Danny Campbell, and the mEveMon Team
6 # mEveMon is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # mEveMon is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 from eveapi import eveapi
30 #conic is used for connection handling
32 #import socket for handling socket exceptions
35 # we will store our preferences in gconf
38 #ugly hack to check maemo version. any better way?
39 if hasattr(hildon, "StackableWindow"):
40 from ui.fremantle import gui
42 from ui.diablo import gui
46 The controller class for mEvemon. The intent is to help
47 abstract the EVE API and settings code from the UI code.
51 GCONF_DIR = "/apps/maemo/mevemon"
54 self.program = hildon.Program()
55 self.program.__init__()
56 self.gconf = gnome.gconf.client_get_default()
57 #NOTE: remove this after a few releases
58 self.update_settings()
59 self.connect_to_network()
60 self.cached_api = eveapi.EVEAPIConnection( cacheHandler = \
61 apicache.cache_handler(debug=False))
62 self.gui = gui.mEveMonUI(self)
67 def quit(self, *args):
70 def update_settings(self):
72 Update from the old pre 0.3 settings to the new settings layout.
73 We should remove this eventually, once no one is using pre-0.3 mEveMon
75 uid = self.gconf.get_string("%s/eve_uid" % self.GCONF_DIR)
78 key = self.gconf.get_string("%s/eve_api_key" % self.GCONF_DIR)
79 self.add_account(uid, key)
80 self.gconf.unset("%s/eve_uid" % self.GCONF_DIR)
81 self.gconf.unset("%s/eve_api_key" % self.GCONF_DIR)
84 def get_accounts(self):
86 Returns a dictionary containing uid:api_key pairs gathered from gconf
89 entries = self.gconf.all_entries("%s/accounts" % self.GCONF_DIR)
92 key = os.path.basename(entry.get_key())
93 value = entry.get_value().to_string()
98 def get_api_key(self, uid):
100 Returns the api key associated with the given uid.
102 return self.gconf.get_string("%s/accounts/%s" % (self.GCONF_DIR, uid)) or ''
104 def remove_account(self, uid):
106 Removes the provided uid key from gconf
108 self.gconf.unset("%s/accounts/%s" % (self.GCONF_DIR, uid))
110 def add_account(self, uid, api_key):
112 Adds the provided uid:api_key pair to gconf.
114 self.gconf.set_string("%s/accounts/%s" % (self.GCONF_DIR, uid), api_key)
116 def get_auth(self, uid):
118 Returns an authentication object to be used for eveapi calls
119 that require authentication.
121 api_key = self.get_api_key(uid)
124 auth = self.cached_api.auth(userID=uid, apiKey=api_key)
126 traceback.print_exc()
131 def get_char_sheet(self, uid, char_id):
133 Returns an object containing information about the character specified
134 by the provided character ID.
137 sheet = self.get_auth(uid).character(char_id).CharacterSheet()
139 # TODO: we should really have a logger that logs this error somewhere
140 traceback.print_exc()
145 def charid2uid(self, char_id):
147 Takes a character ID and returns the user ID of the account containing
150 Returns None if the character isn't found in any of the registered accounts.
153 acct_dict = self.get_accounts()
155 for uid, api_key in acct_dict.items():
156 auth = self.cached_api.auth(userID=uid, apiKey=api_key)
157 api_char_list = auth.account.Characters()
159 for character in api_char_list.characters:
160 if character.characterID == char_id:
166 def char_id2name(self, char_id):
168 Takes a character ID and returns the character name associated with
170 The EVE API accepts a comma-separated list of IDs, but for now we
171 will just handle a single ID.
174 chars = self.cached_api.eve.CharacterName(ids=char_id).characters
175 name = chars[0].characterName
177 traceback.print_exc()
182 def char_name2id(self, name):
184 Takes the name of an EVE character and returns the characterID.
186 The EVE api accepts a comma separated list of names, but for now
187 we will just handle single names/
190 chars = self.cached_api.eve.CharacterID(names=name).characters
191 char_id = chars[0].characterID
192 char_name = chars[0].name
194 traceback.print_exc()
199 def get_chars_from_acct(self, uid):
201 Returns a list of characters associated with the provided user ID.
203 auth = self.get_auth(uid)
208 api_char_list = auth.account.Characters()
209 char_list = [char.name for char in api_char_list.characters]
211 traceback.print_exc()
216 def get_characters(self):
218 Returns a list of (character_name, image_path, uid) tuples from all the
219 accounts that are registered to mEveMon.
221 If there is an authentication issue, then instead of adding a valid
222 pair to the list, it appends an 'error message'
226 err_img = "/usr/share/mevemon/imgs/error.jpg"
228 placeholder_chars = ("Please check your API settings.", err_img, "0")
230 acct_dict = self.get_accounts()
232 return [placeholder_chars]
234 for uid in acct_dict.keys():
235 char_names = self.get_chars_from_acct(uid)
238 ui_char_list.append(placeholder_chars)
240 # append each char we get to the list we'll return to the
242 for char_name in char_names:
243 ui_char_list.append((char_name, self.get_portrait(char_name, 64) , uid) )
247 def get_portrait(self, char_name, size):
249 Returns the file path of the retrieved portrait
251 char_id = self.char_name2id(char_name)
253 return fetchimg.portrait_filename(char_id, size)
255 def get_skill_tree(self):
257 Returns an object from eveapi containing skill tree info
260 tree = self.cached_api.eve.SkillTree()
262 traceback.print_exc()
267 def get_skill_in_training(self, uid, char_id):
269 Returns an object from eveapi containing information about the
270 current skill in training
274 skill = self.get_auth(uid).character(char_id).SkillInTraining()
276 traceback.print_exc()
281 def connection_cb(self, connection, event, mgc):
285 def connect_to_network(self):
286 connection = conic.Connection()
288 connection.connect("connection-event", self.connection_cb, 0xAA55)
289 assert(connection.request_connection(conic.CONNECT_FLAG_NONE))
292 def get_sp(self, uid, char_id):
293 sheet = self.get_char_sheet(uid, char_id)
295 # TODO: we also have to calculate how much we earned from a
296 # currently training skill
300 for skill in sheet.skills:
301 actual_sp += skill.skillpoints
303 live_sp = actual_sp + self.get_training_sp(uid, char_id)
307 def get_spps(self, uid, char_id):
309 Calculate and returns the skill points per hour for the given character.
311 skill = self.get_skill_in_training(uid, char_id)
313 if not skill.skillInTraining:
316 total_sp = skill.trainingDestinationSP - skill.trainingStartSP
317 total_time = skill.trainingEndTime - skill.trainingStartTime
319 spps = float(total_sp) / total_time
321 return (spps, skill.trainingStartTime)
323 def get_training_sp(self, uid, char_id):
325 returns the additional SP that the in-training skill has acquired
328 spps_tuple = self.get_spps(uid, char_id)
335 spps, start_time = spps_tuple
337 eve_time = time.time() #evetime is utc, right?
339 time_diff = eve_time - start_time
341 return (spps * time_diff)
344 if __name__ == "__main__":