Document upload and metadata input working

This commit is contained in:
Roberto Rosario
2011-02-03 17:17:04 -04:00
parent fc6545f45a
commit 986dc5d805
77 changed files with 2851 additions and 57 deletions

0
apps/common/__init__.py Normal file
View File

32
apps/common/api.py Normal file
View File

@@ -0,0 +1,32 @@
import copy
object_navigation = {}
menu_links = []
def register_links(src, links, menu_name=None):
if menu_name in object_navigation:
if hasattr(src, '__iter__'):
for one_src in src:
if one_src in object_navigation[menu_name]:
object_navigation[menu_name][one_src]['links'].extend(links)
else:
object_navigation[menu_name][one_src]={'links':copy.copy(links)}
else:
if src in object_navigation[menu_name]:
object_navigation[menu_name][src]['links'].extend(links)
else:
object_navigation[menu_name][src] = {'links':links}
else:
object_navigation[menu_name] = {}
if hasattr(src, '__iter__'):
for one_src in src:
object_navigation[menu_name][one_src] = {'links':links}
else:
object_navigation[menu_name] = {src:{'links':links}}
def register_menu(links):
for link in links:
menu_links.append(link)
menu_links.sort(lambda x,y: 1 if x>y else -1, lambda x:x['position'] if 'position' in x else 1)

109
apps/common/forms.py Normal file
View File

@@ -0,0 +1,109 @@
from django import forms
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
from django.db import models
import types
def return_attrib(obj, attrib, arguments=None):
try:
result = reduce(getattr, attrib.split("."), obj)
if isinstance(result, types.MethodType):
if arguments:
return result(**arguments)
else:
return result()
else:
return result
except Exception, err:
if settings.DEBUG:
return "Attribute error: %s; %s" % (attrib, err)
else:
pass
class DetailSelectMultiple(forms.widgets.SelectMultiple):
def __init__(self, queryset=None, *args, **kwargs):
self.queryset=queryset
super(DetailSelectMultiple, self).__init__(*args, **kwargs)
def render(self, name, value, attrs=None, choices=()):
if value is None: value = ''
#final_attrs = self.build_attrs(attrs, name=name)
output = u'<ul class="list">'
options = None
if value:
if getattr(value, '__iter__', None):
options = [(index, string) for index, string in self.choices if index in value]
else:
options = [(index, string) for index, string in self.choices if index == value]
else:
if self.choices:
if self.choices[0] != (u'', u'---------') and value != []:
options = [(index, string) for index, string in self.choices]
if options:
for index, string in options:
if self.queryset:
try:
output += u'<li><a href="%s">%s</a></li>' % (self.queryset.get(pk=index).get_absolute_url(), string)
except AttributeError:
output += u'<li>%s</li>' % (string)
else:
output += u'<li>%s</li>' % string
else:
output += u'<li>%s</li>' % _(u"None")
return mark_safe(output + u'</ul>\n')
class DetailForm(forms.ModelForm):
def __init__(self, extra_fields=None, *args, **kwargs):
super(DetailForm, self).__init__(*args, **kwargs)
if extra_fields:
for extra_field in extra_fields:
result = return_attrib(self.instance, extra_field['field'])
label = 'label' in extra_field and extra_field['label'] or None
#TODO: Add others result types <=> Field types
if isinstance(result, models.query.QuerySet):
self.fields[extra_field['field']]=forms.ModelMultipleChoiceField(queryset=result, label=label)
for field_name, field in self.fields.items():
if isinstance(field.widget, forms.widgets.SelectMultiple):
self.fields[field_name].widget = DetailSelectMultiple(
choices=field.widget.choices,
attrs=field.widget.attrs,
queryset=getattr(field, 'queryset', None),
)
self.fields[field_name].help_text=''
elif isinstance(field.widget, forms.widgets.Select):
self.fields[field_name].widget = DetailSelectMultiple(
choices=field.widget.choices,
attrs=field.widget.attrs,
queryset=getattr(field, 'queryset', None),
)
self.fields[field_name].help_text=''
class GenericConfirmForm(forms.Form):
pass
class GenericAssignRemoveForm(forms.Form):
left_list = forms.ModelMultipleChoiceField(required=False, queryset=None)
right_list = forms.ModelMultipleChoiceField(required=False, queryset=None)
def __init__(self, left_list_qryset=None, right_list_qryset=None, left_filter=None, *args, **kwargs):
super(GenericAssignRemoveForm, self).__init__(*args, **kwargs)
if left_filter:
self.fields['left_list'].queryset = left_list_qryset.filter(*left_filter)
else:
self.fields['left_list'].queryset = left_list_qryset
self.fields['right_list'].queryset = right_list_qryset
class FilterForm(forms.Form):
def __init__(self, list_filters, *args, **kwargs):
super(FilterForm, self).__init__(*args, **kwargs)
for list_filter in list_filters:
label = list_filter.get('title', list_filter['name'])
self.fields[list_filter['name']] = forms.ModelChoiceField(queryset=list_filter['queryset'], label=label[0].upper() + label[1:], required=False)

