Upgrade.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <?php
  2. /**
  3. * 升级
  4. *
  5. * @author mybsdc <[email protected]>
  6. * @date 2021/11/5
  7. * @time 10:52
  8. */
  9. namespace Luolongfei\App\Console;
  10. use GuzzleHttp\Client;
  11. use Luolongfei\Libs\Log;
  12. use Luolongfei\Libs\Message;
  13. class Upgrade extends Base
  14. {
  15. const TIMEOUT = 33;
  16. /**
  17. * @var Upgrade
  18. */
  19. private static $instance;
  20. /**
  21. * @var array 与发布相关的信息
  22. */
  23. public $releaseInfo = [];
  24. /**
  25. * @var string 最新版本号
  26. */
  27. public $latestVer;
  28. /**
  29. * @var string 当前版本号
  30. */
  31. public $currVer;
  32. /**
  33. * @var string 记录已推送版本的文件
  34. */
  35. public $pushedVerFile;
  36. /**
  37. * @return Upgrade
  38. */
  39. public static function getInstance()
  40. {
  41. if (!self::$instance instanceof self) {
  42. self::$instance = new self();
  43. }
  44. return self::$instance;
  45. }
  46. private function __construct()
  47. {
  48. $this->pushedVerFile = DATA_PATH . DS . 'pushed_version.txt';
  49. $this->language = config('language', 'zh');
  50. $this->client = new Client([
  51. 'base_uri' => 'https://api.github.com',
  52. 'headers' => [
  53. 'Accept' => 'application/vnd.github.v3+json'
  54. ],
  55. 'cookies' => false,
  56. 'timeout' => self::TIMEOUT,
  57. 'verify' => config('verify_ssl'),
  58. 'debug' => config('debug'),
  59. ]);
  60. }
  61. private function __clone()
  62. {
  63. }
  64. /**
  65. * 是否需要升级
  66. *
  67. * @return bool
  68. */
  69. public function needToUpgrade()
  70. {
  71. try {
  72. $resp = $this->client->get('/repos/luolongfei/freenom/releases/latest', [
  73. 'timeout' => 5,
  74. ]);
  75. $resp = $resp->getBody()->getContents();
  76. $resp = (array)json_decode($resp, true);
  77. if (!isset($resp['tag_name'])
  78. || !isset($resp['body'])
  79. || !isset($resp['name'])
  80. || !isset($resp['published_at'])
  81. || !isset($resp['html_url'])) {
  82. throw new \Exception(lang('100023') . json_encode($resp, JSON_UNESCAPED_UNICODE));
  83. }
  84. $this->releaseInfo = $resp;
  85. $this->latestVer = $this->getVerNum($resp['tag_name']);
  86. $this->currVer = $this->getVerNum(FreeNom::VERSION);
  87. return version_compare($this->latestVer, $this->currVer, '>');
  88. } catch (\Exception $e) {
  89. Log::error(lang('100024') . $e->getMessage());
  90. return false;
  91. }
  92. }
  93. /**
  94. * 此版本是否已推送过
  95. *
  96. * @param $ver
  97. *
  98. * @return bool
  99. */
  100. public function isPushed($ver)
  101. {
  102. if (!file_exists($this->pushedVerFile)) {
  103. return false;
  104. }
  105. $pushedVerFile = file_get_contents($this->pushedVerFile);
  106. return stripos($pushedVerFile, $ver) !== false;
  107. }
  108. /**
  109. * 记住版本号
  110. *
  111. * @param $ver
  112. *
  113. * @return bool
  114. */
  115. public function rememberVer($ver)
  116. {
  117. return (bool)file_put_contents($this->pushedVerFile, $ver . "\n", FILE_APPEND);
  118. }
  119. /**
  120. * 生成升级送信内容
  121. *
  122. * @return string
  123. */
  124. public function genMsgContent()
  125. {
  126. if ($this->language === 'zh') {
  127. $content = sprintf(
  128. lang('100025'),
  129. $this->friendlyDateFormat($this->releaseInfo['published_at'], 'UTC'),
  130. $this->latestVer,
  131. $this->currVer
  132. );
  133. } else {
  134. $content = sprintf(
  135. lang('100025'),
  136. $this->friendlyDateFormat($this->releaseInfo['published_at'], 'UTC'),
  137. $this->latestVer,
  138. $this->currVer
  139. );
  140. }
  141. $content .= $this->releaseInfo['body'];
  142. $content .= "\n\n" . lang('100026') . $this->releaseInfo['html_url'];
  143. $content .= "\n\n" . lang('100027');
  144. return $content;
  145. }
  146. /**
  147. * 人类友好时间
  148. *
  149. * @param string $date 传入时间
  150. * @param null|string $timezone 传入时间的时区
  151. *
  152. * @return string
  153. */
  154. public function friendlyDateFormat($date, $timezone = null)
  155. {
  156. try {
  157. $d = (new \DateTime($date, $timezone ? new \DateTimeZone($timezone) : null))->setTimezone(new \DateTimeZone('Asia/Shanghai'));
  158. $time = $d->getTimestamp();
  159. $diff = time() - $time;
  160. if ($diff < 86400) {
  161. if ($d->format('d') === date('d')) {
  162. return $diff < 60 ? lang('100028') : ($diff < 3600 ? floor($diff / 60) . lang('100029') : floor($diff / 3600) . lang('100030'));
  163. } else {
  164. return lang('100031') . $d->format('H:i');
  165. }
  166. } else {
  167. return $d->format($d->format('Y') === date('Y') ? 'Y-m-d H:i' : 'Y-m-d');
  168. }
  169. } catch (\Exception $e) {
  170. Log::error(lang('100032') . $e->getMessage());
  171. return $date;
  172. }
  173. }
  174. /**
  175. * @return bool
  176. */
  177. public function handle()
  178. {
  179. try {
  180. if (!$this->needToUpgrade()) {
  181. return true;
  182. }
  183. if ($this->isPushed($this->latestVer)) {
  184. return true;
  185. }
  186. if (IS_SCF) {
  187. system_log(sprintf(
  188. lang('100033'),
  189. $this->currVer,
  190. $this->latestVer,
  191. $this->releaseInfo['html_url']
  192. ));
  193. } else {
  194. system_log(sprintf(
  195. lang('100034'),
  196. $this->latestVer,
  197. $this->releaseInfo['html_url']
  198. ));
  199. $result = Message::send(
  200. $this->genMsgContent(),
  201. sprintf(lang('100035'), $this->latestVer),
  202. 4,
  203. $this->releaseInfo
  204. );
  205. if ($result) {
  206. $this->rememberVer($this->latestVer);
  207. system_log(lang('100036'));
  208. }
  209. }
  210. return true;
  211. } catch (\Exception $e) {
  212. system_log(lang('100037') . $e->getMessage());
  213. return false;
  214. }
  215. }
  216. public function doUpgrade()
  217. {
  218. // TODO 自动升级
  219. // system_log('<green>恭喜,已完成升级。</green>');
  220. }
  221. }