-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
309 lines (272 loc) · 11.2 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
import logging
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher.filters import ChatTypeFilter
from sqlalchemy import func
from config import TOKEN, OWNER, GROUP
from functions import (
get_user,
new_offer_keyboard,
published_offer_keyboard,
group_keyboard,
add_response,
id_and_text,
responses_data,
new_media_keyboard,
published_media_keyboard
)
from models import UserModel, OfferModel, ResponseModel, CommentModel, session
logging.basicConfig(level=logging.INFO)
bot = Bot(token=TOKEN)
dp = Dispatcher(bot)
# TODO: caption is required for photo and video
@dp.message_handler(commands=['start'])
async def start(message: types.Message):
return await message.answer("В сообщении следует указать:\n - Вид работы\n - Адрес\n - Готов заплатить\n - Фото или видео\n - Дополнительно\nОбратившись к нам мы максимально постараемся вам помочь в вашем деле!")
@dp.message_handler(commands=['chatid'])
async def send_welcome(message: types.Message):
chat_id = message.chat.id
await message.reply(f"Chat ID is\n{chat_id}")
@dp.message_handler(is_reply=True)
async def edit_offer_handler(message: types.Message):
"""
This function edit message in owner chat
"""
replied_message = message.reply_to_message
# send private message to customer
if not replied_message.reply_markup:
try:
customer_id, text = id_and_text(replied_message.text)
await bot.send_message(customer_id, text=message.text)
except:
try:
await message.reply(text='Похоже ты ответил не на то сообщение.\nНе доставленно')
except:
pass
# edit offer's discription
elif message.from_user.id == OWNER and replied_message.chat.id == OWNER:
offer_id, text = id_and_text(replied_message.text)
try:
responses_number = text[text.index('\nОткликнулось: '):]
except:
responses_number = ""
try:
await bot.edit_message_text(
text=f"[{offer_id}]\n{message.text}{responses_number}",
message_id=replied_message.message_id,
chat_id=OWNER,
reply_markup=replied_message.reply_markup
)
# if offer is published edit message in group as well
if replied_message.reply_markup.inline_keyboard[0][0]['callback_data'] == 'close':
await bot.edit_message_text(
text=f"[{replied_message.message_id}]\n{message.text}{responses_number}",
message_id=offer_id,
chat_id=GROUP,
reply_markup=group_keyboard()
)
session.query(OfferModel).filter_by(id=offer_id).update({'description': message.text})
session.commit()
except:
pass
await message.delete()
private_chat_filter = ChatTypeFilter(types.ChatType.PRIVATE)
@dp.message_handler(private_chat_filter)
async def communication(message: types.Message):
customer_id = message.from_user.id
username = message.from_user.username
full_name = message.from_user.full_name
# send customer message to owner so he can edit, publish or delete
await bot.send_message(OWNER, text=get_user(message), parse_mode="HTML")
await bot.send_message(OWNER, text="Пока что никто не откликнулся")
await bot.send_message(OWNER, text=f"[{message.from_id}]\n{message.text}", reply_markup=new_offer_keyboard())
data = {'id': customer_id, 'full_name': full_name, 'username': username}
obj = UserModel(**data)
session.merge(obj)
session.commit()
@dp.callback_query_handler(lambda query: query.data == "publish")
async def process_publish(query: types.CallbackQuery):
message_id = query.message.message_id
customer_id, text = id_and_text(query.message.text)
# reopen closed offer
try:
offer_post = await bot.edit_message_text(
chat_id=GROUP,
message_id=customer_id,
text=f"[{query.message.message_id}]\n{text}",
reply_markup=group_keyboard()
)
is_new_offer = False
# send new offer to group
except:
offer_post = await bot.send_message(
chat_id=GROUP,
text=f"[{query.message.message_id}]\n{text}",
reply_markup=group_keyboard()
)
is_new_offer = True
offer_id = offer_post.message_id
edited_text = f"[{offer_id}]\n{text}"
# change publish button to close button
await bot.edit_message_text(
text=edited_text,
chat_id=OWNER,
message_id=message_id,
reply_markup=published_offer_keyboard()
)
if is_new_offer:
db_offer = OfferModel(
id = offer_id,
customer_id = customer_id,
description = text,
date = query.message.date
)
session.add(db_offer)
session.commit()
await query.answer("Успешно опубилкованно", show_alert=True)
@dp.callback_query_handler(lambda query: query.data == "close")
async def process_close(query: types.CallbackQuery):
query_text = query.message.text
offer_id, text = id_and_text(query_text)
message_id = query.message.message_id
# remove respond button from offer in group
await bot.edit_message_text(
text=f"[{message_id}]\n{text}",
chat_id=GROUP,
message_id=offer_id
)
# change close button to publish button
await bot.edit_message_text(
text=query_text,
chat_id=OWNER,
message_id=message_id,
reply_markup=new_offer_keyboard()
)
@dp.callback_query_handler(lambda query: query.data == "edit")
async def process_edit(query: types.CallbackQuery):
text = "Сделай свайп на лево по сообщению и напиши свой вариант"
message = await query.answer(text=text, show_alert=True)
@dp.callback_query_handler(lambda query: query.data == "delete")
async def process_delete(query: types.CallbackQuery):
message_id = query.message.message_id
text = query.message.text
try:
responses_number = int(text[text.index('\nОткликнулось: ')+15:])
if responses_number > 0:
await query.answer("У этого предложения есть отклики. Удали в ручную", show_alert=True)
elif responses_number == 0:
await query.message.delete()
await bot.delete_message(chat_id=OWNER, message_id=message_id-1)
await bot.delete_message(chat_id=OWNER, message_id=message_id-2)
except:
await query.message.delete()
await bot.delete_message(chat_id=OWNER, message_id=message_id-1)
await bot.delete_message(chat_id=OWNER, message_id=message_id-2)
@dp.callback_query_handler(lambda query: query.data == "respond")
async def process_respond(query: types.CallbackQuery):
applicant_id = query.from_user.id
offer_id = query.message.message_id
username = query.from_user.username
full_name = query.from_user.full_name
data = {'id': applicant_id, 'full_name': full_name, 'username': username}
obj = UserModel(**data)
session.merge(obj)
session.commit()
obj = session.query(ResponseModel).filter_by(applicant_id=applicant_id, offer_id=offer_id)
try:
if obj.first().is_canceled:
obj.update({'is_canceled': 0})
session.commit()
await query.answer("Принято", show_alert=True)
else:
obj.update({'is_canceled': 1})
session.commit()
await query.answer("Отменено", show_alert=True)
except:
db_response = ResponseModel(
applicant_id=applicant_id,
offer_id=offer_id
)
session.add(db_response)
session.commit()
await query.answer("Принято", show_alert=True)
objs = session.query(UserModel, ResponseModel).outerjoin(ResponseModel).filter_by(offer_id=offer_id, is_canceled=0)
responses_number = objs.count()
responses_info = responses_data(objs) if responses_number else "Пока что никто не откликнулся"
# chage response's number in group message
text = add_response(query.message.text, responses_number)
await bot.edit_message_text(
text=text,
message_id=offer_id,
chat_id=GROUP,
reply_markup=query.message.reply_markup
)
# and update owner message
message_id, text = id_and_text(text)
await bot.edit_message_text(
text=responses_info,
message_id=message_id-1,
chat_id=OWNER,
parse_mode="HTML"
)
await bot.edit_message_text(
text=f"[{offer_id}]\n{text}",
message_id=message_id,
chat_id=OWNER,
reply_markup=published_offer_keyboard()
)
@dp.callback_query_handler(lambda query: query.data == 'media_publish')
async def process_media_publish(query: types.CallbackQuery):
message_id = query.message.message_id
# send new media to group
if query.message.photo:
file_id = query.message.photo[-1].file_id
media_post = await bot.send_photo(
chat_id=GROUP,
photo=file_id,
caption=query.message.caption
)
if query.message.video:
file_id = query.message.video.file_id
media_post = await bot.send_video(
chat_id=GROUP,
video=file_id,
caption=query.message.caption
)
# change publish button to close button
await bot.edit_message_reply_markup(
chat_id=OWNER,
message_id=message_id,
reply_markup=published_media_keyboard(media_post.message_id)
)
await query.answer("Успешно отправлено", show_alert=True)
@dp.callback_query_handler(lambda query: query.data.startswith(('media_delete')))
async def process_media_delete(query: types.CallbackQuery):
_, message_id = query.data.split()
# delete media from group
await bot.delete_message(chat_id=GROUP, message_id=int(message_id))
# change publish button to close button
await bot.edit_message_reply_markup(
chat_id=OWNER,
message_id=query.message.message_id,
reply_markup=new_media_keyboard()
)
await query.answer("Удалено из группы", show_alert=True)
@dp.message_handler(content_types=[
types.ContentType.PHOTO,
types.ContentType.VIDEO,
# types.ContentType.VIDEO_NOTE,
# types.ContentType.VOICE,
# types.ContentType.DOCUMENT,
# types.ContentType.AUDIO
]
)
async def handle_media(message: types.Message):
customer_id = message.from_user.id
if message.photo:
file_id = message.photo[-1].file_id
await bot.send_photo(chat_id=OWNER, photo=file_id, caption=message.caption, reply_markup=new_media_keyboard())
if message.video:
file_id = message.video.file_id
await bot.send_video(chat_id=OWNER, video=file_id, caption=message.caption, reply_markup=new_media_keyboard())
if __name__ == "__main__":
executor.start_polling(dp)