Exemplo n.º 1
0
def str2glyphName(char):
    if char == ".point":
        char = "."
    codepoint = fontforge.unicodeFromName(char)
    if codepoint != -1:
        glyphName = fontforge.nameFromUnicode(codepoint)
    else:
        codes = codepoints.from_unicode(char)
        if len(codes) == 1:
            glyphName = fontforge.nameFromUnicode(codes[0])
        else:
            glyphName = char
    return glyphName
Exemplo n.º 2
0
        async def _phase2(message):
            response = await self.bot.wait_for('message',
                                               timeout=120,
                                               check=check)

            content = response.content.strip()
            if response.content.lower().strip() == 'skip':
                return True
            if response.content.lower().strip() == 'reset':
                db.update_one({'_id': ctx.author.id},
                              {'$set': {
                                  'regionFlag': None
                              }})
                await message.channel.send(
                    'I\'ve gone ahead and reset your setting for **regional flag**'
                )
                return True

            for x in content:
                if x not in UNICODE_EMOJI:
                    return False

            rawPoints = tuple(codepoints.from_unicode(content))
            points = []

            for x in rawPoints:
                if (
                        str(hex(x)[2:]) not in self.letterCodepoints
                ):  # Flags are the 2 letter abbrev. in regional letter emoji
                    return False

                points.append(str(hex(x)[2:]))

            pointStr = '-'.join(points)
            if not Path(f'{self.twemojiPath}{pointStr}.png').is_file():
                return False

            db.update_one({'_id': ctx.author.id},
                          {'$set': {
                              'regionFlag': pointStr
                          }})
            return True
Exemplo n.º 3
0
def test_to_and_from_unicode(unistr, code_points):
    assert_equal(code_points, tuple(codepoints.from_unicode(unistr)))
    assert_equal(unistr, codepoints.to_unicode(code_points))
