Merge branch 'master' of git://git.assembla.com/fpdboz
This commit is contained in:
		
						commit
						0d79fe8f09
					
				|  | @ -133,8 +133,9 @@ or None if we fail to get the info """ | |||
| 
 | ||||
|         self.info = {} | ||||
|         mg = m.groupdict() | ||||
|         print mg | ||||
| 
 | ||||
|         limits = { 'No Limit':'nl', 'Limit':'fl' } | ||||
|         limits = { 'No Limit':'nl', 'No Limit ':'nl', 'Limit':'fl' } | ||||
|         games = {              # base, category | ||||
|                     'Holdem' : ('hold','holdem'), | ||||
|          'Holdem Tournament' : ('hold','holdem') } | ||||
|  |  | |||
|  | @ -73,7 +73,7 @@ except ImportError: | |||
|     use_numpy = False | ||||
| 
 | ||||
| 
 | ||||
| DB_VERSION = 144 | ||||
| DB_VERSION = 145 | ||||
| 
 | ||||
| 
 | ||||
| # Variance created as sqlite has a bunch of undefined aggregate functions. | ||||
|  | @ -255,6 +255,11 @@ class Database: | |||
|         self.database = db_params['db-databaseName'] | ||||
|         self.host = db_params['db-host'] | ||||
|         self.db_path = '' | ||||
|         gen = c.get_general_params() | ||||
|         self.day_start = 0 | ||||
|          | ||||
|         if 'day_start' in gen: | ||||
|             self.day_start = float(gen['day_start']) | ||||
| 
 | ||||
|         # where possible avoid creating new SQL instance by using the global one passed in | ||||
|         if sql is None: | ||||
|  | @ -291,8 +296,8 @@ class Database: | |||
| 
 | ||||
|             # vars for hand ids or dates fetched according to above config: | ||||
|             self.hand_1day_ago = 0             # max hand id more than 24 hrs earlier than now | ||||
|             self.date_ndays_ago = 'd000000'    # date N days ago ('d' + YYMMDD) | ||||
|             self.h_date_ndays_ago = 'd000000'  # date N days ago ('d' + YYMMDD) for hero | ||||
|             self.date_ndays_ago = 'd00000000'    # date N days ago ('d' + YYMMDD) | ||||
|             self.h_date_ndays_ago = 'd00000000'  # date N days ago ('d' + YYMMDD) for hero | ||||
|             self.date_nhands_ago = {}          # dates N hands ago per player - not used yet | ||||
| 
 | ||||
|             self.saveActions = False if self.import_options['saveActions'] == False else True | ||||
|  | @ -690,20 +695,24 @@ class Database: | |||
|             if row and row[0]: | ||||
|                 self.hand_1day_ago = int(row[0]) | ||||
|                  | ||||
|         d = timedelta(days=hud_days) | ||||
|         now = datetime.utcnow() - d | ||||
|         self.date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day) | ||||
|         tz = datetime.utcnow() - datetime.today() | ||||
|         tz_offset = tz.seconds/3600 | ||||
|         tz_day_start_offset = self.day_start + tz_offset | ||||
|          | ||||
|         d = timedelta(days=h_hud_days) | ||||
|         d = timedelta(days=hud_days, hours=tz_day_start_offset) | ||||
|         now = datetime.utcnow() - d | ||||
|         self.h_date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day) | ||||
|         self.date_ndays_ago = "d%02d%02d%02d%02d" % (now.year - 2000, now.month, now.day, tz_day_start_offset) | ||||
|          | ||||
|         d = timedelta(days=h_hud_days, hours=tz_day_start_offset) | ||||
|         now = datetime.utcnow() - d | ||||
|         self.h_date_ndays_ago = "d%02d%02d%02d%02d" % (now.year - 2000, now.month, now.day, tz_day_start_offset) | ||||
| 
 | ||||
|     def init_player_hud_stat_vars(self, playerid): | ||||
|         # not sure if this is workable, to be continued ... | ||||
|         try: | ||||
|             # self.date_nhands_ago is used for fetching stats for last n hands (hud_style = 'H') | ||||
|             # This option not used yet - needs to be called for each player :-( | ||||
|             self.date_nhands_ago[str(playerid)] = 'd000000' | ||||
|             self.date_nhands_ago[str(playerid)] = 'd00000000' | ||||
| 
 | ||||
|             # should use aggregated version of query if appropriate | ||||
|             c.execute(self.sql.query['get_date_nhands_ago'], (self.hud_hands, playerid)) | ||||
|  | @ -771,11 +780,11 @@ class Database: | |||
|         if hud_style == 'T': | ||||
|             stylekey = self.date_ndays_ago | ||||
|         elif hud_style == 'A': | ||||
|             stylekey = '0000000'  # all stylekey values should be higher than this | ||||
|             stylekey = '000000000'  # all stylekey values should be higher than this | ||||
|         elif hud_style == 'S': | ||||
|             stylekey = 'zzzzzzz'  # all stylekey values should be lower than this | ||||
|             stylekey = 'zzzzzzzzz'  # all stylekey values should be lower than this | ||||
|         else: | ||||
|             stylekey = '0000000' | ||||
|             stylekey = '000000000' | ||||
|             log.info('hud_style: %s' % hud_style) | ||||
| 
 | ||||
|         #elif hud_style == 'H': | ||||
|  | @ -784,11 +793,11 @@ class Database: | |||
|         if h_hud_style == 'T': | ||||
|             h_stylekey = self.h_date_ndays_ago | ||||
|         elif h_hud_style == 'A': | ||||
|             h_stylekey = '0000000'  # all stylekey values should be higher than this | ||||
|             h_stylekey = '000000000'  # all stylekey values should be higher than this | ||||
|         elif h_hud_style == 'S': | ||||
|             h_stylekey = 'zzzzzzz'  # all stylekey values should be lower than this | ||||
|             h_stylekey = 'zzzzzzzzz'  # all stylekey values should be lower than this | ||||
|         else: | ||||
|             h_stylekey = '000000' | ||||
|             h_stylekey = '00000000' | ||||
|             log.info('h_hud_style: %s' % h_hud_style) | ||||
| 
 | ||||
|         #elif h_hud_style == 'H': | ||||
|  | @ -1824,11 +1833,11 @@ class Database: | |||
|         """Update cached statistics. If update fails because no record exists, do an insert.""" | ||||
| 
 | ||||
|         if self.use_date_in_hudcache: | ||||
|             styleKey = datetime.strftime(starttime, 'd%y%m%d') | ||||
|             #styleKey = "d%02d%02d%02d" % (hand_start_time.year-2000, hand_start_time.month, hand_start_time.day) | ||||
|             styleKey = datetime.strftime(starttime, 'd%y%m%d%H') | ||||
|             #styleKey = "d%02d%02d%02d%02d" % (hand_start_time.year-2000, hand_start_time.month, hand_start_time.day, hand_start_time.hour) | ||||
|         else: | ||||
|             # hard-code styleKey as 'A000000' (all-time cache, no key) for now | ||||
|             styleKey = 'A000000' | ||||
|             # hard-code styleKey as 'A00000000' (all-time cache, no key) for now | ||||
|             styleKey = 'A00000000' | ||||
| 
 | ||||
|         update_hudcache = self.sql.query['update_hudcache'] | ||||
|         update_hudcache = update_hudcache.replace('%s', self.sql.query['placeholder']) | ||||
|  |  | |||
|  | @ -50,11 +50,14 @@ import Database | |||
| import Filters | ||||
| import Charset | ||||
| 
 | ||||
| DEBUG = False | ||||
| 
 | ||||
| class GuiSessionViewer (threading.Thread): | ||||
|     def __init__(self, config, querylist, mainwin, debug=True): | ||||
|         self.debug = debug | ||||
|         self.conf = config | ||||
|         self.sql = querylist | ||||
|         self.window = mainwin | ||||
| 
 | ||||
|         self.liststore = None | ||||
| 
 | ||||
|  | @ -153,6 +156,28 @@ class GuiSessionViewer (threading.Thread): | |||
| 
 | ||||
|         # make sure Hand column is not displayed | ||||
|         #[x for x in self.columns if x[0] == 'hand'][0][1] = False | ||||
|         if DEBUG == False: | ||||
|             warning_string = """ | ||||
| Session Viewer is proof of concept code only, and contains many bugs. | ||||
| 
 | ||||
| Feel free to use the viewer, but there is no guarantee that the data is accurate. | ||||
| 
 | ||||
| If you are interested in developing the code further please contact us via the usual channels. | ||||
| 
 | ||||
