diff --git a/lib/http_server.pl b/lib/http_server.pl index 5f8100d55..523d07809 100644 --- a/lib/http_server.pl +++ b/lib/http_server.pl @@ -328,12 +328,14 @@ sub http_process_request { if ( $req_typ eq "POST" || $req_typ eq "PUT" ) { my $cl = $Http{'Content-Length'} || $Http{'Content-length'}; # Netscape uses lower case l - print "http POST query has $cl bytes of args\n" if $main::Debug{http}; + print + "http POST query has $cl bytes of args\n"; # if $main::Debug{http}; my $buf; read $socket, $buf, $cl; # Save the body into the global var $HTTP_BODY = $buf; + print "http POST buf=$buf get_arg=$get_arg\n" if $main::Debug{http}; # This is a bad practice to merge the body and arguments together as the # body may not always contain an argument string. It may contain JSON @@ -341,10 +343,17 @@ sub http_process_request { # Since I can't figure out if any bad code relies on merging the body # into the arguments, the following regex tests if the body is a valid # argument string. If it is, the body is merged. - if ( $buf =~ /^([-\+=&;%@.\w_]*)\s*$/ ) { + if ( $buf =~ /^([-\+=&;%@.*\w_]*)\s*$/ ) { + print "http POST in loop\n" if $main::Debug{http}; $get_arg .= "&" if ( $get_arg ne '' ); $get_arg .= $buf; } + else { + &main::print_log( + "[http_server.pl]: Warning, invalid argument string detected ($buf)\n" + ); + } + print "http POST get_arg=$get_arg\n" if $main::Debug{http}; # shutdown($socket->fileno(), 0); # "how": 0=no more receives, 1=sends, 2=both } @@ -422,23 +431,24 @@ sub http_process_request { $get_arg =~ s/%([0-9a-fA-F]{2})/pack("C",hex($1))/ge; - # print "http: gr=$get_req ga=$get_arg\n" if $main::Debug{http}; + print "http: gr=$get_req ga=$get_arg\n" if $main::Debug{http}; # Store so that include files have access to parent args $ENV{HTTP_QUERY_STRING} = $get_arg; # Prompt for password (SET_PASSWORD) and allow for UNSET_PASSWORD if ( $get_req =~ /SET_PASSWORD$/ ) { - my ($mode) = ($Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\//); + my ($mode) = ( $Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\// ); if ( $config_parms{password_menu} eq 'html' ) { my $html = &html_authorized; if ( $get_req =~ /^\/UNSET_PASSWORD$/ ) { $Authorized = 0; $Cookie .= "Set-Cookie: password=xyz ; ; path=/;\n"; - $html .= ""; + $html .= ""; } - $html .= "
Refresh: Main Page\n" unless (lc $mode eq "ia7"); + $html .= "
Refresh: Main Page\n" + unless ( lc $mode eq "ia7" ); $html .= &html_password('') . '
'; print $socket &html_page( undef, $html, undef, undef, undef, undef ); @@ -446,7 +456,7 @@ sub http_process_request { else { my $html = &html_authorized; $html .= "
Refresh: Main Page\n"; - $html .= "
set_password else Referrer: $Http{Referer}\n"; + $html .= "
set_password else Referrer: $Http{Referer}\n"; # $html .= &html_reload_link('/', 'Refresh Main Page'); # Does not force reload? my ( $name, $name_short ) = &net_domain_name('http'); @@ -474,7 +484,7 @@ sub http_process_request { # Process the html password form elsif ( $get_req =~ /\/SET_PASSWORD_FORM$/ ) { - my ($mode) = ($Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\//); + my ($mode) = ( $Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\// ); my ($password) = $get_arg =~ /password=(\S+)/; my ($html); my ( $name, $name_short ) = &net_domain_name('http'); @@ -483,6 +493,7 @@ sub http_process_request { $html .= &html_authorized; $html .= "REMOVEME = get_arg = " . $get_arg . "
\n"; $html .= "
Refresh: Main Page\n"; + # $html .= &html_reload_link('/', 'Refresh Main Page'); $html .= &html_password(''); if ($password_crypted) { @@ -798,23 +809,28 @@ sub http_process_request { sub html_password { my ($menu) = @_; $menu = $config_parms{password_menu} unless $menu; - my ($mode) = ($Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\//); + my ($mode) = ( $Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\// ); # return $html_unauthorized unless $Authorized; my $html; if ( $menu eq 'html' ) { - $html = qq[\n] unless (lc $mode eq "ia7"); + $html = + qq[\n] + unless ( lc $mode eq "ia7" ); + + # $html .= qq[\n]; + $html .= qq[
\n]; - # $html .= qq[\n]; - $html .= qq[\n]; + # $html .= qq[\n]; ... get not secure from browser history list!! + # $html .= qq[

Password:

\n
\n]; + $html .= + qq[Password:\n]; + $html .= qq[\n\n]; + $html .= + qq[

This form is used for logging into MisterHouse.
For administration please see the documentation of set_password

\n]; - # $html .= qq[
\n]; ... get not secure from browser history list!! - # $html .= qq[

