add checking for updates

This commit is contained in:
printempw 2016-08-09 13:18:27 +08:00
parent 2926f28add
commit 6cef94924e
10 changed files with 250 additions and 31 deletions

View File

@ -35,6 +35,20 @@ class AdminController extends BaseController
View::show('admin.options'); View::show('admin.options');
} }
public function update()
{
if (\Utils::getValue('action', $_GET) == "check") {
$updater = new \Updater(\Application::getVersion());
if ($updater->newVersionAvailable()) {
View::json([
'new_version_available' => true,
'latest_version' => $updater->latest_version
]);
}
}
View::show('admin.update');
}
public function users() public function users()
{ {
$page = isset($_GET['page']) ? $_GET['page'] : 1; $page = isset($_GET['page']) ? $_GET['page'] : 1;

View File

@ -5,22 +5,26 @@ namespace App\Services;
class Updater class Updater
{ {
public $current_version = ""; public $current_version = "";
public $latest_version = ""; public $latest_version = "";
public $update_time = ""; public $update_time = "";
public $update_url = ""; private $update_sources = null;
private $current_source = null;
public $update_info = null; private $update_info = null;
function __construct($current_version) { public function __construct($current_version)
{
$this->current_version = $current_version; $this->current_version = $current_version;
$this->update_url = Option::get('update_url'); $this->update_sources = require BASE_DIR."/config/update.php";
$this->current_source = $this->update_sources[Option::get('update_source')];
} }
public function getUpdateInfo() { public function getUpdateInfo()
{
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->update_url); curl_setopt($ch, CURLOPT_URL, $this->current_source['update_url']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// quick fix for accessing https resources // quick fix for accessing https resources
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
@ -30,13 +34,15 @@ class Updater
return $this->update_info; return $this->update_info;
} }
public function checkUpdate() { public function checkUpdate()
{
$info = $this->getUpdateInfo(); $info = $this->getUpdateInfo();
$this->latest_version = $info['latest_version']; $this->latest_version = $info['latest_version'];
$this->update_time = date('Y-m-d H:i:s', $info['update_time']); $this->update_time = date('Y-m-d H:i:s', $info['update_time']);
} }
public function downloadUpdate($silent = true) { public function downloadUpdate($silent = true)
{
$release_url = $this->update_info['releases'][$this->latest_version]['release_url']; $release_url = $this->update_info['releases'][$this->latest_version]['release_url'];
if (!$silent) echo "<p>正在下载更新包:$release_url </p>"; if (!$silent) echo "<p>正在下载更新包:$release_url </p>";
// I don't know why curl cant get full file here.. // I don't know why curl cant get full file here..
@ -60,11 +66,17 @@ class Updater
* *
* @return bool * @return bool
*/ */
public function newVersionAvailable() { public function newVersionAvailable()
{
$this->checkUpdate(); $this->checkUpdate();
return $this->compareVersion($this->latest_version, $this->current_version); return $this->compareVersion($this->latest_version, $this->current_version);
} }
public function getUpdateSources()
{
return $this->update_sources;
}
/** /**
* Compare version string * Compare version string
* *
@ -72,7 +84,8 @@ class Updater
* @param string $v2 * @param string $v2
* @return boolean * @return boolean
*/ */
private function compareVersion($v1, $v2) { private function compareVersion($v1, $v2)
{
if (strnatcasecmp($v1, $v2) > 0) { if (strnatcasecmp($v1, $v2) > 0) {
// v1 > v2 // v1 > v2
return true; return true;

View File

@ -22,7 +22,8 @@ $menu['admin'] = array(
3 => ['title' => '角色管理', 'link' => '/admin/players', 'icon' => 'fa-gamepad'], 3 => ['title' => '角色管理', 'link' => '/admin/players', 'icon' => 'fa-gamepad'],
4 => ['title' => '个性化', 'link' => '/admin/customize', 'icon' => 'fa-paint-brush'], 4 => ['title' => '个性化', 'link' => '/admin/customize', 'icon' => 'fa-paint-brush'],
5 => ['title' => '积分配置', 'link' => '/admin/score', 'icon' => 'fa-credit-card'], 5 => ['title' => '积分配置', 'link' => '/admin/score', 'icon' => 'fa-credit-card'],
6 => ['title' => '站点配置', 'link' => '/admin/options', 'icon' => 'fa-cog'] 6 => ['title' => '站点配置', 'link' => '/admin/options', 'icon' => 'fa-cog'],
6 => ['title' => '检查更新', 'link' => '/admin/update', 'icon' => 'fa-arrow-up']
); );
return $menu; return $menu;

View File

@ -100,6 +100,7 @@ Route::group(['middleware' => 'App\Middlewares\CheckAdminMiddl
Route::all('/customize', 'AdminController@customize'); Route::all('/customize', 'AdminController@customize');
Route::all('/score', 'AdminController@score'); Route::all('/score', 'AdminController@score');
Route::all('/options', 'AdminController@options'); Route::all('/options', 'AdminController@options');
Route::all('/update', 'AdminController@update');
Route::get('/users', 'AdminController@users'); Route::get('/users', 'AdminController@users');
Route::get('/players', 'AdminController@players'); Route::get('/players', 'AdminController@players');

View File

@ -10,18 +10,19 @@
| |
*/ */
return [ return [
'View' => 'App\Services\View', 'View' => 'App\Services\View',
'Database' => 'App\Services\Database', 'Database' => 'App\Services\Database',
'Option' => 'App\Services\Option', 'Option' => 'App\Services\Option',
'Utils' => 'App\Services\Utils', 'Utils' => 'App\Services\Utils',
'Validate' => 'App\Services\Validate', 'Validate' => 'App\Services\Validate',
'Http' => 'App\Services\Http', 'Http' => 'App\Services\Http',
'Mail' => 'App\Services\Mail', 'Mail' => 'App\Services\Mail',
'Storage' => 'App\Services\Storage', 'Storage' => 'App\Services\Storage',
'Minecraft' => 'App\Services\Minecraft', 'Minecraft' => 'App\Services\Minecraft',
'Updater' => 'App\Services\Updater', 'Updater' => 'App\Services\Updater',
'Config' => 'App\Services\Config', 'Config' => 'App\Services\Config',
'Schema' => 'App\Services\Schema', 'Schema' => 'App\Services\Schema',
'Boot' => 'App\Services\Boot', 'Boot' => 'App\Services\Boot',
'Migration' => 'App\Services\Migration' 'Migration' => 'App\Services\Migration',
'Application' => 'App\Services\Application'
]; ];

20
config/update.php Normal file
View File

@ -0,0 +1,20 @@
<?php
/*
|--------------------------------------------------------------------------
| Update Sources
|--------------------------------------------------------------------------
|
| Urls to get update information
|
*/
return array(
'github' => [
'name' => 'GitHub',
'update_url' => 'https://work.prinzeugen.net/update.json',
],
'local' => [
'name' => 'LocalHost开发用',
'update_url' => 'http://127.0.0.1/test/update.json'
]
);

View File

@ -131,6 +131,17 @@
<script type="text/javascript" src="../assets/dist/js/admin.js"></script> <script type="text/javascript" src="../assets/dist/js/admin.js"></script>
@if (Option::get('check_update') == '1')
<script>
$(document).ready(function() {
$.getJSON('../admin/update?action=check', function(data) {
if (data.new_version_available == true)
$('[href="/admin/update"]').append('<span class="label label-primary pull-right">v'+data.latest_version+'</span>');
})
});
</script>
@endif
@yield('script') @yield('script')
<script>{!! Option::get('custom_js') !!}</script> <script>{!! Option::get('custom_js') !!}</script>

View File

@ -100,10 +100,10 @@
<tr> <tr>
<td class="key">首选 JSON API</td> <td class="key">首选 JSON API</td>
<td class="value"> <td class="value">
<select class="form-control" name="api_type"> <select class="form-control" name="api_type">
<option {{ (Option::get('api_type') == '0') ? 'selected="selected"' : '' }} value="0">CustomSkinLoader API</option> <option {{ (Option::get('api_type') == '0') ? 'selected="selected"' : '' }} value="0">CustomSkinLoader API</option>
<option {{ (Option::get('api_type') == '1') ? 'selected="selected"' : '' }} value="1">UniversalSkinAPI</option> <option {{ (Option::get('api_type') == '1') ? 'selected="selected"' : '' }} value="1">UniversalSkinAPI</option>
</select> </select>
</td> </td>
</tr> </tr>

View File

@ -0,0 +1,156 @@
@extends('admin.master')
@section('title', '检查更新')
@section('content')
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
检查更新
<small>Check Update</small>
</h1>
</section>
<?php $updater = new Updater(Application::getVersion()); ?>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-md-6">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">更新信息</h3>
</div><!-- /.box-header -->
<div class="box-body">
@if ($updater->newVersionAvailable())
<div class="callout callout-info">有更新可用。</div>
<table class="table">
<tbody>
<tr>
<td class="key">最新版本:</td>
<td class="value">
v{{ $updater->latest_version }}
</td>
</tr>
<tr>
<td class="key">当前版本:</td>
<td class="value">
v{{ $updater->current_version }}
</td>
</tr>
<tr>
<td class="key">发布时间:</td>
<td class="value">
{{ $updater->update_time }}
</td>
</tr>
<tr>
<td class="key">更新日志:</td>
<td class="value">
{{ nl2br($updater->getUpdateInfo()['releases'][$updater->latest_version]['release_note']) }}
</td>
</tr>
<tr>
<td class="key">下载地址:</td>
<td class="value">
<a href="{{ $updater->getUpdateInfo()['releases'][$updater->latest_version]['release_url'] }}">@GitHub</a>
</td>
</tr>
</tbody>
</table>
@else
<div class="callout callout-success">已更新至最新版本。</div>
<table class="table">
<tbody>
<tr>
<td class="key">当前版本:</td>
<td class="value">
v{{ $updater->current_version }}
</td>
</tr>
<tr>
<td class="key">发布时间:</td>
<td class="value">
{{ date('Y-m-d H:i:s', $updater->getUpdateInfo()['releases'][$updater->current_version]['release_time']) }}
</td>
</tr>
</tbody>
</table>
@endif
</div><!-- /.box-body -->
<div class="box-footer">
<a <?php if (!$updater->newVersionAvailable()) echo "disabled='disabled'"; ?> href="update.php?action=download" class="btn btn-primary">马上升级</a>
<a href="http://www.mcbbs.net/thread-552877-1-1.html" style="float: right;" class="btn btn-default">查看 MCBBS 发布贴</a>
</div>
</div>
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">注意事项</h3>
</div><!-- /.box-header -->
<div class="box-body">
<p>下载更新需要连接 GitHub 服务器,国内主机可能会长时间无响应。</p>
</div><!-- /.box-body -->
</div>
</div>
<div class="col-md-6">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">更新选项</h3>
</div><!-- /.box-header -->
<div class="box-body">
<form method="post" action="../admin/update">
<div class="box-body">
<?php
if (isset($_POST['submit'])) {
$_POST['check_update'] = isset($_POST['check_update']) ? $_POST['check_update'] : "0";
foreach ($_POST as $key => $value) {
if ($key != "option" && $key != "submit")
Option::set($key, $value);
}
echo '<div class="callout callout-success">设置已保存。</div>';
} ?>
<table class="table">
<tbody>
<tr>
<td class="key">检查更新</td>
<td class="value">
<label for="check_update">
<input {{ (Option::get('check_update') == '1') ? 'checked="true"' : '' }} type="checkbox" id="check_update" name="check_update" value="1"> 自动检查更新并提示
</label>
</td>
</tr>
<tr>
<td class="key">更新源</td>
<td class="value">
<select class="form-control" name="update_source">
@foreach ($updater->getUpdateSources() as $key => $value)
<option {{ (Option::get('update_source') == $key) ? 'selected="selected"' : '' }} value="{{ $key }}">{{ $value['name'] }}</option>
@endforeach
</select>
</td>
</tr>
</tbody>
</table>
</div><!-- /.box-body -->
<div class="box-footer">
<button type="submit" name="submit" class="btn btn-primary">提交</button>
</div>
</form>
</div><!-- /.box-body -->
</div>
</div>
</div>
</section><!-- /.content -->
</div><!-- /.content-wrapper -->
@endsection

View File

@ -3,7 +3,7 @@
* @Author: printempw * @Author: printempw
* @Date: 2016-07-29 11:53:11 * @Date: 2016-07-29 11:53:11
* @Last Modified by: printempw * @Last Modified by: printempw
* @Last Modified time: 2016-08-08 21:51:58 * @Last Modified time: 2016-08-08 22:41:23
*/ */
return [ return [
@ -30,5 +30,7 @@ return [
'score_per_player' => '100', 'score_per_player' => '100',
'sign_after_zero' => '0', 'sign_after_zero' => '0',
'avatar_query_string' => '0', 'avatar_query_string' => '0',
'version' => '' 'version' => '',
'check_update' => '1',
'update_source' => 'github'
]; ];