/lib/galaxy/webapps/demo_sequencer/framework/__init__.py

https://bitbucket.org/cistrome/cistrome-harvard/ · Python · 207 lines · 174 code · 10 blank · 23 comment · 6 complexity · a388f1cc3e5be7feb84b42bcc10da854 MD5 · raw file

  1. """
  2. Demo sequencer web application framework
  3. """
  4. import json
  5. import os
  6. import pkg_resources
  7. import random
  8. import socket
  9. import string
  10. import sys
  11. import time
  12. pkg_resources.require( "Cheetah" )
  13. from Cheetah.Template import Template
  14. from galaxy.web.framework import helpers
  15. from galaxy import util
  16. from galaxy.util.json import to_json_string, from_json_string
  17. from galaxy.web.framework import url_for, expose, json, json_pretty, require_login, expose_api, error, form
  18. from galaxy.web.framework import NOT_SET
  19. from galaxy.web.framework import MessageException, FormBuilder, FormInput, FormData, Bunch
  20. import galaxy.web.framework.base
  21. from galaxy.util import asbool
  22. pkg_resources.require( "Mako" )
  23. import mako.template
  24. import mako.lookup
  25. import mako.runtime
  26. pkg_resources.require( "pexpect" )
  27. pkg_resources.require( "amqp" )
  28. import logging
  29. log = logging.getLogger( __name__ )
  30. class WebApplication( galaxy.web.framework.base.WebApplication ):
  31. def __init__( self, demo_app, session_cookie='demosequencersession' ):
  32. galaxy.web.framework.base.WebApplication.__init__( self )
  33. self.set_transaction_factory( lambda e: self.transaction_chooser( e, demo_app, session_cookie ) )
  34. # Mako support
  35. self.mako_template_lookup = mako.lookup.TemplateLookup(
  36. directories = [ demo_app.config.template_path ] ,
  37. module_directory = demo_app.config.template_cache,
  38. collection_size = 500,
  39. output_encoding = 'utf-8' )
  40. # Security helper
  41. self.security = demo_app.security
  42. def handle_controller_exception( self, e, trans, **kwargs ):
  43. if isinstance( e, MessageException ):
  44. return trans.show_message( e.err_msg, e.type )
  45. def make_body_iterable( self, trans, body ):
  46. if isinstance( body, FormBuilder ):
  47. body = trans.show_form( body )
  48. return galaxy.web.framework.base.WebApplication.make_body_iterable( self, trans, body )
  49. def transaction_chooser( self, environ, demo_app, session_cookie ):
  50. if 'is_api_request' in environ:
  51. return DemoWebAPITransaction( environ, demo_app, self )
  52. else:
  53. return DemoWebUITransaction( environ, demo_app, self, session_cookie )
  54. class DemoWebTransaction( galaxy.web.framework.base.DefaultWebTransaction ):
  55. """
  56. Encapsulates web transaction specific state for the Demo application
  57. (specifically the user's "cookie")
  58. """
  59. def __init__( self, environ, app, webapp ):
  60. self.app = app
  61. self.webapp = webapp
  62. self.security = webapp.security
  63. galaxy.web.framework.base.DefaultWebTransaction.__init__( self, environ )
  64. self.debug = asbool( self.app.config.get( 'debug', False ) )
  65. def get_cookie( self, name='demosequencersession' ):
  66. """Convenience method for getting a session cookie"""
  67. try:
  68. # If we've changed the cookie during the request return the new value
  69. if name in self.response.cookies:
  70. return self.response.cookies[name].value
  71. else:
  72. return self.request.cookies[name].value
  73. except:
  74. return None
  75. def set_cookie( self, value, name='demosequencersession', path='/', age=90, version='1' ):
  76. """Convenience method for setting a session cookie"""
  77. # The demosequencersession cookie value must be a high entropy 128 bit random number encrypted
  78. # using a server secret key. Any other value is invalid and could pose security issues.
  79. self.response.cookies[name] = value
  80. self.response.cookies[name]['path'] = path
  81. self.response.cookies[name]['max-age'] = 3600 * 24 * age # 90 days
  82. tstamp = time.localtime ( time.time() + 3600 * 24 * age )
  83. self.response.cookies[name]['expires'] = time.strftime( '%a, %d-%b-%Y %H:%M:%S GMT', tstamp )
  84. self.response.cookies[name]['version'] = version
  85. def __update_session_cookie( self, name='galaxysession' ):
  86. """
  87. Update the session cookie to match the current session.
  88. """
  89. self.set_cookie( self.security.encode_guid( self.galaxy_session.session_key ), name=name, path=self.app.config.cookie_path )
  90. def get_galaxy_session( self ):
  91. """
  92. Return the current galaxy session
  93. """
  94. return self.galaxy_session
  95. @galaxy.web.framework.base.lazy_property
  96. def template_context( self ):
  97. return dict()
  98. def make_form_data( self, name, **kwargs ):
  99. rval = self.template_context[name] = FormData()
  100. rval.values.update( kwargs )
  101. return rval
  102. def set_message( self, message, type=None ):
  103. """
  104. Convenience method for setting the 'message' and 'message_type'
  105. element of the template context.
  106. """
  107. self.template_context['message'] = message
  108. if type:
  109. self.template_context['status'] = type
  110. def get_message( self ):
  111. """
  112. Convenience method for getting the 'message' element of the template
  113. context.
  114. """
  115. return self.template_context['message']
  116. def show_message( self, message, type='info', refresh_frames=[], cont=None, use_panels=False, active_view="" ):
  117. """
  118. Convenience method for displaying a simple page with a single message.
  119. `type`: one of "error", "warning", "info", or "done"; determines the
  120. type of dialog box and icon displayed with the message
  121. `refresh_frames`: names of frames in the interface that should be
  122. refreshed when the message is displayed
  123. """
  124. return self.fill_template( "message.mako", status=type, message=message, refresh_frames=refresh_frames, cont=cont, use_panels=use_panels, active_view=active_view )
  125. def show_error_message( self, message, refresh_frames=[], use_panels=False, active_view="" ):
  126. """
  127. Convenience method for displaying an error message. See `show_message`.
  128. """
  129. return self.show_message( message, 'error', refresh_frames, use_panels=use_panels, active_view=active_view )
  130. def show_ok_message( self, message, refresh_frames=[], use_panels=False, active_view="" ):
  131. """
  132. Convenience method for displaying an ok message. See `show_message`.
  133. """
  134. return self.show_message( message, 'done', refresh_frames, use_panels=use_panels, active_view=active_view )
  135. def show_warn_message( self, message, refresh_frames=[], use_panels=False, active_view="" ):
  136. """
  137. Convenience method for displaying an warn message. See `show_message`.
  138. """
  139. return self.show_message( message, 'warning', refresh_frames, use_panels=use_panels, active_view=active_view )
  140. def show_form( self, form, header=None, template="form.mako", use_panels=False, active_view="" ):
  141. """
  142. Convenience method for displaying a simple page with a single HTML
  143. form.
  144. """
  145. return self.fill_template( template, form=form, header=header, use_panels=( form.use_panels or use_panels ),
  146. active_view=active_view )
  147. def fill_template(self, filename, **kwargs):
  148. """
  149. Fill in a template, putting any keyword arguments on the context.
  150. """
  151. if filename.endswith( ".mako" ):
  152. return self.fill_template_mako( filename, **kwargs )
  153. else:
  154. template = Template( file=os.path.join(self.app.config.template_path, filename),
  155. searchList=[kwargs, self.template_context, dict(caller=self, t=self, h=helpers, util=util, request=self.request, response=self.response, app=self.app)] )
  156. return str( template )
  157. def fill_template_mako( self, filename, **kwargs ):
  158. template = self.webapp.mako_template_lookup.get_template( filename )
  159. template.output_encoding = 'utf-8'
  160. data = dict( caller=self, t=self, trans=self, h=helpers, util=util, request=self.request, response=self.response, app=self.app )
  161. data.update( self.template_context )
  162. data.update( kwargs )
  163. return template.render( **data )
  164. def stream_template_mako( self, filename, **kwargs ):
  165. template = self.webapp.mako_template_lookup.get_template( filename )
  166. template.output_encoding = 'utf-8'
  167. data = dict( caller=self, t=self, trans=self, h=helpers, util=util, request=self.request, response=self.response, app=self.app )
  168. data.update( self.template_context )
  169. data.update( kwargs )
  170. ## return template.render( **data )
  171. def render( environ, start_response ):
  172. response_write = start_response( self.response.wsgi_status(), self.response.wsgi_headeritems() )
  173. class StreamBuffer( object ):
  174. def write( self, d ):
  175. response_write( d.encode( 'utf-8' ) )
  176. buffer = StreamBuffer()
  177. context = mako.runtime.Context( buffer, **data )
  178. template.render_context( context )
  179. return []
  180. return render
  181. def fill_template_string(self, template_string, context=None, **kwargs):
  182. """
  183. Fill in a template, putting any keyword arguments on the context.
  184. """
  185. template = Template( source=template_string,
  186. searchList=[context or kwargs, dict(caller=self)] )
  187. return str(template)
  188. class DemoWebAPITransaction( DemoWebTransaction ):
  189. def __init__( self, environ, app, webapp ):
  190. DemoWebTransaction.__init__( self, environ, app, webapp )
  191. class DemoWebUITransaction( DemoWebTransaction ):
  192. def __init__( self, environ, app, webapp, session_cookie ):
  193. DemoWebTransaction.__init__( self, environ, app, webapp )