Exemplo n.º 4
0
    async def _generate_profile_card(self,
                                     member: discord.Member) -> discord.File:
        db = mclient.bowser.users
        fs = gridfs.GridFS(mclient.bowser)
        dbUser = db.find_one({'_id': member.id})
        guild = member.guild

        metaFont = ImageFont.truetype('resources/OpenSans-Regular.ttf', 36)
        userFont = ImageFont.truetype('resources/OpenSans-Regular.ttf', 48)
        subtextFont = ImageFont.truetype('resources/OpenSans-Light.ttf', 48)
        mediumFont = ImageFont.truetype('resources/OpenSans-Light.ttf', 36)
        smallFont = ImageFont.truetype('resources/OpenSans-Light.ttf', 30)

        # Start construction of key features
        pfp = (Image.open(
            io.BytesIO(await member.avatar_url_as(
                format='png', size=256).read())).convert("RGBA").resize(
                    (250, 250)))
        pfpBack = Image.open('resources/pfp-background.png').convert('RGBA')
        pfpBack.paste(pfp, (50, 170), pfp)
        card = Image.open('resources/profile-{}.png'.format(
            dbUser['background'])).convert("RGBA")
        pfpBack.paste(card, mask=card)
        card = pfpBack
        snoo = Image.open('resources/snoo.png').convert("RGBA")
        trophyUnderline = Image.open(
            'resources/trophy-case-underline.png').convert("RGBA")
        gameUnderline = Image.open(
            'resources/favorite-games-underline.png').convert("RGBA")

        card.paste(snoo, (50, 50), snoo)
        card.paste(trophyUnderline, (1150, 100), trophyUnderline)
        card.paste(gameUnderline, (60, 645), gameUnderline)

        # Start header/static text
        draw = ImageDraw.Draw(card)
        draw.text((150, 50),
                  '/r/NintendoSwitch Discord', (45, 45, 45),
                  font=metaFont)
        draw.text((150, 90), 'User Profile', (126, 126, 126), font=metaFont)
        draw.text((60, 470), 'Member since', (126, 126, 126), font=smallFont)
        draw.text((440, 470), 'Messages sent', (126, 126, 126), font=smallFont)
        draw.text((800, 470), 'Timezone', (126, 126, 126), font=smallFont)
        draw.text((60, 595), 'Favorite games', (45, 45, 45), font=mediumFont)
        # draw.text((800, 600), 'Looking for group', (126, 126, 126), font=smallFont) # TODO: Find a way to see if game is online enabled
        draw.text((1150, 45), 'Trophy case', (45, 45, 45), font=mediumFont)

        # Start customized content -- userinfo
        memberName = ''
        nameW = 350
        nameH = 0
        for char in member.name:
            if char not in UNICODE_EMOJI:
                memberName += char

            else:
                if memberName:
                    W, nameH = draw.textsize(memberName, font=userFont)
                    draw.text((nameW, 215),
                              memberName, (80, 80, 80),
                              font=userFont)
                    nameW += W
                    memberName = ''

                charset = tuple(codepoints.from_unicode(char))
                unicodePoint = []
                for x in charset:
                    unicodePoint.append(hex(x)[2:])

                unicodeChar = '-'.join(unicodePoint)
                emojiPic = Image.open(self.twemojiPath + unicodeChar +
                                      '.png').convert('RGBA').resize((40, 40))
                card.paste(emojiPic, (nameW + 3, 228), emojiPic)
                nameW += 46

        if memberName:  # Leftovers, text
            draw.text((nameW, 215), memberName, (80, 80, 80), font=userFont)

        draw.text((350, 275),
                  '#' + member.discriminator, (126, 126, 126),
                  font=subtextFont)

        if dbUser['regionFlag']:
            regionImg = Image.open(self.twemojiPath + dbUser['regionFlag'] +
                                   '.png').convert('RGBA')
            card.paste(regionImg, (976, 50), regionImg)

        # Friend code
        if dbUser['friendcode']:
            draw.text((350, 330),
                      dbUser['friendcode'], (87, 111, 251),
                      font=subtextFont)

        # Start customized content -- stats
        draw.text(
            (440, 505),
            f'{mclient.bowser.messages.find({"author": member.id}).count():,}',
            (80, 80, 80),
            font=mediumFont,
        )

        joins = dbUser['joins']
        joins.sort()
        joinDate = datetime.datetime.utcfromtimestamp(joins[0])
        try:  # -d doesn't work on all platforms, such as Windows
            joinDateF = joinDate.strftime('%b. %-d, %Y')
        except:
            joinDateF = joinDate.strftime('%b. %d, %Y')
        draw.text((60, 505), joinDateF, (80, 80, 80), font=mediumFont)

        if not dbUser['timezone']:
            draw.text((800, 505),
                      'Not specified', (126, 126, 126),
                      font=mediumFont)

        else:
            tzOffset = datetime.datetime.now(pytz.timezone(
                dbUser['timezone'])).strftime('%z')
            draw.text((800, 505),
                      'GMT' + tzOffset, (80, 80, 80),
                      font=mediumFont)

        # Start trophies
        trophyLocations = {
            0: (1150, 150),
            1: (1300, 150),
            2: (1450, 150),
            3: (1150, 300),
            4: (1300, 300),
            5: (1450, 300),
            6: (1150, 450),
            7: (1300, 450),
            8: (1450, 450),
            9: (1150, 600),
            10: (1300, 600),
            11: (1450, 600),
            12: (1150, 750),
            13: (1300, 750),
            14: (1450, 750),
        }
        trophies = []
        if dbUser['trophyPreference']:
            for x in dbUser:
                trophies.append(x)

        # Hardcoding IDs like a genius
        if member.id == guild.owner.id:  # Server owner
            trophies.append('owner')

        if member.id in self.bot_contributors:  # Developer
            trophies.append('developer')

        if guild.get_role(config.chatmod) in member.roles:  # Chat-mod role
            trophies.append('chat-mod')

        if guild.get_role(config.submod) in member.roles:  # Sub-mod role
            trophies.append('sub-mod')

        if (guild.get_role(config.modemeritus) in member.roles
                or guild.get_role(
                    config.submodemeritus) in member.roles):  # Mod emeritus
            trophies.append('mod-emeritus')

        if guild.get_role(config.helpfulUser) in member.roles:  # Helpful user
            trophies.append('helpful-user')

        if guild.get_role(config.boostRole) in member.roles:  # Booster role
            trophies.append('booster')

        if len(trophies) < 15:  # Check for additional non-prefered trophies
            for x in dbUser['trophies']:
                if x not in trophies:
                    trophies.append(x)

        while len(trophies) < 15:
            trophies.append('blank')

        trophyNum = 0
        for x in trophies:
            trophyBadge = Image.open('resources/trophies/' + x +
                                     '.png').convert('RGBA')
            card.paste(trophyBadge, trophyLocations[trophyNum], trophyBadge)
            trophyNum += 1

        # Start favorite games
        setGames = dbUser['favgames']
        if not setGames:
            draw.text((60, 665),
                      'Not specified', (126, 126, 126),
                      font=mediumFont)

        else:
            gameIconLocations = {0: (60, 665), 1: (60, 730), 2: (60, 795)}
            gameTextLocations = {0: 660, 1: 725, 2: 791}
            gameCount = 0
            gamesDb = mclient.bowser.games
            for game in setGames:
                gameDoc = gamesDb.find_one({'_id': game})
                if fs.exists(game):
                    gameImg = fs.get(game)
                    gameIcon = Image.open(gameImg).convert('RGBA').resize(
                        (45, 45))
                    card.paste(gameIcon, gameIconLocations[gameCount],
                               gameIcon)

                else:
                    missingImage = Image.open(
                        'resources/missing-game.png').convert("RGBA").resize(
                            (45, 45))
                    card.paste(missingImage, gameIconLocations[gameCount],
                               missingImage)

                if gameDoc['titles']['NA']:
                    gameName = gameDoc['titles']['NA']

                elif gameDoc['titles']['EU']:
                    gameName = gameDoc['titles']['EU']

                else:
                    gameName = gameDoc['titles']['JP']

                nameW = 120
                nameWMax = 950

                for char in gameName:
                    if nameW >= nameWMax:
                        draw.text((nameW, gameTextLocations[gameCount]),
                                  '...', (80, 80, 80),
                                  font=mediumFont)
                        break

                    draw.text((nameW, gameTextLocations[gameCount]),
                              char, (80, 80, 80),
                              font=mediumFont)
                    nameW += mediumFont.getsize(char)[0]
                gameCount += 1

        bytesFile = io.BytesIO()
        card.save(bytesFile, format='PNG')
        return discord.File(io.BytesIO(bytesFile.getvalue()),
                            filename='profile.png')
Exemplo n.º 5
0
import codepoints
import sys
if len(sys.argv) != 3:
    print 'provide file and emoji'
    exit()

filename = sys.argv[1]
c = sys.argv[2]
svgfile = hex(tuple(codepoints.from_unicode(c.decode('utf-8')))[0]).upper().replace('0X', 'u') + '.svg'
print 'looking for', svgfile
for line in open(filename, 'r').readlines():
    if svgfile in line:
        print line.split(':')[1].strip()
Exemplo n.º 6
0
    async def _generate_profile_card(self,
                                     member: discord.Member) -> discord.File:
        db = mclient.bowser.users
        dbUser = db.find_one({'_id': member.id})

        if 'default' in dbUser['backgrounds']:
            backgrounds = list(dbUser['backgrounds'])
            backgrounds.remove('default')
            backgrounds.insert(0, 'default-dark')
            backgrounds.insert(0, 'default-light')

            db.update_one({'_id': member.id},
                          {'$set': {
                              'backgrounds': backgrounds
                          }})

            if dbUser['background'] == 'default':
                db.update_one({'_id': member.id},
                              {'$set': {
                                  'background': 'default-light'
                              }})

            dbUser = db.find_one({'_id': member.id})

        background = self.backgrounds[dbUser['background']]
        theme = self.themes[background["theme"]]

        pfpBytes = io.BytesIO(await member.avatar_url_as(format='png',
                                                         size=256).read())
        pfp = Image.open(pfpBytes).convert("RGBA").resize((250, 250))

        card = theme['pfpBackground'].copy()
        card.paste(pfp, (50, 170), pfp)
        card.paste(background["image"], mask=background["image"])
        card.paste(theme['profileStatic'], mask=theme['profileStatic'])

        guild = member.guild
        draw = ImageDraw.Draw(card)
        fonts = self.profileFonts

        # userinfo
        memberName = ''
        nameW = 350

        # Member name may be rendered in parts, so we want to ensure the font stays the same for the entire thing
        member_name_font = fonts['user'][self._determine_cjk_font(member.name)]

        for char in member.name:
            if char not in emoji_data.EmojiSequence:
                memberName += char

            else:
                if memberName:
                    W, _ = draw.textsize(memberName, font=member_name_font)
                    draw.text((nameW, 215), memberName,
                              tuple(theme["primary"]), member_name_font)
                    nameW += W
                    memberName = ''

                charset = tuple(codepoints.from_unicode(char))
                unicodePoint = []
                for x in charset:
                    unicodePoint.append(hex(x)[2:])

                unicodeChar = '-'.join(unicodePoint)
                emojiPic = Image.open(self.twemojiPath + unicodeChar +
                                      '.png').convert('RGBA').resize((40, 40))
                card.paste(emojiPic, (nameW + 3, 228), emojiPic)
                nameW += 46

        if memberName:  # Leftovers, text
            draw.text((nameW, 215), memberName, tuple(theme["primary"]),
                      member_name_font)

        self._draw_text(draw, (350, 275), '#' + member.discriminator,
                        theme["secondary"], fonts['subtext'])

        if dbUser['regionFlag']:
            regionImg = self._cache_flag_image(dbUser['regionFlag'])
            card.paste(regionImg, (976, 50), regionImg)

        # Friend code
        if dbUser['friendcode']:
            self._draw_text(draw, (350, 330), dbUser['friendcode'],
                            theme["friend_code"], fonts['subtext'])

        # Start customized content -- stats
        message_count = f'{mclient.bowser.messages.find({"author": member.id}).count():,}'
        self._draw_text(draw, (435, 505), message_count, theme["primary"],
                        fonts['medium'])

        joins = dbUser['joins']
        joins.sort()
        joinDate = datetime.datetime.utcfromtimestamp(joins[0])
        try:  # -d doesn't work on all platforms, such as Windows
            joinDateF = joinDate.strftime('%b. %-d, %Y')
        except:
            joinDateF = joinDate.strftime('%b. %d, %Y')
        self._draw_text(draw, (60, 505), joinDateF, theme["primary"],
                        fonts['medium'])

        if not dbUser['timezone']:
            self._draw_text(draw, (790, 505), 'Not specified',
                            theme["secondary"], fonts['medium'])

        else:
            tznow = datetime.datetime.now(pytz.timezone(dbUser['timezone']))
            localtime = tznow.strftime('%H:%M')
            tzOffset = tznow.strftime('%z')

            if tzOffset[-2:] == '00':  # Remove 00 at end, if present
                tzOffset = tzOffset[:-2]
            if tzOffset[1] == '0':  # Remove 0 at start of ±0X, if present
                tzOffset = tzOffset[0] + tzOffset[2:]

            self._draw_text(draw, (790, 505), f'{localtime} (UTC{tzOffset})',
                            theme["primary"], fonts['medium'])

        # Start trophies
        trophyLocations = {
            0: (1150, 150),
            1: (1300, 150),
            2: (1450, 150),
            3: (1150, 300),
            4: (1300, 300),
            5: (1450, 300),
            6: (1150, 450),
            7: (1300, 450),
            8: (1450, 450),
            9: (1150, 600),
            10: (1300, 600),
            11: (1450, 600),
            12: (1150, 750),
            13: (1300, 750),
            14: (1450, 750),
        }
        trophies = []
        if dbUser['trophyPreference']:
            for x in dbUser:
                trophies.append(x)

        for trophy, lambda_function in self.special_trophies.items():
            if lambda_function(member, guild):
                trophies.append(trophy)

        if len(trophies) < 15:  # Check for additional non-prefered trophies
            for x in dbUser['trophies']:
                if x not in trophies:
                    trophies.append(x)

        while len(trophies) < 15:
            trophies.append(None)

        trophyNum = 0
        useBorder = None
        for x in trophies:
            if useBorder is None and x in self.borders['trophy_borders']:
                useBorder = self.borders['trophy_borders'][x]

            trophyBadge = self._cache_trophy_image(x, background["theme"])
            card.paste(trophyBadge, trophyLocations[trophyNum], trophyBadge)
            trophyNum += 1

        # border!
        useBorder = useBorder or self.borders['default']
        border = self._cache_border_image(useBorder)
        card.paste(border, (0, 0), border)

        # Start favorite games
        setGames = dbUser['favgames']
        gameCount = 0
        Games = self.bot.get_cog('Games')
        if setGames:
            gameIconLocations = {0: (60, 665), 1: (60, 730), 2: (60, 795)}
            gameTextLocations = {0: 660, 1: 725, 2: 791}
            gamesDb = mclient.bowser.games

            setGames = list(dict.fromkeys(
                setGames))  # Remove duplicates from list, just in case
            setGames = setGames[:3]  # Limit to 3 results, just in case

            for game_guid in setGames:
                if not Games:
                    continue

                gameName = Games.get_preferred_name(game_guid)

                if not gameName:
                    continue

                gameIcon = await self._cache_game_img(gamesDb, game_guid,
                                                      theme)
                card.paste(gameIcon, gameIconLocations[gameCount], gameIcon)

                nameW = 120
                nameWMax = 950

                game_name_font = fonts['medium'][self._determine_cjk_font(
                    gameName)]

                for char in gameName:
                    if nameW >= nameWMax:
                        draw.text((nameW, gameTextLocations[gameCount]),
                                  '...',
                                  tuple(theme["primary"]),
                                  font=game_name_font)
                        break

                    draw.text((nameW, gameTextLocations[gameCount]),
                              char,
                              tuple(theme["primary"]),
                              font=game_name_font)
                    nameW += game_name_font.getsize(char)[0]
                gameCount += 1

        if gameCount == 0:  # No games rendered
            self._draw_text(draw, (60, 665), 'Not specified',
                            theme["secondary_heading"], fonts['medium'])

        bytesFile = io.BytesIO()
        card.save(bytesFile, format='PNG')
        return discord.File(io.BytesIO(bytesFile.getvalue()),
                            filename='profile.png')