Remove egenix-mx-base and replace it by python-dateutil

This commit is contained in:
Cédric Krier
2009-12-17 11:39:05 +01:00
parent 097b2fe60b
commit 2a486149cd
14 changed files with 145 additions and 133 deletions
+1
View File
@@ -1,3 +1,4 @@
* Remove egenix-mx-base and replace it by python-dateutil
* Add cache to safe_eval
* Use versioned configuration directory
* Next and Previous scroll per page on list and don't loop
+1 -1
View File
@@ -7,7 +7,7 @@ Prerequisites
* Python 2.4 or later (http://www.python.org/)
* pygtk 2.0 or later (http://www.pygtk.org/)
* librsvg (http://librsvg.sourceforge.net/)
* egenix-mx-base (http://www.egenix.com/products/python/mxBase/)
* python-dateutil (http://labix.org/python-dateutil)
* Optional: pytz (http://pytz.sourceforge.net/)
Installation
+1 -1
View File
@@ -114,7 +114,7 @@ dist = setup(name=PACKAGE,
license=LICENSE,
install_requires=[
# "pygtk >= 2.0",
"egenix-mx-base",
"python-dateutil",
],
extras_require={
'timezone': ['pytz'],
-5
View File
@@ -19,7 +19,6 @@ from tryton.config import CONFIG, CURRENT_DIR, PREFIX, PIXMAPS_DIR, \
from tryton import translate
from tryton import gui
import traceback
import mx.DateTime
import time
import signal
@@ -46,10 +45,6 @@ class TrytonClient(object):
logging.getLogger().setLevel(
loglevel[CONFIG['logging.default'].upper()])
if not hasattr(mx.DateTime, 'strptime'):
mx.DateTime.strptime = lambda x, y: mx.DateTime.mktime(
time.strptime(x, y))
factory = gtk.IconFactory()
factory.add_default()
+1
View File
@@ -1,3 +1,4 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from common import *
from datetime_strftime import *
+20 -22
View File
@@ -7,10 +7,9 @@ import gtk
import re
import time
from mx.DateTime import RelativeDateTime
from mx.DateTime import DateTime
from mx.DateTime import now
import mx.DateTime
import datetime
from dateutil.relativedelta import relativedelta
from datetime_strftime import datetime_strftime
mapping = {
'%y': ('__', '([_ 0-9][_ 0-9])'),
@@ -145,7 +144,7 @@ class DateEntry(gtk.Entry):
format = format.replace('%Y', '00%Y')
elif dt.year < 1000:
format = format.replace('%Y', '0%Y')
self.set_text(dt.strftime(format))
self.set_text(datetime_strftime(dt, format))
else:
if self.is_focus():
self.set_text(self.initial_value)
@@ -153,7 +152,7 @@ class DateEntry(gtk.Entry):
self.set_text('')
def date_get(self):
tt = time.strftime(self.format, time.localtime())
tt = datetime_strftime(datetime.datetime.now(), self.format)
tc = self.get_text()
if tc == self.initial_value or not tc:
return False
@@ -180,11 +179,11 @@ class DateEntry(gtk.Entry):
tc = tc[:a] + tt[a] + tc[a+1:]
try:
self.set_text(tc)
return mx.DateTime.strptime(tc, self.format)
return datetime.datetime(*time.strptime(tc, self.format)[:6])
except:
tc = tt
self.set_text(tc)
return mx.DateTime.strptime(tc, self.format)
return datetime.datetime(*time.strptime(tc, self.format)[:6])
def delete_text(self, start, end):
self._interactive_input = False
@@ -282,36 +281,35 @@ class ComplexEntry(gtk.HBox):
def compute_date(cmd, dt, format):
lst = {
'^=(\d+)d$': lambda dt, r: dt + \
RelativeDateTime(day=int(r.group(1))),
relativedelta(day=int(r.group(1))),
'^=(\d+)m$': lambda dt, r: dt + \
RelativeDateTime(month=int(r.group(1))),
relativedelta(month=int(r.group(1))),
'^=(\d\d)y$': lambda dt, r: dt + \
RelativeDateTime(year=int(str(dt.year)[:-2] + r.group(1))),
relativedelta(year=int(str(dt.year)[:-2] + r.group(1))),
'^=(\d+)y$': lambda dt, r: dt + \
RelativeDateTime(year=int(r.group(1))),
relativedelta(year=int(r.group(1))),
'^=(\d+)h$': lambda dt, r: dt + \
RelativeDateTime(hour=int(r.group(1))),
relativedelta(hour=int(r.group(1))),
'^([\\+-]\d+)h$': lambda dt, r: dt + \
RelativeDateTime(hours=int(r.group(1))),
relativedelta(hours=int(r.group(1))),
'^([\\+-]\d+)w$': lambda dt, r: dt + \
RelativeDateTime(weeks=int(r.group(1))),
relativedelta(weeks=int(r.group(1))),
'^([\\+-]\d+)d$': lambda dt, r: dt + \
RelativeDateTime(days=int(r.group(1))),
relativedelta(days=int(r.group(1))),
'^([\\+-]\d+)$': lambda dt, r: dt + \
RelativeDateTime(days=int(r.group(1))),
relativedelta(days=int(r.group(1))),
'^([\\+-]\d+)m$': lambda dt, r: dt + \
RelativeDateTime(months=int(r.group(1))),
relativedelta(months=int(r.group(1))),
'^([\\+-]\d+)y$': lambda dt, r: dt + \
RelativeDateTime(years=int(r.group(1))),
'^=$': lambda dt,r: now(),
relativedelta(years=int(r.group(1))),
'^=$': lambda dt,r: datetime.datetime.now(),
'^-$': lambda dt,r: False
}
for r, f in lst.items():
groups = re.match(r, cmd)
if groups:
if not dt:
dt = time.strftime(format, time.localtime())
dt = mx.DateTime.strptime(dt, format)
dt = datetime.datetime.now()
try:
return f(dt, groups)
except:
+50
View File
@@ -0,0 +1,50 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
#Copyright (c) 2002-2007 John D. Hunter; All Rights Reserved
import time
def datetime_strftime(dt, fmt):
'''
Allow datetime strftime formatting for years before 1900.
See http://bugs.python.org/issue1777412
'''
if dt.year > 1900:
return dt.strftime(fmt)
def _findall(text, substr):
# Also finds overlaps
sites = []
i = 0
while True:
j = text.find(substr, i)
if j == -1:
break
sites.append(j)
i = j + 1
return sites
year = dt.year
# For every non-leap year century, advance by
# 6 years to get into the 28-year repeat cycle
delta = 2000 - year
off = 6 * (delta // 100 + delta // 400)
year = year + off
# Move to around the year 2000
year = year + ((2000 - year) // 28) * 28
timetuple = dt.timetuple()
s1 = time.strftime(fmt, (year,) + timetuple[1:])
sites1 = _findall(s1, str(year))
s2 = time.strftime(fmt, (year + 28,) + timetuple[1:])
sites2 = _findall(s2, str(year + 28))
sites = []
for site in sites1:
if site in sites2:
sites.append(site)
s = s1
syear = "%4d" % (dt.year,)
for site in sites:
s = s[:site] + syear + s[site+4:]
return s
+3 -12
View File
@@ -21,8 +21,6 @@ import tryton.common as common
import pango
from tryton.translate import date_format
from tryton.common import DT_FORMAT, DHM_FORMAT, HM_FORMAT
import mx.DateTime
import datetime as DT
_ = gettext.gettext
@@ -269,25 +267,18 @@ class Form(SignalEvent):
if line.get(key, False) \
and key in ('create_date', 'write_date'):
display_format = date_format() + ' ' + HM_FORMAT
if hasattr(line[key], 'timetuple'):
date = mx.DateTime.DateTime(*(line[key].timetuple()[:6]))
else:
date = mx.DateTime.strptime(str(line[key]), DHM_FORMAT)
date = line[key]
if 'timezone' in rpc.CONTEXT:
try:
import pytz
lzone = pytz.timezone(rpc.CONTEXT['timezone'])
szone = pytz.timezone(rpc.TIMEZONE)
datetime = DT.datetime(date.year, date.month,
date.day, date.hour, date.minute,
int(date.second))
sdt = szone.localize(datetime, is_dst=True)
ldt = sdt.astimezone(lzone)
date = mx.DateTime.DateTime(*(
ldt.timetuple()[:6]))
date = ldt
except:
pass
value = date.strftime(display_format)
value = common.datetime_strftime(date, display_format)
message_str += val + ' ' + value +'\n'
message_str += _('Model:') + ' ' + self.model
message(message_str, self.window)
+6 -11
View File
@@ -2,11 +2,11 @@
#this repository contains the full copyright notices and license terms.
from tryton.rpc import RPCProxy
import tryton.rpc as rpc
from tryton.common import DT_FORMAT, DHM_FORMAT, HM_FORMAT, safe_eval
from tryton.common import DT_FORMAT, DHM_FORMAT, HM_FORMAT, safe_eval, \
datetime_strftime
import time
import datetime
from decimal import Decimal
import mx.DateTime
import logging
@@ -185,9 +185,7 @@ class DateTimeField(CharField):
def set_client(self, model, value, force_change=False):
if value:
date = mx.DateTime.strptime(value, DHM_FORMAT)
value = datetime.datetime(date.year, date.month, date.day,
date.hour, date.minute, int(date.second))
value = datetime.datetime(*time.strptime(value, DHM_FORMAT)[:6])
return super(DateTimeField, self).set_client(model, value,
force_change=force_change)
@@ -195,16 +193,14 @@ class DateTimeField(CharField):
value = super(DateTimeField, self).get_client(model)
if not value:
return False
value = mx.DateTime.DateTime(*(value.timetuple()[:6]))
return value.strftime(DHM_FORMAT)
return datetime_strftime(value, DHM_FORMAT)
class DateField(CharField):
def set_client(self, model, value, force_change=False):
if value:
date = mx.DateTime.strptime(value, DT_FORMAT)
value = datetime.date(date.year, date.month, date.day)
value = datetime.date(*time.strptime(value, DT_FORMAT)[:3])
return super(DateField, self).set_client(model, value,
force_change=force_change)
@@ -212,8 +208,7 @@ class DateField(CharField):
value = super(DateField, self).get_client(model)
if not value:
return False
value = mx.DateTime.DateTime(*(value.timetuple()[:6]))
return value.strftime(DT_FORMAT)
return datetime_strftime(value, DT_FORMAT)
class FloatField(CharField):
@@ -1,7 +1,7 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
import time
import datetime as DT
import datetime
import gtk
import gettext
import locale
@@ -9,9 +9,8 @@ from interface import WidgetInterface
import tryton.rpc as rpc
from tryton.common import DT_FORMAT, DHM_FORMAT, HM_FORMAT, message, \
TRYTON_ICON
from tryton.common import date_widget, Tooltips
from tryton.common import date_widget, Tooltips, datetime_strftime
from tryton.translate import date_format
import mx.DateTime
_ = gettext.gettext
@@ -72,10 +71,10 @@ class Calendar(WidgetInterface):
if value == '':
return False
try:
date = mx.DateTime.strptime(value, self.format)
date = datetime.date(*time.strptime(value, self.format)[:3])
except:
return False
return date.strftime(DT_FORMAT)
return datetime_strftime(date, DT_FORMAT)
def set_value(self, model, model_field):
model_field.set_client(model, self.get_value(model))
@@ -92,7 +91,7 @@ class Calendar(WidgetInterface):
else:
if len(value)>10:
value = value[:10]
date = mx.DateTime.strptime(value, DT_FORMAT)
date = datetime.date(*time.strptime(value, DT_FORMAT)[:3])
format = self.format
if date.year < 10:
format = format.replace('%Y', '000%Y')
@@ -100,7 +99,7 @@ class Calendar(WidgetInterface):
format = format.replace('%Y', '00%Y')
elif date.year < 1000:
format = format.replace('%Y', '0%Y')
value = date.strftime(format)
value = datetime_strftime(date, format)
if len(value) > self.entry.get_width_chars():
self.entry.set_width_chars(len(value))
self.entry.set_text(value)
@@ -138,7 +137,7 @@ class Calendar(WidgetInterface):
response = win.run()
if response == gtk.RESPONSE_OK:
year, month, day = cal.get_date()
date = mx.DateTime.DateTime(year, month + 1, day)
date = datetime.date(year, month + 1, day)
format = self.format
if date.year < 10:
format = format.replace('%Y', '000%Y')
@@ -146,7 +145,7 @@ class Calendar(WidgetInterface):
format = format.replace('%Y', '00%Y')
elif date.year < 1000:
format = format.replace('%Y', '0%Y')
self.entry.set_text(date.strftime(format))
self.entry.set_text(datetime_strftime(date, format))
self._focus_out()
self._window.present()
win.destroy()
@@ -207,7 +206,7 @@ class DateTime(WidgetInterface):
if value == '':
return False
try:
date = mx.DateTime.strptime(value, self.format)
date = datetime.datetime(*time.strptime(value, self.format)[:6])
except:
return False
if 'timezone' in rpc.CONTEXT and timezone:
@@ -215,14 +214,12 @@ class DateTime(WidgetInterface):
import pytz
lzone = pytz.timezone(rpc.CONTEXT['timezone'])
szone = pytz.timezone(rpc.TIMEZONE)
datetime = DT.datetime(date.year, date.month, date.day,
date.hour, date.minute, int(date.second))
ldt = lzone.localize(datetime, is_dst=True)
ldt = lzone.localize(date, is_dst=True)
sdt = ldt.astimezone(szone)
date = mx.DateTime.DateTime(*(sdt.timetuple()[:6]))
date = sdt
except:
pass
return date.strftime(DHM_FORMAT)
return datetime_strftime(date, DHM_FORMAT)
def set_value(self, model, model_field):
model_field.set_client(model, self.get_value(model))
@@ -238,17 +235,15 @@ class DateTime(WidgetInterface):
if not dt_val:
self.entry.clear()
else:
date = mx.DateTime.strptime(dt_val, DHM_FORMAT)
date = datetime.datetime(*time.strptime(dt_val, DHM_FORMAT)[:6])
if 'timezone' in rpc.CONTEXT and timezone:
try:
import pytz
lzone = pytz.timezone(rpc.CONTEXT['timezone'])
szone = pytz.timezone(rpc.TIMEZONE)
datetime = DT.datetime(date.year, date.month, date.day,
date.hour, date.minute, int(date.second))
sdt = szone.localize(datetime, is_dst=True)
sdt = szone.localize(date, is_dst=True)
ldt = sdt.astimezone(lzone)
date = mx.DateTime.DateTime(*(ldt.timetuple()[:6]))
date = ldt
except:
pass
format = self.format
@@ -258,7 +253,7 @@ class DateTime(WidgetInterface):
format = format.replace('%Y', '00%Y')
elif date.year < 1000:
format = format.replace('%Y', '0%Y')
value = date.strftime(format)
value = datetime_strftime(date, format)
if len(value) > self.entry.get_width_chars():
self.entry.set_width_chars(len(value))
self.entry.set_text(value)
@@ -315,8 +310,8 @@ class DateTime(WidgetInterface):
year = int(cal.get_date()[0])
month = int(cal.get_date()[1]) + 1
day = int(cal.get_date()[2])
date = mx.DateTime.DateTime(year, month, day, hour, minute)
value = date.strftime(DHM_FORMAT)
date = datetime.datetime(year, month, day, hour, minute)
value = datetime_strftime(date, DHM_FORMAT)
self.show(value, timezone=False)
self._focus_out()
self._window.present()
@@ -3,12 +3,12 @@
#This code is inspired by the pycha project (http://www.lorenzogil.com/projects/pycha/)
import gtk
from tryton.common import hex2rgb, generateColorscheme, DT_FORMAT, \
COLOR_SCHEMES, safe_eval
DHM_FORMAT, COLOR_SCHEMES, safe_eval, datetime_strftime
import locale
import math
import datetime
import mx.DateTime
import time
from dateutil.relativedelta import relativedelta
import tryton.rpc as rpc
import cairo
from tryton.action import Action
@@ -363,27 +363,23 @@ class Graph(gtk.DrawingArea):
self.datas[x][key] += \
float(model[yfield['name']].get(model))
if isinstance(minx, datetime.datetime):
date = mx.DateTime.mktime(time.strptime(str(minx), '%Y-%m-%d %H:%M:%S'))
end_date = mx.DateTime.mktime(time.strptime(str(maxx), '%Y-%m-%d %H:%M:%S'))
while date <= end_date:
key = datetime.datetime(date.year, date.month, date.day, 0, 0, 0)
self.labels[key] = date.strftime(DT_FORMAT)
self.datas.setdefault(key, {})
date = minx
while date <= maxx:
self.labels[date] = datetime_strftime(date, DT_FORMAT)
self.datas.setdefault(date, {})
for yfield in self.yfields:
self.datas[key].setdefault(
self.datas[date].setdefault(
yfield.get('key', yfield['name']), 0.0)
date = date + mx.DateTime.RelativeDateTime(days=1)
date += relativedelta(days=1)
elif isinstance(minx, datetime.date):
date = mx.DateTime.mktime(time.strptime(str(minx), '%Y-%m-%d'))
end_date = mx.DateTime.mktime(time.strptime(str(maxx), '%Y-%m-%d'))
while date <= end_date:
key = datetime.date(date.year, date.month, date.day)
self.labels[key] = date.strftime(DT_FORMAT)
self.datas.setdefault(key, {})
date = minx
while date <= maxx:
self.labels[date] = datetime_strftime(date, DT_FORMAT)
self.datas.setdefault(date, {})
for yfield in self.yfields:
self.datas[key].setdefault(
self.datas[date].setdefault(
yfield.get('key', yfield['name']), 0.0)
date = date + mx.DateTime.RelativeDateTime(days=1)
date += relativedelta(days=1)
def updateArea(self, cr, width, height):
maxylabel = ''
@@ -16,7 +16,7 @@ from tryton.gui.window.view_form.view.form_gtk.one2many import Dialog \
from tryton.gui.window.win_search import WinSearch
import tryton.rpc as rpc
import datetime as DT
import datetime
from tryton.common import DT_FORMAT, DHM_FORMAT, COLORS, node_attributes, \
TRYTON_ICON, HM_FORMAT
import tryton.common as common
@@ -29,7 +29,6 @@ from tryton.common.cellrendererinteger import CellRendererInteger
from tryton.common.cellrendererfloat import CellRendererFloat
from tryton.action import Action
from tryton.translate import date_format
import mx.DateTime
import gettext
_ = gettext.gettext
@@ -381,17 +380,17 @@ class Date(Char):
value = model[self.field_name].get_client(model)
if not value:
return ''
date = mx.DateTime.strptime(value, self.server_format)
return date.strftime(self.display_format)
date = datetime.date(*time.strptime(value, self.server_format)[:3])
return common.datetime_strftime(date, self.display_format)
def value_from_text(self, model, text):
if not text:
return False
try:
date = mx.DateTime.strptime(text, self.display_format)
date = datetime.date(*time.strptime(test, self.display_format)[:3])
except:
return False
return date.strftime(self.server_format)
return common.datetime_strftime(date, self.server_format)
class Datetime(Date):
@@ -407,26 +406,26 @@ class Datetime(Date):
value = model[self.field_name].get_client(model)
if not value:
return ''
date = mx.DateTime.strptime(value, self.server_format)
date = datetime.datetime(*time.strptime(value,
self.server_format)[:6])
if 'timezone' in rpc.CONTEXT:
try:
import pytz
lzone = pytz.timezone(rpc.CONTEXT['timezone'])
szone = pytz.timezone(rpc.TIMEZONE)
datetime = DT.datetime(date.year, date.month, date.day,
date.hour, date.minute, int(date.second))
sdt = szone.localize(datetime, is_dst=True)
sdt = szone.localize(date, is_dst=True)
ldt = sdt.astimezone(lzone)
date = mx.DateTime.DateTime(*(ldt.timetuple()[:6]))
date = ldt
except:
pass
return date.strftime(self.display_format)
return common.datetime_strftime(date, self.display_format)
def value_from_text(self, model, text):
if not text:
return False
try:
date = mx.DateTime.strptime(text, self.display_format)
date = datetime.datetime(*time.strptime(text,
self.display_format)[:6])
except:
return False
if 'timezone' in rpc.CONTEXT:
@@ -434,14 +433,12 @@ class Datetime(Date):
import pytz
lzone = pytz.timezone(rpc.CONTEXT['timezone'])
szone = pytz.timezone(rpc.TIMEZONE)
datetime = DT.datetime(date.year, date.month, date.day,
date.hour, date.minute, int(date.second))
ldt = lzone.localize(datetime, is_dst=True)
ldt = lzone.localize(date, is_dst=True)
sdt = ldt.astimezone(szone)
date = mx.DateTime.DateTime(*(sdt.timetuple()[:6]))
date = sdt
except:
pass
return date.strftime(self.server_format)
return common.datetime_strftime(date, self.server_format)
class Float(Char):
@@ -1,15 +1,14 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
import time
import datetime as DT
import datetime
import gtk
import gettext
import locale
from interface import Interface
from tryton.common import DT_FORMAT, TRYTON_ICON
from tryton.common import date_widget, Tooltips
from tryton.common import date_widget, Tooltips, datetime_strftime
from tryton.translate import date_format
import mx.DateTime
import gobject
_ = gettext.gettext
@@ -99,10 +98,10 @@ class Calendar(Interface):
def _date_get(self, value):
try:
date = mx.DateTime.strptime(value, self.format)
date = datetime.date(*time.strptime(value, self.format)[:3])
except:
return False
return date.strftime(DT_FORMAT)
return datetime_strftime(date, DT_FORMAT)
def _value_get(self):
oper = self.liststore.get_value(self.combo.get_active_iter(), 0)
@@ -136,8 +135,7 @@ class Calendar(Interface):
if not value:
return ''
try:
value = mx.DateTime.DateTime(*(value.timetuple()[:6]))
return value.strftime(self.format)
return datetime_strftime(value, self.format)
except:
return ''
@@ -184,8 +182,8 @@ class Calendar(Interface):
response = win.run()
if response == gtk.RESPONSE_OK:
year, month, day = cal.get_date()
date = mx.DateTime.DateTime(year, month + 1, day)
dest.set_text(date.strftime(self.format))
date = datetime.date(year, month + 1, day)
dest.set_text(datetime_strftime(date, self.format))
win.destroy()
def clear(self):
+8 -13
View File
@@ -7,12 +7,11 @@ from tryton.config import CONFIG
import time
import tryton.rpc as rpc
from parse import Parse
import datetime as DT
import datetime
import locale
from tryton.common import DT_FORMAT, DHM_FORMAT, HM_FORMAT
from tryton.common import HM_FORMAT
import tryton.common as common
from tryton.translate import date_format
import mx.DateTime
FIELDS_LIST_TYPE = {
'boolean': gobject.TYPE_BOOLEAN,
@@ -72,28 +71,24 @@ class ViewTreeModel(gtk.GenericTreeModel, gtk.TreeSortable):
display_format = date_format()
for obj in res_ids:
if obj[field]:
date = mx.DateTime.strptime(str(obj[field]), DT_FORMAT)
obj[field] = date.strftime(display_format)
obj[field] = common.datetime_strftime(obj[field],
display_format)
elif field_type in ('datetime',):
display_format = date_format() + ' ' + HM_FORMAT
for obj in res_ids:
if obj[field]:
date = mx.DateTime.strptime(str(obj[field]), DHM_FORMAT)
if 'timezone' in rpc.CONTEXT:
try:
import pytz
lzone = pytz.timezone(rpc.CONTEXT['timezone'])
szone = pytz.timezone(rpc.TIMEZONE)
datetime = DT.datetime(date.year, date.month,
date.day, date.hour, date.minute,
int(date.second))
sdt = szone.localize(datetime, is_dst=True)
sdt = szone.localize(obj[field], is_dst=True)
ldt = sdt.astimezone(lzone)
date = mx.DateTime.DateTime(*(
ldt.timetuple()[:6]))
obj[field] = ldt
except:
pass
obj[field] = date.strftime(display_format)
obj[field] = common.datetime_strftime(obj[field],
display_format)
elif field_type in ('many2one',):
for obj in res_ids:
if obj[field]: