Temat: Ktoś może zna system kontroli wersji dla którego istnieje...
Przestałem marzyć o wykorzystaniu sytemu kontroli wersji do rozwiązania tego problemu i tak na szybko sobie wystrugałem coś takiego:
#!/usr/bin/php
<?php
$user = '';
$pass = '';
$server = '';
$serverFtp = '';
$dir = ''; // must have trailing slash if not empty
$secret = 'secretsfdsfajoijid3czxc423423'; // anyone can get list of all files on the server by calling /uploader.php?secret
$exclude= '/Thumbs.db$/|devel/|/\\.(svn|bzr|git)/|(~|\\.bak|\\.orig)$';
function getLocalFileNamesWithMd5s() {
global $exclude;
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(".")) as $file) {
if(!preg_match("`$exclude`", $file->getPathname())) {
$files[$file->getPathname()] = md5(file_get_contents($file->getPathname()));
}
}
return $files;
}
if(php_sapi_name() == "cli"){
$localFiles = getLocalFileNamesWithMd5s();
foreach(file("http://$server/uploader.php?".urlencode($secret), FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
list($md5, $fileName) = explode(" ", $line);
if($localFiles[$fileName] == $md5) {
unset($localFiles[$fileName]);
}
}
if($localFiles) {
$myName = $_SERVER['SCRIPT_FILENAME'];
$ftp = ftp_connect($serverFtp, 21, 10);
if(!$ftp) die;
ftp_login($ftp, $user, $pass);
ftp_pasv($ftp, true);
if($dir) ftp_chdir($ftp, $dir);
ksort($localFiles);
if(isset($localFiles[$myName])) {
unset($localFiles[$myName]);
$localFiles = array_keys($localFiles);
array_unshift($localFiles, $myName);
} else {
$localFiles = array_keys($localFiles);
}
echo "Files to upload:\n".implode("\n", $localFiles)."\n\n";
sleep(5);
foreach($localFiles as $fileName) {
echo "Sending $fileName ... ";
$dirParts = explode('/', dirname(substr($fileName, 2)));
for($i = 1; $i <= count($dirParts); $i++) {
@ftp_mkdir($ftp, implode('/', array_slice($dirParts, 0, $i)));
}
ftp_put($ftp, $fileName, $fileName, FTP_BINARY);
echo "ok\n";
if($fileName == $myName) {
ftp_close($ftp);
die("Just updated self. Please run me again.\n");
}
}
ftp_close($ftp);
} else {
echo "Nothing to send.\n";
}
} else {
if($_SERVER['QUERY_STRING'] == $secret) {
foreach(getLocalFileNamesWithMd5s() as $fileName => $md5) {
echo "$md5 $fileName\n";
}
}
}
Skonfigurować, wrzucić do głównego katalogu z przetestowaną kopią roboczą, odpalić z konsoli.
Łączy się z serwerem ftp i wysyła tam samego siebie. Przy ponownym odpaleniu wykonuje zdalną kopię siebie, która zwraca nazwy plików na serwerze wraz z ich md5. Wysyła FTP-em tylko te pliki lokalne, które mają różne md5 od pobranych.
Możliwe zmiany:
- dla bezpieczeństwa pobierać hasło ftp z $argv, albo wysyłać na serwer tylko część siebie, która jest konieczna (bez konfiguracji ftp).
- dla szybkości, oprócz plików śledzić również katalogi tak, żeby można było założyć je zawczasu (a nie tak jak teraz, podczas uploadowania leżących w nich plików) + gzipować zwracaną z serwera listę nazw plików jeżeli sam serwer tego nie robi.
Kamil Szot edytował(a) ten post dnia 27.10.09 o godzinie 13:00