Convert sources app to use new transformation system

This commit is contained in:
Roberto Rosario
2015-06-08 15:56:16 -04:00
parent 33b56ac5e6
commit 506d53c58a
10 changed files with 35 additions and 199 deletions

View File

@@ -1,11 +1,9 @@
from django.contrib import admin from django.contrib import admin
from .models import ( from .models import (
SourceTransformation, StagingFolderSource, WatchFolderSource, StagingFolderSource, WatchFolderSource, WebFormSource
WebFormSource
) )
admin.site.register(SourceTransformation)
admin.site.register(StagingFolderSource) admin.site.register(StagingFolderSource)
admin.site.register(WatchFolderSource) admin.site.register(WatchFolderSource)
admin.site.register(WebFormSource) admin.site.register(WebFormSource)

View File

@@ -8,6 +8,7 @@ from common import (
menu_setup menu_setup
) )
from common.utils import encapsulate from common.utils import encapsulate
from converter.links import link_transformation_list
from documents.models import Document from documents.models import Document
from navigation.api import register_model_list_columns from navigation.api import register_model_list_columns
from rest_api.classes import APIEndPoint from rest_api.classes import APIEndPoint
@@ -19,13 +20,9 @@ from .links import (
link_setup_source_create_pop3_email, link_setup_source_create_pop3_email,
link_setup_source_create_watch_folder, link_setup_source_create_webform, link_setup_source_create_watch_folder, link_setup_source_create_webform,
link_setup_source_create_staging_folder, link_setup_source_delete, link_setup_source_create_staging_folder, link_setup_source_delete,
link_setup_source_edit, link_setup_source_transformation_create, link_setup_source_edit, link_staging_file_delete, link_upload_version
link_setup_source_transformation_delete,
link_setup_source_transformation_edit,
link_setup_source_transformation_list, link_staging_file_delete,
link_upload_version
) )
from .models import Source, SourceTransformation from .models import Source
from .widgets import staging_file_thumbnail from .widgets import staging_file_thumbnail
@@ -39,12 +36,10 @@ class SourcesApp(apps.AppConfig):
menu_front_page.bind_links(links=[link_document_create_multiple]) menu_front_page.bind_links(links=[link_document_create_multiple])
menu_object.bind_links(links=[link_document_create_siblings], sources=[Document]) menu_object.bind_links(links=[link_document_create_siblings], sources=[Document])
menu_object.bind_links(links=[link_setup_source_edit, link_setup_source_transformation_list, link_setup_source_delete], sources=[Source]) menu_object.bind_links(links=[link_setup_source_edit, link_setup_source_delete, link_transformation_list], sources=[Source])
menu_object.bind_links(links=[link_setup_source_transformation_edit, link_setup_source_transformation_delete], sources=[SourceTransformation])
menu_object.bind_links(links=[link_staging_file_delete], sources=[StagingFile]) menu_object.bind_links(links=[link_staging_file_delete], sources=[StagingFile])
menu_secondary.bind_links(links=[link_setup_sources, link_setup_source_create_webform, link_setup_source_create_staging_folder, link_setup_source_create_pop3_email, link_setup_source_create_imap_email, link_setup_source_create_watch_folder], sources=[Source, 'sources:setup_source_list', 'sources:setup_source_create']) menu_secondary.bind_links(links=[link_setup_sources, link_setup_source_create_webform, link_setup_source_create_staging_folder, link_setup_source_create_pop3_email, link_setup_source_create_imap_email, link_setup_source_create_watch_folder], sources=[Source, 'sources:setup_source_list', 'sources:setup_source_create'])
menu_setup.bind_links(links=[link_setup_sources]) menu_setup.bind_links(links=[link_setup_sources])
menu_sidebar.bind_links(links=[link_setup_source_transformation_create], sources=[SourceTransformation, 'sources:setup_source_transformation_create', 'sources:setup_source_transformation_list'])
menu_sidebar.bind_links(links=[link_upload_version], sources=['documents:document_version_list', 'documents:upload_version', 'documents:document_version_revert']) menu_sidebar.bind_links(links=[link_upload_version], sources=['documents:document_version_list', 'documents:upload_version', 'documents:document_version_revert'])
register_model_list_columns(StagingFile, [ register_model_list_columns(StagingFile, [

View File

@@ -11,7 +11,7 @@ except ImportError:
from django.core.files import File from django.core.files import File
from converter.api import convert from converter import converter_class
from mimetype.api import get_mimetype from mimetype.api import get_mimetype

View File

@@ -9,8 +9,8 @@ from django.utils.translation import ugettext_lazy as _
from documents.forms import DocumentForm from documents.forms import DocumentForm
from .models import ( from .models import (
IMAPEmail, POP3Email, SourceTransformation, StagingFolderSource, IMAPEmail, POP3Email, StagingFolderSource, WebFormSource,
WebFormSource, WatchFolderSource WatchFolderSource
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -109,20 +109,3 @@ class WatchFolderSetupForm(forms.ModelForm):
class Meta: class Meta:
fields = ('title', 'enabled', 'interval', 'document_type', 'uncompress', 'folder_path') fields = ('title', 'enabled', 'interval', 'document_type', 'uncompress', 'folder_path')
model = WatchFolderSource model = WatchFolderSource
class SourceTransformationForm(forms.ModelForm):
class Meta:
fields = ('order', 'transformation', 'arguments')
model = SourceTransformation
def __init__(self, *args, **kwargs):
super(SourceTransformationForm, self).__init__(*args, **kwargs)
self.fields['content_type'].widget = forms.HiddenInput()
self.fields['object_id'].widget = forms.HiddenInput()
class SourceTransformationForm_create(forms.ModelForm):
class Meta:
model = SourceTransformation
exclude = ('content_type', 'object_id')

View File

@@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from converter.permissions import PERMISSION_TRANSFORMATION_VIEW
from documents.permissions import ( from documents.permissions import (
PERMISSION_DOCUMENT_CREATE, PERMISSION_DOCUMENT_NEW_VERSION PERMISSION_DOCUMENT_CREATE, PERMISSION_DOCUMENT_NEW_VERSION
) )
@@ -16,6 +17,7 @@ from .permissions import (
PERMISSION_SOURCES_SETUP_EDIT, PERMISSION_SOURCES_SETUP_VIEW PERMISSION_SOURCES_SETUP_EDIT, PERMISSION_SOURCES_SETUP_VIEW
) )
link_document_create_multiple = Link(icon='fa fa-upload', permissions=[PERMISSION_DOCUMENT_CREATE], text=_('New document'), view='sources:document_create_multiple') link_document_create_multiple = Link(icon='fa fa-upload', permissions=[PERMISSION_DOCUMENT_CREATE], text=_('New document'), view='sources:document_create_multiple')
link_document_create_siblings = Link(permissions=[PERMISSION_DOCUMENT_CREATE], text=_('Clone'), view='sources:document_create_siblings', args='object.id') link_document_create_siblings = Link(permissions=[PERMISSION_DOCUMENT_CREATE], text=_('Clone'), view='sources:document_create_siblings', args='object.id')
link_setup_sources = Link(icon='fa fa-upload', permissions=[PERMISSION_SOURCES_SETUP_VIEW], text=_('Sources'), view='sources:setup_source_list') link_setup_sources = Link(icon='fa fa-upload', permissions=[PERMISSION_SOURCES_SETUP_VIEW], text=_('Sources'), view='sources:setup_source_list')
@@ -26,10 +28,6 @@ link_setup_source_create_watch_folder = Link(permissions=[PERMISSION_SOURCES_SET
link_setup_source_create_webform = Link(permissions=[PERMISSION_SOURCES_SETUP_CREATE], text=_('Add new webform source'), view='sources:setup_source_create', args='"%s"' % SOURCE_CHOICE_WEB_FORM) link_setup_source_create_webform = Link(permissions=[PERMISSION_SOURCES_SETUP_CREATE], text=_('Add new webform source'), view='sources:setup_source_create', args='"%s"' % SOURCE_CHOICE_WEB_FORM)
link_setup_source_delete = Link(permissions=[PERMISSION_SOURCES_SETUP_DELETE], tags='dangerous', text=_('Delete'), view='sources:setup_source_delete', args=['resolved_object.pk']) link_setup_source_delete = Link(permissions=[PERMISSION_SOURCES_SETUP_DELETE], tags='dangerous', text=_('Delete'), view='sources:setup_source_delete', args=['resolved_object.pk'])
link_setup_source_edit = Link(text=_('Edit'), view='sources:setup_source_edit', args=['resolved_object.pk'], permissions=[PERMISSION_SOURCES_SETUP_EDIT]) link_setup_source_edit = Link(text=_('Edit'), view='sources:setup_source_edit', args=['resolved_object.pk'], permissions=[PERMISSION_SOURCES_SETUP_EDIT])
link_setup_source_transformation_create = Link(permissions=[PERMISSION_SOURCES_SETUP_EDIT], text=_('Add transformation'), view='sources:setup_source_transformation_create', args=['resolved_object.pk'])
link_setup_source_transformation_edit = Link(permissions=[PERMISSION_SOURCES_SETUP_EDIT], text=_('Edit'), view='sources:setup_source_transformation_edit', args='resolved_object.pk')
link_setup_source_transformation_delete = Link(permissions=[PERMISSION_SOURCES_SETUP_EDIT], tags='dangerous', text=_('Delete'), view='sources:setup_source_transformation_delete', args='resolved_object.pk')
link_setup_source_transformation_list = Link(permissions=[PERMISSION_SOURCES_SETUP_EDIT], text=_('Transformations'), view='sources:setup_source_transformation_list', args=['resolved_object.pk'])
link_source_list = Link(permissions=[PERMISSION_SOURCES_SETUP_VIEW], text=_('Document sources'), view='sources:setup_web_form_list') link_source_list = Link(permissions=[PERMISSION_SOURCES_SETUP_VIEW], text=_('Document sources'), view='sources:setup_web_form_list')
link_staging_file_delete = Link(keep_query=True, permissions=[PERMISSION_DOCUMENT_NEW_VERSION, PERMISSION_DOCUMENT_CREATE], tags='dangerous', text=_('Delete'), view='sources:staging_file_delete', args=['source.pk', 'object.encoded_filename']) link_staging_file_delete = Link(keep_query=True, permissions=[PERMISSION_DOCUMENT_NEW_VERSION, PERMISSION_DOCUMENT_CREATE], tags='dangerous', text=_('Delete'), view='sources:staging_file_delete', args=['source.pk', 'object.encoded_filename'])
link_upload_version = Link(permissions=[PERMISSION_DOCUMENT_NEW_VERSION], text=_('Upload new version'), view='sources:upload_version', args='object.pk') link_upload_version = Link(permissions=[PERMISSION_DOCUMENT_NEW_VERSION], text=_('Upload new version'), view='sources:upload_version', args='object.pk')

View File

@@ -109,7 +109,7 @@ class Migration(migrations.Migration):
('object_id', models.PositiveIntegerField()), ('object_id', models.PositiveIntegerField()),
('order', models.PositiveIntegerField(default=0, null=True, verbose_name='Order', db_index=True, blank=True)), ('order', models.PositiveIntegerField(default=0, null=True, verbose_name='Order', db_index=True, blank=True)),
('transformation', models.CharField(max_length=128, verbose_name='Transformation', choices=[('resize', 'Resize'), ('rotate', 'Rotate'), ('zoom', 'Zoom')])), ('transformation', models.CharField(max_length=128, verbose_name='Transformation', choices=[('resize', 'Resize'), ('rotate', 'Rotate'), ('zoom', 'Zoom')])),
('arguments', models.TextField(blank=True, help_text="Use dictionaries to indentify arguments, example: {'degrees':90}", null=True, verbose_name='Arguments', validators=[sources.models.argument_validator])), ('arguments', models.TextField(blank=True, help_text="Use dictionaries to indentify arguments, example: {'degrees':90}", null=True, verbose_name='Arguments', validators=[])),
('content_type', models.ForeignKey(to='contenttypes.ContentType')), ('content_type', models.ForeignKey(to='contenttypes.ContentType')),
], ],
options={ options={

View File

@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('sources', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='sourcetransformation',
name='content_type',
),
migrations.DeleteModel(
name='SourceTransformation',
),
]

View File

@@ -1,6 +1,5 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from ast import literal_eval
from email.Utils import collapse_rfc2231_value from email.Utils import collapse_rfc2231_value
from email import message_from_string from email import message_from_string
import json import json
@@ -9,8 +8,6 @@ import logging
import os import os
import poplib import poplib
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.files import File from django.core.files import File
from django.db import models from django.db import models
@@ -19,7 +16,6 @@ from django.utils.translation import ugettext_lazy as _
from model_utils.managers import InheritanceManager from model_utils.managers import InheritanceManager
#from converter.api import get_available_transformations_choices
from converter.literals import DIMENSION_SEPARATOR from converter.literals import DIMENSION_SEPARATOR
from djcelery.models import PeriodicTask, IntervalSchedule from djcelery.models import PeriodicTask, IntervalSchedule
from documents.models import Document, DocumentType from documents.models import Document, DocumentType
@@ -33,7 +29,6 @@ from .literals import (
SOURCE_UNCOMPRESS_CHOICES, SOURCE_UNCOMPRESS_CHOICE_Y, SOURCE_UNCOMPRESS_CHOICES, SOURCE_UNCOMPRESS_CHOICE_Y,
SOURCE_CHOICE_EMAIL_IMAP, SOURCE_CHOICE_EMAIL_POP3 SOURCE_CHOICE_EMAIL_IMAP, SOURCE_CHOICE_EMAIL_POP3
) )
from .managers import SourceTransformationManager
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -56,7 +51,7 @@ class Source(models.Model):
return ' '.join([self.class_fullname(), '"%s"' % self.title]) return ' '.join([self.class_fullname(), '"%s"' % self.title])
def get_transformation_list(self): def get_transformation_list(self):
return SourceTransformation.transformations.get_for_object_as_list(self) return SourceTransformation.objects.get_for_object_as_list(self)
def upload_document(self, file_object, label, description=None, document_type=None, expand=False, language=None, metadata_dict_list=None, user=None): def upload_document(self, file_object, label, description=None, document_type=None, expand=False, language=None, metadata_dict_list=None, user=None):
new_versions = Document.objects.new_document( new_versions = Document.objects.new_document(
@@ -353,40 +348,3 @@ class WatchFolderSource(IntervalBaseModel):
class Meta: class Meta:
verbose_name = _('Watch folder') verbose_name = _('Watch folder')
verbose_name_plural = _('Watch folders') verbose_name_plural = _('Watch folders')
def argument_validator(value):
"""
Validates that the input evaluates correctly.
"""
value = value.strip()
try:
literal_eval(value)
except (ValueError, SyntaxError):
raise ValidationError(_('Enter a valid value.'), code='invalid')
@python_2_unicode_compatible
class SourceTransformation(models.Model):
"""
Model that stores the transformation and transformation arguments
for a given document source
"""
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
order = models.PositiveIntegerField(default=0, blank=True, null=True, verbose_name=_('Order'), db_index=True)
#transformation = models.CharField(choices=get_available_transformations_choices(), max_length=128, verbose_name=_('Transformation'))
transformation = models.CharField(max_length=128, verbose_name=_('Transformation'))
arguments = models.TextField(blank=True, null=True, verbose_name=_('Arguments'), help_text=_('Use dictionaries to indentify arguments, example: {\'degrees\':90}'), validators=[argument_validator])
objects = models.Manager()
transformations = SourceTransformationManager()
def __str__(self):
return self.get_transformation_display()
class Meta:
ordering = ('order',)
verbose_name = _('Document source transformation')
verbose_name_plural = _('Document source transformations')

View File

@@ -26,11 +26,6 @@ urlpatterns = patterns(
url(r'^setup/(?P<source_id>\d+)/delete/$', 'setup_source_delete', (), 'setup_source_delete'), url(r'^setup/(?P<source_id>\d+)/delete/$', 'setup_source_delete', (), 'setup_source_delete'),
url(r'^setup/(?P<source_type>\w+)/create/$', 'setup_source_create', (), 'setup_source_create'), url(r'^setup/(?P<source_type>\w+)/create/$', 'setup_source_create', (), 'setup_source_create'),
url(r'^setup/(?P<source_id>\d+)/transformation/list/$', 'setup_source_transformation_list', (), 'setup_source_transformation_list'),
url(r'^setup/(?P<source_id>\d+)/transformation/create/$', 'setup_source_transformation_create', (), 'setup_source_transformation_create'),
url(r'^setup/source/transformation/(?P<transformation_id>\d+)/edit/$', 'setup_source_transformation_edit', (), 'setup_source_transformation_edit'),
url(r'^setup/source/transformation/(?P<transformation_id>\d+)/delete/$', 'setup_source_transformation_delete', (), 'setup_source_transformation_delete'),
# Document create views # Document create views
url(r'^create/from/local/multiple/$', DocumentCreateWizard.as_view(), name='document_create_multiple'), url(r'^create/from/local/multiple/$', DocumentCreateWizard.as_view(), name='document_create_multiple'),

View File

@@ -25,16 +25,14 @@ from navigation import Link
from permissions.models import Permission from permissions.models import Permission
from .forms import ( from .forms import (
NewDocumentForm, NewVersionForm, SourceTransformationForm, NewDocumentForm, NewVersionForm
SourceTransformationForm_create
) )
from .literals import ( from .literals import (
SOURCE_CHOICE_STAGING, SOURCE_CHOICE_WEB_FORM, SOURCE_UNCOMPRESS_CHOICE_ASK, SOURCE_CHOICE_STAGING, SOURCE_CHOICE_WEB_FORM, SOURCE_UNCOMPRESS_CHOICE_ASK,
SOURCE_UNCOMPRESS_CHOICE_Y SOURCE_UNCOMPRESS_CHOICE_Y
) )
from .models import ( from .models import (
InteractiveSource, Source, StagingFolderSource, SourceTransformation, InteractiveSource, Source, StagingFolderSource, WebFormSource
WebFormSource
) )
from .permissions import ( from .permissions import (
PERMISSION_SOURCES_SETUP_CREATE, PERMISSION_SOURCES_SETUP_DELETE, PERMISSION_SOURCES_SETUP_CREATE, PERMISSION_SOURCES_SETUP_DELETE,
@@ -443,113 +441,3 @@ def setup_source_create(request, source_type):
'source_type': source_type, 'source_type': source_type,
'title': _('Create new source of type: %s') % cls.class_fullname(), 'title': _('Create new source of type: %s') % cls.class_fullname(),
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
def setup_source_transformation_list(request, source_id):
Permission.objects.check_permissions(request.user, [PERMISSION_SOURCES_SETUP_EDIT])
source = get_object_or_404(Source.objects.select_subclasses(), pk=source_id)
context = {
'extra_columns': [
{'name': _('Order'), 'attribute': 'order'},
{'name': _('Transformation'), 'attribute': encapsulate(lambda x: x.get_transformation_display())},
{'name': _('Arguments'), 'attribute': 'arguments'}
],
'hide_link': True,
'hide_object': True,
'navigation_object_list': ['source'],
'object_list': SourceTransformation.transformations.get_for_object(source),
'source': source,
'title': _('Transformations for: %s') % source.fullname(),
}
return render_to_response('appearance/generic_list.html', context,
context_instance=RequestContext(request))
def setup_source_transformation_edit(request, transformation_id):
Permission.objects.check_permissions(request.user, [PERMISSION_SOURCES_SETUP_EDIT])
source_transformation = get_object_or_404(SourceTransformation, pk=transformation_id)
redirect_view = reverse('sources:setup_source_transformation_list', args=[source_transformation.content_object.pk])
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', redirect_view)))
if request.method == 'POST':
form = SourceTransformationForm(instance=source_transformation, data=request.POST)
if form.is_valid():
try:
form.save()
messages.success(request, _('Source transformation edited successfully'))
return HttpResponseRedirect(next)
except Exception as exception:
messages.error(request, _('Error editing source transformation; %s') % exception)
else:
form = SourceTransformationForm(instance=source_transformation)
return render_to_response('appearance/generic_form.html', {
'form': form,
'navigation_object_list': ['source', 'transformation'],
'next': next,
'source': source_transformation.content_object,
'transformation': source_transformation,
'title': _('Edit transformation: %s') % source_transformation,
}, context_instance=RequestContext(request))
def setup_source_transformation_delete(request, transformation_id):
Permission.objects.check_permissions(request.user, [PERMISSION_SOURCES_SETUP_EDIT])
source_transformation = get_object_or_404(SourceTransformation, pk=transformation_id)
redirect_view = reverse('sources:setup_source_transformation_list', args=[source_transformation.content_object.pk])
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', redirect_view)))
if request.method == 'POST':
try:
source_transformation.delete()
messages.success(request, _('Source transformation deleted successfully.'))
except Exception as exception:
messages.error(request, _('Error deleting source transformation; %(error)s') % {
'error': exception}
)
return HttpResponseRedirect(redirect_view)
return render_to_response('appearance/generic_confirm.html', {
'delete_view': True,
'navigation_object_list': ['source', 'transformation'],
'previous': previous,
'source': source_transformation.content_object,
'title': _('Are you sure you wish to delete source transformation "%(transformation)s"') % {
'transformation': source_transformation.get_transformation_display(),
},
'transformation': source_transformation,
}, context_instance=RequestContext(request))
def setup_source_transformation_create(request, source_id):
Permission.objects.check_permissions(request.user, [PERMISSION_SOURCES_SETUP_EDIT])
source = get_object_or_404(Source.objects.select_subclasses(), pk=source_id)
redirect_view = reverse('sources:setup_source_transformation_list', args=[source.pk])
if request.method == 'POST':
form = SourceTransformationForm_create(request.POST)
if form.is_valid():
try:
source_tranformation = form.save(commit=False)
source_tranformation.content_object = source
source_tranformation.save()
messages.success(request, _('Source transformation created successfully'))
return HttpResponseRedirect(redirect_view)
except Exception as exception:
messages.error(request, _('Error creating source transformation; %s') % exception)
else:
form = SourceTransformationForm_create()
return render_to_response('appearance/generic_form.html', {
'form': form,
'source': source,
'navigation_object_list': ['source'],
'title': _('Create new transformation for source: %s') % source,
}, context_instance=RequestContext(request))