galaxy-dev
Threads by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- 10009 discussions
07 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/0d534da7f0ff
changeset: 2964:0d534da7f0ff
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Wed Nov 04 13:09:37 2009 -0500
description:
Eliminate printing PYTHONPATH to stderr in the cleanup_datasets.py script.
diffstat:
scripts/cleanup_datasets/cleanup_datasets.py | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diffs (11 lines):
diff -r fdf07565eedf -r 0d534da7f0ff scripts/cleanup_datasets/cleanup_datasets.py
--- a/scripts/cleanup_datasets/cleanup_datasets.py Wed Nov 04 12:58:48 2009 -0500
+++ b/scripts/cleanup_datasets/cleanup_datasets.py Wed Nov 04 13:09:37 2009 -0500
@@ -387,7 +387,6 @@
class CleanupDatasetsApplication( object ):
"""Encapsulates the state of a Universe application"""
def __init__( self, database_connection=None, file_path=None ):
- print >> sys.stderr, "python path is: " + ", ".join( sys.path )
if database_connection is None:
raise Exception( "CleanupDatasetsApplication requires a database_connection value" )
if file_path is None:
1
0
07 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/92d395c8614b
changeset: 2962:92d395c8614b
user: rc
date: Wed Nov 04 12:30:36 2009 -0500
description:
Fixed a bug in user info - adding new address
diffstat:
lib/galaxy/web/controllers/user.py | 114 +++++++++++++++++++++++---------------
templates/user/edit_address.mako | 2 +-
templates/user/info.mako | 2 +-
templates/user/new_address.mako | 33 +++++++++++
4 files changed, 104 insertions(+), 47 deletions(-)
diffs (200 lines):
diff -r adfcd8bb13d1 -r 92d395c8614b lib/galaxy/web/controllers/user.py
--- a/lib/galaxy/web/controllers/user.py Wed Nov 04 12:21:13 2009 -0500
+++ b/lib/galaxy/web/controllers/user.py Wed Nov 04 12:30:36 2009 -0500
@@ -272,7 +272,7 @@
user_address.country = util.restore_text(params.get('field_%i_country' % index, ''))
user_address.phone = util.restore_text(params.get('field_%i_phone' % index, ''))
user_address.flush()
- trans.user.refresh()
+ trans.sa_session.refresh( user )
values.append(int(user_address.id))
elif value == unicode('none'):
values.append('')
@@ -618,57 +618,81 @@
# User not logged in, history group must be only public
return trans.show_error_message( "You must be logged in to change your default permitted actions." )
@web.expose
- def new_address( self, trans, short_desc='', name='', institution='', address1='',
- address2='', city='', state='', postal_code='', country='', phone='' ):
- if trans.app.config.require_login:
- refresh_frames = [ 'masthead', 'history', 'tools' ]
- else:
- refresh_frames = [ 'masthead', 'history' ]
+ def new_address( self, trans, **kwd ):
+ params = util.Params( kwd )
+ msg = util.restore_text( params.get( 'msg', '' ) )
+ messagetype = params.get( 'messagetype', 'done' )
+ admin_view = params.get( 'admin_view', 'False' )
+ error = ''
+ user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'user_id', None ) ) )
if not trans.app.config.allow_user_creation and not trans.user_is_admin():
return trans.show_error_message( 'User registration is disabled. Please contact your Galaxy administrator for an account.' )
- short_desc_error = name_error = institution_error = address1_error = city_error = None
- address2_error = state_error = postal_code_error = country_error = phone_error = None
- if short_desc:
- if not len( short_desc ):
- short_desc_error = 'Enter a short description for this address'
- elif not len( name ):
- name_error = 'Enter the full name'
- elif not len( institution ):
- institution_error = 'Enter the institution associated with the user'
- elif not len ( address1 ):
- address1_error = 'Enter the address'
- elif not len( city ):
- city_error = 'Enter the city'
- elif not len( state ):
- state_error = 'Enter the state/province/region'
- elif not len( postal_code ):
- postal_code_error = 'Enter the postal code'
- elif not len( country ):
- country_error = 'Enter the country'
+ if params.get( 'save_new_address_button', None ) == 'Save':
+ if not len( util.restore_text( params.get( 'short_desc', '' ) ) ):
+ error = 'Enter a short description for this address'
+ elif not len( util.restore_text( params.get( 'name', '' ) ) ):
+ error = 'Enter the full name'
+ elif not len( util.restore_text( params.get( 'institution', '' ) ) ):
+ error = 'Enter the institution associated with the user'
+ elif not len ( util.restore_text( params.get( 'address1', '' ) ) ):
+ error = 'Enter the address'
+ elif not len( util.restore_text( params.get( 'city', '' ) ) ):
+ error = 'Enter the city'
+ elif not len( util.restore_text( params.get( 'state', '' ) ) ):
+ error = 'Enter the state/province/region'
+ elif not len( util.restore_text( params.get( 'postal_code', '' ) ) ):
+ error = 'Enter the postal code'
+ elif not len( util.restore_text( params.get( 'country', '' ) ) ):
+ error = 'Enter the country'
else:
- user_address = trans.app.model.UserAddress( user=trans.user, desc=short_desc,
- name=name, institution=institution,
- address=address1+' '+address2, city=city,
- state=state, postal_code=postal_code,
- country=country, phone=phone)
+ user_address = trans.app.model.UserAddress( user=user )
+ user_address.desc = util.restore_text( params.get( 'short_desc', '' ) )
+ user_address.name = util.restore_text( params.get( 'name', '' ) )
+ user_address.institution = util.restore_text( params.get( 'institution', '' ) )
+ user_address.address = util.restore_text( params.get( 'address1', '' ) )+' '+util.restore_text( params.get( 'address2', '' ) )
+ user_address.city = util.restore_text( params.get( 'city', '' ) )
+ user_address.state = util.restore_text( params.get( 'state', '' ) )
+ user_address.postal_code = util.restore_text( params.get( 'postal_code', '' ) )
+ user_address.country = util.restore_text( params.get( 'country', '' ) )
+ user_address.phone = util.restore_text( params.get( 'phone', '' ) )
user_address.flush()
+ msg = 'Address <b>%s</b> has been added' % user_address.desc
+ if admin_view == 'True':
+ return trans.response.send_redirect( web.url_for( controller='user',
+ action='show_info',
+ admin_view=True,
+ user_id=user.id,
+ msg=msg,
+ messagetype='done') )
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
- msg='Address <b>%s</b> has been added' % user_address.desc,
+ msg=msg,
messagetype='done') )
-
- return trans.show_form(
- web.FormBuilder( web.url_for(), "New address", submit_text="Save" )
- .add_text( "short_desc", "Short address description", value=short_desc, error=short_desc_error )
- .add_text( "name", "Name", value=name, error=name_error )
- .add_text( "institution", "Institution", value=institution, error=institution_error )
- .add_text( "address1", "Address Line 1", value=address1, error=address1_error )
- .add_text( "address2", "Address Line 2", value=address2, error=address2_error )
- .add_text( "city", "City", value=city, error=city_error )
- .add_text( "state", "State/Province/Region", value=state, error=state_error )
- .add_text( "postal_code", "Postal Code", value=postal_code, error=postal_code_error )
- .add_text( "country", "Country", value=country, error=country_error )
- .add_text( "phone", "Phone", value=phone, error=phone_error ) )
+ else:
+ # show the address form with the current values filled in
+ # create the widgets for each address field
+ widgets = []
+ widgets.append(dict(label='Short description',
+ widget=TextField( 'short_desc', 40, '' ) ) )
+ widgets.append(dict(label='Name',
+ widget=TextField( 'name', 40, '' ) ) )
+ widgets.append(dict(label='Institution',
+ widget=TextField( 'institution', 40, '' ) ) )
+ widgets.append(dict(label='Address Line 1',
+ widget=TextField( 'address1', 40, '' ) ) )
+ widgets.append(dict(label='City',
+ widget=TextField( 'city', 40, '' ) ) )
+ widgets.append(dict(label='State',
+ widget=TextField( 'state', 40, '' ) ) )
+ widgets.append(dict(label='Postal Code',
+ widget=TextField( 'postal_code', 40, '' ) ) )
+ widgets.append(dict(label='Country',
+ widget=TextField( 'country', 40, '' ) ) )
+ widgets.append(dict(label='Phone',
+ widget=TextField( 'phone', 40, '' ) ) )
+ return trans.fill_template( 'user/new_address.mako', user=user,
+ admin_view=admin_view,
+ widgets=widgets, msg=msg, messagetype=messagetype)
@web.expose
def edit_address( self, trans, **kwd ):
params = util.Params( kwd )
diff -r adfcd8bb13d1 -r 92d395c8614b templates/user/edit_address.mako
--- a/templates/user/edit_address.mako Wed Nov 04 12:21:13 2009 -0500
+++ b/templates/user/edit_address.mako Wed Nov 04 12:30:36 2009 -0500
@@ -11,7 +11,7 @@
<ul class="manage-table-actions">
<li>
- <a class="action-button" href="${h.url_for( controller='user', action='show_info')}">
+ <a class="action-button" href="${h.url_for( controller='user', action='show_info', admin_view=admin_view, user_id=user.id)}">
<span>Manage User Information</span></a>
</li>
</ul>
diff -r adfcd8bb13d1 -r 92d395c8614b templates/user/info.mako
--- a/templates/user/info.mako Wed Nov 04 12:21:13 2009 -0500
+++ b/templates/user/info.mako Wed Nov 04 12:30:36 2009 -0500
@@ -99,7 +99,7 @@
</div>
</form>
%endif
- <form name="user_info" id="user_info" action="${h.url_for( controller='user', action='new_address' )}" method="post" >
+ <form name="user_info" id="user_info" action="${h.url_for( controller='user', action='new_address', user_id=user.id, admin_view=admin_view )}" method="post" >
<div class="toolFormTitle">User Addresses</div>
<div class="toolFormBody">
%if user.addresses:
diff -r adfcd8bb13d1 -r 92d395c8614b templates/user/new_address.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/user/new_address.mako Wed Nov 04 12:30:36 2009 -0500
@@ -0,0 +1,33 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+</br>
+</br>
+<h3>New address</h3>
+
+<ul class="manage-table-actions">
+ <li>
+ <a class="action-button" href="${h.url_for( controller='user', action='show_info', admin_view=admin_view, user_id=user.id)}">
+ <span>Manage User Information</span></a>
+ </li>
+</ul>
+<div class="toolForm">
+<form name="login_info" id="login_info" action="${h.url_for( controller='user', action='new_address', admin_view=admin_view, user_id=user.id )}" method="post" >
+ <div class="toolFormTitle">New address</div>
+ <div class="toolFormBody">
+ %for field in widgets:
+ <div class="form-row">
+ <label>${field[ 'label' ]}</label>
+ ${field[ 'widget' ].get_html()}
+ </div>
+ %endfor
+ <div class="form-row">
+ <input type="submit" name="save_new_address_button" value="Save">
+ </div>
+ </div>
+</form>
+</div>
\ No newline at end of file
1
0
07 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/fdf07565eedf
changeset: 2963:fdf07565eedf
user: Nate Coraor <nate(a)bx.psu.edu>
date: Wed Nov 04 12:58:48 2009 -0500
description:
Add the GeneTrack egg. Also includes some enhancements and cleanup of the eggs/fetch/scramble code.
diffstat:
dist-eggs.ini | 4 +
eggs.ini | 5 +-
lib/galaxy/config.py | 13 +++
lib/galaxy/eggs/__init__.py | 149 ++++++++++++++----------------------
scripts/fetch_eggs.py | 36 ++++----
scripts/scramble.py | 28 +++---
scripts/scramble/scripts/GeneTrack.py | 52 +++++++++++++
7 files changed, 164 insertions(+), 123 deletions(-)
diffs (490 lines):
diff -r 92d395c8614b -r fdf07565eedf dist-eggs.ini
--- a/dist-eggs.ini Wed Nov 04 12:30:36 2009 -0500
+++ b/dist-eggs.ini Wed Nov 04 12:58:48 2009 -0500
@@ -57,3 +57,7 @@
all = py2.4-all py2.5-all py2.6-all
; default hosts for platform-inspecific eggs
noplatform = py2.4-linux-i686-ucs4 py2.5-linux-i686-ucs4 py2.6-linux-i686-ucs4
+
+[ignore]
+; Don't build these eggs on these platforms:
+GeneTrack = py2.4-noplatform
diff -r 92d395c8614b -r fdf07565eedf eggs.ini
--- a/eggs.ini Wed Nov 04 12:30:36 2009 -0500
+++ b/eggs.ini Wed Nov 04 12:58:48 2009 -0500
@@ -9,7 +9,7 @@
[general]
repository = http://eggs.g2.bx.psu.edu
; these eggs must be scrambled for your local environment
-no_download = pbs_python DRMAA_python
+no_auto = pbs_python DRMAA_python
[eggs:platform]
bx_python = 0.5.0
@@ -31,6 +31,7 @@
decorator = 3.1.2
docutils = 0.4
elementtree = 1.2.6_20050316
+GeneTrack = 2.0.0_beta_1
lrucache = 0.2
;lsprof - james
Mako = 0.2.5
@@ -61,6 +62,7 @@
python_lzo = _static
flup = .dev_r2311
bx_python = _dev_r4bf1f32e6b76
+GeneTrack = _dev_raa786e9fc131d998e532a1aef39d108850c9e93d
; nose = .dev_r7156749efc58
; source location, necessary for scrambling
@@ -81,6 +83,7 @@
decorator = http://pypi.python.org/packages/source/d/decorator/decorator-3.1.2.tar.gz
docutils = http://downloads.sourceforge.net/docutils/docutils-0.4.tar.gz
elementtree = http://effbot.org/downloads/elementtree-1.2.6-20050316.tar.gz
+GeneTrack = http://github.com/ialbert/genetrack-central/tarball/aa786e9fc131d998e532a1a…
lrucache = http://evan.prodromou.name/lrucache/lrucache-0.2.tar.gz
Mako = http://www.makotemplates.org/downloads/Mako-0.2.5.tar.gz
MyghtyUtils = http://cheeseshop.python.org/packages/source/M/MyghtyUtils/MyghtyUtils-0.52…
diff -r 92d395c8614b -r fdf07565eedf lib/galaxy/config.py
--- a/lib/galaxy/config.py Wed Nov 04 12:30:36 2009 -0500
+++ b/lib/galaxy/config.py Wed Nov 04 12:58:48 2009 -0500
@@ -8,6 +8,9 @@
import ConfigParser
from galaxy.util import string_as_bool
+from galaxy import eggs
+import pkg_resources
+
log = logging.getLogger( __name__ )
def resolve_path( path, root ):
@@ -126,6 +129,16 @@
for path in self.tool_config, self.datatypes_config:
if not os.path.isfile(path):
raise ConfigurationError("File not found: %s" % path )
+ # Check job runners so the admin can scramble dependent egg.
+ if self.start_job_runners is not None:
+ runner_to_egg = dict( pbs = 'pbs_python', sge = 'DRMAA_python' )
+ for runner in self.start_job_runners.split( ',' ):
+ try:
+ pkg_resources.require( runner_to_egg[runner] )
+ except eggs.EggNotFetchable, e:
+ raise eggs.EggNotFetchable( 'You must scramble the %s egg to use the %s job runner. Instructions are available at:\n http://bitbucket.org/galaxy/galaxy-central/wiki/Config/Cluster' % ( runner_to_egg[runner], runner ) )
+ except KeyError:
+ raise Exception( 'No such job runner: %s. Please double-check the value of start_job_runners in universe_wsgi.ini' % runner )
def is_admin_user( self,user ):
"""
diff -r 92d395c8614b -r fdf07565eedf lib/galaxy/eggs/__init__.py
--- a/lib/galaxy/eggs/__init__.py Wed Nov 04 12:30:36 2009 -0500
+++ b/lib/galaxy/eggs/__init__.py Wed Nov 04 12:58:48 2009 -0500
@@ -14,11 +14,12 @@
# within tools. i don't know of any way around this. -ndc
galaxy_dir = os.path.abspath( os.path.join( os.path.dirname( __file__ ), "..", "..", ".." ) )
-class NewEgg( Exception ):
- pass
-
class EggNotFetchable( Exception ):
- pass
+ def __init__( self, eggs ):
+ if type( eggs ) in ( list, tuple ):
+ self.eggs = eggs
+ else:
+ self.eggs = [ eggs ]
class PlatformNotSupported( Exception ):
pass
@@ -157,6 +158,14 @@
# scramble helper methods
def get_archive_path( self, url ):
return os.path.join( Egg.archive_dir, (url.rsplit( '/', 1 ))[1] )
+ def get_tld( self, names ):
+ tld = names[0].split( os.path.sep, 1 )[0]
+ for name in names:
+ try:
+ assert tld == name.split( os.path.sep, 1 )[0]
+ except:
+ raise Exception( "get_tld(): Archive contains multiple top-level directories!" )
+ return tld
def fetch_source( self ):
if not os.access( Egg.archive_dir, os.F_OK ):
os.makedirs( Egg.archive_dir )
@@ -195,7 +204,7 @@
log.warning( " %s" % self.buildpath )
def unpack_zip( self, source_path, unpack_path ):
z = zipfile.ZipFile( source_path, "r" )
- tld = ( z.namelist()[0].split( os.path.sep, 1 ) )[0]
+ tld = self.get_tld( z.namelist() )
cur = os.getcwd()
os.chdir( unpack_path )
for fn in z.namelist():
@@ -211,12 +220,12 @@
os.chdir( cur )
def unpack_tar( self, source_path, unpack_path ):
t = tarfile.open( source_path, "r" )
- tld = ( t.getnames()[0].split( os.path.sep, 1 ) )[0]
+ members = filter( lambda x: "ez_setup" not in x.name and "pax_global_header" != x.name, t.getmembers() )
+ tld = self.get_tld( [ x.name for x in members ] )
cur = os.getcwd()
os.chdir( unpack_path )
- for member in t.getmembers():
- if "ez_setup" not in member.name:
- t.extract( member )
+ for member in members:
+ t.extract( member )
t.close()
os.rename( tld, self.name )
os.chdir( cur )
@@ -265,7 +274,7 @@
self.eggs = {}
self.config = CSConfigParser()
self.repo = None
- self.no_download = []
+ self.no_auto = []
self.platform = { 'peak' : get_platform( platform=True, peak=True ), 'galaxy' : get_platform( platform=True, peak=False ) }
self.noplatform = { 'peak' : get_platform( platform=False, peak=True ), 'galaxy' : get_platform( platform=False, peak=False ) }
def parse( self ):
@@ -273,7 +282,7 @@
raise Exception( "unable to read egg config from %s" % Crate.config_file )
try:
self.repo = self.config.get( "general", "repository" )
- self.no_download = self.config.get( "general", "no_download" ).split()
+ self.no_auto = self.config.get( "general", "no_auto" ).split()
except ConfigParser.NoSectionError:
raise Exception( "eggs.ini is missing required section [general]" )
#except ConfigParser.NoOptionError:
@@ -316,19 +325,19 @@
return True
def fetch( self, ignore=[] ):
"""
- Fetch all eggs in the crate (ignoring any that you want to
- ignore). If your platform isn't available, it'll attempt to
- download all the noplatform eggs before failing.
+ Fetch all eggs in the crate (ignoring any that you want to
+ ignore). If your platform isn't available, it'll attempt to
+ download all the noplatform eggs before failing.
"""
skip_platform = False
- ignore.extend( self.no_download )
+ ignore.extend( self.no_auto )
+ missing = []
try:
f = urllib2.urlopen( "%s/%s" % ( self.repo, self.platform['galaxy'] ) )
f.close()
except urllib2.HTTPError, e:
if e.code == 404:
skip_platform = True
- missing = []
for egg in self.eggs.itervalues():
if ignore is not None:
if egg.name in ignore:
@@ -336,11 +345,18 @@
if skip_platform and egg.platform['galaxy'] == self.platform['galaxy']:
missing.append( egg.name )
continue
- egg.fetch()
+ try:
+ egg.fetch()
+ except EggNotFetchable:
+ missing.append( egg.name )
if skip_platform:
raise PlatformNotSupported( self.platform['galaxy'] )
+ if missing:
+ raise EggNotFetchable( missing )
return True
def scramble( self, ignore=None ):
+ # Crate-scrambling the no_auto eggs makes no sense
+ ignore.extend( self.no_auto )
for egg in self.eggs.itervalues():
if ignore is not None:
if egg.name in ignore:
@@ -379,21 +395,14 @@
if self.config.read( DistCrate.dist_config_file ) == []:
raise Exception( "unable to read dist egg config from %s" % DistCrate.dist_config_file )
try:
- self.hosts = self.dictize_list_of_tuples( self.config.items( "hosts" ) )
- self.groups = self.dictize_list_of_tuples( self.config.items( "groups" ) )
+ self.hosts = dict( self.config.items( "hosts" ) )
+ self.groups = dict( self.config.items( "groups" ) )
+ self.ignore = dict( self.config.items( "ignore" ) )
except ConfigParser.NoSectionError, e:
raise Exception( "eggs.ini is missing required section: %s" % e )
self.platforms = self.get_platforms( self.build_on )
self.noplatforms = self.get_platforms( 'noplatform' )
Crate.parse( self )
- def dictize_list_of_tuples( self, lot ):
- """
- Makes a list of 2-value tuples into a dict.
- """
- d = {}
- for k, v in lot:
- d[k] = v
- return d
def get_platforms( self, wanted ):
# find all the members of a group and process them
if self.groups.has_key( wanted ):
@@ -409,8 +418,8 @@
raise Exception( "unknown platform: %s" % wanted )
def parse_egg_section( self, eggs, type ):
"""
- Overrides the base class's method. Here we use the third arg
- to find out what type of egg we'll be building.
+ Overrides the base class's method. Here we use the third arg
+ to find out what type of egg we'll be building.
"""
if type == "platform":
platforms = self.platforms
@@ -418,14 +427,16 @@
platforms = self.noplatforms
for name, version in eggs:
for platform in platforms:
- # can't use the regular methods here because we're not
- # actually ON the target platform
+ # can't use the regular methods here because we're not
+ # actually ON the target platform
if type == "platform":
gplat = platform
pplat = platform.rsplit('-', 1)[0]
elif type == "noplatform":
gplat = "%s-noplatform" % platform.split('-', 1)[0]
pplat = platform.split('-', 1)[0]
+ if name in self.ignore and gplat in self.ignore[name].split():
+ continue
egg = Egg()
try:
egg.tag = self.config.get( "tags", name )
@@ -448,75 +459,31 @@
class GalaxyConfig:
config_file = os.path.join( galaxy_dir, "universe_wsgi.ini" )
+ always_conditional = ( 'GeneTrack', )
def __init__( self ):
self.config = ConfigParser.ConfigParser()
if self.config.read( GalaxyConfig.config_file ) == []:
raise Exception( "error: unable to read Galaxy config from %s" % GalaxyConfig.config_file )
# TODO: conditionals should really be handled better than this
def check_conditional( self, egg_name ):
- if egg_name == "psycopg2":
+ if egg_name == "pysqlite":
+ # SQLite is different since it can be specified in two config vars and defaults to True
try:
- if self.config.get( "app:main", "database_connection" ).startswith( "postgres://" ):
- return True
- else:
- return False
+ return self.config.get( "app:main", "database_connection" ).startswith( "sqlite://" )
+ except:
+ return True
+ else:
+ try:
+ return { "psycopg2": lambda: self.config.get( "app:main", "database_connection" ).startswith( "postgres://" ),
+ "MySQL_python": lambda: self.config.get( "app:main", "database_connection" ).startswith( "mysql://" ),
+ "DRMAA_python": lambda: "sge" in self.config.get( "app:main", "start_job_runners" ).split(","),
+ "pbs_python": lambda: "pbs" in self.config.get( "app:main", "start_job_runners" ).split(","),
+ "threadframe": lambda: self.config.get( "app:main", "use_heartbeat" ),
+ "guppy": lambda: self.config.get( "app:main", "use_memdump" ),
+ "GeneTrack": lambda: sys.version_info[:2] >= ( 2, 5 ),
+ }.get( egg_name, lambda: True )()
except:
return False
- elif egg_name == "pysqlite":
- try:
- # database connection is the sqlite alchemy dialect (not really
- # a documented usage in Galaxy, but it would work)
- if self.config.get( "app:main", "database_connection" ).startswith( "sqlite://" ):
- return True
- else:
- return False
- # database connection is unset, so sqlite is the default
- except:
- return True
- elif egg_name == "DRMAA_python":
- try:
- runners = self.config.get( "app:main", "start_job_runners" ).split(",")
- if "sge" in runners:
- return True
- else:
- return False
- except:
- return False
- elif egg_name == "pbs_python":
- try:
- runners = self.config.get( "app:main", "start_job_runners" ).split(",")
- if "pbs" in runners:
- return True
- else:
- return False
- except:
- return False
- elif egg_name == "threadframe":
- try:
- if self.config.get( "app:main", "use_heartbeat" ):
- return True
- else:
- return False
- except:
- return False
- elif egg_name == "guppy":
- try:
- if self.config.get( "app:main", "use_memdump" ):
- return True
- else:
- return False
- except:
- return False
- elif egg_name == "MySQL_python":
- try:
- if self.config.get( "app:main", "database_connection" ).startswith( "mysql://" ):
- return True
- else:
- return False
- except:
- return False
- else:
- return True
def require( pkg ):
# add the egg dirs to sys.path if they're not already there
diff -r 92d395c8614b -r fdf07565eedf scripts/fetch_eggs.py
--- a/scripts/fetch_eggs.py Wed Nov 04 12:30:36 2009 -0500
+++ b/scripts/fetch_eggs.py Wed Nov 04 12:58:48 2009 -0500
@@ -25,26 +25,28 @@
c.platform = { 'peak' : sys.argv[2].rsplit('-',1)[0], 'galaxy' : sys.argv[2] }
c.parse()
try:
+ galaxy_config = GalaxyConfig()
+ names = []
if len( sys.argv ) == 1:
- galaxy_config = GalaxyConfig()
- ignore = []
- for name in c.get_names():
- if not galaxy_config.check_conditional( name ):
- ignore.append( name )
- c.fetch( ignore=ignore )
+ names = c.get_names()
+ elif sys.argv[1] == 'all':
+ names = galaxy_config.always_conditional
else:
- if sys.argv[1] == 'all':
- c.fetch()
- else:
- egg = c.get( sys.argv[1] )
- if egg is None:
- print "error: %s not in eggs.ini" % sys.argv[1]
- sys.exit( 1 )
- egg.fetch()
+ # Fetch a specific egg
+ egg = c.get( sys.argv[1] )
+ if egg is None:
+ print "error: %s not in eggs.ini" % sys.argv[1]
+ sys.exit( 1 )
+ egg.fetch()
+ sys.exit( 0 )
+ ignore = filter( lambda x: not galaxy_config.check_conditional( x ), list( names ) )
+ c.fetch( ignore )
except EggNotFetchable, e:
- print "One of the python eggs necessary to run Galaxy couldn't be downloaded"
- print "automatically. You may want to try building it by hand with:"
- print " python scripts/scramble.py %s" % e
+ print "One or more of the python eggs necessary to run Galaxy couldn't be"
+ print "downloaded automatically. You may want to try building them by"
+ print "hand with:"
+ for egg in e.eggs:
+ print " python scripts/scramble.py %s" % egg
sys.exit( 1 )
except PlatformNotSupported, e:
print "Your platform (%s) is not supported." % e
diff -r 92d395c8614b -r fdf07565eedf scripts/scramble.py
--- a/scripts/scramble.py Wed Nov 04 12:30:36 2009 -0500
+++ b/scripts/scramble.py Wed Nov 04 12:58:48 2009 -0500
@@ -18,19 +18,19 @@
c = Crate()
c.parse()
+galaxy_config = GalaxyConfig()
+names = []
if len( sys.argv ) == 1:
- galaxy_config = GalaxyConfig()
- ignore = []
- for name in c.get_names():
- if not galaxy_config.check_conditional( name ):
- ignore.append( name )
- c.scramble( ignore=ignore )
+ names = c.get_names()
+elif sys.argv[1] == 'all':
+ names = galaxy_config.always_conditional
else:
- if sys.argv[1] == 'all':
- c.scramble()
- else:
- egg = c.get( sys.argv[1] )
- if egg is None:
- print "error: %s not in eggs.ini" % sys.argv[1]
- sys.exit( 1 )
- egg.scramble()
+# Scramble a specific egg
+ egg = c.get( sys.argv[1] )
+ if egg is None:
+ print "error: %s not in eggs.ini" % sys.argv[1]
+ sys.exit( 1 )
+ egg.scramble()
+ sys.exit( 0 )
+ignore = filter( lambda x: not galaxy_config.check_conditional( x ), list( names ) )
+c.scramble( ignore=ignore )
diff -r 92d395c8614b -r fdf07565eedf scripts/scramble/scripts/GeneTrack.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/scramble/scripts/GeneTrack.py Wed Nov 04 12:58:48 2009 -0500
@@ -0,0 +1,52 @@
+import os, sys, shutil
+
+# change back to the build dir
+if os.path.dirname( sys.argv[0] ) != "":
+ os.chdir( os.path.dirname( sys.argv[0] ) )
+
+# find setuptools
+scramble_lib = os.path.join( "..", "..", "..", "lib" )
+sys.path.append( scramble_lib )
+from ez_setup import use_setuptools
+use_setuptools( download_delay=8, to_dir=scramble_lib )
+from setuptools import *
+
+# get the tag
+if os.access( ".galaxy_tag", os.F_OK ):
+ tagfile = open( ".galaxy_tag", "r" )
+ tag = tagfile.readline().strip()
+else:
+ tag = None
+
+# in case you're running this by hand from a dirty module source dir
+for dir in [ "build", "dist" ]:
+ if os.access( dir, os.F_OK ):
+ print "scramble.py: removing dir:", dir
+ shutil.rmtree( dir )
+
+# reset args for distutils
+me = sys.argv[0]
+sys.argv = [ me ]
+sys.argv.append( "egg_info" )
+if tag is not None:
+ #sys.argv.append( "egg_info" )
+ sys.argv.append( "--tag-build=%s" %tag )
+# svn revision (if any) is handled directly in tag-build
+sys.argv.append( "--no-svn-revision" )
+sys.argv.append( "bdist_egg" )
+
+print "scramble.py: Creating setup.py for GeneTrack"
+setup_py = """from setuptools import setup, find_packages
+setup(
+ name = "GeneTrack",
+ version = "2.0.0-beta-1",
+ package_data = {'':["*.*"]},
+ packages = find_packages(),
+ zip_safe = True,
+)
+"""
+open( 'setup.py', 'w' ).write( setup_py )
+
+
+# do it
+execfile( "setup.py", globals(), locals() )
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/adfcd8bb13d1
changeset: 2961:adfcd8bb13d1
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Wed Nov 04 12:21:13 2009 -0500
description:
Quick fix for maf_utilities.src_split.
diffstat:
lib/galaxy/tools/util/maf_utilities.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diffs (12 lines):
diff -r 91a3bbb52d7a -r adfcd8bb13d1 lib/galaxy/tools/util/maf_utilities.py
--- a/lib/galaxy/tools/util/maf_utilities.py Wed Nov 04 12:15:53 2009 -0500
+++ b/lib/galaxy/tools/util/maf_utilities.py Wed Nov 04 12:21:13 2009 -0500
@@ -23,7 +23,7 @@
fields = src.split( SRC_SPLIT_CHAR, 1 )
spec = fields.pop( 0 )
if fields:
- chrom = fields
+ chrom = fields.pop( 0 )
else:
chrom = spec
return spec, chrom
1
0
07 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/91a3bbb52d7a
changeset: 2960:91a3bbb52d7a
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Wed Nov 04 12:15:53 2009 -0500
description:
Fix maf_utilities.src_split. Should resolve tickets #200, #215 and #220.
Note: Do not use bx.align.src_split in Galaxy.
diffstat:
lib/galaxy/datatypes/converters/maf_to_interval_converter.py | 2 +-
lib/galaxy/datatypes/converters/maf_to_interval_converter.xml | 2 +-
lib/galaxy/tools/util/maf_utilities.py | 11 +++++++----
3 files changed, 9 insertions(+), 6 deletions(-)
diffs (49 lines):
diff -r 4bca8f8ed94d -r 91a3bbb52d7a lib/galaxy/datatypes/converters/maf_to_interval_converter.py
--- a/lib/galaxy/datatypes/converters/maf_to_interval_converter.py Wed Nov 04 11:35:50 2009 -0500
+++ b/lib/galaxy/datatypes/converters/maf_to_interval_converter.py Wed Nov 04 12:15:53 2009 -0500
@@ -21,7 +21,7 @@
for block in bx.align.maf.Reader( open( input_name, 'r' ) ):
for c in maf_utilities.iter_components_by_src_start( block, species ):
if c is not None:
- out.write( "%s\t%i\t%i\t%s\n" % ( bx.align.src_split( c.src )[-1], c.get_forward_strand_start(), c.get_forward_strand_end(), c.strand ) )
+ out.write( "%s\t%i\t%i\t%s\n" % ( maf_utilities.src_split( c.src )[-1], c.get_forward_strand_start(), c.get_forward_strand_end(), c.strand ) )
count += 1
except Exception, e:
print >> sys.stderr, "There was a problem processing your input: %s" % e
diff -r 4bca8f8ed94d -r 91a3bbb52d7a lib/galaxy/datatypes/converters/maf_to_interval_converter.xml
--- a/lib/galaxy/datatypes/converters/maf_to_interval_converter.xml Wed Nov 04 11:35:50 2009 -0500
+++ b/lib/galaxy/datatypes/converters/maf_to_interval_converter.xml Wed Nov 04 12:15:53 2009 -0500
@@ -1,4 +1,4 @@
-<tool id="CONVERTER_maf_to_interval_0" name="Convert MAF to Genomic Intervals" version="1.0.1">
+<tool id="CONVERTER_maf_to_interval_0" name="Convert MAF to Genomic Intervals" version="1.0.2">
<!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
<command interpreter="python">maf_to_interval_converter.py $output1 $input1 ${input1.metadata.dbkey}</command>
<inputs>
diff -r 4bca8f8ed94d -r 91a3bbb52d7a lib/galaxy/tools/util/maf_utilities.py
--- a/lib/galaxy/tools/util/maf_utilities.py Wed Nov 04 11:35:50 2009 -0500
+++ b/lib/galaxy/tools/util/maf_utilities.py Wed Nov 04 12:15:53 2009 -0500
@@ -20,9 +20,12 @@
SRC_SPLIT_CHAR = '.'
def src_split( src ):
- spec, chrom = bx.align.maf.src_split( src )
- if None in [ spec, chrom ]:
- spec = chrom = src
+ fields = src.split( SRC_SPLIT_CHAR, 1 )
+ spec = fields.pop( 0 )
+ if fields:
+ chrom = fields
+ else:
+ chrom = spec
return spec, chrom
def src_merge( spec, chrom, contig = None ):
@@ -530,7 +533,7 @@
if suffix:
header = "%s%s" % ( header, suffix )
else:
- header = "%s%s" % ( header, bx.align.src_split( component.src )[ 0 ] )
+ header = "%s%s" % ( header, src_split( component.src )[ 0 ] )
return header
def get_attributes_from_fasta_header( header ):
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/4bca8f8ed94d
changeset: 2959:4bca8f8ed94d
user: James Taylor <james(a)jamestaylor.org>
date: Wed Nov 04 11:35:50 2009 -0500
description:
Fix tool test specification by id
diffstat:
test/functional/test_toolbox.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diffs (9 lines):
diff -r 0e78d558fe57 -r 4bca8f8ed94d test/functional/test_toolbox.py
--- a/test/functional/test_toolbox.py Wed Nov 04 10:16:20 2009 -0500
+++ b/test/functional/test_toolbox.py Wed Nov 04 11:35:50 2009 -0500
@@ -128,4 +128,4 @@
for j, testdef in enumerate( tool.tests ):
name = "%s ( %s ) > %s" % ( tool.name, tool.id, testdef.name )
testcase = get_case( testdef, name )
- G[ 'testcase_%d_%d' % ( i, j ) ] = testcase
+ G[ testcase.__name__ ] = testcase
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/0e78d558fe57
changeset: 2958:0e78d558fe57
user: rc
date: Wed Nov 04 10:16:20 2009 -0500
description:
Fixed the ordering in selectboxes
Fixed a bug in editing samples in the request page
diffstat:
lib/galaxy/model/mapping.py | 3 ++-
lib/galaxy/web/controllers/forms.py | 4 +++-
lib/galaxy/web/controllers/requests.py | 9 +++++----
lib/galaxy/web/controllers/requests_admin.py | 22 ++++++++++++----------
templates/admin/requests/show_request.mako | 2 +-
templates/requests/show_request.mako | 4 ----
test/base/twilltestcase.py | 2 +-
7 files changed, 24 insertions(+), 22 deletions(-)
diffs (191 lines):
diff -r 5b2d593d9aed -r 0e78d558fe57 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py Wed Nov 04 10:04:51 2009 -0500
+++ b/lib/galaxy/model/mapping.py Wed Nov 04 10:16:20 2009 -0500
@@ -652,7 +652,8 @@
primaryjoin=( Request.table.c.user_id == User.table.c.id ),
backref="requests" ),
samples=relation( Sample,
- primaryjoin=( Request.table.c.id == Sample.table.c.request_id ) ),
+ primaryjoin=( Request.table.c.id == Sample.table.c.request_id ),
+ order_by=asc(Sample.table.c.update_time) ),
folder=relation( LibraryFolder,
primaryjoin=( Request.table.c.folder_id == LibraryFolder.table.c.id ) ),
library=relation( Library,
diff -r 5b2d593d9aed -r 0e78d558fe57 lib/galaxy/web/controllers/forms.py
--- a/lib/galaxy/web/controllers/forms.py Wed Nov 04 10:04:51 2009 -0500
+++ b/lib/galaxy/web/controllers/forms.py Wed Nov 04 10:16:20 2009 -0500
@@ -60,7 +60,9 @@
form_type_selectbox.add_option('Select one', 'none', selected=True)
else:
form_type_selectbox.add_option('Select one', 'none')
- for ft in trans.app.model.FormDefinition.types.items():
+ fd_types = trans.app.model.FormDefinition.types.items()
+ fd_types.sort()
+ for ft in fd_types:
if selected == ft[1]:
form_type_selectbox.add_option(ft[1], ft[1], selected=True)
else:
diff -r 5b2d593d9aed -r 0e78d558fe57 lib/galaxy/web/controllers/requests.py
--- a/lib/galaxy/web/controllers/requests.py Wed Nov 04 10:04:51 2009 -0500
+++ b/lib/galaxy/web/controllers/requests.py Wed Nov 04 10:16:20 2009 -0500
@@ -304,8 +304,7 @@
s = trans.app.model.Sample(sample_name, '', request, form_values)
s.flush()
else:
- for index in range(len(current_samples)):
- sample_index = index
+ for sample_index in range(len(current_samples)):
sample_name = current_samples[sample_index][0]
new_sample_name = util.restore_text( params.get( 'sample_%i_name' % sample_index, '' ) )
sample_values = []
@@ -379,8 +378,10 @@
details=details,
edit_mode=edit_mode)
def __select_request_type(self, trans, rtid):
+ requesttype_list = trans.sa_session.query( trans.app.model.RequestType )\
+ .order_by( trans.app.model.RequestType.name.asc() )
rt_ids = ['none']
- for rt in trans.sa_session.query( trans.app.model.RequestType ):
+ for rt in requesttype_list:
if not rt.deleted:
rt_ids.append(str(rt.id))
select_reqtype = SelectField('select_request_type',
@@ -390,7 +391,7 @@
select_reqtype.add_option('Select one', 'none', selected=True)
else:
select_reqtype.add_option('Select one', 'none')
- for rt in trans.sa_session.query( trans.app.model.RequestType ):
+ for rt in requesttype_list:
if not rt.deleted:
if rtid == rt.id:
select_reqtype.add_option(rt.name, rt.id, selected=True)
diff -r 5b2d593d9aed -r 0e78d558fe57 lib/galaxy/web/controllers/requests_admin.py
--- a/lib/galaxy/web/controllers/requests_admin.py Wed Nov 04 10:04:51 2009 -0500
+++ b/lib/galaxy/web/controllers/requests_admin.py Wed Nov 04 10:16:20 2009 -0500
@@ -266,8 +266,10 @@
#---- Request Creation ----------------------------------------------------------
#
def __select_request_type(self, trans, rtid):
+ requesttype_list = trans.sa_session.query( trans.app.model.RequestType )\
+ .order_by( trans.app.model.RequestType.name.asc() )
rt_ids = ['none']
- for rt in trans.sa_session.query( trans.app.model.RequestType ):
+ for rt in requesttype_list:
if not rt.deleted:
rt_ids.append(str(rt.id))
select_reqtype = SelectField('select_request_type',
@@ -277,7 +279,7 @@
select_reqtype.add_option('Select one', 'none', selected=True)
else:
select_reqtype.add_option('Select one', 'none')
- for rt in trans.sa_session.query( trans.app.model.RequestType ):
+ for rt in requesttype_list:
if not rt.deleted:
if rtid == rt.id:
select_reqtype.add_option(rt.name, rt.id, selected=True)
@@ -799,7 +801,7 @@
# save all the new/unsaved samples entered by the user
if edit_mode == 'False':
for index in range(len(current_samples)-len(request.samples)):
- sample_index = index + len(request.samples)
+ sample_index = len(request.samples)
sample_name = util.restore_text( params.get( 'sample_%i_name' % sample_index, '' ) )
sample_values = []
for field_index in range(len(request.type.sample_form.fields)):
@@ -992,7 +994,7 @@
bar_code = util.restore_text(params.get('sample_%i_bar_code' % index, ''))
# check for empty bar code
if not bar_code.strip():
- msg = 'Please fill the bar code for sample <b>%s</b>.' % request.samples[index].name
+ msg = 'Please fill the barcode for sample <b>%s</b>.' % request.samples[index].name
break
# check all the unsaved bar codes
count = 0
@@ -1000,8 +1002,8 @@
if bar_code == util.restore_text(params.get('sample_%i_bar_code' % i, '')):
count = count + 1
if count > 1:
- msg = '''The bar code <b>%s</b> of sample <b>%s</b> already belongs
- another sample in this request. The sample bar codes must
+ msg = '''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
@@ -1009,7 +1011,7 @@
all_samples = trans.sa_session.query( trans.app.model.Sample )
for sample in all_samples:
if bar_code == sample.bar_code:
- msg = '''The bar code <b>%s</b> of sample <b>%s</b> already
+ msg = '''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)
@@ -1044,7 +1046,7 @@
return trans.response.send_redirect( web.url_for( controller='requests_admin',
action='bar_codes',
request_id=request.id,
- msg='Bar codes has been saved for this request',
+ msg='Bar codes have been saved for this request',
messagetype='done'))
def __set_request_state(self, request):
@@ -1162,8 +1164,8 @@
if params.get( 'create', False ):
return trans.fill_template( '/admin/requests/create_request_type.mako',
request_forms=get_all_forms( trans,
- filter=dict(deleted=False),
- form_type=trans.app.model.FormDefinition.types.REQUEST ),
+ 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 ),
diff -r 5b2d593d9aed -r 0e78d558fe57 templates/admin/requests/show_request.mako
--- a/templates/admin/requests/show_request.mako Wed Nov 04 10:04:51 2009 -0500
+++ b/templates/admin/requests/show_request.mako Wed Nov 04 10:16:20 2009 -0500
@@ -195,7 +195,7 @@
<div class="toolForm">
##<div class="toolFormTitle">Samples (${len(request.samples)})</div>
- <form id="edit_form" name="edit_form" action="${h.url_for( controller='requests_admin', action='show_request' )}" enctype="multipart/form-data" method="post" >
+ <form id="show_request" name="show_request" action="${h.url_for( controller='requests_admin', action='show_request', edit_mode=edit_mode )}" enctype="multipart/form-data" method="post" >
<div class="form-row">
%if current_samples:
%if not request.type.sample_form.layout:
diff -r 5b2d593d9aed -r 0e78d558fe57 templates/requests/show_request.mako
--- a/templates/requests/show_request.mako Wed Nov 04 10:04:51 2009 -0500
+++ b/templates/requests/show_request.mako Wed Nov 04 10:16:20 2009 -0500
@@ -224,20 +224,16 @@
%endif
</td>
<td>
- ##<div class="form-row">
<label>Import from csv file</label>
<input type="file" name="file_data" />
<input type="submit" name="import_samples_button" value="Import samples"/>
- ##</div>
</td>
<td>
- ##<div class="form-row">
%if current_samples:
<label>Copy from sample</label>
${sample_copy.get_html()}
%endif
<input type="submit" name="add_sample_button" value="Add New"/>
- ##</div>
</td>
</div>
</tr>
diff -r 5b2d593d9aed -r 0e78d558fe57 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py Wed Nov 04 10:04:51 2009 -0500
+++ b/test/base/twilltestcase.py Wed Nov 04 10:16:20 2009 -0500
@@ -1272,7 +1272,7 @@
for index, bar_code in enumerate(bar_codes):
tc.fv( "1", "sample_%i_bar_code" % index, bar_code )
tc.submit( "save_bar_codes" )
- self.check_page_for_string( 'Bar codes has been saved for this request' )
+ self.check_page_for_string( 'Bar codes have been saved for this request' )
def change_sample_state( self, sample_name, sample_id, new_state_id, new_state_name, comment='' ):
self.home()
self.visit_url( "%s/requests_admin/show_events?sample_id=%i" % (self.url, sample_id) )
1
0
07 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/984b1eb6c428
changeset: 2956:984b1eb6c428
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Wed Nov 04 09:32:09 2009 -0500
description:
When reseting password, if an email has not yet been provided, make text box empty and not contain 'None'
diffstat:
lib/galaxy/web/controllers/user.py | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diffs (12 lines):
diff -r d7c66019de13 -r 984b1eb6c428 lib/galaxy/web/controllers/user.py
--- a/lib/galaxy/web/controllers/user.py Tue Nov 03 19:16:01 2009 -0500
+++ b/lib/galaxy/web/controllers/user.py Wed Nov 04 09:32:09 2009 -0500
@@ -571,6 +571,8 @@
return trans.show_ok_message( "Password has been reset and emailed to: %s. <a href='%s'>Click here</a> to return to the login form." % ( email, web.url_for( action='login' ) ) )
elif email != None:
error = "The specified user does not exist"
+ elif email is None:
+ email = ""
return trans.show_form(
web.FormBuilder( web.url_for(), "Reset Password", submit_text="Submit" )
.add_text( "email", "Email", value=email, error=error ) )
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/5b2d593d9aed
changeset: 2957:5b2d593d9aed
user: rc
date: Wed Nov 04 10:04:51 2009 -0500
description:
AMQP messaging server and client files.
diffstat:
scripts/galaxy_messaging/amqp_consumer.py | 94 -------------
scripts/galaxy_messaging/client/amqp_publisher.py | 87 ++++++++++++
scripts/galaxy_messaging/client/galaxy_amq.ini.sample | 32 ++++
scripts/galaxy_messaging/client/report.bat.sample | 1 +
scripts/galaxy_messaging/client/scan.bat.sample | 1 +
scripts/galaxy_messaging/client/scan.sh.sample | 1 +
scripts/galaxy_messaging/client/scanner.py | 92 +++++++++++++
scripts/galaxy_messaging/client/scanner_interface.py | 76 ++++++++++
scripts/galaxy_messaging/galaxydb_interface.py | 151 ---------------------
scripts/galaxy_messaging/server/amqp_consumer.py | 94 +++++++++++++
scripts/galaxy_messaging/server/galaxydb_interface.py | 149 +++++++++++++++++++++
11 files changed, 533 insertions(+), 245 deletions(-)
diffs (829 lines):
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/amqp_consumer.py
--- a/scripts/galaxy_messaging/amqp_consumer.py Wed Nov 04 09:32:09 2009 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-'''
-Galaxy Messaging with AMQP (RabbitMQ)
-Galaxy uses AMQ protocol to receive messages from external sources like
-bar code scanners. Galaxy has been tested against RabbitMQ AMQP implementation.
-For Galaxy to receive messages from a message queue the RabbitMQ server has
-to be set up with a user account and other parameters listed in the [galaxy:amq]
-section in the universe_wsgi.ini config file
-Once the RabbitMQ server has been setup and started with the given parameters,
-this script can be run to receive messages and update the Galaxy database accordingly
-'''
-
-import ConfigParser
-import sys, os
-import optparse
-import xml.dom.minidom
-from galaxydb_interface import GalaxyDbInterface
-
-assert sys.version_info[:2] >= ( 2, 4 )
-new_path = [ os.path.join( os.getcwd(), "lib" ) ]
-new_path.extend( sys.path[1:] ) # remove scripts/ from the path
-sys.path = new_path
-
-from galaxy import eggs
-import pkg_resources
-pkg_resources.require( "amqplib" )
-
-from amqplib import client_0_8 as amqp
-
-import logging
-logging.basicConfig(level=logging.DEBUG)
-log = logging.getLogger( 'GalaxyAMQP' )
-
-
-galaxy_config_file = 'universe_wsgi.ini'
-global dbconnstr
-
-def get_value(dom, tag_name):
- '''
- This method extracts the tag value from the xml message
- '''
- nodelist = dom.getElementsByTagName(tag_name)[0].childNodes
- rc = ""
- for node in nodelist:
- if node.nodeType == node.TEXT_NODE:
- rc = rc + node.data
- return rc
-
-def recv_callback(msg):
- dom = xml.dom.minidom.parseString(msg.body)
- barcode = get_value(dom, 'barcode')
- state = get_value(dom, 'state')
- log.debug('Barcode: '+barcode)
- log.debug('State: '+state)
- # update the galaxy db
- galaxy = GalaxyDbInterface(dbconnstr)
- sample_id = galaxy.get_sample_id(field_name='bar_code', value=barcode)
- if sample_id == -1:
- log.debug('Invalid barcode.')
- return
- galaxy.change_state(sample_id, state)
-
-def main():
- config = ConfigParser.ConfigParser()
- config.read(galaxy_config_file)
- global dbconnstr
- dbconnstr = config.get("app:main", "database_connection")
- amqp_config = {}
- for option in config.options("galaxy:amqp"):
- amqp_config[option] = config.get("galaxy:amqp", option)
- log.debug(str(amqp_config))
- conn = amqp.Connection(host=amqp_config['host']+":"+amqp_config['port'],
- userid=amqp_config['userid'],
- password=amqp_config['password'],
- virtual_host=amqp_config['virtual_host'],
- insist=False)
- chan = conn.channel()
- chan.queue_declare(queue=amqp_config['queue'], durable=True, exclusive=True, auto_delete=False)
- chan.exchange_declare(exchange=amqp_config['exchange'], type="direct", durable=True, auto_delete=False,)
- chan.queue_bind(queue=amqp_config['queue'],
- exchange=amqp_config['exchange'],
- routing_key=amqp_config['routing_key'])
-
- chan.basic_consume(queue=amqp_config['queue'],
- no_ack=True,
- callback=recv_callback,
- consumer_tag="testtag")
- while True:
- chan.wait()
- chan.basic_cancel("testtag")
- chan.close()
- conn.close()
-
-if __name__ == '__main__':
- main()
\ No newline at end of file
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/client/amqp_publisher.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/galaxy_messaging/client/amqp_publisher.py Wed Nov 04 10:04:51 2009 -0500
@@ -0,0 +1,87 @@
+'''
+This script gets barcode data from a barcode scanner using serial communication
+and sends the state representated by the barcode scanner & the barcode string
+to the Galaxy LIMS RabbitMQ server. The message is sent in XML which has 2 tags,
+barcode & state. The state of the scanner should be set in the galaxy_amq.ini
+file as a configuration variable.
+'''
+
+from amqplib import client_0_8 as amqp
+import ConfigParser
+import sys, os
+import serial
+import array
+import time
+import optparse
+
+
+xml = \
+''' <sample>
+ <barcode>%(BARCODE)s</barcode>
+ <state>%(STATE)s</state>
+ </sample>'''
+
+
+def handle_scan(states, amqp_config, barcode):
+ if states.get(barcode[:2], None):
+ values = dict( BARCODE=barcode[2:],
+ STATE=states.get(barcode[:2]) )
+ print values
+ data = xml % values
+ print data
+ conn = amqp.Connection(host=amqp_config['host']+":"+amqp_config['port'],
+ userid=amqp_config['userid'],
+ password=amqp_config['password'],
+ virtual_host=amqp_config['virtual_host'],
+ insist=False)
+ chan = conn.channel()
+ msg = amqp.Message(data)
+ msg.properties["delivery_mode"] = 2
+ chan.basic_publish(msg,
+ exchange=amqp_config['exchange'],
+ routing_key=amqp_config['routing_key'])
+ chan.close()
+ conn.close()
+
+def recv_data(states, amqp_config, s):
+ while True:
+ bytes = s.inWaiting()
+ if bytes:
+ print '%i bytes recvd' % bytes
+ msg = s.read(bytes)
+ print msg
+ handle_scan(states, amqp_config, msg.strip())
+
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('-c', '--config-file', help='config file with all the AMQP config parameters',
+ dest='config_file', action='store')
+ parser.add_option('-p', '--port', help='Name of the port where the scanner is connected',
+ dest='port', action='store')
+ (opts, args) = parser.parse_args()
+ config = ConfigParser.ConfigParser()
+ config.read(opts.config_file)
+ amqp_config = {}
+ states = {}
+ for option in config.options("galaxy:amqp"):
+ amqp_config[option] = config.get("galaxy:amqp", option)
+ count = 1
+ while True:
+ section = 'scanner%i' % count
+ if config.has_section(section):
+ states[config.get(section, 'prefix')] = config.get(section, 'state')
+ count = count + 1
+ else:
+ break
+ print amqp_config
+ print states
+ s = serial.Serial(int(opts.port))
+ print 'Port %s is open: %s' %( opts.port, s.isOpen())
+ recv_data(states, amqp_config, s)
+ s.close()
+ print 'Port %s is open: %s' %( opts.port, s.isOpen())
+
+
+if __name__ == '__main__':
+ main()
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/client/galaxy_amq.ini.sample
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/galaxy_messaging/client/galaxy_amq.ini.sample Wed Nov 04 10:04:51 2009 -0500
@@ -0,0 +1,32 @@
+# Galaxy Message Queue
+# Galaxy uses AMQ protocol to receive messages from external sources like
+# bar code scanners. Galaxy has been tested against RabbitMQ AMQP implementation.
+# For Galaxy to receive messages from a message queue the RabbitMQ server has
+# to be set up with a user account and other parameters listed below. The 'host'
+# and 'port' fields should point to where the RabbitMQ server is running.
+
+#[galaxy:amqp]
+#host = 127.0.0.1
+#port = 5672
+#userid = galaxy
+#password = galaxy
+#virtual_host = galaxy_messaging_engine
+#queue = galaxy_queue
+#exchange = galaxy_exchange
+#routing_key = bar_code_scanner
+
+# The following section(s) 'scanner#' is for specifying the state of the
+# sample this scanner represents. This state name should be one of the
+# possible states created for this request type in Galaxy
+# If there multiple scanners attached to this host the add as many "scanner#"
+# sections below each with the name & prefix of the bar code scanner and
+# the state it represents
+#[scanner1]
+#name =
+#state =
+#prefix =
+
+#[scanner2]
+#name =
+#state =
+#prefix =
\ No newline at end of file
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/client/report.bat.sample
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/galaxy_messaging/client/report.bat.sample Wed Nov 04 10:04:51 2009 -0500
@@ -0,0 +1,1 @@
+python scanner.py -p 2 -c galaxy_amq.ini -r
\ No newline at end of file
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/client/scan.bat.sample
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/galaxy_messaging/client/scan.bat.sample Wed Nov 04 10:04:51 2009 -0500
@@ -0,0 +1,1 @@
+python amqp_publisher.py -p 2 -c galaxy_amq.ini
\ No newline at end of file
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/client/scan.sh.sample
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/galaxy_messaging/client/scan.sh.sample Wed Nov 04 10:04:51 2009 -0500
@@ -0,0 +1,1 @@
+python amqp_publisher.py -p 3 -c galaxy_amq.ini
\ No newline at end of file
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/client/scanner.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/galaxy_messaging/client/scanner.py Wed Nov 04 10:04:51 2009 -0500
@@ -0,0 +1,92 @@
+import sys, os
+import serial
+import array
+import time
+import optparse
+import ConfigParser, logging
+from scanner_interface import ScannerInterface
+
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger( 'Scanner' )
+
+# command prefix: SYN M CR
+cmd = [22, 77, 13]
+response = { 6: 'ACK', 5: 'ENQ', 21: 'NAK' }
+image_scanner_report = 'RPTSCN.'
+get_prefix1 = 'PREBK2?.'
+get_prefix2 = ':4820:PREBK2?.'
+set_prefix = 'PREBK2995859.'
+clear_prefix = 'PRECA2.'
+
+def get_prefix_cmd(name):
+ return ':' + name + ':' + 'PREBK2?.'
+
+def set_prefix_cmd(name, prefix):
+ prefix_str = ''
+ for c in prefix:
+ prefix_str = prefix_str + hex(ord(c))[2:]
+ return ':' + name + ':' + 'PREBK299' + prefix_str + '!'
+
+def read_config_file(config_file):
+ config = ConfigParser.ConfigParser()
+ config.read(config_file)
+ count = 1
+ scanners_list = []
+ while True:
+ section = 'scanner%i' % count
+ if config.has_section(section):
+ scanner = dict(name=config.get(section, 'name'),
+ prefix=config.get(section, 'prefix'),
+ state=config.get(section, 'state'))
+ scanners_list.append(scanner)
+ count = count + 1
+ else:
+ return scanners_list
+
+def main():
+ usage = "python %s -p PORT -c CONFIG_FILE [ OPTION ]" % sys.argv[0]
+ parser = optparse.OptionParser(usage=usage)
+ parser.add_option('-p', '--port', help='Name of the port where the scanner is connected',
+ dest='port', action='store')
+ parser.add_option('-c', '--config-file', help='config file with all the AMQP config parameters',
+ dest='config_file', action='store')
+ parser.add_option('-r', '--report', help='scanner report',
+ dest='report', action='store_true', default=False)
+ parser.add_option('-i', '--install', help='install the scanners',
+ dest='install', action='store_true', default=False)
+ (opts, args) = parser.parse_args()
+ # validate
+ if not opts.port:
+ parser.print_help()
+ sys.exit(0)
+ if ( opts.report or opts.install ) and not opts.config_file:
+ parser.print_help()
+ sys.exit(0)
+
+ # create the scanner interface
+ si = ScannerInterface(opts.port)
+ if opts.install:
+ scanners_list = read_config_file(opts.config_file)
+ for scanner in scanners_list:
+ msg = set_prefix_cmd(scanner['name'], scanner['prefix'])
+ si.send(msg)
+ response = si.recv()
+ if not response:
+ log.error("Scanner %s could not be installed." % scanner['name'])
+ elif opts.report:
+ si.send(image_scanner_report)
+ rep = si.recv()
+ log.info(rep)
+ scanners_list = read_config_file(opts.config_file)
+ for scanner in scanners_list:
+ msg = get_prefix_cmd(scanner['name'])
+ si.send(msg)
+ response = si.recv()
+ if response:
+ log.info('PREFIX for scanner %s: %s' % (scanner['name'], chr(int(response[8:12][:2], 16))+chr(int(response[8:12][2:], 16)) ))
+ si.close()
+
+
+
+if __name__ == "__main__":
+ main()
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/client/scanner_interface.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/galaxy_messaging/client/scanner_interface.py Wed Nov 04 10:04:51 2009 -0500
@@ -0,0 +1,76 @@
+import sys, os
+import serial
+import array
+import time
+import optparse
+import ConfigParser
+import logging
+
+logging.basicConfig(level=logging.INFO)
+log = logging.getLogger( 'ScannerInterface' )
+
+class ScannerInterface( object ):
+ cmdprefix = [22, 77, 13]
+ response = { 6: 'ACK', 5: 'ENQ', 21: 'NAK' }
+
+ def __init__( self, port ):
+ if os.name in ['posix', 'mac']:
+ self.port = port
+ elif os.name == 'nt':
+ self.port = int(port)
+ if self.port:
+ self.open()
+
+ def open(self):
+ try:
+ self.serial_conn = serial.Serial(self.port)
+ except serial.SerialException:
+ log.exception('Unable to open port: %s' % str(self.port))
+ sys.exit(1)
+ log.debug('Port %s is open: %s' %( str(self.port), self.serial_conn.isOpen() ) )
+
+ def is_open(self):
+ return self.serial_conn.isOpen()
+
+ def close(self):
+ self.serial_conn.close()
+ log.debug('Port %s is open: %s' %( str(self.port), self.serial_conn.isOpen() ) )
+
+ def send(self, msg):
+ message = self.cmdprefix + map(ord, msg)
+ byte_array = array.array('B', message)
+ log.debug('Sending message to %s: %s' % ( str(self.port), message) )
+ bytes = self.serial_conn.write( byte_array.tostring() )
+ log.debug('%i bytes out of %i bytes sent to the scanner' % ( bytes, len(message) ) )
+
+ def recv(self):
+ time.sleep(1)
+ self.serial_conn.flush()
+ nbytes = self.serial_conn.inWaiting()
+ log.debug('%i bytes received' % nbytes)
+ if nbytes:
+ msg = self.serial_conn.read(nbytes)
+ byte_array = map(ord, msg)
+ log.debug('Message received [%s]: %s' % (self.response.get(byte_array[len(byte_array)-2], byte_array[len(byte_array)-2]),
+ msg))
+ return msg
+ else:
+ log.error('Error!')
+ return None
+
+ def setup_recv(self, callback):
+ self.recv_callback = callback
+
+ def wait(self):
+ nbytes = self.serial_conn.inWaiting()
+ if nbytes:
+ msg = self.serial_conn.read(nbytes)
+ byte_array = map(ord, msg)
+ log.debug('Message received [%s]: %s' % (self.response.get(byte_array[len(byte_array)-2], byte_array[len(byte_array)-2],
+ msg)))
+ if self.recv_callback:
+ self.recv_callback(msg)
+ return
+
+
+
\ No newline at end of file
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/galaxydb_interface.py
--- a/scripts/galaxy_messaging/galaxydb_interface.py Wed Nov 04 09:32:09 2009 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-#/usr/bin/python
-
-from datetime import datetime, timedelta
-import sys
-import optparse
-import os
-import time
-import logging
-
-assert sys.version_info[:2] >= ( 2, 4 )
-new_path = [ os.path.join( os.getcwd(), "lib" ) ]
-new_path.extend( sys.path[1:] ) # remove scripts/ from the path
-sys.path = new_path
-from galaxy import eggs
-import pkg_resources
-pkg_resources.require( "psycopg2" )
-import psycopg2
-pkg_resources.require( "SQLAlchemy >= 0.4" )
-from sqlalchemy import *
-from sqlalchemy.orm import sessionmaker
-
-logging.basicConfig(level=logging.DEBUG)
-log = logging.getLogger( 'GalaxyDbInterface' )
-
-class GalaxyDbInterface(object):
-
- def __init__(self, dbstr):
- self.dbstr = dbstr
- self.db_engine = create_engine(self.dbstr)
-# self.db_engine.echo = True
- self.metadata = MetaData(self.db_engine)
- self.session = sessionmaker(bind=self.db_engine)
- self.event_table = Table('sample_event', self.metadata, autoload=True )
- self.sample_table = Table('sample', self.metadata, autoload=True )
- self.request_table = Table('request', self.metadata, autoload=True )
- self.state_table = Table('sample_state', self.metadata, autoload=True )
-
- def get_sample_id(self, field_name='bar_code', value=None):
- if not value:
- return -1
- sample_id = -1
- if field_name =='name':
- stmt = select(columns=[self.sample_table.c.id],
- whereclause=self.sample_table.c.name==value)
- result = stmt.execute()
- sample_id = result.fetchone()[0]
- elif field_name == 'bar_code':
- stmt = select(columns=[self.sample_table.c.id],
- whereclause=self.sample_table.c.bar_code==value)
- result = stmt.execute()
- x = result.fetchone()
- if x:
- sample_id = x[0]
- log.debug('Sample ID: %i' % sample_id)
- return sample_id
- log.warning('This sample %s %s does not belong to any sample in the database.' % (field_name, value))
- return -1
-
- def current_state(self, sample_id):
- '''
- This method returns the current state of the sample for the given sample_id
- '''
- stmt = select(columns=[self.event_table.c.sample_state_id],
- whereclause=self.event_table.c.sample_id==sample_id,
- order_by=self.event_table.c.update_time.desc())
- result = stmt.execute()
- all_states = result.fetchall()
- current_state_id = all_states[0][0]
- return current_state_id
-
- def all_possible_states(self, sample_id):
- subsubquery = select(columns=[self.sample_table.c.request_id],
- whereclause=self.sample_table.c.id==sample_id)
- self.request_id = subsubquery.execute().fetchall()[0][0]
- log.debug('REQUESTID: %i' % self.request_id)
- subquery = select(columns=[self.request_table.c.request_type_id],
- whereclause=self.request_table.c.id==self.request_id)
- request_type_id = subquery.execute().fetchall()[0][0]
- log.debug('REQUESTTYPEID: %i' % request_type_id)
- query = select(columns=[self.state_table.c.id, self.state_table.c.name],
- whereclause=self.state_table.c.request_type_id==request_type_id,
- order_by=self.state_table.c.id.asc())
- states = query.execute().fetchall()
- log.debug('POSSIBLESTATES: '+ str(states))
- return states
-
- def change_state(self, sample_id, new_state=None):
- '''
- This method changes the state of the sample to the the 'new_state'
- '''
- if not new_state:
- return
- new_state_id = -1
- # find the state_id for this new state in the list of possible states
- possible_states = self.all_possible_states(sample_id)
- for state_id, state_name in possible_states:
- if new_state == state_name:
- new_state_id = state_id
- if new_state_id == -1:
- return
- log.debug('Updating sample_id %i state to %s' % (sample_id, new_state))
- d = timedelta(hours=4)
- i = self.event_table.insert()
- i.execute(update_time=datetime.now()+d,
- create_time=datetime.now()+d,
- sample_id=sample_id,
- sample_state_id=int(new_state_id),
- comment='bar code scanner')
- # if all the samples for this request are in the final state
- # then change the request state to 'Complete'
- result = select(columns=[self.sample_table.c.id],
- whereclause=self.sample_table.c.request_id==self.request_id).execute()
- sample_id_list = result.fetchall()
- request_complete = True
- for sid in sample_id_list:
- current_state_id = self.current_state(sid[0])
- if current_state_id != possible_states[-1][0]:
- request_complete = False
- break
- if request_complete:
- request_state = 'Complete'
- else:
- request_state = 'Submitted'
- log.debug('Updating request_id %i state to "%s"' % (self.request_id, request_state))
- d = timedelta(hours=4)
- i = self.request_table.update(whereclause=self.request_table.c.id==self.request_id,
- values={self.request_table.c.state: request_state})
- i.execute()
-
-
-
-if __name__ == '__main__':
- print '''This file should not be run directly. To start the Galaxy AMQP Listener:
- %sh run_galaxy_listener.sh'''
-# dbstr = 'postgres://postgres:postgres@localhost/galaxy_ft'
-#
-# parser = optparse.OptionParser()
-# parser.add_option('-n', '--name', help='name of the sample field', dest='name', \
-# action='store', default='bar_code')
-# parser.add_option('-v', '--value', help='value of the sample field', dest='value', \
-# action='store')
-# parser.add_option('-s', '--state', help='new state of the sample', dest='state', \
-# action='store')
-# (opts, args) = parser.parse_args()
-#
-# gs = GalaxyDbInterface(dbstr)
-# sample_id = gs.get_sample_id(field_name=opts.name, value=opts.value)
-# gs.change_state(sample_id, opts.state)
-
-
-
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/server/amqp_consumer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/galaxy_messaging/server/amqp_consumer.py Wed Nov 04 10:04:51 2009 -0500
@@ -0,0 +1,94 @@
+'''
+Galaxy Messaging with AMQP (RabbitMQ)
+Galaxy uses AMQ protocol to receive messages from external sources like
+bar code scanners. Galaxy has been tested against RabbitMQ AMQP implementation.
+For Galaxy to receive messages from a message queue the RabbitMQ server has
+to be set up with a user account and other parameters listed in the [galaxy:amq]
+section in the universe_wsgi.ini config file
+Once the RabbitMQ server has been setup and started with the given parameters,
+this script can be run to receive messages and update the Galaxy database accordingly
+'''
+
+import ConfigParser
+import sys, os
+import optparse
+import xml.dom.minidom
+from galaxydb_interface import GalaxyDbInterface
+
+assert sys.version_info[:2] >= ( 2, 4 )
+new_path = [ os.path.join( os.getcwd(), "lib" ) ]
+new_path.extend( sys.path[1:] ) # remove scripts/ from the path
+sys.path = new_path
+
+from galaxy import eggs
+import pkg_resources
+pkg_resources.require( "amqplib" )
+
+from amqplib import client_0_8 as amqp
+
+import logging
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger( 'GalaxyAMQP' )
+
+
+galaxy_config_file = 'universe_wsgi.ini'
+global dbconnstr
+
+def get_value(dom, tag_name):
+ '''
+ This method extracts the tag value from the xml message
+ '''
+ nodelist = dom.getElementsByTagName(tag_name)[0].childNodes
+ rc = ""
+ for node in nodelist:
+ if node.nodeType == node.TEXT_NODE:
+ rc = rc + node.data
+ return rc
+
+def recv_callback(msg):
+ dom = xml.dom.minidom.parseString(msg.body)
+ barcode = get_value(dom, 'barcode')
+ state = get_value(dom, 'state')
+ log.debug('Barcode: '+barcode)
+ log.debug('State: '+state)
+ # update the galaxy db
+ galaxy = GalaxyDbInterface(dbconnstr)
+ sample_id = galaxy.get_sample_id(field_name='bar_code', value=barcode)
+ if sample_id == -1:
+ log.debug('Invalid barcode.')
+ return
+ galaxy.change_state(sample_id, state)
+
+def main():
+ config = ConfigParser.ConfigParser()
+ config.read(galaxy_config_file)
+ global dbconnstr
+ dbconnstr = config.get("app:main", "database_connection")
+ amqp_config = {}
+ for option in config.options("galaxy:amqp"):
+ amqp_config[option] = config.get("galaxy:amqp", option)
+ log.debug(str(amqp_config))
+ conn = amqp.Connection(host=amqp_config['host']+":"+amqp_config['port'],
+ userid=amqp_config['userid'],
+ password=amqp_config['password'],
+ virtual_host=amqp_config['virtual_host'],
+ insist=False)
+ chan = conn.channel()
+ chan.queue_declare(queue=amqp_config['queue'], durable=True, exclusive=True, auto_delete=False)
+ chan.exchange_declare(exchange=amqp_config['exchange'], type="direct", durable=True, auto_delete=False,)
+ chan.queue_bind(queue=amqp_config['queue'],
+ exchange=amqp_config['exchange'],
+ routing_key=amqp_config['routing_key'])
+
+ chan.basic_consume(queue=amqp_config['queue'],
+ no_ack=True,
+ callback=recv_callback,
+ consumer_tag="testtag")
+ while True:
+ chan.wait()
+ chan.basic_cancel("testtag")
+ chan.close()
+ conn.close()
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff -r 984b1eb6c428 -r 5b2d593d9aed scripts/galaxy_messaging/server/galaxydb_interface.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/galaxy_messaging/server/galaxydb_interface.py Wed Nov 04 10:04:51 2009 -0500
@@ -0,0 +1,149 @@
+#/usr/bin/python
+
+from datetime import datetime
+import sys
+import optparse
+import os
+import time
+import logging
+
+assert sys.version_info[:2] >= ( 2, 4 )
+new_path = [ os.path.join( os.getcwd(), "lib" ) ]
+new_path.extend( sys.path[1:] ) # remove scripts/ from the path
+sys.path = new_path
+from galaxy import eggs
+import pkg_resources
+pkg_resources.require( "psycopg2" )
+import psycopg2
+pkg_resources.require( "SQLAlchemy >= 0.4" )
+from sqlalchemy import *
+from sqlalchemy.orm import sessionmaker
+
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger( 'GalaxyDbInterface' )
+
+class GalaxyDbInterface(object):
+
+ def __init__(self, dbstr):
+ self.dbstr = dbstr
+ self.db_engine = create_engine(self.dbstr)
+# self.db_engine.echo = True
+ self.metadata = MetaData(self.db_engine)
+ self.session = sessionmaker(bind=self.db_engine)
+ self.event_table = Table('sample_event', self.metadata, autoload=True )
+ self.sample_table = Table('sample', self.metadata, autoload=True )
+ self.request_table = Table('request', self.metadata, autoload=True )
+ self.state_table = Table('sample_state', self.metadata, autoload=True )
+
+ def get_sample_id(self, field_name='bar_code', value=None):
+ if not value:
+ return -1
+ sample_id = -1
+ if field_name =='name':
+ stmt = select(columns=[self.sample_table.c.id],
+ whereclause=self.sample_table.c.name==value)
+ result = stmt.execute()
+ sample_id = result.fetchone()[0]
+ elif field_name == 'bar_code':
+ stmt = select(columns=[self.sample_table.c.id],
+ whereclause=self.sample_table.c.bar_code==value)
+ result = stmt.execute()
+ x = result.fetchone()
+ if x:
+ sample_id = x[0]
+ log.debug('Sample ID: %i' % sample_id)
+ return sample_id
+ log.warning('This sample %s %s does not belong to any sample in the database.' % (field_name, value))
+ return -1
+
+ def current_state(self, sample_id):
+ '''
+ This method returns the current state of the sample for the given sample_id
+ '''
+ stmt = select(columns=[self.event_table.c.sample_state_id],
+ whereclause=self.event_table.c.sample_id==sample_id,
+ order_by=self.event_table.c.update_time.desc())
+ result = stmt.execute()
+ all_states = result.fetchall()
+ current_state_id = all_states[0][0]
+ return current_state_id
+
+ def all_possible_states(self, sample_id):
+ subsubquery = select(columns=[self.sample_table.c.request_id],
+ whereclause=self.sample_table.c.id==sample_id)
+ self.request_id = subsubquery.execute().fetchall()[0][0]
+ log.debug('REQUESTID: %i' % self.request_id)
+ subquery = select(columns=[self.request_table.c.request_type_id],
+ whereclause=self.request_table.c.id==self.request_id)
+ request_type_id = subquery.execute().fetchall()[0][0]
+ log.debug('REQUESTTYPEID: %i' % request_type_id)
+ query = select(columns=[self.state_table.c.id, self.state_table.c.name],
+ whereclause=self.state_table.c.request_type_id==request_type_id,
+ order_by=self.state_table.c.id.asc())
+ states = query.execute().fetchall()
+ log.debug('POSSIBLESTATES: '+ str(states))
+ return states
+
+ def change_state(self, sample_id, new_state=None):
+ '''
+ This method changes the state of the sample to the the 'new_state'
+ '''
+ if not new_state:
+ return
+ new_state_id = -1
+ # find the state_id for this new state in the list of possible states
+ possible_states = self.all_possible_states(sample_id)
+ for state_id, state_name in possible_states:
+ if new_state == state_name:
+ new_state_id = state_id
+ if new_state_id == -1:
+ return
+ log.debug('Updating sample_id %i state to %s' % (sample_id, new_state))
+ i = self.event_table.insert()
+ i.execute(update_time=datetime.utcnow(),
+ create_time=datetime.utcnow(),
+ sample_id=sample_id,
+ sample_state_id=int(new_state_id),
+ comment='bar code scanner')
+ # if all the samples for this request are in the final state
+ # then change the request state to 'Complete'
+ result = select(columns=[self.sample_table.c.id],
+ whereclause=self.sample_table.c.request_id==self.request_id).execute()
+ sample_id_list = result.fetchall()
+ request_complete = True
+ for sid in sample_id_list:
+ current_state_id = self.current_state(sid[0])
+ if current_state_id != possible_states[-1][0]:
+ request_complete = False
+ break
+ if request_complete:
+ request_state = 'Complete'
+ else:
+ request_state = 'Submitted'
+ log.debug('Updating request_id %i state to "%s"' % (self.request_id, request_state))
+ i = self.request_table.update(whereclause=self.request_table.c.id==self.request_id,
+ values={self.request_table.c.state: request_state})
+ i.execute()
+
+
+
+if __name__ == '__main__':
+ print '''This file should not be run directly. To start the Galaxy AMQP Listener:
+ %sh run_galaxy_listener.sh'''
+ dbstr = 'postgres://postgres:postgres@localhost/galaxy_uft'
+
+ parser = optparse.OptionParser()
+ parser.add_option('-n', '--name', help='name of the sample field', dest='name', \
+ action='store', default='bar_code')
+ parser.add_option('-v', '--value', help='value of the sample field', dest='value', \
+ action='store')
+ parser.add_option('-s', '--state', help='new state of the sample', dest='state', \
+ action='store')
+ (opts, args) = parser.parse_args()
+
+ gs = GalaxyDbInterface(dbstr)
+ sample_id = gs.get_sample_id(field_name=opts.name, value=opts.value)
+ gs.change_state(sample_id, opts.state)
+
+
+
1
0
07 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/6491acd0bef2
changeset: 2952:6491acd0bef2
user: Nate Coraor <nate(a)bx.psu.edu>
date: Tue Nov 03 15:39:51 2009 -0500
description:
Fix a bug in streaming library tarballs. Quoth James:
This bears repeating (heh, again... -nate) -- NEVER use a mutable object (like
a dict) as a function parameter default. The default is evaluated once (at def
time) and then used for every call to the function.
This is really bad since every call, across multiple thread, are writing to
that one dict. In this case, it resulted in the values of parameters that have
dependencies being persisted across requests. Took me three solid days to
find!
diffstat:
lib/galaxy/util/streamball.py | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diffs (17 lines):
diff -r 2300a80d80e5 -r 6491acd0bef2 lib/galaxy/util/streamball.py
--- a/lib/galaxy/util/streamball.py Tue Nov 03 13:04:35 2009 -0500
+++ b/lib/galaxy/util/streamball.py Tue Nov 03 15:39:51 2009 -0500
@@ -7,9 +7,11 @@
log = logging.getLogger( __name__ )
class StreamBall( object ):
- def __init__( self, mode, members={} ):
+ def __init__( self, mode, members=None ):
+ self.members = members
+ if members is None:
+ self.members = {}
self.mode = mode
- self.members = members
self.wsgi_status = None
self.wsgi_headeritems = None
def add( self, file, relpath ):
1
0