galaxy-dev
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
January 2010
- 29 participants
- 156 discussions
details: http://www.bx.psu.edu/hg/galaxy/rev/e8e73460f0d4
changeset: 3191:e8e73460f0d4
user: Kanwei Li <kanwei(a)gmail.com>
date: Mon Dec 21 18:03:50 2009 -0500
description:
Correctly fit "loading workflow" dialog
diffstat:
static/june_2007_style/blue/panel_layout.css | 2 +-
static/june_2007_style/panel_layout.css.tmpl | 1 -
templates/base_panels.mako | 2 +-
3 files changed, 2 insertions(+), 3 deletions(-)
diffs (35 lines):
diff -r e52685283a90 -r e8e73460f0d4 static/june_2007_style/blue/panel_layout.css
--- a/static/june_2007_style/blue/panel_layout.css Mon Dec 21 17:20:46 2009 -0500
+++ b/static/june_2007_style/blue/panel_layout.css Mon Dec 21 18:03:50 2009 -0500
@@ -31,7 +31,7 @@
#overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;}
.dialog-box-container{position:relative;margin-top:80px;margin-right:auto;margin-left:auto;}
.dialog-box-wrapper{position:relative;padding:1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;}
-.dialog-box{border:solid #999 1px;background:white;min-width:230px;z-index:80000;}
+.dialog-box{border:solid #999 1px;background:white;z-index:80000;}
.dialog-box .body,.dialog-box .buttons{padding:5px;}
.panel-error-message,.panel-warning-message,.panel-done-message,.panel-info-message{height:24px;line-height:24px;color:#303030;padding:0px;padding-left:26px;background-color:#FFCCCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:6px 50%;}
.panel-warning-message{background-image:url(warn_small.png);background-color:#FFFFCC;}
diff -r e52685283a90 -r e8e73460f0d4 static/june_2007_style/panel_layout.css.tmpl
--- a/static/june_2007_style/panel_layout.css.tmpl Mon Dec 21 17:20:46 2009 -0500
+++ b/static/june_2007_style/panel_layout.css.tmpl Mon Dec 21 18:03:50 2009 -0500
@@ -191,7 +191,6 @@
.dialog-box {
border: solid #999 1px;
background: white;
- min-width: 230px;
z-index: 80000;
}
diff -r e52685283a90 -r e8e73460f0d4 templates/base_panels.mako
--- a/templates/base_panels.mako Mon Dec 21 17:20:46 2009 -0500
+++ b/templates/base_panels.mako Mon Dec 21 18:03:50 2009 -0500
@@ -296,7 +296,7 @@
<div class="unified-panel-header">
<div class="unified-panel-header-inner"><span class='title'>${title}</span></div>
</div>
- <div class="body" style="max-height: 600px; overflow: auto;">${content}</div>
+ <div class="body" style="max-height: 600px;">${content}</div>
<div>
<div class="buttons" style="display: none; float: right;"></div>
<div class="extra_buttons" style="display: none; padding: 5px;"></div>
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/e52685283a90
changeset: 3190:e52685283a90
user: Kanwei Li <kanwei(a)gmail.com>
date: Mon Dec 21 17:20:46 2009 -0500
description:
Escape preview data
diffstat:
lib/galaxy/web/controllers/dataset.py | 3 ++-
templates/dataset/large_file.mako | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diffs (30 lines):
diff -r 89d265617353 -r e52685283a90 lib/galaxy/web/controllers/dataset.py
--- a/lib/galaxy/web/controllers/dataset.py Mon Dec 21 12:16:21 2009 -0500
+++ b/lib/galaxy/web/controllers/dataset.py Mon Dec 21 17:20:46 2009 -0500
@@ -198,6 +198,7 @@
return trans.show_error_message( "Please wait until this dataset finishes uploading before attempting to view it." )
if filename and filename != "index":
+ # For files in extra_files_path
file_path = os.path.join( data.extra_files_path, filename )
if os.path.exists( file_path ):
mime, encoding = mimetypes.guess_type( file_path )
@@ -205,7 +206,7 @@
try:
mime = trans.app.datatypes_registry.get_mimetype_by_extension( ".".split( file_path )[-1] )
except:
- mime = "txt"
+ mime = "text/plain"
trans.response.set_content_type( mime )
return open( file_path )
diff -r 89d265617353 -r e52685283a90 templates/dataset/large_file.mako
--- a/templates/dataset/large_file.mako Mon Dec 21 12:16:21 2009 -0500
+++ b/templates/dataset/large_file.mako Mon Dec 21 17:20:46 2009 -0500
@@ -7,5 +7,5 @@
</div>
<pre>
-${ truncated_data }
+${ truncated_data | h }
</pre>
1
0
05 Jan '10
details: http://www.bx.psu.edu/hg/galaxy/rev/89d265617353
changeset: 3189:89d265617353
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Mon Dec 21 12:16:21 2009 -0500
description:
Bug fix: removed route memory from galaxy masthead links so that they work when viewing items.
diffstat:
templates/base_panels.mako | 30 +++++++++++++++---------------
templates/grid_base.mako | 2 +-
2 files changed, 16 insertions(+), 16 deletions(-)
diffs (108 lines):
diff -r 369f6b15f3f1 -r 89d265617353 templates/base_panels.mako
--- a/templates/base_panels.mako Mon Dec 21 09:33:46 2009 -0500
+++ b/templates/base_panels.mako Mon Dec 21 12:16:21 2009 -0500
@@ -98,7 +98,7 @@
$.ajax( {
async: false,
type: "POST",
- url: "${h.url_for(controller='tool_runner', action='upload_async_create')}",
+ url: "${h.url_for(controller='/tool_runner', action='upload_async_create')}",
data: $(this).formSerialize(),
dataType: "json",
success: function( d, s ) { async_datasets = d.join() }
@@ -156,13 +156,13 @@
</%def>
%if app.config.cloud_controller_instance:
- ${tab( "cloud", "Cloud", h.url_for( controller='cloud', action='index' ))}
+ ${tab( "cloud", "Cloud", h.url_for( controller='/cloud', action='index' ))}
%else:
- ${tab( "analysis", "Analyze Data", h.url_for( controller='root', action='index' ))}
+ ${tab( "analysis", "Analyze Data", h.url_for( controller='/root', action='index' ))}
- ${tab( "workflow", "Workflow", h.url_for( controller='workflow', action='index' ))}
+ ${tab( "workflow", "Workflow", h.url_for( controller='/workflow', action='index' ))}
- ${tab( "libraries", "Data Libraries", h.url_for( controller='library', action='index' ))}
+ ${tab( "libraries", "Data Libraries", h.url_for( controller='/library', action='index' ))}
%endif
%if trans.user and trans.request_types():
@@ -170,7 +170,7 @@
<a>Lab</a>
<div class="submenu">
<ul>
- <li><a href="${h.url_for( controller='requests', action='index' )}">Sequencing Requests</a></li>
+ <li><a href="${h.url_for( controller='/requests', action='index' )}">Sequencing Requests</a></li>
</ul>
</div>
</td>
@@ -186,15 +186,15 @@
Visualization
<div class="submenu">
<ul>
- <li><a href="${h.url_for( controller='tracks', action='index' )}">Build track browser</a></li>
+ <li><a href="${h.url_for( controller='/tracks', action='index' )}">Build track browser</a></li>
<li><hr style="color: inherit; background-color: gray"/></li>
- <li><a href="${h.url_for( controller='visualization', action='index' )}">Stored visualizations</a></li>
+ <li><a href="${h.url_for( controller='/visualization', action='index' )}">Stored visualizations</a></li>
</ul>
</div>
</td>
%endif
- ${tab( "admin", "Admin", h.url_for( controller='admin', action='index' ), extra_class="admin-only", visible=( trans.user and app.config.is_admin_user( trans.user ) ) )}
+ ${tab( "admin", "Admin", h.url_for( controller='/admin', action='index' ), extra_class="admin-only", visible=( trans.user and app.config.is_admin_user( trans.user ) ) )}
<td class="tab">
<a>Help</a>
@@ -222,9 +222,9 @@
%>
<div class="submenu">
<ul class="loggedout-only" style="${style1}">
- <li><a target="galaxy_main" href="${h.url_for( controller='user', action='login' )}">Login</a></li>
+ <li><a target="galaxy_main" href="${h.url_for( controller='/user', action='login' )}">Login</a></li>
%if app.config.allow_user_creation:
- <li><a target="galaxy_main" href="${h.url_for( controller='user', action='create' )}">Register</a></li>
+ <li><a target="galaxy_main" href="${h.url_for( controller='/user', action='create' )}">Register</a></li>
%endif
</ul>
<ul class="loggedin-only" style="${style2}">
@@ -234,21 +234,21 @@
%endif
%else:
<li>Logged in as <span id="user-email">${user_email}</span></li>
- <li><a target="galaxy_main" href="${h.url_for( controller='user', action='index' )}">Preferences</a></li>
+ <li><a target="galaxy_main" href="${h.url_for( controller='/user', action='index' )}">Preferences</a></li>
<%
if app.config.require_login:
logout_target = ""
- logout_url = h.url_for( controller='root', action='index', m_c='user', m_a='logout' )
+ logout_url = h.url_for( controller='/root', action='index', m_c='user', m_a='logout' )
else:
logout_target = "galaxy_main"
- logout_url = h.url_for( controller='user', action='logout' )
+ logout_url = h.url_for( controller='/user', action='logout' )
%>
<li><a target="${logout_target}" href="${logout_url}">Logout</a></li>
<li><hr style="color: inherit; background-color: gray"/></li>
<li><a target="galaxy_main" href="${h.url_for( controller='/history', action='list' )}">Histories</a></li>
<li><a target="galaxy_main" href="${h.url_for( controller='/dataset', action='list' )}">Datasets</a></li>
%if app.config.get_bool( 'enable_pages', False ):
- <li><a href="${h.url_for( controller='page' )}">Pages</a></li>
+ <li><a href="${h.url_for( controller='/page' )}">Pages</a></li>
%endif
%endif
</ul>
diff -r 369f6b15f3f1 -r 89d265617353 templates/grid_base.mako
--- a/templates/grid_base.mako Mon Dec 21 09:33:46 2009 -0500
+++ b/templates/grid_base.mako Mon Dec 21 12:16:21 2009 -0500
@@ -733,7 +733,7 @@
background-color : white;
opacity : 0.5;
width : 100%;
- height : 85%;
+ height : 100%;
z-index : 14000;
position : absolute;
display: none;
1
0
05 Jan '10
details: http://www.bx.psu.edu/hg/galaxy/rev/369f6b15f3f1
changeset: 3188:369f6b15f3f1
user: jeremy goecks <jeremy.goecks at emory.edu>
date: Mon Dec 21 09:33:46 2009 -0500
description:
Added functionality for public repositories of histories and pages. Features added include: (a) unique slugs for histories; (b) pretty URLs for histories; (c) public grids for histories and pages; (d) links between lists of public pages and histories and individual pages and histories. Also fixed some bugs in grid framework.
diffstat:
lib/galaxy/model/mapping.py | 3 +-
lib/galaxy/model/migrate/versions/0030_history_slug_column.py | 38 +
lib/galaxy/web/base/controller.py | 16 +
lib/galaxy/web/buildapp.py | 1 +
lib/galaxy/web/controllers/history.py | 106 +-
lib/galaxy/web/controllers/page.py | 46 +-
lib/galaxy/web/framework/helpers/grids.py | 9 +-
templates/base_panels.mako | 4 +-
templates/display_common.mako | 12 +
templates/grid_base.mako | 16 +-
templates/grid_common.mako | 29 +-
templates/history/list_public.mako | 23 +
templates/history/sharing.mako | 3 +-
templates/history/view.mako | 615 +++++----
templates/page/display.mako | 31 +-
templates/page/editor.mako | 17 +-
16 files changed, 628 insertions(+), 341 deletions(-)
diffs (1332 lines):
diff -r e7244f7d613b -r 369f6b15f3f1 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py Fri Dec 18 14:18:56 2009 -0500
+++ b/lib/galaxy/model/mapping.py Mon Dec 21 09:33:46 2009 -0500
@@ -78,7 +78,8 @@
Column( "deleted", Boolean, index=True, default=False ),
Column( "purged", Boolean, index=True, default=False ),
Column( "genome_build", TrimmedString( 40 ) ),
- Column( "importable", Boolean, default=False ) )
+ Column( "importable", Boolean, default=False ),
+ Column( "slug", TEXT, index=True ) )
HistoryUserShareAssociation.table = Table( "history_user_share_association", metadata,
Column( "id", Integer, primary_key=True ),
diff -r e7244f7d613b -r 369f6b15f3f1 lib/galaxy/model/migrate/versions/0030_history_slug_column.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/model/migrate/versions/0030_history_slug_column.py Mon Dec 21 09:33:46 2009 -0500
@@ -0,0 +1,38 @@
+"""
+Migration script to add column for a history slug.
+"""
+
+from sqlalchemy import *
+from migrate import *
+from migrate.changeset import *
+
+import logging
+log = logging.getLogger( __name__ )
+
+metadata = MetaData( migrate_engine )
+
+def upgrade():
+
+ print __doc__
+ metadata.reflect()
+
+ History_table = Table( "history", metadata, autoload=True )
+
+ # Create slug column.
+ c = Column( "slug", TEXT, index=True )
+ c.create( History_table )
+ assert c is History_table.c.slug
+
+ # Create slug index.
+ try:
+ i = Index( "ix_history_slug", History_table.c.slug )
+ i.create()
+ except:
+ # Mysql doesn't have a named index, but alter should work
+ History_table.c.slug.alter( unique=False )
+
+def downgrade():
+ metadata.reflect()
+
+ History_table = Table( "history", metadata, autoload=True )
+ History_table.c.slug.drop()
diff -r e7244f7d613b -r 369f6b15f3f1 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py Fri Dec 18 14:18:56 2009 -0500
+++ b/lib/galaxy/web/base/controller.py Mon Dec 21 09:33:46 2009 -0500
@@ -8,11 +8,27 @@
from galaxy import config, tools, web, model, util
from galaxy.web import error, form, url_for
from galaxy.model.orm import *
+from galaxy.web.framework.helpers import grids
from Cheetah.Template import Template
log = logging.getLogger( __name__ )
+# Useful columns in many grids used by controllers.
+
+# Item's user/owner.
+class OwnerColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, item ):
+ return item.user.username
+
+# Item's public URL based on username and slug.
+class PublicURLColumn( grids.TextColumn ):
+ def get_link( self, trans, grid, item ):
+ if item.user.username:
+ return dict( action='display_by_username_and_slug', username=item.user.username, slug=item.slug )
+ else:
+ return None
+
class BaseController( object ):
"""
Base class for Galaxy web application controllers.
diff -r e7244f7d613b -r 369f6b15f3f1 lib/galaxy/web/buildapp.py
--- a/lib/galaxy/web/buildapp.py Fri Dec 18 14:18:56 2009 -0500
+++ b/lib/galaxy/web/buildapp.py Mon Dec 21 09:33:46 2009 -0500
@@ -80,6 +80,7 @@
webapp.add_route( '/:action', controller='root', action='index' )
webapp.add_route( '/datasets/:dataset_id/:action/:filename', controller='dataset', action='index', dataset_id=None, filename=None)
webapp.add_route( '/u/:username/p/:slug', controller='page', action='display_by_username_and_slug' )
+ webapp.add_route( '/u/:username/h/:slug', controller='history', action='display_by_username_and_slug' )
webapp.finalize_config()
# Wrap the webapp in some useful middleware
if kwargs.get( 'middleware', True ):
diff -r e7244f7d613b -r 369f6b15f3f1 lib/galaxy/web/controllers/history.py
--- a/lib/galaxy/web/controllers/history.py Fri Dec 18 14:18:56 2009 -0500
+++ b/lib/galaxy/web/controllers/history.py Mon Dec 21 09:33:46 2009 -0500
@@ -10,6 +10,7 @@
import webhelpers, logging, operator
from datetime import datetime
from cgi import escape
+import re
log = logging.getLogger( __name__ )
@@ -171,7 +172,33 @@
return session.query( self.model_class ).join( 'users_shared_with' )
def apply_default_filter( self, trans, query, **kwargs ):
return query.filter( model.HistoryUserShareAssociation.user == trans.user )
-
+
+class PublicHistoryListGrid( grids.Grid ):
+ title = "Public Histories"
+ model_class = model.History
+ default_sort_key = "-update_time"
+ default_filter = dict( public_url="All", username="All", tags="All" )
+ use_async = True
+ columns = [
+ PublicURLColumn( "Name", key="name", model_class=model.History, filterable="advanced"),
+ OwnerColumn( "Owner", key="username", model_class=model.User, filterable="advanced", sortable=False ),
+ grids.GridColumn( "Created", key="create_time", format=time_ago ),
+ grids.GridColumn( "Last Updated", key="update_time", format=time_ago )
+ ]
+ columns.append(
+ grids.MulticolFilterColumn(
+ "Search",
+ cols_to_filter=[ columns[0], columns[1] ],
+ key="free-text-search", visible=False, filterable="standard" )
+ )
+ operations = []
+ def build_initial_query( self, session ):
+ # Join so that searching history.user makes sense.
+ return session.query( self.model_class ).join( model.User.table )
+ def apply_default_filter( self, trans, query, **kwargs ):
+ # A public history is importable, has a slug, and is not deleted.
+ return query.filter( self.model_class.importable==True ).filter( self.model_class.slug != None ).filter( self.model_class.deleted == False )
+
class HistoryController( BaseController ):
@web.expose
def index( self, trans ):
@@ -183,6 +210,17 @@
stored_list_grid = HistoryListGrid()
shared_list_grid = SharedHistoryListGrid()
+ public_list_grid = PublicHistoryListGrid()
+
+ @web.expose
+ @web.require_login()
+ def list_public( self, trans, **kwargs ):
+ grid = self.public_list_grid( trans, **kwargs )
+ if 'async' in kwargs:
+ return grid
+ else:
+ # Render grid wrapped in panels
+ return trans.fill_template( "history/list_public.mako", grid=grid )
@web.expose
@web.require_login( "work with multiple histories" )
@@ -234,7 +272,7 @@
elif operation == "enable import via link":
for history in histories:
if not history.importable:
- history.importable = True
+ self.make_history_importable( trans.sa_session, history )
elif operation == "disable import via link":
if history_ids:
histories = [ self.get_history( trans, history_id ) for history_id in history_ids ]
@@ -372,26 +410,31 @@
trans.sa_session.flush()
@web.expose
- @web.require_login( "get history name" )
- def get_name_async( self, trans, id=None ):
- """ Returns the name for a given history. """
+ @web.require_login( "get history name, slug, and owner's username" )
+ def get_name_slug_username_async( self, trans, id=None ):
+ """ Returns the name, slug, and owner's username for a given history. """
history = self.get_history( trans, id, False )
- # To get name: user must own history, history must be importable.
- if history.user == trans.get_user() or history.importable or trans.get_user() in history.users_shared_with:
- return history.name
+ # To get info: user must own history.
+ if history.user == trans.get_user():
+ slug = iff( history.slug, history.slug, "" )
+ username = iff ( history.user.username, history.user.username, "" )
+ return history.name + "," + slug + "," + username
return
@web.expose
@web.require_login( "set history's importable flag" )
def set_importable_async( self, trans, id=None, importable=False ):
- """ Set history's importable attribute. """
+ """ Set history's importable attribute and sets history's slug. """
history = self.get_history( trans, id, True )
# Only set if importable value would change; this prevents a change in the update_time unless attribute really changed.
importable = importable in ['True', 'true', 't', 'T'];
if history and history.importable != importable:
- history.importable = importable
+ if importable:
+ self.make_history_importable( trans.sa_session, history )
+ else:
+ history.importable = importable
trans.sa_session.flush()
return
@@ -492,6 +535,31 @@
datasets = query.all(),
user_owns_history = user_owns_history,
show_deleted = False )
+
+ @web.expose
+ def display_by_username_and_slug( self, trans, username, slug ):
+ session = trans.sa_session
+ user = session.query( model.User ).filter_by( username=username ).first()
+ if user is None:
+ raise web.httpexceptions.HTTPNotFound()
+ history = trans.sa_session.query( model.History ).filter_by( user=user, slug=slug, deleted=False, importable=True ).first()
+ if history is None:
+ raise web.httpexceptions.HTTPNotFound()
+
+ query = trans.sa_session.query( model.HistoryDatasetAssociation ) \
+ .filter( model.HistoryDatasetAssociation.history == history ) \
+ .options( eagerload( "children" ) ) \
+ .join( "dataset" ).filter( model.Dataset.purged == False ) \
+ .options( eagerload_all( "dataset.actions" ) )
+ # Do not show deleted datasets.
+ query = query.filter( model.HistoryDatasetAssociation.deleted == False )
+ user_owns_history = ( trans.get_user() == history.user )
+ return trans.stream_template_mako( "history/view.mako",
+ history = history,
+ datasets = query.all(),
+ user_owns_history = user_owns_history,
+ show_deleted = False )
+
@web.expose
@web.require_login( "share histories with other users" )
def share( self, trans, id=None, email="", **kwd ):
@@ -780,7 +848,7 @@
for history in histories:
trans.sa_session.add( history )
if params.get( 'enable_import_via_link', False ):
- history.importable = True
+ self.make_history_importable( trans.sa_session, history )
trans.sa_session.flush()
elif params.get( 'disable_import_via_link', False ):
history.importable = False
@@ -896,4 +964,18 @@
msg = 'Clone with name "%s" is now included in your previously stored histories.' % new_history.name
else:
msg = '%d cloned histories are now included in your previously stored histories.' % len( histories )
- return trans.show_ok_message( msg )
\ No newline at end of file
+ return trans.show_ok_message( msg )
+
+ def make_history_importable( self, sa_session, history ):
+ """ Makes history importable and sets history's slug. Does not flush/commit changes, however. """
+ history.importable = True
+
+ # Set history slug. Slug must be unique among user's importable pages.
+ slug_base = re.sub( "\s+", "-", history.name.lower() )
+ slug = slug_base
+ count = 1
+ while sa_session.query( model.History ).filter_by( user=history.user, slug=slug, importable=True ).count() != 0:
+ # Slug taken; choose a new slug based on count. This approach can handle numerous histories with the same name gracefully.
+ slug = '%s-%i' % ( slug_base, count )
+ count += 1
+ history.slug = slug
\ No newline at end of file
diff -r e7244f7d613b -r 369f6b15f3f1 lib/galaxy/web/controllers/page.py
--- a/lib/galaxy/web/controllers/page.py Fri Dec 18 14:18:56 2009 -0500
+++ b/lib/galaxy/web/controllers/page.py Mon Dec 21 09:33:46 2009 -0500
@@ -13,20 +13,6 @@
else:
return ""
-class PublicURLColumn( grids.TextColumn ):
- def get_value( self, trans, grid, item ):
- username = item.user.username or "???"
- return username + "/" + item.slug
- def get_link( self, trans, grid, item ):
- if item.user.username:
- return dict( action='display_by_username_and_slug', username=item.user.username, slug=item.slug )
- else:
- return None
-
-class OwnerColumn( grids.TextColumn ):
- def get_value( self, trans, grid, item ):
- return item.user.username
-
class PageListGrid( grids.Grid ):
# Grid definition
use_panels = True
@@ -58,18 +44,28 @@
class PageAllPublishedGrid( grids.Grid ):
# Grid definition
use_panels = True
- title = "Published Pages From All Users"
+ use_async = True
+ title = "Published Pages"
model_class = model.Page
- default_sort_key = "-create_time"
+ default_sort_key = "-update_time"
+ default_filter = dict( title="All", username="All" )
columns = [
- grids.TextColumn( "Title", model_class=model.Page, key="title", filterable="standard" ),
- PublicURLColumn( "Public URL" ),
- OwnerColumn( "Published by", model_class=model.User, key="username" ),
+ PublicURLColumn( "Title", key="title", model_class=model.Page, filterable="advanced"),
+ OwnerColumn( "Owner", key="username", model_class=model.User, filterable="advanced", sortable=False ),
grids.GridColumn( "Created", key="create_time", format=time_ago ),
- grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
+ grids.GridColumn( "Last Updated", key="update_time", format=time_ago )
]
+ columns.append(
+ grids.MulticolFilterColumn(
+ "Search",
+ cols_to_filter=[ columns[0], columns[1] ],
+ key="free-text-search", visible=False, filterable="standard" )
+ )
+ def build_initial_query( self, session ):
+ # Join so that searching history.user makes sense.
+ return session.query( self.model_class ).join( model.User.table )
def apply_default_filter( self, trans, query, **kwargs ):
- return query.filter_by( deleted=False, published=True )
+ return query.filter( self.model_class.deleted==False ).filter( self.model_class.published==True )
class HistorySelectionGrid( grids.Grid ):
# Custom columns.
@@ -169,11 +165,13 @@
return trans.fill_template( "page/index.mako", grid=grid )
@web.expose
- @web.require_login()
def list_published( self, trans, *args, **kwargs ):
grid = self._all_published_list( trans, *args, **kwargs )
- # Render grid wrapped in panels
- return trans.fill_template( "page/index.mako", grid=grid )
+ if 'async' in kwargs:
+ return grid
+ else:
+ # Render grid wrapped in panels
+ return trans.fill_template( "page/index.mako", grid=grid )
@web.expose
diff -r e7244f7d613b -r 369f6b15f3f1 lib/galaxy/web/framework/helpers/grids.py
--- a/lib/galaxy/web/framework/helpers/grids.py Fri Dec 18 14:18:56 2009 -0500
+++ b/lib/galaxy/web/framework/helpers/grids.py Mon Dec 21 09:33:46 2009 -0500
@@ -122,6 +122,9 @@
column_filter = from_json_string_recurse( column_filter )
if len( column_filter ) == 1:
column_filter = column_filter[0]
+ # Interpret ',' as a separator for multiple terms.
+ if isinstance( column_filter, basestring ) and column_filter.find(',') != -1:
+ column_filter = column_filter.split(',')
# If filter criterion is empty, do nothing.
if column_filter == '':
continue
@@ -273,8 +276,8 @@
class GridColumn( object ):
def __init__( self, label, key=None, model_class=None, method=None, format=None, link=None, attach_popup=False, visible=True, ncells=1,
- # Valid values for filterable are ['default', 'advanced', None]
- filterable=None ):
+ # Valid values for filterable are ['standard', 'advanced', None]
+ filterable=None, sortable=True ):
self.label = label
self.key = key
self.model_class = model_class
@@ -287,7 +290,7 @@
self.filterable = filterable
# Currently can only sort of columns that have a database
# representation, not purely derived.
- if self.key:
+ if self.key and sortable:
self.sortable = True
else:
self.sortable = False
diff -r e7244f7d613b -r 369f6b15f3f1 templates/base_panels.mako
--- a/templates/base_panels.mako Fri Dec 18 14:18:56 2009 -0500
+++ b/templates/base_panels.mako Mon Dec 21 09:33:46 2009 -0500
@@ -245,8 +245,8 @@
%>
<li><a target="${logout_target}" href="${logout_url}">Logout</a></li>
<li><hr style="color: inherit; background-color: gray"/></li>
- <li><a target="galaxy_main" href="${h.url_for( controller='history', action='list' )}">Histories</a></li>
- <li><a target="galaxy_main" href="${h.url_for( controller='dataset', action='list' )}">Datasets</a></li>
+ <li><a target="galaxy_main" href="${h.url_for( controller='/history', action='list' )}">Histories</a></li>
+ <li><a target="galaxy_main" href="${h.url_for( controller='/dataset', action='list' )}">Datasets</a></li>
%if app.config.get_bool( 'enable_pages', False ):
<li><a href="${h.url_for( controller='page' )}">Pages</a></li>
%endif
diff -r e7244f7d613b -r 369f6b15f3f1 templates/display_common.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/display_common.mako Mon Dec 21 09:33:46 2009 -0500
@@ -0,0 +1,12 @@
+##
+## A set of useful methods for displaying different items.
+##
+
+## Return a link to view a history.
+<%def name="get_history_link( history, qualify=False )">
+ %if history.slug and history.user.username:
+ <% return h.url_for( controller='/history', action='display_by_username_and_slug', username=history.user.username, slug=history.slug, qualified=qualify ) %>
+ %else:
+ <% return h.url_for( controller='/history', action='view', id=trans.security.encode_id( history.id ), qualified=qualify ) %>
+ %endif
+</%def>
\ No newline at end of file
diff -r e7244f7d613b -r 369f6b15f3f1 templates/grid_base.mako
--- a/templates/grid_base.mako Fri Dec 18 14:18:56 2009 -0500
+++ b/templates/grid_base.mako Mon Dec 21 09:33:46 2009 -0500
@@ -34,6 +34,12 @@
$(document).ready(function() {
init_grid_elements();
init_grid_controls();
+
+ // Initalize filter elements.
+ $('input[type=text]').each( function()
+ {
+ $(this).click( function() { $(this).attr('value', '') } );
+ });
});
## Can this be moved into base.mako?
%if refresh_frames:
@@ -69,11 +75,11 @@
// Code to handle grid operations: filtering, sorting, paging, and operations.
//
- // Operations that are not async (AJAX) compatible.
- var no_async_ops = new Object();
+ // Operations that are async (AJAX) compatible.
+ var async_ops = new Object();
%for operation in grid.operations:
- %if not operation.async_compatible:
- no_async_ops['${operation.label.lower()}'] = "True";
+ %if operation.async_compatible:
+ async_ops['${operation.label.lower()}'] = "True";
%endif
%endfor
@@ -536,7 +542,7 @@
url_args['id'] = item_ids;
// If operation cannot be performed asynchronously, redirect to location. Otherwise do operation.
- var no_async = ( no_async_ops[operation] != undefined && no_async_ops[operation] != null);
+ var no_async = ( async_ops[operation] == undefined || async_ops[operation] == null);
if (no_async)
{
go_to_URL();
diff -r e7244f7d613b -r 369f6b15f3f1 templates/grid_common.mako
--- a/templates/grid_common.mako Fri Dec 18 14:18:56 2009 -0500
+++ b/templates/grid_common.mako Mon Dec 21 09:33:46 2009 -0500
@@ -1,4 +1,7 @@
-<%! from galaxy.web.framework.helpers.grids import TextColumn, GridColumnFilter %>
+<%!
+ from galaxy.web.framework.helpers.grids import TextColumn, GridColumnFilter
+ from galaxy.web.framework.helpers import iff
+%>
## Render a filter UI for a grid column. Filter is rendered as a table row.
<%def name="render_grid_column_filter(column)">
@@ -8,7 +11,9 @@
if column.filterable == "advanced":
column_label = column_label.lower()
%>
- <td align="left" style="padding-left: 10px">${column_label}:</td>
+ %if column.filterable == "advanced":
+ <td align="left" style="padding-left: 10px">${column_label}:</td>
+ %endif
<td>
%if isinstance(column, TextColumn):
<form class="text-filter-form" column_key="${column.key}" action="${url( dict() )}" method="get" >
@@ -43,13 +48,14 @@
%if i > 0:
,
%endif
- <span style="font-style: italic">${filter}</span>
- <%
- new_filter = list( column_filter )
- del new_filter[ i ]
- new_column_filter = GridColumnFilter( "", { column.key : h.to_json_string( new_filter ) } )
- %>
- <a href="${url( new_column_filter.get_url_args() )}"><img src="${h.url_for('/static/images/delete_tag_icon_gray.png')}"/></a>
+ <span class='text-filter-val'>${filter}
+ <%
+ new_filter = list( column_filter )
+ del new_filter[ i ]
+ new_column_filter = GridColumnFilter( "", { column.key : h.to_json_string( new_filter ) } )
+ %>
+ <a href="${url( new_column_filter.get_url_args() )}"><img src="${h.url_for('/static/images/delete_tag_icon_gray.png')}"/></a>
+ </span>
%endfor
%endif
@@ -57,7 +63,8 @@
</span>
## Print input field for column.
<span>
- <input class="no-padding-or-margin" id="input-${column.key}-filter" name="f-${column.key}" type="text" value="" size="15"/>
+ <% value = iff( column.filterable == "standard", column.label.lower(), "") %>
+ <input class="no-padding-or-margin" id="input-${column.key}-filter" name="f-${column.key}" type="text" value="${value}" size="15"/>
<input class='submit-image' type='image' src='${h.url_for('/static/images/mag_glass.png')}' alt='Filter'/>
</span>
</form>
@@ -131,7 +138,7 @@
if 'advanced-search' in kwargs and kwargs['advanced-search'] in ['True', 'true']:
advanced_search_display = "block"
- for column in grid.columns:
+ for column in grid.columns:
if column.filterable == "advanced":
## Show div if current filter has value that is different from the default filter.
if column.key in cur_filter_dict and column.key in default_filter_dict and \
diff -r e7244f7d613b -r 369f6b15f3f1 templates/history/list_public.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/history/list_public.mako Mon Dec 21 09:33:46 2009 -0500
@@ -0,0 +1,23 @@
+<%inherit file="/base_panels.mako"/>
+
+<%def name="init()">
+<%
+ self.has_left_panel=False
+ self.has_right_panel=False
+ self.active_view="page"
+ self.message_box_visible=False
+%>
+</%def>
+
+<%def name="center_panel()">
+
+ ## <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${h.url_for( controller="page", action="list" )}"> </iframe>
+
+ <div style="overflow: auto; height: 100%;">
+ <div class="page-container" style="padding: 10px;">
+ ${grid}
+ </div>
+ </div>
+
+
+</%def>
diff -r e7244f7d613b -r 369f6b15f3f1 templates/history/sharing.mako
--- a/templates/history/sharing.mako Fri Dec 18 14:18:56 2009 -0500
+++ b/templates/history/sharing.mako Mon Dec 21 09:33:46 2009 -0500
@@ -1,5 +1,6 @@
<%inherit file="/base.mako"/>
<%namespace file="/message.mako" import="render_msg" />
+<%namespace file="/display_common.mako" import="get_history_link" />
##<h2>Import via link</h2>
@@ -34,7 +35,7 @@
%endif
%if history.importable:
<div class="form-row">
- <% url = h.url_for( controller='history', action='view', id=trans.security.encode_id(history.id), qualified=True ) %>
+ <% url = get_history_link( history, True )%>
<a href="${url}" target="_blank">${url}</a>
<div class="toolParamHelp" style="clear: both;">
Send the above link to users as an easy way for them to view the history.
diff -r e7244f7d613b -r 369f6b15f3f1 templates/history/view.mako
--- a/templates/history/view.mako Fri Dec 18 14:18:56 2009 -0500
+++ b/templates/history/view.mako Mon Dec 21 09:33:46 2009 -0500
@@ -1,8 +1,271 @@
<%inherit file="/base_panels.mako"/>
+<%namespace file="/display_common.mako" import="get_history_link" />
+<%namespace file="/root/history_common.mako" import="render_dataset" />
+<%namespace file="../tagging_common.mako" import="render_tagging_element, render_community_tagging_element" />
<%def name="javascripts()">
${parent.javascripts()}
${h.js( "galaxy.base", "jquery", "json2", "jquery.jstore-all", "jquery.autocomplete", "autocomplete_tagging" )}
+ <script type="text/javascript">
+ $(function() {
+ // Load jStore for local storage
+ $.extend(jQuery.jStore.defaults, { project: 'galaxy', flash: '/static/jStore.Flash.html' })
+ $.jStore.load(); // Auto-select best storage
+
+ $.jStore.ready(function(engine) {
+ engine.ready(function() {
+ // Init stuff that requires the local storage to be running
+ initShowHide();
+ setupHistoryItem( $("div.historyItemWrapper") );
+ });
+ });
+
+ // Generate 'collapse all' link
+ $("#top-links").append( "| " ).append( $("<a href='#'>${_('collapse all')}</a>").click( function() {
+ $( "div.historyItemBody:visible" ).each( function() {
+ if ( $.browser.mozilla ) {
+ $(this).find( "pre.peek" ).css( "overflow", "hidden" );
+ }
+ $(this).slideUp( "fast" );
+ });
+ $.jStore.remove("history_expand_state");
+ }));
+
+ $("#history-rename").click( function() {
+ var old_name = $("#history-name").text()
+ var t = $("<input type='text' value='" + old_name + "'></input>" );
+ t.blur( function() {
+ $(this).remove();
+ $("#history-name").show();
+ });
+ t.keyup( function( e ) {
+ if ( e.keyCode == 27 ) {
+ // Escape key
+ $(this).trigger( "blur" );
+ } else if ( e.keyCode == 13 ) {
+ // Enter key
+ new_value = this.value;
+ $(this).trigger( "blur" );
+ $.ajax({
+ url: "${h.url_for( controller='history', action='rename_async', id=history.id )}",
+ data: { "_": true, new_name: new_value },
+ error: function() { alert( "Rename failed" ) },
+ success: function() {
+ $("#history-name").text( new_value );
+ }
+ });
+ }
+ });
+ $("#history-name").hide();
+ $("#history-name-area").append( t );
+ t.focus();
+ return false;
+ });
+ // Updater
+ updater({
+ <% updateable = [data for data in reversed( datasets ) if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]] %>
+ ${ ",".join( map(lambda data: "\"%s\" : \"%s\"" % (data.id, data.state), updateable) ) }
+ });
+ });
+ // Functionized so AJAX'd datasets can call them
+ function initShowHide() {
+
+ // Load saved state and show as necessary
+ try {
+ var stored = $.jStore.store("history_expand_state");
+ if (stored) {
+ var st = JSON.parse(stored);
+ for (var id in st) {
+ $("#" + id + " div.historyItemBody" ).show();
+ }
+ }
+ } catch(err) {
+ // Something was wrong with values in storage, so clear storage
+ $.jStore.remove("history_expand_state");
+ }
+
+ // If Mozilla, hide scrollbars in hidden items since they cause animation bugs
+ if ( $.browser.mozilla ) {
+ $( "div.historyItemBody" ).each( function() {
+ if ( ! $(this).is( ":visible" ) ) $(this).find( "pre.peek" ).css( "overflow", "hidden" );
+ })
+ }
+ }
+ // Add show/hide link and delete link to a history item
+ function setupHistoryItem( query ) {
+ query.each( function() {
+ var id = this.id;
+ var body = $(this).children( "div.historyItemBody" );
+ var peek = body.find( "pre.peek" )
+ $(this).children( ".historyItemTitleBar" ).find( ".historyItemTitle" ).wrap( "<a href='#'></a>" ).click( function() {
+ if ( body.is(":visible") ) {
+ // Hiding stuff here
+ if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ) }
+ body.slideUp( "fast" );
+
+ // Save setting
+ var stored = $.jStore.store("history_expand_state")
+ var prefs = stored ? JSON.parse(stored) : null
+ if (prefs) {
+ delete prefs[id];
+ $.jStore.store("history_expand_state", JSON.stringify(prefs));
+ }
+ } else {
+ // Showing stuff here
+ body.slideDown( "fast", function() {
+ if ( $.browser.mozilla ) { peek.css( "overflow", "auto" ); }
+ });
+
+ // Save setting
+ var stored = $.jStore.store("history_expand_state")
+ var prefs = stored ? JSON.parse(stored) : new Object;
+ prefs[id] = true;
+ $.jStore.store("history_expand_state", JSON.stringify(prefs));
+ }
+ return false;
+ });
+ // Delete link
+ $(this).find( "div.historyItemButtons > .delete" ).each( function() {
+ var data_id = this.id.split( "-" )[1];
+ $(this).click( function() {
+ $( '#historyItem-' + data_id + "> div.historyItemTitleBar" ).addClass( "spinner" );
+ $.ajax({
+ url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ),
+ error: function() { alert( "Delete failed" ) },
+ success: function() {
+ %if show_deleted:
+ var to_update = {};
+ to_update[data_id] = "none";
+ updater( to_update );
+ %else:
+ $( "#historyItem-" + data_id ).fadeOut( "fast", function() {
+ $( "#historyItemContainer-" + data_id ).remove();
+ if ( $( "div.historyItemContainer" ).length < 1 ) {
+ $( "#emptyHistoryMessage" ).show();
+ }
+ });
+ %endif
+ }
+ });
+ return false;
+ });
+ });
+ // Undelete link
+ $(this).find( "a.historyItemUndelete" ).each( function() {
+ var data_id = this.id.split( "-" )[1];
+ $(this).click( function() {
+ $( '#historyItem-' + data_id + " > div.historyItemTitleBar" ).addClass( "spinner" );
+ $.ajax({
+ url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ),
+ error: function() { alert( "Undelete failed" ) },
+ success: function() {
+ var to_update = {};
+ to_update[data_id] = "none";
+ updater( to_update );
+ }
+ });
+ return false;
+ });
+ });
+ });
+ };
+ // Looks for changes in dataset state using an async request. Keeps
+ // calling itself (via setTimeout) until all datasets are in a terminal
+ // state.
+ var updater = function ( tracked_datasets ) {
+ // Check if there are any items left to track
+ var empty = true;
+ for ( i in tracked_datasets ) {
+ empty = false;
+ break;
+ }
+ if ( ! empty ) {
+ // console.log( "Updater running in 3 seconds" );
+ setTimeout( function() { updater_callback( tracked_datasets ) }, 3000 );
+ } else {
+ // console.log( "Updater finished" );
+ }
+ };
+ var updater_callback = function ( tracked_datasets ) {
+ // Build request data
+ var ids = []
+ var states = []
+ var force_history_refresh = false
+ $.each( tracked_datasets, function ( id, state ) {
+ ids.push( id );
+ states.push( state );
+ });
+ // Make ajax call
+ $.ajax( {
+ type: "POST",
+ url: "${h.url_for( controller='root', action='history_item_updates' )}",
+ dataType: "json",
+ data: { ids: ids.join( "," ), states: states.join( "," ) },
+ success : function ( data ) {
+ $.each( data, function( id, val ) {
+ // Replace HTML
+ var container = $("#historyItemContainer-" + id);
+ container.html( val.html );
+ setupHistoryItem( container.children( ".historyItemWrapper" ) );
+ initShowHide();
+ // If new state was terminal, stop tracking
+ if (( val.state == "ok") || ( val.state == "error") || ( val.state == "empty") || ( val.state == "deleted" ) || ( val.state == "discarded" )) {
+ if ( val.force_history_refresh ){
+ force_history_refresh = true;
+ }
+ delete tracked_datasets[ parseInt(id) ];
+ } else {
+ tracked_datasets[ parseInt(id) ] = val.state;
+ }
+ });
+ if ( force_history_refresh ) {
+ parent.frames.galaxy_history.location.reload();
+ } else {
+ // Keep going (if there are still any items to track)
+ updater( tracked_datasets );
+ }
+ },
+ error: function() {
+ // Just retry, like the old method, should try to be smarter
+ updater( tracked_datasets );
+ }
+ });
+ };
+
+ //
+ // Function provides text for tagging toggle link.
+ //
+ var get_toggle_link_text = function(tags)
+ {
+ var text = "";
+ var num_tags = array_length(tags);
+ if (num_tags != 0)
+ {
+ text = num_tags + (num_tags != 1 ? " Tags" : " Tag");
+ }
+ else
+ {
+ // No tags.
+ text = "Add tags to history";
+ }
+ return text;
+ };
+
+ //
+ // Handle click on community tag.
+ //
+ function community_tag_click(tag_name, tag_value)
+ {
+ // Do nothing until community tags are implemented in public histories grid.
+ /*
+ var href = '${h.url_for( controller='/history', action='list_public')}';
+ href = href + "?f-tags=" + tag_name;
+ if (tag_value != null && tag_value != "")
+ href = href + ":" + tag_value;
+ self.location = href;
+ */
+ }
+ </script>
</%def>
<%def name="stylesheets()">
@@ -13,12 +276,40 @@
padding-right: 3px;
border-right-style: solid;
border-right-color: #66AA66;
- };
+ }
+ .page-body
+ {
+ padding: 10px;
+ float: left;
+ width: 65%;
+ }
+ .page-meta
+ {
+ float: right;
+ width: 27%;
+ padding: 0.5em;
+ margin: 0.25em;
+ vertical-align: text-top;
+ border: 2px solid #DDDDDD;
+ border-top: 4px solid #DDDDDD;
+ }
</style>
+
+ <style>
+ .historyItemBody {
+ display: none;
+ }
+ </style>
+
+ <noscript>
+ <style>
+ .historyItemBody {
+ display: block;
+ }
+ </style>
+ </noscript>
</%def>
-<%namespace file="/root/history_common.mako" import="render_dataset" />
-
<%def name="init()">
<%
self.has_left_panel=False
@@ -33,274 +324,28 @@
user_owns_history = False
%>
- <div style="overflow: auto; height: 100%;">
- <div style="padding: 10px;">
+ ## Get URL to other histories owned by user that owns this history.
+ <%
+ ##TODO: is there a better way to create this URL? Can't use 'f-username' as a key b/c it's not a valid identifier.
+ href_to_user_histories = h.url_for( controller='/history', action='list_public', xxx=history.user.username)
+ href_to_user_histories = href_to_user_histories.replace( 'xxx', 'f-username')
+ %>
+
+ <div class="unified-panel-header" unselectable="on">
+ <div class="unified-panel-header-inner">
+ <a href="${h.url_for ( controller='/history', action='list_public' )}">Public Histories</a> |
+ <a href="${href_to_user_histories}">${history.user.username}</a> | ${history.name}
+ </div>
+ </div>
+
+ <div class="unified-panel-body">
+ <div class="page-body">
## Render view of history.
- <script type="text/javascript">
- $(function() {
- // Load jStore for local storage
- $.extend(jQuery.jStore.defaults, { project: 'galaxy', flash: '/static/jStore.Flash.html' })
- $.jStore.load(); // Auto-select best storage
-
- $.jStore.ready(function(engine) {
- engine.ready(function() {
- // Init stuff that requires the local storage to be running
- initShowHide();
- setupHistoryItem( $("div.historyItemWrapper") );
- });
- });
-
- // Generate 'collapse all' link
- $("#top-links").append( "| " ).append( $("<a href='#'>${_('collapse all')}</a>").click( function() {
- $( "div.historyItemBody:visible" ).each( function() {
- if ( $.browser.mozilla ) {
- $(this).find( "pre.peek" ).css( "overflow", "hidden" );
- }
- $(this).slideUp( "fast" );
- });
- $.jStore.remove("history_expand_state");
- }));
-
- $("#history-rename").click( function() {
- var old_name = $("#history-name").text()
- var t = $("<input type='text' value='" + old_name + "'></input>" );
- t.blur( function() {
- $(this).remove();
- $("#history-name").show();
- });
- t.keyup( function( e ) {
- if ( e.keyCode == 27 ) {
- // Escape key
- $(this).trigger( "blur" );
- } else if ( e.keyCode == 13 ) {
- // Enter key
- new_value = this.value;
- $(this).trigger( "blur" );
- $.ajax({
- url: "${h.url_for( controller='history', action='rename_async', id=history.id )}",
- data: { "_": true, new_name: new_value },
- error: function() { alert( "Rename failed" ) },
- success: function() {
- $("#history-name").text( new_value );
- }
- });
- }
- });
- $("#history-name").hide();
- $("#history-name-area").append( t );
- t.focus();
- return false;
- });
- // Updater
- updater({
- <% updateable = [data for data in reversed( datasets ) if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]] %>
- ${ ",".join( map(lambda data: "\"%s\" : \"%s\"" % (data.id, data.state), updateable) ) }
- });
- });
- // Functionized so AJAX'd datasets can call them
- function initShowHide() {
-
- // Load saved state and show as necessary
- try {
- var stored = $.jStore.store("history_expand_state");
- if (stored) {
- var st = JSON.parse(stored);
- for (var id in st) {
- $("#" + id + " div.historyItemBody" ).show();
- }
- }
- } catch(err) {
- // Something was wrong with values in storage, so clear storage
- $.jStore.remove("history_expand_state");
- }
-
- // If Mozilla, hide scrollbars in hidden items since they cause animation bugs
- if ( $.browser.mozilla ) {
- $( "div.historyItemBody" ).each( function() {
- if ( ! $(this).is( ":visible" ) ) $(this).find( "pre.peek" ).css( "overflow", "hidden" );
- })
- }
- }
- // Add show/hide link and delete link to a history item
- function setupHistoryItem( query ) {
- query.each( function() {
- var id = this.id;
- var body = $(this).children( "div.historyItemBody" );
- var peek = body.find( "pre.peek" )
- $(this).children( ".historyItemTitleBar" ).find( ".historyItemTitle" ).wrap( "<a href='#'></a>" ).click( function() {
- if ( body.is(":visible") ) {
- // Hiding stuff here
- if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ) }
- body.slideUp( "fast" );
-
- // Save setting
- var stored = $.jStore.store("history_expand_state")
- var prefs = stored ? JSON.parse(stored) : null
- if (prefs) {
- delete prefs[id];
- $.jStore.store("history_expand_state", JSON.stringify(prefs));
- }
- } else {
- // Showing stuff here
- body.slideDown( "fast", function() {
- if ( $.browser.mozilla ) { peek.css( "overflow", "auto" ); }
- });
-
- // Save setting
- var stored = $.jStore.store("history_expand_state")
- var prefs = stored ? JSON.parse(stored) : new Object;
- prefs[id] = true;
- $.jStore.store("history_expand_state", JSON.stringify(prefs));
- }
- return false;
- });
- // Delete link
- $(this).find( "div.historyItemButtons > .delete" ).each( function() {
- var data_id = this.id.split( "-" )[1];
- $(this).click( function() {
- $( '#historyItem-' + data_id + "> div.historyItemTitleBar" ).addClass( "spinner" );
- $.ajax({
- url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ),
- error: function() { alert( "Delete failed" ) },
- success: function() {
- %if show_deleted:
- var to_update = {};
- to_update[data_id] = "none";
- updater( to_update );
- %else:
- $( "#historyItem-" + data_id ).fadeOut( "fast", function() {
- $( "#historyItemContainer-" + data_id ).remove();
- if ( $( "div.historyItemContainer" ).length < 1 ) {
- $( "#emptyHistoryMessage" ).show();
- }
- });
- %endif
- }
- });
- return false;
- });
- });
- // Undelete link
- $(this).find( "a.historyItemUndelete" ).each( function() {
- var data_id = this.id.split( "-" )[1];
- $(this).click( function() {
- $( '#historyItem-' + data_id + " > div.historyItemTitleBar" ).addClass( "spinner" );
- $.ajax({
- url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ),
- error: function() { alert( "Undelete failed" ) },
- success: function() {
- var to_update = {};
- to_update[data_id] = "none";
- updater( to_update );
- }
- });
- return false;
- });
- });
- });
- };
- // Looks for changes in dataset state using an async request. Keeps
- // calling itself (via setTimeout) until all datasets are in a terminal
- // state.
- var updater = function ( tracked_datasets ) {
- // Check if there are any items left to track
- var empty = true;
- for ( i in tracked_datasets ) {
- empty = false;
- break;
- }
- if ( ! empty ) {
- // console.log( "Updater running in 3 seconds" );
- setTimeout( function() { updater_callback( tracked_datasets ) }, 3000 );
- } else {
- // console.log( "Updater finished" );
- }
- };
- var updater_callback = function ( tracked_datasets ) {
- // Build request data
- var ids = []
- var states = []
- var force_history_refresh = false
- $.each( tracked_datasets, function ( id, state ) {
- ids.push( id );
- states.push( state );
- });
- // Make ajax call
- $.ajax( {
- type: "POST",
- url: "${h.url_for( controller='root', action='history_item_updates' )}",
- dataType: "json",
- data: { ids: ids.join( "," ), states: states.join( "," ) },
- success : function ( data ) {
- $.each( data, function( id, val ) {
- // Replace HTML
- var container = $("#historyItemContainer-" + id);
- container.html( val.html );
- setupHistoryItem( container.children( ".historyItemWrapper" ) );
- initShowHide();
- // If new state was terminal, stop tracking
- if (( val.state == "ok") || ( val.state == "error") || ( val.state == "empty") || ( val.state == "deleted" ) || ( val.state == "discarded" )) {
- if ( val.force_history_refresh ){
- force_history_refresh = true;
- }
- delete tracked_datasets[ parseInt(id) ];
- } else {
- tracked_datasets[ parseInt(id) ] = val.state;
- }
- });
- if ( force_history_refresh ) {
- parent.frames.galaxy_history.location.reload();
- } else {
- // Keep going (if there are still any items to track)
- updater( tracked_datasets );
- }
- },
- error: function() {
- // Just retry, like the old method, should try to be smarter
- updater( tracked_datasets );
- }
- });
- };
-
- //
- // Function provides text for tagging toggle link.
- //
- var get_toggle_link_text = function(tags)
- {
- var text = "";
- var num_tags = array_length(tags);
- if (num_tags != 0)
- {
- text = num_tags + (num_tags != 1 ? " Tags" : " Tag");
- }
- else
- {
- // No tags.
- text = "Add tags to history";
- }
- return text;
- };
- </script>
-
- <style>
- .historyItemBody {
- display: none;
- }
- </style>
-
- <noscript>
- <style>
- .historyItemBody {
- display: block;
- }
- </style>
- </noscript>
-
<div id="top-links" class="historyLinks" style="padding: 0px 0px 5px 0px">
%if not user_owns_history:
<a href="${h.url_for( controller='history', action='imp', id=trans.security.encode_id(history.id) )}">import and start using history</a> |
%endif
- <a href="${h.url_for( controller='history', action='view', id=trans.security.encode_id(history.id) )}">${_('refresh')}</a>
+ <a href="${get_history_link( history )}">${_('refresh')}</a>
%if show_deleted:
| <a href="${h.url_for('history', show_deleted=False)}">${_('hide deleted')}</a>
%endif
@@ -320,13 +365,6 @@
<p></p>
%endif
- <%namespace file="../tagging_common.mako" import="render_tagging_element" />
-
- %if trans.get_user() is not None:
- <div id='history-tag-area' class="tag-element"></div>
- ${render_tagging_element(tagged_item=history, elt_context="history/view.mako", use_toggle_link=False, get_toggle_link_text_fn='get_toggle_link_text', editable=user_owns_history)}
- %endif
-
%if not datasets:
<div class="infomessagesmall" id="emptyHistoryMessage">
@@ -334,7 +372,7 @@
%else:
## Render requested datasets, ordered from newest to oldest
- %for data in reversed( datasets ):
+ %for data in datasets:
%if data.visible:
<div class="historyItemContainer visible-right-border" id="historyItemContainer-${data.id}">
${render_dataset( data, data.hid, show_deleted_on_refresh = show_deleted, user_owns_dataset=user_owns_history )}
@@ -347,7 +385,32 @@
${_("Your history is empty. Click 'Get Data' on the left pane to start")}
</div>
</div>
+
+ <div class="page-meta">
+ ## Histories.
+ <div><strong>Related Histories</strong></div>
+ <p>
+ <a href="${h.url_for ( controller='/history', action='list_public' )}">All public histories</a><br>
+ <a href="${href_to_user_histories}">Histories owned by ${history.user.username}</a>
+
+ ## Tags.
+ <div><strong>Tags</strong></div>
+ <p>
+ ## Community tags.
+ <div>
+ Community:
+ ${render_community_tagging_element( tagged_item=history, tag_click_fn='community_tag_click', use_toggle_link=False )}
+ %if len ( history.tags ) == 0:
+ none
+ %endif
+ </div>
+ ## User tags.
+ <p>
+ <div>
+ ##Yours:
+ ##${render_tagging_element( tagged_item=history, elt_context='view.mako', use_toggle_link=False )}
+ </div>
+ </div>
+
</div>
-
-
</%def>
diff -r e7244f7d613b -r 369f6b15f3f1 templates/page/display.mako
--- a/templates/page/display.mako Fri Dec 18 14:18:56 2009 -0500
+++ b/templates/page/display.mako Mon Dec 21 09:33:46 2009 -0500
@@ -150,7 +150,14 @@
//
function community_tag_click(tag_name, tag_value)
{
- alert("community tag click: " + tag_name);
+ // Do nothing until community tags implemented in published pages grid.
+ /*
+ var href = '${h.url_for( controller='/page', action='list_published')}';
+ href = href + "?f-tags=" + tag_name;
+ if (tag_value != null && tag_value != "")
+ href = href + ":" + tag_value;
+ self.location = href;
+ */
}
</script>
</%def>
@@ -173,6 +180,7 @@
margin: 0.25em;
vertical-align: text-top;
border: 2px solid #DDDDDD;
+ border-top: 4px solid #DDDDDD;
}
</style>
</%def>
@@ -190,9 +198,17 @@
<%def name="center_panel()">
+ ## Get URL to other pages owned by user that owns this page.
+ <%
+ ##TODO: is there a better way to create this URL? Can't use 'f-username' as a key b/c it's not a valid identifier.
+ href_to_user_pages = h.url_for( controller='/page', action='list_published', xxx=page.user.username)
+ href_to_user_pages = href_to_user_pages.replace( 'xxx', 'f-username')
+ %>
+
<div class="unified-panel-header" unselectable="on">
<div class="unified-panel-header-inner">
- ${page.user.username} :: ${page.title}
+ <a href="${h.url_for ( controller='/page', action='list_published' )}">Published Pages</a> |
+ <a href="${href_to_user_pages}">${page.user.username}</a> | ${page.title}
</div>
</div>
@@ -202,6 +218,13 @@
${page.latest_revision.content.decode( "utf-8" )}
</div>
<div class="page-meta">
+ ## Pages.
+ <div><strong>Related Pages</strong></div>
+ <p>
+ <a href="${h.url_for ( controller='/page', action='list_published' )}">All published pages</a><br>
+ <a href="${href_to_user_pages}">Pages published by ${page.user.username}</a>
+
+ ## Tags.
<div><strong>Tags</strong></div>
<p>
## Community tags.
@@ -215,8 +238,8 @@
## User tags.
<p>
<div>
- Yours:
- ${render_tagging_element( tagged_item=page, elt_context='display.mako', use_toggle_link=False )}
+ ##Yours:
+ ##${render_tagging_element( tagged_item=page, elt_context='display.mako', use_toggle_link=False )}
</div>
</div>
</div>
diff -r e7244f7d613b -r 369f6b15f3f1 templates/page/editor.mako
--- a/templates/page/editor.mako Fri Dec 18 14:18:56 2009 -0500
+++ b/templates/page/editor.mako Mon Dec 21 09:33:46 2009 -0500
@@ -248,8 +248,21 @@
// User selected no text; create link from scratch and use default text.
// Get history name.
- $.get( '${h.url_for( controller='history', action='get_name_async' )}?id=' + item_id, function( history_name ) {
- var href = '${h.url_for( controller='history', action='view' )}?id=' + item_id;
+ $.get( '${h.url_for( controller='history', action='get_name_slug_username_async' )}?id=' + item_id,
+ function( history_info ) {
+ // Parse history info.
+ history_info = history_info.split(",");
+ var
+ history_name = history_info[0],
+ history_slug = history_info[1],
+ history_user_username = history_info[2];
+
+ // Build href from history info.
+ var href;
+ if (history_slug != "" && history_user_username != "")
+ var href = "/u/" + history_user_username + "/h/" + history_slug;
+ else
+ var href = '${h.url_for( controller='/history', action='view' )}?id=' + item_id;
wym.insert("<a href='" + href + "'>History '" + history_name + "'</a>");
});
}
1
0
Greetings,
I have implemented a tool to export data to an external site. I used
"tools/data_destination/epigraph.xml" as a template & this works nicely. I
am simply wondering if there is a way to control the destination frame of
the external website. Currently the entire window is replaced. If possible,
I would like it to appear in the content area (galaxy_main?), similar to the
way many of the "Get Data" tools work (eg: UCSC Main).
Thanks very much,
Chris Zaleski
5
6
Dear Dev Team,
We are planning on installing the Galaxy framework on our production systems and understandably we are trying to examine the exposure to security risks that we might experience with deploying the system. Has Galaxy been profiled for security flaws? Are there any areas of the system which are historically, or have recently been identified as having security problems?
Many thanks,
Matt Goyder
----------------------------------------- Confidentiality Notice:
The following mail message, including any attachments, is for the
sole use of the intended recipient(s) and may contain confidential
and privileged information. The recipient is responsible to
maintain the confidentiality of this information and to use the
information only for authorized purposes. If you are not the
intended recipient (or authorized to receive information for the
intended recipient), you are hereby notified that any review, use,
disclosure, distribution, copying, printing, or action taken in
reliance on the contents of this e-mail is strictly prohibited. If
you have received this communication in error, please notify us
immediately by reply e-mail and destroy all copies of the original
message. Thank you.
2
1