[ckan-changes] [okfn/ckan] 370e73: Merge branch 'release-v1.7' of https://github.com/...
GitHub
noreply at github.com
Tue May 1 13:58:11 UTC 2012
Branch: refs/heads/release-v1.7
Home: https://github.com/okfn/ckan
Commit: 370e7352991da0e71b2dad8967158fe5f141c480
https://github.com/okfn/ckan/commit/370e7352991da0e71b2dad8967158fe5f141c480
Author: Ross Jones <rossdjones at gmail.com>
Date: 2012-05-01 (Tue, 01 May 2012)
Changed paths:
M ckan/config/middleware.py
M ckan/lib/helpers.py
M ckan/public/scripts/vendor/recline/css/graph.css
M ckan/public/scripts/vendor/recline/recline.js
M ckan/templates/facets.html
M ckan/templates/js_strings.html
M ckan/templates/layout_base.html
Log Message:
-----------
Merge branch 'release-v1.7' of https://github.com/okfn/ckan into release-v1.7
diff --git a/ckan/config/middleware.py b/ckan/config/middleware.py
index 5d2be57..f0dca73 100644
--- a/ckan/config/middleware.py
+++ b/ckan/config/middleware.py
@@ -135,7 +135,8 @@ def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
app = PageCacheMiddleware(app, config)
# Tracking add config option
- app = TrackingMiddleware(app, config)
+ if asbool(config.get('ckan.tracking_enabled', 'false')):
+ app = TrackingMiddleware(app, config)
return app
class I18nMiddleware(object):
diff --git a/ckan/lib/helpers.py b/ckan/lib/helpers.py
index 78924b4..408b912 100644
--- a/ckan/lib/helpers.py
+++ b/ckan/lib/helpers.py
@@ -676,8 +676,8 @@ def group_link(group):
url = url_for(controller='group', action='read', id=group['name'])
return link_to(group['name'], url)
-def dump_json(obj):
- return json.dumps(obj)
+def dump_json(obj, **kw):
+ return json.dumps(obj, **kw)
def auto_log_message(*args):
# auto_log_message() used to need c passing as the first arg
@@ -809,4 +809,5 @@ def process_names(items):
'mail_to',
'radio',
'submit',
+ 'asbool',
]
diff --git a/ckan/public/scripts/vendor/recline/css/graph.css b/ckan/public/scripts/vendor/recline/css/graph.css
index 88acf5f..413ac14 100644
--- a/ckan/public/scripts/vendor/recline/css/graph.css
+++ b/ckan/public/scripts/vendor/recline/css/graph.css
@@ -13,6 +13,11 @@
line-height: 13px;
}
+.recline-graph .graph .alert {
+ width: 450px;
+ margin: auto;
+}
+
/**********************************************************
* Editor
*********************************************************/
diff --git a/ckan/public/scripts/vendor/recline/recline.js b/ckan/public/scripts/vendor/recline/recline.js
index a4c01ca..271e9c5 100644
--- a/ckan/public/scripts/vendor/recline/recline.js
+++ b/ckan/public/scripts/vendor/recline/recline.js
@@ -757,22 +757,13 @@ my.Graph = Backbone.View.extend({
<label>Group Column (x-axis)</label> \
<div class="input editor-group"> \
<select> \
+ <option value="">Please choose ...</option> \
{{#fields}} \
<option value="{{id}}">{{label}}</option> \
{{/fields}} \
</select> \
</div> \
<div class="editor-series-group"> \
- <div class="editor-series"> \
- <label>Series <span>A (y-axis)</span></label> \
- <div class="input"> \
- <select> \
- {{#fields}} \
- <option value="{{id}}">{{label}}</option> \
- {{/fields}} \
- </select> \
- </div> \
- </div> \
</div> \
</div> \
<div class="editor-buttons"> \
@@ -784,13 +775,34 @@ my.Graph = Backbone.View.extend({
</div> \
</form> \
</div> \
- <div class="panel graph"></div> \
+ <div class="panel graph"> \
+ <div class="js-temp-notice alert alert-block"> \
+ <h3 class="alert-heading">Hey there!</h3> \
+ <p>There\'s no graph here yet because we don\'t know what fields you\'d like to see plotted.</p> \
+ <p>Please tell us by <strong>using the menu on the right</strong> and a graph will automatically appear.</p> \
+ </div> \
+ </div> \
</div> \
',
+ templateSeriesEditor: ' \
+ <div class="editor-series js-series-{{seriesIndex}}"> \
+ <label>Series <span>{{seriesName}} (y-axis)</span> \
+ [<a href="#remove" class="action-remove-series">Remove</a>] \
+ </label> \
+ <div class="input"> \
+ <select> \
+ <option value="">Please choose ...</option> \
+ {{#fields}} \
+ <option value="{{id}}">{{label}}</option> \
+ {{/fields}} \
+ </select> \
+ </div> \
+ </div> \
+ ',
events: {
'change form select': 'onEditorSubmit',
- 'click .editor-add': 'addSeries',
+ 'click .editor-add': '_onAddSeries',
'click .action-remove-series': 'removeSeries',
'click .action-toggle-help': 'toggleHelp'
},
@@ -807,7 +819,8 @@ my.Graph = Backbone.View.extend({
this.model.currentDocuments.bind('reset', this.redraw);
var stateData = _.extend({
group: null,
- series: [],
+ // so that at least one series chooser box shows up
+ series: [""],
graphType: 'lines-and-points'
},
options.state
@@ -817,21 +830,45 @@ my.Graph = Backbone.View.extend({
},
render: function() {
- htmls = $.mustache(this.template, this.model.toTemplateJSON());
+ var self = this;
+ var tmplData = this.model.toTemplateJSON();
+ var htmls = $.mustache(this.template, tmplData);
$(this.el).html(htmls);
- // now set a load of stuff up
this.$graph = this.el.find('.panel.graph');
- // for use later when adding additional series
- // could be simpler just to have a common template!
- this.$seriesClone = this.el.find('.editor-series').clone();
- this._updateSeries();
+
+ // set up editor from state
+ if (this.state.get('graphType')) {
+ this._selectOption('.editor-type', this.state.get('graphType'));
+ }
+ if (this.state.get('group')) {
+ this._selectOption('.editor-group', this.state.get('group'));
+ }
+ _.each(this.state.get('series'), function(series, idx) {
+ self.addSeries(idx);
+ self._selectOption('.editor-series.js-series-' + idx, series);
+ });
return this;
},
+ // Private: Helper function to select an option from a select list
+ //
+ _selectOption: function(id,value){
+ var options = this.el.find(id + ' select > option');
+ if (options) {
+ options.each(function(opt){
+ if (this.value == value) {
+ $(this).attr('selected','selected');
+ return false;
+ }
+ });
+ }
+ },
+
onEditorSubmit: function(e) {
var select = this.el.find('.editor-group select');
- $editor = this;
- var series = this.$series.map(function () {
+ var $editor = this;
+ var $series = this.el.find('.editor-series select');
+ var series = $series.map(function () {
return $(this).val();
});
var updatedState = {
@@ -870,10 +907,20 @@ my.Graph = Backbone.View.extend({
// }
},
+ // ### getGraphOptions
+ //
+ // Get options for Flot Graph
+ //
// needs to be function as can depend on state
+ //
+ // @param typeId graphType id (lines, lines-and-points etc)
getGraphOptions: function(typeId) {
var self = this;
// special tickformatter to show labels rather than numbers
+ // TODO: we should really use tickFormatter and 1 interval ticks if (and
+ // only if) x-axis values are non-numeric
+ // However, that is non-trivial to work out from a dataset (datasets may
+ // have no field type info). Thus at present we only do this for bars.
var tickFormatter = function (val) {
if (self.model.currentDocuments.models[val]) {
var out = self.model.currentDocuments.models[val].get(self.state.attributes.group);
@@ -886,20 +933,25 @@ my.Graph = Backbone.View.extend({
}
return val;
};
- // TODO: we should really use tickFormatter and 1 interval ticks if (and
- // only if) x-axis values are non-numeric
- // However, that is non-trivial to work out from a dataset (datasets may
- // have no field type info). Thus at present we only do this for bars.
- var options = {
+
+ var xaxis = {};
+ // check for time series on x-axis
+ if (this.model.fields.get(this.state.get('group')).get('type') === 'date') {
+ xaxis.mode = 'time';
+ xaxis.timeformat = '%y-%b';
+ }
+ var optionsPerGraphType = {
lines: {
- series: {
- lines: { show: true }
- }
+ series: {
+ lines: { show: true }
+ },
+ xaxis: xaxis
},
points: {
series: {
points: { show: true }
},
+ xaxis: xaxis,
grid: { hoverable: true, clickable: true }
},
'lines-and-points': {
@@ -907,6 +959,7 @@ my.Graph = Backbone.View.extend({
points: { show: true },
lines: { show: true }
},
+ xaxis: xaxis,
grid: { hoverable: true, clickable: true }
},
bars: {
@@ -930,7 +983,7 @@ my.Graph = Backbone.View.extend({
}
}
};
- return options[typeId];
+ return optionsPerGraphType[typeId];
},
setupTooltips: function() {
@@ -987,8 +1040,15 @@ my.Graph = Backbone.View.extend({
_.each(this.state.attributes.series, function(field) {
var points = [];
_.each(self.model.currentDocuments.models, function(doc, index) {
- var x = doc.get(self.state.attributes.group);
- var y = doc.get(field);
+ var xfield = self.model.fields.get(self.state.attributes.group);
+ var x = doc.getFieldValue(xfield);
+ // time series
+ var isDateTime = xfield.get('type') === 'date';
+ if (isDateTime) {
+ x = new Date(x);
+ }
+ var yfield = self.model.fields.get(field);
+ var y = doc.getFieldValue(yfield);
if (typeof x === 'string') {
x = index;
}
@@ -1006,23 +1066,25 @@ my.Graph = Backbone.View.extend({
// Public: Adds a new empty series select box to the editor.
//
- // All but the first select box will have a remove button that allows them
- // to be removed.
+ // @param [int] idx index of this series in the list of series
//
// Returns itself.
- addSeries: function (e) {
- e.preventDefault();
- var element = this.$seriesClone.clone(),
- label = element.find('label'),
- index = this.$series.length;
-
- this.el.find('.editor-series-group').append(element);
- this._updateSeries();
- label.append(' [<a href="#remove" class="action-remove-series">Remove</a>]');
- label.find('span').text(String.fromCharCode(this.$series.length + 64));
+ addSeries: function (idx) {
+ var data = _.extend({
+ seriesIndex: idx,
+ seriesName: String.fromCharCode(idx + 64 + 1),
+ }, this.model.toTemplateJSON());
+
+ var htmls = $.mustache(this.templateSeriesEditor, data);
+ this.el.find('.editor-series-group').append(htmls);
return this;
},
+ _onAddSeries: function(e) {
+ e.preventDefault();
+ this.addSeries(this.state.get('series').length);
+ },
+
// Public: Removes a series list item from the editor.
//
// Also updates the labels of the remaining series elements.
@@ -1030,26 +1092,12 @@ my.Graph = Backbone.View.extend({
e.preventDefault();
var $el = $(e.target);
$el.parent().parent().remove();
- this._updateSeries();
- this.$series.each(function (index) {
- if (index > 0) {
- var labelSpan = $(this).prev().find('span');
- labelSpan.text(String.fromCharCode(index + 65));
- }
- });
this.onEditorSubmit();
},
toggleHelp: function() {
this.el.find('.editor-info').toggleClass('editor-hide-info');
},
-
- // Private: Resets the series property to reference the select elements.
- //
- // Returns itself.
- _updateSeries: function () {
- this.$series = this.el.find('.editor-series select');
- }
});
})(jQuery, recline.View);
diff --git a/ckan/templates/facets.html b/ckan/templates/facets.html
index f8c104b..001be8c 100644
--- a/ckan/templates/facets.html
+++ b/ckan/templates/facets.html
@@ -5,7 +5,7 @@
py:strip=""
>
-<!--
+<!--!
Construct a facet <div> populated with links to filtered results.
name
@@ -40,7 +40,7 @@
</div>
</py:def>
-<!--
+<!--!
Generate <li>s for facet items. The generated tags are not wrapped by any
other tag, ie - it's up to the caller to wrap them in something suitable.
@@ -75,7 +75,7 @@
</li>
</py:def>
-<!--
+<!--!
DEPRECATED. Provided only for backward compatibility with existing plugins.
Use `facet_div` instead.
@@ -129,7 +129,7 @@
</div>
</py:def>
-<!--
+<!--!
DEPRECATED. Provided only for backward compatibility with existing plugins.
Use `facet_li` instead.
diff --git a/ckan/templates/js_strings.html b/ckan/templates/js_strings.html
index a22ea2f..1b757bb 100644
--- a/ckan/templates/js_strings.html
+++ b/ckan/templates/js_strings.html
@@ -14,7 +14,7 @@
* Used in application.js.
*/
CKAN.Strings = ${
- h.json.dumps(dict(
+ h.dump_json(dict(
checking = _('Checking...'),
urlIsTooShort = _('Type at least two characters...'),
urlIsUnchanged = _('This is the current URL.'),
diff --git a/ckan/templates/layout_base.html b/ckan/templates/layout_base.html
index a983d4b..9ed0ce6 100644
--- a/ckan/templates/layout_base.html
+++ b/ckan/templates/layout_base.html
@@ -251,9 +251,11 @@ <h3 class="widget-title">Meta</h3>
CKAN.plugins.push('storage');
</py:if>
CKAN.SITE_URL = '${h.url('/')}';
+ CKAN.SITE_URL_NO_LOCALE = '${h.url('/', locale='default')}';
CKAN.LANG = '${h.lang()}';
// later use will add offsets with leading '/' so ensure no trailing slash
CKAN.SITE_URL = CKAN.SITE_URL.replace(/\/$/, '');
+ CKAN.SITE_URL_NO_LOCALE = CKAN.SITE_URL_NO_LOCALE.replace(/\/$/, '');
$(document).ready(function() {
var ckan_user = '${c.user}';
if (ckan_user) {
@@ -266,19 +268,20 @@ <h3 class="widget-title">Meta</h3>
});
</script>
+ <py:if test="h.asbool(config.get('ckan.tracking_enabled', 'false'))">
<script type="text/javascript">
$(function (){
// Tracking
var url = location.pathname;
// remove any site root from url
url = url.substring(CKAN.SITE_URL.length, url.length - 1);
- $.ajax({url : CKAN.SITE_URL + '/_tracking',
+ $.ajax({url : CKAN.SITE_URL_NO_LOCALE + '/_tracking',
type : 'POST',
data : {url:url, type:'page'},
timeout : 300 });
$('a.resource-url-analytics').click(function (e){
var url = $(e.target).closest('a').attr('href');
- $.ajax({url : CKAN.SITE_URL + '/_tracking',
+ $.ajax({url : CKAN.SITE_URL_NO_LOCALE + '/_tracking',
data : {url:url, type:'resource'},
type : 'POST',
complete : function () {location.href = url;},
@@ -287,6 +290,7 @@ <h3 class="widget-title">Meta</h3>
});
});
</script>
+ </py:if>
<py:if test="defined('optional_footer')">
${optional_footer()}
================================================================
Commit: b64dc2f83c0dda80c8af460917d1f1a2f25c4fd7
https://github.com/okfn/ckan/commit/b64dc2f83c0dda80c8af460917d1f1a2f25c4fd7
Author: Ross Jones <rossdjones at gmail.com>
Date: 2012-05-01 (Tue, 01 May 2012)
Changed paths:
A ckanext/multilingual/__init__.py
Log Message:
-----------
Merge branch 'release-v1.7' of https://github.com/okfn/ckan into release-v1.7
diff --git a/ckanext/multilingual/__init__.py b/ckanext/multilingual/__init__.py
new file mode 100644
index 0000000..e69de29
================================================================
Commit: d41a5399b86e23647c33651cc3bafabb677b98bc
https://github.com/okfn/ckan/commit/d41a5399b86e23647c33651cc3bafabb677b98bc
Author: Ross Jones <rossdjones at gmail.com>
Date: 2012-05-01 (Tue, 01 May 2012)
Changed paths:
M ckan/controllers/group.py
M ckan/controllers/home.py
M ckan/lib/dictization/model_dictize.py
M ckan/logic/action/get.py
M ckan/model/group.py
Log Message:
-----------
Fix counts that are including private datasets
diff --git a/ckan/controllers/group.py b/ckan/controllers/group.py
index 95a4597..30e4825 100644
--- a/ckan/controllers/group.py
+++ b/ckan/controllers/group.py
@@ -72,7 +72,8 @@ def index(self):
group_type = self._guess_group_type()
context = {'model': model, 'session': model.Session,
- 'user': c.user or c.author, 'for_view': True}
+ 'user': c.user or c.author, 'for_view': True,
+ 'with_private': False}
data_dict = {'all_fields': True}
diff --git a/ckan/controllers/home.py b/ckan/controllers/home.py
index a675826..cfa139c 100644
--- a/ckan/controllers/home.py
+++ b/ckan/controllers/home.py
@@ -31,7 +31,7 @@ def __before__(self, action, **env):
# TODO: send an email to the admin person (#1285)
else:
raise
-
+
def index(self):
try:
@@ -43,6 +43,7 @@ def index(self):
'facet.field':g.facets,
'rows':0,
'start':0,
+ 'fq': 'capacity:"public"'
}
query = ckan.logic.get_action('package_search')(context,data_dict)
c.package_count = query['count']
diff --git a/ckan/lib/dictization/model_dictize.py b/ckan/lib/dictization/model_dictize.py
index 75fe85e..74aa8b7 100644
--- a/ckan/lib/dictization/model_dictize.py
+++ b/ckan/lib/dictization/model_dictize.py
@@ -15,7 +15,7 @@ def group_list_dictize(obj_list, context,
sort_key=lambda x:x['display_name'], reverse=False):
active = context.get('active', True)
-
+ with_private = context.get('include_private_packages', False)
result_list = []
for obj in obj_list:
@@ -30,7 +30,8 @@ def group_list_dictize(obj_list, context,
group_dict['display_name'] = obj.display_name
- group_dict['packages'] = len(obj.active_packages().all())
+ group_dict['packages'] = \
+ len(obj.active_packages(with_private=with_private).all())
if context.get('for_view'):
for item in plugins.PluginImplementations(
diff --git a/ckan/logic/action/get.py b/ckan/logic/action/get.py
index fd0ce25..b2afe94 100644
--- a/ckan/logic/action/get.py
+++ b/ckan/logic/action/get.py
@@ -491,9 +491,9 @@ def resource_status_show(context, data_dict):
check_access('resource_status_show', context, data_dict)
# needs to be text query as celery tables are not in our model
- q = text("""select status, date_done, traceback, task_status.*
- from task_status left join celery_taskmeta
- on task_status.value = celery_taskmeta.task_id and key = 'celery_task_id'
+ q = text("""select status, date_done, traceback, task_status.*
+ from task_status left join celery_taskmeta
+ on task_status.value = celery_taskmeta.task_id and key = 'celery_task_id'
where entity_id = :entity_id """)
result = model.Session.connection().execute(q, entity_id=id)
diff --git a/ckan/model/group.py b/ckan/model/group.py
index f622a7a..de2e4cd 100644
--- a/ckan/model/group.py
+++ b/ckan/model/group.py
@@ -166,13 +166,18 @@ def get_children_groups(self, type='group'):
from_statement(HIERARCHY_CTE).params(id=self.id, type=type).all()
return [ { "id":idf, "name": name, "title": title } for idf,name,title in results ]
- def active_packages(self, load_eager=True):
+ def active_packages(self, load_eager=True, with_private=False):
query = Session.query(Package).\
filter_by(state=vdm.sqlalchemy.State.ACTIVE).\
filter(group_table.c.id == self.id).\
- filter(member_table.c.state == 'active').\
- join(member_table, member_table.c.table_id == Package.id).\
+ filter(member_table.c.state == 'active')
+
+ if not with_private:
+ query = query.filter(member_table.c.capacity == 'public')
+
+ query = query.join(member_table, member_table.c.table_id == Package.id).\
join(group_table, group_table.c.id == member_table.c.group_id)
+
return query
@classmethod
================================================================
Compare: https://github.com/okfn/ckan/compare/e64a803...d41a539
More information about the ckan-changes
mailing list