Example #1
0
    def menuExportToExcel(self, event):
        self.commit()
        iSelection = self.notebook.GetSelection()
        page = self.pages[iSelection]
        try:
            grid = page.getGrid()
        except:
            return

        try:
            pageTitle = self.pages[iSelection].getTitle()
        except:
            pageTitle = self.attrClassName[iSelection][2]

        if not self.fileName or len(self.fileName) < 4:
            Utils.MessageOK(self,
                            'You must Save before you can Export to Excel',
                            'Excel Write')
            return

        pageTitle = Utils.RemoveDisallowedFilenameChars(
            pageTitle.replace('/', '_'))
        xlfileName = self.fileName[:-4] + '-' + pageTitle + '.xls'
        dlg = wx.DirDialog(self,
                           'Folder to write "%s"' %
                           os.path.basename(xlfileName),
                           style=wx.DD_DEFAULT_STYLE,
                           defaultPath=os.path.dirname(xlfileName))
        ret = dlg.ShowModal()
        dName = dlg.GetPath()
        dlg.Destroy()
        if ret != wx.ID_OK:
            return

        xlfileName = os.path.join(dName, os.path.basename(xlfileName))

        title = self.getTitle()

        wb = xlwt.Workbook()
        sheetName = self.attrClassName[self.notebook.GetSelection()][2]
        sheetCur = wb.add_sheet(sheetName)
        export = ExportGrid(title, grid)
        export.toExcelSheet(sheetCur)

        try:
            wb.save(xlfileName)
            webbrowser.open(xlfileName, new=2, autoraise=True)
            Utils.MessageOK(self,
                            'Excel file written to:\n\n   %s' % xlfileName,
                            'Excel Export')
        except IOError:
            Utils.MessageOK(
                self,
                'Cannot write "%s".\n\nCheck if this spreadsheet is open.\nIf so, close it, and try again.'
                % xlfileName,
                'Excel File Error',
                iconMask=wx.ICON_ERROR)
Example #2
0
	def prepareGrid( self, page ):
		showLapTimes = (not Model.race) or getattr( Model.race, 'includeLapTimesInPrintout', True )
		with UnstartedRaceWrapper():
			if self.pageInfo[page][0] == 'Primes':
				exportGrid = ExportGrid( **Primes.GetGrid() )
			else:
				exportGrid = ExportGrid()
				exportGrid.setResultsOneList( self.pageInfo[page][0], True, showLapTimes=showLapTimes )
		return exportGrid
Example #3
0
	def prepareGrid( self, page ):
		exportGrid = ExportGrid()
		try:
			with UnstartedRaceWrapper():
				if self.pageInfo[page][0] == 'Primes':
					exportGrid = ExportGrid( **Primes.GetGrid() )
				else:
					exportGrid.setResultsOneList( self.pageInfo[page][0], True, showLapTimes=False )
		except KeyError:
			return ExportGrid()
		exportGrid.title = u'\n'.join( [_('Podium Results'), u'', exportGrid.title] )
		return exportGrid
Example #4
0
    def onExcel(self, event):
        self.commit()
        export = getExportGrid()
        xlFName = Utils.getMainWin().getFormatFilename('excel')
        xlFName = os.path.splitext(
            xlFName)[0] + '-Categories' + os.path.splitext(xlFName)[1]

        wb = xlsxwriter.Workbook(xlFName)
        sheetCur = wb.add_worksheet(_('Categories'))
        export.toExcelSheetXLSX(ExportGrid.getExcelFormatsXLSX(wb), sheetCur)
        try:
            wb.close()
            if Utils.getMainWin().launchExcelAfterPublishingResults:
                Utils.LaunchApplication(xlFName)
            Utils.MessageOK(
                self, u'{}:\n\n   {}'.format(_('Excel file written to'),
                                             xlFName), _('Excel Write'))
        except IOError:
            Utils.MessageOK(
                self,
                u'{} "{}"\n\n{}\n{}'.format(
                    _('Cannot write'), xlFName,
                    _('Check if this spreadsheet is already open.'),
                    _('If so, close it, and try again.')),
                _('Excel File Error'),
                iconMask=wx.ICON_ERROR)
Example #5
0
	def menuExportToExcel( self, event ):
		self.commit()
		iSelection = self.notebook.GetSelection()
		page = self.pages[iSelection]
		try:
			grid = page.getGrid()
		except:
			return
		
		try:
			pageTitle = self.pages[iSelection].getTitle()
		except:
			pageTitle = self.attrClassName[iSelection][2]
		
		if not self.fileName or len(self.fileName) < 4:
			Utils.MessageOK(self, 'You must Save before you can Export to Excel', 'Excel Write')
			return

		pageTitle = Utils.RemoveDisallowedFilenameChars( pageTitle.replace('/', '_') )
		xlFName = self.fileName[:-4] + '-' + pageTitle + '.xls'
		dlg = wx.DirDialog( self, 'Folder to write "%s"' % os.path.basename(xlFName),
						style=wx.DD_DEFAULT_STYLE, defaultPath=os.path.dirname(xlFName) )
		ret = dlg.ShowModal()
		dName = dlg.GetPath()
		dlg.Destroy()
		if ret != wx.ID_OK:
			return

		xlFName = os.path.join( dName, os.path.basename(xlFName) )

		title = self.getTitle()
		
		wb = xlwt.Workbook()
		sheetName = pageTitle
		sheetName = re.sub('[+!#$%&+~`".:;|\\/?*\[\] ]+', ' ', sheetName)[:31]
		sheetCur = wb.add_sheet( sheetName )
		export = ExportGrid( title, grid )
		export.toExcelSheet( sheetCur )

		try:
			wb.save( xlFName )
			webbrowser.open( xlFName, new = 2, autoraise = True )
			Utils.MessageOK(self, 'Excel file written to:\n\n   %s' % xlFName, 'Excel Export')
		except IOError:
			Utils.MessageOK(self,
						'Cannot write "%s".\n\nCheck if this spreadsheet is open.\nIf so, close it, and try again.' % xlFName,
						'Excel File Error', iconMask=wx.ICON_ERROR )
