bridgehandscanner / hand_record.py
vincentlui's picture
update ui
743c074
from fpdf import FPDF
import tempfile
import os
import bridgebots
from pbn_util import merge_pbn, parse_pbn
DEALER_LIST = ['N', 'E', 'S', 'W']
VULNERABILITY_LIST = ["None","NS","EW","All","NS","EW","All","None","EW","All","None","NS","All","None","NS","EW"]
SUITS = [bridgebots.Suit.SPADES, bridgebots.Suit.HEARTS, bridgebots.Suit.DIAMONDS, bridgebots.Suit.CLUBS]
SUIT_SYMBOLS = ['♠','♥','♦','♣']
class PDF(FPDF):
value_column_span = 7
def __init__(self, event, site, *args, **kwargs):
super().__init__(*args, **kwargs)
self.event = event
self.site = site
def header(self) -> None:
# Setting font: helvetica bold 15
self.set_font("helvetica", "B", 12)
# Moving cursor to the right:
self.cell(80, 5, self.event)
# Printing title:
self.cell(80, 5, self.site, align="C", new_x="LMARGIN",
new_y="NEXT",)
# Performing a line break:
self.ln(5)
def footer(self) -> None:
return super().footer()
def print_boards(self, results):
self.add_page()
self.add_font('times2', style='', fname='times.ttf')
self.set_font("times2", "", 10)
self.c_margin = 0.1
table_config = {
'borders_layout':'NONE',
'col_widths':3,
'line_height':self.font_size + 0.4,
'align': 'L',
'text_align': 'L',
'first_row_as_headings': False,
}
start_x,start_y = 9, self.y
table_size = 45, 46
table_margin = 2
for i, result in enumerate(results):
deal = result[0]
board_no = int(result[1][0]['Board'])
dds_tricks_table = result[1][0]['dds_tricks_table']
page_i = i % 20
if (i % 20 == 0) and (i != 0):
self.add_page()
row_idx = page_i // 4
col_idx = page_i % 4
x = start_x + (table_size[0] + 2 * table_margin + 1) * col_idx
y = start_y + (table_size[1] + 2 * table_margin + 1) * row_idx
top_left = x - table_margin, y - table_margin
top_right = x + table_size[0] + table_margin, y - table_margin
bottom_left = x - table_margin, y + table_size[1] + table_margin
bottom_right = x + table_size[0] + table_margin, y + table_size[1] + table_margin
self.set_xy(x,y)
self.line(*top_left, *bottom_left)
self.line(*top_left, * top_right)
self.line(*top_right, *bottom_right)
self.line(*bottom_left, *bottom_right)
dds_top_left = x - table_margin, y + 35 - 1
dds_top_right = x - table_margin + 18, y + 35 - 1
dds_bottom_right = x - table_margin + 18, y + table_size[1] + table_margin
self.line(*dds_top_left, *dds_top_right)
self.line(*dds_top_right, *dds_bottom_right)
dealer = DEALER_LIST[(board_no-1) % 4]
vul = VULNERABILITY_LIST[(board_no-1) % 16]
self.set_font_size(10)
with self.table(**table_config) as table:
row = table.row()
self.set_font_size(16)
row.cell(str(board_no), colspan=6, rowspan=2, align='C', v_align='C', padding=(2,0,0,0))
self.set_font_size(10)
for i, (suit, values) in enumerate(zip(SUIT_SYMBOLS, get_values(deal, 'N'))):
if i!=0:
row = table.row()
if i == 2:
row.cell(f'{dealer} / {vul}', colspan=6, rowspan=2, align='C', v_align='C')
print_suit_values(self,row,suit,values)
# row = table.row()
# row = table.row()
for i, (suit, values1, values2) in enumerate(zip(SUIT_SYMBOLS, get_values(deal, 'W'), get_values(deal, 'E'))):
row = table.row()
row.cell('', colspan=1, rowspan=1)
print_suit_values(self, row, suit, values1)
# row.cell('',colspan=1)
print_suit_values(self, row, suit, values2)
# row = table.row()
row = table.row()
row.cell('', colspan=6, rowspan=4)
for i, (suit, values) in enumerate(zip(SUIT_SYMBOLS, get_values(deal, 'S'))):
if i!=0:
row = table.row()
print_suit_values(self, row, suit, values)
self.set_xy(x-1,y+34)
self.set_font_size(7)
dds_table_config = {
'borders_layout':'NONE',
'col_widths':2.8,
'line_height':self.font_size + 0.1,
'align': 'L',
'text_align': 'L',
'first_row_as_headings': False,
'padding': 0.1
}
with self.table(**dds_table_config) as table:
row = table.row()
row.cell('')
self.set_font_size(5)
row.cell('NT', align='C')
self.set_font_size(7)
row.cell(SUIT_SYMBOLS[0], align='C')
row.cell(SUIT_SYMBOLS[1], align='C')
row.cell(SUIT_SYMBOLS[2], align='C')
row.cell(SUIT_SYMBOLS[3], align='C')
row = table.row()
for i in range(4):
if i!=0:
row = table.row()
row.cell(dds_tricks_table[i*5][0], align='C')
row.cell(dds_tricks_table[i*5][2], align='C')
row.cell(dds_tricks_table[i*5+1][2], align='C')
row.cell(dds_tricks_table[i*5+2][2], align='C')
row.cell(dds_tricks_table[i*5+3][2], align='C')
row.cell(dds_tricks_table[i*5+4][2], align='C')
def create_hand_record_pdf(pbn_paths, event, site):
filepath_merged_pbn = merge_pbn(pbn_paths)
results = parse_pbn(filepath_merged_pbn)
fd,fn = tempfile.mkstemp(".pdf")
pdf = PDF(event, site)
pdf.print_boards(results)
pdf.output(fn)
os.close(fd)
return fn
def get_values(result, direction):
d = bridgebots.Direction.from_str(direction)
hand = result.hands[d]
return [''.join([value.abbreviation()
for value in hand.suits[suit]])
for suit in SUITS]
def print_suit_values(pdf, row, suit, values):
if (suit=='♥') or (suit=='♦'): # Hearts or Diamonds
pdf.set_text_color(255,0,0)
row.cell(suit, colspan=1)
pdf.set_text_color(0,0,0)
row.cell(values, colspan=PDF.value_column_span)