PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Python/plasma/ptWordFilter.py

https://bitbucket.org/cwalther/moulscript-dlanor
Python | 156 lines | 100 code | 4 blank | 52 comment | 16 complexity | 6921bdc27dd86aeec54fb1055ab26082 MD5 | raw file
Possible License(s): AGPL-1.0, GPL-3.0
  1. """ *==LICENSE==*
  2. CyanWorlds.com Engine - MMOG client, server and tools
  3. Copyright (C) 2011 Cyan Worlds, Inc.
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. Additional permissions under GNU GPL version 3 section 7
  15. If you modify this Program, or any covered work, by linking or
  16. combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
  17. NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
  18. JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
  19. (or a modified version of those libraries),
  20. containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
  21. PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
  22. JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
  23. licensors of this Program grant you additional
  24. permission to convey the resulting work. Corresponding Source for a
  25. non-source form of such a combination shall include the source code for
  26. the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
  27. work.
  28. You can contact Cyan Worlds, Inc. by email legal@cyan.com
  29. or by snail mail at:
  30. Cyan Worlds, Inc.
  31. 14617 N Newport Hwy
  32. Mead, WA 99021
  33. *==LICENSE==* """
  34. """
  35. This module is the word filter to be used...
  36. """
  37. import string
  38. import re
  39. # Rating levels
  40. xRatedG = 0
  41. xRatedPG = 1
  42. xRatedPG13 = 2
  43. xRatedR = 3
  44. xRatedX = 4
  45. class LanguageFilter:
  46. def __init__(self):
  47. pass
  48. def test(self,sentence):
  49. "returns censored sentence"
  50. return xRatedG
  51. def censor(self,sentence,censorLevel):
  52. "returns censored sentence"
  53. return sentence
  54. class ExactMatchListFilter(LanguageFilter):
  55. def __init__(self,wordlist):
  56. self.wordlist = wordlist
  57. def test(self,sentence):
  58. "return the rating of sentence in question"
  59. rated = xRatedG # assume rated lowest level
  60. startidx = 0
  61. for endidx in range(len(sentence)):
  62. if sentence[endidx] in string.whitespace or sentence[endidx] in string.punctuation:
  63. if startidx != endidx:
  64. try:
  65. # find and get rating and substitute
  66. rating = self.wordlist[string.lower(sentence[startidx:endidx])]
  67. except LookupError:
  68. # couldn't find word
  69. rating = None
  70. if rating != None and rating.rating > rated:
  71. # substitute into string
  72. rated = rating.rating
  73. startidx = endidx + 1
  74. if startidx < len(sentence):
  75. try:
  76. # find and get rating and substitute
  77. rating = self.wordlist[string.lower(sentence[startidx:])]
  78. except LookupError:
  79. # couldn't find word
  80. rating = None
  81. if rating != None and rating.rating > rated:
  82. # substitute into string
  83. rated = rating.rating
  84. return rated
  85. def censor(self,sentence,censorLevel):
  86. "censors a sentence to a rating"
  87. # break into words, but perserve original punctuation
  88. censored = ""
  89. startidx = 0
  90. for endidx in range(len(sentence)):
  91. if sentence[endidx] in string.whitespace or sentence[endidx] in string.punctuation:
  92. if startidx != endidx:
  93. try:
  94. # find and get rating and substitute
  95. rating = self.wordlist[string.lower(sentence[startidx:endidx])]
  96. except LookupError:
  97. # couldn't find word
  98. rating = None
  99. if rating != None and rating.rating > censorLevel:
  100. # substitute into string
  101. censored += rating.substitute + sentence[endidx]
  102. else:
  103. censored += sentence[startidx:endidx] + sentence[endidx]
  104. else:
  105. censored += sentence[startidx]
  106. startidx = endidx + 1
  107. if startidx < len(sentence):
  108. # Special after loop processing!
  109. try:
  110. # find and get rating and substitute
  111. rating = self.wordlist[string.lower(sentence[startidx:])]
  112. except LookupError:
  113. # couldn't find word
  114. rating = None
  115. if rating != None and rating.rating > censorLevel:
  116. # substitute into string
  117. censored += rating.substitute
  118. else:
  119. censored += sentence[startidx:]
  120. return censored
  121. class REFilter(LanguageFilter):
  122. def __init__(self,regexp,rating):
  123. self.compiledRE = re.compile(regexp, re.IGNORECASE | re.MULTILINE )
  124. if not isinstance(rating,Rating):
  125. PtDebugPrint("ptWordFilter: rating for %s not of type Rating" % (regexp))
  126. self.rating = rating
  127. def test(self,sentence):
  128. "return the rating of sentence in question"
  129. if self.compiledRE.search(sentence) != None:
  130. return self.rating.rating
  131. return xRatedG
  132. def censor(self,sentence,censorLevel):
  133. "censors a sentence to a rating"
  134. if self.rating.rating > censorLevel:
  135. if self.compiledRE.search(sentence) != None:
  136. return self.compiledRE.sub(self.rating.substitute,sentence)
  137. return sentence
  138. class Rating:
  139. "substitute can be string for exact substitute or number of splat replacement"
  140. def __init__(self,rating,subtitute="*****"):
  141. self.rating = rating
  142. self.substitute = subtitute