Initial commit
Some checks failed
定时更新GitHub源插件 / 自动更新GitHub插件 (push) Has been cancelled

This commit is contained in:
chorblack
2026-03-07 11:19:25 +08:00
commit e75f275ef4
4484 changed files with 645480 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
<?php
/**
* Typecho update assistant.
*
* @package UpdateAssistant
* @author mrgeneral
* @version 1.0.1
* @link https://www.chengxiaobai.cn
*/
class Archive extends Base
{
protected function compress($archiveName, $targets, $workRootPath)
{
$archiveRealPath = rtrim($workRootPath, '/.\\') . DIRECTORY_SEPARATOR . 'archive' . DIRECTORY_SEPARATOR . 'back' . DIRECTORY_SEPARATOR . $archiveName . '.zip';
// cache
if (is_file($archiveRealPath)) {
return true;
}
$archive = new ZipArchive();
$archive->open($archiveRealPath, ZipArchive::CREATE);
foreach ($targets as $realPath => $realRootPath) {
if (!is_dir($realPath)) {
$archive->addFile($realPath, str_replace($realRootPath, '', $realPath));
continue;
}
$directoryIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($realPath), RecursiveIteratorIterator::SELF_FIRST);
foreach ($directoryIterator as $fileInfo) {
if (in_array($fileInfo->getFilename(), ['.', '..'])) {
continue;
}
if ($fileInfo->isDir()) {
$archive->addEmptyDir(str_replace($realRootPath, '', $fileInfo->getRealPath()));
} else {
$archive->addFile($fileInfo->getRealPath(), str_replace($realRootPath, '', $fileInfo->getRealPath()));
}
}
}
if (!$archive->close()) {
throw new Exception('Compress failed!');
}
return $archiveRealPath;
}
protected function decompression($archiveName, $workRootPath)
{
$tmpPath = rtrim($workRootPath, '/.\\') . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
$archiveRealPath = rtrim($workRootPath, '/.\\') . DIRECTORY_SEPARATOR . 'archive' . DIRECTORY_SEPARATOR . $archiveName . '.zip';
$archive = new ZipArchive();
if ($archive->open($archiveRealPath) !== true) {
throw new Exception('Open archive failed!');
}
$this->clearPath($tmpPath);
$archive->extractTo($tmpPath);
if (!$archive->close()) {
throw new Exception('Decompression failed!');
}
foreach (scandir($tmpPath) as $item) {
if (!in_array($item, ['.', '..']) && is_dir($tmpPath . $item)) {
return $tmpPath . $item . DIRECTORY_SEPARATOR;
}
}
return $tmpPath;
}
protected function clearPath($realPath)
{
if (!is_dir($realPath)) {
return unlink($realPath);
}
$directoryIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($realPath), RecursiveIteratorIterator::CHILD_FIRST);
foreach ($directoryIterator as $fileInfo) {
if (in_array($fileInfo->getFilename(), ['.', '..'])) {
continue;
}
if ($fileInfo->isDir()) {
$this->clearPath($fileInfo->getRealPath());
rmdir($fileInfo->getRealPath());
} elseif (substr($fileInfo->getPath(), -3) !== 'tmp') {
unlink($fileInfo->getRealPath());
}
}
return true;
}
}

View File

@@ -0,0 +1,110 @@
<?php
/**
* Typecho update assistant.
*
* @package UpdateAssistant
* @author mrgeneral
* @version 1.0.1
* @link https://www.chengxiaobai.cn
*/
abstract class Base
{
protected static $instance;
protected $handler;
protected $defaultHeaders = [
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3_CXB) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
'Referer' => 'https://github.com/typecho/typecho',
'Cache-Control' => 'max-age=0',
];
public function __construct()
{
if (!extension_loaded('zip')) {
throw new Exception('Not found zip extension!');
}
if (function_exists('curl_exec')) {
$this->handler = 'curlHandler';
} elseif (ini_get('allow_url_fopen')) {
$this->handler = 'streamHandler';
} else {
throw new Exception('Requires cURL or set allow_url_fopen = 1 in your php.ini!');
}
}
protected static function getInstance()
{
if (static::$instance instanceof static) {
return static::$instance;
}
return static::$instance = new static;
}
public static function __callStatic($name, $arguments)
{
return call_user_func_array([static::getInstance(), $name], $arguments);
}
protected function curlHandler($url, $storedFileRealPath = '', $options = [], $headers = [])
{
$defaultOptions = [
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 3,
CURLOPT_TIMEOUT => 60,
CURLOPT_HTTPHEADER => $this->buildHeaders(array_merge($this->defaultHeaders, $headers)),
];
if (!empty($storedFileRealPath)) {
$fileHandler = fopen($storedFileRealPath, 'wb+');
$defaultOptions[CURLOPT_FILE] = $fileHandler;
}
$curl = curl_init($url);
curl_setopt_array($curl, $options + $defaultOptions);
$result = curl_exec($curl);
if (curl_getinfo($curl, CURLINFO_HTTP_CODE) !== 200) {
curl_close($curl);
throw new Exception('Request failed, please try again!');
}
curl_close($curl);
return empty($storedFileRealPath) ? $result : fclose($fileHandler);
}
protected function streamHandler($url, $storedFileRealPath = '', $options = [], $headers = [])
{
$context = [
'http' => [
'header' => implode("\r\n", $this->buildHeaders(array_merge($this->defaultHeaders, $headers))),
'protocol_version' => '1.1',
'ignore_errors' => true,
'timeout' => 60,
'follow_location' => 5,
],
];
$streamHandler = fopen($url, 'rb', null, stream_context_create(array_merge($context, $options)));
$result = empty($storedFileRealPath) ? stream_get_contents($streamHandler) : file_put_contents($storedFileRealPath, $streamHandler, LOCK_EX);
fclose($streamHandler);
return $result;
}
private function buildHeaders($headers = [])
{
$result = [];
foreach ($headers as $name => $value) {
$result[] = "$name: $value";
}
return $result;
}
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* Typecho update assistant.
*
* @package UpdateAssistant
* @author mrgeneral
* @version 1.0.1
* @link https://www.chengxiaobai.cn
*/
class Downloader extends Base
{
protected function down($isDevelop, $archiveName, $workRootPath)
{
$downloadUrl = 'https://github.com/typecho/typecho/archive/master.zip';
$archiveRealPath = rtrim($workRootPath, '/.\\') . DIRECTORY_SEPARATOR . 'archive' . DIRECTORY_SEPARATOR . $archiveName . '.zip';
// cache
if (is_file($archiveRealPath)) {
return true;
}
if (!$isDevelop) {
$content = $this->{$this->handler}('http://typecho.org/version.json');
if (empty($content)
|| null === ($content = json_decode($content, true))
|| empty($content['release'])
|| empty($content['version'])
) {
throw new Exception('Fetch release version failed!');
}
$downloadUrl = sprintf('https://github.com/typecho/typecho/archive/v%s-%s-release.zip', $content['release'], $content['version']);
}
return $this->{$this->handler}($downloadUrl, $archiveRealPath);
}
}

View File

@@ -0,0 +1,61 @@
<?php
/**
* Typecho update assistant.
*
* @package UpdateAssistant
* @author mrgeneral
* @version 1.0.1
* @link https://www.chengxiaobai.cn
*/
class Version extends Base
{
protected function getVersion($isDevelop = true)
{
return $isDevelop ? $this->getDevelop() : $this->getRelease();
}
protected function getDevelop()
{
$content = $this->{$this->handler}(
'https://raw.githubusercontent.com/typecho/typecho/master/var/Typecho/Common.php',
'',
[],
['Referer' => 'https://github.com/typecho/typecho/blob/master/var/Typecho/Common.php']
);
if (empty($content) || !preg_match('/const VERSION = \'(\w.*)\';/', $content, $result)) {
throw new Exception('Fetch develop version failed!');
}
return $result[1];
}
protected function getRelease()
{
$content = $this->{$this->handler}('http://typecho.org/version.json');
if (empty($content)
|| null === ($content = json_decode($content, true))
|| empty($content['release'])
|| empty($content['version'])
) {
throw new Exception('Fetch release version failed!');
}
return sprintf('%s/%s', $content['release'], $content['version']);
}
protected function compare($currentVersion, $remoteVersion, $operator)
{
return version_compare(str_replace('/', '.', $currentVersion), str_replace('/', '.', $remoteVersion), $operator);
}
protected function toString($version)
{
return implode(array_map(function ($subVersion) {
return sprintf('%02s', $subVersion);
}, explode('.', str_replace('/', '.', $version))));
}
}