diff --git a/gramps/webapp/dbdjango.py b/gramps/webapp/dbdjango.py index bc50650a3..d0b1c6ad5 100644 --- a/gramps/webapp/dbdjango.py +++ b/gramps/webapp/dbdjango.py @@ -27,11 +27,6 @@ # #------------------------------------------------------------------------ import sys -if sys.version_info[0] < 3: - import cPickle as pickle -else: - import pickle -import base64 import time import re import gramps @@ -723,49 +718,49 @@ class DbDjango(DbWriteBase, DbReadBase): def make_repository(self, repository): if self.use_db_cache and repository.cache: - data = pickle.loads(base64.decodestring(repository.cache)) + data = repository.from_cache() else: data = self.dji.get_repository(repository) return Repository.create(data) def make_citation(self, citation): if self.use_db_cache and citation.cache: - data = pickle.loads(base64.decodestring(citation.cache)) + data = citation.from_cache() else: data = self.dji.get_citation(citation) return Citation.create(data) def make_source(self, source): if self.use_db_cache and source.cache: - data = pickle.loads(base64.decodestring(source.cache)) + data = source.from_cache() else: data = self.dji.get_source(source) return Source.create(data) def make_family(self, family): if self.use_db_cache and family.cache: - data = pickle.loads(base64.decodestring(family.cache)) + data = family.from_cache() else: data = self.dji.get_family(family) return Family.create(data) def make_person(self, person): if self.use_db_cache and person.cache: - data = pickle.loads(base64.decodestring(person.cache)) + data = person.from_cache() else: data = self.dji.get_person(person) return Person.create(data) def make_event(self, event): if self.use_db_cache and event.cache: - data = pickle.loads(base64.decodestring(event.cache)) + data = event.from_cache() else: data = self.dji.get_event(event) return Event.create(data) def make_note(self, note): if self.use_db_cache and note.cache: - data = pickle.loads(base64.decodestring(note.cache)) + data = note.from_cache() else: data = self.dji.get_note(note) return Note.create(data) @@ -776,14 +771,14 @@ class DbDjango(DbWriteBase, DbReadBase): def make_place(self, place): if self.use_db_cache and place.cache: - data = pickle.loads(base64.decodestring(place.cache)) + data = place.from_cache() else: data = self.dji.get_place(place) return Place.create(data) def make_media(self, media): if self.use_db_cache and media.cache: - data = pickle.loads(base64.decodestring(media.cache)) + data = media.from_cache() else: data = self.dji.get_media(media) return MediaObject.create(data) @@ -1348,3 +1343,17 @@ class DbDjango(DbWriteBase, DbReadBase): # Next we add the links: self.dji.update_publics() + def get_from_name_and_handle(self, table_name, handle): + """ + Returns a gen.lib object (or None) given table_name and + handle. + + Examples: + + >>> self.get_from_name_and_handle("Person", "a7ad62365bc652387008") + >>> self.get_from_name_and_handle("Media", "c3434653675bcd736f23") + """ + if table_name in self._tables: + return self._tables[table_name]["handle_func"](handle) + return None + diff --git a/gramps/webapp/grampsdb/models.py b/gramps/webapp/grampsdb/models.py index 518dc65c8..2e75f63bb 100644 --- a/gramps/webapp/grampsdb/models.py +++ b/gramps/webapp/grampsdb/models.py @@ -38,6 +38,13 @@ from gramps.gen.utils.id import create_id, create_uid from gramps.webapp.grampsdb.profile import Profile from gramps.gen.constfunc import cuni +import sys +if sys.version_info[0] < 3: + import cPickle as pickle +else: + import pickle +import base64 + #--------------------------------------------------------------------------- # # Support functions @@ -424,6 +431,8 @@ class Tag(models.Model): name = models.TextField('name') color = models.CharField(max_length=13, blank=True, null=True) # "#000000000000" # Black priority = models.IntegerField('priority', blank=True, null=True) + cache = models.TextField(blank=True, null=True) + dji = None def __unicode__(self): return cuni(self.name) @@ -434,6 +443,34 @@ class Tag(models.Model): def get_link(self): return cuni("%s") % (self.get_url(), self.name) + def make_cache(self): + from gramps.webapp.libdjango import DjangoInterface + if self.dji is None: + self.dji = DjangoInterface() + raw = self.dji.get_tag(self) + return base64.encodestring(pickle.dumps(raw)) + + def from_cache(self): + return pickle.loads(base64.decodestring(self.cache)) + + def save_cache(self): + cache = self.make_cache() + if cache != self.cache: + self.cache = cache + models.Model.save(self) + + def save(self, *args, **kwargs): + save_cache = True + if "save_cache" in kwargs: + save_cache = kwargs["save_cache"] + del kwargs["save_cache"] + if not save_cache: + self.cache = "" + else: + self.cache = self.make_cache() + models.Model.save(self, *args, **kwargs) # save to db + + # Just the following have tag lists: # --------------------------------- #src/gen/lib/family.py @@ -461,6 +498,7 @@ class PrimaryObject(models.Model): #attributes = models.ManyToManyField("Attribute", blank=True, null=True) cache = models.TextField(blank=True, null=True) tags = models.ManyToManyField('Tag', blank=True, null=True) + dji = None def __unicode__(self): return cuni("%s: %s") % (self.__class__.__name__, @@ -473,6 +511,55 @@ class PrimaryObject(models.Model): def get_tag_list(self): return tuple([tag.handle for tag in self.tags.all()]) + def make_cache(self): + from gramps.webapp.libdjango import DjangoInterface + if self.dji is None: + self.dji = DjangoInterface() + + if isinstance(self, Person): + raw = self.dji.get_person(self) + elif isinstance(self, Family): + raw = self.dji.get_family(self) + elif isinstance(self, Place): + raw = self.dji.get_place(self) + elif isinstance(self, Media): + raw = self.dji.get_media(self) + elif isinstance(self, Source): + raw = self.dji.get_source(self) + elif isinstance(self, Citation): + raw = self.dji.get_citation(self) + elif isinstance(self, Repository): + raw = self.dji.get_repository(self) + elif isinstance(self, Note): + raw = self.dji.get_note(self) + elif isinstance(self, Event): + raw = self.dji.get_event(self) + elif isinstance(self, Tag): + raw = self.dji.get_tag(self) + else: + raise Exception("Don't know how to get raw '%s'" % type(item)) + return base64.encodestring(pickle.dumps(raw)) + + def from_cache(self): + return pickle.loads(base64.decodestring(self.cache)) + + def save_cache(self): + cache = self.make_cache() + if cache != self.cache: + self.cache = cache + models.Model.save(self) + + def save(self, *args, **kwargs): + save_cache = True + if "save_cache" in kwargs: + save_cache = kwargs["save_cache"] + del kwargs["save_cache"] + if not save_cache: + self.cache = "" + else: + self.cache = self.make_cache() + models.Model.save(self, *args, **kwargs) # save to db + class MyFamilies(models.Model): person = models.ForeignKey("Person") family = models.ForeignKey("Family") diff --git a/gramps/webapp/grampsdb/view/citation.py b/gramps/webapp/grampsdb/view/citation.py index 51643894c..a0f58f2e6 100644 --- a/gramps/webapp/grampsdb/view/citation.py +++ b/gramps/webapp/grampsdb/view/citation.py @@ -70,7 +70,7 @@ def process_citation(request, context, handle, act, add_to=None): # view, edit, ref_handle = pickform.data["picklist"] ref_obj = Citation.objects.get(handle=ref_handle) dji.add_citation_ref_default(parent_obj, ref_obj) - dji.rebuild_cache(parent_obj) # rebuild cache + parent_obj.save_cache() # rebuild cache return redirect("/%s/%s%s#tab-citations" % (item, handle, build_search(request))) else: context["pickform"] = pickform @@ -98,7 +98,6 @@ def process_citation(request, context, handle, act, add_to=None): # view, edit, if citationform.is_valid(): update_last_changed(citation, request.user.username) citation = citationform.save() - dji.rebuild_cache(citation) act = "view" else: act = "edit" @@ -114,15 +113,15 @@ def process_citation(request, context, handle, act, add_to=None): # view, edit, source = sourceform.save() citation.source = source update_last_changed(citation, request.user.username) - citation = citationform.save() - dji.rebuild_cache(source) - dji.rebuild_cache(citation) + citation = citationform.save(save_cache=False) + source.save_cache() + citation.save_cache() if add_to: item, handle = add_to model = dji.get_model(item) obj = model.objects.get(handle=handle) dji.add_citation_ref(obj, citation.handle) - dji.rebuild_cache(obj) + obj.save_cache() return redirect("/%s/%s#tab-citations" % (item, handle)) act = "view" else: diff --git a/gramps/webapp/grampsdb/view/event.py b/gramps/webapp/grampsdb/view/event.py index 714a8ccd6..4f50ea2e5 100644 --- a/gramps/webapp/grampsdb/view/event.py +++ b/gramps/webapp/grampsdb/view/event.py @@ -71,7 +71,6 @@ def delete_event(event): for person in people: recheck_birth_death_refs(person) person.save() - dji.rebuild_cache(person) def check_event(event): obj_type = ContentType.objects.get_for_model(Person) @@ -90,7 +89,6 @@ def check_event(event): continue recheck_birth_death_refs(person) person.save() - dji.rebuild_cache(person) def recheck_birth_death_refs(person): """ @@ -167,8 +165,8 @@ def process_event(request, context, handle, act, add_to=None): # view, edit, sav dji.add_event_ref_default(parent_obj, ref_obj) if item == "person": # then need to recheck birth/death indexes: recheck_birth_death_refs(parent_obj) - parent_obj.save() - dji.rebuild_cache(parent_obj) # rebuild cache + parent_obj.save(save_cache=False) + parent_obj.save_cache() return redirect("/%s/%s%s#tab-events" % (item, handle, build_search(request))) else: context["pickform"] = pickform @@ -198,7 +196,6 @@ def process_event(request, context, handle, act, add_to=None): # view, edit, sav # birth/death issues changed: check_event(event) event.save() - dji.rebuild_cache(event) act = "view" else: act = "edit" @@ -209,7 +206,6 @@ def process_event(request, context, handle, act, add_to=None): # view, edit, sav if eventform.is_valid(): update_last_changed(event, request.user.username) event = eventform.save() - dji.rebuild_cache(event) if add_to: item, handle = add_to model = dji.get_model(item) @@ -217,8 +213,8 @@ def process_event(request, context, handle, act, add_to=None): # view, edit, sav dji.add_event_ref_default(obj, event) if item == "person": # then need to recheck birth/death indexes: recheck_birth_death_refs(obj) - obj.save() - dji.rebuild_cache(obj) + obj.save(save_cache=False) + obj.save_cache() return redirect("/%s/%s#tab-events" % (item, handle)) act = "view" else: diff --git a/gramps/webapp/grampsdb/view/family.py b/gramps/webapp/grampsdb/view/family.py index bc63a695e..1f1eaeab9 100644 --- a/gramps/webapp/grampsdb/view/family.py +++ b/gramps/webapp/grampsdb/view/family.py @@ -87,8 +87,6 @@ def process_family(request, context, handle, act, add_to=None): # view, edit, sa pfo.save() ref_obj.save() person.save() - dji.rebuild_cache(person) # rebuild child - dji.rebuild_cache(ref_obj) # rebuild cache return redirect("/%s/%s%s#tab-references" % ("person", handle, build_search(request))) else: context["pickform"] = pickform @@ -150,7 +148,6 @@ def process_family(request, context, handle, act, add_to=None): # view, edit, sa order=len(familyform.cleaned_data["father"].families.all())+1) pfo.save() familyform.save() - dji.rebuild_cache(family) act = "view" else: act = "edit" @@ -173,7 +170,7 @@ def process_family(request, context, handle, act, add_to=None): # view, edit, sa pfo = MyFamilies(person=family.father, family=family, order=len(family.father.families.all())+1) pfo.save() - dji.rebuild_cache(family) + family.save_cache() if add_to: # add child or spouse to family item, handle = add_to person = Person.objects.get(handle=handle) @@ -186,7 +183,6 @@ def process_family(request, context, handle, act, add_to=None): # view, edit, sa #elif item == "spouse": # already added by selecting person.save() - dji.rebuild_cache(person) # rebuild child return redirect("/%s/%s%s#tab-references" % ("person", handle, build_search(request))) act = "view" else: diff --git a/gramps/webapp/grampsdb/view/media.py b/gramps/webapp/grampsdb/view/media.py index cd83f0202..fc4234031 100644 --- a/gramps/webapp/grampsdb/view/media.py +++ b/gramps/webapp/grampsdb/view/media.py @@ -88,7 +88,7 @@ def process_media(request, context, handle, act, add_to=None): # view, edit, sav ref_handle = pickform.data["picklist"] ref_obj = Media.objects.get(handle=ref_handle) dji.add_media_ref_default(parent_obj, ref_obj) - dji.rebuild_cache(parent_obj) # rebuild cache + parent_obj.save_cache() # rebuild cache return redirect("/%s/%s%s#tab-media" % (item, handle, build_search(request))) else: context["pickform"] = pickform @@ -167,7 +167,6 @@ def process_media(request, context, handle, act, add_to=None): # view, edit, sav if mediaform.is_valid(): update_last_changed(media, request.user.username) media = mediaform.save() - dji.rebuild_cache(media) act = "view" else: act = "edit" @@ -177,16 +176,17 @@ def process_media(request, context, handle, act, add_to=None): # view, edit, sav mediaform.model = media if mediaform.is_valid(): update_last_changed(media, request.user.username) - media = mediaform.save() + media = mediaform.save(save_cache=False) if add_to: item, handle = add_to model = dji.get_model(item) obj = model.objects.get(handle=handle) dji.add_media_ref_default(obj, media) - dji.rebuild_cache(obj) + obj.save_cache() + media.save_cache() return redirect("/%s/%s#tab-gallery" % (item, handle)) else: - dji.rebuild_cache(media) + media.save_cache() act = "view" else: act = "add" diff --git a/gramps/webapp/grampsdb/view/note.py b/gramps/webapp/grampsdb/view/note.py index aefea7891..3ac1c29d8 100644 --- a/gramps/webapp/grampsdb/view/note.py +++ b/gramps/webapp/grampsdb/view/note.py @@ -80,7 +80,7 @@ def process_note(request, context, handle, act, add_to=None): # view, edit, save ref_handle = pickform.data["picklist"] ref_obj = Note.objects.get(handle=ref_handle) dji.add_note_ref(parent_obj, ref_obj) - dji.rebuild_cache(parent_obj) # rebuild cache + parent_obj.save_cache() # rebuild cache return redirect("/%s/%s%s#tab-notes" % (item, handle, build_search(request))) else: context["pickform"] = pickform @@ -109,7 +109,7 @@ def process_note(request, context, handle, act, add_to=None): # view, edit, save note.text = notedata[0] note = noteform.save() dji.save_note_markup(note, notedata[1]) - dji.rebuild_cache(note) + note.save_cache() notetext = noteform.data["notetext"] act = "view" else: @@ -126,13 +126,13 @@ def process_note(request, context, handle, act, add_to=None): # view, edit, save note.text = notedata[0] note = noteform.save() dji.save_note_markup(note, notedata[1]) - dji.rebuild_cache(note) + note.save_cache() if add_to: item, handle = add_to model = dji.get_model(item) obj = model.objects.get(handle=handle) dji.add_note_ref(obj, note) - dji.rebuild_cache(obj) + obj.save_cache() return redirect("/%s/%s#tab-notes" % (item, handle)) notetext = noteform.data["notetext"] act = "view" diff --git a/gramps/webapp/grampsdb/view/person.py b/gramps/webapp/grampsdb/view/person.py index 849ff1edb..49c82af6d 100644 --- a/gramps/webapp/grampsdb/view/person.py +++ b/gramps/webapp/grampsdb/view/person.py @@ -167,7 +167,7 @@ def process_surname(request, handle, order, sorder, act="view"): surname = sf.save(commit=False) check_primary(surname, surnames) surname.save() - dji.rebuild_cache(person) + person.save_cache() return redirect("/person/%s/name/%s/surname/%s%s#tab-surnames" % (person.handle, name.order, sorder, build_search(request))) @@ -182,7 +182,7 @@ def process_surname(request, handle, order, sorder, act="view"): surname = sf.save(commit=False) check_primary(surname, name.surname_set.all().exclude(order=surname.order)) surname.save() - dji.rebuild_cache(person) + person.save_cache() return redirect("/person/%s/name/%s/surname/%s%s#tab-surnames" % (person.handle, name.order, sorder, build_search(request))) @@ -281,7 +281,7 @@ def process_name(request, handle, order, act="view"): surname.prefix = sf.cleaned_data["prefix"] if sf.cleaned_data["prefix"] != " prefix " else "" surname.primary = True # FIXME: why is this False? Remove from form? surname.save() - dji.rebuild_cache(person) + person.save_cache() return redirect("/person/%s/name/%s%s#tab-surnames" % (person.handle, name.order, build_search(request))) else: @@ -317,7 +317,7 @@ def process_name(request, handle, order, act="view"): surname.prefix = sf.cleaned_data["prefix"] if sf.cleaned_data["prefix"] != " prefix " else "" surname.primary = True # FIXME: why is this False? Remove from form? surname.save() - dji.rebuild_cache(person) + person.save_cache() return redirect("/person/%s/name/%s%s#tab-surnames" % (person.handle, name.order, build_search(request))) else: @@ -373,8 +373,8 @@ def process_person(request, context, handle, act, add_to=None): # view, edit, sa pfo = MyParentFamilies(person=person, family=obj, order=len(person.parent_families.all())+1) pfo.save() - dji.rebuild_cache(person) # rebuild child - dji.rebuild_cache(obj) # rebuild family + person.save_cache() # rebuild child + obj.save_cache() # rebuild family return redirect("/%s/%s%s" % (item, handle, build_search(request))) else: context["pickform"] = pickform @@ -447,10 +447,10 @@ def process_person(request, context, handle, act, add_to=None): # view, edit, sa pfo = MyParentFamilies(person=person, family=obj, order=len(person.parent_families.all())+1) pfo.save() - dji.rebuild_cache(person) # rebuild child - dji.rebuild_cache(obj) # rebuild family + person.save_cache() # rebuild child + obj.save_cache() # rebuild family return redirect("/%s/%s%s" % (item, handle, build_search(request))) - dji.rebuild_cache(person) + person.save_cache() return redirect("/person/%s%s" % (person.handle, build_search(request))) else: # need to edit again diff --git a/gramps/webapp/grampsdb/view/place.py b/gramps/webapp/grampsdb/view/place.py index 052c6dc94..b4ea60ffb 100644 --- a/gramps/webapp/grampsdb/view/place.py +++ b/gramps/webapp/grampsdb/view/place.py @@ -64,7 +64,6 @@ def process_place(request, context, handle, act, add_to=None): # view, edit, sav if placeform.is_valid(): update_last_changed(place, request.user.username) place = placeform.save() - dji.rebuild_cache(place) act = "view" else: act = "edit" @@ -75,13 +74,12 @@ def process_place(request, context, handle, act, add_to=None): # view, edit, sav if placeform.is_valid(): update_last_changed(place, request.user.username) place = placeform.save() - dji.rebuild_cache(place) if add_to: item, handle = add_to model = dji.get_model(item) obj = model.objects.get(handle=handle) dji.add_place_ref(obj, place.handle) - dji.rebuild_cache(obj) + obj.save_cache() return redirect("/%s/%s#tab-places" % (item, handle)) act = "view" else: diff --git a/gramps/webapp/grampsdb/view/repository.py b/gramps/webapp/grampsdb/view/repository.py index 95410a1eb..25cbd74ea 100644 --- a/gramps/webapp/grampsdb/view/repository.py +++ b/gramps/webapp/grampsdb/view/repository.py @@ -70,7 +70,7 @@ def process_repository(request, context, handle, act, add_to=None): # view, edit ref_handle = pickform.data["picklist"] ref_obj = Repository.objects.get(handle=ref_handle) dji.add_repository_ref_default(parent_obj, ref_obj) - dji.rebuild_cache(parent_obj) # rebuild cache + parent_obj.save_cache() # rebuild cache return redirect("/%s/%s%s#tab-repositories" % (item, handle, build_search(request))) else: context["pickform"] = pickform @@ -92,7 +92,6 @@ def process_repository(request, context, handle, act, add_to=None): # view, edit if repositoryform.is_valid(): update_last_changed(repository, request.user.username) repository = repositoryform.save() - dji.rebuild_cache(repository) act = "view" else: act = "edit" @@ -103,13 +102,12 @@ def process_repository(request, context, handle, act, add_to=None): # view, edit if repositoryform.is_valid(): update_last_changed(repository, request.user.username) repository = repositoryform.save() - dji.rebuild_cache(repository) if add_to: item, handle = add_to model = dji.get_model(item) obj = model.objects.get(handle=handle) dji.add_repository_ref_default(obj, repository) - dji.rebuild_cache(obj) + obj.save_cache() return redirect("/%s/%s#tab-repositories" % (item, handle)) act = "view" else: diff --git a/gramps/webapp/grampsdb/view/source.py b/gramps/webapp/grampsdb/view/source.py index b0e178f05..278c9f67f 100644 --- a/gramps/webapp/grampsdb/view/source.py +++ b/gramps/webapp/grampsdb/view/source.py @@ -70,7 +70,7 @@ def process_source(request, context, handle, act, add_to=None): # view, edit, sa ref_handle = pickform.data["picklist"] ref_obj = Source.objects.get(handle=ref_handle) dji.add_source_ref_default(parent_obj, ref_obj) - dji.rebuild_cache(parent_obj) # rebuild cache + parent_obj.save_cache() # rebuild cache return redirect("/%s/%s%s#tab-sources" % (item, handle, build_search(request))) else: context["pickform"] = pickform diff --git a/gramps/webapp/grampsdb/view/tag.py b/gramps/webapp/grampsdb/view/tag.py index ffd743b2a..924e90b2a 100644 --- a/gramps/webapp/grampsdb/view/tag.py +++ b/gramps/webapp/grampsdb/view/tag.py @@ -79,7 +79,7 @@ def process_tag(request, context, handle, act, add_to=None): # view, edit, save model = dji.get_model(item) obj = model.objects.get(handle=handle) dji.add_tag_ref_default(obj, tag) - dji.rebuild_cache(obj) + obj.save_cache() return redirect("/%s/%s#tab-tags" % (item, handle)) act = "view" else: diff --git a/gramps/webapp/grampsdb/views.py b/gramps/webapp/grampsdb/views.py index c77b3f169..f05f51645 100644 --- a/gramps/webapp/grampsdb/views.py +++ b/gramps/webapp/grampsdb/views.py @@ -274,8 +274,8 @@ def process_report_run(request, handle): # just give it, perhaps in a new tab from django.http import HttpResponse response = HttpResponse(mimetype="text/html") - content = "".join(open(filename).readlines()) - response._set_content(content) + for line in open(filename): + response.write(line) return response else: return send_file(request, filename, mimetype) @@ -1474,9 +1474,15 @@ def process_json_request(request): """ Process an Ajax/Json query request. """ + import gramps.gen.lib + from gramps.gen.proxy import PrivateProxyDb, LivingProxyDb + db = DbDjango() if not request.user.is_authenticated(): - response_data = {"results": [], "total": 0} - return HttpResponse(simplejson.dumps(response_data), mimetype="application/json") + db = PrivateProxyDb(db) + db = LivingProxyDb(db, + LivingProxyDb.MODE_INCLUDE_LAST_NAME_ONLY, + None, # current year + 1) # years after death field = request.GET.get("field", None) query = request.GET.get("q", "") page = int(request.GET.get("p", "1")) @@ -1485,40 +1491,30 @@ def process_json_request(request): q, order, terms = build_person_query(request, query) q &= Q(person__gender_type__name="Female") matches = Name.objects.filter(q).order_by(*order) - response_data = {"results": [], "total": len(matches)} - for match in matches[(page - 1) * size:page * size]: - response_data["results"].append( - {"id": match.person.handle, - "name": match.get_selection_string(), - }) + class_type = gramps.gen.lib.Person + handle_expr = "match.person.handle" elif field == "father": q, order, terms = build_person_query(request, query) q &= Q(person__gender_type__name="Male") matches = Name.objects.filter(q).order_by(*order) - response_data = {"results": [], "total": len(matches)} - for match in matches[(page - 1) * size:page * size]: - response_data["results"].append( - {"id": match.person.handle, - "name": match.get_selection_string(), - }) + class_type = gramps.gen.lib.Person + handle_expr = "match.person.handle" elif field == "person": q, order, terms = build_person_query(request, query) matches = Name.objects.filter(q).order_by(*order) - response_data = {"results": [], "total": len(matches)} - for match in matches[(page - 1) * size:page * size]: - response_data["results"].append( - {"id": match.person.handle, - "name": match.get_selection_string(), - }) + class_type = gramps.gen.lib.Person + handle_expr = "match.person.handle" elif field == "place": q, order, terms = build_place_query(request, query) matches = Place.objects.filter(q).order_by(*order) - response_data = {"results": [], "total": len(matches)} - for match in matches[(page - 1) * size:page * size]: - response_data["results"].append( - {"id": match.handle, - "name": match.get_selection_string(), - }) + class_type = gramps.gen.lib.Place + handle_expr = "match.handle" else: raise Exception("""Invalid field: '%s'; Example: /json/?field=mother&q=Smith&p=1&size=10""" % field) + ## ------------ + response_data = {"results": [], "total": len(matches)} + for match in matches[(page - 1) * size:page * size]: + obj = db.get_from_name_and_handle(class_type.__name__, eval(handle_expr)) + if obj: + response_data["results"].append(obj.to_struct()) return HttpResponse(simplejson.dumps(response_data), mimetype="application/json") diff --git a/gramps/webapp/init.py b/gramps/webapp/init.py index b581c3179..18a17a3bb 100644 --- a/gramps/webapp/init.py +++ b/gramps/webapp/init.py @@ -151,7 +151,7 @@ for table, entries in [("grampsdb.config", (("name", '"Gramps package (portable XML) Import"'), ('gramps_id', '"R0019"'), ("handle", '"im_gpkg"'), - ("options", '"iff=gramps\\ni=http://sourceforge.net/p/gramps/source/ci/master/tree/example/gramps/example.gramps"'), + ("options", '"iff=gramps\\ni=http://sourceforge.net/p/gramps/source/ci/master/tree/example/gramps/example.gramps?format=raw"'), ("report_type", '"import"')), ])]: entry_count = 0 diff --git a/gramps/webapp/libdjango.py b/gramps/webapp/libdjango.py index 9b0703e12..ec0f012c8 100644 --- a/gramps/webapp/libdjango.py +++ b/gramps/webapp/libdjango.py @@ -64,6 +64,13 @@ from gramps.gen.utils.file import fix_encoding # OR # gperson = dbdjango.DbDjango().get_person_from_handle(handle) +def check_diff(item, raw): + encoded = base64.encodestring(pickle.dumps(raw)) + if item.cache != encoded: + print("Different:", item.__class__.__name__, item.gramps_id) + print("raw :", raw) + print("cache:", item.from_cache()) + #------------------------------------------------------------------------- # # Import functions @@ -922,7 +929,7 @@ class DjangoInterface(object): last_changed=todate(changed), confidence=confidence, page=page) - citation.save() + citation.save(save_cache=False) def add_citation_detail(self, citation_data): (handle, gid, date, page, confidence, source_handle, note_list, @@ -941,12 +948,12 @@ class DjangoInterface(object): return citation.source = source self.add_date(citation, date) - citation.cache = self.encode_raw(citation_data) - citation.save() + citation.save(save_cache=False) self.add_note_list(citation, note_list) self.add_media_ref_list(citation, media_list) self.add_citation_attribute_list(citation, attribute_list) self.add_tag_list(citation, tag_list) + citation.save_cache() def add_child_ref_default(self, obj, child, frel=1, mrel=1, private=False): object_type = ContentType.objects.get_for_model(obj) # obj is family @@ -1210,8 +1217,10 @@ class DjangoInterface(object): str(parent_family_handle)), file=sys.stderr) return #person.parent_families.add(family) - pfo = models.MyParentFamilies(person=person, family=family, - order=len(models.MyParentFamilies.objects.filter(person=person)) + 1) + pfo = models.MyParentFamilies( + person=person, + family=family, + order=len(models.MyParentFamilies.objects.filter(person=person)) + 1) pfo.save() person.save() @@ -1309,8 +1318,7 @@ class DjangoInterface(object): last_changed=todate(change), private=private, gender_type=models.get_type(models.GenderType, gender)) - #person.cache = base64.encodestring(cPickle.dumps(data)) - person.save() + person.save(save_cache=False) def add_person_detail(self, data): # Unpack from the BSDDB: @@ -1378,19 +1386,9 @@ class DjangoInterface(object): if events: person.death = events[0].ref_object person.death_ref_index = lookup_role_index(models.EventType.DEATH, all_events) - person.cache = self.encode_raw(data) person.save() return person - def add_note_detail(self, data): - # Unpack from the BSDDB: - (handle, gid, styled_text, format, note_type, - change, tag_list, private) = data - note = models.Note.objects.get(handle=handle) - note.cache = self.encode_raw(data) - note.save() - self.add_tag_list(note, tag_list) - def save_note_markup(self, note, markup_list): # delete any prexisting markup: models.Markup.objects.filter(note=note).delete() @@ -1419,10 +1417,18 @@ class DjangoInterface(object): preformatted=format, text=text, note_type=models.get_type(models.NoteType, note_type)) - #n.cache = base64.encodestring(cPickle.dumps(data)) - n.save() + n.save(save_cache=False) self.save_note_markup(n, markup_list) + def add_note_detail(self, data): + # Unpack from the BSDDB: + (handle, gid, styled_text, format, note_type, + change, tag_list, private) = data + note = models.Note.objects.get(handle=handle) + note.save(save_cache=False) + self.add_tag_list(note, tag_list) + note.save_cache() + def add_family(self, data): # Unpack from the BSDDB: (handle, gid, father_handle, mother_handle, @@ -1434,8 +1440,7 @@ class DjangoInterface(object): family_rel_type = models.get_type(models.FamilyRelType, the_type), last_changed=todate(change), private=private) - #family.cache = base64.encodestring(cPickle.dumps(data)) - family.save() + family.save(save_cache=False) def add_family_detail(self, data): # Unpack from the BSDDB: @@ -1465,8 +1470,7 @@ class DjangoInterface(object): print(("ERROR: Mother does not exist: '%s'" % str(mother_handle)), file=sys.stderr) family.mother = None - family.cache = self.encode_raw(data) - family.save() + family.save(save_cache=False) self.add_child_ref_list(family, child_ref_list) self.add_note_list(family, note_list) self.add_attribute_list(family, attribute_list) @@ -1475,6 +1479,7 @@ class DjangoInterface(object): self.add_event_ref_list(family, event_ref_list) self.add_lds_list("family", family, lds_seal_list) self.add_tag_list(family, tag_list) + family.save_cache() def add_source(self, data): (handle, gid, title, @@ -1489,8 +1494,7 @@ class DjangoInterface(object): source = models.Source(handle=handle, gramps_id=gid, title=title, author=author, pubinfo=pubinfo, abbrev=abbrev, last_changed=todate(change), private=private) - #source.cache = base64.encodestring(cPickle.dumps(data)) - source.save() + source.save(save_cache=False) def add_source_detail(self, data): (handle, gid, title, @@ -1508,13 +1512,13 @@ class DjangoInterface(object): print(("ERROR: Source does not exist: '%s'" % str(handle)), file=sys.stderr) return - source.cache = self.encode_raw(data) - source.save() + source.save(save_cache=False) self.add_note_list(source, note_list) self.add_media_ref_list(source, media_list) self.add_source_attribute_list(source, attribute_list) self.add_repository_ref_list(source, reporef_list) self.add_tag_list(source, tag_list) + source.save_cache() def add_repository(self, data): (handle, gid, the_type, name, note_list, @@ -1526,8 +1530,7 @@ class DjangoInterface(object): private=private, repository_type=models.get_type(models.RepositoryType, the_type), name=name) - #repository.cache = base64.encodestring(cPickle.dumps(data)) - repository.save() + repository.save(save_cache=False) def add_repository_detail(self, data): (handle, gid, the_type, name, note_list, @@ -1538,12 +1541,12 @@ class DjangoInterface(object): print(("ERROR: Repository does not exist: '%s'" % str(handle)), file=sys.stderr) return - repository.cache = self.encode_raw(data) - repository.save() + repository.save(save_cache=False) self.add_note_list(repository, note_list) self.add_url_list("repository", repository, url_list) self.add_address_list("repository", repository, address_list) self.add_tag_list(repository, tag_list) + repository.save_cache() def add_location(self, field, obj, location_data, order): # location now has 8 items @@ -1607,7 +1610,10 @@ class DjangoInterface(object): code=code, last_changed=todate(change), private=private) - place.save() + try: + place.save(save_cache=False) + except: + print("FIXME: error in saving place") def add_place_detail(self, data): (handle, gid, title, long, lat, @@ -1629,8 +1635,7 @@ class DjangoInterface(object): print(("ERROR: Place does not exist: '%s'" % str(handle)), file=sys.stderr) return - place.cache = self.encode_raw(data) - place.save() + place.save(save_cache=False) self.add_url_list("place", place, url_list) self.add_media_ref_list(place, media_list) self.add_citation_list(place, citation_list) @@ -1641,16 +1646,7 @@ class DjangoInterface(object): for loc_data in alt_location_list: self.add_location("place", place, loc_data, count) count + 1 - - def add_tag_detail(self, data): - (handle, - name, - color, - priority, - change) = data - tag = models.Tag.objects.get(handle=handle) - tag.cache = self.encode_raw(data) - tag.save() + place.save_cache() def add_tag(self, data): (handle, @@ -1664,8 +1660,17 @@ class DjangoInterface(object): color=color, priority=priority, last_changed=todate(change)) - tag.save() + tag.save(save_cache=False) + def add_tag_detail(self, data): + (handle, + name, + color, + priority, + change) = data + tag = models.Tag.objects.get(handle=handle) + tag.save() + def add_media(self, data): (handle, gid, path, mime, desc, checksum, @@ -1680,9 +1685,8 @@ class DjangoInterface(object): path=path, mime=mime, checksum=checksum, desc=desc, last_changed=todate(change), private=private) - #media.cache = base64.encodestring(cPickle.dumps(data)) self.add_date(media, date) - media.save() + media.save(save_cache=False) def add_media_detail(self, data): (handle, gid, path, mime, desc, @@ -1700,12 +1704,12 @@ class DjangoInterface(object): print(("ERROR: Media does not exist: '%s'" % str(handle)), file=sys.stderr) return - media.cache = self.encode_raw(data) - media.save() + media.save(save_cache=False) self.add_note_list(media, note_list) self.add_citation_list(media, citation_list) self.add_attribute_list(media, attribute_list) self.add_tag_list(media, tag_list) + media.save_cache() def add_event(self, data): (handle, gid, the_type, date, description, place_handle, @@ -1717,9 +1721,8 @@ class DjangoInterface(object): private=private, description=description, last_changed=todate(change)) - #event.cache = base64.encodestring(cPickle.dumps(data)) self.add_date(event, date) - event.save() + event.save(save_cache=False) def add_event_detail(self, data): (handle, gid, the_type, date, description, place_handle, @@ -1738,13 +1741,13 @@ class DjangoInterface(object): print(("ERROR: Place does not exist: '%s'" % str(place_handle)), file=sys.stderr) event.place = place - event.cache = self.encode_raw(data) - event.save() + event.save(save_cache=False) self.add_note_list(event, note_list) self.add_attribute_list(event, attribute_list) self.add_media_ref_list(event, media_list) self.add_citation_list(event, citation_list) self.add_tag_list(event, tag_list) + event.save_cache() def get_raw(self, item): """ @@ -1772,101 +1775,6 @@ class DjangoInterface(object): raise Exception("Don't know how to get raw '%s'" % type(item)) return raw - def reset_cache(self, item): - """ - Resets the cache version of an object, but doesn't save it to the database. - """ - item.cache = self.get_cache(item) - - def encode_raw(self, raw): - return base64.encodestring(pickle.dumps(raw)) - - def get_cache(self, item): - """ - Gets the cache version of an object. - """ - raw = self.get_raw(item) - return base64.encodestring(pickle.dumps(raw)) - - def rebuild_cache(self, item): - """ - Resets the cache version of an object, and saves it to the database. - """ - self.update_public(item, save=False) - self.reset_cache(item) - item.save() - - @transaction.commit_on_success - def rebuild_caches(self, callback=None): - """ - Call this to rebuild the caches for all primary models. - """ - if not isinstance(callback, collections.Callable): - callback = lambda percent: None # dummy - - callback(0) - count = 0.0 - total = (self.Note.all().count() + - self.Person.all().count() + - self.Event.all().count() + - self.Family.all().count() + - self.Repository.all().count() + - self.Place.all().count() + - self.Media.all().count() + - self.Source.all().count() + - self.Citation.all().count() + - self.Tag.all().count()) - - for item in self.Note.all(): - self.rebuild_cache(item) - count += 1 - callback(100 * (count/total if total else 0)) - - for item in self.Person.all(): - self.rebuild_cache(item) - count += 1 - callback(100 * (count/total if total else 0)) - - for item in self.Family.all(): - self.rebuild_cache(item) - count += 1 - callback(100 * (count/total if total else 0)) - - for item in self.Source.all(): - self.rebuild_cache(item) - count += 1 - callback(100 * (count/total if total else 0)) - - for item in self.Event.all(): - self.rebuild_cache(item) - count += 1 - callback(100 * (count/total if total else 0)) - - for item in self.Repository.all(): - self.rebuild_cache(item) - count += 1 - callback(100 * (count/total if total else 0)) - - for item in self.Place.all(): - self.rebuild_cache(item) - count += 1 - callback(100 * (count/total if total else 0)) - - for item in self.Media.all(): - self.rebuild_cache(item) - count += 1 - callback(100 * (count/total if total else 0)) - - for item in self.Citation.all(): - self.rebuild_cache(item) - count += 1 - callback(100 * (count/total if total else 0)) - - for item in self.Tag.all(): - self.rebuild_cache(item) - count += 1 - callback(100) - def check_caches(self, callback=None): """ Call this to check the caches for all primary models. @@ -1889,71 +1797,62 @@ class DjangoInterface(object): for item in self.Note.all(): raw = self.get_note(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) count += 1 callback(100 * (count/total if total else 0)) for item in self.Person.all(): raw = self.get_person(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) count += 1 callback(100 * (count/total if total else 0)) for item in self.Family.all(): raw = self.get_family(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) count += 1 callback(100 * (count/total if total else 0)) for item in self.Source.all(): raw = self.get_source(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) count += 1 callback(100 * (count/total if total else 0)) for item in self.Event.all(): raw = self.get_event(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) count += 1 callback(100 * (count/total if total else 0)) for item in self.Repository.all(): raw = self.get_repository(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) count += 1 callback(100 * (count/total if total else 0)) for item in self.Place.all(): raw = self.get_place(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) count += 1 callback(100 * (count/total if total else 0)) for item in self.Media.all(): raw = self.get_media(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) + encoded = base64.encodestring(pickle.dumps(raw)) count += 1 callback(100 * (count/total if total else 0)) for item in self.Citation.all(): raw = self.get_citation(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) count += 1 callback(100 * (count/total if total else 0)) for item in self.Tag.all(): raw = self.get_tag(item) - if item.cache == base64.encodestring(pickle.dumps(raw)): - print("Different!", item) + check_diff(item, raw) count += 1 callback(100) @@ -2066,11 +1965,20 @@ class DjangoInterface(object): if obj.public != public: obj.public = public if save: + print("Updating public:", obj.__class__.__name__, obj.gramps_id) obj.save() + #log = self.Log() + #log.referenced_by = obj + #log.object_id = obj.id + #log.object_type = obj_type + #log.log_type = "update public status" + #log.reason = reason + #log.order = 0 + #log.save() def update_publics(self, callback=None): """ - Call this to check the caches for all primary models. + Call this to update probably_alive for all primary models. """ if not isinstance(callback, collections.Callable): callback = lambda percent: None # dummy diff --git a/gramps/webapp/reports.py b/gramps/webapp/reports.py index 9601be855..d72b183e6 100644 --- a/gramps/webapp/reports.py +++ b/gramps/webapp/reports.py @@ -92,10 +92,6 @@ def import_file(db, filename, user): db.prepare_import() retval = import_function(db, filename, user) db.commit_import() - # FIXME: need to call probably_alive - for person in Person.objects.all(): - person.probably_alive = not bool(person.death) - person.save() return retval return False diff --git a/gramps/webapp/utils.py b/gramps/webapp/utils.py index 36abc5a06..6b588c275 100644 --- a/gramps/webapp/utils.py +++ b/gramps/webapp/utils.py @@ -364,13 +364,13 @@ def make_image_button2(button, text, url, kwargs="", last=""): elif button == "?": # edit filename = "/images/text-editor.png" elif button == "add child to existing family": - filename = "/images/scalable/gramps-parents-open.svg" + filename = "/images/gramps-parents-open.png" elif button == "add child to new family": - filename = "/images/scalable/gramps-parents-add.svg" + filename = "/images/gramps-parents-add.png" elif button == "add spouse to existing family": - filename = "/images/scalable/add-parent-existing-family.svg" + filename = "/images/add-parent-existing-family.png" elif button == "add spouse to new family": - filename = "/images/scalable/gramps-parents.svg" + filename = "/images/gramps-parents.png" return cuni("""%s""") % (text, text, filename, url, kwargs, last) def event_table(obj, user, act, url, args): diff --git a/images/add-parent-existing-family.png b/images/add-parent-existing-family.png new file mode 100644 index 000000000..5b5d4a0ce Binary files /dev/null and b/images/add-parent-existing-family.png differ diff --git a/images/gramps-parents-add.png b/images/gramps-parents-add.png new file mode 100644 index 000000000..23c669914 Binary files /dev/null and b/images/gramps-parents-add.png differ diff --git a/images/gramps-parents-open.png b/images/gramps-parents-open.png new file mode 100644 index 000000000..ecaebff62 Binary files /dev/null and b/images/gramps-parents-open.png differ diff --git a/images/gramps-parents.png b/images/gramps-parents.png new file mode 100644 index 000000000..012b6ca75 Binary files /dev/null and b/images/gramps-parents.png differ