Example #6
0
def ToHtml( html ):
	for title, report in (('Results', Utils.getMainWin().rankSummary), ('Details', Utils.getMainWin().rankDetails), ):
		report.refresh()
		ExportGrid( title, report.grid).toHtml( html )
		html.write( u'<br/><hr/><br/>' )
	Utils.getMainWin().commentary.refresh()
	html.write(u'<span id="idRaceName">Commentary</span>')
	Utils.getMainWin().commentary.toHtml(html)
Example #7
0
 def prepareGrid(self, page):
     exportGrid = ExportGrid()
     try:
         with UnstartedRaceWrapper():
             if self.pageInfo[page][0] == 'Primes':
                 exportGrid = ExportGrid(**Primes.GetGrid())
             else:
                 exportGrid.setResultsOneList(self.pageInfo[page][0],
                                              True,
                                              showLapTimes=False)
     except KeyError:
         return ExportGrid()
     exportGrid.title = u'\n'.join(
         [_('Podium Results'), u'', exportGrid.title])
     return exportGrid
Example #8
0
 def prepareGrid(self, page):
     showLapTimes = (not Model.race) or getattr(
         Model.race, 'includeLapTimesInPrintout', True)
     try:
         with UnstartedRaceWrapper():
             if self.pageInfo[page][0] == 'Primes':
                 exportGrid = ExportGrid(**Primes.GetGrid())
             else:
                 exportGrid = ExportGrid()
                 exportGrid.setResultsOneList(self.pageInfo[page][0],
                                              True,
                                              showLapTimes=showLapTimes)
     except KeyError:
         return ExportGrid()
     return exportGrid
Example #9
0
def ToExcel( wb ):
	for title, report in (('Results', Utils.getMainWin().rankSummary), ('Details', Utils.getMainWin().rankDetails), ):
		sheetCur = wb.add_sheet( title )
		report.refresh()
		ExportGrid( title, report.grid).toExcelSheet( sheetCur )
Example #10
0
def getExportGrid():
    race = Model.race
    try:
        externalInfo = race.excelLink.read()
    except:
        externalInfo = {}

    GetTranslation = _
    allZeroStarters = True
    with UnstartedRaceWrapper():
        catMap = dict(
            (c.fullname, c) for c in race.getCategories(startWaveOnly=False))
        catDetails = GetCategoryDetails(False, True)
        catDetailsMap = dict((cd['name'], cd) for cd in catDetails)

        title = u'\n'.join([
            _('Categories'), race.title, race.scheduledStart + u' ' +
            _('Start on') + u' ' + Utils.formatDate(race.date)
        ])
        colnames = [
            _('Start Time'),
            _('Category'),
            _('Gender'),
            _('Numbers'),
            _('Laps'),
            _('Distance'),
            _('Starters')
        ]

        raceStart = Utils.StrToSeconds(race.scheduledStart + ':00')
        catData = []
        for catInfo in catDetails:
            c = catMap.get(catInfo['name'], None)
            if not c:
                continue

            starters = race.catCount(c)
            if starters:
                allZeroStarters = False
            else:
                starters = ''

            laps = catInfo.get('laps', '') or ''
            raceDistance = catInfo.get('raceDistance', '')
            raceDistanceUnit = catInfo.get('distanceUnit', '')

            if raceDistance:
                raceDistance = '%.2f' % raceDistance

            if c.catType == c.CatWave:
                catStart = Utils.SecondsToStr(raceStart +
                                              c.getStartOffsetSecs())
            elif c.catType == c.CatCustom:
                catStart = Utils.SecondsToStr(raceStart)
            else:
                catStart = ''

            catData.append([
                catStart,
                u' - ' + c.name if c.catType == c.CatComponent else c.name,
                GetTranslation(catInfo.get('gender', 'Open')), c.catStr,
                u'{}'.format(laps), u' '.join([raceDistance, raceDistanceUnit])
                if raceDistance else '', u'{}'.format(starters)
            ])

    if allZeroStarters:
        colnames.remove(_('Starters'))
    data = [[None] * len(catData) for i in xrange(len(colnames))]
    for row in xrange(len(catData)):
        for col in xrange(len(colnames)):
            data[col][row] = catData[row][col]

    exportGrid = ExportGrid(title=title, colnames=colnames, data=data)
    exportGrid.leftJustifyCols = {1, 2, 3}
    return exportGrid