| Thankyou | ||||
| """ | ||||
|             self.warning_box(warning_string) | ||||
| 
 | ||||
|     def warning_box(self, str, diatitle=_("FPDB WARNING")): | ||||
|         diaWarning = gtk.Dialog(title=diatitle, parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) | ||||
| 
 | ||||
|         label = gtk.Label(str) | ||||
|         diaWarning.vbox.add(label) | ||||
|         label.show() | ||||
| 
 | ||||
|         response = diaWarning.run() | ||||
|         diaWarning.destroy() | ||||
|         return response | ||||
| 
 | ||||
|     def get_vbox(self): | ||||
|         """returns the vbox of this thread""" | ||||
|  |  | |||
							
								
								
									
										218
									
								
								pyfpdb/GuiStove.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								pyfpdb/GuiStove.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,218 @@ | |||
| #!/usr/bin/python | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| #Copyright 2008-2010 Steffen Schaumburg | ||||
| #This program is free software: you can redistribute it and/or modify | ||||
| #it under the terms of the GNU Affero General Public License as published by | ||||
| #the Free Software Foundation, version 3 of the License. | ||||
| # | ||||
| #This program is distributed in the hope that it will be useful, | ||||
| #but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| #GNU General Public License for more details. | ||||
| # | ||||
| #You should have received a copy of the GNU Affero General Public License | ||||
| #along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
| #In the "official" distribution you can find the license in agpl-3.0.txt. | ||||
| 
 | ||||
| import L10n | ||||
| _ = L10n.get_translation() | ||||
| 
 | ||||
| import pygtk | ||||
| pygtk.require('2.0') | ||||
| import gtk | ||||
| import os | ||||
| import sys | ||||
| 
 | ||||
| import Charset | ||||
| 
 | ||||
| DEBUG = False | ||||
| 
 | ||||
| class GuiStove(): | ||||
| 
 | ||||
|     def __init__(self, config, parent, debug=True): | ||||
|         """Constructor for GraphViewer""" | ||||
|         self.conf = config | ||||
|         self.parent = parent | ||||
| 
 | ||||
|         self.mainHBox = gtk.HBox(False, 0) | ||||
| 
 | ||||
|         # hierarchy:  self.mainHBox / self.notebook | ||||
| 
 | ||||
|         self.notebook = gtk.Notebook() | ||||
|         self.notebook.set_tab_pos(gtk.POS_TOP) | ||||
|         self.notebook.set_show_tabs(True) | ||||
|         self.notebook.set_show_border(True) | ||||
| 
 | ||||
|         self.createFlopTab() | ||||
|         self.createStudTab() | ||||
|         self.createDrawTab() | ||||
| 
 | ||||
| 
 | ||||
|         self.mainHBox.add(self.notebook) | ||||
| 
 | ||||
|         self.mainHBox.show_all() | ||||
| 
 | ||||
|         if DEBUG == False: | ||||
|             warning_string = """ | ||||
| Stove is a GUI mockup of a EV calculation page, and completely non functional. | ||||
| 
 | ||||
| Unless you are interested in developing this feature, please ignore this page. | ||||
| 
 | ||||
| If you are interested in developing the code further see GuiStove.py and Stove.py | ||||
| 
 | ||||
| Thankyou | ||||
| """ | ||||
|             self.warning_box(warning_string) | ||||
| 
 | ||||
| 
 | ||||
|     def warning_box(self, str, diatitle=_("FPDB WARNING")): | ||||
|         diaWarning = gtk.Dialog(title=diatitle, parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) | ||||
| 
 | ||||
|         label = gtk.Label(str) | ||||
|         diaWarning.vbox.add(label) | ||||
|         label.show() | ||||
| 
 | ||||
|         response = diaWarning.run() | ||||
|         diaWarning.destroy() | ||||
|         return response | ||||
| 
 | ||||
| 
 | ||||
|     def get_active_text(combobox): | ||||
|         model = combobox.get_model() | ||||
|         active = combobox.get_active() | ||||
|         if active < 0: | ||||
|             return None | ||||
|         return model[active][0] | ||||
| 
 | ||||
|     def create_combo_box(self, strings): | ||||
|         combobox = gtk.combo_box_new_text() | ||||
|         for label in strings: | ||||
|             combobox.append_text(label) | ||||
|         combobox.set_active(0) | ||||
|         return combobox | ||||
| 
 | ||||
|     def createDrawTab(self): | ||||
|         tab_title = "Draw" | ||||
|         label = gtk.Label(tab_title) | ||||
| 
 | ||||
|         ddbox = gtk.VBox(False, 0) | ||||
|         self.notebook.append_page(ddbox, label) | ||||
| 
 | ||||
|     def createStudTab(self): | ||||
|         tab_title = "Stud" | ||||
|         label = gtk.Label(tab_title) | ||||
| 
 | ||||
|         ddbox = gtk.VBox(False, 0) | ||||
|         self.notebook.append_page(ddbox, label) | ||||
| 
 | ||||
|     def createFlopTab(self): | ||||
|         # hierarchy: hbox / ddbox     / ddhbox / Label + flop_games_cb | label + players_cb | ||||
|         #                 / gamehbox / in_frame / table / | ||||
|         #                            / out_frame | ||||
| 
 | ||||
|         tab_title = "Flop" | ||||
|         label = gtk.Label(tab_title) | ||||
| 
 | ||||
|         ddbox = gtk.VBox(False, 0) | ||||
|         self.notebook.append_page(ddbox, label) | ||||
| 
 | ||||
|         ddhbox = gtk.HBox(False, 0) | ||||
|         gamehbox = gtk.HBox(False, 0) | ||||
| 
 | ||||
|         ddbox.add(ddhbox) | ||||
|         ddbox.add(gamehbox) | ||||
| 
 | ||||
|         # Combo boxes in the top row | ||||
| 
 | ||||
|         games =   [ "Holdem", "Omaha", "Omaha 8", ] | ||||
|         players = [ "2", "3", "4", "5", "6", "7", "8", "9", "10" ] | ||||
|         flop_games_cb = self.create_combo_box(games) | ||||
|         players_cb = self.create_combo_box(players) | ||||
| 
 | ||||
|         label = gtk.Label("Gametype:") | ||||
|         ddhbox.add(label) | ||||
|         ddhbox.add(flop_games_cb) | ||||
|         label = gtk.Label("Players:") | ||||
|         ddhbox.add(label) | ||||
|         ddhbox.add(players_cb) | ||||
| 
 | ||||
|         # Frames for Stove input and output | ||||
| 
 | ||||
|         in_frame = gtk.Frame("Input:") | ||||
|         out_frame = gtk.Frame("Output:") | ||||
| 
 | ||||
|         gamehbox.add(in_frame) | ||||
|         gamehbox.add(out_frame) | ||||
| 
 | ||||
|         outstring = """ | ||||
| No board given. Using Monte-Carlo simulation... | ||||
| Enumerated 2053443 possible plays. | ||||
| Your hand: (Ad Ac) | ||||
| Against the range: { | ||||
|                     AhAd, AhAs, AdAs, KhKd, KhKs,  | ||||
|                     KhKc, KdKs, KdKc, KsKc, QhQd,  | ||||
|                     QhQs, QhQc, QdQs, QdQc, QsQc,  | ||||
|                     JhJd, JhJs, JhJc, JdJs, JdJc,  | ||||
|                     JsJc | ||||
|                    } | ||||
| 
 | ||||
|   Win       Lose       Tie | ||||
|  69.91%    15.83%    14.26% | ||||
| 
 | ||||
