mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 04:12:45 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			1.1.1
			...
			access-pip
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2c709e65d0 | ||
| 
						 | 
					71c0ddf515 | ||
| 
						 | 
					5c395d1e06 | 
@@ -6,6 +6,7 @@ from app import db, hashids
 | 
				
			|||||||
from app.models import (
 | 
					from app.models import (
 | 
				
			||||||
    Job,
 | 
					    Job,
 | 
				
			||||||
    JobInput,
 | 
					    JobInput,
 | 
				
			||||||
 | 
					    JobResult,
 | 
				
			||||||
    JobStatus,
 | 
					    JobStatus,
 | 
				
			||||||
    TesseractOCRPipelineModel,
 | 
					    TesseractOCRPipelineModel,
 | 
				
			||||||
    SpaCyNLPPipelineModel
 | 
					    SpaCyNLPPipelineModel
 | 
				
			||||||
@@ -74,6 +75,8 @@ def tesseract_ocr_pipeline():
 | 
				
			|||||||
    version = request.args.get('version', service_manifest['latest_version'])
 | 
					    version = request.args.get('version', service_manifest['latest_version'])
 | 
				
			||||||
    if version not in service_manifest['versions']:
 | 
					    if version not in service_manifest['versions']:
 | 
				
			||||||
        abort(404)
 | 
					        abort(404)
 | 
				
			||||||
 | 
					    job_results = JobResult.query.all()
 | 
				
			||||||
 | 
					    choosable_job_ids = [job_result.job.hashid for job_result in job_results if job_result.job.service == "file-setup-pipeline" and job_result.filename.endswith('.pdf')]
 | 
				
			||||||
    form = CreateTesseractOCRPipelineJobForm(prefix='create-job-form', version=version)
 | 
					    form = CreateTesseractOCRPipelineJobForm(prefix='create-job-form', version=version)
 | 
				
			||||||
    if form.is_submitted():
 | 
					    if form.is_submitted():
 | 
				
			||||||
        if not form.validate():
 | 
					        if not form.validate():
 | 
				
			||||||
@@ -111,6 +114,7 @@ def tesseract_ocr_pipeline():
 | 
				
			|||||||
    return render_template(
 | 
					    return render_template(
 | 
				
			||||||
        'services/tesseract_ocr_pipeline.html.j2',
 | 
					        'services/tesseract_ocr_pipeline.html.j2',
 | 
				
			||||||
        title=service_manifest['name'],
 | 
					        title=service_manifest['name'],
 | 
				
			||||||
 | 
					        choosable_job_ids=choosable_job_ids,
 | 
				
			||||||
        form=form,
 | 
					        form=form,
 | 
				
			||||||
        tesseract_ocr_pipeline_models=tesseract_ocr_pipeline_models,
 | 
					        tesseract_ocr_pipeline_models=tesseract_ocr_pipeline_models,
 | 
				
			||||||
        user_tesseract_ocr_pipeline_models_count=user_tesseract_ocr_pipeline_models_count
 | 
					        user_tesseract_ocr_pipeline_models_count=user_tesseract_ocr_pipeline_models_count
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										137
									
								
								app/static/js/resource-lists/job-output-list.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								app/static/js/resource-lists/job-output-list.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
				
			|||||||
 | 
					nopaque.resource_lists.JobOutputList = class JobOutputList extends nopaque.resource_lists.ResourceList {
 | 
				
			||||||
 | 
					  static htmlClass = 'job-output-list';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(listContainerElement, options = {}) {
 | 
				
			||||||
 | 
					    super(listContainerElement, options);
 | 
				
			||||||
 | 
					    this.listjs.list.addEventListener('click', (event) => {this.onClick(event)});
 | 
				
			||||||
 | 
					    this.isInitialized = false;
 | 
				
			||||||
 | 
					    this.userId = listContainerElement.dataset.userId;
 | 
				
			||||||
 | 
					    this.jobOutput = listContainerElement.dataset.jobOutput;
 | 
				
			||||||
 | 
					    this.jobIds = listContainerElement.dataset.jobIds;
 | 
				
			||||||
 | 
					    if (this.userId === undefined) {return;}
 | 
				
			||||||
 | 
					    app.subscribeUser(this.userId).then((response) => {
 | 
				
			||||||
 | 
					      app.socket.on('PATCH', (patch) => {
 | 
				
			||||||
 | 
					        if (this.isInitialized) {this.onPatch(patch);}
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    app.getUser(this.userId).then((user) => {
 | 
				
			||||||
 | 
					      let jobIds = JSON.parse(this.jobIds.replace(/'/g, '"'));
 | 
				
			||||||
 | 
					      let job_results = {};
 | 
				
			||||||
 | 
					      for (let jobId of jobIds) {
 | 
				
			||||||
 | 
					        for (let jobResult of Object.values(user.jobs[jobId].results)) {
 | 
				
			||||||
 | 
					          if (jobResult.mimetype === 'application/pdf') {
 | 
				
			||||||
 | 
					            job_results[jobResult.id] = jobResult;
 | 
				
			||||||
 | 
					            job_results[jobResult.id].description = user.jobs[jobId].description;
 | 
				
			||||||
 | 
					            job_results[jobResult.id].title = user.jobs[jobId].title;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      this.add(Object.values(job_results));
 | 
				
			||||||
 | 
					      this.isInitialized = true;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get item() {
 | 
				
			||||||
 | 
					    return `
 | 
				
			||||||
 | 
					      <tr class="list-item clickable hoverable">
 | 
				
			||||||
 | 
					        <td><span class="title"></span></td>
 | 
				
			||||||
 | 
					        <td><span class="description"></span></td>
 | 
				
			||||||
 | 
					        <td><span class="filename"></span></td>
 | 
				
			||||||
 | 
					        <td class="right-align">
 | 
				
			||||||
 | 
					          <a class="list-action-trigger btn-flat waves-effect waves-light" data-list-action="add"><i class="material-icons">add</i></a>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					      </tr>
 | 
				
			||||||
 | 
					    `.trim();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get valueNames() {
 | 
				
			||||||
 | 
					    return [
 | 
				
			||||||
 | 
					      {data: ['id']},
 | 
				
			||||||
 | 
					      {data: ['creation-date']},
 | 
				
			||||||
 | 
					      'title',
 | 
				
			||||||
 | 
					      'description',
 | 
				
			||||||
 | 
					      'filename'
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  initListContainerElement() {
 | 
				
			||||||
 | 
					    if (!this.listContainerElement.hasAttribute('id')) {
 | 
				
			||||||
 | 
					      this.listContainerElement.id = nopaque.Utils.generateElementId('job-output-list-');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    let listSearchElementId = nopaque.Utils.generateElementId(`${this.listContainerElement.id}-search-`);
 | 
				
			||||||
 | 
					    this.listContainerElement.innerHTML = `
 | 
				
			||||||
 | 
					      <div class="input-field">
 | 
				
			||||||
 | 
					        <i class="material-icons prefix">search</i>
 | 
				
			||||||
 | 
					        <input id="${listSearchElementId}" class="search" type="text"></input>
 | 
				
			||||||
 | 
					        <label for="${listSearchElementId}">Search job output</label>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <table>
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					          <tr>
 | 
				
			||||||
 | 
					            <th>Title</th>
 | 
				
			||||||
 | 
					            <th>Description</th>
 | 
				
			||||||
 | 
					            <th>Filename</th>
 | 
				
			||||||
 | 
					            <th></th>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody class="list"></tbody>
 | 
				
			||||||
 | 
					      </table>
 | 
				
			||||||
 | 
					      <ul class="pagination"></ul>
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mapResourceToValue(jobOutput) {
 | 
				
			||||||
 | 
					    console.log(jobOutput);
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      'id': jobOutput.id,
 | 
				
			||||||
 | 
					      'creation-date': jobOutput.creationDate,
 | 
				
			||||||
 | 
					      'title': jobOutput.title,
 | 
				
			||||||
 | 
					      'description': jobOutput.description,
 | 
				
			||||||
 | 
					      'filename': jobOutput.filename
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sort() {
 | 
				
			||||||
 | 
					    this.listjs.sort('title', {order: 'asc'});
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onClick(event) {
 | 
				
			||||||
 | 
					    let listItemElement = event.target.closest('.list-item[data-id]');
 | 
				
			||||||
 | 
					    if (listItemElement === null) {return;}
 | 
				
			||||||
 | 
					    let itemId = listItemElement.dataset.id;
 | 
				
			||||||
 | 
					    let listActionElement = event.target.closest('.list-action-trigger[data-list-action]');
 | 
				
			||||||
 | 
					    let listAction = listActionElement === null ? 'add' : listActionElement.dataset.listAction;
 | 
				
			||||||
 | 
					    switch (listAction) {
 | 
				
			||||||
 | 
					      case 'add': {
 | 
				
			||||||
 | 
					        listActionElement.querySelector('i').textContent = 'done';
 | 
				
			||||||
 | 
					        listActionElement.dataset.listAction = 'remove';
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      case 'remove': {
 | 
				
			||||||
 | 
					        listActionElement.querySelector('i').textContent = 'add';
 | 
				
			||||||
 | 
					        listActionElement.dataset.listAction = 'add';
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      default: {
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // onPatch(patch) {
 | 
				
			||||||
 | 
					  //   let re = new RegExp(`^/users/${this.userId}/jobs/${this.jobId}/results/([A-Za-z0-9]*)`);
 | 
				
			||||||
 | 
					  //   let filteredPatch = patch.filter(operation => re.test(operation.path));
 | 
				
			||||||
 | 
					  //   for (let operation of filteredPatch) {
 | 
				
			||||||
 | 
					  //     switch(operation.op) {
 | 
				
			||||||
 | 
					  //       case 'add': {
 | 
				
			||||||
 | 
					  //         let re = new RegExp(`^/users/${this.userId}/jobs/${this.jobId}/results/([A-Za-z0-9]*)$`);
 | 
				
			||||||
 | 
					  //         if (re.test(operation.path)) {this.add(operation.value);}
 | 
				
			||||||
 | 
					  //         break;
 | 
				
			||||||
 | 
					  //       }
 | 
				
			||||||
 | 
					  //       default: {
 | 
				
			||||||
 | 
					  //         break;
 | 
				
			||||||
 | 
					  //       }
 | 
				
			||||||
 | 
					  //     }
 | 
				
			||||||
 | 
					  //   }
 | 
				
			||||||
 | 
					  // }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -52,6 +52,7 @@
 | 
				
			|||||||
  'js/resource-lists/job-input-list.js',
 | 
					  'js/resource-lists/job-input-list.js',
 | 
				
			||||||
  'js/resource-lists/job-list.js',
 | 
					  'js/resource-lists/job-list.js',
 | 
				
			||||||
  'js/resource-lists/job-result-list.js',
 | 
					  'js/resource-lists/job-result-list.js',
 | 
				
			||||||
 | 
					  'js/resource-lists/job-output-list.js',
 | 
				
			||||||
  'js/resource-lists/public-corpus-list.js',
 | 
					  'js/resource-lists/public-corpus-list.js',
 | 
				
			||||||
  'js/resource-lists/public-user-list.js',
 | 
					  'js/resource-lists/public-user-list.js',
 | 
				
			||||||
  'js/resource-lists/spacy-nlp-pipeline-model-list.js',
 | 
					  'js/resource-lists/spacy-nlp-pipeline-model-list.js',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <div class="col s12">
 | 
					    <div class="col s12">
 | 
				
			||||||
      <h2>Submit a job</h2>
 | 
					      <h2>Submit a job</h2>
 | 
				
			||||||
 | 
					      <div class="card">
 | 
				
			||||||
 | 
					        <div class="card-content">
 | 
				
			||||||
 | 
					          <p>Add an existing file from your workflow or add a new one below.</p>
 | 
				
			||||||
 | 
					          <div class="job-output-list" data-user-id="{{ current_user.hashid}}" data-job-ids="{{ choosable_job_ids }}"></div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="card-action right-align">
 | 
				
			||||||
 | 
					          <a class="waves-effect waves-light btn"><i class="material-icons right">send</i>Submit</a>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
      <div class="card">
 | 
					      <div class="card">
 | 
				
			||||||
        <form class="create-job-form" enctype="multipart/form-data" method="POST">
 | 
					        <form class="create-job-form" enctype="multipart/form-data" method="POST">
 | 
				
			||||||
          <div class="card-content">
 | 
					          <div class="card-content">
 | 
				
			||||||
@@ -51,6 +60,8 @@
 | 
				
			|||||||
              <div class="col s12 l5">
 | 
					              <div class="col s12 l5">
 | 
				
			||||||
                {{ wtf.render_field(form.pdf, accept='application/pdf', placeholder='Choose a PDF file') }}
 | 
					                {{ wtf.render_field(form.pdf, accept='application/pdf', placeholder='Choose a PDF file') }}
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="row">
 | 
				
			||||||
              <div class="col s12 l4">
 | 
					              <div class="col s12 l4">
 | 
				
			||||||
                <div class="input-field">
 | 
					                <div class="input-field">
 | 
				
			||||||
                  <i class="material-icons prefix">language</i>
 | 
					                  <i class="material-icons prefix">language</i>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user