[Top][All Lists]
[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)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUtrition-commits] /srv/bzr/gnutrition/trunk r15: Several changes mostly related to import of old (MySQL) databases,
Thomas Sinclair <=