| """ | ||||
|         label = gtk.Label(outstring) | ||||
|         out_frame.add(label) | ||||
| 
 | ||||
|         # Input Frame | ||||
|         table = gtk.Table(4, 4, True) | ||||
|         label = gtk.Label("Board:") | ||||
|         board = gtk.Entry() | ||||
|         #board.connect("changed", self._some_function, arg) | ||||
| 
 | ||||
|         btn1 = gtk.Button() | ||||
|         btn1.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) | ||||
|         #btn.connect('clicked', self._some_function, arg) | ||||
|         table.attach(label, 0, 1, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
|         table.attach(board, 1, 2, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
|         table.attach(btn1, 2, 3, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
| 
 | ||||
| 
 | ||||
|         label = gtk.Label("Player1:") | ||||
|         board = gtk.Entry() | ||||
|         #board.connect("changed", self._some_function, arg) | ||||
|         btn2 = gtk.Button() | ||||
|         btn2.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) | ||||
|         #btn.connect('clicked', self._some_function, arg) | ||||
|         btn3 = gtk.Button() | ||||
|         btn3.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) | ||||
|         #btn.connect('clicked', self._some_function, arg) | ||||
|         table.attach(label, 0, 1, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
|         table.attach(board, 1, 2, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
|         table.attach(btn2, 2, 3, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
|         table.attach(btn3, 3, 4, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
| 
 | ||||
| 
 | ||||
|         label = gtk.Label("Player2:") | ||||
|         board = gtk.Entry() | ||||
|         #board.connect("changed", self._some_function, arg) | ||||
|         btn4 = gtk.Button() | ||||
|         btn4.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) | ||||
|         #btn.connect('clicked', self._some_function, arg) | ||||
|         btn5 = gtk.Button() | ||||
|         btn5.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) | ||||
|         #btn.connect('clicked', self._some_function, arg) | ||||
|         table.attach(label, 0, 1, 2, 3, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
|         table.attach(board, 1, 2, 2, 3, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
|         table.attach(btn4, 2, 3, 2, 3, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
|         table.attach(btn5, 3, 4, 2, 3, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK) | ||||
|          | ||||
|         #table.attach(label, i, i+1, j, j+1,) | ||||
|         in_frame.add(table) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     def get_vbox(self): | ||||
|         """returns the vbox of this thread""" | ||||
|         return self.mainHBox | ||||
|     #end def get_vbox | ||||
|  | @ -1,4 +1,4 @@ | |||
| #!/usr/bin/python | ||||
| #!/usr/bin/env python | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| #Copyright 2010 Chaz Littlejohn | ||||
|  | @ -28,18 +28,21 @@ import Configuration | |||
| import Database | ||||
| 
 | ||||
| __ARCHIVE_PRE_HEADER_REGEX='^Hand #(\d+)\s*$|\*{20}\s#\s\d+\s\*+\s+' | ||||
| re_SplitArchive = re.compile(__ARCHIVE_PRE_HEADER_REGEX) | ||||
| re_SplitArchive = re.compile(__ARCHIVE_PRE_HEADER_REGEX, re.MULTILINE) | ||||
| 
 | ||||
| 
 | ||||
| class IdentifySite: | ||||
|     def __init__(self, config, in_path = '-'): | ||||
|         self.in_path = in_path | ||||
|         self.config = config | ||||
|         self.db = Database.Database(config) | ||||
|         self.db = Database.Database(self.config) | ||||
|         self.sitelist = {} | ||||
|         self.filelist = {} | ||||
|         self.generateSiteList() | ||||
|         self.walkDirectory(self.in_path, self.sitelist) | ||||
|         if os.path.isdir(self.in_path): | ||||
|             self.walkDirectory(self.in_path, self.sitelist) | ||||
|         else: | ||||
|             self.idSite(self.in_path, self.sitelist) | ||||
|          | ||||
|     def generateSiteList(self): | ||||
|         """Generates a ordered dictionary of site, filter and filter name for each site in hhcs""" | ||||
|  | @ -80,7 +83,7 @@ class IdentifySite: | |||
|                 for kodec in self.__listof(obj.codepage): | ||||
|                     try: | ||||
|                         in_fh = codecs.open(file, 'r', kodec) | ||||
|                         whole_file = in_fh.read() | ||||
|                         whole_file = in_fh.read(2000) | ||||
|                         in_fh.close() | ||||
|                  | ||||
|                         if info[2] in ('OnGame', 'Winamax'): | ||||
|  | @ -94,7 +97,7 @@ class IdentifySite: | |||
|                             if re_SplitArchive.search(whole_file): | ||||
|                                 archive = True | ||||
|                         if m: | ||||
|                             self.filelist[file] = [info[0]] + [info[1]] + [kodec] + [archive] | ||||
|                             self.filelist[file] = [info[1]] + [kodec] + [archive] | ||||
|                             break | ||||
|                     except: | ||||
|                         pass | ||||
|  |  | |||
|  | @ -59,6 +59,8 @@ def fpdb_options(): | |||
|                     help=_("File to be split is a PokerStars or Full Tilt Poker archive file")) | ||||
|     parser.add_option("-n", "--numhands", dest="hands", default="100", type="int", | ||||
|                     help=_("How many hands do you want saved to each file. Default is 100")) | ||||
|     parser.add_option("-w", "--workerid", dest="workerid", default="0", type="int", | ||||
|                     help=_("Specifies the worker id running the script")) | ||||
| 
 | ||||
| 
 | ||||
|     (options, argv) = parser.parse_args() | ||||
|  |  | |||
|  | @ -298,7 +298,7 @@ class PokerStars(HandHistoryConverter): | |||
|             if key == 'BUTTON': | ||||
|                 hand.buttonpos = info[key] | ||||
|             if key == 'MAX': | ||||
|                 hand.maxseats = int(info[key]) | ||||
|                 if info[key]: hand.maxseats = int(info[key]) | ||||
| 
 | ||||
|             if key == 'MIXED': | ||||
|                 hand.mixed = self.mixes[info[key]] if info[key] is not None else None | ||||
|  |  | |||
|  | @ -1064,7 +1064,7 @@ class Sql: | |||
|                         activeSeats SMALLINT NOT NULL, | ||||
|                         position CHAR(1), | ||||
|                         tourneyTypeId SMALLINT UNSIGNED, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id), | ||||
|                         styleKey CHAR(7) NOT NULL,  /* 1st char is style (A/T/H/S), other 6 are the key */ | ||||
|                         styleKey CHAR(9) NOT NULL,  /* 1st char is style (A/T/H/S), other 8 are the key */ | ||||
|                         HDs INT NOT NULL, | ||||
| 
 | ||||
|                         wonWhenSeenStreet1 FLOAT, | ||||
|  | @ -1165,7 +1165,7 @@ class Sql: | |||
|                         activeSeats SMALLINT, | ||||
|                         position CHAR(1), | ||||
|                         tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id), | ||||
|                         styleKey CHAR(7) NOT NULL,  /* 1st char is style (A/T/H/S), other 6 are the key */ | ||||
|                         styleKey CHAR(9) NOT NULL,  /* 1st char is style (A/T/H/S), other 8 are the key */ | ||||
|                         HDs INT, | ||||
| 
 | ||||
|                         wonWhenSeenStreet1 FLOAT, | ||||
|  | @ -2047,7 +2047,7 @@ class Sql: | |||
|         # gets a date, would need to use handsplayers (not hudcache) to get exact hand Id | ||||
|         if db_server == 'mysql': | ||||
|             self.query['get_date_nhands_ago'] = """ | ||||
|                 select concat( 'd', date_format(max(h.startTime), '%Y%m%d') ) | ||||
|                 select concat( 'd', date_format(max(h.startTime), '%Y%m%d%H') ) | ||||
|                 from (select hp.playerId | ||||
|                             ,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx | ||||
|                       from HandsPlayers hp | ||||
|  | @ -2059,7 +2059,7 @@ class Sql: | |||
|                 """ | ||||
|         elif db_server == 'postgresql': | ||||
|             self.query['get_date_nhands_ago'] = """ | ||||
|                 select 'd' || to_char(max(h3.startTime), 'YYMMDD') | ||||
|                 select 'd' || to_char(max(h3.startTime), 'YYMMDDHH') | ||||
|                 from (select hp.playerId | ||||
|                             ,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx | ||||
|                       from HandsPlayers hp | ||||
|  | @ -2071,7 +2071,7 @@ class Sql: | |||
|                 """ | ||||
|         elif db_server == 'sqlite': # untested guess at query: | ||||
|             self.query['get_date_nhands_ago'] = """ | ||||
|                 select 'd' || strftime(max(h3.startTime), 'YYMMDD') | ||||
|                 select 'd' || strftime(max(h3.startTime), 'YYMMDDHH') | ||||
|                 from (select hp.playerId | ||||
|                             ,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx | ||||
|                       from HandsPlayers hp | ||||
|  | @ -3290,7 +3290,7 @@ class Sql: | |||
|                             else 'E' | ||||
|                        end                                            AS hc_position | ||||
|                       <tourney_select_clause> | ||||
|                       ,date_format(h.startTime, 'd%y%m%d') | ||||
|                       ,date_format(h.startTime, 'd%y%m%d%H') | ||||
|                       ,count(1) | ||||
|                       ,sum(wonWhenSeenStreet1) | ||||
|                       ,sum(wonWhenSeenStreet2) | ||||
|  | @ -3379,7 +3379,7 @@ class Sql: | |||
|                         ,h.seats | ||||
|                         ,hc_position | ||||
|                         <tourney_group_clause> | ||||
|                         ,date_format(h.startTime, 'd%y%m%d') | ||||
|                         ,date_format(h.startTime, 'd%y%m%d%H') | ||||
| """ | ||||
|         elif db_server == 'postgresql': | ||||
|             self.query['rebuildHudCache'] = """ | ||||
|  | @ -3488,7 +3488,7 @@ class Sql: | |||
|                             else 'E' | ||||
|                        end                                            AS hc_position | ||||
|                       <tourney_select_clause> | ||||
|                       ,'d' || to_char(h.startTime, 'YYMMDD') | ||||
|                       ,'d' || to_char(h.startTime, 'YYMMDDHH') | ||||
|                       ,count(1) | ||||
|                       ,sum(wonWhenSeenStreet1) | ||||
|                       ,sum(wonWhenSeenStreet2) | ||||
|  | @ -3577,7 +3577,7 @@ class Sql: | |||
|                         ,h.seats | ||||
|                         ,hc_position | ||||
|                         <tourney_group_clause> | ||||
|                         ,to_char(h.startTime, 'YYMMDD') | ||||
|                         ,to_char(h.startTime, 'YYMMDDHH') | ||||
| """ | ||||
|         else:   # assume sqlite | ||||
|             self.query['rebuildHudCache'] = """ | ||||
|  | @ -3686,7 +3686,7 @@ class Sql: | |||
|                             else 'E' | ||||
|                        end                                            AS hc_position | ||||
|                       <tourney_select_clause> | ||||
|                       ,'d' || substr(strftime('%Y%m%d', h.startTime),3,7) | ||||
|                       ,'d' || substr(strftime('%Y%m%d%H', h.startTime),3,9) | ||||
|                       ,count(1) | ||||
|                       ,sum(wonWhenSeenStreet1) | ||||
|                       ,sum(wonWhenSeenStreet2) | ||||
|  | @ -3775,7 +3775,7 @@ class Sql: | |||
|                         ,h.seats | ||||
|                         ,hc_position | ||||
|                         <tourney_group_clause> | ||||
|                         ,'d' || substr(strftime('%Y%m%d', h.startTime),3,7) | ||||
|                         ,'d' || substr(strftime('%Y%m%d%H', h.startTime),3,9) | ||||
| """ | ||||
| 
 | ||||
|         self.query['insert_hudcache'] = """ | ||||
|  |  | |||
|  | @ -1,19 +1,22 @@ | |||
| #!/usr/bin/python | ||||
| # -*- coding: utf-8 -*- | ||||
| #!/usr/bin/env python | ||||
| 
 | ||||
| #Copyright 2010 Chaz Littlejohn | ||||
| #This program is free software: you can redistribute it and/or modify | ||||
| #it under the terms of the GNU Affero General Public License as published by | ||||
| #the Free Software Foundation, version 3 of the License. | ||||
| #    Copyright 2010, Chaz Littlejohn | ||||
| #     | ||||
| #This program is distributed in the hope that it will be useful, | ||||
| #but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| #GNU General Public License for more details. | ||||
| #    This program is free software; you can redistribute it and/or modify | ||||
| #    it under the terms of the GNU General Public License as published by | ||||
| #    the Free Software Foundation; either version 2 of the License, or | ||||
| #    (at your option) any later version. | ||||
| #     | ||||
| #You should have received a copy of the GNU Affero General Public License | ||||
| #along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
| #In the "official" distribution you can find the license in agpl-3.0.txt. | ||||
| #    This program is distributed in the hope that it will be useful, | ||||
| #    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| #    GNU General Public License for more details. | ||||
| #     | ||||
| #    You should have received a copy of the GNU General Public License | ||||
| #    along with this program; if not, write to the Free Software | ||||
| #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||
| 
 | ||||
| ######################################################################## | ||||
| 
 | ||||
| import L10n | ||||
| _ = L10n.get_translation() | ||||
|  | @ -28,6 +31,7 @@ import Options | |||
| import Configuration | ||||
| from Exceptions import * | ||||
| from cStringIO import StringIO | ||||
| import time | ||||
| 
 | ||||
| (options, argv) = Options.fpdb_options() | ||||
| 
 | ||||
|  | @ -37,7 +41,7 @@ codepage = ["utf-16", "utf-8", "cp1252"] | |||
| 
 | ||||
| 
 | ||||
| class SplitHandHistory: | ||||
|     def __init__(self, config, in_path = '-', out_path = None, hands = 100, filter = "PokerStarsToFpdb", archive = False): | ||||
|     def __init__(self, config, in_path = '-', out_path = None, hands = 100, filter = "PokerStarsToFpdb", archive = False, workerid = 0): | ||||
|         self.config = config | ||||
|         self.in_path = in_path | ||||
|         self.out_path = out_path | ||||
|  | @ -50,22 +54,25 @@ class SplitHandHistory: | |||
|         self.line_addendum = None | ||||
|         self.filedone = False | ||||
|          | ||||
|         self.timestamp = str(time.time()) | ||||
|         self.workerid = '%02d' % workerid | ||||
|          | ||||
|         #Acquire re_SplitHands for this hh | ||||
|         filter_name = filter.replace("ToFpdb", "") | ||||
|         self.filter_name = filter.replace("ToFpdb", "") | ||||
|         mod = __import__(filter) | ||||
|         obj = getattr(mod, filter_name, None) | ||||
|         obj = getattr(mod, self.filter_name, None) | ||||
|         self.re_SplitHands = obj.re_SplitHands | ||||
|          | ||||
|         #Determine line delimiter type if any | ||||
|         if self.re_SplitHands.match('\n\n'): | ||||
|             self.line_delimiter = '\n\n' | ||||
|         if self.re_SplitHands.match('\n\n\n'): | ||||
|             self.line_delimiter = '\n\n\n' | ||||
|         if self.re_SplitHands.match('\n\n'): | ||||
|             self.line_delimiter = '\n\n' | ||||
|              | ||||
|         #Add new line addendum for sites which match SplitHand to next line as well | ||||
|         if filter_name == 'OnGame': | ||||
|         if self.filter_name == 'OnGame': | ||||
|             self.line_addendum = '*' | ||||
|         if filter_name == 'Carbon': | ||||
|         if self.filter_name == 'Carbon': | ||||
|             self.line_addendum = '<game' | ||||
|              | ||||
|         #Open the gargantuan file | ||||
|  | @ -75,6 +82,7 @@ class SplitHandHistory: | |||
|             except IOError: | ||||
|                 print _('File not found') | ||||
|                 sys.exit(2) | ||||
|             self.kodec = kodec | ||||
|          | ||||
|         #Split with do_hands_per_file if archive and paragraphs if a regular hh | ||||
|         if self.archive: | ||||
|  | @ -105,9 +113,10 @@ class SplitHandHistory: | |||
|             print _('Nope, will not work (fileno=%d)' % fileno) | ||||
|             sys.exit(2) | ||||
|         basename = os.path.splitext(os.path.basename(self.in_path))[0] | ||||
|         name = os.path.join(self.out_path, basename+'-%06d.txt' % fileno) | ||||
|         name = os.path.join(self.out_path, self.filter_name+'-'+basename+'_'+self.workerid+'_'+self.timestamp+'_%06d.txt' % fileno) | ||||
|         print '-> %s' % name | ||||
|         newfile = file(name, 'w') | ||||
|         os.chmod(name, 0775) | ||||
|         return newfile | ||||
|          | ||||
|     #Archive Hand Splitter | ||||
|  | @ -122,8 +131,11 @@ class SplitHandHistory: | |||
|             except FpdbEndOfFile: | ||||
|                 done = True | ||||
|                 break | ||||
|             except UnicodeEncodeError: | ||||
|                 print _('Absurd character done messed you up') | ||||
|                 sys.exit(2) | ||||
|             except: | ||||
|                 print _("Unexpected error processing file") | ||||
|                 print _('Unexpected error processing file') | ||||
|                 sys.exit(2) | ||||
|             n += 1 | ||||
|         outfile.close() | ||||
|  | @ -174,7 +186,7 @@ class SplitHandHistory: | |||
|         l = infile.readline() | ||||
|         l = l.replace('\r\n', '\n') | ||||
|         outfile.write(l) | ||||
|         l = infile.readline() | ||||
|         l = infile.readline().encode(self.kodec) | ||||
|      | ||||
|         while len(l) < 3: | ||||
|             l = infile.readline() | ||||
|  | @ -182,7 +194,7 @@ class SplitHandHistory: | |||
|         while len(l) > 2: | ||||
|             l = l.replace('\r\n', '\n') | ||||
|             outfile.write(l) | ||||
|             l = infile.readline() | ||||
|             l = infile.readline().encode(self.kodec) | ||||
|         outfile.write(self.line_delimiter) | ||||
|         return infile | ||||
|          | ||||
|  | @ -196,12 +208,18 @@ def main(argv=None): | |||
|     if argv is None: | ||||
|         argv = sys.argv[1:] | ||||
|          | ||||
|     if not options.filename: | ||||
|         options.filename = sys.argv[1] | ||||
| 
 | ||||
|     if not options.config: | ||||
|         options.config = Configuration.Config(file = "HUD_config.test.xml") | ||||
|         options.config = sys.argv[2] | ||||
|          | ||||
|     if sys.argv[3] == "True": | ||||
|         options.archive = True | ||||
|          | ||||
|     if options.filename: | ||||
|         SplitHH = SplitHandHistory(options.config, options.filename, options.outpath, options.hands, | ||||
|                                    options.hhc, options.archive) | ||||
|                                    options.hhc, options.archive, options.workerid) | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     sys.exit(main()) | ||||
|  |  | |||
							
								
								
									
										118
									
								
								pyfpdb/Stove.py
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								pyfpdb/Stove.py
									
									
									
									
									
								
							|  | @ -22,14 +22,57 @@ OFFSUIT = 2 | |||
| 
 | ||||
| ev = pokereval.PokerEval() | ||||
| 
 | ||||
| holder = None | ||||
| 
 | ||||
| class Holder: | ||||
| class Stove: | ||||
|     def __init__(self): | ||||
|         self.hand = None | ||||
|         self.board = None | ||||
|         self.range = None | ||||
| 
 | ||||
|     def set_board_with_list(self, board): | ||||
|         pass | ||||
| 
 | ||||
|     def set_board_string(self, string): | ||||
|         board = Board() | ||||
| 
 | ||||
|         # Board | ||||
|         b = string.strip().split() | ||||
|         if len(b) > 4: | ||||
|             board.b5 = b[4] | ||||
|         if len(b) > 3: | ||||
|             board.b4 = b[3] | ||||
|         if len(b) > 2: | ||||
|             board.b1 = b[0] | ||||
|             board.b2 = b[1] | ||||
|             board.b3 = b[2] | ||||
| 
 | ||||
|         self.board = board | ||||
| 
 | ||||
|     def set_hero_cards_string(self, string): | ||||
|         # Our pocket cards | ||||
|         cc = string.strip().split() | ||||
|         c1 = cc[0] | ||||
|         c2 = cc[1] | ||||
|         pocket_cards = Cards(c1, c2) | ||||
|         self.hand = pocket_cards | ||||
| 
 | ||||
|     def set_villain_range_string(self, string): | ||||
|         # Villain's range | ||||
|         range = Range() | ||||
|         hands_in_range = string.strip().split(',') | ||||
|         for h in hands_in_range: | ||||
|             _h = h.strip() | ||||
|             if len(_h) > 3: | ||||
|                 cc = _h.split() | ||||
|                 r1 = cc[0] | ||||
|                 r2 = cc[1] | ||||
|                 vp = Cards(r1, r2) | ||||
|                 range.add(vp) | ||||
|             else: | ||||
|                 range.expand(expand_hands(_h, pocket_cards, board)) | ||||
| 
 | ||||
|         self.range = range | ||||
| 
 | ||||
| 
 | ||||
| class Cards: | ||||
|     def __init__(self, c1, c2): | ||||
|  | @ -177,50 +220,15 @@ def expand_hands(abbrev, hand, board): | |||
|     return range | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|      | ||||
| 
 | ||||
| def parse_args(args, container): | ||||
|     # args[0] is the path being executed; need 3 more args | ||||
|     if len(args) < 4: | ||||
|         return False | ||||
| 
 | ||||
|     board = Board() | ||||
|     container.set_board_string(args[1]) | ||||
|     container.set_hero_cards_string(args[2]) | ||||
|     container.set_villain_range_string(args[3]) | ||||
| 
 | ||||
|     # Board | ||||
|     b = args[1].strip().split() | ||||
|     if len(b) > 4: | ||||
|         board.b5 = b[4] | ||||
|     if len(b) > 3: | ||||
|         board.b4 = b[3] | ||||
|     if len(b) > 2: | ||||
|         board.b1 = b[0] | ||||
|         board.b2 = b[1] | ||||
|         board.b3 = b[2] | ||||
| 
 | ||||
|     # Our pocket cards | ||||
|     cc = args[2].strip().split() | ||||
|     c1 = cc[0] | ||||
|     c2 = cc[1] | ||||
|     pocket_cards = Cards(c1, c2) | ||||
| 
 | ||||
|     # Villain's range | ||||
|     range = Range() | ||||
|     hands_in_range = args[3].strip().split(',') | ||||
|     for h in hands_in_range: | ||||
|         _h = h.strip() | ||||
|         if len(_h) > 3: | ||||
|             cc = _h.split() | ||||
|             r1 = cc[0] | ||||
|             r2 = cc[1] | ||||
|             vp = Cards(r1, r2) | ||||
|             range.add(vp) | ||||
|         else: | ||||
|             range.expand(expand_hands(_h, pocket_cards, board)) | ||||
| 
 | ||||
|     holder.hand = pocket_cards | ||||
|     holder.range = range | ||||
|     holder.board = board | ||||
| 
 | ||||
|     return True | ||||
| 
 | ||||
|  | @ -284,26 +292,12 @@ def odds_for_range(holder): | |||
| 
 | ||||
|     sev.show(holder.hand, holder.range.get()) | ||||
| 
 | ||||
| def main(argv=None): | ||||
|     stove = Stove() | ||||
|     if not parse_args(sys.argv, stove): | ||||
|         usage(sys.argv[0]) | ||||
|         sys.exit(2) | ||||
|     odds_for_range(stove) | ||||
| 
 | ||||
| 
 | ||||
| holder = Holder() | ||||
| if not parse_args(sys.argv, holder): | ||||
|     usage(sys.argv[0]) | ||||
|     sys.exit(2) | ||||
| odds_for_range(holder) | ||||
| 
 | ||||
| # debugs | ||||
| #print '%s, %s' % ( holder.hand.c1, holder.hand.c2) | ||||
| #print '%s %s %s %s %s' % (holder.board.b1, holder.board.b2, | ||||
| #    holder.board.b3, holder.board.b4, holder.board.b5) | ||||
| #while True: | ||||
| #    try: | ||||
| #        vl = holder.range.get() | ||||
| #        v = vl.pop() | ||||
| #        print '\t%s %s' % (v.c1, v.c2) | ||||
| #    except IndexError: | ||||
| #        break | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| if __name__  == '__main__': | ||||
|     sys.exit(main()) | ||||
|  |  | |||
|  | @ -201,6 +201,7 @@ def main(argv=None): | |||
|         walk_testfiles("regression-test-files/cash/iPoker/", compare, importer, iPokerErrors, "iPoker") | ||||
|     if sites['Winamax'] == True: | ||||
|         walk_testfiles("regression-test-files/cash/Winamax/", compare, importer, WinamaxErrors, "Winamax") | ||||
|         walk_testfiles("regression-test-files/tour/Winamax/", compare, importer, WinamaxErrors, "Winamax") | ||||
|     if sites['Win2day'] == True: | ||||
|         walk_testfiles("regression-test-files/cash/Win2day/", compare, importer, Win2dayErrors, "Win2day") | ||||
| 
 | ||||
|  |  | |||
|  | @ -82,15 +82,26 @@ class Winamax(HandHistoryConverter): | |||
| # Winamax Poker - CashGame - HandId: #279823-223-1285031451 - Holdem no limit (0.02€/0.05€) - 2010/09/21 03:10:51 UTC | ||||
| # Table: 'Charenton-le-Pont' 9-max (real money) Seat #5 is the button | ||||
|     re_HandInfo = re.compile(u""" | ||||
|             \s*Winamax\sPoker\s-\sCashGame\s-\sHandId:\s\#(?P<HID1>\d+)-(?P<HID2>\d+)-(?P<HID3>\d+).*\s | ||||
|             \s*Winamax\sPoker\s-\s | ||||
|             (?P<RING>CashGame)? | ||||
|             (?P<TOUR>Tournament\s | ||||
|             (?P<TOURNAME>.+)?\s | ||||
|             buyIn:\s(?P<BUYIN>(?P<BIAMT>[%(LS)s\d\,]+)?\s\+?\s(?P<BIRAKE>[%(LS)s\d\,]+)?\+?(?P<BOUNTY>[%(LS)s\d\.]+)?\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)?|Gratuit|Ticket\suniquement)?\s | ||||
|             (level:\s(?P<LEVEL>\d+))? | ||||
|             .*)? | ||||
|             \s-\sHandId:\s\#(?P<HID1>\d+)-(?P<HID2>\d+)-(?P<HID3>\d+).*\s | ||||
|             (?P<GAME>Holdem|Omaha)\s | ||||
|             (?P<LIMIT>no\slimit|pot\slimit)\s | ||||
|             \( | ||||
|             (((%(LS)s)?(?P<ANTE>[.0-9]+)(%(LS)s)?)/)? | ||||
|             ((%(LS)s)?(?P<SB>[.0-9]+)(%(LS)s)?)/ | ||||
|             ((%(LS)s)?(?P<BB>[.0-9]+)(%(LS)s)?) | ||||
|             \)\s-\s | ||||
|             (?P<DATETIME>.*) | ||||
|             Table:\s\'(?P<TABLE>[^']+)\'\s(?P<MAXPLAYER>\d+)\-max | ||||
|             Table:\s\'(?P<TABLE>[^(]+) | ||||
|             (.(?P<TOURNO>\d+).\#(?P<TABLENO>\d+))?.* | ||||
|             \' | ||||
|             \s(?P<MAXPLAYER>\d+)\-max | ||||
|             """ % substitutions, re.MULTILINE|re.DOTALL|re.VERBOSE) | ||||
| 
 | ||||
|     re_TailSplitHands = re.compile(r'\n\s*\n') | ||||
|  | @ -126,8 +137,8 @@ class Winamax(HandHistoryConverter): | |||
|             self.re_PostSB    = re.compile('%(PLYR)s posts small blind (%(CUR)s)?(?P<SB>[\.0-9]+)(%(CUR)s)?' % subst, re.MULTILINE) | ||||
|             self.re_PostBB    = re.compile('%(PLYR)s posts big blind (%(CUR)s)?(?P<BB>[\.0-9]+)(%(CUR)s)?' % subst, re.MULTILINE) | ||||
|             self.re_DenySB    = re.compile('(?P<PNAME>.*) deny SB' % subst, re.MULTILINE) | ||||
|             self.re_Antes     = re.compile(r"^%(PLYR)s: posts the ante (%(CUR)s)?(?P<ANTE>[\.0-9]+)(%(CUR)s)?" % subst, re.MULTILINE) | ||||
|             self.re_BringIn   = re.compile(r"^%(PLYR)s: brings[- ]in( low|) for (%(CUR)s)?(?P<BRINGIN>[\.0-9]+(%(CUR)s)?)" % subst, re.MULTILINE) | ||||
|             self.re_Antes     = re.compile(r"^%(PLYR)s posts ante (%(CUR)s)?(?P<ANTE>[\.0-9]+)(%(CUR)s)?" % subst, re.MULTILINE) | ||||
|             self.re_BringIn   = re.compile(r"^%(PLYR)s brings[- ]in( low|) for (%(CUR)s)?(?P<BRINGIN>[\.0-9]+(%(CUR)s)?)" % subst, re.MULTILINE) | ||||
|             self.re_PostBoth  = re.compile('(?P<PNAME>.*): posts small \& big blind \( (%(CUR)s)?(?P<SBBB>[\.0-9]+)(%(CUR)s)?\)' % subst) | ||||
|             self.re_PostDead  = re.compile('(?P<PNAME>.*) posts dead blind \((%(CUR)s)?(?P<DEAD>[\.0-9]+)(%(CUR)s)?\)' % subst, re.MULTILINE) | ||||
|             self.re_HeroCards = re.compile('Dealt\sto\s%(PLYR)s\s\[(?P<CARDS>.*)\]' % subst) | ||||
|  | @ -144,6 +155,9 @@ class Winamax(HandHistoryConverter): | |||
|                 ["ring", "hold", "fl"], | ||||
|                 ["ring", "hold", "nl"], | ||||
|                 ["ring", "hold", "pl"], | ||||
|                 ["tour", "hold", "fl"], | ||||
|                 ["tour", "hold", "nl"], | ||||
|                 ["tour", "hold", "pl"], | ||||
|                ] | ||||
| 
 | ||||
|     def determineGameType(self, handText): | ||||
|  | @ -160,7 +174,11 @@ class Winamax(HandHistoryConverter): | |||
| 
 | ||||
|         mg = m.groupdict() | ||||
| 
 | ||||
|         info['type'] = 'ring' | ||||
|         if mg.get('TOUR'): | ||||
|             info['type'] = 'tour' | ||||
|         elif mg.get('RING'): | ||||
|             info['type'] = 'ring' | ||||
| 
 | ||||
|         info['currency'] = 'EUR' | ||||
| 
 | ||||
|         if 'LIMIT' in mg: | ||||
|  | @ -202,11 +220,62 @@ class Winamax(HandHistoryConverter): | |||
|                 hand.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") # also timezone at end, e.g. " ET" | ||||
|                 hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, "CET", "UTC") | ||||
|             if key == 'HID1': | ||||
|                 hand.handid = "1%.4d%s%s"%(int(info['HID2']),info['HID1'],info['HID3']) | ||||
|                 # Need to remove non-alphanumerics for MySQL | ||||
|                 hand.handid = "1%.9d%s%s"%(int(info['HID2']),info['HID1'],info['HID3']) | ||||
|             if key == 'TOURNO': | ||||
|                 hand.tourNo = info[key] | ||||
|             if key == 'TABLE': | ||||
|                 hand.tablename = info[key] | ||||
| 
 | ||||
