diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index fa23f1cd..89d3d630 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -1694,11 +1694,15 @@ class Database: def storeHand(self, p, printdata = False): if printdata: - print "######## Hands ##########" + print _("######## Hands ##########") import pprint pp = pprint.PrettyPrinter(indent=4) pp.pprint(p) - print "###### End Hands ########" + print _("###### End Hands ########") + + # Tablename can have odd charachers + p['tableName'] = Charset.to_db_utf8(p['tableName']) + #stores into table hands: q = self.sql.query['store_hand'] diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 487cb12d..955b55b9 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -37,7 +37,8 @@ class Fulltilt(HandHistoryConverter): substitutions = { 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes 'LS' : u"\$|\u20AC|\xe2\x82\xac|", # legal currency symbols - Euro(cp1252, utf-8) - 'TAB' : u"-\u2013\s\da-zA-Z" + 'TAB' : u"-\u2013'\s\da-zA-Z", # legal characters for tablename + 'NUM' : u".,\d", # legal characters in number format } # Static regexes @@ -45,10 +46,10 @@ class Fulltilt(HandHistoryConverter): (?:(?P.+)\s\((?P\d+)\),\s)? .+ -\s(?P[%(LS)s]|)? - (?P[.0-9]+)/ - [%(LS)s]?(?P[.0-9]+)\s - (Ante\s\$?(?P[.0-9]+)\s)?-\s - [%(LS)s]?(?P[.0-9]+\sCap\s)? + (?P[%(NUM)s]+)/ + [%(LS)s]?(?P[%(NUM)s]+)\s + (Ante\s\$?(?P[%(NUM)s]+)\s)?-\s + [%(LS)s]?(?P[%(NUM)s]+\sCap\s)? (?P(No\sLimit|Pot\sLimit|Limit))?\s (?P(Hold\'em|Omaha\sHi|Omaha\sH/L|7\sCard\sStud|Stud\sH/L|Razz|Stud\sHi|2-7\sTriple\sDraw|5\sCard\sDraw|Badugi)) ''' % substitutions, re.VERBOSE) @@ -60,7 +61,7 @@ class Fulltilt(HandHistoryConverter): (?PPlay\sChip\s|PC)? (?P[%(TAB)s]+)\s (\((?P.+)\)\s)?-\s - [%(LS)s]?(?P[.0-9]+)/[%(LS)s]?(?P[.0-9]+)\s(Ante\s[%(LS)s]?(?P[.0-9]+)\s)?-\s + [%(LS)s]?(?P[%(NUM)s]+)/[%(LS)s]?(?P[%(NUM)s]+)\s(Ante\s[%(LS)s]?(?P[.0-9]+)\s)?-\s [%(LS)s]?(?P[.0-9]+\sCap\s)? (?P[-\da-zA-Z\/\'\s]+)\s-\s (?P.*$) @@ -140,16 +141,16 @@ class Fulltilt(HandHistoryConverter): self.substitutions['PLAYERS'] = player_re logging.debug("player_re: " + player_re) - self.re_PostSB = re.compile(r"^%(PLAYERS)s posts the small blind of [%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_PostDead = re.compile(r"^%(PLAYERS)s posts a dead small blind of [%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_PostBB = re.compile(r"^%(PLAYERS)s posts (the big blind of )?[%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_Antes = re.compile(r"^%(PLAYERS)s antes [%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_BringIn = re.compile(r"^%(PLAYERS)s brings in for [%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_PostBoth = re.compile(r"^%(PLAYERS)s posts small \& big blinds \[[%(LS)s]? (?P[.0-9]+)" % self.substitutions, re.MULTILINE) + self.re_PostSB = re.compile(r"^%(PLAYERS)s posts the small blind of [%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_PostDead = re.compile(r"^%(PLAYERS)s posts a dead small blind of [%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_PostBB = re.compile(r"^%(PLAYERS)s posts (the big blind of )?[%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_Antes = re.compile(r"^%(PLAYERS)s antes [%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_BringIn = re.compile(r"^%(PLAYERS)s brings in for [%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_PostBoth = re.compile(r"^%(PLAYERS)s posts small \& big blinds \[[%(LS)s]? (?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) self.re_HeroCards = re.compile(r"^Dealt to %s(?: \[(?P.+?)\])?( \[(?P.+?)\])" % player_re, re.MULTILINE) - self.re_Action = re.compile(r"^%(PLAYERS)s(?P bets| checks| raises to| completes it to| calls| folds)( [%(LS)s]?(?P[.,\d]+))?" % self.substitutions, re.MULTILINE) + self.re_Action = re.compile(r"^%(PLAYERS)s(?P bets| checks| raises to| completes it to| calls| folds)( [%(LS)s]?(?P[%(NUM)s]+))?" % self.substitutions, re.MULTILINE) self.re_ShowdownAction = re.compile(r"^%s shows \[(?P.*)\]" % player_re, re.MULTILINE) - self.re_CollectPot = re.compile(r"^Seat (?P[0-9]+): %(PLAYERS)s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \([%(LS)s]?(?P[.,\d]+)\)(, mucked| with.*)" % self.substitutions, re.MULTILINE) + self.re_CollectPot = re.compile(r"^Seat (?P[0-9]+): %(PLAYERS)s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \([%(LS)s]?(?P[%(NUM)s]+)\)(, mucked| with.*)" % self.substitutions, re.MULTILINE) self.re_SitsOut = re.compile(r"^%s sits out" % player_re, re.MULTILINE) self.re_ShownCards = re.compile(r"^Seat (?P[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(?Pshowed|mucked) \[(?P.*)\].*" % player_re, re.MULTILINE) @@ -206,8 +207,8 @@ class Fulltilt(HandHistoryConverter): info['limitType'] = 'cn' else: info['limitType'] = limits[mg['LIMIT']] - info['sb'] = mg['SB'] - info['bb'] = mg['BB'] + info['sb'] = self.clearMoneyString(mg['SB']) + info['bb'] = self.clearMoneyString(mg['BB']) if mg['GAME'] is not None: (info['base'], info['category']) = games[mg['GAME']] if mg['CURRENCY'] is not None: @@ -339,15 +340,15 @@ class Fulltilt(HandHistoryConverter): def readBlinds(self, hand): try: m = self.re_PostSB.search(hand.handText) - hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB')) + hand.addBlind(m.group('PNAME'), 'small blind', self.clearMoneyString(m.group('SB'))) except: # no small blind hand.addBlind(None, None, None) for a in self.re_PostDead.finditer(hand.handText): - hand.addBlind(a.group('PNAME'), 'secondsb', a.group('SB')) + hand.addBlind(a.group('PNAME'), 'secondsb', self.clearMoneyString(a.group('SB'))) for a in self.re_PostBB.finditer(hand.handText): - hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB')) + hand.addBlind(a.group('PNAME'), 'big blind', self.clearMoneyString(a.group('BB'))) for a in self.re_PostBoth.finditer(hand.handText): - hand.addBlind(a.group('PNAME'), 'small & big blinds', a.group('SBBB')) + hand.addBlind(a.group('PNAME'), 'small & big blinds', self.clearMoneyString(a.group('SBBB'))) def readAntes(self, hand): logging.debug(_("reading antes")) @@ -528,10 +529,10 @@ class Fulltilt(HandHistoryConverter): # Additional info can be stored in the tourney object if mg['BUYIN'] is not None: - tourney.buyin = 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) + tourney.buyin = 100*Decimal(self.clearMoneyString(mg['BUYIN'])) tourney.fee = 0 if mg['FEE'] is not None: - tourney.fee = 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) + tourney.fee = 100*Decimal(self.clearMoneyString(mg['FEE'])) if mg['TOURNAMENT_NAME'] is not None: # Tournament Name can have a trailing space at the end (depending on the tournament description) tourney.tourneyName = mg['TOURNAMENT_NAME'].rstrip() @@ -575,25 +576,25 @@ class Fulltilt(HandHistoryConverter): mg = m.groupdict() if tourney.isMatrix : if mg['BUYIN'] is not None: - tourney.subTourneyBuyin = 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) + tourney.subTourneyBuyin = 100*Decimal(self.clearMoneyString(mg['BUYIN'])) tourney.subTourneyFee = 0 if mg['FEE'] is not None: - tourney.subTourneyFee = 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) + tourney.subTourneyFee = 100*Decimal(self.clearMoneyString(mg['FEE'])) else : if mg['BUYIN'] is not None: if tourney.buyin is None: - tourney.buyin = 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) + tourney.buyin = 100*Decimal(clearMoneyString(mg['BUYIN'])) else : - if 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) != tourney.buyin: + if 100*Decimal(clearMoneyString(mg['BUYIN'])) != tourney.buyin: log.error(_("Conflict between buyins read in topline (%s) and in BuyIn field (%s)") % (tourney.buyin, 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN']))) ) - tourney.subTourneyBuyin = 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) + tourney.subTourneyBuyin = 100*Decimal(clearMoneyString(mg['BUYIN'])) if mg['FEE'] is not None: if tourney.fee is None: - tourney.fee = 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) + tourney.fee = 100*Decimal(clearMoneyString(mg['FEE'])) else : - if 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) != tourney.fee: - log.error(_("Conflict between fees read in topline (%s) and in BuyIn field (%s)") % (tourney.fee, 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE']))) ) - tourney.subTourneyFee = 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) + if 100*Decimal(clearMoneyString(mg['FEE'])) != tourney.fee: + log.error(_("Conflict between fees read in topline (%s) and in BuyIn field (%s)") % (tourney.fee, 100*Decimal(clearMoneyString(mg['FEE']))) ) + tourney.subTourneyFee = 100*Decimal(clearMoneyString(mg['FEE'])) if tourney.buyin is None: log.info(_("Unable to affect a buyin to this tournament : assume it's a freeroll")) @@ -662,10 +663,10 @@ class Fulltilt(HandHistoryConverter): tourney.koCounts.update( { tourney.hero : Decimal(mg['COUNT_KO']) } ) # Deal with money amounts - tourney.koBounty = 100*Decimal(re.sub(u',', u'', "%s" % tourney.koBounty)) - tourney.prizepool = 100*Decimal(re.sub(u',', u'', "%s" % tourney.prizepool)) - tourney.rebuyCost = 100*Decimal(re.sub(u',', u'', "%s" % tourney.rebuyCost)) - tourney.addOnCost = 100*Decimal(re.sub(u',', u'', "%s" % tourney.addOnCost)) + tourney.koBounty = 100*Decimal(clearMoneyString(tourney.koBounty)) + tourney.prizepool = 100*Decimal(clearMoneyString(tourney.prizepool)) + tourney.rebuyCost = 100*Decimal(clearMoneyString(tourney.rebuyCost)) + tourney.addOnCost = 100*Decimal(clearMoneyString(tourney.addOnCost)) # Calculate payin amounts and update winnings -- not possible to take into account nb of rebuys, addons or Knockouts for other players than hero on FTP for p in tourney.players : @@ -691,7 +692,7 @@ class Fulltilt(HandHistoryConverter): rank = Decimal(a.group('RANK')) if a.group('WINNING') is not None: - winnings = 100*Decimal(re.sub(u',', u'', "%s" % a.group('WINNING'))) + winnings = 100*Decimal(clearMoneyString(a.group('WINNING'))) else: winnings = "0" diff --git a/pyfpdb/GuiReplayer.py b/pyfpdb/GuiReplayer.py index bc29090c..ba5a985e 100644 --- a/pyfpdb/GuiReplayer.py +++ b/pyfpdb/GuiReplayer.py @@ -118,11 +118,11 @@ class GuiReplayer: self.table[i]={"name":self.MyHand.players[i][1],"stack":Decimal(self.MyHand.players[i][2]),"x":x,"y":y,"chips":0,"status":"live"} #save coordinates of each player try: self.table[i]['holecards']=self.MyHand.holecards["PREFLOP"][self.MyHand.players[i][1]][1]+' '+self.MyHand.holecards["PREFLOP"][self.MyHand.players[i][1]][2] - print "holecards",self.table[i]['holecards'] + print "holecards: ",self.table[i]['holecards'] except: self.table[i]['holecards']='' except IndexError: #if seat is empty - print "seat",i+1,"out of",self.maxseats,"empty" + print "seat ",i+1," out of ",self.maxseats," empty" self.actions=[] #create list with all actions @@ -236,7 +236,7 @@ class GuiReplayer: rect = gtk.gdk.Rectangle(270,270,100,50) self.area.window.invalidate_rect(rect, True) #refresh pot area self.area.window.process_updates(True) - print "draw action",self.action_number,self.actions[self.action_number][1],self.actions[self.action_number][2],self.actions[self.action_number][3] + print "draw action: ",self.action_number,self.actions[self.action_number][1],self.actions[self.action_number][2],self.actions[self.action_number][3] return True diff --git a/pyfpdb/GuiSessionViewer.py b/pyfpdb/GuiSessionViewer.py index 466f8d9b..8a85fd30 100644 --- a/pyfpdb/GuiSessionViewer.py +++ b/pyfpdb/GuiSessionViewer.py @@ -155,15 +155,10 @@ 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 -""" + warning_string = _("Session Viewer is proof of concept code only, and contains many bugs.\n") + warning_string += _("Feel free to use the viewer, but there is no guarantee that the data is accurate.\n") + warning_string += _("If you are interested in developing the code further please contact us via the usual channels.\n") + warning_string += _("Thankyou") self.warning_box(warning_string) def warning_box(self, str, diatitle=_("FPDB WARNING")): diff --git a/pyfpdb/GuiStove.py b/pyfpdb/GuiStove.py index f238e503..b600c81e 100644 --- a/pyfpdb/GuiStove.py +++ b/pyfpdb/GuiStove.py @@ -54,15 +54,10 @@ class GuiStove(): 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 -""") + warning_string = _("Stove is a GUI mockup of a EV calculation page, and completely non functional.\n") + warning_string = _("Unless you are interested in developing this feature, please ignore this page.\n") + warning_string = _("If you are interested in developing the code further see GuiStove.py and Stove.py\n") + warning_string = _("Thank you\n") self.warning_box(warning_string) diff --git a/pyfpdb/HUD_config.test.xml b/pyfpdb/HUD_config.test.xml index cfad09c5..7ce84651 100644 --- a/pyfpdb/HUD_config.test.xml +++ b/pyfpdb/HUD_config.test.xml @@ -581,6 +581,7 @@ Left-Drag to Move" + diff --git a/pyfpdb/HUD_main.pyw b/pyfpdb/HUD_main.pyw index 4a8f46ed..4a8cbc0d 100755 --- a/pyfpdb/HUD_main.pyw +++ b/pyfpdb/HUD_main.pyw @@ -323,7 +323,7 @@ def idle_resize(hud): [aw.update_card_positions() for aw in hud.aux_windows] hud.resize_windows() except: - log.exception("Error resizing HUD for table: %s." % hud.table.title) + log.exception(_("Error resizing HUD for table: %s.") % hud.table.title) finally: gtk.gdk.threads_leave() @@ -337,7 +337,7 @@ def idle_kill(hud_main, table): del(hud_main.hud_dict[table]) hud_main.main_window.resize(1, 1) except: - log.exception("Error killing HUD for table: %s." % table.title) + log.exception(_("Error killing HUD for table: %s.") % table.title) finally: gtk.gdk.threads_leave() @@ -360,7 +360,7 @@ def idle_create(hud_main, new_hand_id, table, temp_key, max, poker_game, type, s hud_main.hud_dict[temp_key].update(new_hand_id, hud_main.config) hud_main.hud_dict[temp_key].reposition_windows() except: - log.exception("Error creating HUD for hand %s." % new_hand_id) + log.exception(_("Error creating HUD for hand %s.") % new_hand_id) finally: gtk.gdk.threads_leave() return False @@ -371,7 +371,7 @@ def idle_update(hud_main, new_hand_id, table_name, config): hud_main.hud_dict[table_name].update(new_hand_id, config) [aw.update_gui(new_hand_id) for aw in hud_main.hud_dict[table_name].aux_windows] except: - log.exception("Error updating HUD for hand %s." % new_hand_id) + log.exception(_("Error updating HUD for hand %s.") % new_hand_id) finally: gtk.gdk.threads_leave() return False diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py index 62383beb..34760664 100644 --- a/pyfpdb/HandHistoryConverter.py +++ b/pyfpdb/HandHistoryConverter.py @@ -675,6 +675,11 @@ or None if we fail to get the info """ # PokerStars: WCOOP 2nd Chance 02: $1,050 NLHE - Tournament 307521826 Table 1 - Blinds $30/$60 return "%s.+Table (\d+)" % (tournament, ) + @staticmethod + def clearMoneyString(money): + "Renders 'numbers' like '1 200' and '2,000'" + return money.replace(' ', '').replace(',', '') + def getTableTitleRe(config, sitename, *args, **kwargs): "Returns string to search in windows titles for current site" return getSiteHhc(config, sitename).getTableTitleRe(*args, **kwargs) diff --git a/pyfpdb/IdentifySite.py b/pyfpdb/IdentifySite.py old mode 100644 new mode 100755 index b4f1a8a7..26a3e1e2 --- a/pyfpdb/IdentifySite.py +++ b/pyfpdb/IdentifySite.py @@ -1,122 +1,122 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -#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. -# -#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 . -#In the "official" distribution you can find the license in agpl-3.0.txt. - -import L10n -_ = L10n.get_translation() - -import re -import sys -import os -import os.path -from optparse import OptionParser -import codecs -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) - - -class IdentifySite: - def __init__(self, config, in_path = '-'): - self.in_path = in_path - self.config = config - self.db = Database.Database(config) - self.sitelist = {} - self.filelist = {} - self.generateSiteList() - self.walkDirectory(self.in_path, self.sitelist) - - def generateSiteList(self): - """Generates a ordered dictionary of site, filter and filter name for each site in hhcs""" - for site, hhc in self.config.hhcs.iteritems(): - filter = hhc.converter - filter_name = filter.replace("ToFpdb", "") - result = self.db.get_site_id(site) - if len(result) == 1: - self.sitelist[result[0][0]] = (site, filter, filter_name) - else: - pass - - def walkDirectory(self, dir, sitelist): - """Walks a directory, and executes a callback on each file""" - dir = os.path.abspath(dir) - for file in [file for file in os.listdir(dir) if not file in [".",".."]]: - nfile = os.path.join(dir,file) - if os.path.isdir(nfile): - self.walkDirectory(nfile, sitelist) - else: - self.idSite(nfile, sitelist) - - def __listof(self, x): - if isinstance(x, list) or isinstance(x, tuple): - return x - else: - return [x] - - def idSite(self, file, sitelist): - """Identifies the site the hh file originated from""" - if file.endswith('.txt'): - self.filelist[file] = '' - archive = False - for site, info in sitelist.iteritems(): - mod = __import__(info[1]) - obj = getattr(mod, info[2], None) - - for kodec in self.__listof(obj.codepage): - try: - in_fh = codecs.open(file, 'r', kodec) - whole_file = in_fh.read() - in_fh.close() - - if info[2] in ('OnGame', 'Winamax'): - m = obj.re_HandInfo.search(whole_file) - elif info[2] in ('PartyPoker'): - m = obj.re_GameInfoRing.search(whole_file) - if not m: - m = obj.re_GameInfoTrny.search(whole_file) - else: - m = obj.re_GameInfo.search(whole_file) - if re_SplitArchive.search(whole_file): - archive = True - if m: - self.filelist[file] = [info[0]] + [info[1]] + [kodec] + [archive] - break - except: - pass - -def main(argv=None): - if argv is None: - argv = sys.argv[1:] - - config = Configuration.Config(file = "HUD_config.test.xml") - in_path = 'regression-test-files/' - IdSite = IdentifySite(config, in_path) - - print "\n----------- SITE LIST -----------" - for site, info in IdSite.sitelist.iteritems(): - print site, info - print "----------- END SITE LIST -----------" - - print "\n----------- ID REGRESSION FILES -----------" - for file, site in IdSite.filelist.iteritems(): - print file, site - print "----------- END ID REGRESSION FILES -----------" - - -if __name__ == '__main__': - sys.exit(main()) +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#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. +# +#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 . +#In the "official" distribution you can find the license in agpl-3.0.txt. + +import L10n +_ = L10n.get_translation() + +import re +import sys +import os +import os.path +from optparse import OptionParser +import codecs +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) + + +class IdentifySite: + def __init__(self, config, in_path = '-'): + self.in_path = in_path + self.config = config + self.db = Database.Database(config) + self.sitelist = {} + self.filelist = {} + self.generateSiteList() + self.walkDirectory(self.in_path, self.sitelist) + + def generateSiteList(self): + """Generates a ordered dictionary of site, filter and filter name for each site in hhcs""" + for site, hhc in self.config.hhcs.iteritems(): + filter = hhc.converter + filter_name = filter.replace("ToFpdb", "") + result = self.db.get_site_id(site) + if len(result) == 1: + self.sitelist[result[0][0]] = (site, filter, filter_name) + else: + pass + + def walkDirectory(self, dir, sitelist): + """Walks a directory, and executes a callback on each file""" + dir = os.path.abspath(dir) + for file in [file for file in os.listdir(dir) if not file in [".",".."]]: + nfile = os.path.join(dir,file) + if os.path.isdir(nfile): + self.walkDirectory(nfile, sitelist) + else: + self.idSite(nfile, sitelist) + + def __listof(self, x): + if isinstance(x, list) or isinstance(x, tuple): + return x + else: + return [x] + + def idSite(self, file, sitelist): + """Identifies the site the hh file originated from""" + if file.endswith('.txt'): + self.filelist[file] = '' + archive = False + for site, info in sitelist.iteritems(): + mod = __import__(info[1]) + obj = getattr(mod, info[2], None) + + for kodec in self.__listof(obj.codepage): + try: + in_fh = codecs.open(file, 'r', kodec) + whole_file = in_fh.read() + in_fh.close() + + if info[2] in ('OnGame', 'Winamax'): + m = obj.re_HandInfo.search(whole_file) + elif info[2] in ('PartyPoker'): + m = obj.re_GameInfoRing.search(whole_file) + if not m: + m = obj.re_GameInfoTrny.search(whole_file) + else: + m = obj.re_GameInfo.search(whole_file) + if re_SplitArchive.search(whole_file): + archive = True + if m: + self.filelist[file] = [info[0]] + [info[1]] + [kodec] + [archive] + break + except: + pass + +def main(argv=None): + if argv is None: + argv = sys.argv[1:] + + config = Configuration.Config(file = "HUD_config.test.xml") + in_path = 'regression-test-files/' + IdSite = IdentifySite(config, in_path) + + print "\n----------- SITE LIST -----------" + for site, info in IdSite.sitelist.iteritems(): + print site, info + print "----------- END SITE LIST -----------" + + print "\n----------- ID REGRESSION FILES -----------" + for file, site in IdSite.filelist.iteritems(): + print file, site + print "----------- END ID REGRESSION FILES -----------" + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/pyfpdb/OnGameToFpdb.py b/pyfpdb/OnGameToFpdb.py index faf52522..7de6d1a5 100755 --- a/pyfpdb/OnGameToFpdb.py +++ b/pyfpdb/OnGameToFpdb.py @@ -42,11 +42,12 @@ class OnGame(HandHistoryConverter): siteId = 5 # Needs to match id entry in Sites database mixes = { } # Legal mixed games - sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\xe2\x82\xac", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE + sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": u"\u20ac", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE substitutions = { 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes - 'LS' : "\$|\xe2\x82\xac|" # legal currency symbols - Euro(cp1252, utf-8) + 'LS' : u"\$|\xe2\x82\xac|\u20ac" # legal currency symbols - Euro(cp1252, utf-8) } + currencies = { u'\u20ac':'EUR', u'\xe2\x82\xac':'EUR', '$':'USD', '':'T$' } limits = { 'NO_LIMIT':'nl', 'LIMIT':'fl'} @@ -89,10 +90,10 @@ class OnGame(HandHistoryConverter): ( (?PNO_LIMIT|Limit|LIMIT|Pot\sLimit)\s (?PTEXAS_HOLDEM|OMAHA_HI|SEVEN_CARD_STUD|SEVEN_CARD_STUD_HI_LO|RAZZ|FIVE_CARD_DRAW)\s - (%(LS)s)?(?P[.0-9]+)/ + (?P%(LS)s|)?(?P[.0-9]+)/ (%(LS)s)?(?P[.0-9]+) )? - """ % substitutions, re.MULTILINE|re.DOTALL|re.VERBOSE) + """ % substitutions, re.MULTILINE|re.DOTALL|re.VERBOSE) #TODO: detect play money (identified by "Play money" rather than "Real money" and set currency accordingly re_TailSplitHands = re.compile(u'(\*\*\*\*\*\sEnd\sof\shand\s[-A-Z\d]+.*\n)(?=\*)') re_Button = re.compile('Button: seat (?P