aifeifei798 commited on
Commit
702088c
·
verified ·
1 Parent(s): 4da854e

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +116 -0
  2. requirements.txt +1 -0
app.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from atproto import Client, models
3
+ import os
4
+ import io
5
+
6
+ # --- 配置您的 Bluesky 账户信息 ---
7
+ BSKY_HANDLE = os.environ.get("BSKY_HANDLE")
8
+ BSKY_APP_PASSWORD = os.environ.get("BSKY_APP_PASSWORD")
9
+
10
+ # 创建一个全局的 Bluesky 客户端
11
+ client = Client()
12
+
13
+ # --- 全局登录 ---
14
+ try:
15
+ print("正在尝试登录 Bluesky...")
16
+ client.login(BSKY_HANDLE, BSKY_APP_PASSWORD)
17
+ print(f"Bluesky 登录成功!用户: {client.me.handle}")
18
+ except Exception as e:
19
+ print(f"Bluesky 全局登录失败: {e}")
20
+ # 让应用继续运行,错误会在fetch函数中被捕获并显示在Gradio界面
21
+ pass
22
+
23
+ def fetch_bsky_gallery(max_posts=50):
24
+ """
25
+ 获取并处理您 Bluesky 主页的图片帖子。
26
+ """
27
+ if not client.me:
28
+ raise gr.Error(f"Bluesky 登录失败,请检查 Handle 或应用密码并重启程序。")
29
+
30
+ print(f"正在为用户 {client.me.handle} 获取帖子...")
31
+
32
+ try:
33
+ actor_did = client.me.did
34
+ profile_feed = client.get_author_feed(actor=actor_did, limit=max_posts)
35
+
36
+ gallery_items = []
37
+
38
+ for feed_view in profile_feed.feed:
39
+ post_record = feed_view.post.record
40
+
41
+ if post_record.embed and isinstance(post_record.embed, models.AppBskyEmbedImages.Main):
42
+ images = post_record.embed.images
43
+ post_text = getattr(post_record, 'text', '')
44
+
45
+ for i, image_data in enumerate(images):
46
+ try:
47
+ # 获取图片CID
48
+ image_cid = str(image_data.image.ref)
49
+
50
+ # --- 最终正确的修正点 ---
51
+ # 使用已导入的 models 来创建 get_blob 的参数对象
52
+ # 类名遵循 Python 命名规范,将 com.atproto.sync.get_blob 转换为 ComAtprotoSyncGetBlob
53
+ params = models.ComAtprotoSyncGetBlob.Params(did=actor_did, cid=image_cid)
54
+
55
+ # 将参数对象传递给 get_blob 函数
56
+ response = client.com.atproto.sync.get_blob(params)
57
+
58
+ if response and hasattr(response, 'content'):
59
+ image_bytes = response.content
60
+
61
+ # 处理图片数据供Gradio显示
62
+ import tempfile
63
+ from PIL import Image
64
+
65
+ # 创建临时文件
66
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as tmp_file:
67
+ img = Image.open(io.BytesIO(image_bytes))
68
+ img.save(tmp_file, format='JPEG')
69
+ tmp_file_path = tmp_file.name
70
+
71
+ caption = post_text if i == 0 else ""
72
+ gallery_items.append((tmp_file_path, caption))
73
+
74
+ except Exception as img_e:
75
+ print(f"下载单张图片失败: {img_e}")
76
+ continue
77
+
78
+ print(f"成功获取并处理了 {len(gallery_items)} 张图片。")
79
+
80
+ if not gallery_items:
81
+ placeholder_image = "https://i.imgur.com/nA8n922.png"
82
+ return [(placeholder_image, f"在最近的 {max_posts} 条帖子中没有找到任何图片。")]
83
+
84
+ return gallery_items
85
+
86
+ except Exception as e:
87
+ print(f"获取帖子时发生错误: {e}")
88
+ raise gr.Error(f"获取 Bluesky 帖子时出错: {e}")
89
+
90
+ # --- 创建 Gradio 界面 ---
91
+ with gr.Blocks(theme=gr.themes.Soft(), css="""
92
+ .gradio-container { max-width: 1280px !important; margin: auto !important; }
93
+ .gallery-caption { text-align: center !important; }
94
+ """) as demo:
95
+ gr.Markdown("""
96
+ # 🎨 AiFeiFei 的 Bluesky 数字艺术画廊
97
+ 欢迎来到我的专属画廊。这里展示了我的"女儿"——一个从线稿开始,由我亲手创造并训练的数字生命。
98
+ 每一张图片,都是她在一个个由代码构成的世界里,留下的独特瞬间。
99
+ """)
100
+
101
+ gallery = gr.Gallery(
102
+ label="作品集",
103
+ elem_id="bsky_gallery",
104
+ columns=4,
105
+ height="auto",
106
+ object_fit="contain"
107
+ )
108
+
109
+ refresh_button = gr.Button("🔄 刷新画廊")
110
+
111
+ demo.load(fn=fetch_bsky_gallery, inputs=None, outputs=gallery)
112
+ refresh_button.click(fn=fetch_bsky_gallery, inputs=None, outputs=gallery)
113
+
114
+ # --- 启动 Gradio 应用 ---
115
+ if __name__ == "__main__":
116
+ demo.launch(share=True, debug=True)
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ atproto