cfn/app/Http/Controllers/ExecController.php
2025-07-19 18:23:16 +08:00

594 lines
19 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\ArticleList;
use App\Models\Tags;
use App\Services\Time;
use App\Models\Option as ModelOption;
class ExecController extends Controller
{
public function __construct(Request $request)
{
$sIpAddress = $request->ip();
if ($sIpAddress != $_SERVER['SERVER_ADDR']) {
echo 'only local';
exit;
}
}
// cron n合1
// 半小时一次 @cron
public function cron ()
{
$this->FreenodeDelAuto();
// 期望每天一次
if (rand(1, 48) == 1) {
$this->tagCountToHtml();
}
// 期望每小时一次
if (rand(1, 2) == 1) {
$this->likeAuto();
}
$this->freenodeUp();
}
// 客户端文章静态化
public function clientSingleToHtml()
{
$sUrlBase = env('APP_URL').'/client/single/';
$sHtmlPathBase = "client/";
$aArticleCode = [
'1001',
'1002',
'1003',
'1004',
'1005',
'1006',
'1007',
'1008',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$i = 0;
foreach ($aArticleCode as $iCode) {
$sUrl = $sUrlBase.$iCode;
$sHtmlPath = $sHtmlPathBase.$iCode.'.html';
curl_setopt($ch, CURLOPT_URL, $sUrl);
$sArticleView = curl_exec($ch);
$r = file_put_contents($sHtmlPath, $sArticleView);
$i++;
}
echo "静态化".$i."";
curl_close($ch);
}
// 热门标签,计数,静态化 @cron
public function tagCountToHtml()
{
echo "\n#start# top tag to html \n";
$aTags = Tags::all()->toArray();
foreach ($aTags as $k => $v) {
$sTagLike = '%['.$v['id'].']%';
$iTagCount = ArticleList::where('tags', 'like', $sTagLike)->count();
$r = Tags::where('id', '=', $v['id'])->update(['count' => $iTagCount]);
echo($r);
}
$aTopTags = Tags::where('count', '>', 0)->orderBy("count", "desc")->get()->toArray();
$sTopTagsView = view('widget/toptags', [
'aToptags' => $aTopTags,
]);
$sTopTagsHtmlPath = "widget/toptags.html";
$r = file_put_contents($sTopTagsHtmlPath, $sTopTagsView);
if ($r === false) {
echo "<br>fail<br>";return;
}
echo "#end# top tag to html - end \n";
}
// 文章自动删除 @cron
public function FreenodeDelAuto()
{
echo "\n#start# article del auto \n";
$sTimeSet = -366;
$sTimeForDel = strtotime($sTimeSet." day");
$sDateCodeForDel = date("Ymd", $sTimeForDel);
//// 数据删除 start
$r = ArticleList::where("code", $sDateCodeForDel)->delete();
if ($r) {
echo "data del - done \n";
}
//// 数据删除 end
//// 静态页面删除 start
$file = 'fn/'.$sDateCodeForDel.'.html';
if (file_exists($file)) {
if (unlink($file)) {
echo "static page del - done \n";
} else {
echo "static page del - fail \n";
}
} else {
echo "static page - not exits \n";
}
//// 静态页面删除 end
//// clash订阅删除 start
$file = 'feed/clash-'.$sDateCodeForDel.'.html';
if (file_exists($file)) {
if (unlink($file)) {
echo "clash feed del - done \n";
} else {
echo "clash feed del - fail \n";
}
} else {
echo "clash feed - not exits \n";
}
//// clash订阅删除 end
//// v2ray订阅删除 start
$file = 'feed/v2ray-'.$sDateCodeForDel.'.html';
if (file_exists($file)) {
if (unlink($file)) {
echo "v2ray feed del - done \n";
} else {
echo "v2ray feed del - fail \n";
}
} else {
echo "v2ray feed - exits \n";
}
//// clash订阅删除 end
echo "#end# article del auto \n";
}
// 自动点赞 @cron
public function likeAuto ()
{
echo "\n#start# like auto \n";
$iRand = rand(1, 2);
if ($iRand === 1) {
$r = ArticleList::where('code', date('Ymd'))
->increment('like', 1);
echo $r;
}
echo '\n';
echo "#end# like auto \n";
}
// 点赞初始
public function likeInit ()
{
$aFreenodeAll = ArticleList::all()->toArray();
foreach ($aFreenodeAll as $aRow) {
if ($aRow['type'] == 'node') {
$iLikeCount = rand(3, 16);
} else {
$iLikeCount = rand(30, 120);
}
$r = ArticleList::where('id', $aRow['id'])
->update(['like' => $iLikeCount]);
echo $r;
}
// dd($aFreenodeAll);
}
// 节点文章批量抓取,倒数
// public function freenodeCraw($day) {
//
// $sDateStart = date("Ymd", strtotime("-$day day"));
//
// $iLimit = 10;
//
// for ($i=$day; $i>($day - $iLimit); $i--) {
// echo "<br>";
// echo ($i);
// echo "<br>";
// echo $this->freenodeUp(-$i);
// }
//
// }
public function freenodeCraw($iStart = 1, $iLimit = 1) {
for ($i=$iStart; $i>($iStart - $iLimit); $i--) {
echo "<br>";
echo ($i);
echo "<br>";
echo $this->freenodeUp(-$i);
}
}
// 免费节点每日更新
public function freenodeUp($sTimeSet = "0") {
echo "\n#start# article fn up \n";
$sTimeStart = strtotime($sTimeSet." day");
$sTimeNextDay = strtotime(($sTimeSet+1)." day");
$sTimeNext10Day = strtotime(($sTimeSet+10)." day");
$sTimePrevDay = strtotime(($sTimeSet-1)." day");
$sDateStartCode = date("Ymd", $sTimeStart);
$sDateNextDayCode = date("Ymd", $sTimeNextDay);
$sDateNext10DayCode = date("Ymd", $sTimeNext10Day);
$sFreeNodePath = "fn/".$sDateStartCode.".html";
$aOption = ModelOption::_all();
//// 生成订阅 start
$iTodayCode = ArticleList::where("code", $sDateStartCode)->first()?->code;
if ($iTodayCode) {
echo "article already exists.\n";
return;
}
$sV2rayTodayUrl = $aOption["freenode_craw_url"].date('Y', $sTimeStart)."/".date('m', $sTimeStart)."/".$sDateStartCode.".txt";
$sV2rayToday = @file_get_contents($sV2rayTodayUrl);
$sV2rayNextUrl = $aOption["freenode_craw_url"].date('Y', $sTimeNext10Day)."/".date('m', $sTimeNext10Day)."/".$sDateNext10DayCode.".txt";
$sV2rayNext = @file_get_contents($sV2rayNextUrl);
if (empty($sV2rayNext) || $sV2rayNext == $sV2rayToday) {
echo "not have update. \n";return;
}
$sV2rayPath = "feed/v2ray-".$sDateStartCode.".txt";
$mV2rayR = file_put_contents($sV2rayPath, $sV2rayToday);
if ($mV2rayR === false) {
echo "v2ray feed save - fail \n";return;
} else {
echo "v2ray feed save: $sV2rayPath \n<br>";
}
$sClashPath = "feed/clash-".$sDateStartCode.".yaml";
$sClashTodayUrl = $aOption["freenode_craw_url"].date('Y', $sTimeStart)."/".date('m', $sTimeStart)."/".$sDateStartCode.".yaml";
$sClashToday = @file_get_contents($sClashTodayUrl);
// tomd($aOption["freenode_craw_url"].date('Y', $sTimeStart)."/".date('m', $sTimeStart)."/".$sDateStartCode.".yaml", 1);
var_dump($sClashToday);exit;
$mClashR = file_put_contents($sClashPath, $sClashToday);
if ($mClashR === false) {
echo "clash feed save - fail \n";return;
} else {
echo "clash feed save: $sClashPath \n";
}
//// 生成订阅 end
//// 文章入库 start
// 图片
$iPrevImgId = ArticleList::where("code", date("Ymd", $sTimePrevDay))->first()?->img_id;
if ($iPrevImgId >= env('article_img_count')) {
$iImgId = 1;
} else {
$iImgId = $iPrevImgId + 1;
}
// 地区
$aNodeRegionPool = [
'美国、日本、俄罗斯、新加坡、香港、台湾、越南、德国',
'美国、日本、新加坡、台湾、韩国',
'美国、新加坡、日本、俄罗斯、越南',
'美国、新加坡、日本、俄罗斯',
'香港、台湾、美国、日本、新加坡、德国',
'美国、新加坡、加拿大、香港、欧洲、韩国、日本',
'美国、日本、新加坡、台湾',
'日本、香港、台湾、越南、土耳其、阿根廷、俄罗斯',
'日本、台湾、新加坡,韩国、俄罗斯、法国、美国、德国',
'新加坡、日本、台湾、美国、韩国、德国、香港',
'香港、台湾、日本、韩国、越南、阿根廷、俄罗斯、加拿大、美国',
];
$iNodeRegionRandKey = array_rand($aNodeRegionPool);
$sNodeZone = $aNodeRegionPool[$iNodeRegionRandKey];
// 标题
$aTitlePool = [
date('Y', $sTimeStart).$aOption["freenode_title"]
];
$iTitlePoolRandKey = array_rand($aTitlePool);
$sTitle = $aTitlePool[$iTitlePoolRandKey];
// 内容
$iNodeSpeed = rand((int) env("freenode_speed_min"), (int) env("freenode_speed_max"));
$iNodeCount = rand((int) env("freenode_count_min"), (int) env("freenode_count_max"));
$sV2raySubPath = env('APP_URL')."/sub/v2ray-".$sDateStartCode.".txt";
$sClashSubPath = env('APP_URL')."/sub/clash-".$sDateStartCode.".yaml";
$sContent = "
<p>本次更新共".$iNodeCount."个可用节点,最高速度".$iNodeSpeed."M/S。</p>
<p>覆盖".$sNodeZone."等多个区域。</p>
<p>复制下方的v2ray/Clash订阅链接在客户端添加即可正常使用。<br />
";
// 副标题
$sTitleSub = "
本次更新共".$iNodeCount."个可用节点,最高速度".$iNodeSpeed."M/S。
覆盖".$sNodeZone."等多个区域。
复制下方的v2ray/Clash订阅链接在客户端添加即可正常使用。
";
// 标签
$aTagPool = [
'[1][2][3][4][5][6][7][8][11]'
];
$iTagPoolRandKey = array_rand($aTagPool);
$sTag = $aTagPool[$iTagPoolRandKey];
$oFreenoodList = new ArticleList();
$oFreenoodList->img_id = $iImgId;
$oFreenoodList->date_str = date('n月j日', $sTimeStart);
$oFreenoodList->created_at = $sTimeStart;
$oFreenoodList->title = $sTitle;
$oFreenoodList->code = $sDateStartCode;
$oFreenoodList->tags = $sTag;
$oFreenoodList->type = 'node';
$oFreenoodList->content = $sContent;
$oFreenoodList->title_sub = $sTitleSub;
$r = $oFreenoodList->save();
if ($r != true) {
echo "article insert - fail.";var_dump($r);return;
} else {
// 标签计数增加
// $sTagsStr = $sTag;
// $sTagsStr = substr($sTagsStr, 1, -1);
// $aTags = explode('][', $sTagsStr);
//
// $r = \DB::table('tags')
// ->whereIn('id', $aTags)
// ->increment('count', 1);
}
//// 文章入库 end
//// 文章静态化 start
$sFreenodeNewUrl = env("APP_URL")."/fn/single/".$sDateStartCode;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $sFreenodeNewUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$sFreeNodeNewView = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 获取 HTTP 响应代码
if ($httpCode !== 200) {
ArticleList::where("code", $sDateStartCode)->delete();
echo "发生了 $httpCode 错误";
return;
}
curl_close($ch);
$r = file_put_contents($sFreeNodePath, $sFreeNodeNewView);
if ($r == false) {
echo "article static - fail \n";return;
} else {
echo 'article static - done \n';
}
//// 静态化 end
// 标签统计&静态化
// $this->tagCountToHtml();
echo "#end# article fn up \n";
}
// 直接生成文章
public function freenodeDataAll()
{
$aOption = ModelOption::_all();
ArticleList::where('type', 'node')->delete(); // 先删除节点文章
$sTimeSet = -env('freenode_keep_day');
for ($i=$sTimeSet; $i<=0; $i++) {
$sTimeStart = strtotime($i." day");
$sTimePrev = strtotime(($i-1)." day");
$sDateCodeStart = date("Ymd", $sTimeStart);
$sDateCodePrev = date("Ymd", $sTimePrev);
//// 文章入库 start
// 图片
$iPrevImgId = ArticleList::where("code", $sDateCodePrev)->first()?->img_id;
if ($iPrevImgId >= env('article_img_count')) {
$iImgId = 1;
} else {
$iImgId = $iPrevImgId + 1;
}
// 地区
$aNodeRegionPool = [
'美国、日本、俄罗斯、新加坡、香港、台湾、越南、德国',
'美国、日本、新加坡、台湾、韩国',
'美国、新加坡、日本、俄罗斯、越南',
'美国、新加坡、日本、俄罗斯',
'香港、台湾、美国、日本、新加坡、德国',
'美国、新加坡、加拿大、香港、欧洲、韩国、日本',
'美国、日本、新加坡、台湾',
'日本、香港、台湾、越南、土耳其、阿根廷、俄罗斯',
'日本、台湾、新加坡,韩国、俄罗斯、法国、美国、德国',
'新加坡、日本、台湾、美国、韩国、德国、香港',
'香港、台湾、日本、韩国、越南、阿根廷、俄罗斯、加拿大、美国',
];
$iNodeRegionRandKey = array_rand($aNodeRegionPool);
$sNodeZone = $aNodeRegionPool[$iNodeRegionRandKey];
// 标题
$aTitlePool = [
date('Y', $sTimeStart).$aOption["freenode_title"]
];
$iTitlePoolRandKey = array_rand($aTitlePool);
$sTitle = $aTitlePool[$iTitlePoolRandKey];
// 副标题
$iNodeSpeed = rand((int) env("freenode_speed_min"), (int) env("freenode_speed_max"));
$iNodeCount = rand((int) env("freenode_count_min"), (int) env("freenode_count_max"));
$sTitleSub = "
本次更新共".$iNodeCount."个可用节点,最高速度".$iNodeSpeed."M/S。
覆盖".$sNodeZone."等多个区域。
复制下方的v2ray/Clash订阅链接在客户端添加即可正常使用。
";
$sContent = "
<p>本次更新共".$iNodeCount."个可用节点,最高速度".$iNodeSpeed."M/S。</p>
<p>覆盖".$sNodeZone."等多个区域。</p>
<p>复制下方的v2ray/Clash订阅链接在客户端添加即可正常使用。<br />
";
// 标签
$aTagPool = [
'[1][2][3][4][5][6][7][8][11]'
];
$iTagPoolRandKey = array_rand($aTagPool);
$sTag = $aTagPool[$iTagPoolRandKey];
// 入库
$oFreenoodList = new ArticleList();
$oFreenoodList->img_id = $iImgId;
$oFreenoodList->date_str = date('n月j日', $sTimeStart);
$oFreenoodList->created_at = $sTimeStart;
$oFreenoodList->title = $sTitle;
$oFreenoodList->code = $sDateCodeStart;
$oFreenoodList->tags = $sTag;
$oFreenoodList->type = 'node';
$oFreenoodList->content = $sContent;
$oFreenoodList->title_sub = $sTitleSub;
$r = $oFreenoodList->save();
if ($r != true) {
echo "article insert - fail \n";var_dump($r);return;
} else {
echo "article insert - done \n";
}
//// 文章入库 end
}
dd($sDateCodeStart);
}
// 指定文章静态化
public function freenodeHtmlSingle($code)
{
if (!$code) {
echo "not have code";
exit;
}
$sFreenodeNewUrl = env("APP_URL")."/fn/single/".$code;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $sFreenodeNewUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$sFreeNodeNewView = curl_exec($ch);
curl_close($ch);
$sFreeNodePath = "fn/".$code.".html";
$r = file_put_contents($sFreeNodePath, $sFreeNodeNewView);
if ($r == false) {
echo "false";
} else {
echo "true";
}
exit;
}
// 节点文章静态化,所有
public function freenodeHtmlAll ()
{
$aFreenodeAll = ArticleList::where("type", "node")->get()->toArray();
foreach ($aFreenodeAll as $aRow) {
$sFreenodeNewUrl = env("APP_URL")."/fn/single/".$aRow['code'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $sFreenodeNewUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$sFreeNodeNewView = curl_exec($ch);
curl_close($ch);
$sFreeNodePath = "fn/".$aRow['code'].".html";
$r = file_put_contents($sFreeNodePath, $sFreeNodeNewView);
if ($r == false) {
echo "article to static - fail \n";return;
} else {
echo 'article to static - done:'.$aRow['code'].'\n';
}
}
}
}