🔄 卡若AI 同步 2026-02-21 19:39 | 更新:金仓、水桥平台对接、总索引与入口、运营中枢工作台 | 排除 >20MB: 5 个
This commit is contained in:
140
01_卡资(金)/金仓_存储备份/服务器管理/scripts/kr宝塔_node项目批量修复.py
Normal file
140
01_卡资(金)/金仓_存储备份/服务器管理/scripts/kr宝塔_node项目批量修复.py
Normal file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
kr宝塔:仅使用宝塔 Node 项目接口,批量修复 run=False 项目。
|
||||
|
||||
策略:
|
||||
1) 拉取 Node 项目列表
|
||||
2) 对 run=False 项目:
|
||||
- stop_project
|
||||
- 杀掉其目标端口上的冲突进程(EADDRINUSE)
|
||||
- 清理 pid 文件
|
||||
- start_project
|
||||
3) 回查 run/listen_ok
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import ssl
|
||||
import subprocess
|
||||
import time
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
|
||||
PANEL = "https://127.0.0.1:9988"
|
||||
API_KEY = "qcWubCdlfFjS2b2DMT1lzPFaDfmv1cBT"
|
||||
|
||||
|
||||
def sign():
|
||||
now = int(time.time())
|
||||
s = str(now) + hashlib.md5(API_KEY.encode("utf-8")).hexdigest()
|
||||
return {
|
||||
"request_time": now,
|
||||
"request_token": hashlib.md5(s.encode("utf-8")).hexdigest(),
|
||||
}
|
||||
|
||||
|
||||
def post(path, data=None, timeout=25):
|
||||
payload = sign()
|
||||
if data:
|
||||
payload.update(data)
|
||||
req = urllib.request.Request(
|
||||
PANEL + path, data=urllib.parse.urlencode(payload).encode("utf-8")
|
||||
)
|
||||
with urllib.request.urlopen(req, timeout=timeout) as resp:
|
||||
txt = resp.read().decode("utf-8", errors="ignore")
|
||||
try:
|
||||
return json.loads(txt)
|
||||
except Exception:
|
||||
return {"raw": txt[:800]}
|
||||
|
||||
|
||||
def fetch_list():
|
||||
result = post("/project/nodejs/get_project_list")
|
||||
items = result.get("data") if isinstance(result, dict) else None
|
||||
if not isinstance(items, list):
|
||||
items = result.get("list") if isinstance(result, dict) else None
|
||||
if not isinstance(items, list):
|
||||
raise RuntimeError("获取 Node 项目列表失败: %s" % str(result)[:300])
|
||||
return items
|
||||
|
||||
|
||||
def pids_on_port(port):
|
||||
cmd = "ss -tlnp | grep ':%s ' || true" % port
|
||||
out = subprocess.check_output(cmd, shell=True, universal_newlines=True)
|
||||
return sorted({int(x) for x in re.findall(r"pid=(\d+)", out)})
|
||||
|
||||
|
||||
def collect_ports(item):
|
||||
ports = []
|
||||
cfg = item.get("project_config") or {}
|
||||
p = cfg.get("port")
|
||||
if p:
|
||||
try:
|
||||
ports.append(int(p))
|
||||
except Exception:
|
||||
pass
|
||||
script = str(cfg.get("project_script") or "")
|
||||
for m in re.findall(r"-p\s*(\d+)", script):
|
||||
try:
|
||||
ports.append(int(m))
|
||||
except Exception:
|
||||
pass
|
||||
return sorted(set(ports))
|
||||
|
||||
|
||||
def main():
|
||||
items = fetch_list()
|
||||
operations = []
|
||||
|
||||
for it in items:
|
||||
name = it.get("name")
|
||||
if not name or it.get("run") is True:
|
||||
continue
|
||||
|
||||
ports = collect_ports(it)
|
||||
post("/project/nodejs/stop_project", {"project_name": name})
|
||||
|
||||
killed = []
|
||||
for port in ports:
|
||||
for pid in pids_on_port(port):
|
||||
subprocess.call("kill -9 %s" % pid, shell=True)
|
||||
killed.append((port, pid))
|
||||
|
||||
pid_file = "/www/server/nodejs/vhost/pids/%s.pid" % name
|
||||
try:
|
||||
if os.path.exists(pid_file):
|
||||
with open(pid_file, "w", encoding="utf-8") as f:
|
||||
f.write("0")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
r = post("/project/nodejs/start_project", {"project_name": name})
|
||||
ok = isinstance(r, dict) and (
|
||||
r.get("status") is True or "成功" in str(r.get("msg", ""))
|
||||
)
|
||||
msg = str(r.get("msg", r) if isinstance(r, dict) else r)[:220]
|
||||
operations.append((name, ports, killed, ok, msg))
|
||||
time.sleep(1)
|
||||
|
||||
print("=== 操作结果 ===")
|
||||
for row in operations:
|
||||
print(row)
|
||||
|
||||
time.sleep(4)
|
||||
items2 = fetch_list()
|
||||
run_cnt = sum(1 for x in items2 if x.get("run") is True)
|
||||
stop_cnt = sum(1 for x in items2 if x.get("run") is not True)
|
||||
|
||||
print("\n=== 回查(run/listen_ok) ===")
|
||||
for x in items2:
|
||||
print((x.get("name"), x.get("run"), x.get("listen_ok")))
|
||||
print("\nSUMMARY", run_cnt, stop_cnt)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
147
02_卡人(水)/水桥_平台对接/Soul文章上传/SKILL.md
Normal file
147
02_卡人(水)/水桥_平台对接/Soul文章上传/SKILL.md
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
name: Soul文章上传
|
||||
description: 《一场soul的创业实验》第9章文章写入小程序后端,写好即传,id 已存在则更新不重复
|
||||
triggers: Soul文章上传、Soul派对文章、第9章上传、soul 上传、写soul文章
|
||||
owner: 水桥
|
||||
group: 水
|
||||
version: "1.0"
|
||||
updated: "2026-02-20"
|
||||
---
|
||||
|
||||
# Soul文章上传 Skill
|
||||
|
||||
> 写好文章直接上传到 Soul 小程序,id 已存在则更新,保持不重复。 —— 水桥
|
||||
|
||||
---
|
||||
|
||||
## 触发条件
|
||||
|
||||
用户说以下关键词时自动激活:
|
||||
- Soul文章上传、Soul派对文章、第9章上传
|
||||
- soul 上传、写soul文章、上传到soul
|
||||
- 写好文章上传、文章写好了上传
|
||||
|
||||
---
|
||||
|
||||
## 核心配置
|
||||
|
||||
| 项目 | 路径/值 |
|
||||
|:---|:---|
|
||||
| Soul 项目根目录 | `/Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验` |
|
||||
| 第9章文章目录 | `/Users/karuo/Documents/个人/2、我写的书/《一场soul的创业实验》/第四篇|真实的赚钱/第9章|我在Soul上亲访的赚钱案例/` |
|
||||
| 上传脚本 | `一场soul的创业实验/scripts/upload_soul_article.sh` |
|
||||
| 底层工具 | `一场soul的创业实验/content_upload.py` |
|
||||
| 第9章固定参数 | part-4(第四篇|真实的赚钱), chapter-9(第9章|我在Soul上亲访的赚钱案例) |
|
||||
|
||||
---
|
||||
|
||||
## 执行步骤
|
||||
|
||||
### 1. 写好文章
|
||||
|
||||
文章放在第9章目录,文件名格式:`9.xx 第X场|主题.md`
|
||||
|
||||
示例:`9.18 第105场|创业社群、直播带货与程序员.md`
|
||||
|
||||
### 2. 执行上传
|
||||
|
||||
```bash
|
||||
/Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验/scripts/upload_soul_article.sh "/Users/karuo/Documents/个人/2、我写的书/《一场soul的创业实验》/第四篇|真实的赚钱/第9章|我在Soul上亲访的赚钱案例/9.xx 第X场|标题.md"
|
||||
```
|
||||
|
||||
### 3. 一键命令(替换为实际文件路径)
|
||||
|
||||
```bash
|
||||
cd /Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验
|
||||
./scripts/upload_soul_article.sh "<文章完整路径>"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 输出说明
|
||||
|
||||
| 返回 | 含义 |
|
||||
|:---|:---|
|
||||
| `"action": "创建"` | 新章节已写入 |
|
||||
| `"action": "更新"` | 同 id 已存在,内容已更新(不重复) |
|
||||
|
||||
---
|
||||
|
||||
## 配套脚本
|
||||
|
||||
| 脚本 | 用途 |
|
||||
|:---|:---|
|
||||
| `content_upload.py` | 直连数据库,创建/更新章节(依赖 pymysql) |
|
||||
| `scripts/upload_soul_article.sh` | 从文件名提取 id、title,调用 content_upload |
|
||||
|
||||
### 手动调用 content_upload(高级)
|
||||
|
||||
```bash
|
||||
cd /Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验
|
||||
|
||||
# 上传指定文章
|
||||
python3 content_upload.py --id 9.18 --title "9.18 第105场|主题" \
|
||||
--content-file "<文章路径>" --part part-4 --chapter chapter-9 --price 1.0
|
||||
|
||||
# 查看篇章结构
|
||||
python3 content_upload.py --list-structure
|
||||
|
||||
# 列出所有章节
|
||||
python3 content_upload.py --list-chapters
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API 接口(备用)
|
||||
|
||||
管理后台 API(需 Token):
|
||||
|
||||
| 接口 | 说明 |
|
||||
|:---|:---|
|
||||
| `POST /api/admin` | 登录获取 Token,Body: `{"username":"admin","password":"admin123"}` |
|
||||
| `POST /api/db/book` | 创建/更新章节,Header: `Authorization: Bearer {token}` |
|
||||
|
||||
正式环境:`https://soulapi.quwanzhi.com`
|
||||
开发环境:`https://souldev.quwanzhi.com`
|
||||
|
||||
---
|
||||
|
||||
## 经验与注意
|
||||
|
||||
### 1. 不重复机制
|
||||
|
||||
- 以 `id`(如 9.18)为唯一键
|
||||
- id 已存在 → **更新**;不存在 → **创建**
|
||||
- 同一场次多次上传不会重复,只会覆盖
|
||||
|
||||
### 2. 文件名规范
|
||||
|
||||
- 格式:`9.xx 第X场|主题.md`
|
||||
- id 从文件名提取,必须形如 `9.18`(章.节)
|
||||
|
||||
### 3. 环境依赖
|
||||
|
||||
```bash
|
||||
pip3 install pymysql
|
||||
```
|
||||
|
||||
### 4. 与书的对应关系
|
||||
|
||||
- 书稿目录:`个人/2、我写的书/《一场soul的创业实验》/第四篇|真实的赚钱/第9章|...`
|
||||
- 小程序内容来源:腾讯云 MySQL `soul_miniprogram.chapters`
|
||||
- content_upload 直连数据库,与 API 共用同一数据源
|
||||
|
||||
### 5. 工作流建议
|
||||
|
||||
1. 根据 Soul 派对 TXT 写好文章(按书格式:一句一行、金句开头、日期、`---` 分段)
|
||||
2. 保存为 `9.xx 第X场|主题.md` 到第9章目录
|
||||
3. 执行 `upload_soul_article.sh "<文章路径>"`
|
||||
4. 检查返回为「创建」或「更新」即完成
|
||||
|
||||
---
|
||||
|
||||
## 版本记录
|
||||
|
||||
| 版本 | 日期 | 说明 |
|
||||
|:---|:---|:---|
|
||||
| 1.0 | 2026-02-20 | 初版,从 Soul 项目抽取为独立技能 |
|
||||
@@ -1,7 +1,7 @@
|
||||
# 卡若AI 技能注册表(Skill Registry)
|
||||
|
||||
> **一张表查所有技能**。任何 AI 拿到这张表,就能按关键词找到对应技能的 SKILL.md 路径并执行。
|
||||
> 46 技能 | 14 成员 | 5 负责人
|
||||
> 47 技能 | 14 成员 | 5 负责人
|
||||
> 版本:5.0 | 更新:2026-02-16
|
||||
|
||||
---
|
||||
@@ -52,6 +52,7 @@
|
||||
| W07 | 飞书管理 | 水桥 | 飞书日志、写入飞书 | `02_卡人(水)/水桥_平台对接/飞书管理/SKILL.md` | 飞书日志/文档自动化 |
|
||||
| W08 | 智能纪要 | 水桥 | 会议纪要、产研纪要、**飞书妙记、飞书链接、妙记下载、第几场、指定场次、批量下载妙记、cunkebao.feishu.cn、meetings.feishu.cn/minutes** | `02_卡人(水)/水桥_平台对接/智能纪要/SKILL.md` | 会议录音转结构化纪要;飞书妙记识别与下载(单条/批量),完毕用复盘格式回复 |
|
||||
| W09 | 小程序管理 | 水桥 | 小程序、微信小程序 | `02_卡人(水)/水桥_平台对接/小程序管理/SKILL.md` | 微信小程序发布与维护 |
|
||||
| W10 | Soul文章上传 | 水桥 | **Soul文章上传、Soul派对文章、第9章上传、soul上传** | `02_卡人(水)/水桥_平台对接/Soul文章上传/SKILL.md` | 《一场soul的创业实验》第9章文章写好后上传到小程序,id 已存在则更新不重复 |
|
||||
|
||||
## 木组 · 卡木(产品内容创造)
|
||||
|
||||
@@ -109,8 +110,8 @@
|
||||
| 组 | 负责人 | 成员数 | 技能数 |
|
||||
|:--|:---|:--|:--|
|
||||
| 金 | 卡资 | 2 | 20 |
|
||||
| 水 | 卡人 | 3 | 9 |
|
||||
| 水 | 卡人 | 3 | 10 |
|
||||
| 木 | 卡木 | 3 | 6 |
|
||||
| 火 | 卡火 | 4 | 13 |
|
||||
| 土 | 卡土 | 4 | 6 |
|
||||
| **合计** | **5** | **14** | **54** |
|
||||
| **合计** | **5** | **14** | **55** |
|
||||
|
||||
@@ -43,3 +43,4 @@
|
||||
| 2026-02-20 18:17:38 | 🔄 卡若AI 同步 2026-02-20 18:17 | 更新:水桥平台对接、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 5 个 |
|
||||
| 2026-02-20 18:29:55 | 🔄 卡若AI 同步 2026-02-20 18:29 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 5 个 |
|
||||
| 2026-02-20 18:38:29 | 🔄 卡若AI 同步 2026-02-20 18:38 | 更新:金仓、运营中枢工作台 | 排除 >20MB: 5 个 |
|
||||
| 2026-02-21 13:04:58 | 🔄 卡若AI 同步 2026-02-21 13:04 | 更新:金仓、水桥平台对接、运营中枢工作台 | 排除 >20MB: 5 个 |
|
||||
|
||||
@@ -46,3 +46,4 @@
|
||||
| 2026-02-20 18:17:38 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-20 18:17 | 更新:水桥平台对接、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 5 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-02-20 18:29:55 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-20 18:29 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 5 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-02-20 18:38:29 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-20 18:38 | 更新:金仓、运营中枢工作台 | 排除 >20MB: 5 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-02-21 13:04:58 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-21 13:04 | 更新:金仓、水桥平台对接、运营中枢工作台 | 排除 >20MB: 5 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
|
||||
48
运营中枢/工作台/存客宝_卡若AI磁盘清理脚本.sh
Normal file
48
运营中枢/工作台/存客宝_卡若AI磁盘清理脚本.sh
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
# 存客宝 42.194.245.239 磁盘清理 · 卡若AI 生成
|
||||
# 在宝塔面板【终端】中粘贴本脚本内容执行,或上传后 bash 本脚本
|
||||
|
||||
set -e
|
||||
echo "========== 存客宝 卡若AI 磁盘清理 =========="
|
||||
echo "--- 清理前 ---"
|
||||
df -h /
|
||||
echo ""
|
||||
echo "--- 大目录 TOP15 ---"
|
||||
du -sh /www/* /var/log /tmp 2>/dev/null | sort -rh | head -15
|
||||
echo ""
|
||||
|
||||
# 1. 清理系统日志(保留结构)
|
||||
echo "[1/6] 清理系统旧日志..."
|
||||
journalctl --vacuum-time=3d 2>/dev/null || true
|
||||
find /var/log -type f -name "*.log" -mtime +7 -exec truncate -s 0 {} \; 2>/dev/null || true
|
||||
find /var/log -type f -name "*.gz" -mtime +7 -delete 2>/dev/null || true
|
||||
|
||||
# 2. 清理 apt 缓存(Ubuntu)
|
||||
echo "[2/6] 清理 apt 缓存..."
|
||||
apt-get clean 2>/dev/null || true
|
||||
apt-get autoremove -y 2>/dev/null || true
|
||||
|
||||
# 3. 清理临时目录
|
||||
echo "[3/6] 清理 /tmp /var/tmp..."
|
||||
rm -rf /tmp/* 2>/dev/null || true
|
||||
rm -rf /var/tmp/* 2>/dev/null || true
|
||||
|
||||
# 4. 宝塔面板日志截断(不删文件)
|
||||
echo "[4/6] 截断宝塔 request 日志..."
|
||||
for f in /www/server/panel/logs/request/*.log; do [ -f "$f" ] && truncate -s 0 "$f"; done 2>/dev/null || true
|
||||
|
||||
# 5. 网站日志截断(会清空当前日志内容,慎选)
|
||||
echo "[5/6] 检查网站日志大小..."
|
||||
du -sh /www/wwwlogs/ 2>/dev/null || true
|
||||
# 若需清空网站日志,取消下一行注释:
|
||||
# truncate -s 0 /www/wwwlogs/*.log 2>/dev/null || true
|
||||
|
||||
# 6. 回收站(需在面板【文件】里手动清空,此处仅提示)
|
||||
echo "[6/6] 请在面板【文件】→【回收站】中清空回收站以释放空间。"
|
||||
echo ""
|
||||
echo "--- 清理后 ---"
|
||||
df -h /
|
||||
echo ""
|
||||
echo "--- 大目录 TOP15 ---"
|
||||
du -sh /www/* /var/log /tmp 2>/dev/null | sort -rh | head -15
|
||||
echo "========== 清理完成 =========="
|
||||
Reference in New Issue
Block a user