def sync_imanage_config(self, imanage_config: IManageConfig): auth_token = imanage_config.login() # Step 1: Find documents about which we don't know and store their ids in IManageDocument table imanage_docs = imanage_config.search_documents(auth_token) self.log_info('Found {0} documents at imanage server'.format(len(imanage_docs) if imanage_docs else None)) with connection.cursor() as cursor: for docs_chunk in chunks(imanage_docs, 50): # type: List[Dict] insert_clause = 'insert into "{table_name}" ' \ '(imanage_config_id, imanage_doc_id, imanage_doc_number, imanage_doc_data, ' \ ' import_problem) ' \ 'values {values_place_holders} on conflict do nothing'.format( table_name=IManageDocument._meta.db_table, values_place_holders=', '.join(['(%s, %s, %s, %s, %s)'] * len(docs_chunk))) params = list(chain(*[(imanage_config.pk, str(doc['id']), str(doc.get('document_number')) if 'document_number' in doc else None, json.dumps(doc), False) for doc in docs_chunk])) cursor.execute(insert_clause, params) # Step 2. Get iManage doc ids for which we don't have Contraxsuite Documents created # Further we can add re-reading them from iManage by some logic args = [(imanage_config.id, imanage_doc_id) for imanage_doc_id in IManageDocument.objects.filter(imanage_config=imanage_config, import_problem=False, document__isnull=True).values_list('imanage_doc_id', flat=True)] imanage_config.last_sync_start = timezone.now() imanage_config.save(update_fields=['last_sync_start']) self.log_info('Found {0} new imanage documents for which we do not have Contraxsute documents' .format(len(args) if args else 0)) self.run_sub_tasks('Sync iManage documents for config: {0}'.format(imanage_config.code), IManageSynchronization.sync_imanage_document, args)
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=ErrorList, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None): super().__init__(data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted, instance, use_required_attribute) eval_locals = IManageConfig.prepare_eval_locals( {}, log=ErrorCollectingLogger()) self.fields[ 'project_resolving_code'].help_text = '''Python code returning correct Project to put the imported document. Executed with Python exec. Should set "result" variable to the value it returns (e.g. contain "result = 123" as its last line). Local context: {0}'''.format(eval_locals) self.fields[ 'assignee_resolving_code'].help_text = '''Python code returning correct User to assign the imported document to. Executed with Python exec. Should set "result" variable to the value it returns (e.g. contain "result = 123" as its last line). Local context: {0}'''.format( eval_locals)
def clean(self): super().clean() example_doc = {'id': '12345', 'document_number': '67890'} eval_locals = IManageConfig.prepare_eval_locals( example_doc, log=ErrorCollectingLogger()) password = self.cleaned_data.get('auth_password') if password is False and self.instance and self.instance.pk: conf = IManageConfig.objects.filter( pk=self.instance.pk).first() # type: IManageConfig if conf: self.cleaned_data['auth_password'] = conf.auth_password assignee = self.cleaned_data['assignee'] project = self.cleaned_data['project'] assignee_code = self.cleaned_data['assignee_resolving_code'] project_code = self.cleaned_data['project_resolving_code'] if project and project_code: self.add_error( 'project', 'Both project and project resolving code specified. ' 'Please use only one of the options.') if assignee and assignee_code: self.add_error( 'assignee', 'Both assignee and assignee resolving code specified.' 'Please use only one of the options.') if assignee_code: try: test_value = exec_script( 'assignee resolving on a test document', assignee_code, eval_locals) if test_value is not None and not isinstance(test_value, User): raise RuntimeError( 'Assignee resolving script must return either None or a User.' ) except RuntimeError as err: self.add_error('assignee_resolving_code', str(err).split('\n')) if project_code: try: test_value = exec_script('test project resolving', project_code, eval_locals) if not isinstance(test_value, Project): raise RuntimeError( 'Project resolving script must return either a Project.' ) except RuntimeError as err: self.add_error('project_resolving_code', str(err).split('\n'))