diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..bd11db36 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +pyfpdb/HUD_config.xml.example -crlf + diff --git a/packaging/announce-0.20.905.txt b/packaging/announce-0.20.905.txt new file mode 100644 index 00000000..cf4932c5 --- /dev/null +++ b/packaging/announce-0.20.905.txt @@ -0,0 +1,32 @@ +Hello everyone, +The new snapshot 0.20.905 is now available for download as source or as packages/installers for Debian, Gentoo, Ubuntu and Windows. +This version brings many improvements and bugfixes, updating is recommended for users of previous snapshots. If you're using a stable version like 0.20 or 0.20.1 please consider trying this version and report any bugs, and in particular regressions, so we can fix them. This snapshot will hopefully be the last, next step is one or more release candidates, and then the next stable release. + +We are still looking for translators! You can find some information about what languages we are still missing here: http://sourceforge.net/apps/mediawiki/fpdb/index.php?title=Translation + +188 changesets (excl. merges) have gone in since 0.20.904. +Please note that you will have to either recreate your database or use a new one if you're updating from 0.20.904 or older. +Config files from 0.20 and later should work. Please report if you have problems with config files from that version or later. + +What's changed: +- Fpdb now supports running in languages other than English, Erki supplied a translation for Hungarian. French, Spanish and Italian are in progress by new contributors. Fpdb will use the system-configured language, a configuration option will be added before the next stable release. Note that this is about the user interface language, non-English history file parsing is a seperate topic. +- Much improved testing to improve the recording of data, especially corner cases and non-trivial stats +- OnGame network (which now includes Betfair) is now properly supported +- FTP.fr importing now works. We don't know if the HUD works yet, give it a go and let us know +- We noticed that fpdb already supports PS.fr +- PokerStars should support all limits now +- The Debian package now handles a missing config file properly +- Many minor improvements to the Gentoo ebuilds for the upcoming submission to the sunrise overlay +- We changed how email import is configured. Either delete your old config or see the HUD_config.xml.example file for how to add the section to the right place +- fpdb should now be able to run with any config file from 0.20 or later, including all 0.20.9* snapshots +- Some more fixes to window visibility and the minimise to tray icon feature +- Various other small cleanups, fixes and improvements. See the git changelog for full details + +To download: +- Debian/Ubuntu Linux: http://sourceforge.net/projects/fpdb/files/fpdb/Snapshots/python-fpdb_0.20.905-1_all.deb/download +- Gentoo Linux: http://sourceforge.net/projects/fpdb/files/fpdb/Snapshots/fpdb-0.20.905.ebuild/download +- Windows: http://sourceforge.net/projects/fpdb/files/fpdb/Snapshots/fpdb-0.20.905anyCPU.exe/download +- Source version for those who installed the dependencies manually: http://sourceforge.net/projects/fpdb/files/fpdb/Snapshots/fpdb-0.20.905.tar.bz2/download + +Thanks to everyone who contributed code, translations, testing and bug reports! +The fpdb team diff --git a/packaging/gentoo/current_stable.ebuild b/packaging/gentoo/current_stable.ebuild index a62b2fe0..edc70791 100644 --- a/packaging/gentoo/current_stable.ebuild +++ b/packaging/gentoo/current_stable.ebuild @@ -1,6 +1,7 @@ # Copyright 1999-2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# created by Steffen Schaumburg, steffen@schaumburger.info and Erki Ferenc, erkiferenc@gmail.com +# $Header: $ + EAPI="2" inherit eutils diff --git a/packaging/gentoo/current_testing.ebuild b/packaging/gentoo/current_testing.ebuild index e2a9c67c..9741f2b8 100644 --- a/packaging/gentoo/current_testing.ebuild +++ b/packaging/gentoo/current_testing.ebuild @@ -1,6 +1,7 @@ # Copyright 1999-2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# created by Steffen Schaumburg, steffen@schaumburger.info and Erki Ferenc, erkiferenc@gmail.com +# $Header: $ + EAPI="2" inherit eutils @@ -17,7 +18,7 @@ SLOT="0" KEYWORDS="~amd64 ~x86" #note: this should work on other architectures too, please send me your experiences -IUSE="graph mysql postgres sqlite" +IUSE="graph mysql postgres sqlite linguas_hu linguas_it" RDEPEND=" mysql? ( virtual/mysql dev-python/mysql-python ) @@ -37,6 +38,15 @@ src_install() { insinto "${GAMES_DATADIR}"/${PN} doins -r gfx doins -r pyfpdb + + if use linguas_hu; then + dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/hu/LC_MESSAGES/${PN}.mo /usr/share/locale/hu/LC_MESSAGES/${PN}.mo + fi + + if use linguas_it; then + dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/it/LC_MESSAGES/${PN}.mo /usr/share/locale/it/LC_MESSAGES/${PN}.mo + fi + doins readme.txt exeinto "${GAMES_DATADIR}"/${PN} diff --git a/packaging/gentoo/fpdb-9999.ebuild b/packaging/gentoo/fpdb-9999.ebuild index a2e28197..683b3f45 100644 --- a/packaging/gentoo/fpdb-9999.ebuild +++ b/packaging/gentoo/fpdb-9999.ebuild @@ -1,6 +1,7 @@ # Copyright 1999-2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# created by Steffen Schaumburg, steffen@schaumburger.info and Erki Ferenc, erkiferenc@gmail.com +# $Header: $ + EAPI="2" inherit eutils @@ -18,7 +19,7 @@ SLOT="0" KEYWORDS="" #note: this should work on other architectures too, please send me your experiences -IUSE="graph mysql postgres sqlite" +IUSE="graph mysql postgres sqlite linguas_hu linguas_it" RDEPEND=" mysql? ( virtual/mysql dev-python/mysql-python ) @@ -42,6 +43,15 @@ src_install() { insinto "${GAMES_DATADIR}"/${PN} doins -r gfx doins -r pyfpdb + + if use linguas_hu; then + dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/hu/LC_MESSAGES/${PN}.mo /usr/share/locale/hu/LC_MESSAGES/${PN}.mo + fi + + if use linguas_it; then + dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/it/LC_MESSAGES/${PN}.mo /usr/share/locale/it/LC_MESSAGES/${PN}.mo + fi + doins readme.txt exeinto "${GAMES_DATADIR}"/${PN} diff --git a/packaging/windows/py2exeWalkthroughPython26.txt b/packaging/windows/py2exeWalkthroughPython26.txt index b023d80d..68a74c81 100644 --- a/packaging/windows/py2exeWalkthroughPython26.txt +++ b/packaging/windows/py2exeWalkthroughPython26.txt @@ -103,6 +103,7 @@ Step 4 Get the fpdb GIT tree ---------------------------- 4.1/ Best to take a copy to work with; following steps will assume that the fpdb folder is on the Desktop +4.2/ Edit the script in packaging/windows/py2exe_setup.py to set the fpdbver variable for this release 5.3/ Install correct Numpy for this build @@ -158,7 +159,7 @@ Step 6 Run py2exe to generate fpdb.exe 6.1/ Run the script to create the fpdb.exe bundle -dos> cd Desktop\fpdb\pyfpdb +dos> cd Desktop\fpdb\packaging\windows dos> c:\python26\python.exe py2exe_setup.py py2exe wait a while, watch lots of copying and whatever. @@ -183,16 +184,14 @@ Step 8 Drag out the completed bundle ------------------------------------ py2exe creates a new folder for the created software bundle, drag this out to the desktop for ease of working. -As far as I know you cannot rerun the build if the fpdb-yyyymmdd-exe exists in the tree, so dragging this out -also allows the build to re-run at step 6. -8.1/ Drag Desktop\fpdb\pyfpdb\fpdb-yyyymmdd-exe to Desktop\ +8.1/ Drag Desktop\fpdb\packaging\windows\fpdb-n.nn.nnn to Desktop\ Step 9 Initial run ------------------ -9.1/ Open the Desktop\fpdb-yyyymmdd-exe folder +9.1/ Open the Desktop\fpdb-n.nn.nnn folder 9.2/ In explorer...tools...folder options...View uncheck "Hide extensions for known file types" 9.3/ Double click run_fpdb.bat 9.4/ check the contents of pyfpdb\fpdb.exe.log, deal with any errors thrown @@ -222,7 +221,7 @@ pyfpdb/share/man Step 12 rename folder --------------------- -Rename the folder to something meaningful to the community. If you have built for NoSSE, append anyCPU to the directory name. +If needed, rename the folder to something meaningful to the community. If you have built for NoSSE, append anyCPU to the directory name. Step 13 Compress to executable archive diff --git a/pyfpdb/py2exe_setup.py b/packaging/windows/py2exe_setup.py similarity index 55% rename from pyfpdb/py2exe_setup.py rename to packaging/windows/py2exe_setup.py index 9dbda8dd..8bf723a4 100644 --- a/pyfpdb/py2exe_setup.py +++ b/packaging/windows/py2exe_setup.py @@ -32,14 +32,10 @@ Py2exe script for fpdb. #HOW TO USE this script: # -#- cd to the folder where this script is stored, usually .../pyfpdb. -# [If there are build and dist subfolders present , delete them to get -# rid of earlier builds. Update: script now does this for you] -#- Run the script with "py2exe_setup.py py2exe" -#- You will frequently get messages about missing .dll files. E. g., -# MSVCP90.dll. These are somewhere in your windows install, so you -# can just copy them to your working folder. (or just assume other -# person will have them? any copyright issues with including them?) +#- cd to the folder where this script is stored, usually ...packaging/windows +#- Run the script with python "py2exe_setup.py py2exe" +#- You will frequently get messages about missing .dll files.just assume other +# person will have them? we have copyright issues including some dll's #- If it works, you'll have a new dir fpdb-YYYYMMDD-exe which should # contain 2 dirs; gfx and pyfpdb and run_fpdb.bat #- [ This bit is now automated: @@ -49,27 +45,11 @@ Py2exe script for fpdb. #- You can (should) then prune the etc/, lib/ and share/ folders to # remove components we don't need. (see output at end of program run) -# sqlcoder notes: this worked for me with the following notes: -#- I used the following versions: -# python 2.5.4 -# gtk+ 2.14.7 (gtk_2.14.7-20090119) -# pycairo 1.4.12-2 -# pygobject 2.14.2-2 -# pygtk 2.12.1-3 -# matplotlib 0.98.3 -# numpy 1.4.0 -# py2exe-0.6.9 for python 2.5 -# -#- I also copied these dlls manually from /bin to /dist : -# -# libgobject-2.0-0.dll -# libgdk-win32-2.0-0.dll -# -# Now updated to work with python 2.6 + related dependencies # See walkthrough in packaging directory for versions used -# Updates to this script have broken python 2.5 compatibility (gio module, msvcr71 references now msvcp90) # steffeN: Doesnt seem necessary to gettext-ify this, but feel free to if you disagree +# Gimick: restructure to allow script to run from packaging/windows directory, and not to write to source pyfpdb + import os import sys @@ -86,33 +66,14 @@ import py2exe import glob import matplotlib import shutil -from datetime import date +#from datetime import date -origIsSystemDLL = py2exe.build_exe.isSystemDLL def isSystemDLL(pathname): #dwmapi appears to be vista-specific file, not XP if os.path.basename(pathname).lower() in ("dwmapi.dll"): return 0 return origIsSystemDLL(pathname) -py2exe.build_exe.isSystemDLL = isSystemDLL - - -def remove_tree(top): - # Delete everything reachable from the directory named in 'top', - # assuming there are no symbolic links. - # CAUTION: This is dangerous! For example, if top == '/', it - # could delete all your disk files. - # sc: Nicked this from somewhere, added the if statement to try - # make it a bit safer - if top in ('build','dist','pyfpdb',dist_dirname) and os.path.basename(os.getcwd()) == 'pyfpdb': - #print "removing directory '"+top+"' ..." - for root, dirs, files in os.walk(top, topdown=False): - for name in files: - os.remove(os.path.join(root, name)) - for name in dirs: - os.rmdir(os.path.join(root, name)) - os.rmdir(top) def test_and_remove(top): if os.path.exists(top): @@ -121,31 +82,64 @@ def test_and_remove(top): else: print "Unexpected file '"+top+"' found. Exiting." exit() + +def remove_tree(top): + # Delete everything reachable from the directory named in 'top', + # assuming there are no symbolic links. + # CAUTION: This is dangerous! For example, if top == '/', it + # could delete all your disk files. + # sc: Nicked this from somewhere, added the if statement to try + # make it a bit safer + if top in ('build','dist',distdir) and os.path.basename(os.getcwd()) == 'windows': + #print "removing directory '"+top+"' ..." + for root, dirs, files in os.walk(top, topdown=False): + for name in files: + os.remove(os.path.join(root, name)) + for name in dirs: + os.rmdir(os.path.join(root, name)) + os.rmdir(top) -today = date.today().strftime('%Y%m%d') -print "\n" + r"Output will be created in \pyfpdb\ and \fpdb_"+today+'\\' -#print "Enter value for XXX (any length): ", # the comma means no newline -#xxx = sys.stdin.readline().rstrip() -dist_dirname = r'fpdb-' + today + '-exe' -dist_dir = r'..\fpdb-' + today + '-exe' -print +def copy_tree(source,destination): + source = source.replace('\\', '\\\\') + destination = destination.replace('\\', '\\\\') + print "*** Copying " + source + " to " + destination + " ***" + shutil.copytree( source, destination ) -# remove build and dist dirs if they exist +def copy_file(source,destination): + source = source.replace('\\', '\\\\') + destination = destination.replace('\\', '\\\\') + print "*** Copying " + source + " to " + destination + " ***" + shutil.copy( source, destination ) + + +fpdbver = '0.20.906' + +distdir = r'fpdb-' + fpdbver +rootdir = r'../../' #cwd is normally /packaging/windows +pydir = rootdir+'pyfpdb/' +gfxdir = rootdir+'gfx/' +sys.path.append( pydir ) # allows fpdb modules to be found by options/includes below + +print "\n" + r"Output will be created in "+distdir + +print "*** Cleaning working folders ***" test_and_remove('dist') test_and_remove('build') -test_and_remove('pyfpdb') +test_and_remove(distdir) -test_and_remove(dist_dirname) +print "*** Building now in dist folder ***" +origIsSystemDLL = py2exe.build_exe.isSystemDLL +py2exe.build_exe.isSystemDLL = isSystemDLL setup( name = 'fpdb', description = 'Free Poker DataBase', - version = '0.20.903', + version = fpdbver, - windows = [ {'script': 'fpdb.pyw', "icon_resources": [(1, "../gfx/fpdb_large_icon.ico")]}, - {'script': 'HUD_main.pyw', }, - {'script': 'Configuration.py', } + windows = [ {'script': pydir+'fpdb.pyw', "icon_resources": [(1, gfxdir+"fpdb_large_icon.ico")]}, + {'script': pydir+'HUD_main.pyw', }, + {'script': pydir+'Configuration.py', } ], options = {'py2exe': { @@ -158,74 +152,56 @@ setup( ,'PartyPokerToFpdb', 'PokerStarsToFpdb' ,'UltimateBetToFpdb', 'Win2dayToFpdb' ], - 'excludes' : ['_tkagg', '_agg2', 'cocoaagg', 'fltkagg'], # surely we need this? '_gtkagg' + 'excludes' : ['_tkagg', '_agg2', 'cocoaagg', 'fltkagg'], 'dll_excludes': ['libglade-2.0-0.dll', 'libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll' , 'msvcr90.dll', 'MSVCP90.dll', 'MSVCR90.dll','msvcr90.dll'], # these are vis c / c++ runtimes, and must not be redistributed } }, # files in 2nd value in tuple are moved to dir named in 1st value - #data_files updated for new locations of licences + readme nolonger exists - data_files = [('', ['HUD_config.xml.example', 'Cards01.png', 'logging.conf', '../agpl-3.0.txt', '../fdl-1.2.txt', '../gpl-3.0.txt', '../gpl-2.0.txt', '../mit.txt', '../readme.txt']) - ,(dist_dir, [r'..\run_fpdb.bat']) - ,( dist_dir + r'\gfx', glob.glob(r'..\gfx\*.*') ) - # line below has problem with fonts subdir ('not a regular file') - #,(r'matplotlibdata', glob.glob(r'c:\python25\Lib\site-packages\matplotlib\mpl-data\*')) + # this code will not walk a tree + # Note: cwd for 1st value is packaging/windows/dist (this is confusing BTW) + # Note: only include files here which are to be put into the package pyfpdb folder or subfolders + + data_files = [('', glob.glob(rootdir+'*.txt')) + ,('', [pydir+'HUD_config.xml.example',pydir+'Cards01.png', pydir+'logging.conf']) ] + matplotlib.get_py2exe_datafiles() ) -# rename completed output package as pyfpdb -os.rename('dist', 'pyfpdb') +# ,(distdir, [rootdir+'run_fpdb.bat']) +# ,(distdir+r'\gfx', glob.glob(gfxdir+'*.*')) +# ] + +print "*** py2exe build phase complete ***" -# pull pytz zoneinfo into pyfpdb package folder -src_dir = r'c:\python26\Lib\site-packages\pytz\zoneinfo' -src_dir = src_dir.replace('\\', '\\\\') -dest_dir = os.path.join(r'pyfpdb', 'zoneinfo') -shutil.copytree( src_dir, dest_dir ) +# copy zone info and fpdb translation folders +copy_tree (r'c:\python26\Lib\site-packages\pytz\zoneinfo', os.path.join(r'dist', 'zoneinfo')) +copy_tree (pydir+r'locale', os.path.join(r'dist', 'locale')) -# shunt pyfpdb package over to the distribution folder -dest = os.path.join(dist_dirname, 'pyfpdb') -# print "try renaming pyfpdb to", dest -dest = dest.replace('\\', '\\\\') -# print "dest is now", dest -os.rename( 'pyfpdb', dest ) +# create distribution folder and populate with gfx + bat +copy_tree (gfxdir, os.path.join(distdir, 'gfx')) +copy_file (rootdir+'run_fpdb.bat', distdir) -# prompt for gtk location +print "*** Renaming dist folder as distribution pyfpdb folder ***" +dest = os.path.join(distdir, 'pyfpdb') +os.rename( 'dist', dest ) +print "*** copying GTK runtime ***" gtk_dir = "" while not os.path.exists(gtk_dir): - print "Enter directory name for GTK (e.g. c:\code\gtk_2.14.7-20090119)\n: ", # the comma means no newline + print "Enter directory name for GTK (e.g. c:/gtk) : ", # the comma means no newline gtk_dir = sys.stdin.readline().rstrip() -print "\ncopying files and dirs from ", gtk_dir, "to", dest.replace('\\\\', '\\'), "..." -src = os.path.join(gtk_dir, 'bin', 'libgdk-win32-2.0-0.dll') -src = src.replace('\\', '\\\\') -shutil.copy( src, dest ) +print "*** copying GTK runtime ***" +dest = os.path.join(distdir, 'pyfpdb') +copy_file(os.path.join(gtk_dir, 'bin', 'libgdk-win32-2.0-0.dll'), dest ) +copy_file(os.path.join(gtk_dir, 'bin', 'libgobject-2.0-0.dll'), dest) +copy_tree(os.path.join(gtk_dir, 'etc'), os.path.join(dest, 'etc')) +copy_tree(os.path.join(gtk_dir, 'lib'), os.path.join(dest, 'lib')) +copy_tree(os.path.join(gtk_dir, 'share'), os.path.join(dest, 'share')) -src = os.path.join(gtk_dir, 'bin', 'libgobject-2.0-0.dll') -src = src.replace('\\', '\\\\') -shutil.copy( src, dest ) - -src_dir = os.path.join(gtk_dir, 'etc') -src_dir = src_dir.replace('\\', '\\\\') -dest_dir = os.path.join(dest, 'etc') -dest_dir = dest_dir.replace('\\', '\\\\') -shutil.copytree( src_dir, dest_dir ) - -src_dir = os.path.join(gtk_dir, 'lib') -src_dir = src_dir.replace('\\', '\\\\') -dest_dir = os.path.join(dest, 'lib') -dest_dir = dest_dir.replace('\\', '\\\\') -shutil.copytree( src_dir, dest_dir ) - -src_dir = os.path.join(gtk_dir, 'share') -src_dir = src_dir.replace('\\', '\\\\') -dest_dir = os.path.join(dest, 'share') -dest_dir = dest_dir.replace('\\', '\\\\') -shutil.copytree( src_dir, dest_dir ) - -print "\nIf py2exe was successful you should now have a new dir" -print dist_dirname+" in your pyfpdb dir" +print "*** All done! ***" +test_and_remove('build') +print distdir+" is in the pyfpdb dir" print """ The following dirs can probably removed to make the final package smaller: @@ -243,5 +219,3 @@ pyfpdb/share/themes/Default Use 7-zip to zip up the distribution and create a self extracting archive and that's it! """ - - diff --git a/pyfpdb/AlchemyTables.py b/pyfpdb/AlchemyTables.py index c74665b1..e89380a7 100644 --- a/pyfpdb/AlchemyTables.py +++ b/pyfpdb/AlchemyTables.py @@ -450,7 +450,6 @@ def sss(): self.settings['os']="windows" self.settings.update(self.config.get_db_parameters()) - self.settings.update(self.config.get_tv_parameters()) self.settings.update(self.config.get_import_parameters()) self.settings.update(self.config.get_default_paths()) diff --git a/pyfpdb/BetfairToFpdb.py b/pyfpdb/BetfairToFpdb.py index 62db0311..07ee2612 100755 --- a/pyfpdb/BetfairToFpdb.py +++ b/pyfpdb/BetfairToFpdb.py @@ -44,9 +44,8 @@ class Betfair(HandHistoryConverter): siteId = 7 # Needs to match id entry in Sites database # Static regexes - #re_SplitHands = re.compile(r'\n\n+') # Betfair 1.0 version re_GameInfo = re.compile("^(?PNL|PL|) (?P\$|)?(?P[.0-9]+)/\$?(?P[.0-9]+) (?P(Texas Hold\'em|Omaha Hi|Razz))", re.MULTILINE) - re_SplitHands = re.compile(r'End of hand .{2}-\d{7,9}-\d+ \*\*\*\*\*\n') + re_SplitHands = re.compile(r'\n\n+') re_HandInfo = re.compile("\*\*\*\*\* Betfair Poker Hand History for Game (?P[0-9]+) \*\*\*\*\*\n(?PNL|PL|) (?P\$|)?(?P[.0-9]+)/\$?(?P[.0-9]+) (?P(Texas Hold\'em|Omaha Hi|Razz)) - (?P[a-zA-Z]+, [a-zA-Z]+ \d+, \d\d:\d\d:\d\d GMT \d\d\d\d)\nTable (?P[ a-zA-Z0-9]+) \d-max \(Real Money\)\nSeat (?P- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 377c7ed6..7ae5f044 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -58,7 +58,7 @@ class Hand(object): LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'} SYMBOL = {'USD': '$', 'EUR': u'$', 'T$': '', 'play': ''} MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE', 'ha': 'HA'} - SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7, 'Absolute':8, 'PartyPoker':9, 'Partouche':10, 'Carbon':11 } + SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7, 'Absolute':8, 'PartyPoker':9, 'Partouche':10, 'Carbon':11, 'PKR':12 } def __init__(self, config, sitename, gametype, handText, builtFrom = "HHC"): @@ -321,10 +321,8 @@ If a player has None chips he won't be added.""" def checkPlayerExists(self,player): if player not in [p[1] for p in self.players]: - print _("DEBUG: checkPlayerExists %s fail") % player - raise FpdbParseError(_("checkPlayerExists: '%s' failed.") % player) - - + print (_("DEBUG: checkPlayerExists %s fail on hand number %s") % (player, self.handid)) + raise FpdbParseError(_("checkPlayerExists: '%s fail on hand number %s") % (player, self.handid)) def setCommunityCards(self, street, cards): log.debug("setCommunityCards %s %s" %(street, cards)) diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py index af758352..860d05e1 100644 --- a/pyfpdb/HandHistoryConverter.py +++ b/pyfpdb/HandHistoryConverter.py @@ -587,6 +587,7 @@ or None if we fail to get the info """ offset = int(givenTimezone[-5:]) givenTimezone = givenTimezone[0:-5] log.debug( _("changeTimeZone: offset=") + str(offset) ) + else: offset=0 if givenTimezone=="ET": givenTZ = timezone('US/Eastern') diff --git a/pyfpdb/OnGameToFpdb.py b/pyfpdb/OnGameToFpdb.py index b7344ed6..8ba8f9b4 100755 --- a/pyfpdb/OnGameToFpdb.py +++ b/pyfpdb/OnGameToFpdb.py @@ -96,7 +96,7 @@ class OnGame(HandHistoryConverter): Start\shand:\s(?P.*) Table:\s(?P
[\'\w\s]+)\s\[\d+\]\s\( ( - (?PNo\sLimit|Limit|LIMIT|Pot\sLimit)\s + (?PNO_LIMIT|Limit|LIMIT|Pot\sLimit)\s (?PTEXAS_HOLDEM|RAZZ)\s (%(LS)s)?(?P[.0-9]+)/ (%(LS)s)?(?P[.0-9]+) @@ -142,7 +142,7 @@ class OnGame(HandHistoryConverter): self.re_Antes = re.compile(r"^%(PLYR)s: posts the ante (%(CUR)s)?(?P[\.0-9]+)" % subst, re.MULTILINE) self.re_BringIn = re.compile(r"^%(PLYR)s: brings[- ]in( low|) for (%(CUR)s)?(?P[\.0-9]+)" % subst, re.MULTILINE) self.re_PostBoth = re.compile('.*\n(?P.*): posts small \& big blinds \( (%(CUR)s)?(?P[\.0-9]+)\)' % subst) - self.re_HeroCards = re.compile('.*\nDealt\sto\s(?P.*)\s\[ (?P.*) \]') + self.re_HeroCards = re.compile('Dealing\sto\s%(PLYR)s:\s\[(?P.*)\]' % subst) #lopllopl checks, Eurolll checks, .Lucchess checks. #chumley. calls $0.25 @@ -152,9 +152,6 @@ class OnGame(HandHistoryConverter): #Uchilka shows [ KC,JD ] self.re_ShowdownAction = re.compile('(?P.*) shows \[ (?P.+) \]') - # TODO: read SUMMARY correctly for collected pot stuff. - #Uchilka, bets $11.75, collects $23.04, net $11.29 - #like this: #Main pot: $3.57 won by mleo17 ($3.40) #Side pot 1: $3.26 won by maac_5 ($3.10) #Main pot: $2.87 won by maac_5 ($1.37), sagi34 ($1.36) @@ -309,35 +306,15 @@ class OnGame(HandHistoryConverter): hand.addBringIn(m.group('PNAME'), m.group('BRINGIN')) def readHeroCards(self, hand): - m = self.re_HeroCards.search(hand.handText) - if(m == None): - #Not involved in hand - hand.involved = False - else: - hand.hero = m.group('PNAME') - # "2c, qh" -> set(["2c","qc"]) - # Also works with Omaha hands. - cards = m.group('CARDS') - cards = set(cards.split(',')) - hand.addHoleCards(cards, m.group('PNAME')) - - def readAction_old(self, hand, street): - m = self.re_Action.finditer(hand.streets.group(street)) - for action in m: - if action.group('ATYPE') == ' raises': - hand.addRaiseTo( street, action.group('PNAME'), action.group('BET') ) - elif action.group('ATYPE') == ' calls': - hand.addCall( street, action.group('PNAME'), action.group('BET') ) - elif action.group('ATYPE') == ' bets': - hand.addBet( street, action.group('PNAME'), action.group('BET') ) - elif action.group('ATYPE') == ' folds': - hand.addFold( street, action.group('PNAME')) - elif action.group('ATYPE') == ' checks': - hand.addCheck( street, action.group('PNAME')) - else: - print "DEBUG: unimplemented readAction: %s %s" %(action.group('PNAME'),action.group('ATYPE'),) - #hand.actions[street] += [[action.group('PNAME'), action.group('ATYPE')]] - # TODO: Everleaf does not record uncalled bets. + # streets PREFLOP, PREDRAW, and THIRD are special cases beacause + # we need to grab hero's cards + for street in ('PREFLOP', 'DEAL'): + if street in hand.streets.keys(): + m = self.re_HeroCards.finditer(hand.streets[street]) + for found in m: + hand.hero = found.group('PNAME') + newcards = found.group('CARDS').split(', ') + hand.addHoleCards(street, hand.hero, closed=newcards, shown=False, mucked=False, dealt=True) def readAction(self, hand, street): m = self.re_Action.finditer(hand.streets[street]) diff --git a/pyfpdb/PkrToFpdb.py b/pyfpdb/PkrToFpdb.py new file mode 100755 index 00000000..a94cd030 --- /dev/null +++ b/pyfpdb/PkrToFpdb.py @@ -0,0 +1,390 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2010, Carl Gherardi +# +# 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. +# +# 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 sys +from HandHistoryConverter import * + +import locale +lang=locale.getdefaultlocale()[0][0:2] +if lang=="en": + def _(string): return string +else: + import gettext + try: + trans = gettext.translation("fpdb", localedir="locale", languages=[lang]) + trans.install() + except IOError: + def _(string): return string + + +class Pkr(HandHistoryConverter): + + # Class Variables + + sitename = "PKR" + filetype = "text" + codepage = ("utf8", "cp1252") + siteId = 12 # Needs to match id entry in Sites database + + mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games + sym = {'USD': "\$"} # ADD Euro, Sterling, etc HERE + substitutions = { + 'LEGAL_ISO' : "USD", # legal ISO currency codes + 'LS' : "\$|" # legal currency symbols - Euro(cp1252, utf-8) + } + + limits = { 'NO LIMIT':'nl', 'POT LIMIT':'pl', 'LIMIT':'fl' } + games = { # base, category + "HOLD'EM" : ('hold','holdem'), + 'FIXMEOmaha' : ('hold','omahahi'), + 'FIXMEOmaha Hi/Lo' : ('hold','omahahilo'), + 'FIXME5 Card Draw' : ('draw','fivedraw') + } + currencies = { u'€':'EUR', '$':'USD', '':'T$' } + + # Static regexes + re_GameInfo = re.compile(u""" + Table\s\#\d+\s\-\s(?P
[a-zA-Z\ \d]+)\s + Starting\sHand\s\#(?P[0-9]+)\s + Start\stime\sof\shand:\s(?P.*)\s + Last\sHand\s\#[0-9]+\s + Game\sType:\s(?PHOLD'EM|5\sCard\sDraw)\s + Limit\sType:\s(?PNO\sLIMIT|LIMIT|POT\sLIMIT)\s + Table\sType\:\sRING\s + Money\sType:\sREAL\sMONEY\s + Blinds\sare\snow\s(?P%(LS)s|)? + (?P[.0-9]+)/(%(LS)s)? + (?P[.0-9]+) + """ % substitutions, re.MULTILINE|re.VERBOSE) + + re_PlayerInfo = re.compile(u""" + ^Seat\s(?P[0-9]+):\s + (?P.*)\s-\s + (%(LS)s)?(?P[.0-9]+) + """ % substitutions, re.MULTILINE|re.VERBOSE) + + re_HandInfo = re.compile(""" + ^Table\s\'(?P
[-\ a-zA-Z\d]+)\'\s + ((?P\d+)-max\s)? + (?P\(Play\sMoney\)\s)? + (Seat\s\#(?P
[ a-zA-Z]+) - \$?(?P[.0-9]+)/\$?(?P[.0-9]+) - (?P.*) - (?P
[0-9]+):(?P[0-9]+) ET - (?P[0-9]+)/(?P[0-9]+)/(?P[0-9]+)Table (?P
[ a-zA-Z]+)\nSeat (?P