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)
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)
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
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
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")
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")
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
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
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")
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