changeset 3:d4ae83dedb14 draft

planemo upload for repository https://github.com/TAMU-CPT/galaxy-webapollo commit 4ac38d0b6dba1183f3e78eb5c224c7051064b4a5
author eric-rasche
date Thu, 12 Jan 2017 11:52:28 -0500
parents c8e16c8eff98
children 23ead6905145
files README.md add_organism.py add_organism.xml clean_org.py create_account.py create_account.xml create_features_from_gff3.py create_features_from_gff3.xml create_or_update_organism.py create_or_update_organism.xml export.py export.xml fetch_organism_jbrowse.py fetch_organism_jbrowse.xml find_organism.py find_organism.xml gff3_cleaner.py gff3_cleaner.xml json2iframe.py json2iframe.xml list_organisms.py list_organisms.xml macros.xml renumber.py renumber.xml test.json update_organism.py update_organism.xml webapollo.py
diffstat 29 files changed, 380 insertions(+), 772 deletions(-) [+]
line wrap: on
line diff
--- a/README.md	Tue May 03 13:48:11 2016 -0400
+++ b/README.md	Thu Jan 12 11:52:28 2017 -0500
@@ -1,7 +1,20 @@
-# galaxy-webapollo
+# galaxy-apollo
+
+Galaxy tools to interface with Apollo
+The webapollo.py file is also [separately available](https://github.com/erasche/python-apollo) as a pip-installable package.
+
+## ENV
+
+The following environment variables must be set:
 
-Galaxy tools to interface with WebApollo
-The webapollo.py file is also [separately available](https://github.com/erasche/python-apollo) as a pip-installable package.
+
+ENV                           | Use
+---                           | ---
+ `$GALAXY_WEBAPOLLO_URL`      | The URL at which Apollo is accessible, internal to Galaxy and where the tools run. Must be absolute, with FQDN and protocol.
+ `$GALAXY_WEBAPOLLO_USER`     | The admin user which Galaxy should use to talk to Apollo.
+ `$GALAXY_WEBAPOLLO_PASSWORD` | The password for the admin user.
+ `$GALAXY_WEBAPOLLO_EXT_URL`  | The external URL at which Apollo is accessible to end users. May be relative or absolute.
+ `$GALAXY_SHARED_DIR`         | Directory shared between Galaxy and Apollo, used to exchange JBrowse instances.
 
 ## License
 
--- a/add_organism.py	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-import json
-import argparse
-import time
-from webapollo import WebApolloInstance
-import logging
-logging.basicConfig(level=logging.INFO)
-log = logging.getLogger(__name__)
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Admin Username')
-    parser.add_argument('password', help='WA Admin Password')
-
-    parser.add_argument('cn', help='Organism Common Name')
-    parser.add_argument('jbrowse', help='JBrowse Data Directory')
-    parser.add_argument('email', help='User Email')
-    parser.add_argument('--blatdb', help='BlatDB Directory')
-    parser.add_argument('--genus', help='Organism Genus')
-    parser.add_argument('--species', help='Organism Species')
-    parser.add_argument('--public', action='store_true', help='Make organism public')
-
-    args = parser.parse_args()
-
-
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
-    # User must have an account
-    gx_user = wa.users.loadUsers(email=args.email)
-    if len(gx_user) == 0:
-        raise Exception("Unknown user. Please register first")
-
-    log.info("Adding Organism")
-    orgs = wa.organisms.addOrganism(
-        args.cn,
-        args.jbrowse,
-        blatdb=args.blatdb,
-        genus=args.genus,
-        species=args.species,
-        public=args.public
-    )
-    log.info("Success: %s", orgs[0]['id'])
-
-    # Must sleep before we're ready to handle
-    time.sleep(1)
-    log.info("Updating permissions for %s on %s", gx_user[0], args.cn)
-    data = wa.users.updateOrganismPermission(
-        gx_user[0], args.cn,
-        write=True,
-        export=True,
-        read=True,
-    )
-
-    print json.dumps([org for org in orgs if org['commonName'] == args.cn], indent=2)
--- a/add_organism.xml	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-<?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.add_organism" name="WA2: Add Organism" version="1.5">
-  <description>registers a new genome with WebApollo</description>
-  <macros>
-    <import>macros.xml</import>
-  </macros>
-  <expand macro="requirements"/>
-  <command detect_errors="aggressive"><![CDATA[
-cp -R ${jbrowse.extra_files_path}/data/ /opt/apollo/data/galaxy/${jbrowse.id};
-
-python $__tool_directory__/add_organism.py
-
-@AUTH@
-
-#if str($blatdb) != "None":
-    --blatdb "$blatdb"
-#end if
-
---genus "$genus"
---species "$species"
-$public
-
-@CN_OR_GUESS@
-
-"/opt/apollo/data/galaxy/${jbrowse.id}"
-
-$__user_email__
-
-> $output]]></command>
-  <inputs>
-    <param name="jbrowse" type="data" format="html" label="JBrowse HTML Output" />
-    <param name="blatdb" type="data" label="Blat DB" optional="True" />
-
-    <expand macro="cn_or_guess" />
-    <param name="genus" type="text" label="Host Bacteria" optional="True" />
-    <param name="species" type="text" label="Phage Name" optional="True" />
-    <param name="public" type="boolean" truevalue="--public" falsevalue="" label="Is Organism Public" />
-  </inputs>
-  <outputs>
-    <data format="json" name="output"/>
-  </outputs>
-  <help><![CDATA[
-**NOTA BENE**
-
-All organism data is currently shared. By using this tool your annotation data will be visible to your fellow lab members.
-This will be fixed at a later date.
-
-This only works with JBrowse v0.4 and above!
-
-**What it does**
-
-Adds an organism to the Apollo database. The tool takes the output of a
-JBrowse run as that contains all of the necessary information for which
-tracks are appropriate for a given analysis.
-
-@REFERENCES@
-      ]]></help>
-</tool>
--- a/clean_org.py	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#!/usr/bin/env python
-import argparse
-from webapollo import WebApolloInstance
-import logging
-logging.basicConfig(level=logging.INFO)
-log = logging.getLogger(__name__)
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Admin Username')
-    parser.add_argument('password', help='WA Admin Password')
-
-    parser.add_argument('cn', help='Organism Common Name')
-    parser.add_argument('email', help='User Email')
-    args = parser.parse_args()
-
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
-    # User must have an account
-    gx_user = wa.users.loadUsers(email=args.email)
-    if len(gx_user) == 0:
-        raise Exception("Unknown user. Please register first")
-
-    # TODO: Check user perms on org.
-    org = wa.organisms.findOrganismByCn(args.cn)
-
-    wa.annotations.setSequence(args.cn, org['id'])
-
-    for feature in wa.annotations.getFeatures().get('features', []):
-        print feature['uniquename']
-        wa.annotations.deleteFeatures([feature['uniquename']])
--- a/create_account.py	Tue May 03 13:48:11 2016 -0400
+++ b/create_account.py	Thu Jan 12 11:52:28 2017 -0500
@@ -2,7 +2,8 @@
 import random
 import argparse
 import time
-from webapollo import WebApolloInstance, GroupObj
+from webapollo import WAAuth, WebApolloInstance
+
 
 def pwgen(length):
     chars = list('qwrtpsdfghjklzxcvbnm')
@@ -10,28 +11,28 @@
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='Sample script to add an account via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Admin Username')
-    parser.add_argument('password', help='WA Admin Password')
+    WAAuth(parser)
 
     parser.add_argument('email', help='User Email')
-    parser.add_argument('--first', help='First Name', default='J')
+    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)
 
     password = pwgen(12)
-    wa.users.createUser(args.email, args.first, args.last, password, role='user')
     time.sleep(1)
-    user = [u for u in wa.users.loadUsers()
-            if u.username == args.email][0]
-
-    bich464 = GroupObj(name="bich464-2016-spring")
+    users = wa.users.loadUsers()
+    user = [u for u in users
+            if u.username == args.email]
 
-    # Update name, regen password if the user ran it again
-    wa.users.updateUser(user, args.email, args.first, args.last, password)
-    # Add to bich464 group
-    wa.users.addUserToGroup(bich464, user)
+    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)
+        print 'Updated User\nUsername: %s\nPassword: %s' % (args.email, password)
+    else:
+        returnData = wa.users.createUser(args.email, args.first, args.last, password, role='user')
+        print 'Created User\nUsername: %s\nPassword: %s' % (args.email, password)
 
-    print 'Username: %s\nPassword: %s' % (args.email, password)
+    print "Return data: " + str(returnData)
--- a/create_account.xml	Tue May 03 13:48:11 2016 -0400
+++ b/create_account.xml	Thu Jan 12 11:52:28 2017 -0500
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.create_account" name="WA2: Register Account" version="1.5">
-  <description>registers a new account with WebApollo</description>
+<tool id="edu.tamu.cpt2.webapollo.create_account" name="Register Account" version="3.0">
+  <description>with Apollo</description>
   <macros>
     <import>macros.xml</import>
   </macros>
@@ -8,7 +8,7 @@
   <command detect_errors="aggressive"><![CDATA[
 python $__tool_directory__/create_account.py
 
-@AUTH@
+@ADMIN_AUTH@
 
 $__user_email__
 
@@ -20,12 +20,12 @@
     <param name="last" type="text" label="Last Name" />
   </inputs>
   <outputs>
-    <data format="txt" name="output" label="WebApollo Credentials"/>
+    <data format="txt" name="output" label="Apollo Credentials"/>
   </outputs>
   <help><![CDATA[
 **What it does**
 
-Registers an account with WebApollo. Just click run, then view
+Registers an account with Apollo. Just click run, then view
 the output file for your password.
 
 @REFERENCES@
--- a/create_features_from_gff3.py	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-import argparse
-from webapollo import WebApolloInstance, featuresToFeatureSchema
-from BCBio import GFF
-import logging
-logging.basicConfig(level=logging.INFO)
-log = logging.getLogger(__name__)
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Admin Username')
-    parser.add_argument('password', help='WA Admin Password')
-
-    parser.add_argument('cn', help='Organism Common Name')
-    parser.add_argument('email', help='User Email')
-    parser.add_argument('gff3', type=file, help='GFF3 file')
-    args = parser.parse_args()
-
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
-    # User must have an account
-    gx_user = wa.users.loadUsers(email=args.email)
-    if len(gx_user) == 0:
-        raise Exception("Unknown user. Please register first")
-
-    # TODO: Check user perms on org.
-
-    org = wa.organisms.findOrganismByCn(args.cn)
-    wa.annotations.setSequence(args.cn, org['id'])
-
-    for rec in GFF.parse(args.gff3):
-        featureData = featuresToFeatureSchema(rec.features)
-        wa.annotations.addFeature(
-            {
-                'features': featureData
-            }, trustme=True
-        )
--- a/create_features_from_gff3.xml	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-<?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.feat_from_gff3" name="WA2: Create Features from GFF3" version="0.1">
-  <description></description>
-  <macros>
-    <import>macros.xml</import>
-  </macros>
-  <expand macro="requirements"/>
-  <command detect_errors="aggressive"><![CDATA[
-python $__tool_directory__/create_features_from_gff3.py
-@AUTH@
-@CN_OR_GUESS@
-"$__user_email__"
-$gff3_data
-> $output]]></command>
-  <inputs>
-    <expand macro="cn_or_guess" />
-    <expand macro="gff3_input" />
-  </inputs>
-  <outputs>
-    <data format="json" name="output"/>
-  </outputs>
-  <help><![CDATA[
-**NOTA BENE**
-
-This is **incredibly, highly experimental*
-
-DO NOT:
-
--  Run on gff3 referencing multiple reference sequences/contigs
--  Expect it to work well
--  Expect it to work at all
-
-
-@REFERENCES@
-]]></help>
-</tool>
--- a/create_or_update_organism.py	Tue May 03 13:48:11 2016 -0400
+++ b/create_or_update_organism.py	Thu Jan 12 11:52:28 2017 -0500
@@ -2,7 +2,7 @@
 import json
 import argparse
 import time
-from webapollo import WebApolloInstance
+from webapollo import WAAuth, WebApolloInstance, OrgOrGuess, GuessOrg, AssertUser
 import logging
 logging.basicConfig(level=logging.INFO)
 log = logging.getLogger(__name__)
@@ -10,41 +10,39 @@
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Admin Username')
-    parser.add_argument('password', help='WA Admin Password')
+    WAAuth(parser)
 
-    parser.add_argument('cn', help='Organism Common Name')
     parser.add_argument('jbrowse', help='JBrowse Data Directory')
     parser.add_argument('email', help='User Email')
-    parser.add_argument('--blatdb', help='BlatDB Directory')
+    OrgOrGuess(parser)
     parser.add_argument('--genus', help='Organism Genus')
     parser.add_argument('--species', help='Organism Species')
     parser.add_argument('--public', action='store_true', help='Make organism public')
 
     args = parser.parse_args()
-
+    wa = WebApolloInstance(args.apollo, args.username, args.password)
 
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
+    org_cn = GuessOrg(args, wa)
+    if isinstance(org_cn, list):
+        org_cn = org_cn[0]
+
     # User must have an account
-    gx_user = wa.users.loadUsers(email=args.email)
-    if len(gx_user) == 0:
-        raise Exception("Unknown user. Please register first")
+    gx_user = AssertUser(wa.users.loadUsers(email=args.email))
 
     log.info("Determining if add or update required")
     try:
-        org = wa.organisms.findOrganismByCn(args.cn)
+        org = wa.organisms.findOrganismByCn(org_cn)
     except Exception:
         org = None
 
+    # TODO: Check ownership
     if org:
         log.info("\tUpdating Organism")
         data = wa.organisms.updateOrganismInfo(
             org['id'],
-            args.cn,
+            org_cn,
             args.jbrowse,
             # mandatory
-            blatdb=args.blatdb,
             genus=args.genus,
             species=args.species,
             public=args.public
@@ -53,23 +51,22 @@
         # New organism
         log.info("\tAdding Organism")
         data = wa.organisms.addOrganism(
-            args.cn,
+            org_cn,
             args.jbrowse,
-            blatdb=args.blatdb,
             genus=args.genus,
             species=args.species,
             public=args.public
         )
 
         # Must sleep before we're ready to handle
-        time.sleep(1)
-        log.info("Updating permissions for %s on %s", gx_user[0], args.cn)
+        time.sleep(2)
+        log.info("Updating permissions for %s on %s", gx_user, org_cn)
         wa.users.updateOrganismPermission(
-            gx_user[0], args.cn,
+            gx_user, org_cn,
             write=True,
             export=True,
             read=True,
         )
 
-    data = [o for o in data if o['commonName'] == args.cn]
+    data = [o for o in data if o['commonName'] == org_cn]
     print json.dumps(data, indent=2)
--- a/create_or_update_organism.xml	Tue May 03 13:48:11 2016 -0400
+++ b/create_or_update_organism.xml	Thu Jan 12 11:52:28 2017 -0500
@@ -1,58 +1,53 @@
 <?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.create_or_update" name="WA2: Create or Update Organism" version="1.5">
+<tool id="edu.tamu.cpt2.webapollo.create_or_update" name="Create or Update Organism" version="3.0">
   <description>will create the organism if it doesn't exist, and update otherwise</description>
   <macros>
     <import>macros.xml</import>
   </macros>
+  <code file="webapollo.py"/>
   <expand macro="requirements"/>
   <command detect_errors="aggressive"><![CDATA[
-cp -R ${jbrowse.extra_files_path}/data/ /opt/apollo/data/galaxy/${jbrowse.id};
+cp -R ${jbrowse.extra_files_path}/data/ @DATA_DIR@/${jbrowse.id};
 
 python $__tool_directory__/create_or_update_organism.py
 
-@AUTH@
-
-#if str($blatdb) != "None":
-    --blatdb "$blatdb"
-#end if
+@ADMIN_AUTH@
 
 --genus "$genus"
 --species "$species"
 $public
 
-@CN_OR_GUESS@
+@ORG_OR_GUESS@
 
-"/opt/apollo/data/galaxy/${jbrowse.id}"
+"@DATA_DIR@/${jbrowse.id}"
 
 $__user_email__
 
 > $output]]></command>
   <inputs>
     <param name="jbrowse" type="data" format="html" label="JBrowse HTML Output" />
-    <param name="blatdb" type="data" label="Blat DB" optional="True" />
-
-    <expand macro="cn_or_guess" />
-    <param name="genus" type="text" label="Host Bacteria" optional="True" />
-    <param name="species" type="text" label="Phage Name" optional="True" />
+    <expand macro="org_or_guess" />
+    <param name="genus" type="text" label="Genus" optional="False" />
+    <param name="species" type="text" label="Species" optional="True" />
     <param name="public" type="boolean" truevalue="--public" falsevalue="" label="Is Organism Public" />
   </inputs>
   <outputs>
     <data format="json" name="output"/>
   </outputs>
   <help><![CDATA[
-**NOTA BENE**
-
-All organism data is currently shared. By using this tool your annotation data will be visible to your fellow lab members.
-This will be fixed at a later date.
-
-This only works with JBrowse v0.4 and above!
-
 **What it does**
 
 Adds an organism to the Apollo database. The tool takes the output of a
 JBrowse run as that contains all of the necessary information for which
 tracks are appropriate for a given analysis.
 
+**WARNINGS**
+
+- Do not use names which conflict with other users.
+- If you provide an Apollo JSON file, only the first organism block will
+  be used in Common Name determination, as it is improbable you wish to
+  apply a single JBrowse instance to multiple organisms.
+
 @REFERENCES@
       ]]></help>
 </tool>
--- a/export.py	Tue May 03 13:48:11 2016 -0400
+++ b/export.py	Thu Jan 12 11:52:28 2017 -0500
@@ -1,44 +1,74 @@
 #!/usr/bin/env python
+import sys
 import StringIO
-import sys
 import json
 import argparse
 from Bio import SeqIO
 from BCBio import GFF
-from webapollo import WebApolloInstance
+from webapollo import WAAuth, WebApolloInstance, CnOrGuess, GuessCn
+
+
+def export(org_cn, seqs):
+    org_data = wa.organisms.findOrganismByCn(org_cn)
+
+    data = StringIO.StringIO()
+
+    kwargs = dict(
+        exportType='GFF3',
+        seqType='genomic',
+        exportGff3Fasta=True,
+        output="text",
+        exportFormat="text",
+        organism=org_cn,
+    )
+
+    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)
+
+    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 = {}
+            if args.gff:
+                GFF.write([record], args.gff)
+            record.description = ""
+            if args.fasta:
+                SeqIO.write([record], args.fasta, 'fasta')
+
+    return org_data
 
 if __name__ == '__main__':
-    json
     parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Username')
-    parser.add_argument('password', help='WA Password')
-
-    parser.add_argument('commonName', nargs='+', help='Sequence Unique Names')
-
+    WAAuth(parser)
+    CnOrGuess(parser)
     parser.add_argument('--gff', type=argparse.FileType('w'))
     parser.add_argument('--fasta', type=argparse.FileType('w'))
+    parser.add_argument('--json', type=argparse.FileType('w'))
 
     args = parser.parse_args()
 
     wa = WebApolloInstance(args.apollo, args.username, args.password)
 
-    data = StringIO.StringIO(wa.io.write(
-        exportType='GFF3',
-        seqType='genomic',
-        exportAllSequences=False,
-        exportGff3Fasta=True,
-        output="text",
-        exportFormat="text",
-        # TODO: CPT specific convention!!!!!!!!
-        organism=args.commonName,
-        sequences=args.commonName
-    ))
-    data.seek(0)
+    org_cn_list, seqs = GuessCn(args, wa)
 
-    for record in GFF.parse(data):
-        record.annotations = {}
-        GFF.write([record], args.gff)
-        record.description = ""
-        SeqIO.write([record], args.fasta, 'fasta')
-        sys.exit()
+    org_data = []
+    for org_cn in org_cn_list:
+        indiv_org_data = export(org_cn, seqs)
+        org_data.append(indiv_org_data)
+    args.json.write(json.dumps(org_data, indent=2))
--- a/export.xml	Tue May 03 13:48:11 2016 -0400
+++ b/export.xml	Thu Jan 12 11:52:28 2017 -0500
@@ -1,32 +1,41 @@
 <?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.export" name="WA2: Retrieve/Export data" version="1.4">
-  <description>from WebApollo into Galaxy</description>
+<tool id="edu.tamu.cpt2.webapollo.export" name="Retrieve Data" version="3.0">
+  <description>from Apollo into Galaxy</description>
   <macros>
     <import>macros.xml</import>
   </macros>
+  <code file="webapollo.py"/>
   <expand macro="requirements"/>
   <command detect_errors="aggressive"><![CDATA[
 python $__tool_directory__/export.py
 
-@AUTH@
+@ADMIN_AUTH@
+
+@ORG_CN_OR_GUESS@
 
-@CN_OR_GUESS@
-
---gff $gff_out
---fasta $fasta_out
+--gff "$gff_out"
+--fasta "$fasta_out"
+--json "$json_out"
 
 ]]></command>
   <inputs>
     <expand macro="cn_or_guess" />
   </inputs>
   <outputs>
-    <data format="gff3" name="gff_out" />
-    <data format="fasta" name="fasta_out"/>
+    <data format="gff3" name="gff_out" label="Annotations from Apollo"/>
+    <data format="fasta" name="fasta_out" label="Sequence(s) from Apollo"/>
+    <data format="json" name="json_out" label="Metadata from Apollo"/>
   </outputs>
   <help><![CDATA[
 **What it does**
 
-Exports the GFF3/Fasta sequence from WebApollo.
+Exports the sequence data and annotations from Apollo.
+
+If you provide an Apollo JSON file as input to the Organism Common Name list,
+this will enable extracting multiple organism's data at once from Apollo.
+Beware that currently all gff3 and fasta responses are merged together. If you
+have two separate organisms with identically named reference sequences, it will
+not be possible to separate those out.
 
 @REFERENCES@
       ]]></help>
--- a/fetch_organism_jbrowse.py	Tue May 03 13:48:11 2016 -0400
+++ b/fetch_organism_jbrowse.py	Thu Jan 12 11:52:28 2017 -0500
@@ -1,9 +1,7 @@
 #!/usr/bin/env python
 import os
-import json
 import argparse
-import time
-from webapollo import WebApolloInstance
+from webapollo import WAAuth, WebApolloInstance, GuessOrg, OrgOrGuess
 import logging
 import subprocess
 logging.basicConfig(level=logging.INFO)
@@ -12,23 +10,18 @@
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Admin Username')
-    parser.add_argument('password', help='WA Admin Password')
-    parser.add_argument('cn', help='Organism Common Name')
-    parser.add_argument('email', help='User Email')
+    WAAuth(parser)
+    OrgOrGuess(parser)
     parser.add_argument('target_dir', help='Target directory')
 
     args = parser.parse_args()
 
-
     wa = WebApolloInstance(args.apollo, args.username, args.password)
     # User must have an account
-    gx_user = wa.users.loadUsers(email=args.email)
-    if len(gx_user) == 0:
-        raise Exception("Unknown user. Please register first")
-    org = wa.organisms.findOrganismByCn(args.cn)
-
+    org_cn = GuessOrg(args, wa)
+    if isinstance(org_cn, list):
+        org_cn = org_cn[0]
+    org = wa.organisms.findOrganismByCn(org_cn)
 
     if not os.path.exists(args.target_dir):
         os.makedirs(args.target_dir)
@@ -38,5 +31,4 @@
         org['directory'],
         os.path.join(args.target_dir, 'data')
     ]
-    print ' '.join(cmd)
     subprocess.check_call(cmd)
--- a/fetch_organism_jbrowse.xml	Tue May 03 13:48:11 2016 -0400
+++ b/fetch_organism_jbrowse.xml	Thu Jan 12 11:52:28 2017 -0500
@@ -1,17 +1,18 @@
 <?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.fetch_jbrowse" name="WA2: Fetch JBrowse" version="1.4">
-  <description>fetches JBrowse data for existing organisms</description>
+<tool id="edu.tamu.cpt2.webapollo.fetch_jbrowse" name="Retrieve JBrowse" version="3.0">
+  <description>for an organism, from Apollo</description>
   <macros>
     <import>macros.xml</import>
   </macros>
+  <code file="webapollo.py"/>
   <expand macro="requirements"/>
   <command detect_errors="aggressive"><![CDATA[
 mkdir -p $jbrowse.files_path/;
 
 python $__tool_directory__/fetch_organism_jbrowse.py
-@AUTH@
-@CN_OR_GUESS@
-$__user_email__
+@ADMIN_AUTH@
+
+@ORG_OR_GUESS@
 $jbrowse.files_path/;
 
 cp $dummyIndex $jbrowse;
@@ -45,21 +46,22 @@
       </configfile>
   </configfiles>
   <inputs>
-    <expand macro="cn_or_guess" />
+    <expand macro="org_or_guess" />
   </inputs>
   <outputs>
     <data format="html" name="jbrowse"/>
   </outputs>
   <help><![CDATA[
-**NOTA BENE**
-
-All organism data is currently shared. By using this tool your annotation data will be visible to your fellow lab members.
-This will be fixed at a later date.
-
 **What it does**
 
 Fetches the JBrowse directory from Apollo back into Galaxy.
 
+**WARNINGS**
+
+- If you provide an Apollo JSON file, only the first organism block will
+  be used in Common Name determination, as it is improbable you wish to
+  apply a single JBrowse instance to multiple organisms.
+
 @REFERENCES@
 ]]></help>
 </tool>
--- a/find_organism.py	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#!/usr/bin/env python
-import json
-import argparse
-from webapollo import WebApolloInstance
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Admin Username')
-    parser.add_argument('password', help='WA Admin Password')
-
-    parser.add_argument('--commonName', help='Common Name')
-
-    args = parser.parse_args()
-
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
-    data = wa.organisms.findAllOrganisms()
-    if args.commonName is not None:
-        data = [o for o in data if o['commonName'] == args.commonName]
-
-    print json.dumps(data, indent=2)
--- a/find_organism.xml	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-<?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.find_organism" name="WA2: Find Organism" version="1.0">
-  <description>finds an organism's details by common name</description>
-  <macros>
-    <import>macros.xml</import>
-  </macros>
-  <expand macro="requirements"/>
-  <command detect_errors="aggressive"><![CDATA[
-python $__tool_directory__/find_organism.py
-
-@AUTH@
-
---commonName
-@CN_OR_GUESS@
-
-> $output]]></command>
-  <inputs>
-    <expand macro="cn_or_guess" />
-  </inputs>
-  <outputs>
-    <data format="json" name="output"/>
-  </outputs>
-  <help><![CDATA[
-**What it does**
-
-Searches for an organism's information in the Apollo database.
-
-@REFERENCES@
-]]></help>
-</tool>
--- a/gff3_cleaner.py	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-import sys
-import argparse
-from gff3 import feature_lambda, feature_test_type
-from BCBio import GFF
-import logging
-logging.basicConfig(level=logging.WARN)
-log = logging.getLogger(name='pav')
-
-def coding_genes(feature_list):
-    for x in feature_lambda(feature_list, feature_test_type, {'type': 'gene'}, subfeatures=True):
-        if len(list(feature_lambda(x.sub_features, feature_test_type, {'type': 'CDS'}, subfeatures=False))) > 0:
-            yield x
-
-
-def genes(feature_list, feature_type='gene'):
-    for x in feature_lambda(feature_list, feature_test_type,
-                            {'type': feature_type},
-                            subfeatures=True):
-        yield x
-
-
-def fix_apollo_issues(annotations, user_email):
-    for rec in GFF.parse(annotations):
-        for feat in rec.features:
-            if feat.type != 'gene':
-                continue
-
-            for sf in feat.sub_features:
-                if sf.type != 'mRNA':
-                    continue
-
-                for ssf in sf.sub_features:
-                    if ssf.type != 'exon':
-                        continue
-
-                    if len(ssf) > 10:
-                        continue
-
-                    ssf.type = 'Shine_Dalgarno_sequence'
-
-                sf.sub_features = [x for x in sf.sub_features if x.type not in
-                                   ('non_canonical_five_prime_splice_site',
-                                    'non_canonical_three_prime_splice_site')]
-        yield rec
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='rebase gff3 features against parent locations', epilog="")
-    parser.add_argument('annotations', type=file, help='Parent GFF3 annotations')
-    # parser.add_argument('genome', type=file, help='Genome Sequence')
-    parser.add_argument('--user_email')
-
-    args = parser.parse_args()
-    for rec in fix_apollo_issues(**vars(args)):
-        rec.annotations = {}
-        GFF.write([rec], sys.stdout)
--- a/gff3_cleaner.xml	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-<?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.fix_model" name="Fix Apollo Gene Model" version="1.0">
-  <description></description>
-  <macros>
-    <import>macros.xml</import>
-  </macros>
-  <expand macro="requirements"/>
-  <command><![CDATA[
-$__tool_directory__/gff3_cleaner.py
-$gff3_data
-> $output]]></command>
-  <inputs>
-      <expand macro="gff3_input" />
-  </inputs>
-  <outputs>
-    <data format="gff3" name="output"/>
-  </outputs>
-  <tests>
-      <test>
-          <param name="gff3_data" value="bad-model.gff3" />
-          <output name="output" file="good-model.gff3" />
-      </test>
-  </tests>
-  <help><![CDATA[
-**What it does**
-
-This tool corrects the gene model to fix some issues with Apollo's model
-
--  small "exons" are returned to their correct state of "Shine_Dalgarno_sequence"
--  non_canonical_*_splice_sites are removed
-
-@REFERENCES@
-      ]]></help>
-</tool>
--- a/json2iframe.py	Tue May 03 13:48:11 2016 -0400
+++ b/json2iframe.py	Thu Jan 12 11:52:28 2017 -0500
@@ -7,15 +7,12 @@
     parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
     parser.add_argument('apollo', help='Complete Apollo URL')
     parser.add_argument('json', type=file, help='JSON Data')
+    parser.add_argument('external_apollo_url')
 
     args = parser.parse_args()
 
-
-    # https://cpt.tamu.edu/apollo/annotator/loadLink?loc=NC_005880:0..148317&organism=326&tracks=
+    # https://fqdn/apollo/annotator/loadLink?loc=NC_005880:0..148317&organism=326&tracks=
     data = json.load(args.json)
-    print data
-    if len(data) > 1:
-        raise Exception("More than one organism listed. Contact your local admin for help.")
 
     # This is base64 encoded to get past the toolshed's filters.
     HTML_TPL = """
@@ -27,4 +24,4 @@
     """
     HTML_TPL = base64.b64decode(HTML_TPL.replace('\n', ''))
 
-    print HTML_TPL.format(base_url=args.apollo, chrom="", orgId=data[0]['id'])
+    print HTML_TPL.format(base_url=args.external_apollo_url, chrom="", orgId=data[0]['id'])
--- a/json2iframe.xml	Tue May 03 13:48:11 2016 -0400
+++ b/json2iframe.xml	Thu Jan 12 11:52:28 2017 -0500
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.iframe" name="WA2: Annotate" version="1.4">
+<tool id="edu.tamu.cpt2.webapollo.iframe" name="Annotate" version="3.0">
   <description>opens an IFrame to Apollo</description>
   <macros>
     <import>macros.xml</import>
@@ -9,9 +9,10 @@
 python $__tool_directory__/json2iframe.py
 @URL@
 $json_file
+@EXT_URL@
 > $output]]></command>
   <inputs>
-    <param name="json_file" type="data" format="json" label="WebApollo Organism Listing" />
+    <param name="json_file" type="data" format="json" label="Apollo Organism Listing" />
   </inputs>
   <outputs>
     <data format="html" name="output"/>
@@ -19,7 +20,7 @@
   <help><![CDATA[
 **What it does**
 
-Given a json file that's output by the Galaxy<->WebApollo bridge, this
+Given a json file that's output by the Galaxy<->Apollo bridge, this
 generates a nice little IFrame that you can use to access Apollo
 
 @REFERENCES@
--- a/list_organisms.py	Tue May 03 13:48:11 2016 -0400
+++ b/list_organisms.py	Thu Jan 12 11:52:28 2017 -0500
@@ -1,17 +1,19 @@
 #!/usr/bin/env python
 import json
 import argparse
-from webapollo import WebApolloInstance
+from webapollo import WAAuth, WebApolloInstance, AssertUser, accessible_organisms
 
 if __name__ == '__main__':
-    json
     parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Username')
-    parser.add_argument('password', help='WA Password')
-
+    WAAuth(parser)
+    parser.add_argument('email', help='User Email')
     args = parser.parse_args()
 
     wa = WebApolloInstance(args.apollo, args.username, args.password)
-    print json.dumps(wa.organisms.findAllOrganisms(), indent=2)
+
+    gx_user = AssertUser(wa.users.loadUsers(email=args.email))
+    all_orgs = wa.organisms.findAllOrganisms()
 
+    orgs = accessible_organisms(gx_user, all_orgs)
+
+    print json.dumps(orgs, indent=2)
--- a/list_organisms.xml	Tue May 03 13:48:11 2016 -0400
+++ b/list_organisms.xml	Thu Jan 12 11:52:28 2017 -0500
@@ -1,13 +1,14 @@
 <?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.list_organism" name="WA2: List Organisms" version="1.2">
-  <description>lists all organisms know to Apollo</description>
+<tool id="edu.tamu.cpt2.webapollo.list_organism" name="List Organisms" version="3.0">
+  <description>in Apollo</description>
   <macros>
     <import>macros.xml</import>
   </macros>
   <expand macro="requirements"/>
   <command detect_errors="aggressive"><![CDATA[
 python $__tool_directory__/list_organisms.py
-@AUTH@
+@ADMIN_AUTH@
+$__user_email__
 > $output]]></command>
   <inputs>
   </inputs>
--- a/macros.xml	Tue May 03 13:48:11 2016 -0400
+++ b/macros.xml	Thu Jan 12 11:52:28 2017 -0500
@@ -3,48 +3,94 @@
   <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>
       <yield/>
     </requirements>
   </xml>
+  <token name="@DATA_DIR@">\$GALAXY_SHARED_DIR</token>
+  <token name="@EXT_URL@">
+\$GALAXY_WEBAPOLLO_EXT_URL
+  </token>
   <token name="@URL@">
 \$GALAXY_WEBAPOLLO_URL
   </token>
-  <token name="@AUTH@">
-@URL@
-galaxy@gmod.org
+  <token name="@USER_AUTH_REMOTE@">
+\$GALAXY_WEBAPOLLO_URL
+$__user_email__
+""
+--remote_user REMOTE_USER
+  </token>
+  <token name="@ADMIN_AUTH@">
+\$GALAXY_WEBAPOLLO_URL
+\$GALAXY_WEBAPOLLO_USER
 \$GALAXY_WEBAPOLLO_PASSWORD
   </token>
-  <xml name="auth_file">
-    <param label="Apollo Authentication File"
-    name="apolloCredentialsFile" type="data" format="json" />
-  </xml>
 
-  <token name="@CN_OR_GUESS@">
+  <token name="@ORG_OR_GUESS@">
 <![CDATA[
-#if $cn_source.source_select == "auto":
-    \$(cat $cn_source.cn_file | grep '^>' | head -n 1  | sed 's/\s.*//g;s/>//g')
-#elif $cn_source.source_select == "auto_json":
-    \$(cat $cn_source.cn_file | grep 'commonName' | head -n 1| sed 's/.*: "//g;s/".*//g')
-#else
-    "${cn_source.organism_cn}"
+#if $org_source.source_select == "auto_json":
+    --org_json "${org_source.org_file}"
+#elif $org_source.source_select == "select":
+    --org_id "${org_source.org_select}"
+#else:
+    --org_raw "${org_source.org_raw}"
 #end if
 ]]>
   </token>
-  <xml name="cn_or_guess">
-    <conditional name="cn_source">
+  <token name="@ORG_CN_OR_GUESS@">
+<![CDATA[
+@ORG_OR_GUESS@
+
+#if $cn_source.source_select == "auto":
+    #if str($cn_source.cn_file) != "None":
+        --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}"
+        #end for
+    #end if
+#end if
+]]>
+  </token>
+  <xml name="org_or_guess">
+    <conditional name="org_source">
         <param name="source_select" type="select" label="Organism Common Name Source">
-            <option value="auto">Autodetect from Fasta</option>
+            <option value="select">Select</option>
+            <option value="direct">Direct Entry</option>
             <option value="auto_json">Autodetect from Apollo JSON</option>
-            <option value="direct">Direct Entry</option>
         </param>
-        <when value="auto">
-            <param name="cn_file" type="data" format="fasta" label="Organism Common Name" />
+        <when value="select">
+            <param name="org_select" type="select" dynamic_options="galaxy_list_orgs(__trans__)" label="Organism" />
+        </when>
+        <when value="direct">
+            <param name="org_raw" type="text" label="Organism Common Name" />
         </when>
         <when value="auto_json">
-            <param name="cn_file" type="data" format="json" label="Apollo Organism File" />
+            <param name="org_file" type="data" format="json" label="Apollo Organism File" help="Will only fetch first organism" />
+        </when>
+    </conditional>
+  </xml>
+  <xml name="cn_or_guess">
+    <expand macro="org_or_guess" />
+    <conditional name="cn_source">
+        <param name="source_select" type="select" label="Organism Sequence(s) Source">
+            <option value="all">All Refseqs</option>
+            <option value="direct">Direct Entry</option>
+            <option value="auto">Autodetect from Fasta</option>
+        </param>
+        <when value="all">
+        </when>
+        <when value="auto">
+            <param name="cn_file" type="data" format="fasta" label="Reference sequence(s)" optional="true"/>
         </when>
         <when value="direct">
-            <param name="organism_cn" type="text" label="Organism Common Name" />
+            <repeat name="refseqs" title="Reference Sequences" help="These are used to identify sequences within an organism that you wish to extract">
+                <param name="refseq" type="text" label="Reference sequence(s)" />
+            </repeat>
         </when>
     </conditional>
   </xml>
@@ -53,21 +99,6 @@
       <citations>
       </citations>
   </xml>
-  <xml name="dummy">
-    <param label="Dummy Inputs" name="dummy" type="data" multiple="True" optional="True">
-        <help>
-            With workflows that contact remote databases, it is sometimes
-            necessary to have particular operations happen in a particular
-            order. I.e. you would not want to try and add data to an organism
-            if the organism did not yet exist in WebApollo.
-            Since few of the WebApollo2 toolsuite output files which are
-            used in a downstream task (e.g. the output adding an organism is
-            not used elsewhere), we provide this dummy option which lets you
-            select outputs to help provide context for when this task should
-            execute.
-        </help>
-    </param>
-  </xml>
   <xml name="gff3_input">
     <param label="GFF3 Annotations" name="gff3_data" type="data" format="gff3"/>
   </xml>
--- a/renumber.py	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-#!/usr/bin/env python
-import json
-import copy
-import argparse
-from webapollo import WebApolloInstance
-import logging
-logging.basicConfig(level=logging.INFO)
-log = logging.getLogger(__name__)
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Admin Username')
-    parser.add_argument('password', help='WA Admin Password')
-
-    parser.add_argument('cn', help='Organism Common Name')
-
-    parser.add_argument('--email')
-    parser.add_argument('--prefix', default='gene_')
-    parser.add_argument('--leading', default='3')
-
-    args = parser.parse_args()
-
-
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
-    # User must have an account
-    gx_user = wa.users.loadUsers(email=args.email)
-    if len(gx_user) == 0:
-        raise Exception("Unknown user. Please register first")
-
-    # Must find the organism
-    org = wa.organisms.findOrganismByCn(args.cn)
-    # TODO: verify user has permissions on the organism
-    wa.annotations.setSequence(args.cn, org['id'])
-    raw_data =  wa.annotations.getFeatures()['features']
-
-    data = sorted([
-        (x['parent_id'], x['uniquename'], x['location']['fmin'], x['name'])
-        for x in raw_data
-    ], key=lambda x: x[2])
-
-    format_string = args.prefix + '%0' + args.leading + 'd'
-    format_string_mrna = format_string + '.mRNA'
-
-    outData = copy.copy(org)
-    outData['changes'] = []
-
-    for i, feat in enumerate(data):
-        idx = i + 1
-        log.info('Renaming %s to %s', feat[3], format_string % idx)
-        outData['changes'].append((feat[0], format_string % idx))
-        wa.annotations.setName(feat[0], format_string % idx)
-        outData['changes'].append((feat[1], format_string_mrna % idx))
-        wa.annotations.setName(feat[1], format_string_mrna % idx)
-
-    print json.dumps(outData, indent=2)
--- a/renumber.xml	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-<?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.renumber" name="WA2: Renumber Genes" version="1.1">
-  <description>following standard conventions</description>
-  <macros>
-    <import>macros.xml</import>
-  </macros>
-  <expand macro="requirements"/>
-  <command detect_errors="aggressive"><![CDATA[
-python $__tool_directory__/renumber.py
-
-@AUTH@
-
-@CN_OR_GUESS@
-
---prefix $prefix
---leading $leading
---email $__user_email__
-
-> $output]]></command>
-  <inputs>
-    <expand macro="cn_or_guess" />
-    <param name="prefix" type="text" label="Prefix" optional="True" value="gene_"/>
-    <param name="leading" type="integer" value="3" label="Number of Leading Zeroes" />
-  </inputs>
-  <outputs>
-    <data format="json" name="output"/>
-  </outputs>
-  <help><![CDATA[
-**NOTA BENE**
-
-All organism data is currently shared. By using this tool your annotation data will be visible to your fellow lab members.
-This will be fixed at a later date.
-
-This only works with JBrowse v0.4 and above!
-
-**What it does**
-
-Adds an organism to the Apollo database. The tool takes the output of a
-JBrowse run as that contains all of the necessary information for which
-tracks are appropriate for a given analysis.
-
-@REFERENCES@
-      ]]></help>
-</tool>
--- a/test.json	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-[
-    {
-        "chrom": "Test",
-        "id": 123
-    }
-]
--- a/update_organism.py	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-import json
-import argparse
-from webapollo import WebApolloInstance
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Sample script to add an attribute to a feature via web services')
-    parser.add_argument('apollo', help='Complete Apollo URL')
-    parser.add_argument('username', help='WA Admin Username')
-    parser.add_argument('password', help='WA Admin Password')
-
-    parser.add_argument('organismId', help='Organism ID #')
-    parser.add_argument('email', help='User Email')
-
-    parser.add_argument('--commonName', help='Organism Common Name')
-    parser.add_argument('--jbrowse', help='JBrowse Data Directory')
-    parser.add_argument('--blatdb', help='BlatDB Directory')
-    parser.add_argument('--genus', help='Organism Genus')
-    parser.add_argument('--species', help='Organism Species')
-    parser.add_argument('--public', action='store_true', help='Make organism public')
-
-    args = parser.parse_args()
-
-    wa = WebApolloInstance(args.apollo, args.username, args.password)
-    data = wa.organisms.updateOrganismInfo(
-        args.organismId,
-        args.commonName,
-        args.jbrowse,
-        # mandatory
-        blatdb=args.blatdb,
-        genus=args.genus,
-        species=args.species,
-        public=args.public
-    )
-    # Need to filter data
-    wanted_data = [x for x in data if str(x['id']) == str(args.organismId)]
-    print json.dumps(wanted_data, indent=2)
--- a/update_organism.xml	Tue May 03 13:48:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-<?xml version="1.0"?>
-<tool id="edu.tamu.cpt2.webapollo.update_organism" name="WA2: Update Organism" version="1.7">
-  <description>updates an existing genome with WebApollo</description>
-  <macros>
-    <import>macros.xml</import>
-  </macros>
-  <expand macro="requirements"/>
-  <command detect_errors="aggressive"><![CDATA[
-#if str($jbrowse) != "None":
-    cp -R ${jbrowse.extra_files_path}/data/ /opt/apollo/data/galaxy/${jbrowse.id};
-#end if
-
-python $__tool_directory__/update_organism.py
-
-@AUTH@
-
-\$(python $__tool_directory__/find_organism.py @AUTH@ --commonName @CN_OR_GUESS@ | grep '"id"' | sed 's/.*: //g')
-
-#if str($jbrowse) !="None":
-    --jbrowse "/opt/apollo/data/galaxy/${jbrowse.id}"
-#end if
-
---commonName
-@CN_OR_GUESS@
-
-#if str($blatdb) != "None" and str($blatdb) != "":
-    --blatdb "$blatdb"
-#end if
-
-#if str($genus) != "None" and str($genus) != "":
-    --genus "$genus"
-#end if
-
-#if str($species) != "None" and str($species) != "":
-    --species "$species"
-#end if
-
-$public
-
-$__user_email__
-
-> $output]]></command>
-  <inputs>
-    <!--<expand macro="auth_file" />-->
-    <param name="jbrowse" type="data" format="html" label="JBrowse Output" optional="True"/>
-    <param name="blatdb" type="data" label="Blat DB"  optional="True"/>
-    <expand macro="cn_or_guess" />
-    <param name="genus" type="text" label="Host Bacteria" optional="True" />
-    <param name="species" type="text" label="Phage Name" optional="True" />
-
-    <param name="public" type="boolean" truevalue="--public" falsevalue="" label="Is Organism Public" />
-  </inputs>
-  <outputs>
-    <data format="json" name="output"/>
-  </outputs>
-  <help><![CDATA[
-**NOTA BENE**
-
-All organism data is currently shared. By using this tool your annotation data will be visible to your fellow lab members.
-This will be fixed at a later date.
-
-This only works with JBrowse v0.4 and above!
-
-**What it does**
-
-Adds an organism to the Apollo database. The tool takes the output of a
-JBrowse run as that contains all of the necessary information for which
-tracks are appropriate for a given analysis.
-
-@REFERENCES@
-      ]]></help>
-</tool>
--- a/webapollo.py	Tue May 03 13:48:11 2016 -0400
+++ b/webapollo.py	Thu Jan 12 11:52:28 2017 -0500
@@ -1,13 +1,79 @@
 import requests
 import json
+import os
 import collections
-from BCBio import GFF
 import StringIO
 import logging
+from BCBio import GFF
+from Bio import SeqIO
 logging.getLogger("requests").setLevel(logging.CRITICAL)
 log = logging.getLogger()
 
 
+def WAAuth(parser):
+    parser.add_argument('apollo', help='Complete Apollo URL')
+    parser.add_argument('username', help='WA Username')
+    parser.add_argument('password', help='WA Password')
+    parser.add_argument('--remote_user', default='', help='If set, ignore password, set the header with the name supplied to this argument to the value of email')
+
+
+def OrgOrGuess(parser):
+    parser.add_argument('--org_json', type=file, help='Apollo JSON output, source for common name')
+    parser.add_argument('--org_raw', help='Common Name')
+    parser.add_argument('--org_id', help='Organism ID')
+
+
+def CnOrGuess(parser):
+    OrgOrGuess(parser)
+    parser.add_argument('--seq_fasta', type=file, help='Fasta file, IDs used as sequence sources')
+    parser.add_argument('--seq_raw', nargs='*', help='Sequence Names')
+
+
+def GuessOrg(args, wa):
+    if args.org_json:
+        orgs = [x.get('commonName', None)
+                for x in json.load(args.org_json)]
+        orgs = [x for x in orgs if x is not None]
+        return orgs
+    elif args.org_raw:
+        org = args.org_raw.strip()
+        if len(org) > 0:
+            return [org]
+        else:
+            raise Exception("Organism Common Name not provided")
+    elif args.org_id:
+        return [wa.organisms.findOrganismById(args.org_id).get('commonName', None)]
+    else:
+        raise Exception("Organism Common Name not provided")
+
+
+def GuessCn(args, wa):
+    org = GuessOrg(args, wa)
+    seqs = []
+    if args.seq_fasta:
+        # If we have a fasta, pull all rec ids from that.
+        for rec in SeqIO.parse(args.seq_fasta, 'fasta'):
+            seqs.append(rec.id)
+    elif args.seq_raw:
+        # Otherwise raw list.
+        seqs = [x.strip() for x in args.seq_raw if len(x.strip()) > 0]
+
+    return org, seqs
+
+
+def AssertUser(user_list):
+    if len(user_list) == 0:
+        raise Exception("Unknown user. Please register first")
+    else:
+        return user_list[0]
+
+
+def AssertAdmin(user):
+    if user.role == 'ADMIN':
+        return True
+    else:
+        raise Exception("User is not an administrator. Permission denied")
+
 
 class WebApolloInstance(object):
 
@@ -53,7 +119,6 @@
 
         self.__props = kwargs.keys()
 
-
     def isAdmin(self):
         if hasattr(self, 'role'):
             return self.role == self.ROLE_ADMIN
@@ -100,9 +165,9 @@
         })
 
         r = requests.post(url, data=json.dumps(data), headers=headers,
-                          verify=self.__verify, params=post_params, **self._requestArgs)
+                          verify=self.__verify, params=post_params, allow_redirects=False, **self._requestArgs)
 
