Skip to content

Instantly share code, notes, and snippets.

@jeka-kiselyov
Last active August 16, 2018 04:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jeka-kiselyov/643474c4705ce98ec62f to your computer and use it in GitHub Desktop.
Save jeka-kiselyov/643474c4705ce98ec62f to your computer and use it in GitHub Desktop.
Backup wordpress installation and blog database to pbworks workspace
<?php
//// usage - php backup.php domain
$network = 'network';
$workspace = 'workspace';
$apikey = '...........';
$tmp_path = sys_get_temp_dir(); //// should be writable
define( 'ABSPATH', dirname(__FILE__) . '/' );
//// create empty wp-settings.php file (wp config tries to find it)
if (!is_file(ABSPATH.'wp-settings.php'))
file_put_contents(ABSPATH.'wp-settings.php', '');
$what = 0;
if (isset($argv[1])) $what = trim($argv[1]);
if (strpos($what, '.') === false)
$path = $what.".com";
$old = umask();
if (is_file('/var/www/'.$path.'/wp-config.php'))
require '/var/www/'.$path.'/wp-config.php';
else
die("Config file not found\n");
umask($old);
$db_common_host = DB_HOST;
define('__db_database__', DB_NAME);
define('__file_path__', "/var/www/".$path);
define('__db_password__', DB_PASSWORD);
define('__db_username__', DB_USER);
define('__db_host__', DB_HOST);
$backup_name = __db_database__."_backup";
$backups = array();
$backups[] = array('type'=>'mysql', 'host'=>__db_host__, 'user'=>__db_username__, 'password'=>__db_password__, 'database'=>__db_database__);
$backups[] = array('type'=>'folder', 'folder'=>__file_path__);
if (!$network || !$workspace || !$apikey)
die("ERROR:'\n");
$pbworks = new pbworks($network, $workspace, $apikey);
$free_space = $pbworks->get_free_space();
echo "Free space on pbworks workspace: ".$free_space." KB\n\n";
if (!$free_space)
die("ERROR: Can't get free space on workspace. Be sure to run script as 'php backup_to_pbworks.php network workspace apikey'\n");
$time_string = date("Ymd-Hi"); /// time part of filenames
$filter = $backup_name; /// We'll use it to filter remote backups;
$archive_file_name = $filter."-".$time_string.".tgz";
$keep_rules = array(); //// Keep archives for this times
$keep_rules[] = array('from' => false, 'to'=>time()-24*60*60); // 1 day.
$keep_rules[] = array('from' => time()-24*60*60, 'to'=>time()-2*24*60*60); // 2 days
$keep_rules[] = array('from' => time()-2*24*60*60, 'to'=>time()-3*24*60*60); // 3 days
$keep_rules[] = array('from' => time()-3*24*60*60, 'to'=>time()-7*24*60*60); // 1 week
$keep_rules[] = array('from' => time()-7*24*60*60, 'to'=>time()-30*24*60*60); // 1 month
$keep_rules[] = array('from' => time()-30*24*60*60, 'to'=>time()-365*24*60*60); // 1 year
if (substr($tmp_path, -1) !== '/')
$tmp_path.='/';
/// Remove old files from pbworks
echo "Removing remote backups...\n";
$i = 0;
$files = $pbworks->get_files($filter);
echo "There're ".count($files)." files on pbworks workspace\n";
foreach ($keep_rules as $rule)
{
$rule['most_recent_file'] = false;
$rule['oldest_file'] = false;
$count_files = 0;
foreach ($files as $key=>$file)
if ( ($rule['from'] !== false && $file['mtime'] >= $rule['to'] && $file['mtime'] <= $rule['from']) || ($rule['from'] === false && $file['mtime'] >= $rule['to']) )
{
$count_files++;
if ($rule['most_recent_file'] === false)
$rule['most_recent_file'] = $key;
else
{
if ($file['mtime'] > $files[$rule['most_recent_file']]['mtime'])
$rule['most_recent_file'] = $key;
}
if ($rule['oldest_file'] === false)
$rule['oldest_file'] = $key;
else
{
if ($file['mtime'] < $files[$rule['oldest_file']]['mtime'])
$rule['oldest_file'] = $key;
}
}
if ($rule['most_recent_file'] !== false)
$files[$rule['most_recent_file']]['keep'] = true;
if ($rule['oldest_file'] !== false)
$files[$rule['oldest_file']]['keep'] = true;
echo "Keep rule #".$i++.": ".$count_files." files\n";
}
/// Send queries to pbworks to remove
foreach ($files as $file)
{
if (!isset($file['keep']) || !$file['keep'])
{
echo "Removing remote backup ".$file['name']."\n";
$pbworks->remove_file($file['name']);
} else
echo "Keeping remote backup ".$file['name']."\n";
}
echo "Done.\n\n";
$i=0;
$ready_filenames = array();
foreach ($backups as $backup)
{
echo "Making backup #".$i."...\n";
if ($backup['type'] == 'mysql')
$filename = $i."_".$backup['database']."_".$time_string.".sql";
elseif ($backup['type'] == 'folder')
$filename = $i."_backup_".$time_string.".tar";
echo "Filename: ".$filename."\n";
if ($backup['type'] == 'mysql')
$cmd = "mysqldump --host=".$backup['host']." --password=".escapeshellarg($backup['password'])." --user=".$backup['user']." -C ".$backup['database']." >> ".$tmp_path.$filename;
else
$cmd = "tar -cvPf ".$tmp_path.$filename." ".$backup['folder'];
echo "Executing...\n";
$s = exec($cmd, $o);
sleep(1);
if (is_file($tmp_path.$filename))
{
$ready_filenames[] = $tmp_path.$filename;
echo "File is ready.\n";
} else {
echo "ERROR: File is not ready. Please check configuration.\n";
}
$i++;
}
//// Merging.
echo "Making merge archive...\n";
$merge_cmd = "tar -zPcvf ".$tmp_path.$archive_file_name." ".implode(" ", $ready_filenames);
echo "Executing...\n";
$s = exec($merge_cmd, $o);
sleep(1);
if (is_file($tmp_path.$archive_file_name))
{
echo "Backup file created: ".$archive_file_name."\n";
echo "Uploading...\n";
///// Uploading
$success = $pbworks->submit_file($tmp_path.$archive_file_name);
if ($success)
{
echo "SUCCESS: Backup file is on pbworks now\n";
} else {
echo "ERROR: Can not upload file to pbworks\n";
}
} else {
echo "ERROR: No backup. Something is wrong\n";
}
///// Clean up
echo "Cleaning up...\n";
foreach ($ready_filenames as $filename)
{
unlink($filename);
}
unlink($tmp_path.$archive_file_name);
echo "Done.\n";
class pbworks {
private $regular_query_timeout = 30;
private $upload_query_timeout = 300;
public $network;
public $workspace;
private $user_key;
public function pbworks($network, $workspace, $user_key)
{
$this->network = $network;
$this->workspace = $workspace;
$this->user_key = $user_key;
}
public function get_host()
{
return $this->network."-".$this->workspace.".pbworks.com";
}
public function get_free_space()
{
$stats = $this->query("op/GetStorageInfo");
if (isset($stats->available))
return $stats->available;
else
return 0;
}
public function remove_file($filename)
{
$data = $this->query("op/DeleteFile/file/".$filename);
if (isset($data->success) && $data->success)
return true;
else
return false;
}
public function get_files($filter = false)
{
if ($filter)
$data = $this->query("op/GetFiles/filter/".$filter);
else
$data = $this->query("op/GetFiles");
$files = array();
if (!isset($data->files) || !$data->files)
return array();
foreach ($data->files as $f)
$files[] = array('name'=>$f->name, "mtime"=>$f->mtime);
return $files;
}
public function submit_file($filename)
{
set_time_limit($this->upload_query_timeout);
$fname = explode("/", $filename);
if ($fname)
$fname = $fname[count($fname)-1];
else
$fname = $filename;
$boundary = md5(rand(0, time())).md5(time());
$precontent = "--".$boundary."\r\n";
$precontent.= "Content-Disposition: form-data; name=\"var_file\"; filename=\"".urlencode($fname)."\"\r\n";
$precontent.= "Content-Type: application/x-gzip\r\n\r\n";
$postcontent="\r\n--".$boundary."--\r\n";
$content_length = strlen($precontent)+strlen($postcontent)+filesize($filename);
$fp = fsockopen("ssl://".$this->get_host(), 443, $errno, $errstr, $this->upload_query_timeout);
if (!$fp)
{
return false;
}
$out = "POST /api_v2/op/PutFile/user_key/".$this->user_key."/filename/".urlencode($fname)."/raw/false HTTP/1.1\r\n";
$out .= "Host: ".$this->get_host()."\r\n";
$out .= "Content-Type: multipart/form-data, boundary=".$boundary."\r\n";
$out .= "Content-Length: ".$content_length."\r\n\r\n";
fwrite($fp, $out);
fwrite($fp, $precontent);
$toout = fopen($filename, "rb");
while (!feof($toout))
{
fwrite($fp, fread($toout, 100*1024));
usleep(100);
}
fclose($toout);
fwrite($fp, $postcontent);
$headers = "";
$results = "";
$current = 'headers';
while (!feof($fp)) {
if ($current == 'results')
$results.= fgets($fp, 128);
else
$headers.= fgets($fp, 128);
if ($current == 'headers' && strpos($headers, "\r\n\r\n") !== false)
{
$headers = explode("\r\n\r\n", $headers);
$results = $headers[1];
$headers = $headers[0];
$current = 'results';
}
}
$results = substr($results, strpos($results, "/*-secure-")+11); /// remove secure wrapper from json
$results = substr($results, 0, strrpos($results, "*/"));
$results = @json_decode($results);
if (!isset($results->success) || !$results->success)
return false;
else
return true;
}
public function query($params)
{
$fp = fsockopen("ssl://".$this->get_host(), 443, $errno, $errstr, $this->regular_query_timeout);
if (!$fp)
{
throw new Exception("Can not connect to ".$this->get_host()." via ssl", 1);
}
$out = "GET /api_v2/".$params."/user_key/".$this->user_key." HTTP/1.1\r\n";
$out .= "Host: ".$this->get_host()."\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
$headers = "";
$results = "";
$current = 'headers';
while (!feof($fp))
{
if ($current == 'results')
$results.= fgets($fp, 128);
else
$headers.= fgets($fp, 128);
if ($current == 'headers' && strpos($headers, "\r\n\r\n") !== false)
{
$headers = explode("\r\n\r\n", $headers);
$results = $headers[1];
$headers = $headers[0];
$current = 'results';
}
}
$results = substr($results, strpos($results, "/*-secure-")+11); /// remove s$
$results = substr($results, 0, strrpos($results, "*/"));
$results = @json_decode($results);
if (!$results)
{
return false;
}
return $results;
}
}
<?php
//// usage - php downloadbackup.php domain
$network = 'network';
$workspace = 'workspace';
$apikey = '...........';
$tmp_path = sys_get_temp_dir(); //// should be writable
define( 'ABSPATH', dirname(__FILE__) . '/' );
//// create empty wp-settings.php file (wp config tries to find it)
if (!is_file(ABSPATH.'wp-settings.php'))
file_put_contents(ABSPATH.'wp-settings.php', '');
$what = 0;
if (isset($argv[1])) $what = trim($argv[1]);
if (strpos($what, '.') === false)
$path = $what.".com";
$backup_name = $what."_backup";
if (!$network || !$workspace || !$apikey)
die("ERROR:'\n");
$pbworks = new pbworks($network, $workspace, $apikey);
$free_space = $pbworks->get_free_space();
echo "Free space on pbworks workspace: ".$free_space." KB\n\n";
if (!$free_space)
die("ERROR: Can't get free space on workspace. Be sure to run script as 'php backup_to_pbworks.php network workspace apikey'\n");
$files = $pbworks->get_files($backup_name);
$most_recent_mtime = 0;
$most_recent_fname = '';
foreach ($files as $f) {
if ($f['mtime'] > $most_recent_mtime) {
$most_recent_mtime = $f['mtime'];
$most_recent_fname = $f['name'];
}
}
if (!$most_recent_fname)
die("Can not find any backup file\n");
$url = $pbworks->get_download_link($most_recent_fname);
if (!$url)
die("Can not get file url");
echo "Downloading ".$url."...\n";
set_time_limit(0);
$fp = fopen ('backup.tgz', 'w+');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 75);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_exec($ch);
curl_close($ch);
fclose($fp);
// var_dump($files);
echo "Done.\n";
class pbworks {
private $regular_query_timeout = 30;
private $upload_query_timeout = 300;
public $network;
public $workspace;
private $user_key;
public function pbworks($network, $workspace, $user_key)
{
$this->network = $network;
$this->workspace = $workspace;
$this->user_key = $user_key;
}
public function get_host()
{
return $this->network."-".$this->workspace.".pbworks.com";
}
public function get_free_space()
{
$stats = $this->query("op/GetStorageInfo");
if (isset($stats->available))
return $stats->available;
else
return 0;
}
public function remove_file($filename)
{
$data = $this->query("op/DeleteFile/file/".$filename);
if (isset($data->success) && $data->success)
return true;
else
return false;
}
public function get_download_link($filename)
{
$data = $this->query("op/GetFile/file/".$filename);
var_dump($data);
if (isset($data['url']) && $data['url'])
return $data['url'];
else
return false;
}
public function get_files($filter = false)
{
if ($filter)
$data = $this->query("op/GetFiles/filter/".$filter);
else
$data = $this->query("op/GetFiles");
$files = array();
if (!isset($data->files) || !$data->files)
return array();
foreach ($data->files as $f)
$files[] = array('name'=>$f->name, "mtime"=>$f->mtime);
return $files;
}
public function submit_file($filename)
{
set_time_limit($this->upload_query_timeout);
$fname = explode("/", $filename);
if ($fname)
$fname = $fname[count($fname)-1];
else
$fname = $filename;
$boundary = md5(rand(0, time())).md5(time());
$precontent = "--".$boundary."\r\n";
$precontent.= "Content-Disposition: form-data; name=\"var_file\"; filename=\"".urlencode($fname)."\"\r\n";
$precontent.= "Content-Type: application/x-gzip\r\n\r\n";
$postcontent="\r\n--".$boundary."--\r\n";
$content_length = strlen($precontent)+strlen($postcontent)+filesize($filename);
$fp = fsockopen("ssl://".$this->get_host(), 443, $errno, $errstr, $this->upload_query_timeout);
if (!$fp)
{
return false;
}
$out = "POST /api_v2/op/PutFile/user_key/".$this->user_key."/filename/".urlencode($fname)."/raw/false HTTP/1.1\r\n";
$out .= "Host: ".$this->get_host()."\r\n";
$out .= "Content-Type: multipart/form-data, boundary=".$boundary."\r\n";
$out .= "Content-Length: ".$content_length."\r\n\r\n";
fwrite($fp, $out);
fwrite($fp, $precontent);
$toout = fopen($filename, "rb");
while (!feof($toout))
{
fwrite($fp, fread($toout, 100*1024));
usleep(100);
}
fclose($toout);
fwrite($fp, $postcontent);
$headers = "";
$results = "";
$current = 'headers';
while (!feof($fp)) {
if ($current == 'results')
$results.= fgets($fp, 128);
else
$headers.= fgets($fp, 128);
if ($current == 'headers' && strpos($headers, "\r\n\r\n") !== false)
{
$headers = explode("\r\n\r\n", $headers);
$results = $headers[1];
$headers = $headers[0];
$current = 'results';
}
}
$results = substr($results, strpos($results, "/*-secure-")+11); /// remove secure wrapper from json
$results = substr($results, 0, strrpos($results, "*/"));
$results = @json_decode($results);
if (!isset($results->success) || !$results->success)
return false;
else
return true;
}
public function query($params)
{
$fp = fsockopen("ssl://".$this->get_host(), 443, $errno, $errstr, $this->regular_query_timeout);
if (!$fp)
{
throw new Exception("Can not connect to ".$this->get_host()." via ssl", 1);
}
$out = "GET /api_v2/".$params."/user_key/".$this->user_key." HTTP/1.1\r\n";
$out .= "Host: ".$this->get_host()."\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
$headers = "";
$results = "";
$current = 'headers';
while (!feof($fp))
{
if ($current == 'results')
$results.= fgets($fp, 128);
else
$headers.= fgets($fp, 128);
if ($current == 'headers' && strpos($headers, "\r\n\r\n") !== false)
{
$headers = explode("\r\n\r\n", $headers);
$results = $headers[1];
$headers = $headers[0];
$current = 'results';
}
}
$results = substr($results, strpos($results, "/*-secure-")+11); /// remove s$
$results = substr($results, 0, strrpos($results, "*/"));
$results = @json_decode($results);
preg_match("#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#", $headers, $m);
if ($m && $m[0]) {
$results['url'] = $m[0];
}
if (!$results)
{
return false;
}
return $results;
}
}
#!/bin/bash
run()
{
echo "Restore backup"
echo "Please enter backup filename. Should be located in current directory:"
read archive
tmpfile=$(mktemp /tmp/restore_backup.XXXXXX)
tar -tvf $archive >> $tmpfile
backupfname="$(grep -i 'sql' $tmpfile | awk '{print $NF}')";
echo "Found backup: ${backupfname}"
tar --strip-components=1 -zxvf $archive $backupfname
}
run
#!/bin/bash
run()
{
echo "Restore backup"
echo "Please enter backup filename. Should be located in current directory:"
read archive
tmpfile=$(mktemp /tmp/restore_backup.XXXXXX)
tar -tvf $archive >> $tmpfile
backupfname="$(grep -i 'backup' $tmpfile | awk '{print $NF}')";
echo "Found backup: ${backupfname}"
tar --strip-components=1 -zxvf $archive $backupfname
backupfilename=$(basename $backupfname)
tar -xvf $backupfilename -C /
}
run
mysql -h localhost -u username -p dbname < 0_db_20170118-1432.sql
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment