return False
cr = pooler.get_db(db).cursor()
try:
- # We autocommit: our single request will be performed atomically.
+ # autocommit: our single request will be performed atomically.
# (In this way, there is no opportunity to have two transactions
- # interleaving ther cr.execute()..cr.commit() calls and have one
- # of them rollbacked due to a concurrent access.)
+ # interleaving their cr.execute()..cr.commit() calls and have one
+ # of them rolled back due to a concurrent access.)
# We effectively unconditionally write the res_users line.
cr.autocommit(True)
+ # Even w/ autocommit there's a chance the user row will be locked,
+ # in which case we can't delay the login just for the purpose of
+ # update the last login date - hence we use FOR UPDATE NOWAIT to
+ # try to get the lock - fail-fast
+ cr.execute("""SELECT id from res_users
+ WHERE login=%s AND password=%s
+ AND active FOR UPDATE NOWAIT""",
+ (tools.ustr(login), tools.ustr(password)))
cr.execute("""UPDATE res_users
SET date = now() AT TIME ZONE 'UTC'
- WHERE login=%s AND password=%s AND active RETURNING id""",
+ WHERE login=%s AND password=%s AND active
+ RETURNING id""",
+ (tools.ustr(login), tools.ustr(password)))
+ except Exception:
+ # Failing to acquire the lock on the res_users row probably means
+ # another request is holding it. No big deal, we don't want to
+ # prevent/delay login in that case. It will also have been logged
+ # as a SQL error, if anyone cares.
+ cr.execute("""SELECT id from res_users
+ WHERE login=%s AND password=%s
+ AND active""",
(tools.ustr(login), tools.ustr(password)))
+ finally:
res = cr.fetchone()
+ cr.close()
if res:
return res[0]
- else:
- return False
- finally:
- cr.close()
+ return False
def check_super(self, passwd):
if passwd == tools.config['admin_passwd']:
import base64
import datetime as DT
import logging
+import pytz
import re
-import string
-import sys
import xmlrpclib
from psycopg2 import Binary
import openerp
-import openerp.netsvc as netsvc
import openerp.tools as tools
from openerp.tools.translate import _
from openerp.tools import float_round, float_repr
class date(_column):
_type = 'date'
+
@staticmethod
def today(*args):
""" Returns the current date in a format fit for being a
return DT.date.today().strftime(
tools.DEFAULT_SERVER_DATE_FORMAT)
+ @staticmethod
+ def context_today(cr, uid, today=None, context=None):
+ """Returns the current date as seen in the client's timezone
+ in a format fit for date fields.
+ This method may be passed as value to initialize _defaults.
+
+ :param datetime today: optional date value to use instead of
+ the current date"""
+ today = DT.datetime.now()
+ context_today = None
+ if context and context.get('tz'):
+ try:
+ utc = pytz.timezone('UTC')
+ context_tz = pytz.timezone(context['tz'])
+ utc_today = utc.localize(today, is_dst=False)
+ context_today = utc_today.astimezone(context_tz)
+ except Exception:
+ _logger.debug("failed to compute context/client-specific today date, "
+ "using the UTC value for `today`",
+ exc_info=True)
+ return (context_today or today).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+
class datetime(_column):
_type = 'datetime'
@staticmethod