|             if key == 'BUYIN': | ||||
|                 if hand.tourNo!=None: | ||||
|                     #print "DEBUG: info['BUYIN']: %s" % info['BUYIN'] | ||||
|                     #print "DEBUG: info['BIAMT']: %s" % info['BIAMT'] | ||||
|                     #print "DEBUG: info['BIRAKE']: %s" % info['BIRAKE'] | ||||
|                     #print "DEBUG: info['BOUNTY']: %s" % info['BOUNTY'] | ||||
|                     for k in ['BIAMT','BIRAKE']: | ||||
|                         if k in info.keys() and info[k]: | ||||
|                             info[k] = info[k].replace(',','.') | ||||
| 
 | ||||
|                     if info[key] == 'Freeroll': | ||||
|                         hand.buyin = 0 | ||||
|                         hand.fee = 0 | ||||
|                         hand.buyinCurrency = "FREE" | ||||
|                     else: | ||||
|                         if info[key].find("$")!=-1: | ||||
|                             hand.buyinCurrency="USD" | ||||
|                         elif info[key].find(u"€")!=-1: | ||||
|                             hand.buyinCurrency="EUR" | ||||
|                         elif info[key].find("FPP")!=-1: | ||||
|                             hand.buyinCurrency="PSFP" | ||||
|                         else: | ||||
|                             #FIXME: handle other currencies, FPP, play money | ||||
|                             raise FpdbParseError(_("failed to detect currency")) | ||||
| 
 | ||||
