Initial changes to support document tags

This commit is contained in:
Roberto Rosario
2011-04-27 17:23:52 -04:00
parent 20dadafd61
commit 8fbd174643
18 changed files with 245 additions and 11 deletions

View File

@@ -364,10 +364,21 @@ class MetaDataImageWidget(forms.widgets.Widget):
output.append(u'<div style="white-space:nowrap; overflow: auto;">') output.append(u'<div style="white-space:nowrap; overflow: auto;">')
for document in value['group_data']: for document in value['group_data']:
tags_template = []
tag_count = document.tags.count()
if tag_count:
tags_template.append(u'<div class="tc">')
tags_template.append(u'%(tag_string)s (%(tag_count)s): ' % {
'tag_string': _(u'Tags'), 'tag_count': tag_count})
tags_template.append(u', '.join(document.tags.values_list('name', flat=True)))
tags_template.append(u'</div>')
output.append( output.append(
u'''<div style="display: inline-block; margin: 10px; %(current)s"> u'''<div style="display: inline-block; margin: 10px; %(current)s">
<div class="tc">%(document_name)s</div> <div class="tc">%(document_name)s</div>
<div class="tc">%(page_string)s: %(document_pages)d</div> <div class="tc">%(page_string)s: %(document_pages)d</div>
%(tags_template)s
<div class="tc"> <div class="tc">
<a rel="group_%(group_id)d_documents_gallery" class="fancybox-noscaling" href="%(view_url)s"> <a rel="group_%(group_id)d_documents_gallery" class="fancybox-noscaling" href="%(view_url)s">
<img class="lazy-load" style="border: 1px solid black; margin: 10px;" src="%(media_url)s/images/blank.gif" data-href="%(img)s" /> <img class="lazy-load" style="border: 1px solid black; margin: 10px;" src="%(media_url)s/images/blank.gif" data-href="%(img)s" />
@@ -389,7 +400,8 @@ class MetaDataImageWidget(forms.widgets.Widget):
'details_string': ugettext(u'Select'), 'details_string': ugettext(u'Select'),
'group_id': value['group'].pk, 'group_id': value['group'].pk,
'document_name': document, 'document_name': document,
'media_url': settings.MEDIA_URL 'media_url': settings.MEDIA_URL,
'tags_template': u''.join(tags_template) if tags_template else u''
}) })
output.append(u'</div>') output.append(u'</div>')
output.append( output.append(

View File

@@ -9,6 +9,7 @@ from django.contrib.auth.models import User
from python_magic import magic from python_magic import magic
from taggit.managers import TaggableManager
from dynamic_search.api import register from dynamic_search.api import register
from converter.api import get_page_count from converter.api import get_page_count
from converter import TRANFORMATION_CHOICES from converter import TRANFORMATION_CHOICES
@@ -57,6 +58,8 @@ class Document(models.Model):
checksum = models.TextField(blank=True, null=True, verbose_name=_(u'checksum'), editable=False) checksum = models.TextField(blank=True, null=True, verbose_name=_(u'checksum'), editable=False)
description = models.TextField(blank=True, null=True, verbose_name=_(u'description'), db_index=True) description = models.TextField(blank=True, null=True, verbose_name=_(u'description'), db_index=True)
tags = TaggableManager()
class Meta: class Meta:
verbose_name = _(u'document') verbose_name = _(u'document')
verbose_name_plural = _(u'documents') verbose_name_plural = _(u'documents')
@@ -444,5 +447,5 @@ class RecentDocument(models.Model):
verbose_name_plural = _(u'recent documents') verbose_name_plural = _(u'recent documents')
register(Document, _(u'document'), ['document_type__name', 'file_mimetype', 'file_filename', 'file_extension', 'documentmetadata__value', 'documentpage__content', 'description']) register(Document, _(u'document'), ['document_type__name', 'file_mimetype', 'file_filename', 'file_extension', 'documentmetadata__value', 'documentpage__content', 'description', 'tags__name'])
#register(Document, _(u'document'), ['document_type__name', 'file_mimetype', 'file_extension', 'documentmetadata__value', 'documentpage__content', 'description', {'field_name':'file_filename', 'comparison':'iexact'}]) #register(Document, _(u'document'), ['document_type__name', 'file_mimetype', 'file_extension', 'documentmetadata__value', 'documentpage__content', 'description', {'field_name':'file_filename', 'comparison':'iexact'}])

View File

@@ -869,9 +869,20 @@ def document_view_simple(request, document_id):
} }
) )
subtemplates_dict.append(
{
'name': 'generic_list_subtemplate.html',
'title': _(u'tags'),
'object_list': document.tags.all(),
#'extra_columns': [{'name': _(u'value'), 'attribute': 'value'}],
'hide_link': True,
}
)
return render_to_response('generic_detail.html', { return render_to_response('generic_detail.html', {
'form_list': form_list, 'form_list': form_list,
'object': document, 'object': document,
'document': document,
'subtemplates_dict': subtemplates_dict, 'subtemplates_dict': subtemplates_dict,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))

View File

@@ -14,7 +14,10 @@ class AddDocumentForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None) user = kwargs.pop('user', None)
super(AddDocumentForm, self).__init__(*args, **kwargs) super(AddDocumentForm, self).__init__(*args, **kwargs)
self.fields['existing_folder'] = forms.ModelChoiceField(required=False, queryset=Folder.objects.filter(user=user)) self.fields['existing_folder'] = forms.ModelChoiceField(
required=False,
queryset=Folder.objects.filter(user=user),
label=_(u'Existing folders'))
self.fields['title'].required = False self.fields['title'].required = False
self.fields['title'].label = _(u'New folder') self.fields['title'].label = _(u'New folder')

15
apps/tags/__init__.py Normal file
View File

@@ -0,0 +1,15 @@
from django.utils.translation import ugettext_lazy as _
from navigation.api import register_links, register_menu, \
register_model_list_columns, register_multi_item_links
from permissions.api import register_permissions
from navigation.api import register_sidebar_template
from taggit.models import Tag
tag_delete = {'text': _('delete'), 'view': 'tag_remove', 'args': ['object.id', 'document.id'], 'famfam': 'tag_blue_delete'}#, 'permissions': {'namespace': 'documents', 'permissions': [PERMISSION_DOCUMENT_DELETE]}}
register_links(Tag, [tag_delete])
register_sidebar_template(['document_view', 'document_view_simple'], 'tags_sidebar_template.html')

29
apps/tags/forms.py Normal file
View File

@@ -0,0 +1,29 @@
from django import forms
from django.utils.translation import ugettext as _
from taggit.models import Tag
#class FolderForm(forms.ModelForm):
# class Meta:
# model = Folder
# fields = ('title',)
class AddTagForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
#user = kwargs.pop('user', None)
super(AddTagForm, self).__init__(*args, **kwargs)
#self.fields['title'].required = False
#self.fields['title'].label = _(u'New folder')
self.fields['existing_tags'] = forms.ModelChoiceField(
required=False,
queryset=Tag.objects.all(), #(user=user),
label=_(u'Existing tags'))
self.fields['name'].required = False
self.fields['name'].label = _(u'New tag')
class Meta:
model = Tag
fields = ('name',)

38
apps/tags/models.py Normal file
View File

@@ -0,0 +1,38 @@
from django.db import models
from django.utils.translation import ugettext as _
from taggit.models import Tag
COLOR_RED = u'red'
COLOR_BLUE = u'blu'
COLOR_MAGENTA = u'mag'
COLOR_CYAN = u'cya'
COLOR_YELLOW = u'yel'
COLOR_CHOICES = (
(COLOR_RED, _(u'red')),
(COLOR_BLUE, _(u'blue')),
# (COLOR_MAGENTA, _(u'magenta')),
# (COLOR_CYAN, _(u'cyan')),
(COLOR_YELLOW, _(u'yellow'))
)
COLOR_CODES = (
(COLOR_RED, u'FF0000'),
(COLOR_BLUE, u'0000FF'),
# (COLOR_MAGENTA, u'FF0000'),
# (COLOR_CYAN, u'FF0000'),
(COLOR_YELLOW, u'00FFFF')
)
class TagProperties(models.Model):
tag = models.ForeignKey(Tag, verbose_name=_(u'tag'))
color = models.CharField(max_length=3, choices=COLOR_CHOICES, verbose_name=_(u'color'))
class Meta:
verbose_name = _(u'tag properties')
verbose_name_plural = _(u'tags properties')
def __unicode__(self):
return self.tag

View File

@@ -0,0 +1,2 @@
{% load tags_tags %}
{% get_add_tag_to_document_form %}

View File

View File

@@ -0,0 +1,19 @@
from django.core.urlresolvers import reverse
from django.template import Library
from django.utils.translation import ugettext as _
from tags.forms import AddTagForm
register = Library()
@register.inclusion_tag('generic_form_subtemplate.html', takes_context=True)
def get_add_tag_to_document_form(context):
context.update({
'form': AddTagForm(),#user=context['request'].user),
'request': context['request'],
'form_action': reverse('tag_add', args=[context['document'].pk]),
'title': _('Add tag to document')
})
return context

23
apps/tags/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
"""}

17
apps/tags/urls.py Normal file
View File

@@ -0,0 +1,17 @@
from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('tags.views',
url(r'^(?P<tag_id>\d+)/remove_from_document/(?P<document_id>\d+)$', 'tag_remove', (), 'tag_remove'),
url(r'^add_to_document/(?P<document_id>\d+)$', 'tag_add', (), 'tag_add'),
# url(r'^ocr/queue/document/list/$', 'queue_document_list', (), 'queue_document_list'),
# url(r'^ocr/queue/document/(?P<queue_document_id>\d+)/delete/$', 'queue_document_delete', (), 'queue_document_delete'),
# url(r'^ocr/queue/document/multiple/delete/$', 'queue_document_multiple_delete', (), 'queue_document_multiple_delete'),
# url(r'^ocr/queue/document/(?P<queue_document_id>\d+)/re-queue/$', 're_queue_document', (), 're_queue_document'),
# url(r'^ocr/queue/document/multiple/re-queue/$', 're_queue_multiple_document', (), 're_queue_multiple_document'),#
# url(r'^ocr/queue/(?P<document_queue_id>\d+)/enable/$', 'document_queue_enable', (), 'document_queue_enable'),#
# url(r'^ocr/queue/(?P<document_queue_id>\d+)/disable/$', 'document_queue_disable', (), 'document_queue_disable'),
# url(r'^ocr/document/all/clean_up/$', 'all_document_ocr_cleanup', (), 'all_document_ocr_cleanup'),
# url(r'^ocr/node/active/list/$', 'node_active_list', (), 'node_active_list'),
)

53
apps/tags/views.py Normal file
View File

@@ -0,0 +1,53 @@
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from permissions.api import check_permissions
from taggit.models import Tag
from documents.models import Document
from tags.forms import AddTagForm
def tag_remove(request, tag_id, document_id):
# check_permissions(request.user, 'ocr', [PERMISSION_OCR_DOCUMENT])
tag = get_object_or_404(Tag, pk=tag_id)
document = get_object_or_404(Document, pk=document_id)
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', None)))
tag.delete()
messages.success(request, _(u'Tag: %s, removed successfully.') % tag)
return HttpResponseRedirect(previous)
def tag_add(request, document_id):
# check_permissions(request.user, 'ocr', [PERMISSION_OCR_DOCUMENT])
document = get_object_or_404(Document, pk=document_id)
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', None)))
#document.tags.add(tag)
#messages.success(request, _(u'Tag: %s, removed successfully.') % tag)
#tag = get_object_or_404(Tag, pk=tag_id)
#return HttpResponseRedirect(previous)
if request.method == 'POST':
previous = request.META.get('HTTP_REFERER', '/')
form = AddTagForm(request.POST)#, user=request.user)
if form.is_valid():
if form.cleaned_data['existing_tags']:
tag = form.cleaned_data['existing_tags']
elif form.cleaned_data['name']:
tag = form.cleaned_data['name']
document.tags.add(tag)
return HttpResponseRedirect(previous)

View File

@@ -124,3 +124,7 @@ Image 1299551545_egypt200.png
django-sendfile - This is a wrapper around web-server specific methods for sending files to web clients. django-sendfile - This is a wrapper around web-server specific methods for sending files to web clients.
johnsensible (John Montgomery) johnsensible (John Montgomery)
https://github.com/johnsensible/django-sendfile https://github.com/johnsensible/django-sendfile
jQuery-Jail
django-taggit

View File

@@ -8,3 +8,4 @@ wsgiref==0.1.2
celery==2.2.2 celery==2.2.2
django-celery==2.2.2 django-celery==2.2.2
django-sentry==1.6.0 django-sentry==1.6.0
django-taggit==0.9.3

View File

@@ -5,3 +5,4 @@ wsgiref==0.1.2
celery==2.2.2 celery==2.2.2
django-celery==2.2.2 django-celery==2.2.2
django-sentry==1.6.0 django-sentry==1.6.0
django-taggit==0.9.3

View File

@@ -139,6 +139,8 @@ INSTALLED_APPS = (
'filesystem_serving', 'filesystem_serving',
'storage', 'storage',
'folders', 'folders',
'taggit',
'tags',
) )
TEMPLATE_CONTEXT_PROCESSORS = ( TEMPLATE_CONTEXT_PROCESSORS = (

View File

@@ -13,6 +13,7 @@ urlpatterns = patterns('',
(r'^search/', include('dynamic_search.urls')), (r'^search/', include('dynamic_search.urls')),
(r'^ocr/', include('ocr.urls')), (r'^ocr/', include('ocr.urls')),
(r'^permissions/', include('permissions.urls')), (r'^permissions/', include('permissions.urls')),
(r'^tags/', include('tags.urls')),
(r'^admin/doc/', include('django.contrib.admindocs.urls')), (r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^admin/', include(admin.site.urls)), (r'^admin/', include(admin.site.urls)),
(r'^grappelli/', include('grappelli.urls')), (r'^grappelli/', include('grappelli.urls')),