galaxy-dev
Threads by month
- ----- 2025 -----
- 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
- 10008 discussions
details: http://www.bx.psu.edu/hg/galaxy/rev/c48de7f12e58
changeset: 3455:c48de7f12e58
user: Kanwei Li <kanwei(a)gmail.com>
date: Mon Mar 01 17:47:28 2010 -0500
description:
Fix uploads not working
diffstat:
lib/galaxy/jobs/__init__.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diffs (12 lines):
diff -r 29bb8ebb3a59 -r c48de7f12e58 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py Mon Mar 01 16:07:54 2010 -0500
+++ b/lib/galaxy/jobs/__init__.py Mon Mar 01 17:47:28 2010 -0500
@@ -155,7 +155,7 @@
run and dispatching if so.
"""
# HACK: Delay until after forking, we need a way to do post fork notification!!!
- time.sleep( 1000 )
+ time.sleep( 10 )
while self.running:
try:
self.__monitor_step()
1
0

03 Mar '10
details: http://www.bx.psu.edu/hg/galaxy/rev/29bb8ebb3a59
changeset: 3454:29bb8ebb3a59
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Mon Mar 01 16:07:54 2010 -0500
description:
Passwords are no longer changed ( sanitized ) as part of processing the request. Enhanced functional tests to cover the scenario where passwords include chars that break in sanitization.
diffstat:
lib/galaxy/web/controllers/requests_admin.py | 4 +-
lib/galaxy/web/controllers/user.py | 30 ++++++++++++++++-----------
test/base/twilltestcase.py | 5 +++-
test/functional/test_user_info.py | 7 ++++-
4 files changed, 29 insertions(+), 17 deletions(-)
diffs (118 lines):
diff -r 58ba6e72d803 -r 29bb8ebb3a59 lib/galaxy/web/controllers/requests_admin.py
--- a/lib/galaxy/web/controllers/requests_admin.py Mon Mar 01 16:00:26 2010 -0500
+++ b/lib/galaxy/web/controllers/requests_admin.py Mon Mar 01 16:07:54 2010 -0500
@@ -1703,7 +1703,7 @@
# data transfer info
rt.datatx_info = dict(host=util.restore_text( params.get( 'host', '' ) ),
username=util.restore_text( params.get( 'username', '' ) ),
- password=util.restore_text( params.get( 'password', '' ) ),
+ password=params.get( 'password', '' ),
data_dir=util.restore_text( params.get( 'data_dir', '' ) ))
trans.sa_session.add( rt )
trans.sa_session.flush()
@@ -1775,7 +1775,7 @@
# data transfer info
rt.datatx_info = dict(host=util.restore_text( params.get( 'host', '' ) ),
username=util.restore_text( params.get( 'username', '' ) ),
- password=util.restore_text( params.get( 'password', '' ) ))
+ password=params.get( 'password', '' ))
trans.sa_session.add( rt )
trans.sa_session.flush()
# set sample states
diff -r 58ba6e72d803 -r 29bb8ebb3a59 lib/galaxy/web/controllers/user.py
--- a/lib/galaxy/web/controllers/user.py Mon Mar 01 16:00:26 2010 -0500
+++ b/lib/galaxy/web/controllers/user.py Mon Mar 01 16:07:54 2010 -0500
@@ -167,12 +167,14 @@
@web.expose
def create( self, trans, **kwd ):
params = util.Params( kwd )
- email = util.restore_text( params.get('email', '') )
- username = util.restore_text( params.get('username', '') )
- password = util.restore_text( params.get('password', '') )
- confirm = util.restore_text( params.get('confirm', '') )
- subscribe = CheckboxField.is_checked( params.get('subscribe', '') )
- admin_view = params.get('admin_view', 'False')
+ email = util.restore_text( params.get( 'email', '' ) )
+ username = util.restore_text( params.get( 'username', '' ) )
+ # Do not sanitize passwords, so take from kwd
+ # instead of params ( which were sanitized )
+ password = kwd.get( 'password', '' )
+ confirm = kwd.get( 'confirm', '' )
+ subscribe = CheckboxField.is_checked( params.get( 'subscribe', '' ) )
+ admin_view = params.get( 'admin_view', 'False' )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
if trans.app.config.require_login:
@@ -413,11 +415,11 @@
login_info = { 'Email': TextField( 'email', 40,
util.restore_text( params.get('email', '') ) ),
'Public Username': TextField( 'username', 40,
- util.restore_text( params.get('username', '') ) ),
+ util.restore_text( params.get( 'username', '' ) ) ),
'Password': PasswordField( 'password', 40,
- util.restore_text( params.get('password', '') ) ),
+ params.get( 'password', '' ) ),
'Confirm': PasswordField( 'confirm', 40,
- util.restore_text( params.get('confirm', '') ) ),
+ params.get( 'confirm', '' ) ),
'Subscribe To Mailing List': CheckboxField( 'subscribe',
util.restore_text( params.get('subscribe', '') ) ) }
# user information
@@ -531,11 +533,15 @@
# Change password
#
elif params.get('change_password_button', None) == 'Save':
- password = util.restore_text( params.get('password', '') )
- confirm = util.restore_text( params.get('confirm', '') )
+ # Do not sanitize passwords, so get from kwd and not params
+ # ( which were sanitized ).
+ password = kwd.get( 'password', '' )
+ confirm = kwd.get( 'confirm', '' )
# when from the user perspective, validate the current password
if params.get('admin_view', 'False') == 'False':
- current = util.restore_text( params.get('current', '') )
+ # Do not sanitize passwords, so get from kwd and not params
+ # ( which were sanitized ).
+ current = kwd.get( 'current', '' )
if not trans.user.check_password( current ):
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
diff -r 58ba6e72d803 -r 29bb8ebb3a59 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py Mon Mar 01 16:00:26 2010 -0500
+++ b/test/base/twilltestcase.py Mon Mar 01 16:07:54 2010 -0500
@@ -745,7 +745,10 @@
self.create( email=email, password=password )
except:
self.home()
- self.visit_page( "user/login?email=%s&password=%s" % ( email, password ) )
+ self.visit_url( "%s/user/login" % self.url )
+ tc.fv( '1', 'email', email )
+ tc.fv( '1', 'password', password )
+ tc.submit( 'Login' )
self.check_page_for_string( "Now logged in as %s" %email )
self.home()
def logout( self ):
diff -r 58ba6e72d803 -r 29bb8ebb3a59 test/functional/test_user_info.py
--- a/test/functional/test_user_info.py Mon Mar 01 16:00:26 2010 -0500
+++ b/test/functional/test_user_info.py Mon Mar 01 16:07:54 2010 -0500
@@ -20,7 +20,6 @@
return fdc.latest_form
return None
-
class TestUserInfo( TwillTestCase ):
def test_000_create_user_info_forms( self ):
"""Testing creating a new user info form and editing it"""
@@ -127,7 +126,11 @@
user = sa_session.query( galaxy.model.User ) \
.filter( and_( galaxy.model.User.table.c.email=='test11(a)bx.psu.edu' ) ).first()
self.edit_login_info( new_email='test11_new(a)bx.psu.edu', new_username='test11_new' )
- self.change_password('testuser', 'new_testuser')
+ self.change_password( 'testuser', 'testuser#' )
+ self.logout()
+ self.login( email='test11_new(a)bx.psu.edu', password='testuser#' )
+ self.edit_login_info( new_email='test11(a)bx.psu.edu', new_username='test11' )
+ self.change_password( 'testuser#', 'testuser' )
self.edit_user_info( ['Research', 'PSU'] )
def test_020_create_user_as_admin( self ):
''' Testing creating users as an admin '''
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/58ba6e72d803
changeset: 3453:58ba6e72d803
user: Nate Coraor <nate(a)bx.psu.edu>
date: Mon Mar 01 16:00:26 2010 -0500
description:
update GeneTrack egg
diffstat:
eggs.ini | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diffs (12 lines):
diff -r 0cb68935eede -r 58ba6e72d803 eggs.ini
--- a/eggs.ini Mon Mar 01 15:41:30 2010 -0500
+++ b/eggs.ini Mon Mar 01 16:00:26 2010 -0500
@@ -60,7 +60,7 @@
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
bx_python = _dev_3b9d30e47619
-GeneTrack = _dev_bf44f7054c30f19bd9f79106c1fd69849562b361
+GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_90e03180969d
1
0

03 Mar '10
details: http://www.bx.psu.edu/hg/galaxy/rev/0cb68935eede
changeset: 3452:0cb68935eede
user: Nate Coraor <nate(a)bx.psu.edu>
date: Mon Mar 01 15:41:30 2010 -0500
description:
Egg support overhaul, introduces a number of fixes to the ABI recognition, better build scripts, a rewrite of the eggs library and eliminition of the need for python -ES
diffstat:
dist-eggs.ini | 79 +-
eggs.ini | 63 +-
lib/galaxy/__init__.py | 78 +-
lib/galaxy/eggs/__init__.py | 769 ++++++++--------------
lib/galaxy/eggs/dist.py | 86 ++
lib/galaxy/eggs/scramble.py | 234 ++++++
manage_db.sh | 2 +-
run.sh | 8 +-
run_functional_tests.sh | 10 +-
run_reports.sh | 3 +-
run_unit_tests.sh | 2 +-
scripts/check_eggs.py | 10 +-
scripts/check_python.py | 13 +-
scripts/dist-scramble.py | 22 +-
scripts/fetch_eggs.py | 56 +-
scripts/get_platforms.py | 6 +-
scripts/paster.py | 1 +
scripts/scramble.py | 44 +-
scripts/scramble/lib/get_platform.py | 18 -
scripts/scramble/lib/scramble_lib.py | 164 ++++
scripts/scramble/patches/Cheetah/SetupConfig.py | 103 +++
scripts/scramble/patches/GeneTrack/setup.py | 15 +
scripts/scramble/patches/MySQL_python/site.cfg | 18 +
scripts/scramble/patches/PasteScript/setup.py | 145 ++++
scripts/scramble/patches/psycopg2/setup.py | 252 +++++++
scripts/scramble/scripts/Cheetah.py | 62 -
scripts/scramble/scripts/DRMAA_python-macosx.py | 29 +-
scripts/scramble/scripts/DRMAA_python-solaris.py | 44 +-
scripts/scramble/scripts/DRMAA_python.py | 30 +-
scripts/scramble/scripts/GeneTrack.py | 58 -
scripts/scramble/scripts/MySQL_python-solaris.py | 81 ++
scripts/scramble/scripts/MySQL_python.py | 188 +---
scripts/scramble/scripts/PasteScript.py | 53 -
scripts/scramble/scripts/generic.py | 28 +-
scripts/scramble/scripts/pbs_python.py | 57 +-
scripts/scramble/scripts/psycopg2-cygwin.py | 39 -
scripts/scramble/scripts/psycopg2.py | 177 +---
scripts/scramble/scripts/pysam-solaris.py | 29 +
scripts/scramble/scripts/pysqlite.py | 43 +-
scripts/scramble/scripts/python_lzo.py | 129 ---
set_metadata.sh | 2 +-
setup.sh | 4 +-
setup_paths.sh | 46 -
43 files changed, 1817 insertions(+), 1483 deletions(-)
diffs (truncated from 3938 to 3000 lines):
diff -r a6c9862ece3d -r 0cb68935eede dist-eggs.ini
--- a/dist-eggs.ini Mon Mar 01 13:30:37 2010 -0500
+++ b/dist-eggs.ini Mon Mar 01 15:41:30 2010 -0500
@@ -1,9 +1,9 @@
;
; Config for building eggs for distribution (via a site such as
; eggs.g2.bx.psu.edu) Probably only useful to Galaxy developers at
-; Penn State. This file is used by dist-scramble.py
+; Penn State. This file is used by scripts/dist-scramble.py
;
-; More information: http://g2.trac.bx.psu.edu/wiki/GalaxyEggs
+; More information: http://bitbucket.org/galaxy/galaxy-central/wiki/Config/Eggs
;
[hosts]
@@ -22,16 +22,32 @@
py2.4-macosx-10.3-fat-ucs2 = medeski.bx.psu.edu /usr/local/bin/python2.4
py2.5-macosx-10.3-fat-ucs2 = medeski.bx.psu.edu /usr/local/bin/python2.5
py2.6-macosx-10.3-fat-ucs2 = medeski.bx.psu.edu /usr/local/bin/python2.6
-py2.5-macosx-10.5-i386-ucs2 = lion.bx.psu.edu /usr/bin/python2.5
-py2.4-solaris-2.10-i86pc-ucs2 = thumper.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-i86pc-ucs2/bin/python2.4
-py2.5-solaris-2.10-i86pc-ucs2 = thumper.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-i86pc-ucs2/bin/python2.5
-py2.6-solaris-2.10-i86pc-ucs2 = thumper.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-i86pc-ucs2/bin/python2.6
-py2.4-solaris-2.11-i86pc-ucs2 = victory.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.11-i86pc-ucs2/bin/python2.4
-py2.5-solaris-2.11-i86pc-ucs2 = victory.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.11-i86pc-ucs2/bin/python2.5
-py2.6-solaris-2.11-i86pc-ucs2 = victory.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.11-i86pc-ucs2/bin/python2.6
-py2.4-solaris-2.10-sun4u-ucs2 = v880.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-sun4u-ucs2/bin/python2.4
-py2.5-solaris-2.10-sun4u-ucs2 = v880.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-sun4u-ucs2/bin/python2.5
-py2.6-solaris-2.10-sun4u-ucs2 = v880.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-sun4u-ucs2/bin/python2.6
+py2.6-macosx-10.6-universal-ucs2 = lion.bx.psu.edu /usr/bin/python2.6
+py2.4-solaris-2.10-i86pc_32-ucs2 = thumper.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-i86pc_32-ucs2/bin/python2.4
+py2.5-solaris-2.10-i86pc_32-ucs2 = thumper.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-i86pc_32-ucs2/bin/python2.5
+py2.6-solaris-2.10-i86pc_32-ucs2 = thumper.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-i86pc_32-ucs2/bin/python2.6
+py2.4-solaris-2.10-i86pc_64-ucs2 = thumper.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-i86pc_64-ucs2/bin/python2.4
+py2.5-solaris-2.10-i86pc_64-ucs2 = thumper.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-i86pc_64-ucs2/bin/python2.5
+py2.6-solaris-2.10-i86pc_64-ucs2 = thumper.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.10-i86pc_64-ucs2/bin/python2.6
+py2.4-solaris-2.8-sun4u_32-ucs2 = troegs.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_32-ucs2/bin/python2.4
+py2.5-solaris-2.8-sun4u_32-ucs2 = troegs.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_32-ucs2/bin/python2.5
+py2.6-solaris-2.8-sun4u_32-ucs2 = troegs.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_32-ucs2/bin/python2.6
+py2.4-solaris-2.8-sun4u_64-ucs2 = troegs.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_64-ucs2/bin/python2.4
+py2.5-solaris-2.8-sun4u_64-ucs2 = troegs.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_64-ucs2/bin/python2.5
+py2.6-solaris-2.8-sun4u_64-ucs2 = troegs.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_64-ucs2/bin/python2.6
+
+; pysam doesn't build on solaris < 10, so for it alone we need these hosts
+py2.4-solaris-2.10-sun4u_32-ucs2 = early.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_32-ucs2/bin/python2.4
+py2.5-solaris-2.10-sun4u_32-ucs2 = early.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_32-ucs2/bin/python2.5
+py2.6-solaris-2.10-sun4u_32-ucs2 = early.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_32-ucs2/bin/python2.6
+py2.4-solaris-2.10-sun4u_64-ucs2 = early.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_64-ucs2/bin/python2.4
+py2.5-solaris-2.10-sun4u_64-ucs2 = early.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_64-ucs2/bin/python2.5
+py2.6-solaris-2.10-sun4u_64-ucs2 = early.bx.psu.edu /afs/bx.psu.edu/project/pythons/solaris-2.8-sun4u_64-ucs2/bin/python2.6
+
+; these hosts are used to build eggs with no C extensions
+py2.4 = straub.bx.psu.edu /afs/bx.psu.edu/project/pythons/linux-x86_64-ucs4/bin/python2.4
+py2.5 = straub.bx.psu.edu /afs/bx.psu.edu/project/pythons/linux-x86_64-ucs4/bin/python2.5
+py2.6 = straub.bx.psu.edu /afs/bx.psu.edu/project/pythons/linux-x86_64-ucs4/bin/python2.6
[groups]
py2.4-linux-i686 = py2.4-linux-i686-ucs2 py2.4-linux-i686-ucs4
@@ -47,20 +63,37 @@
linux-x86_64 = py2.4-linux-x86_64 py2.5-linux-x86_64 py2.6-linux-x86_64
linux = linux-i686 linux-x86_64
py2.4-macosx = py2.4-macosx-10.3-fat-ucs2
-py2.5-macosx = py2.5-macosx-10.3-fat-ucs2 py2.5-macosx-10.5-i386-ucs2
-py2.6-macosx = py2.6-macosx-10.3-fat-ucs2
+py2.5-macosx = py2.5-macosx-10.3-fat-ucs2
+py2.6-macosx = py2.6-macosx-10.3-fat-ucs2 py2.6-macosx-10.6-universal-ucs2
macosx = py2.4-macosx py2.5-macosx py2.6-macosx
-py2.4-solaris = py2.4-solaris-2.10-i86pc-ucs2 py2.4-solaris-2.11-i86pc-ucs2 py2.4-solaris-2.10-sun4u-ucs2
-py2.5-solaris = py2.5-solaris-2.10-i86pc-ucs2 py2.5-solaris-2.11-i86pc-ucs2 py2.5-solaris-2.10-sun4u-ucs2
-py2.6-solaris = py2.6-solaris-2.10-i86pc-ucs2 py2.6-solaris-2.11-i86pc-ucs2 py2.6-solaris-2.10-sun4u-ucs2
-solaris = py2.4-solaris py2.5-solaris py2.6-solaris
+py2.4-solaris-i86pc = py2.4-solaris-2.10-i86pc_32-ucs2 py2.4-solaris-2.10-i86pc_64-ucs2
+py2.5-solaris-i86pc = py2.5-solaris-2.10-i86pc_32-ucs2 py2.5-solaris-2.10-i86pc_64-ucs2
+py2.6-solaris-i86pc = py2.6-solaris-2.10-i86pc_32-ucs2 py2.6-solaris-2.10-i86pc_64-ucs2
+py2.4-solaris-sun4u = py2.4-solaris-2.8-sun4u_32-ucs2 py2.4-solaris-2.8-sun4u_64-ucs2
+py2.5-solaris-sun4u = py2.5-solaris-2.8-sun4u_32-ucs2 py2.5-solaris-2.8-sun4u_64-ucs2
+py2.6-solaris-sun4u = py2.6-solaris-2.8-sun4u_32-ucs2 py2.6-solaris-2.8-sun4u_64-ucs2
+py2.4-solaris = py2.4-solaris-i86pc py2.4-solaris-sun4u
+py2.5-solaris = py2.5-solaris-i86pc py2.5-solaris-sun4u
+py2.6-solaris = py2.6-solaris-i86pc py2.6-solaris-sun4u
+solaris-i86pc = py2.4-solaris-i86pc py2.5-solaris-i86pc py2.6-solaris-i86pc
+solaris-sun4u = py2.4-solaris-sun4u py2.5-solaris-sun4u py2.6-solaris-sun4u
+solaris = solaris-i86pc solaris-sun4u
py2.4-all = py2.4-linux py2.4-macosx py2.4-solaris
py2.5-all = py2.5-linux py2.5-macosx py2.5-solaris
py2.6-all = py2.6-linux py2.6-macosx py2.6-solaris
-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
+; group for building pysam on solaris 10 sparc
+solaris-2.10-sun4u = py2.4-solaris-2.10-sun4u_32-ucs2 py2.5-solaris-2.10-sun4u_32-ucs2 py2.6-solaris-2.10-sun4u_32-ucs2 py2.4-solaris-2.10-sun4u_64-ucs2 py2.5-solaris-2.10-sun4u_64-ucs2 py2.6-solaris-2.10-sun4u_64-ucs2
+
+; the 'all' key is used internally by the build system to specify which hosts
+; to build on when no hosts are specified on the dist-eggs.py command line.
+all = linux macosx solaris
+
+; the 'noplatform' key, likewise, is for which build hosts should be used when
+; building pure python (noplatform) eggs.
+noplatform = py2.4 py2.5 py2.6
+
+; don't build these eggs on these platforms:
[ignore]
-; Don't build these eggs on these platforms:
-GeneTrack = py2.4-noplatform
+GeneTrack = py2.4
+pysam = py2.4-solaris-2.8-sun4u_32-ucs2 py2.5-solaris-2.8-sun4u_32-ucs2 py2.6-solaris-2.8-sun4u_32-ucs2 py2.4-solaris-2.8-sun4u_64-ucs2 py2.5-solaris-2.8-sun4u_64-ucs2 py2.6-solaris-2.8-sun4u_64-ucs2
diff -r a6c9862ece3d -r 0cb68935eede eggs.ini
--- a/eggs.ini Mon Mar 01 13:30:37 2010 -0500
+++ b/eggs.ini Mon Mar 01 15:41:30 2010 -0500
@@ -3,11 +3,11 @@
;
; This file is version controlled and should not be edited by hand!
; For more information, see:
-; http://g2.trac.bx.psu.edu/wiki/GalaxyEggs
+; http://bitbucket.org/galaxy/galaxy-central/wiki/Config/Eggs
;
[general]
-repository = http://eggs.g2.bx.psu.edu
+repository = http://eggs.g2.bx.psu.edu/new
; these eggs must be scrambled for your local environment
no_auto = pbs_python DRMAA_python
@@ -15,13 +15,13 @@
bx_python = 0.5.0
Cheetah = 2.2.2
DRMAA_python = 0.2
-MySQL_python = 1.2.2
+MySQL_python = 1.2.3c1
pbs_python = 2.9.4
psycopg2 = 2.0.6
pycrypto = 2.0.1
pysam = 0.1.1
pysqlite = 2.5.6
-python_lzo = 1.08
+python_lzo = 1.08_2.03_static
threadframe = 0.2
guppy = 0.1.8
@@ -33,10 +33,9 @@
elementtree = 1.2.6_20050316
GeneTrack = 2.0.0_beta_1
lrucache = 0.2
-;lsprof - james
Mako = 0.2.5
nose = 0.11.1
-NoseHTML = 0.3
+NoseHTML = 0.3.1
Paste = 1.6
PasteDeploy = 1.3.3
PasteScript = 1.7.3
@@ -58,52 +57,16 @@
; extra version information
[tags]
psycopg2 = _8.2.6_static
-pysqlite = _static
-MySQL_python = _5.0.67_static
-python_lzo = _static
+pysqlite = _3.6.17_static
+MySQL_python = _5.1.41_static
bx_python = _dev_3b9d30e47619
GeneTrack = _dev_bf44f7054c30f19bd9f79106c1fd69849562b361
SQLAlchemy = _dev_r6498
-; nose = .dev_r7156749efc58
+pysam = _kanwei_90e03180969d
-; source location, necessary for scrambling
+; dependency source urls, necessary for scrambling. for an explanation, see
+; the wiki page above
[source]
-bx_python = http://bitbucket.org/james_taylor/bx-python/get/3b9d30e47619.bz2
-Cheetah = http://pypi.python.org/packages/source/C/Cheetah/Cheetah-2.2.2.tar.gz
-DRMAA_python = http://gridengine.sunsource.net/files/documents/7/36/DRMAA-python-0.2.tar.gz
-MySQL_python = http://downloads.sourceforge.net/project/mysql-python/mysql-python/1.2.2/My… http://downloads.mysql.com/archives/mysql-5.0/mysql-5.0.67.tar.gz
-pbs_python = http://ftp.sara.nl/pub/outgoing/pbs_python-2.9.4.tar.gz
-pexpect = http://pypi.python.org/packages/source/p/pexpect/pexpect-2.4.tar.gz
-psycopg2 = http://initd.org/pub/software/psycopg/PSYCOPG-2-0/psycopg2-2.0.6.tar.gz ftp://ftp-archives.postgresql.org/pub/source/v8.2.6/postgresql-8.2.6.tar.bz2
-pycrypto = http://www.amk.ca/files/python/crypto/pycrypto-2.0.1.tar.gz
-pysam = http://bitbucket.org/kanwei/kanwei-pysam/get/e3c601a062fd.gz
-pysqlite = http://pypi.python.org/packages/source/p/pysqlite/pysqlite-2.5.6.tar.gz
-python_lzo = http://www.oberhumer.com/opensource/lzo/download/LZO-v1/python-lzo-1.08.tar… http://www.oberhumer.com/opensource/lzo/download/LZO-v1/lzo-1.08.tar.gz
-threadframe = http://www.majid.info/python/threadframe/threadframe-0.2.tar.gz
-guppy = http://pypi.python.org/packages/source/g/guppy/guppy-0.1.8.tar.gz
-amqplib = http://py-amqplib.googlecode.com/files/amqplib-0.6.1.tgz
-Beaker = http://cheeseshop.python.org/packages/source/B/Beaker/Beaker-1.4.tar.gz
-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/bf44f7054c30f19bd9f7910…
-lrucache = http://evan.prodromou.name/lrucache/lrucache-0.2.tar.gz
-Mako = http://www.makotemplates.org/downloads/Mako-0.2.5.tar.gz
-nose = http://pypi.python.org/packages/source/n/nose/nose-0.11.1.tar.gz
-NoseHTML = http://bitbucket.org/james_taylor/nosehtml/get/c46a54d569ae.bz2
-Paste = http://cheeseshop.python.org/packages/source/P/Paste/Paste-1.6.tar.gz
-PasteDeploy = http://cheeseshop.python.org/packages/source/P/PasteDeploy/PasteDeploy-1.3.…
-PasteScript = http://cheeseshop.python.org/packages/source/P/PasteScript/PasteScript-1.7.…
-Routes = http://pypi.python.org/packages/source/R/Routes/Routes-1.11.tar.gz
-simplejson = http://cheeseshop.python.org/packages/source/s/simplejson/simplejson-1.5.ta…
-SQLAlchemy = http://dist.g2.bx.psu.edu/SQLAlchemy-0.5.6_r6498.tar.bz2
-sqlalchemy_migrate = http://pypi.python.org/packages/source/s/sqlalchemy-migrate/sqlalchemy-migr…
-Tempita = http://pypi.python.org/packages/source/T/Tempita/Tempita-0.1.tar.gz
-twill = http://darcs.idyll.org/~t/projects/twill-0.9.tar.gz
-WebError = http://pypi.python.org/packages/source/W/WebError/WebError-0.8a.tar.gz
-WebHelpers = http://pypi.python.org/packages/source/W/WebHelpers/WebHelpers-0.2.tar.gz
-WebOb = http://pypi.python.org/packages/source/W/WebOb/WebOb-0.8.5.tar.gz
-wsgiref = http://pypi.python.org/packages/source/w/wsgiref/wsgiref-0.1.2.zip
-Babel = http://ftp.edgewall.com/pub/babel/Babel-0.9.4.zip
-wchartype = http://ginstrom.com/code/wchartype-0.1.zip
-boto = http://boto.googlecode.com/files/boto-1.8d.tar.gz
+MySQL_python = mysql-5.1.41
+psycopg2 = postgresql-8.2.6
+pysqlite = sqlite-amalgamation-3_6_17
diff -r a6c9862ece3d -r 0cb68935eede lib/galaxy/__init__.py
--- a/lib/galaxy/__init__.py Mon Mar 01 13:30:37 2010 -0500
+++ b/lib/galaxy/__init__.py Mon Mar 01 15:41:30 2010 -0500
@@ -2,30 +2,62 @@
Galaxy root package -- this is a namespace package.
"""
-# Starting somewhere in 2.5.x, Python on Mac became broken - despite being fat,
-# the machine portion of the platform is not set to 'fat'.
-#
-# For more, see:
-#
-# http://bugs.python.org/setuptools/issue19
-#
-import os, sys
-from distutils.sysconfig import get_config_vars
+__import__( "pkg_resources" ).declare_namespace( __name__ )
-if sys.version_info[:2] == ( 2, 5 ) and \
+import os, sys, re
+from distutils.sysconfig import get_config_var, get_config_vars
+
+import pkg_resources
+
+# patch get_platform() for better ABI recognition
+def _get_build_platform():
+ plat = pkg_resources._get_build_platform()
+ if sys.version_info[:2] == ( 2, 5 ) and \
( ( os.uname()[-1] in ( 'i386', 'ppc' ) and sys.platform == 'darwin' and os.path.abspath( sys.prefix ).startswith( '/System' ) ) or \
( sys.platform == 'darwin' and get_config_vars().get('UNIVERSALSDK', '').strip() ) ):
- # Has to be before anything imports pkg_resources
- def _get_platform_monkeypatch():
- plat = distutils.util._get_platform()
- if plat.startswith( 'macosx-' ):
- plat = 'macosx-10.3-fat'
- return plat
- import distutils.util
- try:
- assert distutils.util._get_platform
- except:
- distutils.util._get_platform = distutils.util.get_platform
- distutils.util.get_platform = _get_platform_monkeypatch
+ plat = 'macosx-10.3-fat'
+ if sys.platform == "sunos5" and not (plat.endswith('_32') or plat.endswith('_64')):
+ if sys.maxint > 2**31:
+ plat += '_64'
+ else:
+ plat += '_32'
+ if not (plat.endswith('-ucs2') or plat.endswith('-ucs4')):
+ if sys.maxunicode > 2**16:
+ plat += '-ucs4'
+ else:
+ plat += '-ucs2'
+ return plat
+try:
+ assert pkg_resources._get_build_platform
+except:
+ pkg_resources._get_build_platform = pkg_resources.get_build_platform
+ pkg_resources.get_build_platform = _get_build_platform
+ pkg_resources.get_platform = _get_build_platform
-__import__( "pkg_resources" ).declare_namespace( __name__ )
+# patch compatible_platforms() to allow for Solaris binary compatibility
+solarisVersionString = re.compile(r"solaris-(\d)\.(\d+)-(.*)")
+def _compatible_platforms(provided,required):
+ # this is a bit kludgey since we need to know a bit about what happened in
+ # the original method
+ if provided is None or required is None or provided==required:
+ return True # easy case
+ reqMac = pkg_resources.macosVersionString.match(required)
+ if reqMac:
+ return pkg_resources._compatible_platforms(provided,required)
+ 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
+ return False
+try:
+ assert pkg_resources._compatible_platforms
+except:
+ pkg_resources._compatible_platforms = pkg_resources.compatible_platforms
+ pkg_resources.compatible_platforms = _compatible_platforms
diff -r a6c9862ece3d -r 0cb68935eede lib/galaxy/eggs/__init__.py
--- a/lib/galaxy/eggs/__init__.py Mon Mar 01 13:30:37 2010 -0500
+++ b/lib/galaxy/eggs/__init__.py Mon Mar 01 15:41:30 2010 -0500
@@ -2,17 +2,15 @@
Manage Galaxy eggs
"""
-import os, sys, shutil, tarfile, zipfile, zipimport, subprocess, ConfigParser, glob, urllib2, shutil
-from types import ModuleType
+import os, sys, glob, urllib, urllib2, ConfigParser, HTMLParser, zipimport, zipfile
import logging
log = logging.getLogger( __name__ )
import pkg_resources
-# we MUST have the top level galaxy dir for automatic egg fetching
-# within tools. i don't know of any way around this. -ndc
-galaxy_dir = os.path.abspath( os.path.join( os.path.dirname( __file__ ), "..", "..", ".." ) )
+galaxy_dir = os.path.abspath( os.path.join( os.path.dirname( __file__ ), '..', '..', '..' ) )
+py = 'py%s' % sys.version[:3]
class EggNotFetchable( Exception ):
def __init__( self, eggs ):
@@ -23,452 +21,287 @@
def __str__( self ):
return ' '.join( self.eggs )
-class PlatformNotSupported( Exception ):
- pass
-
-# TODO: we should really be using exceptions instead of returns for everything
-
# need the options to remain case sensitive
-class CSConfigParser( ConfigParser.SafeConfigParser ):
+class CaseSensitiveConfigParser( ConfigParser.SafeConfigParser ):
def optionxform( self, optionstr ):
return optionstr
+# so we can actually detect failures
+class URLRetriever( urllib.FancyURLopener ):
+ def http_error_default( *args ):
+ urllib.URLopener.http_error_default( *args )
+
class Egg( object ):
"""
- Contains information about locating, downloading and scrambling eggs.
+ Contains information about locating and downloading eggs.
"""
- archive_dir = os.path.join( galaxy_dir, "scripts", "scramble", "archives" )
- script_dir = os.path.join( galaxy_dir, "scripts", "scramble", "scripts" )
- build_dir = os.path.join( galaxy_dir, "scripts", "scramble", "build" )
- ez_setup = os.path.join( galaxy_dir, "scripts", "scramble", "lib", "ez_setup.py" )
- ez_setup_url = "http://peak.telecommunity.com/dist/ez_setup.py"
- def __init__( self ):
- self.name = None
- self.version = None
- self.tag = None
- self.sources = []
- self.platform = {}
- self.url = None
- self.have = False
- self.path = None
- self.doppelgangers = []
- self.buildpath = None
+ def __init__( self, name=None, version=None, tag=None, url=None, platform=None ):
+ self.name = name
+ self.version = version
+ self.tag = tag
+ self.url = url
+ self.platform = platform
+ self.distribution = None
self.dir = None
- self.build_host = None
- self.python = sys.executable
+ if self.name is not None and self.version is not None:
+ self.set_distribution()
def set_dir( self ):
- if self.build_host is not None:
- self.dir = os.path.join( galaxy_dir, "dist-eggs", self.platform['galaxy'] )
- else:
- self.dir = os.path.join( galaxy_dir, "eggs", self.platform['galaxy'] )
- def get_namever( self ):
- return( "%s-%s" %( self.name, self.version ) )
- def get_namevertag( self ):
- if self.tag is None:
- return( "%s-%s" %( self.name, self.version ) )
- else:
- return( "%s-%s%s" %( self.name, self.version, self.tag ) )
- def get_vertag( self ):
- if self.tag is None:
- return self.version
- else:
- return( "%s%s" %( self.version, self.tag ) )
- def get_filename( self ):
- if self.tag is None:
- return( "%s-%s-%s.egg" %( self.name, self.version, self.platform['peak'] ) )
- else:
- return( "%s-%s%s-%s.egg" %( self.name, self.version, self.tag, self.platform['peak'] ) )
- def find( self ):
- # TODO: should be able to set a search path in eggs.ini
+ self.dir = os.path.join( galaxy_dir, 'eggs' )
+ if not os.path.exists( self.dir ):
+ os.makedirs( self.dir )
+ def set_distribution( self ):
+ """
+ Stores a pkg_resources Distribution object for reference later
+ """
if self.dir is None:
self.set_dir()
- self.path = os.path.join( self.dir, self.get_filename() )
- self.doppelgangers = glob.glob( os.path.join( self.dir, "%s-*-%s.egg" % (self.name, self.platform['peak'] ) ) )
- if os.access( self.path, os.F_OK ):
- self.have = True
- self.doppelgangers.remove( self.path )
- def fetch( self ):
- if self.path is None:
- self.find()
- if not self.have:
- if not os.access( os.path.dirname( self.path ), os.F_OK ):
- os.makedirs( os.path.dirname( self.path ) )
+ tag = self.tag or ''
+ self.distribution = pkg_resources.Distribution.from_filename(
+ os.path.join( self.dir, '-'.join( ( self.name, self.version + tag, self.platform ) ) + '.egg' ) )
+ @property
+ def path( self ):
+ """
+ Return the path of the egg, if it exists, or None
+ """
+ if env[self.distribution.project_name]:
+ return env[self.distribution.project_name][0].location
+ return None
+ 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:
- inf = urllib2.urlopen( self.url )
- otf = open( self.path, 'wb' )
- otf.write( inf.read() )
- inf.close()
- otf.close()
- log.debug( "Fetched %s" % self.url )
+ parser.feed( urllib2.urlopen( self.url + '/' ).read() )
except urllib2.HTTPError, e:
- raise EggNotFetchable( self.name )
- #if e.code == 404:
- # return False
- self.unpack_if_needed()
- for doppelganger in self.doppelgangers:
- remove_file_or_path( doppelganger )
- log.debug( "Removed conflicting egg: %s" % doppelganger )
- return True
+ 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 \
+ pkg_resources.compatible_platforms( tmp_dist.platform, pkg_resources.get_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 unpack_if_needed( self ):
- meta = pkg_resources.EggMetadata( zipimport.zipimporter( self.path ) )
+ meta = pkg_resources.EggMetadata( zipimport.zipimporter( self.distribution.location ) )
if meta.has_metadata( 'not-zip-safe' ):
- unpack_zipfile( self.path, self.path + "-tmp" )
- os.remove( self.path )
- os.rename( self.path + "-tmp", self.path )
- def scramble( self, dist=False ):
- if self.path is None:
- self.find()
- if os.access( self.path, os.F_OK ):
- log.warning( "scramble(): Egg already exists, remove to force rebuild:" )
- log.warning( " %s" % self.path )
- return True
- self.fetch_source()
- self.unpack_source()
- self.copy_build_script()
- if not os.access( Egg.ez_setup, os.F_OK ):
- if not os.access( os.path.dirname( Egg.ez_setup ), os.F_OK ):
- os.makedirs( os.path.dirname( Egg.ez_setup ) )
- inf = urllib2.urlopen( Egg.ez_setup_url )
- otf = open( Egg.ez_setup, 'wb' )
- otf.write( inf.read() )
- inf.close()
- otf.close()
- shutil.copyfile( Egg.ez_setup, os.path.join( self.buildpath, "ez_setup.py" ) )
- log.warning( "scramble(): Beginning build" )
- # subprocessed to sterilize the env
- if self.build_host is not None:
- cmd = "ssh %s 'cd %s; %s -ES %s'" % ( self.build_host, self.buildpath, self.python, "scramble.py" )
- else:
- cmd = "%s -ES %s" % ( self.python, "scramble.py" )
- log.debug( 'Executing: %s' % cmd )
- p = subprocess.Popen( args = cmd, shell = True, cwd = self.buildpath )
- r = p.wait()
- if r != 0:
- log.error( "scramble(): Egg build failed for %s" % self.get_namevertag() )
- return False
- new_egg = os.path.join( self.buildpath, "dist", os.path.basename( self.path ) )
- if not os.access( os.path.dirname( self.path ), os.F_OK ):
- os.makedirs( os.path.dirname( self.path ) )
- shutil.copyfile( new_egg, self.path )
- log.warning( "scramble(): Copied egg to:" )
- log.warning( " %s" % self.path )
- if not dist:
- self.unpack_if_needed()
- for doppelganger in self.doppelgangers:
+ unpack_zipfile( self.distribution.location, self.distribution.location + "-tmp" )
+ os.remove( self.distribution.location )
+ os.rename( self.distribution.location + "-tmp", self.distribution.location )
+ def remove_doppelgangers( self ):
+ doppelgangers = glob.glob( os.path.join( self.dir, "%s-*-%s.egg" % ( self.name, self.platform ) ) )
+ if self.distribution.location in doppelgangers:
+ doppelgangers.remove( self.distribution.location )
+ for doppelganger in doppelgangers:
remove_file_or_path( doppelganger )
- log.warning( "Removed conflicting egg: %s" % doppelganger )
- return True
- # 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 )
- for source_url in self.sources:
- source_path = self.get_archive_path( source_url )
- if os.access( source_path, os.F_OK ):
- log.warning( "fetch_source(): Using existing source, remove to download again:" )
- log.warning( " %s" % source_path )
- continue
- log.warning( "fetch_source(): Attempting to download" )
- log.warning( " %s" % source_url )
- inf = urllib2.urlopen( source_url )
- otf = open( source_path, 'wb' )
- otf.write( inf.read() )
- inf.close()
- otf.close()
- log.warning( "fetch_source(): Fetched %s" % source_url )
- def unpack_source( self ):
- unpack_dir = os.path.join( Egg.build_dir, self.platform['galaxy'] )
- if not os.access( unpack_dir, os.F_OK ):
- os.makedirs( unpack_dir )
- self.buildpath = os.path.join( unpack_dir, self.name )
- if os.access( self.buildpath, os.F_OK ):
- log.warning( "Removing old build directory at:" )
- log.warning( " %s" % self.buildpath )
- shutil.rmtree( self.buildpath )
- source_path = self.get_archive_path( self.sources[0] )
- if tarfile.is_tarfile( source_path ):
- self.unpack = self.unpack_tar
- elif zipfile.is_zipfile( source_path ):
- self.unpack = self.unpack_zip
- else:
- raise Exception( "unpack_source(): Unknown archive file type for %s" % source_path )
- self.unpack( source_path, unpack_dir )
- log.warning( "unpack_source(): Unpacked to:" )
- log.warning( " %s" % self.buildpath )
- def unpack_zip( self, source_path, unpack_path ):
- z = zipfile.ZipFile( source_path, "r" )
- tld = self.get_tld( z.namelist() )
- cur = os.getcwd()
- os.chdir( unpack_path )
- for fn in z.namelist():
- if "ez_setup" in fn:
- continue
- if not os.access( os.path.dirname( fn ), os.F_OK ):
- os.makedirs( os.path.dirname( fn ) )
- otf = open( fn, "wb" )
- otf.write( z.read( fn ) )
- otf.close()
- z.close()
- os.rename( tld, self.name )
- os.chdir( cur )
- def unpack_tar( self, source_path, unpack_path ):
- t = tarfile.open( source_path, "r" )
- 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 members:
- t.extract( member )
- t.close()
- os.rename( tld, self.name )
- os.chdir( cur )
- def copy_build_script( self ):
- peak_platform = get_platform( platform=True, peak=True )
- nopy_platform = ( peak_platform.split( "-", 1 ) )[1]
- just_os = ( nopy_platform.split( "-", 1 ) )[0]
- just_py = ( peak_platform.split( "-", 1 ) )[0]
- # will try:
- # bx_python-py2.4-solaris-2.11-i86pc.py
- # bx_python-py2.4-solaris.py
- # bx_python-solaris-2.11-i86pc.py
- # bx_python-solaris.py
- # bx_python-py2.4.py
- # bx_python.py
- # generic.py
- build_scripts = [
- os.path.join( Egg.script_dir, "%s-%s.py" % ( self.name, peak_platform ) ),
- os.path.join( Egg.script_dir, "%s-%s-%s.py" % ( self.name, just_py, just_os ) ),
- os.path.join( Egg.script_dir, "%s-%s.py" % ( self.name, nopy_platform ) ),
- os.path.join( Egg.script_dir, "%s-%s.py" % ( self.name, just_os ) ),
- os.path.join( Egg.script_dir, "%s-%s.py" % ( self.name, just_py ) ),
- os.path.join( Egg.script_dir, "%s.py" % self.name ),
- os.path.join( Egg.script_dir, "generic.py" )
- ]
- for build_script in build_scripts:
- try:
- f = open( build_script, "r" )
- f.close()
- log.warning( "scramble(): Using build script %s" % build_script )
- break
- except IOError:
- pass
- shutil.copyfile( build_script, os.path.join( self.buildpath, "scramble.py" ) )
- if self.tag is not None:
- tagfile = open( os.path.join( self.buildpath, ".galaxy_tag" ), "w" )
- print >>tagfile, self.tag
- tagfile.close()
+ log.debug( "Removed conflicting egg: %s" % doppelganger )
+ def resolve( self ):
+ try:
+ return pkg_resources.working_set.resolve( ( self.distribution.as_requirement(), ), env, self.fetch )
+ except pkg_resources.DistributionNotFound, e:
+ # If this statement is true, it means we do have the requested egg,
+ # just not one (or more) of its deps.
+ if e.args[0].project_name != self.distribution.project_name:
+ log.warning( "Warning: %s (a dependant egg of %s) cannot be fetched" % ( e.args[0].project_name, self.distribution.project_name ) )
+ return ( self.distribution, )
+ else:
+ raise EggNotFetchable( self )
+ except pkg_resources.VersionConflict, e:
+ # there's a conflicting egg on the path, remove it
+ dist = e.args[0]
+ # use the canonical path for comparisons
+ location = os.path.realpath( dist.location )
+ for entry in pkg_resources.working_set.entries:
+ if os.path.realpath( entry ) == location:
+ pkg_resources.working_set.entries.remove( entry )
+ break
+ else:
+ location = entry = None
+ del pkg_resources.working_set.by_key[dist.key]
+ if entry is not None:
+ pkg_resources.working_set.entry_keys[entry] = []
+ if entry in sys.path:
+ sys.path.remove(entry)
+ r = pkg_resources.working_set.resolve( ( self.distribution.as_requirement(), ), env, self.fetch )
+ if location is not None and not location.endswith( '.egg' ):
+ # re-add the path if it's a non-egg dir, in case more deps live there
+ pkg_resources.working_set.entries.append( location )
+ sys.path.append( location )
+ return r
+ def require( self ):
+ try:
+ dists = self.resolve()
+ for dist in dists:
+ pkg_resources.working_set.add( dist )
+ return dists
+ except:
+ raise
class Crate( object ):
"""
- Reads the eggs.ini file for use with checking, fetching and scrambling eggs.
+ Reads the eggs.ini file for use with checking and fetching.
"""
- config_file = os.path.join( galaxy_dir, "eggs.ini" )
+ config_file = os.path.join( galaxy_dir, 'eggs.ini' )
def __init__( self ):
self.eggs = {}
- self.config = CSConfigParser()
+ self.config = CaseSensitiveConfigParser()
self.repo = None
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 ) }
+ self.galaxy_config = GalaxyConfig()
+ self.parse()
def parse( self ):
- if self.config.read( Crate.config_file ) == []:
- raise Exception( "unable to read egg config from %s" % Crate.config_file )
- try:
- self.repo = self.config.get( "general", "repository" )
- 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:
- # raise Exception( "eggs.ini is missing required [general] option 'repository'" )
- try:
- platform_eggs = self.config.items( "eggs:platform" )
- noplatform_eggs = self.config.items( "eggs:noplatform" )
- except ConfigParser.NoSectionError, e:
- raise Exception( "eggs.ini is missing required section: %s" % e )
- self.parse_egg_section( platform_eggs, self.platform )
- self.parse_egg_section( noplatform_eggs, self.noplatform )
- def parse_egg_section( self, eggs, platform ):
+ self.config.read( Crate.config_file )
+ self.repo = self.config.get( 'general', 'repository' )
+ self.no_auto = self.config.get( 'general', 'no_auto' ).split()
+ self.parse_egg_section( self.config.items( 'eggs:platform' ), self.config.items( 'tags' ), True )
+ self.parse_egg_section( self.config.items( 'eggs:noplatform' ), self.config.items( 'tags' ) )
+ def parse_egg_section( self, eggs, tags, full_platform=False, egg_class=Egg ):
for name, version in eggs:
- egg = Egg()
+ tag = dict( tags ).get( name, '' )
+ url = '/'.join( ( self.repo, name ) )
+ if full_platform:
+ platform = '-'.join( ( py, pkg_resources.get_platform() ) )
+ else:
+ platform = py
+ egg = egg_class( name, version, tag, url, platform )
+ self.eggs[name] = egg
+ @property
+ def config_missing( self ):
+ """
+ Return true if any eggs are missing, conditional on options set in the
+ Galaxy config file.
+ """
+ for egg in self.config_eggs:
+ if not egg.path:
+ return True
+ return False
+ @property
+ def all_missing( self ):
+ """
+ Return true if any eggs in the eggs config file are missing.
+ """
+ for egg in self.all_eggs:
+ if not os.path.exists( egg.distribution.location ):
+ return True
+ return False
+ @property
+ def config_names( self ):
+ """
+ Return a list of names of all eggs in the crate that are needed based
+ on the options set in the Galaxy config file.
+ """
+ return [ egg.name for egg in self.config_eggs ]
+ @property
+ def all_names( self ):
+ """
+ Return a list of names of all eggs in the crate.
+ """
+ return [ egg.name for egg in self.all_eggs ]
+ @property
+ def config_eggs( self ):
+ """
+ Return a list of all eggs in the crate that are needed based on the
+ options set in the Galaxy config file.
+ """
+ return [ egg for egg in self.eggs.values() if self.galaxy_config.check_conditional( egg.name ) ]
+ @property
+ def all_eggs( self ):
+ """
+ Return a list of all eggs in the crate.
+ """
+ rval = []
+ 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 ):
+ """
+ Return a specific egg.
+ """
+ name = name.replace( '-', '_' )
+ return self.eggs[name]
+ def resolve( self, all=False ):
+ """
+ Try to resolve (e.g. fetch) all eggs in the crate.
+ """
+ if all:
+ eggs = self.all_eggs
+ else:
+ eggs = self.config_eggs
+ eggs = filter( lambda x: x.name not in self.no_auto, eggs )
+ missing = []
+ for egg in eggs:
try:
- egg.tag = self.config.get( "tags", name )
+ egg.resolve()
except:
- egg.tag = None
- try:
- egg.sources = self.config.get( "source", name ).split()
- except:
- egg.sources = None
- egg.name = name
- egg.version = version
- egg.platform['galaxy'] = platform['galaxy']
- egg.platform['peak'] = platform['peak']
- egg.url = "%s/%s/%s" %( self.repo, platform['galaxy'], egg.get_filename() )
- self.eggs[name] = egg
- def find( self, ignore=None ):
- missing = []
- for egg in self.eggs.itervalues():
- if ignore is not None:
- if egg.name in ignore:
- continue
- egg.find()
- if not egg.have:
- missing.append( egg.name )
- if len( missing ):
- return False
- 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.
- """
- skip_platform = False
- 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
- for egg in self.eggs.itervalues():
- if ignore is not None:
- if egg.name in ignore:
- continue
- if skip_platform and egg.platform['galaxy'] == self.platform['galaxy']:
- missing.append( egg.name )
- continue
- try:
- egg.fetch()
- except EggNotFetchable:
- missing.append( egg.name )
- if skip_platform:
- raise PlatformNotSupported( self.platform['galaxy'] )
+ missing.append( egg )
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:
- continue
- if not egg.scramble():
- return False
- return True
- def get_names( self ):
- return self.eggs.keys()
- def get( self, name ):
- if self.eggs.has_key( name ):
- return self.eggs[name]
- else:
- return None
- def get_for_require( self, name ):
- """
- return an egg based on a lowercase name comparo and with _ instead of -. used by require.
- """
- for key in self.eggs.keys():
- if key.lower() == name.lower().replace( '-', '_' ):
- return self.eggs[key]
-class DistCrate( Crate ):
- """
- A subclass of Crate that holds eggs with info on how to build them for distribution.
- """
- dist_config_file = os.path.join( galaxy_dir, "dist-eggs.ini" )
- def __init__( self, build_on="all" ):
- self.eggs = {}
- self.config = CSConfigParser()
- self.repo = None
- self.build_on = build_on
- self.platform = 'platform'
- self.noplatform = 'noplatform'
- def parse( self ):
- 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 = 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 get_platforms( self, wanted ):
- # find all the members of a group and process them
- if self.groups.has_key( wanted ):
- platforms = []
- for name in self.groups[wanted].split():
- for platform in self.get_platforms( name ):
- if platform not in platforms:
- platforms.append( platform )
- return platforms
- elif self.hosts.has_key( wanted ):
- return [ wanted ]
- else:
- 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.
- """
- if type == "platform":
- platforms = self.platforms
- elif type == "noplatform":
- 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
- 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 )
- except:
- egg.tag = None
- try:
- egg.sources = self.config.get( "source", name ).split()
- except:
- egg.sources = None
- egg.name = name
- egg.version = version
- egg.platform['galaxy'] = gplat
- egg.platform['peak'] = pplat
- egg.url = "%s/%s/%s" %( self.repo, gplat, egg.get_filename() )
- egg.build_host, egg.python = self.hosts[platform].split()
- if not self.eggs.has_key( name ):
- self.eggs[name] = [ egg ]
- else:
- self.eggs[name].append( egg )
-
-class GalaxyConfig:
+class GalaxyConfig( object ):
config_file = os.path.join( galaxy_dir, "universe_wsgi.ini" )
- always_conditional = ( 'GeneTrack', )
+ always_conditional = ( 'GeneTrack', 'pysam' )
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 ):
+ def check_pysam():
+ # can't build pysam on solaris < 10
+ plat = pkg_resources.get_platform().split( '-' )
+ if plat[0] == 'solaris':
+ minor = plat[1].split('.')[1]
+ if int( minor ) < 10:
+ return False
+ return True
if egg_name == "pysqlite":
# SQLite is different since it can be specified in two config vars and defaults to True
try:
@@ -484,102 +317,45 @@
"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 ),
+ "pysam": check_pysam()
}.get( egg_name, lambda: True )()
except:
return False
-def require( pkg ):
- # add the egg dirs to sys.path if they're not already there
- for platform in [ get_platform(), get_platform( platform=True ) ]:
- path = os.path.join( galaxy_dir, "eggs", platform )
- if path not in sys.path:
- new_path = [ path ]
- new_path.extend( sys.path )
- sys.path = new_path
- pkg_resources.working_set.add_entry(path)
- name = pkg_resources.Requirement.parse( pkg ).project_name
+def get_env():
+ env = pkg_resources.Environment( platform=pkg_resources.get_platform() )
+ for dist in pkg_resources.find_distributions( os.path.join( galaxy_dir, 'eggs' ), False ):
+ env.add( dist )
+ return env
+env = get_env()
+
+def require( req_str ):
c = Crate()
- c.parse()
- egg = c.get_for_require( name )
+ req = pkg_resources.Requirement.parse( req_str )
try:
- if egg is None:
- return pkg_resources.working_set.require( pkg )
- else:
- return pkg_resources.working_set.require( "%s==%s" % ( name, egg.get_vertag() ) )
- except pkg_resources.VersionConflict, e:
- # there's a conflicting egg on the pythonpath, remove it
- dist = e.args[0]
- working_set = pkg_resources.working_set
- # use the canonical path for comparisons
- location = os.path.realpath( dist.location )
- for entry in working_set.entries:
- if os.path.realpath( entry ) == location:
- working_set.entries.remove( entry )
- break
- else:
- location = None
- del working_set.by_key[dist.key]
- working_set.entry_keys[entry] = []
- try:
- sys.path.remove(entry)
- except ValueError:
- raise Exception( "Cannot remove entry: %s" % str(entry) )
- r = require( pkg )
- if location is not None and not location.endswith( '.egg' ):
- # re-add the path if it's a non-egg dir, in case more deps live there
- working_set.entries.append( location ) # re-add to the set if it's a dir.
- sys.path.append( location ) # re-add to the set if it's a dir.
- return r
- except pkg_resources.DistributionNotFound, e:
- # the initial require itself is the first dep, but it can have
- # multiple deps, which will be fetched by the require below.
- dep = pkg_resources.Requirement.parse( str( e ) ).project_name
- egg = c.get_for_require( dep )
- if egg is None:
- # we don't have it and we can't get it
- raise
- egg.find()
- if not egg.have:
- if not egg.fetch():
- raise EggNotFetchable( egg.name )
- return require( pkg )
+ return c[req.project_name].require()
+ except KeyError:
+ # not a galaxy-owned dependency
+ return pkg_resources.working_set.require( req_str )
+ except EggNotFetchable, e:
+ raise EggNotFetchable( str( [ egg.name for egg in e.eggs ] ) )
+pkg_resources.require = require
-# convenience stuff
-def get_ucs():
- if sys.maxunicode > 65535:
- return "ucs4"
- else:
- return "ucs2"
-
-def get_py():
- return "py%s" % sys.version[:3]
-
-def get_noplatform():
- return "%s-noplatform" % get_py()
-
-def get_platform( platform=False, peak=False ):
- if platform:
- if peak:
- return "%s-%s" % ( get_py(), pkg_resources.get_platform() )
- else:
- return "%s-%s-%s" % ( get_py(), pkg_resources.get_platform(), get_ucs() )
- else:
- if peak:
- return get_py()
- else:
- return "%s-noplatform" % get_py()
-
-def unpack_zipfile( filename, extract_dir):
+def unpack_zipfile( filename, extract_dir, ignores=[] ):
z = zipfile.ZipFile(filename)
try:
for info in z.infolist():
name = info.filename
+ perm = (info.external_attr >> 16L) & 0777
# don't extract absolute paths or ones with .. in them
if name.startswith('/') or '..' in name:
continue
target = os.path.join(extract_dir, *name.split('/'))
if not target:
continue
+ for ignore in ignores:
+ if ignore in name:
+ continue
if name.endswith('/'):
# directory
pkg_resources.ensure_directory(target)
@@ -593,6 +369,11 @@
finally:
f.close()
del data
+ try:
+ if not os.path.islink():
+ os.chmod(target, mode)
+ except:
+ pass
finally:
z.close()
@@ -601,5 +382,3 @@
shutil.rmtree( f )
else:
os.remove( f )
-
-pkg_resources.require = require
diff -r a6c9862ece3d -r 0cb68935eede lib/galaxy/eggs/dist.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/eggs/dist.py Mon Mar 01 15:41:30 2010 -0500
@@ -0,0 +1,86 @@
+"""
+Manage Galaxy eggs
+"""
+
+import os, sys, subprocess
+from scramble import ScrambleEgg, ScrambleCrate, ScrambleFailure, galaxy_dir, py
+from __init__ import Crate, CaseSensitiveConfigParser
+
+import logging
+log = logging.getLogger( __name__ )
+
+class DistScrambleEgg( ScrambleEgg ):
+ def set_dir( self ):
+ self.dir = os.path.join( galaxy_dir, 'dist-eggs', self.name )
+ if not os.path.exists( self.dir ):
+ os.makedirs( self.dir )
+ @property
+ def path( self ):
+ # don't look for compatible eggs, look for exact matches
+ if os.path.exists( self.distribution.location ):
+ return self.distribution.location
+ return None
+ def run_scramble_script( self ):
+ log.warning( "%s(): Beginning build" % sys._getframe().f_code.co_name )
+ # subprocessed to sterilize the env
+ cmd = "ssh %s 'cd %s; %s -ES %s'" % ( self.build_host, self.buildpath, self.python, 'scramble.py' )
+ log.debug( '%s(): Executing:' % sys._getframe().f_code.co_name )
+ log.debug( ' %s' % cmd )
+ p = subprocess.Popen( args = cmd, shell = True )
+ r = p.wait()
+ if r != 0:
+ raise ScrambleFailure( "%s(): Egg build failed for %s %s" % ( sys._getframe().f_code.co_name, self.name, self.version ) )
+ def unpack_if_needed( self ):
+ return # do not unpack dist eggs
+
+class DistScrambleCrate( ScrambleCrate ):
+ """
+ Holds eggs with info on how to build them for distribution.
+ """
+ dist_config_file = os.path.join( galaxy_dir, 'dist-eggs.ini' )
+ def __init__( self, build_on='all' ):
+ self.dist_config = CaseSensitiveConfigParser()
+ self.build_on = build_on
+ ScrambleCrate.__init__( self )
+ def parse( self ):
+ self.dist_config.read( DistScrambleCrate.dist_config_file )
+ self.hosts = dict( self.dist_config.items( 'hosts' ) )
+ self.groups = dict( self.dist_config.items( 'groups' ) )
+ self.ignore = dict( self.dist_config.items( 'ignore' ) )
+ self.platforms = self.get_platforms( self.build_on )
+ self.noplatforms = self.get_platforms( 'noplatform' )
+ Crate.parse( self )
+ def get_platforms( self, wanted ):
+ # find all the members of a group and process them
+ if self.groups.has_key( wanted ):
+ platforms = []
+ for name in self.groups[wanted].split():
+ for platform in self.get_platforms( name ):
+ if platform not in platforms:
+ platforms.append( platform )
+ return platforms
+ elif self.hosts.has_key( wanted ):
+ return [ wanted ]
+ else:
+ raise Exception( "unknown platform: %s" % wanted )
+ def parse_egg_section( self, eggs, tags, full_platform=False ):
+ for name, version in eggs:
+ self.eggs[name] = []
+ tag = dict( tags ).get( name, '' )
+ url = '/'.join( ( self.repo, name ) )
+ try:
+ sources = self.config.get( 'source', name ).split()
+ except:
+ sources = []
+ if full_platform:
+ platforms = self.platforms
+ else:
+ platforms = self.noplatforms
+ for platform in platforms:
+ if name in self.ignore and platform in self.ignore[name].split():
+ continue
+ egg = DistScrambleEgg( name, version, tag, url, platform )
+ host_info = self.hosts[platform].split()
+ egg.build_host, egg.python = host_info[:2]
+ egg.sources = sources
+ self.eggs[name].append( egg )
diff -r a6c9862ece3d -r 0cb68935eede lib/galaxy/eggs/scramble.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/eggs/scramble.py Mon Mar 01 15:41:30 2010 -0500
@@ -0,0 +1,234 @@
+"""
+Manage Galaxy eggs
+"""
+
+import os, sys, shutil, tempfile, subprocess, urlparse, urllib
+from __init__ import Egg, Crate, URLRetriever, galaxy_dir, py, unpack_zipfile
+from distutils.sysconfig import get_config_var
+
+import tarfile, zipfile, zlib
+arctypes = ( 'tar.gz', 'tgz', 'zip' )
+
+import logging
+log = logging.getLogger( __name__ )
+
+import pkg_resources
+
+class ScrambleFailure( Exception ):
+ def __init__( self, eggs, msg=None ):
+ if type( eggs ) in ( list, tuple ):
+ self.eggs = eggs
+ else:
+ self.eggs = [ eggs ]
+ self.msg = msg
+ def __str__( self ):
+ return self.msg or ' '.join( self.eggs )
+
+class ScrambleEgg( Egg ):
+ """
+ Contains information about scrambling eggs.
+ """
+ scramble_dir = os.path.join( galaxy_dir, 'scripts', 'scramble' )
+ archive_dir = os.path.join( scramble_dir, 'archives' )
+ script_dir = os.path.join( scramble_dir, 'scripts' )
+ build_dir = os.path.join( scramble_dir, 'build' )
+ ez_setup = os.path.join( scramble_dir, 'lib', 'ez_setup.py' )
+ ez_setup_url = 'http://peak.telecommunity.com/dist/ez_setup.py'
+ def __init__( self, *args, **kwargs ):
+ Egg.__init__( self, *args, **kwargs )
+ self.sources = []
+ self.buildpath = None
+ self.source_path = None
+ self.py = py
+ self.build_host = None
+ self.python = sys.executable
+ def scramble( self ):
+ if self.path:
+ log.warning( "%s(): Egg already exists, remove to force rebuild:" % sys._getframe().f_code.co_name )
+ log.warning( " %s" % self.path )
+ return
+ self.fetch_source()
+ self.unpack_source()
+ self.copy_build_script()
+ if not os.path.exists( ScrambleEgg.ez_setup ):
+ URLRetriever().retrieve( ScrambleEgg.ez_setup_url, ScrambleEgg.ez_setup )
+ shutil.copyfile( ScrambleEgg.ez_setup, os.path.join( self.buildpath, 'ez_setup.py' ) )
+ self.run_scramble_script()
+ new_egg = os.path.join( self.buildpath, 'dist', os.path.basename( self.distribution.location ) )
+ if not os.path.exists( new_egg ):
+ raise ScrambleFailure( self, "%s(): Egg build for %s did not appear to fail, but no egg found to copy from expected path:\n %s" % ( sys._getframe().f_code.co_name, self.name, egg_name ) )
+ shutil.copyfile( new_egg, self.distribution.location )
+ log.warning( "%s(): Copied egg to:" % sys._getframe().f_code.co_name )
+ log.warning( " %s" % self.distribution.location )
+ self.unpack_if_needed()
+ self.remove_doppelgangers()
+ # scramble helper methods
+ 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( "%s(): Archive contains multiple top-level directories!" % sys._getframe().f_code.co_name )
+ return tld
+ def fetch_one( self, urls ):
+ """
+ Fetches the first available archive out of a list.
+ """
+ for url in urls:
+ file = os.path.join( ScrambleEgg.archive_dir, ( urllib.unquote( url ).rsplit( '/', 1 ) )[-1] )
+ if os.path.exists( file ):
+ log.warning( "%s(): Using existing source, remove to download again:" % sys._getframe().f_code.co_name )
+ log.warning( " %s" % file )
+ return file
+ # if we don't have one, get one
+ for url in urls:
+ file = os.path.join( ScrambleEgg.archive_dir, ( urllib.unquote( url ).rsplit( '/', 1 ) )[-1] )
+ try:
+ log.debug( "%s(): Trying to fetch:" % sys._getframe().f_code.co_name )
+ log.debug( " %s" % url )
+ URLRetriever().retrieve( url, file + '.download' )
+ shutil.move( file + '.download', file )
+ log.debug( "%s(): Fetched to:" % sys._getframe().f_code.co_name )
+ log.debug( " %s" % file )
+ return file
+ except IOError, e:
+ if e[1] != 404:
+ raise
+ else:
+ return None
+ def fetch_source( self ):
+ """
+ Get egg (and dependent) source
+ """
+ if not os.path.exists( ScrambleEgg.archive_dir ):
+ os.makedirs( ScrambleEgg.archive_dir )
+ urls = []
+ url_base = self.url + '/' + '-'.join( ( self.name, self.version ) )
+ urls.extend( map( lambda x: '.'.join( ( url_base, x ) ), arctypes ) )
+ if self.tag:
+ urls.extend( map( lambda x: '.'.join( ( url_base + self.tag, x ) ), arctypes ) )
+ self.source_path = self.fetch_one( urls )
+ if self.source_path is None:
+ raise Exception( "%s(): Couldn't find a suitable source archive for %s %s from %s" % ( sys._getframe().f_code.co_name, self.name, self.version, self.url ) )
+ for url in self.sources:
+ if not urlparse.urlparse( url )[0]:
+ url = self.url + '/' + url.lstrip( '/' )
+ urls = [ url ]
+ urls.extend( map( lambda x: '.'.join( ( url, x ) ), arctypes ) ) # allows leaving off the extension and we'll try to find one
+ file = self.fetch_one( urls )
+ if file is None:
+ raise Exception( "%s(): Couldn't fetch extra source for %s, check path in %s. URL(s) attempted output above." % ( sys._getframe().f_code.co_name, self.name, Crate.config_file, ) )
+ def unpack_source( self ):
+ unpack_dir = os.path.join( ScrambleEgg.build_dir, self.platform )
+ if not os.path.exists( unpack_dir ):
+ os.makedirs( unpack_dir )
+ self.buildpath = os.path.join( unpack_dir, self.name )
+ if os.path.exists( self.buildpath ):
+ log.warning( "%s(): Removing old build directory at:" % sys._getframe().f_code.co_name )
+ log.warning( " %s" % self.buildpath )
+ shutil.rmtree( self.buildpath )
+ if tarfile.is_tarfile( self.source_path ):
+ self.unpack_tar()
+ elif zipfile.is_zipfile( self.source_path ):
+ self.unpack_zip()
+ else:
+ raise Exception( "%s(): Unknown archive file type for %s" % ( sys._getframe().f_code.co_name, source_path ) )
+ log.warning( "%s(): Unpacked to:" % sys._getframe().f_code.co_name )
+ log.warning( " %s" % self.buildpath )
+ def unpack_zip( self ):
+ unpack_path = os.path.dirname( self.buildpath )
+ tld = self.get_tld( zipfile.ZipFile( self.source_path, 'r' ).namelist() )
+ unpack_zipfile( self.source_path, unpack_path, ( 'ez_setup', ) )
+ os.rename( os.path.join( unpack_path, tld ), self.buildpath )
+ def unpack_tar( self ):
+ unpack_path = os.path.dirname( self.buildpath )
+ t = tarfile.open( self.source_path, "r" )
+ 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 members:
+ t.extract( member )
+ t.close()
+ os.rename( tld, self.name )
+ os.chdir( cur )
+ def copy_build_script( self ):
+ # will try:
+ # bx_python-py2.4-solaris-2.11-i86pc.py
+ # bx_python-py2.4-solaris.py
+ # bx_python-solaris-2.11-i86pc.py
+ # bx_python-solaris.py
+ # bx_python-py2.4.py
+ # bx_python.py
+ # generic.py
+ platform = self.platform.replace( '-ucs2', '' ).replace( '-ucs4', '' ) # ucs is unimportant here
+ build_scripts = (
+ "%s-%s.py" % ( self.name, platform ),
+ "%s-%s.py" % ( self.name, '-'.join( platform.split( '-' )[:2] ) ),
+ "%s-%s.py" % ( self.name, '-'.join( platform.split( '-' )[1:] ) ),
+ "%s-%s.py" % ( self.name, self.py ),
+ "%s-%s.py" % ( self.name, platform.split( '-' )[0] ),
+ "%s.py" % self.name,
+ "generic.py" )
+ for build_script in build_scripts:
+ build_script = os.path.join( ScrambleEgg.script_dir, build_script )
+ if os.path.exists( build_script ):
+ log.warning( "%s(): Using build script %s" % ( sys._getframe().f_code.co_name, build_script ) )
+ break
+ shutil.copyfile( build_script, os.path.join( self.buildpath, "scramble.py" ) )
+ verfile = open( os.path.join( self.buildpath, ".galaxy_ver" ), "w" )
+ verfile.write( self.version + '\n' )
+ verfile.close()
+ if self.tag is not None:
+ tagfile = open( os.path.join( self.buildpath, ".galaxy_tag" ), "w" )
+ tagfile.write( self.tag + '\n' )
+ tagfile.close()
+ def run_scramble_script( self ):
+ log.warning( "%s(): Beginning build" % sys._getframe().f_code.co_name )
+ # subprocessed to sterilize the env
+ cmd = "%s -ES %s" % ( self.python, "scramble.py" )
+ log.debug( '%s(): Executing in %s:' % ( sys._getframe().f_code.co_name, self.buildpath ) )
+ log.debug( ' %s' % cmd )
+ p = subprocess.Popen( args = cmd, shell = True, cwd = self.buildpath )
+ r = p.wait()
+ if r != 0:
+ if sys.platform == 'sunos5' and get_config_var('CC').endswith('pycc') and not os.environ.get( 'PYCC_CC', None ):
+ log.error( "%s(): Your python interpreter was compiled with Sun's pycc" % sys._getframe().f_code.co_name )
+ log.error( " pseudo-compiler. You may need to set PYCC_CC and PYCC_CXX in your" )
+ log.error( " environment if your compiler is in a non-standard location." )
+ raise ScrambleFailure( self, "%s(): Egg build failed for %s %s" % ( sys._getframe().f_code.co_name, self.name, self.version ) )
+
+class ScrambleCrate( Crate ):
+ """
+ Reads the eggs.ini file for use with scrambling eggs.
+ """
+ def parse( self ):
+ Crate.parse( self )
+ # get dependency sources
+ for egg in self.eggs.values():
+ try:
+ egg.sources = self.config.get( "source", egg.name ).split()
+ except:
+ egg.sources = []
+ def parse_egg_section( self, *args, **kwargs ):
+ kwargs['egg_class'] = ScrambleEgg
+ Crate.parse_egg_section( self, *args, **kwargs )
+ def scramble( self, all=False ):
+ if all:
+ eggs = self.all_eggs
+ else:
+ eggs = self.config_eggs
+ eggs = filter( lambda x: x.name not in self.no_auto, eggs )
+ failed = []
+ for egg in eggs:
+ try:
+ egg.scramble()
+ except Exception, e:
+ failed.append( egg )
+ last_exc = e
+ if failed:
+ if len( failed ) == 1:
+ raise last_exc # only 1 failure out of the crate, be more informative
+ else:
+ raise ScrambleFailure( failed )
diff -r a6c9862ece3d -r 0cb68935eede manage_db.sh
--- a/manage_db.sh Mon Mar 01 13:30:37 2010 -0500
+++ b/manage_db.sh Mon Mar 01 15:41:30 2010 -0500
@@ -6,4 +6,4 @@
#######
cd `dirname $0`
-`python ./scripts/check_python.py` ./scripts/manage_db.py $@
+python ./scripts/manage_db.py $@
diff -r a6c9862ece3d -r 0cb68935eede run.sh
--- a/run.sh Mon Mar 01 13:30:37 2010 -0500
+++ b/run.sh Mon Mar 01 15:41:30 2010 -0500
@@ -2,18 +2,16 @@
cd `dirname $0`
-CLEAN_PYTHON=`python ./scripts/check_python.py`
-
# explicitly attempt to fetch eggs before running
FETCH_EGGS=1
for arg in "$@"; do
[ "$arg" = "--stop-daemon" ] && FETCH_EGGS=0; break
done
if [ $FETCH_EGGS -eq 1 ]; then
- $CLEAN_PYTHON ./scripts/check_eggs.py quiet
+ python ./scripts/check_eggs.py quiet
if [ $? -ne 0 ]; then
echo "Some eggs are out of date, attempting to fetch..."
- $CLEAN_PYTHON ./scripts/fetch_eggs.py
+ python ./scripts/fetch_eggs.py
if [ $? -eq 0 ]; then
echo "Fetch successful."
else
@@ -22,4 +20,4 @@
fi
fi
fi
-$CLEAN_PYTHON ./scripts/paster.py serve universe_wsgi.ini $@
+python ./scripts/paster.py serve universe_wsgi.ini $@
diff -r a6c9862ece3d -r 0cb68935eede run_functional_tests.sh
--- a/run_functional_tests.sh Mon Mar 01 13:30:37 2010 -0500
+++ b/run_functional_tests.sh Mon Mar 01 15:41:30 2010 -0500
@@ -4,10 +4,8 @@
rm -f run_functional_tests.log
-CLEAN_PYTHON=`python ./scripts/check_python.py`
-
if [ ! $1 ]; then
- $CLEAN_PYTHON ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html --exclude="^get" functional
+ python ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html --exclude="^get" functional
elif [ $1 = 'help' ]; then
echo "'run_functional_tests.sh' for testing all the tools in functional directory"
echo "'run_functional_tests.sh aaa' for testing one test case of 'aaa' ('aaa' is the file name with path)"
@@ -15,16 +13,16 @@
echo "'run_functional_tests.sh -sid ccc' for testing one section with sid 'ccc' ('ccc' is the string after 'section::')"
echo "'run_functional_tests.sh -list' for listing all the tool ids"
elif [ $1 = '-id' ]; then
- $CLEAN_PYTHON ./scripts/functional_tests.py -v functional.test_toolbox:TestForTool_$2 --with-nosehtml --html-report-file run_functional_tests.html
+ python ./scripts/functional_tests.py -v functional.test_toolbox:TestForTool_$2 --with-nosehtml --html-report-file run_functional_tests.html
elif [ $1 = '-sid' ]; then
- $CLEAN_PYTHON ./scripts/functional_tests.py --with-nosehtml --html-report-file run_functional_tests.html -v `python tool_list.py $2`
+ python ./scripts/functional_tests.py --with-nosehtml --html-report-file run_functional_tests.html -v `python tool_list.py $2`
elif [ $1 = '-list' ]; then
python tool_list.py
echo "==========================================================================================================================================="
echo "'run_functional_tests.sh -id bbb' for testing one tool with id 'bbb' ('bbb' is the tool id)"
echo "'run_functional_tests.sh -sid ccc' for testing one section with sid 'ccc' ('ccc' is the string after 'section::')"
else
- $CLEAN_PYTHON ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html $1
+ python ./scripts/functional_tests.py -v --with-nosehtml --html-report-file run_functional_tests.html $1
fi
echo "'run_functional_tests.sh help' for help"
diff -r a6c9862ece3d -r 0cb68935eede run_reports.sh
--- a/run_reports.sh Mon Mar 01 13:30:37 2010 -0500
+++ b/run_reports.sh Mon Mar 01 15:41:30 2010 -0500
@@ -1,5 +1,4 @@
#!/bin/sh
cd `dirname $0`
-
-`python ./scripts/check_python.py` ./scripts/paster.py serve reports_wsgi.ini --pid-file=reports_webapp.pid --log-file=reports_webapp.log $@
+python ./scripts/paster.py serve reports_wsgi.ini --pid-file=reports_webapp.pid --log-file=reports_webapp.log $@
diff -r a6c9862ece3d -r 0cb68935eede run_unit_tests.sh
--- a/run_unit_tests.sh Mon Mar 01 13:30:37 2010 -0500
+++ b/run_unit_tests.sh Mon Mar 01 15:41:30 2010 -0500
@@ -2,6 +2,6 @@
## Excluding controllers due to the problematic genetrack dependency
-`python ./scripts/check_python.py` ./scripts/nosetests.py -v -w lib \
+python ./scripts/nosetests.py -v -w lib \
--with-nosehtml --html-report-file run_unit_tests.html \
--with-doctest --exclude=functional --exclude="^get" --exclude=controllers
diff -r a6c9862ece3d -r 0cb68935eede scripts/check_eggs.py
--- a/scripts/check_eggs.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/check_eggs.py Mon Mar 01 15:41:30 2010 -0500
@@ -17,16 +17,10 @@
except:
quiet = False
-from galaxy.eggs import *
+from galaxy.eggs import Crate
c = Crate()
-c.parse()
-galaxy_config = GalaxyConfig()
-ignore = []
-for name in c.get_names():
- if not galaxy_config.check_conditional( name ):
- ignore.append( name )
-if not c.find( ignore=ignore ):
+if c.config_missing:
if not quiet:
print "Some of your Galaxy eggs are out of date. Please update them"
print "by running:"
diff -r a6c9862ece3d -r 0cb68935eede scripts/check_python.py
--- a/scripts/check_python.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/check_python.py Mon Mar 01 15:41:30 2010 -0500
@@ -6,13 +6,6 @@
supported version is installed but is not your default, getgalaxy.org
contains instructions on how to force Galaxy to use a different version.""" % sys.version[:3]
-def check_virtualenv():
- try:
- assert sys.real_prefix
- return 'python -E'
- except:
- return 'python -ES'
-
def check_python():
try:
assert sys.version_info[:2] >= ( 2, 4 ) and sys.version_info[:2] <= ( 2, 6 )
@@ -21,9 +14,9 @@
raise
if __name__ == '__main__':
+ rval = 0
try:
check_python()
- print check_virtualenv()
- sys.exit( 0 )
except StandardError:
- sys.exit( 1 )
+ rval = 1
+ sys.exit( rval )
diff -r a6c9862ece3d -r 0cb68935eede scripts/dist-scramble.py
--- a/scripts/dist-scramble.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/dist-scramble.py Mon Mar 01 15:41:30 2010 -0500
@@ -11,28 +11,30 @@
root.setLevel( 10 )
root.addHandler( logging.StreamHandler( sys.stdout ) )
-lib = os.path.abspath( os.path.join( os.path.dirname( __file__ ), "..", "lib" ) )
+lib = os.path.abspath( os.path.join( os.path.dirname( __file__ ), '..', 'lib' ) )
sys.path.append( lib )
-from galaxy.eggs import DistCrate
+from galaxy.eggs.dist import DistScrambleCrate, ScrambleFailure
if len( sys.argv ) > 3 or len( sys.argv ) < 2:
print __doc__
sys.exit( 1 )
elif len( sys.argv ) == 3:
- c = DistCrate( sys.argv[2] )
+ c = DistScrambleCrate( sys.argv[2] )
else:
- c = DistCrate()
+ c = DistScrambleCrate()
-c.parse()
-egg_list = c.get( sys.argv[1] )
-if egg_list is None:
+try:
+ eggs = c[sys.argv[1]]
+except:
print "error: %s not in eggs.ini" % sys.argv[1]
sys.exit( 1 )
failed = []
-for egg in egg_list:
- if not egg.scramble( dist=True ):
- failed.append( egg.platform['galaxy'] )
+for egg in eggs:
+ try:
+ egg.scramble()
+ except ScrambleFailure:
+ failed.append( egg.platform )
if len( failed ):
print ""
print "Scramble failed to build eggs on the following platforms (more details"
diff -r a6c9862ece3d -r 0cb68935eede scripts/fetch_eggs.py
--- a/scripts/fetch_eggs.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/fetch_eggs.py Mon Mar 01 15:41:30 2010 -0500
@@ -18,39 +18,43 @@
lib = os.path.abspath( os.path.join( os.path.dirname( __file__ ), "..", "lib" ) )
sys.path.append( lib )
-from galaxy.eggs import *
+from galaxy.eggs import Crate, EggNotFetchable
+import pkg_resources
c = Crate()
-if len( sys.argv ) == 3:
- c.platform = { 'peak' : sys.argv[2].rsplit('-',1)[0], 'galaxy' : sys.argv[2] }
-c.parse()
try:
- galaxy_config = GalaxyConfig()
- names = []
+ c.platform = sys.argv[2]
+except:
+ pass
+try:
if len( sys.argv ) == 1:
- names = c.get_names()
+ c.resolve() # Only fetch eggs required by the config
elif sys.argv[1] == 'all':
- names = galaxy_config.always_conditional
+ c.resolve( all=True ) # Fetch everything
else:
# Fetch a specific egg
- egg = c.get( sys.argv[1] )
- if egg is None:
- print "error: %s not in eggs.ini" % sys.argv[1]
+ name = sys.argv[1]
+ try:
+ egg = c[name]
+ except:
+ print "error: %s not in eggs.ini" % name
sys.exit( 1 )
- egg.fetch()
- sys.exit( 0 )
- ignore = filter( lambda x: not galaxy_config.check_conditional( x ), list( names ) )
- c.fetch( ignore )
+ dist = egg.resolve()[0]
+ print "%s %s is installed at %s" % ( dist.project_name, dist.version, dist.location )
except EggNotFetchable, 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
+ try:
+ assert sys.argv[1] != 'all'
+ egg = e.eggs[0]
+ print "%s %s couldn't be downloaded automatically. You can try" % ( egg.name, egg.version )
+ print "building it by hand with:"
+ print " python scripts/scramble.py %s"
+ except ( AssertionError, IndexError ):
+ print "One or more of the python eggs necessary to run Galaxy couldn't be"
+ print "downloaded automatically. You can try building them by hand (all"
+ print "at once) with:"
+ print " python scripts/scramble.py"
+ print "Or individually:"
+ for egg in e.eggs:
+ print " python scripts/scramble.py %s" % egg.name
sys.exit( 1 )
-except PlatformNotSupported, e:
- print "Your platform (%s) is not supported." % e
- print "Pre-built galaxy eggs are not available from the Galaxy developers for"
- print "your platform. You may be able to build them by hand with:"
- print " python scripts/scramble.py"
- sys.exit( 1 )
+sys.exit( 0 )
diff -r a6c9862ece3d -r 0cb68935eede scripts/get_platforms.py
--- a/scripts/get_platforms.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/get_platforms.py Mon Mar 01 15:41:30 2010 -0500
@@ -7,6 +7,6 @@
lib = os.path.abspath( os.path.join( os.path.dirname( __file__ ), "..", "lib" ) )
sys.path.append( lib )
-from galaxy.eggs import get_platform
-print get_platform()
-print get_platform( True )
+import galaxy
+import pkg_resources
+print pkg_resources.get_platform()
diff -r a6c9862ece3d -r 0cb68935eede scripts/paster.py
--- a/scripts/paster.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/paster.py Mon Mar 01 15:41:30 2010 -0500
@@ -28,6 +28,7 @@
pkg_resources.require( "Paste" )
pkg_resources.require( "PasteScript" )
+pkg_resources.require( "PasteDeploy" )
from paste.script import command
command.run()
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble.py
--- a/scripts/scramble.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/scramble.py Mon Mar 01 15:41:30 2010 -0500
@@ -14,23 +14,29 @@
lib = os.path.abspath( os.path.join( os.path.dirname( __file__ ), "..", "lib" ) )
sys.path.append( lib )
-from galaxy.eggs import Crate, GalaxyConfig
+from galaxy.eggs.scramble import ScrambleCrate, ScrambleFailure
-c = Crate()
-c.parse()
-galaxy_config = GalaxyConfig()
-names = []
-if len( sys.argv ) == 1:
- names = c.get_names()
-elif sys.argv[1] == 'all':
- names = galaxy_config.always_conditional
-else:
-# 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 )
+c = ScrambleCrate()
+
+try:
+ if len( sys.argv ) == 1:
+ eggs = c.scramble()
+ elif sys.argv[1] == 'all':
+ c.scramble( all=True )
+ else:
+ # Scramble a specific egg
+ name = sys.argv[1]
+ try:
+ egg = c[name]
+ except:
+ print "error: %s not in eggs.ini" % name
+ sys.exit( 1 )
+ egg.scramble()
+ sys.exit( 0 )
+except ScrambleFailure, e:
+ if len( e.eggs ) == 1:
+ raise
+ else:
+ print 'Scrambling the following eggs failed:\n ',
+ print '\n '.join( [ egg.name for egg in e.eggs ] )
+ sys.exit( 1 )
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/lib/get_platform.py
--- a/scripts/scramble/lib/get_platform.py Mon Mar 01 13:30:37 2010 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-"""
-Monkeypatch get_platform since it's broken on OS X versions of Python 2.5
-"""
-import os, sys
-from distutils.sysconfig import get_config_vars
-if sys.platform == 'darwin' and get_config_vars().get('UNIVERSALSDK', '').strip():
- # Has to be before anything imports pkg_resources
- def _get_platform_monkeypatch():
- plat = distutils.util._get_platform()
- if plat.startswith( 'macosx-' ):
- plat = 'macosx-10.3-fat'
- return plat
- import distutils.util
- try:
- assert distutils.util._get_platform
- except:
- distutils.util._get_platform = distutils.util.get_platform
- distutils.util.get_platform = _get_platform_monkeypatch
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/lib/scramble_lib.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/scramble/lib/scramble_lib.py Mon Mar 01 15:41:30 2010 -0500
@@ -0,0 +1,164 @@
+"""
+Various utilities for scrambling.
+"""
+import os, sys, errno, re, distutils.util, glob, shutil, subprocess, tarfile, zipfile
+from distutils.sysconfig import get_config_var, get_config_vars
+
+try:
+ import zlib
+except:
+ raise Exception( 'Cannot import zlib, which must exist to build eggs. If your python interpreter is truly missing it, you will need to recompile or (on supported platforms) download a binary version from python.org.' )
+
+def get_tag():
+ try:
+ return open( '.galaxy_tag', 'r' ).read().strip()
+ except:
+ return None
+
+def get_ver():
+ try:
+ return open( '.galaxy_ver', 'r' ).read().strip()
+ except:
+ return None
+
+def clean( extra_dirs=[] ):
+ for dir in [ 'build', 'dist' ] + extra_dirs:
+ try:
+ shutil.rmtree( dir )
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+
+def apply_patches():
+ name = os.path.basename( os.getcwd() )
+ for file in glob.glob( os.path.join( patches, name, '*' ) ):
+ shutil.copy( file, os.path.basename( file ) )
+
+def get_archive( base ):
+ for arctype in ( 'tar.gz', 'tgz', 'zip' ):
+ archive = '.'.join( ( base, arctype ) )
+ if os.path.exists( archive ):
+ return archive
+ else:
+ raise Exception( "%s(): Couldn't find a suitable archive for %s in %s" % ( sys._getframe().f_code.co_name, os.path.basename( base ), archives ) )
+
+def compress( path, *files ):
+ tarcf( path, *files )
+
+def uncompress( path ):
+ if path.endswith( '.zip' ):
+ unzip( path )
+ else:
+ tarxf( path )
+
+def unzip( zipf ):
+ z = zipfile.ZipFile( zipf )
+ try:
+ for info in z.infolist():
+ name = info.filename
+ mode = (info.external_attr >> 16L) & 0777
+ # don't extract absolute paths or ones with .. in them
+ if name.startswith('/') or '..' in name:
+ continue
+ if not name:
+ continue
+ if name.endswith('/'):
+ # directory
+ pkg_resources.ensure_directory(name)
+ else:
+ # file
+ pkg_resources.ensure_directory(name)
+ data = z.read(info.filename)
+ f = open(name,'wb')
+ try:
+ f.write(data)
+ finally:
+ f.close()
+ del data
+ try:
+ if not os.path.islink( name ):
+ os.chmod(name,mode)
+ except:
+ pass
+ finally:
+ z.close()
+
+def tarxf( ball ):
+ t = tarfile.open( ball, 'r' )
+ for fn in t.getnames():
+ t.extract( fn )
+ t.close()
+
+def tarcf( ball, *files ):
+ if ball.endswith( '.gz' ):
+ t = tarfile.open( ball, 'w:gz' )
+ elif ball.endswith( '.bz2' ):
+ t = tarfile.open( ball, 'w:bz2' )
+ else:
+ t = tarfile.open( ball, 'w' )
+ for file in files:
+ t.add( file )
+ t.close()
+
+def run( cmd, d, txt ):
+ p = subprocess.Popen( args = cmd, shell = True, cwd = d )
+ r = p.wait()
+ if r != 0:
+ print '%s(): %s failed' % ( sys._getframe().f_code.co_name, txt )
+ sys.exit( 1 )
+
+def unpack_dep( source, prepped, builder, args={} ):
+ if prepped is not None and os.path.exists( prepped ):
+ print "%s(): Prepared dependency already exists at the following path, remove to force re-prep:" % sys._getframe().f_code.co_name
+ print " ", prepped
+ uncompress( prepped )
+ else:
+ print "%s(): Prepared dependency does not exist, preparing now from source:" % sys._getframe().f_code.co_name
+ print " ", source
+ uncompress( source )
+ builder( prepped, args )
+
+def get_solaris_compiler():
+ p = subprocess.Popen( '%s -V 2>&1' % get_config_var('CC'), shell = True, stdout = subprocess.PIPE )
+ out = p.stdout.read()
+ p.wait()
+ if 'Sun C' in out:
+ return 'cc'
+ else:
+ return 'gcc'
+
+# Monkeypatch pkg_resources for better ABI recognition
+def _get_platform():
+ plat = distutils.util._get_platform()
+ if sys.version_info[:2] == ( 2, 5 ) and \
+ ( ( os.uname()[-1] in ( 'i386', 'ppc' ) and sys.platform == 'darwin' and os.path.abspath( sys.prefix ).startswith( '/System' ) ) or \
+ ( sys.platform == 'darwin' and get_config_vars().get('UNIVERSALSDK', '').strip() ) ):
+ plat = 'macosx-10.3-fat'
+ if sys.platform == "sunos5" and not (plat.endswith('_32') or plat.endswith('_64')):
+ if sys.maxint > 2**31:
+ plat += '_64'
+ else:
+ plat += '_32'
+ if not (plat.endswith('-ucs2') or plat.endswith('-ucs4')):
+ if sys.maxunicode > 2**16:
+ plat += '-ucs4'
+ else:
+ plat += '-ucs2'
+ return plat
+try:
+ assert distutil.util._get_platform
+except:
+ distutils.util._get_platform = distutils.util.get_platform
+ distutils.util.get_platform = _get_platform
+
+# get setuptools
+from ez_setup import use_setuptools
+use_setuptools( download_delay=8, to_dir=os.path.dirname( __file__ ) )
+from setuptools import *
+import pkg_resources
+
+# some constants
+root = os.path.abspath( os.path.join( os.path.dirname( __file__ ), '..' ) )
+archives = os.path.abspath( os.path.join( root, 'archives' ) )
+patches = os.path.abspath( os.path.join( root, 'patches' ) )
+platform_noucs = pkg_resources.get_platform().rsplit( '-', 1 )[0]
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/patches/Cheetah/SetupConfig.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/scramble/patches/Cheetah/SetupConfig.py Mon Mar 01 15:41:30 2010 -0500
@@ -0,0 +1,103 @@
+#-------Main Package Settings-----------#
+import sys
+
+name = 'Cheetah'
+from cheetah.Version import Version as version
+maintainer = "R. Tyler Ballance"
+author = "Tavis Rudd"
+author_email = "cheetahtemplate-discuss(a)lists.sf.net"
+url = "http://www.cheetahtemplate.org/"
+packages = ['Cheetah',
+ 'Cheetah.Macros',
+ 'Cheetah.Templates',
+ 'Cheetah.Tests',
+ 'Cheetah.Tools',
+ 'Cheetah.Utils',
+ ]
+classifiers = [line.strip() for line in '''\
+ #Development Status :: 4 - Beta
+ Development Status :: 5 - Production/Stable
+ Intended Audience :: Developers
+ Intended Audience :: System Administrators
+ License :: OSI Approved :: MIT License
+ Operating System :: OS Independent
+ Programming Language :: Python
+ Topic :: Internet :: WWW/HTTP
+ Topic :: Internet :: WWW/HTTP :: Dynamic Content
+ Topic :: Internet :: WWW/HTTP :: Site Management
+ Topic :: Software Development :: Code Generators
+ Topic :: Software Development :: Libraries :: Python Modules
+ Topic :: Software Development :: User Interfaces
+ Topic :: Text Processing'''.splitlines() if not line.strip().startswith('#')]
+del line
+
+package_dir = {'Cheetah':'cheetah'}
+
+import os
+import os.path
+from distutils.core import Extension
+
+ext_modules=[
+ Extension("Cheetah._namemapper",
+ [os.path.join('cheetah', 'c', '_namemapper.c')]),
+ # Extension("Cheetah._verifytype",
+ # [os.path.join('cheetah', 'c', '_verifytype.c')]),
+ # Extension("Cheetah._filters",
+ # [os.path.join('cheetah', 'c', '_filters.c')]),
+ # Extension('Cheetah._template',
+ # [os.path.join('cheetah', 'c', '_template.c')]),
+ ]
+
+## Data Files and Scripts
+scripts = ['bin/cheetah-compile',
+ 'bin/cheetah',
+ ]
+
+data_files = ['recursive: cheetah *.tmpl *.txt LICENSE README TODO CHANGES',]
+
+if not os.getenv('CHEETAH_INSTALL_WITHOUT_SETUPTOOLS'):
+ try:
+ from setuptools import setup
+# install_requires = [
+# "Markdown >= 2.0.1",
+# ]
+ if sys.platform == 'win32':
+ # use 'entry_points' instead of 'scripts'
+ del scripts
+ entry_points = {
+ 'console_scripts': [
+ 'cheetah = Cheetah.CheetahWrapper:_cheetah',
+ 'cheetah-compile = Cheetah.CheetahWrapper:_cheetah_compile',
+ ]
+ }
+ except ImportError:
+ print 'Not using setuptools, so we cannot install the Markdown dependency'
+
+
+description = "Cheetah is a template engine and code generation tool."
+
+long_description = '''Cheetah is an open source template engine and code generation tool.
+
+It can be used standalone or combined with other tools and frameworks. Web
+development is its principle use, but Cheetah is very flexible and is also being
+used to generate C++ game code, Java, sql, form emails and even Python code.
+
+Documentation
+================================================================================
+For a high-level introduction to Cheetah please refer to the User\'s Guide
+at http://www.cheetahtemplate.org/learn.html
+
+Mailing list
+================================================================================
+cheetahtemplate-discuss(a)lists.sourceforge.net
+Subscribe at http://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
+
+Credits
+================================================================================
+http://www.cheetahtemplate.org/credits.html
+
+Recent Changes
+================================================================================
+See http://www.cheetahtemplate.org/CHANGES.txt for full details
+
+'''
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/patches/GeneTrack/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/scramble/patches/GeneTrack/setup.py Mon Mar 01 15:41:30 2010 -0500
@@ -0,0 +1,15 @@
+from os import walk
+from os.path import join
+from setuptools import setup, find_packages
+
+def walk_files( top ):
+ for dir, dirs, files in walk( top ):
+ yield( dir, [ join( dir, f ) for f in files ] )
+
+setup(
+ name = "GeneTrack",
+ version = "2.0.0-beta-1",
+ packages = ['genetrack','genetrack.scripts'],
+ data_files = [ f for f in walk_files('tests') ],
+ zip_safe = False
+)
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/patches/MySQL_python/site.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/scramble/patches/MySQL_python/site.cfg Mon Mar 01 15:41:30 2010 -0500
@@ -0,0 +1,18 @@
+[options]
+# embedded: link against the embedded server library
+# threadsafe: use the threadsafe client
+# static: link against a static library (probably required for embedded)
+
+embedded = False
+threadsafe = True
+static = True
+
+# The path to mysql_config.
+# Only use this if mysql_config is not on your PATH, or you have some weird
+# setup that requires it.
+mysql_config = mysql/bin/mysql_config
+
+# The Windows registry key for MySQL.
+# This has to be set for Windows builds to work.
+# Only change this if you have a different version.
+registry_key = SOFTWARE\MySQL AB\MySQL Server 5.0
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/patches/PasteScript/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/scramble/patches/PasteScript/setup.py Mon Mar 01 15:41:30 2010 -0500
@@ -0,0 +1,145 @@
+import ez_setup
+ez_setup.use_setuptools()
+from setuptools import setup, find_packages
+import re, os
+
+version = '1.7.3'
+
+news = os.path.join(os.path.dirname(__file__), 'docs', 'news.txt')
+news = open(news).read()
+parts = re.split(r'([0-9\.]+)\s*\n\r?-+\n\r?', news)
+found_news = ''
+for i in range(len(parts)-1):
+ if parts[i] == version:
+ found_news = parts[i+i]
+ break
+if not found_news:
+ print 'Warning: no news for this version found'
+
+long_description="""\
+This is a pluggable command-line tool.
+
+It includes some built-in features;
+
+* Create file layouts for packages. For instance, ``paste create
+ --template=basic_package MyPackage`` will create a `setuptools
+ <http://peak.telecommunity.com/DevCenter/setuptools>`_-ready
+ file layout.
+
+* Serving up web applications, with configuration based on
+ `paste.deploy <http://pythonpaste.org/deploy/paste-deploy.html>`_.
+
+The latest version is available in a `Subversion repository
+<http://svn.pythonpaste.org/Paste/Script/trunk#egg=PasteScript-dev>`_.
+
+For the latest changes see the `news file
+<http://pythonpaste.org/script/news.html>`_.
+"""
+
+if found_news:
+ title = 'Changes in %s' % version
+ long_description += "\n%s\n%s\n" % (title, '-'*len(title))
+ long_description += found_news
+
+setup(
+ name="PasteScript",
+ version=version,
+ description="A pluggable command-line frontend, including commands to setup package file layouts",
+ long_description=long_description,
+ classifiers=[
+ "Development Status :: 5 - Production/Stable",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Programming Language :: Python",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Framework :: Paste",
+ ],
+ keywords='web wsgi setuptools framework command-line setup',
+ author="Ian Bicking",
+ author_email="ianb(a)colorstudy.com",
+ url="http://pythonpaste.org/script/",
+ namespace_packages=['paste'],
+ license='MIT',
+ packages=find_packages(exclude='tests'),
+ package_data={
+ 'paste.script': ['paster-templates/basic_package/setup.*',
+ 'paster-templates/basic_package/tests/*.py',
+ # @@: docs/ doesn't have any files :(
+ 'paster-templates/basic_package/+package+/*.py'],
+ },
+ zip_safe=False,
+ scripts=['scripts/paster'],
+ extras_require={
+ 'Templating': [],
+ 'Cheetah': ['Cheetah'],
+ 'Config': ['PasteDeploy'],
+ 'WSGIUtils': ['WSGIUtils'],
+ 'Flup': ['Flup'],
+ # the Paste feature means the complete set of features;
+ # (other features are truly optional)
+ 'Paste': ['PasteDeploy', 'Cheetah'],
+ },
+ entry_points="""
+ [paste.global_paster_command]
+ help=paste.script.help:HelpCommand
+ create=paste.script.create_distro:CreateDistroCommand [Templating]
+ serve=paste.script.serve:ServeCommand [Config]
+ request=paste.script.request:RequestCommand [Config]
+ post=paste.script.request:RequestCommand [Config]
+ exe=paste.script.exe:ExeCommand
+ points=paste.script.entrypoints:EntryPointCommand
+ make-config=paste.script.appinstall:MakeConfigCommand
+ setup-app=paste.script.appinstall:SetupCommand
+
+ [paste.paster_command]
+ grep = paste.script.grep:GrepCommand
+
+ [paste.paster_create_template]
+ basic_package=paste.script.templates:BasicPackage
+
+ [paste.server_runner]
+ wsgiutils=paste.script.wsgiutils_server:run_server [WSGIUtils]
+ flup_ajp_thread=paste.script.flup_server:run_ajp_thread [Flup]
+ flup_ajp_fork=paste.script.flup_server:run_ajp_fork [Flup]
+ flup_fcgi_thread=paste.script.flup_server:run_fcgi_thread [Flup]
+ flup_fcgi_fork=paste.script.flup_server:run_fcgi_fork [Flup]
+ flup_scgi_thread=paste.script.flup_server:run_scgi_thread [Flup]
+ flup_scgi_fork=paste.script.flup_server:run_scgi_fork [Flup]
+ cgi=paste.script.cgi_server:paste_run_cgi
+ cherrypy=paste.script.cherrypy_server:cpwsgi_server
+ twisted=paste.script.twisted_web2_server:run_twisted
+
+ [paste.app_factory]
+ test=paste.script.testapp:make_test_application
+
+ [paste.entry_point_description]
+ paste.entry_point_description = paste.script.epdesc:MetaEntryPointDescription
+ paste.paster_create_template = paste.script.epdesc:CreateTemplateDescription
+ paste.paster_command = paste.script.epdesc:PasterCommandDescription
+ paste.global_paster_command = paste.script.epdesc:GlobalPasterCommandDescription
+ paste.app_install = paste.script.epdesc:AppInstallDescription
+
+ # These aren't part of Paste Script particularly, but
+ # we'll document them here
+ console_scripts = paste.script.epdesc:ConsoleScriptsDescription
+ # @@: Need non-console scripts...
+ distutils.commands = paste.script.epdesc:DistutilsCommandsDescription
+ distutils.setup_keywords = paste.script.epdesc:SetupKeywordsDescription
+ egg_info.writers = paste.script.epdesc:EggInfoWriters
+ # @@: Not sure what this does:
+ #setuptools.file_finders = paste.script.epdesc:SetuptoolsFileFinders
+
+ [console_scripts]
+ paster=paste.script.command:run
+
+ [distutils.setup_keywords]
+ paster_plugins = setuptools.dist:assert_string_list
+
+ [egg_info.writers]
+ paster_plugins.txt = setuptools.command.egg_info:write_arg
+ """,
+ install_requires=[
+ ],
+ )
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/patches/psycopg2/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/scramble/patches/psycopg2/setup.py Mon Mar 01 15:41:30 2010 -0500
@@ -0,0 +1,252 @@
+# setup.py - distutils packaging
+#
+# Copyright (C) 2003-2004 Federico Di Gregorio <fog(a)debian.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+
+"""Python-PostgreSQL Database Adapter
+
+psycopg is a PostgreSQL database adapter for the Python programming
+language. This is version 2, a complete rewrite of the original code to
+provide new-style classes for connection and cursor objects and other sweet
+candies. Like the original, psycopg 2 was written with the aim of being
+very small and fast, and stable as a rock.
+
+psycopg is different from the other database adapter because it was
+designed for heavily multi-threaded applications that create and destroy
+lots of cursors and make a conspicuous number of concurrent INSERTs or
+UPDATEs. psycopg 2 also provide full asycronous operations for the really
+brave programmer.
+"""
+
+classifiers = """\
+Development Status :: 4 - Beta
+Intended Audience :: Developers
+License :: OSI Approved :: GNU General Public License (GPL)
+License :: OSI Approved :: Zope Public License
+Programming Language :: Python
+Programming Language :: C
+Programming Language :: SQL
+Topic :: Database
+Topic :: Database :: Front-Ends
+Topic :: Software Development
+Topic :: Software Development :: Libraries :: Python Modules
+Operating System :: Microsoft :: Windows
+Operating System :: Unix
+"""
+
+import os
+import os.path
+import sys
+import popen2
+import ConfigParser
+from glob import glob
+from distutils.core import setup, Extension
+from distutils.errors import DistutilsFileError
+from distutils.command.build_ext import build_ext
+from distutils.sysconfig import get_python_inc
+from distutils.ccompiler import get_default_compiler
+
+assert sys.version_info[:2] >= ( 2, 4 )
+
+PSYCOPG_VERSION = '2.0.6'
+version_flags = []
+
+PG_VERSION = '8.2.6'
+
+class psycopg_build_ext(build_ext):
+ """Conditionally complement the setup.cfg options file.
+
+ This class configures the include_dirs, libray_dirs, libraries
+ options as required by the system. Most of the configuration happens
+ in finalize_options() method.
+
+ If you want to set up the build step for a peculiar platform, add a
+ method finalize_PLAT(), where PLAT matches your sys.platform.
+ """
+ user_options = build_ext.user_options[:]
+ user_options.extend([
+ ('use-pydatetime', None,
+ "Use Python datatime objects for date and time representation."),
+ ('use-decimal', None,
+ "Use Decimal type even on Python 2.3 if the module is provided."),
+ ])
+
+ boolean_options = build_ext.boolean_options[:]
+ boolean_options.extend(('use-pydatetime', 'use-decimal', 'have-ssl'))
+
+ def initialize_options(self):
+ build_ext.initialize_options(self)
+ self.use_pg_dll = 1
+ self.pgdir = None
+ self.mx_include_dir = None
+
+ def get_compiler(self):
+ """Return the name of the C compiler used to compile extensions.
+
+ If a compiler was not explicitely set (on the command line, for
+ example), fall back on the default compiler.
+ """
+ if self.compiler:
+ # distutils doesn't keep the type of self.compiler uniform; we
+ # compensate:
+ if isinstance(self.compiler, str):
+ name = self.compiler
+ else:
+ name = self.compiler.compiler_type
+ else:
+ name = get_default_compiler()
+ return name
+
+ def finalize_darwin(self):
+ """Finalize build system configuration on darwin platform."""
+ self.libraries.append('ssl')
+ self.libraries.append('crypto')
+
+ def finalize_options(self):
+ """Complete the build system configuation."""
+ build_ext.finalize_options(self)
+
+ self.include_dirs.append(".")
+ self.include_dirs.append("postgresql-8.2.6/src/interfaces/libpq")
+ self.include_dirs.append("postgresql-8.2.6/src/include")
+ self.include_dirs.append("postgresql-8.2.6/src/port")
+ pgmajor, pgminor, pgpatch = PG_VERSION.split('.')
+ define_macros.append(("PG_MAJOR_VERSION", pgmajor))
+ define_macros.append(("PG_MINOR_VERSION", pgminor))
+ define_macros.append(("PG_PATCH_VERSION", pgpatch))
+
+ if hasattr(self, "finalize_" + sys.platform):
+ getattr(self, "finalize_" + sys.platform)()
+
+# let's start with macro definitions (the ones not already in setup.cfg)
+define_macros = []
+include_dirs = []
+
+# python version
+define_macros.append(('PY_MAJOR_VERSION', str(sys.version_info[0])))
+define_macros.append(('PY_MINOR_VERSION', str(sys.version_info[1])))
+
+# some macros related to python versions and features
+if sys.version_info[0] >= 2 and sys.version_info[1] >= 3:
+ define_macros.append(('HAVE_PYBOOL','1'))
+
+# gather information to build the extension module
+ext = [] ; data_files = []
+
+# sources
+
+sources = [
+ 'psycopgmodule.c', 'pqpath.c', 'typecast.c',
+ 'microprotocols.c', 'microprotocols_proto.c',
+ 'connection_type.c', 'connection_int.c', 'cursor_type.c', 'cursor_int.c',
+ 'adapter_qstring.c', 'adapter_pboolean.c', 'adapter_binary.c',
+ 'adapter_asis.c', 'adapter_list.c']
+
+parser = ConfigParser.ConfigParser()
+parser.read('setup.cfg')
+
+# Choose if to use Decimal type
+use_decimal = int(parser.get('build_ext', 'use_decimal'))
+if sys.version_info[0] >= 2 and (
+ sys.version_info[1] >= 4 or (sys.version_info[1] == 3 and use_decimal)):
+ define_macros.append(('HAVE_DECIMAL','1'))
+ version_flags.append('dec')
+
+# Choose a datetime module
+have_pydatetime = False
+have_mxdatetime = False
+use_pydatetime = int(parser.get('build_ext', 'use_pydatetime'))
+
+# check for mx package
+if parser.has_option('build_ext', 'mx_include_dir'):
+ mxincludedir = parser.get('build_ext', 'mx_include_dir')
+else:
+ mxincludedir = os.path.join(get_python_inc(plat_specific=1), "mx")
+if os.path.exists(mxincludedir):
+ include_dirs.append(mxincludedir)
+ define_macros.append(('HAVE_MXDATETIME','1'))
+ sources.append('adapter_mxdatetime.c')
+ have_mxdatetime = True
+ version_flags.append('mx')
+
+# check for python datetime package
+if os.path.exists(os.path.join(get_python_inc(plat_specific=1),"datetime.h")):
+ define_macros.append(('HAVE_PYDATETIME','1'))
+ sources.append('adapter_datetime.c')
+ have_pydatetime = True
+ version_flags.append('dt')
+
+# now decide which package will be the default for date/time typecasts
+if have_pydatetime and use_pydatetime \
+ or have_pydatetime and not have_mxdatetime:
+ define_macros.append(('PSYCOPG_DEFAULT_PYDATETIME','1'))
+elif have_mxdatetime:
+ define_macros.append(('PSYCOPG_DEFAULT_MXDATETIME','1'))
+else:
+ def e(msg):
+ sys.stderr.write("error: " + msg + "\n")
+ e("psycopg requires a datetime module:")
+ e(" mx.DateTime module not found")
+ e(" python datetime module not found")
+ e("Note that psycopg needs the module headers and not just the module")
+ e("itself. If you installed Python or mx.DateTime from a binary package")
+ e("you probably need to install its companion -dev or -devel package.")
+ sys.exit(1)
+
+# generate a nice version string to avoid confusion when users report bugs
+for have in parser.get('build_ext', 'define').split(','):
+ if have == 'PSYCOPG_EXTENSIONS':
+ version_flags.append('ext')
+ elif have == 'HAVE_PQPROTOCOL3':
+ version_flags.append('pq3')
+if version_flags:
+ PSYCOPG_VERSION_EX = PSYCOPG_VERSION + " (%s)" % ' '.join(version_flags)
+else:
+ PSYCOPG_VERSION_EX = PSYCOPG_VERSION
+
+define_macros.append(('PSYCOPG_VERSION', '"'+PSYCOPG_VERSION_EX+'"'))
+
+if parser.has_option('build_ext', 'have_ssl'):
+ have_ssl = int(parser.get('build_ext', 'have_ssl'))
+else:
+ have_ssl = 0
+
+# build the extension
+
+sources = map(lambda x: os.path.join('psycopg', x), sources)
+sources.append( 'postgresql-%s/src/port/pgstrcasecmp.c' % PG_VERSION )
+sources.append( 'postgresql-%s/src/backend/libpq/md5.c' % PG_VERSION )
+sources.extend( glob('postgresql-%s/src/interfaces/libpq/*.c' % PG_VERSION) )
+
+ext.append(Extension("psycopg2._psycopg", sources,
+ define_macros=define_macros,
+ include_dirs=include_dirs,
+ undef_macros=[]))
+setup(name="psycopg2",
+ version=PSYCOPG_VERSION,
+ maintainer="Federico Di Gregorio",
+ maintainer_email="fog(a)initd.org",
+ author="Federico Di Gregorio",
+ author_email="fog(a)initd.org",
+ url="http://initd.org/tracker/psycopg",
+ download_url = "http://initd.org/pub/software/psycopg2",
+ license="GPL with exceptions or ZPL",
+ platforms = ["any"],
+ description=__doc__.split("\n")[0],
+ long_description="\n".join(__doc__.split("\n")[2:]),
+ classifiers=filter(None, classifiers.split("\n")),
+ data_files=data_files,
+ package_dir={'psycopg2':'lib'},
+ packages=['psycopg2'],
+ cmdclass={ 'build_ext': psycopg_build_ext },
+ ext_modules=ext)
+
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/scripts/Cheetah.py
--- a/scripts/scramble/scripts/Cheetah.py Mon Mar 01 13:30:37 2010 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-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 )
-import get_platform # fixes fat python 2.5
-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_it.py: removing dir:", dir
- shutil.rmtree( dir )
-
-# patch
-file = "SetupConfig.py"
-if not os.access( "%s.orig" %file, os.F_OK ):
- print "scramble.py(): Patching", file
- shutil.copyfile( file, "%s.orig" %file )
- i = open( "%s.orig" %file, "r" )
- o = open( file, "w" )
- comment = False
- for line in i.readlines():
- if line == " install_requires = [\n":
- comment = True
- print >>o, "#" + line,
- elif comment and line == " ]\n":
- comment = False
- print >>o, "#" + line,
- elif comment:
- print >>o, "#" + line,
- else:
- print >>o, line,
- i.close()
- o.close()
-
-# 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" )
-
-# do it
-execfile( "setup.py", globals(), locals() )
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/scripts/DRMAA_python-macosx.py
--- a/scripts/scramble/scripts/DRMAA_python-macosx.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/scramble/scripts/DRMAA_python-macosx.py Mon Mar 01 15:41:30 2010 -0500
@@ -1,8 +1,8 @@
import os, sys, shutil
if "SGE_ROOT" not in os.environ:
- print "scramble(): Please set SGE_ROOT to the path of your SGE installation"
- print "scramble(): before scrambling DRMAA_python"
+ print "main(): Please set SGE_ROOT to the path of your SGE installation"
+ print "main(): before scrambling DRMAA_python"
sys.exit(1)
# change back to the build dir
@@ -10,27 +10,15 @@
os.chdir( os.path.dirname( sys.argv[0] ) )
# find setuptools
-scramble_lib = os.path.join( "..", "..", "..", "lib" )
-sys.path.append( scramble_lib )
-import get_platform # fixes fat python 2.5
-try:
- from setuptools import *
- import pkg_resources
-except:
- from ez_setup import use_setuptools
- use_setuptools( download_delay=8, to_dir=scramble_lib )
- from setuptools import *
- import pkg_resources
+sys.path.append( os.path.join( '..', '..', '..', 'lib' ) )
+from scramble_lib import *
-# clean, in case you're running this by hand from a dirty module source dir
-for dir in [ "build", "dist", "gridengine" ]:
- if os.access( dir, os.F_OK ):
- print "scramble_it.py: removing dir:", dir
- shutil.rmtree( dir )
+tag = get_tag() # get the tag
+clean() # clean up any existing stuff (could happen if you run scramble.py by hand)
# patch
file = "setup.py"
-print "scramble(): Patching", file
+print "main(): Patching", file
if not os.access( "%s.orig" %file, os.F_OK ):
shutil.copyfile( file, "%s.orig" %file )
i = open( "%s.orig" %file, "r" )
@@ -44,7 +32,7 @@
i.close()
o.close()
-# go
+# build
me = sys.argv[0]
sys.argv = [ me ]
sys.argv.append( "build" )
@@ -55,6 +43,7 @@
libdrmaa = os.path.join(SGE6_ROOT, "lib", SGE6_ARCH, "libdrmaa.dylib.1.0" )
os.system( "install_name_tool -change libdrmaa.dylib.1.0 %s %s" % ( libdrmaa, so ) )
+# package
sys.argv = [ me ]
sys.argv.append( "bdist_egg" )
execfile( "setup.py", globals(), locals() )
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/scripts/DRMAA_python-solaris.py
--- a/scripts/scramble/scripts/DRMAA_python-solaris.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/scramble/scripts/DRMAA_python-solaris.py Mon Mar 01 15:41:30 2010 -0500
@@ -1,8 +1,8 @@
import os, sys, shutil
if "SGE_ROOT" not in os.environ:
- print "scramble(): Please set SGE_ROOT to the path of your SGE installation"
- print "scramble(): before scrambling DRMAA_python"
+ print "main(): Please set SGE_ROOT to the path of your SGE installation"
+ print "main(): before scrambling DRMAA_python"
sys.exit(1)
# change back to the build dir
@@ -10,22 +10,11 @@
os.chdir( os.path.dirname( sys.argv[0] ) )
# find setuptools
-scramble_lib = os.path.join( "..", "..", "..", "lib" )
-sys.path.append( scramble_lib )
-try:
- from setuptools import *
- import pkg_resources
-except:
- from ez_setup import use_setuptools
- use_setuptools( download_delay=8, to_dir=scramble_lib )
- from setuptools import *
- import pkg_resources
+sys.path.append( os.path.join( '..', '..', '..', 'lib' ) )
+from scramble_lib import *
-# clean, in case you're running this by hand from a dirty module source dir
-for dir in [ "build", "dist", "gridengine" ]:
- if os.access( dir, os.F_OK ):
- print "scramble_it.py: removing dir:", dir
- shutil.rmtree( dir )
+tag = get_tag() # get the tag
+clean() # clean up any existing stuff (could happen if you run scramble.py by hand)
# if our python is 64 bit, use 64 bit sge...
if sys.maxint < ( 2048 * 1024 * 1024 ):
@@ -38,24 +27,13 @@
arch = "sparc64"
else:
arch = "amd64"
- if not "CFLAGS" in os.environ:
- os.environ["CFLAGS"] = ""
- os.environ["CFLAGS"] += " -m64"
# if we're using sun cc, drop the gcc -Wno-unused option
-import distutils.sysconfig
-cc = distutils.sysconfig.get_config_var('CC')
-if os.popen( cc + ' --version 2>&1' ).read().strip().split('\n')[0].startswith('gcc'):
- compiler = 'gcc'
-elif os.popen( cc + ' -V 2>&1' ).read().strip().split('\n')[0].startswith('cc: Sun C'):
- compiler = 'sun'
-else:
- print "scramble(): Unable to determine compiler"
- sys.exit(1)
+cc = get_solaris_compiler()
# patch
file = "setup.py"
-print "scramble(): Patching", file
+print "main(): Patching", file
if not os.access( "%s.orig" %file, os.F_OK ):
shutil.copyfile( file, "%s.orig" %file )
i = open( "%s.orig" %file, "r" )
@@ -68,14 +46,16 @@
elif line.startswith('link_args ='):
line = 'link_args = [ "-L%s" % os.path.join(SGE6_ROOT, "lib", SGE6_ARCH), "-Wl,-R%s" % os.path.join(SGE6_ROOT, "lib", SGE6_ARCH), "-ldrmaa" ]\n'
if line == " + [ '-Wno-unused' ]\n":
- if compiler == 'sun':
+ if cc == 'cc':
line = " #+ [ '-Wno-unused' ]\n"
print >>o, line,
i.close()
o.close()
-# go
+# reset args for distutils
me = sys.argv[0]
sys.argv = [ me ]
sys.argv.append( "bdist_egg" )
+
+# do it
execfile( "setup.py", globals(), locals() )
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/scripts/DRMAA_python.py
--- a/scripts/scramble/scripts/DRMAA_python.py Mon Mar 01 13:30:37 2010 -0500
+++ b/scripts/scramble/scripts/DRMAA_python.py Mon Mar 01 15:41:30 2010 -0500
@@ -1,8 +1,8 @@
import os, sys, shutil
if "SGE_ROOT" not in os.environ:
- print "scramble(): Please set SGE_ROOT to the path of your SGE installation"
- print "scramble(): before scrambling DRMAA_python"
+ print "main(): Please set SGE_ROOT to the path of your SGE installation"
+ print "main(): before scrambling DRMAA_python"
sys.exit(1)
# change back to the build dir
@@ -10,27 +10,15 @@
os.chdir( os.path.dirname( sys.argv[0] ) )
# find setuptools
-scramble_lib = os.path.join( "..", "..", "..", "lib" )
-sys.path.append( scramble_lib )
-import get_platform # fixes fat python 2.5
-try:
- from setuptools import *
- import pkg_resources
-except:
- from ez_setup import use_setuptools
- use_setuptools( download_delay=8, to_dir=scramble_lib )
- from setuptools import *
- import pkg_resources
+sys.path.append( os.path.join( '..', '..', '..', 'lib' ) )
+from scramble_lib import *
-# clean, in case you're running this by hand from a dirty module source dir
-for dir in [ "build", "dist", "gridengine" ]:
- if os.access( dir, os.F_OK ):
- print "scramble_it.py: removing dir:", dir
- shutil.rmtree( dir )
+tag = get_tag() # get the tag
+clean() # clean up any existing stuff (could happen if you run scramble.py by hand)
# patch
file = "setup.py"
-print "scramble(): Patching", file
+print "main(): Patching", file
if not os.access( "%s.orig" %file, os.F_OK ):
shutil.copyfile( file, "%s.orig" %file )
i = open( "%s.orig" %file, "r" )
@@ -44,8 +32,10 @@
i.close()
o.close()
-# go
+# reset args for distutils
me = sys.argv[0]
sys.argv = [ me ]
sys.argv.append( "bdist_egg" )
+
+# do it
execfile( "setup.py", globals(), locals() )
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/scripts/GeneTrack.py
--- a/scripts/scramble/scripts/GeneTrack.py Mon Mar 01 13:30:37 2010 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-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" )
-
-if not os.access( 'setup.py', os.F_OK ):
- print "scramble.py: Creating setup.py for GeneTrack"
- setup_py = """from os import walk
-from os.path import join
-from setuptools import setup, find_packages
-def walk_files( top ):
- for dir, dirs, files in walk( top ):
- yield( dir, [ join( dir, f ) for f in files ] )
-setup(
- name = "GeneTrack",
- version = "2.0.0-beta-1",
- packages = ['genetrack','genetrack.scripts'],
- data_files = [ f for f in walk_files('tests') ],
- zip_safe = False
-)
-"""
- open( 'setup.py', 'w' ).write( setup_py )
-
-
-# do it
-execfile( "setup.py", globals(), locals() )
diff -r a6c9862ece3d -r 0cb68935eede scripts/scramble/scripts/MySQL_python-solaris.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/scramble/scripts/MySQL_python-solaris.py Mon Mar 01 15:41:30 2010 -0500
@@ -0,0 +1,81 @@
+import os, sys, shutil
+from distutils.sysconfig import get_config_var
+
+def prep_mysql( prepped, args ):
+
+ my_version = args['version']
+ my_srcdir = os.path.join( os.getcwd(), "mysql-%s" % my_version )
+
+ # set up environment
+ os.environ['CC'] = get_config_var('CC')
+ os.environ['CFLAGS'] = get_config_var('CFLAGS')
+ os.environ['LDFLAGS'] = get_config_var('LDFLAGS')
+
+ cc = get_solaris_compiler()
+ if cc == 'cc':
+ os.environ['CFLAGS'] += ' -KPIC'
+ elif cc == 'gcc':
+ os.environ['CFLAGS'] += ' -fPIC -DPIC'
+
+ # run configure
+ run( "./configure --prefix=%s/mysql --disable-dependency-tracking --enable-static --disable-shared --without-server --without-uca " %os.getcwd() + \
+ "--without-libwrap --without-ssl --without-docs --without-man --enable-thread-safe-client --with-named-curses-libs=''",
+ my_srcdir, "Configuring mysql (./configure)" )
+
+ # compile
+ run( "make", os.path.join( my_srcdir, 'include' ), "Preparing mysql includes (cd include; make)" )
+ run( "make link_sources", os.path.join( my_srcdir, 'libmysql' ), "Preparing libmysql (cd libmysql; make link_sources)" )
+ run( "make link_sources", os.path.join( my_srcdir, 'libmysql_r' ), "Preparing libmysql_r (cd libmysql_r; make link_sources)" )
+ run( "make", os.path.join( my_srcdir, 'libmysql_r' ), "Compiling libmysql_r (cd libmysql_r; make)" )
+ run( "make", os.path.join( my_srcdir, 'scripts' ), "Preparing scripts (cd scripts; make)" )
+
+ # install
+ run( "make install", os.path.join( my_srcdir, 'include' ), "Installing mysql includes (cd include; make install)" )
+ run( "make install", os.path.join( my_srcdir, 'libmysql_r' ), "Installing libmysql_r (cd libmysql_r; make install)" )
+ run( "make install", os.path.join( my_srcdir, 'scripts' ), "Installing mysql scripts (cd scripts; make install)" )
+ shutil.copy( os.path.join( my_srcdir, 'include', 'mysqld_error.h' ), os.path.join( 'mysql', 'include', 'mysql' ) )
+
+ # create prepped archive
+ print "%s(): Creating prepped archive for future builds at:" % sys._getframe().f_code.co_name
+ print " ", prepped
+ compress( prepped,
+ 'mysql/bin/mysql_config',
+ 'mysql/include',
+ 'mysql/lib' )
+
+if __name__ == '__main__':
+
+ # change back to the build dir
+ if os.path.dirname( sys.argv[0] ) != "":
+ os.chdir( os.path.dirname( sys.argv[0] ) )
+
+ # find setuptools
+ sys.path.append( os.path.abspath( os.path.join( '..', '..', '..', 'lib' ) ) )
+ from scramble_lib import *
+
+ tag = get_tag()
+
+ my_version = ( tag.split( '_' ) )[1]
+ my_archive_base = os.path.join( archives, 'mysql-%s' % my_version )
+ my_archive = get_archive( my_archive_base )
+ my_archive_prepped = os.path.join( archives, 'mysql-%s-%s.tar.gz' % ( my_version, platform_noucs ) )
+
+ # clean up any existing stuff (could happen if you run scramble.py by hand)
+ clean( [ 'mysql-%s' % my_version, 'mysql' ] )
+
+ # unpack mysql
+ unpack_dep( my_archive, my_archive_prepped, prep_mysql, dict( version=my_version ) )
+
+ # get site.cfg
+ shutil.copy( os.path.join( patches, 'MySQL_python', 'site.cfg' ), 'site.cfg' )
+
+ # tag
+ me = sys.argv[0]
+ sys.argv = [ me ]
+ if tag is not None:
+ sys.argv.append( "egg_info" )
+ sys.argv.append( "--tag-build=%s" %tag )
+ sys.argv.append( "bdist_egg" )
+
+ # go
+ execfile( "setup.py", globals(), locals() )
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/a6c9862ece3d
changeset: 3451:a6c9862ece3d
user: James Taylor <james(a)jamestaylor.org>
date: Mon Mar 01 13:30:37 2010 -0500
description:
UI tweaks
diffstat:
templates/display_base.mako | 9 ++++-----
templates/page/display.mako | 2 +-
templates/user/info.mako | 15 ++++++++++++---
3 files changed, 17 insertions(+), 9 deletions(-)
diffs (80 lines):
diff -r 71a525ae9426 -r a6c9862ece3d templates/display_base.mako
--- a/templates/display_base.mako Mon Mar 01 12:46:54 2010 -0500
+++ b/templates/display_base.mako Mon Mar 01 13:30:37 2010 -0500
@@ -190,14 +190,13 @@
<div class="unified-panel-body">
<div style="overflow: auto; height: 100%;">
<div style="padding: 10px;">
+
+ <div style="float: right;"><img src="http://www.gravatar.com/avatar/${h.md5(item.user.email)}?d=identicon"></div>
+
<h4>Author</h4>
<p>${item.user.username | h}</p>
-
- <div><img src="http://www.gravatar.com/avatar/${h.md5(item.user.email)}?d=identicon&s=150"></div>
-
-
-
+
## Page meta.
<h4>Related ${item_plural}</h4>
<p>
diff -r 71a525ae9426 -r a6c9862ece3d templates/page/display.mako
--- a/templates/page/display.mako Mon Mar 01 12:46:54 2010 -0500
+++ b/templates/page/display.mako Mon Mar 01 13:30:37 2010 -0500
@@ -20,7 +20,7 @@
if ( $.browser.mozilla ) {
$(this).find( "pre.peek" ).css( "overflow", "hidden" );
}
- $(this).slideUp( "fast" );
+ $(this).hide();
});
});
diff -r 71a525ae9426 -r a6c9862ece3d templates/user/info.mako
--- a/templates/user/info.mako Mon Mar 01 12:46:54 2010 -0500
+++ b/templates/user/info.mako Mon Mar 01 13:30:37 2010 -0500
@@ -56,6 +56,9 @@
<input type="submit" name="login_info_button" value="Save">
</div>
</form>
+</div>
+<p></p>
+<div class="toolForm">
<form name="change_password" id="change_password" action="${h.url_for( controller='user', action='edit_info', user_id=user.id, admin_view=admin_view )}" method="post" >
<div class="toolFormTitle">Change Password</div>
%if not admin_view:
@@ -76,7 +79,10 @@
<input type="submit" name="change_password_button" value="Save">
</div>
</form>
- %if user.values or user_info_forms:
+</div>
+%if user.values or user_info_forms:
+<p></p>
+<div class="toolForm">
<form name="user_info" id="user_info" action="${h.url_for( controller='user', action='edit_info', user_id=user.id, admin_view=admin_view )}" method="post" >
<div class="toolFormTitle">User information</div>
%if user_info_select:
@@ -104,7 +110,10 @@
<input type="submit" name="edit_user_info_button" value="Save">
</div>
</form>
- %endif
+</div>
+%endif
+<p></p>
+<div class="toolForm">
<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">
@@ -160,7 +169,7 @@
</div>
</div>
</form>
-
+
1
0

