1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
from collections import OrderedDict
from urlparse import urlparse, parse_qsl
from urllib import urlencode
import re, warnings
from . import DealFormat
from .. import dto
class TXTFormat(DealFormat):
_url_prefix = 'https://www.bridgebase.com/tools/handviewer.html'
_hand_format = re.compile(r'([shdc])([akqjt2-9]*)', re.I)
_hand_designations = {
'n': dto.POSITION_NORTH,
'e': dto.POSITION_EAST,
's': dto.POSITION_SOUTH,
'w': dto.POSITION_WEST
}
_suit_designations = {
's': dto.SUIT_SPADES,
'h': dto.SUIT_HEARTS,
'd': dto.SUIT_DIAMONDS,
'c': dto.SUIT_CLUBS
}
@property
def suffix(self):
return '.txt'
def parse_content(self, content):
deal_list = []
deal_numbers = []
renumber_deals = False
event = ''
lines = [line.strip() for line in content.readlines()]
for line in lines:
if line.startswith(self._url_prefix):
deal = dto.Deal()
url = urlparse(line)
params = OrderedDict(parse_qsl(url.query))
for hand in self._hand_designations.keys():
if hand not in params:
raise RuntimeError(
'URL %s is missing "%s" hand' % (
line, hand
)
)
suits = OrderedDict(
self._hand_format.findall(params[hand]))
for suit, cards in suits.iteritems():
cards = cards.upper()
deal.hands[
self._hand_designations[hand]
][
self._suit_designations[suit]
] = list(cards)
if 'b' in params:
try:
deal.number = int(params['b'])
except:
warnings.warn(
'URL %s contains no deal number. ALL deals will be auto-number, maintaining their vulnerability if defined' % (line)
)
renumber_deals = True
else:
warnings.warn(
'URL %s contains no deal number. ALL deals will be auto-number, maintaining their vulnerability if defined' % (line)
)
renumber_deals = True
if deal.number:
if deal.number in deal_numbers:
warnings.warn(
'Duplicate deal number %d. ALL deals will be auto-number, maintaining their vulnerability if defined' % (deal.number)
)
renumber_deals = True
deal_numbers.append(deal.number)
if 'v' in params:
deal.vulnerable['NS'] = params['v'].lower() in ['b', 'n']
deal.vulnerable['EW'] = params['v'].lower() in ['b', 'e']
else:
deal.vulnerable = None
if 'd' in params:
deal.dealer = self._hand_designations.get(
params['d'], None)
deal.event = event
event = ''
deal_list.append(deal)
else:
event = line
for idx, deal in enumerate(deal_list):
if renumber_deals:
deal.number = idx+1
if not deal.vulnerable:
deal.vulnerable = deal.get_vulnerability(deal.number)
if not deal.dealer:
deal.dealer = deal.get_dealer(deal.number)
return deal_list
def output_content(self, out_file, dealset):
lines = []
dealers = {}
for designation, hand in self._hand_designations.iteritems():
dealers[hand] = designation
suits = {}
for deal in dealset:
if deal.event:
lines.append(deal.event)
params = {
'b': deal.number,
'd': dealers[deal.dealer],
'v': ['0', 'n', 'e', 'b'][
deal.vulnerable['NS'] + 2 * deal.vulnerable['EW']
],
'a': 'pppp'
}
for hand, designation in dealers.iteritems():
params[designation] = ''
for suit, idx in self._suit_designations.iteritems():
params[designation] += suit
params[designation] += ''.join(deal.hands[hand][idx]).lower()
url = '%s?%s' % (
self._url_prefix, urlencode(params))
lines.append(url)
for line in lines:
out_file.write(line + '\r\n')
|