ComfyUI-SEEDVR2
功能:修复视频像素

“一句有哲理的话”
跑了一下午,40min才能修1s 修了跟没修差不多…
可能是我的电脑显卡还是太垃圾了
To be without some of the things you want is an indispensable part of happiness.
没有一些你想要的东西是幸福不可或缺的一部分。
ComfyUI-SEEDVR2
功能:修复视频像素

“一句有哲理的话”
跑了一下午,40min才能修1s 修了跟没修差不多…
可能是我的电脑显卡还是太垃圾了
To be without some of the things you want is an indispensable part of happiness.
没有一些你想要的东西是幸福不可或缺的一部分。
莱恩纳德伯爵有一桩旁人难以理解的苦处——他有洁癖。
虽不严重,却也足以让他对城中日益堆积的粪便问题寝食难安。按帝国律法,封地内的污物清理由领主责成下属官吏分管。莱恩纳德早已将此事明确划归几位行政官:昂格林负责东城,斯拉格负责西城,康德曼则总领协调。
然而数月过去,城中粪便未见减少。
并非几位行政官无能。昂格林与斯拉格近日痴迷于王都新近风行的“无畏”骑士角斗——两位铁甲骑士在圈中持钝器互搏,直至一方倒地。两人日日研究骑士的胜负赔率,将俸禄大半押在赌盘上。至于城中粪便,“不过是些秽物,迟一日早一日又有何妨?”
而康德曼则另有一番本事。
每逢莱恩纳德问起,康德曼总是满脸诚恳:“大人放心,属下已在安排。近日正与清运行会商谈,不日便有进展。”他说得如此笃定,如此流畅,仿佛真有一份详细的方案藏在他胸中。可出了议事厅,他便将此事抛诸脑后,继续研究下一场角斗的赔率。
坦纳伯斯伯爵曾私下听闻,康德曼年轻时曾游历南方诸城邦,习得一种“政客之术”——用最动听的承诺换取最廉价的信任,至于承诺能否兑现,那便是另一回事了。
起初,莱恩纳德尚能容忍。
他自掏腰包,雇佣城中闲汉清运秽物。他有洁癖,无法忍受污秽满城,权当是为自己的安宁付账。可日复一日,月复一月,他的积蓄渐渐吃紧,而几位行政官依旧无动于衷。
“我总不能替他们做一辈子。”莱恩纳德终于下了决心,他要看看,若自己不再插手,这些人究竟会不会动。
于是他闭门不出,将自己锁在城堡的书房里,埋头批阅那些永远处理不完的文书——粮赋账册、边境巡逻报告、商队通行许可。他试图相信,几位行政官再不济,也不至于让整座城池淹没在粪便之中。
然而命运偏要嘲弄他的信任。
数周后,莱恩纳德染了风寒。头重脚轻之际,他想出门透一透气。城堡的大门缓缓打开,他深吸一口气——
几乎窒息。
那股恶臭扑面而来,浓烈得仿佛有形。他定睛看去,街巷之中,马粪、牛粪、狗粪、乃至人的排泄物,混杂着烂菜叶和污水,铺满了石板路。苍蝇成群,野狗在秽物中翻找残食。行人掩鼻疾走,孩童光着脚踩过泥泞——那泥泞的颜色令人作呕。
莱恩纳德站在门口,久久未动。
他去了东城,昂格林正与几个商贾热烈讨论下一场角斗的胜率,桌上摊着一幅画着两位骑士的羊皮纸。
“昂格林,城中的粪便你打算何时处理?”
“大人稍候,待我算完这场赔率……”
莱恩纳德转身去了西城。斯拉格不在岗哨,旁人说他去酒馆与人兑换赌赢的金币了。
最后他找到了康德曼。康德曼正端坐在自己的办公桌前,面前摊着一份空白的羊皮纸,笔搁在一旁,墨迹已干。
“康德曼,你总说在安排。”
“大人,确实在安排。只是清运行会最近人手紧缺……”
莱恩纳德盯着他的眼睛看了很久。
康德曼的目光坦然而诚恳,没有一丝闪躲——这才是最可怕的。他不是在撒谎,他只是在表演一种自己都信以为真的“正在处理”。
莱恩纳德没有再说什么。
他回到城堡,换了一身旧衣,从工具房取出一把铁锹。
百姓们惊讶地看见,他们的领主——那位向来衣着整洁、连书案都要擦拭三遍的莱恩纳德伯爵——正弯着腰,一锹一锹地将街头的粪便铲入推车。他的鼻子塞着布条,额头上沁出细汗,不时咳嗽几声,显然风寒未愈。
渐渐地,有几个老妇拎着桶出来了。接着是铁匠铺的学徒,然后是屠户,然后是酒馆的伙计。
没有人说话。
日落时分,主街终于露出了石板的本来面目。
莱恩纳德直起腰,将铁锹靠在墙边,慢慢走回城堡。他的旧衣上沾满了污渍,他却没有像往常那样急着换洗。
他只是坐在台阶上,望着渐暗的天色,一言不发。
坦纳伯斯伯爵后来问及此事,莱恩纳德淡淡道:“我原想看看,没有我,他们能不能做成事。结果证明,他们确实不能。而我也不能眼睁睁看着自己的城淹在粪水里。”
“所以你认了?”
“我认了。”他站起身,拍了拍衣袍上并不存在的灰尘,“只是从今往后,我再不会对康德曼的‘正在安排’抱任何期待。他的诺言,比街上的粪便还不值钱——至少粪便还能肥田。”
(坦纳伯斯伯爵的结语)
女巫在搅拌一锅沸腾的粪水时曾说:世间有三种人最令人生厌——第一种是制造污秽却浑然不觉的人,第二种是眼见污秽却忙于赌斗的人,第三种则是用最动听的承诺把污秽掩盖起来、让你以为已经有人去清理的人。莱恩纳德错在何处?他错在相信了一件事——即那些坐在办公室里的人,会在意他坐在办公室里在意的事。他们不在意的。他们只在意角斗场上谁赢谁输,以及下一次该用什么漂亮话搪塞过去。而那个最厌恶污秽的人,最终注定要亲手铲除最多的污秽。这便是洁癖者的宿命:因为无法忍受,所以不得不做。

ESP8266电子时钟
功能:自定义API访问
显示天气
显示时间
#include <U8g2lib.h>
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
// ==================== OLED配置 ====================
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 5, /* data=*/ 4);
// ==================== 蜂鸣器配置 ====================
#define BUZZER_PIN 0 // D3 (GPIO0)
// ==================== WiFi配置 ====================
const char* ssid = "N/A";
const char* password = "N/A";
// ==================== API配置 ====================
const char* timeUrl = "N/A";
const char* serverUrl = "N/A";
// 心知天气配置(免费注册:https://www.seniverse.com/)
const char* xinzhiKey = "N/A";
const char* city = "N/A";
const char* weatherUrl = "https://api.seniverse.com/v3/weather/now.json";
WiFiClientSecure client;
// ==================== 全局变量 ====================
int currentHour = 0;
int currentMinute = 0;
int currentSecond = 0;
int currentWeekday = 0;
String currentDateFormatted = "";
// 天气
String weatherText = "";
String weatherTemp = "";
// 通知
String notifications[30];
int notificationCount = 0;
int currentNotificationIndex = 0;
// 定时
unsigned long lastTimeUpdate = 0;
unsigned long lastWeatherUpdate = 0;
unsigned long lastDataUpdate = 0;
unsigned long lastModeSwitch = 0;
int displayMode = 0; // 0:时间界面, 1:通知界面
bool notificationJustShown = false;
// ==================== 辅助函数 ====================
String getWeekdayCN(int w) {
String weekdays[] = {"周一", "周二", "周三", "周四", "周五", "周六", "周日"};
if (w >= 0 && w <= 6) return weekdays[w];
return "周一";
}
String getWeatherCN(String weather) {
if (weather.indexOf("Clear") >= 0) return "晴";
if (weather.indexOf("Cloud") >= 0) return "多云";
if (weather.indexOf("Overcast") >= 0) return "阴";
if (weather.indexOf("Light Rain") >= 0) return "小雨";
if (weather.indexOf("Moderate Rain") >= 0) return "中雨";
if (weather.indexOf("Heavy Rain") >= 0) return "大雨";
if (weather.indexOf("Rain") >= 0) return "雨";
if (weather.indexOf("Snow") >= 0) return "雪";
if (weather.indexOf("Fog") >= 0) return "雾";
return weather;
}
void beepLight() {
digitalWrite(BUZZER_PIN, LOW);
delay(80);
digitalWrite(BUZZER_PIN, HIGH);
}
// ==================== 获取数据 ====================
void updateTime() {
if (WiFi.status() != WL_CONNECTED) return;
HTTPClient https;
client.setInsecure();
https.setTimeout(5000);
if (!https.begin(client, timeUrl)) return;
int httpCode = https.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = https.getString();
DynamicJsonDocument doc(512);
deserializeJson(doc, payload);
currentHour = doc["hour"];
currentMinute = doc["minute"];
currentWeekday = doc["weekday"];
String timeStr = doc["time"].as<String>();
if (timeStr.length() >= 19) {
currentSecond = timeStr.substring(17, 19).toInt();
}
String dateStr = doc["date"].as<String>();
if (dateStr.length() >= 10) {
String month = dateStr.substring(5, 7);
String day = dateStr.substring(8, 10);
currentDateFormatted = month + "月" + day + "日";
}
}
https.end();
}
void updateWeather() {
if (WiFi.status() != WL_CONNECTED) return;
if (String(xinzhiKey).length() == 0) return;
String url = String(weatherUrl) + "?key=" + xinzhiKey + "&location=" + city + "&language=en&unit=c";
HTTPClient https;
client.setInsecure();
https.setTimeout(5000);
if (!https.begin(client, url)) return;
int httpCode = https.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = https.getString();
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
if (doc.containsKey("results")) {
JsonObject now = doc["results"][0]["now"];
weatherText = now["text"].as<String>();
float temp = now["temperature"];
weatherTemp = String(temp, 0);
}
}
https.end();
}
void fetchNotifications() {
if (WiFi.status() != WL_CONNECTED) return;
HTTPClient https;
client.setInsecure();
https.setTimeout(10000);
if (!https.begin(client, serverUrl)) return;
int httpCode = https.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = https.getString();
DynamicJsonDocument doc(4096);
deserializeJson(doc, payload);
if (doc["status"] == "success") {
notificationCount = 0;
JsonArray notificationsArr = doc["notifications"];
for (JsonObject n : notificationsArr) {
if (notificationCount < 30) {
notifications[notificationCount] = n["content"].as<String>();
notificationCount++;
}
}
}
}
https.end();
}
// ==================== 手表界面 ====================
void displayWatchFace() {
u8g2.firstPage();
do {
// ========== 顶部区域 ==========
u8g2.setFont(u8g2_font_wqy12_t_chinese3);
u8g2.drawHLine(0, 15, 128); // 顶部分割线
// 日期(左上角)
u8g2.setCursor(5, 12);
if (currentDateFormatted.length() > 0) {
u8g2.print(currentDateFormatted);
} else {
u8g2.print("03月24日");
}
// 星期(右上角)
u8g2.setCursor(95, 12);
u8g2.print(getWeekdayCN(currentWeekday));
// ========== 中间时间区域 ==========
// 时间往下移(从y=42移到y=48)
u8g2.setFont(u8g2_font_logisoso24_tf);
u8g2.setCursor(25, 48);
char timeBuf[6];
sprintf(timeBuf, "%02d:%02d", currentHour, currentMinute);
u8g2.print(timeBuf);
// 秒数(放在时间右侧)
u8g2.setFont(u8g2_font_helvB08_tf);
u8g2.setCursor(105, 38);
char secBuf[3];
sprintf(secBuf, "%02d", currentSecond);
u8g2.print(secBuf);
// ========== 底部区域 ==========
// 底部文字(放在线下方,y=63)
u8g2.setCursor(10, 63);
if (weatherText.length() > 0 && weatherTemp.length() > 0) {
u8g2.print(getWeatherCN(weatherText));
u8g2.print(" ");
u8g2.print(weatherTemp);
u8g2.print("°C");
} else if (String(xinzhiKey).length() > 0) {
u8g2.print("天气加载中");
} else {
u8g2.print("WiFi:");
u8g2.print(WiFi.RSSI());
u8g2.print("dBm");
}
// 通知数量(右侧)
if (notificationCount > 0) {
u8g2.setCursor(100, 63);
u8g2.print("[");
u8g2.print(notificationCount);
u8g2.print("]");
}
} while (u8g2.nextPage());
}
// ==================== 通知界面 ====================
void displayNotification() {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_wqy12_t_chinese3);
u8g2.drawHLine(0, 15, 128);
u8g2.setCursor(45, 12);
u8g2.print("通 知");
u8g2.drawHLine(0, 22, 128);
if (notificationCount > 0 && currentNotificationIndex < notificationCount) {
String content = notifications[currentNotificationIndex];
int lineHeight = 12;
int startPos = 0;
int lines = 0;
while (startPos < content.length() && lines < 3) {
int endPos = startPos + 18;
if (endPos > content.length()) endPos = content.length();
u8g2.setCursor(5, 32 + lines * lineHeight);
u8g2.print(content.substring(startPos, endPos));
startPos = endPos;
lines++;
}
u8g2.setCursor(100, 63);
u8g2.print(currentNotificationIndex + 1);
u8g2.print("/");
u8g2.print(notificationCount);
} else {
u8g2.setCursor(35, 40);
u8g2.print("暂无通知");
}
} while (u8g2.nextPage());
}
// ==================== 初始化 ====================
void setup() {
Serial.begin(115200);
delay(100);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, HIGH);
u8g2.begin();
u8g2.enableUTF8Print();
u8g2.setFont(u8g2_font_wqy12_t_chinese3);
u8g2.firstPage();
do {
u8g2.setCursor(35, 30);
u8g2.print("连接WiFi");
} while (u8g2.nextPage());
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 25) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi已连接");
u8g2.firstPage();
do {
u8g2.setCursor(40, 30);
u8g2.print("WiFi已连");
} while (u8g2.nextPage());
delay(1000);
}
client.setInsecure();
updateTime();
updateWeather();
fetchNotifications();
beepLight();
}
// ==================== 主循环 ====================
void loop() {
unsigned long now = millis();
if (now - lastTimeUpdate >= 1000) {
updateTime();
lastTimeUpdate = now;
}
if (now - lastWeatherUpdate >= 300000) {
updateWeather();
lastWeatherUpdate = now;
}
// 每15分钟检查通知
if (now - lastDataUpdate >= 900000) {
fetchNotifications();
lastDataUpdate = now;
if (notificationCount > 0) {
displayMode = 1;
lastModeSwitch = now;
currentNotificationIndex = 0;
notificationJustShown = true;
beepLight();
}
}
// 通知界面显示10秒后切回
if (displayMode == 1 && notificationJustShown) {
if (now - lastModeSwitch >= 10000) {
displayMode = 0;
notificationJustShown = false;
lastModeSwitch = now;
}
}
// 通知界面自动翻页
if (displayMode == 1 && notificationCount > 0 && notificationJustShown) {
static unsigned long lastNotiSwitch = 0;
if (now - lastNotiSwitch >= 3000) {
currentNotificationIndex = (currentNotificationIndex + 1) % notificationCount;
lastNotiSwitch = now;
}
}
if (displayMode == 0) {
displayWatchFace();
} else {
displayNotification();
}
delay(50);
}C++“记住他人名字带给他人被记住的感觉是这个时代所稀缺的,因为效率至上的时代,每个人都忽视了彼此包括自己”
–
“Making someone feel remembered just by knowing their name—that’s something rare in today’s world. In an era that prioritizes efficiency, people often neglect others, and even themselves.“
I wonder how many people I’ve looked at all my life and never seen.
我想知道,我一生中曾看过多少人,却从未真正看见过他们。
——摘自《坦纳伯斯伯爵手记·卷五》
坦纳伯斯伯爵途经边陲时,曾在一间小酒馆里,听见邻桌的商人低声议论:“听说了吗?莱恩纳德伯爵家出事了。”
他放下酒杯,侧耳倾听。
莱恩纳德家族的起家,在边地并非秘密。老莱恩纳德并非生而显贵,年轻时不过是戍边军团的一名普通甲士。某次蛮族夜袭,他独守隘口至援军抵达,战后先帝感其勇,赐了一小块边陲封地——便是如今的莱恩纳德郡下。
老莱恩纳德卸甲归田后,始终忘不了那些戍边的岁月。他将那套随他出生入死的旧甲胄偷偷藏在谷仓深处,每年擦拭一回,仿佛这样就能留住自己曾经的身份。
如今老莱恩纳德年事已高,思乡之情日甚。他想回到幼年居住的怡人之滨,在故土终老。临行前,他舍不得那套旧甲,便将其装入箱中,随车队一同带走。
途经王都检查站时,守兵打开了那口箱子。
甲胄在阳光下泛着冷光。按帝国律法,私藏制式甲胄者,以谋逆论处。
消息传到王都时,昔日的先帝早已驾崩。如今的皇帝坐在金殿上听完奏报,只淡淡问了句:“此人如今任何官职?”
“回陛下,一介边陲老卒,已无军职。”
皇帝便不再多问。他没有兴趣为一个没有用处的小人物翻旧账,也没有兴趣展现仁慈。重罚便是了。
判决很快下达:老莱恩纳德罚没半数家产,本人监禁三年。其子孙三代不得入仕,不得担任任何公职,不得参与帝国任何层级的人才选拔。
三代不得触及权力核心。
判决书上甚至附了一笔——有人曾提议将莱恩纳德郡下收回王室,但经吏员核查,那片封地“过于偏远贫瘠,年贡不足修缮王都一段城墙”,便作罢了。
消息传到莱恩纳德伯爵耳中时,他正在书案前批阅秋收账册。
他沉默了许久,然后继续批阅。
但坦纳伯斯伯爵后来听说,那几天夜里,城堡的书房灯火彻夜未熄。管家送进去的晚餐,常常原样端出来。
其实莱恩纳德早有经商之意。他秉公廉洁多年,未曾借职权敛过一枚铜板,积蓄寥寥。他也曾试着做几回买卖——贩过毛皮,倒过铁器,甚至动过酿酒的心思——但每每浅尝辄止,多以亏损收尾。他骨子里终究是个务实的人,对商贾之事既无天赋,也无热忱,只是觉得或许该为郡下多寻一条出路。
如今这判决落下,他未来的路,又少了一条。
他本就在犹豫:郡下的未来,是该倾力发展商贸,还是该广纳贤才,兴办学堂?前者见效快但根基不稳,后者见效慢却利在长远。他为此辗转了无数个夜晚,始终未能决断。
如今倒好,不必决断了。
三代不得入仕,不得参与选拔。他的子孙,他的郡下子弟,即便再有才华,也触摸不到帝国权力的门槛。兴办学堂、培养人才,又有什么意义呢?
而商贸之路——他自己都做不成的买卖,又如何指望郡下能靠它繁荣?
某个黄昏,坦纳伯斯伯爵在城墙上找到了莱恩纳德。他独自站在那里,望着西沉的日头,面色平静,只是眉心拧着一道深深的纹路。
“你可还好?”坦纳伯斯问。
莱恩纳德沉默片刻,缓缓开口:“我父亲那套甲胄,其实早已锈蚀。他留着它,不过是想记住自己曾经是谁。”
他顿了顿,又说:“先帝赐他封地时,说这是‘酬忠义之士’。如今新帝罚他三代,也是依律而行。我怨不得谁。”
“只是……”他的声音低了下去,“我勤勤恳恳治理这片土地,从未懈怠一日。我清廉自守,不取分毫不义之财。我以为只要把郡下治理好,便算对得起先帝的恩赐,对得起父亲留下的这份家业。”
“可现在我才明白——在权力中心的眼里,我和我的郡下,不过是一片‘过于偏远贫瘠、不值得收回’的地方。”
他苦笑了一下。
“连被剥夺的资格,都是因为太不值钱。”
坦纳伯斯没有说话。
风吹过城墙,带着秋末的凉意。
良久,莱恩纳德直起身,整了整衣襟,朝城墙下走去。
“但郡下还是需要治理的,不是吗?”他在经过坦纳伯斯身边时,说了这么一句,便头也不回地走了。
坦纳伯斯站在原地,看着他的背影消失在暮色里。
那背影依旧挺直,只是脚步比来时沉重了些。
(坦纳伯斯伯爵的结语)
沼泽女巫在翻看旧羊皮卷时曾说:忠诚是一种极其脆弱的货币,它的价值完全取决于发行它的人是否还在位。先帝用它换来了一块封地,新帝却连兑换的机会都不再给予。最荒谬的莫过于此——那套甲胄从未伤人,它只是提醒了一位老者他曾是谁。而帝国惩罚他的,恰恰是他曾经忠心的证明。至于莱恩纳德……他如今才知,勤恳和廉洁,在权力的账簿上,从不被记作资产。
——摘自《坦纳伯斯伯爵手记·卷四》
据传,莱恩纳德伯爵年少时,曾在王立治术学堂修习。彼时他一心钻研法典、粮秣与城防,视同窗间的宴饮嬉游为无用之物,独来独往,如一头不合群的幼狼。
直到一个名叫奎因桑的女子出现在他的世界里。
她是友人之友,初时不过是巡猎途中偶然同行的身影。但古怪之人自有古怪之人才能辨认的磁场——莱恩纳德发现,她同样不善言辞,同样会在旁人谈笑时走神去看天边的云,同样对猎犬的耳朵比对人脸更感兴趣。
他们开始结伴巡猎。
那些日子里,莱恩纳德第一次觉得,清晨的露水是有温度的,林间的风声是有语言的。他学会了辨认她箭囊上那根歪斜的羽毛,她记住了他整理马鬃时那种近乎偏执的认真。他们可以在沉默中共度整个下午,谁也不觉得尴尬。
他没有说。
他有一千个理由:学业未成,领地未继,前途未卜。他告诉自己,真正的爱意应当等到配得上她的那一天。于是那支箭始终搭在弦上,引而不发。
毕业那日,她朝他挥了挥手,转身消失在王都的街道里。他没有追。
此后的年月,莱恩纳德伯爵果然将封地治理得井井有条。只是每当巡猎经过那片旧林,他总会在某个树桩前勒马片刻——那是她曾经坐过的地方。他暗自发愿:待领地再无饥馑,待城墙再无裂缝,待所有麻烦都平息,他便去找她。
然而领地如活物,旧的沟渠填平,新的税案便来;春荒刚过,夏汛又至。他永远在“还差一点”的路上。
直到某个秋日午后,他在边境集市处理牲畜贸易纠纷时,听见两个皮毛商贩的闲谈。
“听说了吗?北境那位传奇猎人,去年娶了个怪脾气的女人。”
“怎么个怪法?”
“据说她能在林中静坐半日不动,就为看一只松鼠埋橡果。还能叫出每只猎犬的名字。那猎人逢人便夸,说她是森林赐给他的礼物。”
商贩们哄笑。莱恩纳德手中的账册滑落在地。
他派了最可靠的人去北境查探。半月后回报:奎因桑,确已嫁与那位以箭术闻名的猎人,夫妻二人居于林畔木屋,出入成双,据说颇为和睦。
那天夜里,莱恩纳德的城堡灯火通明。他没有处理任何政务,只是坐在议事厅的高背椅上,对着壁炉里跳动的火焰,沉默了一整夜。
次日清晨,他的管家发现伯爵已经坐在书案前批阅积压的文书,字迹如常工整,只是墨痕有几处洇开了。
后来,坦纳伯斯伯爵在路过他的领地时,曾与他共饮一杯。席间问及此事,莱恩纳德放下酒杯,目光落在窗外远处那片模糊的林线上,缓缓说道:
“我用了很久才想明白。我许下的那个‘等我治好领地就去找她’的誓言,不过是一张永远不必兑现的借口。因为领地永远会有新的麻烦——正如我永远会有新的理由。我以为自己在等一个对的时机,其实只是在等自己足够勇敢。而勇气这种东西,等是等不来的。”
他顿了顿,又说:“但有一件事,我确实没有骗自己。治理这片领地,从来不是为了她,也不是为了逃避她。我脚下的土地和土地上的人,才是真实的。那支没有射出的箭,就让它永远留在箭囊里吧。至少它提醒我,有些东西,错过了就是错过了。但手里剩下的箭,还得射向该去的地方。”
(坦纳伯斯伯爵的结语)
沼泽女巫在占卜时曾说:世间最锋利的箭,往往不是射中靶心的那一支,而是搭在弦上太久、最终被收回箭囊的那一支。它不曾射向何,却日复一日地磨损着持弓者的掌心。世人总以为遗憾是因为没有勇气,却不知有时候,正是因为没有勇气,我们才得以保全那些本会在日常琐碎中碎裂的幻梦。莱恩纳德的悲剧不在于他错过了她,而在于他用一个永远无法兑现的“以后”,欺骗了自己那么多年。所幸,他终于学会了区分——什么是可以弥补的,什么是只能咽下的。
风很大,但我还站着。这就够了。这就是我的 Done。
2026年的某一天,我站在学校操场上,吹着冷风,和自己说了很久的话。
那天我知道了:她有了男朋友。
这件事我早就模拟过无数次——从我意识到“她会有男朋友”的那天起,我就在心里预演过这个场景。但当它真的发生时,我还是去了操场。不是去哭的。一滴眼泪都流不出来。
我只是觉得有点冷。
然后我开始和自己说话。不是自言自语,是真的说话——像对着另一个自己,把那些年积压的东西,全部摊开来,一件一件地看。
那段录音,我今天翻出来听了。声音被风吹得有点抖,但每句话都像钉子,钉在那个晚上的空气里。
这是我“Do and Done”诞生的夜晚。
“我做任何事,都是为了拯救去的。这个课题很高尚。”
这是我过去人生的全部脚本。
我有一个“白骑士综合征”。我把喜欢的人变成了一个需要被拯救的符号,然后把“拯救她”设定为我活着的意义。考大学是为了拯救她,变好是为了拯救她,做一切事情都是为了那个宏大的目标。
这个剧本有一个致命的漏洞:扮演英雄的人,自己却没有血包。
“连自己都拯救不了的人,遑论拯救他人”——这句话我曾经说得理直气壮。我以为这是谦卑,后来才明白,这是逃避。我把爱“私有化”了:爱是需要先“配得上”才能领取的东西。而我永远配不上,因为我永远“还没拯救好自己”。
所以我什么都不用真正去做。
高尚的口号挂在嘴边,行动却停在原地。口号没有让我多10%的效率,但我仍然不肯放下。为什么?因为放下它,我就不知道我是谁了。
“现在好了,梦碎了。你连这个理由都没有了。”
她找到那个人的时候,我的神像塌了。
不是突然塌的。我早就模拟过这一天。从上学期末开始,我已经在慢慢接受她不在我生命中的事实。我只是没想到,当预言被验证的那一刻,我会这么……平静。
一滴眼泪都没有。
我难过吗?不难过。我只是把过去所有积压的情绪,重新过了一遍。然后发现:那个我曾经以为非她不可的人,其实早就不是我生活的一部分了。
最讽刺的是什么?
她过得很好。比我好。
我一直在担心“她别死了”,结果活得比我还滋润。那个我曾经想要“拯救”的人,根本不需要我拯救。她靠自己,或者靠别人,走到了我当初设定的“拯救目标”那里——比如,找到一个可靠的男友。
而我自己呢?
“你考了个破大专,躺了两年。你做出什么成绩了?你连一等奖学金都没得。你做什么事情都不做出百分百的努力?”
这是我对自己说的话。每句都扎在自己身上。
“你一直在做计划,但是你去执行了吗?很少。你的脑子一直在空想我该怎么解决问题,但是你真的落地去解决了吗?”
这是我对自己的第二个发现。
过去的我,活在一个奇怪的循环里:
做计划 → 空想怎么执行 → 焦虑 → 再做计划
就像一个传动轴,拼命转,却没有接上发动机。我以为自己在努力,其实只是在空转。我做项目,做题库,做小程序——但碰到一点困难就掉头。
“你只敢撞一次南墙,你不敢撞第二次。你分不清哪些是小石子,哪些是真正的南墙。”
小石子,掉头就走。
真正的南墙,从来不敢撞。
因为撞墙会痛。而我已经没有“为了她”这个理由,去承受那个痛了。
“事情的意义大多是事后赋予的。我只需要 Do and Done 就行了。”
这句话,是在那片废墟上长出来的。
它不是一句漂亮的口号。它是我在发现自己所有“高尚”都是骗局之后,能找到的、唯一可以握住的、最小的东西。
什么是“Do and Done”?
它和“得过且过”的区别是什么?
得过且过是:反正没意义,所以我什么都不做。
Do and Done是:正因为意义不明,所以我要先做点什么。
每一个“Done”,都是在虚无里钉下的木桩。
我按时吃饭了——Done。
我跑完步了——Done。
我把这个项目做完了——Done。
这些木桩可能很小,但它们证明一件事:我存在过,我行动过,我没有停在原地。
“接着走下去,带着疑惑,接着走下去。生命会自己找出出路。”
我不知道这个哲学能带我走多远。
我不知道做完一堆“Done”之后,我的人生会不会有答案。
但我站在那个晚上的风里时,想明白了一件事:
出路不是想出来的,是走出来的。
我过去一直在空想“出路在哪里”。现在我决定,先迈一步。迈完一步,再迈一步。走完之后,回头看,那条路可能就是出路。
那个晚上,风很大,人很多,每个人都拿着手机,每个人都像一座孤岛。
“我觉得我是一个内部极大丰富的人,但是没有人能理解我,因为大家都被手机给困住了。”
我也想被理解。但我知道,在被理解之前,我得先把自己活出来。
活出来,不是靠“高尚的口号”活出来,而是靠一个又一个微小的“Do”,把自己从废墟里一点点挖出来。
“风吹过我的指尖,风吹过我的脸颊,风吹过我的发梢,好凉快,好舒服。但是感受过后呢,我确确实实的活着,但我活着我干嘛呢?”
这是那天晚上,我问自己的最后一个问题。
我没有答案。
但我选择继续活着。继续感受风。继续做下一件小事。继续在每个夜晚,对自己说:
今天,我又完成了一个 Done。
那个曾经需要靠拯救别人来证明自己有价值的人,现在只需要靠做完一件小事,就能在深夜里对自己说:
看,我今天存在过了。
这就够了。
风很大,但我还站着。
关于“拯救者”的幻灭:
“我做任何事,都是为了拯救去的。这个课题很高尚,现在这份高尚被击碎了,你的高尚一点都不高尚,他一点都不在乎。这只是你一直一直在欺骗自己。”
关于“私有化的爱”:
“你不敢面对他的根本原因,就是你不敢面对你自己。你不敢把这个自己都拿不出手的人去面对他。所以你会说:连自己都拯救不了的人,遑论拯救他人呢。”
关于“神像倒塌”:
“梦碎了,你现在连这个理由都没有了。现在好了,梦碎了,你现在连这个理由都没有了。”
关于“被验证的预言”:
“你接触了你一早就模拟好这种——她会有男朋友,她已经有男朋友,现在只是把事实摆在你面前。这件事你已经试想过发生了,但是现在确实发生了,它只是验证了你的预言。”
关于“计划与执行的断裂”:
“你一直在做计划,在做计划,但是你去执行了吗?很少。你的脑子一直在空想我该怎么解决问题,但是你真的落地去解决这个问题了没有?……就像那个传动轴没有接上那个发动机。”
关于“不敢撞南墙”:
“你只敢撞一次南墙,你不敢撞第二次。拿你的破头,一个项目撞一次南墙,哪怕是轻微的,哪怕是踩了一个石头,你都要往回掉头……你现在分不清哪些该调头,哪些是小石子,哪些是真正的南墙。”
关于“用微小成就欺骗自己”:
“还是在骗自己,拿一点微不足道的成就去骗自己。我今天做完一个项目,但是你真的学到了吗?你只是会用AI而已,给你的幻觉把你骗住了。”
关于“缺乏宏大目标”:
“所有事情都完成之后,你现在还是跟个无头苍蝇一样乱撞,因为你缺乏一个宏大的目标。你之前宏大的目标就是我要去变得更好,我要去拯救他……现在我缺乏一个宏大目标。”
关于“意义在事后赋予”:
“事情的意义大多是事后赋予的。我只需要 Do and Done 就行了。”
关于“带着疑惑走下去”:
“接着走下去,带着疑惑,接着走下去。坚持下去,然后呢?然后说,生命会自己找出出路。”
关于“真实的活着”:
“我能感受到我有些时候我确实在感受到,风吹过我的指尖,风吹过我的脸颊,风吹过我的发梢,好凉快,好舒服。但是感受过后呢,我确确实实的活着,但我活着我干嘛呢?”
关于“哭不出来”:
“一滴眼泪都流不出来。你难过吗?你这些事情你早预料到了。你难过吗?你不难过。我只是觉得有点冷。”
关于“人和人的隔阂”:
“每一个人拿着手机,都像一座无形的牢笼,把这彼此隔开了。我们再也不对话,然后矛盾越来越深。”
关于“渴望被理解”:
“我觉得我是一个内部极大丰富的人,但是没有人能理解我、来解读我,因为大家都被手机给困住了。”
核心洞察:
“高尚的口号并没有为我的行事+10%效率,但我仍然不肯放下。”
本质剖析:
核心洞察:
“在做之前就赋予意义的,叫预设意义,或本质先于存在。”
本质剖析:
核心洞察:
“你一直在做计划,但不去执行;你在空想如何解决问题,但不落地解决。”
本质剖析:
核心洞察:
“你只敢撞一次南墙,你不敢撞第二次。你分不清哪些是小石子,哪些是真正的南墙。”
本质剖析:
核心洞察:
“事情的意义大多是做完之后被赋予的。在做之前就赋予意义的,叫预设意义。”
本质剖析:
核心洞察:
“我只需要 Do and Done 就行了。”
本质剖析:
核心洞察:
“接着走下去,带着疑惑,接着走下去。生命会自己找出出路。”
本质剖析:
核心洞察:
“每一个人拿着手机,都像一座无形的牢笼,把彼此隔开了。我觉得我是一个内部极大丰富的人,但是没有人能理解我。”
本质剖析:
核心洞察:
“遗憾只是被证实了,现在遗憾就是遗憾了。你已经无法做到遗憾的事情,那你就不用担心那么多了。”
本质剖析:
核心洞察:
“风吹过我的指尖,风吹过我的脸颊,风吹过我的发梢,好凉快,好舒服。但是感受过后呢,我确确实实的活着,但我活着我干嘛呢?”
本质剖析:
2026年3月12日,一滴眼泪都没有,只是觉得有点冷”
It’s a funny thing about life; if you refuse to accept anything but the best, you very often get it.
生活的讽刺之处在于:如果你只接受最好的,你经常会得到最好的。

