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
February 2010
- 32 participants
- 180 discussions
09 Feb '10
details: http://www.bx.psu.edu/hg/galaxy/rev/606686b073f3
changeset: 3361:606686b073f3
user: Nate Coraor <nate(a)bx.psu.edu>
date: Tue Feb 09 13:40:01 2010 -0500
description:
Fix for a bug in library uploads introduced with recent PBS job name changes
diffstat:
lib/galaxy/jobs/__init__.py | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diffs (14 lines):
diff -r b4c811246b1d -r 606686b073f3 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py Tue Feb 09 11:21:53 2010 -0500
+++ b/lib/galaxy/jobs/__init__.py Tue Feb 09 13:40:01 2010 -0500
@@ -751,7 +751,9 @@
@property
def user( self ):
job = self.sa_session.query( model.Job ).get( self.job_id )
- if job.history.user is None:
+ if not job.history:
+ return 'non_history_job'
+ elif job.history.user is None:
return 'anonymous@' + job.galaxy_session.remote_addr.split()[-1]
else:
return job.history.user.email
1
0
09 Feb '10
details: http://www.bx.psu.edu/hg/galaxy/rev/b4c811246b1d
changeset: 3360:b4c811246b1d
user: rc
date: Tue Feb 09 11:21:53 2010 -0500
description:
LIMS: replaced os.system with subprocess to spawn the data transfer daemon process
diffstat:
lib/galaxy/web/controllers/forms.py | 2 +-
lib/galaxy/web/controllers/requests_admin.py | 42 +++++++++++++++++------
scripts/galaxy_messaging/server/daemon.py | 2 +-
scripts/galaxy_messaging/server/data_transfer.py | 13 ++++--
4 files changed, 40 insertions(+), 19 deletions(-)
diffs (145 lines):
diff -r 185eab051284 -r b4c811246b1d lib/galaxy/web/controllers/forms.py
--- a/lib/galaxy/web/controllers/forms.py Tue Feb 09 04:16:26 2010 -0500
+++ b/lib/galaxy/web/controllers/forms.py Tue Feb 09 11:21:53 2010 -0500
@@ -137,7 +137,7 @@
msg=msg,
messagetype='error',
name=util.restore_text( params.get( 'name', '' ) ),
- description=util.restore_text( params.get( 'description', '' ) ) ) )
+ description=util.restore_text( params.get( 'description', '' ) ) ))
self.__get_saved_form( fd )
if self.__imported_from_file:
return trans.response.send_redirect( web.url_for( controller='forms',
diff -r 185eab051284 -r b4c811246b1d lib/galaxy/web/controllers/requests_admin.py
--- a/lib/galaxy/web/controllers/requests_admin.py Tue Feb 09 04:16:26 2010 -0500
+++ b/lib/galaxy/web/controllers/requests_admin.py Tue Feb 09 11:21:53 2010 -0500
@@ -4,7 +4,7 @@
from galaxy.datatypes import sniff
from galaxy import util
from galaxy.util.streamball import StreamBall
-import logging, tempfile, zipfile, tarfile, os, sys
+import logging, tempfile, zipfile, tarfile, os, sys, subprocess
from galaxy.web.form_builder import *
from datetime import datetime, timedelta
from galaxy.web.controllers.forms import get_all_forms
@@ -1526,31 +1526,49 @@
sample_id=trans.security.encode_id(sample.id),
messagetype='error',
msg=msg))
+ error_msg = ''
transfer_script = "scripts/galaxy_messaging/server/daemon.py"
for index, dataset in enumerate(sample.dataset_files):
dfile = dataset[0]
status = dataset[1]
if status == sample.transfer_status.NOT_STARTED:
- cmd = "python %s %s %s %s %s %s %s %s %s" % ( transfer_script,
- datatx_info['host'],
- datatx_info['username'],
- datatx_info['password'],
- dfile,
- sample.id,
- index,
- trans.security.encode_id(sample.library.id),
- trans.security.encode_id(sample.folder.id))
+ cmd = ( "python",
+ transfer_script,
+ datatx_info['host'],
+ datatx_info['username'],
+ datatx_info['password'],
+ dfile,
+ str(sample.id),
+ str(index),
+ trans.security.encode_id(sample.library.id),
+ trans.security.encode_id(sample.folder.id) )
# set the transfer status
sample.dataset_files[index][1] = sample.transfer_status.IN_PROGRESS
trans.sa_session.add( sample )
trans.sa_session.flush()
- os.system(cmd)
+ try:
+ retcode = subprocess.call(cmd)
+ except Exception, e:
+ error_msg = dfile.split('/')[-1] + ": Data transfer failed. " + str(e) + "<br/>"
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='show_datatx_page',
+ sample_id=trans.security.encode_id(sample.id),
+ folder_path=os.path.dirname(dfile),
+ messagetype='error',
+ msg=error_msg))
# set the sample state to the last state
if sample.current_state().id != sample.request.type.states[-1].id:
event = trans.app.model.SampleEvent(sample, sample.request.type.states[-1],
- 'The dataset are ready & are being transfered to Galaxy')
+ 'The dataset is ready and are being transfered to Galaxy')
trans.sa_session.add( event )
trans.sa_session.flush()
+ if error_msg:
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='show_datatx_page',
+ sample_id=trans.security.encode_id(sample.id),
+ folder_path=os.path.dirname(dfile),
+ messagetype='error',
+ msg=error_msg))
return trans.response.send_redirect( web.url_for( controller='requests_admin',
action='show_datatx_page',
sample_id=trans.security.encode_id(sample.id),
diff -r 185eab051284 -r b4c811246b1d scripts/galaxy_messaging/server/daemon.py
--- a/scripts/galaxy_messaging/server/daemon.py Tue Feb 09 04:16:26 2010 -0500
+++ b/scripts/galaxy_messaging/server/daemon.py Tue Feb 09 11:21:53 2010 -0500
@@ -29,6 +29,6 @@
sys.exit(0) # Exit first parent.
except OSError, e:
sys.stderr.write("fork #1 failed: (%d) %sn" % (e.errno, e.strerror))
- sys.exit(1)
+ sys.exit(2)
os.execv(os.path.join( os.getcwd(), "scripts/galaxy_messaging/server/data_transfer.py"), sys.argv)
diff -r 185eab051284 -r b4c811246b1d scripts/galaxy_messaging/server/data_transfer.py
--- a/scripts/galaxy_messaging/server/data_transfer.py Tue Feb 09 04:16:26 2010 -0500
+++ b/scripts/galaxy_messaging/server/data_transfer.py Tue Feb 09 11:21:53 2010 -0500
@@ -41,8 +41,8 @@
curr_dir = os.getcwd()
logfile = os.path.join(curr_dir, 'data_transfer.log')
-logging.basicConfig(filename=logfile, level=logging.DEBUG,
- format="%(asctime)s [%(levelname)s] %(message)s")
+logging.basicConfig(filename=sys.stdout, level=logging.DEBUG,
+ format="%(asctime)s [%(levelname)s] %(message)s")
class DataTransferException(Exception):
def __init__(self, value):
@@ -137,7 +137,9 @@
timeout=10)
logging.debug(output)
if not os.path.exists(os.path.join(self.server_dir, os.path.basename(self.remote_file))):
- raise Exception
+ raise DataTransferException('Could not find the local file after transfer (%s)' % os.path.join(self.server_dir, os.path.basename(self.remote_file)))
+ except DataTransferException, (e):
+ self.error_and_exit(e.msg)
except:
self.error_and_exit()
@@ -192,6 +194,8 @@
raise DataTransferException("The "+email+" user could not logout of Galaxy")
except DataTransferException, (e):
self.error_and_exit(e.msg)
+ except:
+ self.error_and_exit()
def update_status(self, status):
'''
@@ -202,7 +206,6 @@
df = from_json_string(galaxy.get_sample_dataset_files(self.sample_id))
logging.debug(df)
df[self.dataset_index][1] = status
-
galaxy.set_sample_dataset_files(self.sample_id, to_json_string(df))
logging.debug("######################\n"+str(from_json_string(galaxy.get_sample_dataset_files(self.sample_id))[self.dataset_index]))
except:
@@ -219,5 +222,5 @@
dt = DataTransfer(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4],
int(sys.argv[5]), int(sys.argv[6]), sys.argv[7], sys.argv[8])
dt.start()
+ sys.exit(0)
-
1
0
#3351 should fix this - Juan, can you please try pulling the current code to
see if it works for you?
Also, some notes on how to maintain a local code repository have also been
added to section 6 of
http://bitbucket.org/galaxy/galaxy-central/wiki/GetGalaxy - no need to do a
fresh clone each time you want to update your local copy.
Fixes and comments on the updated notes welcomed...
On Mon, Feb 8, 2010 at 12:37 PM, <galaxy-dev-request(a)lists.bx.psu.edu>wrote:
>
>
> Message: 1
> Date: Fri, 5 Feb 2010 18:13:05 -0500
> From: Kanwei Li <kanwei(a)gmail.com>
> To: Juan Perin <juanperin(a)gmail.com>, James Taylor
> <james.taylor(a)emory.edu>
> Cc: galaxy-dev(a)bx.psu.edu
> Subject: Re: [galaxy-dev] Python problems
> Message-ID:
> <1469e4b41002051513o5a21793an348c37646724cb3e(a)mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> Hi Juan,
>
> After some searching it seems that it is an issue with python2.4 and
> hashlib. We recently introduced a change that might be responsible for
> this (commit 3311) and we'll look into it.
>
> Thanks,
>
> Kanwei
>
> On Fri, Feb 5, 2010 at 12:47 PM, Juan Perin <juanperin(a)gmail.com> wrote:
> > I've been working with a much older release of galaxy for a while, and it
> > has worked great for the last few months. ?I noticed some progress with
> the
> > NGS tools, so decided to attempt updating. ?My first mistake was in not
> > knowing how to do so, so I essentially decided to start from the hg clone
> > step and rebuild galaxy entirely in a new place on the same machine. ? ?I
> > stupidly ran the database update script without listening to the warning
> > about backing up the original galaxy db. ?So, my original instance won't
> > work now...
> > So, i'm trying to get the new instance working. ?Copied over my universe
> > file and the custom .loc files from tool-data/ . ?everything seems to be
> ok,
> > however I'm getting a python error that essentially repeats for anything
> I
> > try to do, I'll paste the full output below for reference. ?I'm using
> python
> > 2.4
> > Any ideas?
> > Thanks in advance.
> > URL: http://variome.chop.edu:8082/tool_runner?tool_id=bowtie_wrapperFile
> >
> '/opt/galaxy-dist/eggs/py2.4-noplatform/WebError-0.8a-py2.4.egg/weberror/evalexception/middleware.py',
> > line 364 in respond app_iter = self.application(environ,
> > detect_start_response) File
> >
> '/opt/galaxy-dist/eggs/py2.4-noplatform/Paste-1.6-py2.4.egg/paste/debug/prints.py',
> > line 97 in __call__ status, headers, body = wsgilib.intercept_output(
> File
> >
> '/opt/galaxy-dist/eggs/py2.4-noplatform/Paste-1.6-py2.4.egg/paste/wsgilib.py',
> > line 539 in intercept_output app_iter = application(environ,
> > replacement_start_response) File
> >
> '/opt/galaxy-dist/eggs/py2.4-noplatform/Paste-1.6-py2.4.egg/paste/recursive.py',
> > line 80 in __call__ return self.application(environ, start_response) File
> >
> '/opt/galaxy-dist/eggs/py2.4-noplatform/Paste-1.6-py2.4.egg/paste/httpexceptions.py',
> > line 632 in __call__ return self.application(environ, start_response)
> File
> > '/opt/galaxy-dist/lib/galaxy/web/framework/base.py', line 125 in __call__
> > body = method( trans, **kwargs ) File
> > '/opt/galaxy-dist/lib/galaxy/web/controllers/tool_runner.py', line 61 in
> > index return trans.fill_template( template, history=history,
> > toolbox=toolbox, tool=tool, util=util, add_frame=add_frame, **vars ) File
> > '/opt/galaxy-dist/lib/galaxy/web/framework/__init__.py', line 602 in
> > fill_template return self.fill_template_mako( filename, **kwargs ) File
> > '/opt/galaxy-dist/lib/galaxy/web/framework/__init__.py', line 613 in
> > fill_template_mako return template.render( **data ) File
> >
> '/opt/galaxy-dist/eggs/py2.4-noplatform/Mako-0.2.5-py2.4.egg/mako/template.py',
> > line 133 in render return runtime._render(self, self.callable_, args,
> data)
> > File
> >
> '/opt/galaxy-dist/eggs/py2.4-noplatform/Mako-0.2.5-py2.4.egg/mako/runtime.py',
> > line 364 in _render _render_context(template, callable_, context, *args,
> > **_kwargs_for_callable(callable_, data)) File
> >
> '/opt/galaxy-dist/eggs/py2.4-noplatform/Mako-0.2.5-py2.4.egg/mako/runtime.py',
> > line 381 in _render_context _exec_template(inherit, lclcontext,
> args=args,
> > kwargs=kwargs) File
> >
> '/opt/galaxy-dist/eggs/py2.4-noplatform/Mako-0.2.5-py2.4.egg/mako/runtime.py',
> > line 414 in _exec_template callable_(context, *args, **kwargs) File
> > '/opt/galaxy-dist/database/compiled_templates/tool_form.mako.py', line
> 103
> > in render_body __M_writer(unicode(util.object_to_string(
> tool_state.encode(
> > tool, app ) ))) File '/opt/galaxy-dist/lib/galaxy/tools/__init__.py',
> line
> > 216 in encode a = hmac_new( app.config.tool_secret, value ) File
> > '/opt/galaxy-dist/lib/galaxy/util/hash_util.py', line 33 in hmac_new
> return
> > hmac.new( key, value, sha1 ).hexdigest() File
> > '/usr/lib64/python2.4/hmac.py', line 107 in new return HMAC(key, msg,
> > digestmod) File '/usr/lib64/python2.4/hmac.py', line 42 in __init__
> > self.outer = digestmod.new() AttributeError: 'builtin_function_or_method'
> > object has no attribute 'new'
>
1
0
09 Feb '10
details: http://www.bx.psu.edu/hg/galaxy/rev/185eab051284
changeset: 3359:185eab051284
user: James Taylor <james(a)jamestaylor.org>
date: Tue Feb 09 04:16:26 2010 -0500
description:
Update tooltips using a modified version of tipsy, these can be used on any page if you include the tipsy script. Also, updating some styles and icons for tags.
diffstat:
static/images/fugue/tag--plus.png | 0
static/images/fugue/tags.png | 0
static/images/tipsy.gif | 0
static/june_2007_style/autocomplete_tagging.css.tmpl | 6 +-
static/june_2007_style/base.css.tmpl | 58 ++++--
static/june_2007_style/blue/autocomplete_tagging.css | 4 +-
static/june_2007_style/blue/base.css | 29 ++-
static/june_2007_style/blue/history-buttons.png | 0
static/scripts/galaxy.base.js | 10 +-
static/scripts/jquery.tipsy.js | 161 +++++++++++++++++++
static/scripts/packed/galaxy.base.js | 2 +-
static/scripts/packed/jquery.tipsy.js | 1 +
templates/root/history.mako | 44 ++--
templates/tagging_common.mako | 5 +-
14 files changed, 256 insertions(+), 64 deletions(-)
diffs (492 lines):
diff -r b36c13131ac7 -r 185eab051284 static/images/fugue/tag--plus.png
Binary file static/images/fugue/tag--plus.png has changed
diff -r b36c13131ac7 -r 185eab051284 static/images/fugue/tags.png
Binary file static/images/fugue/tags.png has changed
diff -r b36c13131ac7 -r 185eab051284 static/images/tipsy.gif
Binary file static/images/tipsy.gif has changed
diff -r b36c13131ac7 -r 185eab051284 static/june_2007_style/autocomplete_tagging.css.tmpl
--- a/static/june_2007_style/autocomplete_tagging.css.tmpl Mon Feb 08 23:52:56 2010 -0500
+++ b/static/june_2007_style/autocomplete_tagging.css.tmpl Tue Feb 09 04:16:26 2010 -0500
@@ -94,12 +94,12 @@
display: inline-block;
cursor: pointer;
margin: 0.2em;
- border: 0;
+ border: solid #bbb 1px;
padding: 0.1em 0.5em 0.1em 0.5em;
-moz-border-radius: .5em;
-webkit-border-radius: .5em;
border-radius: .5em;
- background:#bbb;
+ background:#eee;
}
.tag-button img
@@ -109,7 +109,7 @@
.tag-button .tag-name:hover
{
- color: white;
+ color: black;
}
.add-tag-button
diff -r b36c13131ac7 -r 185eab051284 static/june_2007_style/base.css.tmpl
--- a/static/june_2007_style/base.css.tmpl Mon Feb 08 23:52:56 2010 -0500
+++ b/static/june_2007_style/base.css.tmpl Tue Feb 09 04:16:26 2010 -0500
@@ -667,6 +667,9 @@
margin-left: 2px;
## Allow alt text for screen readers
text-indent: 20px;
+ background-repeat:no-repeat;
+ background-position: 0px 0px;
+ padding: 0;
}
.icon-button.display {
@@ -700,38 +703,53 @@
}
.icon-button.tag {
- background-image:url(/static/images/tag-label.png);
- background-repeat:no-repeat;
- background-position:center;
- padding: 0px 0px 0px 0px;
+ background-image: url(/static/images/tag-label.png);
+}
+
+.icon-button.tags {
+ background-image: url(/static/images/fugue/tags.png);
+}
+
+.icon-button.tag--plus {
+ background-image: url(/static/images/fugue/tag--plus.png);
}
.icon-button.annotate {
background-image:url(/static/images/sticky-note-text.png);
background-repeat:no-repeat;
background-position:center;
- padding: 0px 0px 0px 0px;
+ padding: 0;
}
-.tooltip {
- position: relative;
- cursor: pointer;
+.tipsy {
+ padding: 5px;
+ font-size: 10px;
+ filter: alpha(opacity=80);
+ background-repeat: no-repeat;
+ background-image: url(../images/tipsy.gif);
+}
+.tipsy-inner {
+ padding: 5px 8px 4px 8px;
+ background-color: black;
+ color: white;
+ max-width: 200px;
+ text-align: center;
}
-span.tip {
- display: none
+.tipsy-north {
+ background-position: top center;
}
-.tooltip:hover span.tip {
- font-size: 90%;
- display: block;
- position: absolute;
- left:2em;
- bottom:1.75em;
- background-color: black;
- color: white;
- text-align: center;
- padding: 0.25em 0.5em;
+.tipsy-south {
+ background-position: bottom center;
+}
+
+.tipsy-east {
+ background-position: right center;
+}
+
+.tipsy-west {
+ background-position: left center;
}
.editable-text {
diff -r b36c13131ac7 -r 185eab051284 static/june_2007_style/blue/autocomplete_tagging.css
--- a/static/june_2007_style/blue/autocomplete_tagging.css Mon Feb 08 23:52:56 2010 -0500
+++ b/static/june_2007_style/blue/autocomplete_tagging.css Tue Feb 09 04:16:26 2010 -0500
@@ -10,9 +10,9 @@
.individual-tag-area{border:solid 1px #eee;cursor:pointer;}
.active-tag-area{background-color:white;}
.toggle-link{font-weight:normal;padding:0.3em;margin-bottom:1em;width:100%;padding:0.2em 0em 0.2em 0em;}
-.tag-button{width:auto;color:#444;text-decoration:none;display:inline-block;cursor:pointer;margin:0.2em;border:0;padding:0.1em 0.5em 0.1em 0.5em;-moz-border-radius:.5em;-webkit-border-radius:.5em;border-radius:.5em;background:#bbb;}
+.tag-button{width:auto;color:#444;text-decoration:none;display:inline-block;cursor:pointer;margin:0.2em;border:solid #bbb 1px;padding:0.1em 0.5em 0.1em 0.5em;-moz-border-radius:.5em;-webkit-border-radius:.5em;border-radius:.5em;background:#eee;}
.tag-button img{padding-left:0.4em;}
-.tag-button .tag-name:hover{color:white;}
+.tag-button .tag-name:hover{color:black;}
.add-tag-button{margin-bottom:0.3em;vertical-align:middle;padding:0.3em;}
.add-tag-button:hover{cursor:pointer;}
.tag-input{vertical-align:bottom;border:none;outline:none;resize:none;}
diff -r b36c13131ac7 -r 185eab051284 static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css Mon Feb 08 23:52:56 2010 -0500
+++ b/static/june_2007_style/blue/base.css Tue Feb 09 04:16:26 2010 -0500
@@ -110,17 +110,22 @@
.text-content fieldset{border-color:#ccc;border:1px solid #ccc;}
.text-content th,.text-content td{border-bottom:1px solid #ddd;border-right:1px solid #ccc;}
.text-content th,.text-content td{padding:.8em;}
-.icon-button{width:16px;height:16px;display:block;float:left;margin-left:2px;text-indent:20px;}
-.icon-button.edit{background:url(history-buttons.png) no-repeat 0px -52px;}
-.icon-button.edit:hover{background:url(history-buttons.png) no-repeat 0px -78px;}
+.icon-button{width:16px;height:16px;display:block;float:left;margin-left:2px;text-indent:20px;background-repeat:no-repeat;background-position:0px 0px;padding:0;}
.icon-button.display{background:url(history-buttons.png) no-repeat 0px -0px;}
.icon-button.display:hover{background:url(history-buttons.png) no-repeat 0px -26px;}
-.icon-button.delete{background:url(history-buttons.png) no-repeat 0px -104px;}
-.icon-button.delete:hover{background:url(history-buttons.png) no-repeat 0px -130px;}
-.icon-button.tag{background-image:url(/static/images/tag-label.png);background-repeat:no-repeat;background-position:center;padding: 0px 0px 0px 0px;}
-.icon-button.annotate{background-image:url(/static/images/sticky-note-text.png);background-repeat:no-repeat;background-position:center;padding: 0px 0px 0px 0px;}
-.tooltip {position: relative; cursor: pointer}
-span.tip{display: none;}
-.tooltip:hover span.tip{font-size: 90%; display: block;position: absolute;left:3em;bottom:1.75em; background-color: black;color: white;text-align: center;padding: 0.25em 0.5em;}
-.editable-text{cursor:pointer}
-.editable-text:hover{background-image:url();background-repeat:no-repeat;background-position:right}
\ No newline at end of file
+.icon-button.delete{background:url(history-buttons.png) no-repeat 0px -52px;}
+.icon-button.delete:hover{background:url(history-buttons.png) no-repeat 0px -78px;}
+.icon-button.edit{background:url(history-buttons.png) no-repeat 0px -104px;}
+.icon-button.edit:hover{background:url(history-buttons.png) no-repeat 0px -130px;}
+.icon-button.tag{background-image:url(/static/images/tag-label.png);}
+.icon-button.tags{background-image:url(/static/images/fugue/tags.png);}
+.icon-button.tag--plus{background-image:url(/static/images/fugue/tag--plus.png);}
+.icon-button.annotate{background-image:url(/static/images/sticky-note-text.png);background-repeat:no-repeat;background-position:center;padding:0;}
+.tipsy{padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);}
+.tipsy-inner{padding:5px 8px 4px 8px;background-color:black;color:white;max-width:200px;text-align:center;}
+.tipsy-north{background-position:top center;}
+.tipsy-south{background-position:bottom center;}
+.tipsy-east{background-position:right center;}
+.tipsy-west{background-position:left center;}
+.editable-text{cursor:pointer;}
+.editable-text:hover{background-image:url();background-repeat:no-repeat;background-position:right;}
diff -r b36c13131ac7 -r 185eab051284 static/june_2007_style/blue/history-buttons.png
Binary file static/june_2007_style/blue/history-buttons.png has changed
diff -r b36c13131ac7 -r 185eab051284 static/scripts/galaxy.base.js
--- a/static/scripts/galaxy.base.js Mon Feb 08 23:52:56 2010 -0500
+++ b/static/scripts/galaxy.base.js Tue Feb 09 04:16:26 2010 -0500
@@ -14,11 +14,15 @@
});
}
-jQuery(document).ready( function() {
+$(document).ready( function() {
// Links with confirmation
- jQuery( "a[confirm]" ).click( function() {
- return confirm( jQuery(this).attr( "confirm" ) )
+ $( "a[confirm]" ).click( function() {
+ return confirm( $(this).attr( "confirm" ) )
});
+ // Tooltips
+ if ( $.fn.tipsy ) {
+ $(".tooltip").tipsy( { gravity: 's' } );
+ }
// Make popup menus.
make_popup_menus();
});
diff -r b36c13131ac7 -r 185eab051284 static/scripts/jquery.tipsy.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/static/scripts/jquery.tipsy.js Tue Feb 09 04:16:26 2010 -0500
@@ -0,0 +1,161 @@
+(function($) {
+ function fixTitle($ele) {
+ if ($ele.attr('title') || typeof($ele.attr('original-title')) != 'string') {
+ $ele.attr('original-title', $ele.attr('title') || '').removeAttr('title');
+ }
+ }
+
+ $.fn.tipsy = function(options) {
+
+ options = $.extend({}, $.fn.tipsy.defaults, options);
+
+ return this.each(function() {
+
+ fixTitle($(this));
+ var opts = $.fn.tipsy.elementOptions(this, options);
+ var timeout = null;
+
+ $(this).hover(function() {
+ var self = this;
+ timeout = setTimeout(function() {
+ $.data(self, 'cancel.tipsy', true);
+
+ var tip = $.data(self, 'active.tipsy');
+ if (!tip) {
+ tip = $('<div class="tipsy"><div class="tipsy-inner"/></div>');
+ tip.css({position: 'absolute', zIndex: 100000});
+ $.data(self, 'active.tipsy', tip);
+ }
+
+ fixTitle($(self));
+
+ var title;
+ if (typeof opts.title == 'string') {
+ title = $(self).attr(opts.title == 'title' ? 'original-title' : opts.title);
+ } else if (typeof opts.title == 'function') {
+ title = opts.title.call(self);
+ }
+
+ tip.find('.tipsy-inner')[opts.html ? 'html' : 'text'](title || opts.fallback);
+
+
+ var pos = $.extend({}, $(self).offset(), {width: self.offsetWidth, height: self.offsetHeight});
+ tip.get(0).className = 'tipsy'; // reset classname in case of dynamic gravity
+ tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
+
+ tip.css( { width: tip.width() + 1, height: tip.height() } );
+
+ var actualWidth = tip[0].offsetWidth, actualHeight = tip[0].offsetHeight;
+ var gravity = (typeof opts.gravity == 'function') ? opts.gravity.call(self) : opts.gravity;
+
+ var top, left;
+ switch (gravity.charAt(0)) {
+ case 'n':
+ top = pos.top + pos.height;
+ left = pos.left + pos.width / 2 - actualWidth / 2;
+ tip.addClass('tipsy-north');
+ break;
+ case 's':
+ top = pos.top - actualHeight;
+ left = pos.left + pos.width / 2 - actualWidth / 2;
+ tip.addClass('tipsy-south');
+ break;
+ case 'e':
+ top = pos.top + pos.height / 2 - actualHeight / 2;
+ left = pos.left - actualWidth;
+ tip.addClass('tipsy-east');
+ break;
+ case 'w':
+ top = pos.top + pos.height / 2 - actualHeight / 2;
+ left = pos.left + pos.width;
+ tip.addClass('tipsy-west');
+ break;
+ }
+ // Shift if off screen
+ var window = $(window);
+
+ top = Math.max( top, window.scrollTop() );
+ top = Math.min( top, window.scrollTop() + window.height() - tip.outerHeight() );
+
+ var left_shift = 0;
+ if ( left < window.scrollLeft() ) {
+ left_shift = left - window.scrollLeft();
+ }
+ var t = window.scrollLeft() + window.width() - tip.outerWidth();
+ if ( left > t ) {
+ left_shift = left - t;
+ }
+
+ left -= left_shift;
+
+ tip.css( { left: left, top: top } );
+
+ // Shift background to center over element (not implemented for east/west)
+ switch (gravity.charAt(0)) {
+ case 'n':
+ tip.css( 'background-position', - ( 250 - tip.outerWidth() / 2 ) + left_shift + "px top" );
+ break;
+ case 's':
+ tip.css( 'background-position', - ( 250 - tip.outerWidth() / 2 ) + left_shift + "px bottom" );
+ break;
+ case 'e':
+ break;
+ case 'w':
+ break;
+ }
+
+ if (opts.fade) {
+ tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: opts.opacity});
+ } else {
+ tip.css({visibility: 'visible', opacity: opts.opacity});
+ }
+ }, opts.delayIn);
+
+ }, function() {
+ $.data(this, 'cancel.tipsy', false);
+ var self = this;
+ clearTimeout(timeout);
+ setTimeout(function() {
+ if ($.data(this, 'cancel.tipsy')) { return; }
+ var tip = $.data(self, 'active.tipsy');
+ if (opts.fade) {
+ tip.stop().fadeOut(function() { $(this).remove(); });
+ } else if (tip) {
+ tip.remove();
+ }
+ }, opts.delayOut);
+
+ });
+
+ });
+
+ };
+
+ // Overwrite this method to provide options on a per-element basis.
+ // For example, you could store the gravity in a 'tipsy-gravity' attribute:
+ // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
+ // (remember - do not modify 'options' in place!)
+ $.fn.tipsy.elementOptions = function(ele, options) {
+ return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
+ };
+
+ $.fn.tipsy.defaults = {
+ delayIn: 0,
+ delayOut: 100,
+ fade: false,
+ fallback: '',
+ gravity: 'n',
+ html: false,
+ opacity: 0.8,
+ title: 'title'
+ };
+
+ $.fn.tipsy.autoNS = function() {
+ return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
+ };
+
+ $.fn.tipsy.autoWE = function() {
+ return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
+ };
+
+})(jQuery);
diff -r b36c13131ac7 -r 185eab051284 static/scripts/packed/galaxy.base.js
--- a/static/scripts/packed/galaxy.base.js Mon Feb 08 23:52:56 2010 -0500
+++ b/static/scripts/packed/galaxy.base.js Tue Feb 09 04:16:26 2010 -0500
@@ -1,1 +1,1 @@
-$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};jQuery(document).ready(function(){jQuery("a[confirm]").click(function(){return confirm(jQuery(this).attr("confirm"))});make_popup_menus()});function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var c={};$(this).find("a").each(function(){var b=$(this).attr("confirm"),d=$(this).attr("href"),e=$(this).attr("target");c[$(this).text()]=function(){if(!b||confirm(b)){var g=window;if(e=="_parent"){g=window.parent}else{if(e=="_top"){g=window.top}}g.location=d}}});var a=$("#"+$(this).attr("popupmenu"));make_popupmenu(a,c);$(this).remove();a.addClass("popup").show()})}function ensure_popup_helper(){if($("#popup-helper").length==0){$("<div id='popup-helper'/>").css({background:"white",opacity:0,zIndex:15000,position:"absolute",t
op:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function make_popupmenu(d,c){ensure_popup_helper();var a=$(d);var b=$("<ul id='"+d.attr("id")+"-menu'></ul>");$.each(c,function(g,f){if(f){$("<li/>").html(g).click(f).appendTo(b)}else{$("<li class='head'/>").html(g).appendTo(b)}});var e=$("<div class='popmenu-wrapper'>");e.append(b).append("<div class='overlay-border'>").css("position","absolute").appendTo("body").hide();attach_popupmenu(d,e)}function attach_popupmenu(b,d){var a=function(){d.unbind().hide();$("#popup-helper").unbind("click.popupmenu").hide()};var c=function(g){var h=$(b).offset();$("#popup-helper").bind("click.popupmenu",a).show();d.click(a).css({left:0,top:-1000}).show();var f=g.pageX-d.width()/2;f=Math.min(f,$(document).scrollLeft()+$(window).width()-$(d).width()-20);f=Math.max(f,$(document).scrollLeft()+20);d.css({top:g.pageY-5,left:f});return false};$(b).click(c)}var array_length=function(a){if(a.length){return a.length}var b=0;for(element
in a){b++}return b};var replace_dbkey_select=function(){var c=$("select[name=dbkey]");var d=c.attr("value");if(c.length!=0){var e=$("<input id='dbkey-input' type='text'></input>");e.attr("size",40);e.attr("name",c.attr("name"));e.click(function(){var g=$(this).attr("value");$(this).attr("value","Loading...");$(this).showAllInCache();$(this).attr("value",g);$(this).select()});var b=new Array();var a=new Object();c.children("option").each(function(){var h=$(this).text();var g=$(this).attr("value");if(g=="?"){return}b.push(h);a[h]=g;if(g==d){e.attr("value",h)}});if(e.attr("value")==""){e.attr("value","Click to Search or Select Build")}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:1000,minChars:0,hideForLessThanMinChars:false};e.autocomplete(b,f);c.replaceWith(e);$("form").submit(function(){var i=$("#dbkey-input");if(i.length!=0){var h=i.attr("value");var g=a[h];if(g!=null&&g!=undefined){i.attr("value",g)}else{if(d!=""){i.attr("value",d)}else{i.
attr("value","?")}}}})}};function async_save_text(d,f,e,a,c,h,i,g,b){if(c==null){c=30}if(i==null){i=4}$("#"+d).click(function(){var l=$("#"+f).text();if(h){var j=$("<textarea rows='"+i+"' cols='"+c+"'>"+l+"</textarea>")}else{var j=$("<input type='text' value='"+l+"' size='"+c+"'></input>")}j.blur(function(){$(this).remove();$("#"+f).show();if(m){k.addClass("tooltip")}if(b!=null){b(j)}});var m=$(this).hasClass("tooltip");var k=$(this);j.keyup(function(o){if(o.keyCode==27){$(this).trigger("blur")}else{if(o.keyCode==13){new_text=this.value;$(this).trigger("blur");var n=new Object();n[a]=new_text;$.ajax({url:e,data:n,error:function(){alert("Text editing for elt "+f+" failed")},success:function(p){$("#"+f).text(p);if(b!=null){b(j)}}})}}});if(g!=null){g(j)}$("#"+f).hide();j.insertAfter($("#"+f));j.focus();j.select();$(this).removeClass("tooltip");return false})};
\ No newline at end of file
+$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};$(document).ready(function(){$("a[confirm]").click(function(){return confirm($(this).attr("confirm"))});if($.fn.tipsy){$(".tooltip").tipsy({gravity:"s"})}make_popup_menus()});function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var c={};$(this).find("a").each(function(){var b=$(this).attr("confirm"),d=$(this).attr("href"),e=$(this).attr("target");c[$(this).text()]=function(){if(!b||confirm(b)){var g=window;if(e=="_parent"){g=window.parent}else{if(e=="_top"){g=window.top}}g.location=d}}});var a=$("#"+$(this).attr("popupmenu"));make_popupmenu(a,c);$(this).remove();a.addClass("popup").show()})}function ensure_popup_helper(){if($("#popup-helper").length==0){$("<div id='popup-helper'/>").css({background:"white",opacity:0
,zIndex:15000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function make_popupmenu(d,c){ensure_popup_helper();var a=$(d);var b=$("<ul id='"+d.attr("id")+"-menu'></ul>");$.each(c,function(g,f){if(f){$("<li/>").html(g).click(f).appendTo(b)}else{$("<li class='head'/>").html(g).appendTo(b)}});var e=$("<div class='popmenu-wrapper'>");e.append(b).append("<div class='overlay-border'>").css("position","absolute").appendTo("body").hide();attach_popupmenu(d,e)}function attach_popupmenu(b,d){var a=function(){d.unbind().hide();$("#popup-helper").unbind("click.popupmenu").hide()};var c=function(g){var h=$(b).offset();$("#popup-helper").bind("click.popupmenu",a).show();d.click(a).css({left:0,top:-1000}).show();var f=g.pageX-d.width()/2;f=Math.min(f,$(document).scrollLeft()+$(window).width()-$(d).width()-20);f=Math.max(f,$(document).scrollLeft()+20);d.css({top:g.pageY-5,left:f});return false};$(b).click(c)}var array_length=function(a){if(a.length){
return a.length}var b=0;for(element in a){b++}return b};var replace_dbkey_select=function(){var c=$("select[name=dbkey]");var d=c.attr("value");if(c.length!=0){var e=$("<input id='dbkey-input' type='text'></input>");e.attr("size",40);e.attr("name",c.attr("name"));e.click(function(){var g=$(this).attr("value");$(this).attr("value","Loading...");$(this).showAllInCache();$(this).attr("value",g);$(this).select()});var b=new Array();var a=new Object();c.children("option").each(function(){var h=$(this).text();var g=$(this).attr("value");if(g=="?"){return}b.push(h);a[h]=g;if(g==d){e.attr("value",h)}});if(e.attr("value")==""){e.attr("value","Click to Search or Select Build")}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:1000,minChars:0,hideForLessThanMinChars:false};e.autocomplete(b,f);c.replaceWith(e);$("form").submit(function(){var i=$("#dbkey-input");if(i.length!=0){var h=i.attr("value");var g=a[h];if(g!=null&&g!=undefined){i.attr("value",g)}else{
if(d!=""){i.attr("value",d)}else{i.attr("value","?")}}}})}};function async_save_text(d,f,e,a,c,h,i,g,b){if(c==null){c=30}if(i==null){i=4}$("#"+d).click(function(){var l=$("#"+f).text();if(h){var j=$("<textarea rows='"+i+"' cols='"+c+"'>"+l+"</textarea>")}else{var j=$("<input type='text' value='"+l+"' size='"+c+"'></input>")}j.blur(function(){$(this).remove();$("#"+f).show();if(m){k.addClass("tooltip")}if(b!=null){b(j)}});var m=$(this).hasClass("tooltip");var k=$(this);j.keyup(function(o){if(o.keyCode==27){$(this).trigger("blur")}else{if(o.keyCode==13){new_text=this.value;$(this).trigger("blur");var n=new Object();n[a]=new_text;$.ajax({url:e,data:n,error:function(){alert("Text editing for elt "+f+" failed")},success:function(p){$("#"+f).text(p);if(b!=null){b(j)}}})}}});if(g!=null){g(j)}$("#"+f).hide();j.insertAfter($("#"+f));j.focus();j.select();$(this).removeClass("tooltip");return false})};
\ No newline at end of file
diff -r b36c13131ac7 -r 185eab051284 static/scripts/packed/jquery.tipsy.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/static/scripts/packed/jquery.tipsy.js Tue Feb 09 04:16:26 2010 -0500
@@ -0,0 +1,1 @@
+(function(b){function a(c){if(c.attr("title")||typeof(c.attr("original-title"))!="string"){c.attr("original-title",c.attr("title")||"").removeAttr("title")}}b.fn.tipsy=function(c){c=b.extend({},b.fn.tipsy.defaults,c);return this.each(function(){a(b(this));var d=b.fn.tipsy.elementOptions(this,c);var e=null;b(this).hover(function(){var f=this;e=setTimeout(function(){b.data(f,"cancel.tipsy",true);var o=b.data(f,"active.tipsy");if(!o){o=b('<div class="tipsy"><div class="tipsy-inner"/></div>');o.css({position:"absolute",zIndex:100000});b.data(f,"active.tipsy",o)}a(b(f));var n;if(typeof d.title=="string"){n=b(f).attr(d.title=="title"?"original-title":d.title)}else{if(typeof d.title=="function"){n=d.title.call(f)}}o.find(".tipsy-inner")[d.html?"html":"text"](n||d.fallback);var l=b.extend({},b(f).offset(),{width:f.offsetWidth,height:f.offsetHeight});o.get(0).className="tipsy";o.remove().css({top:0,left:0,visibility:"hidden",display:"block"}).appendTo(document.body);o.css({width:o.wi
dth()+1,height:o.height()});var h=o[0].offsetWidth,j=o[0].offsetHeight;var q=(typeof d.gravity=="function")?d.gravity.call(f):d.gravity;var m,i;switch(q.charAt(0)){case"n":m=l.top+l.height;i=l.left+l.width/2-h/2;o.addClass("tipsy-north");break;case"s":m=l.top-j;i=l.left+l.width/2-h/2;o.addClass("tipsy-south");break;case"e":m=l.top+l.height/2-j/2;i=l.left-h;o.addClass("tipsy-east");break;case"w":m=l.top+l.height/2-j/2;i=l.left+l.width;o.addClass("tipsy-west");break}var k=b(k);m=Math.max(m,k.scrollTop());m=Math.min(m,k.scrollTop()+k.height()-o.outerHeight());var g=0;if(i<k.scrollLeft()){g=i-k.scrollLeft()}var p=k.scrollLeft()+k.width()-o.outerWidth();if(i>p){g=i-p}i-=g;o.css({left:i,top:m});switch(q.charAt(0)){case"n":o.css("background-position",-(250-o.outerWidth()/2)+g+"px top");break;case"s":o.css("background-position",-(250-o.outerWidth()/2)+g+"px bottom");break;case"e":break;case"w":break}if(d.fade){o.stop().css({opacity:0,display:"block",visibility:"visible"}).animate({o
pacity:d.opacity})}else{o.css({visibility:"visible",opacity:d.opacity})}},d.delayIn)},function(){b.data(this,"cancel.tipsy",false);var f=this;clearTimeout(e);setTimeout(function(){if(b.data(this,"cancel.tipsy")){return}var g=b.data(f,"active.tipsy");if(d.fade){g.stop().fadeOut(function(){b(this).remove()})}else{if(g){g.remove()}}},d.delayOut)})})};b.fn.tipsy.elementOptions=function(d,c){return b.metadata?b.extend({},c,b(d).metadata()):c};b.fn.tipsy.defaults={delayIn:0,delayOut:100,fade:false,fallback:"",gravity:"n",html:false,opacity:0.8,title:"title"};b.fn.tipsy.autoNS=function(){return b(this).offset().top>(b(document).scrollTop()+b(window).height()/2)?"s":"n"};b.fn.tipsy.autoWE=function(){return b(this).offset().left>(b(document).scrollLeft()+b(window).width()/2)?"e":"w"}})(jQuery);
\ No newline at end of file
diff -r b36c13131ac7 -r 185eab051284 templates/root/history.mako
--- a/templates/root/history.mako Mon Feb 08 23:52:56 2010 -0500
+++ b/templates/root/history.mako Tue Feb 09 04:16:26 2010 -0500
@@ -15,7 +15,7 @@
<meta http-equiv="Pragma" content="no-cache">
${h.css( "base", "history", "autocomplete_tagging" )}
-${h.js( "galaxy.base", "jquery", "json2", "jquery.jstore-all", "jquery.autocomplete", "autocomplete_tagging" )}
+${h.js( "jquery", "jquery.tipsy", "galaxy.base", "json2", "jquery.jstore-all", "jquery.autocomplete", "autocomplete_tagging" )}
<script type="text/javascript">
$(function() {
@@ -46,15 +46,25 @@
async_save_text("history-name-container", "history-name", "${h.url_for( controller="/history", action="rename_async", id=trans.security.encode_id(history.id) )}", "new_name", 18);
// Tag management.
+ var historyTagArea = $('#history-tag-area');
$('#history-tag').click( function()
{
- $('#history-tag-area').toggle("fast");
+ if ( historyTagArea.is( ":hidden" ) ) {
+ historyTagArea.slideDown("fast");
+ } else {
+ historyTagArea.slideUp("fast");
+ }
return false;
});
- // Annotation management.
+ // Annotation management.
+ var historyAnnotationArea = $('#history-annotation-area');
$('#history-annotate').click( function() {
- $('#history-annotation-area').toggle("fast");
+ if ( historyAnnotationArea.is( ":hidden" ) ) {
+ historyAnnotationArea.slideDown("fast");
+ } else {
+ historyAnnotationArea.slideUp("fast");
+ }
return false;
});
async_save_text("history-annotation-container", "history-annotation", "${h.url_for( controller="/history", action="annotate_async", id=trans.security.encode_id(history.id) )}", "new_annotation", 18, true, 4);
@@ -281,15 +291,14 @@
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td align="left">
- <div id="history-name-container" class="editable-text tooltip">
- <span id="history-name">${history.get_display_name() | h}</span>
- <span class="tip">Click to edit</span></a>
+ <div id="history-name-container" class="editable-text">
+ <span id="history-name" class="tooltip" title="Click to rename history">${history.get_display_name() | h}</span>
</div>
</td>
<td align="right" style="width: 40px">
<div style="float: right; white-space: nowrap">
- <a id="history-tag" title="Tag" class="icon-button tag tooltip" target="galaxy_main" href="${h.url_for( controller='history', action='tag' )}"></a>
- <a id="history-annotate" title="Annotate" class="icon-button annotate" target="galaxy_main" href="${h.url_for( controller='history', action='annotate' )}"></a>
+ <a id="history-tag" title="Edit history tags" class="icon-button tags tooltip" target="galaxy_main" href="${h.url_for( controller='history', action='tag' )}"></a>
+ <a id="history-annotate" title="Edit history annotation" class="icon-button annotate tooltip" target="galaxy_main" href="${h.url_for( controller='history', action='annotate' )}"></a>
</div>
</td>
</tr>
@@ -309,8 +318,8 @@
%if trans.get_user() is not None:
<div style="margin: 0px 0px 5px 10px">
## Tagging elt.
- <div id="history-tag-area" class="form-row" style="display: none">
- <label>Tags:</label>
+ <div id="history-tag-area" style="display: none">
+ <b>Tags:</b>
<style>
.tag-area {
border: none;
@@ -320,15 +329,10 @@
</div>
## Annotation elt.
- <div id="history-annotation-area" class="form-row" style="display: none">
- <label>Annotation / Notes:</label>
- <div id="history-annotation-container" class="tooltip">
- %if annotation:
- <span id="history-annotation">${annotation | h}</span>
- %else:
- <span id="history-annotation">None</span>
- %endif
- <span class="tip">Click to edit annotation</span>
+ <div id="history-annotation-area" style="display: none">
+ <b>Annotation / Notes:</b>
+ <div id="history-annotation-container">
+ <span id="history-annotation" class="tooltip" title="Click to edit annotation">${annotation or 'None' | h}</span>
</div>
</div>
diff -r b36c13131ac7 -r 185eab051284 templates/tagging_common.mako
--- a/templates/tagging_common.mako Mon Feb 08 23:52:56 2010 -0500
+++ b/templates/tagging_common.mako Tue Feb 09 04:16:26 2010 -0500
@@ -37,7 +37,7 @@
%if use_toggle_link:
<a class="toggle-link" href="#">${num_tags} Tag${iff( num_tags == 1, "", "s")}</a>
%endif
- <div class="tag-area tooltip
+ <div class="tag-area
%if tag_type == 'individual':
individual-tag-area
%endif
@@ -80,9 +80,8 @@
%endif
## Add "add tag" button.
%if render_add_tag_button:
- <img src='${h.url_for('/static/images/add_icon.png')}' rollover='${h.url_for('/static/images/add_icon_dark.png')}' class="add-tag-button"/>
+ <img src='${h.url_for('/static/images/fugue/tag--plus.png')}' class="add-tag-button tooltip" title="Add tags"/>
%endif
- <span class="tip">Click to edit tags</span>
%endif
</div>
</div>
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/b36c13131ac7
changeset: 3358:b36c13131ac7
user: Kelly Vincent <kpvincent(a)bx.psu.edu>
date: Mon Feb 08 23:52:56 2010 -0500
description:
Initial version of DNA code filter tool
diffstat:
test-data/dna_filter_in1.bed | 49 ++++++++++
test-data/dna_filter_out1.bed | 4 +
test-data/dna_filter_out2.bed | 39 ++++++++
test-data/dna_filter_out3.bed | 41 ++++++++
test-data/dna_filter_out4.bed | 24 +++++
tool_conf.xml.sample | 1 +
tools/stats/dna_filtering.py | 195 ++++++++++++++++++++++++++++++++++++++++++
tools/stats/dna_filtering.xml | 114 ++++++++++++++++++++++++
8 files changed, 467 insertions(+), 0 deletions(-)
diffs (506 lines):
diff -r dedb7be9aa44 -r b36c13131ac7 test-data/dna_filter_in1.bed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dna_filter_in1.bed Mon Feb 08 23:52:56 2010 -0500
@@ -0,0 +1,49 @@
+chr1 256 257 A N M N - M N U N N A N D N G N N K N N N
+chr1 468 469 C C C N M N N K . N C U N H N G N N M N S
+chr1 582 583 G G G N G R N R N - N M N V K N N N G C R
+chr1 602 603 G G G N G N Y N R G G N N U N T N A K N R
+chr1 4792 4793 A A M K N W S S N N Y N N N N N M R N R N
+chr1 6119 6120 G G M N S N N W B N S D N N H V N B W N N
+chr1 6357 6358 G G N M K N G - N N G U N N N B N N K N S
+chr1 6433 6434 G G N R N N C N N N . N N . N N N N N R N
+chr1 39160 39161 T T T N N Y N - N N N N N N N V N N N N Y
+chr1 41920 41921 G C G N M C G N A N G N K N W S N N N V N
+chr1 42100 42101 T T T Y R W N N N V N M R N N G N M Y N K
+chr1 45026 45027 C A C N N Y N S Y N N X N A D N N K N N A
+chr1 45161 45162 C T C . N X H V N N C R N Y N N N N R N Y
+chr2 45407 45408 C N C S B N N N N N C N Y N N T K G N C N
+chr2 45788 45789 T T T N W S N Y N R Y N S N W M N C T N C
+chr2 46243 46244 T T T N W N N B V N U N T N N Y C N U N N
+chr2 47814 47815 A C A S N X D N N H W N G N Y C N N M R N
+chr2 48073 48074 A G A Y W . N K N N N G N N N G N N N Y N
+chr2 48633 48634 T T T N G N N N . N N N N S N Y N . N N N
+chr2 51304 51305 A G N N C N W - N S Y N . N N G N N N W R
+chr2 51324 51325 T T N R N N N N N - N U N W A N N N N N N
+chr2 52065 52066 T C T N N N S N . N T N M N S W N T Y C N
+chr2 53130 53131 T C T K R . N B N N T N N M N Y N N Y N N
+chr2 53505 53506 A A A M N N Y N N N N - K N W N N N S N R
+chr2 53559 53560 T T T N N V R V N N T N U N N B N M N V Y
+chr2 55607 55608 A N A U S N N H R K N N N Y N N G N N N N
+chr10 55659 55660 T N T C N K N N N U N S N N N V C R S N N
+chr10 55734 55735 T N T G N C N M M G C N B N . N G N N N N
+chr10 55870 55871 C G C N H G - N N N C N H K N M G N N N N
+chr10 56024 56025 A T A N D U N Y B N N X N N Y N T N - N N
+chr10 56100 56101 T T A W N N W N S N K M N R N R N R N G N
+chr10 56120 56121 A - A N A N N Y N N N W V N N Y G N N W N
+chr10 56137 56138 A A A N A Y H . Y N G N . D N N T N N N N
+chr10 56174 56175 A T A Y A N N N N N N N N N . S T Y N B N
+chr10 59373 59374 A G A N N N N N N T N S N N N G N N N V N
+chr10 68912 68913 G T G R N B R N H N U W Y N N N N N N N T
+chr10 72946 72947 T A N N N N N N B N N . B D W U N U N D A
+chr10 77052 77053 G A R N G N N Y N N N N N N B R N W N N R
+chr18 78200 78201 G G G N N H N N V N G N N N N A A N K X N
+chr18 81076 81077 T A T B N N G N N X W N X N V N N D N N N
+chr18 81198 81199 A T A N N N N - N N X N K T N M N K X N W
+chr18 81216 81217 G A G Y N N D N X N N N N A N S N N N D N
+chr18 81398 81399 G T G N - W N N M N G C N K N S N N N N K
+chr18 91548 91549 A A A S N X H S R N A K N N N N U A R N N
+chr18 93895 93896 T T T H N N V W Y N N N - N N N N N N Y N
+chr18 98172 98173 T T T N . N N N S N T N Y N N Y X D V N Y
+chr18 110904 110905 T - A A N A N A W A N N A X N W N N N N N
+chr18 140324 140325 A A A N M N N Y N S N V N N X N C N N . M
+chr18 160592 160593 C G G G N G N G N G N N G N N M T N Y N N
\ No newline at end of file
diff -r dedb7be9aa44 -r b36c13131ac7 test-data/dna_filter_out1.bed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dna_filter_out1.bed Mon Feb 08 23:52:56 2010 -0500
@@ -0,0 +1,4 @@
+chr1 582 583 G G G N G R N R N - N M N V K N N N G C R
+chr1 602 603 G G G N G N Y N R G G N N U N T N A K N R
+chr2 48633 48634 T T T N G N N N . N N N N S N Y N . N N N
+chr10 77052 77053 G A R N G N N Y N N N N N N B R N W N N R
diff -r dedb7be9aa44 -r b36c13131ac7 test-data/dna_filter_out2.bed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dna_filter_out2.bed Mon Feb 08 23:52:56 2010 -0500
@@ -0,0 +1,39 @@
+chr1 256 257 A N M N - M N U N N A N D N G N N K N N N
+chr1 602 603 G G G N G N Y N R G G N N U N T N A K N R
+chr1 4792 4793 A A M K N W S S N N Y N N N N N M R N R N
+chr1 6119 6120 G G M N S N N W B N S D N N H V N B W N N
+chr1 6357 6358 G G N M K N G - N N G U N N N B N N K N S
+chr1 6433 6434 G G N R N N C N N N . N N . N N N N N R N
+chr1 39160 39161 T T T N N Y N - N N N N N N N V N N N N Y
+chr1 41920 41921 G C G N M C G N A N G N K N W S N N N V N
+chr1 42100 42101 T T T Y R W N N N V N M R N N G N M Y N K
+chr2 45788 45789 T T T N W S N Y N R Y N S N W M N C T N C
+chr2 46243 46244 T T T N W N N B V N U N T N N Y C N U N N
+chr2 47814 47815 A C A S N X D N N H W N G N Y C N N M R N
+chr2 48633 48634 T T T N G N N N . N N N N S N Y N . N N N
+chr2 51304 51305 A G N N C N W - N S Y N . N N G N N N W R
+chr2 51324 51325 T T N R N N N N N - N U N W A N N N N N N
+chr2 53130 53131 T C T K R . N B N N T N N M N Y N N Y N N
+chr2 53505 53506 A A A M N N Y N N N N - K N W N N N S N R
+chr2 53559 53560 T T T N N V R V N N T N U N N B N M N V Y
+chr2 55607 55608 A N A U S N N H R K N N N Y N N G N N N N
+chr10 55659 55660 T N T C N K N N N U N S N N N V C R S N N
+chr10 55734 55735 T N T G N C N M M G C N B N . N G N N N N
+chr10 56024 56025 A T A N D U N Y B N N X N N Y N T N - N N
+chr10 56100 56101 T T A W N N W N S N K M N R N R N R N G N
+chr10 56120 56121 A - A N A N N Y N N N W V N N Y G N N W N
+chr10 56137 56138 A A A N A Y H . Y N G N . D N N T N N N N
+chr10 56174 56175 A T A Y A N N N N N N N N N . S T Y N B N
+chr10 59373 59374 A G A N N N N N N T N S N N N G N N N V N
+chr10 68912 68913 G T G R N B R N H N U W Y N N N N N N N T
+chr10 72946 72947 T A N N N N N N B N N . B D W U N U N D A
+chr10 77052 77053 G A R N G N N Y N N N N N N B R N W N N R
+chr18 78200 78201 G G G N N H N N V N G N N N N A A N K X N
+chr18 81076 81077 T A T B N N G N N X W N X N V N N D N N N
+chr18 81198 81199 A T A N N N N - N N X N K T N M N K X N W
+chr18 81216 81217 G A G Y N N D N X N N N N A N S N N N D N
+chr18 81398 81399 G T G N - W N N M N G C N K N S N N N N K
+chr18 91548 91549 A A A S N X H S R N A K N N N N U A R N N
+chr18 98172 98173 T T T N . N N N S N T N Y N N Y X D V N Y
+chr18 110904 110905 T - A A N A N A W A N N A X N W N N N N N
+chr18 160592 160593 C G G G N G N G N G N N G N N M T N Y N N
diff -r dedb7be9aa44 -r b36c13131ac7 test-data/dna_filter_out3.bed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dna_filter_out3.bed Mon Feb 08 23:52:56 2010 -0500
@@ -0,0 +1,41 @@
+chr1 468 469 C C C N M N N K . N C U N H N G N N M N S
+chr1 582 583 G G G N G R N R N - N M N V K N N N G C R
+chr1 602 603 G G G N G N Y N R G G N N U N T N A K N R
+chr1 6119 6120 G G M N S N N W B N S D N N H V N B W N N
+chr1 6357 6358 G G N M K N G - N N G U N N N B N N K N S
+chr1 6433 6434 G G N R N N C N N N . N N . N N N N N R N
+chr1 39160 39161 T T T N N Y N - N N N N N N N V N N N N Y
+chr1 41920 41921 G C G N M C G N A N G N K N W S N N N V N
+chr1 42100 42101 T T T Y R W N N N V N M R N N G N M Y N K
+chr1 45026 45027 C A C N N Y N S Y N N X N A D N N K N N A
+chr1 45161 45162 C T C . N X H V N N C R N Y N N N N R N Y
+chr2 45407 45408 C N C S B N N N N N C N Y N N T K G N C N
+chr2 45788 45789 T T T N W S N Y N R Y N S N W M N C T N C
+chr2 46243 46244 T T T N W N N B V N U N T N N Y C N U N N
+chr2 48073 48074 A G A Y W . N K N N N G N N N G N N N Y N
+chr2 48633 48634 T T T N G N N N . N N N N S N Y N . N N N
+chr2 51324 51325 T T N R N N N N N - N U N W A N N N N N N
+chr2 52065 52066 T C T N N N S N . N T N M N S W N T Y C N
+chr2 53130 53131 T C T K R . N B N N T N N M N Y N N Y N N
+chr2 53559 53560 T T T N N V R V N N T N U N N B N M N V Y
+chr2 55607 55608 A N A U S N N H R K N N N Y N N G N N N N
+chr10 55659 55660 T N T C N K N N N U N S N N N V C R S N N
+chr10 55734 55735 T N T G N C N M M G C N B N . N G N N N N
+chr10 55870 55871 C G C N H G - N N N C N H K N M G N N N N
+chr10 56100 56101 T T A W N N W N S N K M N R N R N R N G N
+chr10 56120 56121 A - A N A N N Y N N N W V N N Y G N N W N
+chr10 56174 56175 A T A Y A N N N N N N N N N . S T Y N B N
+chr10 59373 59374 A G A N N N N N N T N S N N N G N N N V N
+chr10 68912 68913 G T G R N B R N H N U W Y N N N N N N N T
+chr10 72946 72947 T A N N N N N N B N N . B D W U N U N D A
+chr10 77052 77053 G A R N G N N Y N N N N N N B R N W N N R
+chr18 78200 78201 G G G N N H N N V N G N N N N A A N K X N
+chr18 81076 81077 T A T B N N G N N X W N X N V N N D N N N
+chr18 81198 81199 A T A N N N N - N N X N K T N M N K X N W
+chr18 81216 81217 G A G Y N N D N X N N N N A N S N N N D N
+chr18 81398 81399 G T G N - W N N M N G C N K N S N N N N K
+chr18 93895 93896 T T T H N N V W Y N N N - N N N N N N Y N
+chr18 98172 98173 T T T N . N N N S N T N Y N N Y X D V N Y
+chr18 110904 110905 T - A A N A N A W A N N A X N W N N N N N
+chr18 140324 140325 A A A N M N N Y N S N V N N X N C N N . M
+chr18 160592 160593 C G G G N G N G N G N N G N N M T N Y N N
diff -r dedb7be9aa44 -r b36c13131ac7 test-data/dna_filter_out4.bed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/dna_filter_out4.bed Mon Feb 08 23:52:56 2010 -0500
@@ -0,0 +1,24 @@
+chr1 582 583 G G G N G R N R N - N M N V K N N N G C R
+chr1 602 603 G G G N G N Y N R G G N N U N T N A K N R
+chr1 6119 6120 G G M N S N N W B N S D N N H V N B W N N
+chr1 6433 6434 G G N R N N C N N N . N N . N N N N N R N
+chr1 41920 41921 G C G N M C G N A N G N K N W S N N N V N
+chr1 45161 45162 C T C . N X H V N N C R N Y N N N N R N Y
+chr2 45788 45789 T T T N W S N Y N R Y N S N W M N C T N C
+chr2 46243 46244 T T T N W N N B V N U N T N N Y C N U N N
+chr2 48633 48634 T T T N G N N N . N N N N S N Y N . N N N
+chr2 51304 51305 A G N N C N W - N S Y N . N N G N N N W R
+chr2 51324 51325 T T N R N N N N N - N U N W A N N N N N N
+chr2 52065 52066 T C T N N N S N . N T N M N S W N T Y C N
+chr2 53559 53560 T T T N N V R V N N T N U N N B N M N V Y
+chr10 55734 55735 T N T G N C N M M G C N B N . N G N N N N
+chr10 55870 55871 C G C N H G - N N N C N H K N M G N N N N
+chr10 56120 56121 A - A N A N N Y N N N W V N N Y G N N W N
+chr10 59373 59374 A G A N N N N N N T N S N N N G N N N V N
+chr10 72946 72947 T A N N N N N N B N N . B D W U N U N D A
+chr10 77052 77053 G A R N G N N Y N N N N N N B R N W N N R
+chr18 81198 81199 A T A N N N N - N N X N K T N M N K X N W
+chr18 98172 98173 T T T N . N N N S N T N Y N N Y X D V N Y
+chr18 110904 110905 T - A A N A N A W A N N A X N W N N N N N
+chr18 140324 140325 A A A N M N N Y N S N V N N X N C N N . M
+chr18 160592 160593 C G G G N G N G N G N N G N N M T N Y N N
diff -r dedb7be9aa44 -r b36c13131ac7 tool_conf.xml.sample
--- a/tool_conf.xml.sample Mon Feb 08 21:33:12 2010 -0500
+++ b/tool_conf.xml.sample Mon Feb 08 23:52:56 2010 -0500
@@ -49,6 +49,7 @@
<tool file="filters/headWrapper.xml" />
<tool file="filters/tailWrapper.xml" />
<tool file="filters/trimmer.xml" />
+ <tool file="stats/dna_filtering.xml" />
</section>
<section name="Filter and Sort" id="filter">
<tool file="stats/filtering.xml" />
diff -r dedb7be9aa44 -r b36c13131ac7 tools/stats/dna_filtering.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/stats/dna_filtering.py Mon Feb 08 23:52:56 2010 -0500
@@ -0,0 +1,195 @@
+#!/usr/bin/env python
+
+"""
+This tool takes a tab-delimited text file as input and creates filters on columns based on certain properties. The tool will skip over invalid lines within the file, informing the user about the number of lines skipped.
+
+usage: %prog [options]
+ -i, --input=i: tabular input file
+ -o, --output=o: filtered output file
+ -c, --cond=c: conditions to filter on
+ -n, --n_handling=n: how to handle N and X
+ -l, --columns=l: columns
+ -t, --col_types=t: column types
+
+"""
+
+#from __future__ import division
+import os.path, re, string, sys
+from galaxy import eggs
+import pkg_resources; pkg_resources.require( "bx-python" )
+from bx.cookbook import doc_optparse
+
+# Older py compatibility
+try:
+ set()
+except:
+ from sets import Set as set
+
+#assert sys.version_info[:2] >= ( 2, 4 )
+
+def get_operands( filter_condition ):
+ # Note that the order of all_operators is important
+ items_to_strip = [ '==', '!=', ' and ', ' or ' ]
+ for item in items_to_strip:
+ if filter_condition.find( item ) >= 0:
+ filter_condition = filter_condition.replace( item, ' ' )
+ operands = set( filter_condition.split( ' ' ) )
+ return operands
+
+def stop_err( msg ):
+ sys.stderr.write( msg )
+ sys.exit()
+
+def __main__():
+ #Parse Command Line
+ options, args = doc_optparse.parse( __doc__ )
+ input = options.input
+ output = options.output
+ cond = options.cond
+ n_handling = options.n_handling
+ columns = options.columns
+ col_types = options.col_types
+
+ try:
+ in_columns = int( columns )
+ assert col_types #check to see that the column types variable isn't null
+ in_column_types = col_types.split( ',' )
+ except:
+ stop_err( "Data does not appear to be tabular. This tool can only be used with tab-delimited data." )
+
+ # Unescape if input has been escaped
+ cond_text = cond.replace( '__eq__', '==' ).replace( '__ne__', '!=' ).replace( '__sq__', "'" )
+ orig_cond_text = cond_text
+ # Expand to allow for DNA codes
+ dot_letters = [ letter for letter in string.uppercase if letter not in \
+ [ 'A', 'T', 'U', 'G', 'C', 'K', 'M', 'R', 'Y', 'S', 'W', 'B', 'V', 'H', 'D', 'N', 'X' ] ]
+ codes = {'A': [ 'A', 'M', 'R', 'W', 'V', 'H', 'D' ],
+ 'T': [ 'T', 'U', 'K', 'Y', 'W', 'B', 'H', 'D' ],
+ 'G': [ 'G', 'K', 'R', 'S', 'B', 'V', 'D' ],
+ 'C': [ 'C', 'M', 'Y', 'S', 'B', 'V', 'H' ],
+ 'U': [ 'T', 'U', 'K', 'Y', 'W', 'B', 'H', 'D' ],
+ 'K': [ 'K', 'G', 'T' ],
+ 'M': [ 'M', 'A', 'C' ],
+ 'R': [ 'R', 'A', 'G' ],
+ 'Y': [ 'Y', 'C', 'T' ],
+ 'S': [ 'S', 'C', 'G' ],
+ 'W': [ 'W', 'A', 'T' ],
+ 'B': [ 'B', 'C', 'G', 'T' ],
+ 'V': [ 'V', 'A', 'C', 'G' ],
+ 'H': [ 'H', 'A', 'C', 'T' ],
+ 'D': [ 'D', 'A', 'G', 'T' ],
+ '.': dot_letters,
+ '-': [ '-' ]}
+ # Add handling for N and X
+ if n_handling == "all":
+ codes[ 'N' ] = [ 'G', 'A', 'T', 'C', 'U', 'K', 'M', 'R', 'Y', 'S', 'W', 'B', 'V', 'H', 'D', 'N', 'X' ]
+ codes[ 'X' ] = [ 'G', 'A', 'T', 'C', 'U', 'K', 'M', 'R', 'Y', 'S', 'W', 'B', 'V', 'H', 'D', 'N', 'X' ]
+ for code in codes.keys():
+ if code != '.' and code != '-':
+ codes[code].append( 'N' )
+ codes[code].append( 'X' )
+ else:
+ codes[ 'N' ] = dot_letters
+ codes[ 'X' ] = dot_letters
+ # Expand conditions to allow for DNA codes
+ try:
+ match_replace = {}
+ pat = re.compile( "c\d+\s*[!=]=\s*[\w']+" )
+ matches = pat.findall( cond_text )
+ for match in matches:
+ if match.find( '==' ) > 0:
+ match_parts = match.split( '==' )
+ new_match = '(%s in codes[%s] and %s in codes[%s])' % ( match_parts[0], match_parts[1], match_parts[1], match_parts[0] )
+ elif match.find( '!=' ) > 0 :
+ match_parts = match.split( '!=' )
+ new_match = '(%s not in codes[%s] or %s not in codes[%s])' % ( match_parts[0], match_parts[1], match_parts[1], match_parts[0] )
+ else:
+ raise Exception
+ if match_parts[1].find( "'" ) >= 0:
+ assert match_parts[1].replace( "'", '' ) in [ 'G', 'A', 'T', 'C', 'U', 'K', 'M', 'R', 'Y', 'S', 'W', 'B', 'V', 'H', 'D', 'N', 'X', '-', '.' ]
+ else:
+ assert match_parts[1].startswith( 'c' )
+ match_replace[match] = new_match
+ for match in match_replace.keys():
+ cond_text = cond_text.replace(match, match_replace[match])
+ if len( match_replace ) == 0:
+ raise Exception
+ except:
+ stop_err( "One of your conditions is invalid. Make sure to use only '!=' or '==', valid column numbers, and valid base values." )
+
+ # Attempt to determine if the condition includes executable stuff and, if so, exit
+ secured = dir()
+ operands = get_operands( cond_text )
+ for operand in operands:
+ try:
+ check = int( operand )
+ except:
+ if operand in secured:
+ stop_err( "Illegal value '%s' in condition '%s'" % ( operand, cond_text ) )
+
+ # Prepare the column variable names and wrappers for column data types
+ cols, type_casts = [], []
+ for col in range( 1, in_columns + 1 ):
+ col_name = "c%d" % col
+ cols.append( col_name )
+ col_type = in_column_types[ col - 1 ]
+ type_cast = "%s(%s)" % ( col_type, col_name )
+ type_casts.append( type_cast )
+
+ col_str = ', '.join( cols ) # 'c1, c2, c3, c4'
+ type_cast_str = ', '.join( type_casts ) # 'str(c1), int(c2), int(c3), str(c4)'
+ assign = "%s = line.split( '\\t' )" % col_str
+ wrap = "%s = %s" % ( col_str, type_cast_str )
+ skipped_lines = 0
+ first_invalid_line = 0
+ invalid_line = None
+ lines_kept = 0
+ total_lines = 0
+ out = open( output, 'wt' )
+ # Read and filter input file, skipping invalid lines
+ code = '''
+for i, line in enumerate( file( input ) ):
+ total_lines += 1
+ line = line.rstrip( '\\r\\n' )
+ if not line or line.startswith( '#' ):
+ skipped_lines += 1
+ if not invalid_line:
+ first_invalid_line = i + 1
+ invalid_line = line
+ continue
+ try:
+ %s = line.split( '\\t' )
+ %s = %s
+ if %s:
+ lines_kept += 1
+ print >> out, line
+ except Exception, e:
+ skipped_lines += 1
+ if not invalid_line:
+ first_invalid_line = i + 1
+ invalid_line = line
+''' % ( col_str, col_str, type_cast_str, cond_text )
+
+ valid_filter = True
+ try:
+ exec code
+ except Exception, e:
+ out.close()
+ if str( e ).startswith( 'invalid syntax' ):
+ valid_filter = False
+ stop_err( 'Filter condition "%s" likely invalid. See tool tips, syntax and examples.' % orig_cond_text )
+ else:
+ stop_err( str( e ) )
+
+ if valid_filter:
+ out.close()
+ valid_lines = total_lines - skipped_lines
+ print 'Filtering with %s, ' % orig_cond_text
+ if valid_lines > 0:
+ print 'kept %4.2f%% of %d lines.' % ( 100.0*lines_kept/valid_lines, total_lines )
+ else:
+ print 'Possible invalid filter condition "%s" or non-existent column referenced. See tool tips, syntax and examples.' % orig_cond_text
+ if skipped_lines > 0:
+ print 'Skipped %d invalid lines starting at line #%d: "%s"' % ( skipped_lines, first_invalid_line, invalid_line )
+
+if __name__ == "__main__" : __main__()
diff -r dedb7be9aa44 -r b36c13131ac7 tools/stats/dna_filtering.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/stats/dna_filtering.xml Mon Feb 08 23:52:56 2010 -0500
@@ -0,0 +1,114 @@
+<tool id="dna_filter" name="DNA Filter" version="1.0.0">
+ <description>filter column data on DNA ambiguity codes using simple expressions</description>
+ <command interpreter="python">
+ dna_filtering.py
+ --input=$input
+ --output=$out_file1
+ --cond="$cond"
+ --n_handling=$n_handling
+ --columns=${input.metadata.columns}
+ --col_types="${input.metadata.column_types}"
+ </command>
+ <inputs>
+ <param format="tabular" name="input" type="data" label="Filter" help="Query missing? See TIP below."/>
+ <param name="cond" size="40" type="text" value="c8=='G'" label="With following condition" help="Double equal signs, ==, must be used as shown above. To filter for an arbitrary string, use the Select tool.">
+ <validator type="empty_field" message="Enter a valid filtering condition, see syntax and examples below."/>
+ </param>
+ <param name="n_handling" type="select" label="Do you want N (and X) to match A or C or G or T OR nothing?">
+ <option value="all">N = A or C or G or T</option>
+ <option value="none">N = nothing</option>
+ </param>
+ </inputs>
+ <outputs>
+ <data format="input" name="out_file1" metadata_source="input"/>
+ </outputs>
+ <tests>
+ <test>
+ <param name="input" value="dna_filter_in1.bed" />
+ <param name="cond" value="c8=='G'" />
+ <param name="n_handling" value="all" />
+ <output name="out_file1" file="dna_filter_out1.bed" />
+ </test>
+ <test>
+ <param name="input" value="dna_filter_in1.bed" />
+ <param name="cond" value="(c10==c11 or c17==c18) and c6!='C' and c23=='R'" />
+ <param name="n_handling" value="all" />
+ <output name="out_file1" file="dna_filter_out2.bed" />
+ </test>
+ <test>
+ <param name="input" value="dna_filter_in1.bed" />
+ <param name="cond" value="c4=='B' or c9==c10" />
+ <param name="n_handling" value="none" />
+ <output name="out_file1" file="dna_filter_out3.bed" />
+ </test>
+ <test>
+ <param name="input" value="dna_filter_in1.bed" />
+ <param name="cond" value="c7!='Y' and c9!='U'" />
+ <param name="n_handling" value="none" />
+ <output name="out_file1" file="dna_filter_out4.bed" />
+ </test>
+ </tests>
+ <help>
+
+.. class:: warningmark
+
+Double equal signs, ==, must be used as *"equal to"* (e.g., **c1 == 'G'**)
+
+.. class:: infomark
+
+**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert*
+
+.. class:: infomark
+
+**TIP:** This tool is intended primarily for comparing column values (such as "c5==c12"), although it is also possible to filter on specific values (like "c6!='G'"). Be aware that when searching for specific values, any possible match is considered. So if you search on "c6!='G'", rows will be excluded when c6 is G, K, R, S, B, V, or D (plus N or X if you set that to equal "all"), because it is possible those values could be G.
+
+-----
+
+**Syntax**
+
+The filter tool allows you to restrict the dataset using simple conditional statements.
+
+- Columns are referenced with **c** and a **number**. For example, **c1** refers to the first column of a tab-delimited file
+- Make sure that multi-character operators contain no white space ( e.g., **!=** is valid while **! =** is not valid )
+- When using 'equal-to' operator **double equal sign '==' must be used** ( e.g., **c1=='chr1'** )
+- Non-numerical values must be included in single or double quotes ( e.g., **c6=='C'** )
+- Filtering condition can include logical operators, but **make sure operators are all lower case** ( e.g., **(c1!='chrX' and c1!='chrY') or c6=='+'** )
+
+-----
+
+**DNA Codes**
+
+The following are the DNA codes used for filtering::
+
+ Code Meaning
+ ---- ---------------------------
+ A A
+ T T
+ U T
+ G G
+ C C
+ K G or T
+ M A or C
+ R A or G
+ Y C or T
+ S C or G
+ W A or T
+ B C, G or T
+ V A, C or G
+ H A, C or T
+ D A, G or T
+ X A, C, G or T
+ N A, C, G or T
+ . not (A, C, G or T)
+ - gap of indeterminate length
+
+-----
+
+**Example**
+
+- **c8=='A'** selects lines in which the eighth column is A, M, R, W, V, H, D and N or X if appropriate
+- **c12==c15** selects lines where the value in the twelfth column could be the same as the fifteenth and the fifteenth column could be the same as the twelfth column (based on appropriate codes)
+- **c9!=c19** selects lines where column nine could not be the same as column nineteen and column nineteen could not be the same as column nine (using appropriate codes)
+
+</help>
+</tool>
1
0
09 Feb '10
details: http://www.bx.psu.edu/hg/galaxy/rev/dedb7be9aa44
changeset: 3357:dedb7be9aa44
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Mon Feb 08 21:33:12 2010 -0500
description:
Change naming of converter to conversion for 3356:c64ef44ed4c5 to more properly reflect the function.
diffstat:
lib/galaxy/tools/__init__.py | 18 ++++++++--------
lib/galaxy/tools/actions/__init__.py | 40 ++++++++++++++++++------------------
lib/galaxy/tools/parameters/basic.py | 8 +++---
3 files changed, 33 insertions(+), 33 deletions(-)
diffs (128 lines):
diff -r c64ef44ed4c5 -r dedb7be9aa44 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py Mon Feb 08 12:45:28 2010 -0500
+++ b/lib/galaxy/tools/__init__.py Mon Feb 08 21:33:12 2010 -0500
@@ -1198,27 +1198,27 @@
current = values["__current_case__"]
wrap_values( input.cases[current].inputs, values )
elif isinstance( input, DataToolParameter ):
- ##FIXME: We're populating param_dict with converters when wrapping values,
+ ##FIXME: We're populating param_dict with conversions when wrapping values,
##this should happen as a separate step before wrapping (or call this wrapping step something more generic)
##(but iterating this same list twice would be wasteful)
- #add explicit converters by name to current parent
- for converter_name, converter_extensions, converter_datatypes in input.converters:
+ #add explicit conversions by name to current parent
+ for conversion_name, conversion_extensions, conversion_datatypes in input.conversions:
#if we are at building cmdline step, then converters have already executed
- conv_ext, converted_dataset = input_values[ input.name ].find_conversion_destination( converter_datatypes )
+ conv_ext, converted_dataset = input_values[ input.name ].find_conversion_destination( conversion_datatypes )
#when dealing with optional inputs, we'll provide a valid extension to be used for None converted dataset
if not conv_ext:
- conv_ext = converter_extensions[0]
+ conv_ext = conversion_extensions[0]
#input_values[ input.name ] is None when optional dataset,
#'conversion' of optional dataset should create wrapper around NoneDataset for converter output
if input_values[ input.name ] and not converted_dataset:
#input that converter is based from has a value, but converted dataset does not exist
- raise Exception, 'A path for explicit datatype conversion has not been found: %s --/--> %s' % ( input_values[ input.name ].extension, converter_extensions )
+ raise Exception, 'A path for explicit datatype conversion has not been found: %s --/--> %s' % ( input_values[ input.name ].extension, conversion_extensions )
else:
- input_values[ converter_name ] = \
+ input_values[ conversion_name ] = \
DatasetFilenameWrapper( converted_dataset,
datatypes_registry = self.app.datatypes_registry,
- tool = Bunch( converter_name = Bunch( extensions = conv_ext ) ), #trick wrapper into using target conv ext (when None) without actually being a tool parameter
- name = converter_name )
+ tool = Bunch( conversion_name = Bunch( extensions = conv_ext ) ), #trick wrapper into using target conv ext (when None) without actually being a tool parameter
+ name = conversion_name )
#wrap actual input dataset
input_values[ input.name ] = \
DatasetFilenameWrapper( input_values[ input.name ],
diff -r c64ef44ed4c5 -r dedb7be9aa44 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py Mon Feb 08 12:45:28 2010 -0500
+++ b/lib/galaxy/tools/actions/__init__.py Mon Feb 08 21:33:12 2010 -0500
@@ -63,41 +63,41 @@
# are stored as name1, name2, ...
for i, v in enumerate( value ):
input_datasets[ prefix + input.name + str( i + 1 ) ] = process_dataset( v )
- converters = []
- for converter_name, converter_extensions, converter_datatypes in input.converters:
- new_data = process_dataset( input_datasets[ prefix + input.name + str( i + 1 ) ], converter_datatypes )
- if not new_data or isinstance( new_data.datatype, converter_datatypes ):
- input_datasets[ prefix + converter_name + str( i + 1 ) ] = new_data
- converters.append( ( converter_name, new_data ) )
+ conversions = []
+ for conversion_name, conversion_extensions, conversion_datatypes in input.conversions:
+ new_data = process_dataset( input_datasets[ prefix + input.name + str( i + 1 ) ], conversion_datatypes )
+ if not new_data or isinstance( new_data.datatype, conversion_datatypes ):
+ input_datasets[ prefix + conversion_name + str( i + 1 ) ] = new_data
+ conversions.append( ( conversion_name, new_data ) )
else:
- raise Exception, 'A path for explicit datatype conversion has not been found: %s --/--> %s' % ( input_datasets[ prefix + input.name + str( i + 1 ) ].extension, converter_extensions )
+ raise Exception, 'A path for explicit datatype conversion has not been found: %s --/--> %s' % ( input_datasets[ prefix + input.name + str( i + 1 ) ].extension, conversion_extensions )
if parent:
parent[input.name] = input_datasets[ prefix + input.name + str( i + 1 ) ]
- for converter_name, converter_data in converters:
+ for conversion_name, conversion_data in conversions:
#allow explicit conversion to be stored in job_parameter table
- parent[ converter_name ] = converter_data.id #a more robust way to determine JSONable value is desired
+ parent[ conversion_name ] = conversion_data.id #a more robust way to determine JSONable value is desired
else:
param_values[input.name][i] = input_datasets[ prefix + input.name + str( i + 1 ) ]
- for converter_name, converter_data in converters:
+ for conversion_name, conversion_data in conversions:
#allow explicit conversion to be stored in job_parameter table
- param_values[ converter_name ][i] = converter_data.id #a more robust way to determine JSONable value is desired
+ param_values[ conversion_name ][i] = conversion_data.id #a more robust way to determine JSONable value is desired
else:
input_datasets[ prefix + input.name ] = process_dataset( value )
- converters = []
- for converter_name, converter_extensions, converter_datatypes in input.converters:
- new_data = process_dataset( input_datasets[ prefix + input.name ], converter_datatypes )
- if not new_data or isinstance( new_data.datatype, converter_datatypes ):
- input_datasets[ prefix + converter_name ] = new_data
- converters.append( ( converter_name, new_data ) )
+ conversions = []
+ for conversion_name, conversion_extensions, conversion_datatypes in input.conversions:
+ new_data = process_dataset( input_datasets[ prefix + input.name ], conversion_datatypes )
+ if not new_data or isinstance( new_data.datatype, conversion_datatypes ):
+ input_datasets[ prefix + conversion_name ] = new_data
+ conversions.append( ( conversion_name, new_data ) )
else:
- raise Exception, 'A path for explicit datatype conversion has not been found: %s --/--> %s' % ( input_datasets[ prefix + input.name ].extension, converter_extensions )
+ raise Exception, 'A path for explicit datatype conversion has not been found: %s --/--> %s' % ( input_datasets[ prefix + input.name ].extension, conversion_extensions )
target_dict = parent
if not target_dict:
target_dict = param_values
target_dict[ input.name ] = input_datasets[ prefix + input.name ]
- for converter_name, converter_data in converters:
+ for conversion_name, conversion_data in conversions:
#allow explicit conversion to be stored in job_parameter table
- target_dict[ converter_name ] = converter_data.id #a more robust way to determine JSONable value is desired
+ target_dict[ conversion_name ] = conversion_data.id #a more robust way to determine JSONable value is desired
tool.visit_inputs( param_values, visitor )
return input_datasets
diff -r c64ef44ed4c5 -r dedb7be9aa44 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py Mon Feb 08 12:45:28 2010 -0500
+++ b/lib/galaxy/tools/parameters/basic.py Mon Feb 08 21:33:12 2010 -0500
@@ -1168,15 +1168,15 @@
else:
self.options = dynamic_options.DynamicOptions( options, self )
self.is_dynamic = self.options is not None
- # Load converters required for the dataset input
- self.converters = []
- for conv_elem in elem.findall( "converter" ):
+ # Load conversions required for the dataset input
+ self.conversions = []
+ for conv_elem in elem.findall( "conversion" ):
name = conv_elem.get( "name" ) #name for commandline substitution
conv_extensions = conv_elem.get( "type" ) #target datatype extension
# FIXME: conv_extensions should be able to be an ordered list
assert None not in [ name, type ], 'A name (%s) and type (%s) are required for explicit conversion' % ( name, type )
conv_types = tool.app.datatypes_registry.get_datatype_by_extension( conv_extensions.lower() ).__class__
- self.converters.append( ( name, conv_extensions, conv_types ) )
+ self.conversions.append( ( name, conv_extensions, conv_types ) )
def get_html_field( self, trans=None, value=None, other_values={} ):
filter_value = None
1
0
09 Feb '10
details: http://www.bx.psu.edu/hg/galaxy/rev/c64ef44ed4c5
changeset: 3356:c64ef44ed4c5
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Mon Feb 08 12:45:28 2010 -0500
description:
First pass at allowing explicit datatype conversion to be specified. This can be used for e.g. providing a tool with a non-metadata based index file.
Defined as part of a DataToolParameter:
<param name="input1" type="interval" label="An Interval File">
<converter name='input1_as_a_bed_file' type='bed'/>
</param>
Both the original input as well as the converted dataset can be accessed like:
<command>some_binary $input1 $input1_as_a_bed_file </command>
if $input1 is already BED, it will be used for input1_as_a_bed_file.
The name is be placed in the dictionary space of the data input parameter's parent; so for Grouping objects, e.g. a repeat:
<repeat name="queries" title="Query">
<param name="input2" type="data" label="Select" >
<converter name='input2_as_a_bed_file' type='bed'/>
</param>
</repeat>
is accessed like (putting both the original and converted dataset as arguments on the command line):
<command> ...
#for $q in $queries
${q.input2} ${q.input2_as_a_bed_file}
#end for
... </command>
See notes in code in commit for additional comments.
diffstat:
lib/galaxy/tools/__init__.py | 28 ++++++++++++++++++++++++
lib/galaxy/tools/actions/__init__.py | 41 +++++++++++++++++++++++++++++------
lib/galaxy/tools/parameters/basic.py | 13 +++++++++-
3 files changed, 73 insertions(+), 9 deletions(-)
diffs (147 lines):
diff -r 26f01eafc6bd -r c64ef44ed4c5 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py Mon Feb 08 11:20:44 2010 -0500
+++ b/lib/galaxy/tools/__init__.py Mon Feb 08 12:45:28 2010 -0500
@@ -1198,6 +1198,28 @@
current = values["__current_case__"]
wrap_values( input.cases[current].inputs, values )
elif isinstance( input, DataToolParameter ):
+ ##FIXME: We're populating param_dict with converters when wrapping values,
+ ##this should happen as a separate step before wrapping (or call this wrapping step something more generic)
+ ##(but iterating this same list twice would be wasteful)
+ #add explicit converters by name to current parent
+ for converter_name, converter_extensions, converter_datatypes in input.converters:
+ #if we are at building cmdline step, then converters have already executed
+ conv_ext, converted_dataset = input_values[ input.name ].find_conversion_destination( converter_datatypes )
+ #when dealing with optional inputs, we'll provide a valid extension to be used for None converted dataset
+ if not conv_ext:
+ conv_ext = converter_extensions[0]
+ #input_values[ input.name ] is None when optional dataset,
+ #'conversion' of optional dataset should create wrapper around NoneDataset for converter output
+ if input_values[ input.name ] and not converted_dataset:
+ #input that converter is based from has a value, but converted dataset does not exist
+ raise Exception, 'A path for explicit datatype conversion has not been found: %s --/--> %s' % ( input_values[ input.name ].extension, converter_extensions )
+ else:
+ input_values[ converter_name ] = \
+ DatasetFilenameWrapper( converted_dataset,
+ datatypes_registry = self.app.datatypes_registry,
+ tool = Bunch( converter_name = Bunch( extensions = conv_ext ) ), #trick wrapper into using target conv ext (when None) without actually being a tool parameter
+ name = converter_name )
+ #wrap actual input dataset
input_values[ input.name ] = \
DatasetFilenameWrapper( input_values[ input.name ],
datatypes_registry = self.app.datatypes_registry,
@@ -1212,6 +1234,12 @@
# tools (e.g. UCSC) should really be handled in a special way.
if self.check_values:
wrap_values( self.inputs, param_dict )
+ ###FIXME: when self.check_values==True, input datasets are being wrapped twice
+ ### (above and below, creating 2 separate DatasetFilenameWrapper objects - first is overwritten by second),
+ ###is this necessary? - if we get rid of this way to access children, can we stop this redundancy, or is there another reason for this?
+ ###Only necessary when self.check_values is False (==external dataset tool?: can this be abstracted out as part of being a datasouce tool?)
+ ### but we still want (ALWAYS) to wrap input datasets
+ ### (this should be checked to prevent overhead of creating a new object?)
# Additionally, datasets go in the param dict. We wrap them such that
# if the bare variable name is used it returns the filename (for
# backwards compatibility). We also add any child datasets to the
diff -r 26f01eafc6bd -r c64ef44ed4c5 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py Mon Feb 08 11:20:44 2010 -0500
+++ b/lib/galaxy/tools/actions/__init__.py Mon Feb 08 12:45:28 2010 -0500
@@ -31,11 +31,13 @@
"""
input_datasets = dict()
def visitor( prefix, input, value, parent = None ):
- def process_dataset( data ):
- if data and not isinstance( data.datatype, input.formats ):
+ def process_dataset( data, formats = None ):
+ if formats is None:
+ formats = input.formats
+ if data and not isinstance( data.datatype, formats ):
# Need to refresh in case this conversion just took place, i.e. input above in tool performed the same conversion
trans.sa_session.refresh( data )
- target_ext, converted_dataset = data.find_conversion_destination( input.formats, converter_safe = input.converter_safe( param_values, trans ) )
+ target_ext, converted_dataset = data.find_conversion_destination( formats, converter_safe = input.converter_safe( param_values, trans ) )
if target_ext:
if converted_dataset:
data = converted_dataset
@@ -61,16 +63,41 @@
# are stored as name1, name2, ...
for i, v in enumerate( value ):
input_datasets[ prefix + input.name + str( i + 1 ) ] = process_dataset( v )
+ converters = []
+ for converter_name, converter_extensions, converter_datatypes in input.converters:
+ new_data = process_dataset( input_datasets[ prefix + input.name + str( i + 1 ) ], converter_datatypes )
+ if not new_data or isinstance( new_data.datatype, converter_datatypes ):
+ input_datasets[ prefix + converter_name + str( i + 1 ) ] = new_data
+ converters.append( ( converter_name, new_data ) )
+ else:
+ raise Exception, 'A path for explicit datatype conversion has not been found: %s --/--> %s' % ( input_datasets[ prefix + input.name + str( i + 1 ) ].extension, converter_extensions )
if parent:
parent[input.name] = input_datasets[ prefix + input.name + str( i + 1 ) ]
+ for converter_name, converter_data in converters:
+ #allow explicit conversion to be stored in job_parameter table
+ parent[ converter_name ] = converter_data.id #a more robust way to determine JSONable value is desired
else:
param_values[input.name][i] = input_datasets[ prefix + input.name + str( i + 1 ) ]
+ for converter_name, converter_data in converters:
+ #allow explicit conversion to be stored in job_parameter table
+ param_values[ converter_name ][i] = converter_data.id #a more robust way to determine JSONable value is desired
else:
input_datasets[ prefix + input.name ] = process_dataset( value )
- if parent:
- parent[input.name] = input_datasets[ prefix + input.name ]
- else:
- param_values[input.name] = input_datasets[ prefix + input.name ]
+ converters = []
+ for converter_name, converter_extensions, converter_datatypes in input.converters:
+ new_data = process_dataset( input_datasets[ prefix + input.name ], converter_datatypes )
+ if not new_data or isinstance( new_data.datatype, converter_datatypes ):
+ input_datasets[ prefix + converter_name ] = new_data
+ converters.append( ( converter_name, new_data ) )
+ else:
+ raise Exception, 'A path for explicit datatype conversion has not been found: %s --/--> %s' % ( input_datasets[ prefix + input.name ].extension, converter_extensions )
+ target_dict = parent
+ if not target_dict:
+ target_dict = param_values
+ target_dict[ input.name ] = input_datasets[ prefix + input.name ]
+ for converter_name, converter_data in converters:
+ #allow explicit conversion to be stored in job_parameter table
+ target_dict[ converter_name ] = converter_data.id #a more robust way to determine JSONable value is desired
tool.visit_inputs( param_values, visitor )
return input_datasets
diff -r 26f01eafc6bd -r c64ef44ed4c5 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py Mon Feb 08 11:20:44 2010 -0500
+++ b/lib/galaxy/tools/parameters/basic.py Mon Feb 08 12:45:28 2010 -0500
@@ -50,14 +50,14 @@
def get_html( self, trans=None, value=None, other_values={}):
"""
- Returns the html widget corresponding to the paramter.
+ Returns the html widget corresponding to the parameter.
Optionally attempt to retain the current value specific by 'value'
"""
return self.get_html_field( trans, value, other_values ).get_html()
def from_html( self, value, trans=None, other_values={} ):
"""
- Convert a value from an HTML POST into the parameters prefered value
+ Convert a value from an HTML POST into the parameters preferred value
format.
"""
return value
@@ -1168,6 +1168,15 @@
else:
self.options = dynamic_options.DynamicOptions( options, self )
self.is_dynamic = self.options is not None
+ # Load converters required for the dataset input
+ self.converters = []
+ for conv_elem in elem.findall( "converter" ):
+ name = conv_elem.get( "name" ) #name for commandline substitution
+ conv_extensions = conv_elem.get( "type" ) #target datatype extension
+ # FIXME: conv_extensions should be able to be an ordered list
+ assert None not in [ name, type ], 'A name (%s) and type (%s) are required for explicit conversion' % ( name, type )
+ conv_types = tool.app.datatypes_registry.get_datatype_by_extension( conv_extensions.lower() ).__class__
+ self.converters.append( ( name, conv_extensions, conv_types ) )
def get_html_field( self, trans=None, value=None, other_values={} ):
filter_value = None
1
0
09 Feb '10
details: http://www.bx.psu.edu/hg/galaxy/rev/26f01eafc6bd
changeset: 3355:26f01eafc6bd
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Mon Feb 08 11:20:44 2010 -0500
description:
On edit attributes page, only sanitize and add annotation when it exists.
Metadata editing was throwing server error when not logged in.
diffstat:
lib/galaxy/web/controllers/root.py | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diffs (15 lines):
diff -r 4e8785b6815c -r 26f01eafc6bd lib/galaxy/web/controllers/root.py
--- a/lib/galaxy/web/controllers/root.py Mon Feb 08 10:00:30 2010 -0500
+++ b/lib/galaxy/web/controllers/root.py Mon Feb 08 11:20:44 2010 -0500
@@ -307,8 +307,9 @@
setattr( data.metadata, name, spec.unwrap( params.get (name, None) ) )
data.datatype.after_setting_metadata( data )
# Sanitize annotation before adding it.
- annotation = sanitize_html( params.annotation, 'utf-8', 'text/html' )
- self.add_item_annotation( trans, data, annotation )
+ if params.annotation:
+ annotation = sanitize_html( params.annotation, 'utf-8', 'text/html' )
+ self.add_item_annotation( trans, data, annotation )
else:
msg = ' (Metadata could not be changed because this dataset is currently being used as input or output. You must cancel or wait for these jobs to complete before changing metadata.)'
trans.sa_session.flush()
1
0
09 Feb '10
details: http://www.bx.psu.edu/hg/galaxy/rev/4e8785b6815c
changeset: 3354:4e8785b6815c
user: Nate Coraor <nate(a)bx.psu.edu>
date: Mon Feb 08 10:00:30 2010 -0500
description:
Fix from Assaf Gordon for Cheetah syntax errors in the Bar Chart tool.
diffstat:
tools/plotting/bar_chart.py | 1 -
tools/plotting/bar_chart.xml | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diffs (25 lines):
diff -r 390dfb039df7 -r 4e8785b6815c tools/plotting/bar_chart.py
--- a/tools/plotting/bar_chart.py Mon Feb 08 09:53:20 2010 -0500
+++ b/tools/plotting/bar_chart.py Mon Feb 08 10:00:30 2010 -0500
@@ -23,7 +23,6 @@
"""
-from Numeric import *
import Gnuplot, Gnuplot.funcutils
import sys, string, tempfile, os
diff -r 390dfb039df7 -r 4e8785b6815c tools/plotting/bar_chart.xml
--- a/tools/plotting/bar_chart.xml Mon Feb 08 09:53:20 2010 -0500
+++ b/tools/plotting/bar_chart.xml Mon Feb 08 10:00:30 2010 -0500
@@ -1,8 +1,8 @@
<tool id="barchart_gnuplot" name="Bar chart">
<description>for multiple columns</description>
<command interpreter="python">
- #if $xtic.userSpecified == "Yes": #bar_chart.py $input $xtic.xticColumn $colList "$title" "$ylabel" $ymin $ymax $out_file1 "$pdf_size"
- #else: #bar_chart.py $input 0 $colList "$title" "$ylabel" $ymin $ymax $out_file1 "$pdf_size"
+ #if $xtic.userSpecified == "Yes" #bar_chart.py $input $xtic.xticColumn $colList "$title" "$ylabel" $ymin $ymax $out_file1 "$pdf_size"
+ #else #bar_chart.py $input 0 $colList "$title" "$ylabel" $ymin $ymax $out_file1 "$pdf_size"
#end if
</command>
<inputs>
1
0
09 Feb '10
details: http://www.bx.psu.edu/hg/galaxy/rev/390dfb039df7
changeset: 3353:390dfb039df7
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Mon Feb 08 09:53:20 2010 -0500
description:
Refactoring grid code: moved numerous grid column definitions from controller.py to grids.py
diffstat:
lib/galaxy/web/base/controller.py | 83 --------------------------
lib/galaxy/web/controllers/admin.py | 6 +-
lib/galaxy/web/controllers/forms.py | 2 +-
lib/galaxy/web/controllers/history.py | 8 +-
lib/galaxy/web/controllers/library_admin.py | 2 +-
lib/galaxy/web/controllers/page.py | 28 ++++----
lib/galaxy/web/controllers/requests.py | 2 +-
lib/galaxy/web/controllers/requests_admin.py | 4 +-
lib/galaxy/web/controllers/workflow.py | 4 +-
lib/galaxy/web/framework/helpers/grids.py | 89 ++++++++++++++++++++++++++-
10 files changed, 113 insertions(+), 115 deletions(-)
diffs (465 lines):
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/base/controller.py Mon Feb 08 09:53:20 2010 -0500
@@ -9,41 +9,10 @@
from galaxy.web import error, form, url_for
from galaxy.model.orm import *
from galaxy.web.framework.helpers import grids
-from galaxy.util.odict import odict
from Cheetah.Template import Template
log = logging.getLogger( __name__ )
-
-# Useful columns in many grids used by controllers.
-
-class OwnerColumn( grids.TextColumn ):
- """ Column that lists item's owner. """
- def get_value( self, trans, grid, item ):
- return item.user.username
-
-class PublicURLColumn( grids.TextColumn ):
- """ Column displays item's public URL based on username and slug. """
- def get_link( self, trans, grid, item ):
- if item.user.username and item.slug:
- return dict( action='display_by_username_and_slug', username=item.user.username, slug=item.slug )
- elif not item.user.username:
- # TODO: provide link to set username.
- return None
- elif not item.user.slug:
- # TODO: provide link to set slg
- return None
-
-class DeletedColumn( grids.GridColumn ):
- """ Column that tracks and filters for items with deleted attribute. """
- def get_accepted_filters( self ):
- """ Returns a list of accepted filters for this column. """
- accepted_filter_labels_and_vals = { "active" : "False", "deleted" : "True", "all": "All" }
- accepted_filters = []
- for label, val in accepted_filter_labels_and_vals.items():
- args = { self.key: val }
- accepted_filters.append( grids.GridColumnFilter( label, args) )
- return accepted_filters
class BaseController( object ):
"""
@@ -138,58 +107,6 @@
return True
Root = BaseController
-
-class SharingStatusColumn( grids.GridColumn ):
- """ Grid column to indicate sharing status. """
- def get_value( self, trans, grid, item ):
- # Delete items cannot be shared.
- if item.deleted:
- return ""
-
- # Build a list of sharing for this item.
- sharing_statuses = []
- if item.users_shared_with:
- sharing_statuses.append( "Shared" )
- if item.importable:
- sharing_statuses.append( "Accessible" )
- if item.published:
- sharing_statuses.append( "Published" )
- return ", ".join( sharing_statuses )
-
- def get_link( self, trans, grid, item ):
- if not item.deleted and ( item.users_shared_with or item.importable or item.published ):
- return dict( operation="share or publish", id=item.id )
- return None
-
- def filter( self, db_session, user, query, column_filter ):
- """ Modify query to filter histories by sharing status. """
- if column_filter == "All":
- pass
- elif column_filter:
- if column_filter == "private":
- query = query.filter( self.model_class.users_shared_with == None )
- query = query.filter( self.model_class.importable == False )
- elif column_filter == "shared":
- query = query.filter( self.model_class.users_shared_with != None )
- elif column_filter == "accessible":
- query = query.filter( self.model_class.importable == True )
- elif column_filter == "published":
- query = query.filter( self.model_class.published == True )
- return query
-
- def get_accepted_filters( self ):
- """ Returns a list of accepted filters for this column. """
- accepted_filter_labels_and_vals = odict()
- accepted_filter_labels_and_vals["private"] = "private"
- accepted_filter_labels_and_vals["shared"] = "shared"
- accepted_filter_labels_and_vals["accessible"] = "accessible"
- accepted_filter_labels_and_vals["published"] = "published"
- accepted_filter_labels_and_vals["all"] = "All"
- accepted_filters = []
- for label, val in accepted_filter_labels_and_vals.items():
- args = { self.key: val }
- accepted_filters.append( grids.GridColumnFilter( label, args) )
- return accepted_filters
class Sharable:
""" Mixin for a controller that manages and item that can be shared. """
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/controllers/admin.py Mon Feb 08 09:53:20 2010 -0500
@@ -71,7 +71,7 @@
LastLoginColumn( "Last Login", format=time_ago ),
StatusColumn( "Status", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
]
columns.append( grids.MulticolFilterColumn( "Search",
cols_to_filter=[ columns[0], columns[1] ],
@@ -159,7 +159,7 @@
UsersColumn( "Users", attach_popup=False ),
StatusColumn( "Status", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
]
columns.append( grids.MulticolFilterColumn( "Search",
cols_to_filter=[ columns[0], columns[1], columns[2] ],
@@ -225,7 +225,7 @@
RolesColumn( "Roles", attach_popup=False ),
StatusColumn( "Status", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
]
columns.append( grids.MulticolFilterColumn( "Search",
cols_to_filter=[ columns[0], columns[1], columns[2] ],
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/controllers/forms.py
--- a/lib/galaxy/web/controllers/forms.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/controllers/forms.py Mon Feb 08 09:53:20 2010 -0500
@@ -44,7 +44,7 @@
model_class=model.FormDefinition,
filterable="advanced" ),
TypeColumn( "Type" ),
- DeletedColumn( "Deleted",
+ grids.DeletedColumn( "Deleted",
key="deleted",
visible=False,
filterable="advanced" )
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/controllers/history.py
--- a/lib/galaxy/web/controllers/history.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/controllers/history.py Mon Feb 08 09:53:20 2010 -0500
@@ -44,11 +44,11 @@
attach_popup=True, filterable="advanced" ),
DatasetsByStateColumn( "Datasets (by state)", ncells=4 ),
grids.IndividualTagsColumn( "Tags", "tags", model.History, model.HistoryTagAssociation, filterable="advanced", grid_name="HistoryListGrid" ),
- SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False ),
+ grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False ),
grids.GridColumn( "Created", key="create_time", format=time_ago ),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
]
columns.append(
grids.MulticolFilterColumn(
@@ -118,7 +118,7 @@
return query.filter( model.HistoryUserShareAssociation.user == trans.user )
class HistoryAllPublishedGrid( grids.Grid ):
- class NameURLColumn( PublicURLColumn, NameColumn ):
+ class NameURLColumn( grids.PublicURLColumn, NameColumn ):
pass
title = "Published Histories"
@@ -128,7 +128,7 @@
use_async = True
columns = [
NameURLColumn( "Name", key="name", model_class=model.History, filterable="advanced" ),
- OwnerColumn( "Owner", key="username", model_class=model.User, filterable="advanced", sortable=False ),
+ grids.OwnerColumn( "Owner", key="username", model_class=model.User, filterable="advanced", sortable=False ),
grids.CommunityTagsColumn( "Community Tags", "tags", model.History, model.HistoryTagAssociation, filterable="advanced", grid_name="PublicHistoryListGrid" ),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago )
]
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/controllers/library_admin.py
--- a/lib/galaxy/web/controllers/library_admin.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/controllers/library_admin.py Mon Feb 08 09:53:20 2010 -0500
@@ -52,7 +52,7 @@
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
StatusColumn( "Status", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
]
columns.append( grids.MulticolFilterColumn( "Search",
cols_to_filter=[ columns[0], columns[1] ],
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/controllers/page.py
--- a/lib/galaxy/web/controllers/page.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/controllers/page.py Mon Feb 08 09:53:20 2010 -0500
@@ -16,7 +16,7 @@
class PageListGrid( grids.Grid ):
# Custom column.
- class URLColumn( PublicURLColumn ):
+ class URLColumn( grids.PublicURLColumn ):
def get_value( self, trans, grid, item ):
return url_for( action='display_by_username_and_slug', username=item.user.username, slug=item.slug )
@@ -30,7 +30,7 @@
grids.TextColumn( "Title", key="title", model_class=model.Page, attach_popup=True, filterable="advanced" ),
URLColumn( "Public URL" ),
grids.IndividualTagsColumn( "Tags", "tags", model.Page, model.PageTagAssociation, filterable="advanced", grid_name="PageListGrid" ),
- SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False ),
+ grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False ),
grids.GridColumn( "Created", key="create_time", format=time_ago ),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
]
@@ -62,8 +62,8 @@
default_sort_key = "-update_time"
default_filter = dict( title="All", username="All" )
columns = [
- PublicURLColumn( "Title", key="title", model_class=model.Page, filterable="advanced"),
- OwnerColumn( "Owner", key="username", model_class=model.User, filterable="advanced", sortable=False ),
+ grids.PublicURLColumn( "Title", key="title", model_class=model.Page, filterable="advanced"),
+ grids.OwnerColumn( "Owner", key="username", model_class=model.User, filterable="advanced", sortable=False ),
grids.CommunityTagsColumn( "Community Tags", "tags", model.Page, model.PageTagAssociation, filterable="advanced", grid_name="PageAllPublishedGrid" ),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago )
]
@@ -100,8 +100,8 @@
grids.IndividualTagsColumn( "Tags", "tags", model.History, model.HistoryTagAssociation, filterable="advanced"),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
- SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False, visible=False ),
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
+ grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False, visible=False ),
]
columns.append(
grids.MulticolFilterColumn(
@@ -144,8 +144,8 @@
grids.IndividualTagsColumn( "Tags", "tags", model.History, model.HistoryTagAssociation, filterable="advanced"),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
- SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False, visible=False ),
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
+ grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False, visible=False ),
]
columns.append(
grids.MulticolFilterColumn(
@@ -167,8 +167,8 @@
grids.IndividualTagsColumn( "Tags", "tags", model.StoredWorkflow, model.HistoryDatasetAssociationTagAssociation, filterable="advanced"),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
- SharingStatusColumn( "Sharing", key="sharing", model_class=model.HistoryDatasetAssociation, filterable="advanced", sortable=False, visible=False ),
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
+ grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.HistoryDatasetAssociation, filterable="advanced", sortable=False, visible=False ),
]
columns.append(
grids.MulticolFilterColumn(
@@ -192,8 +192,8 @@
grids.IndividualTagsColumn( "Tags", "tags", model.StoredWorkflow, model.StoredWorkflowTagAssociation, filterable="advanced"),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
- SharingStatusColumn( "Sharing", key="sharing", model_class=model.StoredWorkflow, filterable="advanced", sortable=False, visible=False ),
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
+ grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.StoredWorkflow, filterable="advanced", sortable=False, visible=False ),
]
columns.append(
grids.MulticolFilterColumn(
@@ -212,8 +212,8 @@
grids.IndividualTagsColumn( "Tags", "tags", model.Page, model.PageTagAssociation, filterable="advanced"),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
# Columns that are valid for filtering but are not visible.
- DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
- SharingStatusColumn( "Sharing", key="sharing", model_class=model.Page, filterable="advanced", sortable=False, visible=False ),
+ grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
+ grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.Page, filterable="advanced", sortable=False, visible=False ),
]
columns.append(
grids.MulticolFilterColumn(
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/controllers/requests.py
--- a/lib/galaxy/web/controllers/requests.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/controllers/requests.py Mon Feb 08 09:53:20 2010 -0500
@@ -95,7 +95,7 @@
link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), ),
TypeColumn( "Type" ),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
- DeletedColumn( "Deleted",
+ grids.DeletedColumn( "Deleted",
key="deleted",
visible=False,
filterable="advanced" ),
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/controllers/requests_admin.py
--- a/lib/galaxy/web/controllers/requests_admin.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/controllers/requests_admin.py Mon Feb 08 09:53:20 2010 -0500
@@ -107,7 +107,7 @@
TypeColumn( "Type",
link=( lambda item: iff( item.deleted, None, dict( operation="view_type", id=item.type.id ) ) ), ),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
- DeletedColumn( "Deleted",
+ grids.DeletedColumn( "Deleted",
key="deleted",
visible=False,
filterable="advanced" ),
@@ -184,7 +184,7 @@
link=( lambda item: iff( item.deleted, None, dict( operation="view_form", id=item.request_form.id ) ) ), ),
SampleFormColumn( "Sample Form",
link=( lambda item: iff( item.deleted, None, dict( operation="view_form", id=item.sample_form.id ) ) ), ),
- DeletedColumn( "Deleted",
+ grids.DeletedColumn( "Deleted",
key="deleted",
visible=False,
filterable="advanced" )
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/controllers/workflow.py Mon Feb 08 09:53:20 2010 -0500
@@ -59,8 +59,8 @@
default_filter = dict( public_url="All", username="All", tags="All" )
use_async = True
columns = [
- PublicURLColumn( "Name", key="name", model_class=model.StoredWorkflow, filterable="advanced" ),
- OwnerColumn( "Owner", key="username", model_class=model.User, filterable="advanced", sortable=False ),
+ grids.PublicURLColumn( "Name", key="name", model_class=model.StoredWorkflow, filterable="advanced" ),
+ grids.OwnerColumn( "Owner", key="username", model_class=model.User, filterable="advanced", sortable=False ),
grids.CommunityTagsColumn( "Community Tags", "tags", model.StoredWorkflow, model.StoredWorkflowTagAssociation, filterable="advanced", grid_name="PublicWorkflowListGrid" ),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago )
]
diff -r aa81684b9275 -r 390dfb039df7 lib/galaxy/web/framework/helpers/grids.py
--- a/lib/galaxy/web/framework/helpers/grids.py Mon Feb 08 09:03:07 2010 -0500
+++ b/lib/galaxy/web/framework/helpers/grids.py Mon Feb 08 09:53:20 2010 -0500
@@ -5,6 +5,7 @@
from galaxy.tags.tag_handler import TagHandler
from galaxy.web import url_for
from galaxy.util.json import from_json_string, to_json_string
+from galaxy.util.odict import odict
import sys, logging, math
@@ -329,8 +330,8 @@
accepted_filters.append( GridColumnFilter( val, args) )
return accepted_filters
-# Generic column that employs freetext and, hence, supports freetext, case-independent filtering.
class TextColumn( GridColumn ):
+ """ Generic column that employs freetext and, hence, supports freetext, case-independent filtering. """
def filter( self, db_session, user, query, column_filter ):
""" Modify query to filter using free text, case independence. """
if column_filter == "All":
@@ -350,8 +351,8 @@
clause_list.append( func.lower( model_class_key_field ).like( "%" + filter.lower() + "%" ) )
return and_( *clause_list )
-# Column that supports community tags.
class CommunityTagsColumn( TextColumn ):
+ """ Column that supports community tags. """
def __init__( self, col_name, key, model_class, model_tag_association_class, filterable, grid_name=None ):
GridColumn.__init__(self, col_name, key=key, model_class=model_class, filterable=filterable)
self.model_tag_association_class = model_tag_association_class
@@ -386,8 +387,8 @@
clause_list.append( self.model_class.tags.any( func.lower( self.model_tag_association_class.user_value ).like( "%" + value.lower() + "%" ) ) )
return and_( *clause_list )
-# Column that supports individual tags.
class IndividualTagsColumn( CommunityTagsColumn ):
+ """ Column that supports individual tags. """
def get_value( self, trans, grid, item ):
return trans.fill_template( "/tagging_common.mako", tag_type="individual", trans=trans, user=trans.get_user(), tagged_item=item, elt_context=self.grid_name,
in_form=True, input_size="20", tag_click_fn="add_tag_to_grid_filter" )
@@ -408,8 +409,8 @@
clause_list.append( self.model_class.tags.any( and_( func.lower( self.model_tag_association_class.user_value ).like( "%" + value.lower() + "%" ), self.model_tag_association_class.user == user ) ) )
return and_( *clause_list )
-# Column that performs multicolumn filtering.
class MulticolFilterColumn( TextColumn ):
+ """ Column that performs multicolumn filtering. """
def __init__( self, col_name, cols_to_filter, key, visible, filterable="default" ):
GridColumn.__init__( self, col_name, key=key, visible=visible, filterable=filterable)
self.cols_to_filter = cols_to_filter
@@ -432,6 +433,86 @@
complete_filter = or_( *clause_list )
return query.filter( complete_filter )
+
+class OwnerColumn( TextColumn ):
+ """ Column that lists item's owner. """
+ def get_value( self, trans, grid, item ):
+ return item.user.username
+
+class PublicURLColumn( TextColumn ):
+ """ Column displays item's public URL based on username and slug. """
+ def get_link( self, trans, grid, item ):
+ if item.user.username and item.slug:
+ return dict( action='display_by_username_and_slug', username=item.user.username, slug=item.slug )
+ elif not item.user.username:
+ # TODO: provide link to set username.
+ return None
+ elif not item.user.slug:
+ # TODO: provide link to set slg
+ return None
+
+class DeletedColumn( GridColumn ):
+ """ Column that tracks and filters for items with deleted attribute. """
+ def get_accepted_filters( self ):
+ """ Returns a list of accepted filters for this column. """
+ accepted_filter_labels_and_vals = { "active" : "False", "deleted" : "True", "all": "All" }
+ accepted_filters = []
+ for label, val in accepted_filter_labels_and_vals.items():
+ args = { self.key: val }
+ accepted_filters.append( GridColumnFilter( label, args) )
+ return accepted_filters
+
+class SharingStatusColumn( GridColumn ):
+ """ Grid column to indicate sharing status. """
+ def get_value( self, trans, grid, item ):
+ # Delete items cannot be shared.
+ if item.deleted:
+ return ""
+
+ # Build a list of sharing for this item.
+ sharing_statuses = []
+ if item.users_shared_with:
+ sharing_statuses.append( "Shared" )
+ if item.importable:
+ sharing_statuses.append( "Accessible" )
+ if item.published:
+ sharing_statuses.append( "Published" )
+ return ", ".join( sharing_statuses )
+
+ def get_link( self, trans, grid, item ):
+ if not item.deleted and ( item.users_shared_with or item.importable or item.published ):
+ return dict( operation="share or publish", id=item.id )
+ return None
+
+ def filter( self, db_session, user, query, column_filter ):
+ """ Modify query to filter histories by sharing status. """
+ if column_filter == "All":
+ pass
+ elif column_filter:
+ if column_filter == "private":
+ query = query.filter( self.model_class.users_shared_with == None )
+ query = query.filter( self.model_class.importable == False )
+ elif column_filter == "shared":
+ query = query.filter( self.model_class.users_shared_with != None )
+ elif column_filter == "accessible":
+ query = query.filter( self.model_class.importable == True )
+ elif column_filter == "published":
+ query = query.filter( self.model_class.published == True )
+ return query
+
+ def get_accepted_filters( self ):
+ """ Returns a list of accepted filters for this column. """
+ accepted_filter_labels_and_vals = odict()
+ accepted_filter_labels_and_vals["private"] = "private"
+ accepted_filter_labels_and_vals["shared"] = "shared"
+ accepted_filter_labels_and_vals["accessible"] = "accessible"
+ accepted_filter_labels_and_vals["published"] = "published"
+ accepted_filter_labels_and_vals["all"] = "All"
+ accepted_filters = []
+ for label, val in accepted_filter_labels_and_vals.items():
+ args = { self.key: val }
+ accepted_filters.append( GridColumnFilter( label, args) )
+ return accepted_filters
class GridOperation( object ):
def __init__( self, label, key=None, condition=None, allow_multiple=True, allow_popup=True, target=None, url_args=None, async_compatible=False, confirm=None ):
1
0