Password:

\n
\n]; - $html .= qq[Password:\n]; - $html .= qq[\n\n]; - $html .= qq[

This form is used for logging into MisterHouse.
For administration please see the documentation of set_password

\n]; -# } + # } } else { $html = qq[HTTP/1.0 401 Unauthorized\n]; @@ -826,7 +842,7 @@ sub html_password { } sub html_authorized { - my $html = "Status: "; + my $html = "Status: "; if ($Authorized) { $html .= ""; $html .= "Logged In as $Authorized"; @@ -1578,8 +1594,9 @@ sub html_error_log { # These html_form functions are used by mh/web/bin/*.pl scrips sub html_form_input_set_func { my ( $func, $resp, $var1, $var2 ) = @_; - my ($mode) = ($Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\//); + my ($mode) = ( $Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\// ); my $id = ""; + #$id = "id='mhresponse'" if ($mode eq 'ia7'); my $html .= qq|
\n|; $html .= qq|\n|; @@ -1596,9 +1613,10 @@ sub html_form_input_set_func { sub html_form_input_set_var { my ( $var, $resp, $default ) = @_; $default = HTML::Entities::encode($default); - my ($mode) = ($Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\//); + my ($mode) = ( $Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\// ); my $id = ""; - #$id = "id='mhresponse'" if ($mode eq 'ia7'); + + #$id = "id='mhresponse'" if ($mode eq 'ia7'); my $html .= qq|\n|; $html .= qq|\n|; $html .= qq|\n|; @@ -1626,10 +1644,11 @@ sub html_form_select { sub html_form_select_set_func { my ( $func, $resp, $var1, $default, @values ) = @_; - my ($mode) = ($Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\//); + my ($mode) = ( $Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\// ); my $id = ""; + #$id = "id='mhresponse'" if ($mode eq 'ia7'); -# my $form .= qq|\n|; + # my $form .= qq|\n|; my $form .= qq|\n|; $form .= qq|\n|; $form .= qq|\n|; @@ -1643,15 +1662,17 @@ sub html_form_select_set_func { $form .= qq|\n|; } $form .= "
\n"; -# $form .= "\n"; + + # $form .= "\n"; return $form; } sub html_form_select_set_var { my ( $var, $default, @values ) = @_; - my ($mode) = ($Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\//); + my ($mode) = ( $Http{Referer} =~ /https?:\/\/\S+:?\D*\/(\S+)\// ); my $id = ""; - #$id = "id='mhresponse'" if ($mode eq 'ia7'); + + #$id = "id='mhresponse'" if ($mode eq 'ia7'); my $html = "
\n"; $html .= qq|\n|; $html .= qq|\n|; diff --git a/web/ia7/house/main.shtml b/web/ia7/house/main.shtml index 7f917f592..d66a35d99 100644 --- a/web/ia7/house/main.shtml +++ b/web/ia7/house/main.shtml @@ -82,7 +82,7 @@

MisterHouse was created by Bruce Winter. Ron Klinkien developed the v2.3 web interface. Kevin Robert Keegan - developed the v4 web interface, updates by H.Plato. IA7 v1.3.560 Font Awesome by Dave Gandy - http://fontawesome.io

+ designed the v4 web prototype, updates by H.Plato. IA7 v1.3.600 Font Awesome by Dave Gandy - http://fontawesome.io

diff --git a/web/ia7/include/javascript.js b/web/ia7/include/javascript.js index c06d61b55..8e5d4fabb 100644 --- a/web/ia7/include/javascript.js +++ b/web/ia7/include/javascript.js @@ -1,4 +1,4 @@ -// v1.3 +// v1.3.600 var entity_store = {}; //global storage of entities var json_store = {}; @@ -202,7 +202,6 @@ function changePage (){ } else if (path.indexOf('prefs') === 0){ var pref_name = path.replace(/\prefs\/?/,''); - console.log("loadprefs() "+pref_name); loadPrefs(pref_name); } else if(URLHash._request == 'page'){ @@ -308,31 +307,20 @@ function loadPrefs (config_name){ //show ia7 prefs, args ia7_prefs, ia7_rrd_pref }); } html += ""+ config_name + "_config.json "; - console.log(config_data); - console.log("in prefs="+config_data.length); for (var i in config_data){ if ( typeof config_data[i] === 'object') { console.log("i "+i+":"); html += ""+ i + ""; for (var j in config_data[i]) { if ( typeof config_data[i][j] === 'object') { - //console.log("j "+j+":"); html += ""+ j + ""; - for (var k in config_data[i][j]){ - //console.log("k "+k+" = "+json_store.ia7_config[i][j][k]); html += ""+k+" = "+config_data[i][j][k]+""; } - //html +=""; } else { - //console.log("j "+j+" = "+json_store.ia7_config[i][j]); html += ""+j+" = "+config_data[i][j]+"" } } - //html +=""; - } else { - //console.log("i "+i+" : "+json_store.ia7_config[i]); - //html += ""+ String(json_store.ia7_config[i]) + ""; } } @@ -358,7 +346,6 @@ function parseLinkData (link,data) { data = data.replace(/
.*?<\/a>/img,''); } if (link == "/bin/items.pl") { - console.log("items data="+data); var coll_key = window.location.href.substr(window.location.href.indexOf('_collection_key')) data = data.replace(/href=\/bin\/items.pl/img, 'onclick="changePage()"'); data = data.replace(/\(back to top<\/a>\)/img, ''); @@ -377,14 +364,11 @@ function parseLinkData (link,data) { } if (link == "/bin/triggers.pl") { //fix links in the triggers modules var coll_key = window.location.href.substr(window.location.href.indexOf('_collection_key')) - //data = data.replace(/href=\/bin\/triggers.pl/img, 'href=/ia7/#_request=page&link=/bin/triggers.pl&'+coll_key); data = data.replace(/href=\/bin\/triggers.pl/img, 'onclick="changePage()"'); data = data.replace(/\(back to top<\/a>\)/img, ''); data = data.replace(/Trigger Index:/img,''); data = data.replace(/.*?<\/a>/img,''); - //data = data.replace(/onChange=\'form.submit\(\)\'/img,'onChange=\'this\.form\.submit\(\)\''); data = data.replace(/input name='resp' value="\/bin\/triggers.pl"/img, 'input name=\'resp\' value=\"/ia7/#_request=page&link=/bin/triggers.pl&'+coll_key+'\"'); - //console.log(data); } if (link == "/ia5/news/main.shtml") { //fix links in the email module 1 var coll_key = window.location.href.substr(window.location.href.indexOf('_collection_key')) @@ -427,12 +411,6 @@ function parseLinkData (link,data) { if (btn.attr('name') !== undefined) { form_data.push({name : btn.attr('name'), value : btn.attr('value')}); } - console.log("MHResponse Custom submit function "+ form.attr('action')); - console.log( $(this).serializeArray() ); - console.log( "btn: "+btn.attr('name')+"="+btn.attr('value')); -// if (btn.attr('value') !== undefined) { -// console.log("executing data!"); -// unless the btn attribute has a name, then don't push the data (prevent text fields $.ajax({ type: "POST", url: form.attr('action'), @@ -448,12 +426,9 @@ function parseLinkData (link,data) { var end = data.toLowerCase().indexOf(''); if (form.attr('action') === "/bin/triggers.pl?add" && ! data.match(/Not authorized to make updates/)) { - //location.reload(); changePage(); } else if (form.attr('action') === "/bin/iniedit.pl") { -// var pdata = parseLinkData("/bin/iniedit.pl",data); parseLinkData("/bin/iniedit.pl",data); -// $('#row_page').html(pdata); //TODO parse data } else { $('#lastResponse').find('.modal-body').html(data.substring(start, end)); @@ -463,7 +438,6 @@ function parseLinkData (link,data) { } } }); -// } }); $('#mhresponse :input:not(:text)').change(function() { //TODO - don't submit when a text field changes @@ -911,7 +885,6 @@ var updateItem = function(item,link,time) { //URLHash.time = json_store.meta.time; if (updateSocket !== undefined && updateSocket.readyState != 4){ // Only allow one update thread to run at once - //console.log("updateItem: Aborting update. updateSocket="+updateSocket.readyState); updateSocket.abort(); } if (time === undefined) { @@ -999,12 +972,31 @@ var updateStaticPage = function(link,time) { $('button[entity="'+entity+'"]').removeClass("btn-danger"); $('button[entity="'+entity+'"]').removeClass("btn-info"); $('button[entity="'+entity+'"]').addClass("btn-"+color); - + if (json_store.ia7_config.objects[entity].direct_control !== undefined && json_store.ia7_config.objects[entity].direct_control == "yes") $('button[entity="'+entity+'"]').addClass("btn-direct"); + //don't run this if stategrp0 exists if (states_loaded == 0) { $(".btn-state-cmd").click( function () { - var entity = $(this).attr("entity"); - create_state_modal(entity); + var entity = $(this).attr("entity"); + if (json_store.ia7_config.objects !== undefined && json_store.ia7_config.objects[entity] !== undefined) { + if (json_store.ia7_config.objects[entity].direct_control !== undefined && json_store.ia7_config.objects[entity].direct_control == "yes") { + var new_state = ""; + var possible_states = 0; + for (var i = 0; i < json_store.objects[entity].states.length; i++){ + if (filterSubstate(json_store.objects[entity].states[i]) == 1) continue; + possible_states++; + if (json_store.objects[entity].states[i] !== json_store.objects[entity].state) new_state = json_store.objects[entity].states[i]; + + } + if ((possible_states > 2) || (new_state == "")) alert("Check configuration of "+entity+". "+possible_states+" states detected for direct control object. State is "+new_state); + url= '/SET;none?select_item='+entity+'&select_state='+new_state; + $.get( url); + } else { + create_state_modal(entity); + } + } else { + create_state_modal(entity); + } }); } } @@ -1028,7 +1020,6 @@ function authDetails() { alert("Warning, Collection ID 700: Authorize, is not defined in your collections.json!"); } else { if (json_store.collections[700].user !== undefined) { -// console.log ("user found "+json_store.collections[700].user+"."); if (json_store.collections[700].user == "0") { json_store.collections[700].name = "Log in"; json_store.collections[700].icon = "fa-lock"; @@ -1058,17 +1049,10 @@ var loadCollection = function(collection_keys) { if (entity_sort.length <= 0){ entity_arr.push("Childless Collection"); } -// if (json_store.collections[700] == undefined) { -// alert("Warning, Collection ID 700: Authorize, is not defined in your collections.json!"); -// } else { -// authDetails(); -// } for (var i = 0; i < entity_sort.length; i++){ var collection = entity_sort[i]; -// console.log ("col="+collection); if (!(collection in json_store.collections)) continue; -// console.log ("starting"); var link = json_store.collections[collection].link; var icon = json_store.collections[collection].icon; @@ -1199,7 +1183,6 @@ function fixIA7Nav() { var url = $(location).attr('href'); var collid = url.split("_collection_key="); - console.log("fixing nav..."+url+" "+collid[1]); $('a').each(function() { if ($(this).attr('href').match("^/ia7/")) { this.href += '&_collection_key='+collid[1]+','; @@ -1327,7 +1310,6 @@ var mobile_device = function() { function audio_play(audioElement,srcUrl) { - //console.log ("in audio_play:"+srcUrl); audioElement.pause(); audioElement.src=''; //force playback to stop and quit buffering. Not sure if this is strictly necessary. $("#sound_element2").attr("src", srcUrl); //needed for mobile @@ -1341,7 +1323,6 @@ function playWhenReady() {//wait for media element to be ready, then play audioElement=document.getElementById('sound_element'); var audioReady=audioElement.readyState; - //console.log("playWhenReady = "+audioReady); if(audioReady>2) { audioElement.play(); } else if(audioElement.error) { @@ -1689,9 +1670,6 @@ var object_history = function(items,start,days,time) { }); $('.update_history').click(function() { - console.log ("start="+$('.hist_start').val()+" end="+$('.hist_end').val()); -// var new_start = new Date($('.hist_start').val()).getTime(); -// var new_end = new Date($('.hist_end').val()).getTime(); var new_start = new Date($('.hist_start').val().split('-')).getTime(); var new_end = new Date($('.hist_end').val().split('-')).getTime(); var end_days = (new_start - new_end) / (24 * 60 * 60 * 1000) @@ -1731,13 +1709,9 @@ var object_history = function(items,start,days,time) { // take away the border so that it looks better and span the graph from start to end. json.data.options.grid.borderWidth = 0; -// json.data.options.xaxis.min = new Date($('.hist_end').val()).getTime(); -// json.data.options.xaxis.max = new Date($('.hist_start').val()).getTime() + (24 * 60 * 60 * 1000); json.data.options.xaxis.min = new Date($('.hist_end').val().split('-')).getTime(); json.data.options.xaxis.max = new Date($('.hist_start').val().split('-')).getTime() + (24 * 60 * 60 * 1000); -//console.log("data="+JSON.stringify(data)); -//console.log("xmin="+json.data.options.xaxis.min+" xmax="+json.data.options.xaxis.max); $.plot($("#hist-graph"), data, json.data.options); $('.legend').hide(); } @@ -1803,13 +1777,15 @@ var object_history = function(items,start,days,time) { $('#hist-legend').find("li").eq(i).prepend('    '); }); } else { + // table var html = ""; html += ""; html += ""; if (json.data.data !== undefined) { //If no data, at least show the header + json.data.data.reverse(); for (var i = 0; i < json.data.data.length; i++){ html +=""; - html += ""; + html += ""; html += ""; html += ""; html += ""; @@ -1883,7 +1859,6 @@ var fp_resize_floorplan_image = function(){ $("#fp_graphic").attr("width", "1px"); fp_display_width = $("#graphic").width(); - console.log("FP: resize "+ floor_width + " => " + fp_display_width); $('#fp_graphic').attr("width",fp_display_width+"px"); fp_display_height = $("#fp_graphic").height(); }; @@ -1891,7 +1866,7 @@ var fp_resize_floorplan_image = function(){ var fp_reposition_entities = function(){ var t0 = performance.now(); var fp_graphic_offset = $("#fp_graphic").offset(); - console.log("fp_graphic_offset: "+ JSON.stringify(fp_graphic_offset)); +// console.log("fp_graphic_offset: "+ JSON.stringify(fp_graphic_offset)); var width = fp_display_width; var hight = fp_display_height; var onePercentWidthInPx = width/100; @@ -1928,7 +1903,6 @@ var fp_reposition_entities = function(){ var fp_scale = width/nwidth; var fp_scale_percent = Math.round( fp_scale * 100); - console.log("width="+width+" nwidth="+nwidth+" scale="+fp_scale_percent); // update the location of all the objects... $(".floorplan_item").each(function(index) { var classstr = $(this).attr("class"); @@ -1940,19 +1914,9 @@ var fp_reposition_entities = function(){ } var fp_location = coords.split(/x/); var fp_offset = fp_get_offset_from_location(fp_location); - console.log("coords="+coords); - - // this seems to make the repositioning slow - // ~ 300+ms on my nexus7 firefox-beta vs <100ms with this code commented out - // var baseimg_width = $("#fp_graphic").width(); - // if (baseimg_width < 500) { - // $(this).attr('src',$(this).attr('src').replace('48.png','32.png')); - // } else { - // $(this).attr('src',$(this).attr('src').replace('32.png','48.png')); - // } + var element_id = $(this).attr('id'); var adjust = fp_icon_image_size*fp_scale/2; - console.log("adjust="+adjust+" fp_offset.top="+fp_offset.top+" fp_offset.left="+fp_offset.left); var fp_off_center = { "top": fp_offset.top - adjust, "left": fp_offset.left - adjust @@ -1961,33 +1925,25 @@ var fp_reposition_entities = function(){ }); $('.icon_select img').each(function(){ - $(this).width(fp_scale + "%"); + $(this).width(fp_scale_percent + "%"); }); var t1 = performance.now(); console.log("FP: reposition and scale: " +Math.round(t1 - t0) + "ms "); }; +var fp_show_all_icons = function() { + + $(".floorplan_item").each(function(index) { + $(this).show(); + }); +}; + var fp_set_pos = function(id, offset){ var item = $('#' + id); // do not move the span, this make the popup to narrow somehow // item.closest("span").offset(offset); - var left11 = item.css("left"); - var left12 = item[0].style.left; - var top11 = item.css("top"); - var top12 = item[0].style.top; - var before = item.offset(); - var init = false - if (item.css("left") == "auto") { - console.log("auto found, fixing left property"); - offset.left = 0 - fp_icon_image_size/2; - } item.offset(offset); - var after = item.offset(); - var left21 = item.css("left"); - var left22 = item[0].style.left; - console.log("offset.top="+offset.top+" offset.left="+offset.left+" before.top="+before.top+" before.left="+before.left+" after.top="+after.top+" after.left="+after.left); - console.log("top11="+top11+" top12="+top12); - console.log("left11="+left11+" left12="+left12+" left21="+left21+" left22="+left22); + }; var fp_is_point_on_fp = function (p){ @@ -2033,7 +1989,7 @@ var floorplan = function(group,time) { $('#list_content').append("
");
         }
         $('#fp_graphic').bind("load", function () {
-            console.log("FP: background loaded.");
+//            console.log("FP: background loaded.");
             fp_resize_floorplan_image();
             floorplan(group, time);
         });
@@ -2165,7 +2121,7 @@ var floorplan = function(group,time) {
             return;
         }
 
-        console.log("FP: window resized");
+//        console.log("FP: window resized");
         fp_resize_floorplan_image();
         fp_reposition_entities();
     };
@@ -2275,16 +2231,13 @@ var floorplan = function(group,time) {
                                                     }
                                                 }
                                                 html += "";