Binary file not shown.

View File

@@ -0,0 +1,33 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-01-28 09:33-0400\n"
"PO-Revision-Date: 2011-01-28 09:33\n"
"Last-Translator: <admin@admin.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"X-Translated-Using: django-rosetta 0.5.6\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: views.py:6 templates/password_change_done.html:5
msgid "Your password has been successfully changed."
msgstr "Su contraseña se ha modificado correctamente."
#: templates/login.html:5
msgid "Login"
msgstr "Iniciar sesión"
#: templates/password_change_done.html:3 templates/password_change_form.html:3
#: templates/password_change_form.html:5
msgid "Password change"
msgstr "Cambio de contraseña"

Binary file not shown.

View File

@@ -0,0 +1,33 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-01-30 16:51+0300\n"
"PO-Revision-Date: 2011-01-30 13:08\n"
"Last-Translator: <garison2004@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"X-Translated-Using: django-rosetta 0.5.5\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#: views.py:6 templates/password_change_done.html:5
msgid "Your password has been successfully changed."
msgstr "Ваш пароль был успешно изменен."
#: templates/login.html:5
msgid "Login"
msgstr "Логин"
#: templates/password_change_done.html:3 templates/password_change_form.html:3
#: templates/password_change_form.html:5
msgid "Password change"
msgstr "Сменить пароль"

3
apps/common/models.py Normal file
View File

@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

@@ -0,0 +1,9 @@
{% extends "base.html" %}
{% block title %}Page not found{% endblock %}
{% block content %}
<h1>Page not found</h1>
<p>Sorry, but the requested page could not be found.</p>
{% endblock %}

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Page unavailable</title>
</head>
<body>
<h1>Page unavailable</h1>
<p>Sorry, but the requested page is unavailable due to a
server problem.</p>
<p>Administrators have been notified, so check back later.</p>
</body>
</html>

View File

@@ -0,0 +1,30 @@
{% load i18n %}
{% if title %}
{% if striptags %}
{{ title|capfirst|striptags }}
{% else %}
{{ title|capfirst|safe }}
{% endif %}
{% else %}
{% if read_only %}
{% if object_name %}
{% blocktrans %}Details for {{ object_name }}: {{ object }}{% endblocktrans %}
{% else %}
{% blocktrans %}Details for: {{ object }}{% endblocktrans %}
{% endif %}
{% else %}
{% if object %}
{% if object_name %}
{% blocktrans %}Edit {{ object_name }}:{% endblocktrans %} {% if not striptags %}<a href="{{ object.get_absolute_url }}">{% endif %}{{ object|capfirst }}{% if not striptags %}</a>{% endif %}
{% else %}
{% trans "Edit" %}: {% if not striptags %}<a href="{{ object.get_absolute_url }}">{% endif %}{{ object|capfirst }}{% if not striptags %}</a>{% endif %}
{% endif %}
{% else %}
{% if object_name %}
{% blocktrans %}Create new {{ object_name }}{% endblocktrans %}
{% else %}
{% trans "Create" %}
{% endif %}
{% endif %}
{% endif %}
{% endif %}

View File