Example #11
0
	def OnPrintPage(self, page):
		race = Model.race
		if not race:
			return
		
		try:
			externalInfo = race.excelLink.read()
		except:
			externalInfo = {}
		
		GetTranslation = _
		allZeroStarters = True
		with UnstartedRaceWrapper():
			catMap = dict( (c.fullname, c) for c in race.getCategories( startWaveOnly=False ) )
			catDetails = GetCategoryDetails( ignoreEmptyCategories=False, publishOnly=True )
			catDetailsMap = dict( (cd['name'], cd) for cd in catDetails )
			
			title = u'\n'.join( [_('Categories'), race.name, race.scheduledStart + u' ' + _('Start on') + u' ' + Utils.formatDate(race.date)] )
			colnames = [_('Start Time'), _('Category'), _('Gender'), _('Numbers'), _('Laps'), _('Distance'), _('Starters')]
			
			raceStart = Utils.StrToSeconds( race.scheduledStart + ':00' )
			catData = []
			for catInfo in catDetails:
				c = catMap.get( catInfo['name'], None )
				if not c:
					continue
				
				starters = race.catCount(c)
				if starters:
					allZeroStarters = False
				else:
					starters = ''
				
				laps = catInfo.get( 'laps', '' ) or ''
				raceDistance = catInfo.get( 'raceDistance', '' )
				raceDistanceUnit = catInfo.get( 'distanceUnit', '')
				
				if raceDistance:
					raceDistance = '%.2f' % raceDistance
					
				if c.catType == c.CatWave:
					catStart = Utils.SecondsToStr( raceStart + c.getStartOffsetSecs() )
				elif c.catType == c.CatCustom:
					catStart = Utils.SecondsToStr( raceStart )
				else:
					catStart = ''
					
				catData.append( [
					catStart,
					u' - ' + c.name if c.catType == c.CatComponent else c.name,
					GetTranslation(catInfo.get('gender', 'Open')),
					c.catStr,
					u'{}'.format(laps),
					u' '.join([raceDistance, raceDistanceUnit]) if raceDistance else '',
					u'{}'.format(starters)
				])
		
		if allZeroStarters:
			colnames.remove( _('Starters') )
		data = [[None] * len(catData) for i in xrange(len(colnames))]
		for row in xrange(len(catData)):
			for col in xrange(len(colnames)):
				data[col][row] = catData[row][col]
				
		exportGrid = ExportGrid( title = title, colnames = colnames, data = data )
		exportGrid.leftJustifyCols = { 1, 2, 3 }
		exportGrid.drawToFitDC( self.GetDC() )
		return True
Example #12
0
	def OnPrintPage(self, page):
		exportGrid = ExportGrid( self.title, self.grid )
		dc = self.GetDC()
		exportGrid.drawToFitDC( dc )
		return True
Example #13
0
    def menuExportToHtml(self, event):
        self.commit()
        iSelection = self.notebook.GetSelection()
        page = self.pages[iSelection]
        try:
            grid = page.getGrid()
        except:
            return

        try:
            pageTitle = self.pages[iSelection].getTitle()
        except:
            pageTitle = self.attrClassName[iSelection][2]

        if not self.fileName or len(self.fileName) < 4:
            Utils.MessageOK(self,
                            'You must Save before you can Export to Html',
                            'Html Export')
            return

        pageTitle = Utils.RemoveDisallowedFilenameChars(
            pageTitle.replace('/', '_'))
        htmlfileName = self.fileName[:-4] + '-' + pageTitle + '.html'
        dlg = wx.DirDialog(self,
                           'Folder to write "{}"'.format(
                               os.path.basename(htmlfileName)),
                           style=wx.DD_DEFAULT_STYLE,
                           defaultPath=os.path.dirname(htmlfileName))
        ret = dlg.ShowModal()
        dName = dlg.GetPath()
        dlg.Destroy()
        if ret != wx.ID_OK:
            return

        htmlfileName = os.path.join(dName, os.path.basename(htmlfileName))

        title = self.getTitle()

        html = StringIO.StringIO()

        with tag(html, 'html'):
            with tag(html, 'head'):
                with tag(html, 'title'):
                    html.write(title.replace('\n', ' '))
                with tag(html, 'meta', {'charset': 'UTF-8'}):
                    pass
                for k, v in SeriesModel.model.getMetaTags():
                    with tag(html, 'meta', {'name': k, 'content': v}):
                        pass
                with tag(html, 'style', dict(type="text/css")):
                    html.write('''
body{ font-family: sans-serif; }

#idRaceName {
	font-size: 200%;
	font-weight: bold;
}
#idImgHeader { box-shadow: 4px 4px 4px #888888; }
.smallfont { font-size: 80%; }
.bigfont { font-size: 120%; }
.hidden { display: none; }

table.results
{
	font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
	border-collapse:collapse;
}
table.results td, table.results th 
{
	font-size:1em;
	padding:3px 7px 2px 7px;
	text-align: left;
}
table.results th 
{
	font-size:1.1em;
	text-align:left;
	padding-top:5px;
	padding-bottom:4px;
	background-color:#7FE57F;
	color:#000000;
}
table.results tr.odd
{
	color:#000000;
	background-color:#EAF2D3;
}
table.results tr:hover
{
	color:#000000;
	background-color:#FFFFCC;
}
table.results tr.odd:hover
{
	color:#000000;
	background-color:#FFFFCC;
}

table.results td {
	border-top:1px solid #98bf21;
}

table.results td.noborder {
	border-top:0px solid #98bf21;
}

table.results td.rAlign, table.results th.rAlign {
	text-align:right;
}

table.results tr td.fastest{
	color:#000000;
	background-color:#80FF80;
}

@media print { .noprint { display: none; } }''')

            with tag(html, 'body'):
                ExportGrid(title, grid).toHtml(html)

        html = html.getvalue()

        try:
            with open(htmlfileName, 'wb') as fp:
                fp.write(html)
            webbrowser.open(htmlfileName, new=2, autoraise=True)
            Utils.MessageOK(self,
                            'Html file written to:\n\n   %s' % htmlfileName,
                            'Html Write')
        except IOError:
            Utils.MessageOK(
                self,
                'Cannot write "%s".\n\nCheck if this file is open.\nIf so, close it, and try again.'
                % htmlfileName,
                'Html File Error',
                iconMask=wx.ICON_ERROR)
Example #14
0
	def refresh( self ):
		self.category = None
		self.isEmpty = True
		self.iLastLap = 0
		self.rcInterp = set()	# Set of row/col coordinates of interpolated numbers.
		self.rcNumTime = set()
		
		self.search.SelectAll()
		
		CloseFinishTime = 0.07
		self.closeFinishBibs = defaultdict( list )
		
		race = Model.race
		if not race:
			self.clearGrid()
			return
		category = FixCategories( self.categoryChoice, getattr(race, 'resultsCategory', 0) )
		self.hbs.RecalcSizes()
		self.hbs.Layout()
		for si in self.hbs.GetChildren():
			if si.IsWindow():
				si.GetWindow().Refresh()
		self.category = category
		sortLap = getattr( race, 'sortLap', None )
		sortLabel = getattr( race, 'sortLabel', None )

		if race.isTimeTrial:
			def getSortTime( rr ):
				try:
					return rr.firstTime + rr._lastTimeOrig
				except:
					return 0
		else:
			def getSortTime( rr ):
				try:
					return rr._lastTimeOrig
				except:
					return 0
					
		results = sorted(
			(rr for rr in GetResults(category)
				if rr.status==Model.Rider.Finisher and rr.lapTimes and getSortTime(rr) > 0),
			key = getSortTime
		)
		for i in xrange(1, len(results)):
			if results[i]._lastTimeOrig - results[i-1]._lastTimeOrig <= CloseFinishTime:
				self.closeFinishBibs[results[i-1].num].append( results[i].num )
				self.closeFinishBibs[results[i].num].append( results[i-1].num )
		
		labelLastX, labelLastY = self.labelGrid.GetViewStart()
		lapLastX, lapLastY = self.lapGrid.GetViewStart()
		
		exportGrid = ExportGrid()
		exportGrid.setResultsOneList( category, self.showRiderData, showLapsFrequency = 1 )
		
		if not exportGrid.colnames:
			self.clearGrid()
			return

		# Fix the speed column.
		speedUnit = None
		iSpeedCol = None
		try:
			iSpeedCol = (i for i, c in enumerate(exportGrid.colnames) if c == _('Speed')).next()
		except StopIteration:
			pass
		if iSpeedCol is not None:
			for r, d in enumerate(exportGrid.data[iSpeedCol]):
				d = d.strip()
				if not d:
					continue
				dSplit = d.split()
				if not speedUnit and len(dSplit) > 1:
					exportGrid.colnames[iSpeedCol] = speedUnit = dSplit[1]
				exportGrid.data[iSpeedCol][r] = dSplit[0]
				if exportGrid.data[iSpeedCol][r] == '"':
					exportGrid.data[iSpeedCol][r] += '    '
			
		colnames = exportGrid.colnames
		data = exportGrid.data
		
		sortCol = None
		if sortLap:
			race.sortLabel = sortLabel = None
			for i, name in enumerate(colnames):
				if name.startswith(_('Lap')) and int(name.split()[1]) == sortLap:
					sortCol = i
					break
		elif sortLabel:
			race.sortLap = sortLap = None
			if sortLabel not in {_('Pos'), _('Gap'), _('Time'), _('mph'), _('km/h')}:
				for i, name in enumerate(colnames):
					if name == sortLabel:
						sortCol = i
						break
		if sortCol is None:
			race.sortLabel = race.sortLap = sortLabel = sortLap = None
		
		results = GetResults( category )
		hasSpeeds = False
		for result in results:
			if getattr(result, 'lapSpeeds', None) or getattr(result, 'raceSpeeds', None):
				hasSpeeds = True
				break
				
		if not hasSpeeds:
			self.showLapSpeedsRadio.Enable( False )
			self.showRaceSpeedsRadio.Enable( False )
			if self.selectDisplay > Results.DisplayRaceTimes:
				self.selectDisplay = Results.DisplayRaceTimes
				self.showRaceTimesRadio.SetValue( True )
		else:
			self.showLapSpeedsRadio.Enable( True )
			self.showRaceSpeedsRadio.Enable( True )
			
		for r in [self.showLapTimesRadio, self.showRaceTimesRadio, self.showLapSpeedsRadio, self.showRaceSpeedsRadio]:
			if r.GetValue():
				r.SetFont( self.boldFont )
			else:
				r.SetFont( wx.NullFont )
		self.hbs.RecalcSizes()
		self.hbs.Layout()
		
		# Find the fastest lap time.
		self.fastestLapRC, fastestLapSpeed, fastestLapTime = None, 0.0, sys.float_info.max
		for r, result in enumerate(results):
			if getattr(result, 'lapSpeeds', None):			# Use speeds if available.
				for c, s in enumerate(result.lapSpeeds):
					if s > fastestLapSpeed:
						fastestLapSpeed = s
						self.fastestLapRC = (r, c)
			elif result.lapTimes:							# Else, use times.
				for c, t in enumerate(result.lapTimes):
					if t < fastestLapTime:
						fastestLapTime = t
						self.fastestLapRC = (r, c)
		
		highPrecision = Model.highPrecisionTimes()
		try:
			firstLapCol = (i for i, name in enumerate(colnames) if name.startswith(_('Lap'))).next()
		except StopIteration:
			firstLapCol = len(colnames)
		
		# Convert to race times, lap speeds or race speeds as required.
		'''
			DisplayLapTimes = 0
			DisplayRaceTimes = 1
			DisplayLapSpeeds = 2
			DisplayRaceSpeeds = 3
		'''
		if self.selectDisplay == Results.DisplayRaceTimes:
			for r, result in enumerate(results):
				for i, t in enumerate(result.raceTimes[1:]):
					try:
						data[i+firstLapCol][r] = Utils.formatTimeCompressed(t, highPrecision)
					except IndexError:
						pass
		elif self.selectDisplay == Results.DisplayLapSpeeds:
			for r, result in enumerate(results):
				if getattr(result, 'lapSpeeds', None):
					for i, s in enumerate(result.lapSpeeds):
						try:
							data[i+firstLapCol][r] = u'{:.2f}'.format(s)
						except IndexError:
							pass
		elif self.selectDisplay == Results.DisplayRaceSpeeds:
			for r, result in enumerate(results):
				if getattr(result, 'raceSpeeds', None):
					for i, s in enumerate(result.raceSpeeds):
						try:
							data[i+firstLapCol][r] = u'{:.2f}'.format(s)
						except IndexError:
							pass
		
		# Sort by the given lap, if there is one.
		# Also, add a position for the lap itself.
		if sortCol is not None:
			maxVal = 1000.0*24.0*60.0*60.0
			if sortLap:
				if self.selectDisplay in [Results.DisplayLapTimes, Results.DisplayRaceTimes]:
					getFunc = Utils.StrToSeconds
				else:
					getFunc = lambda x: -float(x)
			else:
				if colnames[sortCol] in [_('Start'), _('Finish'), _('Time')]:
					getFunc = Utils.StrToSeconds
				elif colnames[sortCol] in [_('mph'), _('km')]:
					getFunc = lambda x: -float(x) if x else 0.0
				elif colnames[sortCol] == _('Factor'):
					getFunc = lambda x: float(x) if x else maxVal
				elif colnames[sortCol] in [_('Pos'), _('Bib')]:
					getFunc = lambda x: int(x) if x and unicode(x).isdigit() else maxVal
				else:
					getFunc = lambda x: u'{}'.format(x)
					maxVal = '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
			sortPairs = []
			for r, result in enumerate(results):
				try:
					k = (getFunc(data[sortCol][r]), r)
				except Exception as e:
					k = (maxVal, r)
				sortPairs.append( (k, r) )
			sortPairs.sort()
			
			for c in xrange(len(data)):
				col = data[c]
				data[c] = [col[i] if i < len(col) else u'' for k, i in sortPairs]
			
			if colnames[sortCol] != _('Bib'):
				for r in xrange(len(data[sortCol])):
					if data[sortCol][r]:
						data[sortCol][r] = u'{} [{}: {}]'.format(data[sortCol][r], r+1, data[1][r])
		
		# Highlight the sorted column.
		if sortLap:
			colnames = []
			for name in exportGrid.colnames:
				try:
					if int(name.split()[1]) == sortLap:
						name = u'<{}>\n{}'.format(name,
												[_('by Lap Time'), _('by Race Time'), _('by Lap Speed'), _('by Race Speed')][self.selectDisplay])
				except:
					pass
				colnames.append( name )
		elif sortLabel:
			colnames = []
			for name in exportGrid.colnames:
				if name == sortLabel:
					name = u'<{}>'.format(name)
				colnames.append( name )
		else:
			colnames = exportGrid.colnames
		
		try:
			iLabelMax = (i for i, name in enumerate(colnames) if name.startswith(_('Lap')) or name.startswith('<' + _('Lap'))).next()
		except StopIteration:
			iLabelMax = len(colnames)
		colnamesLabels = colnames[:iLabelMax]
		dataLabels = data[:iLabelMax]
		
		colnameLaps = colnames[iLabelMax:]
		dataLaps = data[iLabelMax:]
		
		self.labelGrid.Set( data = dataLabels, colnames = colnamesLabels )
		self.labelGrid.SetLeftAlignCols( exportGrid.leftJustifyCols )
		self.labelGrid.AutoSizeColumns( True )
		self.labelGrid.Reset()
		try:
			iUCICodeCol = colnamesLabels.index( _('UCICode') )
			self.labelGrid.SetColRenderer( iUCICodeCol, IOCCodeRenderer() )
		except ValueError:
			pass
		try:
			iNatCodeCol = colnamesLabels.index( _('NatCode') )
			self.labelGrid.SetColRenderer( iNatCodeCol, IOCCodeRenderer() )
		except ValueError:
			pass
		
		self.lapGrid.Set( data = dataLaps, colnames = colnameLaps )
		self.lapGrid.Reset()
		self.lapGrid.AutoSizeColumns( self.lapGrid.GetNumberCols() < 100 )
		
		self.isEmpty = False
		
		# Find interpolated entries.
		with Model.LockRace() as race:
			numTimeInfo = race.numTimeInfo
			riders = race.riders
			for r in xrange(self.lapGrid.GetNumberRows()):
				try:
					rider = riders[int(self.labelGrid.GetCellValue(r, 1))]
				except:
					continue
					
				try:
					entries = rider.interpolate()
				except (ValueError, IndexError):
					continue
				
				if not entries:
					continue
				for c in xrange(self.lapGrid.GetNumberCols()):
					if not self.lapGrid.GetCellValue(r, c):
						break
					try:
						if entries[c+1].interp:
							self.rcInterp.add( (r, c) )
						elif numTimeInfo.getInfo(entries[c+1].num, entries[c+1].t) is not None:
							self.rcNumTime.add( (r, c) )
						elif c > self.iLastLap:
							self.iLastLap = c
					except IndexError:
						pass
		
		self.labelGrid.Scroll( labelLastX, labelLastY )
		self.lapGrid.Scroll( lapLastX, lapLastY )
		self.showNumSelect()
		
		if self.firstDraw:
			self.firstDraw = False
			self.splitter.SetSashPosition( 400 )
		
		# Fix the grids' scrollbars.
		self.labelGrid.FitInside()
		self.lapGrid.FitInside()
