mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-03 11:42:19 +03:00
Some draft code for #318
This commit is contained in:
parent
dcbafb70eb
commit
95b7dee402
4 changed files with 115 additions and 24 deletions
|
|
@ -448,6 +448,33 @@ class ActionsAdmin extends Actions
|
|||
('plugin' !== $sType ? array('Reload' => true) : true) : false);
|
||||
}
|
||||
|
||||
// /?admin/Backup
|
||||
public function DoAdminBackup() : void
|
||||
{
|
||||
try {
|
||||
$this->IsAdminLoggined();
|
||||
$file = \SnappyMail\Upgrade::backup();
|
||||
\header('Content-Type: application/gzip');
|
||||
\header('Content-Disposition: attachment; filename="' . \basename($file) . '"');
|
||||
\header('Content-Transfer-Encoding: binary');
|
||||
\header('Content-Length: ' . \filesize($file));
|
||||
$fp = \fopen($file, 'rb');
|
||||
\fpassthru($fp);
|
||||
\unlink($file);
|
||||
} catch (\Throwable $e) {
|
||||
if (102 == $e->getCode()) {
|
||||
\MailSo\Base\Http::StatusHeader(403);
|
||||
}
|
||||
echo $e->getMessage();
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
public function DoAdminUpgradeCore() : array
|
||||
{
|
||||
return $this->DefaultResponse(__FUNCTION__, \SnappyMail\Upgrade::core());
|
||||
}
|
||||
|
||||
public function DoAdminPluginDisable() : array
|
||||
{
|
||||
$this->IsAdminLoggined();
|
||||
|
|
|
|||
|
|
@ -74,6 +74,16 @@ class ServiceActions
|
|||
return $this;
|
||||
}
|
||||
|
||||
/*
|
||||
public function ServiceBackup() : void
|
||||
{
|
||||
if (\method_exists($this->oActions, 'DoAdminBackup')) {
|
||||
$this->oActions->DoAdminBackup();
|
||||
}
|
||||
exit;
|
||||
}
|
||||
*/
|
||||
|
||||
public function ServiceJson() : string
|
||||
{
|
||||
\ob_start();
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ abstract class Repository
|
|||
// snappyMailRepo
|
||||
const BASE_URL = 'https://snappymail.eu/repository/v2/';
|
||||
|
||||
private static function get(string $path, string $proxy, string $proxy_auth) : string
|
||||
private static function get(string $path) : string
|
||||
{
|
||||
$oHTTP = HTTP\Request::factory(/*'socket' or 'curl'*/);
|
||||
$oHTTP->proxy = $proxy;
|
||||
$oHTTP->proxy_auth = $proxy_auth;
|
||||
$oHTTP->proxy = \RainLoop\Api::Config()->Get('labs', 'curl_proxy', '');
|
||||
$oHTTP->proxy_auth = \RainLoop\Api::Config()->Get('labs', 'curl_proxy_auth', '');
|
||||
$oHTTP->max_response_kb = 0;
|
||||
$oHTTP->timeout = 15; // timeout in seconds.
|
||||
$oResponse = $oHTTP->doRequest('GET', static::BASE_URL . $path);
|
||||
|
|
@ -26,16 +26,17 @@ abstract class Repository
|
|||
|
||||
// $aRep = \json_decode($sRep);
|
||||
|
||||
private static function download(string $path, string $proxy, string $proxy_auth) : string
|
||||
private static function download(string $path) : string
|
||||
{
|
||||
$sTmp = APP_PRIVATE_DATA . \md5(\microtime(true).$path) . \preg_replace('/^.*?(\\.[a-z\\.]+)$/Di', '$1', $path);
|
||||
$pDest = \fopen($sTmp, 'w+b');
|
||||
if (!$pDest) {
|
||||
throw new \Exception('Cannot create temp file: '.$sTmp);
|
||||
}
|
||||
|
||||
$oHTTP = HTTP\Request::factory(/*'socket' or 'curl'*/);
|
||||
$oHTTP->proxy = $proxy;
|
||||
$oHTTP->proxy_auth = $proxy_auth;
|
||||
$oHTTP->proxy = \RainLoop\Api::Config()->Get('labs', 'curl_proxy', '');
|
||||
$oHTTP->proxy_auth = \RainLoop\Api::Config()->Get('labs', 'curl_proxy_auth', '');
|
||||
$oHTTP->max_response_kb = 0;
|
||||
$oHTTP->timeout = 15; // timeout in seconds.
|
||||
$oHTTP->streamBodyTo($pDest);
|
||||
|
|
@ -81,10 +82,7 @@ abstract class Repository
|
|||
|
||||
if ('' === $sRep || 0 === $iRepTime || \time() - 3600 > $iRepTime)
|
||||
{
|
||||
$sRep = static::get($sRepoFile,
|
||||
\RainLoop\Api::Config()->Get('labs', 'curl_proxy', ''),
|
||||
\RainLoop\Api::Config()->Get('labs', 'curl_proxy_auth', '')
|
||||
);
|
||||
$sRep = static::get($sRepoFile);
|
||||
if ($sRep)
|
||||
{
|
||||
$aRep = \json_decode($sRep);
|
||||
|
|
@ -150,6 +148,21 @@ abstract class Repository
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
public static function getLatestCoreInfo()
|
||||
{
|
||||
\RainLoop\Api::Actions()->IsAdminLoggined();
|
||||
$sRep = static::get('core.json');
|
||||
return $sRep ? \json_decode($sRep) : null;
|
||||
}
|
||||
|
||||
public static function downloadCore(string $path) : ?string
|
||||
{
|
||||
$info = static::getLatestCoreInfo();
|
||||
return \version_compare(APP_VERSION, $info->version, '<')
|
||||
? static::download($info->file) // '../latest.tar.gz'
|
||||
: null;
|
||||
}
|
||||
|
||||
public static function getPackagesList() : array
|
||||
{
|
||||
\RainLoop\Api::Actions()->IsAdminLoggined();
|
||||
|
|
@ -230,27 +243,23 @@ abstract class Repository
|
|||
}
|
||||
if (isset($aList[$sId]) && $sFile === $aList[$sId]['file']) {
|
||||
$sRealFile = $sFile;
|
||||
$sTmp = static::download($sFile,
|
||||
\RainLoop\Api::Config()->Get('labs', 'curl_proxy', ''),
|
||||
\RainLoop\Api::Config()->Get('labs', 'curl_proxy_auth', '')
|
||||
);
|
||||
$sTmp = static::download($sFile);
|
||||
}
|
||||
}
|
||||
|
||||
if ($sTmp) {
|
||||
$oArchive = new \PharData($sTmp, 0, $sRealFile);
|
||||
if (static::deletePackageDir($sId)) {
|
||||
if ('.phar' === \substr($sRealFile, -5)) {
|
||||
$bResult = \copy($sTmp, APP_PLUGINS_PATH . \basename($sRealFile));
|
||||
} else {
|
||||
$bResult = $oArchive->extractTo(\rtrim(APP_PLUGINS_PATH, '\\/'));
|
||||
}
|
||||
if (!$bResult) {
|
||||
throw new \Exception('Cannot extract package files: '.$oArchive->getStatusString());
|
||||
}
|
||||
} else {
|
||||
if (!static::deletePackageDir($sId)) {
|
||||
throw new \Exception('Cannot remove previous plugin folder: '.$sId);
|
||||
}
|
||||
if ('.phar' === \substr($sRealFile, -5)) {
|
||||
$bResult = \copy($sTmp, APP_PLUGINS_PATH . \basename($sRealFile));
|
||||
} else {
|
||||
$bResult = $oArchive->extractTo(\rtrim(APP_PLUGINS_PATH, '\\/'));
|
||||
}
|
||||
if (!$bResult) {
|
||||
throw new \Exception('Cannot extract package files: '.$oArchive->getStatusString());
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
\RainLoop\Api::Logger()->Write("Install package {$sRealFile} failed: {$e->getMessage()}", \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
||||
|
|
|
|||
|
|
@ -162,4 +162,49 @@ abstract class Upgrade
|
|||
return \unserialize($sData) ?: array();
|
||||
}
|
||||
}
|
||||
|
||||
public static function backup() : string
|
||||
{
|
||||
// $tar_destination = APP_DATA_FOLDER_PATH . APP_VERSION . '.tar';
|
||||
$tar_destination = APP_DATA_FOLDER_PATH . 'backup-' . \date('YmdHis') . '.tar';
|
||||
$tar = new \PharData($tar_destination);
|
||||
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(APP_DATA_FOLDER_PATH . '_data_'), \RecursiveIteratorIterator::SELF_FIRST);
|
||||
$l = \strlen(APP_DATA_FOLDER_PATH);
|
||||
foreach ($files as $file) {
|
||||
$file = \str_replace('\\', '/', $file);
|
||||
if (\is_file($file) && !\strpos($file, '/cache/')) {
|
||||
$tar->addFile($file, \substr($file, $l));
|
||||
}
|
||||
}
|
||||
$tar->compress(\Phar::GZ);
|
||||
\unlink($tar_destination);
|
||||
return $tar_destination . '.gz';
|
||||
}
|
||||
|
||||
public static function core() : bool
|
||||
{
|
||||
$this->IsAdminLoggined();
|
||||
|
||||
$bResult = false;
|
||||
if (\version_compare(APP_VERSION, '2.0', '>')
|
||||
&& \is_writable(\dirname(APP_VERSION_ROOT_PATH))
|
||||
&& \is_writable(APP_INDEX_ROOT_PATH . 'index.php')
|
||||
) {
|
||||
$sTmp = null;
|
||||
try {
|
||||
$sTmp = Repository::downloadCore($info->file);
|
||||
if ($sTmp) {
|
||||
static::backup();
|
||||
$oArchive = new \PharData($sTmp, 0);
|
||||
$bResult = $oArchive->extractTo(\rtrim(APP_VERSION_ROOT_PATH, '\\/'));
|
||||
if (!$bResult) {
|
||||
throw new \Exception('Cannot extract core files: '.$oArchive->getStatusString());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
$sTmp && \unlink($sTmp);
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue