xync-bot 0.2.10__py3-none-any.whl → 0.3.2__py3-none-any.whl
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.
Potentially problematic release.
This version of xync-bot might be problematic. Click here for more details.
- xync_bot/__init__.py +0 -39
- xync_bot/handlers/__init__.py +0 -2
- xync_bot/handlers/main.py +157 -38
- xync_bot/handlers/order.py +12 -0
- xync_bot/handlers/xicon.png +0 -0
- {xync_bot-0.2.10.dist-info → xync_bot-0.3.2.dist-info}/METADATA +9 -8
- xync_bot-0.3.2.dist-info/RECORD +11 -0
- {xync_bot-0.2.10.dist-info → xync_bot-0.3.2.dist-info}/WHEEL +1 -1
- xync_bot-0.2.10.dist-info/RECORD +0 -9
- {xync_bot-0.2.10.dist-info → xync_bot-0.3.2.dist-info}/top_level.txt +0 -0
xync_bot/__init__.py
CHANGED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
from aiogram.client.default import DefaultBotProperties
|
|
2
|
-
from aiogram.types import MenuButtonWebApp, WebAppInfo
|
|
3
|
-
import logging
|
|
4
|
-
from os import getenv as env
|
|
5
|
-
from dotenv import load_dotenv
|
|
6
|
-
from aiogram import Bot, Dispatcher
|
|
7
|
-
from tortoise.backends.asyncpg import AsyncpgDBClient
|
|
8
|
-
|
|
9
|
-
from xync_bot.handlers import main, vpn
|
|
10
|
-
|
|
11
|
-
load_dotenv()
|
|
12
|
-
|
|
13
|
-
logging.basicConfig(filemode='a', level=logging.DEBUG)
|
|
14
|
-
|
|
15
|
-
bot = Bot(token=env('TOKEN'), default=DefaultBotProperties(parse_mode='Markdown'))
|
|
16
|
-
dp = Dispatcher(bot=bot)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
async def on_startup(wh_url: str, twa_url: str, cn: AsyncpgDBClient, mbt: str = 'Go!'):
|
|
20
|
-
""" SET DEISPATCHER GLOBAL WORKFLOW DATA FOR DB Connection """
|
|
21
|
-
dp['dbc'] = cn
|
|
22
|
-
""" WEBHOOK SETUP """
|
|
23
|
-
webhook_info = await bot.get_webhook_info()
|
|
24
|
-
if webhook_info.url != wh_url:
|
|
25
|
-
await bot.set_webhook(url=wh_url, drop_pending_updates=True)
|
|
26
|
-
""" WEBAPP URL SETUP IN MENU """
|
|
27
|
-
await bot.set_chat_menu_button(menu_button=MenuButtonWebApp(text=mbt, web_app=WebAppInfo(url=twa_url)))
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
async def on_shutdown():
|
|
31
|
-
""" CLOSE BOT SESSION """
|
|
32
|
-
await bot.delete_webhook(drop_pending_updates=True)
|
|
33
|
-
await bot.session.close()
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
dp.startup.register(on_startup)
|
|
37
|
-
dp.shutdown.register(on_shutdown)
|
|
38
|
-
|
|
39
|
-
dp.include_routers(vpn, main)
|
xync_bot/handlers/__init__.py
CHANGED
xync_bot/handlers/main.py
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from os import path
|
|
3
|
+
|
|
2
4
|
from aiogram import Router, F
|
|
3
|
-
from aiogram.
|
|
5
|
+
from aiogram.enums import ContentType
|
|
6
|
+
from aiogram.filters import CommandStart, CommandObject, IS_MEMBER, IS_NOT_MEMBER, ChatMemberUpdatedFilter
|
|
4
7
|
from aiogram.filters.callback_data import CallbackData
|
|
5
|
-
from aiogram.types import
|
|
8
|
+
from aiogram.types import (
|
|
9
|
+
User as TgUser,
|
|
10
|
+
ChatMemberUpdated,
|
|
11
|
+
Message,
|
|
12
|
+
InlineKeyboardMarkup,
|
|
13
|
+
InlineKeyboardButton,
|
|
14
|
+
CallbackQuery,
|
|
15
|
+
ChatJoinRequest,
|
|
16
|
+
WebAppInfo,
|
|
17
|
+
FSInputFile,
|
|
18
|
+
)
|
|
6
19
|
from aiogram.utils.deep_linking import create_start_link
|
|
7
20
|
from aiogram.utils.web_app import WebAppUser
|
|
8
|
-
from
|
|
21
|
+
from tg_auth import Lang
|
|
22
|
+
from xync_schema.models import User, UserStatus, Order, Msg, Forum
|
|
9
23
|
|
|
10
24
|
from xync_bot.shared import NavCallbackData
|
|
11
25
|
|
|
@@ -18,10 +32,13 @@ class RrCallbackData(CallbackData, prefix="reg_res"): # registration response
|
|
|
18
32
|
|
|
19
33
|
|
|
20
34
|
home_btns = InlineKeyboardMarkup(
|
|
21
|
-
inline_keyboard=[
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
inline_keyboard=[
|
|
36
|
+
[
|
|
37
|
+
InlineKeyboardButton(text="Invite", callback_data=NavCallbackData(to="ref_link").pack()),
|
|
38
|
+
InlineKeyboardButton(text="Get VPN", callback_data=NavCallbackData(to="get_vpn").pack()),
|
|
39
|
+
]
|
|
40
|
+
]
|
|
41
|
+
)
|
|
25
42
|
|
|
26
43
|
|
|
27
44
|
@main.message(CommandStart(deep_link=True, deep_link_encoded=True))
|
|
@@ -31,19 +48,24 @@ async def start_handler(msg: Message, command: CommandObject):
|
|
|
31
48
|
user = await User.get_or_none(id=me.id, status__gte=UserStatus.RESTRICTED)
|
|
32
49
|
rm = None
|
|
33
50
|
if user:
|
|
34
|
-
rs, rm = f
|
|
51
|
+
rs, rm = f"{me.full_name}, you have registered already😉", home_btns
|
|
35
52
|
elif not (ref := await User.get_or_none(id=ref_id)):
|
|
36
|
-
rs = f
|
|
53
|
+
rs = f"No registered user #{ref_id}😬"
|
|
37
54
|
else: # new user created
|
|
38
55
|
user, cr = await user_upsert(me)
|
|
39
|
-
await user.update_from_dict({
|
|
56
|
+
await user.update_from_dict({"ref": ref}).save()
|
|
40
57
|
approve_btns = InlineKeyboardMarkup(
|
|
41
|
-
inline_keyboard=[
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
inline_keyboard=[
|
|
59
|
+
[
|
|
60
|
+
InlineKeyboardButton(text="Отклонить", callback_data=RrCallbackData(to=user.id, res=False).pack()),
|
|
61
|
+
InlineKeyboardButton(text="Одобрить", callback_data=RrCallbackData(to=user.id, res=True).pack()),
|
|
62
|
+
]
|
|
63
|
+
]
|
|
64
|
+
)
|
|
65
|
+
await msg.bot.send_message(
|
|
66
|
+
ref.id, f"{me.full_name} просит что б Вы взяли за него/ее ответственность", reply_markup=approve_btns
|
|
67
|
+
)
|
|
68
|
+
return await msg.answer(f"Please wait for @{ref.username} approving...")
|
|
47
69
|
return await msg.answer(rs, reply_markup=rm)
|
|
48
70
|
|
|
49
71
|
|
|
@@ -53,65 +75,162 @@ async def phrases_input_request(cb: CallbackQuery, callback_data: RrCallbackData
|
|
|
53
75
|
if callback_data.res:
|
|
54
76
|
# protege.status = UserStatus.RESTRICTED
|
|
55
77
|
await protege.save()
|
|
56
|
-
rs = f
|
|
78
|
+
rs = f"{cb.from_user.full_name}, теперь Вы несете ответветвенность за {protege.username}"
|
|
57
79
|
else:
|
|
58
80
|
rs = f'Вы отклонили запрос юзера "{protege.username}" на Вашу протекцию'
|
|
59
|
-
res = {True:
|
|
60
|
-
txt = f
|
|
61
|
-
txt, rm = (f
|
|
81
|
+
res = {True: "одобрил", False: "отклонил"}
|
|
82
|
+
txt = f"{cb.from_user.full_name} {res[callback_data.res]} вашу регистрацию"
|
|
83
|
+
txt, rm = (f"Поздравляем! {txt}💥", home_btns) if callback_data.res else (f"К сожалению {txt}😢", None)
|
|
62
84
|
await cb.bot.send_message(protege.id, txt, reply_markup=rm)
|
|
63
|
-
await cb.answer(
|
|
85
|
+
await cb.answer("👌🏼")
|
|
64
86
|
await cb.message.edit_text(rs)
|
|
65
87
|
|
|
66
88
|
|
|
67
89
|
@main.message(CommandStart(deep_link=True)) # attempt to reg by fake link
|
|
68
90
|
async def fraud_handler(msg: Message):
|
|
69
|
-
logging.info(f
|
|
91
|
+
logging.info(f"Start: {msg.from_user.id}. Msg: {msg}")
|
|
70
92
|
# todo: alert to admins! Fraud attempt!
|
|
71
|
-
await msg.answer(
|
|
93
|
+
await msg.answer("🤔")
|
|
72
94
|
|
|
73
95
|
|
|
74
96
|
@main.message(CommandStart())
|
|
75
97
|
async def start_no_ref_handler(msg: Message):
|
|
76
98
|
me = msg.from_user
|
|
77
99
|
user, cr = await user_upsert(me)
|
|
78
|
-
rr =
|
|
100
|
+
rr = "сначала вы должны найти поручителя, и перейти по его реферальной ссылке.\nhttps://telegra.ph/XyncNet-02-13"
|
|
79
101
|
if cr: # has ref and created now
|
|
80
|
-
await msg.answer(f
|
|
102
|
+
await msg.answer(f"Здравствуйте {me.full_name}, что бы использовать возможности нашей сети, {rr}")
|
|
81
103
|
elif not user.ref_id:
|
|
82
104
|
await msg.answer(rr.capitalize())
|
|
83
105
|
else:
|
|
84
|
-
await msg.answer(f
|
|
106
|
+
await msg.answer(f"{me.full_name}, не балуйтесь, вы и так уже активный участник👌🏼", reply_markup=home_btns)
|
|
85
107
|
|
|
86
108
|
|
|
87
|
-
@main.callback_query(NavCallbackData.filter(F.to ==
|
|
109
|
+
@main.callback_query(NavCallbackData.filter(F.to == "ref_link"))
|
|
88
110
|
async def ref_link_handler(cbq: CallbackQuery):
|
|
89
111
|
me = cbq.from_user
|
|
90
|
-
if not (u := await User.get_or_none(id=me.id, status__gt=UserStatus.RESTRICTED).prefetch_related(
|
|
112
|
+
if not (u := await User.get_or_none(id=me.id, status__gt=UserStatus.RESTRICTED).prefetch_related("ref")):
|
|
91
113
|
return await cbq.answer(f"{me.full_name}, сначала сами получите одобрение поручителя😉")
|
|
92
114
|
link = await create_start_link(cbq.bot, str(u.id), encode=True)
|
|
93
|
-
logging.info(f
|
|
94
|
-
await cbq.message.answer(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
115
|
+
logging.info(f"Start: {me.id}. Msg: {cbq}")
|
|
116
|
+
await cbq.message.answer(
|
|
117
|
+
f"Your referrer is {u.ref_id and u.ref.username}"
|
|
118
|
+
f"\nThis is your invite link: {link}"
|
|
119
|
+
f"\nGive it to your protege, and approve his request"
|
|
120
|
+
)
|
|
121
|
+
await cbq.answer("Wait for your protege request..")
|
|
98
122
|
|
|
99
123
|
|
|
100
124
|
async def user_upsert(u: TgUser | WebAppUser, status: UserStatus = None) -> (User, bool):
|
|
101
|
-
pic = (
|
|
102
|
-
|
|
125
|
+
pic = (
|
|
126
|
+
(gpp := await u.get_profile_photos(0, 1)).photos and gpp.photos[0][-1].file_unique_id
|
|
127
|
+
if type(u) is TgUser
|
|
128
|
+
else (u.photo_url[0] if u.photo_url else None)
|
|
129
|
+
)
|
|
130
|
+
udf = {
|
|
131
|
+
"username": u.username,
|
|
132
|
+
"first_name": u.first_name,
|
|
133
|
+
"last_name": u.last_name,
|
|
134
|
+
"status": UserStatus.MEMBER,
|
|
135
|
+
"lang": u.language_code and Lang[u.language_code],
|
|
136
|
+
"pic": pic,
|
|
137
|
+
}
|
|
103
138
|
if status:
|
|
104
|
-
udf.update({
|
|
139
|
+
udf.update({"status": status})
|
|
105
140
|
return await User.update_or_create(udf, id=u.id)
|
|
106
141
|
|
|
107
142
|
|
|
108
143
|
@main.my_chat_member()
|
|
109
144
|
async def user_set_status(my_chat_member: ChatMemberUpdated):
|
|
110
145
|
u: TgUser = my_chat_member.from_user
|
|
111
|
-
new_status = my_chat_member.new_chat_member.status
|
|
146
|
+
new_status = UserStatus[my_chat_member.new_chat_member.status.upper()]
|
|
112
147
|
await user_upsert(u, status=new_status)
|
|
113
148
|
|
|
114
149
|
|
|
115
|
-
@main.
|
|
150
|
+
@main.chat_member(ChatMemberUpdatedFilter(IS_MEMBER >> IS_NOT_MEMBER))
|
|
151
|
+
async def on_user_leave(member: ChatMemberUpdated):
|
|
152
|
+
forum = await Forum[member.chat.id]
|
|
153
|
+
if not forum.joined:
|
|
154
|
+
resp = (
|
|
155
|
+
f"{member.from_user.username or member.from_user.full_name}#{member.from_user.id} "
|
|
156
|
+
f"already leaved from {member.chat.title}#{member.chat.id}"
|
|
157
|
+
)
|
|
158
|
+
logging.error(resp)
|
|
159
|
+
else:
|
|
160
|
+
forum.joined = False
|
|
161
|
+
await forum.save()
|
|
162
|
+
resp = "Bye!"
|
|
163
|
+
return await member.bot.send_message(member.new_chat_member.user.id, resp)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@main.chat_join_request()
|
|
167
|
+
async def on_join_request(req: ChatJoinRequest):
|
|
168
|
+
forum = await Forum[req.chat.id]
|
|
169
|
+
if forum.user_id != req.from_user.id:
|
|
170
|
+
resp = f"{req.chat.title} is chat for user#{forum.user_id}"
|
|
171
|
+
logging.error(resp)
|
|
172
|
+
forum.joined = not await req.decline()
|
|
173
|
+
else:
|
|
174
|
+
resp = "Welcome!"
|
|
175
|
+
forum.joined = await req.approve()
|
|
176
|
+
cp = (await req.bot.get_chat(req.chat.id)).photo
|
|
177
|
+
if not cp:
|
|
178
|
+
pth = path.join(path.dirname(path.abspath(__file__)), "xicon.png")
|
|
179
|
+
await req.chat.set_photo(FSInputFile(pth))
|
|
180
|
+
await forum.save()
|
|
181
|
+
return await req.bot.send_message(req.user_chat_id, resp)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@main.chat_member(ChatMemberUpdatedFilter(IS_NOT_MEMBER >> IS_MEMBER))
|
|
185
|
+
async def on_user_join(member: ChatMemberUpdated):
|
|
186
|
+
forum = await Forum[member.chat.id]
|
|
187
|
+
rm = None
|
|
188
|
+
if forum.user_id != member.from_user.id:
|
|
189
|
+
if member.from_user.id in (6806432376, forum.created_by):
|
|
190
|
+
return
|
|
191
|
+
resp = f"{member.chat.title} is chat for user#{forum.user_id}"
|
|
192
|
+
logging.error(resp)
|
|
193
|
+
await member.bot.ban_chat_member(member.chat.id, member.from_user.id)
|
|
194
|
+
else:
|
|
195
|
+
resp = "Welcome to XyncNetwork"
|
|
196
|
+
rm = InlineKeyboardMarkup(
|
|
197
|
+
inline_keyboard=[[InlineKeyboardButton(text="Go!", web_app=WebAppInfo(url="https://t.me/XyncNetBot/test"))]]
|
|
198
|
+
)
|
|
199
|
+
return await member.bot.send_message(member.new_chat_member.user.id, resp, reply_markup=rm)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@main.message(F.is_topic_message)
|
|
203
|
+
async def order_msg(msg: Message):
|
|
204
|
+
sender = await User[msg.from_user.id]
|
|
205
|
+
cid = msg.chat.shifted_id
|
|
206
|
+
assert sender.forum == cid, "sender is not client"
|
|
207
|
+
if order := await Order.get_or_none(taker__user_id=sender.id, taker_topic=msg.message_thread_id):
|
|
208
|
+
is_taker = True
|
|
209
|
+
elif order := await Order.get_or_none(ad__agent__user_id=sender.id, maker_topic=msg.message_thread_id):
|
|
210
|
+
is_taker = False
|
|
211
|
+
else:
|
|
212
|
+
return await msg.answer("No such order")
|
|
213
|
+
# raise Exception("No such order")
|
|
214
|
+
receiver: User = await (order.ad.agent.user if is_taker else order.taker.user)
|
|
215
|
+
rcv_topic = order.taker_topic if is_taker else order.maker_topic
|
|
216
|
+
await Msg.create(tgid=msg.message_id, txt=msg.text, order_id=order.id, receiver=receiver)
|
|
217
|
+
return await msg.send_copy(receiver.forum, message_thread_id=rcv_topic)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@main.message(
|
|
221
|
+
F.content_type.not_in(
|
|
222
|
+
{
|
|
223
|
+
# ContentType.NEW_CHAT_MEMBERS,
|
|
224
|
+
ContentType.FORUM_TOPIC_CLOSED,
|
|
225
|
+
ContentType.GENERAL_FORUM_TOPIC_HIDDEN,
|
|
226
|
+
# ContentType.LEFT_CHAT_MEMBER,
|
|
227
|
+
ContentType.SUPERGROUP_CHAT_CREATED,
|
|
228
|
+
ContentType.NEW_CHAT_PHOTO,
|
|
229
|
+
# ContentType.FORUM_TOPIC_CREATED,
|
|
230
|
+
# ContentType.FORUM_TOPIC_EDITED,
|
|
231
|
+
# ContentType.FORUM_TOPIC_CLOSED,
|
|
232
|
+
}
|
|
233
|
+
)
|
|
234
|
+
)
|
|
116
235
|
async def del_cbq(msg: Message):
|
|
117
236
|
await msg.delete()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from aiogram import Router, F
|
|
2
|
+
from aiogram.types import Message
|
|
3
|
+
from xync_schema.models import User
|
|
4
|
+
|
|
5
|
+
r = Router()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# @main.message(F.chat.is_forum)
|
|
9
|
+
@r.message(F.is_topic_message)
|
|
10
|
+
async def order_msg(msg: Message):
|
|
11
|
+
await User[msg.from_user.id]
|
|
12
|
+
msg.message_thread_id
|
|
Binary file
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: xync-bot
|
|
3
|
-
Version: 0.2
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Telegram bot with web app for xync net
|
|
5
5
|
Author-email: Artemiev <mixartemev@gmail.com>
|
|
6
|
-
License:
|
|
6
|
+
License: EULA
|
|
7
7
|
Project-URL: Homepage, https://gitlab.com/xync/back/tg-bot
|
|
8
8
|
Project-URL: Repository, https://gitlab.com/xync/back/tg-bot
|
|
9
9
|
Keywords: aiogram,xync-net
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.12
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
-
Requires-Dist: aiogram
|
|
13
|
-
Requires-Dist: python-dotenv
|
|
14
|
-
Requires-Dist: xn-api
|
|
15
12
|
Requires-Dist: xync-schema
|
|
16
|
-
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: pytest; extra == "dev"
|
|
15
|
+
Requires-Dist: python-dotenv; extra == "dev"
|
|
16
|
+
Requires-Dist: build; extra == "dev"
|
|
17
|
+
Requires-Dist: twine; extra == "dev"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
xync_bot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
xync_bot/shared.py,sha256=MlKkTrsT29l7fF6-qAN9FO14cSuXuOuYxbNY5F4S2w4,137
|
|
3
|
+
xync_bot/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
xync_bot/handlers/main.py,sha256=WOaPXjsZ40xUPZi6EHeew-ttee_qxLACt1uVjPC0Ll0,9565
|
|
5
|
+
xync_bot/handlers/order.py,sha256=ZKWDLyiWrXzcR-aHKLBTBCACwp-P0Vvnr22T-EuLHaM,274
|
|
6
|
+
xync_bot/handlers/vpn.py,sha256=qKK55UrjEZeDvu7ljWXNUFBFgXTPTIEaCT2OAmKWky4,2219
|
|
7
|
+
xync_bot/handlers/xicon.png,sha256=O57_kvzhVcCXSoGYZ61m0dW9pizY6gxR8Yj5aeCP0RQ,429283
|
|
8
|
+
xync_bot-0.3.2.dist-info/METADATA,sha256=FwJVU_5hg8oePhgsNeCMiS3b3VThxcpOwLDGZIAh-EE,575
|
|
9
|
+
xync_bot-0.3.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
10
|
+
xync_bot-0.3.2.dist-info/top_level.txt,sha256=O2IjMc1ryAf0rwIXWohSNT5Kzcs9johgKRDz8lCC0rs,9
|
|
11
|
+
xync_bot-0.3.2.dist-info/RECORD,,
|
xync_bot-0.2.10.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
xync_bot/__init__.py,sha256=A4PNsNVDgj5Cg4nIAhyhWbWLODalM3xQyrAzM6Cl2n0,1238
|
|
2
|
-
xync_bot/shared.py,sha256=MlKkTrsT29l7fF6-qAN9FO14cSuXuOuYxbNY5F4S2w4,137
|
|
3
|
-
xync_bot/handlers/__init__.py,sha256=lGPndTeEl1oLFMzFMtKNG2XLL8IecUFj1YIGzkZ55M8,78
|
|
4
|
-
xync_bot/handlers/main.py,sha256=AfWoTjBk_kzZCkR_7XfWYzWT2KV9ni_7TguRiJzxGcg,5757
|
|
5
|
-
xync_bot/handlers/vpn.py,sha256=qKK55UrjEZeDvu7ljWXNUFBFgXTPTIEaCT2OAmKWky4,2219
|
|
6
|
-
xync_bot-0.2.10.dist-info/METADATA,sha256=1CsOEupFK5oWlKfBtCFbqDmqUGT9yYAj4gPnTCClVAI,473
|
|
7
|
-
xync_bot-0.2.10.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
8
|
-
xync_bot-0.2.10.dist-info/top_level.txt,sha256=O2IjMc1ryAf0rwIXWohSNT5Kzcs9johgKRDz8lCC0rs,9
|
|
9
|
-
xync_bot-0.2.10.dist-info/RECORD,,
|
|
File without changes
|