Working on self update feature

This commit is contained in:
Sergio Brighenti 2019-01-24 21:48:22 +01:00
parent 7671962506
commit af92f3d70a
7 changed files with 170 additions and 9 deletions

View file

@ -0,0 +1,121 @@
<?php
namespace App\Controllers;
use Slim\Http\Request;
use Slim\Http\Response;
use ZipArchive;
class UpgradeController extends Controller
{
const GITHUB_SOURCE_API = 'https://api.github.com/repos/SergiX44/XBackBone/releases';
/**
* @param Request $request
* @param Response $response
* @return Response
*/
public function upgrade(Request $request, Response $response): Response
{
try {
$json = $this->getApiJson();
} catch (\RuntimeException $e) {
$jsonResponse['message'] = $e->getMessage();
return $response->withJson($jsonResponse, 503);
}
if (version_compare($json[0]->tag_name, PLATFORM_VERSION, '<=')) {
$this->session->alert(lang('already_latest_version'), 'warning');
return redirect($response, 'system');
}
$tmpFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'xbackbone_update.zip';
if (file_put_contents($tmpFile, file_get_contents($json[0]->assets[0]->browser_download_url)) === false) {
$this->session->alert(lang('cannot_retrieve_file'), 'danger');
return redirect($response, 'system');
};
if (filesize($tmpFile) !== $json[0]->assets[0]->size) {
$this->session->alert(lang('file_size_no_match'), 'danger');
return redirect($response, 'system');
}
$updateZip = new ZipArchive();
$updateZip->open($tmpFile);
for ($i = 0; $i < $updateZip->numFiles; $i++) {
$nameIndex = $updateZip->getNameIndex($i);
if (is_dir(BASE_DIR . $nameIndex)) {
continue;
}
if (file_exists(BASE_DIR . $nameIndex) && md5($updateZip->getFromIndex($i)) !== md5_file(BASE_DIR . $nameIndex)) {
$updateZip->extractTo(BASE_DIR, $nameIndex);
} elseif (!file_exists(BASE_DIR . $nameIndex)) {
$updateZip->extractTo(BASE_DIR, $nameIndex);
}
print_r($updateZip->getNameIndex($i) . '<br>');
}
$updateZip->close();
unlink($tmpFile);
return redirect($response, '/install');
}
/**
* @param Request $request
* @param Response $response
* @return Response
*/
public function checkForUpdates(Request $request, Response $response): Response
{
$jsonResponse = [
'status' => null,
'message' => null,
'upgrade' => false,
];
try {
$json = $this->getApiJson();
$jsonResponse['status'] = 'OK';
if (version_compare($json[0]->tag_name, PLATFORM_VERSION, '>')) {
$jsonResponse['message'] = lang('new_version_available', $json[0]->tag_name); //"New version {$json[0]->tag_name} available!";
$jsonResponse['upgrade'] = true;
} else {
$jsonResponse['message'] = lang('already_latest_version');//'You have already the latest version.';
$jsonResponse['upgrade'] = false;
}
return $response->withJson($jsonResponse, 200);
} catch (\RuntimeException $e) {
$jsonResponse['status'] = 'ERROR';
$jsonResponse['message'] = $e->getMessage();
return $response->withJson($jsonResponse, 503);
}
}
protected function getApiJson()
{
$opts = [
'http' => [
'method' => 'GET',
'header' => [
'User-Agent: XBackBone-App',
'Accept: application/vnd.github.v3+json',
],
],
];
$data = file_get_contents(self::GITHUB_SOURCE_API, false, stream_context_create($opts));
if ($data === false) {
throw new \RuntimeException('Cannot contact the Github API. Try again.');
}
return json_decode($data);
}
}

View file

@ -233,11 +233,11 @@ if (!function_exists('dd')) {
*/
function dd()
{
echo '<pre>';
array_map(function ($x) {
echo '<pre>';
print_r($x);
echo '</pre>';
}, func_get_args());
echo '</pre>';
die();
}
}

View file

@ -5,9 +5,15 @@ $app->group('', function () {
$this->group('', function () {
$this->get('/home/switchView', \App\Controllers\DashboardController::class . ':switchView')->setName('switchView');
$this->get('/system/deleteOrphanFiles', \App\Controllers\AdminController::class . ':deleteOrphanFiles')->setName('system.deleteOrphanFiles');
$this->get('/system/themes', \App\Controllers\ThemeController::class . ':getThemes')->setName('theme');
$this->post('/system/theme/apply', \App\Controllers\ThemeController::class . ':applyTheme')->setName('theme.apply');
$this->post('/system/upgrade', \App\Controllers\UpgradeController::class . ':upgrade')->setName('system.upgrade');
$this->get('/system/checkForUpdates', \App\Controllers\UpgradeController::class . ':checkForUpdates')->setName('system.checkForUpdates');
$this->get('/system', \App\Controllers\AdminController::class . ':system')->setName('system');
$this->get('/users[/page/{page}]', \App\Controllers\UserController::class . ':index')->setName('user.index');

View file

@ -1,6 +1,6 @@
{
"name": "sergix44/xbackbone",
"version": "2.4.1",
"version": "2.5",
"description": "A lightweight ShareX PHP backend",
"type": "project",
"require": {
@ -12,7 +12,8 @@
"intervention/image": "^2.4",
"ext-json": "*",
"ext-gd": "*",
"ext-pdo": "*"
"ext-pdo": "*",
"ext-zip": "*"
},
"autoload": {
"files": [

View file

@ -1,6 +1,7 @@
<?php
require __DIR__ . '/vendor/autoload.php';
define('BASE_DIR', __DIR__ . '/');
define('PLATFORM_VERSION', json_decode(file_get_contents('composer.json'))->version);
require 'bootstrap/app.php';

View file

@ -53,8 +53,8 @@
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="card shadow-sm">
<div class="col-md-8 mb-3">
<div class="card shadow-sm mb-3">
<div class="card-header"><i class="fas fa-paint-brush fa-fw"></i> {{ lang('theme') }}</div>
<div class="card-body">
<form method="post" action="{{ route('theme.apply') }}">
@ -75,9 +75,26 @@
</form>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-sm">
<div class="card-header"><i class="fas fa-cloud-download-alt fa-fw"></i> {{ lang('updates') }}</div>
<div class="card-body">
<div class="row">
<div class="col">
<button type="button" id="checkForUpdatesButton" class="btn btn-block btn-outline-info"><i class="fas fa-sync fa-fw"></i> {{ lang('check_for_updates') }}</button>
</div>
<div class="col text-center"><span class="text-muted" id="checkForUpdatesMessage"></span></div>
<div class="col">
<form method="post" action="{{ route('system.upgrade') }}">
<button type="submit" id="doUpgradeButton" class="btn btn-block btn-outline-success"><i class="fas fa-cloud-download-alt fa-fw"></i> {{ lang('update_now') }}</button>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card shadow-sm mb-3">
<div class="card-header"><i class="fas fa-cog fa-fw"></i> {{ lang('system_info') }}</div>
<div class="card-body">
<strong>Max upload size:</strong>
@ -87,7 +104,7 @@
</ul>
</div>
</div>
<div class="card shadow-sm mt-3">
<div class="card shadow-sm mb-3">
<div class="card-header"><i class="fas fa-tools fa-fw"></i> {{ lang('maintenance') }}</div>
<div class="card-body">
<a href="{{ route('system.deleteOrphanFiles') }}" class="btn btn-outline-dark btn-block"><i class="fas fa-broom fa-fw"></i> {{ lang('clean_orphaned_uploads') }}</a>

View file

@ -8,6 +8,7 @@ var app = {
$('.publish-toggle').click(app.publishToggle);
$('.refresh-token').click(app.refreshToken);
$('#themes').mousedown(app.loadThemes);
$('#checkForUpdatesButton').click(app.checkForUpdates);
$('.alert').fadeTo(4000, 500).slideUp(500, function () {
$('.alert').slideUp(500);
@ -89,6 +90,20 @@ var app = {
},
telegramShare: function () {
window.open($('#telegram-share-button').data('url') + $('#telegram-share-text').val(), '_blank');
},
checkForUpdates: function () {
$('#checkForUpdatesMessage').empty().text('...');
$('#doUpgradeButton').prop('disabled', true);
$.get(window.AppConfig.base_url + '/system/checkForUpdates', function (data) {
if (data.status === 'OK') {
$('#checkForUpdatesMessage').empty().text(data.message);
if (data.upgrade) {
$('#doUpgradeButton').prop('disabled', false);
} else {
$('#doUpgradeButton').prop('disabled', true);
}
}
});
}
};