def checkPeriods(name):
     words = wordList(name)
     for word in words:
         if word[-1] == ',':
             word = word[:-1]
         
         numPeriods = word.count('.')
         if not numPeriods:
             continue
         
         letters = justLetters(word)
         numLetters = len(letters)
         if word[-1] != '.':
             notify.info('word "%s" does not end in a period' % TextEncoder().encodeWtext(word))
             return OTPLocalizer.NCPeriodUsage
         
         if numPeriods > 2:
             notify.info('word "%s" has too many periods' % TextEncoder().encodeWtext(word))
             return OTPLocalizer.NCPeriodUsage
         
         if numPeriods == 2:
             if not word[1] == '.' and word[3] == '.':
                 notify.info('word "%s" does not fit the J.T. pattern' % TextEncoder().encodeWtext(word))
                 return OTPLocalizer.NCPeriodUsage
             
         word[3] == '.'
Ejemplo n.º 2
0
    def checkJapanese(name):
        asciiSpace = range(32, 33)
        asciiDigits = range(48, 64)
        hiragana = range(12353, 12448)
        katakana = range(12449, 12544)
        halfwidthKatakana = range(65381, 65440)
        halfwidthCharacter = set(asciiSpace + halfwidthKatakana)
        allowedUtf8 = set(asciiSpace + hiragana + katakana + halfwidthKatakana)

        te = TextEncoder()
        dc = 0.0

        for char in (ord(char) for char in te.decodeText(name)):
            if char not in allowedUtf8:
                if char in asciiDigits:
                    notify.info('name contains not allowed ascii digits')
                    return OTPLocalizer.NCNoDigits
                else:
                    notify.info('name contains not allowed utf8 char: 0x%04x' %
                                char)
                    return OTPLocalizer.NCBadCharacter % te.encodeWtext(
                        unichr(char))
            elif char in halfwidthCharacter:
                dc += 0.5
            else:
                dc += 1

        if dc < 2:
            notify.info('name is too short: %0.1f' % dc)
            return OTPLocalizer.NCTooShort
        elif dc > 8:
            notify.info(
                'name has been occupied more than eight display cells: %0.1f' %
                dc)
            return OTPLocalizer.NCGeneric
Ejemplo n.º 3
0
    def checkJapanese(name):
        asciiSpace = range(32, 33)
        asciiDigits = range(48, 64)
        hiragana = range(12353, 12448)
        katakana = range(12449, 12544)
        halfwidthKatakana = range(65381, 65440)
        halfwidthCharacter = set(asciiSpace + halfwidthKatakana)
        allowedUtf8 = set(asciiSpace + hiragana + katakana + halfwidthKatakana)

        te = TextEncoder()
        dc = 0.0

        for char in (ord(char) for char in te.decodeText(name)):
            if char not in allowedUtf8:
                if char in asciiDigits:
                    notify.info('name contains not allowed ascii digits')
                    return OTPLocalizer.NCNoDigits
                else:
                    notify.info('name contains not allowed utf8 char: 0x%04x' % char)
                    return OTPLocalizer.NCBadCharacter % te.encodeWtext(unichr(char))
            elif char in halfwidthCharacter:
                dc += 0.5
            else:
                dc += 1

        if dc < 2:
            notify.info('name is too short: %0.1f' % dc)
            return OTPLocalizer.NCTooShort
        elif dc > 8:
            notify.info('name has been occupied more than eight display cells: %0.1f' % dc)
            return OTPLocalizer.NCGeneric
Ejemplo n.º 4
0
 def fontHasCharacters(name, font=font):
     if font:
         tn = TextNode('NameCheck')
         tn.setFont(font)
         for c in name:
             if not tn.hasCharacter(ord(c)):
                 notify.info('name contains bad char: %s' % TextEncoder().encodeWtext(c))
                 return OTPLocalizer.NCBadCharacter % TextEncoder().encodeWtext(c)
 def badCharacters(name, _validCharacter = _validCharacter):
     for char in name:
         if not _validCharacter(char):
             if char in string.digits:
                 notify.info('name contains digits')
                 return OTPLocalizer.NCNoDigits
             else:
                 notify.info('name contains bad char: %s' % TextEncoder().encodeWtext(char))
                 return OTPLocalizer.NCBadCharacter % TextEncoder().encodeWtext(char)
 def perWord(word):
     word = word
     letters = justLetters(word)
     if len(letters) > 2:
         letters = TextEncoder().decodeText(TextEncoder.lower(TextEncoder().encodeWtext(letters)))
         filtered = filterString(letters, letters[0])
         if filtered == letters:
             notify.info('word "%s" uses only one letter' % TextEncoder().encodeWtext(word))
             return OTPLocalizer.NCGeneric
    def allCaps(name):
        letters = justLetters(name)
        if len(letters) > 2:
            upperLetters = TextEncoder().decodeText(TextEncoder.upper(TextEncoder().encodeWtext(letters)))
            for i in xrange(len(upperLetters)):
                if not upperLetters[0].isupper():
                    return

            if upperLetters == letters:
                notify.info('name is all caps')
                return OTPLocalizer.NCAllCaps
Ejemplo n.º 8
0
 def __typedAName(self, *args):
     self.notify.debug('__typedAName')
     self.nameEntry['focus'] = 0
     name = self.nameEntry.get()
     name = TextEncoder().decodeText(name)
     name = name.strip()
     name = TextEncoder().encodeWtext(name)
     self.nameEntry.enterText(name)
     problem = self.nameIsValid(self.nameEntry.get())
     if problem:
         self.rejectName(problem)
         return
     self.checkNameTyped(justCheck=True)
Ejemplo n.º 9
0
 def __typedAName(self, *args):
     self.notify.debug('__typedAName')
     self.nameEntry['focus'] = 0
     name = self.nameEntry.get()
     name = TextEncoder().decodeText(name)
     name = name.strip()
     name = TextEncoder().encodeWtext(name)
     self.nameEntry.enterText(name)
     problem = self.nameIsValid(self.nameEntry.get())
     if problem:
         self.rejectName(problem)
         return
     self.checkNameTyped(justCheck=True)
 def repeatedChars(name):
     count = 1
     lastChar = None
     i = 0
     while i < len(name):
         char = name[i]
         i += 1
         if char == lastChar:
             count += 1
         else:
             count = 1
         lastChar = char
         if count > 2:
             notify.info('character %s is repeated too many times' % TextEncoder().encodeWtext(char))
             return OTPLocalizer.NCRepeatedChar % TextEncoder().encodeWtext(char)
Ejemplo n.º 11
0
 def _typedAName(self, *args):
     self.nameEntry['focus'] = 0
     name = self.nameEntry.get()
     name = TextEncoder().decodeText(name)
     name = name.strip()
     name = TextEncoder().encodeWtext(name)
     self.nameEntry.enterText(name)
     self.notify.debug('Chosen name: %s' % self.nameEntry.get())
     problem = NameCheck.checkName(name, [self._checkNpcNames],
                                   font=self.nameEntry.getFont())
     if problem:
         print problem
         self.nameEntry.enterText('')
     else:
         self.fsm.request('Approved')
 def _typedAName(self, *args):
     self.nameEntry['focus'] = 0
     name = self.nameEntry.get()
     name = TextEncoder().decodeText(name)
     name = name.strip()
     name = TextEncoder().encodeWtext(name)
     self.nameEntry.enterText(name)
     self.notify.debug('Chosen name: %s' % self.nameEntry.get())
     problem = NameCheck.checkName(name, [
         self._checkNpcNames], font = self.nameEntry.getFont())
     if problem:
         print problem
         self.nameEntry.enterText('')
     else:
         self.fsm.request('Approved')
 def makeSign(topStr, signStr, textId):
     top = self.geom.find('**/' + topStr)
     sign = top.find('**/' + signStr)
     locator = top.find('**/sign_origin')
     signText = DirectGui.OnscreenText(text=TextEncoder.upper(TTLocalizer.GlobalStreetNames[textId][-1]), font=ToontownGlobals.getSuitFont(), scale=TTLocalizer.BCHQLsignText, fg=(0, 0, 0, 1), parent=sign)
     signText.setPosHpr(locator, 0, -0.1, -0.25, 0, 0, 0)
     signText.setDepthWrite(0)
Ejemplo n.º 14
0
 def makeSign(topStr, signStr, textId):
     top = self.geom.find('**/' + topStr)
     sign = top.find('**/' + signStr)
     locator = top.find('**/sign_origin')
     signText = DirectGui.OnscreenText(text=TextEncoder.upper(TTLocalizer.GlobalStreetNames[textId][-1]), font=ToontownGlobals.getSuitFont(), scale=TTLocalizer.BCHQLsignText, fg=(0, 0, 0, 1), parent=sign)
     signText.setPosHpr(locator, 0, -0.1, -0.25, 0, 0, 0)
     signText.setDepthWrite(0)
 def hasLetters(name):
     words = wordList(name)
     for word in words:
         letters = justLetters(word)
         if len(letters) == 0:
             notify.info('word "%s" has no letters' % TextEncoder().encodeWtext(word))
             return OTPLocalizer.NCNeedLetters
Ejemplo n.º 16
0
    def checkJapanese(name):
        # Japan allows ASCII space, hiragana, katakana, and half-width katakana,
        # but, allows not ASCII and kanji(CJK) characters for a name
        # All Japanese characters are three-byte-encoded utf-8 characters from unicode
        # Reference: http://unicode.org/charts/
        asciiSpace = range(0x20, 0x21)
        asciiDigits = range(0x30, 0x40)
        hiragana = range(0x3041, 0x30A0)
        katakana = range(0x30A1, 0x3100)
        halfwidthKatakana = range(0xFF65, 0xFFA0)
        halfwidthCharacter = set(asciiSpace + halfwidthKatakana)
        allowedUtf8 = set(asciiSpace + hiragana + katakana + halfwidthKatakana)
        te = TextEncoder()
        dc = 0.0

        # Return None if name is OK, error string if name is not OK
        for char in (ord(char) for char in te.decodeText(name)):
            if char not in allowedUtf8:
                # Notify error string, if not allowed utf-8 character
                if char in asciiDigits:
                    notify.info('name contains not allowed ascii digits')
                    return OTPLocalizer.NCNoDigits
                else:
                    notify.info('name contains not allowed utf8 char: 0x%04x' %
                                char)
                    return OTPLocalizer.NCBadCharacter % te.encodeWtext(
                        unichr(char))
            else:
                # Restrict the number of characters, if three-byte-encoded utf-8 character
                # The full-width characters would fit into a single display cell,
                # and the half-width characters would fit two to a display cell
                if char in halfwidthCharacter:
                    dc += 0.5
                else:
                    dc += 1

        # Japan restricts the number of the characters, if occupied less then two display cell
        # and more then eight display cell.
        if (dc < 2):
            notify.info('name is too short: %0.1f' % dc)
            return OTPLocalizer.NCTooShort
        elif (dc > 8):
            notify.info(
                'name has been occupied more than eight display cells: %0.1f' %
                dc)
            return OTPLocalizer.NCGeneric
Ejemplo n.º 17
0
 def allCaps(name):
     # MICKEY MOUSE
     letters = justLetters(name)
     # J.T. -> OK
     if len(letters) > 2:
         upperLetters = TextEncoder().decodeText(
             TextEncoder.upper(TextEncoder().encodeWtext(letters)))
         # some unicode characters can't be capitalized
         for i in xrange(len(upperLetters)):
             if not upperLetters[0].isupper():
                 # at least one letter is not upper-case
                 # name is not all-caps
                 # excessive capitalization will be caught by mixedCase()
                 return
         if upperLetters == letters:
             notify.info('name is all caps')
             return OTPLocalizer.NCAllCaps
Ejemplo n.º 18
0
 def perWord(word):
     word = word
     letters = justLetters(word)
     if len(letters) > 2:
         letters = TextEncoder().decodeText(TextEncoder.lower(TextEncoder().encodeWtext(letters)))
         filtered = filterString(letters, letters[0])
         if filtered == letters:
             notify.info('word "%s" uses only one letter' % TextEncoder().encodeWtext(word))
             return OTPLocalizer.NCGeneric
 def complete(self):
     self.nameEntry['focus'] = 0
     name = self.nameEntry.get()
     name = TextEncoder().decodeText(name)
     name = name.strip()
     name = TextEncoder().encodeWtext(name)
     self.nameEntry.enterText(name)
     self.notify.debug('Chosen name: %s' % name)
     if self.customName:
         problem = NameCheck.checkName(name, [
             self._checkNpcNames], font = self.nameEntry.getFont())
         if problem:
             print problem
             self.nameEntry.enterText('')
         else:
             self.fsm.request('Done')
     else:
         self.fsm.request('Done')
Ejemplo n.º 20
0
 def complete(self):
     self.nameEntry['focus'] = 0
     name = self.nameEntry.get()
     name = TextEncoder().decodeText(name)
     name = name.strip()
     name = TextEncoder().encodeWtext(name)
     self.nameEntry.enterText(name)
     self.notify.debug('Chosen name: %s' % name)
     if self.customName:
         problem = NameCheck.checkName(name, [self._checkNpcNames],
                                       font=self.nameEntry.getFont())
         if problem:
             print problem
             self.nameEntry.enterText('')
         else:
             self.fsm.request('Done')
     else:
         self.fsm.request('Done')
    def allCaps(name):
        letters = justLetters(name)
        if len(letters) > 2:
            upperLetters = TextEncoder().decodeText(TextEncoder.upper(TextEncoder().encodeWtext(letters)))
            for i in xrange(len(upperLetters)):
                if not upperLetters[0].isupper():
                    return

            if upperLetters == letters:
                notify.info('name is all caps')
                return OTPLocalizer.NCAllCaps
 def getTypeANameProblem(self, callback):
     if not self.customName:
         callback(None)
     else:
         problem = None
         name = self.nameEntry.get()
         name = TextEncoder().decodeText(name)
         name = name.strip()
         name = TextEncoder().encodeWtext(name)
         self.nameEntry.enterText(name)
         problem = NameCheck.checkName(self.nameEntry.get(), [
             self._checkNpcNames], font = self.nameEntry.getFont())
         if problem:
             callback(problem)
         elif self.cr:
             self.ignore(self.cr.getWishNameResultMsg())
             self.acceptOnce(self.cr.getWishNameResultMsg(), self._handleSetWishnameResult)
             self._nameCheckCallback = callback
             self._sendSetWishname(justCheck = True)
             return None
 def checkJapanese(name):
     asciiSpace = range(32, 33)
     asciiDigits = range(48, 64)
     hiragana = range(12353, 12448)
     katakana = range(12449, 12544)
     halfwidthKatakana = range(65381, 65440)
     halfwidthCharacter = set(asciiSpace + halfwidthKatakana)
     allowedUtf8 = set(asciiSpace + hiragana + katakana + halfwidthKatakana)
     te = TextEncoder()
     dc = 0.0
     for char in lambda [outmost-iterable]: for char in [outmost-iterable]:
    def checkApostrophes(name):
        words = wordList(name)
        for word in words:
            numApos = word.count("'")
            if numApos > 2:
                notify.info('word "%s" has too many apostrophes.' % TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCApostrophes

        numApos = name.count("'")
        if numApos > 3:
            notify.info('name has too many apostrophes.')
            return OTPLocalizer.NCApostrophes
Ejemplo n.º 25
0
 def getTypeANameProblem(self, callback):
     if not self.customName:
         callback(None)
     else:
         problem = None
         name = self.nameEntry.get()
         name = TextEncoder().decodeText(name)
         name = name.strip()
         name = TextEncoder().encodeWtext(name)
         self.nameEntry.enterText(name)
         problem = NameCheck.checkName(self.nameEntry.get(),
                                       [self._checkNpcNames],
                                       font=self.nameEntry.getFont())
         if problem:
             callback(problem)
         elif self.cr:
             self.ignore(self.cr.getWishNameResultMsg())
             self.acceptOnce(self.cr.getWishNameResultMsg(),
                             self._handleSetWishnameResult)
             self._nameCheckCallback = callback
             self._sendSetWishname(justCheck=True)
             return None
Ejemplo n.º 26
0
    def _getName(self):
        newName = ''
        if self.mode == self._NameGUI__MODE_TYPEANAME:
            newName = self.nameEntry.get()
            newName = TextEncoder().decodeText(newName)
            newName = newName.strip()
            newName = TextEncoder().encodeWtext(newName)
        else:
            newName += self.names[0]
            if len(newName) > 0 and len(self.names[1]) > 0:
                newName += ' '

            newName += self.names[1]
            if len(newName) > 0 and len(self.names[2]) > 0:
                newName += ' '

            newName += self.names[2]
            if self.names[2] in PL.PirateNames_LastNamePrefixesCapped:
                newName += self.names[3].capitalize()
            else:
                newName += self.names[3]
        return newName
        def perWord(word):
            if '.' in word:
                return None
            for char in word:
                if ord(char) >= 128:
                    return None

            letters = filterString(word, string.letters)
            if len(letters) > 2:
                vowels = filterString(letters, 'aeiouyAEIOUY')
                if len(vowels) == 0:
                    notify.info('word "%s" has no vowels' % TextEncoder().encodeWtext(word))
                    return OTPLocalizer.NCNeedVowels
 def _getName(self):
     newName = ''
     if self.mode == self._NameGUI__MODE_TYPEANAME:
         newName = self.nameEntry.get()
         newName = TextEncoder().decodeText(newName)
         newName = newName.strip()
         newName = TextEncoder().encodeWtext(newName)
     else:
         newName += self.names[0]
         if len(newName) > 0 and len(self.names[1]) > 0:
             newName += ' '
         
         newName += self.names[1]
         if len(newName) > 0 and len(self.names[2]) > 0:
             newName += ' '
         
         newName += self.names[2]
         if self.names[2] in PL.PirateNames_LastNamePrefixesCapped:
             newName += self.names[3].capitalize()
         else:
             newName += self.names[3]
     return newName
Ejemplo n.º 29
0
    def checkPeriods(name):
        """ periods are allowed at the end of words, or in two-letter
        words, like 'J.T.' """
        words = wordList(name)
        for word in words:
            # strip off any trailing commas
            if word[-1] == ',':
                word = word[:-1]

            numPeriods = word.count('.')
            if not numPeriods:
                continue

            letters = justLetters(word)
            numLetters = len(letters)

            # word must end in '.'
            if word[-1] != '.':
                notify.info('word "%s" does not end in a period' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCPeriodUsage

            # max periods is 2
            if numPeriods > 2:
                notify.info('word "%s" has too many periods' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCPeriodUsage

            if numPeriods == 2:
                # 2nd and 4th characters should be periods
                if not ((word[1] == '.') and (word[3] == '.')):
                    notify.info('word "%s" does not fit the J.T. pattern' %
                                TextEncoder().encodeWtext(word))
                    return OTPLocalizer.NCPeriodUsage

        return None
Ejemplo n.º 30
0
        def perWord(word):
            # if there's a period, assume it's an abbrevation
            if '.' in word:
                return None

            # Check if there's an extended character; if
            # so, it might be a vowel.
            for char in word:
                if ord(char) >= 0x80:
                    return None

            letters = filterString(word, string.letters)
            # things like 'MD' are ok without periods
            if len(letters) > 2:
                vowels = filterString(letters, 'aeiouyAEIOUY')
                if len(vowels) == 0:
                    notify.info('word "%s" has no vowels' %
                                TextEncoder().encodeWtext(word))
                    return OTPLocalizer.NCNeedVowels
Ejemplo n.º 31
0
 def match(npcName, name = name):
     name = TextEncoder().encodeWtext(name)
     name = name.strip()
     return TextEncoder.upper(npcName) == TextEncoder.upper(name)
Ejemplo n.º 32
0
def checkName(name, otherCheckFuncs=[], font=None):
    # misc check functions;
    # name should not be a wide-character string (for example it should be utf-8)
    # return None if name is OK, error string if name is not OK
    # check functions are given unicode strings
    # if font is passed in, checkName() will make sure all characters in the name
    # are valid characters in the font
    def longEnough(name):
        if len(name) < 2:
            notify.info('name is too short')
            return OTPLocalizer.NCTooShort

    def emptyName(name):
        if name.strip() == '':
            notify.info('name is empty')
            return OTPLocalizer.NCTooShort

    def printableChars(name):
        for char in name:
            # If it is an extended character, we cannot test it for printability here (but
            # presumably it is some printable character.)
            if ord(char) < 0x80 and char not in string.printable:
                notify.info('name contains non-printable char #%s' % ord(char))
                return OTPLocalizer.NCGeneric

    validAsciiChars = set(".,'-" + string.letters + string.whitespace)

    def _validCharacter(c, validAsciiChars=validAsciiChars, font=font):
        if c in validAsciiChars:
            return True
        # check for Unicode alphabetic characters and whitespace
        if c.isalpha() or c.isspace():
            return True
        return False

    def badCharacters(name, _validCharacter=_validCharacter):
        for char in name:
            if not _validCharacter(char):
                if char in string.digits:
                    notify.info('name contains digits')
                    return OTPLocalizer.NCNoDigits
                else:
                    notify.info('name contains bad char: %s' %
                                TextEncoder().encodeWtext(char))
                    return OTPLocalizer.NCBadCharacter % TextEncoder(
                    ).encodeWtext(char)

    def fontHasCharacters(name, font=font):
        if font:
            tn = TextNode('NameCheck')
            tn.setFont(font)
            for c in name:
                if not tn.hasCharacter(ord(c)):
                    notify.info('name contains bad char: %s' %
                                TextEncoder().encodeWtext(c))
                    return OTPLocalizer.NCBadCharacter % TextEncoder(
                    ).encodeWtext(c)

    def hasLetters(name):
        #,...,
        words = wordList(name)
        for word in words:
            letters = justLetters(word)

            if len(letters) == 0:
                notify.info('word "%s" has no letters' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCNeedLetters

    def hasVowels(name):
        # ndssmvwls
        def perWord(word):
            # if there's a period, assume it's an abbrevation
            if '.' in word:
                return None

            # Check if there's an extended character; if
            # so, it might be a vowel.
            for char in word:
                if ord(char) >= 0x80:
                    return None

            letters = filterString(word, string.letters)
            # things like 'MD' are ok without periods
            if len(letters) > 2:
                vowels = filterString(letters, 'aeiouyAEIOUY')
                if len(vowels) == 0:
                    notify.info('word "%s" has no vowels' %
                                TextEncoder().encodeWtext(word))
                    return OTPLocalizer.NCNeedVowels

        for word in wordList(name):
            problem = perWord(word)
            if problem:
                return problem

    def monoLetter(name):
        # eeeeeeeee
        def perWord(word):
            word = word
            letters = justLetters(word)
            if len(letters) > 2:
                # make case-insensitive
                letters = TextEncoder().decodeText(
                    TextEncoder.lower(TextEncoder().encodeWtext(letters)))
                filtered = filterString(letters, letters[0])
                if filtered == letters:
                    notify.info('word "%s" uses only one letter' %
                                TextEncoder().encodeWtext(word))
                    return OTPLocalizer.NCGeneric

        for word in wordList(name):
            problem = perWord(word)
            if problem:
                return problem

    def checkDashes(name):
        def validDash(index, name=name):
            # if the dash is at the beginning or the end, fail
            if (index == 0) or (i == len(name) - 1):
                return 0
            # dash must be surrounded by letters on both sides
            if not (name[i - 1].isalpha()):
                return 0
            if not (name[i + 1].isalpha()):
                return 0
            return 1

        i = 0
        while 1:
            i = name.find('-', i, len(name))
            if i < 0:
                return None
            if not validDash(i):
                notify.info('name makes invalid use of dashes')
                return OTPLocalizer.NCDashUsage
            i += 1

    def checkCommas(name):
        def validComma(index, name=name):
            # if the comma is at the beginning or the end, fail
            if (index == 0) or (i == len(name) - 1):
                return OTPLocalizer.NCCommaEdge
            # comma must follow a word and be followed by a space
            if (name[i - 1].isspace()):
                return OTPLocalizer.NCCommaAfterWord
            if not (name[i + 1].isspace()):
                return OTPLocalizer.NCCommaUsage
            return None

        i = 0
        while 1:
            i = name.find(',', i, len(name))
            if i < 0:
                return None
            problem = validComma(i)
            if problem:
                notify.info('name makes invalid use of commas')
                return problem
            i += 1

    def checkPeriods(name):
        """ periods are allowed at the end of words, or in two-letter
        words, like 'J.T.' """
        words = wordList(name)
        for word in words:
            # strip off any trailing commas
            if word[-1] == ',':
                word = word[:-1]

            numPeriods = word.count('.')
            if not numPeriods:
                continue

            letters = justLetters(word)
            numLetters = len(letters)

            # word must end in '.'
            if word[-1] != '.':
                notify.info('word "%s" does not end in a period' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCPeriodUsage

            # max periods is 2
            if numPeriods > 2:
                notify.info('word "%s" has too many periods' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCPeriodUsage

            if numPeriods == 2:
                # 2nd and 4th characters should be periods
                if not ((word[1] == '.') and (word[3] == '.')):
                    notify.info('word "%s" does not fit the J.T. pattern' %
                                TextEncoder().encodeWtext(word))
                    return OTPLocalizer.NCPeriodUsage

        return None

    def checkApostrophes(name):
        words = wordList(name)
        for word in words:
            numApos = word.count("'")
            if numApos > 2:
                notify.info('word "%s" has too many apostrophes.' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCApostrophes
        numApos = name.count("'")
        if numApos > 3:
            notify.info('name has too many apostrophes.')
            return OTPLocalizer.NCApostrophes

    def tooManyWords(name):
        if len(wordList(name)) > 4:
            notify.info('name has too many words')
            return OTPLocalizer.NCTooManyWords

    def allCaps(name):
        # MICKEY MOUSE
        letters = justLetters(name)
        # J.T. -> OK
        if len(letters) > 2:
            upperLetters = TextEncoder().decodeText(
                TextEncoder.upper(TextEncoder().encodeWtext(letters)))
            # some unicode characters can't be capitalized
            for i in xrange(len(upperLetters)):
                if not upperLetters[0].isupper():
                    # at least one letter is not upper-case
                    # name is not all-caps
                    # excessive capitalization will be caught by mixedCase()
                    return
            if upperLetters == letters:
                notify.info('name is all caps')
                return OTPLocalizer.NCAllCaps

    def mixedCase(name):
        # MiCkeY MoUsE
        words = wordList(name)
        for word in words:
            if len(word) > 2:
                # allow McQuack
                capitals = justUpper(word)
                if len(capitals) > 2:
                    notify.info('name has mixed case')
                    return OTPLocalizer.NCMixedCase

    def checkJapanese(name):
        # Japan allows ASCII space, hiragana, katakana, and half-width katakana,
        # but, allows not ASCII and kanji(CJK) characters for a name
        # All Japanese characters are three-byte-encoded utf-8 characters from unicode
        # Reference: http://unicode.org/charts/
        asciiSpace = range(0x20, 0x21)
        asciiDigits = range(0x30, 0x40)
        hiragana = range(0x3041, 0x30A0)
        katakana = range(0x30A1, 0x3100)
        halfwidthKatakana = range(0xFF65, 0xFFA0)
        halfwidthCharacter = set(asciiSpace + halfwidthKatakana)
        allowedUtf8 = set(asciiSpace + hiragana + katakana + halfwidthKatakana)
        te = TextEncoder()
        dc = 0.0

        # Return None if name is OK, error string if name is not OK
        for char in (ord(char) for char in te.decodeText(name)):
            if char not in allowedUtf8:
                # Notify error string, if not allowed utf-8 character
                if char in asciiDigits:
                    notify.info('name contains not allowed ascii digits')
                    return OTPLocalizer.NCNoDigits
                else:
                    notify.info('name contains not allowed utf8 char: 0x%04x' %
                                char)
                    return OTPLocalizer.NCBadCharacter % te.encodeWtext(
                        unichr(char))
            else:
                # Restrict the number of characters, if three-byte-encoded utf-8 character
                # The full-width characters would fit into a single display cell,
                # and the half-width characters would fit two to a display cell
                if char in halfwidthCharacter:
                    dc += 0.5
                else:
                    dc += 1

        # Japan restricts the number of the characters, if occupied less then two display cell
        # and more then eight display cell.
        if (dc < 2):
            notify.info('name is too short: %0.1f' % dc)
            return OTPLocalizer.NCTooShort
        elif (dc > 8):
            notify.info(
                'name has been occupied more than eight display cells: %0.1f' %
                dc)
            return OTPLocalizer.NCGeneric

    def repeatedChars(name):
        count = 1
        lastChar = None
        i = 0
        while i < len(name):
            char = name[i]
            i += 1

            if char == lastChar:
                # character is repeating
                count += 1
            else:
                count = 1

            lastChar = char

            if count > 2:
                notify.info('character %s is repeated too many times' %
                            TextEncoder().encodeWtext(char))
                return OTPLocalizer.NCRepeatedChar % TextEncoder().encodeWtext(
                    char)

    checks = [
        printableChars,
        badCharacters,
        fontHasCharacters,
        longEnough,
        emptyName,
        hasLetters,
        hasVowels,
        monoLetter,
        checkDashes,
        checkCommas,
        checkPeriods,
        checkApostrophes,
        tooManyWords,
        allCaps,
        mixedCase,
        repeatedChars,
    ] + otherCheckFuncs

    # checks that should be run on the reversed name string
    symmetricChecks = []

    # make sure we are working with a wide-character version of the string
    name = TextEncoder().decodeText(name)
    notify.info('checking name "%s"...' % TextEncoder().encodeWtext(name))

    # run through all the checks
    for check in checks:
        problem = check(name[:])
        if (not problem) and (check in symmetricChecks):
            # check it backwards.
            nName = name[:]
            bName.reverse()
            problem = check(bName)
            print "problem = %s" % (problem)

        if problem:
            return problem

    return None
Ejemplo n.º 33
0
    return None


# prevent log spam during testing
severity = notify.getSeverity()
notify.setSeverity(NSError)

# these tests can be removed or replaced for international versions of the codebase

# long enough
assert checkName('J')
assert not checkName('Jo')
# empty name
assert checkName('')
assert checkName('\t')
assert checkName(TextEncoder().encodeWtext(u'\xa0'))
assert checkName(TextEncoder().encodeWtext(u'\u1680'))
assert checkName(TextEncoder().encodeWtext(u'\u2001'))
# printable chars
for i in xrange(32):
    assert checkName(chr(i))
assert checkName(chr(0x7f))
# bad characters
for c in '!"#$%&()*+/:;<=>?@[\]^_`{|}~':
    assert checkName('Bob' + c)
# has letters
assert checkName(',...,')
#   katakana = range(0x30A1, 0x30FB)
#assert not checkName(TextEncoder().encodeWtext(u'\u30a1\u30a2'))
# has vowels
assert checkName('Qwrt')
        fontHasCharacters,
        longEnough,
        emptyName,
        hasLetters,
        hasVowels,
        monoLetter,
        checkDashes,
        checkCommas,
        checkPeriods,
        checkApostrophes,
        tooManyWords,
        allCaps,
        mixedCase,
        repeatedChars] + otherCheckFuncs
    symmetricChecks = []
    name = TextEncoder().decodeText(name)
    notify.info('checking name "%s"...' % TextEncoder().encodeWtext(name))
    for check in checks:
        problem = check(name[:])
        if not problem and check in symmetricChecks:
            nName = name[:]
            bName.reverse()
            problem = check(bName)
            print 'problem = %s' % problem
        
        if problem:
            return problem
            continue
    

severity = notify.getSeverity()
Ejemplo n.º 35
0
 def match(npcName, name=name):
     name = TextEncoder().encodeWtext(name)
     name = string.strip(name)
     return TextEncoder.upper(npcName) == TextEncoder.upper(name)
Ejemplo n.º 36
0
def checkName(name, otherCheckFuncs=[], font=None):
    def longEnough(name):
        if len(name) < 2:
            notify.info('name is too short')
            return OTPLocalizer.NCTooShort

    def emptyName(name):
        if name.strip() == '':
            notify.info('name is empty')
            return OTPLocalizer.NCTooShort

    def printableChars(name):
        for char in name:
            if ord(char) < 128 and char not in string.printable:
                notify.info('name contains non-printable char #%s' % ord(char))
                return OTPLocalizer.NCGeneric

    validAsciiChars = set(".,'-" + string.letters + string.whitespace)

    def _validCharacter(c, validAsciiChars=validAsciiChars, font=font):
        if c in validAsciiChars:
            return True
        if c.isalpha() or c.isspace():
            return True
        return False

    def badCharacters(name, _validCharacter=_validCharacter):
        for char in name:
            if not _validCharacter(char):
                if char in string.digits:
                    notify.info('name contains digits')
                    return OTPLocalizer.NCNoDigits
                else:
                    notify.info('name contains bad char: %s' %
                                TextEncoder().encodeWtext(char))
                    return OTPLocalizer.NCBadCharacter % TextEncoder(
                    ).encodeWtext(char)

    def fontHasCharacters(name, font=font):
        if font:
            tn = TextNode('NameCheck')
            tn.setFont(font)
            for c in name:
                if not tn.hasCharacter(ord(c)):
                    notify.info('name contains bad char: %s' %
                                TextEncoder().encodeWtext(c))
                    return OTPLocalizer.NCBadCharacter % TextEncoder(
                    ).encodeWtext(c)

    def hasLetters(name):
        words = wordList(name)
        for word in words:
            letters = justLetters(word)
            if len(letters) == 0:
                notify.info('word "%s" has no letters' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCNeedLetters

    def hasVowels(name):
        def perWord(word):
            if '.' in word:
                return None
            for char in word:
                if ord(char) >= 128:
                    return None

            letters = filterString(word, string.letters)
            if len(letters) > 2:
                vowels = filterString(letters, 'aeiouyAEIOUY')
                if len(vowels) == 0:
                    notify.info('word "%s" has no vowels' %
                                TextEncoder().encodeWtext(word))
                    return OTPLocalizer.NCNeedVowels
            return None

        for word in wordList(name):
            problem = perWord(word)
            if problem:
                return problem

    def monoLetter(name):
        def perWord(word):
            word = word
            letters = justLetters(word)
            if len(letters) > 2:
                letters = TextEncoder().decodeText(
                    TextEncoder.lower(TextEncoder().encodeWtext(letters)))
                filtered = filterString(letters, letters[0])
                if filtered == letters:
                    notify.info('word "%s" uses only one letter' %
                                TextEncoder().encodeWtext(word))
                    return OTPLocalizer.NCGeneric

        for word in wordList(name):
            problem = perWord(word)
            if problem:
                return problem

    def checkDashes(name):
        def validDash(index, name=name):
            if index == 0 or i == len(name) - 1:
                return 0
            if not name[i - 1].isalpha():
                return 0
            if not name[i + 1].isalpha():
                return 0
            return 1

        i = 0
        while 1:
            i = name.find('-', i, len(name))
            if i < 0:
                return None
            if not validDash(i):
                notify.info('name makes invalid use of dashes')
                return OTPLocalizer.NCDashUsage
            i += 1

    def checkCommas(name):
        def validComma(index, name=name):
            if index == 0 or i == len(name) - 1:
                return OTPLocalizer.NCCommaEdge
            if name[i - 1].isspace():
                return OTPLocalizer.NCCommaAfterWord
            if not name[i + 1].isspace():
                return OTPLocalizer.NCCommaUsage
            return None

        i = 0
        while 1:
            i = name.find(',', i, len(name))
            if i < 0:
                return None
            problem = validComma(i)
            if problem:
                notify.info('name makes invalid use of commas')
                return problem
            i += 1

    def checkPeriods(name):
        words = wordList(name)
        for word in words:
            if word[-1] == ',':
                word = word[:-1]
            numPeriods = word.count('.')
            if not numPeriods:
                continue
            letters = justLetters(word)
            numLetters = len(letters)
            if word[-1] != '.':
                notify.info('word "%s" does not end in a period' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCPeriodUsage
            if numPeriods > 2:
                notify.info('word "%s" has too many periods' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCPeriodUsage
            if numPeriods == 2:
                if not (word[1] == '.' and word[3] == '.'):
                    notify.info('word "%s" does not fit the J.T. pattern' %
                                TextEncoder().encodeWtext(word))
                    return OTPLocalizer.NCPeriodUsage

        return None

    def checkApostrophes(name):
        words = wordList(name)
        for word in words:
            numApos = word.count("'")
            if numApos > 2:
                notify.info('word "%s" has too many apostrophes.' %
                            TextEncoder().encodeWtext(word))
                return OTPLocalizer.NCApostrophes

        numApos = name.count("'")
        if numApos > 3:
            notify.info('name has too many apostrophes.')
            return OTPLocalizer.NCApostrophes

    def tooManyWords(name):
        if len(wordList(name)) > 4:
            notify.info('name has too many words')
            return OTPLocalizer.NCTooManyWords

    def allCaps(name):
        letters = justLetters(name)
        if len(letters) > 2:
            upperLetters = TextEncoder().decodeText(
                TextEncoder.upper(TextEncoder().encodeWtext(letters)))
            for i in xrange(len(upperLetters)):
                if not upperLetters[0].isupper():
                    return

            if upperLetters == letters:
                notify.info('name is all caps')
                return OTPLocalizer.NCAllCaps

    def mixedCase(name):
        words = wordList(name)
        for word in words:
            if len(word) > 2:
                capitals = justUpper(word)
                if len(capitals) > 2:
                    notify.info('name has mixed case')
                    return OTPLocalizer.NCMixedCase

    def checkJapanese(name):
        asciiSpace = range(32, 33)
        asciiDigits = range(48, 64)
        hiragana = range(12353, 12448)
        katakana = range(12449, 12544)
        halfwidthKatakana = range(65381, 65440)
        halfwidthCharacter = set(asciiSpace + halfwidthKatakana)
        allowedUtf8 = set(asciiSpace + hiragana + katakana + halfwidthKatakana)

        te = TextEncoder()
        dc = 0.0

        for char in (ord(char) for char in te.decodeText(name)):
            if char not in allowedUtf8:
                if char in asciiDigits:
                    notify.info('name contains not allowed ascii digits')
                    return OTPLocalizer.NCNoDigits
                else:
                    notify.info('name contains not allowed utf8 char: 0x%04x' %
                                char)
                    return OTPLocalizer.NCBadCharacter % te.encodeWtext(
                        unichr(char))
            elif char in halfwidthCharacter:
                dc += 0.5
            else:
                dc += 1

        if dc < 2:
            notify.info('name is too short: %0.1f' % dc)
            return OTPLocalizer.NCTooShort
        elif dc > 8:
            notify.info(
                'name has been occupied more than eight display cells: %0.1f' %
                dc)
            return OTPLocalizer.NCGeneric

    def repeatedChars(name):
        count = 1
        lastChar = None
        i = 0
        while i < len(name):
            char = name[i]
            i += 1
            if char == lastChar:
                count += 1
            else:
                count = 1
            lastChar = char
            if count > 2:
                notify.info('character %s is repeated too many times' %
                            TextEncoder().encodeWtext(char))
                return OTPLocalizer.NCRepeatedChar % TextEncoder().encodeWtext(
                    char)

        return

    checks = [
        printableChars, badCharacters, fontHasCharacters, longEnough,
        emptyName, hasLetters, hasVowels, monoLetter, checkDashes, checkCommas,
        checkPeriods, checkApostrophes, tooManyWords, allCaps, mixedCase,
        repeatedChars
    ] + otherCheckFuncs
    symmetricChecks = []
    name = TextEncoder().decodeText(name)
    notify.info('checking name "%s"...' % TextEncoder().encodeWtext(name))
    for check in checks:
        problem = check(name[:])
        if not problem and check in symmetricChecks:
            nName = name[:]
            bName.reverse()
            problem = check(bName)
            print 'problem = %s' % problem
        if problem:
            return problem

    return None