summaryrefslogtreecommitdiff
path: root/dealconvert/formats/txt.py
blob: e29f37f8a8c4f9e9082d29581cd6244eed71b2ca (plain)
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')