def save_formset(self, request, form, formset, change): """Actions to take while saving inline instances""" instances = formset.save(commit=False) for instance in instances: # only way to tell if its new or not is to check the db change = True try: formset.model.objects.get(pk=instance.pk) except formset.model.DoesNotExist: change = False instance.foia = instance.comm.foia instance.save() # its new, so notify the user about it if not change: instance.comm.foia.update(instance.anchor()) upload_document_cloud.apply_async( args=[instance.pk, change], countdown=30) formset.save_m2m() for obj in formset.deleted_objects: obj.delete()
def save_formset(self, request, form, formset, change): """Actions to take while saving inline files""" # pylint: disable=no-self-use # pylint: disable=unused-argument if formset.model != FOIAFile: return super(FOIACommunicationAdmin, self).save_formset(request, form, formset, change) instances = formset.save(commit=False) for instance in instances: # only way to tell if its new or not is to check the db change = True try: formset.model.objects.get(pk=instance.pk) except formset.model.DoesNotExist: change = False instance.foia = instance.comm.foia instance.save() # its new, so notify the user about it if not change: instance.comm.foia.update(instance.anchor()) upload_document_cloud.apply_async(args=[instance.pk, change], countdown=30) formset.save_m2m() for obj in formset.deleted_objects: obj.delete()
def clone(self, foia_pks): """ Copies the communication to each request in the list, then returns all the new communications. --- When setting self.pk to None and then calling self.save(), Django will clone the communication along with all of its data and give it a new primary key. On the next iteration of the loop, the clone will be cloned along with its data, and so on. Same thing goes for each file attached to the communication. """ # avoid circular imports from muckrock.foia.tasks import upload_document_cloud request_list = requests_from_pks(foia_pks) if not request_list: raise ValueError('No valid request(s) provided for cloning.') cloned_comms = [] original_pk = self.pk files = self.files.all() for request in request_list: this_clone = FOIACommunication.objects.get(pk=original_pk) this_clone.pk = None this_clone.foia = request this_clone.save() access = 'private' if request.embargo else 'public' source = request.agency.name if request.agency else self.from_who for file_ in files: original_file_id = file_.id file_.pk = None file_.foia = request file_.comm = this_clone file_.access = access file_.source = source # make a copy of the file on the storage backend try: new_ffile = ContentFile(file_.ffile.read()) except ValueError: error_msg = ( 'FOIAFile #%s has no data in its ffile field. ' 'It has not been cloned.') logger.error(error_msg, original_file_id) continue new_ffile.name = file_.ffile.name file_.ffile = new_ffile file_.save() upload_document_cloud.apply_async(args=[file_.pk, False], countdown=3) # for each clone, self gets overwritten. each clone needs to be stored explicitly. cloned_comms.append(this_clone) logger.info('Communication #%d cloned to request #%d', original_pk, this_clone.foia.id) return cloned_comms
def foia_update_embargo(sender, **kwargs): """When embargo has possibly been switched, update the document cloud permissions""" # pylint: disable=unused-argument request = kwargs['instance'] old_request = request.get_saved() # if we are saving a new FOIA Request, there are no docs to update if old_request and request.embargo != old_request.embargo: access = 'private' if request.embargo else 'public' for doc in request.files.all(): if doc.is_doccloud() and doc.access != access: doc.access = access doc.save() upload_document_cloud.apply_async(args=[doc.pk, True], countdown=3) return
def _upload_file(foia, comm, file_, sender): """Upload a file to attach to a FOIA request""" access = 'private' if foia and foia.embargo else 'public' source = foia.agency.name if foia and foia.agency else sender foia_file = FOIAFile(foia=foia, comm=comm, title=os.path.splitext(file_.name)[0][:70], date=datetime.now(), source=source[:70], access=access) # max db size of 255, - 22 for folder name foia_file.ffile.save(file_.name[:233].encode('ascii', 'ignore'), file_) foia_file.save() if foia: upload_document_cloud.apply_async(args=[foia_file.pk, False], countdown=3)
def upload_file(self, file_): """Upload and attach a file""" # avoid circular imports from muckrock.foia.tasks import upload_document_cloud # make orphans and embargoed documents private access = 'private' if not self.foia or self.foia.embargo else 'public' source = self.get_source() foia_file = self.files.create(foia=self.foia, title=os.path.splitext( file_.name)[0][:70], date=datetime.now(), source=source[:70], access=access) # max db size of 255, - 22 for folder name foia_file.ffile.save(file_.name[:233].encode('ascii', 'ignore'), file_) foia_file.save() if self.foia: upload_document_cloud.apply_async(args=[foia_file.pk, False], countdown=3)
def clone(self, new_comm): """Clone this file to a new communication""" from muckrock.foia.tasks import upload_document_cloud access = 'private' if new_comm.foia.embargo else 'public' original_id = self.pk self.pk = None self.comm = new_comm self.access = access self.source = new_comm.get_source() # make a copy of the file on the storage backend try: new_ffile = ContentFile(self.ffile.read()) except ValueError: error_msg = ('FOIAFile #%s has no data in its ffile field. ' 'It has not been cloned.') logger.error(error_msg, original_id) return new_ffile.name = self.ffile.name self.ffile = new_ffile self.save() upload_document_cloud.apply_async(args=[self.pk, False], countdown=3)
def save_formset(self, request, form, formset, change): """Actions to take while saving inline instances""" if formset.model == FOIANote: formset.save() # check for foia updates here so that communication updates take priority # (Notes are last) foia = form.instance old_foia = FOIARequest.objects.get(pk=foia.pk) if foia.status != old_foia.status: foia.update() foia.update_dates() foia.save() return # check communications and files for new ones to notify the user of an update instances = formset.save(commit=False) for instance in instances: # only way to tell if its new or not is to check the db change = True try: formset.model.objects.get(pk=instance.pk) except formset.model.DoesNotExist: change = False if formset.model == FOIAFile: instance.foia = instance.comm.foia instance.save() # its new, so notify the user about it if not change and formset.model == FOIACommunication: instance.foia.update(instance.anchor()) if not change and formset.model == FOIAFile: instance.comm.foia.update(instance.anchor()) if formset.model == FOIAFile: upload_document_cloud.apply_async(args=[instance.pk, change], countdown=30) formset.save_m2m()
def move(self, foia_pks, user): """ Move this communication. If more than one foia_pk is given, move the communication to the first request, then clone it across the rest of the requests. Returns the moved and cloned communications. """ # avoid circular imports from muckrock.foia.tasks import upload_document_cloud foias = FOIARequest.objects.filter(pk__in=foia_pks) if not foias: raise ValueError( 'Expected a request to move the communication to.') old_foia = self.foia self.foia = foias[0] # if this was an orphan, it has not yet been uploaded # to document cloud change = old_foia is not None access = 'private' if self.foia.embargo else 'public' for file_ in self.files.all(): file_.access = access file_.source = self.get_source() file_.save() upload_document_cloud.apply_async(args=[file_.pk, change], countdown=3) self.save() CommunicationMoveLog.objects.create( communication=self, foia=old_foia, user=user, ) logger.info('Communication #%d moved to request #%d', self.id, self.foia.id) # if cloning happens, self gets overwritten. so we save it to a variable here comm = FOIACommunication.objects.get(pk=self.pk) moved = [comm] cloned = [] if foias[1:]: cloned = self.clone(foias[1:], user) return moved + cloned
def move(self, foia_pks): """ Move this communication. If more than one foia_pk is given, move the communication to the first request, then clone it across the rest of the requests. Returns the moved and cloned communications. """ # avoid circular imports from muckrock.foia.tasks import upload_document_cloud if not foia_pks: raise ValueError( 'Expected a request to move the communication to.') if not isinstance(foia_pks, list): foia_pks = [foia_pks] move_to_request = get_object_or_404(FOIARequest, pk=foia_pks[0]) old_foia = self.foia self.foia = move_to_request # if this was an orphan, it has not yet been uploaded # to document cloud change = old_foia is not None access = 'private' if self.foia.embargo else 'public' source = self.foia.agency.name if self.foia.agency else self.from_who for each_file in self.files.all(): each_file.foia = move_to_request each_file.access = access each_file.source = source[:70] each_file.save() upload_document_cloud.apply_async(args=[each_file.pk, change], countdown=3) self.save() logger.info('Communication #%d moved to request #%d', self.id, self.foia.id) # if cloning happens, self gets overwritten. so we save it to a variable here this_comm = FOIACommunication.objects.get(pk=self.pk) moved = [this_comm] cloned = [] if foia_pks[1:]: cloned = self.clone(foia_pks[1:]) return moved + cloned