-        if r.status_code == 200:
+        if r.status_code == 200 or r.status_code == 302:
             if isJson:
                 d = r.json()
                 if 'username' in d:
@@ -146,7 +211,9 @@
     CLIENT_BASE = '/annotationEditor/'
 
     def _update_data(self, data):
-        if not hasattr(self, '_extra_data'): raise Exception("Please call setSequence first")
+        if not hasattr(self, '_extra_data'):
+            raise Exception("Please call setSequence first")
+
         data.update(self._extra_data)
         return data
 
@@ -399,7 +466,7 @@
         return self.request('getOrganismPermissionsForGroup', data)
 
     def loadGroups(self, group=None):
-        data ={}
+        data = {}
         if group is not None:
             data['groupId'] = group.groupId
 
@@ -517,6 +584,14 @@
         else:
             return orgs[0]
 
+    def findOrganismById(self, id_number):
+        orgs = self.findAllOrganisms()
+        orgs = [x for x in orgs if str(x['id']) == str(id_number)]
+        if len(orgs) == 0:
+            raise Exception("Unknown ID")
+        else:
+            return orgs[0]
+
     def deleteOrganism(self, organismId):
         return self.request('deleteOrganism', {'id': organismId})
 
@@ -547,11 +622,16 @@
 class UsersClient(Client):
     CLIENT_BASE = '/user/'
 
+    # Real one
+    # def getOrganismPermissionsForUser(self, user):
+    # data = {
+    # 'userId': user.userId,
+    # }
+    # return self.request('getOrganismPermissionsForUser', data)
+
+    # Utter frigging hack
     def getOrganismPermissionsForUser(self, user):
-        data = {
-            'userId': user.userId,
-        }
-        return self.request('getOrganismPermissionsForUser', data)
+        return self.loadUser(user).organismPermissions
 
     def updateOrganismPermission(self, user, organism, administrate=False,
                                  write=False, export=False, read=False):
@@ -651,7 +731,6 @@
 
     def __getattr__(self, key):
         if key in ('_sr', '_wa'):
-            print self.__dict__
             return self.__dict__[key]
         else:
             if key == 'features':
@@ -666,7 +745,6 @@
         else:
             self._sr.__dict__[key] = value
             # Methods acting on the SeqRecord object
-            print key, value
 
 
 class WebApolloSeqFeature(object):
@@ -703,7 +781,7 @@
                 self._sf.__dict__[key] = value
             else:
                 self._sf.__dict__[key] = value
-                print key, value
+
 
 def _tnType(feature):
     if feature.type in ('gene', 'mRNA', 'exon', 'CDS'):
@@ -711,6 +789,7 @@
     else:
         return 'exon'
 
