PageRenderTime 64ms CodeModel.GetById 11ms app.highlight 48ms RepoModel.GetById 2ms app.codeStats 0ms

/lib/galaxy/webapps/demo_sequencer/controllers/common.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 227 lines | 192 code | 2 blank | 33 comment | 40 complexity | d87a546a2b37d1088848e68bc5ce5c0a MD5 | raw file
  1from galaxy.web.base.controller import *
  2from galaxy.web.framework.helpers import time_ago
  3from galaxy import util
  4import time, socket, urllib, urllib2, base64, copy
  5from galaxy.util.json import *
  6from urllib import quote_plus, unquote_plus
  7
  8import logging
  9log = logging.getLogger( __name__ )
 10
 11class CommonController( BaseUIController ):
 12    @web.expose
 13    def index( self, trans, **kwd ):
 14        redirect_action = util.restore_text( kwd.get( 'redirect_action', '' ) )
 15        titles = util.restore_text( kwd.get( 'titles', '' ) )
 16        titles = util.listify( titles )
 17        JobId = util.restore_text( kwd.get( 'JobId', '' ) )
 18        sample_id = util.restore_text( kwd.get( 'sample_id', '' ) )
 19        message = util.restore_text( kwd.get( 'message', '' ) )
 20        status = kwd.get( 'status', 'done' )
 21        redirect_delay = trans.app.sequencer_actions_registry.redirect_delay
 22        sequencer_redirects = copy.deepcopy( trans.app.sequencer_actions_registry.sequencer_redirects )
 23        sequencer_requests = copy.deepcopy( trans.app.sequencer_actions_registry.sequencer_requests )
 24        requests = []
 25        if redirect_action == 'stop':
 26            # Handle any additional requests
 27            for request_tup in sequencer_requests:
 28                url, http_method, request_params, response_type = self.parse_request_tup( request_tup, **kwd )
 29                response = self.handle_request( trans, url, http_method, **request_params )
 30                # Handle response, currently only handles json
 31                if response_type == 'json':
 32                    response = from_json_string( response )
 33                    # Handle response that is an error, for example:
 34                    # { "Success":false, "Message":"some error string" }
 35                    if 'Success' in response and response[ 'Success' ] == 'false':
 36                        message = response[ 'Message' ]
 37                        return self.handle_failure( trans, url, message )
 38                    if 'JobId' in response:
 39                        JobId = str( response[ 'JobId' ] )
 40                        kwd[ 'JobId' ] = JobId
 41            # Handle the final redirect, if any ( should only be 0 or 1 ).
 42            for request_tup in trans.app.sequencer_actions_registry.final_redirect:
 43                url, http_method, request_params, response_type = self.parse_request_tup( request_tup, **kwd )
 44                return trans.fill_template( 'webapps/demo_sequencer/redirect.mako', redirect_url=url )
 45            # Exit if we have no redirection
 46            redirect_action = 'exit'
 47        elif not redirect_action:
 48            # Specially handle the initial request to the demo sequencer by starting with the first defined redirect.
 49            redirect_action, action_dict = sequencer_redirects.items()[0]
 50            titles = [ action_dict[ 'title' ] ]
 51            if 'requests' in action_dict:
 52                requests = action_dict[ 'requests' ]
 53        else:
 54            for index, key in enumerate( sequencer_redirects.iterkeys() ):
 55                if redirect_action == key:
 56                    try:
 57                        # Move to the next action, if there is one.
 58                        redirect_action = sequencer_redirects.keys()[ index + 1 ]
 59                        action_dict = sequencer_redirects[ redirect_action ]
 60                        titles.append( action_dict[ 'title' ] )
 61                    except:
 62                        # If we're done redirecting, stop.
 63                        redirect_action = 'stop'
 64                    break
 65        if not trans.app.sequencer_actions_registry.authenticated:
 66            # Support various types of authentication
 67            if trans.app.sequencer_actions_registry.browser_login:
 68                # We'll just build the URL here since authentication will be handled in the browser
 69                url = trans.app.sequencer_actions_registry.browser_login[ 'url' ]
 70                params = trans.app.sequencer_actions_registry.browser_login[ 'params' ]
 71                trans.app.sequencer_actions_registry.browser_login = '%s?%s' %( url, urllib.urlencode( params ) )
 72                if not trans.app.sequencer_actions_registry.final_redirect:
 73                    # If we don't have a final_redirect tag, but we want our browser to authenticate,
 74                    # do it ow.  If we have a final_redirect tag, browser authentication will happen there.
 75                    url = web.url_for( controller='common', action='index', **kwd )
 76                    return trans.fill_template( 'webapps/demo_sequencer/redirect.mako', redirect_url=url )
 77            if trans.app.sequencer_actions_registry.basic_http_authentication:
 78                # Example tag:
 79                # <basic_http_authentication user="administrator" password="galaxy" url="http://127.0.0.1" realm="" />
 80                user, password, url, realm = trans.app.sequencer_actions_registry.basic_http_authentication
 81                # Create a password manager
 82                password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
 83                # Add the username, password and realm.
 84                if not realm:
 85                    realm = None
 86                password_mgr.add_password( realm, url, user, password )
 87                handler = urllib2.HTTPBasicAuthHandler( password_mgr )
 88                # Create "opener" (OpenerDirector instance)
 89                opener = urllib2.build_opener( handler )
 90                # Install the opener, now all calls to urllib2.urlopen use our opener.
 91                urllib2.install_opener( opener )
 92                trans.app.sequencer_actions_registry.authenticated = True
 93            if trans.app.sequencer_actions_registry.http_headers_authorization:
 94                # Example tag:
 95                # <http_headers_authorization credentials="administrator:galaxy" url="http://127.0.0.1" />
 96                url, credentials = trans.app.sequencer_actions_registry.http_headers_authorization
 97                req = urllib2.Request( url )
 98                req.add_header( 'Authorization', 'Basic %s' % base64.b64encode( credentials ) )
 99                trans.app.sequencer_actions_registry.authenticated = True
100            if trans.app.sequencer_actions_registry.http_cookie_processor_authentication:
101                # Example tag:
102                # <http_cookie_processor_authentication url="http://127.0.0.1/login">
103                #    <param name="user" value="administrator"/>
104                #    <param name="password" value="galaxy"/>
105                # </http_cookie_processor_authentication>
106                url = trans.app.sequencer_actions_registry.http_cookie_processor_authentication[ 'url' ]
107                params = trans.app.sequencer_actions_registry.http_cookie_processor_authentication[ 'params' ]
108                # Build opener with HTTPCookieProcessor
109                opener = urllib2.build_opener( urllib2.HTTPCookieProcessor() )
110                urllib2.install_opener( opener )
111                # Perform login with params
112                page = opener.open( url, urllib.urlencode( params ) )
113                response = page.read()
114                page.close()
115                # Any additional requests should automatically pass back any
116                # cookies received during login, thanks to the HTTPCookieProcessor
117                trans.app.sequencer_actions_registry.authenticated = True
118        # Handle requests, if there are any
119        for request_tup in requests:
120            url, http_method, request_params, response_type = self.parse_request_tup( request_tup, **kwd )
121            response = self.handle_request( trans, url, http_method, **request_params )
122            # Handle response, currently only handles json
123            if response_type == 'json':
124                response = from_json_string( response )
125                # Handle response that is an error, for example:
126                # { "Success":false, "Message":"some error string" }
127                if 'Success' in response and response[ 'Success' ] == 'false':
128                    message = response[ 'Message' ]
129                    return self.handle_failure( trans, url, message )
130                if 'JobId' in response:
131                    JobId = str( response[ 'JobId' ] )
132                    kwd[ 'JobId' ] = JobId
133        titles = ','.join( titles )
134        return trans.fill_template( "webapps/demo_sequencer/index.mako",
135                                    redirect_action=redirect_action,
136                                    redirect_delay=redirect_delay,
137                                    titles=titles,
138                                    sample_id=sample_id,
139                                    JobId=JobId,
140                                    message=message,
141                                    status=status )
142    def parse_request_tup( self, request_tup, **kwd ):
143        redirect_action = util.restore_text( kwd.get( 'redirect_action', '' ) )
144        titles = util.restore_text( kwd.get( 'titles', '' ) )
145        JobId = util.restore_text( kwd.get( 'JobId', '' ) )
146        sample_id = util.restore_text( kwd.get( 'sample_id', '' ) )
147        message = util.restore_text( kwd.get( 'message', '' ) )
148        status = kwd.get( 'status', 'done' )
149        url, http_method, request_params, response_type = request_tup
150        url = unquote_plus( url )
151        # Handle URLs in which we replace param values, which will look something like:
152        # http://127.0.0.1/getinfo/{id}.
153        replace_with_param = url.find( '{' ) > 0
154        if replace_with_param:
155            # Handle the special-case {JobId} param.
156            if url.find( '{JobId}' ) > 0:
157                if JobId:
158                    url = url.replace( '{JobId}', str( JobId ) )
159            for key, value in kwd.items():
160                # Don't attempt to replace if there is nothing with which to do it
161                # or if the value itself should be replaced with something.
162                if value and not value.startswith( '{' ):
163                    replace_str = '{%s}' % key
164                    if url.find( replace_str ) > 0:
165                        url = url.replace( replace_str, value )
166        # Handle request parameters in which we replace param values.
167        for key, val in request_params.items():
168            if val and val.startswith( '{' ):
169                replace_key = val.lstrip( '{' ).rstrip( '}' )
170                if replace_key in kwd:
171                    request_params[ key ] = kwd[ replace_key ]
172        return url, http_method, request_params, response_type
173    def handle_request( self, trans, url, http_method=None, **kwd ):
174        if 'Name' in kwd and not kwd[ 'Name' ]:
175            # Hack: specially handle parameters named "Name" if no param_value is given
176            # by providing a date / time string - guarantees uniqueness, if required.
177            kwd[ 'Name' ] = time.strftime( "%a, %d %b %Y %H:%M:%S", time.gmtime() )
178        if 'Comments' in kwd and not kwd[ 'Comments' ]:
179            # Hack: specially handle parameters named "Comments" if no param_value is given
180            # by providing a date / time string.
181            kwd[ 'Comments' ] = time.strftime( "%a, %d %b %Y %H:%M:%S", time.gmtime() )
182        socket.setdefaulttimeout( 600 )
183        # The following calls to urllib2.urlopen() will use the above default timeout.
184        try:
185            if not http_method or http_method == 'get':
186                page = urllib2.urlopen( url )
187                response = page.read()
188                page.close()
189                return response
190            elif http_method == 'post':
191                page = urllib2.urlopen( url, urllib.urlencode( kwd ) )
192                response = page.read()
193                page.close()
194                return response
195            elif http_method == 'put':
196                url += '/' + str( kwd.pop( 'id' ) ) + '?key=' + kwd.pop( 'key' )
197                output = self.put( url, **kwd )
198        except Exception, e:
199            raise
200            message = 'Problem sending request to the web application: %s.  URL: %s.  kwd: %s.  Http method: %s' % \
201            ( str( e ), str( url ), str( kwd ), str( http_method )  )
202            return self.handle_failure( trans, url, message )
203    def handle_failure( self, trans, url, message ):
204        message = '%s, URL: %s' % ( message, url )
205        params = dict( message = message,
206                       status = 'error',
207                       redirect_action = 'exit',
208                       titles = 'Error' )
209        return trans.response.send_redirect( web.url_for( controller='common',
210                                                          action='index',
211                                                          **params ) )
212    def put( self, url, **kwd ):
213        opener = urllib2.build_opener( urllib2.HTTPHandler )
214        request = urllib2.Request( url, data=to_json_string( kwd ) )
215        request.add_header( 'Content-Type', 'application/json' )
216        request.get_method = lambda: 'PUT'
217        url = opener.open( request )
218        output = url.read()
219        return from_json_string( output )
220    @web.expose
221    def login( self, trans, **kwd ):
222        trans.app.sequencer_actions_registry.authenticated = True
223        return trans.fill_template( "webapps/demo_sequencer/login.mako" )
224    @web.expose
225    def empty_page( self, trans, **kwd ):
226        # Hack to not display responses in the browser - src for a hidden iframe.
227        return trans.fill_template( "webapps/demo_sequencer/empty.mako" )