Пример #1
0
    def get_string_img(self, string, font_size = 16):
        '''
        Get String Image by Google Charts API.
        Google Charts API can convert Japanese characters to an image.
        This function maybe raise urllib.urlopen()'s exception.
        If string is empty, the return value is (None, None).

        日本語を含む文字列を画像にしてGoogle Charts APIから取ってくる
        urllib.urlopen() が投げる例外を送出する可能性がある
        空の文字列が渡されたら(None, None)が帰ります

        '''
        if string == '' or string is None:
             return (None, None)

        if self.string_img.get(string) == None:
            url = 'http://chart.apis.google.com/chart?chst=d_text_outline'\
                  '&chld=000000|' + str(font_size) + '|l|000000|_|'
            url += urllib.quote(u2utf8(string))

            logging.info(u2utf8(string) + ' -> URL:' + url)
            img = urllib2.urlopen(url).read()
            img_obj = Image(img) ### for width,height

            self.string_img_obj[string] = img_obj
            self.string_img[string] = images.resize(img, img_obj.width, img_obj.height)

        return (self.string_img[string], self.string_img_obj[string])
Пример #2
0
    def get_string_img(self, string, font_size=16):
        '''
        Get String Image by Google Charts API.
        Google Charts API can convert Japanese characters to an image.
        This function maybe raise urllib.parse.urlopen()'s exception.
        If string is empty, the return value is (None, None).

        日本語を含む文字列を画像にしてGoogle Charts APIから取ってくる
        urllib.parse.urlopen() が投げる例外を送出する可能性がある
        空の文字列が渡されたら(None, None)が帰ります

        '''
        if string == '' or string is None:
            return (None, None)

        if self.string_img.get(string) == None:
            url = 'http://chart.apis.google.com/chart?chst=d_text_outline'\
                  '&chld=000000|' + str(font_size) + '|l|000000|_|'
            url += urllib.parse.quote(u2utf8(string))

            logging.info(u2utf8(string) + ' -> URL:' + url)
            img = urllib.request.urlopen(url).read()
            img_obj = byte_array_to_image(img)  ### for width,height

            self.string_img_obj[string] = img_obj
            self.string_img[string] = img_obj

        return (self.string_img[string], self.string_img_obj[string])
Пример #3
0
    def get(self):
        url  = self.request.url
        m = re.search('(.+)\/(.+)', url)
        path = m.group(1)
        
        sfen_raw = self.request.get('sfen')
        sfen = urllib.unquote(sfen_raw)
        sfenurl = "{}/sfen?{}".format(path, self.request.query_string)
        resizeurl = "{}/resize?{}".format(path, self.request.query_string)

        sfen = sfen.replace('\r','')
        sfen = sfen.replace('\n','')

        black_name_raw = urllib.unquote(self.request.get('sname'))
        white_name_raw = urllib.unquote(self.request.get('gname'))
        title_raw = self.request.get('title')
        black_name = u2utf8(black_name_raw)
        white_name = u2utf8(white_name_raw)
        if title_raw != "":
            title = u2utf8(urllib.unquote(title_raw))
        else:
            title = u2utf8(self.DEFAULT_TITLE)

        height = 421
        # If board has no name, the image height is smaller.
        if black_name == '' and white_name == '' and self.request.get('title') == '':
            height = 400

        self.response.out.write('<!DOCTYPE html>')
        self.response.out.write('<html>\n<head>\n')
        self.response.out.write('<meta name="twitter:id" content="{}" />\n'.format(str(time())[:-3]))
        self.response.out.write('<meta name="twitter:card" content="summary_large_image" />\n')
        self.response.out.write('<meta name="twitter:site" content="@sfenreader_gae" />\n')
        self.response.out.write('<meta name="twitter:description" content="@sfenreader_gae" />\n')
        self.response.out.write('<meta name="twitter:title" content="{}" />\n'.format(title))
        if black_name != '' and white_name != '':
            self.response.out.write('<meta name="twitter:description" content="{} vs {}" />\n'.format(black_name, white_name))
        else:
            self.response.out.write('<meta name="twitter:description" content="{}" />\n'.format(title))
        
        # self.response.out.write('<meta name="twitter:image" content="{}" />\n'.format(sfenurl))
        self.response.out.write('<meta name="twitter:image" content="{}" />\n'.format(resizeurl))
        # self.response.out.write('<meta name="twitter:image:width" content="400" />\n')
        self.response.out.write('<meta name="twitter:image:width" content="842" />\n')
        self.response.out.write('<meta name="twitter:image:height" content="421" />\n')
        # self.response.out.write('<meta name="twitter:url" content="{}" />\n'.format(sfenurl))
        self.response.out.write('<meta name="twitter:url" content="{}" />\n'.format(resizeurl))
        self.response.out.write('<meta charset="UTF-8" />\n')
        self.response.out.write('</head>\n<body>\n')
        self.response.out.write('<p>\n<div style="text-align:center;">{}</div><br>\n'.format(title))
        self.response.out.write('<img src="{}" /><br>\n'.format(sfenurl))
        query = self.create_sfen_query(sfen_raw, black_name_raw, white_name_raw, title_raw)
        self.response.out.write(u'<span style="text-align:left;"><a href="./ja/create_board.html{}">{}</a></span><br>'.format(query, self.EDITING_STRING_JA))
        self.response.out.write(u'<span style="text-align:left;"><a href="./en/create_board.html{}">{}</a></span><br>'.format(query, self.EDITING_STRING_EN))
        self.response.out.write('</body>\n</html>\n')
