updated logger on build product page

This commit is contained in:
Vokhmin Alexey V 2012-11-09 21:42:25 +04:00
parent ef967e97ae
commit 8f9cd0ff8a
8 changed files with 182 additions and 188 deletions

View File

@ -0,0 +1,111 @@
function initLogWrapper() {
var $wrapper = $('div.log-wrapper');
var $logBody = $wrapper.children('div.log-body').first();
var $logCont = $logBody.children('.log').first();
var logUrl = $logCont.data('url');
var $logHead = $wrapper.children('div.log-header').first();
var $trigger = $logHead.children('span').first();
var $autoload = $('#autoreload');
var state = $logBody.is(':visible');
var t = null; // timer
var first_open = true;
if (state) {
$trigger.removeClass('closed');
$wrapper.removeClass('inactive')
.addClass('active');
} else {
$trigger.addClass('closed');
$logBody.addClass('hidden');
$wrapper.removeClass('active')
.addClass('inactive');
}
function getLineHeight(element){
var temp = document.createElement(element.nodeName);
temp.setAttribute("style","margin:0px;padding:0px;font-family:"+element.style.fontFamily+";font-size:"+element.style.fontSize);
temp.innerHTML = "test";
temp = element.parentNode.appendChild(temp);
var ret = temp.clientHeight;
temp.parentNode.removeChild(temp);
return ret;
}
var loadLog = function() {
$.ajax({
url: logUrl,
type: "GET",
dataType: 'json',
data: $logCont.data(),
beforeSend: function( xhr ) {
var token = $('meta[name="csrf-token"]').attr('content');
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
},
success: function(data, textStatus, jqXHR) {
var l = $logCont[0];
var vScroll = l.scrollTop;
var hScroll = l.scrollLeft;
var onBottom = Math.abs((l.clientHeight + vScroll - l.scrollHeight)) < getLineHeight(l);
$logCont.text(data.log);
$logCont.scrollLeft(hScroll);
$logCont.scrollTop((onBottom || first_open) ? l.scrollHeight - l.clientHeight : vScroll);
first_open = false;
if (!data.building) $autoload.attr({'checked': false}).trigger('change');
}
});
}
var reloadChange = function() {
if ($(this).is(':checked')) {
first_open = true;
loadLog();
$logCont.scrollTop($logCont[0].scrollHeight - $logCont[0].clientHeight);
t = setInterval(function() {
loadLog();
}, $('#reload_interval').val());
} else {
clearInterval(t);
}
}
var toggleHandler = function() {
state = !state;
// if log opened
if (state) {
if ($autoload.is(':checked')) {
$autoload.trigger('change');
}
} else {
clearInterval(t);
}
$logBody.slideToggle('slow')
.toggleClass('hidden');
$logHead.toggleClass('active inactive');
$trigger.toggleClass('closed');
window.location.href = $('a#log_anchor').attr('href');
}
$wrapper.on('click', '.log-header > span', toggleHandler);
$autoload.on('change', reloadChange);
$('#word_wrap').on('change', function() {
$logCont.attr({'wrap': ($(this).is(':checked')) ? 'soft' : 'off'});
});
$('#reload_interval').on('change', function() {
clearInterval(t);
if ($autoload.is(':checked')) {
t = setInterval($(this).val());
}
});
$('#load_lines').on('change', function() {
$logCont.data('load_lines', $(this).val());
}).trigger('change');
loadLog();
}

View File

@ -2,9 +2,9 @@
class Platforms::ProductBuildListsController < Platforms::BaseController
before_filter :authenticate_user!, :except => [:status_build]
skip_before_filter :authenticate_user!, :only => [:index] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :platform, :only => [:create, :destroy, :new, :show]
load_and_authorize_resource :product, :through => :platform, :only => [:create, :destroy, :new, :show]
load_and_authorize_resource :product_build_list, :through => :product, :only => [:create, :destroy, :new, :show]
load_and_authorize_resource :platform, :except => [:index, :status_build]
load_and_authorize_resource :product, :through => :platform, :except => [:index, :status_build]
load_and_authorize_resource :product_build_list, :through => :product, :except => [:index, :status_build]
load_and_authorize_resource :only => [:index]
before_filter :authenticate_product_builder!, :only => [:status_build]
@ -22,7 +22,17 @@ class Platforms::ProductBuildListsController < Platforms::BaseController
end
def show
@logs = JSON.parse(Resque.redis.get("abfworker::iso-worker-#{@product_build_list.id}") || '[]')
end
def log
@log = Resque.redis.get("abfworker::iso-worker-#{@product_build_list.id}") || ''
respond_to do |format|
format.json {
render :json => {
:log => @log,
:building => @product_build_list.build_started? }
}
end
end
def create

View File

@ -40,6 +40,10 @@ class ProductBuildList < ActiveRecord::Base
before_destroy :can_destroy?
after_destroy :xml_delete_iso_container
def build_started?
status == BUILD_STARTED
end
def container_path
"/downloads/#{product.platform.name}/product/#{id}/"
end

View File

@ -8,12 +8,6 @@
%h3= t("layout.product_build_lists.main_data")
.both
%div.reloader
= label_tag :autoreload do
= check_box_tag :autoreload, true, true
= t("layout.autoreload_page")
.both
.leftlist= t("activerecord.attributes.product_build_list.id")
.rightlist= pbl.id
.both
@ -46,20 +40,8 @@
.rightlist= l(pbl.updated_at, :format => :long)
.both
- if @logs.present?
%h3= t("layout.product_build_lists.logs")
%table#logs.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
%thead
%tr
%th.lpadding16= '#'
%th
%tbody
- @logs.each do |item|
%tr
%td= item[0]
%td= item[1]
.both
- if pbl.build_started?
= render 'shared/log', { :build_started => true, :get_log_path => log_platform_product_product_build_list_path(pbl.product.platform, pbl.product, pbl) }
%h3= t("layout.product_build_lists.results")
- unless pbl.results.present?
@ -82,18 +64,4 @@
:javascript
$(function(){
$('article .all').addClass('bigpadding');
var reloadChange = function() {
if ($(this).is(':checked')) {
//reload page every 1 minute
t = setTimeout(function() {
window.location.reload();
}, 10000);
} else {
clearTimeout(t);
}
}
$('#autoreload').on('change', reloadChange)
.trigger('change');
});

View File

@ -1,148 +0,0 @@
.hr
%a{:name => 'log'}
.log-wrapper
.log-header
.text-wrap
= link_to({:anchor => :log}, {:id => 'log_anchor'}) do
%h3= t("layout.build_lists.log.build_log")
%span
.both
.log-body.hidden
.reloader
%table.options
%tr.top
%td.first
= label_tag :word_wrap do
= check_box_tag :word_wrap
= t("layout.word_wrap")
%td.last{ :class => @build_list.build_started? ? nil : :hidden }
= label_tag :autoreload do
= check_box_tag :autoreload, true, @build_list.build_started?
= t("layout.build_lists.log.autoreload")
= select_tag :reload_interval, log_reload_time_options
%tr.bottom
%td.first
= link_to t("layout.build_lists.log.download"), build_list_log_url(:build), :id => :log_url
%td.last{ :class => @build_list.build_started? ? nil : :hidden }
= label_tag :load_lines do
= raw t("layout.build_lists.log.load_lines", :count => select_tag(:load_lines, log_reload_lines_options))
.both
%textarea.log{ :readonly => :readonly, :wrap => 'off',
:data => { :url => log_build_list_path(@build_list), :log_type => :build } }
= t("layout.build_lists.log.not_available")
:javascript
$(function() {
(function() {
var $wrapper = $('div.log-wrapper');
var $logBody = $wrapper.children('div.log-body').first();
var $logCont = $logBody.children('.log').first();
var logUrl = $logCont.data('url');
var $logHead = $wrapper.children('div.log-header').first();
var $trigger = $logHead.children('span').first();
var $autoload = $('#autoreload');
var state = $logBody.is(':visible');
var t = null; // timer
var first_open = true;
if (state) {
$trigger.removeClass('closed');
$wrapper.removeClass('inactive')
.addClass('active');
} else {
$trigger.addClass('closed');
$logBody.addClass('hidden');
$wrapper.removeClass('active')
.addClass('inactive');
}
function getLineHeight(element){
var temp = document.createElement(element.nodeName);
temp.setAttribute("style","margin:0px;padding:0px;font-family:"+element.style.fontFamily+";font-size:"+element.style.fontSize);
temp.innerHTML = "test";
temp = element.parentNode.appendChild(temp);
var ret = temp.clientHeight;
temp.parentNode.removeChild(temp);
return ret;
}
var loadLog = function() {
$.ajax({
url: logUrl,
type: "GET",
dataType: 'json',
data: $logCont.data(),
beforeSend: function( xhr ) {
var token = $('meta[name="csrf-token"]').attr('content');
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
},
success: function(data, textStatus, jqXHR) {
var l = $logCont[0];
var vScroll = l.scrollTop;
var hScroll = l.scrollLeft;
var onBottom = Math.abs((l.clientHeight + vScroll - l.scrollHeight)) < getLineHeight(l);
$logCont.text(data.log);
$logCont.scrollLeft(hScroll);
$logCont.scrollTop((onBottom || first_open) ? l.scrollHeight - l.clientHeight : vScroll);
first_open = false;
if (!data.building) $autoload.attr({'checked': false}).trigger('change');
}
});
}
var reloadChange = function() {
if ($(this).is(':checked')) {
first_open = true;
loadLog();
$logCont.scrollTop($logCont[0].scrollHeight - $logCont[0].clientHeight);
t = setInterval(function() {
loadLog();
}, $('#reload_interval').val());
} else {
clearInterval(t);
}
}
var toggleHandler = function() {
state = !state;
// if log opened
if (state) {
if ($autoload.is(':checked')) {
$autoload.trigger('change');
}
} else {
clearInterval(t);
}
$logBody.slideToggle('slow')
.toggleClass('hidden');
$logHead.toggleClass('active inactive');
$trigger.toggleClass('closed');
window.location.href = $('a#log_anchor').attr('href');
}
$wrapper.on('click', '.log-header > span', toggleHandler);
$autoload.on('change', reloadChange);
$('#word_wrap').on('change', function() {
$logCont.attr({'wrap': ($(this).is(':checked')) ? 'soft' : 'off'});
});
$('#reload_interval').on('change', function() {
clearInterval(t);
if ($autoload.is(':checked')) {
t = setInterval($(this).val());
}
});
$('#load_lines').on('change', function() {
$logCont.data('load_lines', $(this).val());
}).trigger('change');
loadLog();
})();
});

View File

@ -125,7 +125,7 @@
});
- if BuildList::HUMAN_STATUSES[@build_list.status].in? [:build_started, :build_error, :success]
= render :partial => 'projects/build_lists/log'
= render 'shared/log', { :build_started => @build_list.build_started?, :download_log_url => build_list_log_url(:build), :get_log_path => log_build_list_path(@build_list) }
- if (can_publish = @build_list.can_publish? && can?(:publish, @build_list))

View File

@ -0,0 +1,47 @@
-#
params:
- build_started
- download_log_url
- get_log_path
- download_log_url ||= false
.hr
%a{:name => 'log'}
.log-wrapper
.log-header
.text-wrap
= link_to({:anchor => :log}, {:id => 'log_anchor'}) do
%h3= t("layout.build_lists.log.build_log")
%span
.both
.log-body.hidden
.reloader
%table.options
%tr.top
%td.first
= label_tag :word_wrap do
= check_box_tag :word_wrap
= t("layout.word_wrap")
%td.last{ :class => build_started ? nil : :hidden }
= label_tag :autoreload do
= check_box_tag :autoreload, true, build_started
= t("layout.build_lists.log.autoreload")
= select_tag :reload_interval, log_reload_time_options
%tr.bottom
%td.first
- if download_log_url
= link_to t("layout.build_lists.log.download"), download_log_url, :id => :log_url
%td.last{ :class => build_started ? nil : :hidden }
= label_tag :load_lines do
= raw t("layout.build_lists.log.load_lines", :count => select_tag(:load_lines, log_reload_lines_options))
.both
%textarea.log{ :readonly => :readonly, :wrap => 'off',
:data => { :url => get_log_path, :log_type => :build } }
= t("layout.build_lists.log.not_available")
.both
:javascript
$(function() {
initLogWrapper();
});

View File

@ -145,7 +145,9 @@ Rosa::Application.routes.draw do
end
resources :key_pairs, :only => [:create, :index, :destroy]
resources :products do
resources :product_build_lists, :only => [:create, :destroy, :new, :show]
resources :product_build_lists, :only => [:create, :destroy, :new, :show] do
member { get :log }
end
collection { get :autocomplete_project }
end
resources :maintainers, :only => [:index]