gnutrition-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUtrition-commits] /srv/bzr/gnutrition/trunk r15: Several changes most


From: Thomas Sinclair
Subject: [GNUtrition-commits] /srv/bzr/gnutrition/trunk r15: Several changes mostly related to import of old (MySQL) databases
Date: Sun, 14 Oct 2012 18:23:01 -0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 15
committer: Thomas Sinclair <address@hidden>
branch nick: trunk
timestamp: Sun 2012-10-14 18:23:01 -0400
message:
  Several changes mostly related to import of old (MySQL) databases
modified:
  configure.in
  src/base_win_ui.py
  src/database.py
  src/druid.py
  src/food_srch_dlg.py
  src/gnutr_consts.py
  src/install.py.in
  src/mysql.py
  src/nutr_composition_dlg.py
  src/person.py
  src/plan_compute_dlg.py
  src/plan_win.py
  src/recipe_win.py
  src/store.py
  src/version.py
=== modified file 'configure.in'
--- a/configure.in      2012-09-26 05:09:15 +0000
+++ b/configure.in      2012-10-14 22:23:01 +0000
@@ -25,11 +25,11 @@
 MAJOR_VERSION=0
 MINOR_VERSION=32
 REVISION=1
-VERSION="0.32.1"
+GNUTR_VERSION="0.32.1"
 AC_SUBST(MAJOR_VERSION)
 AC_SUBST(MINOR_VERSION)
 AC_SUBST(REVISION)
-AC_SUBST(VERSION)
+AC_SUBST(GNUTR_VERSION)
 
 dnl Get the default Python
 AC_PATH_PROG(PYTHON, python)

=== modified file 'src/base_win_ui.py'
--- a/src/base_win_ui.py        2012-07-27 01:59:48 +0000
+++ b/src/base_win_ui.py        2012-10-14 22:23:01 +0000
@@ -16,7 +16,8 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import gtk
-import install
+from install import gnutr_version
+from config import get_value
 
 import gnutr_stock
 import gnutr_widgets
@@ -64,24 +65,6 @@
         self.plan_button = toolbar.append_button('gnutr-plan', 'Plan', 
tooltips, 'Switch view to plan')
         self.food_button = toolbar.append_button('gnutr-food', 'Food', 
tooltips, 'Switch view to food')
 
-# the original version of the buttons (using the deprecated API) looks
-# a bit different, buttons are smaller and have some padding around
-# them:
-
-#         vbox4 = gtk.VBox()
-#         vbox4.set_border_width(10)
-#         self.recipe_button = gtk.Button()
-#         icon2 = gtk.Image()
-#         icon2.set_from_stock('gnutr-recipe', gtk.ICON_SIZE_LARGE_TOOLBAR)
-#         self.recipe_button.add(icon2)
-#         self.recipe_button.set_relief(gtk.RELIEF_NONE)
-#         vbox4.pack_start(self.recipe_button)
-
-#         label3 = gtk.Label('Recipe')
-#         vbox4.pack_start(label3)
-#         toolbar.append_widget(vbox4, 'Switch view to recipe', None)
-
-
         self.pane_box = gtk.HBox(False, 0)
         self.pane_box.set_border_width(2)
         hpaned1.pack2(self.pane_box, True, True)
@@ -94,13 +77,17 @@
             gtk.RESPONSE_CANCEL))
         self.about_dlg.set_resizable(False)
         about_label = gtk.Label(
-"""GNUtrition %s
-A Diet and Nutrition Analysis Program
-
+"""GNUtrition {0:s}
+A Diet and Nutrition Analysis Program using the USDA
+National Nutrient Database for Standard Reference.
+Current database version is SR{1:s}.
+ 
 (C) 2002 Edgar Denny
 (C) 2010 2012 Free Software Foundation, Inc.
 
-http://www.gnu.org/software/gnutrition/"""; % (install.VERSION))
+http://www.gnu.org/software/gnutrition/""".format(gnutr_version(),
+                                                  get_value('SR')))
+
         about_label.set_justify(gtk.JUSTIFY_CENTER)
         vbox6 = gtk.VBox()
         vbox6.set_border_width(5)

=== modified file 'src/database.py'
--- a/src/database.py   2012-09-30 23:13:51 +0000
+++ b/src/database.py   2012-10-14 22:23:01 +0000
@@ -38,18 +38,38 @@
         return True
     return False
 
-def to_days(datestr):
+def days_since(start_year, datestr):
+    Y = int(start_year)
+    # check for >= 1900 && < 2100
+    c = Y/100
+    if not c in [19,20]:
+        raise Exception("Start year must be 1900 <= y < 2100")
+    if not datestr:
+        raise Exception("Date string required.")
     #          J  F  M  A  M  J  J  A  S  O  N  D