|                         info['BIAMT'] = info['BIAMT'].strip(u'$€FPP') | ||||
| 
 | ||||
|                         if hand.buyinCurrency!="PSFP": | ||||
|                             if info['BOUNTY'] != None: | ||||
|                                 # There is a bounty, Which means we need to switch BOUNTY and BIRAKE values | ||||
|                                 tmp = info['BOUNTY'] | ||||
|                                 info['BOUNTY'] = info['BIRAKE'] | ||||
|                                 info['BIRAKE'] = tmp | ||||
|                                 info['BOUNTY'] = info['BOUNTY'].strip(u'$€') # Strip here where it isn't 'None' | ||||
|                                 hand.koBounty = int(100*Decimal(info['BOUNTY'])) | ||||
|                                 hand.isKO = True | ||||
|                             else: | ||||
|                                 hand.isKO = False | ||||
| 
 | ||||
|                             info['BIRAKE'] = info['BIRAKE'].strip(u'$€') | ||||
|                             hand.buyin = int(100*Decimal(info['BIAMT'])) | ||||
|                             hand.fee = int(100*Decimal(info['BIRAKE'])) | ||||
|                         else: | ||||
|                             hand.buyin = int(Decimal(info['BIAMT'])) | ||||
|                             hand.fee = 0 | ||||
| 
 | ||||
