diff --git a/apps/sources/__init__.py b/apps/sources/__init__.py index 64db8aeaab..0cd2b962d0 100644 --- a/apps/sources/__init__.py +++ b/apps/sources/__init__.py @@ -11,7 +11,7 @@ from documents.models import Document from .staging import StagingFile from .models import (WebForm, StagingFolder, SourceTransformation, - WatchFolder, POP3Email, IMAPEmail) + WatchFolder, POP3Email, IMAPEmail, LocalScanner) from .widgets import staging_file_thumbnail from .tasks import task_fetch_pop3_emails, task_fetch_imap_emails from .conf.settings import EMAIL_PROCESSING_INTERVAL @@ -21,32 +21,35 @@ from .links import (staging_file_delete, setup_sources, setup_source_delete, setup_source_create, setup_source_log_list, setup_source_transformation_list, setup_source_transformation_create, setup_source_transformation_edit, setup_source_transformation_delete, - upload_version, document_create_multiple) + upload_version, document_create_multiple, setup_local_scanner_list) bind_links([StagingFile], [staging_file_delete]) bind_links([SourceTransformation], [setup_source_transformation_edit, setup_source_transformation_delete]) -bind_links(['setup_imap_email_list', 'setup_pop3_email_list', 'setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_create'], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list], menu_name='form_header') -bind_links([WebForm, StagingFolder, POP3Email, IMAPEmail, 'setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_create', 'setup_pop3_email_list', 'setup_imap_email_list'], [setup_source_create], menu_name='secondary_menu') +bind_links(['setup_imap_email_list', 'setup_pop3_email_list', 'setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_create', 'setup_local_scanner_list'], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list, setup_local_scanner_list], menu_name='form_header') +bind_links([WebForm, StagingFolder, POP3Email, IMAPEmail, LocalScanner, 'setup_web_form_list', 'setup_staging_folder_list', 'setup_watch_folder_list', 'setup_source_create', 'setup_pop3_email_list', 'setup_imap_email_list', 'setup_local_scanner_list'], [setup_source_create], menu_name='secondary_menu') -bind_links([WebForm], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list], menu_name='form_header') +bind_links([WebForm], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list, setup_local_scanner_list], menu_name='form_header') bind_links([WebForm], [setup_source_transformation_list, setup_source_edit, setup_source_delete]) -bind_links([StagingFolder], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list], menu_name='form_header') +bind_links([StagingFolder], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list, setup_local_scanner_list], menu_name='form_header') bind_links([StagingFolder], [setup_source_transformation_list, setup_source_edit, setup_source_delete]) -bind_links([POP3Email], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list], menu_name='form_header') +bind_links([POP3Email], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list, setup_local_scanner_list], menu_name='form_header') bind_links([POP3Email], [setup_source_transformation_list, setup_source_edit, setup_source_delete]) bind_links([POP3Email], [setup_source_log_list]) -bind_links([IMAPEmail], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list], menu_name='form_header') +bind_links([IMAPEmail], [setup_web_form_list, setup_staging_folder_list, setup_pop3_email_list, setup_imap_email_list, setup_local_scanner_list], menu_name='form_header') bind_links([IMAPEmail], [setup_source_transformation_list, setup_source_edit, setup_source_delete]) bind_links([IMAPEmail], [setup_source_log_list]) -bind_links([WatchFolder], [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list, setup_imap_email_list], menu_name='form_header') +bind_links([WatchFolder], [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list, setup_imap_email_list, setup_local_scanner_list], menu_name='form_header') bind_links([WatchFolder], [setup_source_transformation_list, setup_source_edit, setup_source_delete]) +bind_links([LocalScanner], [setup_web_form_list, setup_staging_folder_list, setup_watch_folder_list, setup_imap_email_list, setup_local_scanner_list], menu_name='form_header') +bind_links([LocalScanner], [setup_source_transformation_list, setup_source_edit, setup_source_delete]) + # Document version bind_links(['document_version_list', 'upload_version', 'document_version_revert', 'document_version_text_compare', 'document_version_show_diff_text'], [upload_version], menu_name='sidebar') diff --git a/apps/sources/forms.py b/apps/sources/forms.py index 84b6f79281..a2bd2d4f53 100644 --- a/apps/sources/forms.py +++ b/apps/sources/forms.py @@ -7,7 +7,7 @@ from django.utils.translation import ugettext from documents.forms import DocumentForm from .models import (WebForm, StagingFolder, SourceTransformation, - WatchFolder, POP3Email, IMAPEmail) + WatchFolder, POP3Email, IMAPEmail, LocalScanner) from .widgets import FamFamRadioSelect from .utils import validate_whitelist_blacklist @@ -100,6 +100,21 @@ class WatchFolderSetupForm(forms.ModelForm): model = WatchFolder +class LocalScannerSetupForm(forms.ModelForm): + class Meta: + model = LocalScanner + + scanner = forms.ChoiceField(required=False, label=_(u'Active scanners'), help_text=_(u'List of scanners found connected to this node. Choose one to have its device and description automatically saved in the fields above.')) + + def __init__(self, *args, **kwargs): + super(LocalScannerSetupForm, self).__init__(*args, **kwargs) + self.fields['icon'].widget = FamFamRadioSelect( + attrs=self.fields['icon'].widget.attrs, + choices=self.fields['icon'].widget.choices, + ) + self.fields['scanner'].choices = LocalScanner.get_scanner_choices() + + class SourceTransformationForm(forms.ModelForm): class Meta: model = SourceTransformation diff --git a/apps/sources/links.py b/apps/sources/links.py index 1bebe3ac6f..03b269201f 100644 --- a/apps/sources/links.py +++ b/apps/sources/links.py @@ -9,7 +9,7 @@ from .permissions import (PERMISSION_SOURCES_SETUP_VIEW, PERMISSION_SOURCES_SETUP_EDIT, PERMISSION_SOURCES_SETUP_DELETE, PERMISSION_SOURCES_SETUP_CREATE) from .models import (WebForm, StagingFolder, SourceTransformation, - WatchFolder, POP3Email, IMAPEmail) + WatchFolder, POP3Email, IMAPEmail, LocalScanner) staging_file_preview = Link(text=_(u'preview'), klass='fancybox-noscaling', view='staging_file_preview', args=['source.source_type', 'source.pk', 'object.pk'], sprite='zoom', permissions=[PERMISSION_DOCUMENT_NEW_VERSION, PERMISSION_DOCUMENT_CREATE]) staging_file_delete = Link(text=_(u'delete'), view='staging_file_delete', args=['source.source_type', 'source.pk', 'object.pk'], sprite='delete', keep_query=True, permissions=[PERMISSION_DOCUMENT_NEW_VERSION, PERMISSION_DOCUMENT_CREATE]) @@ -20,6 +20,7 @@ setup_staging_folder_list = Link(text=_(u'staging folders'), view='setup_staging setup_watch_folder_list = Link(text=_(u'watch folders'), view='setup_watch_folder_list', sprite='folder_magnify', children_classes=[WatchFolder], permissions=[PERMISSION_SOURCES_SETUP_VIEW]) setup_pop3_email_list = Link(text=_(u'POP3 email'), view='setup_pop3_email_list', sprite='email', children_classes=[POP3Email], permissions=[PERMISSION_SOURCES_SETUP_VIEW]) setup_imap_email_list = Link(text=_(u'IMAP email'), view='setup_imap_email_list', sprite='email', children_classes=[IMAPEmail], permissions=[PERMISSION_SOURCES_SETUP_VIEW]) +setup_local_scanner_list = Link(text=_(u'Local scanner'), view='setup_local_scanner_list', sprite='images', children_classes=[LocalScanner], permissions=[PERMISSION_SOURCES_SETUP_VIEW]) setup_source_edit = Link(text=_(u'edit'), view='setup_source_edit', args=['source.source_type', 'source.pk'], sprite='application_form_edit', permissions=[PERMISSION_SOURCES_SETUP_EDIT]) setup_source_delete = Link(text=_(u'delete'), view='setup_source_delete', args=['source.source_type', 'source.pk'], sprite='application_form_delete', permissions=[PERMISSION_SOURCES_SETUP_DELETE]) diff --git a/apps/sources/literals.py b/apps/sources/literals.py index 8faeb2f4aa..f2b6945f63 100644 --- a/apps/sources/literals.py +++ b/apps/sources/literals.py @@ -35,6 +35,7 @@ SOURCE_ICON_FOLDER = 'folder' SOURCE_ICON_WORLD = 'world' SOURCE_ICON_PRINTER = 'printer' SOURCE_ICON_PRINTER_EMPTY = 'printer_empty' +SOURCE_ICON_IMAGES = 'images' SOURCE_ICON_CHOICES = ( (SOURCE_ICON_DISK, _(u'Disk')), @@ -44,6 +45,7 @@ SOURCE_ICON_CHOICES = ( (SOURCE_ICON_DRIVE_USER, _(u'User drive')), (SOURCE_ICON_EMAIL, _(u'Envelope')), (SOURCE_ICON_FOLDER, _(u'Folder')), + (SOURCE_ICON_IMAGES, _(u'Images')), (SOURCE_ICON_WORLD, _(u'World')), (SOURCE_ICON_PRINTER, _(u'Printer')), (SOURCE_ICON_PRINTER_EMPTY, _(u'Empty printer')), @@ -54,6 +56,7 @@ SOURCE_CHOICE_STAGING = 'staging' SOURCE_CHOICE_WATCH = 'watch' SOURCE_CHOICE_POP3_EMAIL = 'pop3' SOURCE_CHOICE_IMAP_EMAIL = 'imap' +SOURCE_CHOICE_LOCAL_SCANNER = 'local_scanner' SOURCE_CHOICES = ( (SOURCE_CHOICE_WEB_FORM, _(u'web form')), @@ -61,6 +64,7 @@ SOURCE_CHOICES = ( (SOURCE_CHOICE_WATCH, _(u'server watch folder')), (SOURCE_CHOICE_POP3_EMAIL, _(u'POP3 email')), (SOURCE_CHOICE_IMAP_EMAIL, _(u'IMAP email')), + (SOURCE_CHOICE_LOCAL_SCANNER, _(u'Local scanner')), ) SOURCE_CHOICES_PLURAL = ( @@ -69,4 +73,5 @@ SOURCE_CHOICES_PLURAL = ( (SOURCE_CHOICE_WATCH, _(u'server watch folders')), (SOURCE_CHOICE_POP3_EMAIL, _(u'POP3 emails')), (SOURCE_CHOICE_IMAP_EMAIL, _(u'IMAP emails')), + (SOURCE_CHOICE_LOCAL_SCANNER, _(u'Local scanners')), ) diff --git a/apps/sources/migrations/0013_auto__add_localscanner.py b/apps/sources/migrations/0013_auto__add_localscanner.py new file mode 100644 index 0000000000..c4f088cadf --- /dev/null +++ b/apps/sources/migrations/0013_auto__add_localscanner.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'LocalScanner' + db.create_table('sources_localscanner', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('title', self.gf('django.db.models.fields.CharField')(max_length=64)), + ('enabled', self.gf('django.db.models.fields.BooleanField')(default=True)), + ('whitelist', self.gf('django.db.models.fields.TextField')(blank=True)), + ('blacklist', self.gf('django.db.models.fields.TextField')(blank=True)), + ('icon', self.gf('django.db.models.fields.CharField')(max_length=24, null=True, blank=True)), + ('scanner_device', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('scanner_description', self.gf('django.db.models.fields.CharField')(max_length=255)), + )) + db.send_create_signal('sources', ['LocalScanner']) + + + def backwards(self, orm): + # Deleting model 'LocalScanner' + db.delete_table('sources_localscanner') + + + models = { + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'documents.documenttype': { + 'Meta': {'ordering': "['name']", 'object_name': 'DocumentType'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}) + }, + 'sources.imapemail': { + 'Meta': {'ordering': "('title',)", 'object_name': 'IMAPEmail'}, + 'blacklist': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'document_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentType']", 'null': 'True', 'blank': 'True'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'host': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'interval': ('django.db.models.fields.PositiveIntegerField', [], {'default': '900'}), + 'mailbox': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'port': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'ssl': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'uncompress': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'username': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'sources.localscanner': { + 'Meta': {'ordering': "('title',)", 'object_name': 'LocalScanner'}, + 'blacklist': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'icon': ('django.db.models.fields.CharField', [], {'max_length': '24', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'scanner_description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'scanner_device': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'sources.outofprocess': { + 'Meta': {'ordering': "('title',)", 'object_name': 'OutOfProcess'}, + 'blacklist': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'sources.pop3email': { + 'Meta': {'ordering': "('title',)", 'object_name': 'POP3Email'}, + 'blacklist': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'document_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['documents.DocumentType']", 'null': 'True', 'blank': 'True'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'host': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'interval': ('django.db.models.fields.PositiveIntegerField', [], {'default': '900'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'port': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'ssl': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'uncompress': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'username': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'sources.sourcelog': { + 'Meta': {'ordering': "('creation_datetime',)", 'object_name': 'SourceLog'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'creation_datetime': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'status': ('django.db.models.fields.TextField', [], {}) + }, + 'sources.sourcetransformation': { + 'Meta': {'ordering': "('order',)", 'object_name': 'SourceTransformation'}, + 'arguments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'transformation': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'sources.stagingfolder': { + 'Meta': {'ordering': "('title',)", 'object_name': 'StagingFolder'}, + 'blacklist': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'delete_after_upload': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'folder_path': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'icon': ('django.db.models.fields.CharField', [], {'max_length': '24', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'preview_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'preview_width': ('django.db.models.fields.IntegerField', [], {}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'uncompress': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'sources.watchfolder': { + 'Meta': {'ordering': "('title',)", 'object_name': 'WatchFolder'}, + 'blacklist': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'delete_after_upload': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'folder_path': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'interval': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'uncompress': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'sources.webform': { + 'Meta': {'ordering': "('title',)", 'object_name': 'WebForm'}, + 'blacklist': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'icon': ('django.db.models.fields.CharField', [], {'max_length': '24', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'uncompress': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'whitelist': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + } + } + + complete_apps = ['sources'] \ No newline at end of file diff --git a/apps/sources/models.py b/apps/sources/models.py index 9c779eebe7..afaf5a004d 100644 --- a/apps/sources/models.py +++ b/apps/sources/models.py @@ -14,6 +14,8 @@ try: except ImportError: from StringIO import StringIO +import imagescanner + from django.db import models from django.utils.translation import ugettext_lazy as _ from django.contrib.contenttypes.models import ContentType @@ -39,7 +41,8 @@ from .literals import (SOURCE_CHOICES, SOURCE_CHOICES_PLURAL, SOURCE_CHOICE_POP3_EMAIL, DEFAULT_POP3_INTERVAL, IMAP_PORT, IMAP_SSL_PORT, SOURCE_CHOICE_IMAP_EMAIL, DEFAULT_IMAP_INTERVAL, - IMAP_DEFAULT_MAILBOX) + IMAP_DEFAULT_MAILBOX, + SOURCE_CHOICE_LOCAL_SCANNER, SOURCE_ICON_IMAGES) from .compressed_file import CompressedFile, NotACompressedFile from .conf.settings import POP3_TIMEOUT #from . import sources_scheduler @@ -378,6 +381,28 @@ class IMAPEmail(EmailBaseModel): verbose_name_plural = _(u'IMAP email') +class LocalScanner(InteractiveBaseModel): + is_interactive = True + source_type = SOURCE_CHOICE_LOCAL_SCANNER + default_icon = SOURCE_ICON_IMAGES + + scanner_device = models.CharField(max_length=255, verbose_name=_(u'scanner device')) + scanner_description = models.CharField(max_length=255, verbose_name=_(u'scanner description')) + + @classmethod + def get_scanner_choices(cls): + imagescanner.settings.ENABLE_NET_BACKEND = False + imagescanner.settings.ENABLE_TEST_BACKEND = False + + iscanner = imagescanner.ImageScanner(remote_search=False) + scanners = iscanner.list_scanners() + return [(scanner._device, u'%s: %s - %s - %s <%s>' % (scanner.id, scanner.manufacturer, scanner.name, scanner.description, scanner._device)) for scanner in scanners] + + class Meta(InteractiveBaseModel.Meta): + verbose_name = _(u'local scanner') + verbose_name_plural = _(u'local scanners') + + class StagingFolder(InteractiveBaseModel): is_interactive = True source_type = SOURCE_CHOICE_STAGING diff --git a/apps/sources/static/images/icons/image_delete.png b/apps/sources/static/images/icons/image_delete.png new file mode 100755 index 0000000000..580f81a22e Binary files /dev/null and b/apps/sources/static/images/icons/image_delete.png differ diff --git a/apps/sources/urls.py b/apps/sources/urls.py index 333b687b91..ae02bf0ea6 100644 --- a/apps/sources/urls.py +++ b/apps/sources/urls.py @@ -3,7 +3,8 @@ from __future__ import absolute_import from django.conf.urls.defaults import patterns, url from .literals import (SOURCE_CHOICE_WEB_FORM, SOURCE_CHOICE_STAGING, - SOURCE_CHOICE_WATCH, SOURCE_CHOICE_POP3_EMAIL, SOURCE_CHOICE_IMAP_EMAIL) + SOURCE_CHOICE_WATCH, SOURCE_CHOICE_POP3_EMAIL, SOURCE_CHOICE_IMAP_EMAIL, + SOURCE_CHOICE_LOCAL_SCANNER) urlpatterns = patterns('sources.views', url(r'^create/from/local/multiple/$', 'document_create', (), 'document_create_multiple'), @@ -25,6 +26,7 @@ urlpatterns = patterns('sources.views', url(r'^setup/interactive/%s/list/$' % SOURCE_CHOICE_WATCH, 'setup_source_list', {'source_type': SOURCE_CHOICE_WATCH}, 'setup_watch_folder_list'), url(r'^setup/interactive/%s/list/$' % SOURCE_CHOICE_POP3_EMAIL, 'setup_source_list', {'source_type': SOURCE_CHOICE_POP3_EMAIL}, 'setup_pop3_email_list'), url(r'^setup/interactive/%s/list/$' % SOURCE_CHOICE_IMAP_EMAIL, 'setup_source_list', {'source_type': SOURCE_CHOICE_IMAP_EMAIL}, 'setup_imap_email_list'), + url(r'^setup/interactive/%s/list/$' % SOURCE_CHOICE_LOCAL_SCANNER, 'setup_source_list', {'source_type': SOURCE_CHOICE_LOCAL_SCANNER}, 'setup_local_scanner_list'), url(r'^setup/interactive/(?P\w+)/list/$', 'setup_source_list', (), 'setup_source_list'), url(r'^setup/interactive/(?P\w+)/(?P\d+)/edit/$', 'setup_source_edit', (), 'setup_source_edit'), diff --git a/apps/sources/views.py b/apps/sources/views.py index 3e8aa2511a..e78cc3e40d 100644 --- a/apps/sources/views.py +++ b/apps/sources/views.py @@ -29,16 +29,16 @@ from acls.models import AccessEntry from navigation.api import Link from .models import (WebForm, StagingFolder, SourceTransformation, - WatchFolder, POP3Email, SourceLog, IMAPEmail) + WatchFolder, POP3Email, SourceLog, IMAPEmail, LocalScanner) from .literals import (SOURCE_CHOICE_WEB_FORM, SOURCE_CHOICE_STAGING, - SOURCE_CHOICE_WATCH, SOURCE_CHOICE_POP3_EMAIL, SOURCE_CHOICE_IMAP_EMAIL) + SOURCE_CHOICE_WATCH, SOURCE_CHOICE_POP3_EMAIL, SOURCE_CHOICE_IMAP_EMAIL, + SOURCE_CHOICE_LOCAL_SCANNER) from .literals import (SOURCE_UNCOMPRESS_CHOICE_Y, SOURCE_UNCOMPRESS_CHOICE_ASK) from .staging import create_staging_file_class from .forms import (StagingDocumentForm, WebFormForm, - WatchFolderSetupForm) -from .forms import (WebFormSetupForm, StagingFolderSetupForm, - POP3EmailSetupForm, IMAPEmailSetupForm) + WatchFolderSetupForm, WebFormSetupForm, StagingFolderSetupForm, + POP3EmailSetupForm, IMAPEmailSetupForm, LocalScannerSetupForm) from .forms import SourceTransformationForm, SourceTransformationForm_create from .permissions import (PERMISSION_SOURCES_SETUP_VIEW, PERMISSION_SOURCES_SETUP_EDIT, PERMISSION_SOURCES_SETUP_DELETE, @@ -446,6 +446,8 @@ def setup_source_list(request, source_type): cls = POP3Email elif source_type == SOURCE_CHOICE_IMAP_EMAIL: cls = IMAPEmail + elif source_type == SOURCE_CHOICE_LOCAL_SCANNER: + cls = LocalScanner context = { 'object_list': cls.objects.all(), @@ -480,6 +482,9 @@ def setup_source_edit(request, source_type, source_id): elif source_type == SOURCE_CHOICE_IMAP_EMAIL: cls = IMAPEmail form_class = IMAPEmailSetupForm + elif source_type == SOURCE_CHOICE_LOCAL_SCANNER: + cls = LocalScanner + form_class = LocalScannerSetupForm source = get_object_or_404(cls, pk=source_id) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/'))) @@ -530,6 +535,10 @@ def setup_source_delete(request, source_type, source_id): cls = IMAPEmail form_icon = u'email_delete.png' redirect_view = 'setup_imap_email_list' + elif source_type == SOURCE_CHOICE_LOCAL_SCANNER: + cls = LocalScanner + form_icon = u'image_delete.png' + redirect_view = 'setup_local_scanner_list' redirect_view = reverse('setup_source_list', args=[source_type]) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', redirect_view))) @@ -588,7 +597,11 @@ def setup_source_create(request, source_type): cls = IMAPEmail form_class = IMAPEmailSetupForm redirect_view = 'setup_imap_email_list' - + elif source_type == SOURCE_CHOICE_LOCAL_SCANNER: + cls = LocalScanner + form_class = LocalScannerSetupForm + redirect_view = 'setup_local_scanner_list' + if request.method == 'POST': form = form_class(data=request.POST) if form.is_valid(): @@ -623,6 +636,8 @@ def setup_source_log_list(request, source_type, source_pk): cls = POP3Email elif source_type == SOURCE_CHOICE_IMAP_EMAIL: cls = IMAPEmail + elif source_type == SOURCE_CHOICE_LOCAL_SCANNER: + cls = LocalScanner source = get_object_or_404(cls, pk=source_pk) @@ -659,6 +674,8 @@ def setup_source_transformation_list(request, source_type, source_id): cls = POP3Email elif source_type == SOURCE_CHOICE_IMAP_EMAIL: cls = IMAPEmail + elif source_type == SOURCE_CHOICE_LOCAL_SCANNER: + cls = LocalScanner source = get_object_or_404(cls, pk=source_id) @@ -765,6 +782,8 @@ def setup_source_transformation_create(request, source_type, source_id): cls = POP3Email elif source_type == SOURCE_CHOICE_IMAP_EMAIL: cls = IMAPEmail + elif source_type == SOURCE_CHOICE_LOCAL_SCANNER: + cls = LocalScanner source = get_object_or_404(cls, pk=source_id) diff --git a/docs/releases/0.13.rst b/docs/releases/0.13.rst index 3a36a675b5..40b6e27991 100644 --- a/docs/releases/0.13.rst +++ b/docs/releases/0.13.rst @@ -88,6 +88,7 @@ Afterwards migrate existing database schema with:: $ ./manage.py migrate job_processor $ ./manage.py migrate clustering $ ./manage.py migrate trash + $ ./manage.py migrate sources Issue the following command to index existing documents in the new full text search database:: diff --git a/requirements/production.txt b/requirements/production.txt index 9055a27f2f..7844e4d0c0 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -68,6 +68,10 @@ pbs==0.105 psutil==0.5.1 GitPython==0.3.2.RC1 +# Sources + +-e git+https://github.com/rosarior/imagescanner.git#egg=imagescanner + # Misc elementtree==1.2.7-20070827-preview