1 | import os, logging, urllib, tarfile |
---|
2 | |
---|
3 | from galaxy.web.base.controller import * |
---|
4 | from galaxy.webapps.community import model |
---|
5 | from galaxy.web.framework.helpers import time_ago, iff, grids |
---|
6 | from galaxy.model.orm import * |
---|
7 | from common import * |
---|
8 | |
---|
9 | log = logging.getLogger( __name__ ) |
---|
10 | |
---|
11 | class StateColumn( grids.StateColumn ): |
---|
12 | def get_value( self, trans, grid, tool ): |
---|
13 | state = tool.state |
---|
14 | if state == trans.model.Tool.states.APPROVED: |
---|
15 | state_color = 'ok' |
---|
16 | elif state == trans.model.Tool.states.REJECTED: |
---|
17 | state_color = 'error' |
---|
18 | elif state == trans.model.Tool.states.ARCHIVED: |
---|
19 | state_color = 'upload' |
---|
20 | else: |
---|
21 | state_color = state |
---|
22 | return '<div class="count-box state-color-%s">%s</div>' % ( state_color, state ) |
---|
23 | |
---|
24 | class ToolStateColumn( grids.StateColumn ): |
---|
25 | def filter( self, trans, user, query, column_filter ): |
---|
26 | """Modify query to filter self.model_class by state.""" |
---|
27 | if column_filter == "All": |
---|
28 | pass |
---|
29 | elif column_filter in [ v for k, v in self.model_class.states.items() ]: |
---|
30 | # Get all of the latest Events associated with the current version of each tool |
---|
31 | latest_event_id_for_current_versions_of_tools = [ tool.latest_event.id for tool in get_latest_versions_of_tools( trans ) ] |
---|
32 | # Filter query by the latest state for the current version of each tool |
---|
33 | return query.filter( and_( model.Event.table.c.state == column_filter, |
---|
34 | model.Event.table.c.id.in_( latest_event_id_for_current_versions_of_tools ) ) ) |
---|
35 | return query |
---|
36 | |
---|
37 | class ApprovedToolListGrid( ToolListGrid ): |
---|
38 | columns = [ col for col in ToolListGrid.columns ] |
---|
39 | columns.append( |
---|
40 | StateColumn( "Status", |
---|
41 | link=( lambda item: dict( operation="tools_by_state", id=item.id, webapp="community" ) ), |
---|
42 | visible=False, |
---|
43 | attach_popup=False ) |
---|
44 | ) |
---|
45 | columns.append( |
---|
46 | ToolStateColumn( "State", |
---|
47 | key="state", |
---|
48 | visible=False, |
---|
49 | filterable="advanced" ) |
---|
50 | ) |
---|
51 | |
---|
52 | class MyToolsListGrid( ApprovedToolListGrid ): |
---|
53 | columns = [ col for col in ToolListGrid.columns ] |
---|
54 | columns.append( |
---|
55 | StateColumn( "Status", |
---|
56 | link=( lambda item: dict( operation="tools_by_state", id=item.id, webapp="community" ) ), |
---|
57 | visible=True, |
---|
58 | attach_popup=False ) |
---|
59 | ) |
---|
60 | columns.append( |
---|
61 | ToolStateColumn( "State", |
---|
62 | key="state", |
---|
63 | visible=False, |
---|
64 | filterable="advanced" ) |
---|
65 | ) |
---|
66 | |
---|
67 | class ToolCategoryListGrid( CategoryListGrid ): |
---|
68 | """ |
---|
69 | Replaces the tools column in the Category grid with a similar column, |
---|
70 | but displaying the number of APPROVED tools in the category. |
---|
71 | """ |
---|
72 | class ToolsColumn( grids.TextColumn ): |
---|
73 | def get_value( self, trans, grid, category ): |
---|
74 | if category.tools: |
---|
75 | viewable_tools = 0 |
---|
76 | for tca in category.tools: |
---|
77 | tool = tca.tool |
---|
78 | if tool.is_approved: |
---|
79 | viewable_tools += 1 |
---|
80 | return viewable_tools |
---|
81 | return 0 |
---|
82 | |
---|
83 | columns = [] |
---|
84 | for col in CategoryListGrid.columns: |
---|
85 | if not isinstance( col, CategoryListGrid.ToolsColumn ): |
---|
86 | columns.append( col ) |
---|
87 | columns.append( |
---|
88 | ToolsColumn( "Tools", |
---|
89 | model_class=model.Tool, |
---|
90 | attach_popup=False ) |
---|
91 | ) |
---|
92 | |
---|
93 | class ToolController( BaseController ): |
---|
94 | |
---|
95 | tool_list_grid = ApprovedToolListGrid() |
---|
96 | my_tools_list_grid = MyToolsListGrid() |
---|
97 | category_list_grid = ToolCategoryListGrid() |
---|
98 | |
---|
99 | @web.expose |
---|
100 | def index( self, trans, **kwd ): |
---|
101 | params = util.Params( kwd ) |
---|
102 | message = util.restore_text( params.get( 'message', '' ) ) |
---|
103 | status = params.get( 'status', 'done' ) |
---|
104 | return trans.fill_template( '/webapps/community/index.mako', message=message, status=status ) |
---|
105 | @web.expose |
---|
106 | def browse_categories( self, trans, **kwd ): |
---|
107 | if 'operation' in kwd: |
---|
108 | operation = kwd['operation'].lower() |
---|
109 | if operation in [ "tools_by_category", "tools_by_state", "tools_by_user" ]: |
---|
110 | # Eliminate the current filters if any exist. |
---|
111 | for k, v in kwd.items(): |
---|
112 | if k.startswith( 'f-' ): |
---|
113 | del kwd[ k ] |
---|
114 | return trans.response.send_redirect( web.url_for( controller='tool', |
---|
115 | action='browse_tools', |
---|
116 | **kwd ) ) |
---|
117 | # Render the list view |
---|
118 | return self.category_list_grid( trans, **kwd ) |
---|
119 | @web.expose |
---|
120 | def browse_tools( self, trans, **kwd ): |
---|
121 | # We add params to the keyword dict in this method in order to rename the param |
---|
122 | # with an "f-" prefix, simulating filtering by clicking a search link. We have |
---|
123 | # to take this approach because the "-" character is illegal in HTTP requests. |
---|
124 | if 'operation' in kwd: |
---|
125 | operation = kwd['operation'].lower() |
---|
126 | if operation == "view_tool": |
---|
127 | return trans.response.send_redirect( web.url_for( controller='common', |
---|
128 | action='view_tool', |
---|
129 | cntrller='tool', |
---|
130 | **kwd ) ) |
---|
131 | elif operation == "edit_tool": |
---|
132 | return trans.response.send_redirect( web.url_for( controller='common', |
---|
133 | action='edit_tool', |
---|
134 | cntrller='tool', |
---|
135 | **kwd ) ) |
---|
136 | elif operation == "download tool": |
---|
137 | return trans.response.send_redirect( web.url_for( controller='common', |
---|
138 | action='download_tool', |
---|
139 | cntrller='tool', |
---|
140 | **kwd ) ) |
---|
141 | elif operation == "tools_by_user": |
---|
142 | # Eliminate the current filters if any exist. |
---|
143 | for k, v in kwd.items(): |
---|
144 | if k.startswith( 'f-' ): |
---|
145 | del kwd[ k ] |
---|
146 | if 'user_id' in kwd: |
---|
147 | user = get_user( trans, kwd[ 'user_id' ] ) |
---|
148 | kwd[ 'f-email' ] = user.email |
---|
149 | del kwd[ 'user_id' ] |
---|
150 | else: |
---|
151 | # The received id is the tool id, so we need to get the id of the user |
---|
152 | # that uploaded the tool. |
---|
153 | tool_id = kwd.get( 'id', None ) |
---|
154 | tool = get_tool( trans, tool_id ) |
---|
155 | kwd[ 'f-email' ] = tool.user.email |
---|
156 | elif operation == "my_tools": |
---|
157 | # Eliminate the current filters if any exist. |
---|
158 | for k, v in kwd.items(): |
---|
159 | if k.startswith( 'f-' ): |
---|
160 | del kwd[ k ] |
---|
161 | kwd[ 'f-email' ] = trans.user.email |
---|
162 | return self.my_tools_list_grid( trans, **kwd ) |
---|
163 | elif operation == "approved_tools": |
---|
164 | # Eliminate the current filters if any exist. |
---|
165 | for k, v in kwd.items(): |
---|
166 | if k.startswith( 'f-' ): |
---|
167 | del kwd[ k ] |
---|
168 | # Make sure only the latest version of a tool whose state is APPROVED are displayed. |
---|
169 | kwd[ 'f-state' ] = trans.model.Tool.states.APPROVED |
---|
170 | return self.tool_list_grid( trans, **kwd ) |
---|
171 | elif operation == "tools_by_category": |
---|
172 | # Eliminate the current filters if any exist. |
---|
173 | for k, v in kwd.items(): |
---|
174 | if k.startswith( 'f-' ): |
---|
175 | del kwd[ k ] |
---|
176 | category_id = kwd.get( 'id', None ) |
---|
177 | category = get_category( trans, category_id ) |
---|
178 | kwd[ 'f-Category.name' ] = category.name |
---|
179 | # Make sure only the latest version of a tool whose state is APPROVED are displayed. |
---|
180 | kwd[ 'f-state' ] = trans.model.Tool.states.APPROVED |
---|
181 | # Render the list view |
---|
182 | return self.tool_list_grid( trans, **kwd ) |
---|
183 | @web.expose |
---|
184 | def view_tool_file( self, trans, **kwd ): |
---|
185 | params = util.Params( kwd ) |
---|
186 | id = params.get( 'id', None ) |
---|
187 | if not id: |
---|
188 | return trans.response.send_redirect( web.url_for( controller='tool', |
---|
189 | action='browse_tools', |
---|
190 | message='Select a tool to download', |
---|
191 | status='error' ) ) |
---|
192 | tool = get_tool( trans, id ) |
---|
193 | tool_file_name = urllib.unquote_plus( kwd['file_name'] ) |
---|
194 | tool_file = tarfile.open( tool.file_name ).extractfile( tool_file_name ) |
---|
195 | trans.response.set_content_type( 'text/plain' ) |
---|
196 | return tool_file |
---|
197 | @web.expose |
---|
198 | def help( self, trans, **kwd ): |
---|
199 | params = util.Params( kwd ) |
---|
200 | message = util.restore_text( params.get( 'message', '' ) ) |
---|
201 | status = params.get( 'status', 'done' ) |
---|
202 | return trans.fill_template( '/webapps/community/tool/help.mako', message=message, status=status, **kwd ) |
---|