@@ -0,0 +1,43 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %} :: {% blocktrans %}Assign {{ title }} {{ object }}{% endblocktrans %}{% endblock %}
{% block content %}
<style>
#id_right_list,#id_left_list { min-width: 28em; min-height: 13em; }
</style>
<div class="content">
<h2 class="title">{{ title|safe }}</h2>
<form method='POST' action='' id='assign_remove'>{% csrf_token %}
<input name='action' value='' type='hidden' />
<table>
<tbody>
<tr>
<th style='text-align:center;'>{{ left_list_title }}</th><td></td><th style='text-align:center;'>{{ right_list_title }}</th>
</tr>
<tr>
<td>
{{ form.left_list }}{{ form.left_list.errors }}
</td>
<td>
<table>
<tbody>
<tr>
<td><button class="button" onclick='document.forms["assign_remove"].action.value="assign";document.forms["assign_remove"].submit();'>&gt;</button></td>
</tr>
<tr>
<td><button class="button" onclick='document.forms["assign_remove"].action.value="remove";document.forms["assign_remove"].submit();'>&lt;</button></td>
</tr>
</tbody>
</table>
</td>
<td>{{ form.right_list }}{{ form.right_list.errors }}</td>
</tr>
{{ form.media|safe }}
</tbody>
</table>
</form>
</div>
{% endblock %}

View File

@@ -0,0 +1,51 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %} :: {% trans 'Confirm' %} {{ title }}{% endblock %}
{% block sidebar %}
{% for subtemplate in subtemplates %}
{% include subtemplate %}
{% endfor %}
{% endblock %}
{% block content %}
<div id="box">
<div class="block" id="block-login">
{% if delete_view %}
<h2>{% trans 'Confirm delete' %}</h2>
{% else %}
<h2>{% trans 'Confirm' %}</h2>
{% endif %}
<div class="content login">
<form action="" method="post" class="form login">{% csrf_token %}
{% if next %}
<input name='next' type='hidden' value='{{ next }}' />
{% endif %}
{% if delete_view %}
{% if object_name %}
<h3>{% blocktrans %}Are you sure you wish to delete {{ object_name }}: {{ object }}?{% endblocktrans %}</h3>
{% else %}
<h3>{% blocktrans %}Are you sure you wish to delete: {{ object }}?{% endblocktrans %}</h3>
{% endif %}
{% else %}
<h3>{{ title }}</h3>
{% endif %}
<h4>{{ message }}</h4>
<div class="group navform wat-cf">
<button class="button" type="submit">
<img src="{{ MEDIA_URL }}web_theme_media/images/icons/tick.png" alt="{% trans 'Yes' %}" /> {% trans 'Yes' %}
</button>
{# TODO: Fix back button #}
{% comment %}
<a href="#header" onclick='{% if previous %}window.location.replace("{{ previous }}");{% else %}history.go(-1);{% endif %}' class="button">
<img src="{{ MEDIA_URL }}web_theme_media/images/icons/cross.png" alt="{% trans 'No' %}"/> {% trans 'No' %}
</a>
{% endcomment %}
</div>
</form>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,64 @@
{% extends "base.html" %}
{% load i18n %}
{% load styling %}
{% load generic_views_helpers %}
{% block title %} :: {% with "true" as read_only %}{% with "true" as striptags %}{% include "calculate_form_title.html" %}{% endwith %}{% endwith %}{% endblock %}
{% block javascript %}
<script type="text/javascript">
$(function() {
$("#subform form :input").each(function() {
this.disabled = true;
});
});
</script>
{% endblock %}
{% block sidebar %}
{% for subtemplate in sidebar_subtemplates %}
{% include subtemplate %}
{% endfor %}
{% endblock %}
{% block stylesheets %}
<style type="text/css">
#subform form textarea,
#subform form select option,
#subform form input,
#subform form select,
#subform form input { background: none; color: black; border: none; }
</style>
{% endblock %}
{% block content %}
<div id="subform">
{% with "true" as read_only %}
{% include "generic_form_subtemplate.html" %}
{% endwith %}
</div>
{% for subtemplate in subtemplates %}
<div class="content">
{% include subtemplate %}
</div>
{% endfor %}
{% for subtemplate in subtemplates_dict %}
{% with subtemplate.title as title %}
{% with subtemplate.object_list as object_list %}
{% with subtemplate.extra_columns as extra_columns %}
{% with subtemplate.hide_object as hide_object %}
{% with subtemplate.main_object as main_object %}
<div class="content">
{% include subtemplate.name %}
</div>
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endfor %}
{% endblock %}

View File

@@ -0,0 +1,6 @@
{% extends "base.html" %}
{% block title %} :: {% with "true" as striptags %}{% include "calculate_form_title.html" %}{% endwith %}{% endblock %}
{% block content %}
{% include "generic_form_subtemplate.html" %}
{% endblock %}

View File

@@ -0,0 +1,39 @@
{% load i18n %}
{% load styling %}
{{ form.media|safe }}
{% add_classes_to_form form %}
{% if form.non_field_errors %}
<div class="flash">
{% for value in form.non_field_errors %}
<div class="message error">
<p>{{ value }}</p>
</div>
{% endfor %}
</div>
{% endif %}
{% if form_display_mode_table %}
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
<tr class="{% cycle 'odd' 'even2' %}">
{% for field in form.visible_fields %}
<td title="{% if field.errors %}{% for error in field.errors %}{{ error }}{% if not forloop.last %} | {% endif %}{% endfor %}{% else %}{{ field.help_text }}{% endif %}">
{% if field.errors %}<div class="flash"><div class="error">{% endif %}
{{ field }}
{% if field.errors %}</div></div>{% endif %}
</td>
{% endfor %}
</tr>
{% else %}
{% for field in form %}
<div class="group">
{% if field.errors %}<div class="fieldWithErrors">{% endif %}
<label class="label">{{ field.label_tag }}{% if field.field.required and not read_only %} ({% trans 'required' %}){% endif %}</label>
{% if field.errors %}<span class="error">{% for error in field.errors %}{{ error }}{% if not forloop.last %} | {% endif %}{% endfor %}</span></div>{% endif %}
{{ field }}
{% if field.help_text %}<span class="description">{{ field.help_text }}</span>{% endif %}
</div>
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,87 @@
{% load i18n %}
{% if side_bar %}
<div class="block">
<h3>
{% else %}
<div class="content">
<h2 class="title">
{% endif %}
{% include "calculate_form_title.html" %}
{% if side_bar %}
</h3>
<div class="content">
<p>
{% else %}
</h2>
<div class="inner">
{% endif %}
{% if form.is_multipart %}
<form enctype="multipart/form-data" method="{{ submit_method|default:'post' }}" action="" class="form">
{% else %}
<form method="{{ submit_method|default:'post' }}" action="" class="form">
{% endif %}
{% if step_field %}
<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
{% endif %}
{% if submit_method != 'GET' and submit_method != 'get' %}
{% csrf_token %}
{% endif %}
{% for hidden_field in hidden_fields %}
{{ hidden_field.as_hidden }}
{% endfor %}
{% if form.management_form %}
{% with form as formset %}
{{ formset.management_form }}
{% if form_display_mode_table %}
<table class="table">
<tbody>
<tr>
{% for field in formset.forms.0.visible_fields %}
<th>
{{ field.label_tag }}{% if field.field.required and not read_only %} ({% trans 'required' %}){% endif %}
</th>
{#{% if field.help_text %}<span class="description">{{ field.help_text }}</span>{% endif %}#}
{% endfor %}
</tr>
{% endif %}
{% for form in formset.forms %}
{% include "generic_form_instance.html" %}
{% endfor %}
{% if form_display_mode_table %}
</tbody>
</table>
{% endif %}
{% endwith %}
{% else %}
{% include "generic_form_instance.html" %}
{% endif %}
{% if not read_only %}
<div class="group navform wat-cf">
<button class="button" type="submit">
<img src="{{ MEDIA_URL }}web_theme_media/images/icons/tick.png" alt="{% if object %}{% trans 'Save' %}{% else %}{% trans 'Submit' %}{% endif %}" /> {% if object %}{% trans 'Save' %}{% else %}{% trans 'Submit' %}{% endif %}
</button>
{% comment %}
<a href="#header" class="button">
<img src="{{ MEDIA_URL }}web_theme_media/images/icons/cross.png" alt="{% trans 'Cancel' %}"/> {% trans 'Cancel' %}
</a>
{% endcomment %}
</div>
{% endif %}
</form>
{% if sidebar %}
</p></div></div>
{% else %}
</div></div>
{% endif %}

View File

@@ -0,0 +1,8 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %} :: {% blocktrans %}List of {{ title }}{% endblocktrans %}{% endblock %}
{#{% block secondary_links %}{{ secondary_links|safe }}{% endblock %}#}
{% block content %}
{% include 'generic_list_subtemplate.html' %}
{% endblock %}

View File

@@ -0,0 +1,71 @@
{% load i18n %}
{% load attribute_tags %}
{% load pagination_tags %}
{% load navigation %}
{% if side_bar %}
<div class="block">
<h3>
{{ title }}
</h3>
<div class="content">
<p>
{% else %}
{% autopaginate object_list %}
<div class="content">
<h2 class="title">
{% ifnotequal page_obj.paginator.num_pages 1 %}
{% blocktrans with page_obj.start_index as start and page_obj.end_index as end and page_obj.paginator.object_list|length as total %}List of {{ title }} ({{ start }} - {{ end }} out of {{ total }}){% endblocktrans %}
{% else %}
{% blocktrans with page_obj.paginator.object_list|length as total %}List of {{ title }} ({{ total }}){% endblocktrans %}
{% endifnotequal %}
</h2>
<div class="inner">
{% endif %}
<form action="#" class="form">
<table class="table">
<tbody>
{% if not hide_header %}
<tr>
{% if not hide_object %}
<th>{% trans 'Identifier' %}</th>
{% endif %}
{% for column in extra_columns %}
<th>{{ column.name|capfirst }}</th>
{% endfor %}
{% if not hide_links %}
<th class="">&nbsp;</th>
{% endif %}
</tr>
{% endif %}
{% for object in object_list %}
<tr class="{% cycle 'odd' 'even2' %}">
{% if not hide_object %}
{% if main_object %}
{% with object|object_property:main_object as object %}
<td>{% if not hide_link %}<a href="{{ object.get_absolute_url }}">{{ object }}</a>{% else %}{{ object }}{% endif %}</td>
{% endwith %}
{% else %}
<td>{% if not hide_link %}<a href="{{ object.get_absolute_url }}">{{ object }}</a>{% else %}{{ object }}{% endif %}</td>
{% endif %}
{% endif %}
{% for column in extra_columns %}
<td>{{ object|object_property:column.attribute|safe }}</td>
{% endfor %}
{% if not hide_links %}
<td class='last'>
{% object_navigation_template %}
</td>
{% endif %}
</tr>
{% empty %}
<tr><td colspan=99 class="tc">{% blocktrans %}There are no {{ title }}{% endblocktrans %}</td></tr>
{% endfor %}
</tbody>
</table>
{% paginate %}
</form>
</div>
</div>

View File

@@ -0,0 +1,7 @@
{% load i18n %}
{% for link in object_navigation_links %}
{% if as_li %}<li>{% endif %}
<a href="{{ link.url }}">{% if link.famfam %}<span class="famfam active famfam-{{ link.famfam|default:'link' }}"></span>{% endif %}{{ link.text|capfirst }}{% if link.error %} - {{ link.error }}{% endif %}{% if link.active %}<span class="famfam active famfam-resultset_previous"></span>{% endif %}</a>{% if horizontal %}{% if not forloop.last %} | {% endif %}{% endif %}
{% if as_li %}</li>{% endif %}
{% endfor %}

View File

@@ -0,0 +1,17 @@
{% extends "base.html" %}
{% load i18n %}
{% load styling %}
{% add_classes_to_form form %}
{% block content %}
{% with step_title as title %}
{% with previous_fields as hidden_fields %}
{% if form.management_form %}
{% with "true" as form_display_mode_table %}
{% include "generic_form_subtemplate.html" %}
{% endwith %}
{% else %}
{% include "generic_form_subtemplate.html" %}
{% endif %}
{% endwith %}
{% endwith %}
{% endblock %}

View File

@@ -0,0 +1,6 @@
{% extends "web_theme_login.html" %}
{% load i18n %}
{% load project_tags %}
{% block html_title %}{% project_name %} :: {% trans "Login" %}{% endblock %}
{% block project_name %}{% project_name %}{% endblock %}

View File

@@ -0,0 +1,6 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %} :: {% trans "Password change" %}{% endblock %}
{% block content %}
<h2>{% trans "Your password has been successfully changed." %}</h2>
{% endblock %}

