commit 1fd4c94097c9f910e881b8397b2809a295448722 Author: gz Date: Fri May 29 09:40:07 2026 +0800 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/__pycache__/chat.cpython-312.pyc b/__pycache__/chat.cpython-312.pyc new file mode 100644 index 0000000..17799fe Binary files /dev/null and b/__pycache__/chat.cpython-312.pyc differ diff --git a/__pycache__/chat.cpython-38.pyc b/__pycache__/chat.cpython-38.pyc new file mode 100644 index 0000000..c56ff1f Binary files /dev/null and b/__pycache__/chat.cpython-38.pyc differ diff --git a/backups/chat_history_20260522_143254.txt b/backups/chat_history_20260522_143254.txt new file mode 100644 index 0000000..deb880d --- /dev/null +++ b/backups/chat_history_20260522_143254.txt @@ -0,0 +1,99 @@ +[2026-05-22 12:59:36] SYSTEM::zgz 加入聊天室 +[2026-05-22 12:59:38] SYSTEM::gz 加入聊天室 +[2026-05-22 13:00:32] SYSTEM::gz 离开聊天室 +[2026-05-22 13:00:32] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:00:36] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:00:37] SYSTEM::gz 加入聊天室 +[2026-05-22 13:01:06] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:01:09] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:01:15] TEXT::zgz::?试一下 +[2026-05-22 13:01:18] TEXT::zgz::???? +[2026-05-22 13:01:27] TEXT::zgz::123123123123、 +[2026-05-22 13:05:09] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:05:09] SYSTEM::gz 离开聊天室 +[2026-05-22 13:05:14] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:05:14] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:05:18] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:05:21] SYSTEM::gz 加入聊天室 +[2026-05-22 13:12:59] SYSTEM::gz 离开聊天室 +[2026-05-22 13:12:59] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:13:04] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:13:05] SYSTEM::gz 加入聊天室 +[2026-05-22 13:16:58] SYSTEM::gz 离开聊天室 +[2026-05-22 13:16:58] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:17:03] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:17:04] SYSTEM::gz 加入聊天室 +[2026-05-22 13:18:06] SYSTEM::gz 离开聊天室 +[2026-05-22 13:18:06] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:18:12] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:18:14] SYSTEM::gz 加入聊天室 +[2026-05-22 13:19:14] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:19:17] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:19:18] TEXT::zgz::? +[2026-05-22 13:19:23] TEXT::zgz::你好 +[2026-05-22 13:19:26] TEXT::zgz::你好 +[2026-05-22 13:19:27] TEXT::zgz::显示 +[2026-05-22 13:19:31] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:19:33] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:19:35] TEXT::zgz::你好 +[2026-05-22 13:20:14] TEXT::zgz::??? +[2026-05-22 13:20:19] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:20:21] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:20:22] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:20:27] SYSTEM::gz 离开聊天室 +[2026-05-22 13:20:30] SYSTEM::gz 加入聊天室 +[2026-05-22 13:20:35] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:20:45] TEXT::gz::你好 +[2026-05-22 13:20:48] TEXT::gz::??? +[2026-05-22 13:20:55] TEXT::zgz::???? +[2026-05-22 13:28:15] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:28:18] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:28:19] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:28:21] SYSTEM::zgz 加入聊天室 +[2026-05-22 13:30:49] SYSTEM::zgz 离开聊天室 +[2026-05-22 13:30:49] SYSTEM::gz 离开聊天室 +[2026-05-22 14:04:27] SYSTEM::gz 加入聊天室 +[2026-05-22 14:04:31] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:04:32] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:04:34] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:04:37] TEXT::zgz::123 +[2026-05-22 14:04:38] TEXT::zgz::123 +[2026-05-22 14:04:38] TEXT::zgz::12 +[2026-05-22 14:04:38] TEXT::zgz::3 +[2026-05-22 14:04:38] TEXT::zgz::21 +[2026-05-22 14:04:38] TEXT::zgz::321 +[2026-05-22 14:04:39] TEXT::zgz::31 +[2026-05-22 14:04:41] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:04:43] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:04:52] TEXT::zgz::12313 +[2026-05-22 14:04:54] TEXT::zgz::1111 +[2026-05-22 14:11:15] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:11:17] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:11:19] TEXT::zgz::123 +[2026-05-22 14:11:20] TEXT::zgz::123 +[2026-05-22 14:11:22] TEXT::zgz::qwe +[2026-05-22 14:11:22] TEXT::zgz::qwe +[2026-05-22 14:11:25] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:11:27] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:12:30] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:12:30] SYSTEM::gz 离开聊天室 +[2026-05-22 14:13:41] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:13:42] SYSTEM::gz 加入聊天室 +[2026-05-22 14:13:55] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:13:58] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:13:58] TEXT::zgz::1111 +[2026-05-22 14:13:59] TEXT::zgz::2222 +[2026-05-22 14:14:00] TEXT::zgz::3333 +[2026-05-22 14:14:01] TEXT::zgz::444 +[2026-05-22 14:14:03] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:14:05] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:30:26] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:30:26] SYSTEM::gz 离开聊天室 +[2026-05-22 14:30:31] SYSTEM::gz 加入聊天室 +[2026-05-22 14:30:31] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:32:44] SYSTEM::测试机器人 加入聊天室 +[2026-05-22 14:32:44] TEXT::测试机器人::你好世界 +[2026-05-22 14:32:44] SYSTEM::匿名用户 离开聊天室 +[2026-05-22 14:32:48] SYSTEM::测试机器人2 加入聊天室 +[2026-05-22 14:32:48] TEXT::测试机器人2::这是一条实时测试消息! +[2026-05-22 14:32:48] SYSTEM::测试机器人2 离开聊天室 diff --git a/backups/chat_history_20260522_143305.txt b/backups/chat_history_20260522_143305.txt new file mode 100644 index 0000000..256b941 --- /dev/null +++ b/backups/chat_history_20260522_143305.txt @@ -0,0 +1,2 @@ +[2026-05-22 14:32:59] SYSTEM::nginx测试 加入聊天室 +[2026-05-22 14:32:59] SYSTEM::nginx测试 离开聊天室 diff --git a/backups/chat_history_20260523_030001.txt b/backups/chat_history_20260523_030001.txt new file mode 100644 index 0000000..80dcf48 --- /dev/null +++ b/backups/chat_history_20260523_030001.txt @@ -0,0 +1,131 @@ +[2026-05-22 14:36:47] SYSTEM::gz 离开聊天室 +[2026-05-22 14:36:50] SYSTEM::gz 加入聊天室 +[2026-05-22 14:36:54] TEXT::gz::测试一下 +[2026-05-22 14:36:58] TEXT::gz::发送聊天记录 +[2026-05-22 14:37:19] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:37:21] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:37:25] TEXT::zgz::可以,还不错 +[2026-05-22 14:37:28] TEXT::zgz::哪里 +[2026-05-22 14:37:33] TEXT::zgz::什么啊 +[2026-05-22 14:37:47] TEXT::gz::你是谁 +[2026-05-22 14:40:58] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:41:00] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:41:09] TEXT::zgz::你好 +[2026-05-22 14:41:12] TEXT::zgz::什么 +[2026-05-22 14:41:15] TEXT::zgz::这是哪里的消息. +[2026-05-22 14:41:22] TEXT::zgz::可以啊 +[2026-05-22 14:41:57] TEXT::zgz::刚刚发送了图片,是不是没显示成功 +[2026-05-22 14:42:12] TEXT::zgz::还是说文件太大了 +[2026-05-22 14:43:47] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:43:47] SYSTEM::gz 离开聊天室 +[2026-05-22 14:43:57] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:43:57] SYSTEM::gz 加入聊天室 +[2026-05-22 14:44:00] SYSTEM::gz 离开聊天室 +[2026-05-22 14:44:00] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:44:05] SYSTEM::gz 加入聊天室 +[2026-05-22 14:44:05] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:44:47] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:44:49] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:45:15] TEXT::zgz::还没有成功? +[2026-05-22 14:47:35] SYSTEM::gz 离开聊天室 +[2026-05-22 14:47:37] SYSTEM::gz 加入聊天室 +[2026-05-22 14:47:41] TEXT::gz::我再试一下 +[2026-05-22 14:48:22] TEXT::gz::? +[2026-05-22 14:48:43] SYSTEM::gz 离开聊天室 +[2026-05-22 14:48:46] SYSTEM::gz 加入聊天室 +[2026-05-22 14:53:04] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:53:04] SYSTEM::gz 离开聊天室 +[2026-05-22 14:53:09] SYSTEM::gz 加入聊天室 +[2026-05-22 14:53:10] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:53:10] SYSTEM::gz 离开聊天室 +[2026-05-22 14:53:10] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:53:15] SYSTEM::gz 加入聊天室 +[2026-05-22 14:53:15] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:53:25] SYSTEM::测试用户 加入聊天室 +[2026-05-22 14:53:25] SYSTEM::测试用户 离开聊天室 +[2026-05-22 14:53:41] SYSTEM::gz 离开聊天室 +[2026-05-22 14:53:45] SYSTEM::gz 加入聊天室 +[2026-05-22 14:53:49] TEXT::gz::123 +[2026-05-22 14:54:12] TEXT::gz::这次真可以了. +[2026-05-22 14:56:29] SYSTEM::怀旧用户 加入聊天室 +[2026-05-22 14:56:29] TEXT::怀旧用户::你好,老聊天室的感觉! +[2026-05-22 14:56:29] SYSTEM::怀旧用户 离开聊天室 +[2026-05-22 14:56:57] SYSTEM::gz 离开聊天室 +[2026-05-22 14:57:00] SYSTEM::gz 加入聊天室 +[2026-05-22 14:57:15] TEXT::gz::你好 +[2026-05-22 14:57:22] TEXT::gz::测试一下 +[2026-05-22 14:57:39] SYSTEM::zgz 离开聊天室 +[2026-05-22 14:57:41] SYSTEM::zgz 加入聊天室 +[2026-05-22 14:57:43] TEXT::zgz::还可以啊 +[2026-05-22 14:57:56] TEXT::zgz::继续 +[2026-05-22 14:57:59] TEXT::zgz::测试 +[2026-05-22 14:59:09] SYSTEM::ts 加入聊天室 +[2026-05-22 14:59:32] TEXT::ts::什么? +[2026-05-22 14:59:46] TEXT::ts::东东 +[2026-05-22 15:00:22] SYSTEM::ts 离开聊天室 +[2026-05-22 15:03:16] SYSTEM::TG用户 加入聊天室 +[2026-05-22 15:03:16] TEXT::TG用户::Telegram风格测试 +[2026-05-22 15:03:16] SYSTEM::TG用户 离开聊天室 +[2026-05-22 15:03:32] SYSTEM::zgz 离开聊天室 +[2026-05-22 15:03:35] SYSTEM::zgz 加入聊天室 +[2026-05-22 15:09:15] SYSTEM::设计测试 加入聊天室 +[2026-05-22 15:09:15] TEXT::设计测试::对齐布局测试 +[2026-05-22 15:09:15] SYSTEM::设计测试 离开聊天室 +[2026-05-22 15:09:52] SYSTEM::gz 离开聊天室 +[2026-05-22 15:09:54] SYSTEM::gz 加入聊天室 +[2026-05-22 15:12:39] TEXT::gz::这是 +[2026-05-22 15:12:44] TEXT::gz::什么内容. +[2026-05-22 15:14:58] SYSTEM::群聊测试 加入聊天室 +[2026-05-22 15:14:58] TEXT::群聊测试::所有人都在左侧 +[2026-05-22 15:14:58] SYSTEM::群聊测试 离开聊天室 +[2026-05-22 15:15:41] SYSTEM::gz 离开聊天室 +[2026-05-22 15:15:44] SYSTEM::gz 加入聊天室 +[2026-05-22 15:15:49] TEXT::gz::这能区分出来哪个是我吗 +[2026-05-22 15:15:53] TEXT::gz::哦 +[2026-05-22 15:15:56] TEXT::gz::好像可以 +[2026-05-22 15:16:07] SYSTEM::zgz 离开聊天室 +[2026-05-22 15:16:09] SYSTEM::zgz 加入聊天室 +[2026-05-22 15:16:10] TEXT::zgz::试一下 +[2026-05-22 15:16:12] TEXT::zgz::这个是我 +[2026-05-22 15:16:22] SYSTEM::zgz 离开聊天室 +[2026-05-22 15:16:27] SYSTEM::gz 离开聊天室 +[2026-05-22 15:16:29] SYSTEM::gz 加入聊天室 +[2026-05-22 15:16:43] TEXT::gz::好玩的. +[2026-05-22 15:16:47] TEXT::gz::test +[2026-05-22 15:16:47] TEXT::gz::test +[2026-05-22 15:20:08] SYSTEM::无痕测试 加入聊天室 +[2026-05-22 15:20:08] TEXT::无痕测试::退出重进就看不见了 +[2026-05-22 15:20:08] SYSTEM::无痕测试 离开聊天室 +[2026-05-22 15:20:35] SYSTEM::gz 离开聊天室 +[2026-05-22 15:20:37] SYSTEM::gz 加入聊天室 +[2026-05-22 15:20:51] TEXT::gz::你好,这是一条新的消息. +[2026-05-22 15:20:56] TEXT::gz::开始测试. +[2026-05-22 15:21:08] SYSTEM::gz 加入聊天室 +[2026-05-22 15:21:13] SYSTEM::gz 离开聊天室 +[2026-05-22 15:21:28] SYSTEM::ts 加入聊天室 +[2026-05-22 15:21:36] TEXT::ts::hello +[2026-05-22 15:21:36] TEXT::ts::hello +[2026-05-22 15:21:40] TEXT::ts::可以吗 +[2026-05-22 15:21:43] TEXT::ts::历史 +[2026-05-22 15:22:03] SYSTEM::ts 离开聊天室 +[2026-05-22 15:22:25] TEXT::gz::退出再进消息就没了 +[2026-05-22 16:47:10] SYSTEM::ts 加入聊天室 +[2026-05-22 16:47:11] SYSTEM::ts 离开聊天室 +[2026-05-22 16:47:13] SYSTEM::ts 加入聊天室 +[2026-05-22 16:49:26] SYSTEM::ts 离开聊天室 +[2026-05-22 17:59:32] SYSTEM::gz 离开聊天室 +[2026-05-22 17:59:37] SYSTEM::gz 加入聊天室 +[2026-05-22 18:00:16] SYSTEM::gz 离开聊天室 +[2026-05-22 18:01:20] SYSTEM::gz 加入聊天室 +[2026-05-22 18:02:20] SYSTEM::gz 离开聊天室 +[2026-05-22 18:18:47] SYSTEM::gz 加入聊天室 +[2026-05-22 18:22:10] SYSTEM::gz 离开聊天室 +[2026-05-22 18:38:35] SYSTEM::gz 加入聊天室 +[2026-05-22 18:40:16] SYSTEM::gz 离开聊天室 +[2026-05-22 18:57:14] SYSTEM::gz 加入聊天室 +[2026-05-22 21:05:21] SYSTEM::gz 离开聊天室 +[2026-05-22 21:05:26] SYSTEM::gz 加入聊天室 +[2026-05-22 23:10:35] SYSTEM::gz 离开聊天室 +[2026-05-22 23:15:01] SYSTEM::gz 加入聊天室 +[2026-05-22 23:22:08] SYSTEM::gz 离开聊天室 +[2026-05-22 23:26:34] SYSTEM::gz 加入聊天室 diff --git a/backups/chat_history_20260524_030001.txt b/backups/chat_history_20260524_030001.txt new file mode 100644 index 0000000..ba34c08 --- /dev/null +++ b/backups/chat_history_20260524_030001.txt @@ -0,0 +1,8 @@ +[2026-05-23 03:00:06] SYSTEM::gz 离开聊天室 +[2026-05-23 03:01:10] SYSTEM::gz 加入聊天室 +[2026-05-23 09:16:55] SYSTEM::gz 离开聊天室 +[2026-05-23 09:24:58] SYSTEM::gz 加入聊天室 +[2026-05-23 13:21:44] SYSTEM::gz 离开聊天室 +[2026-05-23 13:26:48] SYSTEM::gz 加入聊天室 +[2026-05-23 16:47:08] SYSTEM::gz 离开聊天室 +[2026-05-23 16:47:13] SYSTEM::gz 加入聊天室 diff --git a/backups/chat_history_20260525_030001.txt b/backups/chat_history_20260525_030001.txt new file mode 100644 index 0000000..74c9bf4 --- /dev/null +++ b/backups/chat_history_20260525_030001.txt @@ -0,0 +1,6 @@ +[2026-05-24 03:00:06] SYSTEM::gz 离开聊天室 +[2026-05-24 03:01:11] SYSTEM::gz 加入聊天室 +[2026-05-24 21:55:39] SYSTEM::gz 离开聊天室 +[2026-05-24 22:00:06] SYSTEM::gz 加入聊天室 +[2026-05-24 22:02:28] SYSTEM::gz 离开聊天室 +[2026-05-24 22:07:18] SYSTEM::gz 加入聊天室 diff --git a/backups/chat_history_20260526_030001.txt b/backups/chat_history_20260526_030001.txt new file mode 100644 index 0000000..3259e53 --- /dev/null +++ b/backups/chat_history_20260526_030001.txt @@ -0,0 +1,20 @@ +[2026-05-25 03:00:06] SYSTEM::gz 离开聊天室 +[2026-05-25 03:01:14] SYSTEM::gz 加入聊天室 +[2026-05-25 09:18:50] SYSTEM::gz 离开聊天室 +[2026-05-25 09:21:12] SYSTEM::gz 加入聊天室 +[2026-05-25 13:31:34] SYSTEM::gz 离开聊天室 +[2026-05-25 13:38:33] SYSTEM::gz 加入聊天室 +[2026-05-25 14:30:06] SYSTEM::gz 加入聊天室 +[2026-05-25 14:31:56] SYSTEM::匿名6524 加入聊天室 +[2026-05-25 14:32:07] SYSTEM::匿名6524 离开聊天室 +[2026-05-25 14:35:01] SYSTEM::gz 离开聊天室 +[2026-05-25 14:35:40] SYSTEM::gz 离开聊天室 +[2026-05-25 14:35:41] SYSTEM::gz 加入聊天室 +[2026-05-25 14:35:53] SYSTEM::zgz 加入聊天室 +[2026-05-25 14:35:55] SYSTEM::zgz 离开聊天室 +[2026-05-25 18:12:17] SYSTEM::gz 离开聊天室 +[2026-05-25 18:12:20] SYSTEM::gz 加入聊天室 +[2026-05-25 18:12:22] SYSTEM::gz 离开聊天室 +[2026-05-25 18:12:24] SYSTEM::gz 加入聊天室 +[2026-05-25 18:13:04] SYSTEM::gz 离开聊天室 +[2026-05-25 18:32:44] SYSTEM::gz 加入聊天室 diff --git a/backups/chat_history_20260527_030001.txt b/backups/chat_history_20260527_030001.txt new file mode 100644 index 0000000..362f637 --- /dev/null +++ b/backups/chat_history_20260527_030001.txt @@ -0,0 +1,26 @@ +[2026-05-26 03:00:06] SYSTEM::gz 离开聊天室 +[2026-05-26 03:02:58] SYSTEM::gz 加入聊天室 +[2026-05-26 04:00:38] SYSTEM::gz 离开聊天室 +[2026-05-26 04:05:03] SYSTEM::gz 加入聊天室 +[2026-05-26 09:00:25] SYSTEM::gz 离开聊天室 +[2026-05-26 09:01:05] SYSTEM::gz 加入聊天室 +[2026-05-26 18:04:52] SYSTEM::gz 离开聊天室 +[2026-05-26 18:04:55] SYSTEM::gz 加入聊天室 +[2026-05-26 18:05:35] SYSTEM::gz 离开聊天室 +[2026-05-26 18:20:09] SYSTEM::gz 加入聊天室 +[2026-05-26 18:24:00] SYSTEM::gz 离开聊天室 +[2026-05-26 18:40:12] SYSTEM::gz 加入聊天室 +[2026-05-26 19:47:40] SYSTEM::gz 离开聊天室 +[2026-05-26 20:04:10] SYSTEM::gz 加入聊天室 +[2026-05-26 20:08:33] SYSTEM::gz 离开聊天室 +[2026-05-26 20:25:13] SYSTEM::gz 加入聊天室 +[2026-05-26 20:26:53] SYSTEM::gz 离开聊天室 +[2026-05-26 20:41:49] SYSTEM::gz 加入聊天室 +[2026-05-26 20:52:57] SYSTEM::gz 离开聊天室 +[2026-05-26 21:09:09] SYSTEM::gz 加入聊天室 +[2026-05-26 21:11:10] SYSTEM::gz 离开聊天室 +[2026-05-26 21:26:00] SYSTEM::gz 加入聊天室 +[2026-05-26 21:27:20] SYSTEM::gz 离开聊天室 +[2026-05-26 21:44:19] SYSTEM::gz 加入聊天室 +[2026-05-26 21:45:39] SYSTEM::gz 离开聊天室 +[2026-05-26 22:00:53] SYSTEM::gz 加入聊天室 diff --git a/backups/chat_history_20260528_030001.txt b/backups/chat_history_20260528_030001.txt new file mode 100644 index 0000000..fb5710e --- /dev/null +++ b/backups/chat_history_20260528_030001.txt @@ -0,0 +1,39 @@ +[2026-05-27 03:00:06] SYSTEM::gz 离开聊天室 +[2026-05-27 03:01:45] SYSTEM::gz 加入聊天室 +[2026-05-27 04:00:25] SYSTEM::gz 离开聊天室 +[2026-05-27 04:04:50] SYSTEM::gz 加入聊天室 +[2026-05-27 07:59:08] SYSTEM::gz 离开聊天室 +[2026-05-27 08:18:30] SYSTEM::gz 加入聊天室 +[2026-05-27 08:20:11] SYSTEM::gz 离开聊天室 +[2026-05-27 08:36:08] SYSTEM::gz 加入聊天室 +[2026-05-27 08:42:13] SYSTEM::gz 离开聊天室 +[2026-05-27 08:42:14] SYSTEM::gz 加入聊天室 +[2026-05-27 08:42:42] SYSTEM::张卫贤 加入聊天室 +[2026-05-27 08:42:45] TEXT::张卫贤::1 +[2026-05-27 08:42:47] SYSTEM::匿名9712 加入聊天室 +[2026-05-27 08:42:48] TEXT::gz::? +[2026-05-27 08:42:49] SYSTEM::匿名9712 离开聊天室 +[2026-05-27 08:42:54] SYSTEM::gz 离开聊天室 +[2026-05-27 08:42:56] SYSTEM::gz 加入聊天室 +[2026-05-27 08:42:59] TEXT::gz::哈 +[2026-05-27 08:45:15] SYSTEM::匿名6572 加入聊天室 +[2026-05-27 08:45:17] SYSTEM::匿名6572 离开聊天室 +[2026-05-27 08:46:16] SYSTEM::张卫贤 加入聊天室 +[2026-05-27 08:46:31] SYSTEM::张卫贤 离开聊天室 +[2026-05-27 08:56:47] SYSTEM::张卫贤 离开聊天室 +[2026-05-27 10:15:46] SYSTEM::匿名3899 加入聊天室 +[2026-05-27 10:15:47] SYSTEM::匿名3899 离开聊天室 +[2026-05-27 16:18:34] SYSTEM::gz 离开聊天室 +[2026-05-27 16:18:44] SYSTEM::gz 加入聊天室 +[2026-05-27 18:01:59] SYSTEM::gz 离开聊天室 +[2026-05-27 18:02:02] SYSTEM::gz 加入聊天室 +[2026-05-27 18:02:41] SYSTEM::gz 离开聊天室 +[2026-05-27 18:17:23] SYSTEM::gz 加入聊天室 +[2026-05-27 18:18:43] SYSTEM::gz 离开聊天室 +[2026-05-27 18:34:51] SYSTEM::gz 加入聊天室 +[2026-05-27 20:32:01] SYSTEM::gz 离开聊天室 +[2026-05-27 20:42:44] SYSTEM::gz 加入聊天室 +[2026-05-27 23:06:33] SYSTEM::gz 离开聊天室 +[2026-05-27 23:06:39] SYSTEM::gz 加入聊天室 +[2026-05-27 23:44:03] SYSTEM::gz 加入聊天室 +[2026-05-27 23:44:19] SYSTEM::gz 离开聊天室 diff --git a/backups/chat_history_20260529_030001.txt b/backups/chat_history_20260529_030001.txt new file mode 100644 index 0000000..4fd4f75 --- /dev/null +++ b/backups/chat_history_20260529_030001.txt @@ -0,0 +1,21 @@ +[2026-05-28 03:00:06] SYSTEM::gz 离开聊天室 +[2026-05-28 03:01:42] SYSTEM::gz 加入聊天室 +[2026-05-28 11:15:18] SYSTEM::gz 离开聊天室 +[2026-05-28 11:18:26] SYSTEM::gz 加入聊天室 +[2026-05-28 11:32:23] SYSTEM::gz 离开聊天室 +[2026-05-28 11:34:51] SYSTEM::gz 加入聊天室 +[2026-05-28 11:37:14] SYSTEM::gz 离开聊天室 +[2026-05-28 11:37:18] SYSTEM::gz 加入聊天室 +[2026-05-28 12:42:05] SYSTEM::gz 离开聊天室 +[2026-05-28 12:42:09] SYSTEM::gz 加入聊天室 +[2026-05-28 13:08:21] SYSTEM::gz 离开聊天室 +[2026-05-28 13:09:56] SYSTEM::gz 加入聊天室 +[2026-05-28 13:14:47] SYSTEM::gz 离开聊天室 +[2026-05-28 13:14:51] SYSTEM::gz 加入聊天室 +[2026-05-28 14:04:28] SYSTEM::ts 加入聊天室 +[2026-05-28 14:05:34] SYSTEM::ts 离开聊天室 +[2026-05-28 14:14:02] SYSTEM::ts 加入聊天室 +[2026-05-28 14:17:20] SYSTEM::ts 离开聊天室 +[2026-05-28 14:20:23] SYSTEM::gz 离开聊天室 +[2026-05-28 14:48:35] SYSTEM::ts 加入聊天室 +[2026-05-28 14:50:54] SYSTEM::ts 离开聊天室 diff --git a/chat.py b/chat.py new file mode 100644 index 0000000..f1b430d --- /dev/null +++ b/chat.py @@ -0,0 +1,300 @@ +""" +ChatHub - 实时聊天室 +FastAPI + WebSocket +""" +from fastapi import FastAPI, WebSocket, WebSocketDisconnect, UploadFile, File, Form, Request +from fastapi.responses import HTMLResponse, JSONResponse +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates +from typing import List, Dict, Tuple +import os +import uuid +import json +import asyncio +import shutil +import time +import collections +from datetime import datetime + +app = FastAPI() + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +TEMPLATE_DIR = os.path.join(BASE_DIR, "templates") +UPLOAD_DIR = os.path.join(BASE_DIR, "uploads") +BACKUP_DIR = os.path.join(BASE_DIR, "backups") +os.makedirs(UPLOAD_DIR, exist_ok=True) +os.makedirs(BACKUP_DIR, exist_ok=True) + +CHAT_LOG_FILE = os.path.join(BASE_DIR, "chat_history.txt") +MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB per file + +ALLOWED_IMAGE_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "bmp", "tiff", "webp", "heic"} +ALLOWED_VIDEO_EXTENSIONS = {"mp4", "mov", "wmv", "avi", "m4v", "mpg", "mpeg", "flv", "mkv", "3gp", "webm"} + +templates = Jinja2Templates(directory=TEMPLATE_DIR) +app.mount("/uploads", StaticFiles(directory=UPLOAD_DIR), name="uploads") + +# ── Global State ──────────────────────────────────────────── +connections: Dict[WebSocket, str] = {} # ws -> username +glock = asyncio.Lock() + +# ── Rate Limiting ───────────────────────────────────────── +# Upload rate limit: {ip: [timestamp, ...]} +upload_history: Dict[str, List[float]] = {} +UPLOAD_COOLDOWN = 3.0 # seconds between uploads + +# Message rate limit: per-connection message timestamps +msg_history: Dict[WebSocket, List[float]] = {} +MSG_BURST = 8 # max messages +MSG_WINDOW = 3.0 # per this many seconds + + +def get_ext(fn: str) -> str: + return fn.rsplit(".", 1)[-1].lower() + + +def is_image(ext: str) -> bool: + return ext in ALLOWED_IMAGE_EXTENSIONS + + +def is_video(ext: str) -> bool: + return ext in ALLOWED_VIDEO_EXTENSIONS + + +def log_to_file(msg: str): + ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + try: + with open(CHAT_LOG_FILE, "a", encoding="utf-8") as f: + f.write(f"[{ts}] {msg}\n") + except Exception: + pass + + +def load_recent_history(n: int = 200) -> List[str]: + if not os.path.exists(CHAT_LOG_FILE): + return [] + try: + with open(CHAT_LOG_FILE, "r", encoding="utf-8") as f: + lines = f.readlines() + return [l.strip() for l in lines[-n:]] + except Exception: + return [] + + +# ── HTTP Endpoints ────────────────────────────────────────── + +@app.get("/", response_class=HTMLResponse) +async def index(request: Request): + history = load_recent_history(200) + return templates.TemplateResponse("chat.html", {"request": request, "history": history}) + + +@app.get("/members") +async def get_members(): + """Return current online member list.""" + async with glock: + names = list(connections.values()) + return JSONResponse({"members": names}) + + +# ── Rate Limiter Helpers ──────────────────────────────── + +async def _check_upload_rate(request: Request) -> Tuple[bool, str]: + """Check upload rate limit per client IP. + Returns (allowed, reason). + """ + ip = request.client.host if request.client else "unknown" + now = time.time() + + async with glock: + times = upload_history.get(ip, []) + # Clean old entries + times = [t for t in times if now - t < UPLOAD_COOLDOWN] + if times: + remaining = int(UPLOAD_COOLDOWN - (now - times[-1])) + return False, f"上传太频繁,请 {remaining} 秒后再试" + times.append(now) + upload_history[ip] = times + return True, "" + + +async def _check_msg_rate(ws: WebSocket) -> bool: + """Check message send rate per WebSocket connection.""" + now = time.time() + async with glock: + times = msg_history.get(ws, []) + times = [t for t in times if now - t < MSG_WINDOW] + if len(times) >= MSG_BURST: + return False + times.append(now) + msg_history[ws] = times + return True + + +# ── HTTP Endpoints ────────────────────────────────────────── + +@app.get("/", response_class=HTMLResponse) +async def index(request: Request): + history = load_recent_history(200) + return templates.TemplateResponse("chat.html", {"request": request, "history": history}) + + +@app.get("/members") +async def get_members(): + """Return current online member list.""" + async with glock: + names = list(connections.values()) + return JSONResponse({"members": names}) + + +@app.post("/upload") +async def upload_file(file: UploadFile = File(...), request: Request = None, sender: str = Form("匿名")): + # Rate limit check + allowed, reason = await _check_upload_rate(request) + if not allowed: + return JSONResponse({"error": reason}, status_code=429) + + # File type check + ext = get_ext(file.filename) + if not (is_image(ext) or is_video(ext)): + return JSONResponse({"error": "不支持的文件类型,仅接受图片和视频"}, status_code=400) + + # Read and check size + data = await file.read() + if len(data) > MAX_FILE_SIZE: + size_mb = len(data) / (1024 * 1024) + return JSONResponse({ + "error": f"文件过大({size_mb:.1f}MB),最大允许 10MB" + }, status_code=413) + + # Save and broadcast + fn = f"{uuid.uuid4().hex}.{ext}" + path = os.path.join(UPLOAD_DIR, fn) + with open(path, "wb") as f: + f.write(data) + url = f"/uploads/{fn}" + # Format: TYPE::sender::url — frontend parses two colons + msg = f"IMG::{sender}::{url}" if is_image(ext) else f"VIDEO::{sender}::{url}" + asyncio.create_task(_broadcast(msg)) + return {"url": url} + + +# ── Broadcast ─────────────────────────────────────────────── + +async def _broadcast(message: str): + """Send message to all connected clients. + Uses snapshot-then-send pattern: grab targets under lock, then send concurrently without lock. + """ + async with glock: + targets = list(connections.items()) # [(ws, name), ...] + + tasks = [] + for ws, _ in targets: + tasks.append(_safe_send(ws, message)) + if tasks: + await asyncio.gather(*tasks, return_exceptions=True) + + +async def _safe_send(ws: WebSocket, message: str): + """Send text to one WebSocket, remove on failure.""" + try: + await ws.send_text(message) + except Exception: + async with glock: + connections.pop(ws, None) + + +async def _broadcast_members(): + """Broadcast JSON member list and count to all clients.""" + async with glock: + names = list(connections.values()) + count = len(names) + payload = json.dumps({"type": "members", "data": names}) + await _broadcast(f"MEMBERS::{payload}") + await _broadcast(f"COUNT::{count}") + + +# ── WebSocket Endpoint ────────────────────────────────────── + +@app.websocket("/wschat") +async def ws_endpoint(ws: WebSocket): + await ws.accept() + + # ── 1) Receive username as first text frame ── + try: + raw = await asyncio.wait_for(ws.receive_text(), timeout=30) + except Exception: + await ws.close(1008) + return + + username = (raw.strip() or f"匿名{id(ws) % 10000}")[:20] + + async with glock: + connections[ws] = username + + join_msg = f"SYSTEM::{username} 加入聊天室" + log_to_file(join_msg) + asyncio.create_task(_broadcast(join_msg)) + asyncio.create_task(_broadcast_members()) + + # ── 2) Message loop ── + try: + while True: + text = await ws.receive_text() + if not text or not text.strip(): + continue + # Rate limit check + if not await _check_msg_rate(ws): + asyncio.create_task(_safe_send(ws, "SYSTEM::⚠️ 发送太频繁,请稍后再试")) + continue + msg = f"TEXT::{username}::{text.strip()}" + log_to_file(msg) + asyncio.create_task(_broadcast(msg)) + except (WebSocketDisconnect, Exception): + pass + finally: + async with glock: + name = connections.pop(ws, None) or "匿名用户" + leave_msg = f"SYSTEM::{name} 离开聊天室" + log_to_file(leave_msg) + asyncio.create_task(_broadcast(leave_msg)) + asyncio.create_task(_broadcast_members()) + + +# ── Nightly Cleanup ───────────────────────────────────────── + +@app.post("/api/nightly-cleanup") +async def nightly_cleanup(): + """Backup chat history to backups/ dir, then clear the log. + Also purge uploaded files older than 24h. + Called by cron / systemd timer. + """ + now = datetime.now() + backup_name = f"chat_history_{now.strftime('%Y%m%d_%H%M%S')}.txt" + backup_path = os.path.join(BACKUP_DIR, backup_name) + + if os.path.exists(CHAT_LOG_FILE) and os.path.getsize(CHAT_LOG_FILE) > 0: + shutil.copy2(CHAT_LOG_FILE, backup_path) + # Clear log + open(CHAT_LOG_FILE, "w", encoding="utf-8").close() + + # Clean old uploads (> 24h) + now_ts = time.time() + cleaned = 0 + for fname in os.listdir(UPLOAD_DIR): + fpath = os.path.join(UPLOAD_DIR, fname) + if os.path.isfile(fpath) and now_ts - os.path.getmtime(fpath) > 86400: + try: + os.remove(fpath) + cleaned += 1 + except Exception: + pass + + return {"status": "ok", "backup": backup_name, "cleaned_uploads": cleaned} + + +# ── Main ──────────────────────────────────────────────────── + +if __name__ == "__main__": + import uvicorn + uvicorn.run("chat:app", host="0.0.0.0", port=8202, reload=False, log_level="info") diff --git a/chat.py_20260506 b/chat.py_20260506 new file mode 100644 index 0000000..7c709da --- /dev/null +++ b/chat.py_20260506 @@ -0,0 +1,76 @@ +from fastapi import FastAPI, WebSocket, WebSocketDisconnect +from fastapi.responses import HTMLResponse +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates +from fastapi.requests import Request +import uvicorn + +app = FastAPI() + +# 挂载模板目录 +templates = Jinja2Templates(directory="templates") + +# 活跃连接列表 +active_connections = [] + +# WebSocket 与昵称映射表 +usernames = {} + +# 首页路由 +@app.get("/") +async def get(request: Request): + return templates.TemplateResponse("chat.html", {"request": request}) + +# WebSocket 路由 +@app.websocket("/ws") +async def websocket_endpoint(websocket: WebSocket): + await websocket.accept() + active_connections.append(websocket) + await broadcast_online_count() # 一连上就广播在线人数 + + try: + # 接收第一个消息作为昵称 + username = await websocket.receive_text() + usernames[websocket] = username + + await broadcast(f"[系统]{username} 加入了聊天室") + await broadcast_online_count() + + while True: + data = await websocket.receive_text() + await broadcast(f"{username}:{data}") + + except WebSocketDisconnect: + active_connections.remove(websocket) + left_username = usernames.pop(websocket, "匿名用户") + + await broadcast(f"[系统]{left_username} 离开了聊天室") + await broadcast_online_count() + +# 广播消息给所有连接 +async def broadcast(message: str): + to_remove = [] + for connection in active_connections: + try: + await connection.send_text(message) + except: + to_remove.append(connection) + for conn in to_remove: + active_connections.remove(conn) + usernames.pop(conn, None) + +# 广播在线人数 +async def broadcast_online_count(): + message = f"[人数]{len(active_connections)}" + to_remove = [] + for conn in active_connections: + try: + await conn.send_text(message) + except: + to_remove.append(conn) + for conn in to_remove: + active_connections.remove(conn) + usernames.pop(conn, None) + +if __name__ == "__main__": + uvicorn.run("chat:app", host="0.0.0.0", port=8202) \ No newline at end of file diff --git a/chat.py_new b/chat.py_new new file mode 100644 index 0000000..3d6db09 --- /dev/null +++ b/chat.py_new @@ -0,0 +1,160 @@ +from fastapi import FastAPI, WebSocket, WebSocketDisconnect, UploadFile, File, Request +from fastapi.responses import HTMLResponse +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates +import os +import shutil +import uuid +import uvicorn + +app = FastAPI() + +# ========================= +# 基础配置 +# ========================= + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + +TEMPLATE_DIR = os.path.join(BASE_DIR, "templates") +UPLOAD_DIR = os.path.join(BASE_DIR, "uploads") + +MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB + +ALLOWED_IMAGE_EXTENSIONS = {"png", "jpg", "jpeg", "gif"} +ALLOWED_VIDEO_EXTENSIONS = {"mp4", "webm"} + +# ========================= +# 目录初始化 +# ========================= + +os.makedirs(UPLOAD_DIR, exist_ok=True) + +templates = Jinja2Templates(directory=TEMPLATE_DIR) +app.mount("/uploads", StaticFiles(directory=UPLOAD_DIR), name="uploads") + +# ========================= +# WebSocket 状态 +# ========================= + +active_connections: list[WebSocket] = [] +usernames: dict[WebSocket, str] = {} + +# ========================= +# 工具函数 +# ========================= + +def get_ext(filename: str) -> str: + return filename.rsplit(".", 1)[-1].lower() + +def is_image(ext: str) -> bool: + return ext in ALLOWED_IMAGE_EXTENSIONS + +def is_video(ext: str) -> bool: + return ext in ALLOWED_VIDEO_EXTENSIONS + +# ========================= +# 页面路由 +# ========================= + +@app.get("/", response_class=HTMLResponse) +async def index(request: Request): + return templates.TemplateResponse("chat.html", {"request": request}) + +# ========================= +# 文件上传接口 +# ========================= + +@app.post("/upload") +async def upload_file(file: UploadFile = File(...)): + ext = get_ext(file.filename) + + if not (is_image(ext) or is_video(ext)): + return {"error": "不支持的文件类型"} + + contents = await file.read() + + if len(contents) > MAX_FILE_SIZE: + return {"error": "文件过大(最大 10MB)"} + + filename = f"{uuid.uuid4().hex}.{ext}" + save_path = os.path.join(UPLOAD_DIR, filename) + + with open(save_path, "wb") as f: + f.write(contents) + + file_url = f"/uploads/{filename}" + + if is_image(ext): + msg = f"IMG::{file_url}" + elif is_video(ext): + msg = f"VIDEO::{file_url}" + else: + msg = f"FILE::{file_url}" + + await broadcast(msg) + + return {"url": file_url} + +# ========================= +# WebSocket 聊天 +# ========================= + +@app.websocket("/ws") +async def websocket_endpoint(ws: WebSocket): + await ws.accept() + active_connections.append(ws) + await broadcast_online_count() + + try: + # 首条消息作为用户名 + username = await ws.receive_text() + usernames[ws] = username + + await broadcast(f"SYSTEM::{username} 加入聊天室") + await broadcast_online_count() + + while True: + text = await ws.receive_text() + await broadcast(f"TEXT::{username}::{text}") + + except WebSocketDisconnect: + pass + + finally: + if ws in active_connections: + active_connections.remove(ws) + name = usernames.pop(ws, "匿名用户") + await broadcast(f"SYSTEM::{name} 离开聊天室") + await broadcast_online_count() + +# ========================= +# 广播工具 +# ========================= + +async def broadcast(message: str): + dead = [] + for ws in active_connections: + try: + await ws.send_text(message) + except Exception: + dead.append(ws) + + for ws in dead: + active_connections.remove(ws) + usernames.pop(ws, None) + +async def broadcast_online_count(): + msg = f"COUNT::{len(active_connections)}" + await broadcast(msg) + +# ========================= +# 启动 +# ========================= + +if __name__ == "__main__": + uvicorn.run( + "chat:app", + host="0.0.0.0", + port=8202, + reload=True + ) \ No newline at end of file diff --git a/chat_history.txt b/chat_history.txt new file mode 100644 index 0000000..e69de29 diff --git a/nightly_cleanup.log b/nightly_cleanup.log new file mode 100644 index 0000000..7b3f5aa --- /dev/null +++ b/nightly_cleanup.log @@ -0,0 +1,21 @@ +[2026-05-23 03:00:01] Starting nightly cleanup... +{"status":"ok","backup":"chat_history_20260523_030001.txt","cleaned_uploads":0} +[2026-05-23 03:00:01] Cleanup completed. +[2026-05-24 03:00:01] Starting nightly cleanup... +{"status":"ok","backup":"chat_history_20260524_030001.txt","cleaned_uploads":7} +[2026-05-24 03:00:01] Cleanup completed. +[2026-05-25 03:00:01] Starting nightly cleanup... +{"status":"ok","backup":"chat_history_20260525_030001.txt","cleaned_uploads":0} +[2026-05-25 03:00:01] Cleanup completed. +[2026-05-26 03:00:01] Starting nightly cleanup... +{"status":"ok","backup":"chat_history_20260526_030001.txt","cleaned_uploads":0} +[2026-05-26 03:00:01] Cleanup completed. +[2026-05-27 03:00:01] Starting nightly cleanup... +{"status":"ok","backup":"chat_history_20260527_030001.txt","cleaned_uploads":0} +[2026-05-27 03:00:01] Cleanup completed. +[2026-05-28 03:00:01] Starting nightly cleanup... +{"status":"ok","backup":"chat_history_20260528_030001.txt","cleaned_uploads":0} +[2026-05-28 03:00:01] Cleanup completed. +[2026-05-29 03:00:01] Starting nightly cleanup... +{"status":"ok","backup":"chat_history_20260529_030001.txt","cleaned_uploads":0} +[2026-05-29 03:00:01] Cleanup completed. diff --git a/nightly_cleanup.sh b/nightly_cleanup.sh new file mode 100755 index 0000000..5dab654 --- /dev/null +++ b/nightly_cleanup.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# Nightly cleanup for ChatHub +# Backups chat history, clears log, removes old uploads +# Called by cron at 03:00 daily + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +LOG_FILE="${SCRIPT_DIR}/nightly_cleanup.log" + +echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting nightly cleanup..." >> "$LOG_FILE" + +# Call the API endpoint +curl -s -X POST http://localhost:8202/api/nightly-cleanup >> "$LOG_FILE" 2>&1 + +echo "" >> "$LOG_FILE" +echo "[$(date '+%Y-%m-%d %H:%M:%S')] Cleanup completed." >> "$LOG_FILE" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..528606b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +fastapi +uvicorn +jinja2 \ No newline at end of file diff --git a/templates/chat.html b/templates/chat.html new file mode 100644 index 0000000..6c2f705 --- /dev/null +++ b/templates/chat.html @@ -0,0 +1,821 @@ + + + + + + ChatHub + + + +
+ + + + +
+ +
+
+
💬
+
+
无痕聊天室
+
🟡 连接中...
+
+
+
+ 🌙 +
+
+ + +
+
+
🫧
+
聊天记录为空
+
发出一条消息开始聊天吧
+
+
+ + +
+
+
+ + +
+ +
+ +
+ + +
+
+
+ + + + diff --git a/templates/chat.html_ b/templates/chat.html_ new file mode 100644 index 0000000..d77f6e7 --- /dev/null +++ b/templates/chat.html_ @@ -0,0 +1,199 @@ + + + + 纵有千古、横有八荒 + + + + + +
+
+
+ + +
+
+ + + + \ No newline at end of file diff --git a/templates/chat.html_20260506 b/templates/chat.html_20260506 new file mode 100644 index 0000000..f5af34e --- /dev/null +++ b/templates/chat.html_20260506 @@ -0,0 +1,354 @@ + + + 无痕聊天室 + + + + + +
+
🌙 夜间
+
在线人数:0
+
🟢 已连接
+
+
+ + +
+
+ + + + diff --git a/templates/chat.html_bak b/templates/chat.html_bak new file mode 100644 index 0000000..1d8f588 --- /dev/null +++ b/templates/chat.html_bak @@ -0,0 +1,140 @@ + + + + 纵有千古、横有八荒 + + + + +
+ +
+ + +
+
+ + + + \ No newline at end of file diff --git a/templates/chat.html_bak2 b/templates/chat.html_bak2 new file mode 100644 index 0000000..0651872 --- /dev/null +++ b/templates/chat.html_bak2 @@ -0,0 +1,246 @@ + + + 无痕聊天室 + + + + + + + + +
+
🌙 夜间
+
在线人数:0
+
🟢 已连接
+ +
+ +
+ + + + +
+
+ + + + \ No newline at end of file diff --git a/templates/chat.html_bak3 b/templates/chat.html_bak3 new file mode 100644 index 0000000..0651872 --- /dev/null +++ b/templates/chat.html_bak3 @@ -0,0 +1,246 @@ + + + 无痕聊天室 + + + + + + + + +
+
🌙 夜间
+
在线人数:0
+
🟢 已连接
+ +
+ +
+ + + + +
+
+ + + + \ No newline at end of file diff --git a/templates/chat.html_new b/templates/chat.html_new new file mode 100644 index 0000000..e6ccd2f --- /dev/null +++ b/templates/chat.html_new @@ -0,0 +1,234 @@ + + + 无痕聊天室 + + + + + + + + +
+
🌙 夜间
+
在线人数:0
+
🟢 已连接
+ +
+ +
+ + + + +
+
+ + + + \ No newline at end of file diff --git a/uwsgi.ini b/uwsgi.ini new file mode 100644 index 0000000..b80aed2 --- /dev/null +++ b/uwsgi.ini @@ -0,0 +1,30 @@ +[uwsgi] +uid = uwsgi +gid = uwsgi + +# 启动服务监听的地址和端口 +http-socket = 0.0.0.0:8202 + +# 指定虚拟环境路径 +virtualenv = /opt/service/python_prj/pictoHub.env + +# 指定 Flask 应用文件的路径 +wsgi-file = /opt/service/python_prj/chatHub/chat.py + +# 设置 Flask 的应用实例 +callable = app + +# 设置静态文件目录映射 +static-map = /static=/opt/service/python_prj/chatHub/static/ + +# 日志文件 +logto = /var/log/uwsgi/chat-project.log + +# 设置进程数 +processes = 4 + +# 启动时的 Python 环境路径 +home = /opt/service/python_prj/pictoHub.env + +# 确保应用正常启动 +touch-reload = /opt/service/python_prj/chatHub/chat.py