NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name HPforLSA
// @description Minor HostPilot improvements for LSAs
// @namespace sepa.spb.ru
// @version 2017.04.08
// @require https://code.jquery.com/jquery-2.1.1.min.js
// @resource ace https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js
// @resource sh https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/mode-sh.js
// @resource diff https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/mode-diff.js
// @resource theme https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/theme-clouds.js
// @resource search https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ext-searchbox.js
// @include https://hosting.intermedia.net/asp/Administrator/Tools/LinuxBoxes/Configuration.asp*
// @include https://hosting.intermedia.net/asp/Administrator/Tools/LinuxBoxes/RunCommand.asp*
// @include https://hosting.intermedia.net/asp/Administrator/Tools/LinuxBoxes/ConfigurationFileView.asp*
// @include https://hosting.intermedia.net/asp/Administrator/Tools/DnsServer/DatabaseDomain.asp*
// @include https://hosting.intermedia.net/asp/Administrator/ViewAccounts.asp*
// @include https://hosting.intermedia.net/asp/Administrator/Menu.asp
// @include https://hosting.qaintermedia.net/asp/Administrator/Tools/LinuxBoxes/Configuration.asp*
// @include https://hosting.qaintermedia.net/asp/Administrator/Tools/LinuxBoxes/RunCommand.asp*
// @include https://hosting.qaintermedia.net/asp/Administrator/Tools/LinuxBoxes/ConfigurationFileView.asp*
// @include https://hosting.qaintermedia.net/asp/Administrator/Tools/DnsServer/DatabaseDomain.asp*
// @include https://hosting.qaintermedia.net/asp/Administrator/ViewAccounts.asp*
// @include https://hosting.qaintermedia.net/asp/Administrator/Menu.asp
// @icon http://intermedia.net/assets/tracked/img/favicon.ico
// @run-at document-start
// @grant GM_getResourceText
// @updateURL https://openuserjs.org/install/sepich/HPforLSA.user.js
// @downloadURL https://openuserjs.org/install/sepich/HPforLSA.user.js
// @author i@sepa.spb.ru
// ==/UserScript==
console.log('started');
var $ = jQuery,
setTimeoutCount = 0,
setTimeoutCountMax = 6000,
setTimeoutDelay = 100,
hereDoc;
//heredoc js wrapper ;)
function hereDoc(f) { return f.toString().replace(/^[^\/]+\/\*!?/, '').replace(/\*\/[^\/]+$/, ''); }
//css
var css = hereDoc(function() {/*!
#editor {border: 1px solid #CCCCCC;}
.srv tr.sel {background: #DFD;}
.srv tr:hover {background: #BFB;}
.ace-tm span.ace_string { color: rgb(170, 85, 0); }
.ace-tm span.ace_invisible { color: #FFF; }
.ace-tm .ace_marker-layer div.ace_selected-word { background: #8F8; border: none; }
div.ace_scrollbar {bottom: 16px !important;}
input.sm {padding: 3px !important; margin-right: 0; border-right: 1px solid #ccc;}
#resize {
width: 15px;
height: 15px;
position: absolute;
bottom: 0;
right: 0;
background: url("https://i.sepa.spb.ru/_/imedia/resizer.gif") no-repeat;
cursor: n-resize;
z-index: 9;
}
*/});
//use cached ace edit
function insertCached(m){
var res = ['ace', 'sh', 'search'],
s;
//addons for diff display
if(m == 'diff') {
res.push('diff');
res.push('theme');
}
//injecting resourses to page
console.log('inject: '+res);
for (var i in res) {
s = document.createElement("script");
s.textContent = GM_getResourceText(res[i]);
document.head.appendChild(s);
}
}
console.log(window.location.pathname);
//Run-Command
if(window.location.pathname=='/asp/Administrator/Tools/LinuxBoxes/RunCommand.asp'){
var init,
lastChecked = null;
init = function () {
setTimeoutCount += 1;
console.log('init-'+setTimeoutCount);
if ($('#boxesCountSpan').length) {
$('head').append('<style type="text/css" id="tbl-css">');
$('#tbl-css').html(css);
$('form').attr('target','_blank');
$('#boxesCountSpan').closest('table').addClass('srv');
$('input[name=command]').css('font-family','monospace');
$('input[name=command]').css('width','100%');
$('input[value=Run]').mousedown( function(){
setTimeout(function(){
$('input[name=runButton]').removeAttr('disabled');
}, 5000);
});
$('input[id^=checkbox_]').change(function(){
if(this.checked) { $(this).closest('tr').addClass('sel'); }
else { $(this).closest('tr').removeClass('sel'); }
});
var $chkboxes = $('input[id^=checkbox_]');
$chkboxes.click(function(e){
if(!lastChecked) {
lastChecked = this;
return;
}
if(e.shiftKey) {
var start = $chkboxes.index(this);
var end = $chkboxes.index(lastChecked);
$chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).each(function() {
if($(this).closest('tr').css('display') != "none") {
this.checked=lastChecked.checked;
$(this).trigger('change');
}
});
}
lastChecked = this;
});
$('input[name=allBoxes]').change(function(){
if(this.checked) {
//todo can be faster
$('input[id^=checkbox_]').trigger('change');
}
else{ $('.srv tr').removeClass('sel'); }
});
$('#rolesSelector').change(function(){
$('input[id^=checkbox_]').trigger('change');
});
$('input[name=nameFilter]').change(function(){
$('input[id^=checkbox_]').trigger('change');
});
$('input[id^=checkbox_]').trigger('change');
setTimeoutCount=setTimeoutCountMax;
}
else if (document.readyState == "complete") { setTimeoutCount=setTimeoutCountMax; }
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(init, setTimeoutDelay); }
}
setTimeout(init, setTimeoutDelay);
}
//Configurator
else if(window.location.pathname=='/asp/Administrator/Tools/LinuxBoxes/Configuration.asp') {
var t,
ed,
lastChecked = null,
init, initDiv, initEditor, initTbl, initTbl2;
//wait for jquery and preload Ace
init = function () {
setTimeoutCount += 1;
console.log('init-'+setTimeoutCount);
// only load editor when there is editing field
if (typeof($)=='function') {
insertCached();
$('head').append('<style type="text/css" id="ace-css">');
$('#ace-css').html(css);
setTimeout(initDiv, setTimeoutDelay);
}
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(init, setTimeoutDelay); }
}
//wait for boxType select and sort it
$('select[name=boxType]').ready(function() {
console.log('sort boxType')
var t = $('select[name=boxType]'),
selected = $(t).val(); /* preserving original selection, step 1 */
$(t).append(
$(t).find("option").remove().sort(function(a, b) {
var at = $(a).text().toLowerCase(),
bt = $(b).text().toLowerCase();
return (at == '[linux]' || at < bt)? -1 : ((at > bt )?1:0);
})
);
$(t).val(selected); /* preserving original selection, step 2 */
});
//wait for textarea and replace it
initDiv =function(){
setTimeoutCount += 1;
console.log('initDiv-'+setTimeoutCount);
t = $('textarea[name=content]');
if (t.length) {
t.css('visibility', 'hidden');
t.css('height', '0px');
$('form table')[1].setAttribute('width','100%');
$('<div>', {
position: 'absolute',
width: '100%',
height: '700px',
id: 'editor'
}).insertBefore(t);
//add buttons for next/prev files and reload
var cf=$("select[name=configFile]"),
i=cf.children().index(cf.children().filter(":selected"));
if(i>2) {
cf.before('<input type="button" class="sm" id="prev" value="<" title="Go to previous file">');
$("#prev").click(function() {
cf.val(cf.children().eq(i-1).val());
cf.trigger("change");
});
}
if(i<cf.children().length-1) {
cf.after('<input type="button" class="sm" id="next" value=">" title="Go to next file">');
$("#next").click(function() {
cf.val(cf.children().eq(i+1).val());
cf.trigger("change");
});
}
$('select[name=version]').after('<input type="button" class="sm" id="reload" value="↺" title="Reload status of selected file">');
$("#reload").click(function() {
cf.trigger("change");
});
//add copy button
cf.parent('td').children().last().after('<input type="button" class="sm" id="copy" value="©" title="Copy filename to buffer">');
$('#copy').click(function() {
var fileName = $('select[name=configFile] option:selected').text();
window.prompt("Copy to clipboard: Ctrl+C, Enter", fileName);
});
setTimeout(initEditor, setTimeoutDelay);
}
else if (document.readyState == "complete") { setTimeoutCount=setTimeoutCountMax; }
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(initDiv, setTimeoutDelay); }
}
//wait for Ace load and init it
initEditor = function () {
setTimeoutCount += 1;
console.log('initEd-'+setTimeoutCount);
if(typeof(unsafeWindow.ace)=="object"){
unsafeWindow.ace.config.set("basePath", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/");
var editor = unsafeWindow.ace.edit("editor"),
ed=$("#editor");
editor.getSession().setValue(t.val());
editor.getSession().setMode("ace/mode/sh");
//editor.setTheme("ace/theme/textmate");
editor.getSession().setTabSize(2);
editor.getSession().setUseWrapMode(true);
editor.setShowPrintMargin(true);
editor.renderer.setShowInvisibles(true);
var newHeight = editor.getSession().getScreenLength() * editor.renderer.lineHeight + editor.renderer.scrollBar.getWidth();
if(newHeight < 300) newHeight=300;
if(newHeight > 700) newHeight=700;
$('#editor').height(newHeight.toString() + "px");
editor.resize();
$('#editor').append('<div id="resize">');
$("#resize").mousedown(function(e){
e.preventDefault();
ed.data("height", ed.height());
ed.data("y", e.pageY);
$(document).mousemove(function(e){
ed.height(Math.max(ed.data("height") - ed.data("y") + e.pageY, 300)+ "px");
})
});
$(document).mouseup(function(e){
if(ed.data("height")){
ed.data("height", 0);
$(document).unbind('mousemove');
editor.resize();
}
});
$('input[value="Save This Version To DB"]').mousedown(function(){
t.val(editor.getSession().getValue());
});
setTimeout(initTbl, setTimeoutDelay);
}
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(initEditor, setTimeoutDelay); }
}
//wait for Table load and fix it
initTbl = function () {
setTimeoutCount += 1;
console.log('initTbl-'+setTimeoutCount);
if ($('#uploadButton').length) {
$('input[name=uploadCheckAll]').closest('table').addClass('srv');
$('input[id$=_checkbox]').removeAttr('disabled');
$('input[id$=_checkbox]').change(function(){
if(this.checked) { $(this).closest('tr').addClass('sel'); }
else { $(this).closest('tr').removeClass('sel'); }
});
var $chkboxes = $('input[id$=_checkbox]');
$chkboxes.click(function(e){
if(!lastChecked) {
lastChecked = this;
return;
}
if(e.shiftKey) {
var start = $chkboxes.index(this);
var end = $chkboxes.index(lastChecked);
$chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).each(function() {
this.checked=lastChecked.checked;
$(this).trigger('change');
});
}
lastChecked = this;
});
$('input[name=uploadCheckAll]').change(function(){
if(this.checked) { $('input[id$=_checkbox]').trigger('change'); }
else{ $('.srv tr').removeClass('sel'); }
});
$('#uploadButton').removeAttr('disabled');
var $ahash = $('table.srv tr a');
$ahash.attr('href','')
$ahash.click(function(){
return false;
})
setTimeout(initTbl2, setTimeoutDelay);
}
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(initTbl, setTimeoutDelay); }
}
//wait for Table stops load and fix it
initTbl2 = function () {
setTimeoutCount += 1;
console.log('initTbl2-'+setTimeoutCount);
if ( $('#countTotal').text() != '?' ) {
var $ahash = $('table.srv tr a[href=#]');
$ahash.attr('href','')
$ahash.click(function(){
return false;
})
}
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(initTbl2, setTimeoutDelay); }
}
setTimeout(init, setTimeoutDelay);
}
//FileHistory compare or FileContenet view (ReadOnly)
else if(window.location.pathname=='/asp/Administrator/Tools/LinuxBoxes/ConfigurationFileView.asp') {
var t,
lastChecked = null,
init, initDiv, initEditor;
//wait for jquery and preload Ace
init = function () {
setTimeoutCount += 1;
console.log('init-'+setTimeoutCount);
// only load editor when there is editing field
if (typeof($)=='function') {
$('head').append('<style type="text/css" id="ace-css">');
insertCached('diff');
$('#ace-css').html(css);
setTimeout(initDiv, setTimeoutDelay);
}
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(init, setTimeoutDelay); }
}
//wait for textarea and replace it
initDiv =function(){
setTimeoutCount += 1;
console.log('initDiv-'+setTimeoutCount);
//change Configuration File View to add boxname
var boxName=/box=([^&]+)/.exec(location)[1],
configFile=/configFile=([^&]+)/.exec(location)[1].replace(/%2F/g, '/'),
boxType=/boxType=([^&]+)/.exec(location)[1],
version=location.href.match('version=([^&]+)');
version=version ? "v"+version[1]+" <> " : version='';
$('.header:first').html(unescape(boxType) + ":" + configFile + ' ' + version + "file on "+boxName);
t = $('textarea[name=content]');
if (t.length) {
t.css('visibility', 'hidden');
t.css('height', '0px');
var editDiv = $('<div>', {
position: 'absolute',
width: '100%',
height: '620px',
id: 'editor'
}).insertBefore(t);
setTimeout(initEditor, setTimeoutDelay);
}
else if (document.readyState == "complete") { setTimeoutCount=setTimeoutCountMax; }
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(initDiv, setTimeoutDelay); }
}
//wait for Ace load and init it
initEditor = function () {
setTimeoutCount += 1;
console.log('initEd-'+setTimeoutCount);
if(typeof(unsafeWindow.ace)=="object"){
unsafeWindow.ace.config.set("basePath", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/");
var editor = unsafeWindow.ace.edit("editor"),
ed=$("#editor");
editor.getSession().setValue(t.val());
editor.getSession().setTabSize(2);
editor.renderer.setShowInvisibles(true);
editor.setReadOnly(true);
if ( $('input[value=change]').length > 0) {
if ( $('input[name^=diff]').val().indexOf("y") > -1 ){
editor.getSession().setTabSize(8);
editor.getSession().setMode("ace/mode/sh");
}
else {
editor.getSession().setMode("ace/mode/diff");
editor.getSession().setUseWrapMode(false);
editor.renderer.setShowGutter(false);
editor.setTheme("ace/theme/clouds");
editor.setShowPrintMargin(false);
}
}
else {
editor.getSession().setMode("ace/mode/sh");
editor.getSession().setUseWrapMode(true);
editor.setShowPrintMargin(true);
}
$('#editor').append('<div id="resize">');
$("#resize").mousedown(function(e){
e.preventDefault();
ed.data("height", ed.height());
ed.data("y", e.pageY);
$(document).mousemove(function(e){
ed.height(Math.max(ed.data("height") - ed.data("y") + e.pageY, 300)+ "px");
})
});
$(document).mouseup(function(e){
if(ed.data("height")){
ed.data("height", 0);
$(document).unbind('mousemove');
editor.resize();
}
});
setTimeout(initTbl, setTimeoutDelay);
}
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(initEditor, setTimeoutDelay); }
}
setTimeout(init, setTimeoutDelay);
}
//Search for account
else if(window.location.pathname=='/asp/Administrator/ViewAccounts.asp') {
var init,
lastChecked = null;
init = function () {
setTimeoutCount += 1;
console.log('init-'+setTimeoutCount);
if (typeof($)=='function' && $("b:contains('Dedicated Exchange')").length) {
var tr=$("b:contains('Exchange Hosting')").closest('table').find('tr'),
h=window.location.hostname.replace('hosting','exchange');
if (tr[3].cells.length>1){
console.log('Adding links');
for (i=3;i<tr.length-2;i++){
tr[i].cells[1].innerHTML="<a href='https://"+h+"/asp/Administrator/ModifyAccount.asp?accountID="+tr[i].cells[0].textContent+"'>"+tr[i].cells[1].textContent+"</a>";
}
}
setTimeoutCount=setTimeoutCountMax;
}
else if (document.readyState == "complete") { setTimeoutCount=setTimeoutCountMax; }
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(init, setTimeoutDelay); }
}
setTimeout(init, setTimeoutDelay);
}
//DNS Manager
else if (window.location.pathname == '/asp/Administrator/Tools/DnsServer/DatabaseDomain.asp') {
var lastChecked=null,
init=function(){
setTimeoutCount += 1;
console.log('init-' + setTimeoutCount);
// only edit buttons when they all are loaded
if ($('input[value="Reload domain on dnscache servers"]').length) {
$('head').append('<style type="text/css" id="tbl-css">');
$('#tbl-css').html(css);
$('form[name=EditRecordsForm] table').addClass('srv');
//add checkboxes
$('form[name=EditRecordsForm] table tr').each(function(){
var btn = $(this).find('input[value=Delete]');
if($(btn).length){
var id=$(btn).attr('onclick').match(/recordToDelete.value="(\d*)"/)[1];
$(this).children().first().prepend(
$('<input type="checkbox">').data('id',id).addClass('massDelete').change(function(){
if(this.checked) $(this).closest('tr').addClass('sel');
else $(this).closest('tr').removeClass('sel');
var num=$('.sel').length;
if(num) $('#delSelected').attr("disabled", false).val("Delete Selected ("+num+")");
else $('#delSelected').attr("disabled", true).val("Delete Selected");
})
)
}
})
//shift-click for checkboxes
var $chkboxes = $('input.massDelete');
$chkboxes.click(function(e){
if(e.shiftKey && lastChecked){
var start = $chkboxes.index(this);
var end = $chkboxes.index(lastChecked);
$chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).each(function() {
if($(this).closest('tr').css('display') != "none") {
this.checked=lastChecked.checked;
$(this).trigger('change');
}
});
}
lastChecked = this;
})
//add Delete button
$('form[name=EditRecordsForm] table').find('td').last().append(
$('<input type="button" id="delSelected">').val("Delete Selected").attr("disabled",true).click(function(){
var data=$('form[name=EditRecordsForm]').serializeArray().reduce(function(obj, item) {
obj[item.name] = item.value;
return obj;
}, {});
data['action']='deleteRecord';
$('#delSelected').attr("disabled", true);
$('.massDelete:checked').each(function(){
var id=$(this).data('id'),
tr=$(this).closest('tr');
data['recordToDelete']=id;
$.ajax({
type: 'POST',
url: $('form[name=EditRecordsForm]').attr('action'),
data: data,
success: function(data){
$(tr).remove();
var num=$('.sel').length;
if(num) $('#delSelected').val("Deleting Selected ("+num+")...");
else window.location=window.location; //reload page after mass deletion
},
error: function(xhr, status, err){ console.log(status+err); }
})
})
})
)
//filter records
$('form[name=EditRecordsForm] table').find('td').first().html(
$('<input type="text" style="width:100%;">').on('change keyup', function () {
var filter=$(this).val().toLowerCase();
trs=$('form[name=EditRecordsForm] table tr');
$(trs).each(function(i,tr){
if(i==0 || i>$(trs).length-5) return true; //skip headers/footers
if(filter==='' || $(tr).children('td').first().text().toLowerCase().includes(filter) ) $(tr).show();
else $(tr).hide();
})
})
);
setTimeoutCount=setTimeoutCountMax;
}
else if (document.readyState == "complete") { setTimeoutCount=setTimeoutCountMax; }
else if (setTimeoutCount < setTimeoutCountMax) { setTimeout(init, setTimeoutDelay); }
}
setTimeout(init, setTimeoutDelay);
}
//Ping each 5min for cookie keepalive
else if(window.location.pathname=='/asp/Administrator/Menu.asp') {
ping = function(){
if(document.readyState == "complete"){
$.ajax('https://hosting.intermedia.net/asp/Administrator/LookupAccounts.asp');
$.ajax('https://exchange.intermedia.net/asp/Administrator/LookupAccounts.asp');
}
}
setInterval(ping, 1000*60*5);
}