2 # -*- coding: utf-8 -*-
4 #Copyright 2008-2011 Carl Gherardi
5 #This program is free software: you can redistribute it and/or modify
6 #it under the terms of the GNU Affero General Public License as published by
7 #the Free Software Foundation, version 3 of the License.
9 #This program is distributed in the hope that it will be useful,
10 #but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 #GNU General Public License for more details.
14 #You should have received a copy of the GNU Affero General Public License
15 #along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #In the "official" distribution you can find the license in agpl-3.0.txt.
19 _
= L10n
.get_translation()
21 # Standard Library modules
36 # fpdb/FreePokerTools modules
39 from Exceptions
import FpdbParseError
42 # logging has been set up in fpdb.py or HUD_main.py, use their settings:
43 log
= logging
.getLogger("importer")
46 class GuiTourneyImport():
48 def load_clicked(self
, widget
, data
=None):
49 print "DEBUG: load_clicked"
56 if self
.settings
['global_lock'].acquire(wait
=False, source
="GuiTourneyImport"):
57 print "DEBUG: got global lock"
58 # get the dir to import from the chooser
59 selected
= self
.chooser
.get_filenames()
60 print "DEBUG: Files selected: %s" % selected
62 sitename
= self
.cbfilter
.get_model()[self
.cbfilter
.get_active()][0]
64 for selection
in selected
:
65 self
.importer
.addImportFileOrDir(selection
, site
= sitename
)
67 (stored
, errs
) = self
.importer
.runImport()
69 ttime
= time() - starttime
72 print _('Tourney import done: Stored: %d \tErrors: %d in %s seconds - %.0f/sec')\
73 % (stored
, errs
, ttime
, (stored
+0.0) / ttime
)
74 self
.importer
.clearFileList()
76 self
.settings
['global_lock'].release()
78 print _("tourney import aborted - global lock not available")
81 """returns the vbox of this thread"""
84 def __init__(self
, settings
, config
, sql
= None, parent
= None):
85 self
.settings
= settings
89 self
.importer
= SummaryImporter(config
, sql
, parent
)
91 self
.vbox
= gtk
.VBox(False, 0)
94 self
.chooser
= gtk
.FileChooserWidget()
95 self
.chooser
.set_filename(self
.settings
['bulkImport-defaultPath'])
96 self
.chooser
.set_select_multiple(True)
97 self
.vbox
.add(self
.chooser
)
100 # Table widget to hold the settings
101 self
.table
= gtk
.Table(rows
=5, columns
=5, homogeneous
=False)
102 self
.vbox
.add(self
.table
)
106 self
.lab_filter
= gtk
.Label(_("Site filter:"))
107 self
.table
.attach(self
.lab_filter
, 1, 2, 2, 3, xpadding
=0, ypadding
=0,
109 self
.lab_filter
.show()
110 self
.lab_filter
.set_justify(gtk
.JUSTIFY_RIGHT
)
111 self
.lab_filter
.set_alignment(1.0, 0.5)
114 self
.cbfilter
= gtk
.combo_box_new_text()
115 disabled_sites
= [] # move disabled sites to bottom of list
116 for w
in self
.config
.hhcs
:
117 print "%s = '%s'" %(w
, self
.config
.hhcs
[w
].summaryImporter
)
119 # Include sites with a tourney summary importer, and enabled
120 if self
.config
.supported_sites
[w
].enabled
and self
.config
.hhcs
[w
].summaryImporter
!= '':
121 self
.cbfilter
.append_text(w
)
123 disabled_sites
.append(w
)
124 except: # self.supported_sites[w] may not exist if hud_config is bad
125 disabled_sites
.append(w
)
126 for w
in disabled_sites
:
127 if self
.config
.hhcs
[w
].summaryImporter
!= '':
128 self
.cbfilter
.append_text(w
)
129 self
.cbfilter
.set_active(0)
130 self
.table
.attach(self
.cbfilter
, 2, 3, 2, 3, xpadding
=10, ypadding
=1,
135 self
.load_button
= gtk
.Button(_('_Bulk Import')) # todo: rename variables to import too
136 self
.load_button
.connect('clicked', self
.load_clicked
,
138 self
.table
.attach(self
.load_button
, 2, 3, 4, 5, xpadding
=0, ypadding
=0,
140 self
.load_button
.show()
142 # label - spacer (keeps rows 3 & 5 apart)
143 self
.lab_spacer
= gtk
.Label()
144 self
.table
.attach(self
.lab_spacer
, 3, 5, 3, 4, xpadding
=0, ypadding
=0,
146 self
.lab_spacer
.show()
148 class SummaryImporter
:
149 def __init__(self
, config
, sql
= None, parent
= None):
157 self
.updatedsize
= {}
158 self
.updatedtime
= {}
160 def addImportFile(self
, filename
, site
= "default", tsc
= "passthrough"):
161 if filename
in self
.filelist
or not os
.path
.exists(filename
):
162 print "DEBUG: addImportFile: File exists, or path non-existent"
164 self
.filelist
[filename
] = [site
] + [tsc
]
166 def addImportDirectory(self
,dir,monitor
=False, site
="default", tsc
="passthrough"):
167 if os
.path
.isdir(dir):
170 self
.dirlist
[site
] = [dir] + [tsc
]
172 for file in os
.listdir(dir):
173 self
.addImportFile(os
.path
.join(dir, file), site
, tsc
)
175 log
.warning(_("Attempted to add non-directory '%s' as an import directory") % str(dir))
177 def addImportFileOrDir(self
, inputPath
, site
= "PokerStars"):
178 tsc
= self
.config
.hhcs
[site
].summaryImporter
179 if os
.path
.isdir(inputPath
):
180 for subdir
in os
.walk(inputPath
):
181 for file in subdir
[2]:
182 self
.addImportFile(unicode(os
.path
.join(subdir
[0], file),'utf-8'),
185 self
.addImportFile(unicode(inputPath
,'utf-8'), site
=site
, tsc
=tsc
)
189 start
= datetime
.datetime
.now()
191 log
.info(_("Tourney Summary Import started at %s - %d files to import.") % (start
, len(self
.filelist
)))
195 for f
in self
.filelist
:
196 (site
, tsc
) = self
.filelist
[f
]
197 imported
, errs
= self
.importFile(f
, tsc
, site
)
199 total_imported
+= imported
200 return (total_imported
, total_errors
)
203 def runUpdated(self
):
206 def importFile(self
, filename
, tsc
= "PokerStarsSummary", site
= "PokerStars"):
207 mod
= __import__(tsc
)
208 obj
= getattr(mod
, tsc
, None)
210 foabs
= self
.readFile(obj
, filename
)
211 summaryTexts
= re
.split(obj
.re_SplitTourneys
, foabs
)
213 # The summary files tend to have a header or footer
214 # Remove the first and/or last entry if it has < 100 characters
215 if len(summaryTexts
[-1]) <= 100:
217 log
.warn(_("TourneyImport: Removing text < 100 characters from end of file"))
219 if len(summaryTexts
[0]) <= 130:
221 log
.warn(_("TourneyImport: Removing text < 100 characters from start of file"))
223 print "Found %s summaries" %(len(summaryTexts
))
226 ####Lock Placeholder####
227 for j
, summaryText
in enumerate(summaryTexts
, start
=1):
228 sc
, gsc
= {'bk': []}, {'bk': []}
229 doinsert
= len(summaryTexts
)==j
231 conv
= obj(db
=self
.database
, config
=self
.config
, siteName
=site
, summaryText
=summaryText
, builtFrom
= "IMAP")
232 sc
, gsc
= conv
.updateSessionsCache(sc
, gsc
, None, doinsert
)
233 except FpdbParseError
, e
:
235 print _("Finished importing %s/%s tournament summaries") %(j
, len(summaryTexts
))
237 ####Lock Placeholder####
238 return (imported
- errors
, errors
)
240 def clearFileList(self
):
241 self
.updatedsize
= {}
245 def readFile(self
, tsc
, filename
):
246 codepage
= ["utf8", "utf16"]
250 for kodec
in codepage
:
252 in_fh
= codecs
.open(filename
, 'r', kodec
)
253 whole_file
= in_fh
.read()
256 except UnicodeDecodeError, e
:
257 log
.warn(_("GTI.readFile: '%s'") % e
)
263 """main can also be called in the python interpreter, by supplying the command line as the argument."""
268 (options
, argv
) = Options
.fpdb_options()
270 if options
.usage
== True:
271 #Print usage examples and exit
275 if options
.hhc
== "PokerStarsToFpdb":
276 print _("Need to define a converter")
279 config
= Configuration
.Config("HUD_config.test.xml")
280 sql
= SQL
.Sql(db_server
= 'sqlite')
282 if options
.filename
== None:
283 print _("Need a filename to import")
286 importer
= SummaryImporter(config
, sql
, None)
288 importer
.addImportFileOrDir(options
.filename
, site
= options
.hhc
)
290 (stored
, errs
) = importer
.runImport()
292 ttime
= time() - starttime
295 print _('Tourney import done: Stored: %d \tErrors: %d in %s seconds - %.0f/sec')\
296 % (stored
, errs
, ttime
, (stored
+0.0) / ttime
)
297 importer
.clearFileList()
302 if __name__
== '__main__':