These are the changes we've been discussing to incorporate

galaxy sessions (using cookies) for all histories, events
and jobs.
This commit is contained in:
Greg Von Kuster
2007-01-18 22:10:18 +00:00
parent 59f764fe84
commit f55ac74e09
11 changed files with 203 additions and 19 deletions
+1 -1
View File
@@ -80,7 +80,7 @@ class UCSCProxy(common.Root):
else:
try:
text = page.read()
# Serialize store into a form element
store_text = "<INPUT TYPE=\"HIDDEN\" NAME=\"__GALAXY__\" ID=\"__GALAXY__\" VALUE=\"" \
+ util.object_to_string(store) + "\" \>"
+17 -1
View File
@@ -27,6 +27,8 @@ class Universe(common.Root):
trans.set_cookie(name=self.pref_cookie_name, value=mode)
else:
mode = trans.get_cookie(name=self.pref_cookie_name)
if not trans.galaxy_session_is_valid():
trans.new_galaxy_session()
result = trans.fill_template('index_frames.tmpl', mode=mode)
return [ result ]
@@ -319,6 +321,13 @@ class Universe(common.Root):
new_history = self.copy_history(history)
new_history.name = history.name+" from "+user.email
new_history.user_id = send_to_user.id
"""
gvk TODO: how should we handle galaxy_session_to_history association here?
I'll do the following for now, but not sure if this is what we want...
"""
if not trans.galaxy_session_is_valid():
trans.new_galaxy_session()
new_history.add_galaxy_session(trans.get_galaxy_session())
trans.log_event( "History share: %s to %s" % (str(history.id),str(new_history.id)) )
self.app.model.flush()
return trans.show_message( "History (%s) has been shared with: %s" % (",".join(history_names),email) )
@@ -333,6 +342,8 @@ class Universe(common.Root):
@web.expose
def history_import( self, trans, id=None, confirm=False, **kwd ):
if not trans.galaxy_session_is_valid():
trans.new_galaxy_session()
msg = ""
user = trans.get_user()
user_history = trans.get_history()
@@ -347,6 +358,7 @@ class Universe(common.Root):
new_history = self.copy_history(import_history)
new_history.name = "imported: "+new_history.name
new_history.user_id = user.id
new_history.add_galaxy_session(trans.get_galaxy_session())
new_history.flush()
if not user_history.datasets:
trans.set_history( new_history )
@@ -356,6 +368,7 @@ class Universe(common.Root):
new_history = self.copy_history(import_history)
new_history.name = "imported: "+new_history.name
new_history.user_id = None
new_history.add_galaxy_session(trans.get_galaxy_session())
new_history.flush()
trans.set_history( new_history )
trans.log_event( "History import: %s" % str(new_history.id) )
@@ -367,8 +380,11 @@ class Universe(common.Root):
if not id:
return trans.fill_template( "history_switch.tmpl" )
else:
if not trans.galaxy_session_is_valid():
trans.new_galaxy_session()
new_history = trans.app.model.History.get( id )
if new_history:
new_history.add_galaxy_session(trans.get_galaxy_session())
trans.set_history( new_history )
trans.log_event( "History switch" )
return trans.show_message( "History switched to: %s" % new_history.name,
@@ -379,7 +395,7 @@ class Universe(common.Root):
@web.expose
def history_new( self, trans ):
trans.new_history()
trans.log_event( "History new" )
trans.log_event( "Created new History." )
return self.history( trans )
@web.expose
+3 -1
View File
@@ -37,6 +37,8 @@ class ToolRunner(common.Root):
return "Tool '%s' does not exist, kwd=%s " % (tool_id, kwd)
params = util.Params(kwd)
history = trans.get_history()
if not trans.galaxy_session_is_valid():
trans.new_galaxy_session()
template, vars = tool.handle_input( trans, params.__dict__ )
trans.log_event( "Tool View: %s; %s" % (str(tool),str(params)) )
trans.log_event( "Tool View: %s; %s" % (str(tool),str(params)), tool_id=tool_id )
return trans.fill_template( template, history=history, toolbox=toolbox, tool=tool, util=util, **vars )
+18 -4
View File
@@ -88,6 +88,13 @@ class User( common.Root ):
password_error = "Invalid password"
else:
trans.set_user( user )
if not trans.galaxy_session_is_valid():
trans.new_galaxy_session()
else:
"""
Associate user with galaxy_session and history
"""
trans.make_associations()
trans.log_event( "User logged in" )
return trans.show_ok_message( "Now logged in as " + user.email, \
refresh_frames=['masthead', 'history'] )
@@ -98,12 +105,12 @@ class User( common.Root ):
@web.expose
def logout( self, trans ):
# If the current history is saved for the current user it should be
# disconnected.
trans.log_event( "User logged out" )
# If the current history is saved for the current user it should be disconnected.
if trans.history.user == trans.user:
trans.set_history( None )
trans.log_event( "User logged out" )
trans.set_user( None )
trans.end_galaxy_session()
return trans.show_ok_message( "You are no longer logged in", \
refresh_frames=['masthead', 'history'] )
@@ -126,7 +133,14 @@ class User( common.Root ):
user.set_password_cleartext( password )
user.flush()
trans.set_user( user )
trans.log_event( "User new" )
if not trans.galaxy_session_is_valid():
trans.new_galaxy_session()
else:
"""
Associate user with galaxy_session and history
"""
trans.make_associations()
trans.log_event( "User created a new account" )
trans.log_event( "User logged in" )
#subscribe user to email list
if subscribe:
+4
View File
@@ -209,6 +209,10 @@ class JobWrapper( object ):
def get_command_line( self ):
job = model.Job.get( self.job_id )
return job.command_line
def get_session_id( self ):
job = model.Job.get( self.job_id )
return job.session_id
def get_input_fnames( self ):
job = model.Job.get( self.job_id )
+28 -2
View File
@@ -37,6 +37,7 @@ class Job( object ):
OK = 'ok',
ERROR = 'error' )
def __init__( self ):
self.session_id = None
self.tool_id = None
self.command_line = None
self.param_filename = None
@@ -79,6 +80,7 @@ class History( object ):
# Relationships
self.user = user
self.datasets = []
self.galaxy_sessions = []
def _next_hid( self ):
# TODO: override this with something in the database that ensures
@@ -91,6 +93,9 @@ class History( object ):
if dataset.hid > last_hid:
last_hid = dataset.hid
return last_hid + 1
def add_galaxy_session( self, galaxy_session ):
self.galaxy_sessions.append( GalaxySessionToHistoryAssociation( galaxy_session, self ) )
def add_dataset( self, dataset, parent_id=None ):
if parent_id:
@@ -98,6 +103,7 @@ class History( object ):
if data.id == parent_id:
dataset.hid = data.hid
break
# TODO gvk: ask if this needs to be fixed, I don't want to break it if it isn't broken...
else:
dataset.hid = self._next_hid()
else:
@@ -250,7 +256,27 @@ class Dataset( object ):
log.critical('%s delete error %s' % (self.__class__.__name__, e))
class Event( object ):
def __init__( self, message=None, history=None, user=None ):
self.message = message
def __init__( self, message=None, history=None, user=None, galaxy_session=None ):
self.history = history
self.galaxy_session = galaxy_session
self.user = user
self.tool_id = None
self.message = message
class GalaxySession( object ):
def __init__( self, id=None, user=None, remote_host=None, remote_addr=None ):
self.id = id
self.user = user
self.remote_host = remote_host
self.remote_addr = remote_addr
self.histories = []
def add_history( self, history ):
self.histories.append( GalaxySessionToHistoryAssociation( self, history ) )
class GalaxySessionToHistoryAssociation( object ):
def __init__( self, galaxy_session, history ):
self.galaxy_session = galaxy_session
self.history = history
+33 -4
View File
@@ -73,6 +73,7 @@ Job.table = Table( "job", metadata,
Column( "id", Integer, primary_key=True ),
Column( "create_time", DateTime, PassiveDefault( func.current_timestamp() ) ),
Column( "update_time", DateTime, PassiveDefault( func.current_timestamp() ), onupdate=func.current_timestamp() ),
Column( "session_id", Integer, ForeignKey( "galaxy_session.id" ), nullable=True ),
Column( "history_id", Integer, ForeignKey( "history.id" ) ),
Column( "tool_id", String( 255 ) ),
Column( "state", String( 64 ) ),
@@ -104,10 +105,26 @@ Event.table = Table( "event", metadata,
Column( "id", Integer, primary_key=True ),
Column( "create_time", DateTime, PassiveDefault( func.current_timestamp() ) ),
Column( "update_time", DateTime, PassiveDefault( func.current_timestamp() ), onupdate=func.current_timestamp() ),
Column( "history_id", Integer, nullable=True ),
Column( "history_id", Integer, ForeignKey( "history.id" ), nullable=True ),
Column( "session_id", Integer, ForeignKey( "galaxy_session.id" ), nullable=True ),
Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), nullable=True ),
Column( "tool_id", String( 255 ) ),
Column( "message", TrimmedString( 1024 ) ) )
GalaxySession.table = Table( "galaxy_session", metadata,
Column( "id", Integer, primary_key=True ),
Column( "create_time", DateTime, PassiveDefault( func.current_timestamp() ) ),
Column( "update_time", DateTime, PassiveDefault( func.current_timestamp() ), onupdate=func.current_timestamp() ),
Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), nullable=True ),
Column( "remote_host", String( 255 ) ),
Column( "remote_addr", String( 255 ) ) )
GalaxySessionToHistoryAssociation.table = Table( "galaxy_session_to_history", metadata,
Column( "id", Integer, primary_key=True ),
Column( "create_time", DateTime, PassiveDefault( func.current_timestamp() ) ),
Column( "session_id", Integer, ForeignKey( "galaxy_session.id" ) ),
Column( "history_id", Integer, ForeignKey( "history.id" ) ) )
# With the tables defined we can define the mappers and setup the
# relationships between the model objects.
@@ -119,7 +136,8 @@ assign_mapper( context, Dataset, Dataset.table,
# properties=dict( datasets=relation( model.Dataset.mapper, backref="query") ) )
assign_mapper( context, History, History.table,
properties=dict( datasets=relation( Dataset, backref="history", order_by=asc(Dataset.table.c.hid) ),
properties=dict( galaxy_sessions=relation( GalaxySessionToHistoryAssociation ),
datasets=relation( Dataset, backref="history", order_by=asc(Dataset.table.c.hid) ),
active_datasets=relation( Dataset, primaryjoin=( ( Dataset.c.history_id == History.table.c.id ) & ( Dataset.c.deleted == False ) ), order_by=asc( Dataset.table.c.hid ), lazy=False, viewonly=True ) ) )
assign_mapper( context, User, User.table,
@@ -135,13 +153,24 @@ assign_mapper( context, JobToOutputDatasetAssociation, JobToOutputDatasetAssocia
assign_mapper( context, JobParameter, JobParameter.table )
assign_mapper( context, Job, Job.table,
properties=dict( history=relation( History ),
properties=dict( galaxy_session=relation( GalaxySession ),
history=relation( History ),
parameters=relation( JobParameter ),
input_datasets=relation( JobToInputDatasetAssociation ),
output_datasets=relation( JobToOutputDatasetAssociation ) ) )
assign_mapper( context, Event, Event.table,
properties=dict( user=relation( User.mapper ) ) )
properties=dict( history=relation( History ),
galaxy_session=relation( GalaxySession ),
user=relation( User.mapper ) ) )
assign_mapper( context, GalaxySession, GalaxySession.table,
properties=dict( histories=relation( GalaxySessionToHistoryAssociation ),
user=relation( User.mapper ) ) )
assign_mapper( context, GalaxySessionToHistoryAssociation, GalaxySessionToHistoryAssociation.table,
properties=dict( galaxy_session=relation( GalaxySession ),
history=relation( History ) ) )
def db_next_hid( self ):
"""
+2
View File
@@ -8,6 +8,7 @@ class MappingTests( unittest.TestCase ):
assert model.engine is not None
# Make some changes and commit them
u = model.User( email="james@foo.bar.baz", password="password" )
# gs = model.GalaxySession()
h1 = model.History( name="History 1", user=u)
#h1.queries.append( model.Query( "h1->q1" ) )
#h1.queries.append( model.Query( "h1->q2" ) )
@@ -39,6 +40,7 @@ class MappingTests( unittest.TestCase ):
hists = model.History.select()
assert hists[0].name == "History 1"
assert hists[1].name == "History 2b"
# gvk TODO need to ad test for GalaxySessions, but not yet sure what they should look like.
def get_suite():
suite = unittest.TestSuite()
+8
View File
@@ -588,6 +588,14 @@ class DefaultToolAction( object ):
# Create the job object
job = trans.app.model.Job()
if trans.galaxy_session_is_valid():
a_galaxy_session = trans.get_galaxy_session()
else:
a_galaxy_session = trans.new_galaxy_session()
job.session_id = a_galaxy_session.id
a_history = trans.get_history()
if a_history is not None:
job.history_id = a_history.id
job.tool_id = tool.id
job.command_line = command_line
job.param_filename = param_filename
-1
View File
@@ -7,7 +7,6 @@ class UploadToolAction( object ):
Action for uploading files
"""
def execute( self, tool, trans, incoming={} ):
data_file = incoming['file_data']
file_type = incoming['file_type']
dbkey = incoming['dbkey']
+89 -5
View File
@@ -24,21 +24,24 @@ NOT_SET = object()
class UniverseWebTransaction( framework.DefaultWebTransaction ):
"""
Encapsulates web transaction specific state for the Universe application
(specifically the user's history)
(specifically the user's "cookie" session and history)
"""
def __init__( self, environ, app ):
self.app = app
self.__user = NOT_SET
self.__history = NOT_SET
self.__galaxy_session = NOT_SET
framework.DefaultWebTransaction.__init__( self, environ )
self.app.model.context.current.clear()
self.debug = asbool( self.app.config.get( 'debug', False ) )
def log_event( self, message, **kwargs ):
def log_event( self, message, tool_id=None, **kwargs ):
"""
Application level logging. Still needs fleshing out (log levels and
such)
"""
event = self.app.model.Event()
event.tool_id = tool_id
try:
event.message = message % kwargs
except:
@@ -49,7 +52,10 @@ class UniverseWebTransaction( framework.DefaultWebTransaction ):
except:
event.history_id = None
event.user = self.user
if self.galaxy_session_is_valid():
event.session_id = self.galaxy_session.id
event.flush()
def get_cookie( self, name='universe' ):
"""
Convienience method for getting the universe cookie
@@ -63,6 +69,7 @@ class UniverseWebTransaction( framework.DefaultWebTransaction ):
return self.request.cookies[name].value
except Exception:
return None
def set_cookie( self, value, name='universe', path='/', age=90, version='1' ):
"""
Convienience method for setting the universe cookie
@@ -73,6 +80,7 @@ class UniverseWebTransaction( framework.DefaultWebTransaction ):
tstamp = time.localtime ( time.time() + 3600 * 24 * age )
self.response.cookies[name]['expires'] = time.strftime('%a, %d-%b-%Y %H:%M:%S GMT', tstamp)
self.response.cookies[name]['version'] = version
def get_history( self ):
"""
Load the current history
@@ -84,14 +92,20 @@ class UniverseWebTransaction( framework.DefaultWebTransaction ):
history = self.app.model.History.get( id )
if history is None:
history = self.new_history()
self.__history = history
return self.__history
self.__history = history
return self.__history
def new_history( self ):
history = self.app.model.History()
if history.user_id is None and self.user is not None:
history.user_id = self.user.id
if self.galaxy_session_is_valid():
history.add_galaxy_session(self.get_galaxy_session())
history.flush()
self.set_cookie( name='universe', value=history.id )
self.__history = history
return history
def set_history( self, history ):
if history is None:
self.set_cookie( name='universe', value='' )
@@ -99,6 +113,7 @@ class UniverseWebTransaction( framework.DefaultWebTransaction ):
self.set_cookie( name='universe', value=history.id )
self.__history = history
history = property( get_history, set_history )
def get_user( self ):
"""
Return the current user if logged in (based on cookie) or `None`.
@@ -110,6 +125,7 @@ class UniverseWebTransaction( framework.DefaultWebTransaction ):
else:
self.__user = self.app.model.User.get( int( id ) )
return self.__user
def set_user( self, user ):
"""
Set the current user to `user` (by setting a cookie).
@@ -119,7 +135,75 @@ class UniverseWebTransaction( framework.DefaultWebTransaction ):
else:
self.set_cookie( name='universe_user', value=user.id )
self.__user = user
user = property( get_user, set_user )
user = property( get_user, set_user )
def get_galaxy_session( self ):
"""
Return the current user's galaxy_session.
"""
if self.__galaxy_session is NOT_SET:
id = self.get_cookie( name='universe_session' )
if not id:
self.__galaxy_session = None
else:
self.__galaxy_session = self.app.model.GalaxySession.get( int( id ) )
return self.__galaxy_session
def new_galaxy_session( self ):
galaxy_session = self.app.model.GalaxySession()
if self.user is not None:
galaxy_session.user_id = self.user.id
galaxy_session.remote_host = self.request.remote_host
galaxy_session.remote_addr = self.request.remote_addr
if self.history is not None:
galaxy_session.add_history(self.history)
galaxy_session.flush()
self.set_cookie( name='universe_session', value=galaxy_session.id )
self.__galaxy_session = galaxy_session
return self.__galaxy_session
def set_galaxy_session( self, galaxy_session ):
"""
Set the current galaxy_session by setting the universe_session cookie.
"""
if galaxy_session is None:
#TODO we may want to raise an exception here instead of creating a new galaxy_session
galaxy_session = self.new_galaxy_session()
else:
if galaxy_session.user_id is None and self.user is not None:
galaxy_session.user_id = self.user.id
galaxy_session.flush()
self.set_cookie( name='universe_session', value=galaxy_session.id )
self.__galaxy_session = galaxy_session
def galaxy_session_is_valid( self ):
# TODO do we want better validation here?
valid = False
a_galaxy_session = self.get_galaxy_session()
if a_galaxy_session is not None and a_galaxy_session.id is not None:
valid = True
return valid
def end_galaxy_session( self ):
"""
End the current galaxy_session by expiring the universe_session cookie.
"""
if self.galaxy_session_is_valid():
self.set_cookie( name='universe_session', value=self.galaxy_session.id, age=0 )
self.__galaxy_session = None
galaxy_session = property( get_galaxy_session, set_galaxy_session )
def make_associations( self ):
if self.galaxy_session_is_valid():
if self.galaxy_session.user_id is None and self.user is not None:
self.galaxy_session.user_id = self.user.id
self.galaxy_session.flush()
self.__galaxy_session = self.galaxy_session
if self.history is not None and self.user is not None:
self.history.user_id = self.user.id
self.history.flush()
self.__history = self.history
def get_toolbox(self):
"""Returns the application toolbox"""
return self.app.toolbox