galaxy-commits
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
January 2014
- 1 participants
- 280 discussions
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b76dd608c500/
Changeset: b76dd608c500
User: guerler
Date: 2014-01-16 20:10:32
Summary: Charts: Add configuration model, link all view functions to model events
Affected #: 8 files
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -1,10 +1,10 @@
// dependencies
define(['library/portlet', 'library/ui', 'library/utils',
'views/charts', 'views/viewport', 'views/chart', 'views/group',
- 'models/datasets', 'models/chart', 'models/charts', 'models/types'],
+ 'models/config', 'models/datasets', 'models/chart', 'models/charts', 'models/group', 'models/types'],
function( Portlet, Ui, Utils,
ChartsView, ViewportView, ChartView, GroupView,
- Datasets, Chart, Charts, Types
+ Config, Datasets, Chart, Charts, Group, Types
) {
// widget
@@ -19,10 +19,14 @@
// link galaxy
this.modal = parent.Galaxy.modal;
+ // create configuration model
+ this.config = new Config();
+
// create chart models
this.types = new Types();
this.chart = new Chart();
this.charts = new Charts();
+ this.group = new Group();
// create dataset handler
this.datasets = new Datasets(this);
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/models/chart.js
--- a/config/plugins/visualizations/charts/static/models/chart.js
+++ b/config/plugins/visualizations/charts/static/models/chart.js
@@ -22,8 +22,9 @@
// reset
reset: function()
{
- this.clear().set(this.defaults);
+ this.clear({silent: true}).set(this.defaults);
this.groups.reset();
+ this.trigger('reset', this);
},
// copy
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/models/config.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/models/config.js
@@ -0,0 +1,16 @@
+// dependencies
+define([], function() {
+
+
+// model
+return Backbone.Model.extend(
+{
+ // options
+ defaults : {
+ query_limit : 20,
+ query_pace : 1000,
+ query_max : 5
+ }
+});
+
+});
\ No newline at end of file
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/models/group.js
--- a/config/plugins/visualizations/charts/static/models/group.js
+++ b/config/plugins/visualizations/charts/static/models/group.js
@@ -1,23 +1,14 @@
// dependencies
-define(['library/utils'], function(Utils) {
-
+define([], function() {
// model
return Backbone.Model.extend(
{
- // defaults
- defaults : {
- },
-
- // initialize
- initialize: function(options)
- {
- },
-
// reset
reset: function()
{
- this.clear().set(this.defaults);
+ this.clear({silent: true}).set(this.defaults);
+ this.trigger('reset', this);
}
});
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/views/chart.js
--- a/config/plugins/visualizations/charts/static/views/chart.js
+++ b/config/plugins/visualizations/charts/static/views/chart.js
@@ -125,6 +125,9 @@
this.chart.on('change:type', function(chart) {
self.table.value(chart.get('type'));
});
+ this.chart.on('reset', function(chart) {
+ self._resetChart();
+ });
// collection events
this.app.charts.on('add', function(chart) {
@@ -140,23 +143,17 @@
});
// reset
- this.reset();
+ this._resetChart();
},
// reset
- reset: function() {
- this.chart.reset();
+ _resetChart: function() {
this.chart.set('id', Utils.uuid());
this.chart.set('dataset_id', this.app.options.dataset.id);
this.chart.set('type', 'bardiagram');
this.chart.set('title', 'Chart title');
},
- // set chart
- setChart: function(new_chart) {
- this.chart.copy(new_chart);
- },
-
// create chart
_saveChart: function() {
// update chart data
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/views/charts.js
--- a/config/plugins/visualizations/charts/static/views/charts.js
+++ b/config/plugins/visualizations/charts/static/views/charts.js
@@ -16,12 +16,12 @@
ondblclick : function(chart_id) {
// get chart
var chart = self.app.charts.get(chart_id);
-
+ self.app.chart.copy(chart);
+
// show edit
self.$el.hide();
// update model and show create
- self.app.chart_view.setChart(chart);
self.app.chart_view.$el.show();
},
onchange : function(chart_id) {
@@ -41,7 +41,7 @@
tooltip: 'Create',
onclick: function() {
self.$el.hide();
- self.app.chart_view.reset();
+ self.app.chart.reset();
self.app.chart_view.$el.show();
}
}),
@@ -57,11 +57,11 @@
// get chart
var chart = self.app.charts.get(chart_id);
+ self.app.chart.copy(chart);
// show edit
self.$el.hide();
self.app.chart_view.$el.show();
- self.app.chart_view.setChart(chart);
}
}),
'delete' : new Ui.ButtonIcon({
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/views/group.js
--- a/config/plugins/visualizations/charts/static/views/group.js
+++ b/config/plugins/visualizations/charts/static/views/group.js
@@ -1,13 +1,10 @@
// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'],
- function(Portlet, Table, Ui, Utils, Group) {
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils'],
+ function(Portlet, Table, Ui, Utils) {
// chart config
return Backbone.View.extend(
{
- // model
- group: new Group(),
-
// columns
columns: [],
@@ -18,6 +15,7 @@
// get current chart object
this.chart = this.app.chart;
+ this.group = this.app.group;
// ui elements
this.message = new Ui.Message();
@@ -69,6 +67,9 @@
this.group.on('change', function() {
self._refreshGroup();
});
+ this.group.on('reset', function() {
+ self._resetGroup();
+ });
},
// show
@@ -77,8 +78,7 @@
},
// reset
- reset: function() {
- this.group.reset();
+ _resetGroup: function() {
this.group.set('id', Utils.uuid());
this.group.set('label', 'Group label');
},
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/views/groups.js
--- a/config/plugins/visualizations/charts/static/views/groups.js
+++ b/config/plugins/visualizations/charts/static/views/groups.js
@@ -37,9 +37,9 @@
icon : 'fa-plus',
tooltip: 'Create',
onclick: function() {
+ self.app.group.reset();
self.app.chart_view.$el.hide();
self.app.group_view.show();
- self.app.group_view.reset();
}
}),
'edit' : new Ui.ButtonIcon({
https://bitbucket.org/galaxy/galaxy-central/commits/dec86d2bd3b1/
Changeset: dec86d2bd3b1
User: guerler
Date: 2014-01-16 20:10:56
Summary: Merge
Affected #: 8 files
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -602,7 +602,11 @@
if check_migrate_tools:
# Alert the Galaxy admin to tools that have been moved from the distribution to the tool shed.
from tool_shed.galaxy_install.migrate.check import verify_tools
- verify_tools( self, install_db_url, config_file, self.config.database_engine_options )
+ if combined_install_database:
+ install_database_options = self.config.database_engine_options
+ else:
+ install_database_options = self.config.install_database_engine_options
+ verify_tools( self, install_db_url, config_file, install_database_options )
from galaxy.model import mapping
self.model = mapping.init( self.config.file_path,
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -734,8 +734,7 @@
self.tags = []
def _next_hid( self ):
- # TODO: override this with something in the database that ensures
- # better integrity
+ # this is overriden in mapping.py db_next_hid() method
if len( self.datasets ) == 0:
return 1
else:
@@ -3446,4 +3445,7 @@
self.context = context
class APIKeys( object ):
- pass
+ def __init__( self, id=None, user_id=None, key=None):
+ self.id = id
+ self.user_id = user_id
+ self.key = key
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/galaxy/api/authenticate.py
--- /dev/null
+++ b/lib/galaxy/webapps/galaxy/api/authenticate.py
@@ -0,0 +1,77 @@
+"""
+API key retrieval through BaseAuth
+"""
+
+from galaxy import util, web
+from pprint import pprint
+from galaxy.web.base.controller import BaseAPIController
+from base64 import b64decode, b64encode
+from urllib import quote, unquote
+from galaxy.exceptions import ObjectNotFound
+from paste.httpexceptions import HTTPBadRequest
+
+import logging
+log = logging.getLogger( __name__ )
+
+class AuthenticationController( BaseAPIController ):
+
+ @web.expose_api_anonymous
+ def get_api_key( self, trans, **kwd ):
+ """
+ def get_api_key( self, trans, **kwd )
+ * GET /api/authenticate/baseauth
+ returns an API key for authenticated user based on BaseAuth headers
+ """
+ email, password = self._decode_baseauth( trans.environ.get( 'HTTP_AUTHORIZATION' ) )
+
+ user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email == email ).all()
+
+ if (len(user) is not 1):
+ # DB is inconsistent and we have more users with same email
+ raise ObjectNotFound
+ else:
+ user = user[0]
+ is_valid_user = user.check_password( password )
+
+ if (is_valid_user):
+ user_id = user.id
+ api_key_row = trans.sa_session.query( trans.app.model.APIKeys ).filter( trans.app.model.APIKeys.table.c.user_id == user_id ).first()
+ else:
+ trans.response.status = 500
+ return "invalid password"
+
+ return dict( api_key= api_key_row.key )
+
+ def _decode_baseauth( self, encoded_str ):
+ """Decode an encrypted HTTP basic authentication string. Returns a tuple of
+ the form (email, password), and raises a HTTPBadRequest exception if
+ nothing could be decoded.
+ """
+ split = encoded_str.strip().split(' ')
+
+ # If split is only one element, try to decode the email and password
+ # directly.
+ if len(split) == 1:
+ try:
+ email, password = b64decode(split[0]).split(':')
+ except:
+ raise HTTPBadRequest
+
+ # If there are only two elements, check the first and ensure it says
+ # 'basic' so that we know we're about to decode the right thing. If not,
+ # bail out.
+ elif len(split) == 2:
+ if split[0].strip().lower() == 'basic':
+ try:
+ email, password = b64decode(split[1]).split(':')
+ except:
+ raise HTTPBadRequest
+ else:
+ raise HTTPBadRequest
+
+ # If there are more than 2 elements, something crazy must be happening.
+ # Bail.
+ else:
+ raise HTTPBadRequest
+
+ return unquote(email), unquote(password)
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -2,7 +2,6 @@
API operations on the datasets from library.
"""
import glob
-import logging
import operator
import os
import os.path
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -169,6 +169,16 @@
webapp.mapper.connect( 'workflow_dict', '/api/workflows/download/{workflow_id}', controller='workflows', action='workflow_dict', conditions=dict( method=['GET'] ) )
webapp.mapper.connect( 'import_shared_workflow', '/api/workflows/import', controller='workflows', action='import_shared_worflow', conditions=dict( method=['POST'] ) )
+ # ============================
+ # ===== AUTHENTICATE API =====
+ # ============================
+
+ webapp.mapper.connect( 'api_key_retrieval',
+ '/api/authenticate/baseauth/',
+ controller='authenticate',
+ action='get_api_key',
+ conditions=dict( method=[ "GET" ] ) )
+
# =======================
# ===== LIBRARY API =====
# =======================
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/tool_shed/api/repositories.py
--- a/lib/galaxy/webapps/tool_shed/api/repositories.py
+++ b/lib/galaxy/webapps/tool_shed/api/repositories.py
@@ -129,7 +129,7 @@
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
encoded_repository_id,
changeset_revision )
- if not repository_metadata:
+ if repository_metadata is None:
# The changeset_revision column in the repository_metadata table has been updated with a new
# value value, so find the changeset_revision to which we need to update.
repo_dir = repository.repo_path( trans.app )
@@ -139,7 +139,7 @@
encoded_repository_id,
new_changeset_revision )
changeset_revision = new_changeset_revision
- if repository_metadata:
+ if repository_metadata is not None:
encoded_repository_metadata_id = trans.security.encode_id( repository_metadata.id )
repository_metadata_dict = repository_metadata.to_dict( view='collection',
value_mapper=self.__get_value_mapper( trans ) )
@@ -168,7 +168,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/tool_shed/api/repository_revisions.py
--- a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
+++ b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
@@ -68,7 +68,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api_anonymous
@@ -159,15 +160,33 @@
repository_dependency_repository_metadata = \
suc.get_repository_metadata_by_changeset_revision( trans, repository_dependency_id, changeset_revision )
if repository_dependency_repository_metadata is None:
- log.debug( 'Cannot locate repository_metadata with id %s for repository dependency %s owned by %s.' % \
- ( str( repository_dependency_id ), str( name ), str( owner ) ) )
- continue
+ # The changeset_revision column in the repository_metadata table has been updated with a new
+ # value value, so find the changeset_revision to which we need to update.
+ repo_dir = repository_dependency.repo_path( trans.app )
+ repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository_dependency,
+ repo,
+ changeset_revision )
+ repository_dependency_repository_metadata = \
+ suc.get_repository_metadata_by_changeset_revision( trans,
+ repository_dependency_id,
+ new_changeset_revision )
+ if repository_dependency_repository_metadata is None:
+ decoded_repository_dependency_id = trans.security.decode_id( repository_dependency_id )
+ debug_msg = 'Cannot locate repository_metadata with id %d for repository dependency %s owned by %s ' % \
+ ( decoded_repository_dependency_id, str( name ), str( owner ) )
+ debug_msg += 'using either of these changeset_revisions: %s, %s.' % \
+ ( str( changeset_revision ), str( new_changeset_revision ) )
+ log.debug( debug_msg )
+ continue
+ else:
+ changeset_revision = new_changeset_revision
repository_dependency_repository_metadata_id = trans.security.encode_id( repository_dependency_repository_metadata.id )
repository_dependency_dict = repository_dependency.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
# We have to add the changeset_revision of of the repository dependency.
repository_dependency_dict[ 'changeset_revision' ] = changeset_revision
- repository_dependency_dict[ 'url' ] = web.url_for( controller='repositories',
+ repository_dependency_dict[ 'url' ] = web.url_for( controller='repository_revisions',
action='show',
id=repository_dependency_repository_metadata_id )
repository_dependencies_dicts.append( repository_dependency_dict )
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -724,8 +724,8 @@
def get_next_downloadable_changeset_revision( repository, repo, after_changeset_revision ):
"""
- Return the installable changeset_revision in the repository changelog after the changeset to which after_changeset_revision refers. If there
- isn't one, return None.
+ Return the installable changeset_revision in the repository changelog after the changeset to which
+ after_changeset_revision refers. If there isn't one, return None.
"""
changeset_revisions = get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
if len( changeset_revisions ) == 1:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Fixes in the tool shed api for mapping the repository user_id and for handling repository_dependency changeset_revision values that have been updated.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/11bdc0f5c964/
Changeset: 11bdc0f5c964
User: greg
Date: 2014-01-16 20:07:28
Summary: Fixes in the tool shed api for mapping the repository user_id and for handling repository_dependency changeset_revision values that have been updated.
Affected #: 3 files
diff -r 1ffcb550e2f9464bf71a5f5154dff71ba0dd6379 -r 11bdc0f5c964a18e5a810abc283f7f1ec5e9f5ff lib/galaxy/webapps/tool_shed/api/repositories.py
--- a/lib/galaxy/webapps/tool_shed/api/repositories.py
+++ b/lib/galaxy/webapps/tool_shed/api/repositories.py
@@ -129,7 +129,7 @@
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
encoded_repository_id,
changeset_revision )
- if not repository_metadata:
+ if repository_metadata is None:
# The changeset_revision column in the repository_metadata table has been updated with a new
# value value, so find the changeset_revision to which we need to update.
repo_dir = repository.repo_path( trans.app )
@@ -139,7 +139,7 @@
encoded_repository_id,
new_changeset_revision )
changeset_revision = new_changeset_revision
- if repository_metadata:
+ if repository_metadata is not None:
encoded_repository_metadata_id = trans.security.encode_id( repository_metadata.id )
repository_metadata_dict = repository_metadata.to_dict( view='collection',
value_mapper=self.__get_value_mapper( trans ) )
@@ -168,7 +168,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api
diff -r 1ffcb550e2f9464bf71a5f5154dff71ba0dd6379 -r 11bdc0f5c964a18e5a810abc283f7f1ec5e9f5ff lib/galaxy/webapps/tool_shed/api/repository_revisions.py
--- a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
+++ b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
@@ -68,7 +68,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api_anonymous
@@ -159,15 +160,33 @@
repository_dependency_repository_metadata = \
suc.get_repository_metadata_by_changeset_revision( trans, repository_dependency_id, changeset_revision )
if repository_dependency_repository_metadata is None:
- log.debug( 'Cannot locate repository_metadata with id %s for repository dependency %s owned by %s.' % \
- ( str( repository_dependency_id ), str( name ), str( owner ) ) )
- continue
+ # The changeset_revision column in the repository_metadata table has been updated with a new
+ # value value, so find the changeset_revision to which we need to update.
+ repo_dir = repository_dependency.repo_path( trans.app )
+ repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository_dependency,
+ repo,
+ changeset_revision )
+ repository_dependency_repository_metadata = \
+ suc.get_repository_metadata_by_changeset_revision( trans,
+ repository_dependency_id,
+ new_changeset_revision )
+ if repository_dependency_repository_metadata is None:
+ decoded_repository_dependency_id = trans.security.decode_id( repository_dependency_id )
+ debug_msg = 'Cannot locate repository_metadata with id %d for repository dependency %s owned by %s ' % \
+ ( decoded_repository_dependency_id, str( name ), str( owner ) )
+ debug_msg += 'using either of these changeset_revisions: %s, %s.' % \
+ ( str( changeset_revision ), str( new_changeset_revision ) )
+ log.debug( debug_msg )
+ continue
+ else:
+ changeset_revision = new_changeset_revision
repository_dependency_repository_metadata_id = trans.security.encode_id( repository_dependency_repository_metadata.id )
repository_dependency_dict = repository_dependency.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
# We have to add the changeset_revision of of the repository dependency.
repository_dependency_dict[ 'changeset_revision' ] = changeset_revision
- repository_dependency_dict[ 'url' ] = web.url_for( controller='repositories',
+ repository_dependency_dict[ 'url' ] = web.url_for( controller='repository_revisions',
action='show',
id=repository_dependency_repository_metadata_id )
repository_dependencies_dicts.append( repository_dependency_dict )
diff -r 1ffcb550e2f9464bf71a5f5154dff71ba0dd6379 -r 11bdc0f5c964a18e5a810abc283f7f1ec5e9f5ff lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -724,8 +724,8 @@
def get_next_downloadable_changeset_revision( repository, repo, after_changeset_revision ):
"""
- Return the installable changeset_revision in the repository changelog after the changeset to which after_changeset_revision refers. If there
- isn't one, return None.
+ Return the installable changeset_revision in the repository changelog after the changeset to which
+ after_changeset_revision refers. If there isn't one, return None.
"""
changeset_revisions = get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
if len( changeset_revisions ) == 1:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Fix database engine options when verifying tools using separate install database.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/1ffcb550e2f9/
Changeset: 1ffcb550e2f9
User: jmchilton
Date: 2014-01-16 20:00:30
Summary: Fix database engine options when verifying tools using separate install database.
Bug report and fix thanks to Jim Johnson.
Affected #: 1 file
diff -r dd0bf9c3d0e42246964c8d65785ece1feec6b98e -r 1ffcb550e2f9464bf71a5f5154dff71ba0dd6379 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -602,7 +602,11 @@
if check_migrate_tools:
# Alert the Galaxy admin to tools that have been moved from the distribution to the tool shed.
from tool_shed.galaxy_install.migrate.check import verify_tools
- verify_tools( self, install_db_url, config_file, self.config.database_engine_options )
+ if combined_install_database:
+ install_database_options = self.config.database_engine_options
+ else:
+ install_database_options = self.config.install_database_engine_options
+ verify_tools( self, install_db_url, config_file, install_database_options )
from galaxy.model import mapping
self.model = mapping.init( self.config.file_path,
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/dd0bf9c3d0e4/
Changeset: dd0bf9c3d0e4
User: martenson
Date: 2014-01-16 19:35:51
Summary: remove doubled import
Affected #: 1 file
diff -r 3149e4f0836584708c417c42e36250709026d18c -r dd0bf9c3d0e42246964c8d65785ece1feec6b98e lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -2,7 +2,6 @@
API operations on the datasets from library.
"""
import glob
-import logging
import operator
import os
import os.path
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: removed obvious bugs in api_key retrieval through API using basic authentication
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3149e4f08365/
Changeset: 3149e4f08365
User: martenson
Date: 2014-01-16 19:30:53
Summary: removed obvious bugs in api_key retrieval through API using basic authentication
Affected #: 1 file
diff -r a24014287a29cddcd4ef392a4bde59a833c3ecab -r 3149e4f0836584708c417c42e36250709026d18c lib/galaxy/webapps/galaxy/api/authenticate.py
--- a/lib/galaxy/webapps/galaxy/api/authenticate.py
+++ b/lib/galaxy/webapps/galaxy/api/authenticate.py
@@ -10,7 +10,6 @@
from galaxy.exceptions import ObjectNotFound
from paste.httpexceptions import HTTPBadRequest
-
import logging
log = logging.getLogger( __name__ )
@@ -23,7 +22,7 @@
* GET /api/authenticate/baseauth
returns an API key for authenticated user based on BaseAuth headers
"""
- email, password = _decode_baseauth( trans.environ.get( 'HTTP_AUTHORIZATION' ) )
+ email, password = self._decode_baseauth( trans.environ.get( 'HTTP_AUTHORIZATION' ) )
user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email == email ).all()
@@ -41,38 +40,38 @@
trans.response.status = 500
return "invalid password"
- return dict('api_key', api_key_row.key)
+ return dict( api_key= api_key_row.key )
-def _decode_baseauth( encoded_str ):
- """Decode an encrypted HTTP basic authentication string. Returns a tuple of
- the form (email, password), and raises a DecodeError exception if
- nothing could be decoded.
- """
- split = encoded_str.strip().split(' ')
+ def _decode_baseauth( self, encoded_str ):
+ """Decode an encrypted HTTP basic authentication string. Returns a tuple of
+ the form (email, password), and raises a HTTPBadRequest exception if
+ nothing could be decoded.
+ """
+ split = encoded_str.strip().split(' ')
- # If split is only one element, try to decode the email and password
- # directly.
- if len(split) == 1:
- try:
- email, password = b64decode(split[0]).split(':')
- except:
- raise HTTPBadRequest
+ # If split is only one element, try to decode the email and password
+ # directly.
+ if len(split) == 1:
+ try:
+ email, password = b64decode(split[0]).split(':')
+ except:
+ raise HTTPBadRequest
- # If there are only two elements, check the first and ensure it says
- # 'basic' so that we know we're about to decode the right thing. If not,
- # bail out.
- elif len(split) == 2:
- if split[0].strip().lower() == 'basic':
- try:
- email, password = b64decode(split[1]).split(':')
- except:
- raise DecodeError
+ # If there are only two elements, check the first and ensure it says
+ # 'basic' so that we know we're about to decode the right thing. If not,
+ # bail out.
+ elif len(split) == 2:
+ if split[0].strip().lower() == 'basic':
+ try:
+ email, password = b64decode(split[1]).split(':')
+ except:
+ raise HTTPBadRequest
+ else:
+ raise HTTPBadRequest
+
+ # If there are more than 2 elements, something crazy must be happening.
+ # Bail.
else:
raise HTTPBadRequest
- # If there are more than 2 elements, something crazy must be happening.
- # Bail.
- else:
- raise HTTPBadRequest
-
- return unquote(email), unquote(password)
+ return unquote(email), unquote(password)
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: api_key retrieval through API using basic authentication
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a24014287a29/
Changeset: a24014287a29
User: martenson
Date: 2014-01-16 19:20:10
Summary: api_key retrieval through API using basic authentication
Affected #: 3 files
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r a24014287a29cddcd4ef392a4bde59a833c3ecab lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -734,8 +734,7 @@
self.tags = []
def _next_hid( self ):
- # TODO: override this with something in the database that ensures
- # better integrity
+ # this is overriden in mapping.py db_next_hid() method
if len( self.datasets ) == 0:
return 1
else:
@@ -3446,4 +3445,7 @@
self.context = context
class APIKeys( object ):
- pass
+ def __init__( self, id=None, user_id=None, key=None):
+ self.id = id
+ self.user_id = user_id
+ self.key = key
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r a24014287a29cddcd4ef392a4bde59a833c3ecab lib/galaxy/webapps/galaxy/api/authenticate.py
--- /dev/null
+++ b/lib/galaxy/webapps/galaxy/api/authenticate.py
@@ -0,0 +1,78 @@
+"""
+API key retrieval through BaseAuth
+"""
+
+from galaxy import util, web
+from pprint import pprint
+from galaxy.web.base.controller import BaseAPIController
+from base64 import b64decode, b64encode
+from urllib import quote, unquote
+from galaxy.exceptions import ObjectNotFound
+from paste.httpexceptions import HTTPBadRequest
+
+
+import logging
+log = logging.getLogger( __name__ )
+
+class AuthenticationController( BaseAPIController ):
+
+ @web.expose_api_anonymous
+ def get_api_key( self, trans, **kwd ):
+ """
+ def get_api_key( self, trans, **kwd )
+ * GET /api/authenticate/baseauth
+ returns an API key for authenticated user based on BaseAuth headers
+ """
+ email, password = _decode_baseauth( trans.environ.get( 'HTTP_AUTHORIZATION' ) )
+
+ user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email == email ).all()
+
+ if (len(user) is not 1):
+ # DB is inconsistent and we have more users with same email
+ raise ObjectNotFound
+ else:
+ user = user[0]
+ is_valid_user = user.check_password( password )
+
+ if (is_valid_user):
+ user_id = user.id
+ api_key_row = trans.sa_session.query( trans.app.model.APIKeys ).filter( trans.app.model.APIKeys.table.c.user_id == user_id ).first()
+ else:
+ trans.response.status = 500
+ return "invalid password"
+
+ return dict('api_key', api_key_row.key)
+
+def _decode_baseauth( encoded_str ):
+ """Decode an encrypted HTTP basic authentication string. Returns a tuple of
+ the form (email, password), and raises a DecodeError exception if
+ nothing could be decoded.
+ """
+ split = encoded_str.strip().split(' ')
+
+ # If split is only one element, try to decode the email and password
+ # directly.
+ if len(split) == 1:
+ try:
+ email, password = b64decode(split[0]).split(':')
+ except:
+ raise HTTPBadRequest
+
+ # If there are only two elements, check the first and ensure it says
+ # 'basic' so that we know we're about to decode the right thing. If not,
+ # bail out.
+ elif len(split) == 2:
+ if split[0].strip().lower() == 'basic':
+ try:
+ email, password = b64decode(split[1]).split(':')
+ except:
+ raise DecodeError
+ else:
+ raise HTTPBadRequest
+
+ # If there are more than 2 elements, something crazy must be happening.
+ # Bail.
+ else:
+ raise HTTPBadRequest
+
+ return unquote(email), unquote(password)
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r a24014287a29cddcd4ef392a4bde59a833c3ecab lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -169,6 +169,16 @@
webapp.mapper.connect( 'workflow_dict', '/api/workflows/download/{workflow_id}', controller='workflows', action='workflow_dict', conditions=dict( method=['GET'] ) )
webapp.mapper.connect( 'import_shared_workflow', '/api/workflows/import', controller='workflows', action='import_shared_worflow', conditions=dict( method=['POST'] ) )
+ # ============================
+ # ===== AUTHENTICATE API =====
+ # ============================
+
+ webapp.mapper.connect( 'api_key_retrieval',
+ '/api/authenticate/baseauth/',
+ controller='authenticate',
+ action='get_api_key',
+ conditions=dict( method=[ "GET" ] ) )
+
# =======================
# ===== LIBRARY API =====
# =======================
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Charts: Update view organization
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ee176b881f37/
Changeset: ee176b881f37
User: guerler
Date: 2014-01-16 18:24:47
Summary: Charts: Update view organization
Affected #: 14 files
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -1,9 +1,9 @@
// dependencies
define(['library/portlet', 'library/ui', 'library/utils',
- 'main', 'viewport', 'create', 'config',
+ 'views/charts', 'views/viewport', 'views/chart', 'views/group',
'models/datasets', 'models/chart', 'models/charts', 'models/types'],
function( Portlet, Ui, Utils,
- Main, Viewport, Create, Config,
+ ChartsView, ViewportView, ChartView, GroupView,
Datasets, Chart, Charts, Types
) {
@@ -19,32 +19,32 @@
// link galaxy
this.modal = parent.Galaxy.modal;
- // create chart objects
+ // create chart models
this.types = new Types();
this.chart = new Chart();
- this.charts = new Charts(this);
+ this.charts = new Charts();
// create dataset handler
this.datasets = new Datasets(this);
// create views
- this.main = new Main(this);
- this.viewport = new Viewport(this);
- this.config = new Config(this);
- this.create = new Create(this);
+ this.charts_view = new ChartsView(this);
+ this.group_view = new GroupView(this);
+ this.chart_view = new ChartView(this);
+ this.viewport_view = new ViewportView(this);
// portlet
this.portlet = new Portlet({icon : 'fa-bar-chart-o', label : 'Charts'});
- this.portlet.append(this.main.$el);
- this.portlet.append(this.config.$el);
- this.portlet.append(this.create.$el);
+ this.portlet.append(this.charts_view.$el);
+ this.portlet.append(this.group_view.$el);
+ this.portlet.append(this.chart_view.$el);
// append main
- this.main.append(this.viewport.$el);
+ this.charts_view.append(this.viewport_view.$el);
// create
- this.config.$el.hide();
- this.main.$el.hide();
+ this.group_view.$el.hide();
+ this.charts_view.$el.hide();
// set elements
this.setElement(this.portlet.$el);
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/config.js
--- a/config/plugins/visualizations/charts/static/config.js
+++ /dev/null
@@ -1,219 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'],
- function(Portlet, Table, Ui, Utils, Group) {
-
-// chart config
-return Backbone.View.extend(
-{
- // model
- group: new Group(),
-
- // columns
- columns: [],
-
- // initialize
- initialize: function(app, options) {
- // link app
- this.app = app;
-
- // get current chart object
- this.chart = this.app.chart;
-
- // ui elements
- this.message = new Ui.Message();
- this.label = new Ui.Input({placeholder: 'Group label'});
- this.table = new Table({content: 'No data column.'});
-
- // add table to portlet
- var self = this;
- this.portlet = new Portlet({
- icon : 'fa-edit',
- label : 'Define group properties:',
- operations : {
- 'save' : new Ui.ButtonIcon({
- icon : 'fa-save',
- tooltip : 'Save',
- onclick : function() {
- // save/add group
- self._saveGroup();
- }
- }),
- 'back' : new Ui.ButtonIcon({
- icon : 'fa-caret-left',
- tooltip : 'Return',
- onclick : function() {
- self.$el.hide();
- self.app.create.$el.show();
- }
- })
- }
- });
- this.portlet.append(this.message.$el);
- this.portlet.append(this.label.$el);
- this.portlet.append(this.table.$el);
-
- // add element
- this.setElement(this.portlet.$el);
-
- // change
- var self = this;
- this.chart.on('change:dataset_id', function() {
- self._refreshDataset();
- });
- this.chart.on('change:type', function() {
- self._refreshType();
- });
- this.group.on('change:label', function() {
- self._refreshLabel();
- });
- this.group.on('change', function() {
- self._refreshGroup();
- });
- },
-
- // show
- show: function() {
- this.$el.show();
- },
-
- // reset
- reset: function() {
- this.group.reset();
- this.group.set('id', Utils.uuid());
- this.group.set('label', 'Group label');
- },
-
- // update dataset
- _refreshDataset: function() {
- // identify datasets
- var dataset_id = this.chart.get('dataset_id');
-
- // check if dataset is available
- if (!dataset_id) {
- return;
- }
-
- // get dataset
- var dataset = this.app.datasets.get({id : dataset_id});
-
- // check
- if (!dataset) {
- this.app.log('Config::render()', 'Failed to retrieve dataset.');
- return;
- }
-
- // configure columns
- this.columns = [];
- var meta = dataset.metadata_column_types;
- for (var key in meta){
- this.columns.push({
- 'label' : key + ' [' + meta[key] + ']',
- 'value' : key
- });
- }
-
- // update select fields
- for (var key in this.list) {
- this.list[key].update(this.columns);
- }
- },
-
- // update
- _refreshType: function() {
- // configure chart type
- var self = this;
- var chart_type = this.chart.get('type');
- if (chart_type) {
- var chart_settings = this.app.types.get(chart_type);
-
- // table
- this.table.removeAll();
- this.list = {};
- for (var id in chart_settings.data) {
- // create select field
- var data_def = chart_settings.data[id];
- var select = new Ui.Select({
- id : 'select_' + id,
- gid : id,
- data : this.columns,
- onchange : function(value) {
- self.group.set(this.gid, value);
- }
- });
-
- // add row to table
- this.table.add(data_def.title);
- this.table.add(select.$el);
- this.table.append(id);
-
- // add select field to list
- this.list[id] = select;
- }
- }
- },
-
- // update
- _refreshGroup: function() {
- // update select fields
- for (var id in this.list) {
- var col = this.group.get(id);
- if (col === undefined) {
- col = 0;
- }
- this.list[id].value(col);
- }
- },
-
- // update label
- _refreshLabel: function() {
- var label_text = this.group.get('label');
- if (label_text === undefined) {
- label_text = '';
- }
- this.label.value(label_text);
- },
-
- // create group
- _saveGroup: function() {
- // get current chart
- var chart = this.chart;
-
- // update group object
- var group = this.group;
- for (var key in this.list) {
- group.set(key, this.list[key].value());
- }
-
- // add label
- group.set({
- dataset_id : this.chart.get('dataset_id'),
- label : this.label.value(),
- date : Utils.time()
- });
-
- // validate
- if (!group.get('label')) {
- this.message.update({message : 'Please enter a label for your group.'});
- return;
- }
-
- // get groups of current chart
- var groups = this.chart.groups;
-
- // create/update group
- var group_update = groups.get(group.id);
- if (group_update) {
- group_update.set(group.attributes);
- } else {
- groups.add(group.clone());
- }
-
- // hide
- this.$el.hide();
-
- // update main
- this.app.create.$el.show();
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/create.js
--- a/config/plugins/visualizations/charts/static/create.js
+++ /dev/null
@@ -1,207 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/chart', 'groups'],
- function(Portlet, Table, Ui, Utils, Chart, Groups) {
-
-// widget
-return Backbone.View.extend(
-{
- // defaults options
- optionsDefault: {
- header : true,
- content : 'No content available.'
- },
-
- // current chart
- chart : null,
-
- // initialize
- initialize: function(app, options)
- {
- // link application
- this.app = app;
-
- // get current chart object
- this.chart = this.app.chart;
-
- // configure options
- this.options = Utils.merge(options, this.optionsDefault);
-
- // main elements
- this.message = new Ui.Message();
- this.title = new Ui.Input({placeholder: 'Chart title'});
- this.dataset = new Ui.Input({value : app.options.dataset.id, disabled: true, visible: false});
-
- // configure dataset
- this.groups = new Groups(this.app);
-
- // table
- var self = this;
- this.table = new Table({
- header : false,
- onconfirm : function(type) {
- if (self.chart.groups.length > 0) {
- // show modal
- self.app.modal.show({
- title : 'Switching the chart type?',
- body : 'You configured data sources. If you switch chart types your configurations will be removed.',
- buttons : {
- 'Cancel' : function() {
- // hide modal
- self.app.modal.hide();
- },
- 'Continue' : function() {
- // hide modal
- self.app.modal.hide();
-
- // confirm
- self.table.confirm(type);
- }
- }
- });
- } else {
- // confirm
- self.table.confirm(type);
- }
- },
- onchange : function(type) {
- // update chart type
- self.chart.set({type: type});
-
- // reset groups
- self.chart.groups.reset();
- },
- content: 'No chart types available'
- });
-
- // add types
- var types_n = 0;
- var types = app.types.attributes;
- for (var id in types){
- var chart_type = types[id];
- this.table.add (++types_n + '.');
- this.table.add (chart_type.title);
- this.table.append(id);
- }
-
- // add table to portlet
- var self = this;
- this.portlet = new Portlet({
- icon : 'fa-edit',
- label : 'Create a new chart:',
- operations : {
- 'save' : new Ui.ButtonIcon({
- icon : 'fa-save',
- tooltip : 'Save Chart',
- onclick : function() {
- self._saveChart();
- }
- }),
- 'back' : new Ui.ButtonIcon({
- icon : 'fa-caret-left',
- tooltip : 'Return',
- onclick : function() {
- self.$el.hide();
- self.app.main.$el.show();
- }
- })
- }
- });
- this.portlet.append(this.message.$el);
- this.portlet.append(this.dataset.$el);
- this.portlet.append((new Ui.Label({ label : 'Provide a chart title:'})).$el);
- this.portlet.append(this.title.$el);
- this.portlet.append((new Ui.Label({ label : 'Select a chart type:'})).$el);
- this.portlet.append(this.table.$el);
- this.portlet.append(this.groups.$el);
-
- // elements
- this.setElement(this.portlet.$el);
-
- // hide back button on startup
- this.portlet.hideOperation('back');
-
- // model events
- var self = this;
- this.chart.on('change:title', function(chart) {
- self.title.value(chart.get('title'));
- });
- this.chart.on('change:type', function(chart) {
- self.table.value(chart.get('type'));
- });
-
- // collection events
- this.app.charts.on('add', function(chart) {
- self.portlet.showOperation('back');
- });
- this.app.charts.on('remove', function(chart) {
- if (self.app.charts.length == 1) {
- self.portlet.hideOperation('back');
- }
- });
- this.app.charts.on('reset', function(chart) {
- self.portlet.hideOperation('back');
- });
-
- // reset
- this.reset();
- },
-
- // reset
- reset: function() {
- this.chart.reset();
- this.chart.set('id', Utils.uuid());
- this.chart.set('dataset_id', this.app.options.dataset.id);
- this.chart.set('type', 'bardiagram');
- this.chart.set('title', 'Chart title');
- },
-
- // set chart
- setChart: function(new_chart) {
- this.chart.copy(new_chart);
- },
-
- // create chart
- _saveChart: function() {
- // update chart data
- this.chart.set({
- type : this.table.value(),
- title : this.title.value(),
- dataset_id : this.dataset.value(),
- date : Utils.time()
- });
-
- // validate
- if (!this.chart.get('title')) {
- this.message.update({message : 'Please enter a title for your chart.'});
- return;
- }
-
- if (!this.chart.get('type')) {
- this.message.update({message : 'Please select a chart type.'});
- return;
- }
-
- if (this.chart.groups.length == 0) {
- this.message.update({message : 'Please configure at least one data source.'});
- return;
- }
-
- // create/get chart
- var current = this.app.charts.get(this.chart.id);
- if (!current) {
- current = this.chart.clone();
- this.app.charts.add(current);
- }
-
- // update chart model
- current.copy(this.chart);
-
- // hide
- this.$el.hide();
-
- // update main
- this.app.main.$el.show();
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/groups.js
--- a/config/plugins/visualizations/charts/static/groups.js
+++ /dev/null
@@ -1,154 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) {
-
-// chart config
-return Backbone.View.extend(
-{
- // initialize
- initialize: function(app, options) {
- // link app
- this.app = app;
-
- // get current chart object
- this.chart = this.app.chart;
-
- // table
- this.table = new Table({
- content : 'Add data columns to this table.',
- ondblclick : function(group_id) {
- // get group
- var group = self.app.chart.groups.get(group_id);
-
- // show edit
- self.app.create.$el.hide();
- self.app.config.show();
- self.app.config.group.set(group.attributes);
- }
- });
-
- // add table to portlet
- var self = this;
- this.portlet = new Portlet({
- icon : '',
- label : 'Select data columns:',
- height : 100,
- operations : {
- 'new' : new Ui.ButtonIcon({
- icon : 'fa-plus',
- tooltip: 'Create',
- onclick: function() {
- self.app.create.$el.hide();
- self.app.config.show();
- self.app.config.reset();
- }
- }),
- 'edit' : new Ui.ButtonIcon({
- icon : 'fa-pencil',
- tooltip: 'Edit',
- onclick: function() {
- // check if element has been selected
- var group_id = self.table.value();
- if (!group_id) {
- return;
- }
-
- // get group
- var group = self.app.chart.groups.get(group_id);
-
- // show edit
- self.app.create.$el.hide();
- self.app.config.show();
- self.app.config.group.set(group.attributes);
- }
- }),
- 'delete' : new Ui.ButtonIcon({
- icon : 'fa-minus',
- tooltip: 'Delete',
- onclick: function() {
- // check if element has been selected
- var id = self.table.value();
- if (!id) {
- return;
- }
- // remove group from chart
- self.chart.groups.remove(id);
- }
- })
- }
- });
- this.portlet.append(this.table.$el);
-
- // add element
- this.setElement(this.portlet.$el);
-
- // change
- var self = this;
- this.chart.on('change', function() {
- self._refresh();
- });
- this.chart.on('reset', function() {
- self._removeGroupAll();
- });
- this.chart.on('change:type', function() {
- self.app.config.trigger('change');
- });
- this.chart.groups.on('add', function(group) {
- self._addGroup(group);
- });
- this.chart.groups.on('remove', function(group) {
- self._removeGroup(group);
- });
- this.chart.groups.on('reset', function(group) {
- self._removeGroupAll();
- });
- this.chart.groups.on('change', function(group) {
- self._removeGroup(group);
- self._addGroup(group);
- });
- },
-
- // refresh
- _refresh: function() {
- this._removeGroupAll();
- var self = this;
- var groups = this.chart.groups;
- if (groups) {
- groups.each(function(group) { self._addGroup(group); });
- }
- },
-
- // add
- _addGroup: function(group) {
- // make custom info string
- var info = '[';
- var chart_type = this.chart.get('type');
- if (chart_type) {
- var chart_settings = this.app.types.get(chart_type);
- for (var key in chart_settings.data) {
- info += key + '=' + group.get(key) + ', '
- }
- }
- info = info.substring(0, info.length - 2) + ']';
-
- // add to table
- this.table.add(group.get('label'));
- this.table.add(info);
- this.table.add('Last changed: ' + group.get('date'));
- this.table.prepend(group.id);
- this.table.value(group.id);
- },
-
- // remove
- _removeGroup: function(group) {
- // remove from to table
- this.table.remove(group.id);
- },
-
- // data config reset
- _removeGroupAll: function() {
- // reset options table
- this.table.removeAll();
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/library/ui.js
--- a/config/plugins/visualizations/charts/static/library/ui.js
+++ b/config/plugins/visualizations/charts/static/library/ui.js
@@ -48,14 +48,14 @@
this.options = Utils.merge(options, this.optionsDefault);
// create new element
- this.setElement(this.template(this.options));
+ this.setElement(this._template(this.options));
// add event
$(this.el).on('click', options.onclick);
},
// element
- template: function(options) {
+ _template: function(options) {
var str = '<button id="' + options.id + '" type="' + options.type + '" style="margin-right: 5px; float: ' + options.float + ';" type="button" class="btn ' + options.cls + '">';
if (options.icon) {
str += '<i class="icon fa ' + options.icon + '"></i> ' ;
@@ -80,14 +80,14 @@
this.options = Utils.merge(options, this.optionsDefault);
// create new element
- this.setElement(this.template(this.options));
+ this.setElement(this._template(this.options));
// add event
$(this.el).on('click', options.onclick);
},
// element
- template: function(options) {
+ _template: function(options) {
return '<div><a href="javascript:void(0)">' + options.label + '</a></div>';
}
});
@@ -218,7 +218,7 @@
var ButtonMenu = Backbone.View.extend(
{
// main options
- options:
+ optionsDefault:
{
id : '',
title : '',
@@ -237,9 +237,8 @@
// initialize
initialize: function (options)
{
- // read in defaults
- if (options)
- this.options = _.defaults(options, this.options);
+ // get options
+ this.options = Utils.merge(options, this.optionsDefault);
// add template for tab
this.setElement($(this._template(this.options)));
@@ -290,9 +289,8 @@
icon : null
}
- // read in defaults
- if (options)
- menuOptions = _.defaults(options, menuOptions);
+ // get options
+ menuOptions = Utils.merge(options, menuOptions);
// check if submenu element is available
if (!this.$menu)
@@ -388,10 +386,7 @@
// initialize
initialize : function(options) {
// get options
- if (options)
- this.options = _.defaults(options, this.optionsDefault);
- else
- this.options = this.optionsDefault;
+ this.options = Utils.merge(options, this.optionsDefault);
// create new element
this.setElement(this.template(this.options));
@@ -430,11 +425,8 @@
// initialize
initialize : function(options) {
- // get options
- if (options)
- this.options = _.defaults(options, this.optionsDefault);
- else
- this.options = this.optionsDefault;
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
// create new element
this.setElement(this.template(this.options));
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/library/ui.select.js
--- a/config/plugins/visualizations/charts/static/library/ui.select.js
+++ b/config/plugins/visualizations/charts/static/library/ui.select.js
@@ -1,14 +1,14 @@
// dependencies
define(['library/utils'], function(Utils) {
-
// plugin
return Backbone.View.extend(
{
// options
optionsDefault: {
- id : '',
- cls : ''
+ id : '',
+ cls : '',
+ empty : 'No data available'
},
// initialize
@@ -17,21 +17,41 @@
this.options = Utils.merge(options, this.optionsDefault);
// create new element
- this.setElement(this.template(this.options));
+ this.setElement(this._template(this.options));
// add change event
var self = this;
if (this.options.onchange) {
- this.$el.on('change', function() { self.options.onchange(self.value()) });
+ this.$el.on('change', function() { self.options.onchange(self.value()); });
}
+
+ // refresh
+ this._refresh();
},
// value
- value : function (new_val) {
- if (new_val !== undefined) {
- this.$el.val(new_val);
+ value : function (new_value) {
+ // get current id/value
+ var before = this.$el.val();
+
+ // check if new_value is defined
+ if (new_value !== undefined) {
+ this.$el.val(new_value);
}
- return this.$el.val();
+
+ // get current id/value
+ var after = this.$el.val();
+ if(after === undefined) {
+ return null;
+ } else {
+ // fire onchange
+ if ((after != before && this.options.onchange) || this.$el.find('option').length == 1) {
+ this.options.onchange(after);
+ }
+
+ // return current value
+ return after;
+ }
},
// label
@@ -43,6 +63,35 @@
disabled: function() {
return this.$el.is(':disabled');
},
+
+ // enable
+ enable: function() {
+ this.$el.prop('disabled', false);
+ },
+
+ // disable
+ disable: function() {
+ this.$el.prop('disabled', true);
+ },
+
+ // add
+ add: function(options) {
+ // add options
+ $(this.el).append(this._templateOption(options));
+
+ // refresh
+ this._refresh();
+ },
+
+ // remove
+ remove: function(value) {
+ // remove option
+ $(this.el).find('option[value=' + value + ']').remove();
+ $(this.el).trigger('change');
+
+ // refresh
+ this._refresh();
+ },
// render
update: function(options) {
@@ -54,47 +103,46 @@
// add new options
for (var key in options.data) {
- $(this.el).append(this.templateOption(options.data[key]));
+ $(this.el).append(this._templateOption(options.data[key]));
}
- // check if selected value exists
- var exists = 0 != $(this.el).find('option[value=' + selected + ']').length;
+ // add selected value
+ if (this._exists(selected))
+ $(this.el).val(selected);
- // add selected value
- if (exists)
- $(this.el).val(selected);
+ // refresh
+ this._refresh();
},
- // update from url
- updateUrl : function(options, callback) {
- // get json
- var self = this;
- Utils.get(options.url, function(json) {
- // write data into array
- var data = [];
- for (key in json) {
- data.push({label: json[key].name, value: json[key].id});
- }
-
- // check if disabled. do not update disabled select elements.
- if (!self.disabled()) {
- self.update({data: data});
- }
-
- // callback
- if (callback) {
- callback();
- }
- });
+ // refresh
+ _refresh: function() {
+ // remove placeholder
+ $(this.el).find('option[value=null]').remove();
+
+ // count remaining entries
+ var remaining = $(this.el).find('option').length;
+ if (remaining == 0) {
+ // append placeholder
+ $(this.el).append(this._templateOption({value : 'null', label : this.options.empty}));
+ this.disable();
+ } else {
+ this.enable();
+ }
+ },
+
+ // exists
+ _exists: function(value) {
+ // check if selected value exists
+ return 0 != $(this.el).find('option[value=' + value + ']').length;
},
// option
- templateOption: function(options) {
+ _templateOption: function(options) {
return '<option value="' + options.value + '">' + options.label + '</option>';
},
// element
- template: function(options) {
+ _template: function(options) {
var tmpl = '<select id="' + options.id + '" class="select ' + options.cls + ' ' + options.id + '">';
for (key in options.data) {
// options
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/library/utils.js
--- a/config/plugins/visualizations/charts/static/library/utils.js
+++ b/config/plugins/visualizations/charts/static/library/utils.js
@@ -6,21 +6,6 @@
request('GET', url, {}, success, error);
};
-// delete
-function del (url, success, error) {
- request('DELETE', url, {}, success, error);
-};
-
-// post
-function post (url, data, success, error) {
- request('POST', url, data, success, error);
-};
-
-// put
-function put (url, data, success, error) {
- request('PUT', url, data, success, error);
-};
-
// generic function to send json to url
function request (method, url, data, success, error) {
@@ -134,11 +119,8 @@
return {
cssLoadFile : cssLoadFile,
cssGetAttribute : cssGetAttribute,
+ get : get,
merge : merge,
- get : get,
- post : post,
- del : del,
- put : put,
request: request,
uuid: uuid,
wrap : wrap,
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/main.js
--- a/config/plugins/visualizations/charts/static/main.js
+++ /dev/null
@@ -1,150 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) {
-
-// widget
-return Backbone.View.extend(
-{
- // initialize
- initialize: function(app, options)
- {
- // link app
- this.app = app;
-
- // table
- this.table = new Table({
- content : 'Add charts to this table.',
- ondblclick : function(chart_id) {
- // get chart
- var chart = self.app.charts.get(chart_id);
-
- // show edit
- self.$el.hide();
-
- // update model and show create
- self.app.create.setChart(chart);
- self.app.create.$el.show();
- },
- onchange : function(chart_id) {
- self.app.viewport.show(chart_id);
- }
- });
-
- // add table to portlet
- var self = this;
- this.portlet = new Portlet({
- icon : 'fa-list',
- label : 'List of created charts:',
- height : 100,
- operations : {
- 'new' : new Ui.ButtonIcon({
- icon : 'fa-plus',
- tooltip: 'Create',
- onclick: function() {
- self.$el.hide();
- self.app.create.reset();
- self.app.create.$el.show();
- }
- }),
- 'edit' : new Ui.ButtonIcon({
- icon : 'fa-pencil',
- tooltip: 'Edit',
- onclick: function() {
- // check if element has been selected
- var chart_id = self.table.value();
- if (!chart_id) {
- return;
- }
-
- // get chart
- var chart = self.app.charts.get(chart_id);
-
- // show edit
- self.$el.hide();
- self.app.create.$el.show();
- self.app.create.setChart(chart);
- }
- }),
- 'delete' : new Ui.ButtonIcon({
- icon : 'fa-minus',
- tooltip: 'Delete',
- onclick: function() {
-
- // check if element has been selected
- var chart_id = self.table.value();
- if (!chart_id) {
- return;
- }
-
- // title
- var chart = self.app.charts.get(chart_id);
-
- // show modal
- self.app.modal.show({
- title : 'Are you sure?',
- body : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.',
- buttons : {
- 'Cancel' : function() {self.app.modal.hide();},
- 'Delete' : function() {
- // hide modal
- self.app.modal.hide();
-
- // remove chart
- self.app.charts.remove(chart_id);
- }
- }
- });
- }
- }),
- }
- });
- this.portlet.append(this.table.$el);
-
- // append to main
- this.$el.append(this.portlet.$el);
-
- // events
- var self = this;
- this.app.charts.on('add', function(chart) {
- // add
- self._addChart(chart);
- });
- this.app.charts.on('remove', function(chart) {
- // remove
- self._removeChart(chart);
- });
- this.app.charts.on('change', function(chart) {
- // replace
- self._removeChart(chart);
- self._addChart(chart);
- });
- },
-
- // append
- append : function($el) {
- this.$el.append(Utils.wrap(''));
- this.$el.append($el);
- },
-
- // add
- _addChart: function(chart) {
- // add title to table
- this.table.add(chart.get('title'));
-
- // get chart type
- var type = this.app.types.get(chart.get('type'));
- this.table.add(type.title);
-
- // add additional columns
- this.table.add('Last change: ' + chart.get('date'));
- this.table.prepend(chart.get('id'));
- this.table.value(chart.get('id'));
- },
-
- // remove
- _removeChart: function(chart) {
- // remove from to table
- this.table.remove(chart.id);
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/viewport.js
--- a/config/plugins/visualizations/charts/static/viewport.js
+++ /dev/null
@@ -1,202 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/ui', 'library/utils'],
- function(Portlet, Ui, Utils) {
-
-// widget
-return Backbone.View.extend(
-{
- // list
- list: {},
-
- // options
- optionsDefault :
- {
- height : 300
- },
-
- // initialize
- initialize: function(app, options)
- {
- // link app
- this.app = app;
-
- // link options
- this.options = Utils.merge(options, this.optionsDefault);
-
- // add table to portlet
- this.portlet = new Portlet({
- height : this.options.height,
- overflow : 'hidden'
- });
-
- // set this element
- this.setElement(this.portlet.$el);
-
- // events
- var self = this;
-
- // add
- this.app.charts.on('add', function(chart) {
- self._addChart(chart);
- });
-
- // remove
- this.app.charts.on('remove', function(chart) {
- self._removeChart(chart.id);
- });
-
- // replace
- this.app.charts.on('change', function(chart) {
- self._removeChart(chart.id);
- self._addChart(chart);
- });
- },
-
- // show
- show: function(id) {
- // hide all
- this.$el.find('svg').hide();
-
- var item = this.list[id];
- if (item) {
- // show selected chart
- this.$el.find(item.svg_id).show();
-
- // this trigger d3 update events
- $(window).trigger('resize');
- }
- },
-
- // add
- _addChart: function(chart) {
- // make sure that svg does not exist already
- this._removeChart(chart.id);
-
- // create id
- var svg_id = '#svg_' + chart.id;
-
- // create element
- var chart_el = $(this._template({id: svg_id, height : this.options.height}));
-
- // add to portlet
- this.portlet.append(chart_el);
-
- // backup id
- this.list[chart.id] = {
- svg_id : svg_id
- }
-
- // identify chart type
- var chart_type = chart.get('type');
- var chart_settings = this.app.types.get(chart_type);
-
- // create chart view
- var self = this;
- require(['charts/' + chart_type], function(ChartView) {
- // create chart
- var view = new ChartView(self.app, {svg_id : svg_id, chart : chart});
-
- // reset chart data
- var chart_data = [];
-
- // request data
- var chart_index = 0;
- chart.groups.each(function(group) {
-
- // add group data
- chart_data.push({
- key : (chart_index + 1) + ':' + group.get('label'),
- values : []
- });
-
- // get data
- for (var key in chart_settings.data) {
- // configure request
- var data_options = {
- view : view,
- data : chart_data,
- index : chart_index,
- dataset_id : group.get('dataset_id'),
- column : group.get(key),
- column_key : key
- }
-
- // make request
- self._data(data_options);
- }
-
- // count
- chart_index++;
- });
-
- // add view
- self.list[chart.id].view = view;
- });
- },
-
- // data
- _data: function(options) {
- // gather objects
- var view = options.view;
- var data = options.data;
-
- // gather parameters
- var index = options.index;
- var column = options.column;
- var dataset_id = options.dataset_id;
- var column_key = options.column_key;
- var group_data = data[options.index];
-
- // send request
- self.app.datasets.get({id : dataset_id, column: column}, function(dataset) {
- // select column
- var values = dataset.values[column];
- var n_values = values.length;
-
- // read column values
- var column_values = [];
- for (var i = 0; i < n_values; i++) {
- var value = values[i];
- if(!isNaN(value)) {
- column_values.push(value);
- } else {
- column_values.push(0)
- }
- }
-
- // write column values
- for (var i = 0; i < n_values; i++) {
- // make sure dictionary exists
- if (group_data.values[i] === undefined) {
- group_data.values[i] = {
- x : i,
- y : 0
- }
- }
-
- // write data
- group_data.values[i][column_key] = column_values[i];
- }
-
- // refresh view
- view.refresh(data);
- });
-
- },
-
- // remove
- _removeChart: function(id) {
- var item = this.list[id];
- if (item) {
- d3.select(item.svg_id).remove();
- $(item.svg_id).remove();
- }
- },
-
- // template
- _template: function(options) {
- return '<svg id="' + options.id.substr(1) + '"style="height: ' + options.height + 'px;"></svg>';
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/views/chart.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/views/chart.js
@@ -0,0 +1,204 @@
+// dependencies
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/chart', 'views/groups'],
+ function(Portlet, Table, Ui, Utils, Chart, GroupsView) {
+
+// widget
+return Backbone.View.extend(
+{
+ // defaults options
+ optionsDefault: {
+ header : true,
+ content : 'No content available.'
+ },
+
+ // initialize
+ initialize: function(app, options)
+ {
+ // link application
+ this.app = app;
+
+ // get current chart object
+ this.chart = this.app.chart;
+
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // main elements
+ this.message = new Ui.Message();
+ this.title = new Ui.Input({placeholder: 'Chart title'});
+ this.dataset = new Ui.Input({value : app.options.dataset.id, disabled: true, visible: false});
+
+ // configure dataset
+ this.groups_view = new GroupsView(this.app);
+
+ // table
+ var self = this;
+ this.table = new Table({
+ header : false,
+ onconfirm : function(type) {
+ if (self.chart.groups.length > 0) {
+ // show modal
+ self.app.modal.show({
+ title : 'Switching the chart type?',
+ body : 'You configured data sources. If you switch chart types your configurations will be removed.',
+ buttons : {
+ 'Cancel' : function() {
+ // hide modal
+ self.app.modal.hide();
+ },
+ 'Continue' : function() {
+ // hide modal
+ self.app.modal.hide();
+
+ // confirm
+ self.table.confirm(type);
+ }
+ }
+ });
+ } else {
+ // confirm
+ self.table.confirm(type);
+ }
+ },
+ onchange : function(type) {
+ // update chart type
+ self.chart.set({type: type});
+
+ // reset groups
+ self.chart.groups.reset();
+ },
+ content: 'No chart types available'
+ });
+
+ // add types
+ var types_n = 0;
+ var types = app.types.attributes;
+ for (var id in types){
+ var chart_type = types[id];
+ this.table.add (++types_n + '.');
+ this.table.add (chart_type.title);
+ this.table.append(id);
+ }
+
+ // add table to portlet
+ var self = this;
+ this.portlet = new Portlet({
+ icon : 'fa-edit',
+ label : 'Create a new chart:',
+ operations : {
+ 'save' : new Ui.ButtonIcon({
+ icon : 'fa-save',
+ tooltip : 'Save Chart',
+ onclick : function() {
+ self._saveChart();
+ }
+ }),
+ 'back' : new Ui.ButtonIcon({
+ icon : 'fa-caret-left',
+ tooltip : 'Return',
+ onclick : function() {
+ self.$el.hide();
+ self.app.charts_view.$el.show();
+ }
+ })
+ }
+ });
+ this.portlet.append(this.message.$el);
+ this.portlet.append(this.dataset.$el);
+ this.portlet.append((new Ui.Label({ label : 'Provide a chart title:'})).$el);
+ this.portlet.append(this.title.$el);
+ this.portlet.append((new Ui.Label({ label : 'Select a chart type:'})).$el);
+ this.portlet.append(this.table.$el);
+ this.portlet.append(this.groups_view.$el);
+
+ // elements
+ this.setElement(this.portlet.$el);
+
+ // hide back button on startup
+ this.portlet.hideOperation('back');
+
+ // model events
+ var self = this;
+ this.chart.on('change:title', function(chart) {
+ self.title.value(chart.get('title'));
+ });
+ this.chart.on('change:type', function(chart) {
+ self.table.value(chart.get('type'));
+ });
+
+ // collection events
+ this.app.charts.on('add', function(chart) {
+ self.portlet.showOperation('back');
+ });
+ this.app.charts.on('remove', function(chart) {
+ if (self.app.charts.length == 1) {
+ self.portlet.hideOperation('back');
+ }
+ });
+ this.app.charts.on('reset', function(chart) {
+ self.portlet.hideOperation('back');
+ });
+
+ // reset
+ this.reset();
+ },
+
+ // reset
+ reset: function() {
+ this.chart.reset();
+ this.chart.set('id', Utils.uuid());
+ this.chart.set('dataset_id', this.app.options.dataset.id);
+ this.chart.set('type', 'bardiagram');
+ this.chart.set('title', 'Chart title');
+ },
+
+ // set chart
+ setChart: function(new_chart) {
+ this.chart.copy(new_chart);
+ },
+
+ // create chart
+ _saveChart: function() {
+ // update chart data
+ this.chart.set({
+ type : this.table.value(),
+ title : this.title.value(),
+ dataset_id : this.dataset.value(),
+ date : Utils.time()
+ });
+
+ // validate
+ if (!this.chart.get('title')) {
+ this.message.update({message : 'Please enter a title for your chart.'});
+ return;
+ }
+
+ if (!this.chart.get('type')) {
+ this.message.update({message : 'Please select a chart type.'});
+ return;
+ }
+
+ if (this.chart.groups.length == 0) {
+ this.message.update({message : 'Please configure at least one data source.'});
+ return;
+ }
+
+ // create/get chart
+ var current = this.app.charts.get(this.chart.id);
+ if (!current) {
+ current = this.chart.clone();
+ this.app.charts.add(current);
+ }
+
+ // update chart model
+ current.copy(this.chart);
+
+ // hide
+ this.$el.hide();
+
+ // update main
+ this.app.charts_view.$el.show();
+ }
+});
+
+});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/views/charts.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/views/charts.js
@@ -0,0 +1,150 @@
+// dependencies
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options)
+ {
+ // link app
+ this.app = app;
+
+ // table
+ this.table = new Table({
+ content : 'Add charts to this table.',
+ ondblclick : function(chart_id) {
+ // get chart
+ var chart = self.app.charts.get(chart_id);
+
+ // show edit
+ self.$el.hide();
+
+ // update model and show create
+ self.app.chart_view.setChart(chart);
+ self.app.chart_view.$el.show();
+ },
+ onchange : function(chart_id) {
+ self.app.viewport_view.show(chart_id);
+ }
+ });
+
+ // add table to portlet
+ var self = this;
+ this.portlet = new Portlet({
+ icon : 'fa-list',
+ label : 'List of created charts:',
+ height : 100,
+ operations : {
+ 'new' : new Ui.ButtonIcon({
+ icon : 'fa-plus',
+ tooltip: 'Create',
+ onclick: function() {
+ self.$el.hide();
+ self.app.chart_view.reset();
+ self.app.chart_view.$el.show();
+ }
+ }),
+ 'edit' : new Ui.ButtonIcon({
+ icon : 'fa-pencil',
+ tooltip: 'Edit',
+ onclick: function() {
+ // check if element has been selected
+ var chart_id = self.table.value();
+ if (!chart_id) {
+ return;
+ }
+
+ // get chart
+ var chart = self.app.charts.get(chart_id);
+
+ // show edit
+ self.$el.hide();
+ self.app.chart_view.$el.show();
+ self.app.chart_view.setChart(chart);
+ }
+ }),
+ 'delete' : new Ui.ButtonIcon({
+ icon : 'fa-minus',
+ tooltip: 'Delete',
+ onclick: function() {
+
+ // check if element has been selected
+ var chart_id = self.table.value();
+ if (!chart_id) {
+ return;
+ }
+
+ // title
+ var chart = self.app.charts.get(chart_id);
+
+ // show modal
+ self.app.modal.show({
+ title : 'Are you sure?',
+ body : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.',
+ buttons : {
+ 'Cancel' : function() {self.app.modal.hide();},
+ 'Delete' : function() {
+ // hide modal
+ self.app.modal.hide();
+
+ // remove chart
+ self.app.charts.remove(chart_id);
+ }
+ }
+ });
+ }
+ }),
+ }
+ });
+ this.portlet.append(this.table.$el);
+
+ // append to main
+ this.$el.append(this.portlet.$el);
+
+ // events
+ var self = this;
+ this.app.charts.on('add', function(chart) {
+ // add
+ self._addChart(chart);
+ });
+ this.app.charts.on('remove', function(chart) {
+ // remove
+ self._removeChart(chart);
+ });
+ this.app.charts.on('change', function(chart) {
+ // replace
+ self._removeChart(chart);
+ self._addChart(chart);
+ });
+ },
+
+ // append
+ append : function($el) {
+ this.$el.append(Utils.wrap(''));
+ this.$el.append($el);
+ },
+
+ // add
+ _addChart: function(chart) {
+ // add title to table
+ this.table.add(chart.get('title'));
+
+ // get chart type
+ var type = this.app.types.get(chart.get('type'));
+ this.table.add(type.title);
+
+ // add additional columns
+ this.table.add('Last change: ' + chart.get('date'));
+ this.table.prepend(chart.get('id'));
+ this.table.value(chart.get('id'));
+ },
+
+ // remove
+ _removeChart: function(chart) {
+ // remove from to table
+ this.table.remove(chart.id);
+ }
+});
+
+});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/views/group.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/views/group.js
@@ -0,0 +1,219 @@
+// dependencies
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'],
+ function(Portlet, Table, Ui, Utils, Group) {
+
+// chart config
+return Backbone.View.extend(
+{
+ // model
+ group: new Group(),
+
+ // columns
+ columns: [],
+
+ // initialize
+ initialize: function(app, options) {
+ // link app
+ this.app = app;
+
+ // get current chart object
+ this.chart = this.app.chart;
+
+ // ui elements
+ this.message = new Ui.Message();
+ this.label = new Ui.Input({placeholder: 'Group label'});
+ this.table = new Table({content: 'No data column.'});
+
+ // add table to portlet
+ var self = this;
+ this.portlet = new Portlet({
+ icon : 'fa-edit',
+ label : 'Define group properties:',
+ operations : {
+ 'save' : new Ui.ButtonIcon({
+ icon : 'fa-save',
+ tooltip : 'Save',
+ onclick : function() {
+ // save/add group
+ self._saveGroup();
+ }
+ }),
+ 'back' : new Ui.ButtonIcon({
+ icon : 'fa-caret-left',
+ tooltip : 'Return',
+ onclick : function() {
+ self.$el.hide();
+ self.app.chart_view.$el.show();
+ }
+ })
+ }
+ });
+ this.portlet.append(this.message.$el);
+ this.portlet.append(this.label.$el);
+ this.portlet.append(this.table.$el);
+
+ // add element
+ this.setElement(this.portlet.$el);
+
+ // change
+ var self = this;
+ this.chart.on('change:dataset_id', function() {
+ self._refreshDataset();
+ });
+ this.chart.on('change:type', function() {
+ self._refreshType();
+ });
+ this.group.on('change:label', function() {
+ self._refreshLabel();
+ });
+ this.group.on('change', function() {
+ self._refreshGroup();
+ });
+ },
+
+ // show
+ show: function() {
+ this.$el.show();
+ },
+
+ // reset
+ reset: function() {
+ this.group.reset();
+ this.group.set('id', Utils.uuid());
+ this.group.set('label', 'Group label');
+ },
+
+ // update dataset
+ _refreshDataset: function() {
+ // identify datasets
+ var dataset_id = this.chart.get('dataset_id');
+
+ // check if dataset is available
+ if (!dataset_id) {
+ return;
+ }
+
+ // get dataset
+ var dataset = this.app.datasets.get({id : dataset_id});
+
+ // check
+ if (!dataset) {
+ this.app.log('Config::render()', 'Failed to retrieve dataset.');
+ return;
+ }
+
+ // configure columns
+ this.columns = [];
+ var meta = dataset.metadata_column_types;
+ for (var key in meta){
+ this.columns.push({
+ 'label' : key + ' [' + meta[key] + ']',
+ 'value' : key
+ });
+ }
+
+ // update select fields
+ for (var key in this.list) {
+ this.list[key].update(this.columns);
+ }
+ },
+
+ // update
+ _refreshType: function() {
+ // configure chart type
+ var self = this;
+ var chart_type = this.chart.get('type');
+ if (chart_type) {
+ var chart_settings = this.app.types.get(chart_type);
+
+ // table
+ this.table.removeAll();
+ this.list = {};
+ for (var id in chart_settings.data) {
+ // create select field
+ var data_def = chart_settings.data[id];
+ var select = new Ui.Select({
+ id : 'select_' + id,
+ gid : id,
+ data : this.columns,
+ onchange : function(value) {
+ self.group.set(this.gid, value);
+ }
+ });
+
+ // add row to table
+ this.table.add(data_def.title);
+ this.table.add(select.$el);
+ this.table.append(id);
+
+ // add select field to list
+ this.list[id] = select;
+ }
+ }
+ },
+
+ // update
+ _refreshGroup: function() {
+ // update select fields
+ for (var id in this.list) {
+ var col = this.group.get(id);
+ if (col === undefined) {
+ col = 0;
+ }
+ this.list[id].value(col);
+ }
+ },
+
+ // update label
+ _refreshLabel: function() {
+ var label_text = this.group.get('label');
+ if (label_text === undefined) {
+ label_text = '';
+ }
+ this.label.value(label_text);
+ },
+
+ // create group
+ _saveGroup: function() {
+ // get current chart
+ var chart = this.chart;
+
+ // update group object
+ var group = this.group;
+ for (var key in this.list) {
+ group.set(key, this.list[key].value());
+ }
+
+ // add label
+ group.set({
+ dataset_id : this.chart.get('dataset_id'),
+ label : this.label.value(),
+ date : Utils.time()
+ });
+
+ // validate
+ if (!group.get('label')) {
+ this.message.update({message : 'Please enter a label for your group.'});
+ return;
+ }
+
+ // get groups of current chart
+ var groups = this.chart.groups;
+
+ // create/update group
+ var group_update = groups.get(group.id);
+ if (group_update) {
+ group_update.set(group.attributes);
+ } else {
+ groups.add(group.clone());
+ }
+
+ // hide
+ this.$el.hide();
+
+ // update main
+ this.app.chart_view.$el.show();
+ }
+});
+
+});
\ No newline at end of file
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: inithello: Fix deletion of test methods after tests have been run.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7b889da9b563/
Changeset: 7b889da9b563
User: inithello
Date: 2014-01-16 17:30:25
Summary: Fix deletion of test methods after tests have been run.
Affected #: 3 files
diff -r 659a29d112f622db5dabb65e4105535b5aee3b30 -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 scripts/functional_tests.py
--- a/scripts/functional_tests.py
+++ b/scripts/functional_tests.py
@@ -498,6 +498,7 @@
functional.test_toolbox.toolbox = app.toolbox
# When testing data managers, do not test toolbox.
functional.test_toolbox.build_tests(
+ app=app,
testing_shed_tools=testing_shed_tools,
master_api_key=master_api_key,
user_api_key=get_user_api_key(),
diff -r 659a29d112f622db5dabb65e4105535b5aee3b30 -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 test/functional/test_toolbox.py
--- a/test/functional/test_toolbox.py
+++ b/test/functional/test_toolbox.py
@@ -72,13 +72,13 @@
raise
-def build_tests( testing_shed_tools=False, master_api_key=None, user_api_key=None ):
+def build_tests( app=None, testing_shed_tools=False, master_api_key=None, user_api_key=None ):
"""
If the module level variable `toolbox` is set, generate `ToolTestCase`
classes for all of its tests and put them into this modules globals() so
they can be discovered by nose.
"""
- if toolbox is None:
+ if app is None:
return
# Push all the toolbox tests to module level
@@ -88,9 +88,8 @@
for key, val in G.items():
if key.startswith( 'TestForTool_' ):
del G[ key ]
-
- for i, tool_id in enumerate( toolbox.tools_by_id ):
- tool = toolbox.get_tool( tool_id )
+ for i, tool_id in enumerate( app.toolbox.tools_by_id ):
+ tool = app.toolbox.get_tool( tool_id )
if isinstance( tool, TOOL_TYPES_NO_TEST ):
#We do not test certain types of tools (e.g. Data Manager tools) as part of ToolTestCase
continue
diff -r 659a29d112f622db5dabb65e4105535b5aee3b30 -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
--- a/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
+++ b/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
@@ -595,21 +595,16 @@
"""
tests_to_delete = []
tools_to_delete_by_id = []
- # Push all the toolbox tests to module level
- G = globals()
- # Eliminate all previous tests from G.
- for key, val in G.items():
- if key.startswith( 'TestForTool_' ):
- del G[ key ]
- # Find all tests previously generated by twill.
for key in test_toolbox.__dict__:
if key.startswith( 'TestForTool_' ):
- log.debug( 'Tool test %s discovered in test_toolbox.' % str( key ) )
# We can't delete this test just yet, we're still iterating over __dict__.
tests_to_delete.append( key )
tool_id = key.replace( 'TestForTool_', '' )
for app_tool_id in app.toolbox.tools_by_id:
- if app_tool_id.replace( '_', ' ' ) == tool_id.replace( '_', ' ' ):
+ # Revisit this code if at some point we notice that Twill re-runs tests that should have been deleted.
+ # Undoubtedly the following if statement will need to be enhanced to find the tool id in question. For
+ # example, the following or is required because Twill replaces some spaces with underscores in test names.
+ if app_tool_id == tool_id or app_tool_id.replace( '_', ' ' ) == tool_id.replace( '_', ' ' ):
tools_to_delete_by_id.append( tool_id )
# Delete the discovered twill-generated tests.
for key in tests_to_delete:
@@ -617,16 +612,12 @@
log.debug( 'Deleting test %s from test_toolbox.' % str( key ) )
del test_toolbox.__dict__[ key ]
for tool_id in tools_to_delete_by_id:
- if tool_id in app.toolbox.tools_by_id:
- log.debug( 'Deleting tool id %s from app.toolbox[ tools_by_id ].' % str( tool_id ) )
- del app.toolbox.tools_by_id[ tool_id ]
+ log.debug( 'Deleting tool id %s from app.toolbox[ tools_by_id ].' % str( tool_id ) )
+ del app.toolbox.tools_by_id[ tool_id ]
def test_repository_tools( app, repository, repository_dict, tool_test_results_dicts, tool_test_results_dict,
install_and_test_statistics_dict ):
"""Test tools contained in the received repository."""
- # Set the global variable 'test_toolbox', so that test.functional.test_toolbox will generate the
- # appropriate test methods.
- test_toolbox.toolbox = app.toolbox
# Get the attributes that identify the repository whose contained tools are being tested.
name = str( repository.name )
owner = str( repository.owner )
@@ -635,7 +626,8 @@
# Generate the test methods for this installed repository. We need to pass testing_shed_tools=True here
# or twill will look in $GALAXY_HOME/test-data for test data, which may result in missing or invalid test
# files.
- test_toolbox.build_tests( testing_shed_tools=True,
+ test_toolbox.build_tests( app=app,
+ testing_shed_tools=True,
master_api_key=install_and_test_base_util.default_galaxy_master_api_key )
# Set up nose to run the generated functional tests.
test_config = nose.config.Config( env=os.environ, plugins=nose.plugins.manager.DefaultPluginManager() )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4f1f6bb5bf5e/
Changeset: 4f1f6bb5bf5e
User: jmchilton
Date: 2014-01-16 16:30:01
Summary: Add tool execution tests for various exceptional conditions.
Tool action raising exception, redirecting, and returning an error message.
Affected #: 1 file
diff -r ff018b067bb21760335de776f7e97a987d86c7e6 -r 4f1f6bb5bf5e975f4d40a8feeeed77795a6d69aa test/unit/tools/test_execution.py
--- a/test/unit/tools/test_execution.py
+++ b/test/unit/tools/test_execution.py
@@ -15,6 +15,10 @@
from galaxy.util.odict import odict
from tools_support import UsesApp
+from galaxy import eggs
+eggs.require( "Paste" )
+from paste import httpexceptions
+
# Simple tool with just one text parameter and output.
SIMPLE_TOOL_CONTENTS = '''<tool id="test_tool" name="Test Tool"><command>echo "$param1" < $out1</command>
@@ -92,6 +96,41 @@
# Didn't specify a rerun_remap_id so this should be None
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] is None
+ def test_execute_exception( self ):
+ self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self.tool_action.raise_exception( )
+ template, template_vars = self.__handle_with_incoming(
+ param1="moo",
+ runtool_btn="dummy",
+ )
+ assert template == "message.mako"
+ assert template_vars[ "status" ] == "error"
+ assert "Error executing tool" in template_vars[ "message" ]
+
+ def test_execute_errors( self ):
+ self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self.tool_action.return_error( )
+ template, template_vars = self.__handle_with_incoming(
+ param1="moo",
+ runtool_btn="dummy",
+ )
+ assert template == "message.mako"
+ assert template_vars[ "status" ] == "error"
+ assert "Test Error Message" in template_vars[ "message" ], template_vars
+
+ def test_redirect( self ):
+ self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self.tool_action.expect_redirect = True
+ redirect_raised = False
+ try:
+ template, template_vars = self.__handle_with_incoming(
+ param1="moo",
+ runtool_btn="dummy",
+ )
+ except httpexceptions.HTTPFound:
+ redirect_raised = True
+ assert redirect_raised
+
def test_remap_job( self ):
self.__init_tool( SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
@@ -237,12 +276,31 @@
def __init__( self, expected_trans ):
self.expected_trans = expected_trans
self.execution_call_args = []
+ self.expect_redirect = False
+ self.exception_after_exection = None
+ self.error_message_after_excution = None
def execute( self, tool, trans, **kwds ):
assert self.expected_trans == trans
self.execution_call_args.append( kwds )
+ num_calls = len( self.execution_call_args )
+ if self.expect_redirect:
+ raise httpexceptions.HTTPFound( "http://google.com" )
+ if self.exception_after_exection is not None:
+ if num_calls > self.exception_after_exection:
+ raise Exception( "Test Exception" )
+ if self.error_message_after_excution is not None:
+ if num_calls > self.error_message_after_excution:
+ return None, "Test Error Message"
+
return None, odict(dict(out1="1"))
+ def raise_exception( self, after_execution=0 ):
+ self.exception_after_exection = after_execution
+
+ def return_error( self, after_execution=0 ):
+ self.error_message_after_excution = after_execution
+
class MockTrans( object ):
https://bitbucket.org/galaxy/galaxy-central/commits/659a29d112f6/
Changeset: 659a29d112f6
User: jmchilton
Date: 2014-01-16 16:30:01
Summary: Rearrange __handle_execute and handle_input in Tool...
Slightly cleaner this way (fewer exit points) and will enable extensions I am making downstream.
Affected #: 1 file
diff -r 4f1f6bb5bf5e975f4d40a8feeeed77795a6d69aa -r 659a29d112f622db5dabb65e4105535b5aee3b30 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -1871,7 +1871,7 @@
errors, params = self.__check_param_values( trans, incoming, state, old_errors, process_state, history=history, source=source )
if self.__should_refresh_state( incoming ):
- return self.__handle_state_refresh( trans, state, errors )
+ template, template_vars = self.__handle_state_refresh( trans, state, errors )
else:
# User actually clicked next or execute.
@@ -1879,18 +1879,30 @@
# error messages
if errors:
error_message = "One or more errors were found in the input you provided. The specific errors are marked below."
- return "tool_form.mako", dict( errors=errors, tool_state=state, incoming=incoming, error_message=error_message )
+ template = "tool_form.mako"
+ template_vars = dict( errors=errors, tool_state=state, incoming=incoming, error_message=error_message )
# If we've completed the last page we can execute the tool
elif all_pages or state.page == self.last_page:
- return self.__handle_tool_execute( trans, rerun_remap_job_id, params, history )
+ tool_executed, result = self.__handle_tool_execute( trans, rerun_remap_job_id, params, history )
+ if tool_executed:
+ template = 'tool_executed.mako'
+ template_vars = dict( out_data=result )
+ else:
+ template = 'message.mako'
+ template_vars = dict( status='error', message=result, refresh_frames=[] )
# Otherwise move on to the next page
else:
- return self.__handle_page_advance( trans, state, errors )
+ template, template_vars = self.__handle_page_advance( trans, state, errors )
+ return template, template_vars
def __should_refresh_state( self, incoming ):
return not( 'runtool_btn' in incoming or 'URL' in incoming or 'ajax_upload' in incoming )
def __handle_tool_execute( self, trans, rerun_remap_job_id, params, history ):
+ """
+ Return a pair with whether execution is successful as well as either
+ resulting output data or an error message indicating the problem.
+ """
try:
_, out_data = self.execute( trans, incoming=params, history=history, rerun_remap_job_id=rerun_remap_job_id )
except httpexceptions.HTTPFound, e:
@@ -1898,16 +1910,16 @@
raise e
except Exception, e:
log.exception('Exception caught while attempting tool execution:')
- return 'message.mako', dict( status='error', message='Error executing tool: %s' % str(e), refresh_frames=[] )
- try:
- assert isinstance( out_data, odict )
- return 'tool_executed.mako', dict( out_data=out_data )
- except:
+ message = 'Error executing tool: %s' % str(e)
+ return False, message
+ if isinstance( out_data, odict ):
+ return True, out_data
+ else:
if isinstance( out_data, str ):
message = out_data
else:
- message = 'Failure executing tool (odict not returned from tool execution)'
- return 'message.mako', dict( status='error', message=message, refresh_frames=[] )
+ message = 'Failure executing tool (invalid data returned from tool execution)'
+ return False, message
def __handle_state_refresh( self, trans, state, errors ):
try:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Explicitly require UsesAnnotations mixin for the annotations api controller *after* UsesStoredWorkflowMixin.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ff018b067bb2/
Changeset: ff018b067bb2
User: dannon
Date: 2014-01-16 15:56:31
Summary: Explicitly require UsesAnnotations mixin for the annotations api controller *after* UsesStoredWorkflowMixin.
Affected #: 1 file
diff -r 2f7781fc4ce9dbb1768fd345621ec2a62000f2ae -r ff018b067bb21760335de776f7e97a987d86c7e6 lib/galaxy/webapps/galaxy/api/annotations.py
--- a/lib/galaxy/webapps/galaxy/api/annotations.py
+++ b/lib/galaxy/webapps/galaxy/api/annotations.py
@@ -3,13 +3,14 @@
"""
import logging
from galaxy import web
+from galaxy.model.item_attrs import UsesAnnotations
from galaxy.util.sanitize_html import sanitize_html
from galaxy.web.base.controller import BaseAPIController, HTTPNotImplemented, UsesHistoryDatasetAssociationMixin, UsesHistoryMixin, UsesStoredWorkflowMixin
log = logging.getLogger( __name__ )
-class BaseAnnotationsController( BaseAPIController, UsesHistoryMixin, UsesHistoryDatasetAssociationMixin, UsesStoredWorkflowMixin ):
+class BaseAnnotationsController( BaseAPIController, UsesHistoryMixin, UsesHistoryDatasetAssociationMixin, UsesStoredWorkflowMixin, UsesAnnotations ):
@web.expose_api
def index( self, trans, **kwd ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0