# HG changeset patch -- Bitbucket.org # Project galaxy-dist # URL http://bitbucket.org/galaxy/galaxy-dist/overview # User Greg Von Kuster <greg@bx.psu.edu> # Date 1283187298 14400 # Node ID a9316edfcdfcff5f492f5f1aa979675899c5b565 # Parent ecf203e9d70295c9850cad575c63c1760cd83c73 Display the average rating for each tool the tool grid in the Galaxy Tool Shed. Add a common method for rendering the star rating, and clean up template code by using this new common method. --- a/templates/webapps/community/common/rate_tool.mako +++ b/templates/webapps/community/common/rate_tool.mako @@ -1,4 +1,5 @@ <%namespace file="/message.mako" import="render_msg" /> +<%namespace file="/webapps/community/common/common.mako" import="*" /><% from galaxy.web.framework.helpers import time_ago @@ -51,12 +52,6 @@ <%def name="javascripts()"> ${parent.javascripts()} ${h.js( "jquery.rating" )} - - <script type="text/javascript"> - jQuery( function() { - jQuery( 'form.rating' ).rating(); - }); - </script></%def><%def name="title()">Rate Tool</%def> @@ -146,60 +141,12 @@ </div><div class="form-row"><label>Average Rating:</label> - <input name="avg_rating" type="radio" class="star" value="1" disabled="disabled" - %if avg_rating > 0.5 and avg_rating < 1.5: - checked="checked" - %endif - /> - <input name="avg_rating" type="radio" class="star" value="2" disabled="disabled" - %if avg_rating > 1.5 and avg_rating < 2.5: - checked="checked" - %endif - /> - <input name="avg_rating" type="radio" class="star" value="3" disabled="disabled" - %if avg_rating > 2.5 and avg_rating < 3.5: - checked="checked" - %endif - /> - <input name="avg_rating" type="radio" class="star" value="4" disabled="disabled" - %if avg_rating > 3.5 and avg_rating < 4.5: - checked="checked" - %endif - /> - <input name="avg_rating" type="radio" class="star" value="5" disabled="disabled" - %if avg_rating > 4.5 and avg_rating < 5.5: - checked="checked" - %endif - /> + ${render_star_rating( 'avg_rating', avg_rating, disabled=True )} <div style="clear: both"></div></div><div class="form-row"><label>Your Rating:</label> - <input name="rating" type="radio" class="star" value="1" - %if tra and tra.rating == 1: - checked="checked" - %endif - /> - <input name="rating" type="radio" class="star" value="2" - %if tra and tra.rating == 2: - checked="checked" - %endif - /> - <input name="rating" type="radio" class="star" value="3" - %if tra and tra.rating == 3: - checked="checked" - %endif - /> - <input name="rating" type="radio" class="star" value="4" - %if tra and tra.rating == 4: - checked="checked" - %endif - /> - <input name="rating" type="radio" class="star" value="5" - %if tra and tra.rating == 5: - checked="checked" - %endif - /> + ${render_star_rating( 'rating', tra.rating )} <div style="clear: both"></div></div><div class="form-row"> @@ -241,33 +188,7 @@ name = 'rating%d' % count %><tr> - <td> - <input name="${name}" type="radio" class="star" value="1" disabled="disabled" - %if review.rating > 0.5 and review.rating < 1.5: - checked="checked" - %endif - /> - <input name="${name}" type="radio" class="star" value="2" disabled="disabled" - %if review.rating > 1.5 and review.rating < 2.5: - checked="checked" - %endif - /> - <input name="${name}" type="radio" class="star" value="3" disabled="disabled" - %if review.rating > 2.5 and review.rating < 3.5: - checked="checked" - %endif - /> - <input name="${name}" type="radio" class="star" value="4" disabled="disabled" - %if review.rating > 3.5 and review.rating < 4.5: - checked="checked" - %endif - /> - <input name="${name}" type="radio" class="star" value="5" disabled="disabled" - %if review.rating > 4.5 and review.rating < 5.5: - checked="checked" - %endif - /> - </td> + <td>${render_star_rating( name, review.rating, disabled=True )}</td><td>${review.comment}</td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td> --- a/templates/webapps/community/tool/view_tool.mako +++ b/templates/webapps/community/tool/view_tool.mako @@ -1,4 +1,5 @@ <%namespace file="/message.mako" import="render_msg" /> +<%namespace file="/webapps/community/common/common.mako" import="*" /><% from galaxy.web.framework.helpers import time_ago @@ -51,12 +52,6 @@ <%def name="javascripts()"> ${parent.javascripts()} ${h.js( "jquery.rating" )} - - <script type="text/javascript"> - jQuery( function() { - jQuery( 'form.rating' ).rating(); - }); - </script></%def><%def name="title()">View Tool</%def> @@ -205,31 +200,7 @@ </div><div class="form-row"><label>Average Rating:</label> - <input name="avg_rating" type="radio" class="star" value="1" disabled="disabled" - %if avg_rating > 0.5 and avg_rating < 1.5: - checked="checked" - %endif - /> - <input name="avg_rating" type="radio" class="star" value="2" disabled="disabled" - %if avg_rating > 1.5 and avg_rating < 2.5: - checked="checked" - %endif - /> - <input name="avg_rating" type="radio" class="star" value="3" disabled="disabled" - %if avg_rating > 2.5 and avg_rating < 3.5: - checked="checked" - %endif - /> - <input name="avg_rating" type="radio" class="star" value="4" disabled="disabled" - %if avg_rating > 3.5 and avg_rating < 4.5: - checked="checked" - %endif - /> - <input name="avg_rating" type="radio" class="star" value="5" disabled="disabled" - %if avg_rating > 4.5 and avg_rating < 5.5: - checked="checked" - %endif - /> + ${render_star_rating( 'avg_rating', avg_rating, disabled=True )} <div style="clear: both"></div></div></div> @@ -257,33 +228,7 @@ name = 'rating%d' % count %><tr> - <td> - <input name="${name}" type="radio" class="star" value="1" disabled="disabled" - %if review.rating > 0.5 and review.rating < 1.5: - checked="checked" - %endif - /> - <input name="${name}" type="radio" class="star" value="2" disabled="disabled" - %if review.rating > 1.5 and review.rating < 2.5: - checked="checked" - %endif - /> - <input name="${name}" type="radio" class="star" value="3" disabled="disabled" - %if review.rating > 2.5 and review.rating < 3.5: - checked="checked" - %endif - /> - <input name="${name}" type="radio" class="star" value="4" disabled="disabled" - %if review.rating > 3.5 and review.rating < 4.5: - checked="checked" - %endif - /> - <input name="${name}" type="radio" class="star" value="5" disabled="disabled" - %if review.rating > 4.5 and review.rating < 5.5: - checked="checked" - %endif - /> - </td> + <td>${render_star_rating( name, review.rating, disabled=True )}</td><td>${review.comment}</td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td> --- a/lib/galaxy/webapps/community/controllers/common.py +++ b/lib/galaxy/webapps/community/controllers/common.py @@ -11,6 +11,41 @@ log = logging.getLogger( __name__ ) # States for passing messages SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning", "error" +class ItemRatings( UsesItemRatings ): + """Overrides rate_item method since we also allow for comments""" + def rate_item( self, trans, user, item, rating, comment='' ): + """ Rate an item. Return type is <item_class>RatingAssociation. """ + item_rating = self.get_user_item_rating( trans, user, item ) + if not item_rating: + # User has not yet rated item; create rating. + item_rating_assoc_class = self._get_item_rating_assoc_class( trans, item ) + item_rating = item_rating_assoc_class() + item_rating.user = trans.user + item_rating.set_item( item ) + item_rating.rating = rating + item_rating.comment = comment + trans.sa_session.add( item_rating ) + trans.sa_session.flush() + elif item_rating.rating != rating or item_rating.comment != comment: + # User has previously rated item; update rating. + item_rating.rating = rating + item_rating.comment = comment + trans.sa_session.flush() + return item_rating + def get_avg_rating_html( self, avg_rating ): + # FIXME: the class="star" attribute in the input tag does not render correctly inside a table + # with the attribute class="grid-table", so just display the numerical avg_rating value until + # we can figure out why the styles don't work together. When this is fixed, eliminate the following + # line and return the html. + return int( avg_rating ) + html = '' + for index in range( 1, 6 ): + html += '<input name="avg_rating" type="radio" class="star" value="%s" disabled="disabled"' % str( index ) + if avg_rating > ( index - 0.5 ) and avg_rating < ( index + 0.5 ): + html += ' checked="checked"' + html += '/>' + return html + class ToolListGrid( grids.Grid ): class NameColumn( grids.TextColumn ): def get_value( self, trans, grid, tool ): @@ -48,6 +83,10 @@ class ToolListGrid( grids.Grid ): if tool.user: return tool.user.username return 'no user' + class RatingColumn( grids.TextColumn, ItemRatings ): + def get_value( self, trans, grid, tool ): + avg_rating, num_ratings = self.get_ave_item_rating_data( trans, tool ) + return self.get_avg_rating_html( avg_rating ) class EmailColumn( grids.GridColumn ): def filter( self, trans, user, query, column_filter ): if column_filter == 'All': @@ -63,12 +102,10 @@ class ToolListGrid( grids.Grid ): NameColumn( "Name", key="name", link=( lambda item: dict( operation="view_tool", id=item.id, webapp="community" ) ), - model_class=model.Tool, attach_popup=False ), TypeColumn( "Type", key="suite", - model_class=model.Tool, attach_popup=False ), VersionColumn( "Version", key="version", @@ -77,7 +114,6 @@ class ToolListGrid( grids.Grid ): filterable="advanced" ), DescriptionColumn( "Description", key="description", - model_class=model.Tool, attach_popup=False ), CategoryColumn( "Category", @@ -89,6 +125,8 @@ class ToolListGrid( grids.Grid ): link=( lambda item: dict( operation="tools_by_user", id=item.id, webapp="community" ) ), attach_popup=False, filterable="advanced" ), + RatingColumn( "Average Rating", + attach_popup=False ), # Columns that are valid for filtering but are not visible. EmailColumn( "Email", key="email", @@ -142,14 +180,12 @@ class CategoryListGrid( grids.Grid ): columns = [ NameColumn( "Name", key="name", - model_class=model.Category, link=( lambda item: dict( operation="tools_by_category", id=item.id, webapp="community" ) ), attach_popup=False, filterable="advanced" ), DescriptionColumn( "Description", key="description", - model_class=model.Category, attach_popup=False, filterable="advanced" ), @@ -175,28 +211,6 @@ class CategoryListGrid( grids.Grid ): num_rows_per_page = 50 preserve_state = False use_paging = True - -class ItemRatings( UsesItemRatings ): - """Overrides rate_item method since we also allow for comments""" - def rate_item( self, trans, user, item, rating, comment='' ): - """ Rate an item. Return type is <item_class>RatingAssociation. """ - item_rating = self.get_user_item_rating( trans, user, item ) - if not item_rating: - # User has not yet rated item; create rating. - item_rating_assoc_class = self._get_item_rating_assoc_class( trans, item ) - item_rating = item_rating_assoc_class() - item_rating.user = trans.user - item_rating.set_item( item ) - item_rating.rating = rating - item_rating.comment = comment - trans.sa_session.add( item_rating ) - trans.sa_session.flush() - elif item_rating.rating != rating or item_rating.comment != comment: - # User has previously rated item; update rating. - item_rating.rating = rating - item_rating.comment = comment - trans.sa_session.flush() - return item_rating class CommonController( BaseController, ItemRatings ): @web.expose --- /dev/null +++ b/templates/webapps/community/common/common.mako @@ -0,0 +1,15 @@ +<%def name="render_star_rating( name, rating, disabled=False )"> + <% + if disabled: + disabled_str = ' disabled="disabled"' + else: + disabled_str = '' + html = '' + for index in range( 1, 6 ): + html += '<input name="%s" type="radio" class="star" value="%s" %s' % ( str( name ), str( index ), disabled_str ) + if rating > ( index - 0.5 ) and rating < ( index + 0.5 ): + html += ' checked="checked"' + html += '/>' + %> + ${html} +</%def> --- a/lib/galaxy/item_attrs/ratings.py +++ b/lib/galaxy/item_attrs/ratings.py @@ -1,4 +1,7 @@ from sqlalchemy.sql.expression import func +import logging + +log = logging.getLogger( __name__ ) class UsesItemRatings: """ --- a/templates/base_panels.mako +++ b/templates/base_panels.mako @@ -17,7 +17,7 @@ ## Default stylesheets <%def name="stylesheets()"> - ${h.css('base','panel_layout')} + ${h.css('base','panel_layout','jquery.rating')} <style type="text/css"> #center { %if not self.has_left_panel: @@ -51,7 +51,7 @@ <%def name="late_javascripts()"> ## Scripts can be loaded later since they progressively add features to ## the panels, but do not change layout - ${h.js( 'jquery.event.drag', 'jquery.event.hover', 'jquery.form', 'galaxy.base', 'galaxy.panels' )} + ${h.js( 'jquery.event.drag', 'jquery.event.hover', 'jquery.form', 'jquery.rating', 'galaxy.base', 'galaxy.panels' )} <script type="text/javascript"> ensure_dd_helper(); --- a/templates/grid_base.mako +++ b/templates/grid_base.mako @@ -45,7 +45,7 @@ </%def><%def name="grid_javascripts()"> - ${h.js("jquery.autocomplete", "autocomplete_tagging" )} + ${h.js("jquery.autocomplete", "autocomplete_tagging", "jquery.rating" )} <script type="text/javascript"> // This is necessary so that, when nested arrays are used in ajax/post/get methods, square brackets ('[]') are // not appended to the identifier of a nested array. @@ -609,7 +609,7 @@ <%def name="stylesheets()"> ${parent.stylesheets()} - ${h.css( "autocomplete_tagging" )} + ${h.css( "autocomplete_tagging", "jquery.rating" )} <style> ## Not generic to all grids -- move to base? .count-box { @@ -717,8 +717,8 @@ %><form action="${url()}" method="post" onsubmit="return false;"> - <div class='loading-elt-overlay'></div> - <table id='grid-table' class="grid"> + <div class="loading-elt-overlay"></div> + <table id="grid-table" class="grid"><thead id="grid-table-header"><tr> %if show_item_checkboxes: @@ -747,7 +747,7 @@ %endif > %if href: - <a href="${href}" class="sort-link" sort_key='${column.key}'>${column.label}</a> + <a href="${href}" class="sort-link" sort_key="${column.key}">${column.label}</a> %else: ${column.label} %endif