about summary refs log tree commit diff
path: root/bh20simplewebuploader
diff options
context:
space:
mode:
Diffstat (limited to 'bh20simplewebuploader')
-rw-r--r--bh20simplewebuploader/main.py43
-rw-r--r--bh20simplewebuploader/static/main.js31
-rw-r--r--bh20simplewebuploader/templates/form.html54
3 files changed, 74 insertions, 54 deletions
diff --git a/bh20simplewebuploader/main.py b/bh20simplewebuploader/main.py
index e80713f..f4eabe6 100644
--- a/bh20simplewebuploader/main.py
+++ b/bh20simplewebuploader/main.py
@@ -48,10 +48,10 @@ def name_to_label(field_name):
     """
     Turn a filed name like "host_health_status" from the metadata schema into a human-readable label.
     """
-    
+
     # May end in a number, which should be set off by a space
     set_off_number = re.sub('([0-9]+)$', r' \1', field_name)
-    
+
     return string.capwords(set_off_number.replace('_', ' '))
 
 def is_iri(string):
@@ -72,13 +72,13 @@ def generate_form(schema, options):
     Each dict either has a 'heading' (in which case we put a heading for a
     form section in the template) or an 'id', 'label', 'type', and 'required'
     (in which case we make a form field in the template).
-    
+
     Non-heading dicts with type 'select' will have an 'options' field, with a
     list of (name, value) tuples, and represent a form dropdown element.
-    
+
     Non-heading dicts with type 'number' may have a 'step', which, if <1 or
     'any', allows the number to be a float.
-    
+
     Non-heading dicts may have a human-readable 'docstring' field describing
     them.
 
@@ -125,7 +125,7 @@ def generate_form(schema, options):
             docstring = None
             if not isinstance(field_type, str):
                 # If the type isn't a string
-                
+
                 # It may have documentation
                 docstring = field_type.get('doc', None)
 
@@ -159,7 +159,7 @@ def generate_form(schema, options):
                 optional = True
                 # Drop the ?
                 field_type = field_type[:-1]
-                
+
             # Decide if the field is a list (type ends in [])
             is_list = False
             if field_type.endswith('[]'):
