diff --git a/NEWS b/NEWS index e70379d..2f54333 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,11 @@ new Luminotes release. This applies to all Luminotes products. * Added code to support Luminotes discussion forums. * Laid some of the foundational groundwork for future tags support. + * Made the subscription pricing page a little less confusing by hiding some + of the bigger plans by default. + * Fixed an occasional bug that caused unexpected logouts. The solution was + to move the session information into the database where it could be + properly locked. 1.5.4: October 9, 2008 * Fixed a visual bug in which clicking up or down to reorder your notebooks diff --git a/config/Common.py b/config/Common.py index bc4fb15..83789eb 100644 --- a/config/Common.py +++ b/config/Common.py @@ -1,4 +1,5 @@ import cherrypy +from controller.Session_storage import Session_storage MEGABYTE = 1024 * 1024 @@ -9,8 +10,7 @@ settings = { "server.socket_port": 8081, "server.environment": "production", "session_filter.on": True, - "session_filter.storage_type": "file", - "session_filter.storage_path": "session", + "session_filter.storage_class": Session_storage, "session_filter.timeout": 60 * 72, # 72 hours "session_filter.clean_up_delay": 5, "encoding_filter.on": True, diff --git a/config/Desktop.py b/config/Desktop.py index a95bdac..d529edf 100644 --- a/config/Desktop.py +++ b/config/Desktop.py @@ -22,6 +22,7 @@ settings = { "server.socket_port": socket_port, "server.socket_host": "localhost", "server.thread_pool": 4, + "session_filter.storage_class": None, "session_filter.storage_type": "ram", "session_filter.timeout": 60 * 24 * 365, # one year "static_filter.root": os.getcwd(), diff --git a/controller/Database.py b/controller/Database.py index bfd3ca9..b197ec8 100644 --- a/controller/Database.py +++ b/controller/Database.py @@ -152,7 +152,7 @@ class Database( object ): except ImportError: return None - def __get_connection( self ): + def get_connection( self ): if self.__connection: return self.__connection else: @@ -178,7 +178,7 @@ class Database( object ): @type commit: bool @param commit: True to automatically commit after the save """ - connection = self.__get_connection() + connection = self.get_connection() cursor = connection.cursor() cursor.execute( obj.sql_exists() ) @@ -202,7 +202,7 @@ class Database( object ): @synchronized def commit( self ): - connection = self.__get_connection() + connection = self.get_connection() connection.commit() # save any pending saves to the cache @@ -216,7 +216,7 @@ class Database( object ): @synchronized def rollback( self ): - connection = self.__get_connection() + connection = self.get_connection() connection.rollback() def load( self, Object_type, object_id, revision = None ): @@ -276,7 +276,7 @@ class Database( object ): if obj: return obj - connection = self.__get_connection() + connection = self.get_connection() cursor = connection.cursor() cursor.execute( sql_command ) @@ -308,7 +308,7 @@ class Database( object ): @rtype: list of Object_type @return: loaded objects """ - connection = self.__get_connection() + connection = self.get_connection() cursor = connection.cursor() cursor.execute( sql_command ) @@ -343,7 +343,7 @@ class Database( object ): @type commit: bool @param commit: True to automatically commit after the command """ - connection = self.__get_connection() + connection = self.get_connection() cursor = connection.cursor() cursor.execute( sql_command ) @@ -361,7 +361,7 @@ class Database( object ): @type commit: bool @param commit: True to automatically commit after the command """ - connection = self.__get_connection() + connection = self.get_connection() cursor = connection.cursor() if self.__backend == Persistent.SQLITE_BACKEND: @@ -411,7 +411,7 @@ class Database( object ): @type commit: bool @param commit: True to automatically commit after storing the next id """ - connection = self.__get_connection() + connection = self.get_connection() cursor = connection.cursor() # generate a random id, but on the off-chance that it collides with something else already in diff --git a/controller/Session_storage.py b/controller/Session_storage.py new file mode 100644 index 0000000..73c0ff1 --- /dev/null +++ b/controller/Session_storage.py @@ -0,0 +1,21 @@ +import cherrypy +from cherrypy.filters.sessionfilter import PostgreSQLStorage + + +class Session_storage( PostgreSQLStorage ): + """ + A wrapper for CherryPy's PostgreSQLStorage class that commits the current transaction to the + database so session changes actually take effect. + """ + + def __init__( self ): + self.db = cherrypy.root.database.get_connection() + self.cursor = self.db.cursor() + + def save( self, *args, **kwargs ): + PostgreSQLStorage.save( self, *args, **kwargs ) + self.db.commit() + + def clean_up( self, *args, **kwargs ): + PostgreSQLStorage.clean_up( self, *args, **kwargs ) + self.db.commit() diff --git a/model/delta/1.5.5.sql b/model/delta/1.5.5.sql index b39b9bb..80340f2 100644 --- a/model/delta/1.5.5.sql +++ b/model/delta/1.5.5.sql @@ -28,3 +28,9 @@ ALTER TABLE ONLY tag_note ADD CONSTRAINT tag_note_pkey PRIMARY KEY (note_id, tag ALTER TABLE user_notebook ADD COLUMN own_notes_only boolean DEFAULT false; update user_notebook set rank = 0 from luminotes_user_current, notebook_current where user_notebook.user_id = luminotes_user_current.id and username = 'anonymous' and user_notebook.notebook_id = notebook_current.id and notebook_current.name = 'Luminotes'; + +create table session ( + id text, + data text, + expiration_time timestamp +); diff --git a/model/schema.sql b/model/schema.sql index 1acbb05..f383686 100644 --- a/model/schema.sql +++ b/model/schema.sql @@ -141,6 +141,13 @@ CREATE TABLE user_notebook ( own_notes_only boolean DEFAULT false ); ALTER TABLE public.user_notebook OWNER TO luminotes; +CREATE TABLE session ( + id text, + data text, + expiration_time timestamp +); +ALTER TABLE public.session OWNER TO luminotes; + ALTER TABLE ONLY file ADD CONSTRAINT file_pkey PRIMARY KEY (id);