Example #15
0
	def prepareGrid( self, page ):
		exportGrid = ExportGrid()
		with UnstartedRaceWrapper():
			exportGrid.setResultsOneList( self.pageInfo[page][0], True, showLapTimes=False )
		exportGrid.title = u'\n'.join( [_('Podium Results'), u'', exportGrid.title] )
		return exportGrid
Example #16
0
	def prepareGrid( self, page ):
		exportGrid = ExportGrid()
		showLapTimes = (not Model.race) or getattr( Model.race, 'includeLapTimesInPrintout', True )
		exportGrid.setResultsOneList( self.pageInfo[page][0], True, showLapTimes = showLapTimes )
		return exportGrid
Example #17
0
	def menuExportToHtml( self, event ):
		self.commit()
		iSelection = self.notebook.GetSelection()
		page = self.pages[iSelection]
		
		grid = None
		image = None
		try:
			grid = page.getGrid()
		except Exception as e:
			pass
		
		if not grid:
			try:
				image = page.getImage()
			except Exception as e:
				pass
				
		if not (grid or image):
			return
		
		try:
			pageTitle = self.pages[iSelection].getTitle()
		except:
			pageTitle = self.attrClassName[iSelection][2]
		
		if not self.fileName or len(self.fileName) < 4:
			Utils.MessageOK(self, u'You must Save before you can Export to Html', u'Excel Export')
			return

		pageTitle = Utils.RemoveDisallowedFilenameChars( pageTitle.replace(u'/', u'_') )
		htmlFName = self.fileName[:-4] + '-' + pageTitle + '.html'
		dlg = wx.DirDialog( self, u'Folder to write "%s"' % os.path.basename(htmlFName),
						style=wx.DD_DEFAULT_STYLE, defaultPath=os.path.dirname(htmlFName) )
		ret = dlg.ShowModal()
		dName = dlg.GetPath()
		dlg.Destroy()
		if ret != wx.ID_OK:
			return

		htmlFName = os.path.join( dName, os.path.basename(htmlFName) )

		title = self.getTitle()
		
		htmlStream = StringIO()
		html = codecs.getwriter('utf8')( htmlStream )
		
		with tag(html, 'html'):
			with tag(html, 'head'):
				with tag(html, 'title'):
					html.write( title.replace(u'\n', u' ') )
				with tag(html, 'meta', dict(charset="UTF-8", author="Edward Sitarski", copyright="Edward Sitarski, 2013", generator="SprintMgr")):
					pass
				with tag(html, 'style', dict( type="text/css")):
					html.write( '''
body{ font-family: sans-serif; }

#idRaceName {
	font-size: 200%;
	font-weight: bold;
}
#idImgHeader { box-shadow: 4px 4px 4px #888888; }
.smallfont { font-size: 80%; }
.bigfont { font-size: 120%; }
.hidden { display: none; }

table.results
{
	font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
	border-collapse:collapse;
}
table.results td, table.results th 
{
	font-size:1em;
	padding:3px 7px 2px 7px;
	text-align: left;
}
table.results th 
{
	font-size:1.1em;
	text-align:left;
	padding-top:5px;
	padding-bottom:4px;
	background-color:#7FE57F;
	color:#000000;
}
table.results tr.odd
{
	color:#000000;
	background-color:#EAF2D3;
}
table.results tr:hover
{
	color:#000000;
	background-color:#FFFFCC;
}
table.results tr.odd:hover
{
	color:#000000;
	background-color:#FFFFCC;
}

table.results td {
	border-top:1px solid #98bf21;
}

table.results td.noborder {
	border-top:0px solid #98bf21;
}

table.results td.rAlign, table.results th.rAlign {
	text-align:right;
}

table.results tr td.fastest{
	color:#000000;
	background-color:#80FF80;
}

@media print { .noprint { display: none; } }''' )

			with tag(html, 'body'):
				if grid:
					ExportGrid( title, grid ).toHtml(html)
				elif image:
					pngFName = os.path.join( dName, '{}.png'.format(uuid.uuid4()) )
					image.SaveFile( pngFName, wx.BITMAP_TYPE_PNG )
					with open(pngFName, 'rb') as fp:
						data = base64.b64encode( fp.read() )
					os.remove( pngFName )
					writeHtmlHeader( html, title )
					html.write( '<img id="idResultsSummary" src="data:image/png;base64,%s" />' % data )
		
		html = htmlStream.getvalue()
		
		try:
			with open(htmlFName, 'wb') as fp:
				fp.write( html )
			webbrowser.open( htmlFName, new = 2, autoraise = True )
			Utils.MessageOK(self, u'Html file written to:\n\n   %s' % htmlFName, 'Html Write')
		except IOError:
			Utils.MessageOK(self,
						u'Cannot write "%s".\n\nCheck if this file is open.\nIf so, close it, and try again.' % htmlFName,
						u'Html File Error', iconMask=wx.ICON_ERROR )
