Advertisement
Guest User

Untitled

a guest
Jul 13th, 2018
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.58 KB | None | 0 0
  1. #!/usr/bin/env python3.4
  2. import os
  3. import sys
  4. import config
  5. import db
  6. import time
  7. import datetime
  8. import vk_api
  9. import telebot
  10. import threading
  11. import urllib.request as ur
  12. from PIL import Image # Для преобразования изображений из webp в PNG
  13.  
  14. config.initConfig()
  15.  
  16. module = sys.modules[__name__]
  17.  
  18. # Код настоятельно рекомендуется читать снизу вверх!
  19.  
  20. # _______ _
  21. # |__ __| | |
  22. # | | ___ ___| |__
  23. # | |/ _ \/ __| '_ \
  24. # | | __/ (__| | | |
  25. # |_|\___|\___|_| |_|
  26. #
  27. # Технические функции
  28.  
  29. # Получаем текущее время
  30. def current_time():
  31. delta = datetime.timedelta( hours=3 )
  32. utc = datetime.timezone.utc
  33. fmt = '%H:%M:%S'
  34. time = ( datetime.datetime.now(utc) + delta )
  35. timestr = time.strftime(fmt)
  36. return timestr
  37.  
  38. # Получение имени пользователя
  39. def GetUserName( msg ):
  40. dataname = module.vk.users.get( user_ids = msg.get('user_id' ) )
  41. UserName = str ( dataname[0]['first_name'] + ' ' + dataname[0]['last_name'] )
  42. return UserName
  43.  
  44. # Проверка на наличие аттачментов в сообщении
  45. def CheckAttachments( msg, idd ):
  46. if not( msg.get( 'attachments' ) ):
  47. return False
  48. TransferAttachmentsToTelegram( idd, getAttachments( msg ) )
  49. return True
  50.  
  51. # Получаем аттачменты из сообщения ВК
  52. def getAttachments( msg ):
  53.  
  54. AttachList = []
  55.  
  56. for att in msg['attachments'][0:]:
  57.  
  58. AttType = att.get( 'type' )
  59.  
  60. Attachment = att[AttType]
  61.  
  62. if AttType == 'photo': # Проверка на тип фотографии
  63.  
  64. # Различные типы фото
  65. if Attachment.get( 'photo_2560' ):
  66. attachments = Attachment.get( 'photo_2560' )
  67. elif Attachment.get( 'photo_1280' ):
  68. attachments = Attachment.get( 'photo_1280' )
  69. elif Attachment.get( 'photo_604' ):
  70. attachments = Attachment.get( 'photo_604' )
  71. elif Attachment.get( 'photo_130' ):
  72. attachments = Attachment.get( 'photo_130' )
  73. elif Attachment.get( 'photo_75' ):
  74. attachments = Attachment.get( 'photo_75' )
  75.  
  76. elif AttType == 'doc': # Проверка на тип документа:
  77. # Про типы документов можно узнать тут: https://vk.com/dev/objects/doc
  78. DocType = Attachment.get( 'type' )
  79. if DocType != 3 and DocType != 4 and DocType != 5:
  80. AttType = 'file'
  81. if Attachment.get( 'url' ):
  82. attachments = Attachment.get( 'url' )
  83.  
  84. elif AttType == 'sticker': # Проверка на стикеры:
  85. # Можно 256 или 512, но будет слишком огромная пикча
  86. if Attachment.get( 'photo_128' ):
  87. attachments = Attachment.get( 'photo_128' )
  88.  
  89. elif AttType == 'audio':
  90. if Attachment.get( 'url' ):
  91. attachments = Attachment.get( 'url' )
  92.  
  93. elif AttType == 'video':
  94.  
  95. OwnerId = str( Attachment.get( 'owner_id' ) )
  96. VideoId = str( Attachment.get( 'id' ) )
  97. Accesskey = str( Attachment.get( 'access_key' ) )
  98.  
  99. FullURL = str( OwnerId + '_' + VideoId + '_' + Accesskey)
  100.  
  101. attachments = module.vk.video.get(videos = FullURL )['items'][0].get('player')
  102.  
  103. # Неизвестный тип?
  104. else:
  105.  
  106. attachments = None
  107.  
  108. AttachList.append( { 'type':AttType,
  109. 'link':attachments } )
  110.  
  111. #print( AttachList )
  112.  
  113. return AttachList
  114.  
  115. # Проверка чата ВК на различные события
  116. def CheckEvents( msg, chatid ):
  117.  
  118. if not( msg.get( 'action' ) ):
  119. return None # И так сойдёт
  120.  
  121. Event = msg.get( 'action' )
  122. UserName = GetUserName( msg )
  123. time = current_time()
  124.  
  125. # Ниже проверям наш чат на различные события
  126. # См. https://vk.com/dev/objects/message
  127.  
  128. if Event == 'chat_title_update':
  129. Object = str( msg.get( 'action_text' ) )
  130. mbody = " *** " + UserName + " изменил(а) название беседы на " + Object + " ***"
  131. TransferMessagesToTelegram( time, chatid, None, mbody, None )
  132.  
  133. elif Event == 'chat_invite_user':
  134. dataname = module.vk.users.get( user_ids = msg.get( 'action_mid' ) )
  135. Object = str ( dataname[0]['first_name'] + ' ' + dataname[0]['last_name'] )
  136. mbody = " *** " + UserName + " пригласил(а) в беседу " + Object + " ***"
  137. TransferMessagesToTelegram( time, chatid, None, mbody, None )
  138.  
  139. elif Event == 'chat_kick_user':
  140. dataname = module.vk.users.get( user_ids = msg.get( 'action_mid' ) )
  141. Object = str ( dataname[0]['first_name'] + ' ' + dataname[0]['last_name'] )
  142. mbody = " *** " + UserName + " кикнул(а) из беседы " + Object + " ***"
  143. TransferMessagesToTelegram( time, chatid, None, mbody, None )
  144.  
  145. elif Event == 'chat_photo_update':
  146. Object = str( msg.get( 'photo_200' ) )
  147. mbody = " *** " + UserName + " обновил(а) фото беседы: ***"
  148. TransferMessagesToTelegram( time, chatid, None, mbody, None )
  149.  
  150. elif Event == 'chat_photo_remove':
  151. mbody = " *** " + UserName + " удалил(а) фото беседы! ***"
  152. TransferMessagesToTelegram( time, chatid, None, mbody, None )
  153.  
  154. elif Event == 'chat_create':
  155. print( 'Беседа была создана!' )
  156.  
  157. return True
  158.  
  159. # Проверка на наличие перешлённых сообщений
  160. def GetFwdMessages( msg, idd ):
  161.  
  162. if not( msg.get( 'fwd_messages' ) ):
  163. return None # И так сойдёт
  164.  
  165. FwdList = []
  166.  
  167. FwdMsg = msg.get( 'fwd_messages' )
  168.  
  169. while not FwdMsg is None:
  170.  
  171. UserName = GetUserName( FwdMsg[0] )
  172.  
  173. FwdList.append( { 'body':FwdMsg[0].get( 'body' ), 'UserName':UserName } )
  174.  
  175. CheckAttachments( FwdMsg[0], idd )
  176.  
  177. FwdMsg = FwdMsg[0].get( 'fwd_messages' )
  178.  
  179. #print( FwdList )
  180.  
  181. return FwdList
  182.  
  183. # _____ _ _ _
  184. # | __ \ | (_) | |
  185. # | |__) |___ __| |_ _ __ ___ ___| |_ ___
  186. # | _ // _ \/ _` | | '__/ _ \/ __| __/ __|
  187. # | | \ \ __/ (_| | | | | __/ (__| |_\__ \
  188. # |_| \_\___|\__,_|_|_| \___|\___|\__|___/
  189. #
  190. # Функции, принимающие и отправляющие сообщения ВК <==> Telegram
  191.  
  192. def CheckRedirect_vk( msg ):
  193.  
  194. #print( msg )
  195.  
  196. userid = str( msg.get( 'user_id' ) )
  197. chatid = str( msg.get( 'chat_id' ) )
  198.  
  199. #print( str( config.getCell( 'vk_' + chatid) ) )
  200.  
  201. # Сделано на костылях, это я знаю
  202. # Возможно, когда-нибудь я займусь оптимизацией кода....
  203. # ( Когда-нибудь... )
  204.  
  205. if not config.getCell( 'vk_' + chatid ) is None:
  206.  
  207. ForwardMessage = GetFwdMessages( msg, chatid )
  208.  
  209. time = current_time()
  210. UserName = GetUserName( msg )
  211. mbody = msg.get( 'body' )
  212.  
  213. # Чтобы при событии не посылалось пустое сообщение
  214. if CheckEvents( msg, chatid ) is None:
  215. TransferMessagesToTelegram( time, chatid, UserName, mbody, ForwardMessage )
  216.  
  217. # Проверка на аттачменты, пересланные сообщения, видео...
  218. if ForwardMessage is None:
  219. CheckAttachments( msg, chatid )
  220.  
  221. return False
  222.  
  223. elif not config.getCell( 'vk_' + userid ) is None:
  224.  
  225. ForwardMessage = GetFwdMessages( msg, userid )
  226.  
  227. time = current_time()
  228. UserName = GetUserName( msg )
  229. mbody = msg.get( 'body' )
  230.  
  231. TransferMessagesToTelegram( time, userid, UserName, mbody, ForwardMessage )
  232.  
  233. # Проверка на аттачменты, пересланные сообщения, видео...
  234. # Проверка сделана, чтобы исключить повтор картинки
  235. if ForwardMessage is None:
  236. CheckAttachments( msg, userid )
  237.  
  238. return False
  239.  
  240. def TransferMessageToVK( chatid, text, Attachment ):
  241.  
  242. if Attachment is None:
  243.  
  244. try:
  245. time = current_time()
  246. #user = m.from_user.first_name + ' ' + m.from_user.last_name;
  247. NiceText = str('[' + time + ']' + ' | ' + ': ' + text )
  248. module.vk.messages.send( chat_id = config.getCell( 't_' + chatid ), message = NiceText )
  249. except vk_api.ApiError as error_msg:
  250. module.vk.messages.send( user_id = config.getCell( 't_' + chatid ), message = NiceText )
  251. #print( 'Сообщение успешно отправлено! ( ' + text + ' )' )
  252.  
  253. else:
  254.  
  255. GetSticker = db.CheckSticker( Attachment )
  256.  
  257. # Если стикер не найден в БД
  258. if GetSticker is None:
  259. StickerURL = 'https://api.telegram.org/file/bot{0}/{1}'.format( config.getCell( 'telegram_token' ), Attachment )
  260. SaveSticker( StickerURL, Attachment )
  261. GetSticker = db.CheckSticker( Attachment )
  262.  
  263. #print( GetSticker )
  264.  
  265. try:
  266. module.vk.messages.send( chat_id = config.getCell( 't_' + chatid ), message = "", attachment = GetSticker )
  267. except vk_api.ApiError as error_msg:
  268. module.vk.messages.send( user_id = config.getCell( 't_' + chatid ), message = "", attachment = GetSticker )
  269.  
  270. return False
  271.  
  272. def CheckRedirect_telegram( chatid, text, Attachment ):
  273. if not config.getCell( 't_' + chatid ) is None:
  274. TransferMessageToVK( chatid, text, Attachment )
  275. return False
  276.  
  277. # Посылаем простые сообщения в Telegram
  278. # Идея: сделать в будущем наклонные столбики, теперь главное не забыть
  279. def TransferMessagesToTelegram( time, idd, UserName, mbody, FwdList ):
  280.  
  281. # Условие выполняется в случае какого-либо события
  282. if UserName is None:
  283. module.bot.send_message( config.getCell( 'vk_' + idd ), str( mbody ) )
  284. return False
  285.  
  286. NiceText = str('[' + time + ']' + ' | ' + UserName + ': ' + mbody )
  287.  
  288. if not FwdList is None:
  289.  
  290. ForwardText = ''
  291.  
  292. for f in FwdList[0:]:
  293. ForwardText = ForwardText + str( ' | ' + f.get( 'UserName' ) + ':' + ' ' + f.get( 'body' ) + ' \n\n' )
  294.  
  295. module.bot.send_message( config.getCell( 'vk_' + idd ), NiceText + '\n\n' + ForwardText )
  296.  
  297. else:
  298. module.bot.send_message( config.getCell( 'vk_' + idd ), NiceText )
  299.  
  300. # Посылаем аттачменты в Telegram
  301. def TransferAttachmentsToTelegram ( idd, attachments ):
  302.  
  303. for j in attachments[0:]:
  304.  
  305. AttType = j.get( 'type' )
  306. Link = j.get( 'link' )
  307.  
  308. if AttType == 'photo' or AttType == 'sticker':
  309. module.bot.send_photo( config.getCell( 'vk_' + idd ), Link )
  310.  
  311. elif AttType == 'doc' or AttType == 'gif' or AttType == 'audio':
  312. module.bot.send_document( config.getCell( 'vk_' + idd ), Link )
  313.  
  314. elif AttType == 'file':
  315. module.bot.send_message( config.getCell( 'vk_' + idd ), Link )
  316.  
  317. elif AttType == 'video':
  318.  
  319. # Потому что в ВК не может отправить полную ссылку на файл видео -_-
  320. module.bot.send_message( config.getCell( 'vk_' + idd ), Link )
  321.  
  322. else:
  323. module.bot.send_message( config.getCell( 'vk_' + idd ), '( Неизвестный тип аттачмента )' )
  324.  
  325. # __ ___
  326. # \ \ / / |
  327. # \ \ / /| | __
  328. # \ \/ / | |/ /
  329. # \ / | <
  330. # \/ |_|\_\
  331. #
  332. #
  333.  
  334. # При двухфакторной аутентификации вызывается эта функция
  335. def auth_handler():
  336.  
  337. key = input("Enter authentication code: ")
  338. # True - сохранить, False - не сохранять
  339. remember_device = True
  340.  
  341. return key, remember_device
  342.  
  343. # Каптча
  344. def captcha_handler(captcha):
  345. key = input( "Enter Captcha {0}: ".format( captcha.get_url() ) ).strip()
  346. return captcha.try_again(key)
  347.  
  348. def init_vk():
  349.  
  350. login = config.getCell( 'vk_login' )
  351. password = config.getCell( 'vk_password' )
  352.  
  353. print( "login in vk as: " + login )
  354.  
  355. global vk_session
  356.  
  357. vk_session = vk_api.VkApi( login, password, auth_handler=auth_handler, captcha_handler=captcha_handler )
  358.  
  359. try:
  360. vk_session.auth()
  361. except vk_api.AuthError as error_msg:
  362. print( error_msg )
  363.  
  364. module.vk = vk_session.get_api() # Важная штука
  365.  
  366. input_vk()
  367.  
  368. def input_vk():
  369.  
  370. while True:
  371.  
  372. try:
  373. #rawMessages = module.vk.messages.getConversations( count = config.getCell('vk_msgForPick') )
  374. rawMessages = module.vk.messages.getDialogs(offset = 0, count = config.getCell('vk_msgForPick') )
  375. for msg in rawMessages['items'][0]['message']:
  376. if int(msg['read_state']) == 0:
  377. if not msg.get( 'chat_id' ) is None:
  378. module.vk.messages.markAsRead(messages_ids = msg['id'], peer_id = 2000000000 + int(msg['chat_id']))
  379. else:
  380. module.vk.messages.markAsRead(messages_ids = msg['id'], peer_id = int(msg['user_id']))
  381.  
  382. CheckRedirect_vk( msg )
  383.  
  384. # Чтобы не вылетало, а работало дальше
  385. except BaseException as e:
  386. print( e )
  387. continue
  388.  
  389.  
  390. # _______ _
  391. # |__ __| | |
  392. # | | ___| | ___ __ _ _ __ __ _ _ __ ___
  393. # | |/ _ \ |/ _ \/ _` | '__/ _` | '_ ` _ \
  394. # | | __/ | __/ (_| | | | (_| | | | | | |
  395. # |_|\___|_|\___|\__, |_| \__,_|_| |_| |_|
  396. # __/ |
  397. # |___/
  398.  
  399.  
  400. def listener( messages ):
  401. for m in messages:
  402.  
  403. if m.content_type == 'text':
  404.  
  405. # На команду 'Дай ID' кидает ID чата
  406. if m.text == 'Дай ID':
  407. module.bot.send_message( m.chat.id, str( m.chat.id ) )
  408. continue
  409.  
  410. if m.text == 'Дай NAME':
  411. user = m.from_user.first_name + ' ' + m.from_user.last_name;
  412. module.bot.send_message( m.chat.id, str( user ) )
  413. continue
  414.  
  415. if m.text == 'пашёл нахуй':
  416. msone = 'нет ты пашёл нахуй';
  417. module.bot.send_message( m.chat.id, str( msone ) )
  418. continue
  419.  
  420. if m.text == 'время':
  421. time = current_time();
  422. module.bot.send_message( m.chat.id, str( time ) )
  423. continue
  424.  
  425. CheckRedirect_telegram( str( m.chat.id ), str( m.text ), None )
  426.  
  427. elif m.content_type == 'sticker':
  428.  
  429. if config.getCell( 'vk_EnableStickers' ) != 1:
  430. return False
  431.  
  432. # Убираем ненужный на конце формат 'webp'
  433. FilePath = module.bot.get_file( m.sticker.file_id ).file_path
  434.  
  435. CheckRedirect_telegram( str( m.chat.id ), str( m.text ), str( FilePath ) )
  436.  
  437.  
  438. def init_telegram():
  439. module.bot = telebot.TeleBot( config.getCell( 'telegram_token' ) )
  440. module.bot.remove_webhook()
  441. print( "Successfully loginned in telegram!")
  442. input_telegram()
  443.  
  444. def input_telegram():
  445.  
  446. if config.getCell('telegram_useProxy') == 1:
  447. Proxy_type = str( config.getCell('p_type') )
  448. Proxy_UserInfo = str( config.getCell('p_user') + ':' + config.getCell('p_password') )
  449. Proxy_Data = str( config.getCell('p_host') + ':' + config.getCell('p_port') )
  450. telebot.apihelper.proxy = {
  451. 'http': '%s://%s@%s' % ( Proxy_type, Proxy_UserInfo, Proxy_Data ),
  452. 'https': '%s://%s@%s' % ( Proxy_type, Proxy_UserInfo, Proxy_Data )
  453. }
  454.  
  455. module.bot.set_update_listener(listener)
  456. while True: # Костыль на случай timeout'a
  457. try:
  458. module.bot.polling(none_stop=True)
  459. except:
  460. continue
  461.  
  462. # ______ _
  463. # | ____| | |
  464. # | |____ _____ _ __ | |_ ___
  465. # | __\ \ / / _ \ '_ \| __/ __|
  466. # | |___\ V / __/ | | | |_\__ \
  467. # |______\_/ \___|_| |_|\__|___/
  468. #
  469. # Проверка на различные события
  470.  
  471. # _____ _ _ _
  472. # / ____| | (_) | |
  473. # | (___ | |_ _ ___| | _____ _ __ ___
  474. # \___ \| __| |/ __| |/ / _ \ '__/ __|
  475. # ____) | |_| | (__| < __/ | \__ \
  476. # |_____/ \__|_|\___|_|\_\___|_| |___/
  477. #
  478. #
  479.  
  480. # Загрузка стикеров в ВК
  481. def AddStickerIntoVK( path, Sticker ):
  482.  
  483. StickerList = []
  484. OurFile = path + Sticker
  485.  
  486. upload = vk_api.VkUpload( vk_session )
  487. photo = upload.photo( OurFile + ".png", album_id = config.getCell( 'vk_album_id' ) )
  488.  
  489. if config.getCell( 'vk_detelestickers' ) == 1:
  490. os.remove( OurFile + ".png" )
  491.  
  492. OurVK = 'photo{}_{}'.format( photo[0]['owner_id'], photo[0]['id'] )
  493.  
  494. StickerList.append( { 'sticker_t':OurFile,
  495. 'sticker_vk':OurVK } )
  496.  
  497. return StickerList
  498.  
  499. def SaveSticker( StickerURL, Attachment ):
  500.  
  501. Attachment = Attachment.split('/')
  502.  
  503. content = ur.urlopen( StickerURL ).read()
  504.  
  505. path = Attachment[0] + '/'
  506. if not os.path.exists( path ):
  507. os.makedirs( path )
  508.  
  509. # Перекодирование из webp в png
  510.  
  511. ImageWebp = path + Attachment[1]
  512.  
  513. out = open( ImageWebp, 'wb' )
  514. out.write( content )
  515. out.close()
  516.  
  517. img = Image.open(ImageWebp)
  518.  
  519. if config.getCell( 'vk_sticker_EnableScale' ) == 1:
  520. scale = config.getCell( 'vk_sticker_size' )
  521. img.thumbnail((scale, scale))
  522. img.save( ImageWebp + ".png", "PNG")
  523. os.remove( ImageWebp )
  524.  
  525. #print( 'Sticker saved!' )
  526.  
  527. Stickers = AddStickerIntoVK( path, Attachment[1] )
  528. db.AddStickerIntoDb( Stickers )
  529.  
  530. # Разработчикам на заметку:
  531. # Telegram та ещё поехавшая вещь, иногда аттачменты идут с расширением файла, иногда - без него
  532. # Из-за этого я долго не мог понять, почему одни стикеры отправляются нормально, а другие - выдают ошибку при отправке
  533.  
  534. # ______ _ _
  535. # | ____(_) | |
  536. # | |__ _ _ __ __ _| | ___
  537. # | __| | | '_ \ / _` | |/ _ \
  538. # | | | | | | | (_| | | __/
  539. # |_| |_|_| |_|\__,_|_|\___|
  540. #
  541. # Пихаем функции в потоки
  542.  
  543. t1 = threading.Thread( target=init_vk )
  544. t2 = threading.Thread( target=init_telegram )
  545.  
  546. t1.start()
  547. t2.start()
  548. t1.join()
  549. t2.join()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement