Repository 'apollo_create_or_update'
hg clone https://toolshed.g2.bx.psu.edu/repos/gga/apollo_create_or_update

Changeset 10:d72192ec8e39 (2019-12-02)
Previous changeset 9:29ce13734a5c (2019-07-29) Next changeset 11:7609529caafa (2020-04-14)
Commit message:
"planemo upload for repository https://github.com/galaxy-genome-annotation/galaxy-tools/tree/master/tools/apollo commit 08015be1ee8a784e0619f961aaa724857debfd6f"
modified:
README.rst
create_account.py
create_features_from_gff3.py
create_or_update_organism.py
create_or_update_organism.xml
delete_features.py
delete_organism.py
export.py
fetch_organism_jbrowse.py
list_organisms.py
macros.xml
webapollo.py
added:
test-data/arrow.yml
test-data/create_org/output.json
test-data/create_org/output2.json
test-data/dataset_1.dat
test-data/dataset_1_files/data/.htaccess
test-data/dataset_1_files/data/names/02b/9.json
test-data/dataset_1_files/data/names/0e9/3.json
test-data/dataset_1_files/data/names/83f/8.json
test-data/dataset_1_files/data/names/92c/2.json
test-data/dataset_1_files/data/names/cf0/e.json
test-data/dataset_1_files/data/names/f26/8.json
test-data/dataset_1_files/data/names/meta.json
test-data/dataset_1_files/data/raw/4ced49b280a72a29f1b922ae1a9664c8_0.gff.gz
test-data/dataset_1_files/data/raw/4ced49b280a72a29f1b922ae1a9664c8_0.gff.gz.tbi
test-data/dataset_1_files/data/seq/genome.fasta
test-data/dataset_1_files/data/seq/genome.fasta.fai
test-data/dataset_1_files/data/seq/refSeqs.json
test-data/dataset_1_files/data/trackList.json
test-data/dataset_1_files/data/tracks.conf
test-data/dataset_1_files/galaxy.xml
test-data/dataset_1_files/jbrowse.conf
test-data/dataset_1_files/jbrowse_conf.json
test-data/export/cdna.fa
test-data/export/cds.fa
test-data/export/out.vcf
test-data/export/pep.fa
test-data/load_gff3/output.tsv
test-data/merlin.gff
test-data/org_remote.tar.gz
removed:
test-data/bad-model.gff3
test-data/good-model.gff3
b
diff -r 29ce13734a5c -r d72192ec8e39 README.rst
--- a/README.rst Mon Jul 29 10:09:54 2019 -0400
+++ b/README.rst Mon Dec 02 05:46:45 2019 -0500
b
@@ -1,27 +1,13 @@
 Galaxy-apollo
 =============
 
-Galaxy tools to interface with Apollo The webapollo.py file is also
-`separately
-available <https://github.com/galaxy-genome-annotation/python-apollo>`__
-as a pip-installable package.
-
-Dependencies
-------------
-
-You will need to install some python modules in the Galaxy virtualenv for these
-tools to be fully functional:
-
-.. code:: bash
-
-    . /path/to/galaxy/.venv/bin/activate
-    pip install six biopython bcbio-gff
-    deactivate
+Galaxy tools to interface with Apollo.
+Uses `python-apollo <https://github.com/galaxy-genome-annotation/python-apollo>`__ for most of it.
 
 Environment
 -----------
 
-The following environment variables must be set:
+The following environment variables can be set:
 
 +--------------------------------+-----------------------------------------------------------+
 | ENV                            | Use                                                       |
@@ -34,15 +20,22 @@
 |                                |                                                           |
 +--------------------------------+-----------------------------------------------------------+
 | ``$GALAXY_WEBAPOLLO_PASSWORD`` | The password for the admin user.                          |
-|                                |                                                           |
-|                                |                                                           |
++--------------------------------+-----------------------------------------------------------+
+| ``$ARROW_GLOBAL_CONFIG_PATH``  | Path to a python-apollo/arrow conf file. Use in place of  |
+|                                | ``$GALAXY_WEBAPOLLO_URL``, ``$GALAXY_WEBAPOLLO_USER``     |
+|                                | and ``$GALAXY_WEBAPOLLO_PASSWORD``.                       |
 +--------------------------------+-----------------------------------------------------------+
 | ``$GALAXY_WEBAPOLLO_EXT_URL``  | May be relative or absolute.                              |
 |                                | The external URL at which Apollo is accessible to end     |
 |                                | users.                                                    |
 +--------------------------------+-----------------------------------------------------------+
 | ``$GALAXY_SHARED_DIR``         | Directory shared between Galaxy and Apollo, used to       |
-|                                | exchange JBrowse instances.                               |
+|                                | exchange JBrowse instances. If not set, JBrowse data will |
+|                                | be zipped and sent to the remote server.                  |
++--------------------------------+-----------------------------------------------------------+
+| ``$GALAXY_APOLLO_ORG_SUFFIX``  | Set to 'id' if you want organism names to be suffixed     |
+|                                | with user id to avoid name collisions. Set to 'email' to  |
+|                                | use user email as suffix. Leave empty for no suffix.      |
 +--------------------------------+-----------------------------------------------------------+
 
 License
b
diff -r 29ce13734a5c -r d72192ec8e39 create_account.py
--- a/create_account.py Mon Jul 29 10:09:54 2019 -0400
+++ b/create_account.py Mon Dec 02 05:46:45 2019 -0500
[
@@ -4,35 +4,30 @@
 import argparse
 import time
 
-from six.moves.builtins import str
-
-from webapollo import PasswordGenerator, WAAuth, WebApolloInstance
+from arrow.apollo import get_apollo_instance
 
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='Sample script to add an account via web services')
-    WAAuth(parser)
-
     parser.add_argument('email', help='User Email')
     parser.add_argument('--first', help='First Name', default='Jane')
     parser.add_argument('--last', help='Last Name', default='Aggie')
     args = parser.parse_args()
 
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
+    wa = get_apollo_instance()
 
-    password = PasswordGenerator(12)
+    password = wa.users._password_generator(12)
     time.sleep(1)
-    users = wa.users.loadUsers()
+    users = wa.users.get_users()
     user = [u for u in users
-            if u.username == args.email]
+            if u['username'] == args.email]
 
     if len(user) == 1:
         # Update name, regen password if the user ran it again
-        userObj = user[0]
-        returnData = wa.users.updateUser(userObj, args.email, args.first, args.last, password)
+        returnData = wa.users.update_user(args.email, args.first, args.last, password)
         print('Updated User\nUsername: %s\nPassword: %s' % (args.email, password))
     else:
-        returnData = wa.users.createUser(args.email, args.first, args.last, password, role='user')
+        returnData = wa.users.create_user(args.email, args.first, args.last, password, role='user')
         print('Created User\nUsername: %s\nPassword: %s' % (args.email, password))
 
     print("Return data: " + str(returnData))
b
diff -r 29ce13734a5c -r d72192ec8e39 create_features_from_gff3.py
--- a/create_features_from_gff3.py Mon Jul 29 10:09:54 2019 -0400
+++ b/create_features_from_gff3.py Mon Dec 02 05:46:45 2019 -0500
[
b'@@ -1,21 +1,19 @@\n #!/usr/bin/env python\n import argparse\n import logging\n-import sys\n-import time\n+\n+from apollo import accessible_organisms\n+from apollo.util import GuessOrg, OrgOrGuess\n \n-from BCBio import GFF\n+from arrow.apollo import get_apollo_instance\n \n-from six.moves.builtins import str\n-\n-from webapollo import GuessOrg, OrgOrGuess, PermissionCheck, WAAuth, WebApolloInstance, featuresToFeatureSchema, retry\n+from webapollo import UserObj, handle_credentials\n logging.basicConfig(level=logging.INFO)\n log = logging.getLogger(__name__)\n \n \n if __name__ == \'__main__\':\n     parser = argparse.ArgumentParser(description=\'Sample script to add an attribute to a feature via web services\')\n-    WAAuth(parser)\n     parser.add_argument(\'email\', help=\'User Email\')\n     parser.add_argument(\'--source\', help=\'URL where the input dataset can be found.\')\n     OrgOrGuess(parser)\n@@ -23,165 +21,25 @@\n     parser.add_argument(\'gff3\', type=argparse.FileType(\'r\'), help=\'GFF3 file\')\n     args = parser.parse_args()\n \n-    wa = WebApolloInstance(args.apollo, args.username, args.password)\n+    wa = get_apollo_instance()\n     # User must have an account\n-    gx_user = wa.users.assertOrCreateUser(args.email)\n+    gx_user = UserObj(**wa.users._assert_or_create_user(args.email))\n+    handle_credentials(gx_user)\n \n     # Get organism\n     org_cn = GuessOrg(args, wa)\n     if isinstance(org_cn, list):\n         org_cn = org_cn[0]\n \n-    if not PermissionCheck(gx_user, org_cn, "WRITE"):\n-        raise Exception("Action not permitted")\n-    org = wa.organisms.findOrganismByCn(org_cn)\n-\n-    bad_quals = [\'date_creation\', \'source\', \'owner\', \'date_last_modified\', \'Name\', \'ID\']\n-\n-    sys.stdout.write(\'# \')\n-    sys.stdout.write(\'\\t\'.join([\'Feature ID\', \'Apollo ID\', \'Success\', \'Messages\']))\n-    sys.stdout.write(\'\\n\')\n-    # print(wa.annotations.getFeatures())\n-    for rec in GFF.parse(args.gff3):\n-        wa.annotations.setSequence(rec.id, org[\'id\'])\n-        for feature in rec.features:\n-            # We can only handle genes right now\n-            if feature.type not in (\'gene\', \'terminator\'):\n-                continue\n-            # Convert the feature into a presentation that Apollo will accept\n-            featureData = featuresToFeatureSchema([feature])\n-            if \'children\' in featureData[0] and any([child[\'type\'][\'name\'] == \'tRNA\' for child in featureData[0][\'children\']]):\n-                # We\'re experiencing a (transient?) problem where gene_001 to\n-                # gene_025 will be rejected. Thus, hardcode to a known working\n-                # gene name and update later.\n-\n-                featureData[0][\'name\'] = \'tRNA_000\'\n-                tRNA_sf = [child for child in feature.sub_features if child.type == \'tRNA\'][0]\n-                tRNA_type = \'tRNA-\' + tRNA_sf.qualifiers.get(\'Codon\', ["Unk"])[0]\n-\n-                if \'Name\' in feature.qualifiers:\n-                    if feature.qualifiers[\'Name\'][0].startswith(\'tRNA-\'):\n-                        tRNA_type = feature.qualifiers[\'Name\'][0]\n-\n-                newfeature = wa.annotations.addFeature(featureData, trustme=True)\n-\n-                def func0():\n-                    wa.annotations.setName(\n-                        newfeature[\'features\'][0][\'uniquename\'],\n-                        tRNA_type,\n-                    )\n-                retry(func0)\n-\n-                if args.source:\n-                    gene_id = newfeature[\'features\'][0][\'parent_id\']\n-\n-                    def setSource():\n-                        wa.annotations.addAttributes(gene_id, {\'DatasetSource\': [args.source]})\n-                    retry(setSource)\n-\n-                sys.stdout.write(\'\\t\'.join([\n-                    feature.id,\n-                    newfeature[\'features\'][0][\'uniquename\'],\n-                    \'success\',\n-                ]))\n-            elif featureData[0][\'type\'][\'name\'] == \'terminator\':\n-                # We\'re experiencing a (transient?) problem where gene_001 to\n-                # gene_025 will'..b'eature.id,\n-                    newfeature[\'features\'][0][\'uniquename\'],\n-                    \'success\',\n-                ]))\n-            else:\n-                try:\n-                    # We\'re experiencing a (transient?) problem where gene_001 to\n-                    # gene_025 will be rejected. Thus, hardcode to a known working\n-                    # gene name and update later.\n-                    featureData[0][\'name\'] = \'gene_000\'\n-                    # Extract CDS feature from the feature data, this will be used\n-                    # to set the CDS location correctly (apollo currently screwing\n-                    # this up (2.0.6))\n-                    CDS = featureData[0][\'children\'][0][\'children\']\n-                    CDS = [x for x in CDS if x[\'type\'][\'name\'] == \'CDS\'][0][\'location\']\n-                    # Create the new feature\n-                    newfeature = wa.annotations.addFeature(featureData, trustme=True)\n-                    # Extract the UUIDs that apollo returns to us\n-                    mrna_id = newfeature[\'features\'][0][\'uniquename\']\n-                    gene_id = newfeature[\'features\'][0][\'parent_id\']\n-                    # Sleep to give it time to actually persist the feature. Apollo\n-                    # is terrible about writing + immediately reading back written\n-                    # data.\n-                    time.sleep(1)\n-                    # Correct the translation start, but with strand specific log\n-                    if CDS[\'strand\'] == 1:\n-                        wa.annotations.setTranslationStart(mrna_id, min(CDS[\'fmin\'], CDS[\'fmax\']))\n-                    else:\n-                        wa.annotations.setTranslationStart(mrna_id, max(CDS[\'fmin\'], CDS[\'fmax\']) - 1)\n-\n-                    # Finally we set the name, this should be correct.\n-                    time.sleep(0.5)\n-                    wa.annotations.setName(mrna_id, feature.qualifiers.get(\'product\', feature.qualifiers.get(\'Name\', ["Unknown"]))[0])\n-                    time.sleep(0.5)\n-\n-                    def func():\n-                        wa.annotations.setName(gene_id, feature.qualifiers.get(\'product\', feature.qualifiers.get(\'Name\', ["Unknown"]))[0])\n-                    retry(func)\n+    orgs = accessible_organisms(gx_user, [org_cn], \'WRITE\')\n+    if not orgs:\n+        raise Exception("You do not have write permission on this organism")\n \n-                    if args.source:\n-                        gene_id = newfeature[\'features\'][0][\'parent_id\']\n-\n-                        def setSource():\n-                            wa.annotations.addAttributes(gene_id, {\'DatasetSource\': [args.source]})\n-                        retry(setSource)\n-                    extra_attr = {}\n-                    for (key, values) in feature.qualifiers.items():\n-                        if key in bad_quals:\n-                            continue\n-\n-                        if key == \'Note\':\n-                            def func2():\n-                                wa.annotations.addComments(gene_id, values)\n-                            retry(func2)\n-                        else:\n-                            extra_attr[key] = values\n-\n-                    def func3():\n-                        wa.annotations.addAttributes(gene_id, extra_attr)\n-                    retry(func3)\n-\n-                    sys.stdout.write(\'\\t\'.join([\n-                        feature.id,\n-                        gene_id,\n-                        \'success\',\n-                    ]))\n-                except Exception as e:\n-                    msg = str(e)\n-                    if \'\\n\' in msg:\n-                        msg = msg[0:msg.index(\'\\n\')]\n-                    sys.stdout.write(\'\\t\'.join([\n-                        feature.id,\n-                        \'\',\n-                        \'ERROR\',\n-                        msg\n-                    ]))\n-            sys.stdout.write(\'\\n\')\n-            sys.stdout.flush()\n+    wa.annotations.load_gff3(org_cn, args.gff3, args.source)\n'
b
diff -r 29ce13734a5c -r d72192ec8e39 create_or_update_organism.py
--- a/create_or_update_organism.py Mon Jul 29 10:09:54 2019 -0400
+++ b/create_or_update_organism.py Mon Dec 02 05:46:45 2019 -0500
[
b'@@ -2,17 +2,25 @@\n from __future__ import print_function\n \n import argparse\n+import glob\n import json\n import logging\n import os\n import shutil\n+import stat\n import subprocess\n import sys\n+import tarfile\n import tempfile\n import time\n \n+from apollo import accessible_organisms\n+from apollo.util import GuessOrg, OrgOrGuess\n \n-from webapollo import GuessOrg, OrgOrGuess, PermissionCheck, WAAuth, WebApolloInstance\n+from arrow.apollo import get_apollo_instance\n+\n+from webapollo import UserObj, handle_credentials\n+\n logging.basicConfig(level=logging.INFO)\n log = logging.getLogger(__name__)\n \n@@ -27,11 +35,24 @@\n         return False\n \n \n+def IsOrgCNSuffixEnabled():\n+    if \'GALAXY_APOLLO_ORG_SUFFIX\' not in os.environ:\n+        return False\n+    value = os.environ[\'GALAXY_APOLLO_ORG_SUFFIX\'].lower()\n+    if value in (\'id\', \'email\'):\n+        return value\n+\n+    return False\n+\n+\n+def IsRemote():\n+    return \'GALAXY_SHARED_DIR\' not in os.environ or len(os.environ[\'GALAXY_SHARED_DIR\'].lower().strip()) == 0\n+\n+\n if __name__ == \'__main__\':\n     parser = argparse.ArgumentParser(description=\'Create or update an organism in an Apollo instance\')\n-    WAAuth(parser)\n-    parser.add_argument(\'jbrowse_src\', help=\'Old JBrowse Data Directory\')\n-    parser.add_argument(\'jbrowse\', help=\'JBrowse Data Directory\')\n+    parser.add_argument(\'jbrowse_src\', help=\'Source JBrowse Data Directory\')\n+    parser.add_argument(\'jbrowse\', help=\'Destination JBrowse Data Directory\')\n     parser.add_argument(\'email\', help=\'User Email\')\n     OrgOrGuess(parser)\n     parser.add_argument(\'--genus\', help=\'Organism Genus\')\n@@ -39,94 +60,158 @@\n     parser.add_argument(\'--public\', action=\'store_true\', help=\'Make organism public\')\n     parser.add_argument(\'--group\', help=\'Give access to a user group\')\n     parser.add_argument(\'--remove_old_directory\', action=\'store_true\', help=\'Remove old directory\')\n+    parser.add_argument(\'--no_reload_sequences\', action=\'store_true\', help=\'Disable update genome sequence\')\n+    parser.add_argument(\'--userid\', help=\'User unique id\')\n     args = parser.parse_args()\n     CHUNK_SIZE = 2**20\n     blat_db = None\n \n+    path_fasta = args.jbrowse_src + \'/seq/genome.fasta\'\n+\n     # Cleanup if existing\n-    if(os.path.exists(args.jbrowse)):\n-        shutil.rmtree(args.jbrowse)\n-    # Copy files\n-    shutil.copytree(args.jbrowse_src, args.jbrowse, symlinks=True)\n+    if not IsRemote():\n+        if(os.path.exists(args.jbrowse)):\n+            shutil.rmtree(args.jbrowse)\n+        # Copy files\n+        shutil.copytree(args.jbrowse_src, args.jbrowse, symlinks=True)\n \n-    path_fasta = args.jbrowse + \'/seq/genome.fasta\'\n-    path_2bit = args.jbrowse + \'/seq/genome.2bit\'\n+        path_2bit = args.jbrowse + \'/seq/genome.2bit\'\n+    else:\n+        twobittemp = tempfile.NamedTemporaryFile(prefix="genome.2bit")\n+        path_2bit = twobittemp.name\n+        os.chmod(path_2bit, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)\n \n     # Convert fasta if existing\n-    if(IsBlatEnabled() and os.path.exists(path_fasta)):\n+    if IsBlatEnabled() and os.path.exists(path_fasta):\n         arg = [\'faToTwoBit\', path_fasta, path_2bit]\n-        tmp_stderr = tempfile.NamedTemporaryFile(prefix="tmp-twobit-converter-stderr")\n-        proc = subprocess.Popen(args=arg, shell=False, cwd=args.jbrowse, stderr=tmp_stderr.fileno())\n-        return_code = proc.wait()\n-        if return_code:\n-            tmp_stderr.flush()\n-            tmp_stderr.seek(0)\n+        proc = subprocess.Popen(args=arg, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n+        out, err = proc.communicate()\n+        if proc.returncode:\n             print("Error building index:", file=sys.stderr)\n-            while True:\n-                chunk = tmp_stderr.read(CHUNK_SIZE)\n-                if not chunk:\n-                    break\n-                sys.stderr.write(chunk)\n-            sys.exit(return_code)\n-        blat_db = path_2bit\n-        tmp_stderr.close()\n+            sys.stderr.write(er'..b'        blatdb=blat_db,\n+                    genus=args.genus,\n+                    species=args.species,\n+                    public=args.public,\n+                    no_reload_sequences=args.no_reload_sequences\n+                )\n+        else:\n+            data = wa.organisms.update_organism(\n+                org[\'id\'],\n+                org_cn,\n+                args.jbrowse,\n+                # mandatory\n+                genus=args.genus,\n+                species=args.species,\n+                public=args.public,\n+                blatdb=blat_db,\n+                no_reload_sequences=args.no_reload_sequences\n+            )\n         time.sleep(2)\n-        if args.remove_old_directory and args.jbrowse != old_directory:\n+\n+        if not IsRemote() and args.remove_old_directory and args.jbrowse != old_directory:\n             shutil.rmtree(old_directory)\n \n-        data = [wa.organisms.findOrganismById(org[\'id\'])]\n+        data = wa.organisms.show_organism(org_cn)\n \n     else:\n         # New organism\n         log.info("\\tAdding Organism")\n-        data = wa.organisms.addOrganism(\n-            org_cn,\n-            args.jbrowse,\n-            genus=args.genus,\n-            species=args.species,\n-            public=args.public,\n-            blatdb=blat_db\n-        )\n+\n+        if IsRemote():\n+            with tempfile.NamedTemporaryFile(suffix=\'.tar.gz\') as archive:\n+                with tarfile.open(archive.name, mode="w:gz") as tar:\n+                    dataset_data_dir = args.jbrowse_src\n+                    for file in glob.glob(dataset_data_dir):\n+                        tar.add(file, arcname=file.replace(dataset_data_dir, \'./\'))\n+                    if IsBlatEnabled():\n+                        with tempfile.TemporaryDirectory() as empty_dir:\n+                            os.chmod(empty_dir, stat.S_IRUSR | stat.S_IXUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)\n+                            tar.add(empty_dir, arcname="./searchDatabaseData/")\n+                            tar.add(path_2bit, arcname="./searchDatabaseData/genome.2bit")\n+                data = wa.remote.add_organism(\n+                    org_cn,\n+                    archive,\n+                    blatdb=blat_db,\n+                    genus=args.genus,\n+                    species=args.species,\n+                    public=args.public,\n+                    metadata=None\n+                )\n+                if isinstance(data, list) and len(data) > 0:\n+                    data = data[0]\n+        else:\n+            data = wa.organisms.add_organism(\n+                org_cn,\n+                args.jbrowse,\n+                blatdb=blat_db,\n+                genus=args.genus,\n+                species=args.species,\n+                public=args.public,\n+                metadata=None\n+            )\n \n         # Must sleep before we\'re ready to handle\n         time.sleep(2)\n         log.info("Updating permissions for %s on %s", gx_user, org_cn)\n-        wa.users.updateOrganismPermission(\n-            gx_user, org_cn,\n+        wa.users.update_organism_permissions(\n+            gx_user.username,\n+            org_cn,\n             write=True,\n             export=True,\n             read=True,\n@@ -134,10 +219,9 @@\n \n         # Group access\n         if args.group:\n-            group = wa.groups.loadGroupByName(name=args.group)\n-            res = wa.groups.updateOrganismPermission(group, org_cn,\n-                                                     administrate=False, write=True, read=True,\n-                                                     export=True)\n+            group = wa.groups.get_groups(name=args.group)[0]\n+            res = wa.groups.update_organism_permissions(group[\'name\'], org_cn,\n+                                                        administrate=False, write=True, read=True,\n+                                                        export=True)\n \n-    data = [o for o in data if o[\'commonName\'] == org_cn]\n     print(json.dumps(data, indent=2))\n'
b
diff -r 29ce13734a5c -r d72192ec8e39 create_or_update_organism.xml
--- a/create_or_update_organism.xml Mon Jul 29 10:09:54 2019 -0400
+++ b/create_or_update_organism.xml Mon Dec 02 05:46:45 2019 -0500
[
@@ -9,10 +9,9 @@
   </expand>
   <code file="webapollo.py"/>
   <command detect_errors="aggressive"><![CDATA[
+@AUTH@
 
-python $__tool_directory__/create_or_update_organism.py
-
-@ADMIN_AUTH@
+python '$__tool_directory__/create_or_update_organism.py'
 
 --genus '$genus'
 --species '$species'
@@ -20,18 +19,26 @@
 --group '${group}'
 #end if
 
+--userid '$__user_id__'
+
 ${remove_old_directory}
+${no_reload_sequences}
 $public
 
 @ORG_OR_GUESS@
 
+#if $test_hack == "yes":
+## When testing we can't access extra_files_path, but we know the path of test data
+'$__tool_directory__/test-data/dataset_1_files/data/'
+#else:
 '${jbrowse.extra_files_path}/data/'
+#end if
 
 "@DATA_DIR@/${jbrowse.id}"
 
-$__user_email__
+'$__user_email__'
 
-> $output]]></command>
+> '$output']]></command>
   <inputs>
     <param name="jbrowse" type="data" format="html" label="JBrowse HTML Output" />
     <expand macro="org_or_guess" />
@@ -40,6 +47,8 @@
     <param name="public" type="boolean" truevalue="--public" falsevalue="" label="Is Organism Public" />
     <param name="group" type="select" dynamic_options="galaxy_list_groups(__trans__)" label="Grant access to a user group" optional="True" />
     <param name="remove_old_directory" type="boolean" truevalue="--remove_old_directory" falsevalue="" label="Remove old data directory" />
+    <param name="no_reload_sequences" type="boolean" truevalue="" falsevalue="--no_reload_sequences" label="Update genome sequences" help="Select this if you want Apollo to reload the genome sequences when updating an existing organism. BEWARE! You will lose annotation data for all sequences that are not present anymore in the new jbrowse dataset." />
+    <param name="test_hack" type="hidden" value="no"/>
   </inputs>
   <outputs>
     <data format="json" name="output">
@@ -47,16 +56,27 @@
     </data>
   </outputs>
   <tests>
-      <test expect_failure="true">
-          <param name="jbrowse" value="good-model.gff3"/>
+      <test>
+          <param name="jbrowse" value="dataset_1.dat"/>
           <conditional name="org_source">
               <param name="source_select" value="direct"/>
               <param name="org_raw" value="Test org" />
           </conditional>
           <param name="genus" value="genus"/>
-          <assert_stderr>
-              <has_text text="cannot stat" />
-          </assert_stderr>
+          <param name="test_hack" value="yes"/>
+          <output name="output" file="create_org/output.json" lines_diff="6"/>
+      </test>
+      <test>
+          <!-- Send the same input to test updating -->
+          <param name="jbrowse" value="dataset_1.dat"/>
+          <conditional name="org_source">
+              <param name="source_select" value="direct"/>
+              <param name="org_raw" value="Test org" />
+          </conditional>
+          <param name="genus" value="genus2"/>
+          <param name="species" value="sp"/>
+          <param name="test_hack" value="yes"/>
+          <output name="output" file="create_org/output2.json" lines_diff="6"/>
       </test>
   </tests>
   <help><![CDATA[
b
diff -r 29ce13734a5c -r d72192ec8e39 delete_features.py
--- a/delete_features.py Mon Jul 29 10:09:54 2019 -0400
+++ b/delete_features.py Mon Dec 02 05:46:45 2019 -0500
[
@@ -5,40 +5,54 @@
 import logging
 import random
 
-from webapollo import GuessOrg, OrgOrGuess, PermissionCheck, WAAuth, WebApolloInstance, retry
+from apollo import accessible_organisms
+from apollo.util import GuessOrg, OrgOrGuess, retry
+
+from arrow.apollo import get_apollo_instance
+
+from webapollo import UserObj, handle_credentials
+
 logging.basicConfig(level=logging.INFO)
 log = logging.getLogger(__name__)
 
 
 if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Sample script to delete all features from an organism')
-    WAAuth(parser)
+    parser = argparse.ArgumentParser(description='Script to delete all features from an organism')
     parser.add_argument('email', help='User Email')
     parser.add_argument('--type', help='Feature type filter')
     OrgOrGuess(parser)
 
     args = parser.parse_args()
 
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
+    wa = get_apollo_instance()
     # User must have an account
-    gx_user = wa.users.assertOrCreateUser(args.email)
+    gx_user = UserObj(**wa.users._assert_or_create_user(args.email))
+    handle_credentials(gx_user)
 
     # Get organism
     org_cn = GuessOrg(args, wa)
     if isinstance(org_cn, list):
         org_cn = org_cn[0]
 
-    if not PermissionCheck(gx_user, org_cn, "WRITE"):
-        raise Exception("Action not permitted")
-    org = wa.organisms.findOrganismByCn(org_cn)
+    all_orgs = wa.organisms.get_organisms()
+    if 'error' in all_orgs:
+        all_orgs = []
+    all_orgs = [org['commonName'] for org in all_orgs]
+    if org_cn not in all_orgs:
+        raise Exception("Could not find organism %s" % org_cn)
 
-    sequences = wa.organisms.getSequencesForOrganism(org['id'])
+    orgs = accessible_organisms(gx_user, [org_cn], 'WRITE')
+    if not orgs:
+        raise Exception("You do not have write permission on this organism")
+    org = wa.organisms.show_organism(org_cn)
+
+    sequences = wa.organisms.get_sequences(org['id'])
     for sequence in sequences['sequences']:
         log.info("Processing %s %s", org['commonName'], sequence['name'])
         # Call setSequence to tell apollo which organism we're working with
-        wa.annotations.setSequence(sequence['name'], org['id'])
+        wa.annotations.set_sequence(org['id'], sequence['name'])
         # Then get a list of features.
-        features = wa.annotations.getFeatures()
+        features = wa.annotations.get_features()
         # For each feature in the features
         for feature in sorted(features['features'], key=lambda x: random.random()):
             if args.type:
@@ -60,7 +74,7 @@
             # We see that deleteFeatures wants a uniqueName, and so we pass
             # is the uniquename field in the feature.
             def fn():
-                wa.annotations.deleteFeatures([feature['uniquename']])
+                wa.annotations.delete_feature(feature['uniquename'])
                 print('Deleted %s [type=%s]' % (feature['uniquename'], feature['type']['name']))
 
             if not retry(fn, limit=3):
b
diff -r 29ce13734a5c -r d72192ec8e39 delete_organism.py
--- a/delete_organism.py Mon Jul 29 10:09:54 2019 -0400
+++ b/delete_organism.py Mon Dec 02 05:46:45 2019 -0500
[
@@ -3,41 +3,56 @@
 
 import argparse
 import logging
+import os
 
-from webapollo import GuessOrg, OrgOrGuess, PermissionCheck, WAAuth, WebApolloInstance
+from apollo import accessible_organisms
+from apollo.util import GuessOrg, OrgOrGuess
+
+from arrow.apollo import get_apollo_instance
+
+from webapollo import UserObj, handle_credentials
+
 logging.basicConfig(level=logging.INFO)
 log = logging.getLogger(__name__)
 
 
+def IsRemote():
+    return 'GALAXY_SHARED_DIR' not in os.environ or len(os.environ['GALAXY_SHARED_DIR'].lower().strip()) == 0
+
+
 if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Sample script to completely delete an organism')
-    WAAuth(parser)
+    parser = argparse.ArgumentParser(description='Script to completely delete an organism')
     parser.add_argument('email', help='User Email')
     OrgOrGuess(parser)
 
     args = parser.parse_args()
 
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
+    wa = get_apollo_instance()
+
     # User must have an account
-    gx_user = wa.users.assertOrCreateUser(args.email)
+    gx_user = UserObj(**wa.users._assert_or_create_user(args.email))
+    handle_credentials(gx_user)
 
     # Get organism
     org_cn = GuessOrg(args, wa)
     if isinstance(org_cn, list):
         org_cn = org_cn[0]
 
-    if not PermissionCheck(gx_user, org_cn, "WRITE"):
-        raise Exception("You do not have write permission on this organism")
-    org = wa.organisms.findOrganismByCn(org_cn)
+    all_orgs = wa.organisms.get_organisms()
+    if 'error' in all_orgs:
+        all_orgs = []
+    all_orgs = [org['commonName'] for org in all_orgs]
+    if org_cn not in all_orgs:
+        raise Exception("Could not find organism %s" % org_cn)
 
-    # Call setSequence to tell apollo which organism we're working with
-    wa.annotations.setSequence(org['commonName'], org['id'])
-    # Then get a list of features.
-    features = wa.annotations.getFeatures()
-    # For each feature in the features
-    # If it exists
-    if 'features' in features:
-        for feature in features['features']:
-            # We see that deleteFeatures wants a uniqueName, and so we pass
-            # is the uniquename field in the feature.
-            print(wa.annotations.deleteFeatures([feature['uniquename']]))
+    orgs = accessible_organisms(gx_user, [org_cn], 'WRITE')
+    if not orgs:
+        raise Exception("You do not have write permission on this organism")
+    org = wa.organisms.show_organism(org_cn)
+
+    wa.organisms.delete_features(org['id'])
+
+    if IsRemote():
+        print(wa.remote.delete_organism(org['commonName']))
+    else:
+        print(wa.organisms.delete_organism(org['id']))
b
diff -r 29ce13734a5c -r d72192ec8e39 export.py
--- a/export.py Mon Jul 29 10:09:54 2019 -0400
+++ b/export.py Mon Dec 02 05:46:45 2019 -0500
[
@@ -3,89 +3,86 @@
 
 import argparse
 import json
-import sys
-
-from BCBio import GFF
-
-from Bio import SeqIO
-
-from webapollo import CnOrGuess, GuessCn, PermissionCheck, WAAuth, WebApolloInstance
-
-try:
-    import StringIO as io
-except ImportError:
-    import io
-
-
-def export(org_cn, seqs):
-    org_data = wa.organisms.findOrganismByCn(org_cn)
-
-    data = io.StringIO()
-
-    kwargs = dict(
-        exportType='GFF3',
-        seqType='genomic',
-        exportGff3Fasta=True,
-        output="text",
-        exportFormat="text",
-        organism=org_cn,
-    )
+import time
 
-    if len(seqs) > 0:
-        data.write(wa.io.write(
-            exportAllSequences=False,
-            sequences=seqs,
-            **kwargs
-        ).encode('utf-8'))
-    else:
-        data.write(wa.io.write(
-            exportAllSequences=True,
-            sequences=[],
-            **kwargs
-        ).encode('utf-8'))
-
-    # Seek back to start
-    data.seek(0)
+from apollo import accessible_organisms
+from apollo.util import CnOrGuess, GuessCn
 
-    records = list(GFF.parse(data))
-    if len(records) == 0:
-        print("Could not find any sequences or annotations for this organism + reference sequence")
-        sys.exit(2)
-    else:
-        for record in records:
-            record.annotations = {}
-            record.features = sorted(record.features, key=lambda x: x.location.start)
-            if args.gff:
-                GFF.write([record], args.gff)
-            record.description = ""
-            if args.fasta:
-                SeqIO.write([record], args.fasta, 'fasta')
+from arrow.apollo import get_apollo_instance
 
-    return org_data
-
+from webapollo import UserObj, handle_credentials
 
 if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    WAAuth(parser)
+    parser = argparse.ArgumentParser(description='Script to export data from Apollo via web services')
     CnOrGuess(parser)
     parser.add_argument('--gff', type=argparse.FileType('w'))
-    parser.add_argument('--fasta', type=argparse.FileType('w'))
+    parser.add_argument('--fasta_pep', type=argparse.FileType('w'))
+    parser.add_argument('--fasta_cds', type=argparse.FileType('w'))
+    parser.add_argument('--fasta_cdna', type=argparse.FileType('w'))
+    parser.add_argument('--vcf', type=argparse.FileType('w'))
     parser.add_argument('--json', type=argparse.FileType('w'))
     parser.add_argument('email', help='User Email')
     args = parser.parse_args()
 
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
-
-    org_cn_list, seqs = GuessCn(args, wa)
+    wa = get_apollo_instance()
 
     # User must have an apollo account, if not, create it
-    gx_user = wa.users.assertOrCreateUser(args.email)
+    gx_user = UserObj(**wa.users._assert_or_create_user(args.email))
+    handle_credentials(gx_user)
+
+    org_cns, seqs = GuessCn(args, wa)
+    if not isinstance(org_cns, list):
+        org_cns = [org_cns]
+
+    all_orgs = wa.organisms.get_organisms()
+    if 'error' in all_orgs:
+        all_orgs = []
+    all_orgs = [org['commonName'] for org in all_orgs]
 
     org_data = []
-    for org_cn in org_cn_list:
-        # User must have read permission on organism
-        if not PermissionCheck(gx_user, org_cn, "READ"):
-            continue
-        indiv_org_data = export(org_cn, seqs)
-        org_data.append(indiv_org_data)
+    for org_cn in org_cns:
+        if org_cn not in all_orgs:
+            raise Exception("Could not find organism %s" % org_cn)
+
+        orgs = accessible_organisms(gx_user, [org_cn], 'READ')
+        if not orgs:
+            raise Exception("You do not have read permission on organism %s" % org_cn)
+
+        org = wa.organisms.show_organism(org_cn)
+
+        uuid_gff = wa.io.write_downloadable(org['commonName'], 'GFF3', export_gff3_fasta=True, sequences=seqs)
+        if 'error' in uuid_gff or 'uuid' not in uuid_gff:
+            raise Exception("Apollo failed to prepare the file for download: %s" % uuid_gff)
+        args.gff.write(wa.io.download(uuid_gff['uuid'], output_format="text"))
+
+        time.sleep(1)
+
+        uuid_vcf = wa.io.write_downloadable(org['commonName'], 'VCF', sequences=seqs)
+        if 'error' in uuid_vcf or 'uuid' not in uuid_vcf:
+            raise Exception("Apollo failed to prepare the file for download: %s" % uuid_vcf)
+        args.vcf.write(wa.io.download(uuid_vcf['uuid'], output_format="text"))
+
+        time.sleep(1)
+
+        uuid_fa = wa.io.write_downloadable(org['commonName'], 'FASTA', sequences=seqs, seq_type='cdna')
+        if 'error' in uuid_fa or 'uuid' not in uuid_fa:
+            raise Exception("Apollo failed to prepare the file for download: %s" % uuid_fa)
+        args.fasta_cdna.write(wa.io.download(uuid_fa['uuid'], output_format="text"))
+
+        time.sleep(1)
+
+        uuid_fa = wa.io.write_downloadable(org['commonName'], 'FASTA', sequences=seqs, seq_type='cds')
+        if 'error' in uuid_fa or 'uuid' not in uuid_fa:
+            raise Exception("Apollo failed to prepare the file for download: %s" % uuid_fa)
+        args.fasta_cds.write(wa.io.download(uuid_fa['uuid'], output_format="text"))
+
+        time.sleep(1)
+
+        uuid_fa = wa.io.write_downloadable(org['commonName'], 'FASTA', sequences=seqs, seq_type='peptide')
+        if 'error' in uuid_fa or 'uuid' not in uuid_fa:
+            raise Exception("Apollo failed to prepare the file for download: %s" % uuid_fa)
+        args.fasta_pep.write(wa.io.download(uuid_fa['uuid'], output_format="text"))
+
+        org_data.append(org)
+
     args.json.write(json.dumps(org_data, indent=2))
b
diff -r 29ce13734a5c -r d72192ec8e39 fetch_organism_jbrowse.py
--- a/fetch_organism_jbrowse.py Mon Jul 29 10:09:54 2019 -0400
+++ b/fetch_organism_jbrowse.py Mon Dec 02 05:46:45 2019 -0500
[
@@ -9,7 +9,13 @@
 import sys
 import time
 
-from webapollo import GuessOrg, OrgOrGuess, PermissionCheck, WAAuth, WebApolloInstance
+from apollo import accessible_organisms
+from apollo.util import GuessOrg, OrgOrGuess
+
+from arrow.apollo import get_apollo_instance
+
+from webapollo import UserObj, handle_credentials
+
 logging.basicConfig(level=logging.INFO)
 log = logging.getLogger(__name__)
 
@@ -52,27 +58,34 @@
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    WAAuth(parser)
     OrgOrGuess(parser)
     parser.add_argument('target_dir', help='Target directory')
     parser.add_argument('email', help='User Email')
 
     args = parser.parse_args()
 
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
+    wa = get_apollo_instance()
     # User must have an account
     org_cn = GuessOrg(args, wa)
     if isinstance(org_cn, list):
         org_cn = org_cn[0]
-    org = wa.organisms.findOrganismByCn(org_cn)
 
     # User must have an account, if not, create it
-    gx_user = wa.users.assertOrCreateUser(args.email)
+    gx_user = UserObj(**wa.users._assert_or_create_user(args.email))
+    handle_credentials(gx_user)
+
+    all_orgs = wa.organisms.get_organisms()
+    if 'error' in all_orgs:
+        all_orgs = []
+    all_orgs = [org['commonName'] for org in all_orgs]
+    if org_cn not in all_orgs:
+        raise Exception("Could not find organism %s" % org_cn)
 
     # User must have READ access
-
-    if not PermissionCheck(gx_user, org_cn, "READ"):
-        raise Exception("READ permissions are required for this action")
+    orgs = accessible_organisms(gx_user, [org_cn], 'READ')
+    if not orgs:
+        raise Exception("You do not have write permission on this organism")
+    org = wa.organisms.show_organism(org_cn)
 
     if not os.path.exists(args.target_dir):
         os.makedirs(args.target_dir)
@@ -94,7 +107,7 @@
     # files / folders before and after.
     sys.stderr.write(' '.join(cmd))
     sys.stderr.write('\n')
-    sys.stderr.write(subprocess.check_output(cmd))
+    sys.stderr.write(subprocess.check_output(cmd).decode(sys.stderr.encoding))
     if not are_dir_trees_equal(
         os.path.join(org['directory'].rstrip('/')),
         os.path.join(args.target_dir, 'data')
@@ -104,7 +117,7 @@
         sys.stderr.write('\n')
         sys.stderr.write(' '.join(cmd))
         sys.stderr.write('\n')
-        sys.stderr.write(subprocess.check_output(cmd))
+        sys.stderr.write(subprocess.check_output(cmd).decode(sys.stderr.encoding))
         if not are_dir_trees_equal(
             os.path.join(org['directory'].rstrip('/'), 'data'),
             os.path.join(args.target_dir, 'data')
@@ -113,7 +126,7 @@
             sys.stderr.write('\n')
             sys.stderr.write(' '.join(cmd))
             sys.stderr.write('\n')
-            sys.stderr.write(subprocess.check_output(cmd))
+            sys.stderr.write(subprocess.check_output(cmd).decode(sys.stderr.encoding))
             if not are_dir_trees_equal(
                 os.path.join(org['directory'].rstrip('/'), 'data'),
                 os.path.join(args.target_dir, 'data')
b
diff -r 29ce13734a5c -r d72192ec8e39 list_organisms.py
--- a/list_organisms.py Mon Jul 29 10:09:54 2019 -0400
+++ b/list_organisms.py Mon Dec 02 05:46:45 2019 -0500
b
@@ -4,19 +4,23 @@
 import argparse
 import json
 
-from webapollo import WAAuth, WebApolloInstance, accessible_organisms
+from apollo import accessible_organisms
+
+from arrow.apollo import get_apollo_instance
+
+from webapollo import UserObj, handle_credentials
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='List all organisms available in an Apollo instance')
-    WAAuth(parser)
     parser.add_argument('email', help='User Email')
     args = parser.parse_args()
 
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
+    wa = get_apollo_instance()
 
-    gx_user = wa.users.assertOrCreateUser(args.email)
+    gx_user = UserObj(**wa.users._assert_or_create_user(args.email))
+    handle_credentials(gx_user)
 
-    all_orgs = wa.organisms.findAllOrganisms()
+    all_orgs = wa.organisms.get_organisms()
 
     orgs = accessible_organisms(gx_user, all_orgs)
 
b
diff -r 29ce13734a5c -r d72192ec8e39 macros.xml
--- a/macros.xml Mon Jul 29 10:09:54 2019 -0400
+++ b/macros.xml Mon Dec 02 05:46:45 2019 -0500
[
@@ -1,14 +1,10 @@
 <?xml version="1.0"?>
 <macros>
-  <token name="@WRAPPER_VERSION@">4.0.0</token>
+  <token name="@WRAPPER_VERSION@">4.1</token>
 
   <xml name="requirements">
     <requirements>
-      <requirement type="package" version="2.7">python</requirement>
-      <requirement type="package" version="1.65">biopython</requirement>
-      <requirement type="package" version="0.6.2">bcbiogff</requirement>
-      <requirement type="package" version="2.12.4">requests</requirement>
-      <requirement type="package" version="1.11.0">six</requirement>
+      <requirement type="package" version="4.1">apollo</requirement>
       <yield/>
     </requirements>
   </xml>
@@ -19,20 +15,27 @@
   <token name="@URL@">
 "\$GALAXY_WEBAPOLLO_URL"
   </token>
-  <token name="@ADMIN_AUTH@">
-"\$GALAXY_WEBAPOLLO_URL"
-"\$GALAXY_WEBAPOLLO_USER"
-"\$GALAXY_WEBAPOLLO_PASSWORD"
-  </token>
+
+  <token name="@AUTH@"><![CDATA[
+      if [ -z "\$ARROW_GLOBAL_CONFIG_PATH" ]; then
+        echo "__default: local" > '.auth.yml' &&
+        echo "local:" >> '.auth.yml' &&
+        echo "    url: \"\$GALAXY_WEBAPOLLO_URL\"" >> '.auth.yml' &&
+        echo "    username: \"\$GALAXY_WEBAPOLLO_USER\"" >> '.auth.yml' &&
+        echo "    password: \"\$GALAXY_WEBAPOLLO_PASSWORD\"" >> '.auth.yml' &&
+
+        export ARROW_GLOBAL_CONFIG_PATH='.auth.yml'
+      ; fi &&
+  ]]></token>
 
   <token name="@ORG_OR_GUESS@">
 <![CDATA[
 #if $org_source.source_select == "auto_json":
-    --org_json "${org_source.org_file}"
+    --org_json '${org_source.org_file}'
 #elif $org_source.source_select == "select":
-    --org_id "${org_source.org_select}"
+    --org_id '${org_source.org_select}'
 #else:
-    --org_raw "${org_source.org_raw}"
+    --org_raw '${org_source.org_raw}'
 #end if
 ]]>
   </token>
@@ -42,13 +45,13 @@
 
 #if $cn_source.source_select == "auto":
     #if str($cn_source.cn_file) != "None":
-        --seq_fasta $cn_source.cn_file
+        --seq_fasta '$cn_source.cn_file'
     #end if
 #else
     #if $cn_source.source_select != "all" and len($cn_source.refseqs) > 0:
         --seq_raw
         #for $item in $cn_source.refseqs:
-            "${item.refseq}"
+            '${item.refseq}'
         #end for
     #end if
 #end if
@@ -93,12 +96,6 @@
     </conditional>
   </xml>
 
-  <xml name="test_result">
-      <assert_stderr>
-          <has_text text="MissingSchema" />
-      </assert_stderr>
-  </xml>
-
   <xml name="citations">
       <citations>
         <citation type="doi">10.1371/journal.pcbi.1006790</citation>
@@ -109,12 +106,12 @@
   </xml>
   <token name="@GENOME_SELECTOR_PRE@">
 #if $reference_genome.reference_genome_source == 'history':
-    ln -s $reference_genome.genome_fasta genomeref.fa;
+    ln -s '$reference_genome.genome_fasta' genomeref.fa;
 #end if
   </token>
   <token name="@GENOME_SELECTOR@">
 #if $reference_genome.reference_genome_source == 'cached':
-    "${reference_genome.fasta_indexes.fields.path}"
+    '${reference_genome.fasta_indexes.fields.path}'
 #elif $reference_genome.reference_genome_source == 'history':
     genomeref.fa
 #end if
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/arrow.yml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/arrow.yml Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,5 @@
+__default: local
+local:
+    url: "http://localhost:8888"
+    username: "admin@local.host"
+    password: "password"
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/bad-model.gff3
--- a/test-data/bad-model.gff3 Mon Jul 29 10:09:54 2019 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
b
@@ -1,9 +0,0 @@
-##gff-version 3
-##sequence-region Maroon_JMcDermott 1 144762
-Maroon_JMcDermott . gene 14488 14805 . + . Name=gene_26;date_creation=2016-02-17;owner=jmc_texas@tamu.edu;ID=707c88b7-36d1-44e3-93e6-d1d4f1219d57;date_last_modified=2016-02-17
-Maroon_JMcDermott . mRNA 14488 14805 . + . Name=gene_26-00001;date_creation=2016-02-17;Parent=707c88b7-36d1-44e3-93e6-d1d4f1219d57;owner=jmc_texas@tamu.edu;ID=8760695d-b88c-41c0-857b-540e6db81fe8;date_last_modified=2016-02-17
-Maroon_JMcDermott . CDS 14707 14805 . + 0 Name=94abf796-4c8d-45f4-916b-4d279616565e-CDS;Parent=8760695d-b88c-41c0-857b-540e6db81fe8;ID=94abf796-4c8d-45f4-916b-4d279616565e
-Maroon_JMcDermott . exon 14497 14805 . + . Name=d2ebd8d0-6558-4674-a38f-346f88256340-exon;Parent=8760695d-b88c-41c0-857b-540e6db81fe8;ID=d2ebd8d0-6558-4674-a38f-346f88256340
-Maroon_JMcDermott . exon 14488 14491 . + . Name=2e4119f9-3220-4502-8ddd-4821c872e0d6-exon;Parent=8760695d-b88c-41c0-857b-540e6db81fe8;ID=2e4119f9-3220-4502-8ddd-4821c872e0d6
-Maroon_JMcDermott . non_canonical_five_prime_splice_site 14494 14494 . + . Name=8760695d-b88c-41c0-857b-540e6db81fe8-non_canonical_five_prime_splice_site-14493;Parent=8760695d-b88c-41c0-857b-540e6db81fe8;ID=8760695d-b88c-41c0-857b-540e6db81fe8-non_canonical_five_prime_splice_site-14493
-Maroon_JMcDermott . non_canonical_three_prime_splice_site 14497 14497 . + . Name=8760695d-b88c-41c0-857b-540e6db81fe8-non_canonical_three_prive_splice_site-14496;Parent=8760695d-b88c-41c0-857b-540e6db81fe8;ID=8760695d-b88c-41c0-857b-540e6db81fe8-non_canonical_three_prive_splice_site-14496
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/create_org/output.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/create_org/output.json Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,16 @@
+{
+  "commonName": "Test org",
+  "blatdb": "/data/temporary/apollo_data/1384-Test_org/searchDatabaseData/genome.2bit",
+  "metadata": "{\"creator\":\"20\"}",
+  "annotationCount": 0,
+  "currentOrganism": true,
+  "obsolete": false,
+  "sequences": 1,
+  "directory": "/XX/apollo_shared_dir/1",
+  "publicMode": false,
+  "valid": true,
+  "genus": "genus",
+  "species": null,
+  "id": 23,
+  "nonDefaultTranslationTable": null
+}
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/create_org/output2.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/create_org/output2.json Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,16 @@
+{
+  "commonName": "Test org",
+  "blatdb": "/data/temporary/apollo_data/1384-Test_org/searchDatabaseData/genome.2bit",
+  "metadata": "{\"creator\":\"20\"}",
+  "annotationCount": 0,
+  "currentOrganism": true,
+  "obsolete": false,
+  "sequences": 1,
+  "directory": "/XX/apollo_shared_dir/3",
+  "publicMode": false,
+  "valid": true,
+  "genus": "genus2",
+  "species": "sp",
+  "id": 23,
+  "nonDefaultTranslationTable": null
+}
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1.dat
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1.dat Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <title>JBrowse</title>
+
+    <link rel="apple-touch-icon" sizes="180x180" href="img/favicons/apple-touch-icon.png">
+    <link rel="icon" type="image/png" sizes="32x32" href="img/favicons/favicon-32x32.png">
+    <link rel="icon" type="image/png" sizes="16x16" href="img/favicons/favicon-16x16.png">
+    <link rel="manifest" href="site.webmanifest">
+    <link rel="mask-icon" href="img/favicons/safari-pinned-tab.svg" color="#5bbad5">
+    <meta name="msapplication-TileColor" content="#2d89ef">
+    <meta name="theme-color" content="#ffffff">
+
+    <script type="text/javascript">
+        window.onerror=function(msg){
+            if( document.body )
+                document.body.setAttribute("JSError",msg);
+        }
+        if(window.process&&process.versions&&process.versions.electron) {
+            window.electronRequire = require;
+            delete window.require;
+        }
+    </script>
+    <style>
+        html, body, div.jbrowse {
+            margin: 0;
+            padding: 0;
+            height: 100%;
+            width: 100%;
+        }
+    </style>
+    <script type="text/javascript" src="dist/main.bundle.js" charset="utf-8"></script>
+  </head>
+
+  <body>
+    <div class="jbrowse" id="GenomeBrowser" data-config='"allowCrossOriginDataRoot": false, "cacheBuster": true'>
+      <div id="LoadingScreen" style="padding: 50px;">
+        <h1>Loading...</h1>
+      </div>
+    </div>
+    <div style="display: none">JBrowseDefaultMainPage</div>
+  </body>
+</html>
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/.htaccess
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/.htaccess Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,10 @@
+# This Apache .htaccess file is generated by JBrowse (GenomeDB) for
+# allowing cross-origin requests as defined by the Cross-Origin
+# Resource Sharing working draft from the W3C
+# (http://www.w3.org/TR/cors/).  In order for Apache to pay attention
+# to this, it must have mod_headers enabled, and its AllowOverride
+# configuration directive must allow FileInfo overrides.
+<IfModule mod_headers.c>
+    Header onsuccess set Access-Control-Allow-Origin *
+    Header onsuccess set Access-Control-Allow-Headers X-Requested-With,Range
+</IfModule>
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/names/02b/9.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/names/02b/9.json Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,1 @@
+{"merli":{"exact":[],"prefix":["Merlin"]}}
\ No newline at end of file
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/names/0e9/3.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/names/0e9/3.json Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,1 @@
+{"mer":{"prefix":["Merlin"],"exact":[]}}
\ No newline at end of file
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/names/83f/8.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/names/83f/8.json Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,1 @@
+{"merlin":{"prefix":[],"exact":[["Merlin",null,"Merlin",null,0,172788,null]]}}
\ No newline at end of file
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/names/92c/2.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/names/92c/2.json Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,1 @@
+{"me":{"prefix":["Merlin"],"exact":[]}}
\ No newline at end of file
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/names/cf0/e.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/names/cf0/e.json Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,1 @@
+{"merl":{"prefix":["Merlin"],"exact":[]}}
\ No newline at end of file
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/names/f26/8.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/names/f26/8.json Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,1 @@
+{"m":{"exact":[],"prefix":["Merlin"]}}
\ No newline at end of file
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/names/meta.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/names/meta.json Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,1 @@
+{"compress":0,"track_names":[],"format":"json","lowercase_keys":1,"hash_bits":16}
\ No newline at end of file
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/raw/4ced49b280a72a29f1b922ae1a9664c8_0.gff.gz
b
Binary file test-data/dataset_1_files/data/raw/4ced49b280a72a29f1b922ae1a9664c8_0.gff.gz has changed
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/raw/4ced49b280a72a29f1b922ae1a9664c8_0.gff.gz.tbi
b
Binary file test-data/dataset_1_files/data/raw/4ced49b280a72a29f1b922ae1a9664c8_0.gff.gz.tbi has changed
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/seq/genome.fasta
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/seq/genome.fasta Mon Dec 02 05:46:45 2019 -0500
b
b'@@ -0,0 +1,2881 @@\n+>Merlin\n+TCGTTTAGACAAAGGTACATTATTGTATCGTGGCCAAAAATTAGACCTTCCTACATTCGA\n+GCATAACGCAGAGAATAAGTTGTTCTATTTCAGAAACTACGTTTCAACTTCATTAAAGCC\n+TCTGATCTTTGGTGAATTTGGTCGTATGTTTATGGCACTAGATGACGATACTACAATTTA\n+TACTGCTGAGACGCCTGATGATTATAATCGTTTCGCAAACCCAGAAGATATAATTGATAT\n+TGGCGCTACTCAAAAAGACTCATTTGACGATAACAATAATGATGGAACATCTATTAATAT\n+CGGCAAACAAGTTAATTTAGGATTCGTTATTTCCGGTGCTGAAAATGTTCGAGTTATTGT\n+TCCAGGTTCTTTAACTGAATATCCAGAAGAAGCGGAAGTTATTCTGCCTCGTGGTACTCT\n+TTTGAAGATCAATAAAATCACTACTCAAGTAGATAAACGCTCGAATAAGTTCATGGTTGA\n+AGGTTCAATCGTTCCGCCTTCTGAGCAAATTGATGAATCTGTTGAGATTTATGACGGTGA\n+TCTGTTCATGGAAACAGGTGAAGTAGTAAAACTGTCCGGATTCATGCAGTTCGTCAACGA\n+ATCTGCATACGATGAAGAGCAAAACCAGATGGCTGCTGAGATTCTGTCTGGATTCTTGGA\n+CATTGATGACATGCCACGTAAGTTCCGCTAGCCGTTTACATCCACATGGAAGTGGATTAT\n+AATGGCTCTACGTTAACAAGAGGAAAACAACATGAAATCAATTTTTCGTATCAACGGTGT\n+AGAAATTGTAGTTGAAGATGTAGTTCCTATGTCTTATGAATTCAATGAAGTTGTTTTCAA\n+AGAGCTTAAGAAAATTTTAGGCGATAAGAAGCTTCAAAGTACTCCAATTGGACGTTTTGG\n+AATGAAAGAAAACGTTGATACTTATATTGAAAGTGTAGTGACAGGGCAGTTAGAAGGTGA\n+ATTTTCTGTAGCAGTTCAAACTGTAGAAAATGATGAAGTTATTTTAACTTTACCAGCTTT\n+CGTAATTTTCCGCAAATAAAACAATGGGGAGCTATGCTCCCCATTTTTACAATCCAAGTA\n+TTTTCGAAGTAGAGTTTCGGGTCGAATTAATGACGTGAGACAACCCTCCAGCAGCTCCTC\n+CAAGTCTAGATAATCTACTTAAACTTCCATTAAGAGACATTTCACTATTAATTCCAGTTA\n+TAGAATTAACAGCTCTATCTTCAATCCAATCAAGAGCAGCTTGACGTCCAACAGCACCCG\n+TTTGCATTACTCTGTAAGCAAATGTAACATCGAAAACCGCAATTTGGTTATCTCCTTCAT\n+ATGTAAGCTCAGGAGCTCCACACGCAACAGGAACACAACCTGTGAACATTATCACAGTAT\n+GAGGTAATCCATTTCGAGCATGAAGGTTAACCTGAATGTCAGCTTCGACGTCAGTTGGTA\n+ATGCTCGCAATCCAGTAACCGGGTCTTGAACGGAGTTCACCCAATCTTGCATTGCACGAT\n+AGTTACTTGCTTCGGGATCCATTCTGAATGATATAGTTAACGGATCGAGTTCACGTCCAG\n+TTATTCTAATATTCGGTGAGTTATGGTTGAAATCCATTTCATGAGACAATCTGTTCTCTG\n+GAATTTTGACCGAATAAATCATCAATCCAGATTGCGGATAAGCCATGTTAAAGAAGTCTA\n+ACAAATAAGTTCCGACTTCAAATTCACCTAATAAAGACTGAACAACACGATTGCTCATTG\n+CTCCAATAAGATATTTCGATACACCAGACTTTCTTACCAGCTGTTGAGTACCGGCAGTGA\n+TAATTGAGGTGAGTCCTGATGTGAACTCACCTTGTGTTAATCCAAGCCAGTCATTATTCA\n+ACGGAAGGTTATTAAAGAGCATACCGCCAAATTGATCGAGTAATTGTTGAGACTTTGCTG\n+ACGGAGTAGTTGCAAATACACAACTAAACATATTAGTACGCTGAAAGTCTATATTACCCG\n+CTTGGTTTTTAAATTCATCTAAAGTTAGCATCAGAATCCTTCCGCATATACTGAAGCTCG\n+GTTCAATGTCAAGATTTCACGCATAGTAATTTCTAATGTGAATGTACTTGGCAGGTTTGG\n+AGCTATAGCTAAACCGTTAAAGTTTCCATTTGGAGTTTTATCAAAACGGATACTCTGAAT\n+TTGACATGGACCGAATACTTCAGCACGTCCATCGAATTTACTTGTGGTTCCAAAGTTTCT\n+GACGAACCACACAGTAGGGTTACTTACAACAATAACATTACTTAAGAATGAAGTTATTTT\n+CTCAAAAACAGTGTCATTTTTATTAGCTTCATCTGGAGTTAATGTATCAAGGAAAGTTGA\n+TTTATACCATTCATCTAATTGAGACTTAACTTCTTTTGCATAAGTAGACGTTCCCGTTTC\n+GCCATAACTATAGTAGTTAAAGTATTCATAGATCTCGATAATAGCAATAAGATCTTGTAC\n+TGATCGAGGAGTTAAATCCCACGTGAATACCTTCGTACGGTTATCTGCGCCGCCATACAT\n+TGATCGAGCAGTGTTATAGATCTGCTCGTTATGGTCAGCCATTAATCCTTGAGTCAATGA\n+CTCTAATCCGCCAAAGACAGCAGTAGATGCAACGTTACTTAATACCCCTGTAGCAGTACC\n+GCCGCCACGAGAAATAAGTGAATCTCCAACGTCATTAAATTTATGAGAAACTGATTCAAC\n+ATCTGATTTCGAGCGTGGAAGTAAAATATTCACTACTGGAATTTTATCAACTTTATTAGT\n+ATTTGTTCCAGTGATTGATTTCACTACACTATTTGCAGTACGTTTCATTTCACCTAAACG\n+CATGCTACGCATATCACCGGTTGTACGAGAATTCATATCATACGCAGTGAACAACAACCC\n+GTTCTTATAAAGATCATGAACTCGTAAAGAACCAGATGTGTCATTACCAGCTGAACGTTC\n+AGACGGATATTGCGCAGTTATAGTGGATTTTATTTTTGCTGATTGTGAACTTTGACCAGC\n+GGAGGTTTTAACTCCGCTAATTAAAGCATCAGTCTTATCATCTAATTCTCTGACTTTAAT\n+GCTCATTAATTAACTCCTGTTGCCCCGAATACTCCAGGAGCTGGAGTAGCCGTGACTGTT\n+TGAACCTGGTGAATAGTCTTACTATTATTTACGTTATTAACCTGAGTGTTAGCAACATTC\n+ATATCACCGGTTGATTTTTTAGATTGCTCTTTAGCATTTTCAGCTTTTTGAATATTTTGA\n+ACTCGTTGATTATCTTCCGAAGTAGCTGGAGCCGCAGGCTTCGGAGTGTTATCTTCTTTG\n+AGCTTCTGATACTTGGATTCTACTCGTTGGAATCTTTTATCGAGTTCCTTTTTAGTAGCT\n+GGTTGATCACTTATAGCAGAATCACTAATAGACTTTTTGGCACTGTTATATGCCTTCTCT\n+AAAGATTGCATATTAGTTGGATTCTCTGGATCAACATCACCAATATATTTTTCTAAACGC\n+TGAACAGCTGCACGAGCTTCGTTTTGTTTGATCAGTGTTTCTTCGCGTTTTTCAGGAGCC\n+ATTGCTTTAAGATTCTGAGTCTCTTGATCACGGTCAGATGCTTGTGTAGAATCGATTTTA\n+TTCTCTCTTCCTAGTACCCAATCAAATGCACGAGTTTTAAATTCGCCAGCTTTATCAATA\n+ATTCCAGGACCTTCTTCAATACGCTTACTCTGATATTTAGCCAAAGCTTTTTGATCATCT\n+TCAGACAATGAATTACCAGTGCGTTCCTGGAATCCTTCTAGTGCTGAACCACGAATAGTA\n+GTTGCTGCATTTTCAAAGCCAAGTGCATCGAGTATAGAAGCAGATATCTTTGAAATTCCC\n+AA'..b'ATTTCCATGAGGTTACTGGGTTATGAGTTATAAAATTCTTTT\n+AGAAGTTACCGTGATGTCTTCGACTGGACATGTGGCGGTTAGTACTGAACAGCTGGATTT\n+TTATAGCTGGGATAATGCTAATATGTATTATGAAGCAGTAGAAGTTTATGAAGAAACGCC\n+AGATATTAAAGTATGGCGTCAAGTAACAAAACTTTATTAAAGCCCTTCGGGGCTTTTGTT\n+GTCTATAAATATAGTAAACTATAGAGGACTTTTTATGATCGAATTAAATGAAGTCTTCGA\n+TGAAGGGAAAGAACGTCTAGCAGTTACGAACCTTTATCCGAAGCTCAAGATTCCACAAAT\n+TTTTGCAATAGACAACACTAAAGTAGCTTATCGTATGTGCTCATATACTGGTGGTGGAGA\n+TGCAAATAAAAACATCAAACCCGGTGATAAAATGATGCATGTCATTGCATTAGGAGTTAC\n+TGATAAAGGCCTTGGTCAACTTAAGACCTTAGGTGATAATCCAATTGCTGTTATTGATAC\n+AATCTTTAACCACGTAATGGGTATCATGAAGTTTTATCGTTTTGACGCTGCTTTATTTCG\n+TGTTAAAAAGAATAAAACTGGTGGAGCAGGTCGCCAGATGCAAGTTATTGTTGATCGTCT\n+AATCAAGAAGAAAGGCGGTGGCAAATTCGTTATGCTTAAAGAGTTGTATGATTTTGATAA\n+GAAATACAACTACATTTTAGTATACAAGAAGAATGCTGATCTTGTCAATATCCCTGGAAT\n+GACTGAGATCATGGACTCAATTTATAAGAAAGTAGACACTGATGTAGGTGATGCTTATAT\n+CAACGTTGAGACCGGCAAACAAGTATCTAAGCTTGAAGCTATCGCGGGTTCAATCGCAGC\n+AGAAAATGATAAACGCTCAGACCAGGCGGTTGCGTCTCGAGCTAAAATATCTCGTCGTGC\n+TTTAATGGCTTCTCAATATTCAATCCAAGTGGGATTTGATACTCGTAAAGATGCGGTAGA\n+ACATGATAAGCGATTAGATGTAATTAACTCTAAACCTCCGGTTTATTTGACAGATAAGTC\n+TTCTGACCAAGTATCGAATATTCAAATGGCTATTGATAATTTCAGAAATGATTCTCAATC\n+AATTGCTAAAACCGGCGAAGCGTTTAAGACATTTGACCCGTCATGGAAAATGGATGATGA\n+TCGTCATTCTACTGGTACAATGAAAGCCCAAGAACTTGTTCTAAGGCTCACTAATATATT\n+AACCAGTGGAACAGTAGACGATTTCAGTCAACATCCTACTGATAGAAGAGAAGCATTTAA\n+AACATTAGCGGTCAGAGACATTTATCGTATTGGTGAAGCCTGGTCTAAATTAGAGCCTAA\n+TGACTATTATGGTGCTATTAAAGAACTTACTCGAGTCGCAATGGAAGACAAAGAATGGTC\n+TTCTGATGCAAATCGTGAATACGCAGTAAAAGAGATTGTAGAATTAATTTCTAAACAGTT\n+CTCTGATTTAGCAGCTAGCATGTACAAAAATACATCAGATGTGGATCGTTATACTCCGGT\n+ACAATTGTCAGGTTTACATGCTTACGTCGGTTCATCTTATAAGTACATCAACGACTATCT\n+TTTAGGCCTTGATGATTATGGCAAAGAAACTGTTGAAAAATGGATTGAGTCTATCGATTC\n+TGCGTTTGAAAATGGTGTTCGTCTTCCGAAGGGAACTAAGCTATTTCGAGGTCAACATAC\n+TAAGCGCGAAGCTATTGAAGTTAGTTTAGAAAACAAGCACTTCTATTTCAAGAATTATGT\n+GTCAACTTCAATGGCTCCTATTATCTTTGGTGGATATGGACGAGCATATGATGCAATGGA\n+CCCCGCTGCATTGAACACAGATACATCGACTCCTAAAGAAGTGCTTGACTCTGTTTCAAC\n+TGTTCGGCCTGATAGTATTACTAACTCTGAAATGGGTGAATTGCGTTTAGCGTTCGTTAT\n+TTCTGGCGCAGAGAAAATAAAGACTATCGTAACCAATGCTGGAATCTCAGGATTGTCATT\n+TGAAGCTGAAGTTATTCTTCCTCGTGGTACTGTTCTTAGAATTGATAAAATGTATGGAAC\n+AGCTCAGAAACTTCAAGCTAATGACTACACAGCATCAAAGAGTGTTCTTATGGAATGCAC\n+TGTAGTATCTCCAGAACAATTATCTGAAACTACAATTTATGATGGCGATAAATTGTTAGA\n+AGGTGAATTGGTTGAATCTGATTATTCGTTCAGTTCTTTTATTGGTCAATTAAATGAAGC\n+TAAAGTTGAAACACCAGATTGGTTAGGTGAAGCTCTAGCATCATTTGTTGACATAAATAA\n+TTTACCAGAACGATTCATAAATTAATATTTTCACATGGACGTGAATTCAGAGAGGGCTTT\n+ATGGAAATTTTAAACGAAGTACTAGACGAAAGTAAACTGGATTTACCAGTTACGAACCTT\n+TATCCAAAGACGAAAATTCCACAAATTTTTGCTATTCAAACTAACTCCGAGGGTTCACTG\n+CCAGCATTCAGGATGTGTTCATATACATCTGGCGGTGATACCAATAAGAACGTTAAACCT\n+GGCGACAAAATGATTCATGTTGTTATGCTATCATTGAGCGAAAAAGGATCATTAGTTAAG\n+CTTAAAAACTTAGGCGGCGATCCAATTGGTGTTATCTCTACTACGTTCAATATCGTTTAT\n+TCAACGATGAAGCAGTATAAAATGGACGCATGCTTGTTCCGAATGGCCAAAAGCAAAATC\n+GGTGGACAAGCTCGTCAGATGCAGGTTATTATGGACCGACTCGTACGTTCTCGTACTGGT\n+GGTAAATTTGTTATCCTGAAAGAACTCTGGGATTATGATAAGAAGTACGCATATATTCTT\n+ATTCATCGTAAAAATGTTGATCTCTCAACCATCCCTGGCGTCCCAGAGATTGATACTGGA\n+CTGTTCACTGCAGTTGAAACTAAAGTTGGTGAAGTTTATGTTGAAAAGAAATCAGGTCAA\n+CAAGTAACTAAAGCCCAAGCCGTTGCTGCTTCTATTGCAGTCGAAAACGATAAGCGTTCA\n+GATCAAAACGTTATTTCTCGTGCTAAGATAAATCGTCGTCAAGCTATTGCTGCTCAGTAT\n+TCTGTTGATGCATCTAGCATCCAAGGCGATGATCGTGCTGCTGAAGAATTTAAACGCTTA\n+GAAGCTAAAGTTCCAGTTAAAAGCTCTAAAGGCGCTGAGTCATCAGACATGGTAGCAAAA\n+GTTAATACCATCGCTGACCGTCAAGGAAATGAGTATATCGGCAAAGTACTAAACTTCATC\n+ACTAATCCTGAAACATCTCAGGACACAGATGGTAAAGCATTGACTGCACGAATAGGTCAA\n+TTGCGCCAGTTATCTAAAATGCCTAAAGGTGCCATGTTATCAGGTGGATTTGAAACTGGT\n+GGTATGAAGTACTACATGGAAAACCAAAAAGAAATGTACAATGAAGTTCGTTCATTTGCT\n+CGATTGATAGCTGGGGTGAATACAACTAACTCCTTTCAGACGATGAAAGATTTAGTTAAA\n+ATGGCTTCAGCTGGAACTAGACCTGAAGATCGTGAACAGTTAATTGCAAATTTAATTGGA\n+TTAGCTTATAAAGAAATAAGTGCAATCATCAGAGATTCATACCAAACTGCAGCAAGTTTA\n+TCTAAAGAGAATGATCATTATTCTAAAGATGAAAAACAAGCTATCAGTGAATACTGCGCA\n+AACGCTTTCGAATACGTGAATATGTTCTTAATCGGTAAGCCGGAAGAAGGGTATTCAACT\n+TCTGATTCTCTCGAGATCATCGATAATATGGACTCTGCGTTTGAAAAAGGAACTCGTTTA\n+GACAAAGGTACATTATTGTATCGTGGCCAAAAATTAGACCTTCCTACA\n'
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/seq/genome.fasta.fai
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/seq/genome.fasta.fai Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,1 @@
+Merlin 172788 8 60 61
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/seq/refSeqs.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/seq/refSeqs.json Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,1 @@
+[{"end":172788,"length":172788,"line_byte_length":"61","line_length":"60","name":"Merlin","offset":"8","start":0}]
\ No newline at end of file
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/data/trackList.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/data/trackList.json Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,170 @@
+{
+   "formatVersion" : 1,
+   "hideGenomeOptions" : false,
+   "names" : {
+      "type" : "Hash",
+      "url" : "names/"
+   },
+   "plugins" : [
+      {
+         "location" : "https://cdn.jsdelivr.net/gh/TAMU-CPT/blastview@97572a21b7f011c2b4d9a0b5af40e292d694cbef/",
+         "name" : "BlastView"
+      }
+   ],
+   "refSeqs" : "seq/genome.fasta.fai",
+   "shareLink" : true,
+   "show_menu" : true,
+   "show_nav" : true,
+   "show_overview" : true,
+   "show_tracklist" : true,
+   "tracks" : [
+      {
+         "category" : "Reference sequence",
+         "codonStarts" : [
+            "TTG",
+            "CTG",
+            "ATG"
+         ],
+         "codonStops" : [
+            "TAA",
+            "TAG",
+            "TGA"
+         ],
+         "codonTable" : {
+            "AAA" : "K",
+            "AAC" : "N",
+            "AAG" : "K",
+            "AAT" : "N",
+            "ACA" : "T",
+            "ACC" : "T",
+            "ACG" : "T",
+            "ACT" : "T",
+            "AGA" : "R",
+            "AGC" : "S",
+            "AGG" : "R",
+            "AGT" : "S",
+            "ATA" : "I",
+            "ATC" : "I",
+            "ATG" : "M",
+            "ATT" : "I",
+            "CAA" : "Q",
+            "CAC" : "H",
+            "CAG" : "Q",
+            "CAT" : "H",
+            "CCA" : "P",
+            "CCC" : "P",
+            "CCG" : "P",
+            "CCT" : "P",
+            "CGA" : "R",
+            "CGC" : "R",
+            "CGG" : "R",
+            "CGT" : "R",
+            "CTA" : "L",
+            "CTC" : "L",
+            "CTG" : "L",
+            "CTT" : "L",
+            "GAA" : "E",
+            "GAC" : "D",
+            "GAG" : "E",
+            "GAT" : "D",
+            "GCA" : "A",
+            "GCC" : "A",
+            "GCG" : "A",
+            "GCT" : "A",
+            "GGA" : "G",
+            "GGC" : "G",
+            "GGG" : "G",
+            "GGT" : "G",
+            "GTA" : "V",
+            "GTC" : "V",
+            "GTG" : "V",
+            "GTT" : "V",
+            "TAC" : "Y",
+            "TAT" : "Y",
+            "TCA" : "S",
+            "TCC" : "S",
+            "TCG" : "S",
+            "TCT" : "S",
+            "TGC" : "C",
+            "TGG" : "W",
+            "TGT" : "C",
+            "TTA" : "L",
+            "TTC" : "F",
+            "TTG" : "L",
+            "TTT" : "F"
+         },
+         "faiUrlTemplate" : "seq/genome.fasta.fai",
+         "key" : "Reference sequence",
+         "label" : "DNA",
+         "metadata" : {
+            "dataset_edam_format" : "<a target=\"_blank\" href=\"http://edamontology.org/format_1929\">fasta</a>",
+            "dataset_file_ext" : "fasta",
+            "dataset_hid" : "1",
+            "dataset_id" : "7495a4247e72f5f1",
+            "dataset_size" : "171.6 KB",
+            "history_display_name" : "<a target=\"_blank\" href=\"http://localhost/history/view/d29e465b351a50c9\">Unnamed history</a>",
+            "history_id" : "d29e465b351a50c9",
+            "history_user_email" : "<a href=\"mailto:anthony.bretaudeau@irisa.fr\">anthony.bretaudeau@irisa.fr</a>",
+            "history_user_id" : "17",
+            "metadata_data_lines" : "2881",
+            "metadata_dbkey" : "?",
+            "metadata_sequences" : "1",
+            "tool_tool" : "<a target=\"_blank\" href=\"http://localhost/datasets/7495a4247e72f5f1/show_params\">upload1</a>",
+            "tool_tool_id" : "upload1",
+            "tool_tool_version" : "1.1.6"
+         },
+         "seqType" : "dna",
+         "storeClass" : "JBrowse/Store/SeqFeature/IndexedFasta",
+         "type" : "SequenceTrack",
+         "urlTemplate" : "seq/genome.fasta",
+         "useAsRefSeqStore" : 1
+      },
+      {
+         "category" : "Default",
+         "key" : "merlin.gff",
+         "label" : "4ced49b280a72a29f1b922ae1a9664c8_0",
+         "maxHeight" : "600",
+         "menuTemplate" : [
+            {},
+            {},
+            {},
+            {}
+         ],
+         "metadata" : {
+            "dataset_edam_format" : "<a target=\"_blank\" href=\"http://edamontology.org/format_1975\">gff3</a>",
+            "dataset_file_ext" : "gff3",
+            "dataset_hid" : "2",
+            "dataset_id" : "b02ee2031011d9cf",
+            "dataset_size" : "110.3 KB",
+            "history_display_name" : "<a target=\"_blank\" href=\"http://localhost/history/view/d29e465b351a50c9\">Unnamed history</a>",
+            "history_id" : "d29e465b351a50c9",
+            "history_user_email" : "<a href=\"mailto:anthony.bretaudeau@irisa.fr\">anthony.bretaudeau@irisa.fr</a>",
+            "history_user_id" : "17",
+            "metadata_attributes" : "4",
+            "metadata_columns" : "9",
+            "metadata_comment_lines" : "2",
+            "metadata_data_lines" : "1228",
+            "metadata_dbkey" : "?",
+            "metadata_delimiter" : "__tc__",
+            "tool_tool" : "<a target=\"_blank\" href=\"http://localhost/datasets/b02ee2031011d9cf/show_params\">upload1</a>",
+            "tool_tool_id" : "upload1",
+            "tool_tool_version" : "1.1.6"
+         },
+         "overrideDraggable" : false,
+         "overridePlugins" : false,
+         "storeClass" : "JBrowse/Store/SeqFeature/GFF3Tabix",
+         "style" : {
+            "className" : "feature",
+            "color" : "#a6cee3",
+            "description" : "note,description",
+            "label" : "product,name,id"
+         },
+         "trackType" : "NeatHTMLFeatures/View/Track/NeatFeatures",
+         "type" : "NeatHTMLFeatures/View/Track/NeatFeatures",
+         "urlTemplate" : "raw/4ced49b280a72a29f1b922ae1a9664c8_0.gff.gz"
+      }
+   ],
+   "view" : {
+      "trackPadding" : 20
+   }
+}
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/galaxy.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/galaxy.xml Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<root>
+    <metadata>
+        <gencode>1</gencode>
+        <genomes>
+              <genome path="/opt/galaxy-dist/database/files/002/188/dataset_2188862.dat">
+                <metadata>
+                  <dataset id="7495a4247e72f5f1" hid="1"
+                      size="171.6 KB"
+                      edam_format="format_1929"
+                      file_ext="fasta" />
+                  <history id="d29e465b351a50c9"
+                      user_email="anthony.bretaudeau@irisa.fr"
+                      user_id="17"
+                      display_name="Unnamed history"/>
+                  <metadata
+                      dbkey="?"
+                      data_lines="2881"
+                      sequences="1"
+                      />
+                  <tool
+                      tool_id="upload1"
+                      tool_version="1.1.6"
+                      />
+                </metadata>
+              </genome>
+        </genomes>
+        <general>
+            <defaultLocation></defaultLocation>
+            <trackPadding>20</trackPadding>
+
+            <shareLink>true</shareLink>
+            <aboutDescription></aboutDescription>
+            <show_tracklist>true</show_tracklist>
+            <show_nav>true</show_nav>
+            <show_overview>true</show_overview>
+            <show_menu>true</show_menu>
+            <hideGenomeOptions>false</hideGenomeOptions>
+        </general>
+        <galaxyUrl>http://localhost</galaxyUrl>
+    </metadata>
+    <tracks>
+        <track cat="Default" format="gene_calls" visibility="default_off">
+            <files>
+              <trackFile path="/opt/galaxy-dist/database/files/002/188/dataset_2188863.dat" ext="gff3" label="merlin.gff">
+                <metadata>
+                  <dataset id="b02ee2031011d9cf" hid="2"
+                      size="110.3 KB"
+                      edam_format="format_1975"
+                      file_ext="gff3" />
+                  <history id="d29e465b351a50c9"
+                      user_email="anthony.bretaudeau@irisa.fr"
+                      user_id="17"
+                      display_name="Unnamed history"/>
+                  <metadata
+                      dbkey="?"
+                      data_lines="1228"
+                      comment_lines="2"
+                      columns="9"
+                      delimiter="__tc__"
+                      attributes="4"
+                      />
+                  <tool
+                      tool_id="upload1"
+                      tool_version="1.1.6"
+                      />
+                </metadata>
+              </trackFile>
+            </files>
+
+            <options>
+                <style>
+                    <overridePlugins>False</overridePlugins>
+                    <overrideDraggable>False</overrideDraggable>
+                    <className>feature</className>
+                    <description>note,description</description>
+                    <label>product,name,id</label>
+                    <height>10px</height>
+                    <maxHeight>600</maxHeight>
+                </style>
+                <scaling>
+                        <method>ignore</method>
+                        <scheme>
+                            <color>__auto__</color>
+                        </scheme>
+                </scaling>
+                <menus>
+                </menus>
+                <custom_config>
+                </custom_config>
+
+                <gff>
+                    <trackType>NeatHTMLFeatures/View/Track/NeatFeatures</trackType>
+                    <index>false</index>
+                </gff>
+            </options>
+        </track>
+    </tracks>
+    <plugins
+        ComboTrackSelector=""
+        Bookmarks=""
+        GCContent=""
+        BlastView="True"
+        theme=""
+        />
+</root>
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/jbrowse.conf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/jbrowse.conf Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,110 @@
+#### JBrowse main configuration file
+
+## uncomment the section below to customize this browser's title and description
+# [aboutThisBrowser]
+# title = <i>Oryza sativa</i>
+# description = Browser for O. sativa transcripts and RNA-seq data,
+#   produced by the Smith laboratory at Example State University.
+
+## uncomment and edit the example below to configure a faceted track selector
+# [trackSelector]
+# type = Faceted
+# displayColumns =
+#   + label
+#   + key
+#   + organism
+#   + technique
+## optionally sort the faceted track selector by column (use the names from displayColumns)
+# initialSortColumn=label
+## optionally give different names to some of the data facets using renameFacets
+# [trackSelector.renameFacets]
+# submission = Submission ID
+# developmental-stage = Conditions
+# cell-line = Cell Line
+# key = Dataset
+# label = Track
+
+## uncomment this section to get hierarchical trackselector options
+# [trackSelector]
+## optionally turn off sorting for the hierarchical track selector
+# sortHierarchical = false
+## set collapsed categories for the hierarchical track selector
+# collapsedCategories = Reference sequence,Quantitative / XY Plot
+## set category ordering in the hierarchical track selector
+# categoryOrder = BAM, Transcripts, Quantitative/Density, VCF
+
+## configure where to get metadata about tracks.  always indexes the
+## `metadata` part of each track config, but this can be used to load
+## additional metadata from CSV or JSON urls
+# [trackMetadata]
+# sources = data/trackMetadata.csv
+
+
+[GENERAL]
+
+
+## add a document.domain to set the same-origin policy
+# documentDomain=foobar.com
+
+## use classic jbrowse menu with file instead of track and genome
+#classicMenu = true
+
+## hide open genome option
+#hideGenomeOptions = true
+
+## enable or disable high resolution rendering for canvas features. set to auto, disabled, or numerical scaling factor. default: 2
+# highResolutionMode=auto
+
+## uncomment to change the default sort order of the reference
+## sequence dropdown
+# refSeqOrder = length descending
+
+## Uncomment to prevent HTML tracks from displaying gene subfeatures (enabled by default)
+# inferHTMLSubfeatures = false
+
+## to set a default data directory other than 'data', uncomment and
+## edit the line below
+# dataRoot = data
+
+## optionally add more include statements to load and merge in more
+## configuration files
+include  = {dataRoot}/trackList.json
+include += {dataRoot}/tracks.conf
+# include += ../url/of/my/other/config.json
+# include += another_config.conf
+
+## uncomment and edit the example below to enable one or more
+## JBrowse plugins
+# [ plugins.MyPlugin ]
+# location = plugins/MyPlugin
+# [ plugins.AnotherPlugin ]
+# location = ../plugin/dir/someplace/else
+
+## edit the datasets list below to add datasets to the jbrowse dataset
+## selector
+
+# [datasets.volvox]
+# url  = ?data=sample_data/json/volvox
+# name = Volvox Example
+
+# [datasets.modencode]
+# url  = ?data=sample_data/json/modencode
+# name = MODEncode Example
+
+# [datasets.yeast]
+# url  = ?data=sample_data/json/yeast
+# name = Yeast Example
+[ plugins.BlastView ]
+location = ../plugin/BlastView/
+[ plugins.GCContent ]
+location = ../plugin/GCContent/
+[ plugins.ComboTrackSelector ]
+location = ../plugin/ComboTrackSelector/
+[ plugins.MultiBigWig ]
+location = ../plugin/MultiBigWig/
+[ plugins.bookmarks ]
+location = ../plugin/bookmarks/
+[ plugins.NeatCanvasFeatures ]
+location = ../plugin/NeatCanvasFeatures/
+[ plugins.NeatHTMLFeatures ]
+location = ../plugin/NeatHTMLFeatures/
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/dataset_1_files/jbrowse_conf.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dataset_1_files/jbrowse_conf.json Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,9 @@
+// top-level JBrowse configuration file.  Treated the same as
+// jbrowse.conf, but this one is in JSON format.
+//
+// Unless generating configuration from scripts, most users will
+// prefer to add variables to jbrowse.conf instead of this file, since
+// jbrowse.conf is much easier to hand-edit.
+{
+
+}
\ No newline at end of file
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/export/cdna.fa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/export/cdna.fa Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,103 @@
+>ff2fe902-7bab-431c-be82-30ed072915d1 (mRNA) 690 residues [Merlin:2-691 + strand] [cdna] name=Unknown
+CGTTTAGACAAAGGTACATTATTGTATCGTGGCCAAAAATTAGACCTTCCTACATTCGAG
+CATAACGCAGAGAATAAGTTGTTCTATTTCAGAAACTACGTTTCAACTTCATTAAAGCCT
+CTGATCTTTGGTGAATTTGGTCGTATGTTTATGGCACTAGATGACGATACTACAATTTAT
+ACTGCTGAGACGCCTGATGATTATAATCGTTTCGCAAACCCAGAAGATATAATTGATATT
+GGCGCTACTCAAAAAGACTCATTTGACGATAACAATAATGATGGAACATCTATTAATATC
+GGCAAACAAGTTAATTTAGGATTCGTTATTTCCGGTGCTGAAAATGTTCGAGTTATTGTT
+CCAGGTTCTTTAACTGAATATCCAGAAGAAGCGGAAGTTATTCTGCCTCGTGGTACTCTT
+TTGAAGATCAATAAAATCACTACTCAAGTAGATAAACGCTCGAATAAGTTCATGGTTGAA
+GGTTCAATCGTTCCGCCTTCTGAGCAAATTGATGAATCTGTTGAGATTTATGACGGTGAT
+CTGTTCATGGAAACAGGTGAAGTAGTAAAACTGTCCGGATTCATGCAGTTCGTCAACGAA
+TCTGCATACGATGAAGAGCAAAACCAGATGGCTGCTGAGATTCTGTCTGGATTCTTGGAC
+ATTGATGACATGCCACGTAAGTTCCGCTAG
+>f2e1909a-1d40-4a49-a67b-5fe2afdc4957 (mRNA) 288 residues [Merlin:752-1039 + strand] [cdna] name=Unknown
+ATGAAATCAATTTTTCGTATCAACGGTGTAGAAATTGTAGTTGAAGATGTAGTTCCTATG
+TCTTATGAATTCAATGAAGTTGTTTTCAAAGAGCTTAAGAAAATTTTAGGCGATAAGAAG
+CTTCAAAGTACTCCAATTGGACGTTTTGGAATGAAAGAAAACGTTGATACTTATATTGAA
+AGTGTAGTGACAGGGCAGTTAGAAGGTGAATTTTCTGTAGCAGTTCAAACTGTAGAAAAT
+GATGAAGTTATTTTAACTTTACCAGCTTTCGTAATTTTCCGCAAATAA
+>12fe0db6-c8e1-4bc9-b594-87c92c6c9669 (mRNA) 945 residues [Merlin:1067-2011 - strand] [cdna] name=Unknown
+ATGCTAACTTTAGATGAATTTAAAAACCAAGCGGGTAATATAGACTTTCAGCGTACTAAT
+ATGTTTAGTTGTGTATTTGCAACTACTCCGTCAGCAAAGTCTCAACAATTACTCGATCAA
+TTTGGCGGTATGCTCTTTAATAACCTTCCGTTGAATAATGACTGGCTTGGATTAACACAA
+GGTGAGTTCACATCAGGACTCACCTCAATTATCACTGCCGGTACTCAACAGCTGGTAAGA
+AAGTCTGGTGTATCGAAATATCTTATTGGAGCAATGAGCAATCGTGTTGTTCAGTCTTTA
+TTAGGTGAATTTGAAGTCGGAACTTATTTGTTAGACTTCTTTAACATGGCTTATCCGCAA
+TCTGGATTGATGATTTATTCGGTCAAAATTCCAGAGAACAGATTGTCTCATGAAATGGAT
+TTCAACCATAACTCACCGAATATTAGAATAACTGGACGTGAACTCGATCCGTTAACTATA
+TCATTCAGAATGGATCCCGAAGCAAGTAACTATCGTGCAATGCAAGATTGGGTGAACTCC
+GTTCAAGACCCGGTTACTGGATTGCGAGCATTACCAACTGACGTCGAAGCTGACATTCAG
+GTTAACCTTCATGCTCGAAATGGATTACCTCATACTGTGATAATGTTCACAGGTTGTGTT
+CCTGTTGCGTGTGGAGCTCCTGAGCTTACATATGAAGGAGATAACCAAATTGCGGTTTTC
+GATGTTACATTTGCTTACAGAGTAATGCAAACGGGTGCTGTTGGACGTCAAGCTGCTCTT
+GATTGGATTGAAGATAGAGCTGTTAATTCTATAACTGGAATTAATAGTGAAATGTCTCTT
+AATGGAAGTTTAAGTAGATTATCTAGACTTGGAGGAGCTGCTGGAGGGTTGTCTCACGTC
+ATTAATTCGACCCGAAACTCTACTTCGAAAATACTTGGATTGTAA
+>58fc8255-95ed-4417-a373-238f826810ac (mRNA) 1056 residues [Merlin:2011-3066 - strand] [cdna] name=Unknown
+ATGAGCATTAAAGTCAGAGAATTAGATGATAAGACTGATGCTTTAATTAGCGGAGTTAAA
+ACCTCCGCTGGTCAAAGTTCACAATCAGCAAAAATAAAATCCACTATAACTGCGCAATAT
+CCGTCTGAACGTTCAGCTGGTAATGACACATCTGGTTCTTTACGAGTTCATGATCTTTAT
+AAGAACGGGTTGTTGTTCACTGCGTATGATATGAATTCTCGTACAACCGGTGATATGCGT
+AGCATGCGTTTAGGTGAAATGAAACGTACTGCAAATAGTGTAGTGAAATCAATCACTGGA
+ACAAATACTAATAAAGTTGATAAAATTCCAGTAGTGAATATTTTACTTCCACGCTCGAAA
+TCAGATGTTGAATCAGTTTCTCATAAATTTAATGACGTTGGAGATTCACTTATTTCTCGT
+GGCGGCGGTACTGCTACAGGGGTATTAAGTAACGTTGCATCTACTGCTGTCTTTGGCGGA
+TTAGAGTCATTGACTCAAGGATTAATGGCTGACCATAACGAGCAGATCTATAACACTGCT
+CGATCAATGTATGGCGGCGCAGATAACCGTACGAAGGTATTCACGTGGGATTTAACTCCT
+CGATCAGTACAAGATCTTATTGCTATTATCGAGATCTATGAATACTTTAACTACTATAGT
+TATGGCGAAACGGGAACGTCTACTTATGCAAAAGAAGTTAAGTCTCAATTAGATGAATGG
+TATAAATCAACTTTCCTTGATACATTAACTCCAGATGAAGCTAATAAAAATGACACTGTT
+TTTGAGAAAATAACTTCATTCTTAAGTAATGTTATTGTTGTAAGTAACCCTACTGTGTGG
+TTCGTCAGAAACTTTGGAACCACAAGTAAATTCGATGGACGTGCTGAAGTATTCGGTCCA
+TGTCAAATTCAGAGTATCCGTTTTGATAAAACTCCAAATGGAAACTTTAACGGTTTAGCT
+ATAGCTCCAAACCTGCCAAGTACATTCACATTAGAAATTACTATGCGTGAAATCTTGACA
+TTGAACCGAGCTTCAGTATATGCGGAAGGATTCTGA
+>c009dd7a-3284-4e7f-9ee1-3b56e2598e07 (mRNA) 1662 residues [Merlin:3066-4796 - strand] [cdna] name=multiexongene
+ATGAAAAGCGAAAACATGTCCACAATGAGACGTCGTAAAGTTATCGCTGATTCAAAGGGT
+GAAAGAGATGCAGCCTCGACTGCATCTGATCAAGTAGACTCTTTAGAATTAATCGGCCTT
+AAACTTGATGATGTACAAAGCGCTAATGAACTAGTTGCTGAAGTAATTGAAGAAAAGGGC
+AATAACTTAATTGATTCAGTTGATAACGTCGCTGAAGGTACTGAATTAGCTGCTGAAGCA
+TCTGAACGAACTACTGAGTCTATCAAGACTCTTACTGGCGTAGCGTCAACAATCAGCGAC
+AAATTAAGTAAACTCGCTTCGATGCTCGAGTCGAAGGTTCAGGCTGTGGAGCAAAAAGTA
+CAAGAATCTGGTGCCTCAGCTTCAACTGGGCTGTCAGTGATAGAAGATAAGCTTCCAGAT
+CCTGATGAGCCTTTCTTTCCACCTGTCCCTCAGGAACCCGAGAACAACAAGAAAGATCAA
+AAGAAAGATGATAAGAAACCTACCGATATGTTAGGTGACTTGCTGAAGACTACGAAGGGC
+GGATTTAAAGCTACGATATCAATCACTGATAAAATATCGTCTATGCTTTTCAAATACACC
+GTAACAGCATTAGCTGAAGCTGCTAAAATGGCTGCTATGCTATTTGCATTAGTATTAGGC
+ATAGATTTACTTCGTATTCATTTTAAGTATTGGACTGATAAATTCATGAGTAACTTCGAT
+GAATTCAGTGCTGAAGCTGGTGAATGGGGTGGACTGCTTCAATCAATTTTTGGAATGTTA
+GGAGATATTAAAAAGTTCTGGGAAGCTGGAGACTGGAGTGGATTAGCAGTAGCTATTGTC
+AAAGGATTAGCTGATGTGATTTACAACCTGAGCGAAATAATGTCTTTGGGAATTTCAAAG
+ATATCTGCTTCTATACTCGATGCACTTGGCTTTGAAAATGCAGCAACTACTATTCGTGGT
+TCAGCACTAGAAGGATTCCAGGAACGCACTGGTAATTCATTGTCTGAAGATGATCAAAAA
+GCTTTGGCTAAATATCAGAGTAAGCGTATTGAAGAAGGTCCTGGAATTATTGATAAAGCT
+GGCGAATTTAAAACTCGTGCATTTGATTGGGTACTAGGAAGAGAGAATAAAATCGATTCT
+ACACAAGCATCTGACCGTGATCAAGAGACTCAGAATCTTAAAGCAATGGCTCCTGAAAAA
+CGCGAAGAAACACTGATCAAACAAAACGAAGCTCGTGCAGCTGTTCAGCGTTTAGAAAAA
+TATATTGGTGATGTTGATCCAGAGAATCCAACTAATATGCAATCTTTAGAGAAGGCATAT
+AACAGTGCCAAAAAGTCTATTAGTGATTCTGCTATAAGTGATCAACCAGCTACTAAAAAG
+GAACTCGATAAAAGATTCCAACGAGTAGAATCCAAGTATCAGAAGCTCAAAGAAGATAAC
+ACTCCGAAGCCTGCGGCTCCAGCTACTTCGGAAGATAATCAACGAGTTCAAAATATTCAA
+AAAGCTGAAAATGCTAAAGAGCAATCTAAAAAATCAACCGGTGATATGAATGTTGCTAAC
+ACTCAGGTTAATAACGTAAATAATAGTAAGACTATTCACCAGGTTCAAACAGTCACGGCT
+ACTCCAGCTCCTGGAGTATTCGGGGCAACAGGAGTTAATTAA
+>2706ea76-172a-48c1-b940-eb603996f082 (mRNA) 1056 residues [Merlin:5011-6066 - strand] [cdna] name=cds-not-under-exon
+CTTTAATGACGCTGGTGAATCAATAAAAGAGATGATCGGTGCAATTTATGAATCAAAACC
+TCTTATAGCACCTGCGATGAACACAATCAACACATATGTTCCTCGAGTTCCATGGACGAG
+TAACATAACTGAATACAAGAAATATGTTCGAGATGTTGCATTAGCAGTAGATAATGACCA
+ATTCGTTTTTGTATGGGAAGATATCTATGGCTTGAACATGATGGATTATGACGCAATGAT
+TAACCAAGAATCAATCAAGGTTATTGTCGGTGAACCACGCACAATAGGTCAATTTGTCGG
+TGAGCTGGAATATAATCTCGCTTATGACTTCCAGTGGTTAACGAAGGCTAATGCCCATAC
+ACGCGATCCTATTTTTAACGCTACAATCTATTCACACTCATTCTTGGATAATAACCTTCC
+TAGAATAGTAACAGGTGATGGACAGAATAGCATCTTCGTTTCTCGCTCGGGTGCATATTC
+TGAAATGACTTATCGAAATGGATATGAAGAAGCTATCAGGCTTCAGACTATGGCACAATA
+CGACGGTTATGCAACTTGTAAAATGGTTGGAGACTTTGAAATGACTCCTGGAGATAAGAT
+TAATTTCTTTGATCCAAAGAAACAATTCAAAGCTGATTTTTACATTGATGAAGTAATTCA
+TGAAGTAAGTAATAACCAAAGCATAACTACACTTTATATGTTTACTAACTCTCGTAAGTT
+GGAAACAGTAGAACCAATAAAGGTTAAAAATGAACTTAAATCTGATACTACCACTTAAGA
+AAATACAAGTCAATGGCAAAACCATTTCTATTCCTAAGCTTGGCTTGAAGCATCACACGT
+TGATTAAAGATGTTCGTGCAATGGATGAGAACATGGGAATTCTTTTGGACTCAATTCATC
+CTGGGCTAAACGCTGCTGAATCAGATTTAGTGTCTATTCATTTGCTAGAGTTCAATGGCA
+AGTTAAAATCAAGTGTCGTTAAAGATGGATACACTTACAATATCAATGACATTTATATTT
+GCCAACGCCTTGAATTCCAGTTCCAAGGAAAGACAT
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/export/cds.fa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/export/cds.fa Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,68 @@
+>ff2fe902-7bab-431c-be82-30ed072915d1 (mRNA) 690 residues [Merlin:2-691 + strand] [cds] name=Unknown
+CGTTTAGACAAAGGTACATTATTGTATCGTGGCCAAAAATTAGACCTTCCTACATTCGAG
+CATAACGCAGAGAATAAGTTGTTCTATTTCAGAAACTACGTTTCAACTTCATTAAAGCCT
+CTGATCTTTGGTGAATTTGGTCGTATGTTTATGGCACTAGATGACGATACTACAATTTAT
+ACTGCTGAGACGCCTGATGATTATAATCGTTTCGCAAACCCAGAAGATATAATTGATATT
+GGCGCTACTCAAAAAGACTCATTTGACGATAACAATAATGATGGAACATCTATTAATATC
+GGCAAACAAGTTAATTTAGGATTCGTTATTTCCGGTGCTGAAAATGTTCGAGTTATTGTT
+CCAGGTTCTTTAACTGAATATCCAGAAGAAGCGGAAGTTATTCTGCCTCGTGGTACTCTT
+TTGAAGATCAATAAAATCACTACTCAAGTAGATAAACGCTCGAATAAGTTCATGGTTGAA
+GGTTCAATCGTTCCGCCTTCTGAGCAAATTGATGAATCTGTTGAGATTTATGACGGTGAT
+CTGTTCATGGAAACAGGTGAAGTAGTAAAACTGTCCGGATTCATGCAGTTCGTCAACGAA
+TCTGCATACGATGAAGAGCAAAACCAGATGGCTGCTGAGATTCTGTCTGGATTCTTGGAC
+ATTGATGACATGCCACGTAAGTTCCGCTAG
+>f2e1909a-1d40-4a49-a67b-5fe2afdc4957 (mRNA) 9 residues [Merlin:752-1039 + strand] [cds] name=Unknown
+AAATTTTAG
+>12fe0db6-c8e1-4bc9-b594-87c92c6c9669 (mRNA) 108 residues [Merlin:1067-2011 - strand] [cds] name=Unknown
+CACCTCAATTATCACTGCCGGTACTCAACAGCTGGTAAGAAAGTCTGGTGTATCGAAATA
+TCTTATTGGAGCAATGAGCAATCGTGTTGTTCAGTCTTTATTAGGTGA
+>58fc8255-95ed-4417-a373-238f826810ac (mRNA) 1056 residues [Merlin:2011-3066 - strand] [cds] name=Unknown
+ATGAGCATTAAAGTCAGAGAATTAGATGATAAGACTGATGCTTTAATTAGCGGAGTTAAA
+ACCTCCGCTGGTCAAAGTTCACAATCAGCAAAAATAAAATCCACTATAACTGCGCAATAT
+CCGTCTGAACGTTCAGCTGGTAATGACACATCTGGTTCTTTACGAGTTCATGATCTTTAT
+AAGAACGGGTTGTTGTTCACTGCGTATGATATGAATTCTCGTACAACCGGTGATATGCGT
+AGCATGCGTTTAGGTGAAATGAAACGTACTGCAAATAGTGTAGTGAAATCAATCACTGGA
+ACAAATACTAATAAAGTTGATAAAATTCCAGTAGTGAATATTTTACTTCCACGCTCGAAA
+TCAGATGTTGAATCAGTTTCTCATAAATTTAATGACGTTGGAGATTCACTTATTTCTCGT
+GGCGGCGGTACTGCTACAGGGGTATTAAGTAACGTTGCATCTACTGCTGTCTTTGGCGGA
+TTAGAGTCATTGACTCAAGGATTAATGGCTGACCATAACGAGCAGATCTATAACACTGCT
+CGATCAATGTATGGCGGCGCAGATAACCGTACGAAGGTATTCACGTGGGATTTAACTCCT
+CGATCAGTACAAGATCTTATTGCTATTATCGAGATCTATGAATACTTTAACTACTATAGT
+TATGGCGAAACGGGAACGTCTACTTATGCAAAAGAAGTTAAGTCTCAATTAGATGAATGG
+TATAAATCAACTTTCCTTGATACATTAACTCCAGATGAAGCTAATAAAAATGACACTGTT
+TTTGAGAAAATAACTTCATTCTTAAGTAATGTTATTGTTGTAAGTAACCCTACTGTGTGG
+TTCGTCAGAAACTTTGGAACCACAAGTAAATTCGATGGACGTGCTGAAGTATTCGGTCCA
+TGTCAAATTCAGAGTATCCGTTTTGATAAAACTCCAAATGGAAACTTTAACGGTTTAGCT
+ATAGCTCCAAACCTGCCAAGTACATTCACATTAGAAATTACTATGCGTGAAATCTTGACA
+TTGAACCGAGCTTCAGTATATGCGGAAGGATTCTGA
+>c009dd7a-3284-4e7f-9ee1-3b56e2598e07 (mRNA) 1662 residues [Merlin:3066-4796 - strand] [cds] name=multiexongene
+ATGAAAAGCGAAAACATGTCCACAATGAGACGTCGTAAAGTTATCGCTGATTCAAAGGGT
+GAAAGAGATGCAGCCTCGACTGCATCTGATCAAGTAGACTCTTTAGAATTAATCGGCCTT
+AAACTTGATGATGTACAAAGCGCTAATGAACTAGTTGCTGAAGTAATTGAAGAAAAGGGC
+AATAACTTAATTGATTCAGTTGATAACGTCGCTGAAGGTACTGAATTAGCTGCTGAAGCA
+TCTGAACGAACTACTGAGTCTATCAAGACTCTTACTGGCGTAGCGTCAACAATCAGCGAC
+AAATTAAGTAAACTCGCTTCGATGCTCGAGTCGAAGGTTCAGGCTGTGGAGCAAAAAGTA
+CAAGAATCTGGTGCCTCAGCTTCAACTGGGCTGTCAGTGATAGAAGATAAGCTTCCAGAT
+CCTGATGAGCCTTTCTTTCCACCTGTCCCTCAGGAACCCGAGAACAACAAGAAAGATCAA
+AAGAAAGATGATAAGAAACCTACCGATATGTTAGGTGACTTGCTGAAGACTACGAAGGGC
+GGATTTAAAGCTACGATATCAATCACTGATAAAATATCGTCTATGCTTTTCAAATACACC
+GTAACAGCATTAGCTGAAGCTGCTAAAATGGCTGCTATGCTATTTGCATTAGTATTAGGC
+ATAGATTTACTTCGTATTCATTTTAAGTATTGGACTGATAAATTCATGAGTAACTTCGAT
+GAATTCAGTGCTGAAGCTGGTGAATGGGGTGGACTGCTTCAATCAATTTTTGGAATGTTA
+GGAGATATTAAAAAGTTCTGGGAAGCTGGAGACTGGAGTGGATTAGCAGTAGCTATTGTC
+AAAGGATTAGCTGATGTGATTTACAACCTGAGCGAAATAATGTCTTTGGGAATTTCAAAG
+ATATCTGCTTCTATACTCGATGCACTTGGCTTTGAAAATGCAGCAACTACTATTCGTGGT
+TCAGCACTAGAAGGATTCCAGGAACGCACTGGTAATTCATTGTCTGAAGATGATCAAAAA
+GCTTTGGCTAAATATCAGAGTAAGCGTATTGAAGAAGGTCCTGGAATTATTGATAAAGCT
+GGCGAATTTAAAACTCGTGCATTTGATTGGGTACTAGGAAGAGAGAATAAAATCGATTCT
+ACACAAGCATCTGACCGTGATCAAGAGACTCAGAATCTTAAAGCAATGGCTCCTGAAAAA
+CGCGAAGAAACACTGATCAAACAAAACGAAGCTCGTGCAGCTGTTCAGCGTTTAGAAAAA
+TATATTGGTGATGTTGATCCAGAGAATCCAACTAATATGCAATCTTTAGAGAAGGCATAT
+AACAGTGCCAAAAAGTCTATTAGTGATTCTGCTATAAGTGATCAACCAGCTACTAAAAAG
+GAACTCGATAAAAGATTCCAACGAGTAGAATCCAAGTATCAGAAGCTCAAAGAAGATAAC
+ACTCCGAAGCCTGCGGCTCCAGCTACTTCGGAAGATAATCAACGAGTTCAAAATATTCAA
+AAAGCTGAAAATGCTAAAGAGCAATCTAAAAAATCAACCGGTGATATGAATGTTGCTAAC
+ACTCAGGTTAATAACGTAAATAATAGTAAGACTATTCACCAGGTTCAAACAGTCACGGCT
+ACTCCAGCTCCTGGAGTATTCGGGGCAACAGGAGTTAATTAA
+>2706ea76-172a-48c1-b940-eb603996f082 (mRNA) 6 residues [Merlin:5011-6066 - strand] [cds] name=cds-not-under-exon
+CTTTAA
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/export/out.vcf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/export/out.vcf Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,5 @@
+##fileformat=VCFv4.2
+##fileDate=20191025XX
+##source=.
+##reference=/home/apollo_shared_dir/org2/seq/genome.fasta
+#CHROM POS ID REF ALT QUAL FILTER INFO
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/export/pep.fa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/export/pep.fa Mon Dec 02 05:46:45 2019 -0500
[
@@ -0,0 +1,29 @@
+>ff2fe902-7bab-431c-be82-30ed072915d1 (mRNA) 229 residues [Merlin:2-691 + strand] [peptide] name=Unknown
+RLDKGTLLYRGQKLDLPTFEHNAENKLFYFRNYVSTSLKPLIFGEFGRMFMALDDDTTIY
+TAETPDDYNRFANPEDIIDIGATQKDSFDDNNNDGTSINIGKQVNLGFVISGAENVRVIV
+PGSLTEYPEEAEVILPRGTLLKINKITTQVDKRSNKFMVEGSIVPPSEQIDESVEIYDGD
+LFMETGEVVKLSGFMQFVNESAYDEEQNQMAAEILSGFLDIDDMPRKFR
+>f2e1909a-1d40-4a49-a67b-5fe2afdc4957 (mRNA) 2 residues [Merlin:752-1039 + strand] [peptide] name=Unknown
+KF
+>12fe0db6-c8e1-4bc9-b594-87c92c6c9669 (mRNA) 35 residues [Merlin:1067-2011 - strand] [peptide] name=Unknown
+HLNYHCRYSTAGKKVWCIEISYWSNEQSCCSVFIR
+>58fc8255-95ed-4417-a373-238f826810ac (mRNA) 351 residues [Merlin:2011-3066 - strand] [peptide] name=Unknown
+MSIKVRELDDKTDALISGVKTSAGQSSQSAKIKSTITAQYPSERSAGNDTSGSLRVHDLY
+KNGLLFTAYDMNSRTTGDMRSMRLGEMKRTANSVVKSITGTNTNKVDKIPVVNILLPRSK
+SDVESVSHKFNDVGDSLISRGGGTATGVLSNVASTAVFGGLESLTQGLMADHNEQIYNTA
+RSMYGGADNRTKVFTWDLTPRSVQDLIAIIEIYEYFNYYSYGETGTSTYAKEVKSQLDEW
+YKSTFLDTLTPDEANKNDTVFEKITSFLSNVIVVSNPTVWFVRNFGTTSKFDGRAEVFGP
+CQIQSIRFDKTPNGNFNGLAIAPNLPSTFTLEITMREILTLNRASVYAEGF
+>c009dd7a-3284-4e7f-9ee1-3b56e2598e07 (mRNA) 553 residues [Merlin:3066-4796 - strand] [peptide] name=multiexongene
+MKSENMSTMRRRKVIADSKGERDAASTASDQVDSLELIGLKLDDVQSANELVAEVIEEKG
+NNLIDSVDNVAEGTELAAEASERTTESIKTLTGVASTISDKLSKLASMLESKVQAVEQKV
+QESGASASTGLSVIEDKLPDPDEPFFPPVPQEPENNKKDQKKDDKKPTDMLGDLLKTTKG
+GFKATISITDKISSMLFKYTVTALAEAAKMAAMLFALVLGIDLLRIHFKYWTDKFMSNFD
+EFSAEAGEWGGLLQSIFGMLGDIKKFWEAGDWSGLAVAIVKGLADVIYNLSEIMSLGISK
+ISASILDALGFENAATTIRGSALEGFQERTGNSLSEDDQKALAKYQSKRIEEGPGIIDKA
+GEFKTRAFDWVLGRENKIDSTQASDRDQETQNLKAMAPEKREETLIKQNEARAAVQRLEK
+YIGDVDPENPTNMQSLEKAYNSAKKSISDSAISDQPATKKELDKRFQRVESKYQKLKEDN
+TPKPAAPATSEDNQRVQNIQKAENAKEQSKKSTGDMNVANTQVNNVNNSKTIHQVQTVTA
+TPAPGVFGATGVN
+>2706ea76-172a-48c1-b940-eb603996f082 (mRNA) 1 residues [Merlin:5011-6066 - strand] [peptide] name=cds-not-under-exon
+L
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/good-model.gff3
--- a/test-data/good-model.gff3 Mon Jul 29 10:09:54 2019 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
b
@@ -1,7 +0,0 @@
-##gff-version 3
-##sequence-region Maroon_JMcDermott 1 14805
-Maroon_JMcDermott feature gene 14488 14805 . + . ID=707c88b7-36d1-44e3-93e6-d1d4f1219d57;Name=gene_26;date_creation=2016-02-17;date_last_modified=2016-02-17;owner=jmc_texas%40tamu.edu
-Maroon_JMcDermott feature mRNA 14488 14805 . + . ID=8760695d-b88c-41c0-857b-540e6db81fe8;Name=gene_26-00001;Parent=707c88b7-36d1-44e3-93e6-d1d4f1219d57;date_creation=2016-02-17;date_last_modified=2016-02-17;owner=jmc_texas%40tamu.edu
-Maroon_JMcDermott feature CDS 14707 14805 . + 0 ID=94abf796-4c8d-45f4-916b-4d279616565e;Name=94abf796-4c8d-45f4-916b-4d279616565e-CDS;Parent=8760695d-b88c-41c0-857b-540e6db81fe8
-Maroon_JMcDermott feature exon 14497 14805 . + . ID=d2ebd8d0-6558-4674-a38f-346f88256340;Name=d2ebd8d0-6558-4674-a38f-346f88256340-exon;Parent=8760695d-b88c-41c0-857b-540e6db81fe8
-Maroon_JMcDermott feature Shine_Dalgarno_sequence 14488 14491 . + . ID=2e4119f9-3220-4502-8ddd-4821c872e0d6;Name=2e4119f9-3220-4502-8ddd-4821c872e0d6-exon;Parent=8760695d-b88c-41c0-857b-540e6db81fe8
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/load_gff3/output.tsv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/load_gff3/output.tsv Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,7 @@
+# Feature ID Apollo ID Success Messages
+Merlin_1 a036ab4f-512d-45e3-b19e-1fe83984a185 success
+Merlin_2 4a3f5c6b-03fc-43d1-8d6d-1a7075931cc6 success
+Merlin_3 de819682-eb71-4b98-a532-032d59354b95 success
+Merlin_4 423ca5cc-d570-4ae8-8527-6a52e0a6862b success
+Merlin_5 f1b5327d-79ca-40f0-b4b3-90ea03d79a56 success
+Merlin_42 3629a7fe-03bb-420d-85d3-f23e55430abd success
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/merlin.gff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/merlin.gff Mon Dec 02 05:46:45 2019 -0500
b
@@ -0,0 +1,28 @@
+##gff-version 3
+##sequence-region Merlin 1 172788
+Merlin GeneMark.hmm gene 2 691 -856.563659 + . ID=Merlin_1;seqid=Merlin
+Merlin GeneMark.hmm mRNA 2 691 . + . ID=Merlin_1_mRNA;Parent=Merlin_1;seqid=Merlin;color=#00ff00
+Merlin GeneMark.hmm exon 2 691 . + . ID=Merlin_1_exon;Parent=Merlin_1_mRNA;seqid=Merlin
+Merlin GeneMark.hmm CDS 2 691 . + 0 ID=Merlin_1_CDS;Parent=Merlin_1_exon;seqid=Merlin
+Merlin GeneMark.hmm gene 752 1039 -339.046618 + . ID=Merlin_2;seqid=Merlin
+Merlin GeneMark.hmm mRNA 752 1039 . + . ID=Merlin_2_mRNA;Parent=Merlin_2;seqid=Merlin;Name=mrna-name
+Merlin GeneMark.hmm exon 752 1039 . + . ID=Merlin_2_exon;Parent=Merlin_2_mRNA;seqid=Merlin
+Merlin GeneMark.hmm CDS 852 939 . + 0 ID=Merlin_2_CDS;Parent=Merlin_2_exon;seqid=Merlin
+Merlin GeneMark.hmm gene 1067 2011 -1229.683915 - . ID=Merlin_3;seqid=Merlin
+Merlin GeneMark.hmm mRNA 1067 2011 . - . ID=Merlin_3_mRNA;Parent=Merlin_3;seqid=Merlin
+Merlin GeneMark.hmm exon 1067 2011 . - . ID=Merlin_3_exon;Parent=Merlin_3_mRNA;seqid=Merlin
+Merlin GeneMark.hmm CDS 1367 1811 . - 0 ID=Merlin_3_CDS;Parent=Merlin_3_exon;seqid=Merlin
+Merlin GeneMark.hmm gene 2011 3066 -1335.034872 - . ID=Merlin_4;seqid=Merlin
+Merlin GeneMark.hmm mRNA 2011 3066 . - . ID=Merlin_4_mRNA;Parent=Merlin_4;seqid=Merlin
+Merlin GeneMark.hmm exon 2011 3066 . - . ID=Merlin_4_exon;Parent=Merlin_4_mRNA;seqid=Merlin
+Merlin GeneMark.hmm CDS 2011 3066 . - 0 ID=Merlin_4_CDS;Parent=Merlin_4_exon;seqid=Merlin
+Merlin GeneMark.hmm gene 3066 4796 -2177.374893 - . ID=Merlin_5;seqid=Merlin;Name=multiexongene
+Merlin GeneMark.hmm mRNA 3066 4796 . - . ID=Merlin_5_mRNA;Parent=Merlin_5;seqid=Merlin
+Merlin GeneMark.hmm exon 3066 4296 . - . ID=Merlin_5_exon;Parent=Merlin_5_mRNA;seqid=Merlin
+Merlin GeneMark.hmm CDS 3066 4296 . - 0 ID=Merlin_5_CDS;Parent=Merlin_5_exon;seqid=Merlin
+Merlin GeneMark.hmm exon 4366 4796 . - . ID=Merlin_5_exon2;Parent=Merlin_5_mRNA;seqid=Merlin
+Merlin GeneMark.hmm CDS 4366 4796 . - 0 ID=Merlin_5_CDS2;Parent=Merlin_5_exon2;seqid=Merlin
+Merlin GeneMark.hmm gene 5011 6066 -1335.034872 - . ID=Merlin_42;seqid=Merlin;Name=cds-not-under-exon
+Merlin GeneMark.hmm mRNA 5011 6066 . - . ID=Merlin_42_mRNA;Parent=Merlin_42;seqid=Merlin
+Merlin GeneMark.hmm exon 5011 6066 . - . ID=Merlin_42_exon;Parent=Merlin_42_mRNA;seqid=Merlin
+Merlin GeneMark.hmm CDS 5011 6066 . - 0 ID=Merlin_42_CDS;Parent=Merlin_42_mRNA;seqid=Merlin
b
diff -r 29ce13734a5c -r d72192ec8e39 test-data/org_remote.tar.gz
b
Binary file test-data/org_remote.tar.gz has changed
b
diff -r 29ce13734a5c -r d72192ec8e39 webapollo.py
--- a/webapollo.py Mon Jul 29 10:09:54 2019 -0400
+++ b/webapollo.py Mon Dec 02 05:46:45 2019 -0500
[
b'@@ -5,25 +5,16 @@\n import json\n import logging\n import os\n-import random\n import time\n from abc import abstractmethod\n \n-from BCBio import GFF\n-\n-from Bio import SeqIO\n-\n import requests\n \n from six.moves.builtins import next\n from six.moves.builtins import object\n-from six.moves.builtins import str\n-\n \n-try:\n-    import StringIO as io\n-except BaseException:\n-    import io\n+import yaml\n+\n logging.getLogger("requests").setLevel(logging.CRITICAL)\n log = logging.getLogger()\n \n@@ -431,38 +422,6 @@\n     parser.add_argument(\'--seq_raw\', nargs=\'*\', help=\'Sequence Names\')\n \n \n-def GuessOrg(args, wa):\n-    if args.org_json:\n-        orgs = [x.get(\'commonName\', None)\n-                for x in json.load(args.org_json)]\n-        orgs = [x for x in orgs if x is not None]\n-        return orgs\n-    elif args.org_raw:\n-        org = args.org_raw.strip()\n-        if len(org) > 0:\n-            return [org]\n-        else:\n-            raise Exception("Organism Common Name not provided")\n-    elif args.org_id:\n-        return [wa.organisms.findOrganismById(args.org_id).get(\'commonName\', None)]\n-    else:\n-        raise Exception("Organism Common Name not provided")\n-\n-\n-def GuessCn(args, wa):\n-    org = GuessOrg(args, wa)\n-    seqs = []\n-    if args.seq_fasta:\n-        # If we have a fasta, pull all rec ids from that.\n-        for rec in SeqIO.parse(args.seq_fasta, \'fasta\'):\n-            seqs.append(rec.id)\n-    elif args.seq_raw:\n-        # Otherwise raw list.\n-        seqs = [x.strip() for x in args.seq_raw if len(x.strip()) > 0]\n-\n-    return org, seqs\n-\n-\n def AssertUser(user_list):\n     if len(user_list) == 0:\n         raise UnknownUserException()\n@@ -472,50 +431,29 @@\n         raise Exception("Too many users!")\n \n \n-def AssertAdmin(user):\n-    if user.role == \'ADMIN\':\n-        return True\n-    else:\n-        raise Exception("User is not an administrator. Permission denied")\n-\n-\n-def PermissionCheck(user, org_cn, permission_type):\n-    return any(org["organism"] == org_cn and permission_type in org["permissions"] for org in user.organismPermissions)\n-\n-\n-def PasswordGenerator(length):\n-    chars = list(\'qwrtpsdfghjklzxcvbnm\')\n-    return \'\'.join(random.choice(chars) for _ in range(length))\n-\n-\n-def IsRemoteUser():\n-    if \'GALAXY_WEBAPOLLO_REMOTE_USER\' not in os.environ:\n-        return False\n-    value = os.environ[\'GALAXY_WEBAPOLLO_REMOTE_USER\']\n-    if value.lower() in (\'true\', \'t\', \'1\'):\n-        return True\n-    else:\n-        return False\n-\n-\n class WebApolloInstance(object):\n \n-    def __init__(self, url, username, password):\n-        self.apollo_url = url\n-        self.username = username\n-        self.password = password\n+    def __init__(self):\n+\n+        if \'ARROW_GLOBAL_CONFIG_PATH\' in os.environ:\n \n-        self.annotations = AnnotationsClient(self)\n+            with open(os.environ[\'ARROW_GLOBAL_CONFIG_PATH\'], \'r\') as config:\n+                conf = yaml.safe_load(config)\n+                try:\n+                    instance_name = conf[\'__default\']\n+                except KeyError:\n+                    raise Exception("Unknown Apollo instance and no __default provided")\n+                self.apollo_url = conf[instance_name][\'url\']\n+                self.username = conf[instance_name][\'username\']\n+                self.password = conf[instance_name][\'password\']\n+        else:\n+            self.apollo_url = os.environ[\'GALAXY_WEBAPOLLO_URL\']\n+            self.username = os.environ[\'GALAXY_WEBAPOLLO_USER\']\n+            self.password = os.environ[\'GALAXY_WEBAPOLLO_PASSWORD\']\n+\n         self.groups = GroupsClient(self)\n-        self.io = IOClient(self)\n         self.organisms = OrganismsClient(self)\n         self.users = UsersClient(self)\n-        self.metrics = MetricsClient(self)\n-        self.bio = RemoteRecord(self)\n-        self.status = StatusClient(self)\n-        self.canned_comments = CannedCommentsClient(self)\n-        self.canned_keys = CannedKeysClient(self)\n-        self.canned_values = CannedValuesClient(self)\n \n     def '..b'   # Key for cached data\n     cacheKey = \'groups-\' + email\n@@ -1601,11 +658,7 @@\n \n def galaxy_list_orgs(trans, *args, **kwargs):\n     email = trans.get_user().email\n-    wa = WebApolloInstance(\n-        os.environ[\'GALAXY_WEBAPOLLO_URL\'],\n-        os.environ[\'GALAXY_WEBAPOLLO_USER\'],\n-        os.environ[\'GALAXY_WEBAPOLLO_PASSWORD\']\n-    )\n+    wa = WebApolloInstance()\n     try:\n         gx_user = wa.requireUser(email)\n     except UnknownUserException:\n@@ -1635,53 +688,6 @@\n     return orgs\n \n \n-def galaxy_list_users(trans, *args, **kwargs):\n-    email = trans.get_user().email\n-    wa = WebApolloInstance(\n-        os.environ[\'GALAXY_WEBAPOLLO_URL\'],\n-        os.environ[\'GALAXY_WEBAPOLLO_USER\'],\n-        os.environ[\'GALAXY_WEBAPOLLO_PASSWORD\']\n-    )\n-    # Assert that the email exists in apollo\n-    try:\n-        gx_user = wa.requireUser(email)\n-    except UnknownUserException:\n-        return []\n-\n-    # Key for cached data\n-    cacheKey = \'users-\' + email\n-    # We don\'t want to trust "if key in cache" because between asking and fetch\n-    # it might through key error.\n-    if cacheKey not in cache:\n-        # However if it ISN\'T there, we know we\'re safe to fetch + put in\n-        # there.\n-        data = _galaxy_list_users(wa, gx_user, *args, **kwargs)\n-        cache[cacheKey] = data\n-        return data\n-    try:\n-        # The cache key may or may not be in the cache at this point, it\n-        # /likely/ is. However we take no chances that it wasn\'t evicted between\n-        # when we checked above and now, so we reference the object from the\n-        # cache in preparation to return.\n-        data = cache[cacheKey]\n-        return data\n-    except KeyError:\n-        # If access fails due to eviction, we will fail over and can ensure that\n-        # data is inserted.\n-        data = _galaxy_list_users(wa, gx_user, *args, **kwargs)\n-        cache[cacheKey] = data\n-        return data\n-\n-\n-def _galaxy_list_users(wa, gx_user, *args, **kwargs):\n-    # Fetch the users.\n-    user_data = []\n-    for user in wa.users.loadUsers():\n-        # Reformat\n-        user_data.append((user.username, user.username, False))\n-    return user_data\n-\n-\n # This is all for implementing the command line interface for testing.\n class obj(object):\n     pass\n@@ -1698,45 +704,14 @@\n         return o\n \n \n-def retry(closure, sleep=1, limit=5):\n-    """\n-    Apollo has the bad habit of returning 500 errors if you call APIs\n-    too quickly, largely because of the unholy things that happen in\n-    grails.\n-\n-    To deal with the fact that we cannot send an addComments call too\n-    quickly after a createFeature call, we have this function that will\n-    keep calling a closure until it works.\n-    """\n-    count = 0\n-    while True:\n-        count += 1\n-\n-        if count >= limit:\n-            return False\n-        try:\n-            # Try calling it\n-            closure()\n-            # If successful, exit\n-            return True\n-        except Exception as e:\n-            log.info(str(e)[0:100])\n-            time.sleep(sleep)\n-\n-\n if __name__ == \'__main__\':\n     parser = argparse.ArgumentParser(description=\'Test access to apollo server\')\n     parser.add_argument(\'email\', help=\'Email of user to test\')\n-    parser.add_argument(\'--action\', choices=[\'org\', \'group\', \'users\'], default=\'org\', help=\'Data set to test, fetch a list of groups or users known to the requesting user.\')\n+    parser.add_argument(\'--action\', choices=[\'org\', \'group\'], default=\'org\', help=\'Data set to test, fetch a list of groups or orgs known to the requesting user.\')\n     args = parser.parse_args()\n \n     trans = fakeTrans(args.email)\n     if args.action == \'org\':\n-        for f in galaxy_list_orgs(trans):\n-            print(f)\n+        print(galaxy_list_orgs(trans))\n     elif args.action == \'group\':\n-        for f in galaxy_list_groups(trans):\n-            print(f)\n-    else:\n-        for f in galaxy_list_users(trans):\n-            print(f)\n+        print(galaxy_list_groups(trans))\n'