def check_version(): import gnutr_consts import install this_ver = install.gnutr_version() if config.get_value( 'check_disabled') or not config.get_value('check_version'): return 0 import time interval = config.get_value('check_interval') last_check = config.get_value('last_check') time_now = time.time() if (time_now - last_check > interval): (curr_ver, sr, date, sr_url, mesg) = get_latest_version(gnutr_consts.LATEST_VERSION) config.set_key_value('sr', sr) config.set_key_value('sr_date', date) config.set_key_value('sr_url', sr_url) update = False if this_ver == curr_ver: pass # Nothing to do else: update = cmp_version_strings(this_ver, curr_ver) if update: update_version(curr_ver, mesg) last_check = config.set_key_value('last_check', time_now) return 1
def __init__(self): from os import path logfile = path.join(config.udir, 'log') init_logging(logfile, logto='both', level='info') self.first_run = not config.get_value('sqlite3') if self.first_run: # First run, program default values can be added here import druid # Set default version check information import gnutr_consts config.set_key_value('sqlite3', 'Yes') config.set_key_value('check_disabled', gnutr_consts.CHECK_DISABLED) config.set_key_value('check_version', gnutr_consts.CHECK_VERSION) config.set_key_value('check_interval', gnutr_consts.CHECK_INTERVAL) config.set_key_value('last_check', 0) self.user_dir = config.udir self.druid = druid.Druid(self) self.druid.show() else: self.startup()
def user_setup( self, uname, pword): # check to see if user name is already in mysql.user and that the # password is correct if self.user_name_exists( uname): if self.password_match( uname, pword): # add the info to the config file. config.set_key_value( 'Username', uname) config.set_key_value( 'Password', pword) # check to see if user can access 'gnutr_db' if not self.user_db_access( uname): # grant privileges to user self.db.add_user( uname, pword) else: return 0 else: self.db.add_user( uname, pword) config.set_key_value( 'Username', uname) config.set_key_value( 'Password', pword) return 1
def migrate(mysql): """Retrieve gnutrition table data from MySQL database. Parameters uname and pword are the MySQL username and password used with the older version of GNUtritin.""" from gnutr import Dialog lite = Database() # Need to check for tables: recipe, ingredient, preparation # person, food_plan, recipe_plan, nutr_goal tables = [ 'recipe', 'ingredient', 'preparation', 'person', 'food_plan', 'recipe_plan' ] mysql.query('SHOW TABLES') old_tables = mysql.get_result() # At some point use of a 'measure' table was discontinued use_msre_no = False found = [] for t in old_tables: if t[0] in tables: found.append(t[0]) if t[0] == 'measure': use_msre_no = True # Quirks: # 0.31 does not save recipe or food_plan (nothing to migrate except # person data. # 0.31.1 uses fd_no (for NDB_No) and msre_no to index measure table # 0.32 onward uses NDB_No and Msre_Desc (no measure table) # Any version - food numbers may have disappeared from earlier SR data # to later SR data. NDB_No inserted in SQLite tables must # exist in current SR data. # # Create a list of for obsolete NDB_No (food number) and recipe_no # (recipe number) for recipes which will fail to import properly due to # the obsolete NDB_No. recipe_failures = [] obsolete_NDB_No = [] # ingredient table if 'ingredient' in found: sql1 = "SELECT recipe_no, amount, msre_no, fd_no FROM ingredient" sql2 = "SELECT recipe_no, amount, Msre_Desc, NDB_No FROM ingredient" if use_msre_no: mysql.query(sql1) else: mysql.query(sql2) result = mysql.get_result() if result: debug('found {0:d} ingredients'.format(len(result))) debug("{0!r}".format(result)) for i in range(len(result)): NDB_No = num2str(result[i][3], 5) if not good_NDB_No(NDB_No): recipe_failures.append(recipe_no) obsolete_NDB_No.append(NDB_No) debug('NDB_No {0:d} is obsolete.'.format(NDB_No)) continue Msre_No, Msre_Desc = None, None recipe_no = result[i][0] amount = result[i][1] if use_msre_no: Msre_No = result[i][2] else: Msre_Desc = result[i][2] Msre_Desc = to_Msre_Desc(sqlite=lite, mysql=mysql, NDB_No=NDB_No, Msre_Desc=Msre_Desc, Msre_No=Msre_No) assert Msre_Desc debug('Found Msre_Desc {0:s}'.format(Msre_Desc)) params = (recipe_no, amount, Msre_Desc, NDB_No) lite.query("INSERT INTO 'ingredient' VALUES (?,?,?,?)", many=False, sql_params=params, caller='migrate') # recipie table if 'recipe' in found: mysql.query("SELECT recipe_no, recipe_name, no_serv, no_ingr, " + "category_no FROM recipe") result = mysql.get_result() if result: debug('found {0:d} recipies'.format(len(result))) debug('{0!r}'.format(result)) for i in range(len(result)): if result[i][0] in recipe_failures: debug('Recipe {0:s} will not import'.format(result[i][1])) continue lite.query("INSERT INTO 'recipe' VALUES (?,?,?,?,?)", many=False, sql_params=result[i], caller='migrate') # preparation table if 'preparation' in found: mysql.query("SELECT recipe_no, prep_time, prep_desc FROM preparation") result = mysql.get_result() if result: debug('found {0:d} entries in preparation table'.format( len(result))) debug('{0!r}'.format(result)) for i in range(len(result)): if result[i][0] in recipe_failures: continue lite.query("INSERT INTO 'preparation' VALUES (?,?,?)", many=False, sql_params=result[i], caller='migrate') # person table if 'person' in found: mysql.query("SELECT person_no, person_name, user_name FROM person") result = mysql.get_result() if result and len(result) > 0: persons = len(result) debug('found {0:d} entries in person table'.format(persons)) debug('{0!r}'.format(result)) lite.query("INSERT INTO 'person' VALUES (?,?,?)", many=True, sql_params=result, caller='migrate') # This for filling in 'Name' in User Setup Personal Details # User can change but show them what they used before. if persons == 1 and not config.get_value('Name'): config.set_key_value('Name', person_name) # food_plan table if 'food_plan' in found: sql1 = "SELECT person_no, date, time, amount, msre_no, fd_no FROM food_plan" sql2 = "SELECT person_no, date, time, amount, Msre_Desc, NDB_No FROM food_plan" if use_msre_no: mysql.query(sql1) else: mysql.query(sql2) result = mysql.get_result() if result: debug('found {0:d} entries in food_plan table'.format(len(result))) for i in range(len(result)): NDB_No = num2str(result[i][5], 5) date = str(result[i][1]) time = str(result[i][2]) if not good_NDB_No(result[i][5]): s = 'Food plan for {0:s} {1:s} contains obsolete NDB_No.' debug(s.format(date, time)) continue person_no = result[i][0] amount = result[i][3] if use_msre_no: Msre_Desc = msre_desc_from_msre_no(result[i][4]) else: Msre_Desc = result[i][4] Msre_Desc = to_Msre_Desc(sqlite=lite, mysql=mysql, NDB_No=NDB_No, Msre_Desc=Msre_Desc, Msre_No=Msre_No) params = (person_no, date, time[:-3], amount, Msre_Desc, NDB_No) lite.query("INSERT INTO 'food_plan' VALUES (?,?,?,?,?,?)", many=False, sql_params=params, caller='migrate') # recipe_plan table if 'recipe_plan' in found: # Need to convert datetime.date and datetime.timedelta MySQL types to # strings before inserting into SQLite table. mysql.query("SELECT person_no, date, time, no_portions, " + "recipe_no FROM recipe_plan") result = mysql.get_result() debug('found {0:d} entries in recipe_plan table'.format(len(result))) if result: for r in range(len(result)): recipe_no = result[r][4] date = str(result[r][1]) time = str(result[r][2]) if recipe_no in recipe_failures: debug('recipe plan for {0:s} {1:s} will not import'.format( date, time)) continue person_no = result[r][0] no_portions = result[r][3] params = (person_no, date, time[:-3], no_portions, recipe_no) debug("{0!r}".format(params)) lite.query("INSERT INTO 'recipe_plan' VALUES (?,?,?,?,?)", many=False, sql_params=params, caller='migrate') # nutr_goal table needs to be recalculated return True
class Druid: def __init__(self, app): self.app = app self.ui = druid_ui.DruidUI() self.connect_signals() def connect_signals(self): self.ui.cancel_button.connect('clicked', self.on_cancel) self.ui.next_button.connect('clicked', self.on_next) self.ui.back_button.connect('clicked', self.on_back) self.ui.dialog.connect('destroy', self.on_cancel) def show(self): self.ui.dialog.show_all() def on_cancel(self, w, d=None): self.ui.dialog.hide() gtk.main_quit() for user_file in os.listdir(self.app.user_dir): os.unlink(os.path.join(self.app.user_dir, user_file)) return 0 def on_next(self, w, d=None): if self.ui.page_num == 0: self.ui.set_page(1) # Database Create elif self.ui.page_num == 1: try: self.sqlite = database.Database() except Exception, ex: self.ui.set_page(2) return self.sqlite.init_USDA_data() self.sqlite.init_user() # See if this user has GNUtrition data from older version # which used MySQL. That data should be migrated to newer SQLite # storage first. db_uname = config.get_value('Username') db_pword = config.get_value('Password') if (db_uname and db_pword): dialog = Dialog('question', "Would you like to try to import recipies and other\n" + "data from MySQL (from older version of gnutrition)?") reply = dialog.run() dialog.destroy() if reply == gtk.RESPONSE_YES: self.migration = True import mysql self.mysql = mysql.open_mysqldb(db_uname, db_pword) if self.mysql: database.migrate(self.mysql) # no error, so skip over page_db_error self.ui.set_page(3) return # Personal details elif self.ui.page_num == 3: self.person = person.Person() # Does the user have an entry in the person table? They will if # a previous version of gnutrition was installed and the config # file from that installation still remains in user's home directory. # Note: sqlite.user is basename $HOME # gnutrition MySQL setup asks for MySQL username and that # may be what is in the 'person' table for 'user_name' db_uname = config.get_value('Username') if db_uname: db_name = db_uname else: db_name = self.sqlite.user # name1 may or not be 'old' name # person.get_name() returns a name from SQLite database associated # with user_name = db_name name1 = self.person.get_name(db_name) # This is the only place in the sources where 'Username' is set # in ~/.gnutrition/config # Note that this may simply be overwriting with same name if # get_value('Username') above returned a name. config.set_key_value('Username', db_name) new_name = self.ui.page_list[3].name_entry.get_text() age = self.ui.page_list[3].age_entry.get_text() weight_txt = self.ui.page_list[3].weight_entry.get_text() if (not new_name) or (not age) or (not weight_txt): return weight = float(weight_txt) config.set_key_value('Age', age) config.set_key_value('Weight', weight) if name1 and name1 != new_name: # If person changes 'Name' from previously used one to different one they # should be asked (presented a dialog) about associating new name with # imported (old) recipies. If yes, person table needs to be updated. self.person.update_name(name1, new_name) elif not name1: self.person.add_name(new_name) name2 = config.get_value('Name') # 'Name' is set in two places: here and in database.py in migrate() if name2 != new_name: config.set_key_value('Name', new_name) self.person.setup() if self.ui.page_list[3].weight_combo.get_active() == 0: # convert from pounds to kilos weight = weight * 0.4536 female = self.ui.page_list[3].female_button.get_active() if female == 1: pregnant = self.ui.page_list[3].preg_button.get_active() lactating = self.ui.page_list[3].lac_button.get_active() else: pregnant = 0 lactating = 0 data = calc_rdi.compute(age, weight, female, pregnant, lactating) self.nutr_goal_dlg = nutr_goal_dlg.NutrGoalDlg() self.nutr_goal_dlg.save_goal(data) self.ui.set_page(5) return
def on_food_button_released(self, w, d=None): self.hide_view(self.plan.ui) self.hide_view(self.recipe.ui) self.show_view(self.food.ui) config.set_key_value('Page', 'Food')
class Druid: def __init__( self, app): self.app = app self.ui = druid_ui.DruidUI() self.connect_signals() def connect_signals( self): self.ui.cancel_button.connect( 'clicked', self.on_cancel) self.ui.next_button.connect( 'clicked', self.on_next) self.ui.back_button.connect( 'clicked', self.on_back) def show( self): self.ui.dialog.show_all() def on_cancel( self, w, d=None): self.ui.dialog.hide() gtk.main_quit() return 0 def on_next( self, w, d=None): if self.ui.page_num == 0: self.ui.set_page( 1) # Database Create elif self.ui.page_num == 1: uname = self.ui.page_list[1].root_user_entry.get_text() pword = self.ui.page_list[1].root_pass_entry.get_text() if (not uname) or (not pword): return try: self.db = database.Database( uname, pword) except Exception, ex: self.ui.set_page(2) return self.db.initialize() # no error, so skip over page_db_error self.ui.set_page( 3) return # User Setup elif self.ui.page_num == 3: uname = self.ui.page_list[3].user_entry.get_text() pword = self.ui.page_list[3].pass_entry.get_text() if (not uname) or (not pword): return success = self.user_setup( uname, pword) if not success: self.ui.set_page( 4) return self.db.change_user( uname, pword, 'gnutr_db') # does the user have an entry in the person table? self.person = person.Person() person_name = self.person.get_name( uname) if person_name: config.set_key_value( 'Name', person_name) self.person.setup() self.ui.set_page( 7) return self.ui.set_page( 5) return
self.ui.set_page( 7) return self.ui.set_page( 5) return # Personal details elif self.ui.page_num == 5: name = self.ui.page_list[5].name_entry.get_text() age = self.ui.page_list[5].age_entry.get_text() weight_txt = self.ui.page_list[5].weight_entry.get_text() if (not name) or (not age) or (not weight_txt): return weight = float( weight_txt) config.set_key_value( 'Name', name) self.person.add_name( name) self.person.setup() if self.ui.page_list[5].weight_combo.get_active() == 0: # convert from pounds to kilos weight = weight * 0.4536 female = self.ui.page_list[5].female_button.get_active() if female == 1: pregnant = self.ui.page_list[5].preg_button.get_active() lactating = self.ui.page_list[5].lac_button.get_active() else: pregnant = 0 lactating = 0 list = calc_rdi.compute( age, weight, female, pregnant, lactating)
def on_food_button_released( self, w, d=None): self.hide_view( self.plan.ui) self.hide_view( self.recipe.ui) self.show_view( self.food.ui) config.set_key_value( 'Page', 'Food')