Skip to content

Instantly share code, notes, and snippets.

@pce
Created March 1, 2011 00:23
Show Gist options
  • Save pce/848353 to your computer and use it in GitHub Desktop.
Save pce/848353 to your computer and use it in GitHub Desktop.
monitor_changes_dir
#!/usr/bin/env php
<?php
/**
* monitor_changes_dir.php is a simple Command Line Script
* which monitor changes of a directory and calls a `on_file_change' function.
* Make sure it is executable.
*
* `on_file_change' calls sftp_upload,
*
* which requires libssh2
* $ apt-get install libssh2-1-dev libssh2-php
* http://www.php.net/manual/en/function.ssh2-scp-send.php
*
* An older version of this script that requires only
* `phpseclib' ( http://phpseclib.sourceforge.net/ )
* put `phpseclib' in the same dir as the Script, set the includepath.
* https://gist.github.com/486147
*
* @example
* $ php monitor_changes_dir.php
*
* @author Patrick C. Engel <[email protected]>
*
*/
(function_exists("ssh2_connect")) ||
die("function ssh2_connect doesn't exist");
$config = array(
'ssh' => array(
'host' => '10.10.11.22',
'port' => '22',
'username' => 'user',
'password' => 'passwd',
'localpath' => '/home/user/workspaces/project/src/',
'remotepath' => '/var/www/'
),
'exclude' => array(
// '*.swp',
'(.*?).swp',
'notes.txt'
)
);
// or return array from a file
$config = include dirname(__FILE__).'/monitor_changes_conf.php';
$myssh = $config['ssh'];
function every_n_seconds($n, $do, $args=array())
{
do {
$do($args);
sleep($n);
} while (true);
}
function monitor_changes($file, $resolution=2)
{
// printf("monitor_changes\n");
clearstatcache();
$last_change = time();
// printf(' $last_change: %s', $last_change."\n");
sleep($resolution);
$check = filemtime($file);
// printf(' $check: %s', $check."\n");
if ($check > $last_change) {
if (function_exists('on_file_change')) {
on_file_change($file);
}
}
$last_change = $check;
}
function is_excluded($file)
{
global $config;
if (!is_array($config['exclude'])) {
return false;
}
if (in_array($file, $config['exclude'])) {
return true;
}
foreach ($config['exclude'] as $regex) {
$regex = str_replace('/', '\/', $regex);
$regex = '^' . $regex . '\/?$';
if (preg_match("/$regex/i", $file)) {
return true;
}
}
return false;
}
$monitor_changes_dir = function ($dir, $resolution=4)
{
global $config;
clearstatcache();
$last_change = time();
sleep($resolution);
try {
$it = new DirectoryIterator($dir);
while($it->valid()) {
if(!$it->isDot()) {
$file = (string) $it->current();
$check = filemtime($dir.$file);
// printf(' $check: %s', $check."\n");
if ((!is_excluded($file))
&& ($check > $last_change)) {
on_file_change($file);
}
}
$it->next();
}
} catch(Exception $e) {
echo $e->getMessage();
exit(1);
}
};
function scp_upload_file($file)
{
global $myssh;
$localfile = $myssh['localpath'].$file;
$remotefile = $myssh['remotepath'].$file;
printf("[%s] changed %s\n ", date('c'), $localfile);
$connection = ssh2_connect($myssh['host'], $myssh['port']);
ssh2_auth_password(
$connection,
$myssh['username'],
$myssh['password']
);
$localfile = $myssh['localpath'].$file;
$remotefile = $myssh['remotepath'].$file;
ssh2_scp_send(
$connection,
$localfile,
$remotefile, 0644
);
printf("\n\t\scp '%s' '%s'\n",
$remotefile,
$localfile
);
}
/**
* when file changed event/hook
* @param string $file
*/
function on_file_change($file)
{
scp_upload_file($file);
}
$dir = $myssh['localpath'];
every_n_seconds(1, $monitor_changes_dir, $dir);
/*
set tabstop=4
set shiftwidth=4
set expandtab
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment