Coverage for SplitHandHistory.py: 0%

146 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-09-28 16:41 +0000

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3 

4#Copyright 2010-2011 Chaz Littlejohn 

5#This program is free software: you can redistribute it and/or modify 

6#it under the terms of the GNU Affero General Public License as published by 

7#the Free Software Foundation, version 3 of the License. 

8# 

9#This program is distributed in the hope that it will be useful, 

10#but WITHOUT ANY WARRANTY; without even the implied warranty of 

11#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12#GNU General Public License for more details. 

13# 

14#You should have received a copy of the GNU Affero General Public License 

15#along with this program. If not, see <http://www.gnu.org/licenses/>. 

16#In the "official" distribution you can find the license in agpl-3.0.txt. 

17 

18from __future__ import print_function 

19 

20 

21#import L10n 

22#_ = L10n.get_translation() 

23 

24# This code is based heavily on stars-support-hh-split.py by Mika Boström 

25 

26import os 

27import sys 

28import re 

29import codecs 

30import Options 

31import Configuration 

32from Exceptions import * 

33from io import StringIO 

34 

35(options, argv) = Options.fpdb_options() 

36 

37__ARCHIVE_PRE_HEADER_REGEX='^Hand #(\d+)\s*$|\*{20}\s#\s\d+\s\*+\s+' 

38re_SplitArchive = re.compile(__ARCHIVE_PRE_HEADER_REGEX) 

39codepage = ["utf-16", "utf-8", "cp1252"] 

40 

41 

42class SplitHandHistory(object): 

43 def __init__(self, config, in_path = '-', out_path = None, hands = 100, filter = "PokerStarsToFpdb", archive = False): 

44 self.config = config 

45 self.in_path = in_path 

46 self.out_path = out_path 

47 if not self.out_path: 

48 self.out_path = os.path.dirname(self.in_path) 

49 self.hands = hands 

50 self.archive = archive 

51 self.re_SplitHands = None 

52 self.line_delimiter = None 

53 self.line_addendum = None 

54 self.filedone = False 

55 

56 #Acquire re_SplitHands for this hh 

57 filter_name = filter.replace("ToFpdb", "") 

58 mod = __import__(filter) 

59 obj = getattr(mod, filter_name, None) 

60 self.re_SplitHands = obj.re_SplitHands 

61 

62 #Determine line delimiter type if any 

63 if self.re_SplitHands.match('\n\n'): 

64 self.line_delimiter = '\n\n' 

65 if self.re_SplitHands.match('\n\n\n'): 

66 self.line_delimiter = '\n\n\n' 

67 

68 #Add new line addendum for sites which match SplitHand to next line as well 

69 if filter_name == 'OnGame': 

70 self.line_addendum = '*' 

71 if filter_name == 'Merge': 

72 self.line_addendum = '<game' 

73 

74 #Open the gargantuan file 

75 for kodec in self.__listof(codepage): 

76 try: 

77 infile = codecs.open(self.in_path, 'r', kodec) 

78 except IOError: 

79 print (('File not found')) 

80 sys.exit(2) 

81 

82 #Split with do_hands_per_file if archive and paragraphs if a regular hh 

83 if self.archive: 

84 nn = 0 

85 while True: 

86 nn += 1 

87 check = self.do_hands_per_file(infile, nn) 

88 if check is None: 

89 print (('%s processed') % self.in_path) 

90 break 

91 else: 

92 filenum = 0 

93 while not self.filedone: 

94 filenum += 1 

95 outfile = self.new_file(filenum) 

96 handnum = 0 

97 for hand in self.paragraphs(infile, None, self.line_addendum): 

98 outfile.write(hand) 

99 if self.line_delimiter: 

100 outfile.write(self.line_delimiter) 

101 handnum += 1 

102 if handnum >= self.hands: 

103 break 

104 outfile.close() 

105 

106 def new_file(self, fileno=-1): 

107 if fileno < 1: 

108 print (('Invalid file number') + ': %d)' % fileno) 

109 sys.exit(2) 

110 basename = os.path.splitext(os.path.basename(self.in_path))[0] 

111 name = os.path.join(self.out_path, basename+'-%06d.txt' % fileno) 

112 print ('-> %s' % name) 

113 newfile = file(name, 'w') 

114 return newfile 

115 

116 #Archive Hand Splitter 

117 def do_hands_per_file(self, infile, num=-1): 

118 done = False 

119 n = 0 

120 outfile = self.new_file(num) 

121 while n < self.hands: 

122 try: 

123 infile = self.next_hand(infile) 

124 infile = self.process_hand(infile, outfile) 

125 except FpdbEndOfFile: 

126 done = True 

127 break 

128 except: 

129 print(("Unexpected error processing file")) 

130 sys.exit(2) 

131 n += 1 

132 outfile.close() 

133 if not done: 

134 return infile 

135 else: 

136 return None 

137 

138 #Non-Archive Hand Splitter 

139 def paragraphs(self, file, separator=None, addendum=None): 

140 if not callable(separator) and self.line_delimiter: 

141 def separator(line): return line == '\n' 

142 else: 

143 def separator(line): return self.re_SplitHands.search(line) 

144 file_str = StringIO() 

145 print(file_str.getvalue()) 

146 for line in file: 

147 if separator(line+addendum): 

148 if file_str.getvalue(): 

149 if not self.line_delimiter: 

150 file_str.write(line) 

151 yield file_str.getvalue() 

152 file_str = None 

153 file_str = StringIO() 

154 else: 

155 file_str.write(line) 

156 if file_str.getvalue(): yield file_str.getvalue() 

157 self.filedone = True 

158 

159 

160 # Finds pre-hand header (Hand #<num>) 

161 def next_hand(self, infile): 

162 m = None 

163 while not m: 

164 l = infile.readline() 

165 #print l, len(l) 

166 # Catch EOF 

167 if len(l) == 0: 

168 raise FpdbEndOfFile(("End of file reached")) 

169 m = re_SplitArchive.search(l) 

170 # There is an empty line after pre-hand header and actual HH entry 

171 l = infile.readline() 

172 

173 return infile 

174 

175 # Each individual hand is written separately 

176 def process_hand(self, infile=None, outfile=None): 

177 l = infile.readline() 

178 l = l.replace('\r\n', '\n') 

179 outfile.write(l) 

180 l = infile.readline() 

181 

182 while len(l) < 3: 

183 l = infile.readline() 

184 

185 while len(l) > 2: 

186 l = l.replace('\r\n', '\n') 

187 outfile.write(l) 

188 l = infile.readline() 

189 outfile.write(self.line_delimiter) 

190 return infile 

191 

192 def __listof(self, x): 

193 if isinstance(x, list) or isinstance(x, tuple): 

194 return x 

195 else: 

196 return [x] 

197 

198def main(argv=None): 

199 if argv is None: 

200 argv = sys.argv[1:] 

201 

202 Configuration.set_logfile("fpdb-log.txt") 

203 if not options.config: 

204 options.config = Configuration.Config(file = "HUD_config.test.xml") 

205 

206 if options.filename: 

207 SplitHH = SplitHandHistory(options.config, options.filename, options.outpath, options.hands, 

208 options.hhc, options.archive) 

209 

210if __name__ == '__main__': 

211 sys.exit(main())