浏览代码

智能邮件客服初版7

lhq 4 年之前
父节点
当前提交
586f997267
共有 5 个文件被更改,包括 902 次插入118 次删除
  1. 132 70
      Utils/NeteaseMail.py
  2. 507 48
      controller/ComprehendController.py
  3. 200 0
      emailtrainfile/emailtrain.csv
  4. 1 0
      model/models.py
  5. 62 0
      readme.md

+ 132 - 70
Utils/NeteaseMail.py

@@ -1,37 +1,68 @@
 import email
 import email
+import pathlib
 import smtplib
 import smtplib
-from email.header import  Header
+from email.header import Header
+from email.mime.application import MIMEApplication
 from email.mime.text import MIMEText
 from email.mime.text import MIMEText
+from email.mime.image import MIMEImage
+from email.mime.multipart import MIMEMultipart
 from nntplib import decode_header
 from nntplib import decode_header
 from imapclient import IMAPClient
 from imapclient import IMAPClient
 
 
 import email.parser
 import email.parser
 
 
+import boto3
+import time
+import chardet
+import sys
+import importlib
+
+importlib.reload(sys)
+import os
+
+
 class NeteaseMail:
 class NeteaseMail:
+    # aws 账号登录
+    def aws_login(self):
+        client = boto3.client(service_name='comprehend', region_name='us-east-1',
+                              aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                              aws_secret_access_key='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')
+        return client
+
+    def aws_arn(self):
+        document_classifier = 'arn:aws:comprehend:us-east-1:697864307463:document-classifier/'
+        endpoint = 'arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/'
+        return document_classifier, endpoint
+
+    def s3_login(self):
+        client = boto3.client(service_name='s3', region_name='us-east-1',
+                              aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                              aws_secret_access_key='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')
+        return client
 
 
     # 连接邮箱服务器并登录。
     # 连接邮箱服务器并登录。
     def loginEmail(self, imap_server, from_addr, password, imap_port, isssl=True):
     def loginEmail(self, imap_server, from_addr, password, imap_port, isssl=True):
         '''第一部分:收件IMAP4********************************************'''
         '''第一部分:收件IMAP4********************************************'''
         '''登录邮箱IMAP4=========================================================='''
         '''登录邮箱IMAP4=========================================================='''
         email_server = None
         email_server = None
-        #993  465
+        # 993  465
         try:
         try:
 
 
             email_server = IMAPClient(imap_server, ssl=isssl, port=imap_port)
             email_server = IMAPClient(imap_server, ssl=isssl, port=imap_port)
-            #email_server = imaplib.IMAP4_SSL(IMAP_SERVER, 993)  # 网易企业邮箱服务器及SSL端口
+            # email_server = imaplib.IMAP4_SSL(IMAP_SERVER, 993)  # 网易企业邮箱服务器及SSL端口
             print("imap4 服务器连接成功")
             print("imap4 服务器连接成功")
 
 
             email_server.login(from_addr, password)
             email_server.login(from_addr, password)
 
 
             email_server.id_({"name": "IMAPClient", "version": "2.1.0"})
             email_server.id_({"name": "IMAPClient", "version": "2.1.0"})
-            #email_server.login(FROM_ADDR, PASSWORD)
-            print("imap4 账号密码正确,登录成功")
+            # email_server.login(FROM_ADDR, PASSWORD)
+            print("imap4 (%s)账号密码正确,登录成功" % from_addr)
         except:
         except:
             print("imap4 服务器连接失败")
             print("imap4 服务器连接失败")
         else:
         else:
             return email_server
             return email_server
 
 
-    #关闭邮箱服务器连接
+    # 关闭邮箱服务器连接
     def closeEmail(self, email_server):
     def closeEmail(self, email_server):
         # 关闭select
         # 关闭select
         email_server.shutdown()
         email_server.shutdown()
@@ -39,54 +70,86 @@ class NeteaseMail:
         # 关闭连接
         # 关闭连接
         # email_server.logout()
         # email_server.logout()
 
 
-    #获取邮箱内容、标题、发件人
+    # 获取邮箱内容、标题、发件人
     def getEmailContext(self, email_server):
     def getEmailContext(self, email_server):
         ''' 邮箱中收到的未读邮件的数量=========================================================='''
         ''' 邮箱中收到的未读邮件的数量=========================================================='''
-        #email_server.select_folder('INBOX', readonly=True)
+        # email_server.select_folder('INBOX', readonly=True) # readonly=True表明只读并不修改任何信息
 
 
-        email_server.select_folder('INBOX', readonly=True)  # readonly=True表明只读并不修改任何信息
-        results = email_server.search()
+        global a
+        email_server.select_folder('INBOX')
+        results = email_server.search('UNSEEN')  # 读取未读邮件
+        print("邮箱内获取到未读邮件:", len(results))
         subject_list = []
         subject_list = []
         bodydata_list = []
         bodydata_list = []
         from_list = []
         from_list = []
+        uid_list = []
+        email_body = []
+        fujian_list = []
+        image_list = []
         try:
         try:
             for uid in results:
             for uid in results:
-                msgdict = email_server.fetch(uid, ['Body[]','ENVELOPE'], '(RFC822)')
+                msgdict = email_server.fetch(uid, ['Body[]', 'ENVELOPE'], '(RFC822)')
                 mailbody = msgdict[uid][b'BODY[]']
                 mailbody = msgdict[uid][b'BODY[]']
                 envelope = msgdict[uid][b'ENVELOPE']
                 envelope = msgdict[uid][b'ENVELOPE']
                 message = email.message_from_bytes(mailbody)
                 message = email.message_from_bytes(mailbody)
-
-                msgfrom = message['from']
-
                 text = message.as_string()
                 text = message.as_string()
                 body = email.parser.Parser().parsestr(text)
                 body = email.parser.Parser().parsestr(text)
+                email_body.append(body)
+
+                nowtime = time.asctime(time.localtime(time.time()))
+                nowmonth = nowtime.split()[1]
+                nowday = nowtime.split()[2]
+                emailmonth = body['Date'].split()[2]
+                emailday = body['Date'].split()[1]
+                if emailmonth != nowmonth or emailday != nowday:
+                    email_server.remove_flags(uid, b'\\Seen', silent=False)
+                    continue
+
+                subject_list.append(decode_header(body['Subject']))
+                from_list.append(decode_header(body['from']))
+                uid_list.append(uid)
+
+                attlist = {}
                 for part in body.walk():
                 for part in body.walk():
-
-                    if part['Subject']:
-                        subject_list.append(decode_header(part['Subject']))
-
-                    if part['from']:
-                        from_list.append(decode_header(part['from']))
-
                     if not part.is_multipart():
                     if not part.is_multipart():
-                        name = part.get_param("name")  # 如果是附件,这里就会取出附件的文件名
-                        if name:
-                           print('附件')
+                        file = part.get_filename()  # 附件名
+                        if file:
+                            a = 1
+                            filename = email.header.decode_header(file)[0][0]  # 附件名
+                            charset = email.header.decode_header(file)[0][1]  # 编码
+                            if part.get_all("Content-ID"):
+                                content_id = part.get_all("Content-ID")[0][1:-1]
+                            else:
+                                content_id = ""  # 附件ID,也就是邮件源码里面的cid
+                            ''' 多个附件时将附件名和ID对应保存到dict里面,后面将正文中的cid替换为本地保存路径 '''
+                            attlist[content_id] = filename
+                            ''' 附件文件名为中文或有编码的时候要进行转码 '''
+                            if str(charset) != "None":
+                                filename = filename.decode(charset)
+                            filedata = part.get_payload(decode=True)  # 附件内容
+                            ''' 把附件写到文件里面,附件一定要用wb打开,二进制 '''
+                            file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/image/')
+                            image_list.append(file_path + filename)
+                            with open(file_path + filename, "wb") as fw:
+                                fw.write(filedata)
+                                fw.close()
+
                         elif part.get_content_type() == 'text/plain':
                         elif part.get_content_type() == 'text/plain':
                             con3 = part.get_payload(decode=True).strip()
                             con3 = part.get_payload(decode=True).strip()
-                            bodydata_list.append(con3.decode('gbk'))
-                            break
-                        else:
-                            con3 = part.get_payload(decode=True).strip()
-                            bodydata_list.append(con3.decode('utf8'))
-                            break
-                        # print '+'*60 # 用来区别各个部分的输出
+                            print(chardet.detect(con3))
+                            if chardet.detect(con3)['encoding'] == 'utf-8':
+                                bodydata_list.append(con3.decode('utf-8'))
+                            else:
+                                bodydata_list.append(con3.decode('gbk'))
+                if a == 1:
+                    fujian_list.append('have')
+                email_server.remove_flags(uid, b'\\Seen', silent=False)
 
 
-
-        except:
-           print('获取内容出错')
+        except Exception as e:
+            print(e)
+            print('获取内容出错')
         else:
         else:
-            return subject_list, from_list, bodydata_list
+            return subject_list, from_list, bodydata_list, uid_list, results, email_body, fujian_list, image_list
         # if subject_list and bodydata_list:
         # if subject_list and bodydata_list:
         #     data_unseen = [subject_list, bodydata_list]
         #     data_unseen = [subject_list, bodydata_list]
         #     data_unseen1 = pd.DataFrame(data_unseen)
         #     data_unseen1 = pd.DataFrame(data_unseen)
@@ -106,9 +169,8 @@ class NeteaseMail:
         #     upload_key = "86YC8Z192VB1VMKU111A/vod1/test"
         #     upload_key = "86YC8Z192VB1VMKU111A/vod1/test"
         #     file_obj = s3.Bucket(bucket).put_object(Key=upload_key, Body=upload_data)
         #     file_obj = s3.Bucket(bucket).put_object(Key=upload_key, Body=upload_data)
 
 
-
-    #发送邮箱
-    def faEmail(self,email_server,message,subject,from_addr,to_addr):
+    # 发送邮箱
+    def faEmail(self, email_server, message, subject, from_addr, to_addr):
         if email_server:
         if email_server:
             print("邮件开始发送")
             print("邮件开始发送")
 
 
@@ -127,11 +189,13 @@ class NeteaseMail:
 
 
         email_server.quit()
         email_server.quit()
 
 
-    def sentemail(self,message,subject,from_addr,to_addr,iemial, ipassword):
+    def sentemail(self, email_server, uid, message, image, subject, from_addr, to_addr, iemial, ipassword):
         host = 'smtp.163.com'
         host = 'smtp.163.com'
         # 设置发件服务器地址
         # 设置发件服务器地址
         port = 465
         port = 465
         # 设置发件服务器端口号。注意,这里有SSL和非SSL两种形式,现在一般是SSL方式
         # 设置发件服务器端口号。注意,这里有SSL和非SSL两种形式,现在一般是SSL方式
+        # host = 'smtp.qiye.163.com'
+        # port = 994
         sender = iemial
         sender = iemial
         # 设置发件邮箱,一定要自己注册的邮箱
         # 设置发件邮箱,一定要自己注册的邮箱
         pwd = ipassword
         pwd = ipassword
@@ -140,13 +204,33 @@ class NeteaseMail:
         # 设置邮件接收人,可以是QQ邮箱
         # 设置邮件接收人,可以是QQ邮箱
         body = message
         body = message
         # 设置邮件正文,这里是支持HTML的
         # 设置邮件正文,这里是支持HTML的
-        msg = MIMEText(body, 'html')
+        msg = MIMEMultipart()
+        # msg = MIMEText(body, 'html')
+        # msg = MIMEText(body, 'plain', 'utf-8')
+        msg.attach(MIMEText(body, 'plain', 'utf-8'))
+        msg.attach(MIMEText(body, 'html', 'utf-8'))
+        if image:
+            for i in image:
+                print(i.split('.')[-1])
+                if i.split('.')[-1] == 'png' and 'jpeg' and 'jpg':
+                    with open(i, 'rb') as f:
+                        msgImage = MIMEImage(f.read())
+                    # 定义图片ID
+                    msgImage.add_header('Content-ID', '<image1>')
+                    msg.attach(msgImage)  # 添加图片
+                else:
+                    part_attach1 = MIMEApplication(open(i, 'rb').read())  # 打开附件
+                    # 构建邮件附件
+                    part_attach1.add_header('Content-Disposition', 'attachment', filename=pathlib.Path(i).name)  # 为附件命名
+                    msg.attach(part_attach1)  # 添加附件
+
+
         # 设置正文为符合邮件格式的HTML内容
         # 设置正文为符合邮件格式的HTML内容
         msg['subject'] = subject
         msg['subject'] = subject
         # 设置邮件标题
         # 设置邮件标题
-        msg['from'] = from_addr
+        msg['from'] = Header(from_addr)
         # 设置发送人
         # 设置发送人
-        msg['to'] = to_addr
+        msg['to'] = Header(to_addr)
         # 设置接收人
         # 设置接收人
         try:
         try:
             s = smtplib.SMTP_SSL(host, port)
             s = smtplib.SMTP_SSL(host, port)
@@ -155,31 +239,9 @@ class NeteaseMail:
             # 登陆邮箱
             # 登陆邮箱
             s.sendmail(sender, receiver, msg.as_string())
             s.sendmail(sender, receiver, msg.as_string())
             # 发送邮件!
             # 发送邮件!
-            print('Done.sent email success')
-        except smtplib.SMTPException:
-            print('Error.sent email fail')
-
-    # mailto_list = ['xxxxxx@xx.com]
-    #                mail_host = "smtp.163.com"
-    # mail_user = "xxxxxx"
-    # mail_pass = "xxxxxxxxxx"
-    #
-    # def send_mail(mailto_list, sub, content,mail_user,mail_pass):
-    #     me = "hello" + "<" + mail_user + "@1368035>"
-    #     msg = MIMEText(content, _subtype='plain')
-    #     msg['Subject'] = sub
-    #     msg['From'] = me
-    #     try:
-    #         for mail in mailto_list:
-    #             msg['To'] = mail
-    #             server = smtplib.SMTP()
-    #             server.connect(mail_host)
-    #             server.login(mail_user, mail_pass)
-    #             server.sendmail(me, mail, msg.as_string())
-    #             server.close()
-    #             del msg['To']
-    #         return True
-    #     except Exception, e:
-    #         print
-    #         str(e)
-    #         return False
+            print('邮件转发成功')
+            email_server.set_flags(uid, b'\\Seen', silent=False)
+        except smtplib.SMTPException as e:
+            print(e)
+            print('邮件转发失败')
+            email_server.remove_flags(uid, b'\\Seen', silent=False)

+ 507 - 48
controller/ComprehendController.py

@@ -1,13 +1,20 @@
+import imaplib
+import shutil
+import smtplib
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
 import boto3
 import boto3
 from boto3 import Session
 from boto3 import Session
 from django.views import View
 from django.views import View
 
 
-
 from model.models import EmailSortModel, EmailConfigModel
 from model.models import EmailSortModel, EmailConfigModel
 from Utils.NeteaseMail import NeteaseMail
 from Utils.NeteaseMail import NeteaseMail
 from django.views.generic import TemplateView
 from django.views.generic import TemplateView
 
 
 from object.ResponseObject import ResponseObject
 from object.ResponseObject import ResponseObject
+import os
+import csv
 
 
 
 
 class ComprehendView(TemplateView):
 class ComprehendView(TemplateView):
@@ -31,10 +38,28 @@ class ComprehendView(TemplateView):
                 return self.createSort(request_dict, response)
                 return self.createSort(request_dict, response)
             elif operation == 'doStartSortWord':
             elif operation == 'doStartSortWord':
                 return self.doStartSortWord(request_dict, response)
                 return self.doStartSortWord(request_dict, response)
+            elif operation == 'write_csv':
+                return self.write_csv(request_dict, response)
+            elif operation == 'upload_csv':
+                return self.upload_csv(request_dict, response)
+            elif operation == 'create_document_classifier':
+                return self.create_document_classifier(request_dict, response)
+            elif operation == 'create_endpoint':
+                return self.create_endpoint(request_dict, response)
+            elif operation == 'describe_document_classifier':
+                return self.describe_document_classifier(request_dict, response)
+            elif operation == 'describe_endpoint':
+                return self.describe_endpoint(request_dict, response)
+            elif operation == 'delete_endpoint':
+                return self.delete_endpoint(request_dict, response)
+            elif operation == 'delete_document_classifier':
+                return self.delete_document_classifier(request_dict, response)
             elif operation == 'getDocumentClassifier':
             elif operation == 'getDocumentClassifier':
                 return self.get_document_classifier(request_dict, response)
                 return self.get_document_classifier(request_dict, response)
+            elif operation == 'email':
+                return self.email(request_dict, response)
 
 
-    def createSort(self,request_dict, response):
+    def createSort(self, request_dict, response):
         client = boto3.client('comprehend', region_name='region')
         client = boto3.client('comprehend', region_name='region')
 
 
         # Create a document classifier
         # Create a document classifier
@@ -57,8 +82,7 @@ class ComprehendView(TemplateView):
         list_response = client.list_document_classifiers()
         list_response = client.list_document_classifiers()
         print("List response: %s\n", list_response)
         print("List response: %s\n", list_response)
 
 