Example #18
0
 def OnPrintPage(self, page):
     exportGrid = ExportGrid(self.title, self.grid)
     dc = self.GetDC()
     exportGrid.drawToFitDC(dc)
     return True
Example #19
0
    def refresh(self):
        self.category = None
        self.isEmpty = True
        self.iLastLap = 0
        self.rcInterp = set(
        )  # Set of row/col coordinates of interpolated numbers.
        self.rcNumTime = set()

        self.search.SelectAll()

        CloseFinishTime = 0.07
        self.closeFinishBibs = defaultdict(list)

        race = Model.race
        if not race:
            self.clearGrid()
            return
        category = FixCategories(self.categoryChoice,
                                 getattr(race, 'resultsCategory', 0))
        self.hbs.RecalcSizes()
        self.hbs.Layout()
        for si in self.hbs.GetChildren():
            if si.IsWindow():
                si.GetWindow().Refresh()
        self.category = category
        sortLap = getattr(race, 'sortLap', None)
        sortLabel = getattr(race, 'sortLabel', None)

        if race.isTimeTrial:

            def getSortTime(rr):
                try:
                    return rr.firstTime + rr._lastTimeOrig
                except:
                    return 0
        else:

            def getSortTime(rr):
                try:
                    return rr._lastTimeOrig
                except:
                    return 0

        results = sorted((rr for rr in GetResults(category)
                          if rr.status == Model.Rider.Finisher and rr.lapTimes
                          and getSortTime(rr) > 0),
                         key=getSortTime)
        for i in range(1, len(results)):
            if results[i]._lastTimeOrig - results[
                    i - 1]._lastTimeOrig <= CloseFinishTime:
                self.closeFinishBibs[results[i - 1].num].append(results[i].num)
                self.closeFinishBibs[results[i].num].append(results[i - 1].num)

        labelLastX, labelLastY = self.labelGrid.GetViewStart()
        lapLastX, lapLastY = self.lapGrid.GetViewStart()

        exportGrid = ExportGrid()
        exportGrid.setResultsOneList(category,
                                     self.showRiderData,
                                     showLapsFrequency=1)

        if not exportGrid.colnames:
            self.clearGrid()
            return

        # Fix the speed column.
        speedUnit = None
        iSpeedCol = None
        try:
            iSpeedCol = next(i for i, c in enumerate(exportGrid.colnames)
                             if c == _('Speed'))
        except StopIteration:
            pass
        if iSpeedCol is not None:
            for r, d in enumerate(exportGrid.data[iSpeedCol]):
                d = d.strip()
                if not d:
                    continue
                dSplit = d.split()
                if not speedUnit and len(dSplit) > 1:
                    exportGrid.colnames[iSpeedCol] = speedUnit = dSplit[1]
                exportGrid.data[iSpeedCol][r] = dSplit[0]
                if exportGrid.data[iSpeedCol][r] == '"':
                    exportGrid.data[iSpeedCol][r] += '    '

        colnames = exportGrid.colnames
        data = exportGrid.data

        sortCol = None
        if sortLap:
            race.sortLabel = sortLabel = None
            for i, name in enumerate(colnames):
                if name.startswith(_('Lap')) and int(
                        name.split()[1]) == sortLap:
                    sortCol = i
                    break
        elif sortLabel:
            race.sortLap = sortLap = None
            if sortLabel not in {
                    _('Pos'),
                    _('Gap'),
                    _('Time'),
                    _('mph'),
                    _('km/h')
            }:
                for i, name in enumerate(colnames):
                    if name == sortLabel:
                        sortCol = i
                        break
        if sortCol is None:
            race.sortLabel = race.sortLap = sortLabel = sortLap = None

        results = GetResults(category)
        hasSpeeds = False
        for result in results:
            if getattr(result, 'lapSpeeds', None) or getattr(
                    result, 'raceSpeeds', None):
                hasSpeeds = True
                break

        if not hasSpeeds:
            self.showLapSpeedsRadio.Enable(False)
            self.showRaceSpeedsRadio.Enable(False)
            if self.selectDisplay > Results.DisplayRaceTimes:
                self.selectDisplay = Results.DisplayRaceTimes
                self.showRaceTimesRadio.SetValue(True)
        else:
            self.showLapSpeedsRadio.Enable(True)
            self.showRaceSpeedsRadio.Enable(True)

        for r in [
                self.showLapTimesRadio, self.showRaceTimesRadio,
                self.showLapSpeedsRadio, self.showRaceSpeedsRadio
        ]:
            if r.GetValue():
                r.SetFont(self.boldFont)
            else:
                r.SetFont(wx.NullFont)
        self.hbs.RecalcSizes()
        self.hbs.Layout()

        # Find the fastest lap time.
        self.fastestLapRC, fastestLapSpeed, fastestLapTime = None, 0.0, sys.float_info.max
        for r, result in enumerate(results):
            if getattr(result, 'lapSpeeds', None):  # Use speeds if available.
                for c, s in enumerate(result.lapSpeeds):
                    if s > fastestLapSpeed:
                        fastestLapSpeed = s
                        self.fastestLapRC = (r, c)
            elif result.lapTimes:  # Else, use times.
                for c, t in enumerate(result.lapTimes):
                    if t < fastestLapTime:
                        fastestLapTime = t
                        self.fastestLapRC = (r, c)

        highPrecision = Model.highPrecisionTimes()
        try:
            firstLapCol = next(i for i, name in enumerate(colnames)
                               if name.startswith(_('Lap')))
        except StopIteration:
            firstLapCol = len(colnames)

        # Convert to race times, lap speeds or race speeds as required.
        '''
			DisplayLapTimes = 0
			DisplayRaceTimes = 1
			DisplayLapSpeeds = 2
			DisplayRaceSpeeds = 3
		'''
        if self.selectDisplay == Results.DisplayRaceTimes:
            for r, result in enumerate(results):
                for i, t in enumerate(result.raceTimes[1:]):
                    try:
                        data[i + firstLapCol][r] = Utils.formatTimeCompressed(
                            t, highPrecision)
                    except IndexError:
                        pass
        elif self.selectDisplay == Results.DisplayLapSpeeds:
            for r, result in enumerate(results):
                if getattr(result, 'lapSpeeds', None):
                    for i, s in enumerate(result.lapSpeeds):
                        try:
                            data[i + firstLapCol][r] = u'{:.2f}'.format(s)
                        except IndexError:
                            pass
        elif self.selectDisplay == Results.DisplayRaceSpeeds:
            for r, result in enumerate(results):
                if getattr(result, 'raceSpeeds', None):
                    for i, s in enumerate(result.raceSpeeds):
                        try:
                            data[i + firstLapCol][r] = u'{:.2f}'.format(s)
                        except IndexError:
                            pass

        # Sort by the given lap, if there is one.
        # Also, add a position for the lap itself.
        if sortCol is not None:
            maxVal = 1000.0 * 24.0 * 60.0 * 60.0
            if sortLap:
                if self.selectDisplay in [
                        Results.DisplayLapTimes, Results.DisplayRaceTimes
                ]:
                    getFunc = Utils.StrToSeconds
                else:
                    getFunc = lambda x: -float(x)
            else:
                if colnames[sortCol] in [_('Start'), _('Finish'), _('Time')]:
                    getFunc = Utils.StrToSeconds
                elif colnames[sortCol] in [_('mph'), _('km')]:
                    getFunc = lambda x: -float(x) if x else 0.0
                elif colnames[sortCol] == _('Factor'):
                    getFunc = lambda x: float(x) if x else maxVal
                elif colnames[sortCol] in [_('Pos'), _('Bib')]:
                    getFunc = lambda x: int(x) if x and six.text_type(
                        x).isdigit() else maxVal
                else:
                    getFunc = lambda x: u'{}'.format(x)
                    maxVal = '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
            sortPairs = []
            for r, result in enumerate(results):
                try:
                    k = (getFunc(data[sortCol][r]), r)
                except Exception as e:
                    k = (maxVal, r)
                sortPairs.append((k, r))
            sortPairs.sort()

            for c in range(len(data)):
                col = data[c]
                data[c] = [
                    col[i] if i < len(col) else u'' for k, i in sortPairs
                ]

            if colnames[sortCol] != _('Bib'):
                for r in range(len(data[sortCol])):
                    if data[sortCol][r]:
                        data[sortCol][r] = u'{} [{}: {}]'.format(
                            data[sortCol][r], r + 1, data[1][r])

        # Highlight the sorted column.
        if sortLap:
            colnames = []
            for name in exportGrid.colnames:
                try:
                    if int(name.split()[1]) == sortLap:
                        name = u'<{}>\n{}'.format(name, [
                            _('by Lap Time'),
                            _('by Race Time'),
                            _('by Lap Speed'),
                            _('by Race Speed')
                        ][self.selectDisplay])
                except:
                    pass
                colnames.append(name)
        elif sortLabel:
            colnames = []
            for name in exportGrid.colnames:
                if name == sortLabel:
                    name = u'<{}>'.format(name)
                colnames.append(name)
        else:
            colnames = exportGrid.colnames

        try:
            iLabelMax = next(
                i for i, name in enumerate(colnames)
                if name.startswith(_('Lap')) or name.startswith('<' +
                                                                _('Lap')))
        except StopIteration:
            iLabelMax = len(colnames)
        colnamesLabels = colnames[:iLabelMax]
        dataLabels = data[:iLabelMax]

        colnameLaps = colnames[iLabelMax:]
        dataLaps = data[iLabelMax:]

        self.labelGrid.Set(data=dataLabels, colnames=colnamesLabels)
        self.labelGrid.SetLeftAlignCols(exportGrid.leftJustifyCols)
        self.labelGrid.AutoSizeColumns(True)
        self.labelGrid.Reset()
        try:
            iUCICodeCol = colnamesLabels.index(_('UCICode'))
            self.labelGrid.SetColRenderer(iUCICodeCol, IOCCodeRenderer())
        except ValueError:
            pass
        try:
            iNatCodeCol = colnamesLabels.index(_('NatCode'))
            self.labelGrid.SetColRenderer(iNatCodeCol, IOCCodeRenderer())
        except ValueError:
            pass

        self.lapGrid.Set(data=dataLaps, colnames=colnameLaps)
        self.lapGrid.Reset()
        self.lapGrid.AutoSizeColumns(self.lapGrid.GetNumberCols() < 100)

        self.isEmpty = False

        # Find interpolated entries.
        with Model.LockRace() as race:
            numTimeInfo = race.numTimeInfo
            riders = race.riders
            for r in range(self.lapGrid.GetNumberRows()):
                try:
                    rider = riders[int(self.labelGrid.GetCellValue(r, 1))]
                except:
                    continue

                try:
                    entries = rider.interpolate()
                except (ValueError, IndexError):
                    continue

                if not entries:
                    continue
                for c in range(self.lapGrid.GetNumberCols()):
                    if not self.lapGrid.GetCellValue(r, c):
                        break
                    try:
                        if entries[c + 1].interp:
                            self.rcInterp.add((r, c))
                        elif numTimeInfo.getInfo(entries[c + 1].num,
                                                 entries[c + 1].t) is not None:
                            self.rcNumTime.add((r, c))
                        elif c > self.iLastLap:
                            self.iLastLap = c
                    except IndexError:
                        pass

        self.labelGrid.Scroll(labelLastX, labelLastY)
        self.lapGrid.Scroll(lapLastX, lapLastY)
        self.showNumSelect()

        if self.firstDraw:
            self.firstDraw = False
            self.splitter.SetSashPosition(400)

        # Fix the grids' scrollbars.
        self.labelGrid.FitInside()
        self.lapGrid.FitInside()