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])
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])
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')
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)
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
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)