View File

@@ -0,0 +1,11 @@
{% extends "generic_form.html" %}
{% load i18n %}
{% block title %} :: {% trans "Password change" %}{% endblock %}
{% block form_title %}{% trans "Password change" %}{% endblock %}

View File

View File

@@ -0,0 +1,34 @@
import types
from django.core.urlresolvers import reverse
from django.conf import settings
from django.template.defaultfilters import stringfilter
from django.template import Library, Node, Variable, VariableDoesNotExist
register = Library()
def return_attrib(obj, attrib, arguments={}):
try:
if isinstance(obj, types.DictType) or isinstance(obj, types.DictionaryType):
return obj[attrib]
elif isinstance(attrib, types.FunctionType):
return attrib(obj)
else:
result = reduce(getattr, attrib.split("."), obj)
if isinstance(result, types.MethodType):
if arguments:
return result(**arguments)
else:
return result()
else:
return result
except Exception, err:
if settings.DEBUG:
return "Error: %s; %s" % (attrib, err)
else:
pass
@register.filter
def object_property(value, arg):
return return_attrib(value, arg)

View File

@@ -0,0 +1,228 @@
import types
from django.conf import settings
from django.core.urlresolvers import reverse, NoReverseMatch
from django.core.urlresolvers import RegexURLResolver, RegexURLPattern, Resolver404, get_resolver
from django.template import TemplateSyntaxError, Library, \
VariableDoesNotExist, Node, Variable
from django.utils.text import unescape_string_literal
from common.api import object_navigation, menu_links as menu_navigation
register = Library()
def process_links(links, view_name, url):
items = []
active_item = None
for item, count in zip(links, range(len(links))):
item_view = 'view' in item and item['view']
item_url = 'url' in item and item['url']
if view_name == item_view or url == item_url:
active = True
active_item = item
else:
active = False
if 'links' in item:
for child_link in item['links']:
child_view = 'view' in child_link and child_link['view']
child_url = 'url' in child_link and child_link['url']
if view_name == child_view or url == child_url:
active = True
active_item = item
items.append(
{
'first':count==0,
'active':active,
'url':item_view and reverse(item_view) or item_url or '#',
'text':unicode(item['text']),
'famfam':'famfam' in item and item['famfam'],
}
)
return items, active_item
class NavigationNode(Node):
def __init__(self, navigation, *args, **kwargs):
self.navigation = navigation
def render(self, context):
request = Variable('request').resolve(context)
view_name = resolve_to_name(request.META['PATH_INFO'])
main_items, active_item = process_links(links=self.navigation, view_name=view_name, url=request.META['PATH_INFO'])
context['navigation_main_links'] = main_items
if active_item and 'links' in active_item:
secondary_links, active_item = process_links(links=active_item['links'], view_name=view_name, url=request.META['PATH_INFO'])
context['navigation_secondary_links'] = secondary_links
return ''
@register.tag
def main_navigation(parser, token):
args = token.split_contents()
# if len(args) != 3 or args[1] != 'as':
# raise TemplateSyntaxError("'get_all_states' requires 'as variable' (got %r)" % args)
#return NavigationNode(variable=args[2], navigation=navigation)
return NavigationNode(navigation=menu_navigation)
#http://www.djangosnippets.org/snippets/1378/
__all__ = ('resolve_to_name',)
def _pattern_resolve_to_name(self, path):
match = self.regex.search(path)
if match:
name = ""
if self.name:
name = self.name
elif hasattr(self, '_callback_str'):
name = self._callback_str
else:
name = "%s.%s" % (self.callback.__module__, self.callback.func_name)
return name
def _resolver_resolve_to_name(self, path):
tried = []
match = self.regex.search(path)
if match:
new_path = path[match.end():]
for pattern in self.url_patterns:
try:
name = pattern.resolve_to_name(new_path)
except Resolver404, e:
tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0]['tried']])
else:
if name:
return name
tried.append(pattern.regex.pattern)
raise Resolver404, {'tried': tried, 'path': new_path}
# here goes monkeypatching
RegexURLPattern.resolve_to_name = _pattern_resolve_to_name
RegexURLResolver.resolve_to_name = _resolver_resolve_to_name
def resolve_to_name(path, urlconf=None):
return get_resolver(urlconf).resolve_to_name(path)
@register.filter
def resolve_url_name(value):
return resolve_to_name(value)
def resolve_arguments(context, src_args):
args = []
kwargs = {}
if type(src_args) == type([]):
for i in src_args:
val = resolve_template_variable(context, i)
if val:
args.append(val)
elif type(src_args) == type({}):
for key, value in src_args.items():
val = resolve_template_variable(context, value)
if val:
kwargs[key] = val
else:
val = resolve_template_variable(context, src_args)
if val:
args.append(val)
return args, kwargs
def resolve_links(context, links, current_view, current_path):
context_links = []
for link in links:
args, kwargs = resolve_arguments(context, link.get('args', {}))
if 'view' in link:
link['active'] = link['view'] == current_view
args, kwargs = resolve_arguments(context, link.get('args', {}))
try:
if kwargs:
link['url'] = reverse(link['view'], kwargs=kwargs)
else:
link['url'] = reverse(link['view'], args=args)
except NoReverseMatch, err:
link['url'] = '#'
link['error'] = err
elif 'url' in link:
link['active'] = link['url'] == current_path
else:
link['active'] = False
context_links.append(link)
return context_links
def _get_object_navigation_links(context, menu_name=None):
current_path = Variable('request').resolve(context).META['PATH_INFO']
current_view = resolve_to_name(current_path)#.get_full_path())
context_links = []
try:
object_name = Variable('navigation_object_name').resolve(context)
except VariableDoesNotExist:
object_name = 'object'
try:
obj = Variable(object_name).resolve(context)
except VariableDoesNotExist:
obj = None
try:
links = object_navigation[menu_name][current_view]['links']
for link in resolve_links(context, links, current_view, current_path):
context_links.append(link)
except KeyError:
pass
try:
links = object_navigation[menu_name][type(obj)]['links']
for link in resolve_links(context, links, current_view, current_path):
context_links.append(link)
except KeyError:
pass
return context_links
def resolve_template_variable(context, name):
try:
return unescape_string_literal(name)
except ValueError:
return Variable(name).resolve(context)
except TypeError:
return name
class GetNavigationLinks(Node):
def __init__(self, *args):
self.menu_name = None
if args:
self.menu_name = args[0]
def render(self, context):
menu_name = resolve_template_variable(context, self.menu_name)
context['object_navigation_links'] = _get_object_navigation_links(context, menu_name)
return ''
@register.tag
def get_object_navigation_links(parser, token):
args = token.split_contents()
return GetNavigationLinks(*args[1:])
def object_navigation_template(context):
return {
'horizontal':True,
'object_navigation_links':_get_object_navigation_links(context)
}
return new_context
register.inclusion_tag('generic_navigation.html', takes_context=True)(object_navigation_template)

View File

@@ -0,0 +1,8 @@
from django.template import TemplateSyntaxError, Library, VariableDoesNotExist
from django.conf import settings
register = Library()
@register.simple_tag
def project_name():
return settings.PROJECT_TITLE

23
apps/common/tests.py Normal file
View File

@@ -0,0 +1,23 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

25
apps/common/urls.py Normal file
View File

@@ -0,0 +1,25 @@
from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('common.views',
url(r'^about/$', direct_to_template, { 'template' : 'about.html'}, 'about'),
url(r'^password/change/done/$', 'password_change_done', (), name='password_change_done'),
)
urlpatterns += patterns('',
url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}, name='login_view'),
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page' : '/'}, name='logout_view' ),
url(r'^password/change/$', 'django.contrib.auth.views.password_change', {'template_name': 'password_change_form.html', 'post_change_redirect': '/password/change/done/'}, name='password_change_view'),
#url(r'^password/change/done/$', 'django.contrib.auth.views.password_change_done', {'template_name': 'password_change_done.html'}),
url(r'^password/reset/$', 'django.contrib.auth.views.password_reset', {'email_template_name' : 'password_reset_email.html', 'template_name': 'password_reset_form.html', 'post_reset_redirect' : '/password/reset/done'}, name='password_reset_view'),
url(r'^password/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', { 'template_name' : 'password_reset_confirm.html', 'post_reset_redirect' : '/password/reset/complete/'}, name='password_reset_confirm_view'),
url(r'^password/reset/complete/$', 'django.contrib.auth.views.password_reset_complete', { 'template_name' : 'password_reset_complete.html' }, name='password_reset_complete_view'),
url(r'^password/reset/done/$', 'django.contrib.auth.views.password_reset_done', { 'template_name' : 'password_reset_done.html'}, name='password_reset_done_view'),
)
urlpatterns += patterns('',
url(r'^set_language/$', 'django.views.i18n.set_language', name='set_language'),
)