+
 def _yieldFeatData(features):
     for f in features:
         current = {
@@ -733,6 +812,7 @@
 
         yield current
 
+
 def featuresToFeatureSchema(features):
     compiled = []
     for feature in features:
@@ -743,3 +823,36 @@
         for x in _yieldFeatData([feature]):
             compiled.append(x)
     return compiled
+
+
+def accessible_organisms(user, orgs):
+    permissionMap = {
+        x['organism']: x['permissions']
+        for x in user.organismPermissions
+        if 'WRITE' in x['permissions'] or
+        'READ' in x['permissions'] or
+        'ADMINISTRATE' in x['permissions'] or
+        user.role == 'ADMIN'
+    }
+    return [
+        (org['commonName'], org['id'], False)
+        for org in sorted(orgs, key=lambda x: x['commonName'])
+        if org['commonName'] in permissionMap
+    ]
+
+
+def galaxy_list_orgs(trans, *args, **kwargs):
+    email = trans.get_user().email
+
+    wa = WebApolloInstance(
+        os.environ.get('GALAXY_WEBAPOLLO_URL', 'https://example.com'),
+        os.environ.get('GALAXY_WEBAPOLLO_USER', 'admin'),
+        os.environ.get('GALAXY_WEBAPOLLO_PASSWORD', 'admin')
+    )
+
+    gx_user = AssertUser(wa.users.loadUsers(email=email))
+    all_orgs = wa.organisms.findAllOrganisms()
+
+    orgs = accessible_organisms(gx_user, all_orgs)
+
+    return orgs