@@ -280,6 +280,7 @@ def receive_files():
     Receive the uploaded files.
     """
 
+    return 0
     # We're going to work in one directory per request
     dest_dir = tempfile.mkdtemp()
     # The uploader will happily accept a FASTQ with this name
@@ -310,7 +311,7 @@ def receive_files():
         elif request.form.get('metadata_type', None) == 'fill':
             # Build a metadata dict
             metadata = {}
-            
+
             # When we have metadata for an item, use this to set it.
             # If it is an item in a list, set is_list=True
             def set_metadata(item_id, value, is_list=False):
@@ -324,7 +325,7 @@ def receive_files():
                     if parent not in dest_dict:
                         dest_dict[parent] = {}
                     dest_dict = dest_dict[parent]
-                    
+
                 if not is_list:
                     dest_dict[key] = value
                 else:
@@ -336,22 +337,22 @@ def receive_files():
                 # Pull all the field values we wanted from the form
                 if 'heading' in item:
                     continue
-                    
+
                 if item['list']:
                     # This is a list, serialized into form fields
-                    
+
                     # We count how many values we got
                     value_count = 0
-                    
+
                     for index in itertools.count():
                         # Get [0] through [n], until something isn't there.
                         entry_id = '{}[{}]'.format(item['id'], index)
-                        
+
                         if index == 1000:
                             # Don't let them provide too much stuff.
                             return (render_template('error.html',
                                     error_message="You provided an extremely large number of values for the metadata item {}".format(item['id'])), 403)
-                        
+
                         if entry_id in request.form:
                             if len(request.form[entry_id]) > 0:
                                 # Put an entry in the list
@@ -371,7 +372,7 @@ def receive_files():
                         else:
                             # We have run out of form fields for this list.
                             break
-                            
+
                         if item['required'] and value_count == 0:
                             # They forgot a required item. Maybe all entries were empty.
                             return (render_template('error.html',
@@ -450,7 +451,7 @@ def getDetailsForSeq():
 
 @app.route('/api/getSEQCountbytech', methods=['GET'])
 def getSEQCountbytech():
-    query="""SELECT ?tech ?tech_label (count(?fasta) as ?fastaCount) WHERE 
+    query="""SELECT ?tech ?tech_label (count(?fasta) as ?fastaCount) WHERE
     {?fasta ?x [<http://purl.obolibrary.org/obo/OBI_0600047>  ?tech] .
      OPTIONAL {?tech <http://www.w3.org/2000/01/rdf-schema#label> ?tech_tmp_label } .
      BIND(IF(BOUND(?tech_tmp_label), ?tech_tmp_label,?tech) as ?tech_label)}
@@ -466,8 +467,8 @@ def getSEQCountbytech():
 ## Is this one really necessary or should we just use getSEQCountbytech instead?
 @app.route('/api/getAvailableTech', methods=['GET'])
 def getAvailableTech():
-    query="""SELECT distinct ?tech ?tech_label WHERE 
-    {?fasta ?x [<http://purl.obolibrary.org/obo/OBI_0600047> ?tech] 
+    query="""SELECT distinct ?tech ?tech_label WHERE
+    {?fasta ?x [<http://purl.obolibrary.org/obo/OBI_0600047> ?tech]
      BIND (concat(?tech,"_label") as ?tech_label)
     } """
     payload = {'query': query, 'format': 'json'}
@@ -479,7 +480,7 @@ def getAvailableTech():
 ## Has to be encoded again so should be --> http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FOBI_0000759
 @app.route('/api/getSEQbytech', methods=['GET'])
 def getSEQbytech():
-    query="""SELECT ?fasta WHERE 
+    query="""SELECT ?fasta WHERE
     {?fasta ?x [<http://purl.obolibrary.org/obo/OBI_0600047>  <placeholder>] }
     """
     tech = request.args.get('tech')
@@ -565,7 +566,7 @@ def getSEQCountbyHostHealthStatus():
 
 @app.route('/api/getSEQbyLocationAndTech', methods=['GET'])
 def getSEQbyLocationAndTech():
-    query="""SELECT ?fasta WHERE { ?fasta ?x [ 
+    query="""SELECT ?fasta WHERE { ?fasta ?x [
         <http://purl.obolibrary.org/obo/GAZ_00000448> <placeholderLoc>; <http://purl.obolibrary.org/obo/OBI_0600047>  <placeholderTech> ]}"""
     location=request.args.get('location')
     tech=request.args.get('tech')
@@ -582,7 +583,7 @@ def getSEQbyLocationAndTech():
 # Example specimen http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FNCIT_C155831
 @app.route('/api/getSEQbyLocationAndSpecimenSource', methods=['GET'])
 def getSEQbyLocationAndSpecimenSource():
-    query="""SELECT ?fasta WHERE { ?fasta ?x [ 
+    query="""SELECT ?fasta WHERE { ?fasta ?x [
         <http://purl.obolibrary.org/obo/GAZ_00000448> <placeholderLoc>; <http://purl.obolibrary.org/obo/OBI_0001479>  <placeholderSpecimen> ]}
     """
     location = request.args.get('location')
diff --git a/bh20simplewebuploader/static/main.js b/bh20simplewebuploader/static/main.js
index 56213fa..7084e1f 100644
--- a/bh20simplewebuploader/static/main.js
+++ b/bh20simplewebuploader/static/main.js
@@ -49,7 +49,7 @@ let fetchAllaccessions = () => {
 let uploadForm = document.getElementById('metadata_upload_form')
 let uploadFormSpot = document.getElementById('metadata_upload_form_spot')
 let fillForm = document.getElementById('metadata_fill_form')
-let fillFormSpot = document.getElementById('metadata_fill_form_spot') 
+let fillFormSpot = document.getElementById('metadata_fill_form_spot')
 
 function setUploadMode() {
   // Make the upload form the one in use.
@@ -91,20 +91,20 @@ setMode()
 function addField(e) {
   // Find our parent field-group div
   let fieldGroup = this.parentElement
-  
+
   // Get its keypath
   let keypath = fieldGroup.dataset.keypath
-  
+
   // Find its last field child
   let existingFields = fieldGroup.getElementsByClassName('field')
   let templateField = existingFields[existingFields.length - 1]
-  
+
   // Get its number
   let fieldNumber = templateField.dataset.number
-  
+
   // Duplicate it
   let newField = templateField.cloneNode(true)
-  
+
   // Increment the number and use the keypath and number to set IDs and cross
   // references.
   // TODO: Heavily dependent on the form field HTML. Maybe we want custom
@@ -117,13 +117,13 @@ function addField(e) {
   newControl.setAttribute('name', newID)
   let newLabel = newField.getElementsByTagName('label')[0]
   newLabel.setAttribute('for', newID)
-  
+
   // Find the minus button
   let minusButton = fieldGroup.getElementsByClassName('remove-field')[0]
-  
+
   // Put new field as a child before the minus button
   fieldGroup.insertBefore(newField, minusButton)
-  
+
   // Enable the minus button
   minusButton.classList.remove('invisible')
 }
@@ -134,16 +134,16 @@ function addField(e) {
 function removeField(e) {
   // Find our parent field-group div
   let fieldGroup = this.parentElement
-  
+
   // Find its field children
   let existingFields = fieldGroup.getElementsByClassName('field')
-  
+
   if (existingFields.length > 1) {
     // There is a last field we can safely remove.
     let lastField = existingFields[existingFields.length - 1]
     fieldGroup.removeChild(lastField)
   }
-  
+
   if (existingFields.length <= 1) {
     // Collection auto-updates. Now there's only one element. Don't let the
     // user remove it. If they don't want it, they can leave it empty.
@@ -159,3 +159,10 @@ for (let button of document.getElementsByClassName('remove-field')) {
   button.addEventListener('click', removeField)
 }
 
+// Change the submit button after hitting
+
+function on_submit_button() {
+    var elem = document.getElementById("submit");
+    elem.value = "Submitting...";
+    elem.disabled = true;
+}
diff --git a/bh20simplewebuploader/templates/form.html b/bh20simplewebuploader/templates/form.html
index 1bbf515..37a7b72 100644
--- a/bh20simplewebuploader/templates/form.html
+++ b/bh20simplewebuploader/templates/form.html
@@ -2,7 +2,7 @@
 <html>
     <head>
         <meta charset="UTF-8">
-        <link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet"> 
+        <link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
         <link href="/static/main.css" rel="stylesheet" type="text/css">
         <meta name="viewport" content="width=device-width, initial-scale=1">
         <title>Web uploader for Public SARS-CoV-2 Sequence Resource</title>
@@ -21,10 +21,10 @@
               <p>[Demo] Display content sequences by: </p>
 
               <div>
-                  <button class="button" onclick="fetchSEQBySpecimen()">Specimen Source</button>
+                  <button class="button" onclick="fetchSEQBySpecimen()">Specimen source</button>
                   <button class="button" onclick="fetchSEQByLocation()">Location</button>
-                  <button class="button" onclick="fetchSEQByTech()">Tech</button>
-                  <button class="button" onclick="fetchAllaccessions()">Allaccessions</button>
+                  <button class="button" onclick="fetchSEQByTech()">Sequencer</button>
+                  <button class="button" onclick="fetchAllaccessions()">All accessions</button>
               </div>
 
           </div>
@@ -66,7 +66,9 @@
                         A free command line version of the uploader can be
                         installed from <a href="https://github.com/arvados/bh20-seq-resource">source</a>.
                     </p>
-
+                    <p>
+                      Note that form fields contain web <a href="https://en.wikipedia.org/wiki/Web_Ontology_Language">onthology URI's</a> for <a href="https://en.wikipedia.org/wiki/Wikipedia:Disambiguation">disambiguation</a> and machine readable metadata. For examples of use, see the <a href="https://github.com/arvados/bh20-seq-resource/blob/master/doc/blog/using-covid-19-pubseq-part1.org">BLOG</a>.
+                    </p>
                 </div>
 
                 <div class="fasta-file-select">
@@ -75,8 +77,8 @@
                         <path fill-rule="evenodd" d="M5 8.854a.5.5 0 00.707 0L8 6.56l2.293 2.293A.5.5 0 1011 8.146L8.354 5.5a.5.5 0 00-.708 0L5 8.146a.5.5 0 000 .708z" clip-rule="evenodd"/>
                         <path fill-rule="evenodd" d="M8 6a.5.5 0 01.5.5v8a.5.5 0 01-1 0v-8A.5.5 0 018 6z" clip-rule="evenodd"/>
                     </svg> Upload SARS-CoV-2 Sequence</h2>
-                    
-                    <label for="fasta">Select FASTA file of assembled genome (max 50K), or FASTQ of reads (<span class="dropt" title="For a larger fastq file you'll need to use a CLI uploader">max 150MB<span style="width:500px;"></span></span>) : </label>
+
+                    <label for="fasta">Select FASTA file of assembled genome (form upload <span class="dropt" title="For larger files or bulk uploads you can use a CLI uploader">max 50K<span style="width:500px;"></span></span>; FASTQ and BAM is coming soon): </label>
                     <br>
                     <input type="file" id="fasta" name="fasta" accept=".fa,.fasta,.fna,.fq" required>
                     <br>
@@ -97,7 +99,7 @@
                     <div id="metadata_upload_form_spot">
                         <div id="metadata_upload_form">
                           <br>
-                          <label for="metadata">Select JSON or YAML metadata file following <a href="https://github.com/arvados/bh20-seq-resource/blob/master/bh20sequploader/bh20seq-schema.yml" target="_blank">this schema</a> and <a href="https://github.com/arvados/bh20-seq-resource/blob/master/example/metadata.yaml" target="_blank">example</a> (max 50K):</label>
+                          <label for="metadata">Select JSON or YAML metadata file following <a href="https://github.com/arvados/bh20-seq-resource/blob/master/bh20sequploader/bh20seq-schema.yml" target="_blank">this schema</a> and <a href="https://github.com/arvados/bh20-seq-resource/blob/master/example/maximum_metadata_example.yaml" target="_blank">example</a> (max 50K):</label>
                           <br>
                           <input type="file" id="metadata" name="metadata" accept=".json,.yml,.yaml" required>
                           <br>
@@ -105,6 +107,7 @@
                     </div>
 
                 </div>
+
                 <div id="metadata_fill_form_spot">
                     <div id="metadata_fill_form">
                         {% for record in fields %}
@@ -113,35 +116,44 @@
                         {% if loop.index > 1 and 2 < 3  %}
                     </div>
                     {% endif %}
-                    <div class="record">
+                    <div class="record"> <!-- from block, e.g. host fields -->
                         <h4>{{ record['heading'] }}</h4>
-                        {% else %}
+                        {% else %} <!-- handles one field -->
                         <div class="field-group" data-keypath="{{ record['id'] }}">
                             <div class="field" data-number="0">
                                 <label for="{{ record['id'] }}{{ '[0]' if record['list'] else ''}}" title="{{ record.get('docstring', '') }}">
                                     {{ record['label'] }}
                                     {{ "*" if record['required'] else "" }}
                                     {% if 'docstring' in record %}
-                                    <a href='javascript:alert({{ record['docstring'] | tojson }})'>❓</a>
+                                      <a href='javascript:alert({{ record['docstring'] | tojson }})'>❓</a>
                                     {% endif %}
                                     {% if 'ref_iri' in record %}
-                                    <a href="{{ record['ref_iri'] }}" target="_blank" title="Ontology Link">🔗</a>
+                                      <a href="{{ record['ref_iri'] }}" target="_blank" title="Ontology Link">🔗</a>
                                     {% endif %}
                                 </label>
                                 {% if record['type'] == 'select' %}
-                                <select class="control" id="{{ record['id'] }}{{ '[0]' if record['list'] else ''}}" name="{{ record['id'] }}{{ '[0]' if record['list'] else ''}}" {{ "required" if record['required'] else "" }}>
-                                    <option value="" selected>Choose one...</option>
+                                  <select class="control" id="{{ record['id'] }}{{ '[0]' if record['list'] else ''}}" name="{{ record['id'] }}{{ '[0]' if record['list'] else ''}}" {{ "required" if record['required'] else "" }}>
+                                      <option value="" selected>Choose one...</option>
                                     {% for option in record['options'] %}
-                                    <option value="{{ option[1] }}">{{ option[0] }}</option>
+                                      <option value="{{ option[1] }}">{{ option[0] }}</option>
                                     {% endfor %}
-                                </select>
-                                {% else %}
-                                <input class="control" type="{{ record['type'] }}" id="{{ record['id'] }}{{ '[0]' if record['list'] else ''}}" name="{{ record['id'] }}{{ '[0]' if record['list'] else ''}}" {{ "required" if record['required'] else "" }} {{ ("step=" + record['step']) if 'step' in record else ""}}>
+                                  </select>
+                                {% else %} <!-- input field -->
+                                  <input class="control"
+                                         type="{{ record['type'] }}"
+                                         id="{{ record['id'] }}{{ '[0]' if record['list'] else ''}}"
+                                         {{ 'value=http://purl.obolibrary.org/obo/NCBITaxon_9606' if record['id']=='metadata.host.host_species'}}
+                                         {{ 'placeholder=http://www.wikidata.org/entity/Q30' if record['id']=='metadata.sample.collection_location'}}
+                                         {{ 'placeholder=MyUniqueSampleId.1' if record['id']=='metadata.sample.sample_id'}}
+                                         {{ 'value=http://purl.obolibrary.org/obo/NCBITaxon_2697049' if record['id']=='metadata.virus.virus_species'}}
+                                         {{ 'readonly=1 value=http://identifiers.org/insdc/MT334571.1#sequence' if record['id']=='metadata.id'}}
+                                         name="{{ record['id'] }}{{ '[0]' if record['list'] else ''}}"
+                                         {{ "required" if record['required'] else "" }} {{ ("step=" + record['step']) if 'step' in record else ""}}>
                                 {% endif %}
                             </div>
                             {% if record['list'] %}
-                            <button type="button" title="Remove field" class="remove-field invisible">➖</button>
-                            <button type="button" title="Add field" class="add-field">➕</button>
+                              <button type="button" title="Remove field" class="remove-field invisible">➖</button>
+                              <button type="button" title="Add field" class="add-field">➕</button>
                             {% endif %}
                         </div>
                         {% endif %}
@@ -153,7 +165,7 @@
 
                 </div>
 
-                <input class="submit" type="submit" value="Add to Pangenome">
+                <input class="submit" id="submit" onclick="on_submit_button()" type="submit" value="Add to Pangenome">
             </form>
         </section>
 <br>