-    months =  [31,28,31,20,31,30,31,31,30,31,30,31]
+    days_in_month =  [31,28,31,20,31,30,31,31,30,31,30,31]
     ymd = datestr.split('-')
-    year = int(ymd[0])
-    # We only need to know if we are spanning Feb 29
-    # BTW: the next year is 2016
-    if leap_year(year):
-        months[1] = 29
-    days = (year - 1900) * 365; 
-    days = days + months[int(ymd[1])] + int(ymd[2])
-    return days
+    if len(ymd) != 3:
+        raise Exception("Date string must be in YYYY-MM-DD format.")
+    Y,M,D = int(ymd[0]), int(ymd[1]), int(ymd[2])
+    days = 0
+    # Accumulate days since start_year, four years at a time, and adjust for 
leap year
+    for y in range(start_year, Y):
+        days = days + 365
+        if leap_year(y):
+            days = days + 1
+    if leap_year(Y):
+        days_in_month[1] = 29
+    for m in range(0, M-1):
+        days = days + days_in_month[m]
+    days = days + D
+    return days - 1  # Not inclusive- days_since(2012, 2012-01-01) is zero
+
+def to_days(datestr=None):
+    # Replacement for MySQLs TO_DAYS() function:
+    # The app only uses this function for a difference calculation in calandar
+    # days. The arbitrary starting point is January 1, 1900.
+    return days_since(1900, datestr)
 
 dbms.register_adapter(datetime.datetime, curtime)
 dbms.register_adapter(datetime.datetime, curdate)
@@ -87,13 +107,14 @@
         if self.con:
             self.con.close()
 
