Advertisement
Guest User

Untitled

a guest
Nov 28th, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 22.88 KB | None | 0 0
  1. waimport socket
  2. import sys
  3. import re
  4. from time import sleep, time
  5. import errno
  6.  
  7. import pymysql.cursors
  8. import random
  9.  
  10. from btts import btts
  11.  
  12. from config import *
  13.  
  14.  
  15. tts = btts()
  16.  
  17. CHANNEL = 'sentdex'
  18.  
  19.  
  20.  
  21. # Connect to the database
  22. connection = pymysql.connect(host=IP,
  23.                              user=USERNAME,
  24.                              password=PASSWORD,
  25.                              db=DB,
  26.                              charset='utf8mb4',
  27.                              cursorclass=pymysql.cursors.DictCursor)
  28.  
  29. with connection.cursor() as cursor:
  30.     cursor.execute('SET NAMES utf8mb4')
  31.     cursor.execute('SET character_set_client="utf8mb4"')
  32.  
  33.    
  34. def modify_input(string):
  35.   tokenized = string.split(' ')
  36.   if tokenized[0] == '@Charles_the_AI':
  37.     string = ' '.join([i for i in tokenized[1:]])
  38.   if '@Charles_the_AI' in string:
  39.     string = string.replace('@Charles_the_AI','Charles')
  40.  
  41.   if '@charles_the_ai' in string:
  42.     string = string.replace('@charles_the_ai','Charles')
  43.  
  44.   if '@Charles_the_ai' in string:
  45.     string = string.replace('@Charles_the_ai','Charles')
  46.  
  47.   if '@Charles_The_AI' in string:
  48.     string = string.replace('@Charles_The_AI','Charles')
  49.  
  50.   if '@CharlestheAI' in string:
  51.     string = string.replace('@CharlestheAI','Charles')
  52.  
  53.   if '@charlestheai' in string:
  54.     string = string.replace('@charlestheai','Charles')
  55.  
  56.   if '@Charlestheai' in string:
  57.     string = string.replace('@Charlestheai','Charles')
  58.  
  59.   if '@CharlesTheAI' in string:
  60.     string = string.replace('@CharlesTheAI','Charles')
  61.  
  62.   if 'CharlesTheAI' in string:
  63.     string = string.replace('CharlesTheAI','Charles')
  64.   if 'charlestheai' in string:
  65.     string = string.replace('charlestheai','Charles')
  66.  
  67.   #string = re.sub(r"(?<=^|(?<=[^a-zA-Z0-9-_\\.]))@([A-Za-z]+[A-Za-z0-9_]+)","that person",string)
  68.  
  69.   string = string.strip()
  70.  
  71.   #string = string.replace('<3', '&lt;3')
  72.  
  73.   return string
  74.  
  75. def say_something(original,thing,user):
  76.     ##'''
  77.     ##engine = pyttsx3.init()
  78.     ##voices = engine.getProperty('voices')
  79.     ##for voice in voices:
  80.     ##engine.setProperty('voice', 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_EN-US_ZIRA_11.0')
  81.     ##print(voice.id)
  82.     ##engine.say('The quick brown fox jumped over the lazy dog.')
  83.     ##engine.runAndWait()
  84.     ##'''
  85.  
  86.     punc_dict = {"!":['exclaims','yells','shouts','cries','roars','hollers',],
  87.                 "?":['wonders','asks','inquires','is curious','wants to know'],
  88.                 ".":['says','states','declares','proclaims']}
  89.  
  90.  
  91.     try:
  92.         user_emote = random.choice(punc_dict[original[-1]])
  93.     except:
  94.         user_emote = random.choice(punc_dict['.'])
  95.  
  96.  
  97.    
  98.     #original = original.replace('&lt;3', '<3')
  99.     original = '{} {}: {}'.format(user, user_emote, original)
  100.  
  101.     tts.speak({
  102.       'phrases':[
  103.         {
  104.             'text': "{}".format(original),
  105.             'voice': 'Google UK English Female',
  106.         },
  107.         {
  108.             'text': "{}".format( thing.replace("$000","One million dollars").replace("0'0 '","{} centimeters".format(str(random.randrange(183,213)))).replace("00",str(random.randrange(1,99))).replace("0",str(random.randrange(0,9))).replace('00',str(random.randrange(11,99)))     ),
  109.             'voice': 'Google UK English Male',
  110.         }
  111.     ],
  112.       'source':'Twitch'
  113.       })
  114.    
  115.  
  116.    
  117.    
  118. def check_mentions(mentions):
  119.     for mention in mentions:
  120.         try:
  121.             with connection.cursor() as cursor:
  122.  
  123.                 # check to see if user has already asked this message in the last 10 minutes?
  124.                 # check to see if user has asked more than 30 questions in the last 3600 seconds
  125.  
  126.                 if 'charlestheai' in mention['message'].lower():
  127.  
  128.                     #mention['message'] = mention['message'].replace('<3', '&lt;3')
  129.                     print('Yes, a charles mention', mention['message'])
  130.  
  131.                     # check to see if someone recently said this same thing in the last 5 minutes
  132.                     sql = "SELECT `id` FROM `chat_nmt` WHERE `question`=%s AND `unix` > %s"
  133.                     cursor.execute(sql, (mention['message'],int(time()-300))) # last 5 minutes
  134.                     result1 = cursor.fetchone()
  135.  
  136.  
  137.                    
  138.                     # check to see if any one user has asked more than 30 questions in the last hour
  139.                     sql = "SELECT `id` FROM `chat_nmt` WHERE `source_id`=%s AND `unix` > %s"
  140.                     cursor.execute(sql, (mention['user'],int(time()-3600))) # last 5 minutes
  141.                     result2 = cursor.fetchall()
  142.  
  143.                     if result1 == None and len(result2)<=60:
  144.                         # Create a new record
  145.                         sql = "INSERT INTO `chat_nmt` (`unix`, `question`, `source`, `source_id`, `type`) VALUES (%s, %s, %s, %s, %s)"
  146.                         cursor.execute(sql, ( str(int(time())), mention['message'], 'twitch', mention['user'], 'twitch_mention'))
  147.             connection.commit()
  148.         except Exception as e:
  149.             print(str(e))
  150.  
  151.  
  152. def check_to_reply():
  153.     global last_msg
  154.  
  155.  
  156.    
  157.  
  158.  
  159.     unk_msgs = ['Hmm, I do not understand.',
  160.                 'Try asking in another way.',
  161.                 'I am confused with the question.',
  162.                 'I do not know how to answer']
  163.  
  164.     with connection.cursor() as cursor:
  165.         # check to see if that record exists:
  166.         sql = "SELECT `id`, `question`,`response`, `source_id`, `type` FROM `chat_nmt` WHERE `source` = 'twitch' and `responded` = 0 and `response` IS NOT NULL"
  167.         cursor.execute(sql)
  168.         results = cursor.fetchall()
  169.  
  170.  
  171.         replies = []
  172.         for result in results:
  173.             try:
  174.                 print(result)
  175.                 # Create a new record
  176.                 print(result)
  177.                 r_id = result['id']
  178.                 r_question = result['question']
  179.                 r_response = result['response']
  180.                 r_source_id = result['source_id']
  181.                 r_type = result['type']          
  182.                
  183.                 sql = "UPDATE chat SET `responded`=%s WHERE `id`=%s"
  184.                 cursor.execute(sql, ('1', r_id))
  185.                
  186.                 replies.append([r_source_id, r_question, r_response])
  187.  
  188.                 if '_UNK' not in r_response:
  189.                   say_something(modify_input(r_question),r_response, r_source_id)
  190.                   last_msg = time()
  191.  
  192.                 if '_UNK' in r_response:
  193.                   twitch.sendMessage("@{} {}".format(r_source_id, random.choice(unk_msgs)))
  194.                   last_msg = time()
  195.            
  196.  
  197.  
  198.                
  199.                
  200.  
  201.                
  202.  
  203.                
  204.             except Exception as e:
  205.                 print(str(e))
  206.     connection.commit()
  207.     return replies
  208.    
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.    
  220.  
  221. class Twitch():
  222.  
  223.     # socket settings
  224.     socket = {}
  225.     host = None
  226.     port = None
  227.     nickname = None
  228.     tiken = None
  229.     channel = None
  230.  
  231.     received_messages = []
  232.  
  233.     log_file = None
  234.  
  235.     DEBUG = True
  236.  
  237.     # init
  238.     def __init__(self, nickname, token, channel, log_file = 'twitchlog.txt', host = 'irc.chat.twitch.tv', port = 6667):
  239.  
  240.         # set properties
  241.         self.host = host
  242.         self.port = port
  243.         self.nickname = nickname
  244.         self.token = token
  245.         self.channel = channel
  246.         self.log_file = open(log_file, 'w')
  247.  
  248.         # connect
  249.         self.connect()
  250.  
  251.     # tick
  252.     def tick(self):
  253.         self.checkForNewData()
  254.         self.sendMessages()
  255.         self.ping()
  256.  
  257.     # connect to Twitch IRC server
  258.     def connect(self):
  259.        
  260.         self.info("Connecting to Twitch IRC server")
  261.  
  262.         # setup socket
  263.         self.socket = {
  264.             'name':                 "twitch-irc",
  265.             'socket':               socket.socket(socket.AF_INET, socket.SOCK_STREAM),
  266.             'buffer':               "",
  267.             'last_msg':             time(),
  268.             'last_ping_response':   time(),
  269.             'next_ping':            time() + 5,
  270.             'delimiter':            "\r\n",
  271.             'messages':             []
  272.         }
  273.  
  274.         # connect
  275.         self.socket['socket'].settimeout(5)
  276.         try:
  277.             self.socket['socket'].connect((self.host, self.port))
  278.         except IOError as e:
  279.             self.info("%s (%s)" % (e.errno, e.strerror), "ERROR:  ")
  280.             self.socket = None
  281.             return False
  282.         except:
  283.             self.info("Unexpected error: %s" % sys.exc_info()[0], "ERROR:  ")
  284.             self.socket = None
  285.             return False
  286.  
  287.         # set nonblocking connection
  288.         self.socket['socket'].setblocking(0)
  289.        
  290.         self.info("Connected")
  291.  
  292.         # log in
  293.         self.info("Logging in")
  294.         self.socketWrite("CAP REQ :twitch.tv/tags")
  295.         self.socketWrite("CAP REQ :twitch.tv/commands")
  296.         self.socketWrite("CAP END")
  297.         self.socketWrite("PASS oauth:%s" % self.token)
  298.         self.socketWrite("NICK %s" % self.nickname.lower())
  299.  
  300.         # wait for response
  301.         flag = False
  302.         for i in range(500):
  303.             sleep(0.01)
  304.  
  305.             # check if there is any response
  306.             data = self.socketRead()
  307.  
  308.             # if true
  309.             if data:
  310.  
  311.                 # parse data
  312.                 response = self.parseChatLine(data)
  313.  
  314.                 # we are logged in now
  315.                 if response['status'] == 'info' and not flag:
  316.                     self.info("Logged in")
  317.                     flag = True
  318.                     break
  319.  
  320.                 # Twitch returned error message
  321.                 elif response['status'] == 'error':
  322.                     self.info("Login failed", "ERROR:  ")
  323.                     self.socket = None
  324.                     return False
  325.  
  326.             # connection error?
  327.             elif data is not None:
  328.                 self.socket = None
  329.                 return False
  330.                
  331.         # after 5 seconds long loop if there is no response still - error
  332.         if not flag:
  333.             self.info("Login failed", "ERROR:  ")
  334.             self.socket = None
  335.             return False
  336.  
  337.         # join channel
  338.         self.info("Joining #%s" % self.channel)
  339.         self.socketWrite("JOIN #%s" % self.channel)
  340.  
  341.         # wait for response
  342.         flag = False
  343.         for i in range(500):
  344.             sleep(0.01)
  345.  
  346.             # check if there is any response
  347.             data = self.socketRead()
  348.  
  349.             # if true
  350.             if data:
  351.  
  352.                 # parse data
  353.                 response = self.parseChatLine(data)
  354.  
  355.                 # joined a channel
  356.                 if response['status'] == 'join' and not flag:
  357.                     self.info("Joined #%s" % self.channel)
  358.                     flag = True
  359.                     break
  360.  
  361.             # connection error?
  362.             elif data is not None:
  363.                 self.socket = None
  364.                 return False
  365.  
  366.         # after 5 seconds long loop if there is no response still - error
  367.         if not flag:
  368.             self.info("Joining failed", "ERROR:  ")
  369.             self.socket = None
  370.             return False
  371.  
  372.     # parse irc command        
  373.     def parseChatLine(self, line):
  374.  
  375.         # ping
  376.         if line == "PING :tmi.twitch.tv":
  377.             self.socketWrite("PONG :tmi.twitch.tv")
  378.             return {'status': 'ping'}
  379.  
  380.         # pong
  381.         elif "PONG tmi.twitch.tv" in line:
  382.             self.socket['last_ping_response'] = time()
  383.             return {'status': 'pong'}
  384.  
  385.         # parse line
  386.         line = re.search("(?:(?P<badges>[^\s]+) )?:(?P<host>[^\s]+) (?P<code>[^\s]+) (?P<info>[^\s]+)( (?P<message>.*))?", line)
  387.         if line:
  388.             message = line.groupdict().get('message', '')
  389.             message = message[1:] if message and message.startswith(":") else message  # drop first colon
  390.  
  391.             # join
  392.             if line.group('code') == "JOIN":
  393.                 return {'status': 'join'}
  394.  
  395.             # notice
  396.             elif line.group('code') == "NOTICE":
  397.                 self.info(message, "NOTICE: ")
  398.                 if message == "Login authentication failed":
  399.                     return {'status': 'error'}
  400.                 else:
  401.                     return {'status': 'notice'}
  402.  
  403.             # msg https://dev.twitch.tv/docs/v5/guides/irc/#privmsg-twitch-tags
  404.             elif line.group('code') == 'PRIVMSG':
  405.                 user = re.search("!(?P<user>.*?)@", line.group('host'))
  406.                 bits = re.search("bits=(?P<bits>.*?);", line.group('badges'))
  407.                 subscriber = re.search("subscriber=(?P<subscriber>.*?);", line.group('badges'))
  408.                 if bits and bits.group('bits'):
  409.                     return {'status': 'cheer', 'user': user.group('user'), 'message': message, 'bits': int(bits.group('bits'))}
  410.                 else:
  411.                     return {'status': 'message', 'user': user.group('user'), 'message': message, 'subscriber': bool(int(subscriber.group('subscriber')))}
  412.  
  413.             # sub or resub https://dev.twitch.tv/docs/v5/guides/irc/#usernotice-twitch-tags
  414.             elif line.group('code') == 'USERNOTICE':
  415.                 user = re.search("display-name=(?P<user>.*?);", line.group('badges'))
  416.                 if not user.group('user'):
  417.                     user = re.search("login=(?P<user>.*?);", line.group('badges'))
  418.                 wessage = re.search("system-msg=(?P<chatmessage>.*?);", line.group('badges'))
  419.                 if message is None:
  420.                     message = ''
  421.                 return {'status': 'sub', 'user': user.group('user'), 'message': message, 'chatmessage': str(chatmessage.group('chatmessage')).replace("\s", " ")}
  422.  
  423.             # info status
  424.             else:
  425.                 if str(line.group('code')).isnumeric():
  426.                     return {'status': 'info'}
  427.                 line.group('code').isnumeric()
  428.  
  429.         # unrecognized command    
  430.         return {'status': 'unrecognized'}
  431.    
  432.     # still connected?
  433.     def checkIfConnected(self):
  434.  
  435.         # if socket not exists
  436.         if not self.socket:
  437.  
  438.             # connection is lost
  439.             self.info("Connection to Twitch lost. Reconnecting in 5 seconds...", "ERROR:  ")
  440.             sleep(5)
  441.             self.connect()
  442.             if not self.socket:
  443.                 return False
  444.  
  445.         return True
  446.  
  447.     # check for incoming packets
  448.     def checkForNewData(self):
  449.  
  450.         # if socket exists
  451.         if self.socket:
  452.  
  453.             # grab all chat lines
  454.             while True:
  455.  
  456.                 # grab one chat line
  457.                 data = self.socketRead()
  458.  
  459.                 # if there is some data - parse it
  460.                 if data:
  461.                     message = self.parseChatLine(data)
  462.  
  463.                     # if message is unrecognized - drop it
  464.                     if message['status'] == 'unrecognized':
  465.                         continue
  466.  
  467.                     # append message to a list of received messages
  468.                     self.received_messages.append(message)
  469.  
  470.                 # no new data
  471.                 elif data is None:
  472.                     break
  473.  
  474.                 # connection errors
  475.                 else:
  476.                     self.socket = None
  477.                     break
  478.  
  479.     # send message from list to chat
  480.     def sendMessages(self):
  481.  
  482.         # if socket exists and there are messages to be sent back
  483.         if self.socket and len(self.socket['messages']):
  484.            
  485.             # if time less than 0.5s from last sent message
  486.             if time() - self.socket['last_msg'] <= 0.5 or len(self.socket['messages']) == 0:
  487.                 return
  488.  
  489.             # includes callback?
  490.             callback = None
  491.             if type(self.socket['messages'][0]) is list:
  492.                 callback = self.socket['messages'][0][1]
  493.                 self.socket['messages'][0] = self.socket['messages'][0][0]
  494.  
  495.             # send response from list to chat
  496.             response = self.socketWrite(self.socket['messages'][0])
  497.  
  498.             # if successful
  499.             if response:
  500.  
  501.                 # remove message from list
  502.                 self.socket['messages'].pop(0)
  503.  
  504.                 # callback?
  505.                 if callback is not None:
  506.                     callback()
  507.  
  508.             # connection errors
  509.             else:
  510.                 self.socket = None
  511.  
  512.             # update time stamp of last sent message
  513.             if self.socket:
  514.                 self.socket['last_msg'] = time()
  515.  
  516.     # append message to list
  517.     def sendMessage(self, message):
  518.  
  519.         # message with callback
  520.         if type(message) is list:
  521.             message[0] = "PRIVMSG #%s :%s" % (self.channel, message[0])
  522.  
  523.         # just message
  524.         else:
  525.             message = "PRIVMSG #%s :%s" % (self.channel, message)
  526.  
  527.         # append message to a list
  528.         self.socket['messages'].append(message)
  529.  
  530.     # get new messages
  531.     def getMessages(self):
  532.  
  533.         messages = self.received_messages
  534.         self.received_messages = []
  535.         return messages
  536.                
  537.     # ping irc
  538.     def ping(self):
  539.  
  540.         # socket exists and time to ping?
  541.         if self.socket and self.socket['next_ping'] < time():
  542.  
  543.             # write message directly to a socket
  544.             response = self.socketWrite("PING :tmi.twitch.tv")
  545.  
  546.             # connection errors?
  547.             if not response:
  548.                 self.socket = None
  549.                 return False
  550.  
  551.             # set time stamp of next ping
  552.             self.socket['next_ping'] += 60
  553.  
  554.         # check if there is a response for a ping - if not, connection is lost
  555.         if self.socket and self.socket['next_ping'] > self.socket['last_ping_response'] + 130:
  556.             self.socket = None
  557.  
  558.     # write to a log file
  559.     def info(self, line, type="INFO:   "):
  560.         self.log_file.write("%s%s\n" % (type, line))
  561.         self.log_file.flush()
  562.  
  563.     # read from socket, process one line
  564.     def socketRead(self):
  565.  
  566.         # get up to 4096 bytes from socket
  567.         try:
  568.             self.socket['buffer'] += self.socket['socket'].recv(4096).decode("ascii", "backslashreplace")
  569.         except IOError as e:
  570.             if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
  571.                 self.info("Receiving data error: %s (%s)" % (e.errno, e.strerror), "ERROR:  ")
  572.                 return False
  573.         except:
  574.             self.info("Unknown receiving data error: %s" % sys.exc_info()[0], "ERROR:  ")
  575.             return False
  576.  
  577.         # if there is at least one full line
  578.         if not self.socket['delimiter'] or self.socket['delimiter'] in self.socket['buffer']:
  579.  
  580.             # split by delimiter, store in buffer and get one line
  581.             if self.socket['delimiter']:
  582.                 (line, self.socket['buffer']) = self.socket['buffer'].split(self.socket['delimiter'], 1)
  583.  
  584.             # just one full line
  585.             else:
  586.                 line = self.socket['buffer']
  587.                 self.socket['buffer'] = ""
  588.  
  589.             # write received message to a log
  590.             if self.DEBUG and line:
  591.                 self.info(line, "DEBUG:  %s: < " % self.socket['name'])
  592.  
  593.             # return chat message
  594.             return line
  595.  
  596.         # no new data
  597.         return None
  598.  
  599.     # write one line to socket
  600.     def socketWrite(self, line):
  601.  
  602.         # write message to socket
  603.         try:
  604.             self.socket['socket'].send(("%s%s" % (line, self.socket['delimiter'])).encode('utf-8'))
  605.         except IOError as e:
  606.             if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
  607.                 self.info("Writing data error: %s (%s)" % (e.errno, e.strerror), "ERROR:  ")
  608.                 return False
  609.         except:
  610.             self.info("Unknown writing data error: %s" % sys.exc_info()[0], "ERROR:  ")
  611.             return False
  612.  
  613.         # write sent message to a log
  614.         if self.DEBUG:
  615.             self.info(line.replace('\n', '\\n'), "DEBUG:  %s: > " % self.socket['name'])
  616.  
  617.         return True
  618.  
  619. #example:
  620. if __name__ == '__main__':
  621.  
  622.     twitch = Twitch('CharlesTheAI', '88m15rbrvxdzrd29rsjrgst2i2mlu3', CHANNEL)
  623.     #twitch = Twitch('AICharlesBot', 'uxyngxigcs02qs4cfcdo2xqvqxi79x', 'daniel_kukiela')
  624.  
  625.     twitch.sendMessage("Hello everyone!")
  626.     last_msg = time()
  627.  
  628.     # connect to twitch
  629.     # nickname, token, channel, log file (optional, default: ./twitchlog.txt), host (optional, default: irc.chat.twitch.tv), port (optional, default: 6667)
  630.     # main loop
  631.     bored_msgs = ['Hello!',
  632.                   'Hello, anyone there?',
  633.                   'What is everyone up to?',
  634.                   'Hi there!',
  635.                   'Greetings humans.',
  636.                   'Hello humans?',
  637.                   ]
  638.    
  639.     while True:
  640.         try:
  641.             # still connected?
  642.             if not twitch.checkIfConnected():
  643.                 continue
  644.  
  645.             # get messages
  646.             messages =  twitch.getMessages()
  647.             print(messages)
  648.             print(last_msg)
  649.             replies = check_to_reply()
  650.             check_mentions(messages)
  651.             # possible message objects:
  652.             # {'status': 'message', 'user': 'twitch_username', 'message': 'message_body', 'subscriber': is_viewer_a_subcriber}
  653.             # {'status': 'cheer', 'user': 'twitch_username', 'message': 'message_body', 'bits': number_of_bits}
  654.             # {'status': 'sub', 'user': 'twitch_username', 'message': 'message_body', 'chatmessage': subscription_message} - chatmessage is a system message like "xxx has subscribed for y month(s)..."
  655.             # ignore messages with other statuses
  656.  
  657.            
  658.             if time() - last_msg > 300:
  659.               twitch.sendMessage(random.choice(bored_msgs))
  660.               last_msg = time()
  661.  
  662.             # you can also send a message with callback, callback will be called at the moment message is physically sent to a chat
  663.             # (sendMessage method placies it in a list of messages to be sent asap)
  664.             # a callback might be acquired by calling getattr(self, 'some_method')
  665.             # twitch.sendMessage(["Some message", getattr(self, 'some_method')])
  666.  
  667.             # that has to be called just before end of loop
  668.             twitch.tick()
  669.  
  670.             # wait for 1s (as this loop is sending message every passage)
  671.             # should be 0.01s
  672.             sleep(5)
  673.             # sleep(0.01)
  674.  
  675.         except Exception as e:
  676.             sleep(30)
  677.             print(str(e))
  678.             # Connect to the database
  679.             # Connect to the database
  680.             connection = pymysql.connect(host=IP,
  681.                                          user=USERNAME,
  682.                                          password=PASSWORD,
  683.                                          db=DB,
  684.                                          charset='utf8mb4',
  685.                                          cursorclass=pymysql.cursors.DictCursor)
  686.             with connection.cursor() as cursor:
  687.                 cursor.execute('SET NAMES utf8mb4')
  688.                 cursor.execute('SET character_set_client="utf8mb4"')
  689.  
  690.             sleep(5)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement