root/galaxy-central/lib/galaxy/web/controllers/root.py

リビジョン 2, 37.9 KB (コミッタ: hatakeyama, 14 年 前)

import galaxy-central

行番号 
1"""
2Contains the main interface in the Universe class
3"""
4import logging, os, string, shutil, urllib, re, socket
5from cgi import escape, FieldStorage
6from galaxy import util, datatypes, jobs, web, util
7from galaxy.web.base.controller import *
8from galaxy.util.sanitize_html import sanitize_html
9from galaxy.model.orm import *
10from galaxy.model.item_attrs import UsesAnnotations
11
12log = logging.getLogger( __name__ )
13
14class RootController( BaseController, UsesHistory, UsesAnnotations ):
15   
16    @web.expose
17    def default(self, trans, target1=None, target2=None, **kwd):
18        return 'This link may not be followed from within Galaxy.'
19   
20    @web.expose
21    def index(self, trans, id=None, tool_id=None, mode=None, workflow_id=None, m_c=None, m_a=None, **kwd):
22        return trans.fill_template( "root/index.mako",
23                                    tool_id=tool_id,
24                                    workflow_id=workflow_id,
25                                    m_c=m_c, m_a=m_a )
26       
27    ## ---- Tool related -----------------------------------------------------
28   
29    @web.expose
30    def tool_menu( self, trans ):
31        if trans.app.config.require_login and not trans.user:
32            return trans.fill_template( '/no_access.mako', message = 'Please log in to access Galaxy tools.' )
33        else:
34            ## Get most recently used tools.
35            toolbox = self.get_toolbox()
36            recent_tools = []
37            if trans.user:
38                for row in trans.sa_session.query( self.app.model.Job.tool_id ). \
39                                                            filter( self.app.model.Job.user==trans.user ). \
40                                                            order_by( self.app.model.Job.create_time.desc() ):
41                    tool_id = row[0]
42                    a_tool = toolbox.tools_by_id.get( tool_id, None )
43                    if a_tool and not a_tool.hidden and a_tool not in recent_tools:
44                        recent_tools.append( a_tool )
45                        ## TODO: make number of recently used tools a user preference.
46                        if len ( recent_tools ) == 5:
47                            break
48                       
49            return trans.fill_template('/root/tool_menu.mako', toolbox=toolbox, recent_tools=recent_tools )
50
51    @web.json
52    def tool_search( self, trans, query ):
53        trans.log_action( trans.get_user(), "tool_search.search", "", { "query" : query } )
54        return trans.app.toolbox_search.search( query )
55
56    @web.expose
57    def tool_help( self, trans, id ):
58        """Return help page for tool identified by 'id' if available"""
59        toolbox = self.get_toolbox()
60        tool = toolbox.tools_by_id.get(id, '')
61        yield "<html><body>"
62        if not tool:
63            yield "Unknown tool id '%d'" % id
64        elif tool.help:
65            yield tool.help
66        else:
67            yield "No additional help available for tool '%s'" % tool.name
68        yield "</body></html>"
69
70    ## ---- Root history display ---------------------------------------------
71   
72    @web.expose
73    def my_data( self, trans, **kwd ):
74        """
75        Display user's data.
76        """
77        return trans.fill_template_mako( "/my_data.mako" )
78
79    @web.expose
80    def history( self, trans, as_xml=False, show_deleted=False, show_hidden=False, hda_id=None ):
81        """
82        Display the current history, creating a new history if necessary.
83        NOTE: No longer accepts "id" or "template" options for security reasons.
84        """
85        if trans.app.config.require_login and not trans.user:
86            return trans.fill_template( '/no_access.mako', message = 'Please log in to access Galaxy histories.' )
87        history = trans.get_history( create=True )
88        if as_xml:
89            trans.response.set_content_type('text/xml')
90            return trans.fill_template_mako( "root/history_as_xml.mako",
91                                              history=history,
92                                              show_deleted=util.string_as_bool( show_deleted ),
93                                              show_hidden=util.string_as_bool( show_hidden ) )
94        else:
95            show_deleted = util.string_as_bool( show_deleted )
96            show_hidden = util.string_as_bool( show_hidden )
97            datasets = self.get_history_datasets( trans, history, show_deleted, show_hidden )
98            return trans.stream_template_mako( "root/history.mako",
99                                               history = history,
100                                               annotation = self.get_item_annotation_str( trans.sa_session, trans.user, history ),
101                                               datasets = datasets,
102                                               hda_id = hda_id,
103                                               show_deleted = show_deleted,
104                                               show_hidden=show_hidden )
105
106    @web.expose
107    def dataset_state ( self, trans, id=None, stamp=None ):
108        if id is not None:
109            try:
110                data = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( id )
111            except:
112                return trans.show_error_message( "Unable to check dataset %s." %str( id ) )
113            trans.response.headers['X-Dataset-State'] = data.state
114            trans.response.headers['Pragma'] = 'no-cache'
115            trans.response.headers['Expires'] = '0'
116            return data.state
117        else:
118            return trans.show_error_message( "Must specify a dataset id.")
119
120    @web.expose
121    def dataset_code( self, trans, id=None, hid=None, stamp=None ):
122        if id is not None:
123            try:
124                data = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( id )
125            except:
126                return trans.show_error_message( "Unable to check dataset %s." %str( id ) )
127            trans.response.headers['Pragma'] = 'no-cache'
128            trans.response.headers['Expires'] = '0'
129            return trans.fill_template("root/history_item.mako", data=data, hid=hid)
130        else:
131            return trans.show_error_message( "Must specify a dataset id.")
132
133    @web.json
134    def history_item_updates( self, trans, ids=None, states=None ):
135        # Avoid caching
136        trans.response.headers['Pragma'] = 'no-cache'
137        trans.response.headers['Expires'] = '0'
138        # Create new HTML for any that have changed
139        rval = {}
140        if ids is not None and states is not None:
141            ids = map( int, ids.split( "," ) )
142            states = states.split( "," )
143            for id, state in zip( ids, states ):
144                data = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( id )
145                if data.state != state:
146                    job_hda = data
147                    while job_hda.copied_from_history_dataset_association:
148                        job_hda = job_hda.copied_from_history_dataset_association
149                    force_history_refresh = False
150                    if job_hda.creating_job_associations:
151                        tool = trans.app.toolbox.tools_by_id.get( job_hda.creating_job_associations[ 0 ].job.tool_id, None )
152                        if tool:
153                            force_history_refresh = tool.force_history_refresh
154                    if not job_hda.visible:
155                        force_history_refresh = True
156                    rval[id] = {
157                        "state": data.state,
158                        "html": unicode( trans.fill_template( "root/history_item.mako", data=data, hid=data.hid ), 'utf-8' ),
159                        "force_history_refresh": force_history_refresh
160                    }
161        return rval
162
163    ## ---- Dataset display / editing ----------------------------------------
164
165    @web.expose
166    def display( self, trans, id=None, hid=None, tofile=None, toext=".txt", **kwd ):
167        """
168        Returns data directly into the browser.
169        Sets the mime-type according to the extension
170        """
171        if hid is not None:
172            try:
173                hid = int( hid )
174            except:
175                return "hid '%s' is invalid" %str( hid )
176            history = trans.get_history()
177            for dataset in history.datasets:
178                if dataset.hid == hid:
179                    data = dataset
180                    break
181            else:
182                raise Exception( "No dataset with hid '%d'" % hid )
183        else:
184            try:
185                data = self.app.model.HistoryDatasetAssociation.get( id )
186            except:
187                return "Dataset id '%s' is invalid" %str( id )
188        if data:
189            current_user_roles = trans.get_current_user_roles()
190            if trans.app.security_agent.can_access_dataset( current_user_roles, data.dataset ):
191                mime = trans.app.datatypes_registry.get_mimetype_by_extension( data.extension.lower() )
192                trans.response.set_content_type(mime)
193                if tofile:
194                    fStat = os.stat(data.file_name)
195                    trans.response.headers['Content-Length'] = int(fStat.st_size)
196                    if toext[0:1] != ".":
197                        toext = "." + toext
198                    valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
199                    fname = data.name
200                    fname = ''.join(c in valid_chars and c or '_' for c in fname)[0:150]
201                    trans.response.headers["Content-Disposition"] = "attachment; filename=GalaxyHistoryItem-%s-[%s]%s" % (data.hid, fname, toext)
202                trans.log_event( "Display dataset id: %s" % str(id) )
203                try:
204                    return open( data.file_name )
205                except:
206                    return "This dataset contains no content"
207            else:
208                return "You are not allowed to access this dataset"
209        else:
210            return "No dataset with id '%s'" % str( id )
211
212    @web.expose
213    def display_child(self, trans, parent_id=None, designation=None, tofile=None, toext=".txt"):
214        """
215        Returns child data directly into the browser, based upon parent_id and designation.
216        """
217        try:
218            data = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( parent_id )
219            if data:
220                child = data.get_child_by_designation( designation )
221                if child:
222                    current_user_roles = trans.get_current_user_roles()
223                    if trans.app.security_agent.can_access_dataset( current_user_roles, child ):
224                        return self.display( trans, id=child.id, tofile=tofile, toext=toext )
225                    else:
226                        return "You are not privileged to access this dataset."
227        except Exception:
228            pass
229        return "A child named %s could not be found for data %s" % ( designation, parent_id )
230
231    @web.expose
232    def display_as( self, trans, id=None, display_app=None, **kwd ):
233        """Returns a file in a format that can successfully be displayed in display_app"""
234        data = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( id )
235        authz_method = 'rbac'
236        if 'authz_method' in kwd:
237            authz_method = kwd['authz_method']
238        if data:
239            current_user_roles = trans.get_current_user_roles()
240            if authz_method == 'rbac' and trans.app.security_agent.can_access_dataset( current_user_roles, data ):
241                trans.response.set_content_type( data.get_mime() )
242                trans.log_event( "Formatted dataset id %s for display at %s" % ( str( id ), display_app ) )
243                return data.as_display_type( display_app, **kwd )
244            elif authz_method == 'display_at' and trans.app.host_security_agent.allow_action( trans.request.remote_addr,
245                                                                                              data.permitted_actions.DATASET_ACCESS,
246                                                                                              dataset = data ):
247                trans.response.set_content_type( data.get_mime() )
248                return data.as_display_type( display_app, **kwd )
249            else:
250                return "You are not allowed to access this dataset."
251        else:
252            return "No data with id=%d" % id
253
254    @web.expose
255    def peek(self, trans, id=None):
256        """Returns a 'peek' at the data"""
257        data = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( id )
258        if data:
259            yield "<html><body><pre>"
260            yield data.peek
261            yield "</pre></body></html>"
262        else:
263            yield "No data with id=%d" % id
264
265    @web.expose
266    def edit(self, trans, id=None, hid=None, **kwd):
267        """Allows user to modify parameters of an HDA."""
268        message = ''
269        error = False
270        def __ok_to_edit_metadata( dataset_id ):
271            #prevent modifying metadata when dataset is queued or running as input/output
272            #This code could be more efficient, i.e. by using mappers, but to prevent slowing down loading a History panel, we'll leave the code here for now
273            for job_to_dataset_association in trans.sa_session.query( self.app.model.JobToInputDatasetAssociation ) \
274                                                              .filter_by( dataset_id=dataset_id ) \
275                                                              .all() \
276                                            + trans.sa_session.query( self.app.model.JobToOutputDatasetAssociation ) \
277                                                              .filter_by( dataset_id=dataset_id ) \
278                                                              .all():
279                if job_to_dataset_association.job.state not in [ job_to_dataset_association.job.states.OK, job_to_dataset_association.job.states.ERROR, job_to_dataset_association.job.states.DELETED ]:
280                    return False
281            return True
282        if hid is not None:
283            history = trans.get_history()
284            # TODO: hid handling
285            data = history.datasets[ int( hid ) - 1 ]
286        elif id is not None:
287            data = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( id )
288        else:
289            trans.log_event( "Problem loading dataset id %s with history id %s." % ( str( id ), str( hid ) ) )
290            return trans.show_error_message( "Problem loading dataset." )
291        if data is None:
292            trans.log_event( "Problem retrieving dataset id %s with history id." % ( str( id ), str( hid ) ) )
293            return trans.show_error_message( "Problem retrieving dataset." )
294        if id is not None and data.history.user is not None and data.history.user != trans.user:
295            return trans.show_error_message( "This instance of a dataset (%s) in a history does not belong to you." % ( data.id ) )
296        current_user_roles = trans.get_current_user_roles()
297        if trans.app.security_agent.can_access_dataset( current_user_roles, data.dataset ):
298            if data.state == trans.model.Dataset.states.UPLOAD:
299                return trans.show_error_message( "Please wait until this dataset finishes uploading before attempting to edit its metadata." )
300            params = util.Params( kwd, sanitize=False )
301            if params.change:
302                # The user clicked the Save button on the 'Change data type' form
303                if data.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( params.datatype ).allow_datatype_change:
304                    #prevent modifying datatype when dataset is queued or running as input/output
305                    if not __ok_to_edit_metadata( data.id ):
306                        return trans.show_error_message( "This dataset is currently being used as input or output.  You cannot change datatype until the jobs have completed or you have canceled them." )
307                    trans.app.datatypes_registry.change_datatype( data, params.datatype, set_meta = not trans.app.config.set_metadata_externally )
308                    trans.sa_session.flush()
309                    if trans.app.config.set_metadata_externally:
310                        trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute( trans.app.datatypes_registry.set_external_metadata_tool, trans, incoming = { 'input1':data }, overwrite = False ) #overwrite is False as per existing behavior
311                    return trans.show_ok_message( "Changed the type of dataset '%s' to %s" % ( data.name, params.datatype ), refresh_frames=['history'] )
312                else:
313                    return trans.show_error_message( "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( data.extension, params.datatype ) )
314            elif params.save:
315                # The user clicked the Save button on the 'Edit Attributes' form
316                data.name  = params.name
317                data.info  = params.info
318                message = ''
319                if __ok_to_edit_metadata( data.id ):
320                    # The following for loop will save all metadata_spec items
321                    for name, spec in data.datatype.metadata_spec.items():
322                        if spec.get("readonly"):
323                            continue
324                        optional = params.get("is_"+name, None)
325                        other = params.get("or_"+name, None)
326                        if optional and optional == 'true':
327                            # optional element... == 'true' actually means it is NOT checked (and therefore omitted)
328                            setattr(data.metadata, name, None)
329                        else:
330                            if other:
331                                setattr( data.metadata, name, other )
332                            else:
333                                setattr( data.metadata, name, spec.unwrap( params.get (name, None) ) )
334                    data.datatype.after_setting_metadata( data )
335                    # Sanitize annotation before adding it.
336                    if params.annotation:
337                        annotation = sanitize_html( params.annotation, 'utf-8', 'text/html' )
338                        self.add_item_annotation( trans.sa_session, trans.get_user(), data, annotation )
339                    # If setting metadata previously failed and all required elements have now been set, clear the failed state.
340                    if data._state == trans.model.Dataset.states.FAILED_METADATA and not data.missing_meta():
341                        data._state = None
342                    trans.sa_session.flush()
343                    return trans.show_ok_message( "Attributes updated%s" % message, refresh_frames=['history'] )
344                else:
345                    trans.sa_session.flush()
346                    return trans.show_warn_message( "Attributes updated, but metadata could not be changed because this dataset is currently being used as input or output. You must cancel or wait for these jobs to complete before changing metadata.", refresh_frames=['history'] )
347            elif params.detect:
348                # The user clicked the Auto-detect button on the 'Edit Attributes' form
349                #prevent modifying metadata when dataset is queued or running as input/output
350                if not __ok_to_edit_metadata( data.id ):
351                    return trans.show_error_message( "This dataset is currently being used as input or output.  You cannot change metadata until the jobs have completed or you have canceled them." )
352                for name, spec in data.metadata.spec.items():
353                    # We need to be careful about the attributes we are resetting
354                    if name not in [ 'name', 'info', 'dbkey', 'base_name' ]:
355                        if spec.get( 'default' ):
356                            setattr( data.metadata, name, spec.unwrap( spec.get( 'default' ) ) )
357                if trans.app.config.set_metadata_externally:
358                    message = 'Attributes have been queued to be updated'
359                    trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute( trans.app.datatypes_registry.set_external_metadata_tool, trans, incoming = { 'input1':data } )
360                else:
361                    message = 'Attributes updated'
362                    data.set_meta()
363                    data.datatype.after_setting_metadata( data )
364                trans.sa_session.flush()
365                return trans.show_ok_message( message, refresh_frames=['history'] )
366            elif params.convert_data:
367                target_type = kwd.get("target_type", None)
368                if target_type:
369                    message = data.datatype.convert_dataset(trans, data, target_type)
370                    return trans.show_ok_message( message, refresh_frames=['history'] )
371            elif params.update_roles_button:
372                if not trans.user:
373                    return trans.show_error_message( "You must be logged in if you want to change permissions." )
374                if trans.app.security_agent.can_manage_dataset( current_user_roles, data.dataset ):
375                    # The user associated the DATASET_ACCESS permission on the dataset with 1 or more roles.  We
376                    # need to ensure that they did not associate roles that would cause accessibility problems.
377                    permissions, in_roles, error, message = \
378                    trans.app.security_agent.derive_roles_from_access( trans, data.dataset.id, 'root', **kwd )
379                    a = trans.app.security_agent.get_action( trans.app.security_agent.permitted_actions.DATASET_ACCESS.action )
380                    if error:
381                        # Keep the original role associations for the DATASET_ACCESS permission on the dataset.
382                        permissions[ a ] = data.dataset.get_access_roles( trans )
383                    trans.app.security_agent.set_all_dataset_permissions( data.dataset, permissions )
384                    trans.sa_session.refresh( data.dataset )
385                    if not message:
386                        message = 'Your changes completed successfully.'
387                else:
388                    return trans.show_error_message( "You are not authorized to change this dataset's permissions" )
389            if "dbkey" in data.datatype.metadata_spec and not data.metadata.dbkey:
390                # Copy dbkey into metadata, for backwards compatability
391                # This looks like it does nothing, but getting the dbkey
392                # returns the metadata dbkey unless it is None, in which
393                # case it resorts to the old dbkey.  Setting the dbkey
394                # sets it properly in the metadata
395                #### This is likely no longer required, since the dbkey exists entirely within metadata (the old_dbkey field is gone): REMOVE ME?
396                data.metadata.dbkey = data.dbkey
397            # let's not overwrite the imported datatypes module with the variable datatypes?
398            # the built-in 'id' is overwritten in lots of places as well
399            ldatatypes = [ dtype_name for dtype_name, dtype_value in trans.app.datatypes_registry.datatypes_by_extension.iteritems() if dtype_value.allow_datatype_change ]
400            ldatatypes.sort()
401            all_roles = trans.app.security_agent.get_legitimate_roles( trans, data.dataset, 'root' )
402            if error:
403                status = 'error'
404            else:
405                status = 'done'
406            return trans.fill_template( "/dataset/edit_attributes.mako",
407                                        data=data,
408                                        data_annotation=self.get_item_annotation_str( trans.sa_session, trans.user, data ),
409                                        datatypes=ldatatypes,
410                                        current_user_roles=current_user_roles,
411                                        all_roles=all_roles,
412                                        message=message,
413                                        status=status )
414        else:
415            return trans.show_error_message( "You do not have permission to edit this dataset's ( id: %s ) information." % str( id ) )
416
417    def __delete_dataset( self, trans, id ):
418        data = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( id )
419        if data:
420            # Walk up parent datasets to find the containing history
421            topmost_parent = data
422            while topmost_parent.parent:
423                topmost_parent = topmost_parent.parent
424            assert topmost_parent in trans.history.datasets, "Data does not belong to current history"
425            # Mark deleted and cleanup
426            data.mark_deleted()
427            data.clear_associated_files()
428            trans.log_event( "Dataset id %s marked as deleted" % str(id) )
429            if data.parent_id is None and len( data.creating_job_associations ) > 0:
430                # Mark associated job for deletion
431                job = data.creating_job_associations[0].job
432                if job.state in [ self.app.model.Job.states.QUEUED, self.app.model.Job.states.RUNNING, self.app.model.Job.states.NEW ]:
433                    # Are *all* of the job's other output datasets deleted?
434                    if job.check_if_output_datasets_deleted():
435                        job.mark_deleted()               
436                        self.app.job_manager.job_stop_queue.put( job.id )
437            trans.sa_session.flush()
438
439    @web.expose
440    def delete( self, trans, id = None, show_deleted_on_refresh = False, **kwd):
441        if id:
442            if isinstance( id, list ):
443                dataset_ids = id
444            else:
445                dataset_ids = [ id ]
446            history = trans.get_history()
447            for id in dataset_ids:
448                try:
449                    id = int( id )
450                except:
451                    continue
452                self.__delete_dataset( trans, id )
453        return self.history( trans, show_deleted = show_deleted_on_refresh )
454       
455    @web.expose
456    def delete_async( self, trans, id = None, **kwd):
457        if id:
458            try:
459                id = int( id )
460            except:
461                return "Dataset id '%s' is invalid" %str( id )
462            self.__delete_dataset( trans, id )
463        return "OK"
464
465    ## ---- History management -----------------------------------------------
466
467    @web.expose
468    def history_options( self, trans ):
469        """Displays a list of history related actions"""
470        return trans.fill_template( "/history/options.mako",
471                                    user=trans.get_user(),
472                                    history=trans.get_history( create=True ) )
473    @web.expose
474    def history_delete( self, trans, id ):
475        """
476        Backward compatibility with check_galaxy script.
477        """
478        return trans.webapp.controllers['history'].list( trans, id, operation='delete' )
479    @web.expose
480    def clear_history( self, trans ):
481        """Clears the history for a user"""
482        history = trans.get_history()
483        for dataset in history.datasets:
484            dataset.deleted = True
485            dataset.clear_associated_files()
486        trans.sa_session.flush()
487        trans.log_event( "History id %s cleared" % (str(history.id)) )
488        trans.response.send_redirect( url_for("/index" ) )
489    @web.expose
490    def history_import( self, trans, id=None, confirm=False, **kwd ):
491        msg = ""
492        user = trans.get_user()
493        user_history = trans.get_history()
494        if not id:
495            return trans.show_error_message( "You must specify a history you want to import.")
496        import_history = trans.sa_session.query( trans.app.model.History ).get( id )
497        if not import_history:
498            return trans.show_error_message( "The specified history does not exist.")
499        if user:
500            if import_history.user_id == user.id:
501                return trans.show_error_message( "You cannot import your own history.")
502            new_history = import_history.copy( target_user=trans.user )
503            new_history.name = "imported: "+new_history.name
504            new_history.user_id = user.id
505            galaxy_session = trans.get_galaxy_session()
506            try:
507                association = trans.sa_session.query( trans.app.model.GalaxySessionToHistoryAssociation ) \
508                                              .filter_by( session_id=galaxy_session.id, history_id=new_history.id ) \
509                                              .first()
510            except:
511                association = None
512            new_history.add_galaxy_session( galaxy_session, association=association )
513            trans.sa_session.add( new_history )
514            trans.sa_session.flush()
515            if not user_history.datasets:
516                trans.set_history( new_history )
517            trans.log_event( "History imported, id: %s, name: '%s': " % (str(new_history.id) , new_history.name ) )
518            return trans.show_ok_message( """
519                History "%s" has been imported. Click <a href="%s">here</a>
520                to begin.""" % ( new_history.name, web.url_for( '/' ) ) )
521        elif not user_history.datasets or confirm:
522            new_history = import_history.copy()
523            new_history.name = "imported: "+new_history.name
524            new_history.user_id = None
525            galaxy_session = trans.get_galaxy_session()
526            try:
527                association = trans.sa_session.query( trans.app.model.GalaxySessionToHistoryAssociation ) \
528                                              .filter_by( session_id=galaxy_session.id, history_id=new_history.id ) \
529                                              .first()
530            except:
531                association = None
532            new_history.add_galaxy_session( galaxy_session, association=association )
533            trans.sa_session.add( new_history )
534            trans.sa_session.flush()
535            trans.set_history( new_history )
536            trans.log_event( "History imported, id: %s, name: '%s': " % (str(new_history.id) , new_history.name ) )
537            return trans.show_ok_message( """
538                History "%s" has been imported. Click <a href="%s">here</a>
539                to begin.""" % ( new_history.name, web.url_for( '/' ) ) )
540        return trans.show_warn_message( """
541            Warning! If you import this history, you will lose your current
542            history. Click <a href="%s">here</a> to confirm.
543            """ % web.url_for( id=id, confirm=True ) )
544    @web.expose
545    def history_new( self, trans, name=None ):
546        trans.new_history( name=name )
547        trans.log_event( "Created new History, id: %s." % str(trans.history.id) )
548        return trans.show_message( "New history created", refresh_frames = ['history'] )
549    @web.expose
550    def history_add_to( self, trans, history_id=None, file_data=None, name="Data Added to History",info=None,ext="txt",dbkey="?",copy_access_from=None,**kwd ):
551        """Adds a POSTed file to a History"""
552        try:
553            history = trans.sa_session.query( trans.app.model.History ).get( history_id )
554            data = trans.app.model.HistoryDatasetAssociation( name = name,
555                                                              info = info,
556                                                              extension = ext,
557                                                              dbkey = dbkey,
558                                                              create_dataset = True,
559                                                              sa_session = trans.sa_session )
560            if copy_access_from:
561                copy_access_from = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( copy_access_from )
562                trans.app.security_agent.copy_dataset_permissions( copy_access_from.dataset, data.dataset )
563            else:
564                permissions = trans.app.security_agent.history_get_default_permissions( history )
565                trans.app.security_agent.set_all_dataset_permissions( data.dataset, permissions )
566            trans.sa_session.add( data )
567            trans.sa_session.flush()
568            data_file = open( data.file_name, "wb" )
569            file_data.file.seek( 0 )
570            data_file.write( file_data.file.read() )
571            data_file.close()
572            data.state = data.states.OK
573            data.set_size()
574            data.init_meta()
575            data.set_meta()
576            trans.sa_session.flush()
577            history.add_dataset( data )
578            trans.sa_session.flush()
579            data.set_peek()
580            trans.sa_session.flush()
581            trans.log_event("Added dataset %d to history %d" %(data.id, trans.history.id))
582            return trans.show_ok_message("Dataset "+str(data.hid)+" added to history "+str(history_id)+".")
583        except Exception, e:
584            trans.log_event( "Failed to add dataset to history: %s" % ( e ) )
585            return trans.show_error_message("Adding File to History has Failed")
586    @web.expose
587    def history_set_default_permissions( self, trans, id=None, **kwd ):
588        """Sets the permissions on a history"""
589        if trans.user:
590            if 'update_roles_button' in kwd:
591                history = None
592                if id:
593                    try:
594                        id = int( id )
595                    except:
596                        id = None
597                    if id:
598                        history = trans.sa_session.query( trans.app.model.History ).get( id )
599                if not history:
600                    # If we haven't retrieved a history, use the current one
601                    history = trans.get_history()
602                p = util.Params( kwd )
603                permissions = {}
604                for k, v in trans.app.model.Dataset.permitted_actions.items():
605                    in_roles = p.get( k + '_in', [] )
606                    if not isinstance( in_roles, list ):
607                        in_roles = [ in_roles ]
608                    in_roles = [ trans.sa_session.query( trans.app.model.Role ).get( x ) for x in in_roles ]
609                    permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
610                dataset = 'dataset' in kwd
611                bypass_manage_permission = 'bypass_manage_permission' in kwd
612                trans.app.security_agent.history_set_default_permissions( history, permissions, dataset=dataset, bypass_manage_permission=bypass_manage_permission )
613                return trans.show_ok_message( 'Default history permissions have been changed.' )
614            return trans.fill_template( 'history/permissions.mako' )
615        else:
616            #user not logged in, history group must be only public
617            return trans.show_error_message( "You must be logged in to change a history's default permissions." )
618    @web.expose
619    def dataset_make_primary( self, trans, id=None):
620        """Copies a dataset and makes primary"""
621        try:
622            old_data = trans.sa_session.query( self.app.model.HistoryDatasetAssociation ).get( id )
623            new_data = old_data.copy()
624            ## new_data.parent = None
625            ## history = trans.app.model.History.get( old_data.history_id )
626            history = trans.get_history()
627            history.add_dataset(new_data)
628            trans.sa_session.add( new_data )
629            trans.sa_session.flush()
630            return trans.show_message( "<p>Secondary dataset has been made primary.</p>", refresh_frames=['history'] )
631        except:
632            return trans.show_error_message( "<p>Failed to make secondary dataset primary.</p>" )
633
634    # @web.expose
635    # def masthead( self, trans, active_view=None ):
636    #     brand = trans.app.config.get( "brand", "" )
637    #     if brand:
638    #         brand ="<span class='brand'>/%s</span>" % brand
639    #     wiki_url = trans.app.config.get( "wiki_url", "http://g2.trac.bx.psu.edu/" )
640    #     bugs_email = trans.app.config.get( "bugs_email", "mailto:galaxy-bugs@bx.psu.edu"  )
641    #     blog_url = trans.app.config.get( "blog_url", "http://g2.trac.bx.psu.edu/blog"   )
642    #     screencasts_url = trans.app.config.get( "screencasts_url", "http://g2.trac.bx.psu.edu/wiki/ScreenCasts" )
643    #     admin_user = "false"
644    #     admin_users = trans.app.config.get( "admin_users", "" ).split( "," )
645    #     user = trans.get_user()
646    #     if user:
647    #         user_email = trans.get_user().email
648    #         if user_email in admin_users:
649    #             admin_user = "true"
650    #     return trans.fill_template( "/root/masthead.mako", brand=brand, wiki_url=wiki_url,
651    #       blog_url=blog_url,bugs_email=bugs_email, screencasts_url=screencasts_url, admin_user=admin_user, active_view=active_view )
652
653    # @web.expose
654    # def dataset_errors( self, trans, id=None, **kwd ):
655    #     """View/fix errors associated with dataset"""
656    #     data = trans.app.model.HistoryDatasetAssociation.get( id )
657    #     p = kwd
658    #     if p.get("fix_errors", None):
659    #         # launch tool to create new, (hopefully) error free dataset
660    #         tool_params = {}
661    #         tool_params["tool_id"] = 'fix_errors'
662    #         tool_params["runtool_btn"] = 'T'
663    #         tool_params["input"] = id
664    #         tool_params["ext"] = data.ext
665    #         # send methods selected
666    #         repair_methods = data.datatype.repair_methods( data )
667    #         methods = []
668    #         for method, description in repair_methods:
669    #             if method in p: methods.append(method)
670    #         tool_params["methods"] = ",".join(methods)
671    #         url = "/tool_runner/index?" + urllib.urlencode(tool_params)
672    #         trans.response.send_redirect(url)               
673    #     else:
674    #         history = trans.app.model.History.get( data.history_id )
675    #         return trans.fill_template('dataset/validation.tmpl', data=data, history=history)
676
677    # ---- Debug methods ----------------------------------------------------
678
679    @web.expose
680    def echo(self, trans, **kwd):
681        """Echos parameters (debugging)"""
682        rval = ""
683        for k in trans.request.headers:
684            rval += "%s: %s <br/>" % ( k, trans.request.headers[k] )
685        for k in kwd:
686            rval += "%s: %s <br/>" % ( k, kwd[k] )
687            if isinstance( kwd[k], FieldStorage ):
688                rval += "-> %s" % kwd[k].file.read()
689        return rval
690   
691    @web.expose
692    def generate_error( self, trans ):
693        raise Exception( "Fake error!" )
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。