mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 12:22:47 +00:00 
			
		
		
		
	Merge branch 'development' of gitlab.ub.uni-bielefeld.de:sfb1288inf/opaque into development
This commit is contained in:
		@@ -1,11 +1,18 @@
 | 
				
			|||||||
{% extends "nopaque.html.j2" %}
 | 
					{% extends "nopaque.html.j2" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% set headline = '<i class="material-icons left service" data-service="{service}" style="font-size: inherit;"></i>Job'.format(service=job.service) %}
 | 
					{% set headline = '<i class="left material-icons service" data-service="{service}" style="font-size: inherit;"></i>Job view'.format(service=job.service) %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block page_content %}
 | 
					{% block page_content %}
 | 
				
			||||||
<div class="col s12 m4">
 | 
					<div class="col s12">
 | 
				
			||||||
  <h3 id="title">{{ job.title }}</h3>
 | 
					  <div class="card">
 | 
				
			||||||
  <p id="description">{{ job.description }}</p>
 | 
					    <div class="card-content">
 | 
				
			||||||
 | 
					      <div class="row">
 | 
				
			||||||
 | 
					        <div class="col s8 m9 l10">
 | 
				
			||||||
 | 
					          <span class="card-title title">{{ job.title }}</span>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="col s4 m3 l2 right-align">
 | 
				
			||||||
 | 
					          <span class="chip status white-text"></span>
 | 
				
			||||||
          <div class="active preloader-wrapper small" id="progress-indicator">
 | 
					          <div class="active preloader-wrapper small" id="progress-indicator">
 | 
				
			||||||
            <div class="spinner-layer spinner-blue-only">
 | 
					            <div class="spinner-layer spinner-blue-only">
 | 
				
			||||||
              <div class="circle-clipper left">
 | 
					              <div class="circle-clipper left">
 | 
				
			||||||
@@ -19,112 +26,100 @@
 | 
				
			|||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
  <span class="chip status white-text" id="status"></span>
 | 
					        </div>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="col s12">
 | 
				
			||||||
 | 
					          <p class="description">{{ job.description }}</p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="col s12"> </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="col s12 m8">
 | 
					 | 
				
			||||||
  <ul class="collapsible expandable" id="job-list">
 | 
					 | 
				
			||||||
    <li class="active">
 | 
					 | 
				
			||||||
      <div class="collapsible-header">
 | 
					 | 
				
			||||||
        <i class="material-icons">input</i>Input files
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      <div class="collapsible-body">
 | 
					 | 
				
			||||||
        <table class="highlight responsive-table">
 | 
					 | 
				
			||||||
          <thead>
 | 
					 | 
				
			||||||
            <tr>
 | 
					 | 
				
			||||||
              <th>Filename</th>
 | 
					 | 
				
			||||||
              <th>Download</th>
 | 
					 | 
				
			||||||
            </tr>
 | 
					 | 
				
			||||||
          </thead>
 | 
					 | 
				
			||||||
          <tbody id="inputs">
 | 
					 | 
				
			||||||
            {% for input in job.inputs|sort(attribute="id", reverse=true) %}
 | 
					 | 
				
			||||||
            <tr>
 | 
					 | 
				
			||||||
              <td id="input-{{ input.id }}-filename">{{ input.filename }}</td>
 | 
					 | 
				
			||||||
              <td id="input-{{ input.id }}-download">
 | 
					 | 
				
			||||||
                <a class="waves-effect waves-light btn-small" download href="{{ url_for('jobs.download_job_input', job_id=job.id, job_input_id=input.id) }}">
 | 
					 | 
				
			||||||
                  <i class="material-icons">file_download</i>
 | 
					 | 
				
			||||||
                </a>
 | 
					 | 
				
			||||||
              </td>
 | 
					 | 
				
			||||||
            </tr>
 | 
					 | 
				
			||||||
            {% endfor %}
 | 
					 | 
				
			||||||
          </tbody>
 | 
					 | 
				
			||||||
        </table>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <div class="collapsible-header"><i class="material-icons">done</i>Result files</div>
 | 
					 | 
				
			||||||
      <div class="collapsible-body">
 | 
					 | 
				
			||||||
        <table class="highlight responsive-table">
 | 
					 | 
				
			||||||
          <thead>
 | 
					 | 
				
			||||||
            <tr>
 | 
					 | 
				
			||||||
              <th>Bundlename</th>
 | 
					 | 
				
			||||||
              <th>Download</th>
 | 
					 | 
				
			||||||
            </tr>
 | 
					 | 
				
			||||||
          </thead>
 | 
					 | 
				
			||||||
          <tbody id="results"></tbody>
 | 
					 | 
				
			||||||
        </table>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <div class="collapsible-header"><i class="material-icons">settings</i>Settings</div>
 | 
					 | 
				
			||||||
      <div class="collapsible-body">
 | 
					 | 
				
			||||||
        <div class="row">
 | 
					 | 
				
			||||||
          <div class="col s12">Chronometrics</div>
 | 
					 | 
				
			||||||
        <div class="col s12 m6">
 | 
					        <div class="col s12 m6">
 | 
				
			||||||
          <div class="input-field">
 | 
					          <div class="input-field">
 | 
				
			||||||
              <input disabled value="{{ job.creation_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}" id="creation-date" type="text" class="validate">
 | 
					            <input disabled id="creation-date" type="text" value="{{ job.creation_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}">
 | 
				
			||||||
            <label for="creation-date">Creation date</label>
 | 
					            <label for="creation-date">Creation date</label>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="col s12 m6">
 | 
					        <div class="col s12 m6">
 | 
				
			||||||
          <div class="input-field">
 | 
					          <div class="input-field">
 | 
				
			||||||
              <input disabled value="" id="end-date" type="text" class="validate">
 | 
					            <input class="end-date" disabled id="end-date" type="text" value="">
 | 
				
			||||||
            <label for="end-date">End date</label>
 | 
					            <label for="end-date">End date</label>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <div class="col s12">Ressource allocations</div>
 | 
					 | 
				
			||||||
          <div class="col s12 m6">
 | 
					 | 
				
			||||||
            <div class="input-field">
 | 
					 | 
				
			||||||
              <input disabled value="{{ job.mem_mb }}" id="mem-mb" type="text" class="validate">
 | 
					 | 
				
			||||||
              <label for="mem-mb">Memory</label>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
          <div class="col s12 m6">
 | 
					 | 
				
			||||||
            <div class="input-field">
 | 
					 | 
				
			||||||
              <input disabled value="{{ job.n_cores }}" id="n-cores" type="text" class="validate">
 | 
					 | 
				
			||||||
              <label for="n-cores">CPU cores</label>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          <div class="col s12">Service informations</div>
 | 
					 | 
				
			||||||
        <div class="col s12 m4">
 | 
					        <div class="col s12 m4">
 | 
				
			||||||
          <div class="input-field">
 | 
					          <div class="input-field">
 | 
				
			||||||
              <input disabled value="{{ job.service }}" id="service" type="text" class="validate">
 | 
					            <input disabled id="service" type="text" value="{{ job.service }}">
 | 
				
			||||||
            <label for="service">Service</label>
 | 
					            <label for="service">Service</label>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="col s12 m4">
 | 
					        <div class="col s12 m4">
 | 
				
			||||||
          <div class="input-field">
 | 
					          <div class="input-field">
 | 
				
			||||||
              <input disabled value="{{ job.service_args|e }}" id="service-args" type="text" class="validate">
 | 
					            <input disabled id="service-args" type="text" value="{{ job.service_args|e }}">
 | 
				
			||||||
            <label for="service-args">Service arguments</label>
 | 
					            <label for="service-args">Service arguments</label>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="col s12 m4">
 | 
					        <div class="col s12 m4">
 | 
				
			||||||
          <div class="input-field">
 | 
					          <div class="input-field">
 | 
				
			||||||
              <input disabled value="{{ job.service_version }}" id="service-version" type="text" class="validate">
 | 
					            <input disabled id="service-version" type="text" value="{{ job.service_version }}">
 | 
				
			||||||
            <label for="service-version">Service version</label>
 | 
					            <label for="service-version">Service version</label>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
          <div class="col s12 right-align">
 | 
					      </div>
 | 
				
			||||||
            <a href="#" class="waves-effect waves-light btn"><i class="material-icons left">settings</i>Export Parameters</a>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="card-action right-align">
 | 
				
			||||||
 | 
					      <a href="#" class="btn disabled waves-effect waves-light"><i class="material-icons left">settings</i>Export Parameters</a>
 | 
				
			||||||
      <a data-target="delete-job-modal" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete</a>
 | 
					      <a data-target="delete-job-modal" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete</a>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="col s12">
 | 
				
			||||||
 | 
					  <div class="card">
 | 
				
			||||||
 | 
					    <div class="card-content">
 | 
				
			||||||
 | 
					      <div class="row">
 | 
				
			||||||
 | 
					        <div class="col s12 m2">
 | 
				
			||||||
 | 
					          <span class="card-title"><i class="left material-icons" style="font-size: inherit;">input</i>Inputs</span>
 | 
				
			||||||
 | 
					          <p>Original input files.</p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col s12 m10">
 | 
				
			||||||
 | 
					          <div class="inputs row">
 | 
				
			||||||
 | 
					            {% for input in job.inputs %}
 | 
				
			||||||
 | 
					              <div class="col s12 m6">
 | 
				
			||||||
 | 
					                <a class="btn waves-effect waves-light" download href="{{ url_for('jobs.download_job_input', job_id=job.id, job_input_id=input.id) }}">
 | 
				
			||||||
 | 
					                  <i class="material-icons left">file_download</i>{{ input.filename }}
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            {% endfor %}
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="col s12">
 | 
				
			||||||
 | 
					  <div class="card">
 | 
				
			||||||
 | 
					    <div class="card-content">
 | 
				
			||||||
 | 
					      <div class="row">
 | 
				
			||||||
 | 
					        <div class="col s12 m2">
 | 
				
			||||||
 | 
					          <span class="card-title"><i class="left material-icons" style="font-size: inherit;">done</i>Results</span>
 | 
				
			||||||
 | 
					          <p>Processed result files.</p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col s12 m10">
 | 
				
			||||||
 | 
					          <div class="results row">
 | 
				
			||||||
 | 
					            <div class="show-if-only-child">
 | 
				
			||||||
 | 
					              <span class="card-title"><i class="left material-icons" style="font-size: inherit;">file_download</i>Nothing here...</span>
 | 
				
			||||||
 | 
					              <p>No results available (yet). Is the job already completed?</p>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -132,7 +127,7 @@
 | 
				
			|||||||
<div id="delete-job-modal" class="modal">
 | 
					<div id="delete-job-modal" class="modal">
 | 
				
			||||||
  <div class="modal-content">
 | 
					  <div class="modal-content">
 | 
				
			||||||
    <h4>Confirm deletion</h4>
 | 
					    <h4>Confirm deletion</h4>
 | 
				
			||||||
    <p>Do you really want to delete the job {{job.title}}? All associated files will be permanently deleted.</p>
 | 
					    <p>Do you really want to delete the job {{ job.title }}? All associated files will be permanently deleted.</p>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <div class="modal-footer">
 | 
					  <div class="modal-footer">
 | 
				
			||||||
    <a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a>
 | 
					    <a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a>
 | 
				
			||||||
@@ -159,14 +154,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      job = (this.foreignJobFlag ? nopaque.foreignUser.jobs[this.jobId]
 | 
					      job = (this.foreignJobFlag ? nopaque.foreignUser.jobs[this.jobId]
 | 
				
			||||||
                                 : nopaque.user.jobs[this.jobId]);
 | 
					                                 : nopaque.user.jobs[this.jobId]);
 | 
				
			||||||
 | 
					      // Results
 | 
				
			||||||
 | 
					      this.addResults(job.results);
 | 
				
			||||||
      // End date
 | 
					      // End date
 | 
				
			||||||
      this.setEndDate(job.end_date);
 | 
					      this.setEndDate(job.end_date);
 | 
				
			||||||
      // Status
 | 
					      // Status
 | 
				
			||||||
      this.setStatus(job.status);
 | 
					      this.setStatus(job.status);
 | 
				
			||||||
      // End date
 | 
					 | 
				
			||||||
      if (job.end_date) {this.setEndDate(job.end_date);}
 | 
					 | 
				
			||||||
      // Results
 | 
					 | 
				
			||||||
      if (job.results) {this.setResults(job.results);}
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _update(patch) {
 | 
					    _update(patch) {
 | 
				
			||||||
@@ -179,7 +172,7 @@
 | 
				
			|||||||
        switch(operation.op) {
 | 
					        switch(operation.op) {
 | 
				
			||||||
          case "add":
 | 
					          case "add":
 | 
				
			||||||
            if (pathArray[1] === "results") {
 | 
					            if (pathArray[1] === "results") {
 | 
				
			||||||
              this.setResults([operation.value]);
 | 
					              this.addResults([operation.value]);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
          case "delete":
 | 
					          case "delete":
 | 
				
			||||||
@@ -198,53 +191,63 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setEndDate(timestamp) {
 | 
					    addResults(results) {
 | 
				
			||||||
      let end_date;
 | 
					      let resultsArray, resultsElements, resultsHTML, resultType;
 | 
				
			||||||
 | 
					      resultsArray = Object.values(results);
 | 
				
			||||||
      if (timestamp === null) {
 | 
					 | 
				
			||||||
        end_date = "N.a.";
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        end_date = new Date(timestamp * 1000).toLocaleString("en-US");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      document.getElementById("end-date").value = end_date;
 | 
					 | 
				
			||||||
      M.updateTextFields();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    setResults(results) {
 | 
					 | 
				
			||||||
      let resultsArray, resultsElement;
 | 
					 | 
				
			||||||
      resultsArray = Object.values(results)
 | 
					 | 
				
			||||||
      resultsArray.sort(function (a, b) {
 | 
					      resultsArray.sort(function (a, b) {
 | 
				
			||||||
        if (a.filename < b.filename) {return -1;}
 | 
					        if (a.filename < b.filename) {return -1;}
 | 
				
			||||||
        if (a.filename > b.filename) {return 1;}
 | 
					        if (a.filename > b.filename) {return 1;}
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      resultsElement = document.getElementById("results");
 | 
					      resultsHTML = "";
 | 
				
			||||||
      for (let result of resultsArray) {
 | 
					      for (let result of resultsArray) {
 | 
				
			||||||
        resultsElement.insertAdjacentHTML(
 | 
					        if (result.filename.endsWith(".pdf.zip")) {
 | 
				
			||||||
          "beforeend",
 | 
					          resultType = "PDF";
 | 
				
			||||||
          `<tr>
 | 
					        } else if (result.filename.endsWith(".txt.zip")) {
 | 
				
			||||||
            <td>${result.filename}</td>
 | 
					          resultType = "TXT";
 | 
				
			||||||
            <td>
 | 
					        } else if (result.filename.endsWith(".vrt.zip")) {
 | 
				
			||||||
              <a class="btn-small waves-effect waves-light" download href="/jobs/${result.job_id}/results/${result.id}/download">
 | 
					          resultType = "VRT";
 | 
				
			||||||
                <i class="material-icons">file_download</i>
 | 
					        } else if (result.filename.endsWith(".xml.zip")) {
 | 
				
			||||||
 | 
					          resultType = "XML";
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          resultType = "ALL";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        resultsHTML += `<div class="col s4 m3 l2">
 | 
				
			||||||
 | 
					                          <a class="btn waves-effect waves-light" download href="/jobs/${result.job_id}/results/${result.id}/download">
 | 
				
			||||||
 | 
					                            <i class="material-icons left">file_download</i>${resultType}
 | 
				
			||||||
                          </a>
 | 
					                          </a>
 | 
				
			||||||
            </td>
 | 
					                        </div>`;
 | 
				
			||||||
          </tr>`
 | 
					      }
 | 
				
			||||||
        );
 | 
					      resultsElements = document.querySelectorAll(".results");
 | 
				
			||||||
 | 
					      for (let resultsElement of resultsElements) {
 | 
				
			||||||
 | 
					        resultsElement.innerHTML += resultsHTML;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setEndDate(timestamp) {
 | 
				
			||||||
 | 
					      let endDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (timestamp === null) {
 | 
				
			||||||
 | 
					        endDate = "N.a.";
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        endDate = new Date(timestamp * 1000).toLocaleString("en-US");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      document.getElementById("end-date").value = endDate;
 | 
				
			||||||
 | 
					      M.updateTextFields();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setStatus(status) {
 | 
					    setStatus(status) {
 | 
				
			||||||
      let progressIndicator, statusElement;
 | 
					      let progressIndicator, statusElements;
 | 
				
			||||||
      if (status === "complete") {
 | 
					      if (status === "complete") {
 | 
				
			||||||
        progressIndicator = document.getElementById("progress-indicator");
 | 
					        progressIndicator = document.getElementById("progress-indicator");
 | 
				
			||||||
        progressIndicator.classList.add("hide");
 | 
					        progressIndicator.classList.add("hide");
 | 
				
			||||||
        M.Collapsible.getInstance(document.getElementById("job-list")).open(1);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      statusElement = document.getElementById("status");
 | 
					      statusElements = document.querySelectorAll(".status");
 | 
				
			||||||
 | 
					      for (let statusElement of statusElements) {
 | 
				
			||||||
        statusElement.dataset.status = status;
 | 
					        statusElement.dataset.status = status;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  {% if job.creator == current_user %}
 | 
					  {% if job.creator == current_user %}
 | 
				
			||||||
  var informationUpdater = new InformationUpdater({{ job.id }}, false);
 | 
					  var informationUpdater = new InformationUpdater({{ job.id }}, false);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user