|             if key == 'LEVEL': | ||||
|                 hand.level = info[key] | ||||
| 
 | ||||
|         # TODO: These | ||||
|         hand.buttonpos = 1 | ||||
|         hand.maxseats = 10    # Set to None - Hand.py will guessMaxSeats() | ||||
|  |  | |||
|  | @ -116,6 +116,7 @@ import GuiAutoImport | |||
| import GuiGraphViewer | ||||
| import GuiTourneyGraphViewer | ||||
| import GuiSessionViewer | ||||
| import GuiStove | ||||
| import SQL | ||||
| import Database | ||||
| import Configuration | ||||
|  | @ -778,6 +779,7 @@ class fpdb: | |||
|                   <menuitem action="tourneyviewer"/> | ||||
|                   <menuitem action="posnstats"/> | ||||
|                   <menuitem action="sessionstats"/> | ||||
|                   <menuitem action="stove"/> | ||||
|                 </menu> | ||||
|                 <menu action="database"> | ||||
|                   <menuitem action="maintaindbs"/> | ||||
|  | @ -814,6 +816,7 @@ class fpdb: | |||
|                                  ('hudConfigurator', None, _('_HUD Configurator'), _('<control>H'), 'HUD Configurator', self.diaHudConfigurator), | ||||
|                                  ('graphs', None, _('_Graphs'), _('<control>G'), 'Graphs', self.tabGraphViewer), | ||||
|                                  ('tourneygraphs', None, _('Tourney Graphs'), None, 'TourneyGraphs', self.tabTourneyGraphViewer), | ||||
|                                  ('stove', None, _('Stove'), None, 'Stove', self.tabStove), | ||||
|                                  ('ringplayerstats', None, _('Ring _Player Stats (tabulated view, not on pgsql)'), _('<control>P'), 'Ring Player Stats (tabulated view, not on pgsql)', self.tab_ring_player_stats), | ||||
|                                  ('tourneyplayerstats', None, _('_Tourney Stats (tabulated view, not on pgsql)'), _('<control>T'), 'Tourney Stats (tabulated view, not on pgsql)', self.tab_tourney_player_stats), | ||||
|                                  ('tourneyviewer', None, _('Tourney _Viewer'), None, 'Tourney Viewer)', self.tab_tourney_viewer_stats), | ||||
|  | @ -1000,7 +1003,7 @@ class fpdb: | |||
|         self.add_and_display_tab(bulk_tab, _("Bulk Import")) | ||||
| 
 | ||||
|     def tab_tourney_import(self, widget, data=None): | ||||
|         """opens a tab for bulk importing""" | ||||
|         """opens a tab for bulk importing tournament summaries""" | ||||
|         new_import_thread = GuiTourneyImport.GuiTourneyImport(self.settings, self.config, self.sql, self.window) | ||||
|         self.threads.append(new_import_thread) | ||||
|         bulk_tab=new_import_thread.get_vbox() | ||||
|  | @ -1078,6 +1081,13 @@ You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt, gpl-3.0.txt an | |||
|         gv_tab = new_gv_thread.get_vbox() | ||||
|         self.add_and_display_tab(gv_tab, _("Tourney Graphs")) | ||||
| 
 | ||||
