2011-10-15 20:21:48 +00:00

727 lines
28 KiB
Python

# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2009 Douglas S. Blank <doug.blank@gmail.com>
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#
""" Main view handlers """
import os
#------------------------------------------------------------------------
#
# Django Modules
#
#------------------------------------------------------------------------
from django.contrib.auth import logout
from django.contrib.auth.models import User
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.http import Http404, HttpResponseRedirect, HttpResponse
from django.shortcuts import get_object_or_404, render_to_response, redirect
from django.template import Context, RequestContext, escape
from django.db.models import Q
#------------------------------------------------------------------------
#
# Gramps Modules
#
#------------------------------------------------------------------------
import web
from web.grampsdb.models import *
from web.grampsdb.forms import *
from web.dbdjango import DbDjango
import gen.proxy
from Utils import create_id
import const
_ = lambda text: text
# Views: [(<Nice name plural>, /<name>/handle, <Model>), ]
VIEWS = [(_('People'), 'person', Name),
(_('Families'), 'family', Family),
(_('Events'), 'event', Event),
(_('Notes'), 'note', Note),
(_('Media'), 'media', Media),
(_('Sources'), 'source', Source),
(_('Places'), 'place', Place),
(_('Repositories'), 'repository', Repository),
(_('Tags'), 'tag', Tag),
]
def context_processor(request):
"""
This function is executed before template processing.
takes a request, and returns a dictionary context.
"""
context = {}
if request.user.is_authenticated():
profile = request.user.get_profile()
context["css_theme"] = profile.css_theme
else:
context["css_theme"] = "Web_Mainz.css"
# Other things for all environments:
context["gramps_version"] = const.VERSION
context["views"] = VIEWS
context["True"] = True
context["False"] = False
context["default"] = ""
return context
def main_page(request):
context = RequestContext(request)
context["view"] = 'home'
context["tview"] = _('Home')
return render_to_response("main_page.html", context)
def logout_page(request):
context = RequestContext(request)
context["view"] = 'home'
context["tview"] = _('Home')
logout(request)
# TODO: allow this once we have an error page
#if request.GET.has_key("next"):
# return redirect(request.GET.get("next"), context)
return HttpResponseRedirect('/')
def user_page(request, username):
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise Http404(_('Requested user not found.'))
context = RequestContext(request)
context["username"] = username
context["view"] = 'user'
context["tview"] = _('User')
return render_to_response('user_page.html', context)
def fix_person(request, person):
try:
name = person.name_set.get(preferred=True)
except:
names = person.name_set.all().order_by("order")
if names.count() == 0:
name = Name(person=person,
surname_set=[Surname(surname="? Fixed")],
first_name="? Missing name",
preferred=True)
name.save()
else:
order = 1
for name in names:
if order == 1:
name.preferred = True
else:
name.preferred = False
name.order = order
name.save()
order += 1
if request:
return redirect("/person/%s" % person.handle, request)
def set_date(obj):
obj.calendar = 0
obj.modifier = 0
obj.quality = 0
obj.text = ""
obj.sortval = 0
obj.newyear = 0
obj.day1, obj.month1, obj.year1, obj.slash1 = 0, 0, 0, 0
obj.day2, obj.month2, obj.year2, obj.slash2 = 0, 0, 0, 0
def view_name_detail(request, handle, order, action="view"):
if order == "add":
order = 0
action = "add"
if request.POST.has_key("action"):
action = request.POST.get("action")
if action == "view":
person = Person.objects.get(handle=handle)
try:
name = person.name_set.filter(order=order)[0]
except:
return fix_person(request, person)
form = NameForm(instance=name)
form.model = name
elif action == "edit":
person = Person.objects.get(handle=handle)
name = person.name_set.filter(order=order)[0]
form = NameForm(instance=name)
form.model = name
elif action == "delete":
person = Person.objects.get(handle=handle)
names = person.name_set.all().order_by("order")
if names.count() > 1:
name_to_delete = names[0]
was_preferred = name_to_delete.preferred
name_to_delete.delete()
names = person.name_set.all().order_by("order")
for count in range(names[1:].count()):
if was_preferred:
names[count].preferred = True
was_preferred = False
names[count].order = count
names[count].save()
form = NameForm()
name = Name()
action = "back"
elif action == "add": # add name
person = Person.objects.get(handle=handle)
name = Name(person=person,
display_as=NameFormatType.objects.get(val=0),
sort_as=NameFormatType.objects.get(val=0),
name_type=NameType.objects.get(val=2))
form = NameForm(instance=name)
form.model = name
action = "edit"
elif action == "save":
person = Person.objects.get(handle=handle)
try:
name = person.name_set.filter(order=order)[0]
except:
order = person.name_set.count() + 1
name = Name(person=person, order=order)
form = NameForm(request.POST, instance=name)
form.model = name
if form.is_valid():
# now it is preferred:
if name.preferred: # was preferred, stil must be
form.cleaned_data["preferred"] = True
elif form.cleaned_data["preferred"]: # now is
# set all of the other names to be
# not preferred:
person.name_set.filter(~ Q(id=name.id)) \
.update(preferred=False)
# else some other name is preferred
set_date(name)
n = form.save()
else:
action = "edit"
context = RequestContext(request)
context["action"] = action
context["tview"] = _('Name')
context["view"] = 'name'
context["handle"] = handle
context["id"] = id
context["person"] = person
context["form"] = form
context["order"] = name.order
context["next"] = "/person/%s/name/%d" % (person.handle, name.order)
view_template = "view_name_detail.html"
if action == "save":
context["action"] = "view"
return redirect("/person/%s/name/%d" %
(person.handle, name.order), context)
elif action == "back":
return redirect("/person/%s/" %
(person.handle), context)
else:
return render_to_response(view_template, context)
def send_file(request, filename, mimetype):
"""
Send a file through Django without loading the whole file into
memory at once. The FileWrapper will turn the file object into an
iterator for chunks of 8KB.
"""
from django.core.servers.basehttp import FileWrapper
wrapper = FileWrapper(file(filename))
response = HttpResponse(wrapper, mimetype=mimetype)
path, base = os.path.split(filename)
response['Content-Length'] = os.path.getsize(filename)
response['Content-Disposition'] = 'attachment; filename=%s' % base
return response
def process_action(request, view, handle, action):
from web.reports import import_file
from web.reports import export_file
from cli.plug import run_report
db = DbDjango()
if view == "report":
if request.user.is_authenticated():
profile = request.user.get_profile()
report = Report.objects.get(handle=handle)
if action == "run":
args = {"off": "pdf"} # basic defaults
# override from given defaults in table:
if report.options:
for pair in str(report.options).split(" "):
if "=" in pair:
key, value = pair.split("=", 1)
args[key] = value
# override from options on webpage:
if request.GET.has_key("options"):
options = str(request.GET.get("options"))
if options:
for pair in options.split("%3D"): # from webpage
if "=" in pair:
key, value = pair.split("=", 1)
args[key] = value
if report.report_type == "textreport":
filename = "/tmp/%s-%s.%s" % (str(profile.user.username), str(handle), args["off"])
run_report(db, handle, of=filename, **args)
mimetype = 'application/%s' % args["off"]
elif report.report_type == "export":
filename = "/tmp/%s-%s.%s" % (str(profile.user.username), str(handle), args["off"])
export_file(db, filename, lambda n: n) # callback
mimetype = 'text/plain'
else:
pass # FIXME: error
return send_file(request, filename, mimetype)
# If failure, just fail for now:
context = RequestContext(request)
context["tview"] = "Results"
#context["view"] = view
#context["handle"] = handle
#context["action"] = action
context["message"] = "You need to be logged in."
#context["message"] = filename
return render_to_response("process_action.html", context)
def view_detail(request, view, handle, action="view"):
context = RequestContext(request)
context["action"] = action
context["view"] = view
if view == "event":
try:
obj = Event.objects.get(handle=handle)
except:
raise Http404(_("Requested %s does not exist.") % view)
view_template = 'view_event_detail.html'
context["tview"] = _("Event")
elif view == "family":
try:
obj = Family.objects.get(handle=handle)
except:
raise Http404(_("Requested %s does not exist.") % view)
view_template = 'view_family_detail.html'
context["tview"] = _("Family")
elif view == "media":
try:
obj = Media.objects.get(handle=handle)
except:
raise Http404(_("Requested %s does not exist.") % view)
view_template = 'view_media_detail.html'
context["tview"] = _("Media")
elif view == "note":
try:
obj = Note.objects.get(handle=handle)
except:
raise Http404(_("Requested %s does not exist.") % view)
view_template = 'view_note_detail.html'
context["tview"] = _("Note")
elif view == "person":
return view_person_detail(request, view, handle, action)
elif view == "place":
try:
obj = Place.objects.get(handle=handle)
except:
raise Http404(_("Requested %s does not exist.") % view)
view_template = 'view_place_detail.html'
context["tview"] = _("Place")
elif view == "repository":
try:
obj = Repository.objects.get(handle=handle)
except:
raise Http404(_("Requested %s does not exist.") % view)
view_template = 'view_repository_detail.html'
context["tview"] = _("Repository")
elif view == "source":
try:
obj = Source.objects.get(handle=handle)
except:
raise Http404(_("Requested %s does not exist.") % view)
view_template = 'view_source_detail.html'
context["tview"] = _("Source")
elif view == "tag":
try:
obj = Tag.objects.get(handle=handle)
except:
raise Http404(_("Requested %s does not exist.") % view)
view_template = 'view_tag_detail.html'
context["tview"] = _("Tag")
elif view == "report":
try:
obj = Report.objects.get(handle=handle)
except:
raise Http404(_("Requested %s does not exist.") % view)
view_template = 'view_report_detail.html'
context["tview"] = _("Report")
else:
raise Http404(_("Requested page type not known"))
context[view] = obj
context["next"] = "/%s/%s" % (view, obj.handle)
return render_to_response(view_template, context)
def view_person_detail(request, view, handle, action="view"):
context = RequestContext(request)
if handle == "add":
if request.POST.has_key("action"):
action = request.POST.get("action")
else:
action = "add"
elif request.POST.has_key("action"):
action = request.POST.get("action")
if request.user.is_authenticated():
if action == "edit":
# get all of the data:
person = Person.objects.get(handle=handle)
try:
name = person.name_set.get(preferred=True)
except:
name = Name(person=person, preferred=True)
pf = PersonForm(instance=person)
pf.model = person
nf = NameForm(instance=name)
nf.model = name
elif action == "add":
# make new data:
person = Person()
name = Name(person=person, preferred=True,
display_as=NameFormatType.objects.get(val=0),
sort_as=NameFormatType.objects.get(val=0),
name_type=NameType.objects.get(val=2))
nf = NameForm(instance=name)
nf.model = name
pf = PersonForm(instance=person)
pf.model = person
action = "edit"
elif action == "save":
try:
person = Person.objects.get(handle=handle)
except:
person = Person(handle=create_id())
if person.id: # editing
name = person.name_set.get(preferred=True)
else: # adding a new person with new name
name = Name(person=person, preferred=True)
pf = PersonForm(request.POST, instance=person)
pf.model = person
nf = NameFormFromPerson(request.POST, instance=name)
nf.model = name
if nf.is_valid() and pf.is_valid():
person = pf.save()
name = nf.save(commit=False)
name.person = person
name.save()
else:
action = "edit"
else: # view
person = Person.objects.get(handle=handle)
try:
name = person.name_set.get(preferred=True)
except:
return fix_person(request, person)
pf = PersonForm(instance=person)
pf.model = person
nf = NameForm(instance=name)
nf.model = name
else: # view person detail
# BEGIN NON-AUTHENTICATED ACCESS
person = Person.objects.get(handle=handle)
if person:
if person.private:
raise Http404(_("Requested %s is not accessible.") % view)
name = person.name_set.get(preferred=True)
if person.probably_alive:
name.sanitize()
else:
raise Http404(_("Requested %s does not exist.") % view)
pf = PersonForm(instance=person)
pf.model = person
nf = NameForm(instance=name)
nf.model = name
# END NON-AUTHENTICATED ACCESS
if action == "save":
context["action"] = "view"
return redirect("/person/%s" % person.handle, context)
context["action"] = action
context["view"] = view
context["tview"] = _("Person")
context["personform"] = pf
context["nameform"] = nf
context["person"] = person
context["next"] = "/person/%s" % person.handle
view_template = 'view_person_detail.html'
return render_to_response(view_template, context)
def view(request, view):
search = ""
if view == "event":
if request.user.is_authenticated():
private = Q()
else:
# NON-AUTHENTICATED users
private = Q(private=False)
if request.GET.has_key("search"):
search = request.GET.get("search")
object_list = Event.objects \
.filter((Q(gramps_id__icontains=search) |
Q(event_type__name__icontains=search) |
Q(place__title__icontains=search)) &
private
) \
.order_by("gramps_id")
else:
object_list = Event.objects.filter(private).order_by("gramps_id")
view_template = 'view_events.html'
total = Event.objects.all().count()
elif view == "family":
if request.user.is_authenticated():
if request.GET.has_key("search"):
search = request.GET.get("search")
if "," in search:
surname, first = [term.strip() for term in
search.split(",", 1)]
object_list = Family.objects \
.filter((Q(father__name__surname__surname__istartswith=surname) &
Q(father__name__first_name__istartswith=first)) |
(Q(mother__name__surname__surname__istartswith=surname) &
Q(mother__name__first_name__istartswith=first))
) \
.order_by("gramps_id")
else: # no comma
object_list = Family.objects \
.filter(Q(gramps_id__icontains=search) |
Q(family_rel_type__name__icontains=search) |
Q(father__name__surname__surname__istartswith=search) |
Q(father__name__first_name__istartswith=search) |
Q(mother__name__surname__surname__istartswith=search) |
Q(mother__name__first_name__istartswith=search)
) \
.order_by("gramps_id")
else: # no search
object_list = Family.objects.all().order_by("gramps_id")
else:
# NON-AUTHENTICATED users
if request.GET.has_key("search"):
search = request.GET.get("search")
if "," in search:
search_text, trash = [term.strip() for term in search.split(",", 1)]
else:
search_text = search
object_list = Family.objects \
.filter((Q(gramps_id__icontains=search_text) |
Q(family_rel_type__name__icontains=search_text) |
Q(father__name__surname__surname__istartswith=search_text) |
Q(mother__name__surname__surname__istartswith=search_text)) &
Q(private=False) &
Q(mother__private=False) &
Q(father__private=False)
) \
.order_by("gramps_id")
else:
object_list = Family.objects \
.filter(Q(private=False) &
Q(mother__private=False) &
Q(father__private=False)
) \
.order_by("gramps_id")
view_template = 'view_families.html'
total = Family.objects.all().count()
elif view == "media":
if request.user.is_authenticated():
private = Q()
else:
# NON-AUTHENTICATED users
private = Q(private=False)
if request.GET.has_key("search"):
search = request.GET.get("search")
object_list = Media.objects \
.filter(Q(gramps_id__icontains=search) &
private
) \
.order_by("gramps_id")
else:
object_list = Media.objects.filter(private).order_by("gramps_id")
view_template = 'view_media.html'
total = Media.objects.all().count()
elif view == "note":
if request.user.is_authenticated():
private = Q()
else:
# NON-AUTHENTICATED users
private = Q(private=False)
if request.GET.has_key("search"):
search = request.GET.get("search")
object_list = Note.objects \
.filter((Q(gramps_id__icontains=search) |
Q(note_type__name__icontains=search) |
Q(text__icontains=search)) &
private
) \
.order_by("gramps_id")
else:
object_list = Note.objects.filter(private).order_by("gramps_id")
view_template = 'view_notes.html'
total = Note.objects.all().count()
elif view == "person":
if request.user.is_authenticated():
if request.GET.has_key("search"):
search = request.GET.get("search")
if "," in search:
surname, first_name = [term.strip() for term in
search.split(",", 1)]
object_list = Name.objects \
.filter(Q(surname__surname__istartswith=surname,
first_name__istartswith=first_name)) \
.order_by("surname__surname", "first_name")
else:
object_list = Name.objects \
.filter((Q(surname__surname__icontains=search) |
Q(first_name__icontains=search) |
Q(suffix__icontains=search) |
Q(surname__prefix__icontains=search) |
Q(title__icontains=search) |
Q(person__gramps_id__icontains=search))
) \
.order_by("surname__surname", "first_name")
else:
object_list = Name.objects.all().order_by("surname__surname", "first_name")
else:
# BEGIN NON-AUTHENTICATED users
if request.GET.has_key("search"):
search = request.GET.get("search")
if "," in search:
search_text, trash = [term.strip() for term in search.split(",", 1)]
else:
search_text = search
object_list = Name.objects \
.select_related() \
.filter(Q(surname__surname__istartswith=search_text) &
Q(private=False) &
Q(person__private=False)
) \
.order_by("surname__surname", "first_name")
else:
object_list = Name.objects \
.select_related() \
.filter(Q(private=False) &
Q(person__private=False)) \
.order_by("surname__surname", "first_name")
# END NON-AUTHENTICATED users
view_template = 'view_people.html'
total = Name.objects.all().count()
elif view == "place":
if request.user.is_authenticated():
private = Q()
else:
# NON-AUTHENTICATED users
private = Q(private=False)
if request.GET.has_key("search"):
search = request.GET.get("search")
object_list = Place.objects \
.filter((Q(gramps_id__icontains=search) |
Q(title__icontains=search)
) &
private
) \
.order_by("gramps_id")
else:
object_list = Place.objects.filter(private).order_by("gramps_id")
view_template = 'view_places.html'
total = Place.objects.all().count()
elif view == "repository":
if request.user.is_authenticated():
private = Q()
else:
# NON-AUTHENTICATED users
private = Q(private=False)
if request.GET.has_key("search"):
search = request.GET.get("search")
object_list = Repository.objects \
.filter((Q(gramps_id__icontains=search) |
Q(name__icontains=search) |
Q(repository_type__name__icontains=search)
) &
private
) \
.order_by("gramps_id")
else:
object_list = Repository.objects.filter(private).order_by("gramps_id")
view_template = 'view_repositories.html'
total = Repository.objects.all().count()
elif view == "source":
if request.user.is_authenticated():
private = Q()
else:
# NON-AUTHENTICATED users
private = Q(private=False)
if request.GET.has_key("search"):
search = request.GET.get("search")
object_list = Source.objects \
.filter(Q(gramps_id__icontains=search) &
private
) \
.order_by("gramps_id")
else:
object_list = Source.objects.filter(private).order_by("gramps_id")
view_template = 'view_sources.html'
total = Source.objects.all().count()
elif view == "tag":
if request.GET.has_key("search"):
search = request.GET.get("search")
object_list = Tag.objects \
.filter(Q(name__icontains=search)) \
.order_by("name")
else:
object_list = Tag.objects.order_by("name")
view_template = 'view_tags.html'
total = Tag.objects.all().count()
elif view == "report":
if request.GET.has_key("search"):
search = request.GET.get("search")
object_list = Report.objects \
.filter(Q(name__icontains=search)) \
.order_by("name")
else:
object_list = Report.objects.all().order_by("name")
view_template = 'view_report.html'
total = Report.objects.all().count()
else:
raise Http404("Requested page type '%s' not known" % view)
if request.user.is_authenticated():
paginator = Paginator(object_list, 20)
else:
paginator = Paginator(object_list, 20)
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
try:
page = paginator.page(page)
except (EmptyPage, InvalidPage):
page = paginator.page(paginator.num_pages)
context = RequestContext(request)
context["page"] = page
context["view"] = view
context["tview"] = _(view.title())
context["search"] = search
context["total"] = total
context["object_list"] = object_list
context["next"] = "/%s/" % view
if search:
context["search_query"] = ("&search=%s" % search)
else:
context["search_query"] = ""
return render_to_response(view_template, context)