From 76d29b8dfe381e03159d0df7001ca5d26d7fed4c Mon Sep 17 00:00:00 2001 From: MuK IT GmbH Date: Tue, 19 Feb 2019 11:28:48 +0000 Subject: [PATCH] publish muk_session_store - 12.0 --- muk_session_store/__manifest__.py | 2 +- muk_session_store/store/postgres.py | 263 ++++++++++++++-------------- 2 files changed, 134 insertions(+), 131 deletions(-) diff --git a/muk_session_store/__manifest__.py b/muk_session_store/__manifest__.py index 42edd4f..22671c9 100644 --- a/muk_session_store/__manifest__.py +++ b/muk_session_store/__manifest__.py @@ -20,7 +20,7 @@ { "name": "MuK Session Store", "summary": """Session Store Options""", - "version": "12.0.1.0.4", + "version": "12.0.1.0.5", "category": "Extra Tools", "license": "AGPL-3", "website": "http://www.mukit.at", diff --git a/muk_session_store/store/postgres.py b/muk_session_store/store/postgres.py index 8aacc58..6209905 100644 --- a/muk_session_store/store/postgres.py +++ b/muk_session_store/store/postgres.py @@ -1,131 +1,134 @@ -################################################################################### -# -# Copyright (C) 2017 MuK IT GmbH -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -################################################################################### - -import json -import logging -import psycopg2 -import functools - -from contextlib import closing -from datetime import datetime, date - -from werkzeug.contrib.sessions import SessionStore - -from odoo.sql_db import db_connect -from odoo.tools import config - -_logger = logging.getLogger(__name__) - -def ensure_cursor(func): - @functools.wraps(func) - def wrapper(self, *args, **kwargs): - for attempts in range(1, 6): - try: - return func(self, *args, **kwargs) - except psycopg2.InterfaceError as error: - _logger.info("SessionStore connection failed! (%s/5)" % attempts) - if attempts < 5: - self._open_connection() - else: - raise error - return wrapper - -class PostgresSessionStore(SessionStore): - - def __init__(self, *args, **kwargs): - super(PostgresSessionStore, self).__init__(*args, **kwargs) - self.dbname = config.get('session_store_dbname', 'session_store') - self._open_connection() - self._setup_db() - - def _create_database(self): - with closing(db_connect("postgres").cursor()) as cursor: - cursor.autocommit(True) - cursor.execute(""" - CREATE DATABASE {dbname} - ENCODING 'unicode' - TEMPLATE 'template0'; - """.format(dbname=self.dbname)) - self._setup_db() - - def _open_connection(self, create_db=True): - try: - connection = db_connect(self.dbname, allow_uri=True) - self.cursor = connection.cursor() - self.cursor.autocommit(True) - except: - if not create_db: - raise - self._create_database() - return self._open_connection(create_db=False) - - @ensure_cursor - def _setup_db(self): - self.cursor.execute(""" - CREATE TABLE IF NOT EXISTS sessions ( - sid varchar PRIMARY KEY, - write_date timestamp without time zone NOT NULL, - payload text NOT NULL - ); - """) - - @ensure_cursor - def save(self, session): - self.cursor.execute(""" - INSERT INTO sessions (sid, write_date, payload) - VALUES (%(sid)s, now() at time zone 'UTC', %(payload)s) - ON CONFLICT (sid) - DO UPDATE SET payload = %(payload)s, write_date = now() at time zone 'UTC'; - """, dict(sid=session.sid, payload=json.dumps(dict(session)))) - - @ensure_cursor - def delete(self, session): - self.cursor.execute("DELETE FROM sessions WHERE sid=%s;", [session.sid]) - - @ensure_cursor - def get(self, sid): - if not self.is_valid_key(sid): - return self.new() - self.cursor.execute(""" - SELECT payload, write_date - FROM sessions WHERE sid=%s; - """, [sid]) - try: - payload, write_date = self.cursor.fetchone() - if write_date.date() != datetime.today().date(): - self.cursor.execute(""" - UPDATE sessions - SET write_date = now() at time zone 'UTC' - WHERE sid=%s; - """, [sid]) - return self.session_class(json.loads(payload), sid, False) - except Exception: - return self.session_class({}, sid, False) - - @ensure_cursor - def list(self): - self.cursor.execute("SELECT sid FROM sessions;") - return [record[0] for record in self.cursor.fetchall()] - - @ensure_cursor - def clean(self): - self.cursor.execute(""" - DELETE FROM sessions - WHERE now() at time zone 'UTC' - write_date > '7 days'; +################################################################################### +# +# Copyright (C) 2017 MuK IT GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +import json +import logging +import psycopg2 +import functools + +from contextlib import closing +from datetime import datetime, date + +from werkzeug.contrib.sessions import SessionStore + +from odoo.sql_db import db_connect +from odoo.tools import config + +_logger = logging.getLogger(__name__) + +def ensure_cursor(func): + @functools.wraps(func) + def wrapper(self, *args, **kwargs): + for attempts in range(1, 6): + try: + return func(self, *args, **kwargs) + except psycopg2.InterfaceError as error: + _logger.info("SessionStore connection failed! (%s/5)" % attempts) + if attempts < 5: + self._open_connection() + else: + raise error + return wrapper + +class PostgresSessionStore(SessionStore): + + def __init__(self, *args, **kwargs): + super(PostgresSessionStore, self).__init__(*args, **kwargs) + self.dbname = config.get('session_store_dbname', 'session_store') + self._open_connection() + self._setup_db() + + def _create_database(self): + with closing(db_connect("postgres").cursor()) as cursor: + cursor.autocommit(True) + cursor.execute(""" + CREATE DATABASE {dbname} + ENCODING 'unicode' + TEMPLATE 'template0'; + """.format(dbname=self.dbname)) + self._setup_db() + + def _open_connection(self, create_db=True): + try: + connection = db_connect(self.dbname, allow_uri=True) + self.cursor = connection.cursor() + self.cursor.autocommit(True) + except: + if not create_db: + raise + self._create_database() + return self._open_connection(create_db=False) + + def __del__(self): + self.cursor.close() + + @ensure_cursor + def _setup_db(self): + self.cursor.execute(""" + CREATE TABLE IF NOT EXISTS sessions ( + sid varchar PRIMARY KEY, + write_date timestamp without time zone NOT NULL, + payload text NOT NULL + ); + """) + + @ensure_cursor + def save(self, session): + self.cursor.execute(""" + INSERT INTO sessions (sid, write_date, payload) + VALUES (%(sid)s, now() at time zone 'UTC', %(payload)s) + ON CONFLICT (sid) + DO UPDATE SET payload = %(payload)s, write_date = now() at time zone 'UTC'; + """, dict(sid=session.sid, payload=json.dumps(dict(session)))) + + @ensure_cursor + def delete(self, session): + self.cursor.execute("DELETE FROM sessions WHERE sid=%s;", [session.sid]) + + @ensure_cursor + def get(self, sid): + if not self.is_valid_key(sid): + return self.new() + self.cursor.execute(""" + SELECT payload, write_date + FROM sessions WHERE sid=%s; + """, [sid]) + try: + payload, write_date = self.cursor.fetchone() + if write_date.date() != datetime.today().date(): + self.cursor.execute(""" + UPDATE sessions + SET write_date = now() at time zone 'UTC' + WHERE sid=%s; + """, [sid]) + return self.session_class(json.loads(payload), sid, False) + except Exception: + return self.session_class({}, sid, False) + + @ensure_cursor + def list(self): + self.cursor.execute("SELECT sid FROM sessions;") + return [record[0] for record in self.cursor.fetchall()] + + @ensure_cursor + def clean(self): + self.cursor.execute(""" + DELETE FROM sessions + WHERE now() at time zone 'UTC' - write_date > '7 days'; """) \ No newline at end of file