def _process(self): from indico_conversion.plugin import ConversionPlugin try: payload = secure_serializer.loads(request.form['directory'], salt='pdf-conversion') except BadData: ConversionPlugin.logger.exception('Received invalid payload (%s)', request.form['directory']) return jsonify(success=False) attachment = Attachment.get(payload['attachment_id']) if not attachment or attachment.is_deleted or attachment.folder.is_deleted: ConversionPlugin.logger.info('Attachment has been deleted: %s', attachment) return jsonify(success=True) elif request.form['status'] != '1': ConversionPlugin.logger.error('Received invalid status %s for %s', request.form['status'], attachment) return jsonify(success=False) name, ext = os.path.splitext(attachment.file.filename) title = get_pdf_title(attachment) pdf_attachment = Attachment(folder=attachment.folder, user=attachment.user, title=title, description=attachment.description, type=AttachmentType.file, protection_mode=attachment.protection_mode, acl=attachment.acl) # TODO: remove first case when Conversion Server is fully on new version if 'content' in request.form: # handling of legacy API data = BytesIO(base64.decodestring(request.form['content'])) else: filepdf = request.files['content'] data = filepdf.stream.read() pdf_attachment.file = AttachmentFile(user=attachment.file.user, filename='{}.pdf'.format(name), content_type='application/pdf') pdf_attachment.file.save(data) db.session.add(pdf_attachment) db.session.flush() cache.set(unicode(attachment.id), 'finished', timedelta(minutes=15)) ConversionPlugin.logger.info('Added PDF attachment %s for %s', pdf_attachment, attachment) signals.attachments.attachment_created.send(pdf_attachment, user=None) return jsonify(success=True)
def _process(self): from indico_conversion.plugin import ConversionPlugin try: payload = secure_serializer.loads(request.form['directory'], salt='pdf-conversion') except BadData: ConversionPlugin.logger.exception('Received invalid payload (%s)', request.form['directory']) return jsonify(success=False) attachment = Attachment.get(payload['attachment_id']) if not attachment or attachment.is_deleted or attachment.folder.is_deleted: ConversionPlugin.logger.info('Attachment has been deleted: %s', attachment) return jsonify(success=True) elif request.form['status'] != '1': ConversionPlugin.logger.error('Received invalid status %s for %s', request.form['status'], attachment) return jsonify(success=False) name, ext = os.path.splitext(attachment.file.filename) title = get_pdf_title(attachment) pdf_attachment = Attachment(folder=attachment.folder, user=attachment.user, title=title, description=attachment.description, type=AttachmentType.file, protection_mode=attachment.protection_mode, acl=attachment.acl) data = request.files['content'].stream.read() pdf_attachment.file = AttachmentFile(user=attachment.file.user, filename=f'{name}.pdf', content_type='application/pdf') pdf_attachment.file.save(data) db.session.add(pdf_attachment) db.session.flush() pdf_state_cache.set(str(attachment.id), 'finished', timeout=timedelta(minutes=15)) ConversionPlugin.logger.info('Added PDF attachment %s for %s', pdf_attachment, attachment) signals.attachments.attachment_created.send(pdf_attachment, user=None) return jsonify(success=True)
def clone(self, new_event, options): if 'attachments' not in options: return folder_mapping = {} attrs = get_simple_column_attrs(AttachmentFolder) for old_folder in self.find_folders(): new_folder = AttachmentFolder(event_id=new_event.id, **{attr: getattr(old_folder, attr) for attr in attrs}) if new_folder.linked_object is None: continue new_folder.acl = old_folder.acl db.session.add(new_folder) folder_mapping[old_folder] = new_folder attrs = get_simple_column_attrs(Attachment) - {'modified_dt'} for old_attachment in self.find_attachments(): folder = folder_mapping.get(old_attachment.folder) if not folder: continue new_attachment = Attachment(folder=folder, user_id=old_attachment.user_id, acl=old_attachment.acl, **{attr: getattr(old_attachment, attr) for attr in attrs}) if new_attachment.type == AttachmentType.file: old_file = old_attachment.file new_attachment.file = AttachmentFile( attachment=new_attachment, user_id=old_file.user_id, filename=old_file.filename, content_type=old_file.content_type ) with old_file.open() as fd: new_attachment.file.save(fd) db.session.add(new_attachment) db.session.flush()
def _clone_attachment_folder(self, old_folder, new_object): folder_attrs = get_simple_column_attrs(AttachmentFolder) attachment_attrs = (get_simple_column_attrs(Attachment) | {'user'}) - {'modified_dt'} folder = AttachmentFolder(object=new_object) folder.populate_from_attrs(old_folder, folder_attrs) folder.acl_entries = clone_principals(AttachmentFolderPrincipal, old_folder.acl_entries, self._event_role_map, self._regform_map) for old_attachment in old_folder.attachments: attachment = Attachment(folder=folder) attachment.populate_from_attrs(old_attachment, attachment_attrs) attachment.acl_entries = clone_principals( AttachmentPrincipal, old_attachment.acl_entries, self._event_role_map, self._regform_map) if attachment.type == AttachmentType.file: old_file = old_attachment.file attachment.file = AttachmentFile( attachment=attachment, user=old_file.user, filename=old_file.filename, content_type=old_file.content_type) with old_file.open() as fd: attachment.file.save(fd)
def create_contribution_from_abstract(abstract, contrib_session=None): from indico.modules.events.abstracts.settings import abstracts_settings event = abstract.event contrib_person_links = set() author_submission_rights = ( event.cfa.contribution_submitters == SubmissionRightsType.all) person_link_attrs = { '_title', 'address', 'affiliation', 'first_name', 'last_name', 'phone', 'author_type', 'is_speaker', 'display_order' } for abstract_person_link in abstract.person_links: link = ContributionPersonLink(person=abstract_person_link.person) link.populate_from_attrs(abstract_person_link, person_link_attrs) contrib_person_links.add(link) if contrib_session: duration = contrib_session.default_contribution_duration else: duration = contribution_settings.get(event, 'default_duration') custom_fields_data = { f'custom_{field_value.contribution_field.id}': field_value.data for field_value in abstract.field_values } contrib = create_contribution(event, { 'friendly_id': abstract.friendly_id, 'title': abstract.title, 'duration': duration, 'description': abstract.description, 'type': abstract.accepted_contrib_type, 'track': abstract.accepted_track, 'session': contrib_session, 'person_link_data': { link: (author_submission_rights or link.is_speaker) for link in contrib_person_links } }, custom_fields_data=custom_fields_data) if abstracts_settings.get(event, 'copy_attachments') and abstract.files: folder = AttachmentFolder.get_or_create_default(contrib) for abstract_file in abstract.files: attachment = Attachment(user=abstract.submitter, type=AttachmentType.file, folder=folder, title=abstract_file.filename) attachment.file = AttachmentFile( user=abstract.submitter, filename=abstract_file.filename, content_type=abstract_file.content_type) with abstract_file.open() as fd: attachment.file.save(fd) db.session.flush() return contrib
def _clone_attachment_folder(self, old_folder, new_object): folder_attrs = get_simple_column_attrs(AttachmentFolder) | {'acl'} attachment_attrs = (get_simple_column_attrs(Attachment) | {'user', 'acl'}) - {'modified_dt'} folder = AttachmentFolder(object=new_object) folder.populate_from_attrs(old_folder, folder_attrs) for old_attachment in old_folder.attachments: attachment = Attachment(folder=folder) attachment.populate_from_attrs(old_attachment, attachment_attrs) if attachment.type == AttachmentType.file: old_file = old_attachment.file attachment.file = AttachmentFile(attachment=attachment, user=old_file.user, filename=old_file.filename, content_type=old_file.content_type) with old_file.open() as fd: attachment.file.save(fd)
def clone(self, new_event, options): if 'attachments' not in options: return folder_mapping = {} for old_folder in self.find_folders(): new_folder = AttachmentFolder( title=old_folder.title, description=old_folder.description, is_default=old_folder.is_default, is_always_visible=old_folder.is_always_visible, protection_mode=old_folder.protection_mode, link_type=old_folder.link_type, event_id=new_event.id, session_id=old_folder.session_id, contribution_id=old_folder.contribution_id, subcontribution_id=old_folder.subcontribution_id ) if new_folder.linked_object is None: continue new_folder.acl = old_folder.acl db.session.add(new_folder) folder_mapping[old_folder] = new_folder for old_attachment in self.find_attachments(): folder = folder_mapping.get(old_attachment.folder) if not folder: continue new_attachment = Attachment( folder=folder, user_id=old_attachment.user_id, title=old_attachment.title, description=old_attachment.description, type=old_attachment.type, link_url=old_attachment.link_url, protection_mode=old_attachment.protection_mode, acl=old_attachment.acl ) if new_attachment.type == AttachmentType.file: old_file = old_attachment.file new_attachment.file = AttachmentFile( attachment=new_attachment, user_id=old_file.user_id, filename=old_file.filename, content_type=old_file.content_type ) with old_file.open() as fd: new_attachment.file.save(fd) db.session.add(new_attachment) db.session.flush()
def _process(self): form = AddAttachmentFilesForm(linked_object=self.object) if form.validate_on_submit(): files = form.files.data folder = form.folder.data or AttachmentFolder.get_or_create_default( linked_object=self.object) for f in files: filename = secure_client_filename(f.filename) attachment = Attachment( folder=folder, user=session.user, title=f.filename, type=AttachmentType.file, protection_mode=form.protection_mode.data) if attachment.is_self_protected: attachment.acl = form.acl.data content_type = mimetypes.guess_type( f.filename)[0] or f.mimetype or 'application/octet-stream' attachment.file = AttachmentFile(user=session.user, filename=filename, content_type=content_type) attachment.file.save(f.stream) db.session.add(attachment) db.session.flush() logger.info('Attachment %s uploaded by %s', attachment, session.user) signals.attachments.attachment_created.send(attachment, user=session.user) flash( ngettext("The attachment has been uploaded", "{count} attachments have been uploaded", len(files)).format(count=len(files)), 'success') return jsonify_data( attachment_list=_render_attachment_list(self.object)) return jsonify_template( 'attachments/upload.html', form=form, action=url_for('.upload', self.object), protection_message=_render_protection_message(self.object), folders_protection_info=_get_folders_protection_info(self.object), existing_attachment=None)
def _create_material(self, logs): folder = AttachmentFolder.find_first(object=self.event_new, is_default=False, title='Chat Logs', is_deleted=False) if folder is None: folder = AttachmentFolder(protection_mode=ProtectionMode.protected, linked_object=self.event_new, title='Chat Logs', description='Chat logs for this event') db.session.add(folder) filename = '{}.html'.format(secure_filename(self.material_name, 'logs')) attachment = Attachment(folder=folder, user=session.user, title=self.material_name, type=AttachmentType.file, description="Chat logs for the chat room '{}'".format(self.chatroom.name)) attachment.file = AttachmentFile(user=session.user, filename=filename, content_type='text/html') attachment.file.save(logs.encode('utf-8')) db.session.flush() signals.attachments.attachment_created.send(attachment, user=session.user) log_data = [ ('Range', 'Everything' if not self.date_filter else '{} - {}'.format(format_date(self.start_date), format_date(self.end_date))), ] self.event.log(EventLogRealm.management, EventLogKind.positive, 'Chat', 'Created material: {}'.format(filename), session.user, data=log_data)
def _create_material(self, logs): folder = AttachmentFolder.find_first(object=self.event, is_default=False, title='Chat Logs', is_deleted=False) if folder is None: folder = AttachmentFolder(protection_mode=ProtectionMode.protected, linked_object=self.event, title='Chat Logs', description='Chat logs for this event') db.session.add(folder) filename = '{}.html'.format(secure_filename(self.material_name, 'logs')) attachment = Attachment( folder=folder, user=session.user, title=self.material_name, type=AttachmentType.file, description="Chat logs for the chat room '{}'".format( self.chatroom.name)) attachment.file = AttachmentFile(user=session.user, filename=filename, content_type='text/html') attachment.file.save(logs.encode('utf-8')) db.session.flush() signals.attachments.attachment_created.send(attachment, user=session.user) log_data = [ ('Range', 'Everything' if not self.date_filter else '{} - {}'.format( format_date(self.start_date), format_date(self.end_date))), ] self.event.log(EventLogRealm.management, EventLogKind.positive, 'Chat', 'Created material: {}'.format(filename), session.user, data=log_data)
def create_contribution_from_abstract(abstract, contrib_session=None): from indico.modules.events.abstracts.settings import abstracts_settings event = abstract.event contrib_person_links = set() person_link_attrs = {'_title', 'address', 'affiliation', 'first_name', 'last_name', 'phone', 'author_type', 'is_speaker', 'display_order'} for abstract_person_link in abstract.person_links: link = ContributionPersonLink(person=abstract_person_link.person) link.populate_from_attrs(abstract_person_link, person_link_attrs) contrib_person_links.add(link) if contrib_session: duration = contrib_session.default_contribution_duration else: duration = contribution_settings.get(event, 'default_duration') custom_fields_data = {'custom_{}'.format(field_value.contribution_field.id): field_value.data for field_value in abstract.field_values} contrib = create_contribution(event, {'friendly_id': abstract.friendly_id, 'title': abstract.title, 'duration': duration, 'description': abstract.description, 'type': abstract.accepted_contrib_type, 'track': abstract.accepted_track, 'session': contrib_session, 'person_link_data': {link: True for link in contrib_person_links}}, custom_fields_data=custom_fields_data) if abstracts_settings.get(event, 'copy_attachments') and abstract.files: folder = AttachmentFolder.get_or_create_default(contrib) for abstract_file in abstract.files: attachment = Attachment(user=abstract.submitter, type=AttachmentType.file, folder=folder, title=abstract_file.filename) attachment.file = AttachmentFile(user=abstract.submitter, filename=abstract_file.filename, content_type=abstract_file.content_type) with abstract_file.open() as fd: attachment.file.save(fd) db.session.flush() return contrib
def _process(self): form = AddAttachmentFilesForm(linked_object=self.object) if form.validate_on_submit(): files = request.files.getlist('file') folder = form.folder.data or AttachmentFolder.get_or_create_default(linked_object=self.object) for f in files: filename = secure_filename(f.filename, 'attachment') attachment = Attachment(folder=folder, user=session.user, title=to_unicode(f.filename), type=AttachmentType.file, protection_mode=form.protection_mode.data) if attachment.is_self_protected: attachment.acl = form.acl.data content_type = mimetypes.guess_type(f.filename)[0] or f.mimetype or 'application/octet-stream' attachment.file = AttachmentFile(user=session.user, filename=filename, content_type=content_type) attachment.file.save(f.file) db.session.add(attachment) db.session.flush() logger.info('Attachment %s uploaded by %s', attachment, session.user) signals.attachments.attachment_created.send(attachment, user=session.user) flash(ngettext("The attachment has been uploaded", "{count} attachments have been uploaded", len(files)) .format(count=len(files)), 'success') return jsonify_data(attachment_list=_render_attachment_list(self.object)) return jsonify_template('attachments/upload.html', form=form, action=url_for('.upload', self.object), protection_message=_render_protection_message(self.object), folders_protection_info=_get_folders_protection_info(self.object))