get(); $aMsg = []; foreach ($oArticle as $oArticleRow) { $sMsgR = $this->_lifeToTg($oArticleRow); $aMsg[] = $sMsgR; } $oHttpTg->send($aMsg); } } private function _lifeToTg($oArticle) { $oHttp = new Http(); $oHttp->sToUrl = "https://api.github.com/repos/".$oArticle->user_name."/".$oArticle->project_name; $oHttp->sMethod = "get"; $r = $oHttp->send(); $sMsg = "?"; if (!$r) { $oHttpTg = new TGHttp(); $oHttpTg->send("请求github的api失败??"); } $aGitHub = json_decode($r, true); if (isset($aGitHub["status"]) && $aGitHub["status"] == "404") { $aMsg["msg"] = "嘎了~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; $aMsg["article"] = $oArticle; $sMsg = json_encode($aMsg, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); return $sMsg; } $tmp = str_replace("T", " ", rtrim($aGitHub["updated_at"], "Z")); //updated_at, pushed_at $tmp = strtotime($tmp); $tmpDate = date("Y-m-d H:i:s", $tmp + (8 * 3600)); $tmpTime = strtotime($tmpDate); $tmpNowTime = time(); $tmpDiff = $tmpNowTime - $tmpTime; $iLastUpdate = ceil($tmpDiff / 60); $aGitHubNew = []; $aGitHubNew["⭐️星星"] = $aGitHub["stargazers_count"]; $aGitHubNew["♻️最后更新"] = $iLastUpdate."分钟前"; // 替换T为空格并去掉Z $aGitHubNew["forks"] = $aGitHub["forks_count"]; $aGitHubNew["watchers"] = $aGitHub["watchers_count"]; $aGitHubNew["url"] = $this->urlFormat($aGitHub["html_url"]); $sMsg = json_encode($aGitHubNew, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); return $sMsg; } public function urlFormat($sUrl) { $sUrlNew = str_replace('/', '$', $sUrl); return $sUrlNew; } public function index() { try { $h = date("H"); $i = date("i"); $s = date("s"); $iRand = rand(1, 1440); $aUpdate = []; // $bSendTg = true; // $isTest = 0; //// test $aGet = $_GET; if (isset($aGet['is_test']) && $aGet['is_test'] == 1) { $isTest = 1; $this->isTest = 1; $aUpdate["shell"] = "cmd"; if ($aGet["time_type"] == 'i') { $i = (string) $aGet['v']; } else if ($aGet["time_type"] == 'h') { $h = (string) $aGet['v']; } else if ($aGet["time_type"] == "rand") { $iRand = $aGet["v"]; } else if ($aGet["time_type"] == "id") { $iTestId = $aGet["v"]; } } //// test // $h = "08"; // $i = "00"; $this->lifeToTg($h, $i, $s); if (isset($aGet["sSendTg"])) { $this->sSendTg = $aGet["sSendTg"]; } if (isset($aGet["sPull"])) { $this->sPull = $aGet["sPull"]; } // 暂停 // $option = Option::where("type", "pause")->first(); $option = Option::_hit("pause") ?? null; $isPause = isset($option->value) ? $option->value : null; if ($isPause == 1 && $isTest !== 1) { exit("暂停"); } // id测试 if (isset($iTestId)) { $aArticle = Article::where("id", $iTestId)->get()->toArray(); if (!empty($aArticle)) { $this->run($aArticle); } else { exit("这个id没找到"); } exit; } // i_in10规则 $iIin10 = $i[1]; $aArticle = Article::where("i_in10", $iIin10)->where("status", 1)->get()->toArray(); if (!empty($aArticle)) { $this->run($aArticle); } // inday_count规则 // $iRand = rand(1, 1440); // $iRand = 1; $oIndayArticle = Article::where("inday_count", ">=", $iRand)->where("status", 1)->get()->toArray(); // inday24 >= rand10 if (!empty($oIndayArticle)) { $this->run($oIndayArticle); } // i%7==0 $aConditions = Article::select('cron_condition') ->where('status', 1) ->distinct() ->get() ->toArray(); foreach ($aConditions as $row) { $sCondition = $row['cron_condition']; if (!empty($sCondition) && eval("return $sCondition;")) { $aArticle = Article::where("cron_condition", $sCondition)->where("status", 1)->get()->toArray(); $this->run($aArticle); } } } catch (\Throwable $e) { $sMessage = "错误(文件: " . $e->getFile() . ",行: " . $e->getLine() . "): " . $e->getMessage(); $oTGHttp = new TGHttp(); $oTGHttp->sendToTG($sMessage, $aUpdate); } } private function run($aArticle) { foreach ($aArticle as $row) { $this->sUserName = $row["user_name"]; $this->sMailName = $row["mail_name"]; $this->sMailTail = $row["mail_tail"]; $this->sProjectName = $row["project_name"]; $this->sProjectPath = env("BASE_DIR")."github/".$this->sUserName."-".$this->sProjectName; $this->sProjectUrl = "git@".$this->sMailName.".com:".$this->sUserName."/".$this->sProjectName.".git"; $this->aArticle = $row; $aArticleRow = $row; $sModType = $row["mod_type"] ?? "v1"; $sMod = $row["mod"]; // $oHttp->aData = $row; // $sReadMe = $oHttp->send($sMasterUrl); // 获取文章的方式 if ($sModType == "v1") { $sReadMe = ServiceGithub::GetReadMe($row); // 新版 } else { $oHttp = new Http(); $oHttp->sMethod = "post"; $sMasterUrl = "https://".env("www_master")."/api/github/get"; // $oHttp->bIsJson = true; $oHttp->aData = $row; $sReadMe = $oHttp->send($sMasterUrl); } // 没有文件夹,创建一个 if (!is_dir($this->sProjectPath)) { mkdir($this->sProjectPath, 0755, true); // 0755 是权限,true 表示递归创建目录 mkdir($this->sProjectPath."/feed", 0755, true); } // 没有文件夹,创建一个 if (!is_dir($this->sProjectPath."/feed")) { mkdir($this->sProjectPath."/feed", 0755, true); } // 没有仓库,创建一个 if (!is_dir($this->sProjectPath . "/.git")) { $this->gitInit(); $this->sshConfigAdd(); } // 请求cfn,更新订阅文件 // 不管是是否真更新,cfn那边没更新就返回昨天的文件,一样用。 $sFnCode = date("Ymd"); //// test // 20250721 - 23 有数据 // $sFnCode = 20250721; //// test end $oHttp = new Http(); $oHttp->sMethod = "get"; // $sMasterUrl = env("api_url_freenode_base")."/api/github/getfntoday/".$sFnCode; // /api/v1/freenode/url_feed_today/{siteCode}/{client?} $sMasterUrl = "https://".$row["www_master"]."/api/v1/freenode/url_feed_today/".$row["fn_code_short"]; $sReturn = $oHttp->send($sMasterUrl); $aReturn = json_decode($sReturn, true); if (!isset($aReturn["code"])) { exit("异常没有code -> $sReturn"); } if ($aReturn["code"] == "400") { // test exit("异常400"); } if ($aReturn["code"] == "200") { file_put_contents($this->sProjectPath."/feed/clash-".$sFnCode.".yaml", $aReturn["data"]["clash"]); file_put_contents($this->sProjectPath."/feed/v2ray-".$sFnCode.".txt", $aReturn["data"]["v2ray"]); file_put_contents($this->sProjectPath."/feed/singbox-".$sFnCode.".txt", $aReturn["data"]["singbox"]); } // 写入内容 if ($sReadMe) { file_put_contents($this->sProjectPath."/README.md", $this->formatstr($sReadMe)); } file_put_contents($this->sProjectPath."/version.text", md5(time())); if ($this->sPull == "n") { exit("\n 不提交"); } // 提交 if ($this->sSendTg == "n") { $content = file_get_contents($this->sProjectPath."/README.md"); echo $content; exit; } else { $this->gitPush(); } } } private function sshConfigAdd() { // 定义要添加的配置 $host = $this->sMailName; $hostname = "github.com"; $user = "git"; $identityFile = env("path_ssh")."/id_rsa_".$host; // 构建配置字符串 $config = "\nHost ".$host.".com\n"; $config .= "\tHostName $hostname\n"; $config .= "\tUser $user\n"; $config .= "\tIdentityFile $identityFile\n"; // 指定 SSH 配置文件路径 $sshConfigFile = env("path_ssh")."/config"; // 检查文件是否存在,如果不存在则创建 if (!file_exists($sshConfigFile)) { touch($sshConfigFile); } // 追加配置到文件 file_put_contents($sshConfigFile, $config, FILE_APPEND | LOCK_EX); // 设置文件权限 chmod($sshConfigFile, 0600); echo "SSH config updated successfully.\n"; } private function formatstr($str) { // $str = substr($str, 1, -1); return $str; } private function runCommand($command, $show_error = 1) { $output = []; $returnVar = 0; exec($command, $output, $returnVar); if ($returnVar !== 0 && $this->aArticle['show_error'] == 1 && $show_error == 1) { $aMsg = [ "命令" => $command, "结果" => json_encode($output), "文章" => $this->aArticle, ]; throw new \Exception(json_encode($aMsg, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); } } private function gitInit() { // 进入指定目录 if (!chdir($this->sProjectPath)) { throw new \Exception("无法进入目录 {$this->sProjectPath}\n"); } // 初始化 Git 仓库 $this->runCommand('git init'); // 添加安全目录 $this->runCommand("git config --local --add safe.directory \"{$this->sProjectPath}\""); // 设置用户 $this->runCommand("git config --local user.name \"{$this->sUserName}\""); $this->runCommand("git config --local user.email \"{$this->sMailName}@{$this->sMailTail}\""); //这里得改,直接tuta不行 // 创建并切换到 main 分支 $this->runCommand('git branch -M main'); // 添加远程仓库 $this->runCommand("git remote add origin \"{$this->sProjectUrl}\""); // 立即拉取覆盖一次 $this->runCommand("git fetch origin", 0); $this->runCommand("git reset --hard origin/main", 0); echo "操作完成:以初始化仓库[".$this->aArticle['id']."]。\n"; } // private function gitPullR() // { // // 进入指定目录 // if (!chdir($this->sProjectPath)) { // echo "无法进入目录 {$this->sProjectPath}\n"; // exit(1); // } // // // 获取远程更新 // $this->runCommand('git fetch origin'); // // // 硬重置到远程主分支 // $this->runCommand('git reset --hard origin/main'); // // echo "操作完成:已重置到远程主分支。\n"; // } private function gitPush() { // 进入指定目录 if (!chdir($this->sProjectPath)) { throw new \Exception("无法进入目录 {$this->sProjectPath}\n"); } // 添加更改到暂存区 $this->runCommand('git add .'); // 提交更改,使用当前日期作为提交信息 $commitMessage = date('Y-m-d H:i:s'); // 使用当前日期和时间作为提交信息 $this->runCommand("git commit -m \"$commitMessage\""); // 推送到远程主分支 $this->runCommand('git push -u origin main --force'); // 确保将 'main' 替换为你的默认分支名称, 覆盖 echo "操作完成:已提交并推送更改[".$this->aArticle['id']."]。\n"; } }