mirror of
https://github.com/guohuadeng/app-odoo.git
synced 2025-02-23 04:11:36 +02:00
Add app_chatgpt 聊天屏蔽敏感词功能
This commit is contained in:
@@ -4,10 +4,10 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Odoo Server 16.0+e-20230213\n"
|
"Project-Id-Version: Odoo Server 16.0+e-20230320\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2023-03-02 10:08+0000\n"
|
"POT-Creation-Date: 2023-03-29 07:58+0000\n"
|
||||||
"PO-Revision-Date: 2023-03-02 10:08+0000\n"
|
"PO-Revision-Date: 2023-03-29 07:58+0000\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -15,6 +15,21 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: \n"
|
"Content-Transfer-Encoding: \n"
|
||||||
"Plural-Forms: \n"
|
"Plural-Forms: \n"
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__ai_model
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"GPT-4: Can understand Image, generate natural language or code.\n"
|
||||||
|
"GPT-3.5: A set of models that improve on GPT-3 and can understand as well as generate natural language or code\n"
|
||||||
|
"DALL·E: A model that can generate and edit images given a natural language prompt\n"
|
||||||
|
"Whisper: A model that can convert audio into text\n"
|
||||||
|
"Embeddings:\tA set of models that can convert text into a numerical form\n"
|
||||||
|
"CodexLimited: A set of models that can understand and generate code, including translating natural language to code\n"
|
||||||
|
"Moderation: A fine-tuned model that can detect whether text may be sensitive or unsafe\n"
|
||||||
|
"GPT-3\tA set of models that can understand and generate natural language\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
||||||
@@ -405,6 +420,16 @@ msgstr ""
|
|||||||
msgid "ABCD"
|
msgid "ABCD"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__ai_model
|
||||||
|
msgid "AI Model"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__provider
|
||||||
|
msgid "AI Provider"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
||||||
@@ -414,11 +439,14 @@ msgstr ""
|
|||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__openapi_api_key
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__openapi_api_key
|
||||||
#: model:ir.model.fields,field_description:app_chatgpt.field_res_config_settings__openapi_api_key
|
|
||||||
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
|
|
||||||
msgid "API Key"
|
msgid "API Key"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__api_version
|
||||||
|
msgid "API Version"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
||||||
@@ -510,6 +538,11 @@ msgstr ""
|
|||||||
msgid "Australia"
|
msgid "Australia"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__provider__azure
|
||||||
|
msgid "Azure"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
||||||
@@ -619,6 +652,11 @@ msgstr ""
|
|||||||
msgid "ChatGPT"
|
msgid "ChatGPT"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ai.robot,name:app_chatgpt.chatgpt_robot3
|
||||||
|
msgid "ChatGPT Azure"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#: model:ai.robot,name:app_chatgpt.chatgpt_robot1
|
#: model:ai.robot,name:app_chatgpt.chatgpt_robot1
|
||||||
msgid "ChatGPT Coding"
|
msgid "ChatGPT Coding"
|
||||||
@@ -648,6 +686,36 @@ msgstr ""
|
|||||||
msgid "ChatGpt Training"
|
msgid "ChatGpt Training"
|
||||||
msgstr "ChatGpt训练"
|
msgstr "ChatGpt训练"
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__code-davinci-002
|
||||||
|
msgid "Chatgpt 2 Code Optimized"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__text-davinci-002
|
||||||
|
msgid "Chatgpt 2 Davinci"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__text-davinci-003
|
||||||
|
msgid "Chatgpt 3 Davinci"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__gpt-3_5-turbo
|
||||||
|
msgid "Chatgpt 3.5 Turbo"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__gpt-3_5-turbo-0301
|
||||||
|
msgid "Chatgpt 3.5 Turbo on 20230301"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__gpt-4
|
||||||
|
msgid "Chatgpt 4"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
||||||
@@ -710,6 +778,11 @@ msgstr ""
|
|||||||
msgid "DVD"
|
msgid "DVD"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__ai_model__dall-e2
|
||||||
|
msgid "Dall-E Image"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
||||||
@@ -764,6 +837,16 @@ msgstr ""
|
|||||||
msgid "END arrow"
|
msgid "END arrow"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__endpoint
|
||||||
|
msgid "End Point"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__engine
|
||||||
|
msgid "Engine"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
||||||
@@ -822,6 +905,11 @@ msgstr ""
|
|||||||
msgid "Ferris"
|
msgid "Ferris"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__is_filtering
|
||||||
|
msgid "Filter Sensitive Words"
|
||||||
|
msgstr "是否启用敏感词过滤"
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
||||||
@@ -917,6 +1005,11 @@ msgstr ""
|
|||||||
msgid "ILY"
|
msgid "ILY"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__engine
|
||||||
|
msgid "If use Azure, Please input the Model deployment name."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
#: code:addons/app_chatgpt/static/src/models_data/emoji_data.js:0
|
||||||
@@ -1244,6 +1337,11 @@ msgstr ""
|
|||||||
msgid "Mahjong red dragon"
|
msgid "Mahjong red dragon"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__max_length
|
||||||
|
msgid "Max Length"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#: model:ir.model,name:app_chatgpt.model_mail_message
|
#: model:ir.model,name:app_chatgpt.model_mail_message
|
||||||
msgid "Message"
|
msgid "Message"
|
||||||
@@ -1436,8 +1534,13 @@ msgid "Objects"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#: model_terms:ir.ui.view,arch_db:app_chatgpt.is_res_config_settings_view
|
#: model:ir.model.fields.selection,name:app_chatgpt.selection__ai_robot__provider__openai
|
||||||
msgid "OpenAPI API Key"
|
msgid "OpenAI"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model_terms:ir.ui.view,arch_db:app_chatgpt.ai_robot_form_view
|
||||||
|
msgid "OpenAI Document"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
@@ -1487,9 +1590,22 @@ msgstr ""
|
|||||||
msgid "Pisces"
|
msgid "Pisces"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/app_chatgpt/models/ai_robot.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Please Set your AI robot's API Version first."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/app_chatgpt/models/ai_robot.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Please Set your AI robot's endpoint first."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__openapi_api_key
|
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__openapi_api_key
|
||||||
#: model:ir.model.fields,help:app_chatgpt.field_res_config_settings__openapi_api_key
|
|
||||||
msgid "Provide the API key here"
|
msgid "Provide the API key here"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1582,6 +1698,16 @@ msgstr ""
|
|||||||
msgid "Selected Users"
|
msgid "Selected Users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__sensitive_words
|
||||||
|
msgid "Sensitive Words"
|
||||||
|
msgstr "敏感词"
|
||||||
|
|
||||||
|
#. module: app_chatgpt
|
||||||
|
#: model:ir.model.fields,help:app_chatgpt.field_ai_robot__sensitive_words
|
||||||
|
msgid "Sensitive word filtering. Separate keywords with a carriage return."
|
||||||
|
msgstr "敏感词过滤。请用回车符分隔关键词。"
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__sequence
|
#: model:ir.model.fields,field_description:app_chatgpt.field_ai_robot__sequence
|
||||||
msgid "Sequence"
|
msgid "Sequence"
|
||||||
@@ -1805,7 +1931,7 @@ msgstr ""
|
|||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#: model:ir.model,name:app_chatgpt.model_res_users
|
#: model:ir.model,name:app_chatgpt.model_res_users
|
||||||
msgid "User"
|
msgid "User"
|
||||||
msgstr "用户"
|
msgstr ""
|
||||||
|
|
||||||
#. module: app_chatgpt
|
#. module: app_chatgpt
|
||||||
#. odoo-javascript
|
#. odoo-javascript
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ import requests
|
|||||||
import openai
|
import openai
|
||||||
from odoo import api, fields, models, _
|
from odoo import api, fields, models, _
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
|
from .lib.WordsSearch import WordsSearch
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AiRobot(models.Model):
|
class AiRobot(models.Model):
|
||||||
_name = 'ai.robot'
|
_name = 'ai.robot'
|
||||||
_description = 'Gpt Robot'
|
_description = 'Gpt Robot'
|
||||||
@@ -41,6 +43,8 @@ GPT-3 A set of models that can understand and generate natural language
|
|||||||
engine = fields.Char('Engine', help='If use Azure, Please input the Model deployment name.')
|
engine = fields.Char('Engine', help='If use Azure, Please input the Model deployment name.')
|
||||||
api_version = fields.Char('API Version', default='2022-12-01')
|
api_version = fields.Char('API Version', default='2022-12-01')
|
||||||
sequence = fields.Integer('Sequence', help="Determine the display order", default=10)
|
sequence = fields.Integer('Sequence', help="Determine the display order", default=10)
|
||||||
|
sensitive_words = fields.Text('Sensitive Words', help='Sensitive word filtering. Separate keywords with a carriage return.')
|
||||||
|
is_filtering = fields.Boolean('Filter Sensitive Words', default=False)
|
||||||
|
|
||||||
def action_disconnect(self):
|
def action_disconnect(self):
|
||||||
requests.delete('https://chatgpt.com/v1/disconnect')
|
requests.delete('https://chatgpt.com/v1/disconnect')
|
||||||
@@ -68,6 +72,7 @@ GPT-3 A set of models that can understand and generate natural language
|
|||||||
_logger.warning('=====================azure input data: %s' % data)
|
_logger.warning('=====================azure input data: %s' % data)
|
||||||
if 'choices' in response:
|
if 'choices' in response:
|
||||||
res = response['choices'][0]['text'].replace(' .', '.').strip()
|
res = response['choices'][0]['text'].replace(' .', '.').strip()
|
||||||
|
res = self.filter_sensitive_words(res)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@api.onchange('provider')
|
@api.onchange('provider')
|
||||||
@@ -77,3 +82,10 @@ GPT-3 A set of models that can understand and generate natural language
|
|||||||
elif self.provider == 'azure':
|
elif self.provider == 'azure':
|
||||||
self.endpoint = 'https://odoo.openai.azure.com'
|
self.endpoint = 'https://odoo.openai.azure.com'
|
||||||
|
|
||||||
|
def filter_sensitive_words(self, data):
|
||||||
|
if self.is_filtering:
|
||||||
|
search = WordsSearch()
|
||||||
|
s = self.sensitive_words
|
||||||
|
search.SetKeywords(s.split('\n'))
|
||||||
|
result = search.Replace(text=data)
|
||||||
|
return result
|
||||||
|
|||||||
291
app_chatgpt/models/lib/WordsSearch.py
Normal file
291
app_chatgpt/models/lib/WordsSearch.py
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding:utf-8 -*-
|
||||||
|
# ToolGood.Words.WordsSearch.py
|
||||||
|
# 2020, Lin Zhijun, https://github.com/toolgood/ToolGood.Words
|
||||||
|
# Licensed under the Apache License 2.0
|
||||||
|
# 更新日志
|
||||||
|
# 2020.04.06 第一次提交
|
||||||
|
# 2020.05.16 修改,支持大于0xffff的字符
|
||||||
|
|
||||||
|
__all__ = ['WordsSearch']
|
||||||
|
__author__ = 'Lin Zhijun'
|
||||||
|
__date__ = '2020.05.16'
|
||||||
|
|
||||||
|
|
||||||
|
class TrieNode():
|
||||||
|
def __init__(self):
|
||||||
|
self.Index = 0
|
||||||
|
self.Index = 0
|
||||||
|
self.Layer = 0
|
||||||
|
self.End = False
|
||||||
|
self.Char = ''
|
||||||
|
self.Results = []
|
||||||
|
self.m_values = {}
|
||||||
|
self.Failure = None
|
||||||
|
self.Parent = None
|
||||||
|
|
||||||
|
def Add(self, c):
|
||||||
|
if c in self.m_values:
|
||||||
|
return self.m_values[c]
|
||||||
|
node = TrieNode()
|
||||||
|
node.Parent = self
|
||||||
|
node.Char = c
|
||||||
|
self.m_values[c] = node
|
||||||
|
return node
|
||||||
|
|
||||||
|
def SetResults(self, index):
|
||||||
|
if (self.End == False):
|
||||||
|
self.End = True
|
||||||
|
self.Results.append(index)
|
||||||
|
|
||||||
|
|
||||||
|
class TrieNode2():
|
||||||
|
def __init__(self):
|
||||||
|
self.End = False
|
||||||
|
self.Results = []
|
||||||
|
self.m_values = {}
|
||||||
|
self.minflag = 0xffff
|
||||||
|
self.maxflag = 0
|
||||||
|
|
||||||
|
def Add(self, c, node3):
|
||||||
|
if (self.minflag > c):
|
||||||
|
self.minflag = c
|
||||||
|
if (self.maxflag < c):
|
||||||
|
self.maxflag = c
|
||||||
|
self.m_values[c] = node3
|
||||||
|
|
||||||
|
def SetResults(self, index):
|
||||||
|
if (self.End == False):
|
||||||
|
self.End = True
|
||||||
|
if (index in self.Results) == False:
|
||||||
|
self.Results.append(index)
|
||||||
|
|
||||||
|
def HasKey(self, c):
|
||||||
|
return c in self.m_values
|
||||||
|
|
||||||
|
def TryGetValue(self, c):
|
||||||
|
if (self.minflag <= c and self.maxflag >= c):
|
||||||
|
if c in self.m_values:
|
||||||
|
return self.m_values[c]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class WordsSearch():
|
||||||
|
def __init__(self):
|
||||||
|
self._first = {}
|
||||||
|
self._keywords = []
|
||||||
|
self._indexs = []
|
||||||
|
|
||||||
|
def SetKeywords(self, keywords):
|
||||||
|
self._keywords = keywords
|
||||||
|
self._indexs = []
|
||||||
|
for i in range(len(keywords)):
|
||||||
|
self._indexs.append(i)
|
||||||
|
|
||||||
|
root = TrieNode()
|
||||||
|
allNodeLayer = {}
|
||||||
|
|
||||||
|
for i in range(len(self._keywords)): # for (i = 0; i < _keywords.length; i++)
|
||||||
|
p = self._keywords[i]
|
||||||
|
nd = root
|
||||||
|
for j in range(len(p)): # for (j = 0; j < p.length; j++)
|
||||||
|
nd = nd.Add(ord(p[j]))
|
||||||
|
if (nd.Layer == 0):
|
||||||
|
nd.Layer = j + 1
|
||||||
|
if nd.Layer in allNodeLayer:
|
||||||
|
allNodeLayer[nd.Layer].append(nd)
|
||||||
|
else:
|
||||||
|
allNodeLayer[nd.Layer] = []
|
||||||
|
allNodeLayer[nd.Layer].append(nd)
|
||||||
|
nd.SetResults(i)
|
||||||
|
|
||||||
|
allNode = []
|
||||||
|
allNode.append(root)
|
||||||
|
for key in allNodeLayer.keys():
|
||||||
|
for nd in allNodeLayer[key]:
|
||||||
|
allNode.append(nd)
|
||||||
|
allNodeLayer = None
|
||||||
|
|
||||||
|
for i in range(len(allNode)): # for (i = 0; i < allNode.length; i++)
|
||||||
|
if i == 0:
|
||||||
|
continue
|
||||||
|
nd = allNode[i]
|
||||||
|
nd.Index = i
|
||||||
|
r = nd.Parent.Failure
|
||||||
|
c = nd.Char
|
||||||
|
while (r != None and (c in r.m_values) == False):
|
||||||
|
r = r.Failure
|
||||||
|
if (r == None):
|
||||||
|
nd.Failure = root
|
||||||
|
else:
|
||||||
|
nd.Failure = r.m_values[c]
|
||||||
|
for key2 in nd.Failure.Results:
|
||||||
|
nd.SetResults(key2)
|
||||||
|
root.Failure = root
|
||||||
|
|
||||||
|
allNode2 = []
|
||||||
|
for i in range(len(allNode)): # for (i = 0; i < allNode.length; i++)
|
||||||
|
allNode2.append(TrieNode2())
|
||||||
|
|
||||||
|
for i in range(len(allNode2)): # for (i = 0; i < allNode2.length; i++)
|
||||||
|
oldNode = allNode[i]
|
||||||
|
newNode = allNode2[i]
|
||||||
|
|
||||||
|
for key in oldNode.m_values:
|
||||||
|
index = oldNode.m_values[key].Index
|
||||||
|
newNode.Add(key, allNode2[index])
|
||||||
|
|
||||||
|
for index in range(len(oldNode.Results)): # for (index = 0; index < oldNode.Results.length; index++)
|
||||||
|
item = oldNode.Results[index]
|
||||||
|
newNode.SetResults(item)
|
||||||
|
|
||||||
|
oldNode = oldNode.Failure
|
||||||
|
while oldNode != root:
|
||||||
|
for key in oldNode.m_values:
|
||||||
|
if (newNode.HasKey(key) == False):
|
||||||
|
index = oldNode.m_values[key].Index
|
||||||
|
newNode.Add(key, allNode2[index])
|
||||||
|
for index in range(len(oldNode.Results)):
|
||||||
|
item = oldNode.Results[index]
|
||||||
|
newNode.SetResults(item)
|
||||||
|
oldNode = oldNode.Failure
|
||||||
|
allNode = None
|
||||||
|
root = None
|
||||||
|
|
||||||
|
# first = []
|
||||||
|
# for index in range(65535):# for (index = 0; index < 0xffff; index++)
|
||||||
|
# first.append(None)
|
||||||
|
|
||||||
|
# for key in allNode2[0].m_values :
|
||||||
|
# first[key] = allNode2[0].m_values[key]
|
||||||
|
|
||||||
|
self._first = allNode2[0]
|
||||||
|
|
||||||
|
def FindFirst(self, text):
|
||||||
|
ptr = None
|
||||||
|
for index in range(len(text)): # for (index = 0; index < text.length; index++)
|
||||||
|
t = ord(text[index]) # text.charCodeAt(index)
|
||||||
|
tn = None
|
||||||
|
if (ptr == None):
|
||||||
|
tn = self._first.TryGetValue(t)
|
||||||
|
else:
|
||||||
|
tn = ptr.TryGetValue(t)
|
||||||
|
if (tn == None):
|
||||||
|
tn = self._first.TryGetValue(t)
|
||||||
|
|
||||||
|
if (tn != None):
|
||||||
|
if (tn.End):
|
||||||
|
item = tn.Results[0]
|
||||||
|
keyword = self._keywords[item]
|
||||||
|
return {"Keyword": keyword, "Success": True, "End": index, "Start": index + 1 - len(keyword), "Index": self._indexs[item]}
|
||||||
|
ptr = tn
|
||||||
|
return None
|
||||||
|
|
||||||
|
def FindAll(self, text):
|
||||||
|
ptr = None
|
||||||
|
list = []
|
||||||
|
|
||||||
|
for index in range(len(text)): # for (index = 0; index < text.length; index++)
|
||||||
|
t = ord(text[index]) # text.charCodeAt(index)
|
||||||
|
tn = None
|
||||||
|
if (ptr == None):
|
||||||
|
tn = self._first.TryGetValue(t)
|
||||||
|
else:
|
||||||
|
tn = ptr.TryGetValue(t)
|
||||||
|
if (tn == None):
|
||||||
|
tn = self._first.TryGetValue(t)
|
||||||
|
|
||||||
|
if (tn != None):
|
||||||
|
if (tn.End):
|
||||||
|
for j in range(len(tn.Results)): # for (j = 0; j < tn.Results.length; j++)
|
||||||
|
item = tn.Results[j]
|
||||||
|
keyword = self._keywords[item]
|
||||||
|
list.append({"Keyword": keyword, "Success": True, "End": index, "Start": index + 1 - len(keyword), "Index": self._indexs[item]})
|
||||||
|
ptr = tn
|
||||||
|
return list
|
||||||
|
|
||||||
|
def ContainsAny(self, text):
|
||||||
|
ptr = None
|
||||||
|
for index in range(len(text)): # for (index = 0; index < text.length; index++)
|
||||||
|
t = ord(text[index]) # text.charCodeAt(index)
|
||||||
|
tn = None
|
||||||
|
if (ptr == None):
|
||||||
|
tn = self._first.TryGetValue(t)
|
||||||
|
else:
|
||||||
|
tn = ptr.TryGetValue(t)
|
||||||
|
if (tn == None):
|
||||||
|
tn = self._first.TryGetValue(t)
|
||||||
|
|
||||||
|
if (tn != None):
|
||||||
|
if (tn.End):
|
||||||
|
return True
|
||||||
|
ptr = tn
|
||||||
|
return False
|
||||||
|
|
||||||
|
def Replace(self, text, replaceChar='*'):
|
||||||
|
result = list(text)
|
||||||
|
|
||||||
|
ptr = None
|
||||||
|
for i in range(len(text)): # for (i = 0; i < text.length; i++)
|
||||||
|
t = ord(text[i]) # text.charCodeAt(index)
|
||||||
|
tn = None
|
||||||
|
if (ptr == None):
|
||||||
|
tn = self._first.TryGetValue(t)
|
||||||
|
else:
|
||||||
|
tn = ptr.TryGetValue(t)
|
||||||
|
if (tn == None):
|
||||||
|
tn = self._first.TryGetValue(t)
|
||||||
|
|
||||||
|
if (tn != None):
|
||||||
|
if (tn.End):
|
||||||
|
maxLength = len(self._keywords[tn.Results[0]])
|
||||||
|
start = i + 1 - maxLength
|
||||||
|
for j in range(start, i + 1): # for (j = start; j <= i; j++)
|
||||||
|
result[j] = replaceChar
|
||||||
|
ptr = tn
|
||||||
|
return ''.join(result)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
s = "中国|国人|zg人|乾清宫"
|
||||||
|
test = "我是中国人"
|
||||||
|
|
||||||
|
search = WordsSearch()
|
||||||
|
search.SetKeywords(s.split('|'))
|
||||||
|
|
||||||
|
print("----------------------------------- WordsSearch -----------------------------------")
|
||||||
|
|
||||||
|
print("WordsSearch FindFirst is run.")
|
||||||
|
f = search.FindFirst(test)
|
||||||
|
if f["Keyword"] != "中国":
|
||||||
|
print("WordsSearch FindFirst is error.............................")
|
||||||
|
|
||||||
|
print("WordsSearch FindFirst is run.")
|
||||||
|
all = search.FindAll("乾清宫")
|
||||||
|
if all[0]["Keyword"] != "乾清宫":
|
||||||
|
print("WordsSearch FindFirst is error.............................")
|
||||||
|
|
||||||
|
print("WordsSearch FindAll is run.")
|
||||||
|
all = search.FindAll(test)
|
||||||
|
if all[0]["Keyword"] != "中国":
|
||||||
|
print("WordsSearch FindAll is error.............................")
|
||||||
|
if all[1]["Keyword"] != "国人":
|
||||||
|
print("WordsSearch FindAll is error.............................")
|
||||||
|
if all[0]["Start"] != 2:
|
||||||
|
print("WordsSearch FindAll is error.............................")
|
||||||
|
if all[0]["End"] != 3:
|
||||||
|
print("WordsSearch FindAll is error.............................")
|
||||||
|
if len(all) != 2:
|
||||||
|
print("WordsSearch FindAll is error.............................")
|
||||||
|
|
||||||
|
print("WordsSearch ContainsAny is run.")
|
||||||
|
b = search.ContainsAny(test)
|
||||||
|
if b == False:
|
||||||
|
print("WordsSearch ContainsAny is error.............................")
|
||||||
|
|
||||||
|
print("WordsSearch Replace is run.")
|
||||||
|
txt = search.Replace(test)
|
||||||
|
if (txt != "我是***"):
|
||||||
|
print("WordsSearch Replace is error.............................")
|
||||||
|
|
||||||
|
print("----------------------------------- Test End -----------------------------------")
|
||||||
@@ -43,6 +43,10 @@
|
|||||||
<field name="endpoint"/>
|
<field name="endpoint"/>
|
||||||
<field name="api_version"/>
|
<field name="api_version"/>
|
||||||
</group>
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="is_filtering"/>
|
||||||
|
<field name="sensitive_words" attrs="{'invisible': [('is_filtering', '=', False)]}"/>
|
||||||
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</sheet>
|
</sheet>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user