40
apps/common/utils.py Normal file
View File

@@ -0,0 +1,40 @@
from django.utils.http import urlquote as django_urlquote
from django.utils.http import urlencode as django_urlencode
from django.utils.datastructures import MultiValueDict
def urlquote(link=None, get={}):
u'''
This method does both: urlquote() and urlencode()
urlqoute(): Quote special characters in 'link'
urlencode(): Map dictionary to query string key=value&...
HTML escaping is not done.
Example:
urlquote('/wiki/Python_(programming_language)') --> '/wiki/Python_%28programming_language%29'
urlquote('/mypath/', {'key': 'value'}) --> '/mypath/?key=value'
urlquote('/mypath/', {'key': ['value1', 'value2']}) --> '/mypath/?key=value1&key=value2'
urlquote({'key': ['value1', 'value2']}) --> 'key=value1&key=value2'
'''
assert link or get
if isinstance(link, dict):
# urlqoute({'key': 'value', 'key2': 'value2'}) --> key=value&key2=value2
assert not get, get
get=link
link=''
assert isinstance(get, dict), 'wrong type "%s", dict required' % type(get)
#assert not (link.startswith('http://') or link.startswith('https://')), \
# 'This method should only quote the url path. It should not start with http(s):// (%s)' % (
# link)
if get:
# http://code.djangoproject.com/ticket/9089
if isinstance(get, MultiValueDict):
get=get.lists()
if link:
link='%s?' % django_urlquote(link)
return u'%s%s' % (link, django_urlencode(get, doseq=True))
else:
return django_urlquote(link)

7
apps/common/views.py Normal file
View File

@@ -0,0 +1,7 @@
from django.shortcuts import redirect
from django.utils.translation import ugettext as _
from django.contrib import messages
def password_change_done(request):
messages.success(request, _(u'Your password has been successfully changed.'))
return redirect('home')

82
apps/common/wizard.py Normal file
View File

@@ -0,0 +1,82 @@
"""Common abstract classes for forms."""
try:
import cPickle as pickle
except ImportError:
import pickle
from django import forms
from django.conf import settings
from django.contrib.formtools.wizard import FormWizard
from django.forms.forms import BoundField
from django.forms.formsets import BaseFormSet
from django.utils.hashcompat import md5_constructor
__all__ = ('security_hash', 'BoundFormWizard')
def security_hash(request, form, exclude=None, *args):
"""Calculates a security hash for the given Form/FormSet instance.
This creates a list of the form field names/values in a deterministic
order, pickles the result with the SECRET_KEY setting, then takes an md5
hash of that.
"""
data = []
if exclude is None:
exclude = ()
if isinstance(form, BaseFormSet):
for _form in form.forms + [form.management_form]:
for bf in _form:
value = bf.field.clean(bf.data) or ''
if isinstance(value, basestring):
value = value.strip()
data.append((bf.name, value))
else:
for bf in form:
if bf.name in exclude:
continue
value = bf.field.clean(bf.data) or ''
if isinstance(value, basestring):
value = value.strip()
data.append((bf.name, value))
data.extend(args)
data.append(settings.SECRET_KEY)
# Use HIGHEST_PROTOCOL because it's the most efficient. It requires
# Python 2.3, but Django requires 2.3 anyway, so that's OK.
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
return md5_constructor(pickled).hexdigest()
class BoundFormWizard(FormWizard):
"""Render prev_fields as a list of bound form fields in the template
context rather than raw html."""
def security_hash(self, request, form):
"""Calculates the security hash for the given HttpRequest and
Form/FormSet instances.
Subclasses may want to take into account request-specific information,
such as the IP address.
"""
return security_hash(request, form)
def render(self, form, request, step, context=None):
"Renders the given Form object, returning an HttpResponse."
old_data = request.POST
prev_fields = []
if old_data:
for i in range(step):
old_form = self.get_form(i, old_data)
hash_name = 'hash_%s' % i
if isinstance(old_form, BaseFormSet):
for _form in old_form.forms + [old_form.management_form]:
prev_fields.extend([bf for bf in _form])
else:
prev_fields.extend([bf for bf in old_form])
hash_field = forms.Field(initial=old_data.get(hash_name,
self.security_hash(request, old_form)))
bf = BoundField(forms.Form(), hash_field, hash_name)
prev_fields.append(bf)
return self.render_template(request, form, prev_fields, step, context)
# vim: ai ts=4 sts=4 et sw=4