mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 04:12:45 +00:00 
			
		
		
		
	Clean up corpus analysis and add new features
This commit is contained in:
		@@ -43,7 +43,7 @@ def corpus_analysis_query(query):
 | 
			
		||||
            response = {'code': 1}
 | 
			
		||||
            socketio.emit('corpus_analysis_query', response, room=request.sid)
 | 
			
		||||
    else:
 | 
			
		||||
        chunk_size = 500
 | 
			
		||||
        chunk_size = 100
 | 
			
		||||
        chunk_start = 0
 | 
			
		||||
        context = 100
 | 
			
		||||
        while chunk_start < client.match_count:
 | 
			
		||||
 
 | 
			
		||||
@@ -7,12 +7,20 @@ function getQueryData(queryFormElement) {
 | 
			
		||||
  queryData = {"context": formData.get("context"), // global declaration
 | 
			
		||||
               "hits_per_page": formData.get("hits_per_page"),
 | 
			
		||||
               "query": formData.get("query")};
 | 
			
		||||
  console.log("Query data:", queryData);
 | 
			
		||||
  return queryData
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Function to send a query to the CQP server using queryData gatherd with getQueryData
 | 
			
		||||
function sendQuery(event) {
 | 
			
		||||
 | 
			
		||||
  // checks if one query has been finished before
 | 
			
		||||
  // if true result download will be disabled again until query is finished
 | 
			
		||||
  // also shows progress bar again
 | 
			
		||||
  if (queryFinished) {
 | 
			
		||||
    exportQueryResultsElement.classList.add("disabled");
 | 
			
		||||
    queryResultsDeterminateElement.parentNode.parentNode.classList.remove("hide");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  event.preventDefault();
 | 
			
		||||
  queryData = getQueryData(queryFormElement);
 | 
			
		||||
  nopaque.socket.emit("corpus_analysis_query", queryData.query);
 | 
			
		||||
@@ -52,6 +60,7 @@ function sendQuery(event) {
 | 
			
		||||
 | 
			
		||||
// Function used when CQP server sends back the query results using socketio
 | 
			
		||||
function recieveResults(response) {
 | 
			
		||||
 | 
			
		||||
  // ERROR code checking
 | 
			
		||||
  if (response["code"] === 0) {
 | 
			
		||||
    console.log("[SUCCESS] corpus_analysis_init");
 | 
			
		||||
@@ -87,6 +96,7 @@ function recieveResults(response) {
 | 
			
		||||
  // Some hiding and showing of loading animations
 | 
			
		||||
  queryLoadingElement.classList.add("hide");
 | 
			
		||||
  queryResultsTableElement.classList.remove("hide");
 | 
			
		||||
  let queryResultsElement = document.getElementById("query-results");
 | 
			
		||||
  queryResultsElement.innerHTML = "";
 | 
			
		||||
 | 
			
		||||
  // check if query has any results
 | 
			
		||||
@@ -100,7 +110,7 @@ function recieveResults(response) {
 | 
			
		||||
  match_count = chunk["match_count"];
 | 
			
		||||
  let count_corpus_files = Object.keys(result["text_lookup"]).length;
 | 
			
		||||
 | 
			
		||||
  var resultItems = []; // list for holding every row item
 | 
			
		||||
  let resultItems = []; // list for holding every row item
 | 
			
		||||
  // get infos for full match row
 | 
			
		||||
  for (let [index, match] of chunk["matches"].entries()) {
 | 
			
		||||
    resultItems.push({...match, ...{"index": index + result["loaded_match_count"]}});
 | 
			
		||||
@@ -114,12 +124,43 @@ function recieveResults(response) {
 | 
			
		||||
  });
 | 
			
		||||
  result["loaded_match_count"] += Object.keys(chunk["matches"]).length;
 | 
			
		||||
  console.log("After current match count", result["loaded_match_count"]);
 | 
			
		||||
  let queryResultsMetadataElement = document.getElementById("query-results-metadata");
 | 
			
		||||
  queryResultsMetadataElement.innerHTML = `<p>The query resulted in a total of ${chunk["match_count"]} matches. </p> <p> ${result["loaded_match_count"]} of ${result["match_count"]} matches in ${count_corpus_files} corpus files have been loaded.</p>`;
 | 
			
		||||
  queryResultsMetadataElement.appendChild(exportQueryResults);
 | 
			
		||||
  exportQueryResults.classList.remove("hide");
 | 
			
		||||
  let queryResultsInteractionElement = document.getElementById("interaction-elements");
 | 
			
		||||
  queryResultsInteractionElement.appendChild(exportQueryResultsElement);
 | 
			
		||||
  let queryResultsHeadElement = document.getElementById("query-results-head");
 | 
			
		||||
  queryResultsHeadElement.classList.remove("hide");
 | 
			
		||||
  queryStatus = result["loaded_match_count"] / result["match_count"] * 100;
 | 
			
		||||
  console.log(queryStatus);
 | 
			
		||||
  queryResultsDeterminateElement.style["width"] = `${queryStatus}%`;
 | 
			
		||||
  console.log(queryResultsDeterminateElement.style["width"]);
 | 
			
		||||
  // enable download and inspect when query is finished
 | 
			
		||||
  // also sets queryFinished to true
 | 
			
		||||
  if (queryStatus === 100) {
 | 
			
		||||
    queryResultsDeterminateElement.parentNode.parentNode.classList.add("hide");
 | 
			
		||||
    exportQueryResultsElement.classList.remove("disabled");
 | 
			
		||||
    let inspectBtnElements = document.getElementsByClassName("inspect");
 | 
			
		||||
    for (let inspectBtn of inspectBtnElements) {
 | 
			
		||||
      inspectBtn.classList.remove("disabled");
 | 
			
		||||
    queryFinished = true; // global declaration to set downlaod button and inspects buttons back to disabled for new queries
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Function to inspect one match, to show more details
 | 
			
		||||
 | 
			
		||||
// ### Functions to inspect one match, to show more details ###
 | 
			
		||||
 | 
			
		||||
// activate inspect buttons if queryFinished is true
 | 
			
		||||
function activateInspect() {
 | 
			
		||||
  if (queryFinished) {
 | 
			
		||||
    let inspectBtnElements = document.getElementsByClassName("inspect");
 | 
			
		||||
    for (let inspectBtn of inspectBtnElements) {
 | 
			
		||||
      inspectBtn.classList.remove("disabled");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//gets result cpos infos for one dataIndex to send back to the server
 | 
			
		||||
function inspect(dataIndex) {
 | 
			
		||||
  console.log("Inspect!");
 | 
			
		||||
  console.log(result["matches"][dataIndex]["hit"]);
 | 
			
		||||
@@ -127,6 +168,38 @@ function inspect(dataIndex) {
 | 
			
		||||
  nopaque.socket.emit("inspect_match", {"cpos": result["matches"][dataIndex]["hit"]});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showMatchContext(message) {
 | 
			
		||||
  console.log("### match_context ###");
 | 
			
		||||
  console.log("Incoming data:", message);
 | 
			
		||||
  contextResultsElement.innerHTML = "<p> </p>";
 | 
			
		||||
  document.getElementById("context-modal-loading").classList.add("hide");
 | 
			
		||||
  document.getElementById("context-modal-ready").classList.remove("hide");
 | 
			
		||||
 | 
			
		||||
  let sentenceElement, token, tokenElement;
 | 
			
		||||
 | 
			
		||||
  for (let [key, value] of Object.entries(message['context_s_cpos'])) {
 | 
			
		||||
    sentenceElement = document.createElement("p");
 | 
			
		||||
    for (cpos of value) {
 | 
			
		||||
      token = message["cpos_lookup"][cpos];
 | 
			
		||||
      tokenElement = document.createElement("span");
 | 
			
		||||
      tokenElement.classList.add("token");
 | 
			
		||||
      if (message["match_cpos_list"].includes(cpos)) {
 | 
			
		||||
        tokenElement.classList.add("bold");
 | 
			
		||||
        tokenElement.classList.add("light-green");
 | 
			
		||||
      }
 | 
			
		||||
      tokenElement.dataset.cpos = cpos;
 | 
			
		||||
      tokenElement.innerText = token["word"];
 | 
			
		||||
      var expertModeSwitchElement = document.getElementById("expert-mode-switch");
 | 
			
		||||
      if (expertModeSwitchElement.checked) {
 | 
			
		||||
        expertModeOn([tokenElement], message);
 | 
			
		||||
      }
 | 
			
		||||
      sentenceElement.append(tokenElement);
 | 
			
		||||
      sentenceElement.append(document.createTextNode(" "));
 | 
			
		||||
    }
 | 
			
		||||
    contextResultsElement.append(sentenceElement);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ### Display options changing live how the matches are being displayed ###
 | 
			
		||||
 | 
			
		||||
// Event function that changes the shown hits per page.
 | 
			
		||||
@@ -151,6 +224,7 @@ function changeContext(event) {
 | 
			
		||||
      }
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
      console.log(e);
 | 
			
		||||
      console.log("This error is expected.");
 | 
			
		||||
  } finally {
 | 
			
		||||
      var contextPerItemElement = document.getElementById("context");
 | 
			
		||||
      newValue = contextPerItemElement.value;
 | 
			
		||||
 
 | 
			
		||||
@@ -188,39 +188,6 @@ nopaque.socket.on("foreign_jobs_update", function(msg) {
 | 
			
		||||
  for (let subscriber of nopaque.foreignJobsSubscribers) {subscriber._update(patch);}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// get context of one match if inspected
 | 
			
		||||
nopaque.socket.on("match_context", function(message) {
 | 
			
		||||
  console.log("### match_context ###");
 | 
			
		||||
  console.log("Incoming data:", message);
 | 
			
		||||
  contextResultsElement.innerHTML = "<p> </p>";
 | 
			
		||||
  document.getElementById("context-modal-loading").classList.add("hide");
 | 
			
		||||
  document.getElementById("context-modal-ready").classList.remove("hide");
 | 
			
		||||
 | 
			
		||||
  let sentenceElement, token, tokenElement;
 | 
			
		||||
 | 
			
		||||
  for (let [key, value] of Object.entries(message['context_s_cpos'])) {
 | 
			
		||||
    sentenceElement = document.createElement("p");
 | 
			
		||||
    for (cpos of value) {
 | 
			
		||||
      token = message["cpos_lookup"][cpos];
 | 
			
		||||
      tokenElement = document.createElement("span");
 | 
			
		||||
      tokenElement.classList.add("token");
 | 
			
		||||
      if (message["match_cpos_list"].includes(cpos)) {
 | 
			
		||||
        tokenElement.classList.add("bold");
 | 
			
		||||
        tokenElement.classList.add("light-green");
 | 
			
		||||
      }
 | 
			
		||||
      tokenElement.dataset.cpos = cpos;
 | 
			
		||||
      tokenElement.innerText = token["word"];
 | 
			
		||||
      var expertModeSwitchElement = document.getElementById("expert-mode-switch");
 | 
			
		||||
      if (expertModeSwitchElement.checked) {
 | 
			
		||||
        expertModeOn([tokenElement], message);
 | 
			
		||||
      }
 | 
			
		||||
      sentenceElement.append(tokenElement);
 | 
			
		||||
      sentenceElement.append(document.createTextNode(" "));
 | 
			
		||||
    }
 | 
			
		||||
    contextResultsElement.append(sentenceElement);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
document.addEventListener("DOMContentLoaded", function() {
 | 
			
		||||
  nopaque.Workarounds.apply();
 | 
			
		||||
  M.AutoInit();
 | 
			
		||||
 
 | 
			
		||||
@@ -152,7 +152,7 @@ class ResultList extends List {
 | 
			
		||||
      textTitles.add(chunk["text_lookup"][token["text"]]["title"]);
 | 
			
		||||
      // add button to trigger more context to every match td
 | 
			
		||||
      var inspectBtn = document.createElement("a");
 | 
			
		||||
      inspectBtn.setAttribute("class", "btn-floating btn-flat waves-effect waves-light grey right inspect");
 | 
			
		||||
      inspectBtn.setAttribute("class", "btn-floating btn-flat waves-effect waves-light grey right inspect disabled");
 | 
			
		||||
      inspectBtn.innerHTML = '<i class="material-icons">search</i>';
 | 
			
		||||
      inspectBtn.onclick = function() {inspect(values["index"])};
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -157,18 +157,25 @@ server side -->
 | 
			
		||||
  <div class="card">
 | 
			
		||||
    <div class="card-content" id="result-list" style="overflow: hidden;">
 | 
			
		||||
      <span class="card-title">Query Results</span>
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col s12" id="query-results-metadata">
 | 
			
		||||
      <div class="hide" id="query-results-head">
 | 
			
		||||
      <div class="col s12 m6 l6">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div class="col s10" id="query-results-metadata"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col s12">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div class="progress">
 | 
			
		||||
            <div class="determinate" style="width: 70%"></div>
 | 
			
		||||
            <div class="determinate"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <p> </p>
 | 
			
		||||
          <button id="export-query-results" class="waves-effect waves-light btn-small right hide" type="submit">Export Results<i class="material-icons right">file_download</i></button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col s12 m6 l6">
 | 
			
		||||
        <div class="row" id="interaction-elements">
 | 
			
		||||
          <button id="export-query-results" class="waves-effect waves-light btn-small right disabled" type="submit">Export Results<i class="material-icons right">file_download</i></button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      </div>
 | 
			
		||||
<!-- table showing the query results -->
 | 
			
		||||
    <div class="col s12">
 | 
			
		||||
      <ul class="pagination paginationTop"></ul>
 | 
			
		||||
      <table class="responsive-table highlight">
 | 
			
		||||
        <thead>
 | 
			
		||||
@@ -184,6 +191,8 @@ server side -->
 | 
			
		||||
        </tbody>
 | 
			
		||||
      </table>
 | 
			
		||||
      <ul class="pagination paginationBottom"></ul>
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -222,10 +231,24 @@ server side -->
 | 
			
		||||
<script src="{{ url_for('static', filename='js/nopaque.analyse_corpus.js') }}"></script>
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
 // Initialising some modals for later usage
 | 
			
		||||
  // ### Initiating global variables ###
 | 
			
		||||
  // create some globa modals for later usage
 | 
			
		||||
  var contextModal;
 | 
			
		||||
  var loadingModal;
 | 
			
		||||
  var exportModal;
 | 
			
		||||
  // create some global variables
 | 
			
		||||
  var hitsPerPage;
 | 
			
		||||
  var result;
 | 
			
		||||
  var resultList;
 | 
			
		||||
  var queryFinished;
 | 
			
		||||
  // create some global elements
 | 
			
		||||
  var exportQueryResultsElement;
 | 
			
		||||
  var queryResultsDeterminateElement;
 | 
			
		||||
  var queryResultsTableElement;
 | 
			
		||||
  var queryLoadingElement;
 | 
			
		||||
 | 
			
		||||
  var contextResultsElement;
 | 
			
		||||
 | 
			
		||||
  document.addEventListener("DOMContentLoaded", function() {
 | 
			
		||||
    contextModal = M.Modal.init(document.getElementById("context-modal"),
 | 
			
		||||
                                {"onCloseEnd": function() {
 | 
			
		||||
@@ -250,26 +273,24 @@ server side -->
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // getting some HTML-elements to use/hide/remove/show or add some other elements to them
 | 
			
		||||
  var queryResultsElement = document.getElementById("query-results");
 | 
			
		||||
  var queryResultsMetadataElement = document.getElementById("query-results-metadata");
 | 
			
		||||
  var exportQueryResults = document.getElementById("export-query-results");
 | 
			
		||||
  exportQueryResults.onclick = function() {
 | 
			
		||||
    exportModal.open();
 | 
			
		||||
  };
 | 
			
		||||
  var contextResultsElement = document.getElementById("context-results");
 | 
			
		||||
  var queryLoadingElement = document.getElementById("getting-query-results");
 | 
			
		||||
  // getting some HTML-elements to use/hide/remove/show or add some other
 | 
			
		||||
  // elements to them.
 | 
			
		||||
  // These elements will be used inside functions in nopaque.analyse_corpus.js
 | 
			
		||||
  var queryResultsDeterminateElement = document.getElementsByClassName("determinate")[0];
 | 
			
		||||
  var queryResultsTableElement = document.getElementById("recieved-query-results");
 | 
			
		||||
  ;
 | 
			
		||||
  // create some global variables
 | 
			
		||||
  var hitsPerPage;
 | 
			
		||||
  var result;
 | 
			
		||||
  var resultList;
 | 
			
		||||
  var queryLoadingElement = document.getElementById("getting-query-results");
 | 
			
		||||
  var exportQueryResultsElement = document.getElementById("export-query-results");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  var contextResultsElement = document.getElementById("context-results");
 | 
			
		||||
 | 
			
		||||
  // socket.io analysis submit to the CQP server
 | 
			
		||||
  let queryFormElement = document.getElementById("query-form");
 | 
			
		||||
  queryFormElement.addEventListener("submit", sendQuery);
 | 
			
		||||
 | 
			
		||||
  // get context of one match if inspected
 | 
			
		||||
  nopaque.socket.on("match_context", showMatchContext);
 | 
			
		||||
 | 
			
		||||
  // live update of hits per page
 | 
			
		||||
  var hitsPerPageInputElement = document.getElementById("hits-per-page");
 | 
			
		||||
  hitsPerPageInputElement.onchange = changeHitsPerPage;
 | 
			
		||||
@@ -282,11 +303,17 @@ server side -->
 | 
			
		||||
  var paginationElements = document.getElementsByClassName("pagination");
 | 
			
		||||
  for (element of paginationElements) {
 | 
			
		||||
    element.addEventListener("click", changeContext);
 | 
			
		||||
    element.addEventListener("click", activateInspect);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // socket.on triggered when result chunks are recieved
 | 
			
		||||
  nopaque.socket.on("corpus_analysis_query", recieveResults);
 | 
			
		||||
 | 
			
		||||
  // Add onclick to open download modal
 | 
			
		||||
  exportQueryResultsElement.onclick = function() {
 | 
			
		||||
    exportModal.open();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // add onclick to download JSON button and download the file
 | 
			
		||||
  var downloadResultsJSONElement = document.getElementById("download-results-json")
 | 
			
		||||
  downloadResultsJSONElement.onclick = function() {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user