今天是昨天的明天
写了个轻量级个人知识库系统,融合了笔记、时间追踪、关系图谱和日历视图。它支持类 Obsidian 的 [[@页面链接]] 和 [[标签]] 语法,内置待办清单、提醒组件和 Markdown 渲染。
Notiobsidian(Nobsidian)作为开源版本
🌐 Notiobsidian
把 Notion 的交互美学 + Obsidian 的本地自由 + AI Agent 原生接口 揉在一起
一个完全自托管、可编程、跑在你电脑上的个人第二大脑(目前已是我本人的主力生产力工具)
.png)
.png)
.png)
.png)
git clone https://github.com/NanamiChiaki-7/Notiobsidian.git
cd NotiobsidianBash pip install -r requirements.txtBash python Notiobsidian.pyBash→ 默认监听 http://0.0.0.0:5004
生产建议:
--host 0.0.0.0 --port 你的端口 或用 gunicorn / uvicorn 部署nation_pro_v3.db(SQLite),记得定期备份!欢迎 PR 加速这些功能!
欢迎 issue、PR、想法!
喜欢就点个 ⭐ 支持一下~
Last updated: February 2026 · 最后更新:2026年2月
Freedom is nothing but a chance to be better.
自由不过是一个变得更好的机会。
静态资源请求被错误地当成了动态路由处理,导致路径被二次编码。
你的预期:
浏览器请求 /LifeDrive/static/css/style.css
→ Nginx 静态 location
→ 直接读硬盘文件 ✅
实际发生:
浏览器请求 /LifeDrive/static/css/style.css
→ Nginx 无静态 location(或被覆盖)
→ 转发给 Flask 代理
→ Flask 的 ReverseProxied 剥离 /LifeDrive
→ Flask 收到 /static/css/style.css
→ Flask 把它当作路由去找 @app.route('/static/...')
→ 找不到,返回 404 ❌
^~ /Project/static/ 没写alias 路径错误/少斜杠 <!-- 这会让静态请求也经过 Flask 路由系统 -->
<link href="{{ url_for('static', filename='css/style.css') }}">
url_for('static') → 生成 /LifeDrive/static/css/style.css → 同上死循环
| 方案 | 静态文件处理 | 动态路由 | HTML写法 | 适用场景 |
|---|---|---|---|---|
| ❌ 全代理 | Flask处理 | Flask处理 | url_for | 单项目,无Nginx静态 |
| ✅ 组合拳 | Nginx直出 | Flask处理 | 写死路径 | 多项目同域名,性能最优 |
| ⚠️ 全直出 | Nginx直出 | Nginx直出 | 写死路径 | 纯静态站 |
你最终选的是「组合拳」——工业标准做法。
# ✅ 正确顺序
location ^~ /Project/static/ { ... } # 1. 精确匹配优先
location /Project/ { ... } # 2. 模糊匹配在后
<!-- ✅ 静态资源:直接写死,不走 Flask -->
<link href="/Project/static/css/style.css">
<!-- ✅ 动态链接:用 url_for,自动加前缀 -->
<a href="{{ url_for('view_page', id=1) }}">
# ✅ 只有 Flask 需要知道
export BASE_PATH=/Project
# ❌ Nginx 静态 location 完全不需要
# alias 直接写绝对路径即可
^~ /项目名/static/)/项目名/)/项目名/static/xxxexport BASE_PATH=/项目名问题发现:浏览器控制台 404
定位过程:curl → Nginx 404 → 检查 alias → 发现少斜杠
深层原因:发现静态请求进了 Flask
解决方案:Nginx 静态直出 + HTML写死路径
最终验证:静态文件 200,动态页面 200,完美
耗时:一下午
收获:多项目反代的标准模式固化
^~(被正则覆盖)staticcss 经典错误)url_for(本末倒置)这次 BUG 修完,你已经是 Nginx + Flask 多项目部署的专家了。
这套组合拳可以复用到以后所有项目,不会再卡一下午了。
But man is not made for defeat. A man can be destroyed but not defeated.
人不是为失败而生的。一个人可以被毁灭,但不能被打败。
*当初为了项目反代问题处理一下午,今天又处理一下午,要吸取教训了*

我常常想的太多 做的太少 太多想法没得到记录 太多想法没得到事实践 那么这种思考本身就是种逃避 我希望LifeDrive能将我那些天马行空的空中楼阁般的想法托举到地上 虽然这些楼阁大抵是云做的虚无缥缈且摇摇欲坠 我将为我的想法接生 这是就是我对LifeDrive的寄语
*该图为我生日时NASA每日一图 是猫爪星云!