Files
mayan-edms/mayan/apps/sources/models/scanner_sources.py
Roberto Rosario 36a51eeb73 Switch to full app paths
Instead of inserting the path of the apps into the Python app,
the apps are now referenced by their full import path.

This solves name clashes with external or native Python libraries.
Example: Mayan statistics app vs. Python new statistics library.

Every app reference is now prepended with 'mayan.apps'.

Existing config.yml files need to be updated manually.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
2019-04-05 02:02:57 -04:00

124 lines
4.0 KiB
Python

from __future__ import unicode_literals
import logging
import subprocess
from django.db import models
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from mayan.apps.common.utils import TemporaryFile
from ..classes import PseudoFile, SourceUploadedFile
from ..exceptions import SourceException
from ..literals import (
SCANNER_ADF_MODE_CHOICES, SCANNER_MODE_CHOICES, SCANNER_MODE_COLOR,
SCANNER_SOURCE_CHOICES, SOURCE_CHOICE_SANE_SCANNER,
)
from ..settings import setting_scanimage_path
from .base import InteractiveSource
__all__ = ('SaneScanner',)
logger = logging.getLogger(__name__)
class SaneScanner(InteractiveSource):
can_compress = False
is_interactive = True
source_type = SOURCE_CHOICE_SANE_SCANNER
device_name = models.CharField(
max_length=255,
help_text=_('Device name as returned by the SANE backend.'),
verbose_name=_('Device name')
)
mode = models.CharField(
blank=True, choices=SCANNER_MODE_CHOICES, default=SCANNER_MODE_COLOR,
help_text=_(
'Selects the scan mode (e.g., lineart, monochrome, or color). '
'If this option is not supported by your scanner, leave it blank.'
), max_length=16, verbose_name=_('Mode')
)
resolution = models.PositiveIntegerField(
blank=True, null=True, help_text=_(
'Sets the resolution of the scanned image in DPI (dots per inch). '
'Typical value is 200. If this option is not supported by your '
'scanner, leave it blank.'
), verbose_name=_('Resolution')
)
source = models.CharField(
blank=True, choices=SCANNER_SOURCE_CHOICES, help_text=_(
'Selects the scan source (such as a document-feeder). If this '
'option is not supported by your scanner, leave it blank.'
), max_length=32, null=True, verbose_name=_('Paper source')
)
adf_mode = models.CharField(
blank=True, choices=SCANNER_ADF_MODE_CHOICES,
help_text=_(
'Selects the document feeder mode (simplex/duplex). If this '
'option is not supported by your scanner, leave it blank.'
), max_length=16, verbose_name=_('ADF mode')
)
objects = models.Manager()
class Meta:
verbose_name = _('SANE Scanner')
verbose_name_plural = _('SANE Scanners')
def clean_up_upload_file(self, upload_file_object):
pass
def get_upload_file_object(self, form_data):
temporary_file_object = TemporaryFile()
command_line = [
setting_scanimage_path.value, '-d', self.device_name,
'--format', 'tiff',
]
if self.resolution:
command_line.extend(
['--resolution', '{}'.format(self.resolution)]
)
if self.mode:
command_line.extend(
['--mode', self.mode]
)
if self.source:
command_line.extend(
['--source', self.source]
)
if self.adf_mode:
command_line.extend(
['--adf-mode', self.adf_mode]
)
filestderr = TemporaryFile()
try:
logger.debug('Scan command line: %s', command_line)
subprocess.check_call(
command_line, stdout=temporary_file_object, stderr=filestderr
)
except subprocess.CalledProcessError:
filestderr.seek(0)
error_message = filestderr.read()
logger.error(
'Exception while scanning from source:%s ; %s', self,
error_message
)
message = _('Error while scanning; %s') % error_message
self.logs.create(message=message)
raise SourceException(message)
else:
return SourceUploadedFile(
source=self, file=PseudoFile(
file=temporary_file_object, name='scan {}'.format(now())
)
)