forked from expo/troggle
[svn] Added cave and logbook search, collapsible footer navbar, useless statistics page. Also fixed broken css. Toying with forms but not committing those yet.
Copied from http://cucc@cucc.survex.com/svn/trunk/expoweb/troggle/, rev. 8081 by aaron @ 12/8/2008 4:28 AM
This commit is contained in:
parent
47604b1db2
commit
29984ff15a
@ -1,6 +1,6 @@
|
||||
from django.db import models
|
||||
from django.contrib import admin
|
||||
|
||||
from django.forms import ModelForm
|
||||
|
||||
class Expedition(models.Model):
|
||||
year = models.CharField(max_length=20, unique=True)
|
||||
@ -79,9 +79,4 @@ class PersonTrip(models.Model):
|
||||
is_logbook_entry_author = models.BooleanField()
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s %s (%s)" % (self.person_expedition, self.place, self.date)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return "%s %s (%s)" % (self.person_expedition, self.place, self.date)
|
39
expo/search.py
Normal file
39
expo/search.py
Normal file
@ -0,0 +1,39 @@
|
||||
import re
|
||||
|
||||
from django.db.models import Q
|
||||
|
||||
# search script from http://www.julienphalip.com/blog/2008/08/16/adding-search-django-site-snap/
|
||||
|
||||
def normalize_query(query_string,
|
||||
findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
|
||||
normspace=re.compile(r'\s{2,}').sub):
|
||||
''' Splits the query string in invidual keywords, getting rid of unecessary spaces
|
||||
and grouping quoted words together.
|
||||
Example:
|
||||
|
||||
>>> normalize_query(' some random words "with quotes " and spaces')
|
||||
['some', 'random', 'words', 'with quotes', 'and', 'spaces']
|
||||
|
||||
'''
|
||||
return [normspace(' ', (t[0] or t[1]).strip()) for t in findterms(query_string)]
|
||||
|
||||
def get_query(query_string, search_fields):
|
||||
''' Returns a query, that is a combination of Q objects. That combination
|
||||
aims to search keywords within a model by testing the given search fields.
|
||||
|
||||
'''
|
||||
query = None # Query to search for every search term
|
||||
terms = normalize_query(query_string)
|
||||
for term in terms:
|
||||
or_query = None # Query to search for a given term in each field
|
||||
for field_name in search_fields:
|
||||
q = Q(**{"%s__icontains" % field_name: term})
|
||||
if or_query is None:
|
||||
or_query = q
|
||||
else:
|
||||
or_query = or_query | q
|
||||
if query is None:
|
||||
query = or_query
|
||||
else:
|
||||
query = query & or_query
|
||||
return query
|
@ -1,3 +1,4 @@
|
||||
from views_caves import *
|
||||
from views_survex import *
|
||||
from views_logbooks import *
|
||||
from views_other import *
|
||||
|
@ -1,12 +1,15 @@
|
||||
from django.shortcuts import render_to_response
|
||||
from troggle.expo.models import Cave, CaveAndEntrance
|
||||
import troggle.settings as settings
|
||||
from troggle.expo.forms import CaveForm
|
||||
import search
|
||||
|
||||
def caveindex(request):
|
||||
caves = Cave.objects.all()
|
||||
return render_to_response('caveindex.html', {'caves': caves, 'settings': settings})
|
||||
|
||||
def cave(request, cave_id):
|
||||
#hm, we're only choosing by the number within kataster, needs to be fixed. Caves in 1626 will presumably not work. - AC 7DEC08
|
||||
cave = Cave.objects.filter(kataster_number = cave_id)[0]
|
||||
return render_to_response('cave.html', {'cave': cave, 'settings': settings})
|
||||
|
||||
@ -17,3 +20,18 @@ def ent(request, cave_id, ent_letter):
|
||||
'entrance': cave_and_ent.entrance,
|
||||
'letter': cave_and_ent.entrance_letter,
|
||||
'settings': settings})
|
||||
|
||||
def caveSearch(request):
|
||||
query_string = ''
|
||||
found_entries = None
|
||||
if ('q' in request.GET) and request.GET['q'].strip():
|
||||
query_string = request.GET['q']
|
||||
entry_query = search.get_query(query_string, ['underground_description','official_name',])
|
||||
found_entries = Cave.objects.filter(entry_query)
|
||||
|
||||
return render_to_response('cavesearch.html',
|
||||
{ 'query_string': query_string, 'found_entries': found_entries, 'settings': settings})
|
||||
#context_instance=RequestContext(request))
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
from django.shortcuts import render_to_response
|
||||
from troggle.expo.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry
|
||||
import troggle.settings as settings
|
||||
import search
|
||||
|
||||
def personindex(request):
|
||||
persons = Person.objects.all()
|
||||
@ -14,4 +15,14 @@ def logbookentry(request, logbookentry_id):
|
||||
logbookentry = LogbookEntry.objects.filter(id = logbookentry_id)[0]
|
||||
return render_to_response('logbookentry.html', {'logbookentry': logbookentry, 'settings': settings})
|
||||
|
||||
def logbookSearch(request, extra):
|
||||
query_string = ''
|
||||
found_entries = None
|
||||
if ('q' in request.GET) and request.GET['q'].strip():
|
||||
query_string = request.GET['q']
|
||||
entry_query = search.get_query(query_string, ['text','title',])
|
||||
found_entries = LogbookEntry.objects.filter(entry_query)
|
||||
|
||||
return render_to_response('logbooksearch.html',
|
||||
{ 'query_string': query_string, 'found_entries': found_entries, 'settings': settings})
|
||||
#context_instance=RequestContext(request))
|
13
expo/views_other.py
Normal file
13
expo/views_other.py
Normal file
@ -0,0 +1,13 @@
|
||||
from django.shortcuts import render_to_response
|
||||
from troggle.expo.models import Cave, Expedition, Person, LogbookEntry
|
||||
import troggle.settings as settings
|
||||
from django import forms
|
||||
from django.db.models import Q
|
||||
|
||||
def stats(request):
|
||||
statsDict={}
|
||||
statsDict['expoCount'] = int(Expedition.objects.count())
|
||||
statsDict['caveCount'] = int(Cave.objects.count())
|
||||
statsDict['personCount'] = int(Person.objects.count())
|
||||
statsDict['logbookEntryCount'] = int(LogbookEntry.objects.count())
|
||||
return render_to_response('statistics.html', statsDict)
|
@ -5,11 +5,12 @@
|
||||
body, td, center, ul, p, input { color: #000; font-family: sans-serif; }
|
||||
a:link, a:visited { text-decoration: none; }
|
||||
div.centre img { vertical-align: middle; }
|
||||
h1 { text-align: center; font-size: 210%;
|
||||
line-height: 100%; }
|
||||
|
||||
h1 { text-align: center; font-size: 210%; line-height: 100%; }
|
||||
h2 { color: #009900; }
|
||||
h3 { color: #2c105e; }
|
||||
h4 { color: #0d664c; }
|
||||
h4.navbar {line-height: 0px;}
|
||||
img.onright, div.onright { vertical-align: top; float: right;
|
||||
margin-left: 10pt; margin-bottom: 10pt;
|
||||
margin-right: 8pt; }
|
||||
@ -22,6 +23,10 @@ table.imgtable { margin-left: auto; margin-right: auto; }
|
||||
table.imgtable td { vertical-align: middle; text-align: center;
|
||||
padding: 10px; }
|
||||
|
||||
table.normal { border: thin; border-top:solid ; border-left:dotted ; border-bottom:dotted; border-right:hidden ; border-width:1px;}
|
||||
table.normal td { border: thin; border-right:dotted ; border-width:1px; border-spacing:0px }
|
||||
table.normal th { border-left:thin ; border-right:thin ; text-align: left}
|
||||
|
||||
/* "Traditional" table with borders.*/
|
||||
table.trad { margin: 0pt; border: 1px solid #000;
|
||||
border-color: #c0c0c0 #8d8d8d #8d8d8d #c0c0c0; }
|
||||
@ -29,6 +34,30 @@ table.bigfatborder { border-width: 6px; }
|
||||
table.trad td, table.trad th { margin: 0pt; border: 1px solid #aaa;
|
||||
border-color: #8d8d8d #c0c0c0 #c0c0c0 #8d8d8d; }
|
||||
|
||||
/*Divs for layout*/
|
||||
html, body, div.contents {
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
html>body, html>body div.contents {
|
||||
height: auto;
|
||||
}
|
||||
body {
|
||||
}
|
||||
div.contents {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
div.footer {
|
||||
position: fixed;
|
||||
bottom: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
div.main {
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
|
||||
/* You are not expected to understand this. It is necessary. */
|
||||
table.centre { margin-left: auto; margin-right: auto; }
|
||||
table.centre td { text-align: left; }
|
||||
@ -40,4 +69,4 @@ table#cavepage th#name { text-align: center; width: 50%; }
|
||||
table#cavepage th#status { text-align: right; width: 25%; }
|
||||
|
||||
.command { color: #FF0000; }
|
||||
.comment { color: #888888; font-style:italic;}
|
||||
.comment { color: #888888; font-style:italic;}
|
||||
|
@ -73,7 +73,7 @@ def LoadPersons():
|
||||
# this fills in those peopl for whom 2008 was their first expo
|
||||
for name in expomissing:
|
||||
firstname, lastname = name.split()
|
||||
is_guest = name in ["Eeva Makiranta", "Kieth Curtis"]
|
||||
is_guest = name in ["Eeva Makiranta", "Keith Curtis"]
|
||||
pObject = models.Person(first_name = firstname,
|
||||
last_name = lastname,
|
||||
is_vfho = False,
|
||||
|
@ -29,7 +29,8 @@ USE_I18N = True
|
||||
|
||||
# Absolute path to the directory that holds media.
|
||||
# Example: "/home/media/media.lawrence.com/"
|
||||
MEDIA_ROOT = '/media-admin/'
|
||||
# MOVED TO LOCALSETTINGS
|
||||
MEDIA_ROOT = 'C:/Expo/expoweb/troggle/media/'
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash if there is a path component (optional in other cases).
|
||||
|
@ -2,11 +2,67 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}/css/main2.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/main2.css" />
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
|
||||
<!-- script to toggle navbar -->
|
||||
|
||||
<script language="javascript">
|
||||
<!--
|
||||
function showFooter(){
|
||||
document.getElementById('footerHidden').style.display = 'none';
|
||||
document.getElementById('footerShowing').style.display = 'block';
|
||||
}
|
||||
|
||||
function hideFooter(){
|
||||
document.getElementById('footerHidden').style.display = 'block';
|
||||
document.getElementById('footerShowing').style.display = 'none';
|
||||
}
|
||||
|
||||
function makeTransparent(){
|
||||
document.getElementById('footerShowing').style.backgroundColor = 'transparent';
|
||||
}
|
||||
-->
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="contents">
|
||||
<div class="main">
|
||||
{% block content %}{% endblock %}
|
||||
{% block footer %}{% endblock %}
|
||||
</div>
|
||||
{% block footer %}
|
||||
|
||||
<div class="footer" id="footerHidden" style="display:none">
|
||||
<h4><a href="javascript:;" onMouseDown="showFooter();">[Show Troggle Navigation / Search]</a></h4>
|
||||
</div>
|
||||
|
||||
<div class="footer" id="footerShowing" style="background-color:#CCC">
|
||||
<h4 class="navbar"> Troggle navigation <a href="javascript:;" onMouseDown="hideFooter();">[Hide]</a> or <a href="javascript:;" onMouseDown="makeTransparent();">[Make transparent]</a></align></h4>
|
||||
<table class="normal">
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
<a href="{{ settings.URL_ROOT }}cave">list caves</a> or
|
||||
<form name="input" action="{{ settings.URL_ROOT }}cavesearch" method="get">
|
||||
<input type="text" name="q" value="search caves">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</td>
|
||||
<td rowspan="2">
|
||||
<a href="{{ settings.URL_ROOT }}logbookentry">list logbook entries</a> or
|
||||
<form name="input" action="{{ settings.URL_ROOT }}logbooksearch" method="get">
|
||||
<input type="text" name="q" value="search logbooks">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</td>
|
||||
<td><a href="{{ settings.URL_ROOT }}person">list cavers</a></td>
|
||||
<td><a href="{{ settings.URL_ROOT }}statistics"> statistics</a></td>
|
||||
<tr>
|
||||
<td><a href="{{ settings.URL_ROOT }}photos">photos</a></td>
|
||||
<td><a href="{{ settings.URL_ROOT }}admin"> admin</a></td>
|
||||
</table>
|
||||
</div>
|
||||
<p>{% endblock %}</p>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -73,4 +73,4 @@
|
||||
<h2>Notes</h2>
|
||||
{{ cave.notes|wiki_to_html }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
8
templates/statistics.html
Normal file
8
templates/statistics.html
Normal file
@ -0,0 +1,8 @@
|
||||
{% extends "base.html" %}
|
||||
{% load wiki_markup %}
|
||||
|
||||
{% block title %}Database statistics{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
Over the course of {{ expoCount }} expeditions, {{ personCount }} people have contributed {{ caveCount }} caves and {{ logbookEntryCount }} logbook entries.
|
||||
{% endblock %}
|
11
urls.py
11
urls.py
@ -1,6 +1,6 @@
|
||||
from django.conf.urls.defaults import *
|
||||
from expo.views import *
|
||||
|
||||
import troggle.settings as settings
|
||||
from django.contrib import admin
|
||||
admin.autodiscover()
|
||||
|
||||
@ -9,6 +9,8 @@ urlpatterns = patterns('',
|
||||
(r'^cave/$', caveindex),
|
||||
(r'^cave/(?P<cave_id>[^/]+)/$', cave),
|
||||
(r'^cave/(?P<cave_id>[^/]+)/(?P<ent_letter>[^/]?)$', ent),
|
||||
(r'^cave/(?P<cave_id>[^/]+)/edit/$', edit_cave),
|
||||
(r'^cavesearch/$', caveSearch),
|
||||
|
||||
(r'^survex/(?P<survex_file>.*)\.index$', index),
|
||||
(r'^survex/(?P<survex_file>.*)\.svx$', svx),
|
||||
@ -20,11 +22,14 @@ urlpatterns = patterns('',
|
||||
(r'^person/(.*)$', person),
|
||||
|
||||
(r'^logbookentry/(.*)$', logbookentry),
|
||||
(r'^logbooksearch/(.*)$', logbookSearch),
|
||||
|
||||
(r'^troggle/statistics/$', stats),
|
||||
|
||||
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
(r'^admin/(.*)', admin.site.root),
|
||||
|
||||
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
|
||||
{'document_root': 'c:/expodjango/troggle/media/'}),
|
||||
(r'^troggle/site_media/(?P<path>.*)$', 'django.views.static.serve',
|
||||
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
|
||||
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user