php

Automate Ubuntu Server Shutdown

power downSomebody on the Ubuntu Forums was asking how to get their server to shut down automatically when no other computers are online on the network.  This can be useful if you have Wake-On-Lan enabled on the server, and you're only using it for things like printer or file sharing.  I responded with a little php script I whipped up that does the job nicely.

You will need the php package and the nmap package to make this work

sudo apt-get install php nmap

Next, you'll need to know how to setup a cron job.  If you don't, check out this tutorial.

Here is the contents of the php file.
hostsup.php
 

<?php
// Call the nmap command
$output shell_exec('nmap -sP 192.168.1.*');

// Split up the output so we get the number of hosts up
$split1 explode("addresses ("$output);
$split2 explode(" hosts up"$split1[1]);
$hostsup $split2[0];

// If only x number of computer are on + router, shutdown.  Take in account the server being a computer!
if($hostsup == "2") {
    
$shutdown shell_exec('shutdown -h now');
}
?>

You'll need to edit the "192.168.1.*" to fit your network's IP range.  Also, change the $hostsup == "2" to the number of computers you want on when it shuts down.  The server counts as one, your router counts as one, and if you have any of those network printers, they also count.  If it gets an IP, count it.  Feel free to change the shutdown command to something else if you want to put the server into standby or what have you.

In your cron job, just set the command as

php -f /path/to/file/hostsup.php

Set the cron to run as often as you like.  I'd set it for every half-hour just to not use up too many resources, and still be effective.

What this script is doing is executing "nmap -sP 192.168.1.*".  This generates a list of nodes on the network that are currently online, and their IP addresses.  The next 3 lines parse through the information to only get the number of nodes online.  Next we check how many are online, if the numbers match then execute the shutdown command.  You'll need root or sudo access to use the shutdown command, so watch out. Read more about Automate Ubuntu Server Shutdown

Javascript and CSS aggregator/compressor

clampI used an existing php class from http://joliclic.free.fr/php/javascript-packer/en/
Should work on both php4 and php5
(if using php4, just replace class.JavaScriptPacker.php with class.JavaScriptPacker.php4)

This is setup for the following-

/
/inc/
/inc/class.JavaScriptPacker.php
/js/
/js/cache/
/js/main.js
/js/tooltip.js
/js/js.php
/css/
/css/cache
/css/main.css
/ibox/skins/darkbox/darkbox.css

Make sure that /js/cache/ and /css/cache/ are writeable (chmod 777 for most people)

Here is /js/js.php

/js/js.php

 

<?php
ob_start
();
require 
'../inc/class.JavaScriptPacker.php';

/********************************************
Edit the array below to add javascript files, relative to the location of this file.
*/
$arFiles = array(
        
"main.js",
        
"tooltip.js",
        );
/********************************************/
function compressJavascript($file) {
    
$script file_get_contents($file);
    
$packer_php = new JavaScriptPacker($script"Normal"truefalse);
    
$output $packer_php->pack();
    
    return 
$output;
}
$output "";

for(
$i 0$i count($arFiles); $i++) {
    
$devcontent file_get_contents($arFiles[$i]);
    
    if(
file_exists("cache/" md5($arFiles[$i]) . ".cache")) {
        
//file exists.
        
$content file_get_contents("cache/" md5($arFiles[$i]) . ".cache");
        
$split explode("#",$content,2);

        if(
$split[0] == md5($devcontent)) {
            
//file was not modified according to md5
            
$output $output $split[1];
        }else{
            
//file was modified according to md5, so update it.
            
$newcontent compressJavascript($arFiles[$i]);
            
$create file_put_contents("cache/" md5($arFiles[$i]) . ".cache"md5($devcontent) . "#" $newcontent);
            
$output $output $newcontent;
        }
    }else{
        
//file doesn't exist.
        
$newcontent compressJavascript($arFiles[$i]);
        
$create file_put_contents("cache/" md5($arFiles[$i]) . ".cache"md5($devcontent) . "#" $newcontent);
        
$output $output $newcontent;
    }
    
}
header("Content-Type: application/javascript");
echo 
$output;
?>

Then here's /css/css.php

/css/css.php

 

<?php
ob_start
();
require 
'../inc/class.JavaScriptPacker.php';

/********************************************
Edit the array below to add css files, relative to the location of this file.
*/
$arFiles = array(
        
"main.css",
        
"../ibox/skins/darkbox/darkbox.css",
        );
/********************************************/
function compressCSS($file) {
    
$script file_get_contents($file);
    
$packer_css = new JavaScriptPacker($script'None'truefalse);
    
$output $packer_css->pack();
    
    return 
$output;
}
$output "";

for(
$i 0$i count($arFiles); $i++) {
    
$devcontent file_get_contents($arFiles[$i]);
    
    if(
file_exists("cache/" md5($arFiles[$i]) . ".cache")) {
    
        
//file exists.
        
$content file_get_contents("cache/" md5($arFiles[$i]) . ".cache");
        
$split explode("#",$content,2);

        if(
$split[0] == md5($devcontent)) {
            
//file was not modified according to md5
            
$output $output $split[1];
        }else{
            
//file was modified according to md5, so update it.
            
$newcontent compressCSS($arFiles[$i]);
            
$create file_put_contents("cache/" md5($arFiles[$i]) . ".cache"md5($devcontent) . "#" $newcontent);
            
$output $output $newcontent;
        }
    }else{
        
//file doesn't exist.
        
$newcontent compressCSS($arFiles[$i]);
        
$create file_put_contents("cache/" md5($arFiles[$i]) . ".cache"md5($devcontent) . "#" $newcontent);
        
$output $output $newcontent;
    }
    
}
header("Content-Type: text/css");
echo 
$output;
?>

 

What the packer does is strip comments, remove whitespace, and (for the javascript one) it will create shorter variables, and encode it. This is useful because it will save bandwidth and make it a little more challenging for people to take your code or figure out your system.

The js.php and css.php use different compression types. Javascript uses "normal" because this will create shorter variables and whatnot. CSS uses "none" so that only comments and whitespace are removed. If you use "normal" on CSS you'll end up with javascript instead of css code.

So instead of using a <script> or <style> tags for each of your js/css files, you can use two to include js.php and css.php files (or even use PHP to include them in your file, removing any extra http requests.) Then edit the arrays in js.php and css.php to add files. They are all compressed into one page which will cut down on page requests as well as bandwidth.

The advantage of using this is so that you can develop in plain, readable text but still compress or hide your code to users without doing any extra steps. The updated code will create cached versions of the compressed files. Then using md5, compare the 2 copies. If the md5 is different, then it will update the cache.

It's not intended for sites under development. It's almost impossible to debug your javascript if it's compressed/encoded so I'd recommend only using this on a production version of your web site. Read more about Javascript and CSS aggregator/compressor

Subscribe to php