|     def tabStove(self, widget, data=None): | ||||
|         """opens a tab for bulk importing tournament summaries""" | ||||
|         thread = GuiStove.GuiStove(self.config, self.window) | ||||
|         self.threads.append(thread) | ||||
|         tab = thread.get_vbox() | ||||
|         self.add_and_display_tab(tab, _("Stove")) | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         # no more than 1 process can this lock at a time: | ||||
|         self.lock = interlocks.InterProcessLock(name="fpdb_global_lock") | ||||
|  |  | |||
							
								
								
									
										2
									
								
								pyfpdb/interlocks.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										2
									
								
								pyfpdb/interlocks.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							|  | @ -108,7 +108,7 @@ class InterProcessLockFcntl(InterProcessLockBase): | |||
|         self.lockfd = 0 | ||||
|         try: | ||||
|             os.unlink(self.lock_file_name) | ||||
|         except IOError: | ||||
|         except OSError: | ||||
|             # We don't care about the existence of the file too much here.  It's the flock() we care about, | ||||
|             # And that should just go away magically. | ||||
|             pass | ||||
|  |  | |||
|  | @ -0,0 +1,42 @@ | |||
| PokerStars Game #2428142447:  Hold'em Limit ($1/$2 USD) - 2005/08/26 16:12:22 ET | ||||
| Table 'Teucer II' Seat #5 is the button | ||||
| Seat 1: Frankson34 ($24 in chips)  | ||||
| Seat 2: webb22 ($64 in chips)  | ||||
| Seat 3: eric_mtx ($26 in chips)  | ||||
| Seat 4: sososolid ($147.75 in chips)  | ||||
| Seat 5: DRILHER ($48.25 in chips)  | ||||
| Seat 6: Naughtychic ($60 in chips)  | ||||
| Seat 7: Terps78 ($71.50 in chips)  | ||||
| Seat 8: ChazDazzle ($69.25 in chips)  | ||||
| Seat 9: alekos ($55 in chips)  | ||||
| Seat 10: BigNards84 ($64.25 in chips)  | ||||
| Naughtychic: posts small blind $0.50 | ||||
| Terps78: posts big blind $1 | ||||
| *** HOLE CARDS *** | ||||
| Dealt to ChazDazzle [8c Kd] | ||||
| ChazDazzle: folds  | ||||
| alekos: folds  | ||||
| BigNards84: raises $1 to $2 | ||||
| Frankson34: folds  | ||||
| webb22: folds  | ||||
| eric_mtx: folds  | ||||
| ChazDazzle leaves the table | ||||
| sososolid: folds  | ||||
| DRILHER: folds  | ||||
| cdhender joins the table at seat #8  | ||||
| Naughtychic: folds  | ||||
| Terps78: folds  | ||||
| BigNards84 collected $2.50 from pot | ||||
| BigNards84: doesn't show hand  | ||||
| *** SUMMARY *** | ||||
| Total pot $2.50 | Rake $0  | ||||
| Seat 1: Frankson34 folded before Flop (didn't bet) | ||||
| Seat 2: webb22 folded before Flop (didn't bet) | ||||
| Seat 3: eric_mtx folded before Flop (didn't bet) | ||||
| Seat 4: sososolid folded before Flop (didn't bet) | ||||
| Seat 5: DRILHER (button) folded before Flop (didn't bet) | ||||
| Seat 6: Naughtychic (small blind) folded before Flop | ||||
| Seat 7: Terps78 (big blind) folded before Flop | ||||
| Seat 8: ChazDazzle folded before Flop (didn't bet) | ||||
| Seat 9: alekos folded before Flop (didn't bet) | ||||
| Seat 10: BigNards84 collected ($2.50) | ||||
										
											Binary file not shown.
										
									
								
							|  | @ -0,0 +1,310 @@ | |||
| Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 0 - HandId: #7959970263859201-1-1288800933 - Holdem no limit (10/20) - 2010/11/03 17:15:33 UTC | ||||
| Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #3 is the button | ||||
| Seat 1: Player6 (1500) | ||||
| Seat 2: Player3 (1500) | ||||
| Seat 3: Player9 (1500) | ||||
| Seat 4: Player1 (1500) | ||||
| Seat 5: Player0 (1500) | ||||
| Seat 6: Player7 (1500) | ||||
| Seat 7: Player4 (1500) | ||||
| Seat 8: Player2 (1500) | ||||
| Seat 9: Player5 (1500) | ||||
| Seat 10: Player8 (1500) | ||||
| *** ANTE/BLINDS ***  | ||||
| Player1 posts small blind 10 | ||||
| Player0 posts big blind 20 | ||||
| Dealt to Player6 [Jd 7h] | ||||
| *** PRE-FLOP ***  | ||||
| Player7 folds | ||||
| Player4 folds | ||||
| Player2 folds | ||||
| Player5 calls 20 | ||||
| Player8 folds | ||||
| Player6 calls 20 | ||||
| Player3 calls 20 | ||||
| Player9 calls 20 | ||||
| Player1 calls 10 | ||||
| Player0 checks | ||||
| *** FLOP *** [Td 4c 5h] | ||||
| Player1 checks | ||||
| Player0 checks | ||||
| Player5 checks | ||||
| Player6 bets 80 | ||||
| Player3 calls 80 | ||||
| Player9 folds | ||||
| Player1 folds | ||||
| Player0 calls 80 | ||||
| Player5 folds | ||||
| *** TURN *** [Td 4c 5h][3h] | ||||
| Player0 checks | ||||
| Player6 checks | ||||
| Player3 checks | ||||
| *** RIVER *** [Td 4c 5h 3h][Kc] | ||||
| Player0 checks | ||||
| Player6 bets 240 | ||||
| Player3 calls 240 | ||||
| Player0 folds | ||||
| *** SHOW DOWN *** | ||||
| Player6 shows [Jd 7h] (High card : King) | ||||
| Player3 shows [Kd 4d] (Two pairs : Kings and 4) | ||||
| Player3 collected 840 from pot | ||||
| *** SUMMARY *** | ||||
| Total pot 840 | No rake | ||||
| Board: [Td 4c 5h 3h Kc] | ||||
| Seat 1: Player6 showed [Jd 7h] and lost with High card : King | ||||
| Seat 2: Player3 showed [Kd 4d] and won 840 with Two pairs : Kings and 4 | ||||
| Seat 3: Player9 (button) folded on the flop | ||||
| Seat 4: Player1 (small blind) folded on the flop | ||||
| Seat 5: Player0 (big blind) folded on the river | ||||
| Seat 6: Player7 folded on the pre-flop | ||||
| Seat 7: Player4 folded | ||||
| Seat 8: Player2 folded on the pre-flop | ||||
| Seat 9: Player5 folded on the flop | ||||
| Seat 10: Player8 folded on the pre-flop | ||||
| 
 | ||||
| 
 | ||||
| Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 0 - HandId: #7959970263859201-2-1288801071 - Holdem no limit (10/20) - 2010/11/03 17:17:51 UTC | ||||
| Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #4 is the button | ||||
| Seat 1: Player6 (1160) | ||||
| Seat 2: Player3 (2000) | ||||
| Seat 3: Player9 (1480) | ||||
| Seat 4: Player1 (1480) | ||||
| Seat 5: Player0 (1400) | ||||
| Seat 6: Player7 (1500) | ||||
| Seat 7: Player4 (1500) | ||||
| Seat 8: Player2 (1500) | ||||
| Seat 9: Player5 (1480) | ||||
| Seat 10: Player8 (1500) | ||||
| *** ANTE/BLINDS ***  | ||||
| Player0 posts small blind 10 | ||||
| Player7 posts big blind 20 | ||||
| Dealt to Player6 [7h 3s] | ||||
| *** PRE-FLOP ***  | ||||
| Player4 folds | ||||
| Player2 folds | ||||
| Player5 calls 20 | ||||
| Player8 calls 20 | ||||
| Player6 folds | ||||
| Player3 calls 20 | ||||
| Player9 folds | ||||
| Player1 calls 20 | ||||
| Player0 calls 10 | ||||
| Player7 checks | ||||
| *** FLOP *** [Jh 6h Qd] | ||||
| Player0 checks | ||||
| Player7 bets 20 | ||||
| Player5 calls 20 | ||||
| Player8 calls 20 | ||||
| Player3 folds | ||||
| Player1 calls 20 | ||||
| Player0 calls 20 | ||||
| *** TURN *** [Jh 6h Qd][5s] | ||||
| Player0 checks | ||||
| Player7 checks | ||||
| Player5 bets 220 | ||||
| Player8 folds | ||||
| Player1 folds | ||||
| Player0 folds | ||||
| Player7 calls 220 | ||||
| *** RIVER *** [Jh 6h Qd 5s][3c] | ||||
| Player7 checks | ||||
| Player5 bets 660 | ||||
| Player7 folds | ||||
| Player5 collected 1320 from pot | ||||
| *** SUMMARY *** | ||||
| Total pot 1.32k | No rake | ||||
| Board: [Jh 6h Qd 5s 3c] | ||||
| Seat 1: Player6 folded on the pre-flop | ||||
| Seat 2: Player3 folded on the flop | ||||
| Seat 3: Player9 folded on the pre-flop | ||||
| Seat 4: Player1 (button) folded on the turn | ||||
| Seat 5: Player0 (small blind) folded on the turn | ||||
| Seat 6: Player7 (big blind) folded on the river | ||||
| Seat 7: Player4 folded on the pre-flop | ||||
| Seat 8: Player2 folded on the pre-flop | ||||
| Seat 9: Player5 won 1320 | ||||
| Seat 10: Player8 folded on the turn | ||||
| 
 | ||||
| 
 | ||||
| Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 0 - HandId: #7959970263859201-3-1288801160 - Holdem no limit (10/20) - 2010/11/03 17:19:20 UTC | ||||
| Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #5 is the button | ||||
| Seat 1: Player6 (1160) | ||||
| Seat 2: Player3 (1980) | ||||
| Seat 3: Player9 (1480) | ||||
| Seat 4: Player1 (1440) | ||||
| Seat 5: Player0 (1360) | ||||
| Seat 6: Player7 (1240) | ||||
| Seat 7: Player4 (1500) | ||||
| Seat 8: Player2 (1500) | ||||
| Seat 9: Player5 (1880) | ||||
| Seat 10: Player8 (1460) | ||||
| *** ANTE/BLINDS ***  | ||||
| Player7 posts small blind 10 | ||||
| Player4 posts big blind 20 | ||||
| Dealt to Player6 [4h 3d] | ||||
| *** PRE-FLOP ***  | ||||
| Player2 folds | ||||
| Player5 calls 20 | ||||
| Player8 calls 20 | ||||
| Player6 folds | ||||
| Player3 folds | ||||
| Player9 folds | ||||
| Player1 calls 20 | ||||
| Player0 folds | ||||
| Player7 raises 20 to 40 | ||||
| Player4 folds | ||||
| Player5 calls 20 | ||||
| Player8 calls 20 | ||||
| Player1 calls 20 | ||||
| *** FLOP *** [Qd Kh 4s] | ||||
| Player7 bets 1200 and is all-in | ||||
| Player5 folds | ||||
| Player8 folds | ||||
| Player1 folds | ||||
| Player7 collected 1380 from pot | ||||
| *** SUMMARY *** | ||||
| Total pot 1.38k | No rake | ||||
| Board: [Qd Kh 4s] | ||||
| Seat 1: Player6 folded on the pre-flop | ||||
| Seat 2: Player3 folded on the pre-flop | ||||
| Seat 3: Player9 folded on the pre-flop | ||||
| Seat 4: Player1 folded on the flop | ||||
| Seat 5: Player0 (button) folded on the pre-flop | ||||
| Seat 6: Player7 (small blind) won 1380 | ||||
| Seat 7: Player4 (big blind) folded on the pre-flop | ||||
| Seat 8: Player2 folded on the pre-flop | ||||
| Seat 9: Player5 folded on the flop | ||||
| Seat 10: Player8 folded on the flop | ||||
| 
 | ||||
| 
 | ||||
| Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 0 - HandId: #7959970263859201-4-1288801277 - Holdem no limit (10/20) - 2010/11/03 17:21:17 UTC | ||||
| Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #6 is the button | ||||
| Seat 1: Player6 (1160) | ||||
| Seat 2: Player3 (1980) | ||||
| Seat 3: Player9 (1480) | ||||
| Seat 4: Player1 (1400) | ||||
| Seat 5: Player0 (1360) | ||||
| Seat 6: Player7 (1380) | ||||
| Seat 7: Player4 (1480) | ||||
| Seat 8: Player2 (1500) | ||||
| Seat 9: Player5 (1840) | ||||
| Seat 10: Player8 (1420) | ||||
| *** ANTE/BLINDS ***  | ||||
| Player4 posts small blind 10 | ||||
| Player2 posts big blind 20 | ||||
| Dealt to Player6 [Qc 7d] | ||||
| *** PRE-FLOP ***  | ||||
| Player5 calls 20 | ||||
| Player8 folds | ||||
| Player6 folds | ||||
| Player3 folds | ||||
| Player9 folds | ||||
| Player1 calls 20 | ||||
| Player0 folds | ||||
| Player7 calls 20 | ||||
| Player4 calls 10 | ||||
| Player2 checks | ||||
| *** FLOP *** [9s 7h 5h] | ||||
| Player4 checks | ||||
| Player2 checks | ||||
| Player5 checks | ||||
| Player1 checks | ||||
| Player7 checks | ||||
| *** TURN *** [9s 7h 5h][Ts] | ||||
| Player4 checks | ||||
| Player2 checks | ||||
| Player5 checks | ||||
| Player1 checks | ||||
| Player7 bets 20 | ||||
| Player4 calls 20 | ||||
| Player2 folds | ||||
| Player5 folds | ||||
| Player1 calls 20 | ||||
| *** RIVER *** [9s 7h 5h Ts][7s] | ||||
| Player4 checks | ||||
| Player1 checks | ||||
| Player7 bets 160 | ||||
| Player4 folds | ||||
| Player1 calls 160 | ||||
| *** SHOW DOWN *** | ||||
| Player1 shows [4c 4d] (Two pairs : 7 and 4) | ||||
| Player7 shows [4s As] (Flush Ace high) | ||||
| Player7 collected 480 from pot | ||||
| *** SUMMARY *** | ||||
| Total pot 480 | No rake | ||||
| Board: [9s 7h 5h Ts 7s] | ||||
| Seat 1: Player6 folded on the pre-flop | ||||
| Seat 2: Player3 folded on the pre-flop | ||||
| Seat 3: Player9 folded on the pre-flop | ||||
| Seat 4: Player1 showed [4c 4d] and lost with Two pairs : 7 and 4 | ||||
| Seat 5: Player0 folded on the pre-flop | ||||
| Seat 6: Player7 (button) showed [4s As] and won 480 with Flush Ace high | ||||
| Seat 7: Player4 (small blind) folded on the river | ||||
| Seat 8: Player2 (big blind) folded on the turn | ||||
| Seat 9: Player5 folded on the turn | ||||
| Seat 10: Player8 folded on the pre-flop | ||||
| 
 | ||||
| 
 | ||||
| Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 1 - HandId: #7959970263859201-5-1288801360 - Holdem no limit (10/20) - 2010/11/03 17:22:40 UTC | ||||
| Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #7 is the button | ||||
| Seat 1: Player6 (1160) | ||||
| Seat 2: Player3 (1980) | ||||
| Seat 3: Player9 (1480) | ||||
| Seat 4: Player1 (1200) | ||||
| Seat 5: Player0 (1360) | ||||
| Seat 6: Player7 (1660) | ||||
| Seat 7: Player4 (1440) | ||||
| Seat 8: Player2 (1480) | ||||
| Seat 9: Player5 (1820) | ||||
| Seat 10: Player8 (1420) | ||||
| *** ANTE/BLINDS ***  | ||||
| Player2 posts small blind 10 | ||||
| Player5 posts big blind 20 | ||||
| Dealt to Player6 [Kd Ah] | ||||
| *** PRE-FLOP ***  | ||||
| Player8 calls 20 | ||||
| Player6 raises 70 to 90 | ||||
| Player3 folds | ||||
| Player9 calls 90 | ||||
| Player1 calls 90 | ||||
| Player0 calls 90 | ||||
| Player7 calls 90 | ||||
| Player4 calls 90 | ||||
| Player2 folds | ||||
| Player5 calls 70 | ||||
| Player8 calls 70 | ||||
| *** FLOP *** [2s 5h 3h] | ||||
| Player5 checks | ||||
| Player8 checks | ||||
| Player6 bets 365 | ||||
| Player9 folds | ||||
| Player1 folds | ||||
| Player0 folds | ||||
| Player7 calls 365 | ||||
| Player4 folds | ||||
| Player5 folds | ||||
| Player8 folds | ||||
| *** TURN *** [2s 5h 3h][6d] | ||||
| Player6 bets 705 and is all-in | ||||
| Player7 calls 705 | ||||
| *** RIVER *** [2s 5h 3h 6d][5s] | ||||
| *** SHOW DOWN *** | ||||
| Player6 shows [Kd Ah] (One pair : 5) | ||||
| Player7 shows [7d 7h] (Two pairs : 7 and 5) | ||||
| Player7 collected 2870 from pot | ||||
| *** SUMMARY *** | ||||
| Total pot 2.87k | No rake | ||||
| Board: [2s 5h 3h 6d 5s] | ||||
| Seat 1: Player6 showed [Kd Ah] and lost with One pair : 5 | ||||
| Seat 2: Player3 folded on the pre-flop | ||||
| Seat 3: Player9 folded on the flop | ||||
| Seat 4: Player1 folded on the flop | ||||
| Seat 5: Player0 folded on the flop | ||||
| Seat 6: Player7 showed [7d 7h] and won 2870 with Two pairs : 7 and 5 | ||||
| Seat 7: Player4 (button) folded on the flop | ||||
| Seat 8: Player2 (small blind) folded on the pre-flop | ||||
| Seat 9: Player5 (big blind) folded on the flop | ||||
| Seat 10: Player8 folded on the flop | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user