# HG changeset patch
# User yating-l
# Date 1511804967 18000
# Node ID 9945eba268e6bcd3feff9842b5de03f3845dc42a
planemo upload for repository https://github.com/Yating-L/suite_gonramp_apollo.git commit 9009fa8663038d2cb4a1c5130600a51f31f654a1-dirty
diff -r 000000000000 -r 9945eba268e6 README.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/README.rst Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,64 @@
+Suite G-OnRamp Apollo
+=====================
+
+A suite of Galaxy tools for managing a local Apollo server. It includes following tools:
+
+JBrowseHub to Apollo
+--------------------
+
+This Galaxy tool is used to create or overwrite an organism on an Apollo server with a jbrowse hub created by JBrowse Archive Creator.
+
+Apollo User Manager
+-------------------
+
+This Galaxy tool is used to manage Apollo users. The currently supported operation including:
+
+ - Create a new user
+ - Delete a user
+ - Add a user to a group (If the group doesn't exist, create the group)
+ - Remove a user to a group
+
+The tool can do these operations on one student at a time. It can also do the operations on multiple students at a time by uploading a text file, which including students information.
+
+The text file can be either CSV (comma-delimited) or Tabular (tab-delimited). It should have a header line, including names for each column. Example text files:
+
+Text file for creating multiple users:
+
+.. csv-table::
+ :header: "useremail", "firstname", "lastname", "password"
+ :widths: 20, 10, 10, 10
+
+ "test1@demo.com", "test1", "demo", "1234"
+ "test2@demo.com", "test2", "demo", "1234"
+ "test3@demo.com", "test3", "demo", "1234"
+
+
+Text file for deleting multiple users:
+
+.. csv-table::
+ :header: "useremail"
+ :widths: 20
+
+ "test1@demo.com"
+ "test2@demo.com"
+ "test3@demo.com"
+
+Text file for adding multiple users to a group:
+
+.. csv-table::
+ :header: "useremail", "group"
+ :widths: 20, 20
+
+ "test1@demo.com", "Test group"
+ "test2@demo.com", "Test group"
+ "test3@demo.com", "Test group"
+
+Text file for removing multiple users to a group:
+
+.. csv-table::
+ :header: "useremail", "group"
+ :widths: 20, 20
+
+ "test1@demo.com", "Test group"
+ "test2@demo.com", "Test group"
+ "test3@demo.com", "Test group"
diff -r 000000000000 -r 9945eba268e6 apollo/ApolloInstance.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apollo/ApolloInstance.py Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+import os
+import json
+import shutil
+import tempfile
+import logging
+import random
+import string
+from util import subtools
+from mako.lookup import TemplateLookup
+
+from ApolloOrganism import ApolloOrganism
+from ApolloUser import ApolloUser
+
+class ApolloInstance(object):
+ def __init__(self, apollo_host, apollo_admin, tool_directory):
+ self.apollo_host = apollo_host
+ self.tool_directory = tool_directory
+ self.logger = logging.getLogger(__name__)
+ self.apollo_admin = apollo_admin
+ self.apolloTemplate = self._getApolloTemplate()
+ self._arrow_init()
+
+
+ def _arrow_init(self):
+ subtools.verify_user_login(self.apollo_admin['user_email'], self.apollo_admin['password'], self.apollo_host)
+ arrow_config = tempfile.NamedTemporaryFile(bufsize=0)
+ with open(arrow_config.name, 'w') as conf:
+ htmlMakoRendered = self.apolloTemplate.render(
+ apollo_host = self.apollo_host,
+ admin_user = self.apollo_admin['user_email'],
+ admin_pw = self.apollo_admin['password']
+ )
+ conf.write(htmlMakoRendered)
+
+ home_dir = os.path.expanduser('~')
+ arrow_config_dir = os.path.join(home_dir, '.apollo-arrow.yml')
+ shutil.copyfile(arrow_config.name, arrow_config_dir)
+ self.logger.debug("Initated arrow: apollo-arrow.yml= %s", arrow_config_dir)
+
+ #TODO: Encode admin password
+ '''
+ def _generatePassword(self, length=8):
+ chars = string.digits + string.letters
+ pw = ''.join([random.choice(chars) for _ in range(length)])
+ return pw
+ '''
+
+ def _getApolloTemplate(self):
+ mylookup = TemplateLookup(directories=[os.path.join(self.tool_directory, 'templates')],
+ output_encoding='utf-8', encoding_errors='replace')
+ apolloTemplate = mylookup.get_template("apollo-arrow.yml")
+ return apolloTemplate
+
+
+ def manageApolloOrganism(self, organism_name, organism_dir, action):
+ organism = ApolloOrganism(organism_name, organism_dir)
+ if action == "add":
+ organism.addOrganism()
+ self.logger.info("Successfully add a new organism (%s) to Apollo", organism_name)
+ elif action == "overwrite":
+ organism.overwriteOrganism()
+ self.logger.info("Successfully overwrite the organism %s", organism_name)
+ else:
+ self.logger.error("Invalid operation %s", action)
+ exit(-1)
+
+ def manageApolloUser(self, operations_dictionary = dict()):
+ for operation, users_list in operations_dictionary.items():
+ apollo_user = ApolloUser(users_list)
+ if operation == "create":
+ apollo_user.createApolloUser()
+ elif operation == "delete":
+ apollo_user.deleteApolloUser()
+ elif operation == "add":
+ apollo_user.addApolloUserToGroup()
+ elif operation == "delete":
+ apollo_user.removeApolloUserFromeGroup()
+
+
diff -r 000000000000 -r 9945eba268e6 apollo/ApolloInstance.pyc
Binary file apollo/ApolloInstance.pyc has changed
diff -r 000000000000 -r 9945eba268e6 apollo/ApolloOrganism.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apollo/ApolloOrganism.py Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+
+import json
+import logging
+from util import subtools
+
+class ApolloOrganism(object):
+
+ def __init__(self, organism_name, organism_dir):
+ self.organism_name = organism_name
+ self.organism_dir = organism_dir
+ self.logger = logging.getLogger(__name__)
+
+ def addOrganism(self):
+ exist = self.getOrganism(self.organism_name)
+ if not exist:
+ self.logger.debug("The organism does not exist.")
+ p = subtools.arrow_add_organism(self.organism_name, self.organism_dir)
+ if not p:
+ self.logger.error("The user is not authorized to add organism")
+ exit(-1)
+ organism = json.loads(p)
+ organism_id = organism['id']
+ self.logger.debug("A new organism %s was added to Apollo instance", p)
+ return organism_id
+ else:
+ self.logger.error("The organism %s is already on Apollo instance! Rerun the tool to use a different species name or choose to overwrite the organism", self.organism_name)
+ exit(-1)
+
+ #TODO: the JSON dictionary return by deleteOrganism still contains the deleted organism. Improve the API.
+ def deleteOrganism(self):
+ organism_id = self.getOrganism(self.organism_name)
+ if organism_id:
+ self.logger.debug("Deleting the organism %s", self.organism_name)
+ subtools.arrow_delete_organism(organism_id)
+ if not self.getOrganism(self.organism_name):
+ self.logger.debug("Organism %s has been deleted", self.organism_name)
+ else:
+ self.logger.error("Organism %s cannot be deleted", self.organism_name)
+ exit(-1)
+ else:
+ self.logger.error("Organism %s doesn't exist", self.organism_name)
+ exit(-1)
+
+ #TODO: filtering by commonName doesn't work. Improve the API.
+ @staticmethod
+ def getOrganism(organism_name):
+ p = subtools.arrow_get_organism(organism_name)
+ if p:
+ return str(p)
+
+ #TODO: API update_organism not working. Improve the API to enable updating directory.
+ def overwriteOrganism(self):
+ self.deleteOrganism()
+ p = subtools.arrow_add_organism(self.organism_name, self.organism_dir)
+ if not p:
+ self.logger.error("The user is not authorized to add organism")
+ exit(-1)
+ organism = json.loads(p)
+ organism_id = organism['id']
+ self.logger.debug("A new organism %s has been added to Apollo instance", p)
+ return organism_id
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 apollo/ApolloOrganism.pyc
Binary file apollo/ApolloOrganism.pyc has changed
diff -r 000000000000 -r 9945eba268e6 apollo/ApolloUser.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apollo/ApolloUser.py Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,98 @@
+#!/usr/bin/python
+
+
+import os
+import sys
+import json
+import logging
+from util import subtools
+
+class ApolloUser(object):
+ """
+ This class is to manage Apollo users, such as create, delete, add users to a group or delete users from a group
+
+ """
+
+ def __init__(self, users_list):
+ self.users_list = users_list
+ self.logger = logging.getLogger(__name__)
+
+
+ def createApolloUser(self):
+ for user in self.users_list:
+ if user['batch'] == "false":
+ subtools.arrow_create_user(user['useremail'], user['firstname'], user['lastname'], user['password'])
+ elif user['batch'] == "true":
+ users = self.parseUserInfoFile(user['format'], user['false_path'])
+ for u in users:
+ if not 'useremail' in u:
+ self.logger.error("Cannot find useremail in the text file, make sure you use the correct header, see README file for examples.")
+ if not 'firstname' in u:
+ self.logger.error("Cannot find firstname in the text file, make sure you use the correct header, see README file for examples.")
+ if not 'lastname' in u:
+ self.logger.error("Cannot find lastname in the text file, make sure you use the correct header, see README file for examples.")
+ if not 'password' in u:
+ self.logger.error("Cannot find password in the text file, make sure you use the correct header, see README file for examples.")
+ subtools.arrow_create_user(u['useremail'], u['firstname'], u['lastname'], u['password'])
+
+
+ def parseUserInfoFile(self, file_format, filename):
+ if file_format == "tab":
+ delimiter = '\t'
+ elif file_format == "csv":
+ delimiter = ','
+ else:
+ self.logger.error("The %s format is not supported!", file_format)
+ with open(filename, 'r') as f:
+ lines = f.readlines()
+ headers = lines[0].rstrip().split(delimiter)
+ users = []
+ lines = lines[1:]
+ for l in lines:
+ print l
+ l = l.split(delimiter)
+ info = dict()
+ fields = len(l)
+ for i in range(fields):
+ info[headers[i]] = l[i]
+ users.append(info)
+ return users
+
+ def deleteApolloUser(self):
+ for user in self.users_list:
+ if user['batch'] == "false":
+ subtools.arrow_delete_user(user['useremail'])
+ elif user['batch'] == "true":
+ users = self.parseUserInfoFile(user['format'], user['false_path'])
+ for u in users:
+ if not 'useremail' in u:
+ self.logger.error("Cannot find useremail in the text file, make sure you use the correct header, see README file for examples.")
+ subtools.arrow_delete_user(u['useremail'])
+
+ def addApolloUserToGroup(self):
+ for user in self.users_list:
+ if user['batch'] == "false":
+ subtools.arrow_add_to_group(user['group'], user['useremail'])
+ elif user['batch'] == "true":
+ users = self.parseUserInfoFile(user['format'], user['false_path'])
+ for u in users:
+ if not 'useremail' in u:
+ self.logger.error("Cannot find useremail in the text file, make sure you use the correct header, see README file for examples.")
+ if not 'group' in u:
+ self.logger.error("Cannot find group in the text file, make sure you use the correct header, see README file for examples.")
+ subtools.arrow_add_to_group(u['group'], u['useremail'])
+
+ def removeApolloUserFromeGroup(self):
+ for user in self.users_list:
+ if user['batch'] == "false":
+ subtools.arrow_remove_from_group(user['group'], user['useremail'])
+ elif user['batch'] == "true":
+ users = self.parseUserInfoFile(user['format'], user['false_path'])
+ for u in users:
+ if not 'useremail' in u:
+ self.logger.error("Cannot find useremail in the text file, make sure you use the correct header, see README file for examples.")
+ if not 'group' in u:
+ self.logger.error("Cannot find group in the text file, make sure you use the correct header, see README file for examples.")
+ subtools.arrow_add_to_group(u['group'], u['useremail'])
+
+
diff -r 000000000000 -r 9945eba268e6 apollo/ApolloUser.pyc
Binary file apollo/ApolloUser.pyc has changed
diff -r 000000000000 -r 9945eba268e6 apollo/__init__.py
diff -r 000000000000 -r 9945eba268e6 apollo/__init__.pyc
Binary file apollo/__init__.pyc has changed
diff -r 000000000000 -r 9945eba268e6 apolloUserManager.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apolloUserManager.py Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+import os
+import sys
+import argparse
+import json
+import logging
+import socket
+from apollo.ApolloInstance import ApolloInstance
+from apollo.ApolloUser import ApolloUser
+from util.Reader import Reader
+from util.Logger import Logger
+
+
+def main(argv):
+ parser = argparse.ArgumentParser(description='Upload a hub to display on Apollo.')
+ parser.add_argument('-j', '--data_json', help='JSON file containing the metadata of the inputs')
+ parser.add_argument('-o', '--output', help='HTML output')
+
+ # Get the args passed in parameter
+ args = parser.parse_args()
+ json_inputs_data = args.data_json
+ outputFile = args.output
+
+ ##Parse JSON file with Reader
+ reader = Reader(json_inputs_data)
+
+ # Begin init variables
+
+ apollo_port = reader.getPortNum()
+ apollo_host = "http://localhost:"+ apollo_port + "/apollo"
+ apollo_admin_user = reader.getAdminUser()
+ toolDirectory = reader.getToolDir()
+ debug_mode = reader.getDebugMode()
+
+ operations_dictionary = reader.getOperationList()
+ #OPERATIONS = ['create', 'delete', 'add', 'remove']
+ #create_user_list = reader.getOperationList("create")
+ #delete_user_list = reader.getOperationList("delete")
+ #remove_user_list = reader.getOperationList("remove")
+ #add_user_list = reader.getOperationList("add")
+
+
+
+ #### Logging management ####
+ # If we are in Debug mode, also print in stdout the debug dump
+ log = Logger(tool_directory=toolDirectory, debug=debug_mode)
+ log.setup_logging()
+
+ logging.info("#### Apollo User Manager: Start on Apollo instance: %s #### ", apollo_host)
+ logging.debug('JSON parameters: %s\n\n', json.dumps(reader.args))
+
+ # Set up apollo
+ apollo = ApolloInstance(apollo_host, apollo_admin_user, toolDirectory)
+ apollo.manageApolloUser(operations_dictionary)
+
+ logging.info('#### Apollo User Manager: Congratulation! ####\n')
+
+
+
+
+if __name__ == "__main__":
+ main(sys.argv)
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 apolloUserManager.pyc
Binary file apolloUserManager.pyc has changed
diff -r 000000000000 -r 9945eba268e6 apolloUserManager.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apolloUserManager.xml Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,289 @@
+
+
+ This Galaxy tool is used to manage Apollo users.
+
+
+ macros.xml
+
+
+
+ apollo_api
+
+
+
+
+
+
+
+
+import json
+import sys
+
+file_path = sys.argv[1]
+#set global data_parameter_dict = {"operations": dict()}
+## Function to retrieve the data of the inputs
+#def prepare_json($operation_type, $data_dict, $batch)
+ #silent $data_dict.update({"batch": str($batch)})
+ #if $operation_type in $data_parameter_dict["operations"]
+ #silent $data_parameter_dict["operations"][$operation_type].append($data_dict)
+ #else
+ #set array_inputs = []
+ #silent $array_inputs.append($data_dict)
+ #silent $data_parameter_dict["operations"].update({$operation_type: $array_inputs})
+ #end if
+#end def
+
+
+
+
+#for $i, $f in enumerate($operation)
+ #if $f.operation_type_selector.operation_type == "create"
+ #set batch = $f.operation_type_selector.batch_selector.batch
+ #if $batch == "false"
+ #set data_dict = {"useremail": str($f.operation_type_selector.batch_selector.user_email),
+ "firstname": str($f.operation_type_selector.batch_selector.firstname),
+ "lastname": str($f.operation_type_selector.batch_selector.lastname),
+ "password": str($f.operation_type_selector.batch_selector.password)}
+
+ #else
+ #set data_dict = {"format": str($f.operation_type_selector.batch_selector.format),
+ "false_path": str($f.operation_type_selector.batch_selector.user_info_file)}
+ #end if
+ #silent $prepare_json("create", $data_dict, $batch)
+
+ #elif $f.operation_type_selector.operation_type == "delete"
+ #set batch = $f.operation_type_selector.batch_selector.batch
+ #if $batch == "false"
+ #set data_dict = {"useremail": str($f.operation_type_selector.batch_selector.user_email)}
+ #else
+ #set data_dict = {"format": str($f.operation_type_selector.batch_selector.format),
+ "false_path": str($f.operation_type_selector.batch_selector.user_info_file)}
+ #end if
+ #silent $prepare_json("delete", $data_dict, $batch)
+ #elif $f.operation_type_selector.operation_type == "add"
+ #set batch = $f.operation_type_selector.batch_selector.batch
+ #if $batch == "false"
+ #set data_dict = {"useremail": str($f.operation_type_selector.batch_selector.user_email),
+ "group": str($f.operation_type_selector.batch_selector.group_name)}
+ #else
+ #set data_dict = {"format": str($f.operation_type_selector.batch_selector.format),
+ "false_path": str($f.operation_type_selector.batch_selector.user_info_file)}
+ #end if
+ #silent $prepare_json("add", $data_dict, $batch)
+ #elif $f.operation_type_selector.operation_type == "remove"
+ #set batch = $f.operation_type_selector.batch_selector.batch
+ #if $batch == "false"
+ #set data_dict = {"useremail": str($f.operation_type_selector.batch_selector.user_email),
+ "group": str($f.operation_type_selector.batch_selector.group_name)}
+ #else
+ #set data_dict = {"format": str($f.operation_type_selector.batch_selector.format),
+ "false_path": str($f.operation_type_selector.batch_selector.user_info_file)}
+ #end if
+ #silent $prepare_json("remove", $data_dict, $batch)
+ #end if
+#end for
+
+
+#set apollo_admin = {"user_email": str($admin_username), "password": str($admin_password)}
+#silent $data_parameter_dict.update({"apollo_admin": $apollo_admin})
+#silent $data_parameter_dict.update({"tool_directory": str($__tool_directory__)})
+#silent $data_parameter_dict.update({"port": str($advanced_options.port)})
+#silent $data_parameter_dict.update({"debug_mode": str($advanced_options.debug_mode)})
+with open(file_path, 'w') as f:
+ json.dump($data_parameter_dict, f)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use this option if you are a G-OnRamp developer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This Galaxy tool is used to manage Apollo users.The currently supported operation including:
+
+ - Create a new user
+ - Delete a user
+ - Add a user to a group (If the group doesn't exist, create the group)
+ - Remove a user to a group
+
+The tool can do these operations on one student at a time. It can also do the operations on multiple students at a time by uploading a text file, which including students information.
+
+The text file can be either CSV (comma-delimited) or Tabular (tab-delimited). It should have a header line, including names for each column. Example text files:
+
+Text file for creating multiple users:
+
+.. csv-table::
+ :header: "useremail", "firstname", "lastname", "password"
+ :widths: 20, 10, 10, 10
+
+ "test1@demo.com", "test1", "demo", "1234"
+ "test2@demo.com", "test2", "demo", "1234"
+ "test3@demo.com", "test3", "demo", "1234"
+
+
+Text file for deleting multiple users:
+
+.. csv-table::
+ :header: "useremail"
+ :widths: 20
+
+ "test1@demo.com"
+ "test2@demo.com"
+ "test3@demo.com"
+
+
+Text file for adding / removing multiple users from a group:
+
+.. csv-table::
+ :header: "useremail", "group"
+ :widths: 20, 20
+
+ "test1@demo.com", "annotation_group1"
+ "test2@demo.com", "annotation_group1"
+ "test3@demo.com", "annotation_group1"
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 jbrowsehubToApollo.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jbrowsehubToApollo.py Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+import os
+import sys
+import argparse
+import json
+import logging
+import socket
+from apollo.ApolloInstance import ApolloInstance
+from util.Reader import Reader
+from util.Logger import Logger
+
+
+def main(argv):
+ parser = argparse.ArgumentParser(description='Upload a hub to display on Apollo.')
+ parser.add_argument('-j', '--data_json', help='JSON file containing the metadata of the inputs')
+ parser.add_argument('-o', '--output', help='HTML output')
+
+ # Get the args passed in parameter
+ args = parser.parse_args()
+ json_inputs_data = args.data_json
+ outputFile = args.output
+
+ ##Parse JSON file with Reader
+ reader = Reader(json_inputs_data)
+
+ # Begin init variables
+ extra_files_path = reader.getExtFilesPath()
+ #user_email = reader.getUserEmail()
+ species_name = reader.getSpeciesName()
+ #apollo_host = reader.getApolloHost()
+ apollo_port = reader.getPortNum()
+ apollo_host = "http://localhost:"+ apollo_port + "/apollo"
+ #apollo_host = "http://localhost:8080/apollo"
+ #apollo_user = reader.getApolloUser()
+ apollo_admin_user = reader.getAdminUser()
+ toolDirectory = reader.getToolDir()
+ #jbrowse_hub = reader.getJBrowseHubDir()
+ debug_mode = reader.getDebugMode()
+ action = reader.getAction()
+
+ #### Logging management ####
+ # If we are in Debug mode, also print in stdout the debug dump
+ log = Logger(tool_directory=toolDirectory, debug=debug_mode)
+ log.setup_logging()
+
+<<<<<<< HEAD
+ logging.info("#### JBrowsehub To Apollo: Start to %s JBrowse Hub to Apollo instance: %s #### ", action, apollo_host)
+=======
+ logging.info("#### JBrowseArchiveCreator: Start to %s JBrowse Hub to Apollo instance: %s #### ", action, apollo_host)
+>>>>>>> 8b9a3b41d4dd4689764592d278ec2d67f67fbca4
+ logging.debug('JSON parameters: %s\n\n', json.dumps(reader.args))
+
+ # Set up apollo
+ apollo = ApolloInstance(apollo_host, apollo_admin_user, toolDirectory)
+ jbrowse_hub_dir = _getHubDir(extra_files_path)
+<<<<<<< HEAD
+ apollo.manageApolloOrganism(species_name, jbrowse_hub_dir, action)
+=======
+ apollo.loadHubToApollo(species_name, jbrowse_hub_dir, action)
+>>>>>>> 8b9a3b41d4dd4689764592d278ec2d67f67fbca4
+ outHtml(outputFile, apollo_host, species_name)
+
+ logging.info('#### JBrowsehub To Apollo: Congratulation! JBrowse Hub is uploaded! ####\n')
+
+def _getHubDir(extra_files_path):
+ for root, dirs, files in os.walk(extra_files_path):
+ for name in files:
+ if name == "trackList.json":
+ logging.debug("JBrowse hub directory: %s", root)
+ return root
+ logging.error("Cannot find jbrowsehub")
+ exit(-1)
+
+def outHtml(outputFile, host_name, species_name):
+ with open(outputFile, 'w') as htmlfile:
+ htmlstr = 'The new Organism "%s" is created on Apollo:
' % species_name
+ jbrowse_hub = '
View JBrowse Hub on Apollo' % host_name
+ htmlstr += jbrowse_hub
+ htmlfile.write(htmlstr)
+
+if __name__ == "__main__":
+ main(sys.argv)
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 jbrowsehubToApollo.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jbrowsehubToApollo.xml Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,108 @@
+
+
+ This Galaxy tool is used to prepare your files to be ready for displaying on Apollo
+
+
+
+ apollo_api
+
+
+
+
+
+
+
+
+import json
+import sys
+
+file_path = sys.argv[1]
+#set global data_parameter_dict = {}
+#silent $data_parameter_dict.update({"action": str($action)})
+#silent $data_parameter_dict.update({"species_name": str($species_name)})
+#set apollo_admin = {"user_email": str($admin_username), "password": str($admin_password)}
+#silent $data_parameter_dict.update({"apollo_admin": $apollo_admin})
+#silent $data_parameter_dict.update({"tool_directory": str($__tool_directory__)})
+#silent $data_parameter_dict.update({"extra_files_path": str($jbrowse_hub.extra_files_path)})
+#silent $data_parameter_dict.update({"port": str($advanced_options.port)})
+#silent $data_parameter_dict.update({"debug_mode": str($advanced_options.debug_mode)})
+with open(file_path, 'w') as f:
+ json.dump($data_parameter_dict, f)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use this option if you are a G-OnRamp developer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This Galaxy tool is used to create or overwrite an organism on an Apollo server with a jbrowse hub created by JBrowse Archive Creator.
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 logging.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/logging.json Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,38 @@
+{
+ "version": 1,
+ "disable_existing_loggers": false,
+ "formatters": {
+ "simple": {
+ "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
+ }
+ },
+
+ "handlers": {
+ "console": {
+ "class": "logging.StreamHandler",
+ "level": "INFO",
+ "formatter": "simple",
+ "stream": "ext://sys.stdout"
+ },
+
+ "console_stderr": {
+ "class": "logging.StreamHandler",
+ "level": "ERROR",
+ "formatter": "simple",
+ "stream": "ext://sys.stderr"
+ }
+ },
+
+ "loggers": {
+ "Reader": {
+ "level": "INFO",
+ "handlers": ["console"],
+ "propagate": "yes"
+ }
+ },
+
+ "root": {
+ "level": "DEBUG",
+ "handlers": ["console", "console_stderr"]
+ }
+}
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 macros.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/macros.xml Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 templates/__init__.py
diff -r 000000000000 -r 9945eba268e6 templates/apollo-arrow.yml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/apollo-arrow.yml Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,10 @@
+## Apollo's Arrow: Global Configuration File.
+# Each stanza should contian a single galaxy server to control.
+#
+# You can set the key __default to the name of a default instance
+__default: local
+
+local:
+ url: ${apollo_host}
+ username: ${admin_user}
+ password: ${admin_pw}
diff -r 000000000000 -r 9945eba268e6 test-data/usersInfo.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/usersInfo.txt Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,4 @@
+useremail firstname lastname password
+test1@apollo.com test1 apollo 1234
+test2@apollo.com test2 apollo 1234
+test3@apollo.com test3 apollo 4321
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 test-data/usersInfo2.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/usersInfo2.csv Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,4 @@
+useremail,firstname,lastname,password
+test1@apollo.com,test1,apollo,1234
+test2@apollo.com,test2,apollo,1234
+test3@apollo.com,test3,apollo,4321
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 todo.md
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/todo.md Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,9 @@
+# JBrowseHubToApollo's TODO
+
+- [ ] Correct new Apollo user's email address. Galaxy santitizes '@' to '__at__'
+- [ ] Check password for admin login
+
+### DONE
+
+
+- [x] upload jbrowsehub to Apollo instance
diff -r 000000000000 -r 9945eba268e6 tool_dependencies.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool_dependencies.xml Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ https://github.com/galaxy-genome-annotation/python-apollo/archive/3.0.3.tar.gz
+ $INSTALL_DIR/apollo
+
+ export PYTHONPATH=$PYTHONPATH:$INSTALL_DIR/apollo &&
+ python setup.py install --install-lib $INSTALL_DIR/apollo
+
+
+ $INSTALL_DIR/apollo
+ $INSTALL_DIR/apollo
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 9945eba268e6 util/Logger.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/Logger.py Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,39 @@
+import os
+import sys
+import json
+import logging
+import logging.config
+
+#from util.Filters import TraceBackFormatter
+
+class Logger(object):
+ def __init__(self, tool_directory, debug="False", extra_files_path=None):
+ self.tool_directory = tool_directory
+ self.default_level = logging.INFO
+ self.debug = debug
+ self.extra_files_path = extra_files_path
+
+ def setup_logging(self):
+ """
+ Setup logging configuration
+ reference: https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/
+ """
+ config_path = os.path.join(self.tool_directory, 'logging.json')
+ default_level=logging.INFO
+ if self.debug.lower() == "true":
+ default_level=logging.DEBUG
+ if os.path.exists(config_path):
+ with open(config_path, 'rt') as f:
+ config = json.load(f)
+ config["handlers"]["console"]["level"] = default_level
+ if self.extra_files_path:
+ for i in config["handlers"]:
+ if "filename" in config["handlers"][i]:
+ config["handlers"][i]["filename"] = os.path.join(self.extra_files_path, config["handlers"][i]["filename"])
+ logging.config.dictConfig(config)
+ else:
+ logging.warn("Extra files path is not set. The log files will exist at current working directory instead of final output folder")
+ else:
+ logging.basicConfig(level=default_level)
+ logging.warn("Cannot find logging configuration file!\n")
+
diff -r 000000000000 -r 9945eba268e6 util/Logger.pyc
Binary file util/Logger.pyc has changed
diff -r 000000000000 -r 9945eba268e6 util/Reader.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/Reader.py Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,92 @@
+import json
+import re
+import logging
+import codecs
+import socket
+from apollo.ApolloUser import ApolloUser
+from util import santitizer
+
+class Reader(object):
+
+ def __init__(self, input_json_file):
+ self.inputFile = input_json_file
+ self.args = self.loadJson()
+
+
+ def loadJson(self):
+ try:
+ data_file = codecs.open(self.inputFile, 'r', 'utf-8')
+ return json.load(data_file)
+ except IOError:
+ print "Cannot find JSON file\n"
+ exit(1)
+
+ def getJBrowseHubDir(self):
+ try:
+ return self.args["jbrowse_hub"]
+ except KeyError:
+ print ("jbrowse_hub is not defined in the input file!")
+ exit(1)
+
+ def getToolDir(self):
+ try:
+ return self.args["tool_directory"]
+ except KeyError:
+ print ("tool_directory is not defined in the input file!")
+ exit(1)
+
+ def getExtFilesPath(self):
+ try:
+ return self.args["extra_files_path"]
+ except KeyError:
+ print ("extra_files_path is not defined in the input file!")
+ exit(1)
+
+ def getUserEmail(self):
+ try:
+ return self.args["user_email"]
+ except KeyError:
+ print ("user_email is not defined in the input file!")
+ exit(1)
+
+ def getDebugMode(self):
+ try:
+ return self.args["debug_mode"]
+ except KeyError:
+ print ("debug_mode is not defined in the input file!")
+ exit(1)
+
+ def getPortNum(self):
+ try:
+ return self.args["port"]
+ except KeyError:
+ print ("port is not defined in the input file!")
+ exit(1)
+
+ def getApolloHost(self):
+ #apollo_host = self.args.get("apollo_host")
+ hostname = socket.gethostname()
+ ip = socket.gethostbyname(hostname)
+ protocol = socket.getprotobyname(hostname)
+ apollo_host = str(protocol) + str(ip)
+ return apollo_host
+
+
+ def getSpeciesName(self):
+ species_name = santitizer.sanitize_name_input(self.args["species_name"])
+ return species_name
+
+ def getAction(self):
+ action = self.args.get("action")
+ return action
+
+ def getAdminUser(self):
+ apollo_admin = self.args.get("apollo_admin")
+ return apollo_admin
+
+
+ def getOperationList(self):
+ l = self.args.get("operations")
+ return l
+
+
\ No newline at end of file
diff -r 000000000000 -r 9945eba268e6 util/Reader.pyc
Binary file util/Reader.pyc has changed
diff -r 000000000000 -r 9945eba268e6 util/__init__.py
diff -r 000000000000 -r 9945eba268e6 util/__init__.pyc
Binary file util/__init__.pyc has changed
diff -r 000000000000 -r 9945eba268e6 util/santitizer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/santitizer.py Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+"""
+This class handles the subprocess calls of the different tools used
+in HubArchiveCreator
+"""
+
+import logging
+import os
+import subprocess
+import sys
+import string
+import tempfile
+
+
+def prefixTrackName(filename):
+ """
+ santitize trackName. Because track name must begin with a letter and
+ contain only the following chars: [a-zA-Z0-9_].
+ See the "track" Common settings at:
+ https://genome.ucsc.edu/goldenpath/help/trackDb/trackDbHub.html#bigPsl_-_Pairwise_Alignments
+ skip the santitization for cytoBandIdeo track
+ """
+ if filename == 'cytoBandIdeo':
+ return filename
+ valid_chars = "_%s%s" % (string.ascii_letters, string.digits)
+ sanitize_name = ''.join([c if c in valid_chars else '_' for c in filename])
+ sanitize_name = "gonramp_" + sanitize_name
+ return sanitize_name
+
+def sanitize_name_input(string_to_sanitize):
+ """
+ Sanitize the string passed in parameter by replacing '/' and ' ' by '_'
+
+ :param string_to_sanitize:
+ :return :
+
+ :Example:
+
+ >>> sanitize_name_input('this/is an//example')
+ this_is_an__example
+ """
+ return string_to_sanitize \
+ .replace("/", "_") \
+ .replace(" ", "_")
+
+def sanitize_name_inputs(inputs_data):
+ """
+ Sanitize value of the keys "name" of the dictionary passed in parameter.
+
+ Because sometimes output from Galaxy, or even just file name, from user inputs, have spaces.
+ Also, it can contain '/' character and could break the use of os.path function.
+
+ :param inputs_data: dict[string, dict[string, string]]
+ """
+ for key in inputs_data:
+ inputs_data[key]["name"] = sanitize_name_input(inputs_data[key]["name"])
+
+def sanitize_group_name(group_name):
+ return group_name.lower().replace(' ', '_')
+
+def sanitize_name(input_name):
+ """
+ Galaxy will name all the files and dirs as *.dat,
+ the function can replace '.' to '_' for the dirs
+ """
+ validChars = "_-%s%s" % (string.ascii_letters, string.digits)
+ sanitized_name = ''.join([c if c in validChars else '_' for c in input_name])
+ return "gonramp_" + sanitized_name
diff -r 000000000000 -r 9945eba268e6 util/santitizer.pyc
Binary file util/santitizer.pyc has changed
diff -r 000000000000 -r 9945eba268e6 util/subtools.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/subtools.py Mon Nov 27 12:49:27 2017 -0500
@@ -0,0 +1,216 @@
+#!/usr/bin/env python
+
+"""
+This file include common used functions for converting file format to gff3
+"""
+from collections import OrderedDict
+import json
+import subprocess
+import os
+import sys
+import tempfile
+import string
+import logging
+
+class PopenError(Exception):
+ def __init__(self, cmd, error, return_code):
+ self.cmd = cmd
+ self.error = error
+ self.return_code = return_code
+
+ def __str__(self):
+ message = "The subprocess {0} has returned the error: {1}.".format(
+ self.cmd, self.return_code)
+ message = ','.join(
+ (message, "Its error message is: {0}".format(self.error)))
+ return repr(message)
+
+
+def _handleExceptionAndCheckCall(array_call, **kwargs):
+ """
+ This class handle exceptions and call the tool.
+ It maps the signature of subprocess.check_call:
+ See https://docs.python.org/2/library/subprocess.html#subprocess.check_call
+ """
+ stdout = kwargs.get('stdout', subprocess.PIPE)
+ stderr = kwargs.get('stderr', subprocess.PIPE)
+ shell = kwargs.get('shell', False)
+ stdin = kwargs.get('stdin', None)
+
+ cmd = array_call[0]
+
+ output = None
+ error = None
+
+ # TODO: Check the value of array_call and <=[0]
+ logging.debug("Calling {0}:".format(cmd))
+ logging.debug("%s", array_call)
+ logging.debug("---------")
+
+ # TODO: Use universal_newlines option from Popen?
+ try:
+ p = subprocess.Popen(array_call, stdout=stdout,
+ stderr=stderr, shell=shell, stdin=stdin)
+
+ # TODO: Change this because of possible memory issues => https://docs.python.org/2/library/subprocess.html#subprocess.Popen.communicate
+
+ output, error = p.communicate()
+
+ if stdout == subprocess.PIPE:
+ logging.debug("\t{0}".format(output))
+ else:
+ logging.debug("\tOutput in file {0}".format(stdout.name))
+ # If we detect an error from the subprocess, then we raise an exception
+ # TODO: Manage if we raise an exception for everything, or use CRITICAL etc... but not stop process
+ # TODO: The responsability of returning a sys.exit() should not be there, but up in the app.
+ if p.returncode:
+ if stderr == subprocess.PIPE:
+ raise PopenError(cmd, error, p.returncode)
+ else:
+ # TODO: To Handle properly with a design behind, if we received a option as a file for the error
+ raise Exception("Error when calling {0}. Error as been logged in your file {1}. Error code: {2}".format(cmd, stderr.name, p.returncode))
+
+ except OSError as e:
+ message = "The subprocess {0} has encountered an OSError: {1}".format(
+ cmd, e.strerror)
+ if e.filename:
+ message = '\n'.join(
+ (message, ", against this file: {0}".format(e.filename)))
+ logging.error(message)
+ sys.exit(-1)
+ except PopenError as p:
+ message = "The subprocess {0} has returned the error: {1}.".format(
+ p.cmd, p.return_code)
+ message = '\n'.join(
+ (message, "Its error message is: {0}".format(p.error)))
+
+ logging.exception(message)
+
+ sys.exit(p.return_code)
+ except Exception as e:
+ message = "The subprocess {0} has encountered an unknown error: {1}".format(
+ cmd, e)
+ logging.exception(message)
+
+ sys.exit(-1)
+ return output
+
+def arrow_add_organism(organism_name, organism_dir, public=False):
+ array_call = ['arrow', 'organisms', 'add_organism', organism_name, organism_dir]
+ if public:
+ array_call.append('--public')
+ p = _handleExceptionAndCheckCall(array_call)
+ #p = subprocess.check_output(array_call)
+ return p
+
+def arrow_create_user(user_email, firstname, lastname, password, admin=False):
+ """
+ Create a new user of Apollo, the default user_role is "user"
+ """
+ array_call = ['arrow', 'users', 'create_user', user_email, firstname, lastname, password]
+ if admin:
+ array_call += ['--role', 'admin']
+ p = _handleExceptionAndCheckCall(array_call)
+ j = json.loads(p)
+ if "userId" in j:
+ return j['userId']
+ elif "error" in j:
+ logging.error("User %s already exist", user_email)
+ raise Exception(j['error'])
+
+
+def arrow_delete_user(user_email):
+ array_call = ['arrow', 'users', 'delete_user', user_email]
+ p = _handleExceptionAndCheckCall(array_call)
+ j = json.loads(p)
+ if "error" in j:
+ raise Exception(j['error'])
+
+def arrow_add_to_group(groupname, user_email):
+ if not arrow_get_groups(groupname):
+ arrow_create_group(groupname)
+ array_call = ['arrow', 'users', 'add_to_group', groupname, user_email]
+ p = _handleExceptionAndCheckCall(array_call)
+ j = json.loads(p)
+ if j != dict():
+ raise Exception("Error add user %s to group %s", user_email, groupname)
+
+
+def arrow_remove_from_group(groupname, user_email):
+ if arrow_get_groups(groupname):
+ array_call = ['arrow', 'users', 'remove_from_group', groupname, user_email]
+ p = _handleExceptionAndCheckCall(array_call)
+ else:
+ raise Exception("Group %s doesn't exist. Check if you spell the name correctly", groupname)
+
+def arrow_create_group(groupname):
+ if arrow_get_groups(groupname):
+ raise Exception("Group %s already exist. Create a group with another name.", groupname)
+ array_call = ['arrow', 'groups', 'create_group', groupname]
+ p = _handleExceptionAndCheckCall(array_call)
+
+def arrow_get_groups(groupname):
+ array_call = ['arrow', 'groups', 'get_groups']
+ p = _handleExceptionAndCheckCall(array_call)
+ all_groups = json.loads(p)
+ for g in all_groups:
+ if g['name'] == groupname:
+ return True
+ return False
+
+def arrow_update_organism_permissions(user_id, organism, **user_permissions):
+ array_call = ['arrow', 'users', 'update_organism_permissions', str(user_id), str(organism)]
+ admin = user_permissions.get("admin", False)
+ write = user_permissions.get("write", False)
+ read = user_permissions.get("read", False)
+ export = user_permissions.get("export", False)
+ if admin:
+ array_call.append('--administrate')
+ if write:
+ array_call.append('--write')
+ if read:
+ array_call.append('--read')
+ if export:
+ array_call.append('--export')
+ p = _handleExceptionAndCheckCall(array_call)
+ return p
+
+def arrow_get_users(user_email):
+ array_call = ['arrow', 'users', 'get_users']
+ p = _handleExceptionAndCheckCall(array_call)
+ all_users = json.loads(p)
+ for d in all_users:
+ if d['username'] == user_email:
+ return d['userId']
+ logging.error("Cannot find user %s", user_email)
+
+def arrow_get_organism(organism_name):
+ array_call= ['arrow', 'organisms', 'get_organisms']
+ p = _handleExceptionAndCheckCall(array_call)
+ all_organisms = json.loads(p)
+ for org in all_organisms:
+ if org['commonName'] == organism_name:
+ return org['id']
+
+
+def arrow_delete_organism(organism_id):
+ array_call = ['arrow', 'organisms', 'delete_organism', organism_id]
+ p = _handleExceptionAndCheckCall(array_call)
+ return p
+
+def verify_user_login(username, password, apollo_host):
+ user_info = {'username': username, 'password': password}
+ array_call = ['curl',
+ '-b', 'cookies.txt',
+ '-c', 'cookies.txt',
+ '-H', 'Content-Type:application/json',
+ '-d', json.dumps(user_info),
+ apollo_host + '/Login?operation=login'
+ ]
+ p = _handleExceptionAndCheckCall(array_call)
+ msg = json.loads(p)
+ if 'error' in msg:
+ logging.error("The Authentication for user %s failed. Get error message %s", username, msg['error'])
+ exit(-1)
+
+
diff -r 000000000000 -r 9945eba268e6 util/subtools.pyc
Binary file util/subtools.pyc has changed