Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2019
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.57 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. import json
  4. import logging
  5. import os
  6. import random
  7. import time
  8. import traceback
  9. from collections import defaultdict
  10. from typing import List
  11.  
  12. import requests
  13. import vk_api
  14. from django.conf import settings
  15. from vk_api.bot_longpoll import VkBotEventType, VkBotLongPoll, VkBotMessageEvent
  16.  
  17. from api.models import VkAccount, VkChat
  18. from NetworkDiary import exceptions
  19. from vk_bot.Bot.logging import logs_init
  20. from vk_bot.Bot.objects.api_manager import ApiManager
  21. from vk_bot.Bot.objects.event_manager import EventManager, ThreadWithKill
  22. from vk_bot.Bot.objects.keyboard import KeyBoard
  23. from vk_bot.Bot.objects.navigation_user import NavigatingUser
  24.  
  25.  
  26. class VkBot:
  27. def __init__(self, worker_timeout: int, max_events: int, service_bot=None):
  28. logs_init('bot.log', 'INFO')
  29.  
  30. self.__vk_session__ = vk_api.VkApi(token=settings.VK_BOT_TOKEN)
  31. self.long_poll = VkBotLongPoll(self.__vk_session__, settings.VK_GROUP_ID)
  32. self.api = self.__vk_session__.get_api()
  33.  
  34. self.__pages__ = {}
  35. self.__commands__ = {}
  36. self.__path_ts__ = os.path.join('.dm', 'ts.log')
  37. self.__ts__ = self.get_ts()
  38. self.__main_threads__ = []
  39.  
  40. self.users = defaultdict()
  41. self.api_manager = ApiManager()
  42. self.event_manager = EventManager(worker_timeout, max_events)
  43. self.worker_timeout = worker_timeout
  44. self.max_events = max_events
  45.  
  46. self.status = False
  47.  
  48. self.service_tg_bot = service_bot
  49.  
  50. logging.info('vk_bot activated')
  51.  
  52. def send_message(self, user_id: int or str,
  53. text: str = None,
  54. keyboard: KeyBoard = None,
  55. user_ids: List = None,
  56. peer_id: int or str = None,
  57. lat: float = None, lon: float = None,
  58. attachment: List = None,
  59. forward_messages: List = None,
  60. sticker_id: int = None,
  61. dont_parse_links: bool = False,
  62. back=False):
  63. return self.api_manager.method(
  64. 'messages.send',
  65. user_id=None if peer_id else user_id,
  66. peer_id=peer_id if peer_id else user_id,
  67. user_ids=','.join(map(str, user_ids)) if user_ids else None,
  68. message=text,
  69. lat=lat, lon=lon,
  70. attachment=','.join(map(str, attachment)) if attachment else None,
  71. forward_messages=','.join(
  72. map(str, forward_messages)) if forward_messages else None,
  73. sticker_id=sticker_id,
  74. random_id=random.randint(10 ** 8, 10 ** 10),
  75. group_id=settings.VK_GROUP_ID,
  76. keyboard=keyboard.get() if keyboard else None,
  77. dont_parse_links=int(dont_parse_links),
  78. back=back
  79. )
  80.  
  81. def edit_message(self, user_id: int or str,
  82. message_id: int,
  83. text: str = None,
  84. keyboard: KeyBoard = None,
  85. lat: float = None, lon: float = None,
  86. attachment: List = None,
  87. forward_messages: List = None,
  88. sticker_id: int = None):
  89. return self.api_manager.method(
  90. 'messages.edit',
  91. peer_id=user_id,
  92. message_id=message_id,
  93. message=text,
  94. lat=lat, lon=lon,
  95. attachment=','.join(map(str, attachment)) if attachment else None,
  96. forward_messages=','.join(map(str, forward_messages)) if forward_messages else None,
  97. sticker_id=sticker_id,
  98. random_id=random.randint(10 ** 8, 10 ** 10),
  99. group_id=settings.VK_GROUP_ID,
  100. keyboard=keyboard.get() if keyboard else None
  101. )
  102.  
  103. def get_ts(self):
  104. try:
  105. with open(self.__path_ts__) as file:
  106. return int(file.read())
  107.  
  108. except (BaseException, Exception):
  109. pass
  110.  
  111. def set_ts(self):
  112. while True:
  113. try:
  114. with open(self.__path_ts__, 'w') as file:
  115. file.write(str(self.__ts__))
  116. break
  117.  
  118. except (BaseException, Exception):
  119. pass
  120.  
  121. def upload_photo(self, path: str, peer_id: int):
  122. server = self.api_manager.method('photos.getMessagesUploadServer', peer_id=peer_id, back=True)
  123. data = requests.post(server['upload_url'], files={'photo': open(path, 'rb')}).json()
  124. photo = self.api_manager.method(
  125. 'photos.saveMessagesPhoto',
  126. photo=data['photo'],
  127. server=data['server'],
  128. hash=data['hash'],
  129. back=True
  130. )[0]
  131. return 'photo{}_{}'.format(photo['owner_id'], photo['id'])
  132.  
  133. def upload_doc(self, path: str, peer_id: int):
  134. server = self.api_manager.method('docs.getMessagesUploadServer', peer_id=peer_id, back=True)
  135. data = requests.post(server['upload_url'], files={'file': open(path, 'rb')}).json()
  136.  
  137. doc = self.api_manager.method(
  138. 'docs.save',
  139. file=data['file'],
  140. title=path.split('/')[-1],
  141. back=True
  142. )['doc']
  143. return 'doc{}_{}'.format(doc['owner_id'], doc['id'])
  144.  
  145. @staticmethod
  146. def verify_chat(peer_id: int):
  147. VkChat.objects.get_or_create(peer_id=peer_id)
  148.  
  149. def verify_user(self, user_id: int):
  150. vk_account, _ = VkAccount.objects.get_or_create(user_id=user_id)
  151.  
  152. if user_id in self.users:
  153. return self.users[user_id]
  154.  
  155. user = NavigatingUser(user_id, vk_account=vk_account, user=vk_account.active_user)
  156. self.users[user_id] = user
  157. return user
  158.  
  159. def user_message(self, user: NavigatingUser, event: VkBotMessageEvent, status):
  160. raw_object = event.raw['object']
  161.  
  162. if type(raw_object.get('payload')) == str:
  163. payload = raw_object.get('payload')
  164. payload = json.loads(payload) if payload else {'button': None}
  165. raw_object['payload'] = payload
  166.  
  167. if status == 'message':
  168. self.__pages__[user.page[0]](user, raw_object)
  169.  
  170. elif status == 'command':
  171. command = raw_object['text'].split()[0]
  172.  
  173. if command in self.__commands__:
  174. self.__commands__[command](user, raw_object)
  175.  
  176. else:
  177. self.send_message(user.user_id, "Неизвестная команда 😄")
  178.  
  179. else:
  180. raise TypeError('Unknown status: "{}"'.format(status))
  181.  
  182. def chat_message(self, user: NavigatingUser, event: VkBotMessageEvent):
  183. chat_handler = getattr(self, 'chat_handler', None)
  184. chat_handler(user, event.raw['object'])
  185.  
  186. def event_processing(self):
  187. while self.status:
  188. self.event_manager.work(self.event_handler)
  189. time.sleep(0.05)
  190.  
  191. def api_processing(self):
  192. while self.status:
  193. self.api_manager.send(self.api)
  194. time.sleep(0.05)
  195.  
  196. def start_polling(self):
  197. while self.status:
  198. self.long_poll.ts = self.__ts__ if self.__ts__ is not None else self.long_poll.ts
  199.  
  200. logging.info('Long Polling Server starting...')
  201.  
  202. for event in self.long_poll.listen():
  203. self.__ts__ = self.long_poll.ts
  204. self.event_manager.add_event(event)
  205.  
  206. def error_handler(self, func):
  207. while self.status:
  208. try:
  209. func()
  210.  
  211. except KeyboardInterrupt:
  212. print('Exit...')
  213. self.quit()
  214.  
  215. except (BaseException, Exception):
  216. print(traceback.format_exc())
  217.  
  218. if self.service_tg_bot is not None:
  219. msg = 'VK BOT\n\n{}'.format(traceback.format_exc())
  220. self.service_tg_bot.send_message(settings.TG_ADMIN_ID, msg)
  221.  
  222. def run(self):
  223. logging.info('Start polling...')
  224.  
  225. self.status = True
  226.  
  227. self.__main_threads__.append(
  228. ThreadWithKill(target=self.error_handler, args=[self.start_polling], daemon=True)
  229. )
  230. self.__main_threads__.append(
  231. ThreadWithKill(target=self.error_handler, args=[self.event_processing], daemon=True)
  232. )
  233. self.__main_threads__.append(
  234. ThreadWithKill(target=self.error_handler, args=[self.api_processing], daemon=True)
  235. )
  236.  
  237. for thread in self.__main_threads__:
  238. thread.start()
  239.  
  240. def quit(self):
  241. self.status = False
  242.  
  243. for thread in self.__main_threads__:
  244. thread.kill()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement