Advertisement
Guest User

Untitled

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