Spaces:
Running
Running
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) | |