galaxy-commits
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
- 15302 discussions
galaxy-dist commit 1cd9009036f7: Constrain connection to correct outputs when using ChangeDatatypeAction in workflow editor.
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dannon Baker <dannonbaker(a)me.com>
# Date 1283208488 14400
# Node ID 1cd9009036f729c8d36fe40db6cbfd6508c3a635
# Parent a8a59549ca5fcad2769db585a051d4c4bb45f27d
Constrain connection to correct outputs when using ChangeDatatypeAction in workflow editor.
--- a/static/scripts/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/galaxy.workflow_editor.canvas.js
@@ -50,10 +50,8 @@ InputTerminal.prototype = new Terminal()
if (other.node.post_job_actions){
for (var pja_i in other.node.post_job_actions){
var pja = other.node.post_job_actions[pja_i];
- if (pja.action_type == "ChangeDatatypeAction"){
- if (pja.action_arguments){
- cat_outputs.push(pja.action_arguments['newtype']);
- }
+ if (pja.action_type == "ChangeDatatypeAction" && (pja.output_name == '' || pja.output_name == other.name) && pja.action_arguments){
+ cat_outputs.push(pja.action_arguments['newtype']);
}
}
}
1
0
galaxy-dist commit 651228876e99: Don't re-sort BAM files on upload if already sorted (adapted from Brad Chapman patch). Closes #356
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1283193484 14400
# Node ID 651228876e99e39af9c2f0cef70f8d60780f2b71
# Parent 4058759b77518b40561719af15f191d809642b1f
Don't re-sort BAM files on upload if already sorted (adapted from Brad Chapman patch). Closes #356
--- a/lib/galaxy/datatypes/binary.py
+++ b/lib/galaxy/datatypes/binary.py
@@ -50,7 +50,15 @@ class Ab1( Binary ):
class Bam( Binary ):
"""Class describing a BAM binary file"""
file_ext = "bam"
- MetadataElement( name="bam_index", desc="BAM Index File", param=metadata.FileParameter, readonly=True, no_value=None, visible=False, optional=True )
+ MetadataElement( name="bam_index", desc="BAM Index File", param=metadata.FileParameter, readonly=True, no_value=None, visible=False, optional=True )
+
+ def _is_coordinate_sorted(self, filename):
+ """Check if the input BAM file is sorted from the header information.
+ """
+ params = ["samtools", "view", "-H", filename]
+ output = subprocess.Popen(params, stderr=subprocess.PIPE, stdout=subprocess.PIPE).communicate()[0]
+ # find returns -1 if string is not found
+ return output.find("SO:coordinate") != -1 or output.find("SO:sorted") != -1
def groom_dataset_content( self, file_name ):
"""
@@ -63,8 +71,12 @@ class Bam( Binary ):
## Sort alignments by leftmost coordinates. File <out.prefix>.bam will be created.
## This command may also create temporary files <out.prefix>.%d.bam when the
## whole alignment cannot be fitted into memory ( controlled by option -m ).
+ #do this in a unique temp directory, because of possible <out.prefix>.%d.bam temp files
- #do this in a unique temp directory, because of possible <out.prefix>.%d.bam temp files
+ if self._is_coordinate_sorted(file_name):
+ # Don't re-sort if already sorted
+ return
+
tmp_dir = tempfile.mkdtemp()
tmp_sorted_dataset_file_name_prefix = os.path.join( tmp_dir, 'sorted' )
stderr_name = tempfile.NamedTemporaryFile( dir = tmp_dir, prefix = "bam_sort_stderr" ).name
1
0
galaxy-dist commit 667fb4f9cd16: lims: added basic UI framework for operations on multiple samples
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1283200417 14400
# Node ID 667fb4f9cd16237bb74b15c13e7ff5f166a89177
# Parent 651228876e99e39af9c2f0cef70f8d60780f2b71
lims: added basic UI framework for operations on multiple samples
- first pass for state change mechanism for multiple samples
- UI enhancements: checkboxes to select samples & selectfield to select specific operation
- removed state change UI for individual samples in the sample_events page
next is selecting library for multiple samples
--- a/scripts/galaxy_messaging/server/galaxyweb_interface.py
+++ b/scripts/galaxy_messaging/server/galaxyweb_interface.py
@@ -106,11 +106,10 @@ class GalaxyWebInterface(object):
# Encrypt
return id_cipher.encrypt( s ).encode( 'hex' )
- def update_request_state(self, request_id, sample_id):
+ def update_request_state(self, request_id):
params = urllib.urlencode(dict( cntrller='requests_admin',
- request_id=request_id,
- sample_id=sample_id))
- url = self.base_url + "/requests_admin/update_request_state"
+ request_id=request_id))
+ url = self.base_url + "/requests_common/update_request_state"
f = self.opener.open(url, params)
print url
print params
--- a/scripts/galaxy_messaging/server/amqp_consumer.py
+++ b/scripts/galaxy_messaging/server/amqp_consumer.py
@@ -108,7 +108,7 @@ def recv_callback(msg):
webconfig.get("data_transfer_user_login_info", "email"),
webconfig.get("data_transfer_user_login_info", "password"),
config.get("app:main", "id_secret"))
- galaxyweb.update_request_state(galaxydb.get_request_id(sample_id), sample_id)
+ galaxyweb.update_request_state(galaxydb.get_request_id(sample_id))
galaxyweb.logout()
def main():
--- a/templates/requests/common/sample_events.mako
+++ b/templates/requests/common/sample_events.mako
@@ -45,28 +45,3 @@
</tbody></table></div>
-%if cntrller == 'requests_admin' and trans.user_is_admin():
- <div class="toolForm">
- <div class="toolFormTitle">Change current state</div>
- <div class="toolFormBody">
- <form name="event" action="${h.url_for( controller='requests_admin', action='save_state', new=True, sample_id=sample.id)}" method="post" >
- %for w in widgets:
- <div class="form-row">
- <label>
- ${w[0]}
- </label>
- ${w[1].get_html()}
- %if w[0] == 'Comments':
- <div class="toolParamHelp" style="clear: both;">
- Optional
- </div>
- %endif
- </div>
- %endfor
- <div class="form-row">
- <input type="submit" name="add_event_button" value="Save"/>
- </div>
- </form>
- </div>
- </div>
-%endif
--- a/test/functional/test_forms_and_requests.py
+++ b/test/functional/test_forms_and_requests.py
@@ -301,8 +301,8 @@ class TestFormsAndRequests( TwillTestCas
self.add_bar_codes( request_one.id, request_one.name, bar_codes, request_one.samples )
# change the states of all the samples of this request
for sample in request_one.samples:
- self.change_sample_state( sample.name, sample.id, request_type.states[1].id, request_type.states[1].name )
- self.change_sample_state( sample.name, sample.id, request_type.states[2].id, request_type.states[2].name )
+ self.change_sample_state( request_one.id, request_one.name, sample.name, sample.id, request_type.states[1].id, request_type.states[1].name )
+ self.change_sample_state( request_one.id, request_one.name, sample.name, sample.id, request_type.states[2].id, request_type.states[2].name )
self.home()
sa_session.refresh( request_one )
self.logout()
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -1629,6 +1629,7 @@ All samples in state: %(sample_state
event = trans.app.model.RequestEvent(self, self.state(), comments)
trans.sa_session.add(event)
trans.sa_session.flush()
+ return comments
class RequestEvent( object ):
def __init__(self, request=None, request_state=None, comment=''):
@@ -1651,6 +1652,28 @@ class RequestType( object ):
self.datatx_info = datatx_info
def last_state(self):
return self.states[-1]
+
+ def change_state_widgets(self, trans, sample=None):
+ if sample:
+ curr_state = sample.current_state()
+ else:
+ curr_state = self.states[0]
+ states_input = SelectField('select_state')
+ for state in self.states:
+ if curr_state.name == state.name:
+ states_input.add_option(state.name, state.id, selected=True)
+ else:
+ states_input.add_option(state.name, state.id)
+ widgets = []
+ if sample:
+ widgets.append(('Select the new state of the sample from the list of possible state(s)',
+ states_input))
+ else:
+ widgets.append(('Select the new state of the selected sample(s) from the list of possible state(s)',
+ states_input))
+ widgets.append(('Comments', TextArea('comment')))
+ title = 'Change current state'
+ return widgets, title
class RequestTypePermissions( object ):
def __init__( self, action, request_type, role ):
@@ -1659,6 +1682,8 @@ class RequestTypePermissions( object ):
self.role = role
class Sample( object ):
+ bulk_operations = Bunch(CHANGE_STATE = 'Change state',
+ SELECT_LIBRARY = 'Select data library and folder')
transfer_status = Bunch( NOT_STARTED = 'Not started',
IN_QUEUE = 'In queue',
TRANSFERRING = 'Transferring dataset',
--- a/lib/galaxy/web/controllers/requests_common.py
+++ b/lib/galaxy/web/controllers/requests_common.py
@@ -515,7 +515,7 @@ class RequestsCommon( BaseController, Us
@web.require_login( "create/submit sequencing requests" )
def events(self, trans, **kwd):
params = util.Params( kwd )
- cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) )
+ cntrller = params.get( 'cntrller', 'requests' )
try:
request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) )
except:
@@ -533,21 +533,63 @@ class RequestsCommon( BaseController, Us
cntrller=cntrller,
events_list=events_list, request=request)
@web.expose
- @web.require_login( "create/submit sequencing requests" )
- def settings(self, trans, **kwd):
+ @web.require_admin
+ def update_request_state( self, trans, **kwd ):
params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
cntrller = params.get( 'cntrller', 'requests' )
try:
- request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) )
+ request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) )
except:
+ return trans.response.send_redirect( web.url_for( controller='requests_admin',
+ action='list',
+ status='error',
+ message="Invalid request ID",
+ **kwd) )
+ # check if all the samples of the current request are in the sample state
+ common_state = request.common_state()
+ if not common_state:
+ # if the current request state is complete and one of its samples moved from
+ # the final sample state, then move the request state to In-progress
+ if request.complete():
+ status='done'
+ message = "One or more samples' state moved from the final sample state. Now request in '%s' state" % request.states.SUBMITTED
+ event = trans.app.model.RequestEvent(request, request.states.SUBMITTED, message)
+ trans.sa_session.add( event )
+ trans.sa_session.flush()
+ else:
+ message = ''
+ status = 'ok'
return trans.response.send_redirect( web.url_for( controller=cntrller,
action='list',
- status='error',
- message="Invalid request ID") )
- return trans.fill_template( '/requests/common/settings.mako',
- cntrller=cntrller, request=request)
-
+ operation='show',
+ id=trans.security.encode_id(request.id),
+ status=status,
+ message=message ) )
+ final_state = False
+ if common_state.id == request.type.last_state().id:
+ # since all the samples are in the final state, change the request state to 'Complete'
+ comments = "All samples of this request are in the last sample state (%s). " % request.type.last_state().name
+ state = request.states.COMPLETE
+ final_state = True
+ else:
+ comments = "All samples are in %s state. " % common_state.name
+ state = request.states.SUBMITTED
+ event = trans.app.model.RequestEvent(request, state, comments)
+ trans.sa_session.add( event )
+ trans.sa_session.flush()
+ # check if an email notification is configured to be sent when the samples
+ # are in this state
+ retval = request.send_email_notification(trans, common_state, final_state)
+ if retval:
+ message = comments + retval
+ else:
+ message = comments
+ return trans.response.send_redirect( web.url_for( controller=cntrller,
+ action='list',
+ operation='show',
+ id=trans.security.encode_id(request.id),
+ status='done',
+ message=message ) )
@web.expose
@web.require_login( "create/submit sequencing requests" )
def show(self, trans, **kwd):
@@ -588,9 +630,10 @@ class RequestsCommon( BaseController, Us
folder_widget=folder_widget))
return trans.fill_template( '/requests/common/show_request.mako',
cntrller=cntrller,
- request=request,
+ request=request, selected_samples=[],
request_details=self.request_details(trans, request.id),
current_samples=current_samples,
+ sample_ops=self.__sample_operation_selectbox(trans, request, **kwd),
sample_copy=self.__copy_sample(current_samples),
details='hide', edit_mode=util.restore_text( params.get( 'edit_mode', 'False' ) ),
message=message, status=status )
@@ -663,7 +706,7 @@ class RequestsCommon( BaseController, Us
else:
break
return current_samples, details, edit_mode, libraries
-
+
def __library_widgets(self, trans, user, sample_index, libraries, sample=None, lib_id=None, folder_id=None, **kwd):
'''
This method creates the data library & folder selectbox for creating &
@@ -736,7 +779,6 @@ class RequestsCommon( BaseController, Us
else:
folder_widget.add_option(f.name, f.id)
return lib_widget, folder_widget
-
def __copy_sample(self, current_samples):
copy_list = SelectField('copy_sample')
copy_list.add_option('None', -1, selected=True)
@@ -744,6 +786,44 @@ class RequestsCommon( BaseController, Us
copy_list.add_option(s['name'], i)
return copy_list
+ def __sample_operation_selectbox(self, trans, request, **kwd):
+ params = util.Params( kwd )
+ cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) )
+ if cntrller == 'requests_admin' and trans.user_is_admin():
+ if request.complete():
+ bulk_operations = [trans.app.model.Sample.bulk_operations.CHANGE_STATE]
+ if request.rejected():
+ bulk_operations = [trans.app.model.Sample.bulk_operations.SELECT_LIBRARY]
+ else:
+ bulk_operations = [s for i, s in trans.app.model.Sample.bulk_operations.items()]
+ else:
+ if request.complete():
+ bulk_operations = []
+ else:
+ bulk_operations = [trans.app.model.Sample.bulk_operations.SELECT_LIBRARY]
+ op_list = SelectField('select_sample_operation',
+ refresh_on_change=True,
+ refresh_on_change_values=bulk_operations)
+ sel_op = kwd.get('select_sample_operation', 'none')
+ if sel_op == 'none':
+ op_list.add_option('Select operation', 'none', True)
+ else:
+ op_list.add_option('Select operation', 'none')
+ for s in bulk_operations:
+ if s == sel_op:
+ op_list.add_option(s, s, True)
+ else:
+ op_list.add_option(s, s)
+ return op_list
+
+ def __selected_samples(self, trans, request, **kwd):
+ params = util.Params( kwd )
+ selected_samples = []
+ for s in request.samples:
+ if CheckboxField.is_checked(params.get('select_sample_%i' % s.id, '')):
+ selected_samples.append(s.id)
+ return selected_samples
+
@web.expose
@web.require_login( "create/submit sequencing requests" )
def request_page(self, trans, **kwd):
@@ -760,6 +840,15 @@ class RequestsCommon( BaseController, Us
message="Invalid request ID") )
# get the user entered sample details
current_samples, details, edit_mode, libraries = self.__update_samples( trans, request, **kwd )
+ selected_samples = self.__selected_samples(trans, request, **kwd)
+ sample_ops = self.__sample_operation_selectbox(trans, request,**kwd)
+ if params.get('select_sample_operation', 'none') != 'none' and not len(selected_samples):
+ return trans.response.send_redirect( web.url_for( controller=cntrller,
+ action='list',
+ operation='show',
+ id=trans.security.encode_id(request.id),
+ status='error',
+ message='Select at least one sample before selecting an operation.' ))
if params.get('import_samples_button', False) == 'Import samples':
return self.__import_samples(trans, cntrller, request, current_samples, details, libraries, **kwd)
elif params.get('add_sample_button', False) == 'Add New':
@@ -805,7 +894,8 @@ class RequestsCommon( BaseController, Us
request_details=self.request_details(trans, request.id),
current_samples=current_samples,
sample_copy=self.__copy_sample(current_samples),
- details=details,
+ details=details, selected_samples=selected_samples,
+ sample_ops=sample_ops,
edit_mode=edit_mode)
elif params.get('save_samples_button', False) == 'Save':
# check for duplicate sample names
@@ -826,11 +916,12 @@ class RequestsCommon( BaseController, Us
if message:
return trans.fill_template( '/requests/common/show_request.mako',
cntrller=cntrller,
- request=request,
+ request=request, selected_samples=selected_samples,
request_details=self.request_details(trans, request.id),
current_samples = current_samples,
sample_copy=self.__copy_sample(current_samples),
details=details, edit_mode=edit_mode,
+ sample_ops=sample_ops,
status='error', message=message)
# save all the new/unsaved samples entered by the user
if edit_mode == 'False':
@@ -899,10 +990,11 @@ class RequestsCommon( BaseController, Us
edit_mode = 'True'
return trans.fill_template( '/requests/common/show_request.mako',
cntrller=cntrller,
- request=request,
+ request=request, selected_samples=selected_samples,
request_details=self.request_details(trans, request.id),
current_samples=current_samples,
sample_copy=self.__copy_sample(current_samples),
+ sample_ops=sample_ops,
details=details, libraries=libraries,
edit_mode=edit_mode)
elif params.get('cancel_changes_button', False) == 'Cancel':
@@ -910,14 +1002,33 @@ class RequestsCommon( BaseController, Us
action='list',
operation='show',
id=trans.security.encode_id(request.id)) )
+ elif params.get('change_state_button', False) == 'Save':
+ comments = util.restore_text( params.comment )
+ selected_state = int( params.select_state )
+ new_state = trans.sa_session.query( trans.app.model.SampleState ).get( selected_state )
+ for sample_id in selected_samples:
+ sample = trans.sa_session.query( trans.app.model.Sample ).get( sample_id )
+ event = trans.app.model.SampleEvent(sample, new_state, comments)
+ trans.sa_session.add( event )
+ trans.sa_session.flush()
+ return trans.response.send_redirect( web.url_for( controller='requests_common',
+ cntrller=cntrller,
+ action='update_request_state',
+ request_id=request.id ))
+ elif params.get('change_state_button', False) == 'Cancel':
+ return trans.response.send_redirect( web.url_for( controller=cntrller,
+ action='list',
+ operation='show',
+ id=trans.security.encode_id(request.id)) )
else:
return trans.fill_template( '/requests/common/show_request.mako',
- cntrller=cntrller,
- request=request,
+ cntrller=cntrller,
+ request=request, selected_samples=selected_samples,
request_details=self.request_details(trans, request.id),
current_samples=current_samples,
sample_copy=self.__copy_sample(current_samples),
details=details, libraries=libraries,
+ sample_ops=sample_ops,
edit_mode=edit_mode, status=status, message=message)
def __import_samples(self, trans, cntrller, request, current_samples, details, libraries, **kwd):
@@ -1014,21 +1125,12 @@ class RequestsCommon( BaseController, Us
trans.sa_session.delete( s.values )
trans.sa_session.delete( s )
trans.sa_session.flush()
- del current_samples[sample_index]
return trans.response.send_redirect( web.url_for( controller=cntrller,
action='list',
operation='show',
id=trans.security.encode_id(request.id),
status='done',
message='Sample <b>%s</b> has been deleted.' % sample_name ))
- return trans.fill_template( '/requests/common/show_request.mako',
- controller=cntrller,
- request=request,
- request_details=self.request_details(trans, request.id),
- current_samples = current_samples,
- sample_copy=self.__copy_sample(current_samples),
- details=details,
- edit_mode=edit_mode)
def request_details(self, trans, id):
'''
Shows the request details
@@ -1087,11 +1189,10 @@ class RequestsCommon( BaseController, Us
events_list.append((event.state.name, event.state.desc,
time_ago(event.update_time),
event.comment))
- widgets, title = self.__change_state_widgets(trans, sample)
return trans.fill_template( '/requests/common/sample_events.mako',
cntrller=cntrller,
events_list=events_list,
- sample=sample, widgets=widgets, title=title)
+ sample=sample)
def __change_state_widgets(self, trans, sample):
possible_states = sample.request.type.states
curr_state = sample.current_state()
--- a/lib/galaxy/web/controllers/requests_admin.py
+++ b/lib/galaxy/web/controllers/requests_admin.py
@@ -321,8 +321,6 @@ class RequestsAdmin( BaseController, Use
return self.__reject_request( trans, **kwd )
elif operation == "view_type":
return self.__view_request_type( trans, **kwd )
- elif operation == "upload_datasets":
- return self.__upload_datasets( trans, **kwd )
# Render the grid view
return self.request_grid( trans, **kwd )
@@ -399,191 +397,6 @@ class RequestsAdmin( BaseController, Use
action='list',
status='done',
message='Request <b>%s</b> has been rejected.' % request.name) )
-
- def __upload_datasets(self, trans, **kwd):
- return trans.fill_template( '/admin/requests/upload_datasets.mako' )
-
-
- @web.expose
- @web.require_admin
- def bar_codes(self, trans, **kwd):
- params = util.Params( kwd )
- message = util.restore_text( params.get( 'message', '' ) )
- status = params.get( 'status', 'done' )
- request_id = params.get( 'request_id', None )
- if request_id:
- request = trans.sa_session.query( trans.app.model.Request ).get( int( request_id ))
- if not request:
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- action='list',
- status='error',
- message="Invalid request ID",
- **kwd) )
- widgets = []
- for index, sample in enumerate(request.samples):
- if sample.bar_code:
- bc = sample.bar_code
- else:
- bc = util.restore_text(params.get('sample_%i_bar_code' % index, ''))
- widgets.append(TextField('sample_%i_bar_code' % index,
- 40,
- bc))
- return trans.fill_template( '/admin/samples/bar_codes.mako',
- samples_list=[s for s in request.samples],
- user=request.user, request=request, widgets=widgets,
- status=status,
- message=message)
- @web.expose
- @web.require_admin
- def save_bar_codes(self, trans, **kwd):
- params = util.Params( kwd )
- try:
- request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) )
- except:
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- action='list',
- status='error',
- message="Invalid request ID",
- **kwd) )
- # validate
- # bar codes need to be globally unique
- message = ''
- for index in range(len(request.samples)):
- bar_code = util.restore_text(params.get('sample_%i_bar_code' % index, ''))
- # check for empty bar code
- if not bar_code.strip():
- message = 'Please fill the barcode for sample <b>%s</b>.' % request.samples[index].name
- break
- # check all the unsaved bar codes
- count = 0
- for i in range(len(request.samples)):
- if bar_code == util.restore_text(params.get('sample_%i_bar_code' % i, '')):
- count = count + 1
- if count > 1:
- message = '''The barcode <b>%s</b> of sample <b>%s</b> belongs
- another sample in this request. The sample barcodes must
- be unique throughout the system''' % \
- (bar_code, request.samples[index].name)
- break
- # check all the saved bar codes
- all_samples = trans.sa_session.query( trans.app.model.Sample )
- for sample in all_samples:
- if bar_code == sample.bar_code:
- message = '''The bar code <b>%s</b> of sample <b>%s</b>
- belongs another sample. The sample bar codes must be
- unique throughout the system''' % \
- (bar_code, request.samples[index].name)
- break
- if message:
- break
- if message:
- widgets = []
- for index, sample in enumerate(request.samples):
- if sample.bar_code:
- bc = sample.bar_code
- else:
- bc = util.restore_text(params.get('sample_%i_bar_code' % index, ''))
- widgets.append(TextField('sample_%i_bar_code' % index,
- 40,
- util.restore_text(params.get('sample_%i_bar_code' % index, ''))))
- return trans.fill_template( '/admin/samples/bar_codes.mako',
- samples_list=[s for s in request.samples],
- user=request.user, request=request, widgets=widgets, status='error',
- message=message)
- # now save the bar codes
- for index, sample in enumerate(request.samples):
- bar_code = util.restore_text(params.get('sample_%i_bar_code' % index, ''))
- sample.bar_code = bar_code
- trans.sa_session.add( sample )
- trans.sa_session.flush()
- # change the state of all the samples to the next state
- # get the new state
- new_state = request.type.states[1]
- for s in request.samples:
- event = trans.app.model.SampleEvent(s, new_state, 'Bar code added to this sample')
- trans.sa_session.add( event )
- trans.sa_session.flush()
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- action='list',
- operation='show_request',
- id=trans.security.encode_id(request.id),
- message='Bar codes have been saved for this request',
- status='done'))
- @web.expose
- @web.require_admin
- def update_request_state( self, trans, **kwd ):
- params = util.Params( kwd )
- try:
- request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) )
- sample_id = int(params.get('sample_id', False))
- except:
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- action='list',
- status='error',
- message="Invalid request ID",
- **kwd) )
- # check if all the samples of the current request are in the sample state
- common_state = request.common_state()
- if not common_state:
- # if the current request state is complete and one of its samples moved from
- # the final sample state, then move the request state to In-progress
- if request.complete():
- event = trans.app.model.RequestEvent(request, request.states.SUBMITTED, "One or more samples' state moved from the final sample state.")
- trans.sa_session.add( event )
- trans.sa_session.flush()
- return trans.response.send_redirect( web.url_for( controller='requests_common',
- cntrller='requests_admin',
- action='sample_events',
- sample_id=sample_id))
- final_state = False
- if common_state.id == request.type.last_state().id:
- # since all the samples are in the final state, change the request state to 'Complete'
- comments = "All samples of this request are in the last sample state (%s)." % request.type.last_state().name
- state = request.states.COMPLETE
- final_state = True
- else:
- comments = "All samples are in %s state." % common_state.name
- state = request.states.SUBMITTED
- event = trans.app.model.RequestEvent(request, state, comments)
- trans.sa_session.add( event )
- trans.sa_session.flush()
- # check if an email notification is configured to be sent when the samples
- # are in this state
-# if common_state.id in request.notification['sample_states']:
- request.send_email_notification(trans, common_state, final_state)
- return trans.response.send_redirect( web.url_for( controller='requests_common',
- cntrller='requests_admin',
- action='sample_events',
- sample_id=sample_id))
-
- @web.expose
- @web.require_admin
- def save_state(self, trans, **kwd):
- params = util.Params( kwd )
- try:
- sample_id = int(params.get('sample_id', False))
- sample = trans.sa_session.query( trans.app.model.Sample ).get( sample_id )
- except:
- message = "Invalid sample ID"
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- action='list',
- status='error',
- message=message,
- **kwd) )
- comments = util.restore_text( params.comment )
- selected_state = int( params.select_state )
- new_state = trans.sa_session.query( trans.app.model.SampleState ) \
- .filter( and_( trans.app.model.SampleState.table.c.request_type_id == sample.request.type.id,
- trans.app.model.SampleState.table.c.id == selected_state ) ) \
- .first()
- event = trans.app.model.SampleEvent(sample, new_state, comments)
- trans.sa_session.add( event )
- trans.sa_session.flush()
- return trans.response.send_redirect( web.url_for( controller='requests_admin',
- cntrller='requests_admin',
- action='update_request_state',
- request_id=sample.request.id,
- sample_id=sample.id))
#
# Data transfer from sequencer
#
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -1562,13 +1562,17 @@ class TwillTestCase( unittest.TestCase )
self.check_page_for_string( 'Changes made to the sample(s) are saved.' )
for index, bar_code in enumerate(bar_codes):
self.check_page_for_string( bar_code )
- def change_sample_state( self, sample_name, sample_id, new_state_id, new_state_name, comment='' ):
+ def change_sample_state( self, request_id, request_name, sample_name, sample_id, new_state_id, new_state_name, comment='' ):
self.home()
+ url = "%s/requests/list?operation=show&id=%s" % ( self.url, self.security.encode_id( request_id ) )
+ self.visit_url( url )
+ self.check_page_for_string( 'Sequencing Request "%s"' % request_name )
+ url = "%s/requests_common/request_page?cntrller=requests_admin&edit_mode=False&id=%s&comment=%s&change_state_button=Save&select_sample_operation=%s&refresh=true&select_sample_%i=true&select_sample_%i=true&select_state=%i" % \
+ (self.url, self.security.encode_id( request_id ), comment, "Change%20state", sample_id, sample_id, new_state_id )
+ self.visit_url( url )
+ self.check_page_for_string( 'Sequencing Request "%s"' % request_name )
self.visit_url( "%s/requests_common/sample_events?cntrller=requests_admin&sample_id=%i" % (self.url, sample_id) )
self.check_page_for_string( 'Events for Sample "%s"' % sample_name )
- tc.fv( "1", "select_state", str(new_state_id) )
- tc.fv( "1", "comment", comment )
- tc.submit( "add_event_button" )
self.check_page_for_string( new_state_name )
def add_user_address( self, user_id, address_dict ):
self.home()
--- a/templates/requests/common/show_request.mako
+++ b/templates/requests/common/show_request.mako
@@ -113,6 +113,36 @@ function showContent(vThis)
}
});
};
+
+ function checkAllFields()
+ {
+ var chkAll = document.getElementById('checkAll');
+ var checks = document.getElementsByTagName('input');
+ var boxLength = checks.length;
+ var allChecked = false;
+ var totalChecked = 0;
+ if ( chkAll.checked == true )
+ {
+ for ( i=0; i < boxLength; i++ )
+ {
+ if ( checks[i].name.indexOf( 'select_sample_' ) != -1)
+ {
+ checks[i].checked = true;
+ }
+ }
+ }
+ else
+ {
+ for ( i=0; i < boxLength; i++ )
+ {
+ if ( checks[i].name.indexOf( 'select_sample_' ) != -1)
+ {
+ checks[i].checked = false
+ }
+ }
+ }
+ }
+
</script><style type="text/css">
@@ -261,6 +291,40 @@ function showContent(vThis)
%if current_samples:
## first render the basic info grid
${render_basic_info_grid()}
+ %if not request.new() and edit_mode == 'False' and len(sample_ops.options) > 1:
+ <div class="form-row" style="background-color:#FAFAFA;">
+ For selected sample(s):
+ ${sample_ops.get_html()}
+ </div>
+ %if 'none' not in sample_ops.get_selected() and len(selected_samples):
+ <div class="form-row" style="background-color:#FAFAFA;">
+ %if trans.app.model.Sample.bulk_operations.CHANGE_STATE in sample_ops.get_selected():
+ <%
+ widgets, title = request.type.change_state_widgets(trans)
+ %>
+ %for w in widgets:
+ <div class="form-row">
+ <label>
+ ${w[0]}:
+ </label>
+ ${w[1].get_html()}
+ %if w[0] == 'Comments':
+ <div class="toolParamHelp" style="clear: both;">
+ Optional
+ </div>
+ %endif
+ </div>
+ %endfor
+ <div class="form-row">
+ <input type="submit" name="change_state_button" value="Save"/>
+ <input type="submit" name="change_state_button" value="Cancel"/>
+ </div>
+ %elif trans.app.model.Sample.bulk_operations.SELECT_LIBRARY in sample_ops.get_selected():
+ ${current_samples[0]}
+ %endif
+ </div>
+ %endif
+ %endif
## then render the other grid(s)
<% trans.sa_session.refresh( request.type.sample_form ) %>
%for grid_index, grid_name in enumerate(request.type.sample_form.layout):
@@ -407,6 +471,7 @@ function showContent(vThis)
<table class="grid"><thead><tr>
+ <th><input type="checkbox" id="checkAll" name=select_all_samples value="true" onclick='checkAllFields(1);'><input type="hidden" name=select_all_samples value="true"></th><th>Name</th><th>Barcode</th><th>State</th>
@@ -436,6 +501,11 @@ function showContent(vThis)
%else:
<tr>
%if sample_index in range(len(request.samples)):
+ %if sample.id in selected_samples:
+ <td><input type="checkbox" name=select_sample_${sample.id} id="sample_checkbox" value="true" checked><input type="hidden" name=select_sample_${sample.id} id="sample_checkbox" value="true"></td>
+ %else:
+ <td><input type="checkbox" name=select_sample_${sample.id} id="sample_checkbox" value="true"><input type="hidden" name=select_sample_${sample.id} id="sample_checkbox" value="true"></td>
+ %endif
<td>${info['name']}</td><td>${info['barcode']}</td>
%if sample.request.unsubmitted():
@@ -486,6 +556,7 @@ function showContent(vThis)
</%def><%def name="show_basic_info_form( sample_index, sample, info )">
+ <td></td><td><input type="text" name=sample_${sample_index}_name value="${info['name']}" size="10"/><div class="toolParamHelp" style="clear: both;">
1
0
galaxy-dist commit a8a59549ca5f: Workflow Fix- Enabled connection of nodes using ChangeDatatypeAction in the editor pane.
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dannon Baker <dannonbaker(a)me.com>
# Date 1283207915 14400
# Node ID a8a59549ca5fcad2769db585a051d4c4bb45f27d
# Parent 667fb4f9cd16237bb74b15c13e7ff5f166a89177
Workflow Fix- Enabled connection of nodes using ChangeDatatypeAction in the editor pane.
--- a/static/scripts/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/galaxy.workflow_editor.canvas.js
@@ -45,9 +45,21 @@ InputTerminal.prototype = new Terminal()
can_accept: function ( other ) {
if ( this.connectors.length < 1 ) {
for ( var t in this.datatypes ) {
+ var cat_outputs = new Array();
+ cat_outputs = cat_outputs.concat(other.datatypes);
+ if (other.node.post_job_actions){
+ for (var pja_i in other.node.post_job_actions){
+ var pja = other.node.post_job_actions[pja_i];
+ if (pja.action_type == "ChangeDatatypeAction"){
+ if (pja.action_arguments){
+ cat_outputs.push(pja.action_arguments['newtype']);
+ }
+ }
+ }
+ }
// FIXME: No idea what to do about case when datatype is 'input'
- for ( var other_datatype_i in other.datatypes ) {
- if ( other.datatypes[other_datatype_i] == "input" || issubtype( other.datatypes[other_datatype_i], this.datatypes[t] ) ) {
+ for ( var other_datatype_i in cat_outputs ) {
+ if ( cat_outputs[other_datatype_i] == "input" || issubtype( cat_outputs[other_datatype_i], this.datatypes[t] ) ) {
return true;
}
}
@@ -202,6 +214,7 @@ function Node( element ) {
terminal.node = node;
terminal.name = name;
$(this).bind( "dragstart", function( e ) {
+ workflow.check_changes_in_active_form(); //To save PJAs in the case of change datatype actions.
var h = $( '<div class="drag-terminal" style="position: absolute;"></div>' ).appendTo( "#canvas-container" ).get(0);
h.terminal = new OutputTerminal( h );
var c = new Connector();
1
0
galaxy-dist commit 00336a54c6b1: trackster: fix use of an old variable
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1282938191 14400
# Node ID 00336a54c6b1f1202c14737f7cc85bd04fa66247
# Parent 3f841fbbed06c0dc6440c895ff7c32ec61c8cb4d
trackster: fix use of an old variable
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -341,7 +341,7 @@ var View = function( container, chrom, t
var sorted = $("ul#sortable-ul").sortable('toArray');
for (var id_i in sorted) {
var id = sorted[id_i].split("_li")[0].split("track_")[1];
- this.viewport.append( $("#track_" + id) );
+ this.viewport_container.append( $("#track_" + id) );
}
for (var track_id in view.tracks) {
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT
EXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this
.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_o
verview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_i
nput=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.content_div.hide();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_d
iv.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.viewport_container.bind("dragstart",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.active=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.active){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_d
iv=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.
nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.hig
h-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){
e=this.max_high}if(this.high!==0&&d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.update_location(this.low,this.high);if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.hi
gh-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url
,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var c=this,b=c.vi
ew;if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_div);var g=c.display_modes[0];c.mode=g;c.mode_div.text(g);var a=function(h){c.mode_div.text(h);c.mode=h;c.tile_cache.clear();c.draw()};var e={};for(var d in c.display_modes){var f=c.display_modes[d];e[f]=function(h){return function(){a(h)}}(f)}make_popupmenu(c.mode_div,e)}else{c.mode_div.hide()}}if(c.overview_check_div===undefined){c.overview_check_div=$("<div class='right-float' />").css("margin-top","-3px").appendTo(c.header_div);c.overview_check=$("<input type='checkbox' class='overview_check' />").appendTo(c.overview_check_div);c.overview_check.bind("click",function(){var h=this;b.overview_viewport.find("canvas").remove();c.set_overview();$(".overview_check").each(function(){if(this!==h){$(this).attr("checked",false)}})});c.overview_check_div.append($("<label />").text("Overview"))}};$.extend(TiledTrack.prototype,Track.prototype,{dr
aw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.h
eight);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.initial_canvas&&this.overview_check.is(":checked")){a.overview_viewport.append(this.initial_canvas);a.overview_viewport.height(this.initial_canvas.height());a.overview_box.height(this.initial_canvas.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'>
</div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,
j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"L
ine"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_
"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height
=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min
_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("featu
re-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b
=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.mea
sureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(Y,l,o,al){var F=l*DENSITY*Y,ae=(l+1)*DENSITY*Y,E=ae-F;var af=(!this.initial_canvas?"initial":F+"_"+ae);var A=this.data_cache.get(af);var
d;if(A===undefined){this.data_queue[[F,ae]]=true;this.get_data(F,ae);return}var a=Math.ceil(E*al),M=$("<canvas class='tile'></canvas>"),aa=this.prefs.label_color,g=this.prefs.block_color,n=this.mode,W=(n==="Squish")||(n==="Dense")&&(n!=="Pack")||(n==="Auto"&&(A.extra_info==="no_detail")),Q=this.left_offset,ak,t,am;if(A.dataset_type==="summary_tree"){t=this.summary_draw_height}else{if(n==="Dense"){t=15;am=10}else{am=(W?this.vertical_nodetail_px:this.vertical_detail_px);t=this.incremental_slots(this.view.zoom_res,A.data,W,n)*am+15;ak=this.inc_slots[this.view.zoom_res]}}M.css({position:"absolute",top:0,left:(F-this.view.low)*al-Q});M.get(0).width=a+Q;M.get(0).height=t;o.parent().css("height",Math.max(this.height_px,t)+"px");var B=M.get(0).getContext("2d");B.fillStyle=g;B.font=this.default_font;B.textAlign="right";if(A.dataset_type=="summary_tree"){var L,I=55,ad=255-I,h=ad*2/3,S=A.data,D=A.max,m=A.avg,b=Math.ceil(A.delta*al);for(var ah=0,z=S.length;ah<z;ah++){var U=Math.floor((
S[ah][0]-F)*al);var T=S[ah][1];if(!T){continue}L=Math.floor(ad-(T/D)*ad);B.fillStyle="rgb("+L+","+L+","+L+")";B.fillRect(U+Q,0,b,this.summary_draw_height);if(this.prefs.show_counts&&B.measureText(T).width<b){if(L>h){B.fillStyle="black"}else{B.fillStyle="#ddd"}B.textAlign="center";B.fillText(T,U+Q+(b/2),12)}}d="Summary";o.append(M);return M}var aj=A.data;var ag=0;for(var ah=0,z=aj.length;ah<z;ah++){var N=aj[ah],K=N[0],ai=N[1],V=N[2],G=N[3];if(ai<=ae&&V>=F){var X=Math.floor(Math.max(0,(ai-F)*al)),C=Math.ceil(Math.min(a,Math.max(0,(V-F)*al))),R=(n==="Dense"?0:ak[K]*am);if(A.dataset_type==="bai"){B.fillStyle=g;if(N[4] instanceof Array){var u=Math.floor(Math.max(0,(N[4][0]-F)*al)),J=Math.ceil(Math.min(a,Math.max(0,(N[4][1]-F)*al))),s=Math.floor(Math.max(0,(N[5][0]-F)*al)),q=Math.ceil(Math.min(a,Math.max(0,(N[5][1]-F)*al)));if(N[4][1]>=F&&N[4][0]<=ae){this.rect_or_text(B,al,F,ae,N[4][0],N[4][2],u+Q,J-u,R)}if(N[5][1]>=F&&N[5][0]<=ae){this.rect_or_text(B,al,F,ae,N[5][0],N[5][2],s+Q,
q-s,R)}if(s>J){B.fillStyle="#999";B.fillRect(J+Q,R+5,s-J,1)}}else{B.fillStyle=g;this.rect_or_text(B,al,F,ae,ai,G,X+Q,C-X,R)}if(n!=="Dense"&&!W&&ai>F){B.fillStyle=this.prefs.label_color;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(K,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(K,X-2+Q,R+8)}B.fillStyle=g}}else{if(A.dataset_type==="interval_index"){if(W){B.fillRect(X+Q,R+5,C-X,1)}else{var w=N[4],P=N[5],Z=N[6],f=N[7];var v,ab,H=null,an=null;if(P&&Z){H=Math.floor(Math.max(0,(P-F)*al));an=Math.ceil(Math.min(a,Math.max(0,(Z-F)*al)))}if(n!=="Dense"&&G!==undefined&&ai>F){B.fillStyle=aa;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(G,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(G,X-2+Q,R+8)}B.fillStyle=g}if(f){if(w){if(w=="+"){B.fillStyle=RIGHT_STRAND}else{if(w=="-"){B.fillStyle=LEFT_STRAND}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=g}for(var af=0,e=f.length;af<e;af++){var p=f[af],c=Math.floor(Math.max(0,(p[0]-F)*al)),O=Math.ceil(Math.min(a,
Math.max((p[1]-F)*al)));if(c>O){continue}v=5;ab=3;B.fillRect(c+Q,R+ab,O-c,v);if(H!==undefined&&!(c>an||O<H)){v=9;ab=1;var ac=Math.max(c,H),r=Math.min(O,an);B.fillRect(ac+Q,R+ab,r-ac,v)}}}else{v=9;ab=1;B.fillRect(X+Q,R+ab,C-X,v);if(N.strand){if(N.strand=="+"){B.fillStyle=RIGHT_STRAND_INV}else{if(N.strand=="-"){B.fillStyle=LEFT_STRAND_INV}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=prefs.block_color}}}}}ag++}}o.append(M);return M},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",t
his.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
+var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT
EXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this
.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_o
verview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_i
nput=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.content_div.hide();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_d
iv.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.viewport_container.bind("dragstart",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.active=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.active){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_d
iv=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.
nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.hig
h-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport_container.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.
max_high){e=this.max_high}if(this.high!==0&&d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.update_location(this.low,this.high);if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width(
)*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSO
N(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var c=t
his,b=c.view;if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_div);var g=c.display_modes[0];c.mode=g;c.mode_div.text(g);var a=function(h){c.mode_div.text(h);c.mode=h;c.tile_cache.clear();c.draw()};var e={};for(var d in c.display_modes){var f=c.display_modes[d];e[f]=function(h){return function(){a(h)}}(f)}make_popupmenu(c.mode_div,e)}else{c.mode_div.hide()}}if(c.overview_check_div===undefined){c.overview_check_div=$("<div class='right-float' />").css("margin-top","-3px").appendTo(c.header_div);c.overview_check=$("<input type='checkbox' class='overview_check' />").appendTo(c.overview_check_div);c.overview_check.bind("click",function(){var h=this;b.overview_viewport.find("canvas").remove();c.set_overview();$(".overview_check").each(function(){if(this!==h){$(this).attr("checked",false)}})});c.overview_check_div.append($("<label />").text("Overview"))}};$.extend(TiledTrack.prototype,Track.pro
totype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,
l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.initial_canvas&&this.overview_check.is(":checked")){a.overview_viewport.append(this.initial_canvas);a.overview_viewport.height(this.initial_canvas.height());a.overview_box.height(this.initial_canvas.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height
: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){consol
e.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefin
ed,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","
linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get
(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this
.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addCl
ass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(
a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){v
ar t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(Y,l,o,al){var F=l*DENSITY*Y,ae=(l+1)*DENSITY*Y,E=ae-F;var af=(!this.initial_canvas?"initial":F+"_"+ae);var A=this.data_cache.g
et(af);var d;if(A===undefined){this.data_queue[[F,ae]]=true;this.get_data(F,ae);return}var a=Math.ceil(E*al),M=$("<canvas class='tile'></canvas>"),aa=this.prefs.label_color,g=this.prefs.block_color,n=this.mode,W=(n==="Squish")||(n==="Dense")&&(n!=="Pack")||(n==="Auto"&&(A.extra_info==="no_detail")),Q=this.left_offset,ak,t,am;if(A.dataset_type==="summary_tree"){t=this.summary_draw_height}else{if(n==="Dense"){t=15;am=10}else{am=(W?this.vertical_nodetail_px:this.vertical_detail_px);t=this.incremental_slots(this.view.zoom_res,A.data,W,n)*am+15;ak=this.inc_slots[this.view.zoom_res]}}M.css({position:"absolute",top:0,left:(F-this.view.low)*al-Q});M.get(0).width=a+Q;M.get(0).height=t;o.parent().css("height",Math.max(this.height_px,t)+"px");var B=M.get(0).getContext("2d");B.fillStyle=g;B.font=this.default_font;B.textAlign="right";if(A.dataset_type=="summary_tree"){var L,I=55,ad=255-I,h=ad*2/3,S=A.data,D=A.max,m=A.avg,b=Math.ceil(A.delta*al);for(var ah=0,z=S.length;ah<z;ah++){var U=Ma
th.floor((S[ah][0]-F)*al);var T=S[ah][1];if(!T){continue}L=Math.floor(ad-(T/D)*ad);B.fillStyle="rgb("+L+","+L+","+L+")";B.fillRect(U+Q,0,b,this.summary_draw_height);if(this.prefs.show_counts&&B.measureText(T).width<b){if(L>h){B.fillStyle="black"}else{B.fillStyle="#ddd"}B.textAlign="center";B.fillText(T,U+Q+(b/2),12)}}d="Summary";o.append(M);return M}var aj=A.data;var ag=0;for(var ah=0,z=aj.length;ah<z;ah++){var N=aj[ah],K=N[0],ai=N[1],V=N[2],G=N[3];if(ai<=ae&&V>=F){var X=Math.floor(Math.max(0,(ai-F)*al)),C=Math.ceil(Math.min(a,Math.max(0,(V-F)*al))),R=(n==="Dense"?0:ak[K]*am);if(A.dataset_type==="bai"){B.fillStyle=g;if(N[4] instanceof Array){var u=Math.floor(Math.max(0,(N[4][0]-F)*al)),J=Math.ceil(Math.min(a,Math.max(0,(N[4][1]-F)*al))),s=Math.floor(Math.max(0,(N[5][0]-F)*al)),q=Math.ceil(Math.min(a,Math.max(0,(N[5][1]-F)*al)));if(N[4][1]>=F&&N[4][0]<=ae){this.rect_or_text(B,al,F,ae,N[4][0],N[4][2],u+Q,J-u,R)}if(N[5][1]>=F&&N[5][0]<=ae){this.rect_or_text(B,al,F,ae,N[5][0],N[
5][2],s+Q,q-s,R)}if(s>J){B.fillStyle="#999";B.fillRect(J+Q,R+5,s-J,1)}}else{B.fillStyle=g;this.rect_or_text(B,al,F,ae,ai,G,X+Q,C-X,R)}if(n!=="Dense"&&!W&&ai>F){B.fillStyle=this.prefs.label_color;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(K,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(K,X-2+Q,R+8)}B.fillStyle=g}}else{if(A.dataset_type==="interval_index"){if(W){B.fillRect(X+Q,R+5,C-X,1)}else{var w=N[4],P=N[5],Z=N[6],f=N[7];var v,ab,H=null,an=null;if(P&&Z){H=Math.floor(Math.max(0,(P-F)*al));an=Math.ceil(Math.min(a,Math.max(0,(Z-F)*al)))}if(n!=="Dense"&&G!==undefined&&ai>F){B.fillStyle=aa;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(G,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(G,X-2+Q,R+8)}B.fillStyle=g}if(f){if(w){if(w=="+"){B.fillStyle=RIGHT_STRAND}else{if(w=="-"){B.fillStyle=LEFT_STRAND}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=g}for(var af=0,e=f.length;af<e;af++){var p=f[af],c=Math.floor(Math.max(0,(p[0]-F)*al)),O=Math.ceil(M
ath.min(a,Math.max((p[1]-F)*al)));if(c>O){continue}v=5;ab=3;B.fillRect(c+Q,R+ab,O-c,v);if(H!==undefined&&!(c>an||O<H)){v=9;ab=1;var ac=Math.max(c,H),r=Math.min(O,an);B.fillRect(ac+Q,R+ab,r-ac,v)}}}else{v=9;ab=1;B.fillRect(X+Q,R+ab,C-X,v);if(N.strand){if(N.strand=="+"){B.fillStyle=RIGHT_STRAND_INV}else{if(N.strand=="-"){B.fillStyle=LEFT_STRAND_INV}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=prefs.block_color}}}}}ag++}}o.append(M);return M},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("
checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
1
0
galaxy-dist commit 4058759b7751: Display the edit attributes confirmation message in a warning message instead of ok message if unable to update metadata because the dataset is being used as an input or output.
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1283189744 14400
# Node ID 4058759b77518b40561719af15f191d809642b1f
# Parent a9316edfcdfcff5f492f5f1aa979675899c5b565
Display the edit attributes confirmation message in a warning message instead of ok message if unable to update metadata because the dataset is being used as an input or output.
--- a/lib/galaxy/web/controllers/root.py
+++ b/lib/galaxy/web/controllers/root.py
@@ -335,10 +335,11 @@ class RootController( BaseController, Us
if params.annotation:
annotation = sanitize_html( params.annotation, 'utf-8', 'text/html' )
self.add_item_annotation( trans, data, annotation )
+ trans.sa_session.flush()
+ return trans.show_ok_message( "Attributes updated%s" % message, refresh_frames=['history'] )
else:
- message = ' (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()
- return trans.show_ok_message( "Attributes updated%s" % message, refresh_frames=['history'] )
+ trans.sa_session.flush()
+ return trans.show_warn_message( "Attributes updated, but 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.", refresh_frames=['history'] )
elif params.detect:
# The user clicked the Auto-detect button on the 'Edit Attributes' form
#prevent modifying metadata when dataset is queued or running as input/output
1
0
galaxy-dist commit a9316edfcdfc: Display the average rating for each tool the tool grid in the Galaxy Tool Shed. Add a common method for rendering the star rating, and clean up template code by using this new common method.
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1283187298 14400
# Node ID a9316edfcdfcff5f492f5f1aa979675899c5b565
# Parent ecf203e9d70295c9850cad575c63c1760cd83c73
Display the average rating for each tool the tool grid in the Galaxy Tool Shed. Add a common method for rendering the star rating, and clean up template code by using this new common method.
--- a/templates/webapps/community/common/rate_tool.mako
+++ b/templates/webapps/community/common/rate_tool.mako
@@ -1,4 +1,5 @@
<%namespace file="/message.mako" import="render_msg" />
+<%namespace file="/webapps/community/common/common.mako" import="*" /><%
from galaxy.web.framework.helpers import time_ago
@@ -51,12 +52,6 @@
<%def name="javascripts()">
${parent.javascripts()}
${h.js( "jquery.rating" )}
-
- <script type="text/javascript">
- jQuery( function() {
- jQuery( 'form.rating' ).rating();
- });
- </script></%def><%def name="title()">Rate Tool</%def>
@@ -146,60 +141,12 @@
</div><div class="form-row"><label>Average Rating:</label>
- <input name="avg_rating" type="radio" class="star" value="1" disabled="disabled"
- %if avg_rating > 0.5 and avg_rating < 1.5:
- checked="checked"
- %endif
- />
- <input name="avg_rating" type="radio" class="star" value="2" disabled="disabled"
- %if avg_rating > 1.5 and avg_rating < 2.5:
- checked="checked"
- %endif
- />
- <input name="avg_rating" type="radio" class="star" value="3" disabled="disabled"
- %if avg_rating > 2.5 and avg_rating < 3.5:
- checked="checked"
- %endif
- />
- <input name="avg_rating" type="radio" class="star" value="4" disabled="disabled"
- %if avg_rating > 3.5 and avg_rating < 4.5:
- checked="checked"
- %endif
- />
- <input name="avg_rating" type="radio" class="star" value="5" disabled="disabled"
- %if avg_rating > 4.5 and avg_rating < 5.5:
- checked="checked"
- %endif
- />
+ ${render_star_rating( 'avg_rating', avg_rating, disabled=True )}
<div style="clear: both"></div></div><div class="form-row"><label>Your Rating:</label>
- <input name="rating" type="radio" class="star" value="1"
- %if tra and tra.rating == 1:
- checked="checked"
- %endif
- />
- <input name="rating" type="radio" class="star" value="2"
- %if tra and tra.rating == 2:
- checked="checked"
- %endif
- />
- <input name="rating" type="radio" class="star" value="3"
- %if tra and tra.rating == 3:
- checked="checked"
- %endif
- />
- <input name="rating" type="radio" class="star" value="4"
- %if tra and tra.rating == 4:
- checked="checked"
- %endif
- />
- <input name="rating" type="radio" class="star" value="5"
- %if tra and tra.rating == 5:
- checked="checked"
- %endif
- />
+ ${render_star_rating( 'rating', tra.rating )}
<div style="clear: both"></div></div><div class="form-row">
@@ -241,33 +188,7 @@
name = 'rating%d' % count
%><tr>
- <td>
- <input name="${name}" type="radio" class="star" value="1" disabled="disabled"
- %if review.rating > 0.5 and review.rating < 1.5:
- checked="checked"
- %endif
- />
- <input name="${name}" type="radio" class="star" value="2" disabled="disabled"
- %if review.rating > 1.5 and review.rating < 2.5:
- checked="checked"
- %endif
- />
- <input name="${name}" type="radio" class="star" value="3" disabled="disabled"
- %if review.rating > 2.5 and review.rating < 3.5:
- checked="checked"
- %endif
- />
- <input name="${name}" type="radio" class="star" value="4" disabled="disabled"
- %if review.rating > 3.5 and review.rating < 4.5:
- checked="checked"
- %endif
- />
- <input name="${name}" type="radio" class="star" value="5" disabled="disabled"
- %if review.rating > 4.5 and review.rating < 5.5:
- checked="checked"
- %endif
- />
- </td>
+ <td>${render_star_rating( name, review.rating, disabled=True )}</td><td>${review.comment}</td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td>
--- a/templates/webapps/community/tool/view_tool.mako
+++ b/templates/webapps/community/tool/view_tool.mako
@@ -1,4 +1,5 @@
<%namespace file="/message.mako" import="render_msg" />
+<%namespace file="/webapps/community/common/common.mako" import="*" /><%
from galaxy.web.framework.helpers import time_ago
@@ -51,12 +52,6 @@
<%def name="javascripts()">
${parent.javascripts()}
${h.js( "jquery.rating" )}
-
- <script type="text/javascript">
- jQuery( function() {
- jQuery( 'form.rating' ).rating();
- });
- </script></%def><%def name="title()">View Tool</%def>
@@ -205,31 +200,7 @@
</div><div class="form-row"><label>Average Rating:</label>
- <input name="avg_rating" type="radio" class="star" value="1" disabled="disabled"
- %if avg_rating > 0.5 and avg_rating < 1.5:
- checked="checked"
- %endif
- />
- <input name="avg_rating" type="radio" class="star" value="2" disabled="disabled"
- %if avg_rating > 1.5 and avg_rating < 2.5:
- checked="checked"
- %endif
- />
- <input name="avg_rating" type="radio" class="star" value="3" disabled="disabled"
- %if avg_rating > 2.5 and avg_rating < 3.5:
- checked="checked"
- %endif
- />
- <input name="avg_rating" type="radio" class="star" value="4" disabled="disabled"
- %if avg_rating > 3.5 and avg_rating < 4.5:
- checked="checked"
- %endif
- />
- <input name="avg_rating" type="radio" class="star" value="5" disabled="disabled"
- %if avg_rating > 4.5 and avg_rating < 5.5:
- checked="checked"
- %endif
- />
+ ${render_star_rating( 'avg_rating', avg_rating, disabled=True )}
<div style="clear: both"></div></div></div>
@@ -257,33 +228,7 @@
name = 'rating%d' % count
%><tr>
- <td>
- <input name="${name}" type="radio" class="star" value="1" disabled="disabled"
- %if review.rating > 0.5 and review.rating < 1.5:
- checked="checked"
- %endif
- />
- <input name="${name}" type="radio" class="star" value="2" disabled="disabled"
- %if review.rating > 1.5 and review.rating < 2.5:
- checked="checked"
- %endif
- />
- <input name="${name}" type="radio" class="star" value="3" disabled="disabled"
- %if review.rating > 2.5 and review.rating < 3.5:
- checked="checked"
- %endif
- />
- <input name="${name}" type="radio" class="star" value="4" disabled="disabled"
- %if review.rating > 3.5 and review.rating < 4.5:
- checked="checked"
- %endif
- />
- <input name="${name}" type="radio" class="star" value="5" disabled="disabled"
- %if review.rating > 4.5 and review.rating < 5.5:
- checked="checked"
- %endif
- />
- </td>
+ <td>${render_star_rating( name, review.rating, disabled=True )}</td><td>${review.comment}</td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td>
--- a/lib/galaxy/webapps/community/controllers/common.py
+++ b/lib/galaxy/webapps/community/controllers/common.py
@@ -11,6 +11,41 @@ log = logging.getLogger( __name__ )
# States for passing messages
SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning", "error"
+class ItemRatings( UsesItemRatings ):
+ """Overrides rate_item method since we also allow for comments"""
+ def rate_item( self, trans, user, item, rating, comment='' ):
+ """ Rate an item. Return type is <item_class>RatingAssociation. """
+ item_rating = self.get_user_item_rating( trans, user, item )
+ if not item_rating:
+ # User has not yet rated item; create rating.
+ item_rating_assoc_class = self._get_item_rating_assoc_class( trans, item )
+ item_rating = item_rating_assoc_class()
+ item_rating.user = trans.user
+ item_rating.set_item( item )
+ item_rating.rating = rating
+ item_rating.comment = comment
+ trans.sa_session.add( item_rating )
+ trans.sa_session.flush()
+ elif item_rating.rating != rating or item_rating.comment != comment:
+ # User has previously rated item; update rating.
+ item_rating.rating = rating
+ item_rating.comment = comment
+ trans.sa_session.flush()
+ return item_rating
+ def get_avg_rating_html( self, avg_rating ):
+ # FIXME: the class="star" attribute in the input tag does not render correctly inside a table
+ # with the attribute class="grid-table", so just display the numerical avg_rating value until
+ # we can figure out why the styles don't work together. When this is fixed, eliminate the following
+ # line and return the html.
+ return int( avg_rating )
+ html = ''
+ for index in range( 1, 6 ):
+ html += '<input name="avg_rating" type="radio" class="star" value="%s" disabled="disabled"' % str( index )
+ if avg_rating > ( index - 0.5 ) and avg_rating < ( index + 0.5 ):
+ html += ' checked="checked"'
+ html += '/>'
+ return html
+
class ToolListGrid( grids.Grid ):
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, tool ):
@@ -48,6 +83,10 @@ class ToolListGrid( grids.Grid ):
if tool.user:
return tool.user.username
return 'no user'
+ class RatingColumn( grids.TextColumn, ItemRatings ):
+ def get_value( self, trans, grid, tool ):
+ avg_rating, num_ratings = self.get_ave_item_rating_data( trans, tool )
+ return self.get_avg_rating_html( avg_rating )
class EmailColumn( grids.GridColumn ):
def filter( self, trans, user, query, column_filter ):
if column_filter == 'All':
@@ -63,12 +102,10 @@ class ToolListGrid( grids.Grid ):
NameColumn( "Name",
key="name",
link=( lambda item: dict( operation="view_tool", id=item.id, webapp="community" ) ),
- model_class=model.Tool,
attach_popup=False
),
TypeColumn( "Type",
key="suite",
- model_class=model.Tool,
attach_popup=False ),
VersionColumn( "Version",
key="version",
@@ -77,7 +114,6 @@ class ToolListGrid( grids.Grid ):
filterable="advanced" ),
DescriptionColumn( "Description",
key="description",
- model_class=model.Tool,
attach_popup=False
),
CategoryColumn( "Category",
@@ -89,6 +125,8 @@ class ToolListGrid( grids.Grid ):
link=( lambda item: dict( operation="tools_by_user", id=item.id, webapp="community" ) ),
attach_popup=False,
filterable="advanced" ),
+ RatingColumn( "Average Rating",
+ attach_popup=False ),
# Columns that are valid for filtering but are not visible.
EmailColumn( "Email",
key="email",
@@ -142,14 +180,12 @@ class CategoryListGrid( grids.Grid ):
columns = [
NameColumn( "Name",
key="name",
- model_class=model.Category,
link=( lambda item: dict( operation="tools_by_category", id=item.id, webapp="community" ) ),
attach_popup=False,
filterable="advanced"
),
DescriptionColumn( "Description",
key="description",
- model_class=model.Category,
attach_popup=False,
filterable="advanced"
),
@@ -175,28 +211,6 @@ class CategoryListGrid( grids.Grid ):
num_rows_per_page = 50
preserve_state = False
use_paging = True
-
-class ItemRatings( UsesItemRatings ):
- """Overrides rate_item method since we also allow for comments"""
- def rate_item( self, trans, user, item, rating, comment='' ):
- """ Rate an item. Return type is <item_class>RatingAssociation. """
- item_rating = self.get_user_item_rating( trans, user, item )
- if not item_rating:
- # User has not yet rated item; create rating.
- item_rating_assoc_class = self._get_item_rating_assoc_class( trans, item )
- item_rating = item_rating_assoc_class()
- item_rating.user = trans.user
- item_rating.set_item( item )
- item_rating.rating = rating
- item_rating.comment = comment
- trans.sa_session.add( item_rating )
- trans.sa_session.flush()
- elif item_rating.rating != rating or item_rating.comment != comment:
- # User has previously rated item; update rating.
- item_rating.rating = rating
- item_rating.comment = comment
- trans.sa_session.flush()
- return item_rating
class CommonController( BaseController, ItemRatings ):
@web.expose
--- /dev/null
+++ b/templates/webapps/community/common/common.mako
@@ -0,0 +1,15 @@
+<%def name="render_star_rating( name, rating, disabled=False )">
+ <%
+ if disabled:
+ disabled_str = ' disabled="disabled"'
+ else:
+ disabled_str = ''
+ html = ''
+ for index in range( 1, 6 ):
+ html += '<input name="%s" type="radio" class="star" value="%s" %s' % ( str( name ), str( index ), disabled_str )
+ if rating > ( index - 0.5 ) and rating < ( index + 0.5 ):
+ html += ' checked="checked"'
+ html += '/>'
+ %>
+ ${html}
+</%def>
--- a/lib/galaxy/item_attrs/ratings.py
+++ b/lib/galaxy/item_attrs/ratings.py
@@ -1,4 +1,7 @@
from sqlalchemy.sql.expression import func
+import logging
+
+log = logging.getLogger( __name__ )
class UsesItemRatings:
"""
--- a/templates/base_panels.mako
+++ b/templates/base_panels.mako
@@ -17,7 +17,7 @@
## Default stylesheets
<%def name="stylesheets()">
- ${h.css('base','panel_layout')}
+ ${h.css('base','panel_layout','jquery.rating')}
<style type="text/css">
#center {
%if not self.has_left_panel:
@@ -51,7 +51,7 @@
<%def name="late_javascripts()">
## Scripts can be loaded later since they progressively add features to
## the panels, but do not change layout
- ${h.js( 'jquery.event.drag', 'jquery.event.hover', 'jquery.form', 'galaxy.base', 'galaxy.panels' )}
+ ${h.js( 'jquery.event.drag', 'jquery.event.hover', 'jquery.form', 'jquery.rating', 'galaxy.base', 'galaxy.panels' )}
<script type="text/javascript">
ensure_dd_helper();
--- a/templates/grid_base.mako
+++ b/templates/grid_base.mako
@@ -45,7 +45,7 @@
</%def><%def name="grid_javascripts()">
- ${h.js("jquery.autocomplete", "autocomplete_tagging" )}
+ ${h.js("jquery.autocomplete", "autocomplete_tagging", "jquery.rating" )}
<script type="text/javascript">
// This is necessary so that, when nested arrays are used in ajax/post/get methods, square brackets ('[]') are
// not appended to the identifier of a nested array.
@@ -609,7 +609,7 @@
<%def name="stylesheets()">
${parent.stylesheets()}
- ${h.css( "autocomplete_tagging" )}
+ ${h.css( "autocomplete_tagging", "jquery.rating" )}
<style>
## Not generic to all grids -- move to base?
.count-box {
@@ -717,8 +717,8 @@
%><form action="${url()}" method="post" onsubmit="return false;">
- <div class='loading-elt-overlay'></div>
- <table id='grid-table' class="grid">
+ <div class="loading-elt-overlay"></div>
+ <table id="grid-table" class="grid"><thead id="grid-table-header"><tr>
%if show_item_checkboxes:
@@ -747,7 +747,7 @@
%endif
>
%if href:
- <a href="${href}" class="sort-link" sort_key='${column.key}'>${column.label}</a>
+ <a href="${href}" class="sort-link" sort_key="${column.key}">${column.label}</a>
%else:
${column.label}
%endif
1
0
galaxy-dist commit 3f841fbbed06: Fix typo that prevented gff_filter_by_feature_count tool's output from being set correctly.
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1282928040 14400
# Node ID 3f841fbbed06c0dc6440c895ff7c32ec61c8cb4d
# Parent 188f2cd3173dbdc183580e5d8b7beeba779ad9d0
Fix typo that prevented gff_filter_by_feature_count tool's output from being set correctly.
--- a/tools/filters/gff/gff_filter_by_feature_count.xml
+++ b/tools/filters/gff/gff_filter_by_feature_count.xml
@@ -17,7 +17,7 @@
</param></inputs><outputs>
- <data format="input_file1" name="out_file1" metadata_source="input_file1"/>
+ <data format="input" name="out_file1" metadata_source="input_file1"/></outputs><tests><test>
1
0
galaxy-dist commit ecf203e9d702: Fix the platform argument to fetch_eggs.py and create an egg packager for easing the installation/updating of Galaxy on systems without a direct connection to the internet.
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1283182318 14400
# Node ID ecf203e9d70295c9850cad575c63c1760cd83c73
# Parent 00336a54c6b1f1202c14737f7cc85bd04fa66247
Fix the platform argument to fetch_eggs.py and create an egg packager for easing the installation/updating of Galaxy on systems without a direct connection to the internet.
--- /dev/null
+++ b/scripts/egg_packager_template.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python
+
+# Configure stdout logging
+
+import os, sys, logging, glob, zipfile, shutil
+
+log = logging.getLogger()
+log.setLevel( 10 )
+log.addHandler( logging.StreamHandler( sys.stdout ) )
+
+# Fake pkg_resources
+
+import re
+
+macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)")
+darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)")
+solarisVersionString = re.compile(r"solaris-(\d)\.(\d+)-(.*)")
+
+def compatible_platforms(provided,required):
+ """Can code for the `provided` platform run on the `required` platform?
+
+ Returns true if either platform is ``None``, or the platforms are equal.
+
+ XXX Needs compatibility checks for Linux and other unixy OSes.
+ """
+ if provided is None or required is None or provided==required:
+ return True # easy case
+
+ # Mac OS X special cases
+ reqMac = macosVersionString.match(required)
+ if reqMac:
+ provMac = macosVersionString.match(provided)
+
+ # is this a Mac package?
+ if not provMac:
+ # this is backwards compatibility for packages built before
+ # setuptools 0.6. All packages built after this point will
+ # use the new macosx designation.
+ provDarwin = darwinVersionString.match(provided)
+ if provDarwin:
+ dversion = int(provDarwin.group(1))
+ macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2))
+ if dversion == 7 and macosversion >= "10.3" or \
+ dversion == 8 and macosversion >= "10.4":
+
+ #import warnings
+ #warnings.warn("Mac eggs should be rebuilt to "
+ # "use the macosx designation instead of darwin.",
+ # category=DeprecationWarning)
+ return True
+ return False # egg isn't macosx or legacy darwin
+
+ # are they the same major version and machine type?
+ if provMac.group(1) != reqMac.group(1) or \
+ provMac.group(3) != reqMac.group(3):
+ return False
+
+
+
+ # is the required OS major update >= the provided one?
+ if int(provMac.group(2)) > int(reqMac.group(2)):
+ return False
+
+ return True
+
+ # Solaris' special cases
+ reqSol = solarisVersionString.match(required)
+ if reqSol:
+ provSol = solarisVersionString.match(provided)
+ if not provSol:
+ return False
+ if provSol.group(1) != reqSol.group(1) or \
+ provSol.group(3) != reqSol.group(3):
+ return False
+ if int(provSol.group(2)) > int(reqSol.group(2)):
+ return False
+ return True
+
+ # XXX Linux and other platforms' special cases should go here
+ return False
+
+EGG_NAME = re.compile(
+ r"(?P<name>[^-]+)"
+ r"( -(?P<ver>[^-]+) (-py(?P<pyver>[^-]+) (-(?P<plat>.+))? )? )?",
+ re.VERBOSE | re.IGNORECASE
+).match
+
+class Distribution( object ):
+ def __init__( self, egg_name, project_name, version, py_version, platform ):
+ self._egg_name = egg_name
+ self.project_name = project_name
+ if project_name is not None:
+ self.project_name = project_name.replace( '-', '_' )
+ self.version = version
+ if version is not None:
+ self.version = version.replace( '-', '_' )
+ self.py_version = py_version
+ self.platform = platform
+ self.location = os.path.join( tmpd, egg_name ) + '.egg'
+ def egg_name( self ):
+ return self._egg_name
+ @classmethod
+ def from_filename( cls, basename ):
+ project_name, version, py_version, platform = [None]*4
+ basename, ext = os.path.splitext(basename)
+ if ext.lower() == '.egg':
+ match = EGG_NAME( basename )
+ if match:
+ project_name, version, py_version, platform = match.group( 'name','ver','pyver','plat' )
+ return cls( basename, project_name, version, py_version, platform )
+
+class pkg_resources( object ):
+ pass
+
+pkg_resources.Distribution = Distribution
+
+# Fake galaxy.eggs
+
+env = None
+def get_env():
+ return None
+
+import urllib, urllib2, HTMLParser
+class URLRetriever( urllib.FancyURLopener ):
+ def http_error_default( *args ):
+ urllib.URLopener.http_error_default( *args )
+
+class Egg( object ):
+ def __init__( self, distribution ):
+ self.url = url + '/' + distribution.project_name.replace( '-', '_' )
+ self.dir = tmpd
+ self.distribution = distribution
+ def set_distribution( self ):
+ pass
+ def unpack_if_needed( self ):
+ pass
+ def remove_doppelgangers( self ):
+ pass
+ def fetch( self, requirement ):
+ """
+ fetch() serves as the install method to pkg_resources.working_set.resolve()
+ """
+ def find_alternative():
+ """
+ Some platforms (e.g. Solaris) support eggs compiled on older platforms
+ """
+ class LinkParser( HTMLParser.HTMLParser ):
+ """
+ Finds links in what should be an Apache-style directory index
+ """
+ def __init__( self ):
+ HTMLParser.HTMLParser.__init__( self )
+ self.links = []
+ def handle_starttag( self, tag, attrs ):
+ if tag == 'a' and 'href' in dict( attrs ):
+ self.links.append( dict( attrs )['href'] )
+ parser = LinkParser()
+ try:
+ parser.feed( urllib2.urlopen( self.url + '/' ).read() )
+ except urllib2.HTTPError, e:
+ if e.code == 404:
+ return None
+ parser.close()
+ for link in parser.links:
+ file = urllib.unquote( link ).rsplit( '/', 1 )[-1]
+ tmp_dist = pkg_resources.Distribution.from_filename( file )
+ if tmp_dist.platform is not None and \
+ self.distribution.project_name == tmp_dist.project_name and \
+ self.distribution.version == tmp_dist.version and \
+ self.distribution.py_version == tmp_dist.py_version and \
+ compatible_platforms( tmp_dist.platform, self.distribution.platform ):
+ return file
+ return None
+ if self.url is None:
+ return None
+ alternative = None
+ try:
+ url = self.url + '/' + self.distribution.egg_name() + '.egg'
+ URLRetriever().retrieve( url, self.distribution.location )
+ log.debug( "Fetched %s" % url )
+ except IOError, e:
+ if e[1] == 404 and self.distribution.platform != py:
+ alternative = find_alternative()
+ if alternative is None:
+ return None
+ else:
+ return None
+ if alternative is not None:
+ try:
+ url = '/'.join( ( self.url, alternative ) )
+ URLRetriever().retrieve( url, os.path.join( self.dir, alternative ) )
+ log.debug( "Fetched %s" % url )
+ except IOError, e:
+ return None
+ self.platform = alternative.split( '-', 2 )[-1].rsplit( '.egg', 1 )[0]
+ self.set_distribution()
+ self.unpack_if_needed()
+ self.remove_doppelgangers()
+ global env
+ env = get_env() # reset the global Environment object now that we've obtained a new egg
+ return self.distribution
+
+def create_zip():
+ fname = 'galaxy_eggs-%s.zip' % platform
+ z = zipfile.ZipFile( fname, 'w', zipfile.ZIP_STORED )
+ for egg in glob.glob( os.path.join( tmpd, '*.egg' ) ):
+ z.write( egg, 'eggs/' + os.path.basename( egg ) )
+ z.close()
+ print 'Egg package is in %s' % fname
+ print "To install the eggs, please copy this file to your Galaxy installation's root"
+ print "directory and unpack with:"
+ print " unzip %s" % fname
+
+def clean():
+ shutil.rmtree( tmpd )
+
+import tempfile
+tmpd = tempfile.mkdtemp()
+
+failures = []
+
+# Automatically generated egg definitions follow
+
--- a/scripts/fetch_eggs.py
+++ b/scripts/fetch_eggs.py
@@ -21,11 +21,10 @@ sys.path.append( lib )
from galaxy.eggs import Crate, EggNotFetchable
import pkg_resources
-c = Crate()
try:
- c.platform = sys.argv[2]
+ c = Crate( platform = sys.argv[2] )
except:
- pass
+ c = Crate()
try:
if len( sys.argv ) == 1:
c.resolve() # Only fetch eggs required by the config
--- a/lib/galaxy/eggs/__init__.py
+++ b/lib/galaxy/eggs/__init__.py
@@ -190,11 +190,15 @@ class Crate( object ):
Reads the eggs.ini file for use with checking and fetching.
"""
config_file = os.path.join( galaxy_dir, 'eggs.ini' )
- def __init__( self ):
+ def __init__( self, platform=None ):
self.eggs = {}
self.config = CaseSensitiveConfigParser()
self.repo = None
self.no_auto = []
+ self.platform = platform
+ self.py_platform = None
+ if platform is not None:
+ self.py_platform = platform.split( '-' )[0]
self.galaxy_config = GalaxyConfig()
self.parse()
def parse( self ):
@@ -208,9 +212,9 @@ class Crate( object ):
tag = dict( tags ).get( name, '' )
url = '/'.join( ( self.repo, name ) )
if full_platform:
- platform = '-'.join( ( py, pkg_resources.get_platform() ) )
+ platform = self.platform or '-'.join( ( py, pkg_resources.get_platform() ) )
else:
- platform = py
+ platform = self.py_platform or py
egg = egg_class( name, version, tag, url, platform )
self.eggs[name] = egg
@property
@@ -261,8 +265,6 @@ class Crate( object ):
for egg in self.eggs.values():
if egg.name not in self.galaxy_config.always_conditional:
rval.append( egg )
- elif self.galaxy_config.check_conditional( egg.name ):
- rval.append( egg )
return rval
def __getitem__( self, name ):
"""
--- /dev/null
+++ b/scripts/make_egg_packager.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+
+import os, sys, logging, shutil
+
+root = logging.getLogger()
+root.setLevel( 10 )
+root.addHandler( logging.StreamHandler( sys.stdout ) )
+
+lib = os.path.abspath( os.path.join( os.path.dirname( __file__ ), "..", "lib" ) )
+sys.path.append( lib )
+
+from galaxy.eggs import Crate, EggNotFetchable, py
+import pkg_resources
+
+try:
+ platform = sys.argv[1]
+ c = Crate( platform = platform )
+ print "Platform forced to '%s'" % platform
+except:
+ platform = '-'.join( ( py, pkg_resources.get_platform() ) )
+ c = Crate()
+ print "Using Python interpreter at %s, Version %s" % ( sys.executable, sys.version )
+ print "This platform is '%s'" % platform
+ print "Override with:"
+ print " make_egg_packager.py <forced-platform>"
+
+shutil.copy( os.path.join( os.path.dirname( __file__ ), 'egg_packager_template.py' ), 'egg_packager-%s.py' % platform )
+
+packager = open( 'egg_packager-%s.py' % platform, 'a' )
+packager.write( "py = '%s'\n" % py )
+packager.write( "url = '%s'\n" % c.repo )
+packager.write( "platform = '%s'\n" % platform )
+packager.write( "dists = [\n" )
+
+for egg in c.all_eggs:
+ if egg.name in c.no_auto:
+ continue
+ packager.write( " Distribution( '%s', '%s', '%s', '%s', '%s' ),\n" % ( egg.distribution.egg_name(), egg.distribution.project_name, egg.distribution.version, egg.distribution.py_version, egg.distribution.platform ) )
+
+packager.write( """]
+
+for d in dists:
+ e = Egg( d )
+ if not e.fetch( None ):
+ failures.append( e )
+
+if failures:
+ print ""
+ print "Failed:"
+ for e in failures:
+ print e.distribution.project_name
+else:
+ create_zip()
+clean()
+""" )
+
+print "Completed packager is 'egg_packager-%s.py'. To" % platform
+print "fetch eggs, please copy this file to a system with internet access and run"
+print "with:"
+print " python egg_packager-%s.py" % platform
1
0
galaxy-dist commit 39484914b892: Move the get_all_forms() method to the new base controller UsesFormDefinitionWidgets class and uncomment the final reset data method in the test_forms_and_request functional test script ( all library functional tests should once again pass ).
by commits-noreply@bitbucket.org 08 Sep '10
by commits-noreply@bitbucket.org 08 Sep '10
08 Sep '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1282855215 14400
# Node ID 39484914b8920148a4ac845570f7e2f743122f2f
# Parent 1d373ebcef62fbe016d893d247eb6023cf705d05
Move the get_all_forms() method to the new base controller UsesFormDefinitionWidgets class and uncomment the final reset data method in the test_forms_and_request functional test script ( all library functional tests should once again pass ).
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -285,6 +285,22 @@ class UsesHistory( SharableItemSecurity
class UsesFormDefinitionWidgets:
"""Mixin for controllers that use Galaxy form objects."""
+ def get_all_forms( self, trans, all_versions=False, filter=None, form_type='All' ):
+ """
+ Return all the latest forms from the form_definition_current table
+ if all_versions is set to True. Otherwise return all the versions
+ of all the forms from the form_definition table.
+ """
+ if all_versions:
+ return trans.sa_session.query( trans.app.model.FormDefinition )
+ if filter:
+ fdc_list = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ).filter_by( **filter )
+ else:
+ fdc_list = trans.sa_session.query( trans.app.model.FormDefinitionCurrent )
+ if form_type == 'All':
+ return [ fdc.latest_form for fdc in fdc_list ]
+ else:
+ return [ fdc.latest_form for fdc in fdc_list if fdc.latest_form.type == form_type ]
def widget_fields_have_contents( self, widgets ):
# Return True if any of the fields in widgets contain contents, widgets is a list of dictionaries that looks something like:
# [{'widget': <galaxy.web.form_builder.TextField object at 0x10867aa10>, 'helptext': 'Field 0 help (Optional)', 'label': 'Field 0'}]
--- a/test/functional/test_forms_and_requests.py
+++ b/test/functional/test_forms_and_requests.py
@@ -360,44 +360,44 @@ class TestFormsAndRequests( TwillTestCas
# check if the request's state is now set to 'submitted'
assert request_two.state is not request_two.states.REJECTED, "The state of the request '%s' should be set to '%s'" \
% ( request_two.name, request_two.states.REJECTED )
-# def test_055_reset_data_for_later_test_runs( self ):
-# """Reseting data to enable later test runs to pass"""
-# # Logged in as admin_user
-# # remove the request_type permissions
-# rt_actions = sa_session.query( galaxy.model.RequestTypePermissions ) \
-# .filter(and_(galaxy.model.RequestTypePermissions.table.c.request_type_id==request_type.id) ) \
-# .order_by( desc( galaxy.model.RequestTypePermissions.table.c.create_time ) ) \
-# .all()
-# for a in rt_actions:
-# sa_session.delete( a )
-# sa_session.flush()
-# ##################
-# # Purge all libraries
-# ##################
-# for library in [ library_one ]:
-# self.delete_library_item( 'library_admin',
-# self.security.encode_id( library.id ),
-# self.security.encode_id( library.id ),
-# library.name,
-# item_type='library' )
-# self.purge_library( self.security.encode_id( library.id ), library.name )
-# ##################
-# # Eliminate all non-private roles
-# ##################
-# for role in [ role_one, role_two ]:
-# self.mark_role_deleted( self.security.encode_id( role.id ), role.name )
-# self.purge_role( self.security.encode_id( role.id ), role.name )
-# # Manually delete the role from the database
-# sa_session.refresh( role )
-# sa_session.delete( role )
-# sa_session.flush()
-# ##################
-# # Eliminate all groups
-# ##################
-# for group in [ group_one ]:
-# self.mark_group_deleted( self.security.encode_id( group.id ), group.name )
-# self.purge_group( self.security.encode_id( group.id ), group.name )
-# # Manually delete the group from the database
-# refresh( group )
-# sa_session.delete( group )
-# sa_session.flush()
+ def test_055_reset_data_for_later_test_runs( self ):
+ """Reseting data to enable later test runs to pass"""
+ # Logged in as admin_user
+ # remove the request_type permissions
+ rt_actions = sa_session.query( galaxy.model.RequestTypePermissions ) \
+ .filter(and_(galaxy.model.RequestTypePermissions.table.c.request_type_id==request_type.id) ) \
+ .order_by( desc( galaxy.model.RequestTypePermissions.table.c.create_time ) ) \
+ .all()
+ for a in rt_actions:
+ sa_session.delete( a )
+ sa_session.flush()
+ ##################
+ # Purge all libraries
+ ##################
+ for library in [ library_one ]:
+ self.delete_library_item( 'library_admin',
+ self.security.encode_id( library.id ),
+ self.security.encode_id( library.id ),
+ library.name,
+ item_type='library' )
+ self.purge_library( self.security.encode_id( library.id ), library.name )
+ ##################
+ # Eliminate all non-private roles
+ ##################
+ for role in [ role_one, role_two ]:
+ self.mark_role_deleted( self.security.encode_id( role.id ), role.name )
+ self.purge_role( self.security.encode_id( role.id ), role.name )
+ # Manually delete the role from the database
+ sa_session.refresh( role )
+ sa_session.delete( role )
+ sa_session.flush()
+ ##################
+ # Eliminate all groups
+ ##################
+ for group in [ group_one ]:
+ self.mark_group_deleted( self.security.encode_id( group.id ), group.name )
+ self.purge_group( self.security.encode_id( group.id ), group.name )
+ # Manually delete the group from the database
+ refresh( group )
+ sa_session.delete( group )
+ sa_session.flush()
--- a/templates/user/new_address.mako
+++ b/templates/user/new_address.mako
@@ -43,7 +43,7 @@
<div style="clear: both"></div></div><div class="form-row">
- <label>Address Line 1:</label>
+ <label>Address:</label><div style="float: left; width: 250px; margin-right: 10px;"><input type="text" name="address" value="${address}" size="40"></div>
--- a/lib/galaxy/web/controllers/user.py
+++ b/lib/galaxy/web/controllers/user.py
@@ -216,14 +216,10 @@ class User( BaseController, UsesFormDefi
the one that user has selected. And for existing users, the user info form is
retrieved from the db.
'''
- # TODO: the user controller must be decoupled from the model, so this import causes problems.
- # The get_all_forms method is used only if Galaxy is the webapp, so it needs to be re-worked
- # so that it can be imported with no problems if the controller is not 'galaxy'.
- from galaxy.web.controllers.forms import get_all_forms
params = util.Params( kwd )
# get all the user information forms
- user_info_forms = get_all_forms( trans, filter=dict(deleted=False),
- form_type=trans.app.model.FormDefinition.types.USER_INFO )
+ user_info_forms = self.get_all_forms( trans, filter=dict(deleted=False),
+ form_type=trans.app.model.FormDefinition.types.USER_INFO )
if new_user:
# if there are no user forms available then there is nothing to save
if not len( user_info_forms ):
@@ -331,10 +327,9 @@ class User( BaseController, UsesFormDefi
error = self.__validate_username( trans, username )
if not error:
if webapp == 'galaxy':
- from galaxy.web.controllers.forms import get_all_forms
- if len( get_all_forms( trans,
- filter=dict( deleted=False ),
- form_type=trans.app.model.FormDefinition.types.USER_INFO ) ):
+ if len( self.get_all_forms( trans,
+ filter=dict( deleted=False ),
+ form_type=trans.app.model.FormDefinition.types.USER_INFO ) ):
if not params.get( 'user_info_select', False ):
return "Select the user's type and information"
return error
@@ -347,12 +342,11 @@ class User( BaseController, UsesFormDefi
show a selectbox containing all the forms, then the user can select
the one that fits the user's description the most
'''
- from galaxy.web.controllers.forms import get_all_forms
params = util.Params( kwd )
# get all the user information forms
- user_info_forms = get_all_forms( trans,
- filter=dict( deleted=False ),
- form_type=trans.app.model.FormDefinition.types.USER_INFO )
+ user_info_forms = self.get_all_forms( trans,
+ filter=dict( deleted=False ),
+ form_type=trans.app.model.FormDefinition.types.USER_INFO )
user_info_select = None
if user:
if user.values:
@@ -423,7 +417,6 @@ class User( BaseController, UsesFormDefi
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
if webapp == 'galaxy':
- from galaxy.web.controllers.forms import get_all_forms
user_info_select, user_info_form, widgets = self.__user_info_ui( trans, user, **kwd )
# user's addresses
show_filter = util.restore_text( params.get( 'show_filter', 'Active' ) )
@@ -433,9 +426,9 @@ class User( BaseController, UsesFormDefi
addresses = [address for address in user.addresses if address.deleted]
else:
addresses = [address for address in user.addresses if not address.deleted]
- user_info_forms = get_all_forms( trans,
- filter=dict( deleted=False ),
- form_type=trans.app.model.FormDefinition.types.USER_INFO )
+ user_info_forms = self.get_all_forms( trans,
+ filter=dict( deleted=False ),
+ form_type=trans.app.model.FormDefinition.types.USER_INFO )
return trans.fill_template( '/webapps/galaxy/user/info.mako',
user=user,
email=email,
--- a/lib/galaxy/web/controllers/requests_common.py
+++ b/lib/galaxy/web/controllers/requests_common.py
@@ -7,7 +7,6 @@ from galaxy.util.streamball import Strea
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
from sqlalchemy.sql.expression import func, and_
from sqlalchemy.sql import select
import pexpect
--- a/lib/galaxy/web/controllers/forms.py
+++ b/lib/galaxy/web/controllers/forms.py
@@ -665,21 +665,3 @@ class Forms( BaseController ):
current_form_type=current_form[ 'type' ],
layout_grids=form_layout,
response_redirect=response_redirect )
-
-# Common methods for all components that use forms
-def get_all_forms( trans, all_versions=False, filter=None, form_type='All' ):
- '''
- Return all the latest forms from the form_definition_current table
- if all_versions is set to True. Otherwise return all the versions
- of all the forms from the form_definition table.
- '''
- if all_versions:
- return trans.sa_session.query( trans.app.model.FormDefinition )
- if filter:
- fdc_list = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ).filter_by( **filter )
- else:
- fdc_list = trans.sa_session.query( trans.app.model.FormDefinitionCurrent )
- if form_type == 'All':
- return [ fdc.latest_form for fdc in fdc_list ]
- else:
- return [ fdc.latest_form for fdc in fdc_list if fdc.latest_form.type == form_type ]
--- a/templates/user/edit_address.mako
+++ b/templates/user/edit_address.mako
@@ -42,7 +42,7 @@
<div style="clear: both"></div></div><div class="form-row">
- <label>Address Line 1:</label>
+ <label>Address:</label><div style="float: left; width: 250px; margin-right: 10px;"><input type="text" name="address" value="${address_obj.address}" size="40"></div>
--- a/lib/galaxy/web/controllers/requests_admin.py
+++ b/lib/galaxy/web/controllers/requests_admin.py
@@ -8,7 +8,6 @@ import logging, tempfile, zipfile, tarfi
from galaxy.web.form_builder import *
from datetime import datetime, timedelta
from email.MIMEText import MIMEText
-from galaxy.web.controllers.forms import get_all_forms
from sqlalchemy.sql.expression import func, and_
from sqlalchemy.sql import select
import pexpect
@@ -264,7 +263,7 @@ class DataTransferGrid( grids.Grid ):
# ---- Request Controller ------------------------------------------------------
#
-class RequestsAdmin( BaseController ):
+class RequestsAdmin( BaseController, UsesFormDefinitionWidgets ):
request_grid = RequestsGrid()
requesttype_grid = RequestTypeGrid()
datatx_grid = DataTransferGrid()
@@ -1061,7 +1060,7 @@ class RequestsAdmin( BaseController ):
message="Invalid requesttype ID") )
return trans.fill_template( '/admin/requests/view_request_type.mako',
request_type=rt,
- forms=get_all_forms( trans ),
+ forms=self.get_all_forms( trans ),
states_list=rt.states,
rename_dataset_selectbox=self.__rename_dataset_selectbox(trans, rt) )
def __view_form(self, trans, **kwd):
@@ -1104,7 +1103,7 @@ class RequestsAdmin( BaseController ):
rt, message = self.__save_request_type(trans, **kwd)
if not rt:
return trans.fill_template( '/admin/requests/create_request_type.mako',
- forms=get_all_forms( trans ),
+ forms=self.get_all_forms( trans ),
message=message,
status='error')
return trans.response.send_redirect( web.url_for( controller='requests_admin',
@@ -1144,12 +1143,12 @@ class RequestsAdmin( BaseController ):
status=status,
rename_dataset_selectbox=self.__rename_dataset_selectbox(trans))
def __create_request_type_form(self, trans, **kwd):
- request_forms=get_all_forms( trans,
- filter=dict(deleted=False),
- form_type=trans.app.model.FormDefinition.types.REQUEST )
- sample_forms=get_all_forms( trans,
- filter=dict(deleted=False),
- form_type=trans.app.model.FormDefinition.types.SAMPLE )
+ request_forms=self.get_all_forms( trans,
+ filter=dict(deleted=False),
+ form_type=trans.app.model.FormDefinition.types.REQUEST )
+ sample_forms=self.get_all_forms( trans,
+ filter=dict(deleted=False),
+ form_type=trans.app.model.FormDefinition.types.SAMPLE )
if not len(request_forms) or not len(sample_forms):
return [],[]
params = util.Params( kwd )
--- a/lib/galaxy/web/controllers/library_common.py
+++ b/lib/galaxy/web/controllers/library_common.py
@@ -5,7 +5,6 @@ from galaxy.datatypes import sniff
from galaxy.security import RBACAgent
from galaxy.util.json import to_json_string
from galaxy.tools.actions import upload_common
-from galaxy.web.controllers.forms import get_all_forms
from galaxy.model.orm import *
from galaxy.util.streamball import StreamBall
import logging, tempfile, zipfile, tarfile, os, sys
@@ -1935,9 +1934,9 @@ class LibraryCommon( BaseController, Use
@web.expose
def add_template( self, trans, cntrller, item_type, library_id, folder_id=None, ldda_id=None, **kwd ):
# Template can only be added to a Library, Folder or LibraryDatasetDatasetAssociation.
- forms = get_all_forms( trans,
- filter=dict( deleted=False ),
- form_type=trans.app.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE )
+ forms = self.get_all_forms( trans,
+ filter=dict( deleted=False ),
+ form_type=trans.app.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE )
if not forms:
message = "There are no forms on which to base the template, so create a form and then add the template."
return trans.response.send_redirect( web.url_for( controller='forms',
1
0