Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fact sorting for uptime #591

Merged
merged 9 commits into from
Jan 19, 2022
8 changes: 6 additions & 2 deletions puppetboard/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,15 +705,19 @@ def fact(env, fact, value):
value_json = value_object
else:
value_json = dumps(value_object)

natural_time_delta_sort = False
if fact in ["uptime"]:
natural_time_delta_sort = True
return render_template(
gdubicki marked this conversation as resolved.
Show resolved Hide resolved
'fact.html',
fact=fact,
value=value,
value_json=value_json,
render_graph=render_graph,
envs=envs,
current_env=env)
current_env=env,
natural_time_delta_sort=natural_time_delta_sort
)


@app.route('/fact/<fact>/json',
Expand Down
82 changes: 82 additions & 0 deletions puppetboard/static/custom-natural-time-delta/natural-time-delta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* Created by Shodhan Save on Jan 23, 2018.
* Updated @ Jan 25, 2018
* Modified for the Puppetboard by Greg Dubicki.
*/

/**
* This plug-in allows sorting of human-readable time delta, viz.,
* "1 week", "2 weeks 3 days", "4 weeks 5 days 6 hours", "1:24 hours" etc.
*
* Currently this plugin supports time range from microseconds to decades.
*
* The plugin also takes care of singular and plural values like week(s)
*
* @name Natural Time Delta
* @summary Sort human-readable time delta
*
* @example
* $("#example").DataTable({
* columnDefs: [
* { "type": "natural-time-delta", "targets": 2 }
* ]
* });
*/

jQuery.extend(jQuery.fn.dataTableExt.oSort,{
"natural-time-delta-pre" : function(data){
// get the non-formatted value from title
data = data.match(/title="(.*?)"/)[1].toLowerCase();

var total_duration = 0;
var pattern = /(\d+\s*decades?\s*)?(\d+\s*years?\s*)?(\d+\s*months?\s*)?(\d+\s*weeks?\s*)?(\d+\s*days?\s*)?(\d+:?\d*?\s*hours?\s*)?(\d+\s*minutes?\s*)?(\d+\s*seconds?\s*)?(\d+\s*milliseconds?\s*)?(\d+\s*microseconds?\s*)?/i
var get_duration = function (el, unit_name, duration_in_seconds) {
if (el === undefined) {
return 0;
}

var split_by = unit_name[0]
var no_of_units = el.split(split_by)[0].trim()

if ((unit_name === "hour") && (no_of_units.split(':').length === 2)) {
// this is hour with minutes looking like this: "1:26 hours"
var hours = parseFloat(no_of_units.split(':')[0]);
var minutes = parseFloat(no_of_units.split(':')[1]);
return (hours * 60 * 60) + (minutes * 60);
} else {
return parseFloat(no_of_units) * duration_in_seconds;
}
};

var matches = data.match(pattern);
matches.reverse();

var time_elements = [
{"unit_name": "microsecond", "duration_in_seconds": 1 / 1000 / 1000},
{"unit_name": "millisecond", "duration_in_seconds": 1 / 1000},
{"unit_name": "second", "duration_in_seconds": 1},
{"unit_name": "minute", "duration_in_seconds": 1 * 60},
{"unit_name": "hour", "duration_in_seconds": 1 * 60 * 60},
{"unit_name": "day", "duration_in_seconds": 1 * 60 * 60 * 24},
{"unit_name": "week", "duration_in_seconds": 1 * 60 * 60 * 24 * 7},
{"unit_name": "month", "duration_in_seconds": 1 * 60 * 60 * 24 * 7 * 30},
{"unit_name": "year", "duration_in_seconds": 1 * 60 * 60 * 24 * 7 * 30 * 12},
{"unit_name": "decade", "duration_in_seconds": 1 * 60 * 60 * 24 * 7 * 30 * 12 * 10},
];

time_elements.forEach(function (el, i) {
var duration = get_duration(matches[i], el["unit_name"], el["duration_in_seconds"]);
total_duration += duration;
});

return total_duration || -1;
},

"natural-time-delta-asc" : function (a, b) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},

"natural-time-delta-desc" : function (a, b) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
});
10 changes: 7 additions & 3 deletions puppetboard/templates/_macros.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
{% endif %}
{%- endmacro %}

{% macro datatable_init(table_html_id, ajax_url, data, default_length, length_selector, extra_options=None) -%}
{% macro datatable_init(table_html_id, ajax_url, data, default_length, length_selector, extra_options=None, natural_time_delta_sort=False) -%}

// Init datatable
$.fn.dataTable.ext.errMode = 'throw';

Expand Down Expand Up @@ -97,8 +98,11 @@
url = data[0]
to_show = pretty_print(data[1])

return '<a href="' + url + '">' + to_show + '</a>'
}
return `<a title="${data[1]}" href="${url}">${to_show}</a>`
},
{% if natural_time_delta_sort %}
"type": "natural-time-delta",
{% endif %}
},
{% else -%}
{
Expand Down
6 changes: 5 additions & 1 deletion puppetboard/templates/fact.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
{% extends 'layout.html' %}
{% import '_macros.html' as macros %}
{% block head %}
<script src="{{ url_for('static', filename='custom-natural-time-delta/natural-time-delta.js') }}"></script>
{% endblock head %}

{% block onload_script %}
{% macro extra_options(caller) %}
// No per page AJAX
'serverSide': false,
{% endmacro %}
{{ macros.datatable_init(table_html_id="facts_table", ajax_url=url_for('fact_ajax', env=current_env, fact=fact, value=value), data=None, default_length=config.NORMAL_TABLE_COUNT, length_selector=config.TABLE_COUNT_SELECTOR, extra_options=extra_options) }}

{{ macros.datatable_init(table_html_id="facts_table", ajax_url=url_for('fact_ajax', env=current_env, fact=fact, value=value), data=None, default_length=config.NORMAL_TABLE_COUNT, length_selector=config.TABLE_COUNT_SELECTOR, extra_options=extra_options, natural_time_delta_sort=natural_time_delta_sort) }}

{% if render_graph %}
table.on('xhr', function(e, settings, json){
Expand Down