-
-    def doStartSortWord(self,request_dict, response):
+    def doStartSortWord(self, request_dict, response):
         client = boto3.client('comprehend', region_name='region')
         client = boto3.client('comprehend', region_name='region')
 
 
         start_response = client.start_document_classification_job(
         start_response = client.start_document_classification_job(
@@ -84,66 +108,501 @@ class ComprehendView(TemplateView):
         list_response = client.list_document_classification_jobs()
         list_response = client.list_document_classification_jobs()
         print("List response: %s\n", list_response)
         print("List response: %s\n", list_response)
 
 
+    def write_csv(self, request_dict, response):
+        file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/emailtrain.csv')
+        with open(file_path, "w", newline='') as f:
+            sort = EmailSortModel.objects.values('sort', 'clientquestion')
+            for a in sort:
+                text = [a['sort'], a['clientquestion']]
+                csv_writer = csv.writer(f)
+                for i in range(50):
+                    csv_writer.writerow(text)
+        return response.json(0)
 
 
-    def  get_document_classifier(self,request_dict, response):
-        # aws_key = "AKIA2E67UIMD45Y3HL53"  # 【你的 aws_access_key】
-        # aws_secret = "ckYLg4Lo9ZXJIcJEAKkzf2rWvs8Xth1FCjqiAqUw"  # 【你的 aws_secret_key】
-        # session = Session(aws_access_key_id=aws_key,
-        #                   aws_secret_access_key=aws_secret,
-        #                   region_name="us-east-1")  # 此处根据自己的 s3 地区位置改变
-        # client = session.client("asj-amazon-comprehend")
-        # client = boto3.client(
-        #     'asj-amazon-comprehend',
-        #     aws_access_key_id='AKIA2E67UIMD45Y3HL53',
-        #     aws_secret_access_key='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',
-        #     region_name='us-east-1'
-        # )
-        #client = boto3.client(service_name='comprehend',region_name='us-east-1',aws_access_key_id='AKIA2E67UIMD45Y3HL53',aws_secret_access_key='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')
-
-        # response = client.describe_document_classifier(
-        #     DocumentClassifierArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier/txttwo'
-        # )
-        # print(response)
-        ec_qs =EmailConfigModel.objects.filter(emailtag=1) #获取总邮件
+    def upload_csv(self, request_dict, response):
+        file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/emailtrain.csv')
+        bucket_name = "asj-amazon-comprehend"
+        upload_key = "location/emailtrain.csv"
+        with open(file_path, "rb") as f:
+            NeteaseMail().s3_login().upload_fileobj(f, bucket_name, Key=upload_key)
+        return response.json(0)
+
+    def create_document_classifier(self, request_dict, response):
+        try:
+            response1 = NeteaseMail().aws_login().create_document_classifier(
+                DocumentClassifierName='lhq',
+                DataAccessRoleArn='arn:aws:iam::697864307463:role/service-role/AmazonComprehendServiceRoleS3FullAccess-admin',
+                # Tags=[{'Key': 'string','Value': 'string'},],
+                InputDataConfig={
+                    'DataFormat': 'COMPREHEND_CSV',
+                    # | 'AUGMENTED_MANIFEST',
+                    'S3Uri': 's3://asj-amazon-comprehend/location/emailtrain.csv',
+                    # 'LabelDelimiter': 'string',
+                    # 'AugmentedManifests': [
+                    #     {
+                    #         'S3Uri': 'string',
+                    #         'AttributeNames': ['string', ]
+                    #     },
+                    # ]
+                },
+                OutputDataConfig={
+                    'S3Uri': 's3://asj-amazon-comprehend/output/lhq/'},
+                # 'KmsKeyId': 'string'},
+                # ClientRequestToken='string',
+                LanguageCode='en',
+                # | 'es' | 'fr' | 'de' | 'it' | 'pt' | 'ar'
+                # | 'hi' | 'ja' | 'ko' | 'zh' | 'zh-TW',
+                # VolumeKmsKeyId='string',
+                # VpcConfig={
+                #     'SecurityGroupIds': ['string', ],
+                #     'Subnets': ['string', ]
+                # },
+                Mode='MULTI_CLASS'  # 'MULTI_LABEL'
+            )
+        except Exception as e:
+            return response.json(404, repr('模型正在训练或已存在'))
+        else:
+            print(response1)
+            return response.json(0)
+
+    def create_endpoint(self, request_dict, response):
+        try:
+            response1 = NeteaseMail().aws_login().create_endpoint(
+                EndpointName='lhq',
+                ModelArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier/lhq',
+                # Document classifier arn
+                DesiredInferenceUnits=1,
+                # ClientRequestToken='string',
+                # Tags=[{'Key': 'string','Value': 'string'},]
+            )
+        except Exception as e:
+            return response.json(404, repr('模型正在训练或不存在,请等待模型训练完再创建端点'))
+        else:
+            print(response1)
+            return response.json(0)
+
+    def describe_document_classifier(self, request_dict, response):
+        try:
+            # classifier_name = request_dict.get('classifier_name', None)
+            a = NeteaseMail().aws_arn()[0]
+            # classifier_arn = a + str(classifier_name)
+            classifier_arn = a + 'lhq'
+            response1 = NeteaseMail().aws_login().describe_document_classifier(
+                DocumentClassifierArn=classifier_arn
+            )
+            a1 = {"Status": response1['DocumentClassifierProperties']['Status']}
+        except Exception as e:
+            return response.json(404, repr('模型不存在'))
+        else:
+            return response.json(0, a1)
+
+    def describe_endpoint(self, request_dict, response):
+        try:
+            # endpoint_name = request_dict.get('endpoint_name', None)
+            a = NeteaseMail().aws_arn()[1]
+            # endpoint_arn = a + str(endpoint_name)
+            endpoint_arn = a + 'lhq'
+            response1 = NeteaseMail().aws_login().describe_endpoint(
+                EndpointArn=endpoint_arn
+            )
+            a1 = {"Status": response1['EndpointProperties']['Status']}
+        except Exception as e:
+            return response.json(404, repr('端点不存在'))
+        else:
+            return response.json(0, a1)
+
+    def delete_endpoint(self, request_dict, response):
+        try:
+            # endpoint_name = request_dict.get('endpoint_name', None)
+            a = NeteaseMail().aws_arn()[1]
+            # endpoint_arn = a + str(endpoint_name)
+            endpoint_arn = a + 'lhq'
+            response1 = NeteaseMail().aws_login().delete_endpoint(
+                EndpointArn=endpoint_arn)
+        except Exception as e:
+            return response.json(404, repr('端点不存在或正在删除中'))
+        else:
+            return response.json(0)
+
+    def delete_document_classifier(self, request_dict, response):
+        try:
+            # classifier_name = request_dict.get('classifier_name', None)
+            a = NeteaseMail().aws_arn()[0]
+            # classifier_arn = a + str(classifier_name)
+            classifier_arn = a + 'lhq'
+            response1 = NeteaseMail().aws_login().delete_document_classifier(
+                DocumentClassifierArn=classifier_arn)
+        except Exception as e:
+            return response.json(404, repr('模型不存在或正在删除中'))
+        else:
+            return response.json(0)
 
 
+    def get_document_classifier(self, request_dict, response):
+        ec_qs = EmailConfigModel.objects.filter(emailtag=1)  # 获取总邮件
+        emailsum = 0
+        replyemailsum = 0
         for ec in ec_qs:
         for ec in ec_qs:
             email_server = NeteaseMail().loginEmail(ec.emailserver, ec.fromaddr, ec.password, ec.emailserverport)
             email_server = NeteaseMail().loginEmail(ec.emailserver, ec.fromaddr, ec.password, ec.emailserverport)
-            subject_list, from_list, bodydata_list = NeteaseMail().getEmailContext(email_server)
-            print("标题:", subject_list)
-            print("发件人:", from_list)
-            print("邮件内容:", bodydata_list)
-            if subject_list == []:
-                print("邮箱内无邮件")
+            subject_list, from_list, bodydata_list, uid_list, results, email_body, fujian_list, image_list = NeteaseMail().getEmailContext(
+                email_server)
+            emailsum += len(results)
+            print("标题:", len(subject_list), subject_list)
+            print("发件人:", len(from_list), from_list)
+            print("邮件内容:", len(bodydata_list), bodydata_list)
+            print("邮件uid:", len(uid_list), uid_list)
+            print("附件判断:", len(fujian_list), fujian_list)
+            print('图片数量:', len(image_list), image_list)
+            if not bodydata_list:
+                print("邮箱内无未读邮件")
             else:
             else:
-                print('成功拿到邮箱数据')
-            # NeteaseMail().closeEmail(email_server)
+                print('成功拿到邮件数据')
+            for i, v in enumerate(subject_list):
+                print('-------------------------------------------------------------------------')
+                print("邮件标题:", subject_list[i])
+                if not bodydata_list[i] or not subject_list[i]:
+                    print("邮件无正文或无标题,不进行回复")
+                    continue
 
 
-            for i ,v in enumerate(subject_list):
+                if fujian_list[i] == 'have':
+                    reply_model = bodydata_list[i]
+                    image = image_list
+                    shoujianren = 'liehaoquan2021@163.com'
+                    fajianren = from_list[i].split()[1]
+                    NeteaseMail().sentemail(None, uid_list[i],reply_model, image, subject_list[i], fajianren, shoujianren,
+                                            ec.fromaddr, ec.password)
+                    file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/image/')
+                    shutil.rmtree(file_path)
+                    os.mkdir(file_path)
+                    print('邮件含有图片或附件,已转发到zendesk')
+                    email_server.set_flags(uid_list[i], b'\\Seen', silent=False)
+                    continue
 
 
-                client = boto3.client(service_name='comprehend', region_name='us-east-1',
-                                      aws_access_key_id='AKIA2E67UIMD45Y3HL53',
-                                      aws_secret_access_key='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')
-                response1 = client.classify_document(
-                    Text=bodydata_list[i],
-                    EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/test'
+                response1 = NeteaseMail().aws_login().classify_document(
+                    Text=bodydata_list[i].split('\n\n\n\n\n')[0],
+                    EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/lhq'
+                    # EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/test'
                 )
                 )
-                #print(response.index(max(response['Classes']['Score'])))
+                # print(response.index(max(response['Classes']['Score'])))
                 nums = []
                 nums = []
+                print('emailsort:')
                 for cls in response1['Classes']:
                 for cls in response1['Classes']:
                     print(cls['Name'])
                     print(cls['Name'])
                     nums.append(cls['Score'])
                     nums.append(cls['Score'])
+                print("识别种类及命中率:", response1['Classes'][nums.index(max(nums))])
+                if response1['Classes'][nums.index(max(nums))]['Score'] >= 0.95:
+                    reply_sort = EmailSortModel.objects.filter(
+                        sort=response1['Classes'][nums.index(max(nums))]['Name']).values('autoreplymodel')
+                    if reply_sort.exists():
+                        reply_model = reply_sort[0]['autoreplymodel'] + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + \
+                                      'At' + email_body[i]['Date'] + from_list[i].split()[0] + \
+                                      from_list[i].split()[1] + \
+                                      'wrote:\n ' + bodydata_list[i]
+                        print(reply_model)
+                        shoujianren = from_list[i].split()[1].replace('<', '').replace('>', '')
+                        a = NeteaseMail().sentemail(None, uid_list[i], reply_model, None, subject_list[i], ec.fromaddr, shoujianren,
+                                                    ec.fromaddr, ec.password)
+                        email_server.set_flags(uid_list[i], b'\\Seen', silent=False)
+                        if a == 'fail':
+                            print("此邮件被判定为垃圾邮件,不进行回复")
+                            email_server.remove_flags(uid_list[i], b'\\Seen', silent=False)
+                        else:
+                            replyemailsum += a
+                    else:
+                        print("无此转发分类,不进行回复")
+                else:
+                    reply_model = bodydata_list[i]
+                    shoujianren = 'liehaoquan2021@163.com'
+                    fajianren = from_list[i].split()[1]
+                    NeteaseMail().sentemail(reply_model, None, subject_list[i], fajianren, shoujianren,
+                                            ec.fromaddr, ec.password)
+                    email_server.set_flags(uid_list[i], b'\\Seen', silent=False)
+                    print("命中率低于0.95,已转发到zendesk")
+                # es_qs = EmailSortModel.objects.filter(sort=response1['Classes'][nums.index(max(nums))]['Name'])
+                # if es_qs.exists():
+                #     uemail_qs = EmailConfigModel.objects.filter(userid=es_qs[0]['userid'], langconfig__langcode='en')
+                #     if uemail_qs.exists():
+                #         for uem in uemail_qs:
+                #             NeteaseMail().sentemail(bodydata_list[i], subject_list[i], from_list[i], uem.fromaddr, ec.fromaddr, ec.password)
+            NeteaseMail().closeEmail(email_server)
+        emaildict = {
+            "邮箱内获取到未读邮件数": emailsum,
+            "已自动回复的邮件数": replyemailsum
+        }
+        return response.json(0, emaildict)
+
+    def email(self, request_dict, response):
+        from imapclient import IMAPClient
+        import email
+        import time
+        import email.parser
+        from nntplib import decode_header
+        from email.header import Header
+        import chardet
+
+        ec_qs = EmailConfigModel.objects.filter(emailtag=1)  # 获取总邮件
+        for ec in ec_qs:
+            global a, email_server
+
+            #邮件登录
+            try:
+                email_server = IMAPClient(ec.emailserver, ssl=True, port=ec.emailserverport)
+                # email_server = imaplib.IMAP4_SSL(IMAP_SERVER, 993)  # 网易企业邮箱服务器及SSL端口
+                print("imap4 服务器连接成功")
+                email_server.login(ec.fromaddr, ec.password)
+                email_server.id_({"name": "IMAPClient", "version": "2.1.0"})
+                # email_server.login(FROM_ADDR, PASSWORD)
+                print("imap4 (%s)账号密码正确,登录成功" % ec.fromaddr)
+            except:
+                print("imap4 服务器连接失败")
+
+            email_server.select_folder('INBOX')
+            results = email_server.search('UNSEEN')  # 读取未读邮件
+            print("邮箱内获取到未读邮件:", len(results))
+            subject_list = []
+            from_list = []
+            uid_list = []
+            email_body = []
+            fujian_list = []
+            image_list = []
+            plain_list = []
+            html_list = []
+            a = 0
+
+            # 对每一封邮件进行内容解析
+            for uid in results:
+                msgdict = email_server.fetch(uid, ['Body[]', 'ENVELOPE'], '(RFC822)')
+                mailbody = msgdict[uid][b'BODY[]']
+                envelope = msgdict[uid][b'ENVELOPE']
+                message = email.message_from_bytes(mailbody)
+                text = message.as_string()
+                body = email.parser.Parser().parsestr(text)
+
+                nowtime = time.asctime(time.localtime(time.time()))
+                nowmonth = nowtime.split()[1]
+                nowday = nowtime.split()[2]
+                emailmonth = body['Date'].split()[2]
+                emailday = body['Date'].split()[1]
+                print('email',emailmonth,emailday)
+                print('now', nowmonth, nowday)
+                # if emailmonth != nowmonth or emailday != nowday:
+                #     email_server.remove_flags(uid, b'\\Seen', silent=False)
+                #     continue
+
+                email_body.append(body)
+                subject_list.append(decode_header(body['Subject']))
+                from_list.append(decode_header(body['from']))
+                uid_list.append(uid)
+                print("标题:",  subject_list)
+
+                attlist = {}
+                try:
+                    for part in body.walk():
+                        if not part.is_multipart():
+                            file = part.get_filename()  # 附件名
+                            if file:
+                                a = 1
+                                filename = email.header.decode_header(file)[0][0]  # 附件名
+                                charset = email.header.decode_header(file)[0][1]  # 编码
+                                if part.get_all("Content-ID"):
+                                    content_id = part.get_all("Content-ID")[0][1:-1]
+                                else:
+                                    content_id = ""  # 附件ID,也就是邮件源码里面的cid
+                                ''' 多个附件时将附件名和ID对应保存到dict里面,后面将正文中的cid替换为本地保存路径 '''
+                                attlist[content_id] = filename
+                                ''' 附件文件名为中文或有编码的时候要进行转码 '''
+                                if str(charset) != "None":
+                                    filename = filename.decode(charset)
+                                filedata = part.get_payload(decode=True)  # 附件内容
+                                ''' 把附件写到文件里面,附件一定要用wb打开,二进制 '''
+                                file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/image/')
+                                image_list.append(file_path + filename)
+                                with open(file_path + filename, "wb") as fw:
+                                    fw.write(filedata)
+                                    fw.close()
+
+                            elif part.get_content_type() == 'text/plain':
+                                con3 = part.get_payload(decode=True).strip()
+                                print('plain:', chardet.detect(con3))
+                                if chardet.detect(con3)['encoding'] == 'utf-8':
+                                    plain_list.append(con3.decode('utf-8'))
+                                    continue
+                                # if chardet.detect(con3)['encoding'] == 'ISO-8859-1':
+                                #     plain_list.append(con3.decode('ISO-8859-1')) # .decode('gbk').encode('utf8')
+                                #     continue
+                                else:
+                                    plain_list.append(con3.decode('gbk'))
+                                    continue
+                            elif part.get_content_type() == 'text/html':
+                                con3 = part.get_payload(decode=True).strip()
+                                print('html', chardet.detect(con3))
+                                if chardet.detect(con3)['encoding'] == 'utf-8':
+                                    html_list.append(con3.decode('utf-8'))
+                                    continue
+                                # if chardet.detect(con3)['encoding'] == 'ISO-8859-1':
+                                #     html_list.append(con3.decode('ISO-8859-1'))
+                                #     continue
+                                else:
+                                    html_list.append(con3.decode('gbk'))
+                                    continue
+                except Exception as e:
+                    print(e)
+                    print('获取邮件内容失败')
+                    email_server.remove_flags(uid, b'\\Seen', silent=False)
+                    subject_list.clear()
+                    from_list.clear()
+                    uid_list.clear()
+                    email_body.clear()
+                    fujian_list.clear()
+                    image_list.clear()
+                    plain_list.clear()
+                    html_list.clear()
+                    print('-------------------------------------------------------------------------')
+                    continue
+
+
+                if a == 1:
+                    fujian_list.append('have')
+                    a = 0
+                else:
+                    fujian_list.append('none')
+                email_server.remove_flags(uid, b'\\Seen', silent=False)
+                print("发件人:", from_list)
+                print("邮件内容:")
+                print("plain形式:",plain_list)
+                print("html形式:",html_list)
+                print("邮件uid:", uid_list)
+                print("邮件是否含有图片或附件:", fujian_list)
+                print('图片或附件名字:', image_list)
+                if not html_list and not plain_list:
+                    print("邮箱内无未读邮件")
+                else:
+                    print('成功拿到邮件数据')
+
+                # 对邮件类型进行判断处理
+                for i, v in enumerate(uid_list):
+                    print("邮件标题:", subject_list[i])
+                    if html_list and not plain_list:
+                        print('此邮件仅含有html')
+                        reply_model = html_list[i]
+                        fajianren = from_list[i]
+                        shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                        NeteaseMail().sentemail(email_server, uid_list[i],reply_model, None, subject_list[i], fajianren, shoujianren,
+                                                ec.fromaddr, ec.password)
+                        print('-------------------------------------------------------------------------')
+                        break
+
+                    if plain_list[i] == '':
+                        print('此邮件无正文')
+                        reply_model = ''
+                        fajianren = from_list[i]
+                        shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                        NeteaseMail().sentemail(email_server, uid_list[i],reply_model, None, subject_list[i], fajianren, shoujianren,
+                                                ec.fromaddr, ec.password)
+                        print('-------------------------------------------------------------------------')
+                        break
+
+                    if not subject_list[i]:
+                        print('此邮件无主题')
+                        if html_list and not plain_list:
+                            print('此邮件无主题且仅含有html')
+                            reply_model = html_list[i]
+                            fajianren = from_list[i]
+                            shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                            biaoti = '(无主题)'
+                            NeteaseMail().sentemail(email_server, uid_list[i],reply_model, None, biaoti, fajianren, shoujianren,
+                                                    ec.fromaddr, ec.password)
+                            print('-------------------------------------------------------------------------')
+                            break
+                        elif plain_list:
+                            print('此邮件无主题且含有正文')
+                            reply_model = plain_list[i]
+                            fajianren = from_list[i]
+                            shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                            biaoti = '(无主题)'
+                            NeteaseMail().sentemail(email_server, uid_list[i], reply_model, None, biaoti, fajianren, shoujianren,
+                                                    ec.fromaddr, ec.password)
+                        print('-------------------------------------------------------------------------')
+                        break
+
+                    # 处理含有图片或附件的邮件
+                    if fujian_list[i] == 'have':
+                        print('此邮件含有图片或附件或视频或压缩包')
+                        reply_model = html_list[i]
+                        image = image_list
+                        fajianren = from_list[i]
+                        shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                        NeteaseMail().sentemail(email_server, uid_list[i], reply_model, image, subject_list[i], fajianren, shoujianren,
+                                                ec.fromaddr, ec.password)
+                        file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/image/')
+                        shutil.rmtree(file_path)
+                        os.mkdir(file_path)
+                        print('-------------------------------------------------------------------------')
+                        break
 
 
-                print(response1['Classes'][nums.index(max(nums))])
+                    if fujian_list[i] == 'none':
+                        # 处理无图片或附件的邮件
+                        # 进行种类判断
+                        print("识别内容:", plain_list[i].split('\n\n')[0])  # plain
+                        if len(plain_list[i].split('\n\n\n')[0]) < 1000:
+                            response1 = NeteaseMail().aws_login().classify_document(
+                                Text=plain_list[i].split('\n\n\n')[0],
+                                EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/lhq'
+                                # EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/test'
+                            )
+                            # print(response.index(max(response['Classes']['Score'])))
+                            nums = []
+                            print('emailsort:')
+                            for cls in response1['Classes']:
+                                print(cls['Name'])
+                                nums.append(cls['Score'])
+                            print("识别种类及命中率:", response1['Classes'][nums.index(max(nums))])
+                            # 命中率高于0.95时
+                            if response1['Classes'][nums.index(max(nums))]['Score'] >= 0.95:
+                                reply_sort = EmailSortModel.objects.filter(
+                                    sort=response1['Classes'][nums.index(max(nums))]['Name']).values('autoreplymodel')
+                                if reply_sort.exists():
+                                    reply_model = reply_sort[0]['autoreplymodel'] + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + \
+                                                  'At' + email_body[i]['Date'] + str(from_list[i].split()[0:-1]) + \
+                                                  from_list[i].split()[-1] + \
+                                                  'wrote:\n ' + plain_list[i]
+                                    print(reply_model)
+                                    shoujianren = from_list[i].split()[1].replace('<', '').replace('>', '')
+                                    NeteaseMail().sentemail(email_server, uid_list[i], reply_model, None, subject_list[i], ec.fromaddr, shoujianren,
+                                                            ec.fromaddr, ec.password)
+                                    print('-------------------------------------------------------------------------')
+                                    break
+                            else:
+                                print("此邮件命中率低于0.95")
+                                reply_model = html_list[i]  # html
+                                fajianren = from_list[i]
+                                print(fujian_list)
+                                shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                                NeteaseMail().sentemail(email_server, uid_list[i], reply_model, None, subject_list[i],
+                                                        fajianren, shoujianren,
+                                                        ec.fromaddr, ec.password)
+                                print('-------------------------------------------------------------------------')
+                                break
 
 
-                es_qs = EmailSortModel.objects.filter(sort=response1['Classes'][nums.index(max(nums))]['Name'])
-                if es_qs.exists():
-                    uemail_qs = EmailConfigModel.objects.filter(userid=es_qs[0]['userid'], langconfig__langcode='en')
-                    if uemail_qs.exists():
-                        for uem in uemail_qs:
-                            NeteaseMail().sentemail(bodydata_list[i], subject_list[i], from_list[i], uem.fromaddr, ec.fromaddr, ec.password)
+                        else:
+                            print("识别内容过长")
+                            reply_model = html_list[i]  # html
+                            fajianren = from_list[i]
+                            print(fujian_list)
+                            shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                            NeteaseMail().sentemail(email_server, uid_list[i], reply_model, None, subject_list[i], fajianren, shoujianren,
+                                                    ec.fromaddr, ec.password)
+                            print('-------------------------------------------------------------------------')
+                            break
+                subject_list.clear()
+                from_list.clear()
+                uid_list.clear()
+                email_body.clear()
+                fujian_list.clear()
+                image_list.clear()
+                plain_list.clear()
+                html_list.clear()
             NeteaseMail().closeEmail(email_server)
             NeteaseMail().closeEmail(email_server)
         return response.json(0)
         return response.json(0)
-        #print(response)
 
 
 # if __name__ == '__main__':
 # if __name__ == '__main__':
 #     ComprehendAction().get_document_classifier()
 #     ComprehendAction().get_document_classifier()

+ 200 - 0
emailtrainfile/emailtrain.csv

@@ -0,0 +1,200 @@
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter

+ 1 - 0
model/models.py

@@ -272,6 +272,7 @@ class EmailLangConfig(models.Model):
 class EmailSortModel(models.Model):
 class EmailSortModel(models.Model):
     emailsortid = models.AutoField(primary_key=True, verbose_name=u'自增ID')
     emailsortid = models.AutoField(primary_key=True, verbose_name=u'自增ID')
     sort = models.CharField(max_length=200, default='', verbose_name='负责分类')
     sort = models.CharField(max_length=200, default='', verbose_name='负责分类')
+    clientquestion = models.CharField(max_length=200, default='', verbose_name='客户问题内容')
     sortcode = models.CharField(max_length=200, default='', verbose_name='分类编号')
     sortcode = models.CharField(max_length=200, default='', verbose_name='分类编号')
     parentsortid = models.CharField(max_length=200, null=True, verbose_name='父节点分类')
     parentsortid = models.CharField(max_length=200, null=True, verbose_name='父节点分类')
     isautoreply = models.SmallIntegerField(default=0, verbose_name='是否自动回复')  # 0:不自动回复 1:自动回复
     isautoreply = models.SmallIntegerField(default=0, verbose_name='是否自动回复')  # 0:不自动回复 1:自动回复

+ 62 - 0
readme.md

@@ -0,0 +1,62 @@
+# 总项目文件名:langer  
+
+## 项目目录
+1. 智能客服邮件  
+2. 项目2  
+3. 项目3  
+
+### 1.智能客服邮件
+- 项目负责人:列浩铨  
+- 项目日期:2021年2月26日
+
+#### 项目介绍,实际应用及意义
+- 介绍:  
+智能客服邮件是一个基于python语言开发的项目,它是一个类似脚本项目,用于协助客服工作。
+- 实际应用:  
+如今客服以邮件形式处理客户售前售后问题居多,此项目能协助客服工作,对客服从客户接收到的邮件里的一些简单问题进行自动回复。    
+- 意义:  
+减轻客服工作量,提高客服工作效率。
+
+#### 项目具体功能
+1. 获取和解析网易邮箱内邮件的内容,进行转发。  
+2. 对接aws的comprehend的SDK的相关接口,S3存储桶的SDK的相关接口,对训练标签进行存储,对邮件内容进行自然语言分析。
+
+#### 项目运行环境
+- django 2.1 
+- python 3.7  
+
+#### 如何运行及调试  
+本地环境运行在终端输入如下命令:  
+python manage.py runserver 0.0.0.0:8000  
+
+调试:  
+postman软件  
+
+#### 项目相关文件  
+├── controller  
+│ 	├── ComprehendController.py		// comprehend,sdk相关接口,获取,解析,转发邮件功能接口  
+│	├── EmaillangController.py		// 语言配置增删改查接口  
+│ 	├── EmailProjectController.py   // 邮箱项目配置表增删改查接口  
+│ 	├── EmailSortController.py		// 邮箱分类配置表增删改查接口  
+│ 	├── EmailUserController.py		// 邮箱配置表增删改查接口  
+├── emailtrainfile  
+│ 	├── image						// 存放邮件获取的相关附件  
+│ 	├── emailtrain.csv				// 训练标签表  
+├── Utils  
+│ 	├── NeteaseMail.py				// 类  
+
+核心接口或函数:
+- ComprehendController.py下的email接口
+- NeteaseMail.py下的sentmail函数
+
+#### 项目存在问题
+1. 项目前期需求分析不明确,缺少与客服的沟通。  
+2. 转发功能并未完善,存在邮件内容类型问题,内容编码问题。
+
+### 项目2  
+
+### 项目3  
+ 
+
+
+