Ejemplo n.º 1
0
    def _copy_attachment_no_transaction(self, source_attachment, signal):
        from signals.apps.signals.models import Attachment

        target_attachment = Attachment()
        target_attachment._signal = signal

        try:
            _, file_name = os.path.split(source_attachment.file.name)
            target_attachment.file.save(name=f'signal_{signal.pk}_{file_name}', content=source_attachment.file)
        except FileNotFoundError:
            pass
        else:
            target_attachment.save()
            return target_attachment
Ejemplo n.º 2
0
    def test_is_image_gif(self):
        attachment = Attachment()
        attachment.file = self.gif_upload
        attachment._signal = self.signal
        attachment.mimetype = "image/gif"
        attachment.save()

        self.assertTrue(attachment.is_image)
Ejemplo n.º 3
0
    def test_cache_file_with_word_doc(self):
        with open(self.doc_upload_location, "rb") as f:
            doc_upload = SimpleUploadedFile("file.doc", f.read(), content_type="application/msword")

            attachment = Attachment()
            attachment.file = doc_upload
            attachment.mimetype = "application/msword"
            attachment._signal = self.signal
            attachment.save()

        with self.assertRaises(Attachment.NotAnImageException):
            attachment.image_crop()

        resp = requests.get(self.live_server_url + attachment.file.url)
        self.assertEqual(200, resp.status_code, "Original file is not reachable")
Ejemplo n.º 4
0
    def test_is_image_doc_renamed_to_gif(self):
        with open(self.doc_upload_location, "rb") as f:
            doc_upload = SimpleUploadedFile("file.gif",
                                            f.read(),
                                            content_type="application/msword")

            attachment = Attachment()
            attachment.file = doc_upload
            attachment.mimetype = "application/msword"
            attachment._signal = self.signal
            attachment.save()

            self.assertFalse(attachment.is_image)
Ejemplo n.º 5
0
    def test_cropping_image_cache_file(self):
        attachment = Attachment()
        attachment.file = self.gif_upload
        attachment._signal = self.signal
        attachment.mimetype = "image/gif"
        attachment.save()

        self.assertIsInstance(attachment.image_crop.url, str)
        self.assertTrue(attachment.image_crop.url.endswith(".jpg"))

        resp = requests.get(self.live_server_url + attachment.file.url)
        self.assertEqual(200, resp.status_code, "Original image is not reachable")

        resp = requests.get(self.live_server_url + attachment.image_crop.url)
        self.assertEqual(200, resp.status_code, "Cropped image is not reachable")
Ejemplo n.º 6
0
    def test_cache_file_without_mimetype(self):
        with open(self.json_upload_location, "rb") as f:
            doc_upload = SimpleUploadedFile("upload.json", f.read(),
                                            content_type="application/json")

            attachment = Attachment()
            attachment.file = doc_upload
            attachment._signal = self.signal
            attachment.save()

        with self.assertRaises(Attachment.NotAnImageException):
            attachment.image_crop()

        self.assertEqual("application/json", attachment.mimetype, "Mimetype should be set "
                                                                  "automatically when not set "
                                                                  "explicitly")

        resp = requests.get(self.live_server_url + attachment.file.url)
        self.assertEqual(200, resp.status_code, "Original file is not reachable")
Ejemplo n.º 7
0
def add_image_attachments(signal, n=1):
    """ Adds n image attachments to signal. Returns added attachments """
    attachments = []

    for _ in range(n):
        image = SimpleUploadedFile('image.gif',
                                   small_gif,
                                   content_type='image/gif')
        attachment = Attachment()
        attachment.file = image
        attachment._signal = signal
        attachment.save()
        attachments.append(attachment)

    return attachments
Ejemplo n.º 8
0
def add_non_image_attachments(signal, n=1):
    """ Adds n file attachments to signal. Returns added attachments """
    doc_upload_location = os.path.join(os.path.dirname(__file__),
                                       'sia-ontwerp-testfile.doc')
    attachments = []

    for _ in range(n):
        with open(doc_upload_location, "rb") as f:
            doc_upload = SimpleUploadedFile("file.doc",
                                            f.read(),
                                            content_type="application/msword")

            attachment = Attachment()
            attachment.file = doc_upload
            attachment._signal = signal
            attachment.save()
            attachments.append(attachment)

    return attachments
Ejemplo n.º 9
0
    def add_attachment(self, file, signal):
        from .models import Attachment

        with transaction.atomic():
            # Do not take lock, uploads are slow and the lock is not needed for
            # consistency of the history and the signal itself because there
            # is no foreign key from Signal to Attachment.
            # Fixes: SIG-2367 (second and third upload fail because database
            # is locked while the first upload is taking place).
            attachment = Attachment()
            attachment._signal = signal
            attachment.file = file
            attachment.save()

            # SIG-2213 use transaction.on_commit to send relevant Django signals
            transaction.on_commit(lambda: add_attachment.send_robust(
                sender=self.__class__, signal_obj=signal, attachment=attachment))

        return attachment
Ejemplo n.º 10
0
    def split(self, split_data, signal, user=None):  # noqa: C901
        """ Split the original signal into 2 or more (see settings SIGNAL_MAX_NUMBER_OF_CHILDREN)
            new signals

        :param split_data: deserialized data dict containing data for new signals
        :param signal: Signal object, the original Signal
        :return: Signal object, the original Signal
        """
        # See: https://docs.djangoproject.com/en/2.1/topics/db/queries/#copying-model-instances
        from .models import (Attachment, CategoryAssignment, Location,
                             Priority, Reporter, Signal, Status, Type)
        from signals.apps.signals import workflow

        loop_counter = 0
        with transaction.atomic():
            parent_signal = Signal.objects.select_for_update(nowait=True).get(
                pk=signal.pk)
            for validated_data in split_data:
                loop_counter += 1

                # Create a new Signal, save it to get an ID in DB.
                child_signal = Signal.objects.create(
                    **{
                        'text': validated_data['text'],
                        'incident_date_start':
                        parent_signal.incident_date_start,
                        'parent': parent_signal,
                    })

                # Set the relevant properties: location, status, reporter, priority, cate
                # Deal with reverse foreign keys to child signal (for history tracking):
                status = Status.objects.create(
                    **{
                        '_signal': child_signal,
                        'state': workflow.GEMELD,
                        'text': None,
                        'user': None,  # i.e. SIA system
                    })

                location_data = {'_signal': child_signal}
                location_data.update({
                    k: getattr(parent_signal.location, k)
                    for k in [
                        'geometrie', 'stadsdeel', 'buurt_code',
                        'area_type_code', 'area_code', 'address', 'created_by',
                        'extra_properties', 'bag_validated'
                    ]
                })
                location = Location.objects.create(**location_data)

                reporter_data = {'_signal': child_signal}
                reporter_data.update({
                    k: getattr(parent_signal.reporter, k)
                    for k in [
                        'email', 'phone', 'email_anonymized',
                        'phone_anonymized', 'sharing_allowed'
                    ]  # noqa
                })
                reporter = Reporter.objects.create(**reporter_data)

                priority = None
                if parent_signal.priority:
                    priority_data = {'_signal': child_signal}
                    priority_data.update({
                        k: getattr(parent_signal.priority, k)
                        for k in ['priority', 'created_by']
                    })
                    priority = Priority.objects.create(**priority_data)

                if 'category_url' in validated_data['category']:
                    category = validated_data['category']['category_url']
                elif 'sub_category' in validated_data['category']:
                    # Only for backwards compatibility
                    category = validated_data['category']['sub_category']

                category_assignment_data = {
                    '_signal': child_signal,
                    'category': category,
                }

                category_assignment = CategoryAssignment.objects.create(
                    **category_assignment_data)

                if 'type' in validated_data:
                    type_data = validated_data[
                        'type']  # Will create a type with the given name
                    type_data[
                        'created_by'] = None  # noqa We also set the other fields to None. Shouldn't this be "user if user else None"?
                elif parent_signal.type_assignment:
                    type_data = {
                        'name': parent_signal.type_assignment.
                        name,  # noqa Will copy the type with name from the parent signal
                        'created_by':
                        None  # noqa We also set the other fields to None. Shouldn't this be "user if user else None"?
                    }
                else:
                    type_data = {
                    }  # Will create a default type with name "SIGNAL"

                # Creates the Type for the child signal
                Type.objects.create(**type_data, _signal_id=child_signal.pk)

                # Deal with forward foreign keys from child signal
                child_signal.location = location
                child_signal.status = status
                child_signal.reporter = reporter
                child_signal.priority = priority
                child_signal.category_assignment = category_assignment
                child_signal.save()

                # Ensure each child signal creation sends a DjangoSignal.
                transaction.on_commit(lambda: create_child.send_robust(
                    sender=self.__class__, signal_obj=child_signal))

                # Check if we need to copy the images of the parent
                if 'reuse_parent_image' in validated_data and validated_data[
                        'reuse_parent_image']:
                    parent_image_qs = parent_signal.attachments.filter(
                        is_image=True)
                    if parent_image_qs.exists():
                        for parent_image in parent_image_qs.all():
                            # Copy the original file and rename it by pre-pending the name with
                            # split_{loop_counter}_{original_name}
                            child_image_name = 'split_{}_{}'.format(
                                loop_counter,
                                parent_image.file.name.split('/').pop())

                            attachment = Attachment()
                            attachment._signal = child_signal
                            try:
                                attachment.file.save(name=child_image_name,
                                                     content=parent_image.file)
                            except FileNotFoundError:
                                pass
                            else:
                                attachment.save()

            # Let's update the parent signal status to GESPLITST
            status, prev_status = self._update_status_no_transaction(
                {
                    'state': workflow.GESPLITST,
                    'text': 'Deze melding is opgesplitst.',
                    'created_by': user.email if user else None,
                },
                signal=parent_signal)

            transaction.on_commit(
                lambda: update_status.send_robust(sender=self.__class__,
                                                  signal_obj=parent_signal,
                                                  status=status,
                                                  prev_status=prev_status))

        return signal