mirror of
https://github.com/camptocamp/odoo-cloud-platform.git
synced 2026-06-23 18:04:34 +00:00
Merge pull request #178 from guewen/13.0-redis-json-encode-date
Encode/decode date and datetime in redis sessions
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
# Copyright 2016-2020 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
|
||||
|
||||
import json
|
||||
|
||||
from datetime import date, datetime
|
||||
|
||||
import dateutil
|
||||
|
||||
|
||||
class SessionEncoder(json.JSONEncoder):
|
||||
"""Encode date/datetime objects
|
||||
|
||||
So that we can later recompose them if they were stored in the session
|
||||
"""
|
||||
|
||||
def default(self, obj):
|
||||
if isinstance(obj, datetime):
|
||||
return {"_type": "datetime_isoformat", "value": obj.isoformat()}
|
||||
elif isinstance(obj, date):
|
||||
return {"_type": "date_isoformat", "value": obj.isoformat()}
|
||||
elif isinstance(obj, set):
|
||||
return {"_type": "set", "value": tuple(obj)}
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
|
||||
|
||||
class SessionDecoder(json.JSONDecoder):
|
||||
"""Decode json, recomposing recordsets and date/datetime"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(object_hook=self.object_hook, *args, **kwargs)
|
||||
|
||||
def object_hook(self, obj):
|
||||
if "_type" not in obj:
|
||||
return obj
|
||||
type_ = obj["_type"]
|
||||
if type_ == "datetime_isoformat":
|
||||
return dateutil.parser.parse(obj["value"])
|
||||
elif type_ == "date_isoformat":
|
||||
return dateutil.parser.parse(obj["value"]).date()
|
||||
elif type_ == "set":
|
||||
return set(obj["value"])
|
||||
return obj
|
||||
@@ -6,6 +6,8 @@ import logging
|
||||
|
||||
from werkzeug.contrib.sessions import SessionStore
|
||||
|
||||
from . import json_encoding
|
||||
|
||||
# this is equal to the duration of the session garbage collector in
|
||||
# odoo.http.session_gc()
|
||||
DEFAULT_SESSION_TIMEOUT = 60 * 60 * 24 * 7 # 7 days in seconds
|
||||
@@ -57,7 +59,9 @@ class RedisSessionStore(SessionStore):
|
||||
"expiration of %s seconds for %s",
|
||||
key, expiration, user_msg)
|
||||
|
||||
data = json.dumps(dict(session)).encode('utf-8')
|
||||
data = json.dumps(
|
||||
dict(session), cls=json_encoding.SessionEncoder
|
||||
).encode('utf-8')
|
||||
if self.redis.set(key, data):
|
||||
return self.redis.expire(key, expiration)
|
||||
|
||||
@@ -79,7 +83,9 @@ class RedisSessionStore(SessionStore):
|
||||
"returning a new one", key)
|
||||
return self.new()
|
||||
try:
|
||||
data = json.loads(saved.decode('utf-8'))
|
||||
data = json.loads(
|
||||
saved.decode('utf-8'), cls=json_encoding.SessionDecoder
|
||||
)
|
||||
except ValueError:
|
||||
_logger.debug("session for key '%s' has been asked but its json "
|
||||
"content could not be read, it has been reset", key)
|
||||
|
||||
Reference in New Issue
Block a user