-    def initialize(self):
+    def init_core(self):
+        """Load the USDA Standard Reference release data."""
         # Create Food Description (food_des) table.
         # Data file FOOD_DES.
         self.query("DROP TABLE IF EXISTS food_des")
         self.create_load_table("CREATE TABLE food_des" +
-            "(NDB_No INTEGER NOT NULL, " + 
-            "FdGrp_Cd INTEGER NOT NULL, " + 
+            "(NDB_No TEXT NOT NULL, " + 
+            "FdGrp_Cd TEXT NOT NULL, " + 
             "Long_Desc TEXT NOT NULL, " + 
             "Shrt_Desc TEXT NOT NULL, " + 
             # Three new fields for sr24
@@ -118,7 +139,7 @@
         # Data file FD_GROUP.
         self.query("DROP TABLE IF EXISTS fd_group")
         self.create_load_table("CREATE TABLE fd_group " + 
-            "(FdGrp_Cd INTEGER PRIMARY KEY NOT NULL, " + 
+            "(FdGrp_Cd TEXT PRIMARY KEY NOT NULL, " + 
             "FdGrp_Desc TEXT NOT NULL)",
             ### Insert statement for one row
             "INSERT INTO 'fd_group' VALUES (?, ?)",
@@ -128,8 +149,8 @@
         # Data file NUT_DATA
         self.query("DROP TABLE IF EXISTS nut_data")
         self.create_load_table("CREATE TABLE nut_data " + 
-            "(NDB_No INTEGER NOT NULL, " + 
-            "Nutr_No INTEGER NOT NULL, " + 
+            "(NDB_No TEXT NOT NULL, " + 
+            "Nutr_No TEXT NOT NULL, " + 
             "Nutr_Val REAL NOT NULL, " + 
             "Num_Data_Pts REAL NOT NULL, " + 
             "Std_Error REAL, " + 
@@ -156,7 +177,7 @@
         # Data file NUTR_DEF
         self.query("DROP TABLE IF EXISTS nutr_def")
         self.create_load_table("CREATE TABLE nutr_def " + 
-            "(Nutr_No INTEGER PRIMARY KEY NOT NULL, " + 
+            "(Nutr_No TEXT PRIMARY KEY NOT NULL, " + 
             "Units TEXT NOT NULL, " +
             "Tagname TEXT, " +
             "NutrDesc TEXT NOT NULL, " +
@@ -172,7 +193,7 @@
         # Data file WEIGHT.
         self.query("DROP TABLE IF EXISTS weight")
         self.create_load_table("CREATE TABLE weight" +
-            "(NDB_No INTEGER NOT NULL, " +
+            "(NDB_No TEXT NOT NULL, " +
             # Seq == Sequence number for measure description (Msre_Desc)
             # The NDB_No for a food item will appear once for each measure
             # description. Measure descriptions are sequenced. For example:
@@ -194,6 +215,7 @@
             "(?, ?, ?, ?, ?, ?, ?)",
             'weight')
 
+    def init_user(self):
         # May have user data from previous install that we don't want to lose
         # so IF NOT EXISTS is used
 
@@ -211,7 +233,7 @@
             "(recipe_no INTEGER NOT NULL, " + 
             "amount REAL NOT NULL, " +
             "Msre_Desc TEXT NOT NULL, " +
-            "NDB_No INTEGER NOT NULL)", 'ingredient')
+            "NDB_No TEXT NOT NULL)", 'ingredient')
 
         # create recipe category table
         self.create_load_table("CREATE TABLE IF NOT EXISTS category" +
@@ -240,7 +262,7 @@
             "time TEXT NOT NULL, " +
             "amount REAL NOT NULL, " +
             "Msre_Desc TEXT NOT NULL, " +
-            "NDB_No INTEGER NOT NULL)", 'food_plan')
+            "NDB_No TEXT NOT NULL)", 'food_plan')
 
         # create recipe_plan table
         self.create_table("CREATE TABLE IF NOT EXISTS recipe_plan" +
@@ -253,7 +275,7 @@
         # create nutr_goal table
         self.create_table("CREATE TABLE IF NOT EXISTS nutr_goal" +
             "(person_no INTEGER NOT NULL, " +
-            "Nutr_No INTEGER NOT NULL, " +
+            "Nutr_No TEXT NOT NULL, " +
             "goal_val REAL NOT NULL)", 'nutr_goal')
 
         return 1
@@ -346,8 +368,6 @@
         print "created table '{0:s}'".format(tablename)
 
     def load_table(self, sql, data_fn):
-        #self.query("LOAD DATA LOCAL INFILE '"+ fn + "' " +
-        #    "INTO TABLE " + table + " FIELDS TERMINATED BY '^'")
         import csv
         try:
             data = csv.reader(open(data_fn,'r'), delimiter='^', quotechar="'")
@@ -391,6 +411,128 @@
             m += 1
         return m
 
+# These next two are only valid for MySQL database 
+def msre_desc_from_msre_no(mysql=None, msre_no=None):
+    if not (mysql and msre_no):
+        raise Exception("Parameters for MySQL instance and/or msre_no 
missing.")
+    sql = "SELECT msre_desc FROM measure WHERE msre_no = {0:d}"
+    mysql.query(sql.format(msre_no))
+    return mysql.get_single_result()
+
+# Need to be careful here; MySQL db uses int fields in places where SQLite
+# is not.
+def gm_wgt_from_fd_and_msre(mysql, NDB_No, Msre_No):
+    sql = "SELECT wgt_val FROM weight WHERE fd_no = {0:d}" +\
+          " AND msre_no = {1:d}"
+    mysql.query(sql.format(int(NDB_No), int(Msre_No)))
+    return mysql.get_single_result()
+
+# This is only valid for initialized database.Database() class
+def latest_Msre_Desc_for_NDB_No(sqlite, NDB_No):
+    sql = "SELECT Msre_Desc, Gm_wgt FROM weight WHERE NDB_No = '{0:s}'"
+    ndb_no = str(NDB_No)
+    # HERE: no leading zeros from NDB_No values from MySQL tables.
+    if len(ndb_no) < 5:
+        ndb_no = '0' + ndb_no
+    sqlite.query(sql.format(ndb_no))
+    desc_list = sqlite.get_result()
+    if not desc_list:
+        return ([],[]) # Nothing we can do about this...
+    all_desc = []
+    all_weights = []
+    for choice in desc_list: 
+        all_desc.append(choice[0])
+        all_weights.append(choice[1])
+    print 'latest_Msre_Desc_for_NDB_No({0:s}):'.format(str(ndb_no)), all_desc
+    print 'latest_Msre_Desc_for_NDB_No({0:s}):'.format(str(ndb_no)), 
all_weights
+    return (all_desc, all_weights)
+
+def find_closest(desc_list, desc):
+    """Attempt to find a close match for Msre_Desc.
+    Parameter desc_list is a list of all Msre_Desc for a particular NDB_No.
+    Parameter desc is a specific Msre_Desc.
+    """
+    import re
+    possible = []
+    for haystack in desc_list:
+        # First try searching for desc in each MsreDesc
+        if len(desc) <= len(haystack):
+            m = re.search(desc, haystack)
+            if m:
+                possible.append(m.group(0))
+        # and the reverse
+        if len(haystack) <= len(desc):
+            m = re.search(haystack, desc)
+            if m:
+                possible.append(m.group(0))
+        print 'find_closest:', desc_list, desc
+        print '  result:', possible
+    
+def to_Msre_Desc(sqlite=None, mysql=None,
+                            NDB_No=None, Msre_Desc=None, Msre_No=None):
+    """Return a measurement deescription from current database.
+
+    Given Nutrient Database Number NDB_No and one of measure description
+    or measure number, find and return the appropriate MsreDesc from the
+    current USDA Standard Reference data.
+
+    Parameter sqlite must be an initialized instance of database.Database()
+    class.
+    Parameter mysql is needed if parameter Msre_No is given, and must
+    be an instance of mysql.Database() class.
+    """
+    if not sqlite:
+        raise Exception("sqlite parameter for SQLite3 instance missing.")
+    if Msre_No and not mysql:
+        raise Exception("mysql parameter for MySQL instance missing.")
+    if not NDB_No:
+        raise Exception("NDB_No parameter missing.")
+    if not (Msre_Desc or Msre_No) and not (Msre_Desc and Msre_No):
+        raise Exception("Either Msre_Desc or Msre_No must be given.")
+    if Msre_No:
+        desc = msre_desc_from_msre_no(mysql, Msre_No)
+    else:
+        desc = Msre_Desc
+
+    # First see if we have exact match
+    (desc_list, wgt_list) = latest_Msre_Desc_for_NDB_No(sqlite, NDB_No)
+    for d in desc_list:
+        if d == desc:
+            return d  # Great
+
+    # Next see if we can match gram weights. If we can chances are excellent
+    # we then derive the correct Msre_Desc.
+    if Msre_No:
+        gwt = gm_wgt_from_fd_and_msre(mysql, NDB_No, Msre_No)
+        for wt in range(len(wgt_list)):
+            if wgt_list[wt] == gwt:
+                return desc_list[wt]
+
+        # Next see if we are close
+        for wt in range(len(wgt_list)):
+            wgt = wgt_list[wt]
+            # Check +/- five percent of rounded gram weights
+            # Round up
+            if int(wgt+.05) == int(gwt+0.5):
+                return desc_list[wt]
+            # Round down
+            if int(wgt-.05) == int(gwt-0.5):
+                return desc_list[wt]
+    # Still here?
+    description = find_closest(desc_list, desc)
+    if not description:
+        print 'No Msre_Desc found for desc {0:s} and NDB_No {1:d}'.format(
+                desc, NDB_No)
+        print 'All Msre_Desc for NDB_No:', desc_list
+    return description
+
+    # Try to find closest possible match for this measure description and
+    # gram weight. 
+
+#HERE
+def update_data():
+    pass
+
 def migrate(mysql):
     """Retrieve gnutrition table data from MySQL database.
     Parameters uname and pword are the MySQL username and password used with
@@ -419,12 +561,6 @@
     # 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)
 
-    # For gnutrition version < 0.32
-    def msre_desc_from_msre_no(msre_no):
-        sql = "SELECT msre_desc FROM measure WHERE msre_no = {0:d}"
-        mysql.query(sql.format(msre_no))
-        return mysql.get_single_result()
-
     # recipie table
     if 'recipe' in found:
         mysql.query("SELECT recipe_no, recipe_name, no_serv, no_ingr, " +
@@ -448,13 +584,19 @@
             print 'found', len(result), 'ingredients'
             print result
             for i in range(len(result)):
+                Msre_No, Msre_Desc = None, None
                 recipe_no = result[i][0]
                 amount = result[i][1]
                 if use_msre_no:
-                    Msre_Desc = msre_desc_from_msre_no(result[i][2])
+                    Msre_No = result[i][2]
                 else:
                     Msre_Desc = result[i][2]
                 NDB_No = result[i][3]
+
+                Msre_Desc = to_Msre_Desc(sqlite=lite, mysql=mysql, 
NDB_No=NDB_No,
+                                            Msre_Desc=Msre_Desc, 
Msre_No=Msre_No)
+                if not Msre_Desc:
+                    Msre_Desc = 'Unknown'
                 params = (recipe_no, amount, Msre_Desc, NDB_No)
                 lite.query("INSERT INTO 'ingredient' VALUES (?,?,?,?)",
                            many=False, sql_params=params, caller='migrate')
@@ -499,6 +641,8 @@
                     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)
                 NDB_No = result[i][5]
                 params = (person_no, date, time[:-3], amount, Msre_Desc, 
NDB_No)
                 lite.query("INSERT INTO 'food_plan' VALUES (?,?,?,?,?,?)",

=== modified file 'src/druid.py'
--- a/src/druid.py      2012-09-26 05:09:15 +0000
+++ b/src/druid.py      2012-10-14 22:23:01 +0000
@@ -56,8 +56,8 @@
                 self.ui.set_page(2)
                 return
             
-            self.sqlite.initialize()
-
+            self.sqlite.init_core()
+            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.
@@ -72,25 +72,9 @@
                 if reply == gtk.RESPONSE_YES:
                     self.migration = True
                     import mysql
-                    try:
-                        self.mysql = mysql.Database(db_uname, db_pword) 
-                    except Exception:
-                        # HERE: add dialog notification about failure to
-                        #       connect to MySQL server with stored username
-                        #       and password.
-                        dialog = Dialog('error',
-                            "Unable to connect to MySQL's GNUtrition 
database.")
-                    else:
-                        if self.mysql.initialize():
-                            # This needs MySQL root username and password
-                            #if self.mysql.user_setup(db_uname, db_pword):
-                            database.migrate(self.mysql)
-                        else:
-                            # HERE: add dialog notification about missing
-                            #       gnutr_db database
-                            dialog = Dialog('error',
-                              "MySQL GNUtrition database no longer exists.")
-
+                    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

=== modified file 'src/food_srch_dlg.py'
--- a/src/food_srch_dlg.py      2012-09-30 23:13:51 +0000
+++ b/src/food_srch_dlg.py      2012-10-14 22:23:01 +0000
@@ -118,7 +118,7 @@
         else:
             fg_num = self.store.fg_desc2num[fg_desc]
             self.db.query("SELECT NDB_No FROM food_des " +
-                "WHERE FdGrp_Cd = %d AND %s" % (fg_num, where))
+                "WHERE FdGrp_Cd = '%s' AND %s" % (fg_num, where))
         result = self.db.get_result()
 
         food_num_list = []
@@ -172,8 +172,8 @@
         for nutr_desc, constraint in constr_list:
             nutr_num = dict[nutr_desc]
             nutr_tot_list.append((nutr_num, '0.0', constraint))
-            query = query + " Nutr_No = %d OR" % (nutr_num)
-        query = query + " Nutr_No = 208 )"
+            query = query + " Nutr_No = '%s' OR" % (nutr_num)
+        query = query + " Nutr_No = '208' )"
 
         dict = self.store.fg_desc2num
         if fg_desc == 'All Foods':
@@ -183,7 +183,7 @@
             fg_num = self.store.fg_desc2num[fg_desc]
             query = ("SELECT nut_data.NDB_No, Nutr_No, Nutr_Val FROM " +
                 "nut_data, food_des WHERE " +
-                "food_des.FdGrp_Cd = {0:d} AND ".format(fg_num) +
+                "food_des.FdGrp_Cd = '{0:s}' AND ".format(fg_num) +
                 "nut_data.NDB_No = food_des.NDB_No AND " + query)
         self.db.query(query)
         result = self.db.get_result()

=== modified file 'src/gnutr_consts.py'
--- a/src/gnutr_consts.py       2012-09-26 05:09:15 +0000
+++ b/src/gnutr_consts.py       2012-10-14 22:23:01 +0000
@@ -21,8 +21,12 @@
 CHECK_DISABLED = False
 # Next two can be changed by user
 CHECK_VERSION = True
-CHECK_INTERVAL = 604800   # 60*60*24*7
-LATEST_VERSION = "http://www.gnu.org/software/gnutrition/version";
+CHECK_INTERVAL = 604800   # 60*60*24*7 (one week)
+
+# This file has version information for both the latest application version
+# and the current USDA Standard Reference Database version.
+BASE_URL = "http://www.gnu.org/software/gnutrition/";
+LATEST_VERSION = BASE_URL + "version"
 
 PLAN = 0
 RECIPE = 1

=== modified file 'src/install.py.in'
--- a/src/install.py.in 2012-07-25 04:49:08 +0000
+++ b/src/install.py.in 2012-10-14 22:23:01 +0000
@@ -16,5 +16,9 @@
 MAJOR_VERSION = @MAJOR_VERSION@
 MINOR_VERSION = @MINOR_VERSION@
 REVISION = @REVISION@
-VERSION = "@address@hidden@address@hidden@REVISION@"
+GNUTR_VERSION = "@address@hidden@address@hidden@REVISION@"
+
 idir = "@prefix@/share/gnutrition"
+
+def gnutr_version():
+       return GNUTR_VERSION

=== modified file 'src/mysql.py'
--- a/src/mysql.py      2012-09-26 05:09:15 +0000
+++ b/src/mysql.py      2012-10-14 22:23:01 +0000
@@ -16,7 +16,6 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import MySQLdb
-import warnings
 
 class Database:
     _shared_state = {}
@@ -24,26 +23,12 @@
         self.__dict__ = self._shared_state
         if self._shared_state:
             return
-    # supress warning on "DROP TABLE IF EXISTS" for temp tables
-        warnings.filterwarnings("ignore", "Unknown table.*_temp")
-    # supress 'Data truncated ...' 
-        warnings.filterwarnings("ignore", "Data truncated*")
-
         self.db = MySQLdb.Connect(user=uname, passwd=pword)
         self.cursor = self.db.cursor()
         self.user = uname
         self.rows = 0
         self.result = None
  
-    def change_user(self, uname, pword, dbase): 
-        try:
-            self.db = MySQLdb.Connect(user=uname, passwd=pword, db=dbase)
-            self.cursor = self.db.cursor()
-            self.user = uname
-        except:
-            return 0
-        return 1
-
     def initialize(self):
         self.query('SHOW DATABASES')
         db_list = self.get_result()
@@ -67,7 +52,6 @@
         self.result = self.cursor.fetchall()
         self.rows = self.db.affected_rows()
         self.db.commit()
-#        return self.get_result()
 
     def get_result(self):
         result = self.result
@@ -99,78 +83,39 @@
         print 'Error: not a single value'
         return None
 
-    def create_table(self, query, tablename):
-        self.query(query)
-        print "table created: ", tablename
-
-    def load_table(self, fn, table):
-        self.query("LOAD DATA LOCAL INFILE '"+ fn + "' " +
-            "INTO TABLE " + table + " FIELDS TERMINATED BY '^'")
-
-    def create_load_table(self, query, filename):
-        import install
-        from os import path
-        self.create_table(query, filename)
-        fn = path.join(install.idir,'data',filename.upper() + '.txt')
-        self.load_table(fn, filename)
-        print "table loaded: ", filename
-
-    def add_user(self, user, password):
-        self.query("GRANT USAGE ON *.* TO " + user +
-            "@localhost IDENTIFIED BY '" + password + "'")
-        self.query("GRANT ALL ON gnutr_db.* TO " + user + 
-            "@localhost IDENTIFIED BY '" + password + "'")
-        self.query("FLUSH PRIVILEGES")
-
     def delete_db(self):
         self.query("DROP DATABASE gnutr_db")
 
-    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.mysql.add_user(uname, pword)
-            else:
-                # HERE: add dialog notifying that ...
-                return 0
+def open_mysqldb(user=None, passwd=None):
+    from gnutr import Dialog
+    db_uname, db_pword = None, None
+    if user and passwd:
+        db_uname, db_pword = user, passwd
+    else:
+        import config
+        # Username and Password would be left over from MySQL versions
+        # of GNUtrition.
+        db_uname = config.get_value('Username')
+        db_pword = config.get_value('Password')
+    if (db_uname and db_pword):
+        try:
+            db_instance = Database(db_uname, db_pword)
+        except Exception:
+            Dialog('error',"Unable to connect to MySQL's GNUtrition database.")
+            return False
         else:
-            # HERE: add dialog notifying that ...
-            return 0
-        return 1
-
-    def user_name_exists(self, uname):
-        self.mysql.query("USE mysql")
-        self.mysql.query("SELECT User FROM user WHERE " +
-            "User = '" + uname + "'")
-        name = self.mysql.get_single_result()
-        if not name:
-            return 0
-        return 1
-
-    def password_match(self, uname, pword):
-        # check to see if the password is correct
-        self.mysql.query("SELECT Password FROM user WHERE " +
-            "User = '" + str(uname) + "'")
-        result1 = self.mysql.get_single_result()
-        self.db.query("SELECT PASSWORD('" + str(pword) + "')")
-        result2 = self.mysql.get_single_result()
-        if result1 == result2:
-            return 1;
-        return 0
-
-    def user_db_access(self, uname):
-        # does the user have access to the gnutr_db?
-        self.mysql.query("SELECT Db FROM db WHERE " +
-            "User = '" + str(uname) + "'")
-        result = self.mysql.get_result()
-        for db_name in result:
-            if db_name[0] == 'gnutr_db':
-                return 1
-        return 0
+            if not db_instance.initialize():
+                Dialog('error', "MySQL GNUtrition database no longer exists!")
+                return False
+    else:
+        return False
+    return db_instance
+
+if __name__ == '__main__':
+    import sys
+    if open_mysqldb():
+        print 'Successful MySQL database test.'
+    else:
+        print 'MySQL database test failed.', db
+        sys.exit(1)
+    sys.exit(0)

=== modified file 'src/nutr_composition_dlg.py'
--- a/src/nutr_composition_dlg.py       2012-09-30 23:13:51 +0000
+++ b/src/nutr_composition_dlg.py       2012-10-14 22:23:01 +0000
@@ -90,11 +90,11 @@
     def add_food_to_nutr_total(self, amount, msre_desc, food_num):
 
         self.db.query("SELECT Nutr_No, Nutr_Val FROM nut_data " +
-            "WHERE NDB_No = %d" % (food_num))
+            "WHERE NDB_No = '%s'" % (food_num))
         list_food_nutr = self.db.get_result()
 
         self.db.query("SELECT Gm_wgt FROM weight " +
-            "WHERE NDB_No = {0:d}  AND Msre_Desc ='{1:s}'".format(
+            "WHERE NDB_No = '{0:s}'  AND Msre_Desc ='{1:s}'".format(
                     food_num, msre_desc))
         gm_per_msre = self.db.get_single_result()
 

=== modified file 'src/person.py'
--- a/src/person.py     2012-09-30 23:13:51 +0000
+++ b/src/person.py     2012-10-14 22:23:01 +0000
@@ -65,7 +65,7 @@
             "time TEXT NOT NULL, " + 
             "amount REAL NOT NULL, " +
             "Msre_Desc TEXT NOT NULL, " +
-            "NDB_No INTEGER NOT NULL, " +
+            "NDB_No TEXT NOT NULL, " +
             "PRIMARY KEY (date, time, NDB_No))")
 
         #self.db.query("CREATE TEMPORARY TABLE recipe_plan_temp " +
@@ -85,7 +85,7 @@
         if result and len(result) != 0:
             for person_no, date, time, amount, msre_desc, ndb_no in result:
                 self.db.query("INSERT INTO food_plan_temp VALUES" +
-                    "(%d, '%s', '%s', %f, '%s', %d )"
+                    "(%d, '%s', '%s', %f, '%s', '%s' )"
                     %(person_no, str(date), str(time), amount, msre_desc, 
ndb_no),
                         caller='Person.setup')
 

=== modified file 'src/plan_compute_dlg.py'
--- a/src/plan_compute_dlg.py   2012-09-30 23:13:51 +0000
+++ b/src/plan_compute_dlg.py   2012-10-14 22:23:01 +0000
@@ -124,13 +124,13 @@
 
     def get_food_nutrients(self, food_num):
         self.db.query("SELECT Nutr_No, Nutr_Val FROM nut_data " +
-            "WHERE NDB_No = %d" %(food_num))
+            "WHERE NDB_No = '%s'" %(food_num))
         return self.db.get_result()
 
     #HERE: take into account Amount unit modifier?
     def get_gm_per_measure(self, food_num, msre_desc):
         self.db.query("SELECT Gm_wgt FROM weight WHERE " +
-            "NDB_No = %d AND Msre_Desc = '%s'" %(food_num, msre_desc))
+            "NDB_No = '%s' AND Msre_Desc = '%s'" %(food_num, msre_desc))
         return float(self.db.get_single_result())
 
     def add_food_nutr_comp(self, tot_list, food_num, amount, gm_per_msre):

=== modified file 'src/plan_win.py'
--- a/src/plan_win.py   2012-09-30 23:13:51 +0000
+++ b/src/plan_win.py   2012-10-14 22:23:01 +0000
@@ -308,11 +308,11 @@
         return food_list
 
     def food_desc_from_NDB_No(self, food_no):
-        self.db.query("SELECT Long_Desc FROM food_des WHERE NDB_No = 
{0:d}".format(food_no))
+        self.db.query("SELECT Long_Desc FROM food_des WHERE NDB_No = 
'{0:s}'".format(food_no))
         return self.db.get_result()
 
     def food_quantity_info(self, food_no, msre_desc):
-        self.db.query("SELECT Amount, Gm_wgt FROM weight WHERE NDB_No = {0:d}" 
+
+        self.db.query("SELECT Amount, Gm_wgt FROM weight WHERE NDB_No = 
'{0:s}'" +
             "AND Msre_Desc = '{1:s}'".format(food_no, msre_desc))
         return self.db.get_result()
 
@@ -354,7 +354,7 @@
     def delete_from_plan_temp_db(self, date, food=None, recipe=None):
         if food:
             self.db.query("DELETE FROM food_plan_temp WHERE " +
-                "date = '%s' AND time = '%s' AND NDB_No = %d"
+                "date = '%s' AND time = '%s' AND NDB_No = '%s'"
                 %(date, food.time, food.food_num))
         else:
             self.db.query("DELETE FROM recipe_plan_temp WHERE " +
@@ -364,7 +364,7 @@
     def edit_plan_temp_db(self, date, food=None, recipe=None):
         if food:
             self.db.query("SELECT * FROM food_plan_temp WHERE " +
-                "date = '{0:s}' AND time = '{1:s}' AND NDB_No = {2:d}".format(
+                "date = '{0:s}' AND time = '{1:s}' AND NDB_No = 
'{2:s}'".format(
                                        date, food.time, food.food_num))
             data = self.db.get_result()
             # FIXME: catches a bug where two foods have the same name,
@@ -376,10 +376,10 @@
                 data
 
             self.db.query("DELETE FROM food_plan_temp WHERE " +
-                "date = '%s' AND time = '%s' AND NDB_No = %d"
+                "date = '%s' AND time = '%s' AND NDB_No = '%s'"
                 %(date, food.time, food.food_num))
             self.db.query("INSERT INTO food_plan_temp VALUES (" +
-                "{0:d}, '{1:s}', '{2:s}', {3:f}, '{4:s}', {5:d})".format(
+                "{0:d}, '{1:s}', '{2:s}', {3:f}, '{4:s}', '{5:s}')".format(
                 person_num, date2, time, food.amount, food.msre_desc,food_num),
                 caller='PlanWin.edit_plan_temp_db')
         else:

=== modified file 'src/recipe_win.py'
--- a/src/recipe_win.py 2012-09-30 23:13:51 +0000
+++ b/src/recipe_win.py 2012-10-14 22:23:01 +0000
@@ -209,7 +209,7 @@
 
         for ingr in recipe.ingr_list:
             self.db.query("INSERT INTO ingredient VALUES" +
-                "({0:d}, {1:f}, '{2:s}', {3:d})".format(recipe_no,
+                "({0:d}, {1:f}, '{2:s}', '{3:s}')".format(recipe_no,
                 ingr.amount, ingr.msre_desc, ingr.food_num),
                 caller='RecipeWin.save_recipe')
 

=== modified file 'src/store.py'
--- a/src/store.py      2012-09-30 23:13:51 +0000
+++ b/src/store.py      2012-10-14 22:23:01 +0000
@@ -106,6 +106,6 @@
 
     def get_msre_desc_tuples(self, fd_num):
         self.db.query("SELECT Msre_Desc FROM weight WHERE " +
-            "NDB_No = {0:d}".format(fd_num))
+            "NDB_No = '{0:s}'".format(fd_num))
         result = self.db.get_result()
         return result

=== modified file 'src/version.py'
--- a/src/version.py    2012-06-26 19:06:03 +0000
+++ b/src/version.py    2012-10-14 22:23:01 +0000
@@ -26,20 +26,29 @@
         print e
         return "0.0" # Force update bypass
     reex = r"""
-            version"[\s+]?:    #   version":
+            "version"[\s+]?:   #   version":
             [\s+]?"            #  leading junk
-            (?P<version>([0-9]+[.]?)+)  # target match
-            ["][\s+]?,(.+)?$   #  trailing junk until end of line
-            .*"                #  leading junk
-            message"[\s+]?:    #  message":
+            (?P<VER>([0-9]+[.]?)+)  # target match
+            ["][\s+]?,(.+)?$   #  trailing junk until end of line
+            .*"sr"[\s+]?:      #  "sr":
+            [\s+]?"            #  Allow for white space
+            (?P<SR>[2-9][0-9]) # target match  (database version)
+            ["][\s+]?,(.+)?$   #  trailing junk until end of line
+            .*"sr_url"[\s+]?:  #  "sr_url":
+            [\s+]?"            #  Allow for white space
+            (?P<SR_URL>http:..*) #  target match   (where we get database from)
+            ["][\s+]?,(.+)?$   #  trailing junk until end of line
+            .*"message"[\s+]?:    #  "message":
             [\s+]?"            #  eat white space
             (?P<message>.*\.)["]  # target match
             """
     reobj = re.compile(reex, re.X|re.M|re.S)
     m = re.search(reobj, obj.read())
     if m:
-        return (m.group('version'), m.group('message'))
-    return ('0.0', None)
+        config.set_key_value('SR', m.group('SR'))
+        return (m.group('VER'), m.group('SR'),
+                m.group('SR_URL'), m.group('message'))
+    return ('0.0', None, None, None)
 
 def cmp_version_strings(this_ver, curr_ver):
     s1 = this_ver.split('.')
@@ -69,10 +78,30 @@
         msg += '\n{0:s}'.format(message)
     gnutr.Dialog('notify', msg)
 
+def get_database_archive(url):
+    import gnutr_consts
+    from urllib2 import Request, urlopen, URLError, HTTPError
+    from os.path import basename
+    success = 0
+    req = Request(url)
+    try:
+        f = urlopen(req)
+        # HERE: where do we put the file?
+        local_file = open(basename(url), "wb")
+        local_file.write(f.read())
+        local_file.close()
+    except HTTPError, e:
+        print "HTTP Error:",e.code , url
+        success = 1
+    except URLError, e:
+        print "URL Error:",e.reason , url
+        success = 1
+    return success
+
 def check_version():
     import gnutr_consts
     import install
-    this_ver = install.VERSION
+    this_ver = install.gnutr_version()
     if config.get_value('check_disabled') or not 
config.get_value('check_version'):
         return 0
     import time
@@ -80,14 +109,14 @@
     last_check = config.get_value('last_check')
     time_now = time.time()
     if (time_now - last_check > interval):
-        (curr_ver, mesg) = get_latest_version(gnutr_consts.LATEST_VERSION) 
+        (curr_ver, sr, sr_url, mesg) = 
get_latest_version(gnutr_consts.LATEST_VERSION) 
+        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:
-#HERE: Check for existing MySQL db and ask about migration/deletion
             update_version(curr_ver, mesg)
     last_check = config.set_key_value('last_check',time_now)
     return 1
@@ -103,7 +132,14 @@
         print 'False ==', cmp_ver_strings("0.2.1", "0.2")
     import gnutr_consts
     url = gnutr_consts.LATEST_VERSION
-    (ver,msg) = get_latest_version(url)
+    (ver,sr,sr_url,msg) = get_latest_version(url)
     print 'latest version available:', ver
+    print 'SR:', sr
+    print 'SR URL:', sr_url
     print 'version message:', msg
+
+    if not sr_url: exit()
+
     #str_cmp_test()
+    if get_database_archive(sr_url) == 0:
+               print 'sr{0:s} successfully downloaded'.format(sr)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]