03 Mar '10
details: http://www.bx.psu.edu/hg/galaxy/rev/71a525ae9426
changeset: 3450:71a525ae9426
user: James Taylor <james(a)jamestaylor.org>
date: Mon Mar 01 12:46:54 2010 -0500
description:
Page editor: use Galaxy styles for drop downs in menubar
diffstat:
static/june_2007_style/base.css.tmpl | 12 +++++++--
static/june_2007_style/blue/base.css | 3 +-
templates/page/editor.mako | 44 +++++++++++++----------------------
3 files changed, 27 insertions(+), 32 deletions(-)
diffs (118 lines):
diff -r 405764879961 -r 71a525ae9426 static/june_2007_style/base.css.tmpl
--- a/static/june_2007_style/base.css.tmpl Mon Mar 01 12:14:04 2010 -0500
+++ b/static/june_2007_style/base.css.tmpl Mon Mar 01 12:46:54 2010 -0500
@@ -507,9 +507,15 @@
}
}
-.menubutton.popup {
- padding-right: 1.5em;
- background: url(../images/dropdownarrow.png) no-repeat right 8px;
+.menubutton.action-button {
+ border-color: #aaaaaa;
+}
+
+.menubutton.popup, .action-button.popup {
+ padding-right: 20px;
+ background-image: url(../images/dropdownarrow.png);
+ background-repeat: no-repeat;
+ background-position: right 8px;
}
.menubutton:hover {
diff -r 405764879961 -r 71a525ae9426 static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css Mon Mar 01 12:14:04 2010 -0500
+++ b/static/june_2007_style/blue/base.css Mon Mar 01 12:46:54 2010 -0500
@@ -87,7 +87,8 @@
.action-button:active{color:white;background:#aaaaaa;}
.menubutton{display:inline-block;cursor:pointer;position:relative;user-select:none;-moz-user-select:none;-webkit-user-select:none;border:solid transparent 1px;-moz-border-radius:0.5em;-webkit-border-radius:0.5em;border-radius:0.5em;padding:3px 0.5em;margin:-3px -0.5em;}
.menubutton .label{position:relative;display:block;border-right:none;}
-.menubutton.popup{padding-right:1.5em;background:url(../images/dropdownarrow.png) no-repeat right 8px;}
+.menubutton.action-button{border-color:#aaaaaa;}
+.menubutton.popup,.action-button.popup{padding-right:20px;background-image:url(../images/dropdownarrow.png);background-repeat:no-repeat;background-position:right 8px;}
.menubutton:hover{border-color:#aaaaaa;}
.menubutton.popup.split{padding-right:2em;}
.menubutton.popup.split:hover{background:url(../images/ddarrowsplit.png) no-repeat right -38px;}
diff -r 405764879961 -r 71a525ae9426 templates/page/editor.mako
--- a/templates/page/editor.mako Mon Mar 01 12:14:04 2010 -0500
+++ b/templates/page/editor.mako Mon Mar 01 12:46:54 2010 -0500
@@ -534,7 +534,6 @@
boxHtml: "<table class='wym_box' width='100%' height='100%'>"
+ "<tr><td><div class='wym_area_top'>"
+ WYMeditor.TOOLS
- + WYMeditor.CONTAINERS
+ "</div></td></tr>"
+ "<tr height='100%'><td>"
+ "<div class='wym_area_main' style='height: 100%;'>"
@@ -559,11 +558,6 @@
{'name': 'Unlink', 'title': 'Unlink', 'css': 'wym_tools_unlink'},
{'name': 'InsertImage', 'title': 'Image', 'css': 'wym_tools_image'},
{'name': 'InsertTable', 'title': 'Table', 'css': 'wym_tools_table'},
- {'name': 'Insert Galaxy History Link', 'title' : 'Galaxy_History_Link', 'css' : 'galaxy_tools_insert_history_link'},
- {'name': 'Insert Galaxy Dataset Link', 'title' : 'Galaxy_Dataset_Link', 'css' : 'galaxy_tools_insert_dataset_link'},
- {'name': 'Insert Galaxy Workflow Link', 'title' : 'Galaxy_Workflow_Link', 'css' : 'galaxy_tools_insert_workflow_link'},
- {'name': 'Insert Galaxy Page Link', 'title' : 'Galaxy_Page_Link', 'css' : 'galaxy_tools_insert_page_link'},
- {'name': 'Annonate Galaxy History', 'title' : 'Annotate_Galaxy_History', 'css' : 'galaxy_tools_annotate_history'},
]
});
## Get the editor object
@@ -636,35 +630,29 @@
}
});
- // Initialize 'Insert history link' button.
- $('.galaxy_tools_insert_history_link').children().click( function() {
- editor.dialog(Galaxy.DIALOG_HISTORY_LINK);
- });
- // Initialize 'Insert dataset link' button.
- $('.galaxy_tools_insert_dataset_link').children().click( function() {
- editor.dialog(Galaxy.DIALOG_DATASET_LINK);
- });
- // Initialize 'Insert workflow link' button.
- $('.galaxy_tools_insert_workflow_link').children().click( function() {
- editor.dialog(Galaxy.DIALOG_WORKFLOW_LINK);
- });
- // Initialize 'Insert page link' button.
- $('.galaxy_tools_insert_page_link').children().click( function() {
- editor.dialog(Galaxy.DIALOG_PAGE_LINK);
- });
- // Initialize 'Annotate history' button.
- $('.galaxy_tools_annotate_history').children().click( function() {
- editor.dialog(Galaxy.DIALOG_ANNOTATE_HISTORY);
- });
// Initialize galaxy elements.
//init_galaxy_elts(editor);
//
+ // Containers, Galaxy style
+ //
+ var containers_menu = $("<div class='galaxy-page-editor-button'><a id='insert-galaxy-link' class='action-button popup' href='#'>${_('Paragraph type')}</a></div>");
+ $(".wym_area_top").append( containers_menu );
+
+ // Add menu options.
+ var items = {}
+ $.each( editor._options.containersItems, function( k, v ) {
+ var tagname = v.name;
+ items[ v.title.replace( '_', ' ' ) ] = function() { editor.container( tagname ) }
+ });
+ make_popupmenu( containers_menu, items);
+
+ //
// Create 'Insert Link to Galaxy Object' menu.
//
// Add menu button.
- var insert_link_menu_button = $("<div><a id='insert-galaxy-link' class='panel-header-button popup' href='#'>${_('Insert Link to Galaxy Object')}</a></div>").addClass('galaxy-page-editor-button');
+ var insert_link_menu_button = $("<div><a id='insert-galaxy-link' class='action-button popup' href='#'>${_('Insert Link to Galaxy Object')}</a></div>").addClass('galaxy-page-editor-button');
$(".wym_area_top").append(insert_link_menu_button);
// Add menu options.
@@ -688,7 +676,7 @@
//
// Add menu button.
- var embed_object_button = $("<div><a id='embed-galaxy-object' class='panel-header-button popup' href='#'>${_('Embed Galaxy Object')}</a></div>").addClass('galaxy-page-editor-button');
+ var embed_object_button = $("<div><a id='embed-galaxy-object' class='action-button popup' href='#'>${_('Embed Galaxy Object')}</a></div>").addClass('galaxy-page-editor-button');
$(".wym_area_top").append(embed_object_button);
// Add menu options.
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/405764879961
changeset: 3449:405764879961
user: James Taylor <james(a)jamestaylor.org>
date: Mon Mar 01 12:14:04 2010 -0500
description:
Ran optipng on sprite images
diffstat:
static/june_2007_style/blue/fugue.png | 0
static/june_2007_style/blue/history-buttons.png | 0
static/june_2007_style/blue/history-states.png | 0
3 files changed, 0 insertions(+), 0 deletions(-)
diffs (6 lines):
diff -r d3f94b7aa60f -r 405764879961 static/june_2007_style/blue/fugue.png
Binary file static/june_2007_style/blue/fugue.png has changed
diff -r d3f94b7aa60f -r 405764879961 static/june_2007_style/blue/history-buttons.png
Binary file static/june_2007_style/blue/history-buttons.png has changed
diff -r d3f94b7aa60f -r 405764879961 static/june_2007_style/blue/history-states.png
Binary file static/june_2007_style/blue/history-states.png has changed
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/d3f94b7aa60f
changeset: 3448:d3f94b7aa60f
user: James Taylor <james(a)jamestaylor.org>
date: Mon Mar 01 12:09:38 2010 -0500
description:
fix: menu border opacity
diffstat:
static/june_2007_style/blue/base.css | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diffs (12 lines):
diff -r f5d383525d68 -r d3f94b7aa60f static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css Mon Mar 01 12:01:50 2010 -0500
+++ b/static/june_2007_style/blue/base.css Mon Mar 01 12:09:38 2010 -0500
@@ -91,7 +91,7 @@
.menubutton:hover{border-color:#aaaaaa;}
.menubutton.popup.split{padding-right:2em;}
.menubutton.popup.split:hover{background:url(../images/ddarrowsplit.png) no-repeat right -38px;}
-.overlay-border{position:absolute;top:0;left:0;height:100%;width:100%;padding:1em;margin:-1em;background-color:rgba(0,0,0,0.8);-moz-border-radius:1em;-webkit-border-radius:1em;z-index:-1;}
+.overlay-border{position:absolute;top:0;left:0;height:100%;width:100%;padding:1em;margin:-1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;z-index:-1;}
div.popmenu-wrapper{position:absolute;top:100%;z-index:20000;}
div.popmenu-wrapper ul{display:block;margin:0;padding:0;background:white;color:#333;font-weight:bold;font-style:normal;white-space:nowrap;border:solid #aaaaaa 1px;padding:3px 0;-moz-border-radius:0.5em;-webkit-border-radius:0.5em;border-radius:0.5em;user-select:none;-moz-user-select:none;-webkit-user-select:none;}
div.popmenu-wrapper ul li{display:block;padding:3px 1em;cursor:pointer;border-top:solid transparent 1px;border-bottom:solid transparent 1px;}
1
0

03 Mar '10
details: http://www.bx.psu.edu/hg/galaxy/rev/f5d383525d68
changeset: 3447:f5d383525d68
user: James Taylor <james(a)jamestaylor.org>
date: Mon Mar 01 12:01:50 2010 -0500
description:
1) Jquery 1.4 again, with fixed tooltips; 2) Style changes for history, icons and editable text areas.
diffstat:
lib/galaxy/jobs/__init__.py | 2 +-
static/images/fugue/arrow-circle.png | 0
static/images/fugue/bug.png | 0
static/images/fugue/chevron-expand.png | 0
static/images/fugue/chevron.png | 0
static/images/fugue/cross-button.png | 0
static/images/fugue/cross.png | 0
static/images/fugue/disk.png | 0
static/images/fugue/eye.png | 0
static/images/fugue/pencil-small.png | 0
static/images/fugue/pencil.png | 0
static/june_2007_style/base.css.tmpl | 51 +-
static/june_2007_style/blue/base.css | 19 +-
static/june_2007_style/blue/fugue.png | 0
static/june_2007_style/blue/history.css | 2 +-
static/june_2007_style/history.css.tmpl | 3 +-
static/june_2007_style/make_style.py | 2 +-
static/june_2007_style/process_css.py | 27 +-
static/scripts/jquery.js | 7076 +++++++++++++++++++-----------
static/scripts/jquery.tipsy.js | 25 +-
static/scripts/packed/jquery.js | 17 +-
static/scripts/packed/jquery.tipsy.js | 2 +-
templates/root/history.mako | 92 +-
templates/root/history_common.mako | 191 +-
24 files changed, 4715 insertions(+), 2794 deletions(-)
diffs (truncated from 9068 to 3000 lines):
diff -r 143c920af25c -r f5d383525d68 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py Sun Feb 28 22:19:56 2010 -0500
+++ b/lib/galaxy/jobs/__init__.py Mon Mar 01 12:01:50 2010 -0500
@@ -155,7 +155,7 @@
run and dispatching if so.
"""
# HACK: Delay until after forking, we need a way to do post fork notification!!!
- time.sleep( 10 )
+ time.sleep( 1000 )
while self.running:
try:
self.__monitor_step()
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/arrow-circle.png
Binary file static/images/fugue/arrow-circle.png has changed
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/bug.png
Binary file static/images/fugue/bug.png has changed
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/chevron-expand.png
Binary file static/images/fugue/chevron-expand.png has changed
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/chevron.png
Binary file static/images/fugue/chevron.png has changed
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/cross-button.png
Binary file static/images/fugue/cross-button.png has changed
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/cross.png
Binary file static/images/fugue/cross.png has changed
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/disk.png
Binary file static/images/fugue/disk.png has changed
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/eye.png
Binary file static/images/fugue/eye.png has changed
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/pencil-small.png
Binary file static/images/fugue/pencil-small.png has changed
diff -r 143c920af25c -r f5d383525d68 static/images/fugue/pencil.png
Binary file static/images/fugue/pencil.png has changed
diff -r 143c920af25c -r f5d383525d68 static/june_2007_style/base.css.tmpl
--- a/static/june_2007_style/base.css.tmpl Sun Feb 28 22:19:56 2010 -0500
+++ b/static/june_2007_style/base.css.tmpl Mon Mar 01 12:01:50 2010 -0500
@@ -720,57 +720,70 @@
-sprite-group: history-buttons;
-sprite-image: eye_icon.png;
}
-
.icon-button.display:hover {
-sprite-group: history-buttons;
-sprite-image: eye_icon_dark.png;
}
-
.icon-button.delete {
-sprite-group: history-buttons;
-sprite-image: delete_icon.png;
}
-
.icon-button.delete:hover {
-sprite-group: history-buttons;
-sprite-image: delete_icon_dark.png;
}
-
.icon-button.edit {
-sprite-group: history-buttons;
-sprite-image: pencil_icon.png;
}
-
.icon-button.edit:hover {
-sprite-group: history-buttons;
-sprite-image: pencil_icon_dark.png;
}
.icon-button.tag {
- background-image: url(/static/images/fugue/tag-label.png);
+ -sprite-group: fugue;
+ -sprite-image: fugue/tag-label.png;
}
-
.icon-button.tags {
- background-image: url(/static/images/fugue/tags.png);
+ -sprite-group: fugue;
+ -sprite-image: fugue/tags.png;
}
-
.icon-button.tag--plus {
- background-image: url(/static/images/fugue/tag--plus.png);
+ -sprite-group: fugue;
+ -sprite-image: fugue/tag--plus.png;
}
-
.icon-button.toggle-expand {
- background-image:url(/static/images/fugue/toggle-expand.png);
+ -sprite-group: fugue;
+ -sprite-image: fugue/toggle-expand.png;
}
-
+.icon-button.toggle {
+ -sprite-group: fugue;
+ -sprite-image: fugue/toggle.png;
+}
.icon-button.toggle-contract {
- background-image:url(/static/images/fugue/toggle.png);
+ -sprite-group: fugue;
+ -sprite-image: fugue/toggle.png;
}
-
+.icon-button.arrow-circle {
+ -sprite-group: fugue;
+ -sprite-image: fugue/arrow-circle.png;
+}
+.icon-button.chevron {
+ -sprite-group: fugue;
+ -sprite-image: fugue/chevron.png;
+}
+.icon-button.bug {
+ -sprite-group: fugue;
+ -sprite-image: fugue/bug.png;
+}
+.icon-button.disk {
+ -sprite-group: fugue;
+ -sprite-image: fugue/disk.png;
+}
.icon-button.annotate {
- background-image:url(/static/images/fugue/sticky-note-text.png);
- background-repeat:no-repeat;
- background-position:center;
- padding: 0;
+ -sprite-group: fugue;
+ -sprite-image: fugue/sticky-note-text.png;
}
.tipsy {
diff -r 143c920af25c -r f5d383525d68 static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css Sun Feb 28 22:19:56 2010 -0500
+++ b/static/june_2007_style/blue/base.css Mon Mar 01 12:01:50 2010 -0500
@@ -91,7 +91,7 @@
.menubutton:hover{border-color:#aaaaaa;}
.menubutton.popup.split{padding-right:2em;}
.menubutton.popup.split:hover{background:url(../images/ddarrowsplit.png) no-repeat right -38px;}
-.overlay-border{position:absolute;top:0;left:0;height:100%;width:100%;padding:1em;margin:-1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;z-index:-1;}
+.overlay-border{position:absolute;top:0;left:0;height:100%;width:100%;padding:1em;margin:-1em;background-color:rgba(0,0,0,0.8);-moz-border-radius:1em;-webkit-border-radius:1em;z-index:-1;}
div.popmenu-wrapper{position:absolute;top:100%;z-index:20000;}
div.popmenu-wrapper ul{display:block;margin:0;padding:0;background:white;color:#333;font-weight:bold;font-style:normal;white-space:nowrap;border:solid #aaaaaa 1px;padding:3px 0;-moz-border-radius:0.5em;-webkit-border-radius:0.5em;border-radius:0.5em;user-select:none;-moz-user-select:none;-webkit-user-select:none;}
div.popmenu-wrapper ul li{display:block;padding:3px 1em;cursor:pointer;border-top:solid transparent 1px;border-bottom:solid transparent 1px;}
@@ -124,12 +124,17 @@
.icon-button.delete:hover{background:url(history-buttons.png) no-repeat 0px -78px;}
.icon-button.edit{background:url(history-buttons.png) no-repeat 0px -104px;}
.icon-button.edit:hover{background:url(history-buttons.png) no-repeat 0px -130px;}
-.icon-button.tag{background-image:url(/static/images/fugue/tag-label.png);}
-.icon-button.tags{background-image:url(/static/images/fugue/tags.png);}
-.icon-button.tag--plus{background-image:url(/static/images/fugue/tag--plus.png);}
-.icon-button.toggle-expand{background-image:url(/static/images/fugue/toggle-expand.png);}
-.icon-button.toggle-contract{background-image:url(/static/images/fugue/toggle.png);}
-.icon-button.annotate{background-image:url(/static/images/fugue/sticky-note-text.png);background-repeat:no-repeat;background-position:center;padding:0;}
+.icon-button.tag{background:url(fugue.png) no-repeat 0px -0px;}
+.icon-button.tags{background:url(fugue.png) no-repeat 0px -26px;}
+.icon-button.tag--plus{background:url(fugue.png) no-repeat 0px -52px;}
+.icon-button.toggle-expand{background:url(fugue.png) no-repeat 0px -78px;}
+.icon-button.toggle{background:url(fugue.png) no-repeat 0px -104px;}
+.icon-button.toggle-contract{background:url(fugue.png) no-repeat 0px -104px;}
+.icon-button.arrow-circle{background:url(fugue.png) no-repeat 0px -130px;}
+.icon-button.chevron{background:url(fugue.png) no-repeat 0px -156px;}
+.icon-button.bug{background:url(fugue.png) no-repeat 0px -182px;}
+.icon-button.disk{background:url(fugue.png) no-repeat 0px -208px;}
+.icon-button.annotate{background:url(fugue.png) no-repeat 0px -234px;}
.tipsy{padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);}
.tipsy-inner{padding:5px 8px 4px 8px;background-color:black;color:white;max-width:200px;text-align:center;}
.tipsy-north{background-position:top center;}
diff -r 143c920af25c -r f5d383525d68 static/june_2007_style/blue/fugue.png
Binary file static/june_2007_style/blue/fugue.png has changed
diff -r 143c920af25c -r f5d383525d68 static/june_2007_style/blue/history.css
--- a/static/june_2007_style/blue/history.css Sun Feb 28 22:19:56 2010 -0500
+++ b/static/june_2007_style/blue/history.css Mon Mar 01 12:01:50 2010 -0500
@@ -1,6 +1,6 @@
body{background:#C1C9E5;color:#303030;background-image:url(menu_bg.png);background-repeat:repeat-x;background-position:top;margin:5px;border:0;padding:0;}
a{color:#303030;}
-div.historyLinks{padding:5px;margin:5px 0 5px 0;}
+div.historyLinks{margin:5px 5px;}
div.historyItem{margin:5px -5px 5px 0px;padding:5px 11px 5px 5px;border:solid #888888 1px;border-left:solid #888888 5px;border-right:none;background:#EEEEEE;}
div.historyItem .state-icon{display:inline-block;vertical-align:middle;width:16px;height:16px;background-position:0 1px;background-repeat:no-repeat;}
div.historyItem .historyItemTitle{font-weight:bold;line-height:16px;}
diff -r 143c920af25c -r f5d383525d68 static/june_2007_style/history.css.tmpl
--- a/static/june_2007_style/history.css.tmpl Sun Feb 28 22:19:56 2010 -0500
+++ b/static/june_2007_style/history.css.tmpl Mon Mar 01 12:01:50 2010 -0500
@@ -15,8 +15,7 @@
## Control links at top of history
div.historyLinks {
- padding: 5px;
- margin: 5px 0 5px 0;
+ margin: 5px 5px;
}
## Default history item appearance
diff -r 143c920af25c -r f5d383525d68 static/june_2007_style/make_style.py
--- a/static/june_2007_style/make_style.py Sun Feb 28 22:19:56 2010 -0500
+++ b/static/june_2007_style/make_style.py Mon Mar 01 12:01:50 2010 -0500
@@ -66,7 +66,7 @@
for input, output in templates:
print input ,"->", output
- subprocess.call( "./process_css.py %s %s < %s > %s" % ( vars, out_dir, input, os.path.join( out_dir, output ) ), shell=True )
+ subprocess.call( "./process_css.py %s %s:../images %s < %s > %s" % ( vars, out_dir, out_dir, input, os.path.join( out_dir, output ) ), shell=True )
"""
diff -r 143c920af25c -r f5d383525d68 static/june_2007_style/process_css.py
--- a/static/june_2007_style/process_css.py Sun Feb 28 22:19:56 2010 -0500
+++ b/static/june_2007_style/process_css.py Mon Mar 01 12:01:50 2010 -0500
@@ -35,6 +35,20 @@
digits[i] = wheels[i].next()
else:
break
+
+def find_file( path, fname ):
+ # Path can be a single directory or a ':' separated list
+ if ':' in path:
+ paths = path.split( ':' )
+ else:
+ paths = [ path ]
+ # Check in each directory
+ for path in paths:
+ fullname = os.path.join( path, fname )
+ if os.path.exists( fullname ):
+ return fullname
+ # Not found
+ raise IOError( "File '%s' not found in path '%s'" % ( fname, paths ) )
def build_stylesheet_parser():
"""
@@ -87,7 +101,7 @@
class CSSProcessor( object ):
- def process( self, file, out, variables, image_dir ):
+ def process( self, file, out, variables, image_dir, out_dir ):
# Build parse tree
results = stylesheet_parser.parseFile( sys.stdin, parseAll=True )
# Expand rules (elimimate recursion and resolve mixins)
@@ -95,7 +109,7 @@
# Expand variables (inplace)
self.expand_variables( rules, variables )
# Do sprites
- self.make_sprites( rules, image_dir )
+ self.make_sprites( rules, image_dir, out_dir )
# Print
self.print_rules( rules, out )
@@ -139,7 +153,7 @@
for p in properties:
p[1] = string.Template( p[1] ).substitute( context ).strip()
- def make_sprites( self, rules, image_dir ):
+ def make_sprites( self, rules, image_dir, out_dir ):
pad = 10
@@ -159,7 +173,7 @@
class Sprite( object ):
def __init__( self, fname, offset ):
self.fname = fname
- self.image = Image.open( os.path.join( image_dir, fname ) )
+ self.image = Image.open( find_file( image_dir, fname ) )
self.offset = offset
sprite_groups = {}
@@ -200,7 +214,7 @@
for sprite in group.sprites.itervalues():
master.paste( sprite.image, (0,offset) )
offset += sprite.image.size[1] + pad
- master.save( os.path.join( image_dir, group.name + ".png" ) )
+ master.save( os.path.join( out_dir, group.name + ".png" ) )
def print_rules( self, rules, file ):
for selectors, properties in rules:
@@ -223,11 +237,12 @@
context[key] = value
image_dir = sys.argv[2]
+ out_dir = sys.argv[3]
try:
processor = CSSProcessor()
- processor.process( sys.stdin, sys.stdout, context, image_dir )
+ processor.process( sys.stdin, sys.stdout, context, image_dir, out_dir )
except ParseException, e:
diff -r 143c920af25c -r f5d383525d68 static/scripts/jquery.js
--- a/static/scripts/jquery.js Sun Feb 28 22:19:56 2010 -0500
+++ b/static/scripts/jquery.js Mon Mar 01 12:01:50 2010 -0500
@@ -1,567 +1,310 @@
-/*!
- * jQuery JavaScript Library v1.3.2
+/*
+ * jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
- * Copyright (c) 2009 John Resig
- * Dual licensed under the MIT and GPL licenses.
- * http://docs.jquery.com/License
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
*
- * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
- * Revision: 6246
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
*/
-(function(){
-
-var
- // Will speed up references to window, and allows munging its name.
- window = this,
- // Will speed up references to undefined, and allows munging its name.
- undefined,
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
- // Map over the $ in case of overwrite
- _$ = window.$,
-
- jQuery = window.jQuery = window.$ = function( selector, context ) {
+(function( window, undefined ) {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
},
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // Use the correct document accordingly with window argument (sandbox)
+ document = window.document,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
// A simple way to check for HTML strings or ID strings
// (both of which we optimize for)
- quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
+ quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
+
// Is it a simple selector
- isSimple = /^.[^:#\[\.,]*$/;
+ isSimple = /^.[^:#\[\.,]*$/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // Has the ready events already been bound?
+ readyBound = false,
+
+ // The functions to execute on DOM ready
+ readyList = [],
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwnProperty = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ indexOf = Array.prototype.indexOf;
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {
- // Make sure that a selection was provided
- selector = selector || document;
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
// Handle $(DOMElement)
if ( selector.nodeType ) {
- this[0] = selector;
+ this.context = this[0] = selector;
this.length = 1;
- this.context = selector;
return this;
}
+
+ // The body element only exists once, optimize finding it
+ if ( selector === "body" && !context ) {
+ this.context = document;
+ this[0] = document.body;
+ this.selector = "body";
+ this.length = 1;
+ return this;
+ }
+
// Handle HTML strings
if ( typeof selector === "string" ) {
// Are we dealing with HTML string or an ID?
- var match = quickExpr.exec( selector );
+ match = quickExpr.exec( selector );
// Verify a match, and that no context was specified for #id
if ( match && (match[1] || !context) ) {
// HANDLE: $(html) -> $(array)
- if ( match[1] )
- selector = jQuery.clean( [ match[1] ], context );
-
+ if ( match[1] ) {
+ doc = (context ? context.ownerDocument || context : document);
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+ }
+
+ return jQuery.merge( this, selector );
+
// HANDLE: $("#id")
- else {
- var elem = document.getElementById( match[3] );
-
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem && elem.id != match[3] )
- return jQuery().find( selector );
-
- // Otherwise, we inject the element directly into the jQuery object
- var ret = jQuery( elem || [] );
- ret.context = document;
- ret.selector = selector;
- return ret;
+ } else {
+ elem = document.getElementById( match[2] );
+
+ if ( elem ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
}
- // HANDLE: $(expr, [context])
- // (which is just equivalent to: $(content).find(expr)
- } else
+ // HANDLE: $("TAG")
+ } else if ( !context && /^\w+$/.test( selector ) ) {
+ this.selector = selector;
+ this.context = document;
+ selector = document.getElementsByTagName( selector );
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return (context || rootjQuery).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
return jQuery( context ).find( selector );
+ }
// HANDLE: $(function)
// Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) )
- return jQuery( document ).ready( selector );
-
- // Make sure that old selector state is passed along
- if ( selector.selector && selector.context ) {
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if (selector.selector !== undefined) {
this.selector = selector.selector;
this.context = selector.context;
}
- return this.setArray(jQuery.isArray( selector ) ?
- selector :
- jQuery.makeArray(selector));
+ return jQuery.makeArray( selector, this );
},
// Start with an empty selector
selector: "",
// The current version of jQuery being used
- jquery: "1.3.2",
+ jquery: "1.4.2",
+
+ // The default length of a jQuery object is 0
+ length: 0,
// The number of elements contained in the matched element set
size: function() {
return this.length;
},
+ toArray: function() {
+ return slice.call( this, 0 );
+ },
+
// Get the Nth element in the matched element set OR
// Get the whole matched element set as a clean array
get: function( num ) {
- return num === undefined ?
+ return num == null ?
// Return a 'clean' array
- Array.prototype.slice.call( this ) :
+ this.toArray() :
// Return just the object
- this[ num ];
+ ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
},
// Take an array of elements and push it onto the stack
// (returning the new matched element set)
pushStack: function( elems, name, selector ) {
// Build a new jQuery matched element set
- var ret = jQuery( elems );
+ var ret = jQuery();
+
+ if ( jQuery.isArray( elems ) ) {
+ push.apply( ret, elems );
+
+ } else {
+ jQuery.merge( ret, elems );
+ }
// Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context;
- if ( name === "find" )
+ if ( name === "find" ) {
ret.selector = this.selector + (this.selector ? " " : "") + selector;
- else if ( name )
+ } else if ( name ) {
ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
// Return the newly-formed element set
return ret;
},
- // Force the current matched set of elements to become
- // the specified array of elements (destroying the stack in the process)
- // You should use pushStack() in order to do this, but maintain the stack
- setArray: function( elems ) {
- // Resetting the length to 0, then using the native Array push
- // is a super-fast way to populate an object with array-like properties
- this.length = 0;
- Array.prototype.push.apply( this, elems );
-
- return this;
- },
-
// Execute a callback for every element in the matched set.
// (You can seed the arguments with an array of args, but this is
// only used internally.)
each: function( callback, args ) {
return jQuery.each( this, callback, args );
},
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
- // Locate the position of the desired element
- return jQuery.inArray(
- // If it receives a jQuery object, the first element is used
- elem && elem.jquery ? elem[0] : elem
- , this );
- },
-
- attr: function( name, value, type ) {
- var options = name;
-
- // Look for the case where we're accessing a style value
- if ( typeof name === "string" )
- if ( value === undefined )
- return this[0] && jQuery[ type || "attr" ]( this[0], name );
-
- else {
- options = {};
- options[ name ] = value;
- }
-
- // Check to see if we're setting style values
- return this.each(function(i){
- // Set all the styles
- for ( name in options )
- jQuery.attr(
- type ?
- this.style :
- this,
- name, jQuery.prop( this, options[ name ], type, i, name )
- );
- });
- },
-
- css: function( key, value ) {
- // ignore negative width and height values
- if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
- value = undefined;
- return this.attr( key, value, "curCSS" );
- },
-
- text: function( text ) {
- if ( typeof text !== "object" && text != null )
- return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
-
- var ret = "";
-
- jQuery.each( text || this, function(){
- jQuery.each( this.childNodes, function(){
- if ( this.nodeType != 8 )
- ret += this.nodeType != 1 ?
- this.nodeValue :
- jQuery.fn.text( [ this ] );
- });
- });
-
- return ret;
- },
-
- wrapAll: function( html ) {
- if ( this[0] ) {
- // The elements to wrap the target around
- var wrap = jQuery( html, this[0].ownerDocument ).clone();
-
- if ( this[0].parentNode )
- wrap.insertBefore( this[0] );
-
- wrap.map(function(){
- var elem = this;
-
- while ( elem.firstChild )
- elem = elem.firstChild;
-
- return elem;
- }).append(this);
+
+ ready: function( fn ) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady ) {
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ } else if ( readyList ) {
+ // Add the function to the wait list
+ readyList.push( fn );
}
return this;
},
-
- wrapInner: function( html ) {
- return this.each(function(){
- jQuery( this ).contents().wrapAll( html );
- });
+
+ eq: function( i ) {
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, +i + 1 );
},
- wrap: function( html ) {
- return this.each(function(){
- jQuery( this ).wrapAll( html );
- });
+ first: function() {
+ return this.eq( 0 );
},
- append: function() {
- return this.domManip(arguments, true, function(elem){
- if (this.nodeType == 1)
- this.appendChild( elem );
- });
+ last: function() {
+ return this.eq( -1 );
},
- prepend: function() {
- return this.domManip(arguments, true, function(elem){
- if (this.nodeType == 1)
- this.insertBefore( elem, this.firstChild );
- });
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
},
- before: function() {
- return this.domManip(arguments, false, function(elem){
- this.parentNode.insertBefore( elem, this );
- });
- },
-
- after: function() {
- return this.domManip(arguments, false, function(elem){
- this.parentNode.insertBefore( elem, this.nextSibling );
- });
- },
-
- end: function() {
- return this.prevObject || jQuery( [] );
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: [].push,
- sort: [].sort,
- splice: [].splice,
-
- find: function( selector ) {
- if ( this.length === 1 ) {
- var ret = this.pushStack( [], "find", selector );
- ret.length = 0;
- jQuery.find( selector, this[0], ret );
- return ret;
- } else {
- return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
- return jQuery.find( selector, elem );
- })), "find", selector );
- }
- },
-
- clone: function( events ) {
- // Do the clone
- var ret = this.map(function(){
- if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
- // IE copies events bound via attachEvent when
- // using cloneNode. Calling detachEvent on the
- // clone will also remove the events from the orignal
- // In order to get around this, we use innerHTML.
- // Unfortunately, this means some modifications to
- // attributes in IE that are actually only stored
- // as properties will not be copied (such as the
- // the name attribute on an input).
- var html = this.outerHTML;
- if ( !html ) {
- var div = this.ownerDocument.createElement("div");
- div.appendChild( this.cloneNode(true) );
- html = div.innerHTML;
- }
-
- return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
- } else
- return this.cloneNode(true);
- });
-
- // Copy the events from the original to the clone
- if ( events === true ) {
- var orig = this.find("*").andSelf(), i = 0;
-
- ret.find("*").andSelf().each(function(){
- if ( this.nodeName !== orig[i].nodeName )
- return;
-
- var events = jQuery.data( orig[i], "events" );
-
- for ( var type in events ) {
- for ( var handler in events[ type ] ) {
- jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
- }
- }
-
- i++;
- });
- }
-
- // Return the cloned set
- return ret;
- },
-
- filter: function( selector ) {
- return this.pushStack(
- jQuery.isFunction( selector ) &&
- jQuery.grep(this, function(elem, i){
- return selector.call( elem, i );
- }) ||
-
- jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
- return elem.nodeType === 1;
- }) ), "filter", selector );
- },
-
- closest: function( selector ) {
- var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
- closer = 0;
-
- return this.map(function(){
- var cur = this;
- while ( cur && cur.ownerDocument ) {
- if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
- jQuery.data(cur, "closest", closer);
- return cur;
- }
- cur = cur.parentNode;
- closer++;
- }
- });
- },
-
- not: function( selector ) {
- if ( typeof selector === "string" )
- // test special case where just one selector is passed in
- if ( isSimple.test( selector ) )
- return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
- else
- selector = jQuery.multiFilter( selector, this );
-
- var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
- return this.filter(function() {
- return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
- });
- },
-
- add: function( selector ) {
- return this.pushStack( jQuery.unique( jQuery.merge(
- this.get(),
- typeof selector === "string" ?
- jQuery( selector ) :
- jQuery.makeArray( selector )
- )));
- },
-
- is: function( selector ) {
- return !!selector && jQuery.multiFilter( selector, this ).length > 0;
- },
-
- hasClass: function( selector ) {
- return !!selector && this.is( "." + selector );
- },
-
- val: function( value ) {
- if ( value === undefined ) {
- var elem = this[0];
-
- if ( elem ) {
- if( jQuery.nodeName( elem, 'option' ) )
- return (elem.attributes.value || {}).specified ? elem.value : elem.text;
-
- // We need to handle select boxes special
- if ( jQuery.nodeName( elem, "select" ) ) {
- var index = elem.selectedIndex,
- values = [],
- options = elem.options,
- one = elem.type == "select-one";
-
- // Nothing was selected
- if ( index < 0 )
- return null;
-
- // Loop through all the selected options
- for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
- var option = options[ i ];
-
- if ( option.selected ) {
- // Get the specifc value for the option
- value = jQuery(option).val();
-
- // We don't need an array for one selects
- if ( one )
- return value;
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
- }
-
- // Everything else, we just grab the value
- return (elem.value || "").replace(/\r/g, "");
-
- }
-
- return undefined;
- }
-
- if ( typeof value === "number" )
- value += '';
-
- return this.each(function(){
- if ( this.nodeType != 1 )
- return;
-
- if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
- this.checked = (jQuery.inArray(this.value, value) >= 0 ||
- jQuery.inArray(this.name, value) >= 0);
-
- else if ( jQuery.nodeName( this, "select" ) ) {
- var values = jQuery.makeArray(value);
-
- jQuery( "option", this ).each(function(){
- this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
- jQuery.inArray( this.text, values ) >= 0);
- });
-
- if ( !values.length )
- this.selectedIndex = -1;
-
- } else
- this.value = value;
- });
- },
-
- html: function( value ) {
- return value === undefined ?
- (this[0] ?
- this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
- null) :
- this.empty().append( value );
- },
-
- replaceWith: function( value ) {
- return this.after( value ).remove();
- },
-
- eq: function( i ) {
- return this.slice( i, +i + 1 );
- },
-
- slice: function() {
- return this.pushStack( Array.prototype.slice.apply( this, arguments ),
- "slice", Array.prototype.slice.call(arguments).join(",") );
- },
-
map: function( callback ) {
- return this.pushStack( jQuery.map(this, function(elem, i){
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
return callback.call( elem, i, elem );
}));
},
-
- andSelf: function() {
- return this.add( this.prevObject );
+
+ end: function() {
+ return this.prevObject || jQuery(null);
},
- domManip: function( args, table, callback ) {
- if ( this[0] ) {
- var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
- scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
- first = fragment.firstChild;
-
- if ( first )
- for ( var i = 0, l = this.length; i < l; i++ )
- callback.call( root(this[i], first), this.length > 1 || i > 0 ?
- fragment.cloneNode(true) : fragment );
-
- if ( scripts )
- jQuery.each( scripts, evalScript );
- }
-
- return this;
-
- function root( elem, cur ) {
- return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
- (elem.getElementsByTagName("tbody")[0] ||
- elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
- elem;
- }
- }
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
};
// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
-function evalScript( i, elem ) {
- if ( elem.src )
- jQuery.ajax({
- url: elem.src,
- async: false,
- dataType: "script"
- });
-
- else
- jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
-
- if ( elem.parentNode )
- elem.parentNode.removeChild( elem );
-}
-
-function now(){
- return +new Date;
-}
-
jQuery.extend = jQuery.fn.extend = function() {
// copy reference to target object
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
@@ -572,58 +315,137 @@
}
// Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) )
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
+ }
// extend jQuery itself if only one argument is passed
- if ( length == i ) {
+ if ( length === i ) {
target = this;
--i;
}
- for ( ; i < length; i++ )
+ for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null )
+ if ( (options = arguments[ i ]) != null ) {
// Extend the base object
- for ( var name in options ) {
- var src = target[ name ], copy = options[ name ];
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
// Prevent never-ending loop
- if ( target === copy )
+ if ( target === copy ) {
continue;
-
- // Recurse if we're merging object values
- if ( deep && copy && typeof copy === "object" && !copy.nodeType )
- target[ name ] = jQuery.extend( deep,
- // Never move original objects, clone them
- src || ( copy.length != null ? [ ] : { } )
- , copy );
+ }
+
+ // Recurse if we're merging object literal values or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
+ var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
+ : jQuery.isArray(copy) ? [] : {};
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
// Don't bring in undefined values
- else if ( copy !== undefined )
+ } else if ( copy !== undefined ) {
target[ name ] = copy;
-
- }
+ }
+ }
+ }
+ }
// Return the modified object
return target;
};
-// exclude the following css properties to add px
-var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
- // cache defaultView
- defaultView = document.defaultView || {},
- toString = Object.prototype.toString;
-
jQuery.extend({
noConflict: function( deep ) {
window.$ = _$;
- if ( deep )
+ if ( deep ) {
window.jQuery = _jQuery;
+ }
return jQuery;
},
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 13 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( readyList ) {
+ // Execute all of them
+ var fn, i = 0;
+ while ( (fn = readyList[ i++ ]) ) {
+ fn.call( document, jQuery );
+ }
+
+ // Reset the list of functions
+ readyList = null;
+ }
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.triggerHandler ) {
+ jQuery( document ).triggerHandler( "ready" );
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyBound ) {
+ return;
+ }
+
+ readyBound = true;
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ return jQuery.ready();
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", DOMContentLoaded);
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
// See test/unit/core.js for details concerning isFunction.
// Since version 1.3, DOM methods and functions like alert
@@ -636,27 +458,84 @@
return toString.call(obj) === "[object Array]";
},
- // check if an element is in a (or is an) XML document
- isXMLDoc: function( elem ) {
- return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
- !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor
+ && !hasOwnProperty.call(obj, "constructor")
+ && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwnProperty.call( obj, key );
},
+ isEmptyObject: function( obj ) {
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw msg;
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
+
+ // Try to use the native JSON parser first
+ return window.JSON && window.JSON.parse ?
+ window.JSON.parse( data ) :
+ (new Function("return " + data))();
+
+ } else {
+ jQuery.error( "Invalid JSON: " + data );
+ }
+ },
+
+ noop: function() {},
+
// Evalulates a script in a global context
globalEval: function( data ) {
- if ( data && /\S/.test(data) ) {
+ if ( data && rnotwhite.test(data) ) {
// Inspired by code by Andrea Giammarchi
// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.h…
var head = document.getElementsByTagName("head")[0] || document.documentElement,
script = document.createElement("script");
script.type = "text/javascript";
- if ( jQuery.support.scriptEval )
+
+ if ( jQuery.support.scriptEval ) {
script.appendChild( document.createTextNode( data ) );
- else
+ } else {
script.text = data;
-
- // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709).
head.insertBefore( script, head.firstChild );
head.removeChild( script );
@@ -664,785 +543,2130 @@
},
nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
},
// args is for internal usage only
each: function( object, callback, args ) {
- var name, i = 0, length = object.length;
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction(object);
if ( args ) {
- if ( length === undefined ) {
- for ( name in object )
- if ( callback.apply( object[ name ], args ) === false )
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
break;
- } else
- for ( ; i < length; )
- if ( callback.apply( object[ i++ ], args ) === false )
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
break;
+ }
+ }
+ }
// A special, fast, case for the most common use of each
} else {
- if ( length === undefined ) {
- for ( name in object )
- if ( callback.call( object[ name ], name, object[ name ] ) === false )
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
- } else
+ }
+ }
+ } else {
for ( var value = object[0];
- i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+ }
}
return object;
},
- prop: function( elem, value, type, i, name ) {
- // Handle executable functions
- if ( jQuery.isFunction( value ) )
- value = value.call( elem, i );
-
- // Handle passing in a number to a CSS property
- return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
- value + "px" :
- value;
+ trim: function( text ) {
+ return (text || "").replace( rtrim, "" );
},
- className: {
- // internal only, use addClass("class")
- add: function( elem, classNames ) {
- jQuery.each((classNames || "").split(/\s+/), function(i, className){
- if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
- elem.className += (elem.className ? " " : "") + className;
- });
- },
-
- // internal only, use removeClass("class")
- remove: function( elem, classNames ) {
- if (elem.nodeType == 1)
- elem.className = classNames !== undefined ?
- jQuery.grep(elem.className.split(/\s+/), function(className){
- return !jQuery.className.has( classNames, className );
- }).join(" ") :
- "";
- },
-
- // internal only, use hasClass("class")
- has: function( elem, className ) {
- return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
- }
- },
-
- // A method for quickly swapping in/out CSS properties to get correct calculations
- swap: function( elem, options, callback ) {
- var old = {};
- // Remember the old values, and insert the new ones
- for ( var name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- callback.call( elem );
-
- // Revert the old values
- for ( var name in options )
- elem.style[ name ] = old[ name ];
- },
-
- css: function( elem, name, force, extra ) {
- if ( name == "width" || name == "height" ) {
- var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
-
- function getWH() {
- val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
-
- if ( extra === "border" )
- return;
-
- jQuery.each( which, function() {
- if ( !extra )
- val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
- if ( extra === "margin" )
- val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
- else
- val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
- });
- }
-
- if ( elem.offsetWidth !== 0 )
- getWH();
- else
- jQuery.swap( elem, props, getWH );
-
- return Math.max(0, Math.round(val));
- }
-
- return jQuery.curCSS( elem, name, force );
- },
-
- curCSS: function( elem, name, force ) {
- var ret, style = elem.style;
-
- // We need to handle opacity special in IE
- if ( name == "opacity" && !jQuery.support.opacity ) {
- ret = jQuery.attr( style, "opacity" );
-
- return ret == "" ?
- "1" :
- ret;
- }
-
- // Make sure we're using the right name for getting the float value
- if ( name.match( /float/i ) )
- name = styleFloat;
-
- if ( !force && style && style[ name ] )
- ret = style[ name ];
-
- else if ( defaultView.getComputedStyle ) {
-
- // Only "float" is needed here
- if ( name.match( /float/i ) )
- name = "float";
-
- name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
-
- var computedStyle = defaultView.getComputedStyle( elem, null );
-
- if ( computedStyle )
- ret = computedStyle.getPropertyValue( name );
-
- // We should always get a number back from opacity
- if ( name == "opacity" && ret == "" )
- ret = "1";
-
- } else if ( elem.currentStyle ) {
- var camelCase = name.replace(/\-(\w)/g, function(all, letter){
- return letter.toUpperCase();
- });
-
- ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
-
- // From the awesome hack by Dean Edwards
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
- // If we're not dealing with a regular pixel number
- // but a number that has a weird ending, we need to convert it to pixels
- if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
- // Remember the original values
- var left = style.left, rsLeft = elem.runtimeStyle.left;
-
- // Put in the new values to get a computed value out
- elem.runtimeStyle.left = elem.currentStyle.left;
- style.left = ret || 0;
- ret = style.pixelLeft + "px";
-
- // Revert the changed values
- style.left = left;
- elem.runtimeStyle.left = rsLeft;
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // The extra typeof function check is to prevent crashes
+ // in Safari 2 (See: #3039)
+ if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
}
}
return ret;
},
- clean: function( elems, context, fragment ) {
- context = context || document;
-
- // !context.createElement fails in IE with an error but returns typeof 'object'
- if ( typeof context.createElement === "undefined" )
- context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
-
- // If a single string is passed in and it's a single tag
- // just do a createElement and skip the rest
- if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
- var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
- if ( match )
- return [ context.createElement( match[1] ) ];
- }
-
- var ret = [], scripts = [], div = context.createElement("div");
-
- jQuery.each(elems, function(i, elem){
- if ( typeof elem === "number" )
- elem += '';
-
- if ( !elem )
- return;
-
- // Convert html string into DOM nodes
- if ( typeof elem === "string" ) {
- // Fix "XHTML"-style tags in all browsers
- elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
- return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
- all :
- front + "></" + tag + ">";
- });
-
- // Trim whitespace, otherwise indexOf won't work as expected
- var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
-
- var wrap =
- // option or optgroup
- !tags.indexOf("<opt") &&
- [ 1, "<select multiple='multiple'>", "</select>" ] ||
-
- !tags.indexOf("<leg") &&
- [ 1, "<fieldset>", "</fieldset>" ] ||
-
- tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
- [ 1, "<table>", "</table>" ] ||
-
- !tags.indexOf("<tr") &&
- [ 2, "<table><tbody>", "</tbody></table>" ] ||
-
- // <thead> matched above
- (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
- [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
-
- !tags.indexOf("<col") &&
- [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
-
- // IE can't serialize <link> and <script> tags normally
- !jQuery.support.htmlSerialize &&
- [ 1, "div<div>", "</div>" ] ||
-
- [ 0, "", "" ];
-
- // Go to html and back, then peel off extra wrappers
- div.innerHTML = wrap[1] + elem + wrap[2];
-
- // Move to the right depth
- while ( wrap[0]-- )
- div = div.lastChild;
-
- // Remove IE's autoinserted <tbody> from table fragments
- if ( !jQuery.support.tbody ) {
-
- // String was a <table>, *may* have spurious <tbody>
- var hasBody = /<tbody/i.test(elem),
- tbody = !tags.indexOf("<table") && !hasBody ?
- div.firstChild && div.firstChild.childNodes :
-
- // String was a bare <thead> or <tfoot>
- wrap[1] == "<table>" && !hasBody ?
- div.childNodes :
- [];
-
- for ( var j = tbody.length - 1; j >= 0 ; --j )
- if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
- tbody[ j ].parentNode.removeChild( tbody[ j ] );
-
- }
-
- // IE completely kills leading whitespace when innerHTML is used
- if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
- div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
-
- elem = jQuery.makeArray( div.childNodes );
- }
-
- if ( elem.nodeType )
- ret.push( elem );
- else
- ret = jQuery.merge( ret, elem );
-
- });
-
- if ( fragment ) {
- for ( var i = 0; ret[i]; i++ ) {
- if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
- scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
- } else {
- if ( ret[i].nodeType === 1 )
- ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
- fragment.appendChild( ret[i] );
- }
- }
-
- return scripts;
+ inArray: function( elem, array ) {
+ if ( array.indexOf ) {
+ return array.indexOf( elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var i = first.length, j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ if ( !inv !== !callback( elems[ i ], i ) ) {
+ ret.push( elems[ i ] );
+ }
}
return ret;
},
- attr: function( elem, name, value ) {
- // don't set attributes on text and comment nodes
- if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
- return undefined;
-
- var notxml = !jQuery.isXMLDoc( elem ),
- // Whether we are setting (or getting)
- set = value !== undefined;
-
- // Try to normalize/fix the name
- name = notxml && jQuery.props[ name ] || name;
-
- // Only do all the following if this is a node (faster for style)
- // IE elem.getAttribute passes even for style
- if ( elem.tagName ) {
-
- // These attributes require special treatment
- var special = /href|src|style/.test( name );
-
- // Safari mis-reports the default selected property of a hidden option
- // Accessing the parent's selectedIndex property fixes it
- if ( name == "selected" && elem.parentNode )
- elem.parentNode.selectedIndex;
-
- // If applicable, access the attribute via the DOM 0 way
- if ( name in elem && notxml && !special ) {
- if ( set ){
- // We can't allow the type property to be changed (since it causes problems in IE)
- if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
- throw "type property can't be changed";
-
- elem[ name ] = value;
- }
-
- // browsers index elements by id/name on forms, give priority to attributes.
- if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
- return elem.getAttributeNode( name ).nodeValue;
-
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabind…
- if ( name == "tabIndex" ) {
- var attributeNode = elem.getAttributeNode( "tabIndex" );
- return attributeNode && attributeNode.specified
- ? attributeNode.value
- : elem.nodeName.match(/(button|input|object|select|textarea)/i)
- ? 0
- : elem.nodeName.match(/^(a|area)$/i) && elem.href
- ? 0
- : undefined;
- }
-
- return elem[ name ];
- }
-
- if ( !jQuery.support.style && notxml && name == "style" )
- return jQuery.attr( elem.style, "cssText", value );
-
- if ( set )
- // convert the value to a string (all browsers do this but IE) see #1070
- elem.setAttribute( name, "" + value );
-
- var attr = !jQuery.support.hrefNormalized && notxml && special
- // Some attributes require a special call on IE
- ? elem.getAttribute( name, 2 )
- : elem.getAttribute( name );
-
- // Non-existent attributes return null, we normalize to undefined
- return attr === null ? undefined : attr;
- }
-
- // elem is actually elem.style ... set the style
-
- // IE uses filters for opacity
- if ( !jQuery.support.opacity && name == "opacity" ) {
- if ( set ) {
- // IE has trouble with opacity if it does not have layout
- // Force it by setting the zoom level
- elem.zoom = 1;
-
- // Set the alpha filter to set the opacity
- elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
- (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
- }
-
- return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
- (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
- "";
- }
-
- name = name.replace(/-([a-z])/ig, function(all, letter){
- return letter.toUpperCase();
- });
-
- if ( set )
- elem[ name ] = value;
-
- return elem[ name ];
- },
-
- trim: function( text ) {
- return (text || "").replace( /^\s+|\s+$/g, "" );
- },
-
- makeArray: function( array ) {
- var ret = [];
-
- if( array != null ){
- var i = array.length;
- // The window, strings (and functions) also have 'length'
- if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
- ret[0] = array;
- else
- while( i )
- ret[--i] = array[i];
- }
-
- return ret;
- },
-
- inArray: function( elem, array ) {
- for ( var i = 0, length = array.length; i < length; i++ )
- // Use === because on IE, window == document
- if ( array[ i ] === elem )
- return i;
-
- return -1;
- },
-
- merge: function( first, second ) {
- // We have to loop this way because IE & Opera overwrite the length
- // expando of getElementsByTagName
- var i = 0, elem, pos = first.length;
- // Also, we need to make sure that the correct elements are being returned
- // (IE returns comment nodes in a '*' query)
- if ( !jQuery.support.getAll ) {
- while ( (elem = second[ i++ ]) != null )
- if ( elem.nodeType != 8 )
- first[ pos++ ] = elem;
-
- } else
- while ( (elem = second[ i++ ]) != null )
- first[ pos++ ] = elem;
-
- return first;
- },
-
- unique: function( array ) {
- var ret = [], done = {};
-
- try {
-
- for ( var i = 0, length = array.length; i < length; i++ ) {
- var id = jQuery.data( array[ i ] );
-
- if ( !done[ id ] ) {
- done[ id ] = true;
- ret.push( array[ i ] );
- }
- }
-
- } catch( e ) {
- ret = array;
- }
-
- return ret;
- },
-
- grep: function( elems, callback, inv ) {
- var ret = [];
-
- // Go through the array, only saving the items
- // that pass the validator function
- for ( var i = 0, length = elems.length; i < length; i++ )
- if ( !inv != !callback( elems[ i ], i ) )
- ret.push( elems[ i ] );
-
- return ret;
- },
-
- map: function( elems, callback ) {
- var ret = [];
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var ret = [], value;
// Go through the array, translating each of the items to their
// new value (or values).
for ( var i = 0, length = elems.length; i < length; i++ ) {
- var value = callback( elems[ i ], i );
-
- if ( value != null )
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
ret[ ret.length ] = value;
+ }
}
return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ proxy: function( fn, proxy, thisObject ) {
+ if ( arguments.length === 2 ) {
+ if ( typeof proxy === "string" ) {
+ thisObject = fn;
+ fn = thisObject[ proxy ];
+ proxy = undefined;
+
+ } else if ( proxy && !jQuery.isFunction( proxy ) ) {
+ thisObject = proxy;
+ proxy = undefined;
+ }
+ }
+
+ if ( !proxy && fn ) {
+ proxy = function() {
+ return fn.apply( thisObject || this, arguments );
+ };
+ }
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ if ( fn ) {
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+ }
+
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+ /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
+ /(msie) ([\w.]+)/.exec( ua ) ||
+ !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ browser: {}
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+ jQuery.inArray = function( elem, array ) {
+ return indexOf.call( array, elem );
+ };
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+function evalScript( i, elem ) {
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+// Mutifunctional method to get and set values to a collection
+// The value/s can be optionally by executed if its a function
+function access( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : undefined;
+}
+
+function now() {
+ return (new Date).getTime();
+}
+(function() {
+
+ jQuery.support = {};
+
+ var root = document.documentElement,
+ script = document.createElement("script"),
+ div = document.createElement("div"),
+ id = "script" + now();
+
+ div.style.display = "none";
+ div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+ var all = div.getElementsByTagName("*"),
+ a = div.getElementsByTagName("a")[0];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return;
+ }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType === 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: /red/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.55$/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
+
+ parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
+
+ // Will be defined later
+ deleteExpando: true,
+ checkClone: false,
+ scriptEval: false,
+ noCloneEvent: true,
+ boxModel: null
+ };
+
+ script.type = "text/javascript";
+ try {
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ } catch(e) {}
+
+ root.insertBefore( script, root.firstChild );
+
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
+ if ( window[ id ] ) {
+ jQuery.support.scriptEval = true;
+ delete window[ id ];
+ }
+
+ // Test to see if it's possible to delete an expando from an element
+ // Fails in Internet Explorer
+ try {
+ delete script.test;
+
+ } catch(e) {
+ jQuery.support.deleteExpando = false;
+ }
+
+ root.removeChild( script );
+
+ if ( div.attachEvent && div.fireEvent ) {
+ div.attachEvent("onclick", function click() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ jQuery.support.noCloneEvent = false;
+ div.detachEvent("onclick", click);
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ div = document.createElement("div");
+ div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+ var fragment = document.createDocumentFragment();
+ fragment.appendChild( div.firstChild );
+
+ // WebKit doesn't clone checked state correctly in fragments
+ jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+ // Figure out if the W3C box model works as expected
+ // document.body must exist before we can do this
+ jQuery(function() {
+ var div = document.createElement("div");
+ div.style.width = div.style.paddingLeft = "1px";
+
+ document.body.appendChild( div );
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+ document.body.removeChild( div ).style.display = 'none';
+
+ div = null;
+ });
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-bro…
+ var eventSupported = function( eventName ) {
+ var el = document.createElement("div");
+ eventName = "on" + eventName;
+
+ var isSupported = (eventName in el);
+ if ( !isSupported ) {
+ el.setAttribute(eventName, "return;");
+ isSupported = typeof el[eventName] === "function";
+ }
+ el = null;
+
+ return isSupported;
+ };
+
+ jQuery.support.submitBubbles = eventSupported("submit");
+ jQuery.support.changeBubbles = eventSupported("change");
+
+ // release memory in IE
+ root = script = div = all = a = null;
+})();
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ tabindex: "tabIndex",
+ usemap: "useMap",
+ frameborder: "frameBorder"
+};
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+ cache: {},
+
+ expando:expando,
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ "object": true,
+ "applet": true
+ },
+
+ data: function( elem, name, data ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache;
+
+ if ( !id && typeof name === "string" && data === undefined ) {
+ return null;
+ }
+
+ // Compute a unique ID for the element
+ if ( !id ) {
+ id = ++uuid;
+ }
+
+ // Avoid generating a new cache unless none exists and we
+ // want to manipulate it.
+ if ( typeof name === "object" ) {
+ elem[ expando ] = id;
+ thisCache = cache[ id ] = jQuery.extend(true, {}, name);
+
+ } else if ( !cache[ id ] ) {
+ elem[ expando ] = id;
+ cache[ id ] = {};
+ }
+
+ thisCache = cache[ id ];
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined ) {
+ thisCache[ name ] = data;
+ }
+
+ return typeof name === "string" ? thisCache[ name ] : thisCache;
+ },
+
+ removeData: function( elem, name ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( thisCache ) {
+ // Remove the section of cache data
+ delete thisCache[ name ];
+
+ // If we've removed all the data, remove the element's cache
+ if ( jQuery.isEmptyObject(thisCache) ) {
+ jQuery.removeData( elem );
+ }
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ if ( jQuery.support.deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ // Completely remove the data cache
+ delete cache[ id ];
+ }
}
});
-// Use of jQuery.browser is deprecated.
-// It's included for backwards compatibility and plugins,
-// although they should work to migrate away.
-
-var userAgent = navigator.userAgent.toLowerCase();
-
-// Figure out what browser is being used
-jQuery.browser = {
- version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
- safari: /webkit/.test( userAgent ),
- opera: /opera/.test( userAgent ),
- msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
- mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+jQuery.fn.extend({
+ data: function( key, value ) {
+ if ( typeof key === "undefined" && this.length ) {
+ return jQuery.data( this[0] );
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ }
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else {
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
+ jQuery.data( this, key, value );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+jQuery.extend({
+ queue: function( elem, type, data ) {
+ if ( !elem ) {
+ return;
+ }
+
+ type = (type || "fx") + "queue";
+ var q = jQuery.data( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( !data ) {
+ return q || [];
+ }
+
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+ } else {
+ q.push( data );
+ }
+
+ return q;
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ), fn = queue.shift();
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift("inprogress");
+ }
+
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ });
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function( i, elem ) {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function() {
+ var elem = this;
+ setTimeout(function() {
+ jQuery.dequeue( elem, type );
+ }, time );
+ });
+ },
+
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ }
+});
+var rclass = /[\n\t]/g,
+ rspace = /\s+/,
+ rreturn = /\r/g,
+ rspecialurl = /href|src|style/,
+ rtype = /(button|input)/i,
+ rfocusable = /(button|input|object|select|textarea)/i,
+ rclickable = /^(a|area)$/i,
+ rradiocheck = /radio|checkbox/;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name, fn ) {
+ return this.each(function(){
+ jQuery.attr( this, name, "" );
+ if ( this.nodeType === 1 ) {
+ this.removeAttribute( name );
+ }
+ });
+ },
+
+ addClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.addClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ var classNames = (value || "").split( rspace );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className ) {
+ elem.className = value;
+
+ } else {
+ var className = " " + elem.className + " ", setClass = elem.className;
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+ setClass += " " + classNames[c];
+ }
+ }
+ elem.className = jQuery.trim( setClass );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.removeClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ var classNames = (value || "").split(rspace);
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ var className = (" " + elem.className + " ").replace(rclass, " ");
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[c] + " ", " ");
+ }
+ elem.className = jQuery.trim( className );
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value, isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className, i = 0, self = jQuery(this),
+ state = stateVal,
+ classNames = value.split( rspace );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery.data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ";
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ if ( value === undefined ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if ( jQuery.nodeName( elem, "option" ) ) {
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+ }
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(rreturn, "");
+
+ }
+
+ return undefined;
+ }
+
+ var isFunction = jQuery.isFunction(value);
+
+ return this.each(function(i) {
+ var self = jQuery(this), val = value;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call(this, i, self.val());
+ }
+
+ // Typecast each time if the value is a Function and the appended
+ // value is therefore different each time.
+ if ( typeof val === "number" ) {
+ val += "";
+ }
+
+ if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+ this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+ } else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(val);
+
+ jQuery( "option", this ).each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ this.selectedIndex = -1;
+ }
+
+ } else {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attr: function( elem, name, value, pass ) {
+ // don't set attributes on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery(elem)[name](value);
+ }
+
+ var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // Only do all the following if this is a node (faster for style)
+ if ( elem.nodeType === 1 ) {
+ // These attributes require special treatment
+ var special = rspecialurl.test( name );
+
+ // Safari mis-reports the default selected property of an option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name === "selected" && !jQuery.support.optSelected ) {
+ var parent = elem.parentNode;
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ }
+
+ // If applicable, access the attribute via the DOM 0 way
+ if ( name in elem && notxml && !special ) {
+ if ( set ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ }
+
+ elem[ name ] = value;
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+ return elem.getAttributeNode( name ).nodeValue;
+ }
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabind…
+ if ( name === "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+ return attributeNode && attributeNode.specified ?
+ attributeNode.value :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name === "style" ) {
+ if ( set ) {
+ elem.style.cssText = "" + value;
+ }
+
+ return elem.style.cssText;
+ }
+
+ if ( set ) {
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+ }
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special ?
+ // Some attributes require a special call on IE
+ elem.getAttribute( name, 2 ) :
+ elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+
+ // elem is actually elem.style ... set the style
+ // Using attr for specific style information is now deprecated. Use style instead.
+ return jQuery.style( elem, name, value );
+ }
+});
+var rnamespaces = /\.(.*)$/,
+ fcleanup = function( nm ) {
+ return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
+ return "\\" + ch;
+ });
+ };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function( elem, types, handler, data ) {
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
+ elem = window;
+ }
+
+ var handleObjIn, handleObj;
+
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ }
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure
+ var elemData = jQuery.data( elem );
+
+ // If no elemData is found then we must be trying to bind to one of the
+ // banned noData elements
+ if ( !elemData ) {
+ return;
+ }
+
+ var events = elemData.events = elemData.events || {},
+ eventHandle = elemData.handle, eventHandle;
+
+ if ( !eventHandle ) {
+ elemData.handle = eventHandle = function() {
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+ }
+
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native events in IE.
+ eventHandle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ var type, i = 0, namespaces;
+
+ while ( (type = types[ i++ ]) ) {
+ handleObj = handleObjIn ?
+ jQuery.extend({}, handleObjIn) :
+ { handler: handler, data: data };
+
+ // Namespaced event handlers
+ if ( type.indexOf(".") > -1 ) {
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+ } else {
+ namespaces = [];
+ handleObj.namespace = "";
+ }
+
+ handleObj.type = type;
+ handleObj.guid = handler.guid;
+
+ // Get the current list of functions bound to this event
+ var handlers = events[ type ],
+ special = jQuery.event.special[ type ] || {};
+
+ // Init the event handler queue
+ if ( !handlers ) {
+ handlers = events[ type ] = [];
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers.push( handleObj );
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, pos ) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+ elemData = jQuery.data( elem ),
+ events = elemData && elemData.events;
+
+ if ( !elemData || !events ) {
+ return;
+ }
+
+ // types is actually an event object here
+ if ( types && types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Unbind all events for the element
+ if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+ types = types || "";
+
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types );
+ }
+
+ return;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ while ( (type = types[ i++ ]) ) {
+ origType = type;
+ handleObj = null;
+ all = type.indexOf(".") < 0;
+ namespaces = [];
+
+ if ( !all ) {
+ // Namespaced event handlers
+ namespaces = type.split(".");
+ type = namespaces.shift();
+
+ namespace = new RegExp("(^|\\.)" +
+ jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
+ }
+
+ eventType = events[ type ];
+
+ if ( !eventType ) {
+ continue;
+ }
+
+ if ( !handler ) {
+ for ( var j = 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ jQuery.event.remove( elem, origType, handleObj.handler, j );
+ eventType.splice( j--, 1 );
+ }
+ }
+
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+
+ for ( var j = pos || 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( handler.guid === handleObj.guid ) {
+ // remove the given handler for the given type
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ if ( pos == null ) {
+ eventType.splice( j--, 1 );
+ }
+
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+
+ if ( pos != null ) {
+ break;
+ }
+ }
+ }
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/143c920af25c
changeset: 3446:143c920af25c
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Sun Feb 28 22:19:56 2010 -0500
description:
Clean up pages:
-remove unused code;
-show annotation field when creating a page;
-fix bug when filtering pages by sharing status.
diffstat:
lib/galaxy/web/controllers/page.py | 57 +++++++++----------------------------
1 files changed, 14 insertions(+), 43 deletions(-)
diffs (115 lines):
diff -r 5ffd16fb6a12 -r 143c920af25c lib/galaxy/web/controllers/page.py
--- a/lib/galaxy/web/controllers/page.py Thu Feb 25 23:20:19 2010 -0500
+++ b/lib/galaxy/web/controllers/page.py Sun Feb 28 22:19:56 2010 -0500
@@ -24,13 +24,13 @@
use_panels = True
title = "Pages"
model_class = model.Page
- default_filter = { "published" : "All", "tags" : "All", "title" : "All"}
+ default_filter = { "published" : "All", "tags" : "All", "title" : "All", "sharing" : "All" }
default_sort_key = "-create_time"
columns = [
grids.TextColumn( "Title", key="title", model_class=model.Page, attach_popup=True, filterable="advanced" ),
URLColumn( "Public URL" ),
grids.IndividualTagsColumn( "Tags", "tags", model.Page, model.PageTagAssociation, filterable="advanced", grid_name="PageListGrid" ),
- grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False ),
+ grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.Page, filterable="advanced", sortable=False ),
grids.GridColumn( "Created", key="create_time", format=time_ago ),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
]
@@ -79,40 +79,7 @@
return session.query( self.model_class ).join( model.User.table )
def apply_default_filter( self, trans, query, **kwargs ):
return query.filter( self.model_class.deleted==False ).filter( self.model_class.published==True )
-
-class HistorySelectionGrid( grids.Grid ):
- # Custom columns.
- class NameColumn( grids.TextColumn ):
- def get_value(self, trans, grid, history):
- return history.get_display_name()
-
- # Grid definition.
- title = "Saved Histories"
- template = "/page/select_histories_grid.mako"
- async_template = "/page/select_histories_grid_async.mako"
- model_class = model.History
- default_filter = { "deleted" : "False" , "shared" : "All" }
- default_sort_key = "-update_time"
- use_async = True
- use_paging = True
- num_rows_per_page = 10
- columns = [
- NameColumn( "Name", key="name", model_class=model.History, filterable="advanced" ),
- grids.IndividualTagsColumn( "Tags", "tags", model.History, model.HistoryTagAssociation, filterable="advanced"),
- grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
- # Columns that are valid for filtering but are not visible.
- grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ),
- grids.SharingStatusColumn( "Sharing", key="sharing", model_class=model.History, filterable="advanced", sortable=False, visible=False ),
- ]
- columns.append(
- grids.MulticolFilterColumn(
- "Search",
- cols_to_filter=[ columns[0], columns[1] ],
- key="free-text-search", visible=False, filterable="standard" )
- )
- def apply_default_filter( self, trans, query, **kwargs ):
- return query.filter_by( user=trans.user, purged=False )
-
+
class ItemSelectionGrid( grids.Grid ):
""" Base class for pages' item selection grids. """
# Custom columns.
@@ -339,12 +306,12 @@
@web.expose
@web.require_login( "create pages" )
- def create( self, trans, page_title="", page_slug="" ):
+ def create( self, trans, page_title="", page_slug="", page_annotation="" ):
"""
Create a new page
"""
user = trans.get_user()
- page_title_err = page_slug_err = ""
+ page_title_err = page_slug_err = page_annotation_err = ""
if trans.request.method == "POST":
if not page_title:
page_title_err = "Page name is required"
@@ -355,12 +322,14 @@
elif trans.sa_session.query( model.Page ).filter_by( user=user, slug=page_slug, deleted=False ).first():
page_slug_err = "Page id must be unique"
else:
- # Create the new stored workflow
+ # Create the new stored page
page = model.Page()
page.title = page_title
page.slug = page_slug
+ page_annotation = sanitize_html( page_annotation, 'utf-8', 'text/html' )
+ self.add_item_annotation( trans, page, page_annotation )
page.user = user
- # And the first (empty) workflow revision
+ # And the first (empty) page revision
page_revision = model.PageRevision()
page_revision.title = page_title
page_revision.page = page
@@ -381,8 +350,10 @@
public links to this page. A default is generated
from the page title, but can be edited. This field
must contain only lowercase letters, numbers, and
- the '-' character.""" ),
- template="page/create.mako" )
+ the '-' character.""" )
+ .add_text( "page_annotation", "Page annotation", value=page_annotation, error=page_annotation_err,
+ help="A description of the page; annotation is shown alongside published pages."),
+ template="page/create.mako" )
@web.expose
@web.require_login( "create pages" )
@@ -432,7 +403,7 @@
must contain only lowercase letters, numbers, and
the '-' character.""" )
.add_text( "page_annotation", "Page annotation", value=page_annotation, error=page_annotation_err,
- help="A description of or notes about the page. Annotation is shown alongside published pages."),
+ help="A description of the page; annotation is shown alongside published pages."),
template="page/create.mako" )
@web.expose
1
0