root/galaxy-central/lib/galaxy/webapps/community/controllers/upload.py @ 2

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

import galaxy-central

行番号 
1import sys, os, shutil, logging, urllib2
2from galaxy.web.base.controller import *
3from galaxy.web.framework.helpers import time_ago, iff, grids
4from galaxy.model.orm import *
5from galaxy.web.form_builder import SelectField
6from galaxy.webapps.community import datatypes
7from common import get_categories, get_category, get_versions
8
9log = logging.getLogger( __name__ )
10
11# States for passing messages
12SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning", "error"
13
14class UploadError( Exception ):
15    pass
16
17class UploadController( BaseController ):
18   
19    @web.expose
20    @web.require_login( 'upload', use_panels=True, webapp='community' )
21    def upload( self, trans, **kwd ):
22        params = util.Params( kwd )
23        message = util.restore_text( params.get( 'message', ''  ) )
24        status = params.get( 'status', 'done' )
25        category_ids = util.listify( params.get( 'category_id', '' ) )
26        replace_id = params.get( 'replace_id', None )
27        replace_version = None
28        uploaded_file = None
29        upload_type = params.get( 'upload_type', 'tool' )
30        categories = get_categories( trans )
31        if not categories:
32            return trans.response.send_redirect( web.url_for( controller='tool',
33                                                              action='browse_tools',
34                                                              cntrller='tool',
35                                                              message='No categories have been configured in this instance of the Galaxy Tool Shed.  An administrator needs to create some via the Administrator control panel before anything can be uploaded',
36                                                              status='error' ) )
37        if params.get( 'upload_button', False ):
38            url_paste = params.get( 'url', '' ).strip()
39            file_data = params.get( 'file_data', '' )
40            if file_data == '' and url_paste == '':
41                message = 'No files were entered on the upload form.'
42                status = 'error'
43            elif file_data == '':
44                try:
45                    uploaded_file = urllib2.urlopen( url_paste )
46                except ( ValueError, urllib2.HTTPError ), e:
47                    message = 'An error occurred trying to retrieve the URL entered on the upload form: %s' % e
48                    status = 'error'
49                except urllib2.URLError, e:
50                    message = 'An error occurred trying to retrieve the URL entered on the upload form: %s' % e.reason
51                    status = 'error'
52            elif file_data not in ( '', None ):
53                uploaded_file = file_data.file
54            if uploaded_file:
55                datatype = trans.app.datatypes_registry.get_datatype_by_extension( upload_type )
56                if datatype is None:
57                    message = 'An unknown file type was selected.  This should not be possible, please report the error.'
58                    status = 'error'
59                else:
60                    try:
61                        # Initialize the tool object
62                        meta = datatype.verify( uploaded_file )
63                        meta.user = trans.user
64                        meta.guid = trans.app.security.get_new_guid()
65                        meta.suite = upload_type == 'toolsuite'
66                        obj = datatype.create_model_object( meta )
67                        trans.sa_session.add( obj )
68                        if isinstance( obj, trans.app.model.Tool ):
69                            existing = trans.sa_session.query( trans.app.model.Tool ) \
70                                                       .filter_by( tool_id = meta.id ) \
71                                                       .first()
72                            if replace_id:
73                                replace_version = trans.sa_session.query( trans.app.model.Tool ).get( trans.security.decode_id( replace_id ) )
74                            if existing and not replace_id:
75                                raise UploadError( 'A %s with the same Id already exists.  If you are trying to update this %s to a new version, use the upload form on the "Edit Tool" page.  Otherwise, change the Id in the %s config.' % \
76                                                   ( obj.label, obj.label, obj.label ) )
77                            elif replace_id and not existing:
78                                raise UploadError( 'The new %s id (%s) does not match the old %s id (%s).  Check the %s config files.' % \
79                                                   ( obj.label, str( meta.id ), obj.label, str( replace_version.tool_id ), obj.label ) )
80                            elif existing and replace_id:
81                                if replace_version.newer_version:
82                                    # If the user has picked an old version, switch to the newest version
83                                    replace_version = get_versions( replace_version )[0]
84                                if replace_version.tool_id != meta.id:
85                                    raise UploadError( 'The new %s id (%s) does not match the old %s id (%s).  Check the %s config files.' % \
86                                                   ( obj.label, str( meta.id ), obj.label, str( replace_version.tool_id ), obj.label ) )
87                                for old_version in get_versions( replace_version ):
88                                    if old_version.version == meta.version:
89                                        raise UploadError( 'The new version (%s) matches an old version.  Check your version in the %s config file.' % \
90                                                           ( str( meta.version ), obj.label ) )
91                                    if old_version.is_new:
92                                        raise UploadError( 'There is an existing version of this %s which has not yet been submitted for approval, so either <a href="%s">submit it or delete it</a> before uploading a new version.' % \
93                                                           ( obj.label,
94                                                             url_for( controller='common',
95                                                                      action='view_tool',
96                                                                      cntrller='tool',
97                                                                      id=trans.security.encode_id( old_version.id ) ) ) )
98                                    if old_version.is_waiting:
99                                        raise UploadError( 'There is an existing version of this %s which is waiting for administrative approval, so contact an administrator for help.' % \
100                                                           obj.label )
101                                    # Defer setting the id since the newer version id doesn't exist until the new Tool object is flushed
102                            if category_ids:
103                                for category_id in category_ids:
104                                    category = trans.app.model.Category.get( trans.security.decode_id( category_id ) )
105                                    # Initialize the tool category
106                                    tca = trans.app.model.ToolCategoryAssociation( obj, category )
107                                    trans.sa_session.add( tca )
108                            # Initialize the tool event
109                            event = trans.app.model.Event( state=trans.app.model.Tool.states.NEW )
110                            # Flush to get an event id
111                            trans.sa_session.add( event )
112                            trans.sa_session.flush()
113                            tea = trans.app.model.ToolEventAssociation( obj, event )
114                            trans.sa_session.add( tea )
115                        if replace_version and replace_id:
116                            replace_version.newer_version_id = obj.id
117                            trans.sa_session.add( replace_version )
118                        trans.sa_session.flush()
119                        try:
120                            os.link( uploaded_file.name, obj.file_name )
121                        except OSError:
122                            shutil.copy( uploaded_file.name, obj.file_name )
123                        # We're setting cntrller to 'tool' since that is the only controller from which we can upload
124                        # TODO: this will need tweaking when we can upload histories or workflows
125                        return trans.response.send_redirect( web.url_for( controller='common',
126                                                                          action='edit_tool',
127                                                                          cntrller='tool',
128                                                                          id=trans.app.security.encode_id( obj.id ),
129                                                                          message='Uploaded %s' % meta.message,
130                                                                          status='done' ) )
131                    except ( datatypes.DatatypeVerificationError, UploadError ), e:
132                        message = str( e )
133                        status = 'error'
134                    uploaded_file.close()
135            elif replace_id is not None:
136                replace_version = trans.sa_session.query( trans.app.model.Tool ).get( int( trans.app.security.decode_id( replace_id ) ) )
137                old_version = None
138                for old_version in get_versions( replace_version ):
139                    if old_version.is_new:
140                        message = 'There is an existing version of this tool which has not been submitted for approval, so either submit or delete it before uploading a new version.'
141                        break
142                    if old_version.is_waiting:
143                        message = 'There is an existing version of this tool which is waiting for administrative approval, so contact an administrator for help.'
144                        break
145                else:
146                    old_version = None
147                if old_version is not None:
148                    return trans.response.send_redirect( web.url_for( controller='common',
149                                                                      action='view_tool',
150                                                                      cntrller='tool',
151                                                                      id=trans.app.security.encode_id( old_version.id ),
152                                                                      message=message,
153                                                                      status='error' ) )
154        selected_categories = [ trans.security.decode_id( id ) for id in category_ids ]
155        datatype_labels=trans.app.datatypes_registry.get_datatype_labels()
156        type_ids = [ tup[0] for tup in datatype_labels ]
157        upload_type_select_list = SelectField( 'upload_type',
158                                               refresh_on_change=True,
159                                               refresh_on_change_values=type_ids )
160        for type_id, type_label in datatype_labels:
161            if type_id == upload_type:
162                upload_type_select_list.add_option( type_label, type_id, selected = True )
163            else:
164                upload_type_select_list.add_option( type_label, type_id, selected = False )
165        return trans.fill_template( '/webapps/community/upload/upload.mako',
166                                    message=message,
167                                    status=status,
168                                    selected_upload_type=upload_type,
169                                    upload_type_select_list=upload_type_select_list,
170                                    datatype_labels=trans.app.datatypes_registry.get_datatype_labels(),
171                                    replace_id=replace_id,
172                                    selected_categories=selected_categories,
173                                    categories=get_categories( trans ) )
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。