Пример #4
0
    def get(self):
        print(self.url_root)
        print(self.args)
        print(self.query_string)
        print(type(self.args))

        path = self.url_root
        
        sfen_raw = self.args.get('sfen')
        sfen = urllib.parse.unquote(sfen_raw)
        sfenurl = "{}sfen?{}".format(path, self.query_string)
        resizeurl = "{}resize?{}".format(path, self.query_string)

        sfen = sfen.replace('\r','')
        sfen = sfen.replace('\n','')

        black_name_raw = urllib.parse.unquote(self.args.get('sname', ''))
        white_name_raw = urllib.parse.unquote(self.args.get('gname', ''))
        title_raw = self.args.get('title', '')
        black_name = u2utf8(black_name_raw)
        white_name = u2utf8(white_name_raw)
        if title_raw != "":
            title = u2utf8(urllib.parse.unquote(title_raw))
        else:
            title = self.DEFAULT_TITLE

        height = 421
        # If board has no name, the image height is smaller.
        if black_name_raw == '' and white_name_raw == '' and self.args.get('title') == '':
            height = 400

        response = ""
        response += '<!DOCTYPE html>'
        response += '<html>\n<head>\n'
        response += '<meta name="twitter:id" content="{}" />\n'.format(str(time())[:-3])
        response += '<meta name="twitter:card" content="summary_large_image" />\n'
        response += '<meta name="twitter:site" content="@nkkuma_service" />\n'
        response += '<meta name="twitter:description" content="@nkkuma_service" />\n'
        response += '<meta name="twitter:title" content="{}" />\n'.format(title)
        if black_name_raw != '' and white_name_raw != '':
            response += '<meta name="twitter:description" content="{} vs {}" />\n'.format(black_name, white_name)
        else:
            response += '<meta name="twitter:description" content="{}" />\n'.format(title)
        
        # response += '<meta name="twitter:image" content="{}" />\n'.format(sfenurl)
        response += '<meta name="twitter:image" content="{}" />\n'.format(resizeurl)
        # response += ('<meta name="twitter:image:width" content="400" />\n')
        response += '<meta name="twitter:image:width" content="842" />\n'
        response += '<meta name="twitter:image:height" content="421" />\n'
        # response += '<meta name="twitter:url" content="{}" />\n'.format(sfenurl)
        response += '<meta name="twitter:url" content="{}" />\n'.format(resizeurl)
        response += '<meta charset="UTF-8" />\n'
        response += '</head>\n<body>\n'
        response += '<p>\n<br><br><div style="text-align:center;"><font size="6">{}</font></div>\n'.format(title)
        response += '<div style="text-align:center;"><img src="{}" max-width="90%" /></div><br>\n'.format(sfenurl)
        # query = self.create_sfen_query(sfen_raw, black_name_raw, white_name_raw, title_raw)
        # response += u'<span style="text-align:left;"><a href="./ja/create_board.html{}">{}</a></span><br>'.format(query, self.EDITING_STRING_JA)
        # response += u'<span style="text-align:left;"><a href="./en/create_board.html{}">{}</a></span><br>'.format(query, self.EDITING_STRING_EN)
        response += '<br><br><div style="text-align:center;">developed by nkkuma</div>\n'
        response += '<br><br><div style="text-align:center;">This software includes the work that is distributed in <a href="https://github.com/shibacho/sfenreader_gae">@sfenreader_gae</a>.</div>\n'
        response += '</body>\n</html>\n'
        return (200, response)
Пример #5
0
            logging.error('Invalid sfen string:' + str(e))
            self.response.out.write('Invalid sfen string:' + str(e))
            return
        except PieceKindException, e:
            logging.error('Invalid piece kind:' + str(e))
            self.response.out.write('Invalid piece kind:' + str(e))
            return
        except IOError, e:
            logging.error('Cannot create string image:' + str(e))
            self.response.out.write('Cannot create string image:' + str(e))
            return

        if black_name != '' or white_name != '' or title != '' or move_count != '0':
            self.exist_title_flag = True
            if black_name is not None:
                logging.info('black_name:' + u2utf8(black_name))

            if white_name is not None:
                logging.info('white_name:' + u2utf8(white_name))

            if title is not None:
                logging.info('title:' + u2utf8(title))

            if move_count != '0':
                logging.info('move_count:' + move_count)
        else:
            logging.info('No titles found.')
            self.exist_title_flag = False
            self.max_title_height = 0
            self.title_height = 0
Пример #6
0
    def get(self):
        sfen = urllib.parse.unquote(self.args.get('sfen', ''))
        last_move = urllib.parse.unquote(self.args.get('lm', ''))
        piece_kind = urllib.parse.unquote(self.args.get('piece', 'kanji'))
        arrow_str = urllib.parse.unquote(self.args.get('arrow', ''))
        turn_str = urllib.parse.unquote(self.args.get('turn', 'on'))
        move_at = urllib.parse.unquote(self.args.get('ma', 'off'))

        logging.info('sfen:' + sfen + ' last_move:' + last_move)
        if sfen == '':
            return (400, 'Please, specify SFEN string.')

        ### If Move At(ma) is on, draw nth move count.
        if piece_kind == 'kanji':
            move_count_prefix = ''
            move_count_suffix = u' 手目'
        else:
            move_count_prefix = 'at '
            move_count_suffix = ''

        ### Remove CR LF
        sfen = sfen.replace('\r', '')
        sfen = sfen.replace('\n', '')

        black_name = urllib.parse.unquote(self.args.get('sname', ''))
        white_name = urllib.parse.unquote(self.args.get('gname', ''))
        title = urllib.parse.unquote(self.args.get('title', ''))

        font_size_str = urllib.parse.unquote(self.args.get('fontsize', ''))
        if font_size_str.isdigit():
            font_size = int(font_size_str)
        else:
            font_size = self.DEFAULT_FONT_SIZE

        try:
            self.img_init(piece_kind=piece_kind)
            img_list = []
            (board, black_hand, white_hand, turn_sfen,
             move_count) = self.sfen_parse(sfen)
            (black_name_img,
             black_name_img_obj) = self.get_string_img(black_name, font_size)
            (white_name_img,
             white_name_img_obj) = self.get_string_img(white_name, font_size)
            (title_img, title_img_obj) = self.get_string_img(title, font_size)

            if move_at == 'on' and move_count != '0':
                move_count_str = move_count_prefix + move_count + move_count_suffix
                (move_count_img, move_count_img_obj) = self.get_string_img(
                    move_count_str, font_size)

        except BadSfenStringException as e:
            logging.error('Invalid sfen string:' + str(e))
            return (400, 'Invalid sfen string:' + str(e))
        except PieceKindException as e:
            logging.error('Invalid piece kind:' + str(e))
            return (400, ('Invalid piece kind:' + str(e)))
        except IOError as e:
            logging.error('Cannot create string image:' + str(e))
            return (400, 'Cannot create string image:' + str(e))

        if black_name != '' or white_name != '' or title != '' or move_count != '0':
            self.exist_title_flag = True
            if black_name is not None:
                logging.info('black_name:' + black_name)

            if white_name is not None:
                logging.info('white_name:' + white_name)

            if title is not None:
                logging.info('title:' + title)

            if move_count != '0':
                logging.info('move_count:' + move_count)
        else:
            logging.info('No titles found.')
            self.exist_title_flag = False
            self.max_title_height = 0
            self.title_height = 0

        ### タイトル等が存在したら最大の高さを求めて必要に応じて描画する
        if self.exist_title_flag == True:
            self.max_title_height = self.BLACK_MARK_SMALL_HEIGHT
            if black_name_img_obj is not None and black_name_img_obj.height > self.max_title_height:
                self.max_title_height = black_name_img_obj.height

            if white_name_img_obj is not None and white_name_img_obj.height > self.max_title_height:
                self.max_title_height = white_name_img_obj.height

            if title_img_obj is not None and title_img_obj.height > self.max_title_height:
                self.max_title_height = title_img_obj.height

            logging.info('max_title_height:' + str(self.max_title_height))

            self.title_height = self.TITLE_Y + (self.max_title_height *
                                                2) + self.IMAGE_PADDING_Y

            ### 先手のマークを書く位置を画像の右端から求める
            if black_name_img is not None:
                logging.info('Drawing Black Name:' + u2utf8(black_name) +
                             ' width:' + str(black_name_img_obj.width) +
                             ' height:' + str(black_name_img_obj.height))

                black_title_x_left = self.IMAGE_WIDTH - (
                    black_name_img_obj.width + self.BLACK_MARK_SMALL_WIDTH +
                    self.IMAGE_PADDING_X)

                black_title_x = black_title_x_left
                img_list.append(
                    (self.black_img[2], black_title_x, self.TITLE_Y, 1.0))

                black_title_x += self.BLACK_MARK_SMALL_WIDTH + self.IMAGE_PADDING_X
                img_list.append(
                    (black_name_img, black_title_x, self.TITLE_Y, 1.0))

            ### 後手のマークと名前を描画する
            if white_name_img is not None:
                logging.info('Drawing White Name:' + white_name + ' width:' +
                             str(white_name_img_obj.width) + ' height:' +
                             str(white_name_img_obj.height))
                white_title_x = self.WHITE_TITLE_MARK_X
                img_list.append(
                    (self.white_img[2], white_title_x, self.TITLE_Y, 1.0))

                white_title_x += self.WHITE_MARK_SMALL_WIDTH + self.IMAGE_PADDING_X
                img_list.append(
                    (white_name_img, white_title_x, self.TITLE_Y, 1.0))
                white_title_x_right = (white_title_x +
                                       white_name_img_obj.width +
                                       self.IMAGE_PADDING_X)

            ### 中央タイトルの描画
            if title_img is not None:
                center = self.IMAGE_WIDTH / 2

                ### 文字の長さに合わせて描画開始位置を調整
                center_x = center - title_img_obj.width / 2
                img_list.append(
                    (title_img, center_x, self.TITLE_Y +
                     self.max_title_height + self.IMAGE_PADDING_Y, 1.0))

            if move_at == 'on' and move_count != '0':
                center = self.IMAGE_WIDTH / 2
                center_x = center - move_count_img_obj.width / 2
                img_list.append((move_count_img, center_x, self.TITLE_Y, 1.0))

        logging.info('max_title_height:' + str(self.max_title_height))
        if len(img_list) != 0:
            (img, img_list) = self.composite(img_list)

        ### 飛 -> 角 -> 金 -> 銀 -> 桂 -> 香 -> 歩 の順番にarrayに入れる
        white_hand_array = self.sort_hand_array(white_hand)
        black_hand_array = self.sort_hand_array(black_hand)

        ### 最終着手マスの描画
        ### 最終着手マスは &lm=76 (7六のマスを強調表示)のような形式で渡される
        ### TODO: チェス方式(76 -> 7f) も対応したい
        if last_move != '':
            m = re.compile('^([1-9])([1-9])$').match(last_move)
            if m is not None:
                logging.info('Valid last_move:')
                self.last_move_img_init()
                col = int(m.group(1))
                row = int(m.group(2))
                lm_x = (self.SQUARE_ORIGIN_X - 1 + self.BOARD_X +
                        self.SQUARE_MULTIPLE_X * (9 - int(col)))
                lm_y = (self.SQUARE_ORIGIN_Y - 1 + self.BOARD_Y +
                        self.title_height + self.SQUARE_MULTIPLE_Y *
                        (int(row) - 1))
                img_list.append((self.last_move_img, lm_x, lm_y, 0.5))

        ### 盤の描画
        ### 最終着手マスより後に書くのは盤上の星が上に来て欲しいため
        img_list.append((self.draw_board_img, self.BOARD_X,
                         self.BOARD_Y + self.title_height, 1.0))

        ### 盤上の駒の描画
        for pos, piece in board.items():
            turn = self.BLACK
            piece_kind = piece.replace('+', '')
            if piece_kind.isupper():
                turn = self.BLACK
            elif piece_kind.islower():
                turn = self.WHITE

            [col, row] = list(pos)
            piece_lower = piece.lower()

            ### 駒を書く場所を決める
            x = self.BOARD_X + self.SQUARE_ORIGIN_X + self.SQUARE_MULTIPLE_X * (
                9 - int(col))
            y = self.BOARD_Y + self.SQUARE_ORIGIN_Y + self.title_height + self.SQUARE_MULTIPLE_Y * (
                int(row) - 1)
            logging.warn("x:" + str(x) + " y:" + str(y) + " pos:" + pos +
                         " piece:" + piece_lower + " turn:" + str(turn))
            img_list.append(
                (self.draw_piece_img[piece_lower][turn], x, y, 1.0))

            if len(img_list) == self.COMPOSITE_MAX_NUM:
                (img, img_list) = self.composite(img_list)

        (img, img_list) = self.composite(img_list)
        logging.info('Success to draw pieces.')

        ### 手番を書く
        if turn_str == 'on':
            logging.info('draw_turn:' + turn_sfen + ' title_height:' +
                         str(self.title_height))
            if turn_sfen == 'b':
                (img, img_list) = self.draw_turn_mark(
                    img_list, self.BLACK_MARK_X,
                    self.BLACK_MARK_Y + self.title_height)
            elif turn_sfen == 'w':
                (img, img_list) = self.draw_turn_mark(
                    img_list, self.WHITE_MARK_X,
                    self.WHITE_MARK_Y + self.title_height)

        ### 先手のマークを表示する
        img_list.append((self.black_img[0], self.BLACK_MARK_X,
                         self.BLACK_MARK_Y + self.title_height, 1.0))

        ### 後手のマークを表示する
        img_list.append((self.white_img[1], self.WHITE_MARK_X,
                         self.WHITE_MARK_Y + self.title_height, 1.0))
        (img, img_list) = self.composite(img_list)
        logging.info('Success to draw black/white marks.')

        ### 後手の手持ちの駒を描画
        pos_x = self.WHITE_MARK_X
        pos_y = self.WHITE_MARK_Y + self.title_height - (
            self.PIECE_IMAGE_HEIGHT + self.IMAGE_PADDING_Y)

        (img, img_list) = self.draw_hand_pieces(img, white_hand_array, pos_x,
                                                pos_y, self.WHITE)

        ### 先手の手持ちの駒を描画
        pos_x = self.BLACK_MARK_X
        pos_y = self.BLACK_MARK_Y + self.title_height + (
            self.BLACK_MARK_HEIGHT + self.IMAGE_PADDING_Y)
        (img, img_list) = self.draw_hand_pieces(img, black_hand_array, pos_x,
                                                pos_y, self.BLACK)

        ### 矢印を書く(予定)
        # if arrow_str != '':
        #     (img, img_list) = self.create_arrow_img(img_list, arrow_str)
        #     (img, img_list) = self.composite(img_list)

        ## PIL形式からbytearrayに変換
        bytearrayimg = image_to_byte_array(img)
        return (200, bytearrayimg)