nonebot-plugin-savepic 0.2.7__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (19) hide show
  1. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/PKG-INFO +1 -1
  2. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/__init__.py +5 -40
  3. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/config.py +6 -0
  4. nonebot_plugin_savepic-0.3.1/nonebot_plugin_savepic/listpic.py +84 -0
  5. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/mvpic.py +0 -1
  6. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/pic_sql.py +18 -64
  7. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/pyproject.toml +1 -1
  8. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/LICENSE +0 -0
  9. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/README.md +0 -0
  10. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/ai_utils.py +0 -0
  11. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/countpic.py +0 -0
  12. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/error.py +0 -0
  13. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/ext_listener.py +0 -0
  14. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/model.py +0 -0
  15. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/networks/__init__.py +0 -0
  16. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/networks/resnet_big.py +0 -0
  17. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/picture.py +0 -0
  18. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/randpic.py +0 -0
  19. {nonebot_plugin_savepic-0.2.7 → nonebot_plugin_savepic-0.3.1}/nonebot_plugin_savepic/rule.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nonebot-plugin-savepic
3
- Version: 0.2.7
3
+ Version: 0.3.1
4
4
  Summary: 保存表情包(语录)与随机出图
5
5
  Home-page: https://github.com/Yan-Zero/nonebot-plugin-savepic
6
6
  License: MIT
@@ -11,7 +11,7 @@ from nonebot.matcher import Matcher
11
11
  from nonebot.plugin import PluginMetadata
12
12
  from nonebot.dependencies import Dependent
13
13
  from sqlalchemy.exc import DBAPIError
14
- from arclet.alconna import Alconna, Option, Args, CommandMeta, append
14
+ from arclet.alconna import Alconna, Option, Args, CommandMeta
15
15
  import os
16
16
  import random
17
17
  from typing import (
@@ -46,20 +46,19 @@ from .config import Config
46
46
  from .config import WORDS
47
47
  from .pic_sql import ( # noqa: E402
48
48
  savepic,
49
- rename,
50
49
  delete,
51
50
  regexp_pic,
52
- listpic,
53
51
  )
54
52
  from .rule import PIC_AMDIN
55
53
  from .rule import BLACK_GROUP
56
54
  from .rule import GROUP_ADMIN
57
- from .ext_listener import pic_listen # noqa: E402, F401
58
- from .picture import write_pic, load_pic # noqa: E402
55
+ from .picture import write_pic, load_pic
59
56
  from .ai_utils import img2vec
60
57
  from .randpic import url_to_image
61
- from .countpic import cpic
62
58
  from .mvpic import INVALID_FILENAME_CHARACTERS
59
+ from .listpic import s_listpic
60
+ from .ext_listener import pic_listen
61
+ from .countpic import cpic
63
62
 
64
63
 
65
64
  __plugin_meta__ = PluginMetadata(
@@ -89,7 +88,6 @@ a_spic = Alconna(
89
88
  meta=CommandMeta(description="保存图片,默认保存到本群"),
90
89
  )
91
90
  s_simpic = on_command("simpic", priority=5, permission=BLACK_GROUP)
92
- s_listpic = on_command("listpic", priority=5, permission=BLACK_GROUP)
93
91
 
94
92
 
95
93
  def got_random_prompt(
@@ -162,39 +160,6 @@ async def _(bot: Bot, event, args: V11Msg = CommandArg()):
162
160
  )
163
161
 
164
162
 
165
- @s_listpic.handle()
166
- async def _(bot: Bot, event, args: V11Msg = CommandArg()):
167
- reg = args.extract_plain_text().strip().rsplit("\\page", maxsplit=1)
168
- try:
169
- if len(reg) > 1:
170
- reg, pages = reg
171
- else:
172
- reg, pages = reg[0], 0
173
- pages = int(pages)
174
- except Exception as ex:
175
- await repic.finish(
176
- f'{random.choice(WORDS.get("error", ["出错了喵~"]))}\n\n{ex}'
177
- )
178
-
179
- group_id = (
180
- "globe"
181
- if not isinstance(event, GroupMessageEvent)
182
- else f"qq_group:{event.group_id}"
183
- )
184
- try:
185
- pic = await listpic(reg, group_id, pages=pages)
186
- if pic:
187
- await bot.send(event, "\n".join(pic))
188
- except DBAPIError as ex:
189
- await repic.finish(
190
- f'{random.choice(WORDS.get("error", ["出错了喵~"]))}\n\n{ex.orig}'
191
- )
192
- except Exception as ex:
193
- await repic.finish(
194
- f'{random.choice(WORDS.get("error", ["出错了喵~"]))}\n\n{ex}'
195
- )
196
-
197
-
198
163
  @spic.handle()
199
164
  async def _(
200
165
  bot: Bot,
@@ -36,3 +36,9 @@ class Config(BaseModel):
36
36
 
37
37
  notfound_with_jpg: bool = True
38
38
  """ randpic 的时候,尝试带 .jpg 再度检索向量 """
39
+ count_per_page_in_list: int = 7
40
+ """ 每页最多多少条 """
41
+ forward_when_listpic: bool = True
42
+ """ listpic 的时候合并转发 """
43
+ max_page_in_listpic: int = 20
44
+ """ 合并转发中所能显示的最大页数 """
@@ -0,0 +1,84 @@
1
+ import random
2
+ from nonebot import on_command
3
+ from nonebot import get_plugin_config
4
+ from nonebot.params import CommandArg
5
+ from nonebot.internal.adapter import Bot
6
+ from nonebot.adapters.onebot.v11.event import GroupMessageEvent as V11GME
7
+ from nonebot.adapters.onebot.v11.message import Message as V11Msg
8
+ from nonebot.adapters.onebot.v11.message import MessageSegment as V11Seg
9
+ from sqlalchemy.exc import DBAPIError
10
+
11
+ from .rule import BLACK_GROUP
12
+ from .config import WORDS
13
+ from .pic_sql import listpic
14
+ from .config import Config
15
+
16
+ p_config: Config = get_plugin_config(Config)
17
+ s_listpic = on_command("listpic", priority=5, permission=BLACK_GROUP)
18
+
19
+
20
+ @s_listpic.handle()
21
+ async def _(bot: Bot, event, args: V11Msg = CommandArg()):
22
+ reg = args.extract_plain_text().strip().rsplit("\\page", maxsplit=1)
23
+ try:
24
+ if len(reg) > 1:
25
+ reg, pages = reg
26
+ else:
27
+ reg, pages = reg[0], 1
28
+ pages = int(pages)
29
+ except Exception as ex:
30
+ await s_listpic.finish(
31
+ f'{random.choice(WORDS.get("error", ["出错了喵~"]))}\n\n{ex}'
32
+ )
33
+
34
+ group_id = (
35
+ "globe" if not isinstance(event, V11GME) else f"qq_group:{event.group_id}"
36
+ )
37
+ try:
38
+ pics = await listpic(reg, group_id, pages=pages)
39
+ if not pics:
40
+ return
41
+
42
+ cpp = max(p_config.count_per_page_in_list, 1)
43
+ if p_config.forward_when_listpic:
44
+ message = []
45
+ for i in range(len(pics) // cpp + 1):
46
+ if pics[i * cpp : (i + 1) * cpp]:
47
+ message.append(
48
+ {
49
+ "type": "node",
50
+ "data": {
51
+ "uin": str(event.get_user_id()),
52
+ "name": f"Page {pages+i}",
53
+ "content": V11Seg.text(
54
+ "\n".join(pics[i * cpp : (i + 1) * cpp])
55
+ + f"\n\nPage {pages+i}"
56
+ ),
57
+ },
58
+ },
59
+ )
60
+
61
+ if isinstance(event, V11GME):
62
+ await bot.call_api(
63
+ "send_group_forward_msg",
64
+ group_id=event.group_id,
65
+ messages=message,
66
+ )
67
+ else:
68
+ await s_listpic.send(
69
+ V11Seg.forward(
70
+ await bot.call_api("send_forward_msg", messages=message)
71
+ )
72
+ )
73
+ return
74
+
75
+ await s_listpic.send("\n".join(pics[:cpp]))
76
+
77
+ except DBAPIError as ex:
78
+ await s_listpic.finish(
79
+ f'{random.choice(WORDS.get("error", ["出错了喵~"]))}\n\n{ex.orig}'
80
+ )
81
+ except Exception as ex:
82
+ await s_listpic.finish(
83
+ f'{random.choice(WORDS.get("error", ["出错了喵~"]))}\n\n{ex}'
84
+ )
@@ -1,5 +1,4 @@
1
1
  import random
2
- import re
3
2
  from nonebot import on_command
4
3
  from nonebot.params import CommandArg
5
4
  from nonebot.internal.adapter import Bot
@@ -6,7 +6,6 @@ import asyncpg
6
6
  from nonebot import get_driver
7
7
  import dashscope
8
8
  import pathlib
9
- from pinecone import Pinecone, ServerlessSpec
10
9
 
11
10
  from .model import PicData
12
11
  from .picture import del_pic
@@ -20,7 +19,6 @@ from .error import NoPictureException
20
19
  gdriver = get_driver()
21
20
  p_config = Config.parse_obj(gdriver.config)
22
21
  _async_database = None
23
- _pincone_index = None
24
22
  _async_embedding_database = None
25
23
 
26
24
 
@@ -37,15 +35,15 @@ async def update_vec(pic: PicData):
37
35
  return
38
36
 
39
37
  async with AsyncSession(_async_database) as db_session:
40
- if pic.u_vec_text:
41
- pic.u_vec_text = False
42
- await _async_embedding_database.execute(
43
- "UPDATE savepic_word2vec SET embedding = $1 WHERE id = $2",
44
- str(word2vec(pic.name)),
45
- pic.id,
46
- )
47
- db_session.merge(pic)
48
- db_session.commit()
38
+ # if pic.u_vec_text:
39
+ pic.u_vec_text = False
40
+ await _async_embedding_database.execute(
41
+ "UPDATE savepic_word2vec SET embedding = $1 WHERE id = $2",
42
+ str(word2vec(pic.name)),
43
+ pic.id,
44
+ )
45
+ await db_session.merge(pic)
46
+ await db_session.commit()
49
47
 
50
48
 
51
49
  async def select_pic(filename: str, group: str):
@@ -64,37 +62,6 @@ async def select_pic(filename: str, group: str):
64
62
  )
65
63
 
66
64
 
67
- # async def get_most_similar_pic(
68
- # img_vec: list[float],
69
- # group_id: str,
70
- # ignore_diagonal: bool = False,
71
- # ignore_min: bool = False,
72
- # ) -> tuple[float, PicData]:
73
- # async with AsyncSession(_async_database) as db_session:
74
- # ret = _pincone_index.query(img_vec, top_k=20)["matches"]
75
- # if not ret:
76
- # return None, None
77
- # if not ret[0]["id"]:
78
- # return None, None
79
- # if ignore_diagonal and ret[0]["score"] >= 0.999:
80
- # ret.pop(0)
81
-
82
- # for i in ret:
83
- # if i["score"] < 0.65 and not ignore_min:
84
- # return None, None
85
- # if i["id"]:
86
- # despic = await db_session.scalar(
87
- # select(PicData)
88
- # .where(PicData.id == int(i["id"]))
89
- # .where(PicData.name != "")
90
- # .where(sa.or_(PicData.group == group_id, PicData.group == "globe"))
91
- # )
92
- # if despic:
93
- # return i["score"], despic
94
-
95
- # return None, None
96
-
97
-
98
65
  async def savepic(
99
66
  filename: str,
100
67
  url: str,
@@ -173,7 +140,6 @@ async def delete(filename: str, group: str):
173
140
  del_pic(pic.url)
174
141
  pic.name = ""
175
142
  await db_session.merge(pic)
176
- # _pincone_index.delete(ids=[str(pic.id)])
177
143
  await _async_embedding_database.execute(
178
144
  "UPDATE savepic_word2vec SET embedding = NULL WHERE id = $1", pic.id
179
145
  )
@@ -285,7 +251,12 @@ async def listpic(reg: str, group: str = "globe", pages: int = 0) -> list[str]:
285
251
  reg = reg.strip()
286
252
  if not reg:
287
253
  reg = ".*"
288
- pages -= 1
254
+
255
+ pages = max(pages - 1, 0)
256
+ _count = min(
257
+ max(1, p_config.count_per_page_in_list * p_config.max_page_in_listpic), 1000
258
+ )
259
+
289
260
  async with AsyncSession(_async_database) as db_session:
290
261
  pics = await db_session.scalars(
291
262
  select(PicData)
@@ -293,8 +264,8 @@ async def listpic(reg: str, group: str = "globe", pages: int = 0) -> list[str]:
293
264
  .where(PicData.name != "")
294
265
  .where(PicData.name.regexp_match(reg, flags="i"))
295
266
  .order_by(PicData.name)
296
- .offset((0 if pages < 0 else pages) * 10)
297
- .limit(10)
267
+ .offset(pages * p_config.count_per_page_in_list)
268
+ .limit(_count)
298
269
  )
299
270
  if pics:
300
271
  return [str(pic.name) for pic in pics]
@@ -302,7 +273,7 @@ async def listpic(reg: str, group: str = "globe", pages: int = 0) -> list[str]:
302
273
 
303
274
  async def init_db():
304
275
  # check if the table exists
305
- global _async_database, _pincone_index, _async_embedding_database
276
+ global _async_database, _async_embedding_database
306
277
  _async_database = create_async_engine(
307
278
  p_config.savepic_sqlurl,
308
279
  future=True,
@@ -350,22 +321,6 @@ async def init_db():
350
321
  )
351
322
  )
352
323
 
353
- if not p_config.pinecone_apikey:
354
- raise Exception("请配置 pinecone_apikey")
355
- if not p_config.pinecone_environment:
356
- raise Exception("请配置 pinecone_environment")
357
-
358
- pc = Pinecone(api_key=p_config.pinecone_apikey)
359
- if p_config.pinecone_index not in pc.list_indexes().names():
360
- pc.create_index(
361
- name=p_config.pinecone_index,
362
- dimension=1536,
363
- metric="euclidean",
364
- spec=ServerlessSpec(cloud="aws", region="us-west-2"),
365
- )
366
- if not _pincone_index:
367
- _pincone_index = pc.Index(p_config.pinecone_index)
368
-
369
324
 
370
325
  @gdriver.on_startup
371
326
  async def _():
@@ -388,7 +343,6 @@ async def _():
388
343
  # .where(PicData.name != "")
389
344
  # )
390
345
  # if pic:
391
- # _pincone_index.upsert([(str(pic.id), files[i])])
392
346
  # print(f"{pic.name} 加载成功")
393
347
  # except Exception as ex:
394
348
  # print(ex)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "nonebot-plugin-savepic"
3
- version = "0.2.7"
3
+ version = "0.3.1"
4
4
  description = "保存表情包(语录)与随机出图"
5
5
  authors = ["Yan <1964649083@qq.com>"]
6
6
  license = "MIT"