From 21352f74cc9a407cc4f1b9e67f9f258b3b8352f3 Mon Sep 17 00:00:00 2001 From: Danny Campbell Date: Sat, 22 Oct 2011 21:10:52 -0600 Subject: [PATCH] Removed legacy key support, added custom key support --- package/src/constants.py | 13 +++- package/src/file_settings.py | 74 ++++++++++++++-------- package/src/mevemon.py | 94 +++++++++++++++++++--------- package/src/ui/diablo/gui.py | 62 +++++++++--------- package/src/ui/fremantle/characterSheet.py | 12 ++-- package/src/ui/fremantle/dialogs.py | 46 +++++++------- package/src/ui/fremantle/gui.py | 6 +- package/src/ui/models.py | 22 ++++--- package/src/validation.py | 44 +++++++------ 9 files changed, 224 insertions(+), 149 deletions(-) diff --git a/package/src/constants.py b/package/src/constants.py index 2cd44a3..a2f6b4b 100644 --- a/package/src/constants.py +++ b/package/src/constants.py @@ -20,7 +20,14 @@ ABOUT_AUTHORS = ['Ryan Campbell ', 'Danny Campbell '] ABOUT_WEBSITE = 'http://mevemon.garage.maemo.org' -APP_VERSION = '0.5-1' +APP_VERSION = '0.5-2' -# size of a valid api key -KEY_SIZE = 64 +# size of a valid verification code +MIN_VER_CODE_SIZE = 20 +MAX_VER_CODE_SIZE = 64 + +# the access mask we need to perform mevemon's functions (we may want +# this to be a _minimum_ access, but I'd have to take a closer look at +# how the masks work - FIXME, danny) + +REQUIRED_ACCESS_MASK = 131081 diff --git a/package/src/file_settings.py b/package/src/file_settings.py index 93cad57..d3b2a19 100644 --- a/package/src/file_settings.py +++ b/package/src/file_settings.py @@ -1,4 +1,5 @@ """ wrapper for ini-file-based settings""" +import os import configobj import constants @@ -8,13 +9,13 @@ class Settings: For example, a typical mEveMon config file (at '~/.mevemon/mevemon.cfg')will look like this: [accounts] - [[account.]] - uid = - apikey = + [[account.]] + key_id = + ver_code = - [[account.]] - uid = - apikey = + [[account.]] + key_id = + ver_code = [general] # this is just a fake example, we don't store any general @@ -26,11 +27,12 @@ class Settings: """ def __init__(self, cfg_file=constants.CONFIG_PATH): self.cfg_file = cfg_file - self.config = configobj.ConfigObj(self.cfg_file) self._convert_gconf_to_cfgfile() - + self._detect_and_backup_old_cfg() + self.config = configobj.ConfigObj(self.cfg_file) + def get_accounts(self): - """ Returns a dictionary containing uid:api_key pairs gathered from the config file + """ Returns a dictionary containing key_id:ver_code pairs gathered from the config file """ account_dict = {} try: @@ -39,35 +41,35 @@ class Settings: return account_dict for account in cfg_accounts: - account_dict[account['uid']] = account['apikey'] + account_dict[account['key_id']] = account['ver_code'] return account_dict - def get_api_key(self, uid): - """ Returns the api key associated with the given uid. + def get_ver_code(self, key_id): + """ Returns the verification code associated with the given key_id. """ try: - api_key = self.get_accounts()[uid] - return api_key + ver_code = self.get_accounts()[key_id] + return ver_code except KeyError: - raise Exception("UID '%s' is not in settings") + raise Exception("KEY_ID '%s' is not in settings") - def add_account(self, uid, api_key): - """ Adds the provided uid:api_key pair to the config file. + def add_account(self, key_id, ver_code): + """ Adds the provided key_id:ver_code pair to the config file. """ if 'accounts' not in self.config.sections: self.config['accounts'] = {} - self.config['accounts']['account.%s' % uid] = {} - self.config['accounts']['account.%s' % uid]['uid'] = uid - self.config['accounts']['account.%s' % uid]['apikey'] = api_key + self.config['accounts']['account.%s' % key_id] = {} + self.config['accounts']['account.%s' % key_id]['key_id'] = key_id + self.config['accounts']['account.%s' % key_id]['ver_code'] = ver_code self.write() - def remove_account(self, uid): - """ Removes the provided uid key from the config file + def remove_account(self, key_id): + """ Removes the provided key_id key from the config file """ for key in self.config['accounts']: - if self.config['accounts'][key]['uid'] == uid: + if self.config['accounts'][key]['key_id'] == key_id: del self.config['accounts'][key] self.write() @@ -84,6 +86,26 @@ class Settings: """ import gconf_settings gsettings = gconf_settings.Settings() - for uid, apikey in gsettings.get_accounts().items(): - self.add_account(uid, apikey) - gsettings.remove_account(uid) + for key_id, ver_code in gsettings.get_accounts().items(): + self.add_account(key_id, ver_code) + gsettings.remove_account(key_id) + + def _detect_and_backup_old_cfg(self): + """ Searches the config file for the string 'apikey', which + would only be present in the old legacy config file. If it's + found, it backs up the file and we start over. + """ + try: + temp = open(self.cfg_file, "r") + except IOError: + # if it's not here, forget about it - mission accomplished + return + config_contents = temp.read() + temp.close() + if config_contents.find('apikey') > 0: + # move the file then create a new one + os.rename(self.cfg_file, self.cfg_file + '.old') + else: + # we've got an updated cfg file + pass + diff --git a/package/src/mevemon.py b/package/src/mevemon.py index f8036e4..cfa8b33 100755 --- a/package/src/mevemon.py +++ b/package/src/mevemon.py @@ -35,6 +35,7 @@ import apicache import file_settings as settings from constants import LOGPATH, MAXBYTES, LOGCOUNT, CONFIG_DIR, IMG_CACHE_PATH from constants import APICACHE_PATH +from constants import REQUIRED_ACCESS_MASK #ugly hack to check maemo version. any better way? if hasattr(hildon, "StackableWindow"): @@ -61,14 +62,14 @@ class mEveMon: def quit(self, *args): gtk.main_quit() - def get_auth(self, uid): + def get_auth(self, key_id): """ Returns an authentication object to be used for eveapi calls that require authentication. """ - api_key = self.settings.get_api_key(uid) + ver_code = self.settings.get_ver_code(key_id) try: - auth = self.cached_api.auth(userID=uid, apiKey=api_key) + auth = self.cached_api.auth(keyID=key_id, vCode=ver_code) except Exception, e: self.gui.report_error(str(e)) logging.getLogger('mevemon').exception("Failed to get character name") @@ -76,12 +77,12 @@ class mEveMon: return auth - def get_char_sheet(self, uid, char_id): + def get_char_sheet(self, key_id, char_id): """ Returns an object containing information about the character specified by the provided character ID. """ try: - sheet = self.get_auth(uid).character(char_id).CharacterSheet() + sheet = self.get_auth(key_id).character(char_id).CharacterSheet() except Exception, e: self.gui.report_error(str(e)) logging.getLogger('mevemon').exception("Failed to get character name") @@ -89,7 +90,7 @@ class mEveMon: return sheet - def charid2uid(self, char_id): + def charid2key_id(self, char_id): """ Takes a character ID and returns the user ID of the account containing the character. @@ -98,8 +99,8 @@ class mEveMon: """ acct_dict = self.settings.get_accounts() - for uid, api_key in acct_dict.items(): - auth = self.cached_api.auth(userID=uid, apiKey=api_key) + for key_id, ver_code in acct_dict.items(): + auth = self.cached_api.auth(keyID=key_id, vCode=ver_code) try: api_char_list = auth.account.Characters() characters = api_char_list.characters @@ -108,7 +109,7 @@ class mEveMon: for character in characters: if character.characterID == char_id: - return uid + return key_id def char_id2name(self, char_id): @@ -144,25 +145,26 @@ class mEveMon: return char_id - def get_chars_from_acct(self, uid): + def get_chars_from_acct(self, key_id): """ Returns a list of characters associated with the provided user ID. """ - auth = self.get_auth(uid) + auth = self.get_auth(key_id) if not auth: return None else: try: api_char_list = auth.account.Characters() - char_list = [char.name for char in api_char_list.characters] + char_name_list = [char.name for char in api_char_list.characters] + char_id_list = [char.characterID for char in api_char_list.characters] except Exception, e: self.gui.report_error(str(e)) logging.getLogger('mevemon').exception("Failed to get character list") return None - return char_list + return char_name_list, char_id_list def get_characters(self): - """ Returns a list of (character_name, image_path, uid) tuples from all the + """ Returns a list of (character_name, image_path, key_id) tuples from all the accounts that are registered to mEveMon. If there is an authentication issue, then instead of adding a valid @@ -172,6 +174,7 @@ class mEveMon: ui_char_list = [] err_img = "/usr/share/mevemon/imgs/error.jpg" err_txt = "Problem fetching info for account (or no accounts added)" + bad_key = "Incorrect key access. Your access mask should be %s." % REQUIRED_ACCESS_MASK placeholder_chars = (err_txt, err_img, None) @@ -179,16 +182,26 @@ class mEveMon: if not acct_dict: return [placeholder_chars] - for uid in acct_dict.keys(): - char_names = self.get_chars_from_acct(uid) + for key_id, ver_code in acct_dict.items(): + + char_names, char_ids = self.get_chars_from_acct(key_id) if not char_names: - ui_char_list.append((err_txt + "\t(UID: %s)" % uid, err_img, None)) + ui_char_list.append((err_txt + "\t(KEY_ID: %s)" % key_id, err_img, None)) else: - # append each char we get to the list we'll return to the - # UI --danny - for char_name in char_names: - ui_char_list.append((char_name, self.get_portrait(char_name, 64) , uid) ) + + + # since there are char names, let's check the key + # access and if it's bad we'll generate a key URL for + # each character + for char_name, char_id in zip(char_names, char_ids): + if self.get_access_mask(key_id, ver_code) != REQUIRED_ACCESS_MASK: + key_url = self.generate_access_mask_url(char_id) + ui_char_list.append((bad_key, err_img, None)) + else: + # append each char we get to the list we'll + # return to the UI --danny + ui_char_list.append((char_name, self.get_portrait(char_name, 64), key_id)) return ui_char_list @@ -211,12 +224,13 @@ class mEveMon: return tree - def get_skill_in_training(self, uid, char_id): + def get_skill_in_training(self, key_id, char_id): """ Returns an object from eveapi containing information about the current skill in training """ try: - skill = self.get_auth(uid).character(char_id).SkillInTraining() + # should this be accessing the cached object? (confused) --danny + skill = self.get_auth(key_id).character(char_id).SkillInTraining() except Exception, e: self.gui.report_error(str(e)) logging.getLogger('mevemon').exception("Failed to get skill-in-training:") @@ -243,24 +257,24 @@ class mEveMon: assert(connection.request_connection(conic.CONNECT_FLAG_NONE)) - def get_sp(self, uid, char_id): + def get_sp(self, key_id, char_id): """ Adds up the SP for all known skills, then calculates the SP gained from an in-training skill. """ actual_sp = 0 - sheet = self.get_char_sheet(uid, char_id) + sheet = self.get_char_sheet(key_id, char_id) for skill in sheet.skills: actual_sp += skill.skillpoints - live_sp = actual_sp + self.get_training_sp(uid, char_id) + live_sp = actual_sp + self.get_training_sp(key_id, char_id) return live_sp - def get_spps(self, uid, char_id): + def get_spps(self, key_id, char_id): """ Calculate and returns the skill points per hour for the given character. """ - skill = self.get_skill_in_training(uid, char_id) + skill = self.get_skill_in_training(key_id, char_id) if not skill.skillInTraining: return (0, 0) @@ -272,10 +286,10 @@ class mEveMon: return (spps, skill.trainingStartTime) - def get_training_sp(self, uid, char_id): + def get_training_sp(self, key_id, char_id): """ returns the additional SP that the in-training skill has acquired """ - spps_tuple = self.get_spps(uid, char_id) + spps_tuple = self.get_spps(key_id, char_id) if not spps_tuple: return 0 @@ -293,6 +307,26 @@ class mEveMon: except OSError, e: logging.getLogger('mevemon').exception("Failed to clear cache") + def get_access_mask(self, key_id, ver_code): + + """ + Returns the access mask that determines what data we have + access to on the account. + + """ + + return self.cached_api.account.APIKeyInfo(keyID=key_id, vCode=ver_code).key.accessMask + + def generate_access_mask_url(self, char_id): + + """ + Generates a URL to send the user to the page that will help + them create an access key with exactly the access mevemon + needs. + """ + + return "https://supporttest.eveonline.com/api/Key/CreatePredefined/%s/%s/false" % (REQUIRED_ACCESS_MASK, char_id) + def excepthook(ex_type, value, tb): """ a replacement for the default exception handler that logs errors""" logging.getLogger("mevemon").error('Uncaught exception:', diff --git a/package/src/ui/diablo/gui.py b/package/src/ui/diablo/gui.py index ef1ef0f..217db28 100644 --- a/package/src/ui/diablo/gui.py +++ b/package/src/ui/diablo/gui.py @@ -124,14 +124,14 @@ class BaseUI(): return value def edit_account(self, treeview): - uid = self.get_selected_item(treeview, 0) + key_id = self.get_selected_item(treeview, 0) # pop up the account dialog self.accounts_model.get_accounts() def delete_account(self, treeview): - uid = self.get_selected_item(treeview, 0) - self.controller.settings.remove_account(uid) + key_id = self.get_selected_item(treeview, 0) + self.controller.settings.remove_account(key_id) # refresh model self.accounts_model.get_accounts() @@ -139,8 +139,8 @@ class BaseUI(): def add_columns_to_accounts(self, treeview): #Column 0 for the treeview renderer = gtk.CellRendererText() - column = gtk.TreeViewColumn('User ID', renderer, - text=models.AccountsModel.C_UID) + column = gtk.TreeViewColumn('Key ID', renderer, + text=models.AccountsModel.C_KID) column.set_property("expand", True) treeview.append_column(column) @@ -160,23 +160,23 @@ class BaseUI(): dialog.set_transient_for(window) dialog.set_title("New Account") - uidLabel = gtk.Label("User ID:") - uidLabel.set_justify(gtk.JUSTIFY_LEFT) - vbox.add(uidLabel) + key_idLabel = gtk.Label("Key ID:") + key_idLabel.set_justify(gtk.JUSTIFY_LEFT) + vbox.add(key_idLabel) - uidEntry = gtk.Entry() - uidEntry.set_property('is_focus', False) + key_idEntry = gtk.Entry() + key_idEntry.set_property('is_focus', False) - vbox.add(uidEntry) + vbox.add(key_idEntry) - apiLabel = gtk.Label("API key:") - apiLabel.set_justify(gtk.JUSTIFY_LEFT) - vbox.add(apiLabel) + verCodeLabel = gtk.Label("Verification code:") + verCodeLabel.set_justify(gtk.JUSTIFY_LEFT) + vbox.add(verCodeLabel) - apiEntry = gtk.Entry() - apiEntry.set_property('is_focus', False) + verCodeEntry = gtk.Entry() + verCodeEntry.set_property('is_focus', False) - vbox.add(apiEntry) + vbox.add(verCodeEntry) ok_button = dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) cancel_button = dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) @@ -188,18 +188,18 @@ class BaseUI(): while not valid_credentials: if result == gtk.RESPONSE_OK: - uid = uidEntry.get_text() - api_key = apiEntry.get_text() + key_id = key_idEntry.get_text() + ver_code = verCodeEntry.get_text() try: - validation.validate_uid(uid) - validation.validate_api_key(api_key) + validation.validate_key_id(key_id) + validation.validate_ver_code(ver_code) except validation.ValidationError, e: self.report_error(e.message) result = dialog.run() else: valid_credentials = True - self.controller.settings.add_account(uid, api_key) + self.controller.settings.add_account(key_id, ver_code) self.accounts_model.get_accounts() else: break @@ -301,10 +301,10 @@ class mEveMonUI(BaseUI): # column 0 is the portrait, column 1 is name char_name = model.get_value(miter, 1) - uid = model.get_value(miter, 2) + key_id = model.get_value(miter, 2) - if uid: - CharacterSheetUI(self.controller, char_name, uid) + if key_id: + CharacterSheetUI(self.controller, char_name, key_id) else: pass @@ -312,10 +312,10 @@ class CharacterSheetUI(BaseUI): #time between live sp updates (in milliseconds) UPDATE_INTERVAL = 1000 - def __init__(self, controller, char_name, uid): + def __init__(self, controller, char_name, key_id): self.controller = controller self.char_name = char_name - self.uid = uid + self.key_id = key_id self.sheet = None self.char_id = None self.skills_model = None @@ -343,7 +343,7 @@ class CharacterSheetUI(BaseUI): self.char_id = self.controller.char_name2id(self.char_name) - self.sheet = self.controller.get_char_sheet(self.uid, self.char_id) + self.sheet = self.controller.get_char_sheet(self.key_id, self.char_id) self.win.set_title(self.char_name) @@ -402,7 +402,7 @@ class CharacterSheetUI(BaseUI): gtk.Window.destroy(self.win) def display_skill_in_training(self, vbox): - skill = self.controller.get_skill_in_training(self.uid, self.char_id) + skill = self.controller.get_skill_in_training(self.key_id, self.char_id) if skill.skillInTraining: @@ -446,11 +446,11 @@ class CharacterSheetUI(BaseUI): self.add_label("Balance: %s ISK" % util.comma(self.sheet.balance), box) - self.live_sp_val = self.controller.get_sp(self.uid, self.char_id) + self.live_sp_val = self.controller.get_sp(self.key_id, self.char_id) self.live_sp = self.add_label("Total SP: %s" % util.comma(int(self.live_sp_val)), box) - self.spps = self.controller.get_spps(self.uid, self.char_id)[0] + self.spps = self.controller.get_spps(self.key_id, self.char_id)[0] def fill_stats(self, box): diff --git a/package/src/ui/fremantle/characterSheet.py b/package/src/ui/fremantle/characterSheet.py index 133cb01..204ee47 100644 --- a/package/src/ui/fremantle/characterSheet.py +++ b/package/src/ui/fremantle/characterSheet.py @@ -28,10 +28,10 @@ from menu import Menu class CharacterSheetUI: UPDATE_INTERVAL = 1 - def __init__(self, controller, char_name, uid): + def __init__(self, controller, char_name, key_id): self.controller = controller self.char_name = char_name - self.uid = uid + self.key_id = key_id self.sheet = None self.char_id = None self.skills_model = None @@ -57,7 +57,7 @@ class CharacterSheetUI: self.char_id = self.controller.char_name2id(self.char_name) - self.sheet = self.controller.get_char_sheet(self.uid, self.char_id) + self.sheet = self.controller.get_char_sheet(self.key_id, self.char_id) self.win.set_title(self.char_name) @@ -117,7 +117,7 @@ class CharacterSheetUI: def display_skill_in_training(self, vbox): - skill = self.controller.get_skill_in_training(self.uid, self.char_id) + skill = self.controller.get_skill_in_training(self.key_id, self.char_id) if skill.skillInTraining: @@ -161,11 +161,11 @@ class CharacterSheetUI: self.add_label("Balance: %s ISK" % util.comma(self.sheet.balance), box) - self.live_sp_val = self.controller.get_sp(self.uid, self.char_id) + self.live_sp_val = self.controller.get_sp(self.key_id, self.char_id) self.live_sp = self.add_label("Total SP: %s" % util.comma(int(self.live_sp_val)), box) - self.spps = self.controller.get_spps(self.uid, self.char_id)[0] + self.spps = self.controller.get_spps(self.key_id, self.char_id)[0] def fill_stats(self, box): diff --git a/package/src/ui/fremantle/dialogs.py b/package/src/ui/fremantle/dialogs.py index 2db5a9e..ec43656 100644 --- a/package/src/ui/fremantle/dialogs.py +++ b/package/src/ui/fremantle/dialogs.py @@ -61,8 +61,8 @@ class SettingsDialog(gtk.Dialog): def on_delete_account_clicked(self): - uid = self._get_selected_item(0) - self.controller.settings.remove_account(uid) + key_id = self._get_selected_item(0) + self.controller.settings.remove_account(key_id) self.accounts.refresh() def _get_selected_item(self, column): @@ -87,17 +87,17 @@ class NewAccountDialog(gtk.Dialog): while not valid_credentials: if result == gtk.RESPONSE_OK: - uid = self.uidEntry.get_text() - api_key = self.apiEntry.get_text() + key_id = self.keyIDEntry.get_text() + ver_code = self.verCodeEntry.get_text() try: - validation.validate_uid(uid) - validation.validate_api_key(api_key) + validation.validate_key_id(key_id) + validation.validate_ver_code(ver_code) except validation.ValidationError, e: self.report_error(e.message) result = self.run() else: valid_credentials = True - self.controller.settings.add_account(uid, api_key) + self.controller.settings.add_account(key_id, ver_code) else: break @@ -110,25 +110,25 @@ class NewAccountDialog(gtk.Dialog): self.set_title("New Account") - uidLabel = gtk.Label("User ID:") - uidLabel.set_justify(gtk.JUSTIFY_LEFT) - vbox.add(uidLabel) + keyIDLabel = gtk.Label("Key ID:") + keyIDLabel.set_justify(gtk.JUSTIFY_LEFT) + vbox.add(keyIDLabel) - self.uidEntry = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT) - self.uidEntry.set_placeholder("User ID") - self.uidEntry.set_property('is_focus', False) + self.keyIDEntry = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT) + self.keyIDEntry.set_placeholder("Key ID") + self.keyIDEntry.set_property('is_focus', False) - vbox.add(self.uidEntry) + vbox.add(self.keyIDEntry) - apiLabel = gtk.Label("API key:") - apiLabel.set_justify(gtk.JUSTIFY_LEFT) - vbox.add(apiLabel) + verCodeLabel = gtk.Label("Verification code:") + verCodeLabel.set_justify(gtk.JUSTIFY_LEFT) + vbox.add(verCodeLabel) - self.apiEntry = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT) - self.apiEntry.set_placeholder("API Key") - self.apiEntry.set_property('is_focus', False) + self.verCodeEntry = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT) + self.verCodeEntry.set_placeholder("Verification code") + self.verCodeEntry.set_property('is_focus', False) - vbox.add(self.apiEntry) + vbox.add(self.verCodeEntry) ok_button = self.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) @@ -150,8 +150,8 @@ class AccountsTreeView(hildon.GtkTreeView): def add_columns(self): #Column 0 for the treeview renderer = gtk.CellRendererText() - column = gtk.TreeViewColumn('User ID', renderer, - text=models.AccountsModel.C_UID) + column = gtk.TreeViewColumn('Key ID', renderer, + text=models.AccountsModel.C_KID) column.set_property("expand", True) self.append_column(column) diff --git a/package/src/ui/fremantle/gui.py b/package/src/ui/fremantle/gui.py index a811d5f..7655d4a 100644 --- a/package/src/ui/fremantle/gui.py +++ b/package/src/ui/fremantle/gui.py @@ -66,10 +66,10 @@ class mEveMonUI: # column 0 is the portrait, column 1 is name char_name = model.get_value(miter, 1) - uid = model.get_value(miter, 2) + key_id = model.get_value(miter, 2) - if uid: - CharacterSheetUI(self.controller, char_name, uid) + if key_id: + CharacterSheetUI(self.controller, char_name, key_id) else: pass diff --git a/package/src/ui/models.py b/package/src/ui/models.py index f365ae6..a151a0f 100644 --- a/package/src/ui/models.py +++ b/package/src/ui/models.py @@ -2,7 +2,10 @@ import gtk import util class AccountsModel(gtk.ListStore): - C_UID, C_APIKEY, C_CHARS = range(3) + + # userID no longer exists, we want keyID + # api key becomes verification code... --danny + C_KID, C_VCODE, C_CHARS = range(3) def __init__(self, controller): gtk.ListStore.__init__(self, str, str, str) @@ -17,21 +20,22 @@ class AccountsModel(gtk.ListStore): if not accts_dict: return None - for uid, key in accts_dict.items(): + for key_id, key in accts_dict.items(): liter = self.append() - chars = self.controller.get_chars_from_acct(uid) + chars, ids = self.controller.get_chars_from_acct(key_id) if chars: char_str = ', '.join(chars) char_str = "%s" % char_str else: char_str = "" - self.set(liter, self.C_UID, uid, self.C_APIKEY, key, self.C_CHARS, char_str) + self.set(liter, self.C_KID, key_id, self.C_VCODE, key, self.C_CHARS, char_str) class CharacterListModel(gtk.ListStore): - C_PORTRAIT, C_NAME, C_UID = range(3) + + C_PORTRAIT, C_NAME, C_KID = range(3) def __init__(self, controller): gtk.ListStore.__init__(self, gtk.gdk.Pixbuf, str, str) @@ -44,9 +48,9 @@ class CharacterListModel(gtk.ListStore): char_list = self.controller.get_characters() - for name, icon, uid in char_list: + for name, icon, key_id in char_list: liter = self.append() - self.set(liter, self.C_PORTRAIT, self._set_pix(icon), self.C_NAME, name, self.C_UID, uid) + self.set(liter, self.C_PORTRAIT, self._set_pix(icon), self.C_NAME, name, self.C_KID, key_id) def _set_pix(self, filename): pixbuf = gtk.gdk.pixbuf_new_from_file(filename) @@ -67,9 +71,9 @@ class CharacterSkillsModel(gtk.ListStore): def get_skills(self): self.clear() - uid = self.controller.charid2uid(self.charID) + key_id = self.controller.charid2key_id(self.charID) - self.sheet = self.controller.get_char_sheet(uid, self.charID) + self.sheet = self.controller.get_char_sheet(key_id, self.charID) skilltree = self.controller.get_skill_tree() diff --git a/package/src/validation.py b/package/src/validation.py index 1773c11..8c2fb18 100644 --- a/package/src/validation.py +++ b/package/src/validation.py @@ -1,5 +1,5 @@ """ This module contains all our input validation functions """ -from constants import KEY_SIZE +from constants import MIN_VER_CODE_SIZE, MAX_VER_CODE_SIZE class ValidationError(StandardError): """ Exception that is raised if input validation fails @@ -12,27 +12,35 @@ class ValidationError(StandardError): return repr(self.message) +def validate_key_id(key_id): -def validate_api_key(api_key): - """ Validates an EVE api key. throws ValidationError exception if the - format is invalid. + """ Validates an EVE key ID. throws ValidationError exception if + the format is invalid. """ + #TODO: anything else we can do to validate the api key? + + # I don't know enough about the keyID yet. seems to be only + # numeric. The 2 I made were 705 and 706 respectively. I think + # they are just incrementing numbers. But I won't assume that + # yet... - if len(api_key) != KEY_SIZE: - raise ValidationError("API Key must be %s characters" % KEY_SIZE) - elif not api_key.isalnum(): - raise ValidationError("API Key must only contain alphanumeric " +\ - "characters") + pass -def validate_uid(uid): - """ Validates an EVE Online uid, throws ValidationError exception if the - format is invalid. - """ - #TODO: anything else we can do to validate the uid? +def validate_ver_code(ver_code): + + """ Validates an EVE Online verification code, throws + ValidationError exception if the format is invalid. - if not uid.isdigit(): - raise ValidationError("UID must be a number") - if len(uid) < 1: - raise ValidationError("Missing UID") + """ + + # What we DO know about the verification code is that it has to be + # at least 20 digits and at most 64. Seems to be alphanumeric + # only. + + + if len(ver_code) < MIN_VER_CODE_SIZE or len(ver_code) > MAX_VER_CODE_SIZE: + raise ValidationError("Verification code must be from 20 to 64 " + "characters.") + -- 1.7.9.5