-                                                //console.log("html="+html)
                                             }
                                             return html;
                                         }
                                     });
                                 } else {
                                     E.click( function () {
-                                        //var fp_entity = $(this).attr("id").split(/entity_/)[1]; //
                                         var fp_entity = $(this).attr("id").match(/entity_(.*)_\d+$/)[1]; //strip out entity_ and ending _X ... item names can have underscores in them.
-                                        //alert("entity="+fp_entity);
                                         create_state_modal(fp_entity);
                                     });
                                 }
@@ -2328,10 +2281,8 @@ var floorplan = function(group,time) {
                         url: "/LONG_POLL?json('GET','fp_icon_sets','px=48')",
                         dataType: "json",
                         error: function(xhr, textStatus, errorThrown){
-                            console.log('FP: request iconsets failed: "' + textStatus + '" "'+JSON.stringify(errorThrown, undefined,2)+'"');
                         },
                         success: function( json, statusText, jqXHR ) {
-                            console.log('FP: request iconsets: "' + statusText + '" "'+JSON.stringify(jqXHR, undefined,2)+'"');
                             var requestTime = time;
                             if (jqXHR.status === 200) {
                                 var iconlist = '
TimeStateSet By
"+new Date(json.data.data[i][0]).toUTCString()+""+new Date(json.data.data[i][0]).toString().replace(/GMT-\d\d\d\d/,"")+""+String(json.data.data[i][1])+""+String(json.data.data[i][2])+"