From 89e20b90b757891c92b2b4c85f676927daf6b39e Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Mon, 11 May 2015 12:36:35 -0400 Subject: [PATCH] Webapp: added databases directory; changed semantics of save_cache; working signals, for the most part --- gramps/webapp/databases/__init__.py | 0 gramps/webapp/databases/database1/__init__.py | 34 ++++ .../databases/database1/default_settings.py | 150 ++++++++++++++++++ gramps/webapp/databases/database1/sqlite.db | Bin 0 -> 293888 bytes gramps/webapp/databases/database2/__init__.py | 34 ++++ .../databases/database2/default_settings.py | 150 ++++++++++++++++++ gramps/webapp/databases/database2/sqlite.db | Bin 0 -> 293888 bytes gramps/webapp/dbdjango.py | 143 +++++++++++++---- gramps/webapp/grampsdb/models.py | 8 +- 9 files changed, 480 insertions(+), 39 deletions(-) create mode 100644 gramps/webapp/databases/__init__.py create mode 100644 gramps/webapp/databases/database1/__init__.py create mode 100644 gramps/webapp/databases/database1/default_settings.py create mode 100644 gramps/webapp/databases/database1/sqlite.db create mode 100644 gramps/webapp/databases/database2/__init__.py create mode 100644 gramps/webapp/databases/database2/default_settings.py create mode 100644 gramps/webapp/databases/database2/sqlite.db diff --git a/gramps/webapp/databases/__init__.py b/gramps/webapp/databases/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/gramps/webapp/databases/database1/__init__.py b/gramps/webapp/databases/database1/__init__.py new file mode 100644 index 000000000..015757638 --- /dev/null +++ b/gramps/webapp/databases/database1/__init__.py @@ -0,0 +1,34 @@ +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2012 Douglas S. Blank +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +from django.conf import settings +from . import default_settings +try: + settings.configure(default_settings) +except RuntimeError: + # already configured; ignore + pass + +from gramps.webapp.dbdjango import DbDjango +database = DbDjango() + +# For Django 1.6: +import django +django.setup() + diff --git a/gramps/webapp/databases/database1/default_settings.py b/gramps/webapp/databases/database1/default_settings.py new file mode 100644 index 000000000..fae3ffd06 --- /dev/null +++ b/gramps/webapp/databases/database1/default_settings.py @@ -0,0 +1,150 @@ +import os +from gramps.gen.const import DATA_DIR + +WEB_DIR = os.path.dirname(os.path.realpath(__file__)) + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +INTERNAL_IPS = ('127.0.0.1',) + +ADMINS = ( + ('admin', 'your_email@domain.com'), +) + +MANAGERS = ADMINS +DATABASE_ROUTERS = [] +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(WEB_DIR, 'sqlite.db'), + } +} +DATABASE_ENGINE = 'sqlite3' +DATABASE_NAME = os.path.join(WEB_DIR, 'sqlite.db') +DATABASE_USER = '' +DATABASE_PASSWORD = '' +DATABASE_HOST = '' +DATABASE_PORT = '' +TIME_ZONE = 'America/New_York' +LANGUAGE_CODE = 'en-us' +SITE_ID = 1 +USE_I18N = True +MEDIA_ROOT = '' +MEDIA_URL = '' +ADMIN_MEDIA_PREFIX = '/gramps-media/' +SECRET_KEY = 'zd@%vslj5sqhx94_8)0hsx*rk9tj3^ly$x+^*tq4bggr&uh$ac' + +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', # 1.4 + 'django.template.loaders.app_directories.Loader', # 1.4 + #'django.template.loaders.filesystem.load_template_source', + #'django.template.loaders.app_directories.load_template_source', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', +# 'debug_toolbar.middleware.DebugToolbarMiddleware', +) + +ROOT_URLCONF = 'gramps.webapp.urls' +STATIC_URL = '/static/' # 1.4 + +TEMPLATE_DIRS = ( + # Use absolute paths, not relative paths. + os.path.join(DATA_DIR, "templates"), +) + +TEMPLATE_CONTEXT_PROCESSORS = ( + "django.contrib.auth.context_processors.auth", # 1.4 + "django.contrib.messages.context_processors.messages", # 1.4 +# "django.core.context_processors.auth", +# "django.core.context_processors.debug", + "django.core.context_processors.i18n", + "django.core.context_processors.media", + "gramps.webapp.grampsdb.views.context_processor", + "gramps.webapp.context.messages", +) + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.staticfiles', + 'django.contrib.messages', # 1.4 + 'django.contrib.sites', + 'django.contrib.admin', + 'gramps.webapp.grampsdb', +# 'django_extensions', +# 'debug_toolbar', +) + +DEBUG_TOOLBAR_PANELS = ( + 'debug_toolbar.panels.version.VersionDebugPanel', + 'debug_toolbar.panels.timer.TimerDebugPanel', + 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel', + 'debug_toolbar.panels.headers.HeaderDebugPanel', + 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel', + 'debug_toolbar.panels.template.TemplateDebugPanel', + 'debug_toolbar.panels.sql.SQLDebugPanel', + 'debug_toolbar.panels.signals.SignalDebugPanel', + 'debug_toolbar.panels.logger.LoggingPanel', + ) + +def custom_show_toolbar(request): + return True # Always show toolbar, for example purposes only. + +DEBUG_TOOLBAR_CONFIG = { + 'INTERCEPT_REDIRECTS': False, +# 'SHOW_TOOLBAR_CALLBACK': custom_show_toolbar, +# 'EXTRA_SIGNALS': ['myproject.signals.MySignal'], + 'HIDE_DJANGO_SQL': False, + } + +AUTH_PROFILE_MODULE = "grampsdb.Profile" + +# Had to add these to use settings.configure(): +DATABASE_OPTIONS = '' +URL_VALIDATOR_USER_AGENT = '' +DEFAULT_INDEX_TABLESPACE = '' +DEFAULT_TABLESPACE = '' +CACHE_BACKEND = 'locmem://' +TRANSACTIONS_MANAGED = False +LOCALE_PATHS = tuple() + +# Changes for Django 1.3: +USE_L10N = True +FORMAT_MODULE_PATH = "" +## End Changes for Django 1.3 + +# Changes for Django 1.4: +USE_TZ = False +## End Changes for Django 1.4 + +# Changes for Django 1.5: +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + } + } +DEFAULT_CHARSET = "utf-8" +## End Changes for Django 1.5 + +## Changes for Django 1.5.4: +LOGGING_CONFIG = None +AUTH_USER_MODEL = 'auth.User' +## End Changes for Django 1.5.4 + +LOGIN_URL = "/login/" +LOGOUT_URL = "/logout" +LOGIN_REDIRECT_URL = "/" + +## Changes for Django 1.6: +LOGGING = None + +## Changes for Django 1.7.1: +ABSOLUTE_URL_OVERRIDES = {} diff --git a/gramps/webapp/databases/database1/sqlite.db b/gramps/webapp/databases/database1/sqlite.db new file mode 100644 index 0000000000000000000000000000000000000000..84fc95beab3e43bc0017308e6f64367768ce002c GIT binary patch literal 293888 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Ν>o}t~ha9quGg#2BN&pYl`vum?|ICf93 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 literal 0 HcmV?d00001 diff --git a/gramps/webapp/databases/database2/__init__.py b/gramps/webapp/databases/database2/__init__.py new file mode 100644 index 000000000..015757638 --- /dev/null +++ b/gramps/webapp/databases/database2/__init__.py @@ -0,0 +1,34 @@ +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2012 Douglas S. Blank +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +from django.conf import settings +from . import default_settings +try: + settings.configure(default_settings) +except RuntimeError: + # already configured; ignore + pass + +from gramps.webapp.dbdjango import DbDjango +database = DbDjango() + +# For Django 1.6: +import django +django.setup() + diff --git a/gramps/webapp/databases/database2/default_settings.py b/gramps/webapp/databases/database2/default_settings.py new file mode 100644 index 000000000..fae3ffd06 --- /dev/null +++ b/gramps/webapp/databases/database2/default_settings.py @@ -0,0 +1,150 @@ +import os +from gramps.gen.const import DATA_DIR + +WEB_DIR = os.path.dirname(os.path.realpath(__file__)) + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +INTERNAL_IPS = ('127.0.0.1',) + +ADMINS = ( + ('admin', 'your_email@domain.com'), +) + +MANAGERS = ADMINS +DATABASE_ROUTERS = [] +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(WEB_DIR, 'sqlite.db'), + } +} +DATABASE_ENGINE = 'sqlite3' +DATABASE_NAME = os.path.join(WEB_DIR, 'sqlite.db') +DATABASE_USER = '' +DATABASE_PASSWORD = '' +DATABASE_HOST = '' +DATABASE_PORT = '' +TIME_ZONE = 'America/New_York' +LANGUAGE_CODE = 'en-us' +SITE_ID = 1 +USE_I18N = True +MEDIA_ROOT = '' +MEDIA_URL = '' +ADMIN_MEDIA_PREFIX = '/gramps-media/' +SECRET_KEY = 'zd@%vslj5sqhx94_8)0hsx*rk9tj3^ly$x+^*tq4bggr&uh$ac' + +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', # 1.4 + 'django.template.loaders.app_directories.Loader', # 1.4 + #'django.template.loaders.filesystem.load_template_source', + #'django.template.loaders.app_directories.load_template_source', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', +# 'debug_toolbar.middleware.DebugToolbarMiddleware', +) + +ROOT_URLCONF = 'gramps.webapp.urls' +STATIC_URL = '/static/' # 1.4 + +TEMPLATE_DIRS = ( + # Use absolute paths, not relative paths. + os.path.join(DATA_DIR, "templates"), +) + +TEMPLATE_CONTEXT_PROCESSORS = ( + "django.contrib.auth.context_processors.auth", # 1.4 + "django.contrib.messages.context_processors.messages", # 1.4 +# "django.core.context_processors.auth", +# "django.core.context_processors.debug", + "django.core.context_processors.i18n", + "django.core.context_processors.media", + "gramps.webapp.grampsdb.views.context_processor", + "gramps.webapp.context.messages", +) + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.staticfiles', + 'django.contrib.messages', # 1.4 + 'django.contrib.sites', + 'django.contrib.admin', + 'gramps.webapp.grampsdb', +# 'django_extensions', +# 'debug_toolbar', +) + +DEBUG_TOOLBAR_PANELS = ( + 'debug_toolbar.panels.version.VersionDebugPanel', + 'debug_toolbar.panels.timer.TimerDebugPanel', + 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel', + 'debug_toolbar.panels.headers.HeaderDebugPanel', + 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel', + 'debug_toolbar.panels.template.TemplateDebugPanel', + 'debug_toolbar.panels.sql.SQLDebugPanel', + 'debug_toolbar.panels.signals.SignalDebugPanel', + 'debug_toolbar.panels.logger.LoggingPanel', + ) + +def custom_show_toolbar(request): + return True # Always show toolbar, for example purposes only. + +DEBUG_TOOLBAR_CONFIG = { + 'INTERCEPT_REDIRECTS': False, +# 'SHOW_TOOLBAR_CALLBACK': custom_show_toolbar, +# 'EXTRA_SIGNALS': ['myproject.signals.MySignal'], + 'HIDE_DJANGO_SQL': False, + } + +AUTH_PROFILE_MODULE = "grampsdb.Profile" + +# Had to add these to use settings.configure(): +DATABASE_OPTIONS = '' +URL_VALIDATOR_USER_AGENT = '' +DEFAULT_INDEX_TABLESPACE = '' +DEFAULT_TABLESPACE = '' +CACHE_BACKEND = 'locmem://' +TRANSACTIONS_MANAGED = False +LOCALE_PATHS = tuple() + +# Changes for Django 1.3: +USE_L10N = True +FORMAT_MODULE_PATH = "" +## End Changes for Django 1.3 + +# Changes for Django 1.4: +USE_TZ = False +## End Changes for Django 1.4 + +# Changes for Django 1.5: +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + } + } +DEFAULT_CHARSET = "utf-8" +## End Changes for Django 1.5 + +## Changes for Django 1.5.4: +LOGGING_CONFIG = None +AUTH_USER_MODEL = 'auth.User' +## End Changes for Django 1.5.4 + +LOGIN_URL = "/login/" +LOGOUT_URL = "/logout" +LOGIN_REDIRECT_URL = "/" + +## Changes for Django 1.6: +LOGGING = None + +## Changes for Django 1.7.1: +ABSOLUTE_URL_OVERRIDES = {} diff --git a/gramps/webapp/databases/database2/sqlite.db b/gramps/webapp/databases/database2/sqlite.db new file mode 100644 index 0000000000000000000000000000000000000000..84fc95beab3e43bc0017308e6f64367768ce002c GIT binary patch literal 293888 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Ν>o}t~ha9quGg#2BN&pYl`vum?|ICf93 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 literal 0 HcmV?d00001 diff --git a/gramps/webapp/dbdjango.py b/gramps/webapp/dbdjango.py index 41251963f..9ec183e4d 100644 --- a/gramps/webapp/dbdjango.py +++ b/gramps/webapp/dbdjango.py @@ -21,12 +21,20 @@ #------------------------------------------------------------------------ # -# Gramps Modules +# Python Modules # #------------------------------------------------------------------------ import sys import time import re +import base64 +import pickle + +#------------------------------------------------------------------------ +# +# Gramps Modules +# +#------------------------------------------------------------------------ import gramps from gramps.gen.lib import (Person, Family, Event, Place, Repository, Citation, Source, Note, MediaObject, Tag, @@ -424,6 +432,16 @@ class DbDjango(DbWriteBase, DbReadBase): def request_rebuild(self): # caches are ok, but let's compute public's self.dji.update_publics() + self.emit('person-rebuild') + self.emit('family-rebuild') + self.emit('place-rebuild') + self.emit('source-rebuild') + self.emit('citation-rebuild') + self.emit('media-rebuild') + self.emit('event-rebuild') + self.emit('repository-rebuild') + self.emit('note-rebuild') + self.emit('tag-rebuild') def get_undodb(self): return None @@ -1318,7 +1336,7 @@ class DbDjango(DbWriteBase, DbReadBase): if not person.gramps_id and set_gid: person.gramps_id = self.find_next_person_gramps_id() self.commit_person(person, trans) - self.signal("person-add", [person.handle]) + self.emit("person-add", [person.handle]) return person.handle def add_family(self, family, trans, set_gid=True): @@ -1327,7 +1345,7 @@ class DbDjango(DbWriteBase, DbReadBase): if not family.gramps_id and set_gid: family.gramps_id = self.find_next_family_gramps_id() self.commit_family(family, trans) - self.signal("family-add", [family.handle]) + self.emit("family-add", [family.handle]) return family.handle def add_citation(self, citation, trans, set_gid=True): @@ -1336,7 +1354,7 @@ class DbDjango(DbWriteBase, DbReadBase): if not citation.gramps_id and set_gid: citation.gramps_id = self.find_next_citation_gramps_id() self.commit_citation(citation, trans) - self.signal("citation-add", [citation.handle]) + self.emit("citation-add", [citation.handle]) return citation.handle def add_source(self, source, trans, set_gid=True): @@ -1345,7 +1363,7 @@ class DbDjango(DbWriteBase, DbReadBase): if not source.gramps_id and set_gid: source.gramps_id = self.find_next_source_gramps_id() self.commit_source(source, trans) - self.signal("source-add", [source.handle]) + self.emit("source-add", [source.handle]) return source.handle def add_repository(self, repository, trans, set_gid=True): @@ -1354,7 +1372,7 @@ class DbDjango(DbWriteBase, DbReadBase): if not repository.gramps_id and set_gid: repository.gramps_id = self.find_next_repository_gramps_id() self.commit_repository(repository, trans) - self.signal("repository-add", [repository.handle]) + self.emit("repository-add", [repository.handle]) return repository.handle def add_note(self, note, trans, set_gid=True): @@ -1363,7 +1381,7 @@ class DbDjango(DbWriteBase, DbReadBase): if not note.gramps_id and set_gid: note.gramps_id = self.find_next_note_gramps_id() self.commit_note(note, trans) - self.signal("note-add", [note.handle]) + self.emit("note-add", [note.handle]) return note.handle def add_place(self, place, trans, set_gid=True): @@ -1407,63 +1425,117 @@ class DbDjango(DbWriteBase, DbReadBase): self.import_cache[person.handle] = person else: print("WARNING: haven't written logic to update") - self.signal("person-update", [person.handle]) + raw = person.serialize() + dj_person = self.dji.Person.filter(handle=person.handle)[0] + dj_person.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_person.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("person-update", [person.handle]) def commit_family(self, family, trans, change_time=None): if self.use_import_cache: self.import_cache[family.handle] = family else: print("WARNING: haven't written logic to update") - self.signal("family-update", [family.handle]) + raw = family.serialize() + dj_obj = self.dji.Family.filter(handle=family.handle)[0] + dj_obj.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_obj.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("family-update", [family.handle]) def commit_citation(self, citation, trans, change_time=None): if self.use_import_cache: self.import_cache[citation.handle] = citation else: print("WARNING: haven't written logic to update") - self.signal("citation-update", [citation.handle]) + raw = citation.serialize() + dj_obj = self.dji.Citation.filter(handle=citation.handle)[0] + dj_obj.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_obj.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("citation-update", [citation.handle]) def commit_source(self, source, trans, change_time=None): if self.use_import_cache: self.import_cache[source.handle] = source else: print("WARNING: haven't written logic to update") - self.signal("source-update", [source.handle]) + raw = source.serialize() + dj_obj = self.dji.Source.filter(handle=source.handle)[0] + dj_obj.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_obj.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("source-update", [source.handle]) def commit_repository(self, repository, trans, change_time=None): if self.use_import_cache: self.import_cache[repository.handle] = repository else: print("WARNING: haven't written logic to update") - self.signal("repository-update", [repository.handle]) + raw = repository.serialize() + dj_obj = self.dji.Repository.filter(handle=repository.handle)[0] + dj_obj.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_obj.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("repository-update", [repository.handle]) def commit_note(self, note, trans, change_time=None): if self.use_import_cache: self.import_cache[note.handle] = note else: print("WARNING: haven't written logic to update") - self.signal("note-update", [note.handle]) + raw = note.serialize() + dj_obj = self.dji.Note.filter(handle=note.handle)[0] + dj_obj.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_obj.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("note-update", [note.handle]) def commit_place(self, place, trans, change_time=None): if self.use_import_cache: self.import_cache[place.handle] = place else: print("WARNING: haven't written logic to update") - self.signal("place-update", [place.handle]) + raw = place.serialize() + dj_obj = self.dji.Place.filter(handle=place.handle)[0] + dj_obj.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_obj.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("place-update", [place.handle]) def commit_event(self, event, trans, change_time=None): if self.use_import_cache: self.import_cache[event.handle] = event else: print("WARNING: haven't written logic to update") - self.signal("event-update", [event.handle]) + raw = event.serialize() + dj_obj = self.dji.Event.filter(handle=event.handle)[0] + dj_obj.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_obj.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("event-update", [event.handle]) def commit_tag(self, tag, trans, change_time=None): if self.use_import_cache: self.import_cache[tag.handle] = tag else: print("WARNING: haven't written logic to update") - self.signal("tag-update", [tag.handle]) + raw = tag.serialize() + dj_obj = self.dji.Tag.filter(handle=tag.handle)[0] + dj_obj.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_obj.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("tag-update", [tag.handle]) def commit_media_object(self, obj, transaction, change_time=None): """ @@ -1474,7 +1546,13 @@ class DbDjango(DbWriteBase, DbReadBase): self.import_cache[obj.handle] = obj else: print("WARNING: haven't written logic to update") - self.signal("media-update", [obj.handle]) + raw = obj.serialize() + dj_obj = self.dji.Media.filter(handle=obj.handle)[0] + dj_obj.cache = str(base64.encodebytes(pickle.dumps(raw)), "utf-8") + dj_obj.save(save_cache=False) # don't generate the cache from Django objects + # FIXME: propagate changes to rest of Django object from cache + # How? Maybe delete and re-add? + self.emit("media-update", [obj.handle]) def get_gramps_ids(self, obj_key): key2table = { @@ -1603,10 +1681,6 @@ class DbDjango(DbWriteBase, DbReadBase): return False def connect(self, signal, callback): - ## citation-add - ## citation-delete - ## citation-rebuild - ## citation-update #print("Adding signal: ", signal) if signal in self._signals: self._signals[signal].append(callback) @@ -1618,12 +1692,15 @@ class DbDjango(DbWriteBase, DbReadBase): if signal in self._signals: del self._signals[signal] - def signal(self, sig, items): + def emit(self, sig, items=None): #print("Firing signal: ", sig, items) if self._signals_enabled: if sig in self._signals: for callback in self._signals[sig]: - callback(items) + if items: + callback(items) + else: + callback() else: print("WARNING: no such signal: ", sig) @@ -1808,43 +1885,43 @@ class DbDjango(DbWriteBase, DbReadBase): # Removals: def remove_person(self, handle, txn): self.dji.Person.filter(handle=handle)[0].delete() - self.signal("person-delete", [handle]) + self.emit("person-delete", [handle]) def remove_source(self, handle, transaction): self.dji.Source.filter(handle=handle)[0].delete() - self.signal("source-delete", [handle]) + self.emit("source-delete", [handle]) def remove_citation(self, handle, transaction): self.dji.Citation.filter(handle=handle)[0].delete() - self.signal("citation-delete", [handle]) + self.emit("citation-delete", [handle]) def remove_event(self, handle, transaction): self.dji.Event.filter(handle=handle)[0].delete() - self.signal("event-delete", [handle]) + self.emit("event-delete", [handle]) def remove_object(self, handle, transaction): self.dji.Media.filter(handle=handle)[0].delete() - self.signal("media-delete", [handle]) + self.emit("media-delete", [handle]) def remove_place(self, handle, transaction): self.dji.Place.filter(handle=handle)[0].delete() - self.signal("place-delete", [handle]) + self.emit("place-delete", [handle]) def remove_family(self, handle, transaction): self.dji.Family.filter(handle=handle)[0].delete() - self.signal("family-delete", [handle]) + self.emit("family-delete", [handle]) def remove_repository(self, handle, transaction): self.dji.Repository.filter(handle=handle)[0].delete() - self.signal("repository-delete", [handle]) + self.emit("repository-delete", [handle]) def remove_note(self, handle, transaction): self.dji.Note.filter(handle=handle)[0].delete() - self.signal("note-delete", [handle]) + self.emit("note-delete", [handle]) def remove_tag(self, handle, transaction): self.dji.Tag.filter(handle=handle)[0].delete() - self.signal("tag-delete", [handle]) + self.emit("tag-delete", [handle]) def remove_from_surname_list(self, person): ## FIXME diff --git a/gramps/webapp/grampsdb/models.py b/gramps/webapp/grampsdb/models.py index 7dd668068..273aacb11 100644 --- a/gramps/webapp/grampsdb/models.py +++ b/gramps/webapp/grampsdb/models.py @@ -455,9 +455,7 @@ class Tag(models.Model): if "save_cache" in kwargs: save_cache = kwargs["save_cache"] del kwargs["save_cache"] - if not save_cache: - self.cache = "" - else: + if save_cache: self.cache = self.make_cache() models.Model.save(self, *args, **kwargs) # save to db @@ -545,9 +543,7 @@ class PrimaryObject(models.Model): if "save_cache" in kwargs: save_cache = kwargs["save_cache"] del kwargs["save_cache"] - if not save_cache: - self.cache = "" - else: + if save_cache: self.cache = self.make_cache() models.Model.save(self, *args, **kwargs) # save to db