From 02907ecf8ea4445ae5fb503aaac1e46cd0c84fa5 Mon Sep 17 00:00:00 2001 From: esitarski Date: Thu, 25 Jul 2024 16:52:18 -0400 Subject: [PATCH] Fixed up flake8 errors. --- CallupSeedingMgr/CallupResultsToExcel.py | 4 +- CallupSeedingMgr/CallupResultsToGrid.py | 2 +- CallupSeedingMgr/CallupSeedingMgrSetup.py | 3 +- CallupSeedingMgr/CopyMedia.py | 2 +- CallupSeedingMgr/CountryIOC.py | 4 +- CallupSeedingMgr/FitSheetWrapper.py | 1 - CallupSeedingMgr/GetCallups.py | 8 +- CallupSeedingMgr/HelpIndex.py | 4 +- CallupSeedingMgr/MainWin.py | 81 ++- CallupSeedingMgr/Model.py | 12 +- CallupSeedingMgr/Utils.py | 14 +- CallupSeedingMgr/Version.py | 2 +- CrossMgrAlien/Alien.py | 10 +- CrossMgrAlien/Alien2JChip.py | 9 +- CrossMgrAlien/AlienClient.py | 1 - CrossMgrAlien/AlienReader.py | 59 ++- CrossMgrAlien/CrossMgrAlienSetup.py | 7 +- CrossMgrAlien/MainWin.py | 27 +- CrossMgrAlien/Utils.py | 8 +- CrossMgrAlien/Version.py | 2 +- CrossMgrAlien/roundbutton.py | 10 - CrossMgrImpinj/AntennaReads.py | 2 + CrossMgrImpinj/CrossMgrImpinjSetup.py | 4 +- CrossMgrImpinj/Dependencies.py | 1 + CrossMgrImpinj/Impinj.py | 13 +- CrossMgrImpinj/Impinj2JChip.py | 4 +- CrossMgrImpinj/ImpinjClient.py | 3 +- CrossMgrImpinj/MainWin.py | 30 +- CrossMgrImpinj/QuadReg.py | 1 - CrossMgrImpinj/TagGroup.py | 4 +- CrossMgrImpinj/TagGroupTest.py | 2 +- CrossMgrImpinj/UpdateDependencies.py | 26 + CrossMgrImpinj/Utils.py | 13 +- CrossMgrImpinj/Version.py | 2 +- CrossMgrImpinj/pypi.py | 7 +- CrossMgrImpinj/roundbutton.py | 594 ---------------------- PointsRaceMgr/Commentary.py | 5 +- PointsRaceMgr/Configure.py | 9 +- PointsRaceMgr/CopyMedia.py | 2 +- PointsRaceMgr/EventList.py | 2 - PointsRaceMgr/ExportGrid.py | 8 +- PointsRaceMgr/MainWin.py | 30 +- PointsRaceMgr/Model.py | 14 +- PointsRaceMgr/PointsRaceMgrSetup.py | 9 +- PointsRaceMgr/RankDetails.py | 1 - PointsRaceMgr/RankSummary.py | 2 - PointsRaceMgr/ReorderableGrid.py | 2 +- PointsRaceMgr/StartList.py | 28 +- PointsRaceMgr/ToPrintout.py | 8 +- PointsRaceMgr/Utils.py | 13 +- PointsRaceMgr/Version.py | 2 +- PointsRaceMgr/VirusTotalSubmit.py | 2 +- SeriesMgr/Aliases.py | 2 - SeriesMgr/AliasesCategory.py | 2 - SeriesMgr/AliasesLicense.py | 2 - SeriesMgr/AliasesTeam.py | 2 - SeriesMgr/CategorySequence.py | 5 +- SeriesMgr/CmdLine.py | 12 +- SeriesMgr/Errors.py | 4 +- SeriesMgr/ExportGrid.py | 1 - SeriesMgr/FieldMap.py | 2 +- SeriesMgr/FileTrie.py | 6 + SeriesMgr/FtpWriteFile.py | 8 +- SeriesMgr/GetModelInfo.py | 32 +- SeriesMgr/MainWin.py | 66 ++- SeriesMgr/Options.py | 7 +- SeriesMgr/Points.py | 7 +- SeriesMgr/Races.py | 4 - SeriesMgr/ReadRaceResultsSheet.py | 9 +- SeriesMgr/Results.py | 36 +- SeriesMgr/Sequence.py | 8 +- SeriesMgr/SeriesMgrSetup.py | 14 +- SeriesMgr/SeriesModel.py | 32 +- SeriesMgr/TeamResults.py | 29 +- SeriesMgr/TeamResultsNames.py | 9 +- SeriesMgr/Upgrades.py | 6 +- SeriesMgr/Version.py | 2 +- SeriesMgr/virustotal_submit.py | 8 +- SprintMgr/Chart.py | 2 - SprintMgr/Events.py | 13 +- SprintMgr/ExportGrid.py | 3 +- SprintMgr/FieldDef.py | 2 - SprintMgr/GraphDraw.py | 6 +- SprintMgr/HighPrecisionTimeEdit.py | 28 +- SprintMgr/MainWin.py | 40 +- SprintMgr/Model.py | 5 +- SprintMgr/Properties.py | 2 - SprintMgr/Qualifiers.py | 6 - SprintMgr/ReadStartList.py | 25 +- SprintMgr/ReorderableGrid.py | 2 +- SprintMgr/Results.py | 4 - SprintMgr/Seeding.py | 4 +- SprintMgr/SetGraphic.py | 3 +- SprintMgr/Simulate.py | 8 +- SprintMgr/TestData.py | 1 - SprintMgr/Utils.py | 3 +- SprintMgr/Version.py | 2 +- SprintMgr/arial10.py | 2 +- SprintMgr/printout.py | 36 +- StageRaceGC/MainWin.py | 78 ++- StageRaceGC/MakeExampleExcel.py | 8 +- StageRaceGC/Model.py | 33 +- StageRaceGC/StageRaceGCToExcel.py | 101 ++-- StageRaceGC/StageRaceGCToGrid.py | 106 ++-- StageRaceGC/Utils.py | 24 +- StageRaceGC/Version.py | 2 +- TagReadWrite/MainWin.py | 30 +- flake8_ignore.txt | 2 + 108 files changed, 587 insertions(+), 1422 deletions(-) create mode 100644 CrossMgrImpinj/Dependencies.py create mode 100644 CrossMgrImpinj/UpdateDependencies.py delete mode 100644 CrossMgrImpinj/roundbutton.py diff --git a/CallupSeedingMgr/CallupResultsToExcel.py b/CallupSeedingMgr/CallupResultsToExcel.py index e218f7aa..93270185 100644 --- a/CallupSeedingMgr/CallupResultsToExcel.py +++ b/CallupSeedingMgr/CallupResultsToExcel.py @@ -1,8 +1,6 @@ -import wx -import sys import datetime import xlsxwriter -import Utils + import Model from FitSheetWrapper import FitSheetWrapper from GetCallups import make_title diff --git a/CallupSeedingMgr/CallupResultsToGrid.py b/CallupSeedingMgr/CallupResultsToGrid.py index ce2c06e1..63915530 100644 --- a/CallupSeedingMgr/CallupResultsToGrid.py +++ b/CallupSeedingMgr/CallupResultsToGrid.py @@ -1,6 +1,6 @@ import wx import wx.grid as gridlib -import sys + import Utils import Model from GetCallups import make_title diff --git a/CallupSeedingMgr/CallupSeedingMgrSetup.py b/CallupSeedingMgr/CallupSeedingMgrSetup.py index da69da2b..087ca231 100644 --- a/CallupSeedingMgr/CallupSeedingMgrSetup.py +++ b/CallupSeedingMgr/CallupSeedingMgrSetup.py @@ -26,7 +26,7 @@ 'pyinstaller', 'CallupSeedingMgr.pyw', - '--icon=CallupSeedingMgrImages\CallupSeedingMgr.ico', + '--icon=CallupSeedingMgrImages/CallupSeedingMgr.ico', '--clean', '--windowed', '--noconfirm', @@ -71,7 +71,6 @@ def copyDir( d ): inno = innoTest break -from Version import AppVerName def make_inno_version(): setup = { 'AppName': AppVerName.split()[0], diff --git a/CallupSeedingMgr/CopyMedia.py b/CallupSeedingMgr/CopyMedia.py index 8388be0f..5b72ec9e 100644 --- a/CallupSeedingMgr/CopyMedia.py +++ b/CallupSeedingMgr/CopyMedia.py @@ -8,7 +8,7 @@ def NeedsUpdating( srcFName, destFName ): try: srcStat = os.stat( srcFName ) destStat = os.stat( destFName ) - except: + except Exception: return True return srcStat.st_mtime > destStat.st_mtime or srcStat.st_size != destStat.st_size diff --git a/CallupSeedingMgr/CountryIOC.py b/CallupSeedingMgr/CountryIOC.py index 5c5e4812..34b8e7d4 100644 --- a/CallupSeedingMgr/CountryIOC.py +++ b/CallupSeedingMgr/CountryIOC.py @@ -1,14 +1,13 @@ # -*- coding: utf-8 -*- import os -import io import json from Utils import imageFolder, removeDiacritic # from https://github.com/mledoze/countries fname = os.path.join( imageFolder, 'countries.json' ) -with io.open(fname, mode='r', encoding='utf8') as fp: +with open(fname, mode='r', encoding='utf8') as fp: country_info = json.loads( fp.read() ) uci_country_codes = {} @@ -23,6 +22,7 @@ for c in country_info: names = set() + def scan( d ): for k, v in d.items(): if isinstance(v, dict): diff --git a/CallupSeedingMgr/FitSheetWrapper.py b/CallupSeedingMgr/FitSheetWrapper.py index f5fd5961..88a64f6b 100644 --- a/CallupSeedingMgr/FitSheetWrapper.py +++ b/CallupSeedingMgr/FitSheetWrapper.py @@ -1,6 +1,5 @@ import datetime import Utils -import math class FitSheetWrapper(object): """Try to fit columns to max size of any entry. diff --git a/CallupSeedingMgr/GetCallups.py b/CallupSeedingMgr/GetCallups.py index dce0603d..2d2d769e 100644 --- a/CallupSeedingMgr/GetCallups.py +++ b/CallupSeedingMgr/GetCallups.py @@ -1,7 +1,5 @@ -import os import sys -import datetime -import Utils + import random from Model import Source from Excel import GetExcelReader @@ -121,7 +119,7 @@ def GetCallups( fname, soundalike=True, useUciId=True, useLicense=True, callback registration_headers = registration.get_ordered_fields() # Also add the team code if there is one. - if not 'team_code' in registration_headers: + if 'team_code' not in registration_headers: for iSource, source in enumerate(sources): if 'team_code' in source.get_ordered_fields(): try: @@ -137,7 +135,7 @@ def GetCallups( fname, soundalike=True, useUciId=True, useLicense=True, callback for reg in callup_order: try: reg.team_code = reg.result_vector[iSource].matches[0].team_code - except: + except Exception: pass break diff --git a/CallupSeedingMgr/HelpIndex.py b/CallupSeedingMgr/HelpIndex.py index b98a85ea..c239860b 100644 --- a/CallupSeedingMgr/HelpIndex.py +++ b/CallupSeedingMgr/HelpIndex.py @@ -54,13 +54,13 @@ def addDocument( fname, section, lastTitle, textCur ): for child in div.contents: try: tag = child.name - except: + except Exception: tag = None if tag not in titleTags: try: textCur.append( child.get_text() ) - except: + except Exception: pass continue diff --git a/CallupSeedingMgr/MainWin.py b/CallupSeedingMgr/MainWin.py index 38aea895..5b4db99c 100644 --- a/CallupSeedingMgr/MainWin.py +++ b/CallupSeedingMgr/MainWin.py @@ -1,20 +1,16 @@ -import wx -import wx.adv -from wx.lib.wordwrap import wordwrap -import wx.lib.filebrowsebutton as filebrowse -import sys import os -import re import datetime import traceback import webbrowser from optparse import OptionParser from roundbutton import RoundButton +import wx +import wx.adv +import wx.lib.filebrowsebutton as filebrowse + import Utils from ReorderableGrid import ReorderableGrid -import Model -import Version from GetCallups import GetCallups, make_title from CallupResultsToGrid import CallupResultsToGrid from CallupResultsToExcel import CallupResultsToExcel @@ -25,7 +21,7 @@ def ShowSplashScreen(): bitmap = wx.Bitmap( os.path.join(Utils.getImageFolder(), 'CallupSeedingMgr.png'), wx.BITMAP_TYPE_PNG ) showSeconds = 2.5 - frame = wx.adv.SplashScreen(bitmap, wx.adv.SPLASH_CENTRE_ON_SCREEN|wx.adv.SPLASH_TIMEOUT, int(showSeconds*1000), None) + wx.adv.SplashScreen(bitmap, wx.adv.SPLASH_CENTRE_ON_SCREEN|wx.adv.SPLASH_TIMEOUT, int(showSeconds*1000), None) class ErrorDialog( wx.Dialog ): def __init__( self, parent, errors, id=wx.ID_ANY, title='Errors', size=(800,600) ): @@ -452,7 +448,7 @@ def getCycleLast( self ): def doUpdate( self, event=None, fnameNew=None ): try: self.fname = fnameNew or (event and event.GetString()) or self.fileBrowse.GetValue() - except: + except Exception: self.fname = '' if not self.fname: @@ -464,7 +460,7 @@ def doUpdate( self, event=None, fnameNew=None ): return try: - with open(self.fname, 'rb') as f: + with open(self.fname, 'rb'): pass except Exception as e: Utils.MessageOK( self, '{}:\n\n {}\n\n{}'.format( _('Cannot Open Excel file'), self.fname, e), _('Cannot Open Excel File') ) @@ -473,37 +469,38 @@ def doUpdate( self, event=None, fnameNew=None ): self.filehistory.AddFileToHistory( self.fname ) self.filehistory.Save( self.config ) + + with wx.BusyCursor(): + labelSave, backgroundColourSave = self.updateButton.GetLabel(), self.updateButton.GetForegroundColour() + + try: + self.registration_headers, self.callup_headers, self.callup_results, self.sources, self.errors = GetCallups( + self.fname, + soundalike = self.getIsSoundalike(), + useUciId = self.getUseUciId(), + useLicense = self.getUseLicense(), + callbackfunc = self.updateSourceList, + callbackupdate = self.callbackUpdate, + cycleLast = self.getCycleLast(), + ) + except Exception as e: + traceback.print_exc() + Utils.MessageOK( self, '{}:\n\n {}\n\n{}'.format( _('Excel File Error'), self.fname, e), _('Excel File Error') ) + self.setUpdated( False ) + return - wait = wx.BusyCursor() - labelSave, backgroundColourSave = self.updateButton.GetLabel(), self.updateButton.GetForegroundColour() - - try: - self.registration_headers, self.callup_headers, self.callup_results, self.sources, self.errors = GetCallups( - self.fname, - soundalike = self.getIsSoundalike(), - useUciId = self.getUseUciId(), - useLicense = self.getUseLicense(), - callbackfunc = self.updateSourceList, - callbackupdate = self.callbackUpdate, - cycleLast = self.getCycleLast(), + self.setUpdated( True ) + + self.updateSourceList() + + CallupResultsToGrid( + self.grid, + self.registration_headers, self.callup_headers, self.callup_results, + is_callup=(self.callupSeedingRB.GetSelection() == 0), + top_riders=self.getTopRiders(), + exclude_unranked=self.excludeUnrankedCB.GetValue(), ) - except Exception as e: - traceback.print_exc() - Utils.MessageOK( self, '{}:\n\n {}\n\n{}'.format( _('Excel File Error'), self.fname, e), _('Excel File Error') ) - self.setUpdated( False ) - return - self.setUpdated( True ) - - self.updateSourceList() - - CallupResultsToGrid( - self.grid, - self.registration_headers, self.callup_headers, self.callup_results, - is_callup=(self.callupSeedingRB.GetSelection() == 0), - top_riders=self.getTopRiders(), - exclude_unranked=self.excludeUnrankedCB.GetValue(), - ) self.GetSizer().Layout() self.lastUpdateTime = datetime.datetime.now() @@ -580,12 +577,12 @@ def MainLoop(): logSize = os.path.getsize( redirectFileName ) if logSize > 1000000: os.remove( redirectFileName ) - except: + except Exception: pass try: app.RedirectStdio( redirectFileName ) - except: + except Exception: pass mainWin = MainWin( None, title=AppVerName, size=(800,600) ) @@ -596,7 +593,7 @@ def MainLoop(): try: icon = wx.Icon( os.path.join(Utils.getImageFolder(), 'CallupSeedingMgr.ico'), wx.BITMAP_TYPE_ICO ) mainWin.SetIcon( icon ) - except: + except Exception: pass mainWin.Show() diff --git a/CallupSeedingMgr/Model.py b/CallupSeedingMgr/Model.py index 1254b170..310b52de 100644 --- a/CallupSeedingMgr/Model.py +++ b/CallupSeedingMgr/Model.py @@ -1,4 +1,3 @@ -import os import re import sys import datetime @@ -7,8 +6,7 @@ from metaphone import doublemetaphone import Utils -from Excel import GetExcelReader -from CountryIOC import uci_country_codes, uci_country_codes_set, ioc_from_country, country_from_ioc +from CountryIOC import uci_country_codes, ioc_from_country, country_from_ioc countryTranslations = { 'England': 'United Kingdom', @@ -431,7 +429,7 @@ def get_sort_key( self ): key = self.get_key() try: row = self.matches[0].row - except: + except Exception: row = 999999 # Add the row as a sort criteria. return key + tuple([row]) if isinstance(key, tuple) else (key, row) @@ -507,6 +505,7 @@ class Source: 'by_mp_last_name', 'by_mp_first_name', 'by_nation_code', 'by_date_of_birth', 'by_age', ) + def __init__( self, fname, sheet_name, soundalike=True, useUciId=True, useLicense=True ): self.fname = fname self.sheet_name = sheet_name @@ -541,7 +540,6 @@ def get_cmp_policy_name( self ): def read( self, reader ): header_fields = ['name'] + list(Result.Fields) - dCur = datetime.date.today() header_map = {} errors = [] for row_number, row in enumerate(reader.iter_list(self.sheet_name)): @@ -660,7 +658,7 @@ def add( self, result ): assert idx_name != 'by_license' or v not in idx, 'Duplicate license: {}'.format(v) try: key = normalize_name_lookup(v) - except: + except Exception: key = v try: idx[key].append( result ) @@ -701,7 +699,7 @@ def match_indices( self, search, indices ): try: v = normalize_name_lookup( v ) - except: + except Exception: pass if self.debug: print( 'match_indices: value=', v ) diff --git a/CallupSeedingMgr/Utils.py b/CallupSeedingMgr/Utils.py index 87d1258a..5ec412ce 100644 --- a/CallupSeedingMgr/Utils.py +++ b/CallupSeedingMgr/Utils.py @@ -12,20 +12,14 @@ def initTranslation(): if not initTranslationCalled: try: gettext.install(AppVerName.split(None, 1), './locale', unicode=True) - except: + except Exception: gettext.install(AppVerName.split(None, 1), './locale') initTranslationCalled = True initTranslation() -try: - from win32com.shell import shell, shellcon -except ImportError: - pass - import os -import re import sys import platform import datetime @@ -40,7 +34,7 @@ def removeDiacritic( s ): ''' try: return unicodedata.normalize('NFKD', '{}'.format(s)).encode('ASCII', 'ignore').decode() - except: + except Exception: return s ''' @@ -95,7 +89,7 @@ def AdjustGridSize( grid, rowsRequired = None, colsRequired = None ): if 'WXMAC' in wx.Platform: try: topdirName = os.environ['RESOURCEPATH'] - except: + except Exception: topdirName = os.path.dirname(os.path.realpath(__file__)) if os.path.isdir( os.path.join(topdirName, 'CallupSeedingMgrImages') ): dirName = topdirName @@ -109,7 +103,7 @@ def AdjustGridSize( grid, rowsRequired = None, colsRequired = None ): else: try: dirName = os.path.dirname(os.path.abspath(__file__)) - except: + except Exception: dirName = os.path.dirname(os.path.abspath(sys.argv[0])) if os.path.basename(dirName) in ['library.zip', 'MainWin.exe', 'CrossMgrCallUpSeedingMgr.exe']: diff --git a/CallupSeedingMgr/Version.py b/CallupSeedingMgr/Version.py index 448593ce..6e39623f 100644 --- a/CallupSeedingMgr/Version.py +++ b/CallupSeedingMgr/Version.py @@ -1 +1 @@ -AppVerName="CallupSeedingMgr 4.0.0-private" +AppVerName="CallupSeedingMgr 4.0.1-private" diff --git a/CrossMgrAlien/Alien.py b/CrossMgrAlien/Alien.py index 58e710e0..8cf9daa7 100644 --- a/CrossMgrAlien/Alien.py +++ b/CrossMgrAlien/Alien.py @@ -1,10 +1,8 @@ import re import os -import six import time import math import socket -import threading import datetime import xml import xml.etree.ElementTree @@ -15,7 +13,7 @@ from xml.dom.minidom import parseString import traceback from queue import Empty -from Utils import readDelimitedData, timeoutSecs, Bell +from Utils import Bell HOME_DIR = os.path.expanduser("~") @@ -146,7 +144,7 @@ def checkKeepGoing( self ): try: # Check the shutdown queue for a message. If there is one, shutdown. - d = self.shutdownQ.get( False ) + self.shutdownQ.get( False ) self.keepGoing = False return False except Empty: @@ -447,9 +445,9 @@ def runServer( self ): return True def purgeDataQ( self ): - while 1: + while True: try: - d = self.dataQ.get( False ) + self.dataQ.get( False ) except Empty: break diff --git a/CrossMgrAlien/Alien2JChip.py b/CrossMgrAlien/Alien2JChip.py index 0e95d262..14c08f1d 100644 --- a/CrossMgrAlien/Alien2JChip.py +++ b/CrossMgrAlien/Alien2JChip.py @@ -1,11 +1,8 @@ -import re import os -import socket import time -import threading +import socket import datetime from queue import Empty -from Utils import readDelimitedData, timeoutSecs #------------------------------------------------------------------------------ # JChip delimiter (CR, **not** LF) @@ -46,7 +43,7 @@ def checkKeepGoing( self ): return False try: - d = self.shutdownQ.get( False ) + self.shutdownQ.get( False ) self.keepGoing = False return False except Empty: @@ -79,7 +76,7 @@ def runServer( self ): sock.connect((self.crossMgrHost, self.crossMgrPort)) break except Exception as e: - self.messageQ.put( ('Alien2JChip', 'CrossMgr Connection Failed ({}).'.format(e)) ); + self.messageQ.put( ('Alien2JChip', 'CrossMgr Connection Failed ({}).'.format(e)) ) self.messageQ.put( ('Alien2JChip', 'Trying "{}" again in 2 secs...'.format(instance_name)) ) for t in range(2): time.sleep( 1 ) diff --git a/CrossMgrAlien/AlienClient.py b/CrossMgrAlien/AlienClient.py index b9f86fc4..0c2453dd 100644 --- a/CrossMgrAlien/AlienClient.py +++ b/CrossMgrAlien/AlienClient.py @@ -1,4 +1,3 @@ -import sys import time import socket import threading diff --git a/CrossMgrAlien/AlienReader.py b/CrossMgrAlien/AlienReader.py index 92a44090..0a0fe1e4 100644 --- a/CrossMgrAlien/AlienReader.py +++ b/CrossMgrAlien/AlienReader.py @@ -1,12 +1,11 @@ - -import os -import sys -import string import re +import sys import math +import string +import socket import datetime -import random from functools import partial +from xml.dom.minidom import parseString regexURL = re.compile( r'^(?:http|ftp)s?://' # http:// or https:// @@ -32,13 +31,16 @@ def validateEmail( value ): raise ValueError('Invalid Email') return True -class Type( object ): +class Type: def toStr( self, v ): return str(v) + def validate( self, v ): return True + def fromStr( self, v ): return str(v) + def repValue( self ): raise ValueError( 'repValue not implemented' ) @@ -58,8 +60,9 @@ def validate( self, v ): if len(values) != 6: raise ValueError( '{}: Invalid MACAddress: requires 6 hex values'.format(v) ) for v in values: - i = int( v, 16 ) + int( v, 16 ) return True + def repValue( self ): return '00:00:00:00:00:00' @@ -69,8 +72,9 @@ def validate( self, v ): if len(values) != 4: raise ValueError( '{}: Invalid IPAddress: requires 4 decimal values'.format(v) ) for v in values: - i = int( v.strip() ) + int( v.strip() ) return True + def repValue( self ): return '0.0.0.0' @@ -85,18 +89,19 @@ def validate( self, v ): if v.upper() == "SERIAL": return True host, port = v.split( ':' ) - p = int( port ) + int( port ) return super( IPAddressPortSerial, self ).validate( host ) class IPAddressPortSerialEmail( IPAddressPortSerial ): def validate( self, v ): if v.find('@') >= 0: return validateEmail( v ) - return super( IPAddressPortSerialEmail, self ).validate( host ) + return super().validate( v ) class URL( Type ): def validate( self, v ): return validateURL( v ) + def repValue( self ): return 'http://www.google.com' @@ -105,20 +110,24 @@ def validate( self, v ): if not isinstance(v, int): raise ValueError( 'value must be int type' ) return True + def fromStr( self, v ): return int(v) + def repValue( self ): return 999 class IntRange( Int ): def __init__( self, iMin = 0, iMax = sys.maxint ): self.iMin, self.iMax = iMin, iMax + def validate( self, v ): if not isinstance(v, int): raise ValueError( 'value must be int type' ) if not (self.iMin <= v <= self.iMax): raise ValueError( '{} must be in range [{}, {}] inclusive'.format(v, self.iMin, self.iMax) ) return True + def repValue( self ): return self.iMin @@ -128,48 +137,60 @@ def NonNegInt(): class IntChoice( Type ): def __init__( self, choices ): self.choices = choices + def validate( self, v ): - i = int(reponse) + i = int( v ) if i not in self.choices: raise ValueError( '{} must be one of {}'.format(i, ','.join( '{}'.format(k) for k in self.choices) ) ) return True + def fromStr( self, v ): return int(v) + def repValue( self ): - return choices[0] + return self.choices[0] class StringChoice( Type ): def __init__( self, choices ): self.choices = choices + def validate( self, v ): if v not in self.choices: raise ValueError( '"{}" must be one of {}'.format(v, ','.join( '"{}"'.format(k) for k in self.choices) ) ) return True + def fromStr( self, v ): return v + def repValue( self ): - return choices[0] + return self.choices[0] class Bool( Type ): def toStr( self, v ): return 'ON' if v else 'OFF' + def validate( self, v ): if not isinstance(v, bool): raise ValueError( 'Value must be Bool type' ) return True + def fromStr( self, v ): return v.upper() == 'ON' + def repValue( self ): return True class DateTime( Type ): def toStr( self, v ): return v.strftime( '%Y/%M/%D %H:%M:%S' ) + def validate( self, v ): - if not isintance(v, datetime.datetime): + if not isinstance(v, datetime.datetime): raise ValueError( 'Value must be datetime type' ) return True + timeDelimTrans = string.maketrans( '/:', ' ' ) + def fromStr( self, v ): fields = v.translate(self.timeDelimTrans).split() if len(fields) != 6: @@ -179,6 +200,7 @@ def fromStr( self, v ): microsecont = fract * 1000000.0 return datetime.datetime( year=int(year), month=int(month), day=int(day), hour=int(hour), minutes=int(minute), second=int(second), microsecond=int(microsecont) ) + def repValue( self ): return datetime.datetime.now() @@ -327,7 +349,7 @@ def repValue( self ): # Validate that all the commands are coded correctly. cmdsNormalized = {} for cmd, cmdInfo in cmds.iteritems(): - assert isinstance(cmd, basestring) + assert isinstance(cmd, str) try: assert isinstance(cmdInfo, dict) except AssertionError: @@ -339,7 +361,7 @@ def repValue( self ): try: assert len(cmdInfo) == 1 except AssertionError: - print ( 'command: "{}" specifies InOut but also has other specifier: {}'.format(cmd, tName), ','.join( cmdInfo.keys() ) ) + print( 'command: "{}" specifies InOut but also has other specifier: {}'.format(cmd, ','.join(cmdInfo.keys())) ) raise # Check for any unknown type specifiers. @@ -347,7 +369,7 @@ def repValue( self ): try: assert tName in [In, Out, InOut] except AssertionError: - print ( 'command: "{}" has unknown specifier: {}'.format(cmd, tName) ) + print( 'command: "{}" has unknown specifier: {}'.format(cmd, tName) ) raise # Normalize types to In and Out only @@ -454,6 +476,7 @@ class AlienReader( object ): SupressPrefix = '\1' nonCmdAttributes = set( ('testMode', 'CmdHost', 'CmdPort', 'cmdSocket', 'keepGoing') ) + def __init__( self ): self.testMode = True self.CmdHost = None @@ -557,7 +580,7 @@ def __setattr__( self, name, value ): def getResponse( self, conn ): # Read delimited data from the reader - ReaderDelim = seld.ReaderDelim.decode() + ReaderDelim = self.ReaderDelim.decode() response = '' while not response.endswith( ReaderDelim ): more = conn.recv( 4096 ) diff --git a/CrossMgrAlien/CrossMgrAlienSetup.py b/CrossMgrAlien/CrossMgrAlienSetup.py index edb2dca8..990d0c31 100644 --- a/CrossMgrAlien/CrossMgrAlienSetup.py +++ b/CrossMgrAlien/CrossMgrAlienSetup.py @@ -1,4 +1,3 @@ -from distutils.core import setup import os import shutil import zipfile @@ -10,8 +9,10 @@ distDir = r'dist\CrossMgrAlien' distDirParent = os.path.dirname(distDir) + if os.path.exists(distDirParent): shutil.rmtree( distDirParent ) + if not os.path.exists( distDirParent ): os.makedirs( distDirParent ) @@ -20,9 +21,11 @@ r"C:\Users\edwar\Google Drive\Downloads\Windows", r"C:\Users\Edward Sitarski\Google Drive\Downloads\Windows", ] + for googleDrive in gds: if os.path.exists(googleDrive): break + googleDrive = os.path.join( googleDrive, 'CrossMgrAlien' ) subprocess.call( [ @@ -88,13 +91,13 @@ def make_inno_version(): with open('inno_setup.txt', 'w') as f: for k, v in setup.items(): f.write( '{}={}\n'.format(k,v) ) + make_inno_version() cmd = '"' + inno + '" ' + 'CrossMgrAlien.iss' print ( cmd ) os.system( cmd ) # Create versioned executable. -from Version import AppVerName vNum = AppVerName.split()[1] vNum = vNum.replace( '.', '_' ) newExeName = 'CrossMgrAlien_Setup_v' + vNum + '.exe' diff --git a/CrossMgrAlien/MainWin.py b/CrossMgrAlien/MainWin.py index dff70ac0..b17f2327 100644 --- a/CrossMgrAlien/MainWin.py +++ b/CrossMgrAlien/MainWin.py @@ -1,8 +1,13 @@ +import os import sys -import threading -import socket import atexit -import time +import datetime + +import wx +import wx.adv +import wx.lib.masked as masked +import wx.lib.intctrl as intctrl + from roundbutton import RoundButton import Utils from queue import Queue, Empty @@ -12,15 +17,6 @@ from Alien2JChip import CrossMgrServer from AutoDetect import AutoDetect, DefaultAlienCmdPort -import wx -import wx.adv -import wx.lib.masked as masked -import wx.lib.intctrl as intctrl -import sys -import os -import re -import datetime - if 'WXMAC' in wx.Platform: class IpAddrCtrl( wx.TextCtrl ): def GetAddress( self ): @@ -539,11 +535,10 @@ def doCopyToClipboard( self, event ): do.SetText( '\n'.join(cc) ) wx.TheClipboard.SetData(do) wx.TheClipboard.Close() - dlg = wx.MessageDialog(self, 'Configuration and Logs copied to the Clipboard.', + with wx.MessageDialog(self, 'Configuration and Logs copied to the Clipboard.', 'Copy to Clipboard Succeeded', - wx.OK | wx.ICON_INFORMATION ) - ret = dlg.ShowModal() - dlg.Destroy() + wx.OK | wx.ICON_INFORMATION ) as dlg: + dlg.ShowModal() else: # oops... something went wrong! wx.MessageBox("Unable to open the clipboard", "Error") diff --git a/CrossMgrAlien/Utils.py b/CrossMgrAlien/Utils.py index c7e673c6..392629c5 100644 --- a/CrossMgrAlien/Utils.py +++ b/CrossMgrAlien/Utils.py @@ -160,7 +160,7 @@ def getHomeDir(): try: if os.path.basename(homedir) == '.CrossMgr': homedir = os.path.join( os.path.dirname(homedir), '.CrossMgrApp' ) - except: + except Exception: pass if not os.path.exists(homedir): os.makedirs( homedir ) @@ -174,7 +174,7 @@ def getDocumentsDir(): if 'WXMAC' in wx.Platform: try: topdirName = os.environ['RESOURCEPATH'] - except: + except Exception: topdirName = os.path.dirname(os.path.realpath(__file__)) if os.path.isdir( os.path.join(topdirName, 'CrossMgrAlienImages') ): dirName = topdirName @@ -187,7 +187,7 @@ def getDocumentsDir(): else: try: dirName = os.path.dirname(os.path.abspath(__file__)) - except: + except Exception: dirName = os.path.dirname(os.path.abspath(sys.argv[0])) if os.path.basename(dirName) in ['library.zip', 'MainWin.exe', 'CrossMgrAlien.exe']: @@ -247,7 +247,7 @@ def GetAllIps(): for a in addrInfo: try: ip = a[4][0] - except: + except Exception: continue if reIP.search(ip): ips.append( ip ) diff --git a/CrossMgrAlien/Version.py b/CrossMgrAlien/Version.py index 0eafb6c0..7c78ade0 100644 --- a/CrossMgrAlien/Version.py +++ b/CrossMgrAlien/Version.py @@ -1 +1 @@ -AppVerName="CrossMgrAlien 3.0.3-private" +AppVerName="CrossMgrAlien 3.0.4-private" diff --git a/CrossMgrAlien/roundbutton.py b/CrossMgrAlien/roundbutton.py index 8bae0235..e1830beb 100644 --- a/CrossMgrAlien/roundbutton.py +++ b/CrossMgrAlien/roundbutton.py @@ -309,16 +309,6 @@ def SetInitialSize(self, size=None): SetBestSize = SetInitialSize - - #def AcceptsFocus(self): - #""" - #Can this window be given focus by mouse click? - - #:note: Overridden from `wx.Control`. - #""" - - #return self.IsShown() and self.IsEnabled() - def AcceptsFocusFromKeyboard( self ): return True diff --git a/CrossMgrImpinj/AntennaReads.py b/CrossMgrImpinj/AntennaReads.py index 4fb52c96..7b0c779f 100644 --- a/CrossMgrImpinj/AntennaReads.py +++ b/CrossMgrImpinj/AntennaReads.py @@ -101,8 +101,10 @@ class Timer(wx.Timer): def __init__( self ): super( wx.Timer, self ).__init__() self.Start( milliseconds=250 ) + def Notify( self ): ar.Set( [random.random()*1000.0 for i in range(int(random.random()*5))] ) + t = Timer() mainWin.Show() diff --git a/CrossMgrImpinj/CrossMgrImpinjSetup.py b/CrossMgrImpinj/CrossMgrImpinjSetup.py index b5c6a778..97c45e22 100644 --- a/CrossMgrImpinj/CrossMgrImpinjSetup.py +++ b/CrossMgrImpinj/CrossMgrImpinjSetup.py @@ -1,6 +1,4 @@ -from distutils.core import setup import os -import io import shutil import zipfile import datetime @@ -76,7 +74,6 @@ def copyDir( d ): inno = innoTest break -from Version import AppVerName def make_inno_version(): setup = { 'AppName': AppVerName.split()[0], @@ -91,6 +88,7 @@ def make_inno_version(): with open('inno_setup.txt', 'w') as f: for k, v in setup.items(): f.write( '{}={}\n'.format(k,v) ) + make_inno_version() cmd = '"' + inno + '" ' + 'CrossMgrImpinj.iss' print( cmd ) diff --git a/CrossMgrImpinj/Dependencies.py b/CrossMgrImpinj/Dependencies.py new file mode 100644 index 00000000..8e9efb8d --- /dev/null +++ b/CrossMgrImpinj/Dependencies.py @@ -0,0 +1 @@ +import roundbutton diff --git a/CrossMgrImpinj/Impinj.py b/CrossMgrImpinj/Impinj.py index a6d4ded0..0100ad9f 100644 --- a/CrossMgrImpinj/Impinj.py +++ b/CrossMgrImpinj/Impinj.py @@ -1,21 +1,18 @@ -import re import os import time -import math import socket import threading import datetime -import random import traceback from collections import defaultdict from queue import Queue, Empty -from Utils import timeoutSecs, Beep +from Utils import Beep try: from pyllrp.pyllrp import * except ImportError: from pyllrp import * -from TagGroup import TagGroup, QuadraticRegressionMethod, StrongestReadMethod, FirstReadMethod, MostReadsChoice, DBMaxChoice +from TagGroup import TagGroup, QuadraticRegressionMethod, FirstReadMethod, MostReadsChoice getTimeNow = datetime.datetime.now tOld = getTimeNow() - datetime.timedelta( days=200 ) @@ -197,7 +194,7 @@ def checkKeepGoing( self ): try: # Check the shutdown queue for a message. If there is one, shutdown. - d = self.shutdownQ.get( False ) + self.shutdownQ.get( False ) self.keepGoing = False return False except Empty: @@ -441,8 +438,6 @@ def runServer( self ): self.messageQ.put( ('Impinj', '*****************************************' ) ) self.messageQ.put( ('Impinj', 'Reader Server Started: ({}:{})'.format(self.impinjHost, self.impinjPort) ) ) - # Create an old default time for last tag read. - tOld = getTimeNow() - datetime.timedelta( days = 200 ) utcfromtimestamp = datetime.datetime.utcfromtimestamp while self.checkKeepGoing(): @@ -665,7 +660,7 @@ def runServer( self ): def purgeDataQ( self ): while True: try: - d = self.dataQ.get( False ) + self.dataQ.get( False ) except Empty: break diff --git a/CrossMgrImpinj/Impinj2JChip.py b/CrossMgrImpinj/Impinj2JChip.py index c30e51c9..16e129e4 100644 --- a/CrossMgrImpinj/Impinj2JChip.py +++ b/CrossMgrImpinj/Impinj2JChip.py @@ -1,8 +1,6 @@ -import re import os import socket import time -import threading import datetime from queue import Empty @@ -50,7 +48,7 @@ def checkKeepGoing( self ): return False try: - d = self.shutdownQ.get( False ) + self.shutdownQ.get( False ) self.keepGoing = False return False except Empty: diff --git a/CrossMgrImpinj/ImpinjClient.py b/CrossMgrImpinj/ImpinjClient.py index c9cfc5bf..335be04f 100644 --- a/CrossMgrImpinj/ImpinjClient.py +++ b/CrossMgrImpinj/ImpinjClient.py @@ -1,4 +1,3 @@ -import sys import time import socket import random @@ -91,7 +90,7 @@ def StartClient(): raise print( 'StatClient: Sending event notification - everything is OK.' ) - ms = long((datetime.datetime.now() - datetime.datetime( 1970, 1, 1, 0, 0, 0 )).total_seconds() * 1000000) + ms = int((datetime.datetime.now() - datetime.datetime( 1970, 1, 1, 0, 0, 0 )).total_seconds() * 1000000) READER_EVENT_NOTIFICATION_Message( Parameters = [ ReaderEventNotificationData_Parameter( Parameters = [ UTCTimestamp_Parameter( ms ), diff --git a/CrossMgrImpinj/MainWin.py b/CrossMgrImpinj/MainWin.py index e9e13430..2948fd14 100644 --- a/CrossMgrImpinj/MainWin.py +++ b/CrossMgrImpinj/MainWin.py @@ -1,31 +1,25 @@ +import os import sys -import threading -import socket import atexit -import time -from roundbutton import RoundButton -import Utils +import datetime from queue import Queue, Empty from threading import Thread as Process -import Impinj -from Impinj import ImpinjServer, ResetAntennaConnectionsCheck -from Impinj2JChip import CrossMgrServer -from pyllrp.AutoDetect import AutoDetect -import QuadReg -from TagGroup import QuadraticRegressionMethod, StrongestReadMethod, FirstReadMethod, MethodNames, MostReadsChoice, DBMaxChoice, AntennaChoiceNames -from AntennaReads import AntennaReads import wx import wx.lib.masked as masked import wx.lib.intctrl as intctrl import wx.adv import wx.lib.agw.hyperlink as hl -import sys -import os -import io -import re -import datetime -import operator + +import Utils +import Impinj +from Impinj import ImpinjServer, ResetAntennaConnectionsCheck +from Impinj2JChip import CrossMgrServer +from pyllrp.AutoDetect import AutoDetect +import QuadReg +from TagGroup import FirstReadMethod, MethodNames, AntennaChoiceNames +from AntennaReads import AntennaReads +from roundbutton import RoundButton from Version import AppVerName diff --git a/CrossMgrImpinj/QuadReg.py b/CrossMgrImpinj/QuadReg.py index 1507b0d4..06b826c7 100644 --- a/CrossMgrImpinj/QuadReg.py +++ b/CrossMgrImpinj/QuadReg.py @@ -1,7 +1,6 @@ import math from math import log import operator -import itertools import numpy as np import warnings try: diff --git a/CrossMgrImpinj/TagGroup.py b/CrossMgrImpinj/TagGroup.py index 60e9e613..504529e2 100644 --- a/CrossMgrImpinj/TagGroup.py +++ b/CrossMgrImpinj/TagGroup.py @@ -2,12 +2,10 @@ import random import operator import threading -import itertools from time import sleep from datetime import datetime, timedelta from queue import Queue, Empty -from threading import Lock -from QuadReg import QuadRegExtreme, QuadRegRemoveOutliersRobust, QuadRegRemoveOutliersRansac, QuadReg +from QuadReg import QuadRegExtreme, QuadRegRemoveOutliersRansac, QuadReg # Use a reference time to convert given times to float seconds. tRef = datetime.now() diff --git a/CrossMgrImpinj/TagGroupTest.py b/CrossMgrImpinj/TagGroupTest.py index 741dcb57..c0320379 100644 --- a/CrossMgrImpinj/TagGroupTest.py +++ b/CrossMgrImpinj/TagGroupTest.py @@ -1,6 +1,6 @@ import glob import datetime -from TagGroup import TagGroup, QuadraticRegressionMethod, StrongestReadMethod +from TagGroup import TagGroup, QuadraticRegressionMethod def Test(): method = QuadraticRegressionMethod diff --git a/CrossMgrImpinj/UpdateDependencies.py b/CrossMgrImpinj/UpdateDependencies.py new file mode 100644 index 00000000..78b9db14 --- /dev/null +++ b/CrossMgrImpinj/UpdateDependencies.py @@ -0,0 +1,26 @@ +import os + +def UpdateDependencies(): + with open('Dependencies.py', encoding='utf8') as d: + for line in d: + line = line.strip() + if not line: + continue + + fname = line.split()[1] + '.py' + print( 'copying: {}'.format(fname) ) + + try: + os.remove( fname ) + except Exception: + pass + + with open(os.path.join('..', fname), encoding='utf8') as fc: + contents = fc.read() + if fname in ('Utils.py', 'HelpIndex.py'): + contents = contents.replace("'CrossMgr", "'CrossMgrImpinj") + with open(fname, 'w', encoding='utf8') as fc: + fc.write( contents ) + +if __name__ == '__main__': + UpdateDependencies() diff --git a/CrossMgrImpinj/Utils.py b/CrossMgrImpinj/Utils.py index 221f4a97..0bdae7ad 100644 --- a/CrossMgrImpinj/Utils.py +++ b/CrossMgrImpinj/Utils.py @@ -1,9 +1,7 @@ -import datetime import wx import os import re import sys -import math import socket import subprocess @@ -67,7 +65,7 @@ def getHomeDir(): try: if os.path.basename(homedir) == '.CrossMgrImpinj': homedir = os.path.join( os.path.dirname(homedir), '.CrossMgrImpinjApp' ) - except: + except Exception: pass if not os.path.exists(homedir): os.makedirs( homedir ) @@ -81,7 +79,7 @@ def getDocumentsDir(): if 'WXMAC' in wx.Platform: try: topdirName = os.environ['RESOURCEPATH'] - except: + except Exception: topdirName = os.path.dirname(os.path.realpath(__file__)) if os.path.isdir( os.path.join(topdirName, 'CrossMgrImpinjImages') ): dirName = topdirName @@ -94,7 +92,7 @@ def getDocumentsDir(): else: try: dirName = os.path.dirname(os.path.abspath(__file__)) - except: + except Exception: dirName = os.path.dirname(os.path.abspath(sys.argv[0])) if os.path.basename(dirName) == 'library.zip': @@ -127,6 +125,7 @@ def Bell(): # Attempt at portable sound player. if sys.platform.startswith('win'): soundCache = {} + def Play( soundFile ): global soundCache soundFile = os.path.join( imageFolder, soundFile ) @@ -157,7 +156,7 @@ def Play( soundFile ): shell=False, stdin=None, stdout=None, stderr=None, close_fds=True, ) - except Exception as e: + except Exception: pass return True @@ -201,7 +200,7 @@ def GetAllIps(): for a in addrInfo: try: ip = a[4][0] - except: + except Exception: continue if reIP.search(ip): ips.append( ip ) diff --git a/CrossMgrImpinj/Version.py b/CrossMgrImpinj/Version.py index 07ed7654..a1fbe002 100644 --- a/CrossMgrImpinj/Version.py +++ b/CrossMgrImpinj/Version.py @@ -1 +1 @@ -AppVerName="CrossMgrImpinj 3.0.21-private" +AppVerName="CrossMgrImpinj 3.0.22-private" diff --git a/CrossMgrImpinj/pypi.py b/CrossMgrImpinj/pypi.py index e9a1415b..bb8b125b 100644 --- a/CrossMgrImpinj/pypi.py +++ b/CrossMgrImpinj/pypi.py @@ -1,10 +1,9 @@ #!/usr/bin/env python -import shutil import os -import sys import stat import glob +import shutil import datetime import subprocess from Version import AppVerName @@ -39,10 +38,10 @@ def writeToFile( s, fname ): print( 'Clearing previous contents...' ) try: subprocess.call( ['rm', '-rf', pypiDir] ) -except: +except Exception: try: shutil.rmtree( pypiDir, ignore_errors=True ) - except: + except Exception: pass os.mkdir( pypiDir ) diff --git a/CrossMgrImpinj/roundbutton.py b/CrossMgrImpinj/roundbutton.py deleted file mode 100644 index 8bae0235..00000000 --- a/CrossMgrImpinj/roundbutton.py +++ /dev/null @@ -1,594 +0,0 @@ -# --------------------------------------------------------------------------------- # -# ROUNDBUTTON wxPython IMPLEMENTATION -# -# Edward Sitarski, @ Updated April 2019 -# -# -# TODO List -# -# 1) Anything to do? -# -# -# For all kind of problems, requests of enhancements and bug reports, please -# write to me at: -# -# edward.sitarski@gmail.com -# -# End Of Comments -# --------------------------------------------------------------------------------- # - -""" -RoundButton is a custom-drawn button class which draws round buttons that look like they are made of glass. - - -Description -=========== - -RoundButton is a custom-drawn button class which draws round buttons that look like they are made of glass. -Gradient fills are used extensively, both linear and radially to create the 3d effect. -As no bitmaps are required, RoundButtons can be used to display any sized text. - -Yes, they take up a lot of space, but RoundButtons create a dramatic sense of importance to what happens after they are pressed. - -Use with care. Lives might be at stake. - -Supported Platforms -=================== - -RoundButton has been tested on the following platforms: - * Windows (Windows XP). - * Linux (Ubuntu) - - -Window Styles -============= - -`No particular window styles are available for this class.` - - -Events Processing -================= - -This class processes the following events: - -================= ================================================== -Event Name Description -================= ================================================== -``wx.EVT_BUTTON`` Process a `wx.wxEVT_COMMAND_BUTTON_CLICKED` event, when the button is clicked. -================= ================================================== - - -License And Version -=================== - -RoundButton is distributed under the wxPython license. - -Latest Revision: Edward Sitarski @ 27 Nov 2011, 17.00 EST - -Version 0.1 - -""" - -import wx -import math -import wx.lib.agw.artmanager as AM - -HOVER = 1 -CLICK = 2 - -class RoundButtonEvent(wx.PyCommandEvent): - """ Event sent from L{RoundButton} when the button is activated. """ - - def __init__(self, eventType, eventId): - """ - Default class constructor. - - :param `eventType`: the event type; - :param `eventId`: the event identifier. - """ - - super().__init__(eventType, eventId) - self.isDown = False - self.theButton = None - - - def SetButtonObj(self, btn): - """ - Sets the event object for the event. - - :param `btn`: the button object, an instance of L{RoundButton}. - """ - - self.theButton = btn - - - def GetButtonObj(self): - """ Returns the object associated with this event. """ - - return self.theButton - - -class RoundButton(wx.Control): - """ This is the main class implementation of L{RoundButton}. """ - - def __init__(self, parent, id=wx.ID_ANY, label="", pos=wx.DefaultPosition, - size=wx.DefaultSize, style=wx.NO_BORDER, validator=wx.DefaultValidator, - name="roundbutton"): - """ - Default class constructor. - - :param `parent`: the L{RoundButton} parent; - :param `id`: window identifier. A value of -1 indicates a default value; - :param `label`: the button text label; - :param `pos`: the control position. A value of (-1, -1) indicates a default position, - chosen by either the windowing system or wxPython, depending on platform; - :param `size`: the control size. A value of (-1, -1) indicates a default size, - chosen by either the windowing system or wxPython, depending on platform; - :param `style`: the button style (unused); - :param `validator`: the validator associated to the button; - :param `name`: the button name. - """ - - super().__init__(parent, id, pos, size, style, validator, name) - - self.Bind(wx.EVT_PAINT, self.OnPaint) - self.Bind(wx.EVT_ERASE_BACKGROUND, lambda event: None) - self.Bind(wx.EVT_SIZE, self.OnSize) - self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) - self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) - self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeave) - self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter) - self.Bind(wx.EVT_SET_FOCUS, self.OnGainFocus) - self.Bind(wx.EVT_KILL_FOCUS, self.OnLoseFocus) - self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) - self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) - - self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDown) - - self._mouseAction = None - self._hasFocus = False - self._buttonRadius = 0 - - self.SetLabel(label) - self.InheritAttributes() - self.SetInitialSize(size) - - def OnSize(self, event): - """ - Handles the ``wx.EVT_SIZE`` event for L{RoundButton}. - - :param `event`: a `wx.SizeEvent` event to be processed. - """ - - event.Skip() - self.Refresh() - - - def _containsEvent( self, event ): - """ - Checks that the event occured in the L{RoundButton} circle. - - :param `event`: a `wx.MouseEvent` event. - """ - x, y, width, height = self.GetClientRect() - x += width // 2 - y += height // 2 - px, py = event.GetPosition().Get() - dx = px - x - dy = py - y - return dx * dx + dy * dy < self._buttonRadius * self._buttonRadius - - def OnLeftDown(self, event): - """ - Handles the ``wx.EVT_LEFT_DOWN`` event for L{RoundButton}. - - :param `event`: a `wx.MouseEvent` event to be processed. - """ - - if not self.IsEnabled() or not self._containsEvent(event): - return - - self._mouseAction = CLICK - self.CaptureMouse() - self.Refresh() - event.Skip() - - - def OnLeftUp(self, event): - """ - Handles the ``wx.EVT_LEFT_UP`` event for L{RoundButton}. - - :param `event`: a `wx.MouseEvent` event to be processed. - """ - - if not self.IsEnabled() or not self.HasCapture(): - return - - if self.HasCapture(): - self.ReleaseMouse() - - if self._containsEvent(event): - self._mouseAction = HOVER - self.Notify() - else: - self._mouseAction = None - - self.Refresh() - event.Skip() - - - def OnMouseEnter(self, event): - """ - Handles the ``wx.EVT_ENTER_WINDOW`` event for L{RoundButton}. - - :param `event`: a `wx.MouseEvent` event to be processed. - """ - - if not self.IsEnabled(): - return - - self._mouseAction = HOVER - self.Refresh() - event.Skip() - - - def OnMouseLeave(self, event): - """ - Handles the ``wx.EVT_LEAVE_WINDOW`` event for L{RoundButton}. - - :param `event`: a `wx.MouseEvent` event to be processed. - """ - - self._mouseAction = None - self.Refresh() - event.Skip() - - - def OnGainFocus(self, event): - """ - Handles the ``wx.EVT_SET_FOCUS`` event for L{RoundButton}. - - :param `event`: a `wx.FocusEvent` event to be processed. - """ - - self._hasFocus = True - self.Refresh() - self.Update() - - - def OnLoseFocus(self, event): - """ - Handles the ``wx.EVT_KILL_FOCUS`` event for L{RoundButton}. - - :param `event`: a `wx.FocusEvent` event to be processed. - """ - - self._hasFocus = False - self.Refresh() - self.Update() - - - def OnKeyDown(self, event): - """ - Handles the ``wx.EVT_KEY_DOWN`` event for L{RoundButton}. - - :param `event`: a `wx.KeyEvent` event to be processed. - """ - - if self._hasFocus and event.GetKeyCode() == ord(" "): - self._mouseAction = HOVER - self.Refresh() - event.Skip() - - - def OnKeyUp(self, event): - """ - Handles the ``wx.EVT_KEY_UP`` event for L{RoundButton}. - - :param `event`: a `wx.KeyEvent` event to be processed. - """ - - if self._hasFocus and event.GetKeyCode() == ord(" "): - self._mouseAction = HOVER - self.Notify() - self.Refresh() - event.Skip() - - - def SetInitialSize(self, size=None): - """ - Given the current font and bezel width settings, calculate - and set a good size. - - :param `size`: an instance of `wx.Size`. - """ - - if size is None: - size = wx.DefaultSize - wx.Control.SetInitialSize(self, size) - - SetBestSize = SetInitialSize - - - #def AcceptsFocus(self): - #""" - #Can this window be given focus by mouse click? - - #:note: Overridden from `wx.Control`. - #""" - - #return self.IsShown() and self.IsEnabled() - - def AcceptsFocusFromKeyboard( self ): - return True - - def AcceptsFocus( self ): - return False - - def GetDefaultAttributes(self): - """ - Overridden base class virtual. By default we should use - the same font/colour attributes as the native `wx.Button`. - """ - - return wx.Button.GetClassDefaultAttributes() - - - def ShouldInheritColours(self): - """ - Overridden base class virtual. Buttons usually don't inherit - the parent's colours. - - :note: Overridden from `wx.Control`. - """ - - return False - - - def Enable(self, enable=True): - """ - Enables/disables the button. - - :param `enable`: ``True`` to enable the button, ``False`` to disable it. - - :note: Overridden from `wx.Control`. - """ - - wx.Control.Enable(self, enable) - self.Refresh() - - - def DoGetBestSize(self): - """ - Overridden base class virtual. Determines the best size of the - button based on the label and bezel size. - """ - - label = self.GetLabel() - if not label: - return wx.Size(32, 32) - - dc = wx.ClientDC(self) - dc.SetFont(self.GetFont()) - retWidth, retHeight = dc.GetTextExtent(label) - - width = int(max(retWidth, retHeight) * 1.5) - return wx.Size(width, width) - - - def SetDefault(self): - """ Sets the default button. """ - - tlw = wx.GetTopLevelParent(self) - if hasattr(tlw, 'SetDefaultItem'): - tlw.SetDefaultItem(self) - - def Notify(self): - """ Actually sends a ``wx.EVT_BUTTON`` event to the listener (if any). """ - - evt = RoundButtonEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, self.GetId()) - evt.SetButtonObj(self) - evt.SetEventObject(self) - self.GetEventHandler().ProcessEvent(evt) - - def SetFontToFitLabel(self, font = None): - ''' Sets the internal font size so that the label will fit on the button.''' - ''' font parameter is used to get the font specificiation only - the size does not matter. ''' - ''' If no font parameter is given, the current font is used. ''' - label = self.GetLabel().strip() - if not label: - return - - if not font: - font = self.GetFont() - - # Get a known font size based on the font specification. - fontPixels = 48 - fontCur = wx.Font((0,fontPixels), font.GetFamily(), font.GetStyle(), font.GetWeight(), - font.GetUnderlined(), font.GetFaceName(), font.GetEncoding() ) - dc = wx.WindowDC( self ) - dc.SetFont( fontCur ) - - lines = label.strip().split('\n') - tw, th = dc.GetTextExtent( lines[0] ) - - x, y, width, height = self.GetClientRect() - - # Get the centre of the button and the drawable radius. - r = min(width, height) // 2 - xCenter = x + width // 2 - yCenter = y + height // 2 - rDrawable = r * 0.80 * 0.93 * 0.95 - - # For all lines, check the top and bottom corners and get the maximum radius. - r2Max = 0 - yCur = yCenter - th * len(lines) / 2.0 - for line in lines: - twCur, thCur = dc.GetTextExtent( line ) - tx, ty = xCenter - twCur / 2, yCur - dx, dy = tx - xCenter, ty - yCenter - r2Max = max( r2Max, dx*dx + dy*dy ) - dy += th - r2Max = max( r2Max, dx*dx + dy*dy ) - yCur += th - - # Adjust the font size based on the ratio that we would have drawn outside the button circle. - fontPixels *= rDrawable / math.sqrt( r2Max ) - fontCur = wx.Font((0,int(fontPixels)), font.GetFamily(), font.GetStyle(), font.GetWeight(), - font.GetUnderlined(), font.GetFaceName(), font.GetEncoding() ) - self.SetFont( fontCur ) - - def OnPaint(self, event): - """ - Handles the ``wx.EVT_PAINT`` event for L{RoundButton}. - - :param `event`: a `wx.PaintEvent` event to be processed. - """ - - dc = wx.BufferedPaintDC(self) - - am = AM.ArtManager() - - gc = wx.GraphicsContext.Create(dc) - dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour())) - dc.Clear() - - clientRect = self.GetClientRect() - boundaryRect = clientRect - - x, y, width, height = clientRect - colour = self.GetForegroundColour() - textColour = am.DarkColour(wx.WHITE, 3.0) if am.IsDark(colour) else am.LightColour(wx.BLACK, 3.0) - - pressed = False - if wx.Window.GetCapture() != self: - if self._mouseAction == HOVER: - colour = am.LightColour(colour, 10.0) - else: - colour = am.DarkColour(colour, 10.0) - textColour = am.DarkColour(textColour, 10.0) - pressed = True - - r = min(boundaryRect.GetWidth(), boundaryRect.GetHeight()) // 2 - xCenter = x + width // 2 - yCenter = y + height // 2 - - gc.SetPen( wx.TRANSPARENT_PEN ) - - def drawCircle( x, y, r ): - gc.DrawEllipse( x - r, y - r, r * 2, r * 2 ) - - # Draw the metal ring - gc.SetBrush( gc.CreateRadialGradientBrush( - xCenter, yCenter - r, - xCenter, yCenter - r, - r * 2, - wx.WHITE, wx.Colour(33,33,33) ) ) - drawCircle( xCenter, yCenter, r ) - - rSmaller = r * 0.80 - gc.SetBrush( gc.CreateRadialGradientBrush( - xCenter, yCenter + rSmaller, - xCenter, yCenter + rSmaller, - rSmaller * 2, - wx.WHITE, wx.Colour(33,33,33) ) ) - drawCircle( xCenter, yCenter, rSmaller ) - - # Draw the body of the button. - rSmaller *= 0.93 - if pressed: - shrink = 0.025 - yCenter -= r * shrink / 2.0 - - dc.SetFont( self.GetFont() ) - cRegular = colour - gc.SetBrush( gc.CreateRadialGradientBrush( - xCenter, yCenter + rSmaller * 0.9, - xCenter, yCenter + rSmaller, - rSmaller * 2, - am.LightColour(colour, 75.0), cRegular ) ) - drawCircle( xCenter, yCenter, rSmaller ) - self._buttonRadius = rSmaller - - # Draw the flare at the top of the button (a shaded ellipse with a linear gradient). - gc.SetBrush( gc.CreateLinearGradientBrush( - xCenter - rSmaller, yCenter - rSmaller, - xCenter - rSmaller, yCenter, - am.LightColour(colour, 40.0), am.LightColour(colour, 30.0)) ) - - # Magic constants to get things to look right. - rWidth = rSmaller * (2.0 * 0.7 * 0.9) - rHeight = rSmaller * (0.8 * 0.9) - gc.DrawEllipse( round(xCenter - rWidth / 2), round(yCenter - rSmaller), rWidth, rHeight ) - - # Draw an outline around the button body. - # Also covers up the gap between the flare and the top edge of the button. - gc.SetPen( wx.Pen(wx.Colour(50,50,50), round(r * 0.025)) ) - gc.SetBrush( wx.TRANSPARENT_BRUSH ) - gc.DrawEllipse( xCenter - rSmaller, yCenter - rSmaller, rSmaller * 2, rSmaller * 2 ) - - dc.SetTextForeground( textColour ) - - label = self.GetLabel().strip() - if not label: - return - lines = label.split('\n') - textWidth, textHeight = dc.GetTextExtent( label[0] ) - - yText = yCenter - textHeight * len(lines) / 2.0 - for line in lines: - dc.DrawText( line, round(xCenter - dc.GetTextExtent(line)[0] / 2), round(yText) ) - yText += textHeight - -if __name__ == '__main__': - - # Self-test. - app = wx.App(False) - mainWin = wx.Frame(None,title="roundbutton", size=(1024,600)) - mainWin.SetBackgroundColour( wx.WHITE ) - vs = wx.BoxSizer( wx.VERTICAL ) - hs = wx.BoxSizer( wx.HORIZONTAL ) - vs.Add( hs ) - - # Pure colours seem to work best as they approximate the jewel tones of coloured glass. - btnDefs = [ - # Label # Colour # Use bold Font? - #['OK', wx.Colour(0,128,0), True ], - #['SCAN', wx.Colour(0,128,128), False ], - #['Cancel', wx.Colour(128,0,0), True ], - - ['OK', wx.Colour(128,128,128),True ], - ['SCAN', wx.Colour(128,128,128), False ], - ['Cancel', wx.Colour(128,128,128),True ], - - ['STOP', wx.Colour(128,0,0), True ], - ['SLOW', wx.Colour(100,100,0), True ], - ['ENGINE\nSTART', wx.Colour(0,128, 0), False ], - ['Manual\nOverride',wx.Colour(0,0,128), False ], - ['RESET', wx.Colour(128,0,128), False ], - ] - - btnSize = 150 - - # The font size does not matter here - we just it for the properties. - boldFont = wx.Font(wx.FontInfo(10).Bold()) - - for i, (label, colour, boldFlag) in enumerate(btnDefs): - btn = RoundButton(mainWin, label=label, size=(btnSize, btnSize)) - btn.SetBackgroundColour( wx.WHITE ) - btn.SetForegroundColour( colour ) - - # Call SetFontToFitLabel after setting the size of the button. - if boldFlag: - btn.SetFontToFitLabel( boldFont ) - else: - btn.SetFontToFitLabel() # Use the button's default font, but change the font size to fit the label. - if i and i % 4 == 0: - hs = wx.BoxSizer( wx.HORIZONTAL ) - vs.Add( hs ) - hs.Add( btn, flag=wx.ALL, border = 4 ) - - mainWin.SetSizer( vs ) - mainWin.Show() - app.MainLoop() - diff --git a/PointsRaceMgr/Commentary.py b/PointsRaceMgr/Commentary.py index bd3b503d..32d5fc73 100644 --- a/PointsRaceMgr/Commentary.py +++ b/PointsRaceMgr/Commentary.py @@ -1,8 +1,6 @@ -import wx from html import escape -import sys +import wx import Model -import Utils class Commentary( wx.Panel ): def __init__( self, parent, id = wx.ID_ANY ): @@ -113,7 +111,6 @@ def toHtml( self, html ): text = self.getText().replace('.', '') if not text: return '' - lines = [] inList = False html.write( '
' ) for line in text.split('\n'): diff --git a/PointsRaceMgr/Configure.py b/PointsRaceMgr/Configure.py index 3293eb33..964462b6 100644 --- a/PointsRaceMgr/Configure.py +++ b/PointsRaceMgr/Configure.py @@ -1,15 +1,14 @@ +import os +import re +import datetime + import wx import wx.adv from NumCtrl import PosNumCtrl import wx.lib.intctrl as IC -import sys -import os -import re -import datetime import Utils import Model -import Version class Configure( wx.Panel ): def __init__( self, parent, id=wx.ID_ANY, size=(200,200) ): diff --git a/PointsRaceMgr/CopyMedia.py b/PointsRaceMgr/CopyMedia.py index 676b4d9e..f5ddd005 100644 --- a/PointsRaceMgr/CopyMedia.py +++ b/PointsRaceMgr/CopyMedia.py @@ -8,7 +8,7 @@ def NeedsUpdating( srcFName, destFName ): try: srcStat = os.stat( srcFName ) destStat = os.stat( destFName ) - except: + except Exception: return True return srcStat.st_mtime > destStat.st_mtime or srcStat.st_size != destStat.st_size diff --git a/PointsRaceMgr/EventList.py b/PointsRaceMgr/EventList.py index ad26bcf2..2b95fb99 100644 --- a/PointsRaceMgr/EventList.py +++ b/PointsRaceMgr/EventList.py @@ -2,9 +2,7 @@ import wx.grid as gridlib Button = wx.Button from Colours import * -import re import copy -import operator from ReorderableGrid import ReorderableGrid import Model import Utils diff --git a/PointsRaceMgr/ExportGrid.py b/PointsRaceMgr/ExportGrid.py index d757a1b4..158e37bd 100644 --- a/PointsRaceMgr/ExportGrid.py +++ b/PointsRaceMgr/ExportGrid.py @@ -1,14 +1,10 @@ -import wx import io import os -import math from html import escape -import base64 -import xlsxwriter from contextlib import contextmanager +import wx import Utils -import Model from FitSheetWrapper import FitSheetWrapperXLSX #--------------------------------------------------------------------------- @@ -32,7 +28,7 @@ def getHeaderFName(): with io.open(graphicFName, 'rb') as f: pass return graphicFName - except: + except Exception: return os.path.join(Utils.getImageFolder(), 'PointsRaceMgr.png') def getHeaderBitmap(): diff --git a/PointsRaceMgr/MainWin.py b/PointsRaceMgr/MainWin.py index f4a6aec4..8835ebb9 100644 --- a/PointsRaceMgr/MainWin.py +++ b/PointsRaceMgr/MainWin.py @@ -1,21 +1,18 @@ -import wx -import wx.adv as adv -from wx.lib.wordwrap import wordwrap -import wx.lib.dialogs - -import sys -from html import escape import os import io -import re +from html import escape import datetime import xlsxwriter import webbrowser import pickle -import subprocess import traceback from argparse import ArgumentParser +import wx +import wx.adv as adv +from wx.lib.wordwrap import wordwrap +import wx.lib.dialogs + import Utils from Utils import tag import Model @@ -26,8 +23,7 @@ from RankSummary import RankSummary from StartList import StartList from Commentary import Commentary -from ToPrintout import ToPrintout, ToHtml, ToExcel -from ExportGrid import ExportGrid +from ToPrintout import ToHtml, ToExcel from Version import AppVerName @@ -40,8 +36,6 @@ class MainWin( wx.Frame ): def __init__( self, parent, id = wx.ID_ANY, title='', size=(200,200) ): super().__init__(parent, id, title, size=size) - isMac = ('WXMAC' in wx.Platform) - Model.newRace() self.SetBackgroundColour( wx.WHITE ) @@ -497,7 +491,7 @@ def write( v ): try: webbrowser.open( htmlFName ) - except: + except Exception: pass #Utils.MessageOK(self, 'Excel file written to:\n\n {}'.format(htmlFName), 'Excel Write', iconMask=wx.ICON_INFORMATION) @@ -699,7 +693,7 @@ def menuSaveAs( self, event = None ): try: self.writeRaceValidFileName() return True - except: + except Exception: Utils.MessageOK( self, 'WriteRace:\n\nError writing to file.\n\nRace NOT saved.\n\nTry "File|Save As..." again.', iconMask = wx.ICON_ERROR ) return False @@ -853,12 +847,12 @@ def my_handler( type, value, traceback ): logSize = os.path.getsize( redirectFileName ) if logSize > 1000000: os.remove( redirectFileName ) - except: + except Exception: pass try: app.RedirectStdio( redirectFileName ) - except: + except Exception: pass Utils.writeLog( 'start: {}'.format(Version.AppVerName) ) @@ -875,7 +869,7 @@ def my_handler( type, value, traceback ): try: icon = wx.Icon( os.path.join(Utils.getImageFolder(), 'PointsRaceMgr16x16.ico'), wx.BITMAP_TYPE_ICO ) mainWin.SetIcon( icon ) - except: + except Exception: pass if args.verbose: diff --git a/PointsRaceMgr/Model.py b/PointsRaceMgr/Model.py index 8d77ea59..20449d8c 100644 --- a/PointsRaceMgr/Model.py +++ b/PointsRaceMgr/Model.py @@ -3,8 +3,6 @@ import operator import itertools import datetime -import sys -from collections import namedtuple #------------------------------------------------------------------------------ # Define a global current race. @@ -120,7 +118,7 @@ def __init__( self, bib, last_name='', first_name='', team='', team_code='', lic self.nation_code = nation_code try: self.existing_points = float(existing_points) - except: + except Exception: self.existing_points = 0.0 self.status = status @@ -189,7 +187,7 @@ def getCleanBibs( bibs ): for v in bibs.split(): try: biblist.append( int(v) ) - except: + except Exception: continue bibs = biblist @@ -289,7 +287,7 @@ def getRaceType( self ): if ( self.rankBy == Race.RankByPoints and self.pointsForLapping == 20 and - self.doublePointsForLastSprint == True + self.doublePointsForLastSprint ): return 'Points Race' if len(self.pointsForPlace) > 1 else 'Tempo Race' @@ -326,7 +324,7 @@ def setattr( self, attr, v ): def getNumSprints( self ): try: numSprints = max(0, self.laps - self.startLaps) // self.sprintEvery - except: + except Exception: numSprints = 0 return numSprints @@ -364,7 +362,7 @@ def getSprintPoints( self, sprint, place, bibs=None ): while place > 1: try: bib = bibs[place-1] - except IndexException: + except IndexError: break if bib < 0: # If the bib number is negative, tie with the previous position. place -= 1 @@ -374,7 +372,7 @@ def getSprintPoints( self, sprint, place, bibs=None ): # If this is a tie, the following bib will be negative. try: tie = (bibs[place] < 0) - except: + except Exception: tie = False points = self.pointsForPlace.get(place,0) diff --git a/PointsRaceMgr/PointsRaceMgrSetup.py b/PointsRaceMgr/PointsRaceMgrSetup.py index 5170d28c..a260b1fd 100644 --- a/PointsRaceMgr/PointsRaceMgrSetup.py +++ b/PointsRaceMgr/PointsRaceMgrSetup.py @@ -41,11 +41,11 @@ wxHome = r'C:\Python27\Lib\site-packages\wx-2.8-msw-ansi\wx' try: shutil.copy( os.path.join(wxHome, 'MSVCP71.dll'), distDir ) -except: +except Exception: pass try: shutil.copy( os.path.join(wxHome, 'gdiplus.dll'), distDir ) -except: +except Exception: pass # Add images to the distribution folder. @@ -94,14 +94,13 @@ def make_inno_version(): os.system( cmd ) # Create versioned executable. -from Version import AppVerName vNum = AppVerName.split()[1] vNum = vNum.replace( '.', '_' ) newExeName = 'PointsRaceMgr_Setup_v' + vNum + '.exe' try: os.remove( 'install\\' + newExeName ) -except: +except Exception: pass shutil.copy( 'install\\PointsRaceMgr_Setup.exe', 'install\\' + newExeName ) @@ -114,7 +113,7 @@ def make_inno_version(): try: os.remove( newZipName ) -except: +except Exception: pass z = zipfile.ZipFile(newZipName, "w") diff --git a/PointsRaceMgr/RankDetails.py b/PointsRaceMgr/RankDetails.py index 099e3b09..50dbd26b 100644 --- a/PointsRaceMgr/RankDetails.py +++ b/PointsRaceMgr/RankDetails.py @@ -1,4 +1,3 @@ -import re import wx import wx.grid as gridlib import Model diff --git a/PointsRaceMgr/RankSummary.py b/PointsRaceMgr/RankSummary.py index cc91eb00..120d7dd8 100644 --- a/PointsRaceMgr/RankSummary.py +++ b/PointsRaceMgr/RankSummary.py @@ -2,7 +2,6 @@ import wx.grid as gridlib import Model import Utils -import re class RankSummary( wx.Panel ): def __init__( self, parent, id = wx.ID_ANY ): @@ -25,7 +24,6 @@ def refresh( self ): riders = race.getRiders() if race else [] hasNumWins = race.rankBy == race.RankByLapsPointsNumWins pointsFmt = Utils.asInt if all(rr.pointsTotal == int(rr.pointsTotal) for rr in riders) else Utils.asFloat - existingPointsFmt = Utils.asInt if all(rr.existingPoints == int(rr.existingPoints) for rr in riders) else Utils.asFloat riderInfo = {info.bib:info for info in race.riderInfo} if race else {} diff --git a/PointsRaceMgr/ReorderableGrid.py b/PointsRaceMgr/ReorderableGrid.py index 1abbce2b..6e13e12e 100644 --- a/PointsRaceMgr/ReorderableGrid.py +++ b/PointsRaceMgr/ReorderableGrid.py @@ -262,6 +262,6 @@ def GetSelectedRows( self ): if row not in rows: rows.append(row) else: - rows.append(gcr) + rows.append(gcr) return rows diff --git a/PointsRaceMgr/StartList.py b/PointsRaceMgr/StartList.py index 91f39243..2ecfa7d1 100644 --- a/PointsRaceMgr/StartList.py +++ b/PointsRaceMgr/StartList.py @@ -2,9 +2,6 @@ import wx.grid as gridlib import wx.lib.mixins.grid as gae -import os -import sys -import operator from html.parser import HTMLParser import Utils @@ -198,7 +195,7 @@ def onPaste( self, event ): if name and not info['first_name'] and not info['last_name']: try: info['last_name'], info['first_name'] = name.split(',',1) - except: + except Exception: pass # If there is a bib it must be numeric. @@ -218,7 +215,7 @@ def onPaste( self, event ): self.updateGrid() def onImportFromExcel( self, event ): - dlg = wx.MessageBox( + with wx.MessageBox( 'Import from Excel\n\n' 'Reads the first sheet in the file.\n' 'Looks for the first row starting with "Bib","BibNum","Bib Num", "Bib #" or "Bib#".\n\n' @@ -235,18 +232,21 @@ def onImportFromExcel( self, event ): , 'Import from Excel', wx.OK|wx.CANCEL | wx.ICON_INFORMATION, - ) + ) as dlg: + + if dlg.ShowModal() != wx.ID_OK: + return # Get the excel filename. - openFileDialog = wx.FileDialog(self, "Open Excel file", "", "", - "Excel files (*.xls,*.xlsx,*.xlsm)|*.xls;*.xlsx;*.xlsm", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + with wx.FileDialog(self, "Open Excel file", "", "", + "Excel files (*.xls,*.xlsx,*.xlsm)|*.xls;*.xlsx;*.xlsm", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as openFileDialog: - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return + if openFileDialog.ShowModal() != wx.ID_OK: + return - # proceed loading the file chosen by the user - # this can be done with e.g. wxPython input streams: - excelFile = openFileDialog.GetPath() + # proceed loading the file chosen by the user + # this can be done with e.g. wxPython input streams: + excelFile = openFileDialog.GetPath() excel = GetExcelReader( excelFile ) @@ -278,7 +278,7 @@ def onImportFromExcel( self, event ): if name and not info['first_name'] and not info['last_name']: try: info['last_name'], info['first_name'] = name.split(',',1) - except: + except Exception: pass # If there is a bib it must be numeric. diff --git a/PointsRaceMgr/ToPrintout.py b/PointsRaceMgr/ToPrintout.py index 73804071..c1d5575b 100644 --- a/PointsRaceMgr/ToPrintout.py +++ b/PointsRaceMgr/ToPrintout.py @@ -2,7 +2,6 @@ import os import re from html import escape -import math import datetime import Utils from Utils import tag @@ -63,7 +62,7 @@ def isNumeric( v ): try: f = float(v) return True - except: + except Exception: return False numericCols = set( c for c in range(grid.GetNumberCols()) if all(isNumeric(grid.GetCellValue(r, c)) for r in range(grid.GetNumberRows())) ) @@ -312,8 +311,11 @@ def getTitleGrowTable( includeApprovedBy = True ): rowCur = gt.set( rowCur, 0, 'Approved by:________', GrowTable.alignRight )[0] + 1 return gt +def getBodyGrowTable(): + gt = GrowTable(alignHorizontal=GrowTable.alignLeft, alignVertical=GrowTable.alignTop, cellBorder=False) + return gt + def ToPrintout( dc, grid ): - race = Model.race rankSummary = Utils.getMainWin().rankSummary rankDetails = Utils.getMainWin().rankDetails diff --git a/PointsRaceMgr/Utils.py b/PointsRaceMgr/Utils.py index 483391c8..f2829835 100644 --- a/PointsRaceMgr/Utils.py +++ b/PointsRaceMgr/Utils.py @@ -13,7 +13,7 @@ def initTranslation(): if not initTranslationCalled: try: gettext.install(AppVerName.split()[0], './locale', unicode=True) - except: + except Exception: gettext.install(AppVerName.split()[0], './locale') initTranslationCalled = True @@ -25,7 +25,6 @@ def BigFont(): import os import re import sys -import math import wx.grid as gridlib import traceback import unicodedata @@ -33,8 +32,6 @@ def BigFont(): import datetime import string -import Model - def removeDiacritic( s ): ''' Accept a unicode string, and return a normal string @@ -42,7 +39,7 @@ def removeDiacritic( s ): ''' try: return unicodedata.normalize('NFKD', '{}'.format(s)).encode('ASCII', 'ignore').decode() - except: + except Exception: return s invalidFilenameChars = re.compile( "[^-_.() " + string.ascii_letters + string.digits + "]" ) @@ -149,7 +146,7 @@ def formatTime( secs ): if secs is None: secs = 0 secs = int(secs + 0.5) - hours = secs // (60*60); + hours = secs // (60*60) minutes = (secs // 60) % 60 secs = secs % 60 if hours > 0: @@ -213,7 +210,9 @@ def tag( buf, name, attrs = {} ): # Add access functions for all resource folders. from GetFolder import GetFolders globals().update( {'get' + folder[0].upper() + folder[1:]:lambda v=location: v for folder, location in GetFolders().items()} ) -def getImageFile( fname, folder=getImageFolder() ): +def getImageFile( fname, folder=None ): + if not folder: + folder = imageFolder return os.path.join( folder, fname ) def AlignHorizontalScroll( gFrom, gTo ): diff --git a/PointsRaceMgr/Version.py b/PointsRaceMgr/Version.py index fe54cc3b..f4c6efb2 100644 --- a/PointsRaceMgr/Version.py +++ b/PointsRaceMgr/Version.py @@ -1 +1 @@ -AppVerName="PointsRaceMgr 3.4.14-private" +AppVerName="PointsRaceMgr 3.4.16-private" diff --git a/PointsRaceMgr/VirusTotalSubmit.py b/PointsRaceMgr/VirusTotalSubmit.py index ac56a67a..e0e49a59 100644 --- a/PointsRaceMgr/VirusTotalSubmit.py +++ b/PointsRaceMgr/VirusTotalSubmit.py @@ -5,7 +5,7 @@ import argparse try: from virus_total_apis import PublicApi as VirusTotalPublicApi -except: +except Exception: print( '**** virus_total_apis module not found. Do "pip install virustotal-api"' ) raise diff --git a/SeriesMgr/Aliases.py b/SeriesMgr/Aliases.py index 530ff13d..bf93b997 100644 --- a/SeriesMgr/Aliases.py +++ b/SeriesMgr/Aliases.py @@ -1,6 +1,4 @@ import wx -import os -import sys import SeriesModel import Utils from AliasGrid import AliasGrid diff --git a/SeriesMgr/AliasesCategory.py b/SeriesMgr/AliasesCategory.py index 7ce3ccad..97306d37 100644 --- a/SeriesMgr/AliasesCategory.py +++ b/SeriesMgr/AliasesCategory.py @@ -1,6 +1,4 @@ import wx -import os -import sys import SeriesModel import Utils from AliasGrid import AliasGrid diff --git a/SeriesMgr/AliasesLicense.py b/SeriesMgr/AliasesLicense.py index 9a0c6b0b..fb355961 100644 --- a/SeriesMgr/AliasesLicense.py +++ b/SeriesMgr/AliasesLicense.py @@ -1,6 +1,4 @@ import wx -import os -import sys import SeriesModel import Utils from AliasGrid import AliasGrid diff --git a/SeriesMgr/AliasesTeam.py b/SeriesMgr/AliasesTeam.py index 20c1c131..df323339 100644 --- a/SeriesMgr/AliasesTeam.py +++ b/SeriesMgr/AliasesTeam.py @@ -1,6 +1,4 @@ import wx -import os -import sys import SeriesModel import Utils from AliasGrid import AliasGrid diff --git a/SeriesMgr/CategorySequence.py b/SeriesMgr/CategorySequence.py index 3fce0821..3d19af81 100644 --- a/SeriesMgr/CategorySequence.py +++ b/SeriesMgr/CategorySequence.py @@ -1,13 +1,10 @@ import wx import wx.grid as gridlib -import os -import sys import operator from ReorderableGrid import ReorderableGrid import SeriesModel import Utils -from ReadRaceResultsSheet import GetExcelResultsLink, ExcelLink class CategorySequence(wx.Panel): HeaderNames = ['Category', 'Long Name', 'Indiv Publish', 'Points', 'Consider', 'Must Have Completed', 'Team Publish', 'Team Points', 'Use Nth Result Only', 'Team N'] @@ -127,7 +124,7 @@ def refresh( self, backgroundUpdate=False ): if backgroundUpdate: categoryList = [] else: - with wx.BusyCursor() as wait: + with wx.BusyCursor(): model.extractAllRaceResults() # Also harmonizes the categorySequence categoryList = model.getCategoriesSorted() diff --git a/SeriesMgr/CmdLine.py b/SeriesMgr/CmdLine.py index 4f270656..e0b54520 100644 --- a/SeriesMgr/CmdLine.py +++ b/SeriesMgr/CmdLine.py @@ -1,16 +1,14 @@ -import sys -import argparse import os -import Utils +import sys +import pickle + import SeriesModel import Results -import pickle def CmdLine( args ): - import pdb; pdb.set_trace() seriesFileName = None - if args.series: + if args.series: seriesFileName = args.series ext = os.path.splitext( seriesFileName ) if ext != '.smn': @@ -73,7 +71,7 @@ def CmdLine( args ): score_by_points, score_by_time, score_by_percent = False, False, True output_file = args.output or ((os.path.splitext(args.series)[0] + '.html') if args.series else 'SeriesMgr.html') - results = SeriesModel.model.extractAllRaceResults() + SeriesModel.model.extractAllRaceResults() with open( output_file, 'w', encoding='utf8' ) as f: f.write( Results.getHtml(seriesFileName) ) diff --git a/SeriesMgr/Errors.py b/SeriesMgr/Errors.py index 56170e9a..e881c745 100644 --- a/SeriesMgr/Errors.py +++ b/SeriesMgr/Errors.py @@ -1,10 +1,8 @@ import wx import wx.grid as gridlib -import os -import sys -from ReorderableGrid import ReorderableGrid import SeriesModel +from ReorderableGrid import ReorderableGrid import Utils class Errors(wx.Panel): diff --git a/SeriesMgr/ExportGrid.py b/SeriesMgr/ExportGrid.py index 48c2416d..f0e60256 100644 --- a/SeriesMgr/ExportGrid.py +++ b/SeriesMgr/ExportGrid.py @@ -3,7 +3,6 @@ import xlwt import Utils import Model -import math from html import escape import base64 import datetime diff --git a/SeriesMgr/FieldMap.py b/SeriesMgr/FieldMap.py index b220bbe3..9d9f9117 100644 --- a/SeriesMgr/FieldMap.py +++ b/SeriesMgr/FieldMap.py @@ -10,7 +10,7 @@ def remove_diacritic( s ): ''' try: return unicodedata.normalize('NFKD', '{}'.format(s)).encode('ASCII', 'ignore').decode() - except: + except Exception: return s def normalize( s ): diff --git a/SeriesMgr/FileTrie.py b/SeriesMgr/FileTrie.py index 31b5cae6..56a36b9a 100644 --- a/SeriesMgr/FileTrie.py +++ b/SeriesMgr/FileTrie.py @@ -7,20 +7,26 @@ class filesystem_str( str ): """Case insensitive with respect to hashes and comparisons. """ #--Hash/Compare def __hash__(self): return hash(self.lower()) + def __eq__(self, other): if isinstance(other, str): return self.lower() == other.lower() return NotImplemented + def __ne__(self, other): return not (self == other) + def __lt__(self, other): if isinstance(other, str): return self.lower() < other.lower() return NotImplemented + def __ge__(self, other): return not (self < other) + def __gt__(self, other): if isinstance(other, str): return self.lower() > other.lower() return NotImplemented + def __le__(self, other): return not (self > other) else: filesystem_str = str diff --git a/SeriesMgr/FtpWriteFile.py b/SeriesMgr/FtpWriteFile.py index a592bdbb..1d2f2729 100644 --- a/SeriesMgr/FtpWriteFile.py +++ b/SeriesMgr/FtpWriteFile.py @@ -1,11 +1,9 @@ -import wx -import wx.lib.intctrl import os -import sys import ftplib -import datetime -import threading import webbrowser + +import wx +import wx.lib.intctrl import Utils import SeriesModel diff --git a/SeriesMgr/GetModelInfo.py b/SeriesMgr/GetModelInfo.py index 7b27b2e4..0a707ca3 100644 --- a/SeriesMgr/GetModelInfo.py +++ b/SeriesMgr/GetModelInfo.py @@ -10,15 +10,10 @@ import trueskill import Model -import GpxParse -import GeoAnimation -import Animation -import GanttChart -import ReadSignOnSheet import SeriesModel import Utils -from ReadSignOnSheet import GetExcelLink, ResetExcelLinkCache, HasExcelLink -from GetResults import GetResults, GetCategoryDetails +from ReadSignOnSheet import ResetExcelLinkCache, HasExcelLink +from GetResults import GetResults from Excel import GetExcelReader from FieldMap import standard_field_map, standard_field_aliases from GetMatchingExcelFile import GetMatchingExcelFile @@ -76,7 +71,7 @@ def formatTimeGap( secs, highPrecision = False ): def safe_upper( f ): try: return f.upper() - except: + except Exception: return f def fix_uci_id( uci_id ): @@ -181,7 +176,7 @@ def toInt( n ): return SeriesModel.rankDNF try: return int(n.split()[0]) - except: + except Exception: return n def ExtractRaceResultsExcel( raceInSeries, seriesModel ): @@ -303,7 +298,7 @@ def ExtractRaceResultsExcel( raceInSeries, seriesModel ): if name and not info['firstName'] and not info['lastName']: try: info['lastName'], info['firstName'] = name.split(',',1) - except: + except Exception: pass if not info['firstName'] and not info['lastName']: @@ -324,7 +319,7 @@ def ExtractRaceResultsExcel( raceInSeries, seriesModel ): else: try: info['tFinish'] = float( info['tFinish'] ) * 24.0 * 60.0 * 60.0 # Convert Excel day number to seconds. - except Exception as e: + except Exception: info['tFinish'] = 0.0 #print( info ) @@ -365,7 +360,7 @@ def ExtractRaceResultsCrossMgr( raceInSeries, seriesModel ): with open(fileName, 'rb') as fp, Model.LockRace() as race: race = pickle.load( fp, encoding='latin1', errors='replace' ) FixExcelSheetLocal( fileName, race ) - isFinished = race.isFinished() + #isFinished = race.isFinished() race.tagNums = None race.resetAllCaches() Model.setRace( race ) @@ -437,7 +432,7 @@ def ExtractRaceResultsCrossMgr( raceInSeries, seriesModel ): d = race.date.replace('-', ' ').replace('/', ' ') fields = [int(v) for v in d.split()] + [int(v) for v in race.scheduledStart.split(':')] info['raceDate'] = datetime.datetime( *fields ) - except: + except Exception: info['raceDate'] = None info['bib'] = int(rr.num) @@ -488,7 +483,7 @@ def AdjustForUpgrades( raceResults ): try: upgradeFactor = upgradeFactors[i] - except: + except Exception: upgradeFactor = 0.5 categoryPosition = {} @@ -962,7 +957,7 @@ def GetCategoryResultsTeam( categoryName, raceResults, useMostEventsCompleted=Fa # Get all results for this category and valid teams. trn = set( model.teamResultsNames ) raceResults = [rr for rr in raceResults if rr.categoryName == categoryName and ((rr.team in trn) if trn else rr.teamIsValid)] - if not raceResults or not(scoreByPoints or scoreByTime): + if not raceResults or not (scoreByPoints or scoreByTime): return [], [] # Create a map for race filenames to grade. @@ -973,8 +968,7 @@ def GetCategoryResultsTeam( categoryName, raceResults, useMostEventsCompleted=Fa # Get all races for this category. races = set( RaceTuple(rr.raceDate, rr.raceName, rr.raceURL, rr.raceInSeries) for rr in raceResults ) races = sorted( races, key = lambda r: getattr(r[3], 'iSequence', 0) ) - raceSequence = dict( (r.raceInSeries, i) for i, r in enumerate(races) ) - + def asInt( v ): return int(v) if int(v) == v else v @@ -1009,7 +1003,6 @@ def getTeamPointStructure( raceFileName, categoryName ): for team, rrs in teamParticipants.items(): for rr in rrs: - rider = rr.key() primePoints = rr.primePoints if considerPrimePointsOrTimeBonus else 0 earnedPoints = pointsStructure[rr.rank] + primePoints points = asInt( earnedPoints ) @@ -1089,9 +1082,8 @@ def getBestResults( t ): for rr in rrs: if rr.rank == SeriesModel.rankDNF: continue - rider = rr.key() timeBonus = rr.timeBonus if considerPrimePointsOrTimeBonus else 0 - time = rr.tFinish - timeBonus + #time = rr.tFinish - timeBonus teamResults[raceInSeries][team].append( ResultTuple(0, rr.tFinish, rr.rank, 0, timeBonus, rr) ) if len(teamResults[raceInSeries][team]) < teamResultsN and raceInSeries.getFileName() not in pureTeam: diff --git a/SeriesMgr/MainWin.py b/SeriesMgr/MainWin.py index 7fc738ad..1485c23c 100644 --- a/SeriesMgr/MainWin.py +++ b/SeriesMgr/MainWin.py @@ -1,27 +1,25 @@ -import wx -from wx.lib.wordwrap import wordwrap -import wx.adv as adv -import sys import os -import re -import datetime -import random +import sys import time -import json -import webbrowser -from urllib.request import pathname2url -import locale -import traceback import xlwt import base64 +import random +import locale +import datetime +import traceback import threading +import webbrowser + +import wx +from wx.lib.wordwrap import wordwrap +import wx.adv as adv FontSize = 20 try: localDateFormat = locale.nl_langinfo( locale.D_FMT ) localTimeFormat = locale.nl_langinfo( locale.T_FMT ) -except: +except Exception: localDateFormat = '%b %d, %Y' localTimeFormat = '%I:%M%p' @@ -67,7 +65,7 @@ def ShowSplashScreen(): dc.SelectObject( wx.NullBitmap ) showSeconds = 2.5 - frame = adv.SplashScreen(bitmap, wx.adv.SPLASH_CENTRE_ON_SCREEN|wx.adv.SPLASH_TIMEOUT, int(showSeconds*1000), None) + adv.SplashScreen(bitmap, wx.adv.SPLASH_CENTRE_ON_SCREEN|wx.adv.SPLASH_TIMEOUT, int(showSeconds*1000), None) #---------------------------------------------------------------------------------- @@ -82,7 +80,7 @@ def __init__( self, fileName, tipNo = None ): self.tips.append( line ) if tipNo is None: tipNo = (int(round(time.time() * 1000)) * 13) % (len(self.tips) - 1) - except: + except Exception: pass if tipNo is None: tipNo = 0 @@ -136,7 +134,7 @@ def ShowTipAtStartup(): showTipAtStartup = wx.ShowTip( None, provider, True ) if mainWin: mainWin.config.WriteBool('showTipAtStartup', showTipAtStartup) - except: + except Exception: pass #---------------------------------------------------------------------------------- @@ -348,7 +346,7 @@ def getGraphicFName( self ): graphicFName = self.config.Read( 'graphic', defaultFName ) if graphicFName != defaultFName: try: - with open(graphicFName, 'rb') as f: + with open(graphicFName, 'rb'): return graphicFName except IOError: pass @@ -425,7 +423,7 @@ def getTitle( self ): iSelection = self.notebook.GetSelection() try: pageTitle = self.pages[iSelection].getTitle() - except: + except Exception: pageTitle = self.attrClassName[iSelection][2] if pageTitle == 'Results': @@ -486,12 +484,12 @@ def menuExportToExcel( self, event ): page = self.pages[iSelection] try: grid = page.getGrid() - except: + except Exception: return try: pageTitle = self.pages[iSelection].getTitle() - except: + except Exception: pageTitle = self.attrClassName[iSelection][2] if not self.fileName or len(self.fileName) < 4: @@ -502,9 +500,8 @@ def menuExportToExcel( self, event ): xlfileName = self.fileName[:-4] + '-' + pageTitle + '.xls' with wx.DirDialog( self, 'Folder to write "{}"'.format(os.path.basename(xlfileName)), style=wx.DD_DEFAULT_STYLE, defaultPath=os.path.dirname(xlfileName) ) as dlg: - if ret != wx.ID_OK: + if dlg.ShowModal() != wx.ID_OK: return - ret = dlg.ShowModal() dName = dlg.GetPath() xlfileName = os.path.join( dName, os.path.basename(xlfileName) ) @@ -532,12 +529,12 @@ def menuExportToHtml( self, event ): page = self.pages[iSelection] try: grid = page.getGrid() - except: + except Exception: return try: pageTitle = self.pages[iSelection].getTitle() - except: + except Exception: pageTitle = self.attrClassName[iSelection][2] if not self.fileName or len(self.fileName) < 4: @@ -712,7 +709,6 @@ def writeSeries( self ): def menuNew( self, event ): if self.saveExistingSeries(): - model = SeriesModel.model SeriesModel.model = SeriesModel.SeriesModel() SeriesModel.model.postReadFix() @@ -802,7 +798,7 @@ def menuOpen( self, event ): if Utils.MessageOKCancel(self, 'You have Unsaved Changes. Save Now?', 'Unsaved Changes'): try: self.writeSeries() - except: + except Exception: Utils.MessageOK(self, f'Write Failed. Series NOT saved..\n\n "{self.fileName}"', 'Write Failed', iconMask=wx.ICON_ERROR ) return @@ -820,7 +816,7 @@ def menuSave( self, event ): try: self.writeSeries() - except: + except Exception: Utils.MessageOK(self, f'Write Failed. Series NOT saved.\n\n "{self.fileName}".', 'Write Failed', iconMask=wx.ICON_ERROR ) self.updateRecentFiles() @@ -844,7 +840,7 @@ def menuSaveAs( self, event ): fileName += '.smn' try: - with open(fileName, 'rb') as fp: + with open(fileName, 'rb'): pass if not Utils.MessageOKCancel(self, f'File Exists.\n\n "{fileName}"\n\nReplace?', 'File Exists'): return @@ -852,9 +848,9 @@ def menuSaveAs( self, event ): pass try: - with open(fileName, 'wb') as fp: + with open(fileName, 'wb'): pass - except: + except Exception: Utils.MessageOK(self, f'Cannot open file:\n\n "{fileName}"', 'Cannot Open File', iconMask=wx.ICON_ERROR ) return @@ -970,7 +966,7 @@ def refreshAll( self ): # This eliminates user timeouts. def backgroundRefresh(): with Counter(): - raceResults = model.extractAllRaceResults() + model.extractAllRaceResults() wx.CallAfter( self.results.refresh ) wx.CallAfter( self.teamResults.refresh ) wx.CallAfter( self.categorySequence.refresh ) @@ -1041,12 +1037,12 @@ def MainLoop(): logSize = os.path.getsize( redirectFileName ) if logSize > 1000000: os.remove( redirectFileName ) - except: + except Exception: pass try: app.RedirectStdio( redirectFileName ) - except: + except Exception: pass Utils.initTranslation() @@ -1082,7 +1078,7 @@ def MainLoop(): # Try to load a series. if fileName: if os.path.splitext( fileName )[1] != '.smn': - print( 'Cannot open non SeriesMgr file "{}". Aborting.'.format( filename ), file=sys.stderr ) + print( f'Cannot open non SeriesMgr file "{fileName}". Aborting.', file=sys.stderr ) sys.exit( 1 ) try: mainWin.openSeries( fileName ) @@ -1093,7 +1089,7 @@ def MainLoop(): mainWin.GetSizer().Layout() try: app.MainLoop() - except: + except Exception: xc = traceback.format_exception(*sys.exc_info()) wx.MessageBox(''.join(xc)) diff --git a/SeriesMgr/Options.py b/SeriesMgr/Options.py index f5279120..4466d252 100644 --- a/SeriesMgr/Options.py +++ b/SeriesMgr/Options.py @@ -1,11 +1,8 @@ -import wx -import wx.grid as gridlib -import wx.lib.agw.floatspin as FS import os import io -import re -import sys import base64 + +import wx import SeriesModel import Utils diff --git a/SeriesMgr/Points.py b/SeriesMgr/Points.py index 7d3d4d65..40cf7ed7 100644 --- a/SeriesMgr/Points.py +++ b/SeriesMgr/Points.py @@ -2,11 +2,8 @@ import wx.grid as gridlib import wx.lib.intctrl -import os -import sys from ReorderableGrid import ReorderableGrid import SeriesModel -import Utils class PointsEditor(gridlib.GridCellEditor): @@ -32,12 +29,10 @@ def BeginEdit( self, row, col, grid ): self._tc.SetFocus() def EndEdit( self, row, col, grid, value = None ): - changed = False val = self._tc.GetValue().strip() if val: val = SeriesModel.PointStructure( 'EditCheck', val ).getStr() if val != self.startValue: - change = True grid.GetTable().SetValue( row, col, val ) grid.GetParent().updateDepth( row ) wx.CallAfter( grid.GetParent().gridAutoSize ) @@ -246,7 +241,7 @@ def commit( self ): self.grid.DisableCellEditControl() # Make sure the current edit is committed. pointsList = [] for row in range(self.grid.GetNumberRows()): - if( self.grid.GetCellValue(row, self.NameCol).strip() ): + if self.grid.GetCellValue(row, self.NameCol).strip(): pointsList.append( ( self.grid.GetCellValue(row, self.NameCol), self.grid.GetCellValue(row, self.OldNameCol), diff --git a/SeriesMgr/Races.py b/SeriesMgr/Races.py index a5f327a1..35da8384 100644 --- a/SeriesMgr/Races.py +++ b/SeriesMgr/Races.py @@ -1,12 +1,9 @@ import wx import wx.grid as gridlib -import os -import sys from ReorderableGrid import ReorderableGrid import SeriesModel import Utils -from ReadRaceResultsSheet import GetExcelResultsLink, ExcelLink class Races(wx.Panel): #---------------------------------------------------------------------- @@ -201,7 +198,6 @@ def commit( self ): raceList = [] for row in range(self.grid.GetNumberRows()): - race = SeriesModel.model.races[row] fileName = self.grid.GetCellValue(row, self.RaceFileCol).strip() pname = self.grid.GetCellValue( row, self.PointsCol ) pteamname = self.grid.GetCellValue( row, self.TeamPointsCol ) or None diff --git a/SeriesMgr/ReadRaceResultsSheet.py b/SeriesMgr/ReadRaceResultsSheet.py index 4cdcb73a..b8b118df 100644 --- a/SeriesMgr/ReadRaceResultsSheet.py +++ b/SeriesMgr/ReadRaceResultsSheet.py @@ -3,12 +3,9 @@ import wx.lib.scrolledpanel as scrolled import wx.adv import os -import sys import copy import Utils -import traceback import datetime -import Model from Excel import GetExcelReader #----------------------------------------------------------------------------------------------------- @@ -321,7 +318,7 @@ def onPageChanging( self, evt ): evt.Veto() def onPageChanged( self, evt ): - isForward = evt.GetDirection() + pass #---------------------------------------------------------------------------------- class ExcelLink: @@ -367,7 +364,7 @@ def read( self ): self.raceDate = row[1] elif row[0] == 'Time' and row[1] and isinstance(row[1], datetime.time): self.raceTime = row[1] - except: + except Exception: pass data = {} @@ -381,7 +378,7 @@ def read( self ): try: data[field] = '{}'.format(data[field]) - except: + except Exception: data[field] = '' if not data.get('Category', ''): diff --git a/SeriesMgr/Results.py b/SeriesMgr/Results.py index 58e6d740..9a0cd1d6 100644 --- a/SeriesMgr/Results.py +++ b/SeriesMgr/Results.py @@ -1,13 +1,17 @@ -import wx -import wx.grid as gridlib - import os import io -from html import escape -from urllib.parse import quote -import sys +import re import base64 import datetime +import xlsxwriter +import webbrowser +import subprocess +import platform +from html import escape +from urllib.parse import quote + +import wx +import wx.grid as gridlib import Utils import SeriesModel @@ -17,13 +21,6 @@ import FtpWriteFile from ExportGrid import tag -import xlsxwriter -import io -import re -import webbrowser -import subprocess -import platform - reNoDigits = re.compile( '[^0-9]' ) HeaderNamesTemplate = ['Pos', 'Name', 'License', 'UCI ID', 'Team'] @@ -655,7 +652,6 @@ def readReset( self ): def doLabelClick( self, event ): col = event.GetCol() - label = self.grid.GetColLabelValue( col ) if self.sortCol == col: self.sortCol = -self.sortCol elif self.sortCol == -col: @@ -746,9 +742,6 @@ def fixCategories( self ): def refresh( self, backgroundUpdate=False ): model = SeriesModel.model - scoreByTime = model.scoreByTime - scoreByPercent = model.scoreByPercent - scoreByTrueSkill = model.scoreByTrueSkill self.postPublishCmd.SetValue( model.postPublishCmd ) @@ -756,7 +749,7 @@ def refresh( self, backgroundUpdate=False ): self.raceResults = [] self.categoryChoice.SetItems( [] ) else: - with wx.BusyCursor() as wait: + with wx.BusyCursor(): self.raceResults = model.extractAllRaceResults() self.fixCategories() @@ -866,11 +859,6 @@ def getBracketedNumber( v ): def onPublishToExcel( self, event ): model = SeriesModel.model - scoreByTime = model.scoreByTime - scoreByPercent = model.scoreByPercent - scoreByTrueSkill = model.scoreByTrueSkill - HeaderNames = getHeaderNames() - if Utils.mainWin: if not Utils.mainWin.fileName: Utils.MessageOK( self, 'You must save your Series to a file first.', 'Save Series' ) @@ -931,7 +919,7 @@ def onPublishToExcel( self, event ): headerNames, hasTeam, hasLicense, hasUCIID = fixHeaderNames( results ) headerNames.extend( '{}'.format(r[1]) for r in races ) - ws = wb.add_worksheet( re.sub('[:\\/?*\[\]]', ' ', categoryName) ) + ws = wb.add_worksheet( re.sub('[:\\/?*\\[\\]]', ' ', categoryName) ) wsFit = FitSheetWrapperXLSX( ws ) rowCur = 0 diff --git a/SeriesMgr/Sequence.py b/SeriesMgr/Sequence.py index 40359b47..b61bdca6 100644 --- a/SeriesMgr/Sequence.py +++ b/SeriesMgr/Sequence.py @@ -1,12 +1,9 @@ import wx import wx.grid as gridlib -import os -import sys from ReorderableGrid import ReorderableGrid import SeriesModel import Utils -from ReadRaceResultsSheet import GetExcelResultsLink, ExcelLink class Sequence(wx.Panel): def __init__(self, parent): @@ -29,7 +26,7 @@ def __init__(self, parent): self.grid.DisableDragRowSize() self.grid.SetRowLabelSize( 64 ) self.grid.CreateGrid( 0, len(self.headerNames) ) - for col in xrange(self.grid.GetNumberCols()): + for col in range(self.grid.GetNumberCols()): self.grid.SetColLabelValue( col, self.headerNames[col] ) self.pointsChoiceEditor = gridlib.GridCellChoiceEditor([], allowOthers=False) @@ -164,8 +161,7 @@ def commit( self ): self.grid.DisableCellEditControl() # Make sure the current edit is committed. raceList = [] - for row in xrange(self.grid.GetNumberRows()): - race = SeriesModel.model.Sequence[row] + for row in range(self.grid.GetNumberRows()): fileName = self.grid.GetCellValue(row, self.RaceFileCol).strip() pname = self.grid.GetCellValue( row, self.PointsCol ) if not fileName or not pname: diff --git a/SeriesMgr/SeriesMgrSetup.py b/SeriesMgr/SeriesMgrSetup.py index f5f936db..8ff6c760 100644 --- a/SeriesMgr/SeriesMgrSetup.py +++ b/SeriesMgr/SeriesMgrSetup.py @@ -1,11 +1,9 @@ -from distutils.core import setup import os import shutil import zipfile import sys import datetime import subprocess -import platform # Copy all dependent files from the CrossMgr directory into this directory because we are just being lazy # We use the Dependencies file to figure out what files we want and we do this because it's easier @@ -55,7 +53,7 @@ 'pyinstaller', 'SeriesMgr.pyw', - '--icon=SeriesMgrImages\SeriesMgr.ico', + '--icon=SeriesMgrImages/SeriesMgr.ico', '--clean', '--windowed', '--noconfirm', @@ -70,11 +68,11 @@ wxHome = r'C:\Python27\Lib\site-packages\wx-2.8-msw-ansi\wx' try: shutil.copy( os.path.join(wxHome, 'MSVCP71.dll'), distDir ) -except: +except Exception: pass try: shutil.copy( os.path.join(wxHome, 'gdiplus.dll'), distDir ) -except: +except Exception: pass # Add images to the distribution folder. @@ -101,7 +99,6 @@ def copyDir( d ): inno = innoTest break -from Version import AppVerName def make_inno_version(): setup = { 'AppName': AppVerName.split()[0], @@ -116,6 +113,7 @@ def make_inno_version(): with open('inno_setup.txt', 'w') as f: for k, v in setup.items(): f.write( '{}={}\n'.format(k,v) ) + make_inno_version() cmd = '"' + inno + '" ' + 'SeriesMgr.iss' print( cmd ) @@ -128,7 +126,7 @@ def make_inno_version(): try: os.remove( os.path.join('install',newExeName) ) -except: +except Exception: pass shutil.copy( os.path.join('install', 'SeriesMgr_Setup.exe'), os.path.join('install', newExeName) ) @@ -141,7 +139,7 @@ def make_inno_version(): try: os.remove( newZipName ) -except: +except Exception: pass z = zipfile.ZipFile(newZipName, "w") diff --git a/SeriesMgr/SeriesModel.py b/SeriesMgr/SeriesModel.py index 25643101..64285aa6 100644 --- a/SeriesMgr/SeriesModel.py +++ b/SeriesMgr/SeriesModel.py @@ -1,9 +1,6 @@ import os -import re -import sys from html import escape import copy -import time import operator import functools import datetime @@ -148,7 +145,7 @@ def setStr( self, s ): for v in s.split(): try: values.append( int(v) ) - except: + except Exception: continue self.pointsForPlace = dict( (i+1, v) for i, v in enumerate(sorted(values, reverse=True)) ) @@ -417,22 +414,16 @@ def setReferences( self, references ): dExisting = dict( self.references ) changed = (len(dNew) != len(dExisting)) - updated = False for name, aliases in dNew.items(): if name not in dExisting: changed = True - if aliases: - updated = True elif aliases != dExisting[name]: changed = True - updated = True for name, aliases in dExisting.items(): if name not in dNew: changed = True - if aliases: - updated = True if changed: self.changed = changed @@ -443,30 +434,21 @@ def setReferences( self, references ): key = tuple( [nameToAliasKey(n) for n in alias] ) self.aliasLookup[key] = name - #if updated: - # memoize.clear() - def setReferenceLicenses( self, referenceLicenses ): dNew = dict( referenceLicenses ) dExisting = dict( self.referenceLicenses ) changed = (len(dNew) != len(dExisting)) - updated = False for name, aliases in dNew.items(): if name not in dExisting: changed = True - if aliases: - updated = True elif aliases != dExisting[name]: changed = True - updated = True for name, aliases in dExisting.items(): if name not in dNew: changed = True - if aliases: - updated = True if changed: self.changed = changed @@ -482,22 +464,16 @@ def setReferenceTeams( self, referenceTeams ): dExisting = dict( self.referenceTeams ) changed = (len(dNew) != len(dExisting)) - updated = False for name, aliases in dNew.items(): if name not in dExisting: changed = True - if aliases: - updated = True elif aliases != dExisting[name]: changed = True - updated = True for name, aliases in dExisting.items(): if name not in dNew: changed = True - if aliases: - updated = True if changed: self.changed = changed @@ -513,22 +489,16 @@ def setReferenceCategories( self, referenceCategories ): dExisting = dict( self.referenceCategories ) changed = (len(dNew) != len(dExisting)) - updated = False for name, aliases in dNew.items(): if name not in dExisting: changed = True - if aliases: - updated = True elif aliases != dExisting[name]: changed = True - updated = True for name, aliases in dExisting.items(): if name not in dNew: changed = True - if aliases: - updated = True if changed: self.changed = changed diff --git a/SeriesMgr/TeamResults.py b/SeriesMgr/TeamResults.py index eae9d130..ae56646d 100644 --- a/SeriesMgr/TeamResults.py +++ b/SeriesMgr/TeamResults.py @@ -1,14 +1,7 @@ import re -import wx -import wx.grid as gridlib - -import io import os from html import escape from urllib.parse import quote -import sys -import urllib -import base64 import datetime import xlwt @@ -16,6 +9,9 @@ import webbrowser import subprocess +import wx +import wx.grid as gridlib + import Utils import SeriesModel import GetModelInfo @@ -68,7 +64,7 @@ def formatTeamResults( scoreByPoints, rt ): if scoreByPoints: # The first value is the team score. Subsequent values are the individual ranks. if not rt[0]: - return ''; + return '' return '{}'.format(rt[0]) else: rt = [r for r in rt if r.time] @@ -90,7 +86,6 @@ def getHtml( htmlfileName=None, seriesFileName=None ): model = SeriesModel.model scoreByPoints = model.scoreByPoints scoreByTime = model.scoreByTime - mustHaveCompleted = model.mustHaveCompleted considerPrimePointsOrTimeBonus = model.considerPrimePointsOrTimeBonus raceResults = model.extractAllRaceResults( adjustForUpgrades=False, isIndividual=False ) @@ -288,7 +283,7 @@ def write( s ): write( '{}'.format(escape(categoryDisplayNames.get(categoryName,combinedLabel))) ) hasPrimePoints = any( rr.primePoints for rr in raceResults ) - hasTimeBonus = any( rr.timeBonus for rr in raceResults ) + #hasTimeBonus = any( rr.timeBonus for rr in raceResults ) for iTable, categoryName in enumerate(categoryNames): results, races = GetModelInfo.GetCategoryResultsTeam( @@ -300,8 +295,6 @@ def write( s ): results = filterResults( results, scoreByPoints, scoreByTime ) - headerNames = HeaderNames + ['{}'.format(r[1]) for r in races] - with tag(html, 'div', {'id':'catContent{}'.format(iTable)} ): write( '

') write( '


') @@ -537,7 +530,6 @@ def readReset( self ): def doLabelClick( self, event ): col = event.GetCol() - label = self.grid.GetColLabelValue( col ) if self.sortCol == col: self.sortCol = -self.sortCol elif self.sortCol == -col: @@ -635,7 +627,7 @@ def refresh( self, backgroundUpdate=False ): self.raceResults = [] self.categoryChoice.SetItems( [] ) else: - with wx.BusyCursor() as wait: + with wx.BusyCursor(): self.raceResults = model.extractAllRaceResults( adjustForUpgrades=False, isIndividual=False ) self.fixCategories() @@ -731,8 +723,6 @@ def onPublishToExcel( self, event ): scoreByPoints = model.scoreByPoints scoreByTime = model.scoreByTime - scoreByPercent = model.scoreByPercent - scoreByTrueSkill = model.scoreByTrueSkill HeaderNames = getHeaderNames() if Utils.mainWin: @@ -746,9 +736,6 @@ def onPublishToExcel( self, event ): if not categoryNames: return - pointsForRank = { r.getFileName(): r.pointStructure for r in model.races } - teamPointsForRank = { r.getFileName(): r.teamPointStructure for r in model.races } - wb = xlwt.Workbook() for categoryName in categoryNames: @@ -763,7 +750,7 @@ def onPublishToExcel( self, event ): headerNames = HeaderNames + [r[1] for r in races] - ws = wb.add_sheet( re.sub('[:\\/?*\[\]]', ' ', categoryName) ) + ws = wb.add_sheet( re.sub('[:\\/?*\\[\\]]', ' ', categoryName) ) wsFit = FitSheetWrapper( ws ) fnt = xlwt.Font() @@ -784,7 +771,7 @@ def onPublishToExcel( self, event ): colCur = 0 ws.write_merge( rowCur, rowCur, colCur, colCur + 4, categoryName, xlwt.easyxf( "font: name Arial, bold on;" - ) ); + ) ) rowCur += 2 for c, headerName in enumerate(headerNames): diff --git a/SeriesMgr/TeamResultsNames.py b/SeriesMgr/TeamResultsNames.py index 7bd276f8..8c94903d 100644 --- a/SeriesMgr/TeamResultsNames.py +++ b/SeriesMgr/TeamResultsNames.py @@ -1,9 +1,6 @@ -import wx -import wx.grid as gridlib - import re -import os -import sys + +import wx from ReorderableGrid import ReorderableGrid import SeriesModel import Utils @@ -68,7 +65,7 @@ def doRemoveTeamName( self, event ): if row < 0: Utils.MessageOK(self, 'No Selected Team.\nPlease Select a Team to Remove.', 'No Selected Team') return - if Utils.MessageOKCancel(self, 'Confirm Remove Team:\n\n {}'.format( self.grid.GetCellValue(row, iTeamNameCol) ), 'Remove Team'): + if Utils.MessageOKCancel(self, 'Confirm Remove Team:\n\n {}'.format( self.grid.GetCellValue(row, self.iTeamNameCol) ), 'Remove Team'): self.grid.DeleteRows( row ) self.commit() diff --git a/SeriesMgr/Upgrades.py b/SeriesMgr/Upgrades.py index 163e8850..def3cfb4 100644 --- a/SeriesMgr/Upgrades.py +++ b/SeriesMgr/Upgrades.py @@ -1,12 +1,8 @@ +import re import wx -import wx.grid as gridlib import wx.lib.agw.floatspin as FS -import os -import re -import sys import SeriesModel -import Utils class Upgrades(wx.Panel): def __init__(self, parent): diff --git a/SeriesMgr/Version.py b/SeriesMgr/Version.py index 8a19404e..6bfb241b 100644 --- a/SeriesMgr/Version.py +++ b/SeriesMgr/Version.py @@ -1 +1 @@ -AppVerName="SeriesMgr 3.0.37-private" +AppVerName="SeriesMgr 3.0.38-private" diff --git a/SeriesMgr/virustotal_submit.py b/SeriesMgr/virustotal_submit.py index 23571373..f02e2416 100644 --- a/SeriesMgr/virustotal_submit.py +++ b/SeriesMgr/virustotal_submit.py @@ -119,9 +119,9 @@ def SetProxiesIfNecessary(): dProxies['http'] = HTTP_PROXY if HTTPS_PROXY != '': dProxies['https'] = HTTPS_PROXY - if os.getenv('http_proxy') != None: + if os.getenv('http_proxy') is not None: dProxies['http'] = os.getenv('http_proxy') - if os.getenv('https_proxy') != None: + if os.getenv('https_proxy') is not None: dProxies['https'] = os.getenv('https_proxy') if dProxies != {}: urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler(dProxies), poster.streaminghttp.StreamingHTTPSHandler())) @@ -141,7 +141,7 @@ def VirusTotalSubmit(filenames, options): if filename != filenames[0]: time.sleep(options.delay) jsonResponse, error = VTHTTPScanRequest(filename, options) - if jsonResponse == None: + if jsonResponse is None: f.write( '{}: Scan failed (jsonResponse=None)
\n'.format( os.path.basename(filename)) ) else: oResult = jsonalias.loads(jsonResponse) @@ -169,7 +169,7 @@ def Main(): print(' Use at your own risk') print(' https://DidierStevens.com') return - if os.getenv('VIRUSTOTAL_API2_KEY') != None: + if os.getenv('VIRUSTOTAL_API2_KEY') is not None: VIRUSTOTAL_API2_KEY = os.getenv('VIRUSTOTAL_API2_KEY') if options.key != '': VIRUSTOTAL_API2_KEY = options.key diff --git a/SprintMgr/Chart.py b/SprintMgr/Chart.py index 5c20edda..9a8547a1 100644 --- a/SprintMgr/Chart.py +++ b/SprintMgr/Chart.py @@ -1,8 +1,6 @@ import wx import wx.grid as gridlib -import os -import sys import Utils from ReorderableGrid import ReorderableGrid, GridCellMultiLineStringRenderer from Competitions import SetDefaultData diff --git a/SprintMgr/Events.py b/SprintMgr/Events.py index 2ec341ee..bb2dc851 100644 --- a/SprintMgr/Events.py +++ b/SprintMgr/Events.py @@ -3,7 +3,6 @@ import re import os -import sys import Utils import Model from ReorderableGrid import ReorderableGrid, GridCellMultiLineStringRenderer @@ -138,7 +137,7 @@ def refresh( self, event ): attr = gridlib.GridCellAttr() attr.SetFont( font ) if self.headerNames[col] == 'Bib': - attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ); + attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ) attr.SetReadOnly( True ) elif col == 1 or col == 2: attr.SetReadOnly( True ) @@ -340,7 +339,7 @@ def __init__(self, parent): attr.SetFont( font ) attr.SetReadOnly( True ) if self.headerNames[col].startswith('Bib'): - attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ); + attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ) elif self.headerNames[col].startswith('Status'): attr.SetEditor( gridlib.GridCellChoiceEditor(choices = ['DNS', '']) ) attr.SetReadOnly( False ) @@ -538,7 +537,7 @@ def refresh( self, grid ): self.grid.SetColLabelValue( 0, 'Pos' ) attr = gridlib.GridCellAttr() attr.SetFont( font ) - attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ); + attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ) attr.SetReadOnly( True ) self.grid.SetColAttr( 0, attr ) @@ -549,7 +548,7 @@ def refresh( self, grid ): attr = gridlib.GridCellAttr() attr.SetFont( font ) if headerName == 'Bib': - attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ); + attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ) elif headerName.startswith('Time'): attr.SetAlignment( wx.ALIGN_RIGHT, wx.ALIGN_CENTRE ) elif headerName.startswith('Status'): @@ -626,7 +625,7 @@ def __init__(self, parent): attr = gridlib.GridCellAttr() attr.SetFont( font ) if self.headerNames[col] == 'Bib': - attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ); + attr.SetAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP ) attr.SetReadOnly( True ) elif self.headerNames[col].startswith('Time'): attr.SetEditor( HighPrecisionTimeEditor() ) @@ -820,7 +819,7 @@ def doEventPositionStart( self, e ): self.setState( 2 ) def doEventPositionCancel( self, e ): - del( self.event.starts[-1] ) + del self.event.starts[-1] Model.model.setChanged( True ) Utils.setTitle() self.reset() diff --git a/SprintMgr/ExportGrid.py b/SprintMgr/ExportGrid.py index 8383e12b..f2b1ca32 100644 --- a/SprintMgr/ExportGrid.py +++ b/SprintMgr/ExportGrid.py @@ -2,7 +2,6 @@ import os import Utils import Model -import math from html import escape import base64 from FitSheetWrapper import FitSheetWrapperXLSX @@ -26,7 +25,7 @@ def getHeaderFName(): ''' Get the header bitmap if specified and exists, or use a default. ''' try: graphicFName = Utils.getMainWin().getGraphicFName() - with open(graphicFName, 'rb') as f: + with open(graphicFName, 'rb'): pass return graphicFName except Exception: diff --git a/SprintMgr/FieldDef.py b/SprintMgr/FieldDef.py index 1e6da274..e6f902ce 100644 --- a/SprintMgr/FieldDef.py +++ b/SprintMgr/FieldDef.py @@ -7,8 +7,6 @@ from wx.lib.masked.numctrl import NumCtrl from wx.lib.masked import TimeCtrl, EVT_TIMEUPDATE -import Utils - def convert(name): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() diff --git a/SprintMgr/GraphDraw.py b/SprintMgr/GraphDraw.py index 609176ae..a25977d3 100644 --- a/SprintMgr/GraphDraw.py +++ b/SprintMgr/GraphDraw.py @@ -1,12 +1,9 @@ import wx import bisect -import pickle from collections import defaultdict -import Utils import Model from Competitions import getCompetitions, SetDefaultData, DoRandomSimulation -from Utils import WriteCell from Events import GetFont, GetBoldFont class Graph( wx.Control ): @@ -43,7 +40,7 @@ def OnLeftUp( self, evt ): for rect, rider in self.rectRiders[i]: if rect.Contains(x, y): if self.selectedRider != rider: - self.selectedRider = rider; + self.selectedRider = rider wx.CallAfter( self.Refresh ) return if rect.GetY() > y: @@ -506,6 +503,7 @@ def getImage( self ): frame = GraphDrawFrame() pauseMs = 4000 + def nextCompetition(): i = Model.model.competition.i + 1 if Model.model.competition else 0 Model.model = SetDefaultData( i if i < len(getCompetitions()) else 0 ) diff --git a/SprintMgr/HighPrecisionTimeEdit.py b/SprintMgr/HighPrecisionTimeEdit.py index 0b87f94e..4a1ed45e 100644 --- a/SprintMgr/HighPrecisionTimeEdit.py +++ b/SprintMgr/HighPrecisionTimeEdit.py @@ -4,7 +4,7 @@ import datetime import Utils -reNonTimeChars = re.compile('[^0-9:.]') +reNonTimeChars = re.compile(r'[^0-9:.]') def secsToValue( secs, allow_none, display_seconds, display_milliseconds ): if secs is None and allow_none: @@ -45,11 +45,12 @@ def getSeconds( v, display_seconds, display_milliseconds ): return 0.0 # Masked controls still don't work on anything but Windows. Sigh :( -if platform.system() == 'Windows': +if False: # platform.system() == 'Windows': import wx.lib.masked as masked + class HighPrecisionTimeEdit( masked.TextCtrl ): mask = '##:##:##.###' - validRegex = '[0-9][0-9]:[0-5][0-9]:[0-5][0-9]\.[0-9][0-9][0-9]' + validRegex = r'[0-9][0-9]:[0-5][0-9]:[0-5][0-9]\.[0-9][0-9][0-9]' def __init__( self, parent, id=wx.ID_ANY, seconds=None, display_seconds=True, display_milliseconds=True, value=None, allow_none=False, style=0, size=wx.DefaultSize ): # Utils.writeLog( 'HighPrecisionTimeEdit: Windows' ) @@ -59,10 +60,10 @@ def __init__( self, parent, id=wx.ID_ANY, seconds=None, display_seconds=True, di self.display_milliseconds = display_seconds and display_milliseconds if not display_seconds: self.mask = '##:##' - self.validRegex = '[0-9][0-9]:[0-5][0-9]' + self.validRegex = r'[0-9][0-9]:[0-5][0-9]' elif not display_milliseconds: self.mask = '##:##:##' - self.validRegex = '[0-9][0-9]:[0-5][0-9]:[0-5][0-9]' + self.validRegex = r'[0-9][0-9]:[0-5][0-9]:[0-5][0-9]' self.defaultValue = self.mask.replace('#', '0') self.emptyValue = self.mask.replace('#', ' ') @@ -85,7 +86,11 @@ def GetSeconds( self ): return valueToSecs( v, self.display_seconds, self.display_milliseconds ) def SetSeconds( self, secs ): - super().SetValue( secsToValue(secs, self.allow_none, self.display_seconds, self.display_milliseconds) ) + super().SetValue( + secsToValue(secs, self.allow_none, self.display_seconds, self.display_milliseconds) + if secs is not None + else self.emptyValue + ) def SetValue( self, v ): if self.allow_none and v is None: @@ -140,7 +145,7 @@ def __init__( self, parent, id=wx.ID_ANY, seconds=None, value=None, display_seco def onKeypress(self, event): keycode = event.GetKeyCode() obj = event.GetEventObject() - val = obj.GetValue() + val = super(HighPrecisionTimeEdit, obj).GetValue() # Use the actual text value, not the formatted value. # filter unicode characters if keycode == wx.WXK_NONE: @@ -152,7 +157,7 @@ def onKeypress(self, event): elif chr(keycode) not in string.printable: event.Skip() # allow all other special keycode # allow one '.' - elif chr(keycode) == '.' and '.' not in val: + elif chr(keycode) == '.' and val and '.' not in val: event.Skip() return @@ -167,7 +172,7 @@ def onPaste(self, event): self.SetValue(self.text_data) return else: - WarnTip = TextBoxTipPopup(self, wx.SIMPLE_BORDER,"Incorrect time format on the clipboard") + WarnTip = TextBoxTipPopup(self, wx.SIMPLE_BORDER, "Incorrect time format on the clipboard") xPos, yPos = self.GetPosition() height = WarnTip.GetClientSize()[1] pos = self.ClientToScreen( (xPos - xPos, yPos - yPos + height) ) @@ -224,10 +229,13 @@ def GetValue( self ): mainWin = wx.Frame(None,title="hpte", size=(1024,600)) vs = wx.BoxSizer( wx.VERTICAL ) - hpte1 = HighPrecisionTimeEdit( mainWin, value="10:00:00", size=(200,-1) ) + hpte1 = HighPrecisionTimeEdit( mainWin, value="10:00:00", allow_none=True, size=(200,-1) ) hpte2 = HighPrecisionTimeEdit( mainWin, display_milliseconds=False, value="10:00", size=(200,-1) ) hpte3 = HighPrecisionTimeEdit( mainWin, display_seconds=False, value="10:00", size=(200,-1) ) + hpte1.SetSeconds( None ) + #hpte1.SetValue( '' ) + def getValues( event ): print( 'hpte1: {}, {}'.format(hpte1.GetValue(), hpte1.GetSeconds()) ) print( 'hpte2: {}, {}'.format(hpte2.GetValue(), hpte2.GetSeconds()) ) diff --git a/SprintMgr/MainWin.py b/SprintMgr/MainWin.py index 96fd15cd..693a4804 100644 --- a/SprintMgr/MainWin.py +++ b/SprintMgr/MainWin.py @@ -1,7 +1,3 @@ -import wx -import wx.adv -from wx.lib.wordwrap import wordwrap -import wx.lib.agw.flatnotebook as flatnotebook import os import re import sys @@ -10,16 +6,19 @@ import time import json import webbrowser -import locale import traceback import xlsxwriter from argparse import ArgumentParser -import codecs import base64 import uuid import pickle from io import StringIO +import wx +import wx.adv +from wx.lib.wordwrap import wordwrap +import wx.lib.agw.flatnotebook as flatnotebook + import Utils import Model import Version @@ -34,8 +33,6 @@ from Competitions import SetDefaultData from Printing import SprintMgrPrintout, GraphDrawPrintout from ExportGrid import ExportGrid, tag, writeHtmlHeader -from FitSheetWrapper import FitSheetWrapperXLSX -from Events import FontSize from SetGraphic import SetGraphicDialog @@ -56,11 +53,12 @@ def ShowSplashScreen(): # Show the splash screen. splashStyle = wx.adv.SPLASH_CENTRE_ON_PARENT|wx.adv.SPLASH_TIMEOUT - frame = wx.adv.SplashScreen( + wx.adv.SplashScreen( parent=Utils.getMainWin(), splashStyle=splashStyle, bitmap=bitmap, - milliseconds=int(showSeconds*1000) ) + milliseconds=int(showSeconds*1000) + ) #---------------------------------------------------------------------------------- @@ -307,25 +305,11 @@ def addPage( page, name ): def resetEvents( self ): self.events.reset() - def menuUndo( self, event ): - undo.doUndo() - self.refresh() - - def menuRedo( self, event ): - undo.doRedo() - self.refresh() - def menuTipAtStartup( self, event ): showing = self.config.ReadBool('showTipAtStartup', True) if Utils.MessageOKCancel( self, 'Turn Off Tips at Startup?' if showing else 'Show Tips at Startup?', 'Tips at Startup' ): self.config.WriteBool( 'showTipAtStartup', showing ^ True ) - def menuChangeProperties( self, event ): - if not Model.race: - Utils.MessageOK(self, "You must have a valid race.", "No Valid Race", iconMask=wx.ICON_ERROR) - return - ChangeProperties( self ) - def getDirName( self ): return Utils.getDirName() @@ -718,7 +702,7 @@ def menuSave( self, event ): try: self.writeRace() except Exception: - Utils.MessageOK(self, 'Write Failed. Competition NOT saved.\n\n"{}".'.format(fileName), + Utils.MessageOK(self, f'Write Failed. Competition NOT saved.\n\n"{self.fileName}".', 'Write Failed', iconMask=wx.ICON_ERROR ) self.updateRecentFiles() @@ -748,7 +732,7 @@ def menuSaveAs( self, event ): fileName += '.smr' try: - with open(fileName, 'rb') as fp: + with open(fileName, 'rb'): pass if not Utils.MessageOKCancel(self, 'File Exists. Replace?', 'File Exists'): return @@ -756,7 +740,7 @@ def menuSaveAs( self, event ): pass try: - with open(fileName, 'wb') as fp: + with open(fileName, 'wb'): pass except Exception: Utils.MessageOK(self, 'Cannot open file "{}".'.format(fileName), 'Cannot Open File', iconMask=wx.ICON_ERROR ) @@ -815,7 +799,7 @@ def getGraphicFName( self ): graphicFName = self.config.Read( 'graphic', defaultFName ) if graphicFName != defaultFName: try: - with open(graphicFName, 'rb') as f: + with open(graphicFName, 'rb'): return graphicFName except IOError: pass diff --git a/SprintMgr/Model.py b/SprintMgr/Model.py index 353b5794..2e37efff 100644 --- a/SprintMgr/Model.py +++ b/SprintMgr/Model.py @@ -2,7 +2,6 @@ import copy import random import datetime -import traceback from operator import attrgetter from collections import defaultdict @@ -22,6 +21,7 @@ class Rider: fields = { 'bib', 'first_name', 'last_name', 'team', 'team_code', 'uci_id', 'qualifying_time', 'uci_points', 'seeding_rank', 'status' } extended_fields = fields | {'full_name', 'bib_full_name', 'uci_points_text', 'short_name', 'long_name'} + def __init__( self, bib, first_name = '', last_name = '', team = '', team_code = '', uci_id = '', qualifying_time = QualifyingTimeDefault, @@ -307,7 +307,6 @@ def resetPlaces( self ): # Based on the known places and noncontinue status, set the places again so that the # additional data structures get initialized. state = self.event.competition.state - OpenRider = state.OpenRider bibStatus = [] for pos, id in sorted( (pos, id) for pos, id in self.places.items() ): try: @@ -857,7 +856,7 @@ def getResults( self ): abnormalFinishers.add( rider ) status = riderStatus.get(rider,1) - statTxt = statusText[Finisher] if status != DQ and round > 1 else statusText[status] + #statTxt = statusText[Finisher] if status != DQ and round > 1 else statusText[status] compResults.append( ( -round, status, rank, rider.qualifying_time if rider else sys.float_info.max, diff --git a/SprintMgr/Properties.py b/SprintMgr/Properties.py index 70c2ded0..ad4fd8be 100644 --- a/SprintMgr/Properties.py +++ b/SprintMgr/Properties.py @@ -1,6 +1,4 @@ import wx -import os -import sys import Utils import Model from FieldDef import FieldDef diff --git a/SprintMgr/Qualifiers.py b/SprintMgr/Qualifiers.py index dbef7f92..9ac7b34a 100644 --- a/SprintMgr/Qualifiers.py +++ b/SprintMgr/Qualifiers.py @@ -1,5 +1,3 @@ -import os -import sys import wx import wx.grid as gridlib @@ -100,9 +98,6 @@ def setTestData( self ): def doExcelImport( self, event ): self.grid.SaveEditControlValue() - model = Model.model - riders = model.riders - with wx.FileDialog(self, "Choose Excel file with qualifying times", wildcard="Excel files (*.xlsx)|*.xlsx", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_CHANGE_DIR) as fileDialog: @@ -222,7 +217,6 @@ def commit( self ): # The qualifying times can be changed at any time, however, if the competition is underway, the events cannot # be adusted. model = Model.model - riders = model.riders self.setQualifyingInfo() if model.canReassignStarters(): model.setQualifyingInfo() diff --git a/SprintMgr/ReadStartList.py b/SprintMgr/ReadStartList.py index 90db25ec..aac4c09e 100644 --- a/SprintMgr/ReadStartList.py +++ b/SprintMgr/ReadStartList.py @@ -1,15 +1,10 @@ -import wx -import re import os -import sys -import itertools import copy + +import wx import wx.lib.filebrowsebutton as filebrowse import wx.lib.scrolledpanel as scrolled import wx.adv as adv -import string -import webbrowser -import traceback import Utils import Model @@ -317,7 +312,7 @@ def onPageChanging( self, evt ): evt.Veto() def onPageChanged( self, evt ): - isForward = evt.GetDirection() + pass #---------------------------------------------------------------------------------- class ExcelLink: @@ -344,17 +339,6 @@ def hasField( self, field ): def getFields( self ): return [f for f in Fields if self.hasField(f)] - def get( self ): - # Check the cache, but don't bother with the modification date of the file for performance. - if stateCache and infoCache: - try: - state = (self.fileName, self.sheetName, self.fieldCol) - if state == stateCache[-3:]: - return infoCache - except Exception: - pass - return None - def read( self ): try: reader = GetExcelReader( self.fileName ) @@ -388,7 +372,8 @@ def ImportStartList( parent ): info = excelLink.read() errors = [] - if Utils.MessageYesNo( parent, 'Replace existing Riders from Spreadsheet?\n\nOtherwise, data will be merged by Bib number.', + if Utils.MessageYesNo( parent, + 'Replace existing Riders from Spreadsheet?\n\nOtherwise, data will be merged by Bib number.', 'Replace existing Riders' ): Model.model.riders = [] diff --git a/SprintMgr/ReorderableGrid.py b/SprintMgr/ReorderableGrid.py index 65df85e5..33805fe8 100644 --- a/SprintMgr/ReorderableGrid.py +++ b/SprintMgr/ReorderableGrid.py @@ -270,6 +270,6 @@ def GetSelectedRows( self ): if row not in rows: rows.append(row) else: - rows.append(gcr) + rows.append(gcr) return rows diff --git a/SprintMgr/Results.py b/SprintMgr/Results.py index e2966a8c..514adeb1 100644 --- a/SprintMgr/Results.py +++ b/SprintMgr/Results.py @@ -1,10 +1,7 @@ -import os -import sys import wx import wx.grid as gridlib from operator import attrgetter -import TestData import Model import Utils from ReorderableGrid import ReorderableGrid @@ -103,7 +100,6 @@ def getResultChoices( self ): def fixShowResults( self ): model = Model.model - competition = model.competition choices = self.getResultChoices() self.showResults.SetItems( choices ) diff --git a/SprintMgr/Seeding.py b/SprintMgr/Seeding.py index ad9ed1e6..e7516b79 100644 --- a/SprintMgr/Seeding.py +++ b/SprintMgr/Seeding.py @@ -1,7 +1,5 @@ import os -import sys import random -from operator import attrgetter import wx import wx.grid as gridlib @@ -174,7 +172,7 @@ def doSort( self, event ): self.randomize = sortDlg.randomize.GetValue() ttOrder = sortDlg.ttOrder.GetValue() toSort = model.riders[rMin:rMax] - if randomize: + if self.randomize: keyFunc = lambda r: (-r.uci_points, r.seeding_rank, random.random()) else: keyFunc = lambda r: (-r.uci_points, r.seeding_rank) diff --git a/SprintMgr/SetGraphic.py b/SprintMgr/SetGraphic.py index f7a0d93e..b3dc648d 100644 --- a/SprintMgr/SetGraphic.py +++ b/SprintMgr/SetGraphic.py @@ -1,7 +1,6 @@ -import wx import os import imagebrowser -import Utils +import wx #------------------------------------------------------------------------------------------------ class SetGraphicDialog( wx.Dialog ): diff --git a/SprintMgr/Simulate.py b/SprintMgr/Simulate.py index 338a9c7d..7933def3 100644 --- a/SprintMgr/Simulate.py +++ b/SprintMgr/Simulate.py @@ -1,5 +1,4 @@ from Model import * -import Competitions import random def Simulate( competition ): @@ -9,8 +8,8 @@ def Simulate( competition ): print( 'Qualifying Times:' ) for i, (t, rider) in enumerate(competition.state.getQualifyingTimes()): if rider != competition.state.OpenRider: - print('{:2d: {} {:.3f}'.format(i+1, rider, t) ) - print( ) + print('{:2d}: {} {:.3f}'.format(i+1, rider, t) ) + print() tse = competition.getCanStart() while tse: @@ -23,7 +22,7 @@ def Simulate( competition ): results, dnfs, dqs = competition.getResults() for i, r in enumerate(results): if r and r != competition.state.OpenRider: - print( '{:2d: {}'.format(i+1, r) ) + print( '{:2d}: {}'.format(i+1, r) ) print( '\n'.join( 'DNF: {}'.format(r) for r in dnfs ) ) print( '\n'.join( 'DQ: {}'.format(r) for r in dqs ) ) @@ -76,7 +75,6 @@ def Simulate( competition ): print( e ) print() competition.propagate() - se = competition.getCanStart() raw_input() print() diff --git a/SprintMgr/TestData.py b/SprintMgr/TestData.py index 0e10c0db..31ca3957 100644 --- a/SprintMgr/TestData.py +++ b/SprintMgr/TestData.py @@ -1,5 +1,4 @@ import random -import operator def getTestData(): results = ''' diff --git a/SprintMgr/Utils.py b/SprintMgr/Utils.py index 49f2b4d2..8a7a91a9 100644 --- a/SprintMgr/Utils.py +++ b/SprintMgr/Utils.py @@ -55,7 +55,7 @@ def RemoveDisallowedFilenameChars( filename ): def RemoveDisallowedSheetChars( sheetName ): sheetName = unicodedata.normalize('NFKD', str(sheetName)).encode('ASCII', 'ignore').decode() - return re.sub('[+!#$%&+~`".:;|\\\\/?*\[\] ]+', ' ', sheetName)[:31] # four backslashes required to match one backslash in re. + return re.sub(r'[+!#$%&+~`".:;|\\/?*\[\] ]+', ' ', sheetName)[:31] def ordinal( value ): try: @@ -122,6 +122,7 @@ def __init__( self, grid, row, col = 0 ): self.grid = grid self.row = row self.col = col + def __call__( self, value, horiz=None, vert=None ): self.grid.SetCellValue( self.row, self.col, value ) if horiz is not None or vert is not None: diff --git a/SprintMgr/Version.py b/SprintMgr/Version.py index d14f561b..0a4647b4 100644 --- a/SprintMgr/Version.py +++ b/SprintMgr/Version.py @@ -1 +1 @@ -AppVerName="SprintMgr 3.1.7-private" +AppVerName="SprintMgr 3.1.8-private" diff --git a/SprintMgr/arial10.py b/SprintMgr/arial10.py index 7541af38..f59b317d 100644 --- a/SprintMgr/arial10.py +++ b/SprintMgr/arial10.py @@ -160,7 +160,7 @@ def fitlinewidth(data, bold=False): else: units += charwidths['0'] if bold: - units *= 1.1 + units *= 1.12 return max(units, 700) # Don't go smaller than a reported width of 2 def fitWidth(data, bold=False): diff --git a/SprintMgr/printout.py b/SprintMgr/printout.py index 144d0d8d..bf6a65d4 100644 --- a/SprintMgr/printout.py +++ b/SprintMgr/printout.py @@ -1,6 +1,5 @@ import wx import copy -import types class PrintBase: def SetPrintFont(self, font): # set the DC font parameters @@ -34,7 +33,7 @@ def OutTextRegion(self, textout, txtdraw = True): remain = 'X' while remain != "": vout, remain = self.SetFlow(text, self.region) - if self.draw == True and txtdraw == True: + if self.draw is True and txtdraw is True: test_out = self.TestFull(vout) if self.align == wx.ALIGN_LEFT: self.DC.DrawText(test_out, self.indent+self.pcell_left_margin, y) @@ -122,7 +121,7 @@ def OutTextPageWidth(self, textout, y_out, align, indent, txtdraw = True): remain = 'X' while remain != "": vout, remain = self.SetFlow(text, pagew) - if self.draw == True and txtdraw == True: + if self.draw is True and txtdraw is True: test_out = vout if align == wx.ALIGN_LEFT: self.DC.DrawText(test_out, indent, y) @@ -258,22 +257,22 @@ def AdjustValues(self): if isinstance(first_value, str): # a sequence of strings if self.label == [] and self.set_column == []: data = [] - for x in self.data: #becomes one column + for x in self.data: # becomes one column data.append([x]) else: - data = [self.data] #becomes one row + data = [self.data] # becomes one row self.data = data first_value = data[0] try: column_total = len(first_value) except TypeError: # a sequence of non-iterables if self.label == [] and self.set_column == []: - data = [] #becomes one column + data = [] # becomes one column for x in self.data: data.append(['{}'.format(x)]) column_total = 1 else: - data = [self.data] #becomes one row + data = [self.data] # becomes one row column_total = len(self.data) self.data = data first_value = data[0] @@ -382,7 +381,7 @@ def GetTotalPages(self): while 1: test = self.OutPage() self.page_index.append(self.data_cnt) - if test == False: + if test is False: break cnt = cnt + 1 @@ -453,7 +452,7 @@ def PrintLabel(self): self.y = max_y + self.label_space def PrintHeader(self): # print the header array - if self.draw == False: + if self.draw is False: return for val in self.parent.header: @@ -473,7 +472,7 @@ def PrintHeader(self): # print the header array self.OutTextPageWidth(text+addtext, self.pheader_margin, val["Align"], header_indent, True) def PrintFooter(self): # print the header array - if self.draw == False: + if self.draw is False: return footer_pos = self.parent.page_height * self.pheight - self.pfooter_margin + self.vertical_offset @@ -508,7 +507,7 @@ def LabelColorRow(self, colour): self.end_x-self.column[0]+1, height) def ColourRowCells(self, height): - if self.draw == False: + if self.draw is False: return col = 0 @@ -581,8 +580,7 @@ def FinishDraw(self): self.DrawColumns() # draw all vertical lines def DrawGridLine(self): - if self.draw == True \ - and len(self.column) > 2: #supress grid lines if only one column + if self.draw is True and len(self.column) > 2: # suppress grid lines if only one column try: size = self.row_line_size[self.data_cnt] except Exception: @@ -602,8 +600,7 @@ def DrawGridLine(self): self.DC.DrawLine(self.column[0], y_out, self.end_x, y_out) def DrawColumns(self): - if self.draw == True \ - and len(self.column) > 2: #surpress grid line if only one column + if self.draw is True and len(self.column) > 2: # suppress grid line if only one column col = 0 for val in self.column: try: @@ -628,7 +625,6 @@ def DrawText(self): self.DoRefresh() def DoDrawing(self, DC): - size = DC.GetSize() self.DC = DC DC.BeginDrawing() @@ -974,10 +970,6 @@ def SetPreview(self, preview, scale): self.preview = preview self.scale = scale - def SetTotalSize(self, width, height): - self.ptwidth = width - self.ptheight = height - class PrintGrid: def __init__(self, parent, grid, format = [], total_col = None, total_row = None): if total_row is None: @@ -1119,8 +1111,8 @@ def OnPrintPage(self, page): 'This is the first line of text.', 'This is the second line\nand the third. The fourth will be the number "4.0".', 04.00, - 'This is the fifth line, but by design it is too long to fit in the width of a standard'\ - ' page, so it will be forced to wrap around in order to fit without having '\ + 'This is the fifth line, but by design it is too long to fit in the width of a standard' + ' page, so it will be forced to wrap around in order to fit without having ' 'some of its verbose verbage truncated.', 'Here we have the final line.' ) diff --git a/StageRaceGC/MainWin.py b/StageRaceGC/MainWin.py index 14a26390..fdaa0c9c 100644 --- a/StageRaceGC/MainWin.py +++ b/StageRaceGC/MainWin.py @@ -1,25 +1,17 @@ import wx import wx.adv -import wx.lib.masked.numctrl as NC -import wx.lib.intctrl as IC -from wx.lib.wordwrap import wordwrap import wx.lib.filebrowsebutton as filebrowse import wx.lib.agw.flatnotebook as flatnotebook import wx.lib.mixins.listctrl as listmix -import sys import os -import re import datetime import traceback -import xlwt -from optparse import OptionParser +from argparse import ArgumentParser from roundbutton import RoundButton import Utils -from ReorderableGrid import ReorderableGrid import Model -import Version from StageRaceGCToExcel import StageRaceGCToExcel from StageRaceGCToGrid import StageRaceGCToGrid from MakeExampleExcel import MakeExampleExcel @@ -29,7 +21,7 @@ def ShowSplashScreen(): bitmap = wx.Bitmap( os.path.join(Utils.getImageFolder(), 'StageRaceGC.png'), wx.BITMAP_TYPE_PNG ) showSeconds = 2.5 - frame = wx.adv.SplashScreen(bitmap, wx.adv.SPLASH_CENTRE_ON_SCREEN|wx.adv.SPLASH_TIMEOUT, int(showSeconds*1000), None) + wx.adv.SplashScreen(bitmap, wx.adv.SPLASH_CENTRE_ON_SCREEN|wx.adv.SPLASH_TIMEOUT, int(showSeconds*1000), None) class ListMixCtrl( wx.ListCtrl, listmix.ListCtrlAutoWidthMixin ): def __init__( self, parent, ID=-1, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0 ): @@ -211,7 +203,7 @@ def callbackUpdate( self, message ): def doUpdate( self, event=None, fnameNew=None ): try: self.fname = (fnameNew or event.GetString() or self.fileBrowse.GetValue()) - except: + except Exception: self.fname = u'' if not self.fname: @@ -223,7 +215,7 @@ def doUpdate( self, event=None, fnameNew=None ): return try: - with open(self.fname, 'rb') as f: + with open(self.fname, 'rb'): pass except Exception as e: traceback.print_exc() @@ -235,24 +227,22 @@ def doUpdate( self, event=None, fnameNew=None ): self.filehistory.Save( self.config ) self.fileBrowse.SetValue( self.fname ) - wait = wx.BusyCursor() - labelSave, backgroundColourSave = self.updateButton.GetLabel(), self.updateButton.GetForegroundColour() - - try: - Model.read( self.fname, callbackfunc=self.updateStageList ) - except Exception as e: - traceback.print_exc() - Utils.MessageOK( self, '{}:\n\n {}\n\n{}'.format( _('Excel File Error'), self.fname, e), _('Excel File Error') ) - self.setUpdated( False ) - return - - Model.model.getGCs() - self.setUpdated( True ) - - self.updateStageList() - StageRaceGCToGrid( self.notebook ) + with wx.BusyCursor(): + try: + Model.read( self.fname, callbackfunc=self.updateStageList ) + except Exception as e: + traceback.print_exc() + Utils.MessageOK( self, '{}:\n\n {}\n\n{}'.format( _('Excel File Error'), self.fname, e), _('Excel File Error') ) + self.setUpdated( False ) + return + + Model.model.getGCs() + self.setUpdated( True ) + + self.updateStageList() + StageRaceGCToGrid( self.notebook ) - self.lastUpdateTime = datetime.datetime.now() + self.lastUpdateTime = datetime.datetime.now() def getOutputExcelName( self ): fname_base, fname_suffix = os.path.splitext(self.fname) @@ -283,8 +273,8 @@ def saveAsExcel( self, event ): ) return - wait = wx.BusyCursor() - Utils.LaunchApplication( fname_excel ) + with wx.BusyCursor(): + Utils.LaunchApplication( fname_excel ) # Set log file location. dataDir = '' @@ -297,18 +287,14 @@ def MainLoop(): app = wx.App( False ) app.SetAppName("StageRaceGC") - parser = OptionParser( usage = "usage: %prog [options] [StageRaceGCSpreadsheet.xlsx]" ) - parser.add_option("-f", "--file", dest="filename", help="stage race info file", metavar="StageRaceGCSpreadsheet.xlsx") - parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help='hide splash screen') - parser.add_option("-r", "--regular", action="store_true", dest="regular", default=False, help='regular size') - (options, args) = parser.parse_args() + parser = ArgumentParser() + parser.add_argument("-q", "--quiet", action="store_false", dest="verbose", default=True, help='hide splash screen') + parser.add_argument("-r", "--regular", action="store_true", dest="regular", default=False, help='regular size') + parser.add_argument("filename", nargs='?', default=None, help="stage race info file", metavar="StageRaceGCSpreadsheet.xlsx") + args = parser.parse_args( ) # Try to open a specified filename. - fileName = options.filename - - # If nothing, try a positional argument. - if not fileName and args: - fileName = args[0] + fileName = args.filename dataDir = Utils.getHomeDir() redirectFileName = os.path.join(dataDir, 'StageRaceGC.log') @@ -320,30 +306,30 @@ def MainLoop(): logSize = os.path.getsize( redirectFileName ) if logSize > 1000000: os.remove( redirectFileName ) - except: + except Exception: pass try: app.RedirectStdio( redirectFileName ) - except: + except Exception: pass mainWin = MainWin( None, title=AppVerName, size=(800,600) ) - if not options.regular: + if not args.regular: mainWin.Maximize( True ) # Set the upper left icon. try: icon = wx.Icon( os.path.join(Utils.getImageFolder(), 'StageRaceGC.ico'), wx.BITMAP_TYPE_ICO ) mainWin.SetIcon( icon ) - except: + except Exception: pass mainWin.Show() if fileName: wx.CallAfter( mainWin.doUpdate, fnameNew=fileName ) - if options.verbose: + if args.verbose: ShowSplashScreen() # Start processing events. diff --git a/StageRaceGC/MakeExampleExcel.py b/StageRaceGC/MakeExampleExcel.py index 3fdadb9e..70426d7b 100644 --- a/StageRaceGC/MakeExampleExcel.py +++ b/StageRaceGC/MakeExampleExcel.py @@ -1,21 +1,15 @@ # coding=utf8 import os -import datetime -import operator import random +import operator import xlsxwriter import Utils -from Excel import GetExcelReader from FitSheetWrapper import FitSheetWrapperXLSX def get_license(): return ''.join( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[random.randint(0,25)] for i in range(6) ) -def get_uci_id(): - dob = datetime.date.today() - datetime.timedelta( days=random.normalvariate(25,3)*365.25 ) - return 'FRA{}'.format( dob.strftime( '%Y%m%d' ) ) - def get_uci_id(): uci_id = ''.join(random.choice('123456789') for i in range(9)) uci_id += '{:02d}'.format(int(uci_id)%97) diff --git a/StageRaceGC/Model.py b/StageRaceGC/Model.py index 2fc4ced8..950d02eb 100644 --- a/StageRaceGC/Model.py +++ b/StageRaceGC/Model.py @@ -1,9 +1,4 @@ -import os import re -import sys -import six -import math -import datetime import operator from collections import defaultdict, namedtuple from ValueContext import ValueContext as VC @@ -95,7 +90,7 @@ def __init__( self, **kwargs ): if self.uci_id: try: self.uci_id = int(self.uci_id) - except: + except Exception: pass self.uci_id = str(self.uci_id).strip() if len(self.uci_id) != 11: @@ -118,7 +113,7 @@ def __repr__( self ): def ExcelTimeToSeconds( t ): if t is not None: - assert isinstance(t, six.string_types) + assert isinstance(t, str) return Utils.StrToSeconds( t.replace('"',':').replace("'",':') ) return t @@ -156,7 +151,7 @@ def processDeferred( bibResult ): for pointsType, bib, i, v in Result.deferred: try: result = bibResult[bib] - except: + except Exception: continue setValueAt( result.kom if pointsType == 'kom' else result.sprint, i-1, v ) Result.deferred = [] @@ -167,7 +162,7 @@ def __init__( self, **kwargs ): try: self.stage_sprint = int(kwargs.pop('stagesprint', '0')) - except: + except Exception: self.stage_sprint = 0 for f in self.Fields: @@ -191,7 +186,7 @@ def setListValue( a, k, v ): try: bib = int(bib.strip()) v = int(v.strip()) - except: + except Exception: return self.deferred.append( ('kom' if a == self.kom else 'sprint', bib, i, v) ) return @@ -199,7 +194,7 @@ def setListValue( a, k, v ): # Otherwise, add this result to this rider. try: v = int(v) - except: + except Exception: return setValueAt( a, i-1, v ) @@ -218,7 +213,7 @@ def setListValue( a, k, v ): try: self.row = int(self.row) - except: + except Exception: self.row = 0 if not self.place: @@ -226,15 +221,13 @@ def setListValue( a, k, v ): else: try: self.place = int( self.place ) - except: + except Exception: pass if not isinstance( self.place, int ): self.place = 'AB' def __repr__( self ): - values = [u'{}'.format(getattr(self, a)) for a in self.Fields - if not a.startswith('sprint') and not a.startswith('kom')] kom = 'kom=[{}]'.format(','.join('{}'.format(v) for v in self.kom)) sprint = 'sprint=[{}]'.format(','.join('{}'.format(v) for v in self.sprint)) stage_sprint = 'stage_sprint={}'.format( self.stage_sprint ) @@ -289,7 +282,7 @@ def readSheet( reader, sheet_name, header_fields ): if len(climb_categories) < i: climb_categories.extend( [ClimbCategoryLowest] * (i - len(climb_categories)) ) climb_categories[i-1] = category - except: + except Exception: pass for h in header_fields: @@ -439,7 +432,7 @@ def __init__( self, **kwargs ): try: self.row = int(self.row) - except: + except Exception: pass def __repr__( self ): @@ -534,9 +527,9 @@ def read( self, fname, callbackfunc=None ): stage = StageTTT( sheet_name ) elif sheet_name.lower().replace(' ', '') == 'teampenalties': self.team_penalties = TeamPenalties( sheet_name ) - errors = team_penalties.read() + errors = self.team_penalties.read() self.all_teams = { r.team for r in self.registration.riders } - for team in team_penalties.team_penalties.iterkeys(): + for team in self.team_penalties.iterkeys(): if team not in self.all_teams: errors.append( 'Unknown Team: {}'. format(team) ) continue @@ -776,7 +769,7 @@ def getSprintGC( self ): continue try: stage_sprint_count = max(len(r.sprint) for r in stage.results) - except: + except Exception: continue stage_sprint_points = 0 stage_sprint_winner = 0 diff --git a/StageRaceGC/StageRaceGCToExcel.py b/StageRaceGC/StageRaceGCToExcel.py index d3c3314a..cd3e050d 100644 --- a/StageRaceGC/StageRaceGCToExcel.py +++ b/StageRaceGC/StageRaceGCToExcel.py @@ -1,7 +1,5 @@ -import wx -import sys -import datetime import xlsxwriter + import Utils import Model from FitSheetWrapper import FitSheetWrapperXLSX @@ -40,10 +38,6 @@ def formatContextList( context ): time_format = wb.add_format( {'num_format': 'hh:mm:ss'} ) high_precision_time_format = wb.add_format( {'num_format': 'hh:mm:ss.000'} ) - comment_style = {'width':400} - wide_comment_style = {'width':800} - narrow_comment_style = {'width':256} - #--------------------------------------------------------------------------------------- def writeIC( ws, stage ): fit_sheet = FitSheetWrapperXLSX( ws ) @@ -70,25 +64,25 @@ def writeIC( ws, stage ): col = 0 if r.retired_stage > 0: - fit_sheet.write( rowNum, col, 'AB' ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, 'AB' ) else: - fit_sheet.write( rowNum, col, place ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, place ) - fit_sheet.write( rowNum, col, r.bib ); col += 1 - fit_sheet.write( rowNum, col, rider.last_name.upper() ); col += 1 - fit_sheet.write( rowNum, col, rider.first_name ); col += 1 - fit_sheet.write( rowNum, col, rider.team ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, r.bib ) + fit_sheet.write( rowNum, (col:=col+1)-1, rider.last_name.upper() ) + fit_sheet.write( rowNum, (col:=col+1)-1, rider.first_name ) + fit_sheet.write( rowNum, (col:=col+1)-1, rider.team ) if 'uci_id' in riderFields: - fit_sheet.write( rowNum, col, rider.uci_id ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, rider.uci_id ) if 'license' in riderFields: - fit_sheet.write( rowNum, col, rider.license ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, rider.license ) if r.retired_stage == 0: - fit_sheet.write( rowNum, col, r.gap / (24.0*60.0*60.0), time_format ); col += 1 - fit_sheet.write( rowNum, col, r.total_time_with_bonus_plus_penalty / (24.0*60.0*60.0), time_format ); col += 1 - fit_sheet.write( rowNum, col, r.total_time_with_bonus_plus_penalty_plus_second_fraction / (24.0*60.0*60.0), high_precision_time_format ); col += 1 - fit_sheet.write( rowNum, col, r.last_stage_place ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, r.gap / (24.0*60.0*60.0), time_format ) + fit_sheet.write( rowNum, (col:=col+1)-1, r.total_time_with_bonus_plus_penalty / (24.0*60.0*60.0), time_format ) + fit_sheet.write( rowNum, (col:=col+1)-1, r.total_time_with_bonus_plus_penalty_plus_second_fraction / (24.0*60.0*60.0), high_precision_time_format ) + fit_sheet.write( rowNum, (col:=col+1)-1, r.last_stage_place ) rowNum +=1 @@ -105,23 +99,19 @@ def writeTeamClass( ws, stage ): for place, tc in enumerate(stage.team_classification, 1): col = 0 - fit_sheet.write( rowNum, col, place ); col += 1 - fit_sheet.write( rowNum, col, tc.team ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, place ) + fit_sheet.write( rowNum, (col:=col+1)-1, tc.team ) - fit_sheet.write( rowNum, col, tc.gap / (24.0*60.0*60.0), time_format ) - col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, tc.gap / (24.0*60.0*60.0), time_format ) - fit_sheet.write( rowNum, col, tc.sum_best_top_times.value / (24.0*60.0*60.0), time_format ) - # ws.write_comment( rowNum, col, formatContext(tc.sum_best_top_times.context), comment_style ) - col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, tc.sum_best_top_times.value / (24.0*60.0*60.0), time_format ) + # ws.write_comment( rowNum, col-1, formatContext(tc.sum_best_top_times.context), comment_style ) - fit_sheet.write( rowNum, col, tc.sum_best_top_places.value ) - # ws.write_comment( rowNum, col, formatContext(tc.sum_best_top_places.context), comment_style ) - col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, tc.sum_best_top_places.value ) + # ws.write_comment( rowNum, col-1, formatContext(tc.sum_best_top_places.context), comment_style ) - fit_sheet.write( rowNum, col, tc.best_place.value ) - # ws.write_comment( rowNum, col, formatContext(tc.best_place.context), comment_style ) - col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, tc.best_place.value ) + # ws.write_comment( rowNum, col-1, formatContext(tc.best_place.context), comment_style ) rowNum +=1 #--------------------------------------------------------------------------------------- @@ -142,21 +132,19 @@ def writeTeamGC( ws ): leaderTime = None for place, tgc in enumerate(model.team_gc, 1): col = 0 - fit_sheet.write( rowNum, col, place ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, place ) - fit_sheet.write( rowNum, col, tgc[-1] ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, tgc[-1] ) timeCur = tgc[0].value if leaderTime is None: leaderTime = timeCur gap = timeCur - leaderTime - fit_sheet.write( rowNum, col, gap / (24.0*60.0*60.0), time_format ) - col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, gap / (24.0*60.0*60.0), time_format ) - fit_sheet.write( rowNum, col, timeCur / (24.0*60.0*60.0), time_format ) - # ws.write_comment( rowNum, col, formatContextList(tgc[0].context), wide_comment_style ) - col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, timeCur / (24.0*60.0*60.0), time_format ) + # ws.write_comment( rowNum, col-1, formatContextList(tgc[0].context), wide_comment_style ) for i in range(1, len(tgc)-2): if tgc[i].value: @@ -164,16 +152,15 @@ def writeTeamGC( ws ): # ws.write_comment( rowNum, col, u'\n'.join(tgc[i].context), narrow_comment_style ) col += 1 - fit_sheet.write( rowNum, col, tgc[-2].value ) + fit_sheet.write( rowNum, (col:=col+1)-1, tgc[-2].value ) # ws.write_comment( rowNum, col, formatContext(tgc[-2].context), comment_style ) - col += 1 rowNum +=1 for team in model.unranked_teams: col = 0 - fit_sheet.write( rowNum, col, 'DNF' ); col += 1 - fit_sheet.write( rowNum, col, team ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, 'DNF' ) + fit_sheet.write( rowNum, (col:=col+1)-1, team ) rowNum +=1 #--------------------------------------------------------------------------------------- @@ -200,16 +187,16 @@ def writeSprintGC( ws ): continue col = 0 - fit_sheet.write( rowNum, col, str(place) ); col += 1 - fit_sheet.write( rowNum, col, str(rider.bib) ); col += 1 - fit_sheet.write( rowNum, col, str(rider.last_name).upper()); col += 1 - fit_sheet.write( rowNum, col, str(rider.first_name) ); col += 1 - fit_sheet.write( rowNum, col, str(rider.team) ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, str(place) ) + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.bib) ) + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.last_name).upper()) + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.first_name) ) + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.team) ) if 'uci_id' in riderFields: - fit_sheet.write( rowNum, col, str(rider.uci_id) ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.uci_id) ) if 'license' in riderFields: - fit_sheet.write( rowNum, col, str(rider.license) ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.license) ) for v in r[:-1]: if v: @@ -242,16 +229,16 @@ def writeKOMGC( ws ): continue col = 0 - fit_sheet.write( rowNum, col, str(place) ); col += 1 - fit_sheet.write( rowNum, col, str(rider.bib) ); col += 1 - fit_sheet.write( rowNum, col, str(rider.last_name).upper()); col += 1 - fit_sheet.write( rowNum, col, str(rider.first_name) ); col += 1 - fit_sheet.write( rowNum, col, str(rider.team) ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, str(place) ) + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.bib) ) + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.last_name).upper()) + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.first_name) ) + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.team) ) if 'uci_id' in riderFields: - fit_sheet.write( rowNum, col, str(rider.uci_id) ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.uci_id) ) if 'license' in riderFields: - fit_sheet.write( rowNum, col, str(rider.license) ); col += 1 + fit_sheet.write( rowNum, (col:=col+1)-1, str(rider.license) ) for v in r[:-1]: if v: diff --git a/StageRaceGC/StageRaceGCToGrid.py b/StageRaceGC/StageRaceGCToGrid.py index 9c309de9..80035421 100644 --- a/StageRaceGC/StageRaceGCToGrid.py +++ b/StageRaceGC/StageRaceGCToGrid.py @@ -1,6 +1,6 @@ import wx import wx.grid as gridlib -import sys + import Utils import Model from ReorderableGrid import ReorderableGrid @@ -54,7 +54,7 @@ def callback( event ): if key != model.lastKey: try: event.GetEventObject().SetToolTip(model.comments[key]) - except: + except Exception: event.GetEventObject().SetToolTip(u'') model.lastKey = key event.Skip() @@ -97,33 +97,31 @@ def writeIC( stage ): col = 0 if r.retired_stage > 0: - grid.SetCellValue( rowNum, col, 'AB' ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, 'AB' ) else: - grid.SetCellValue( rowNum, col, str(place) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(place) ) - grid.SetCellValue( rowNum, col, str(r.bib) ); col += 1 - grid.SetCellValue( rowNum, col, str(rider.last_name).upper()); col += 1 - grid.SetCellValue( rowNum, col, str(rider.first_name) ); col += 1 - grid.SetCellValue( rowNum, col, str(rider.team) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(r.bib) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.last_name).upper()) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.first_name) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.team) ) if 'uci_id' in riderFields: - grid.SetCellValue( rowNum, col, str(rider.uci_id) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.uci_id) ) if 'license' in riderFields: - grid.SetCellValue( rowNum, col, str(rider.license) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.license) ) if r.retired_stage == 0: - grid.SetCellValue( rowNum, col, Utils.formatTime(r.gap, twoDigitHours=True) if gapLast != r.gap else sameGap ) + grid.SetCellValue( rowNum, (col:=col+1)-1, Utils.formatTime(r.gap, twoDigitHours=True) if gapLast != r.gap else sameGap ) gapLast = r.gap - col += 1 timeCur = r.total_time_with_bonus_plus_penalty - grid.SetCellValue( rowNum, col, Utils.formatTime(timeCur, twoDigitHours=True) if timeCur != timeLast else sameTime ) + grid.SetCellValue( rowNum, (col:=col+1)-1, Utils.formatTime(timeCur, twoDigitHours=True) if timeCur != timeLast else sameTime ) timeLast = timeCur - col += 1 - grid.SetCellValue( rowNum, col, Utils.formatTime(r.total_time_with_bonus_plus_penalty_plus_second_fraction, twoDigitHours=True, extraPrecision=True) ); col += 1 - grid.SetCellValue( rowNum, col, str(r.sum_of_places) ); col += 1 - grid.SetCellValue( rowNum, col, str(r.last_stage_place) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, Utils.formatTime(r.total_time_with_bonus_plus_penalty_plus_second_fraction, twoDigitHours=True, extraPrecision=True) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(r.sum_of_places) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(r.last_stage_place) ) rowNum +=1 @@ -153,26 +151,22 @@ def writeTeamClass( stage ): timeLast = None for place, tc in enumerate(stage.team_classification, 1): col = 0 - grid.SetCellValue( rowNum, col, str(place) ); col += 1 - grid.SetCellValue( rowNum, col, tc.team ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(place) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, tc.team ) - grid.SetCellValue( rowNum, col, Utils.formatTime(tc.gap, twoDigitHours=True) if tc.gap != gapLast else sameGap ) + grid.SetCellValue( rowNum, (col:=col+1)-1, Utils.formatTime(tc.gap, twoDigitHours=True) if tc.gap != gapLast else sameGap ) gapLast = tc.gap - col += 1 timeCur = tc.sum_best_top_times.value - grid.SetCellValue( rowNum, col, Utils.formatTime(timeCur, forceHours=True) if timeCur != timeLast else sameTime ) + grid.SetCellValue( rowNum, (col:=col+1)-1, Utils.formatTime(timeCur, forceHours=True) if timeCur != timeLast else sameTime ) timeLast = timeCur - setComment( rowNum, col, formatContext(tc.sum_best_top_times.context), {'width':256} ) - col += 1 + setComment( rowNum, col-1, formatContext(tc.sum_best_top_times.context), {'width':256} ) - grid.SetCellValue( rowNum, col, str(tc.sum_best_top_places.value) ) - setComment( rowNum, col, formatContext(tc.sum_best_top_places.context), {'width':256} ) - col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(tc.sum_best_top_places.value) ) + setComment( rowNum, col-1, formatContext(tc.sum_best_top_places.context), {'width':256} ) - grid.SetCellValue( rowNum, col, str(tc.best_place.value) ) - setComment( rowNum, col, formatContext(tc.best_place.context), {'width':256} ) - col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(tc.best_place.value) ) + setComment( rowNum, col-1, formatContext(tc.best_place.context), {'width':256} ) rowNum +=1 grid.GetGridWindow().Bind(wx.EVT_MOTION, getCommentCallback(grid)) @@ -205,20 +199,19 @@ def writeTeamGC(): timeLast = None for place, tgc in enumerate(model.team_gc, 1): col = 0 - grid.SetCellValue( rowNum, col, str(place) ); col += 1 - grid.SetCellValue( rowNum, col, str(tgc[-1]) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(place) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(tgc[-1]) ) combinedTime = tgc[0].value if leaderTime is None: leaderTime = combinedTime gap = combinedTime - leaderTime - grid.SetCellValue( rowNum, col, Utils.formatTime(gap, twoDigitHours=True) if gap != gapLast else sameGap ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, Utils.formatTime(gap, twoDigitHours=True) if gap != gapLast else sameGap ) gapLast = gap - grid.SetCellValue( rowNum, col, Utils.formatTime(combinedTime, forceHours=True) if combinedTime != timeLast else sameTime) + grid.SetCellValue( rowNum, (col:=col+1)-1, Utils.formatTime(combinedTime, forceHours=True) if combinedTime != timeLast else sameTime) timeLast = combinedTime - setComment( rowNum, col, formatContextList(tgc[0].context), {'width':512} ) - col += 1 + setComment( rowNum, col-1, formatContextList(tgc[0].context), {'width':512} ) for i in range(1, len(tgc)-2): if tgc[i].value: @@ -226,16 +219,15 @@ def writeTeamGC(): setComment( rowNum, col, u'\n'.join(tgc[i].context), {'width':128} ) col += 1 - grid.SetCellValue( rowNum, col, str(tgc[-2].value) ) - setComment( rowNum, col, formatContext(tgc[-2].context), {'width':256} ) - col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(tgc[-2].value) ) + setComment( rowNum, col-1, formatContext(tgc[-2].context), {'width':256} ) rowNum +=1 for team in model.unranked_teams: col = 0 - grid.SetCellValue( rowNum, col, 'DNF' ); col += 1 - grid.SetCellValue( rowNum, col, team ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, 'DNF' ) + grid.SetCellValue( rowNum, (col:=col+1)-1, team ) rowNum +=1 grid.GetGridWindow().Bind(wx.EVT_MOTION, getCommentCallback(grid)) @@ -275,19 +267,19 @@ def writeSprintGC(): continue col = 0 - grid.SetCellValue( rowNum, col, str(place) ); col += 1 - grid.SetCellValue( rowNum, col, str(rider.bib) ); col += 1 - grid.SetCellValue( rowNum, col, str(rider.last_name).upper()); col += 1 - grid.SetCellValue( rowNum, col, str(rider.first_name) ); col += 1 - grid.SetCellValue( rowNum, col, str(rider.team) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(place) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.bib) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.last_name).upper()) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.first_name) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.team) ) if 'uci_id' in riderFields: - grid.SetCellValue( rowNum, col, str(rider.uci_id) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.uci_id) ) if 'license' in riderFields: - grid.SetCellValue( rowNum, col, str(rider.license) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.license) ) for v in r[:-1]: - grid.SetCellValue( rowNum, col, str(v) if v else '' ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(v) if v else '' ) rowNum +=1 @@ -327,19 +319,19 @@ def writeKOMGC(): continue col = 0 - grid.SetCellValue( rowNum, col, str(place) ); col += 1 - grid.SetCellValue( rowNum, col, str(rider.bib) ); col += 1 - grid.SetCellValue( rowNum, col, str(rider.last_name).upper()); col += 1 - grid.SetCellValue( rowNum, col, str(rider.first_name) ); col += 1 - grid.SetCellValue( rowNum, col, str(rider.team) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(place) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.bib) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.last_name).upper()) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.first_name) ) + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.team) ) if 'uci_id' in riderFields: - grid.SetCellValue( rowNum, col, str(rider.uci_id) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.uci_id) ) if 'license' in riderFields: - grid.SetCellValue( rowNum, col, str(rider.license) ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(rider.license) ) for v in r[:-1]: - grid.SetCellValue( rowNum, col, str(v) if v else '' ); col += 1 + grid.SetCellValue( rowNum, (col:=col+1)-1, str(v) if v else '' ) rowNum +=1 diff --git a/StageRaceGC/Utils.py b/StageRaceGC/Utils.py index 62fa7d12..caca5c22 100644 --- a/StageRaceGC/Utils.py +++ b/StageRaceGC/Utils.py @@ -15,13 +15,7 @@ def initTranslation(): initTranslation() -try: - from win32com.shell import shell, shellcon -except ImportError: - pass - import os -import re import sys import math import subprocess @@ -29,17 +23,18 @@ def initTranslation(): import platform import traceback import unicodedata +import webbrowser -def removeDiacritic(input): +def removeDiacritic( s ): ''' - Accept a unicode string, and return a normal string (bytes in Python 3) + Accept a unicode string, and return a normal string without any diacritical marks. ''' - if type(input) == str: - return input - else: - return unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore') - + try: + return unicodedata.normalize('NFKD', '{}'.format(s)).encode('ASCII', 'ignore').decode() + except Exception: + return s + ''' wx.ICON_EXCLAMATION Shows an exclamation mark icon. wx.ICON_HAND Shows an error icon. @@ -91,7 +86,7 @@ def AdjustGridSize( grid, rowsRequired = None, colsRequired = None ): try: dirName = os.path.dirname(os.path.abspath(__file__)) -except: +except Exception: dirName = os.path.dirname(os.path.abspath(sys.argv[0])) if os.path.basename(dirName) == 'library.zip': @@ -283,7 +278,6 @@ def getHomeDir(): def getDirName(): return dirName def getImageFolder(): return imageFolder -def getHtmlFolder(): return htmlFolder def getHtmlDocFolder(): return htmlDocFolder if sys.platform == 'darwin': diff --git a/StageRaceGC/Version.py b/StageRaceGC/Version.py index 63591115..ddc942f9 100644 --- a/StageRaceGC/Version.py +++ b/StageRaceGC/Version.py @@ -1 +1 @@ -AppVerName="StageRaceGC 1.0.1-private" +AppVerName="StageRaceGC 1.0.2-private" diff --git a/TagReadWrite/MainWin.py b/TagReadWrite/MainWin.py index 4fa9c177..fdc4fd53 100644 --- a/TagReadWrite/MainWin.py +++ b/TagReadWrite/MainWin.py @@ -7,7 +7,6 @@ import re import os import sys -import time import datetime import traceback import secrets @@ -390,6 +389,7 @@ def setWriteSuccess( self, success ): self.writeSuccess.SetValue( 100 if success else 0 ) reTemplate = re.compile( '#+' ) + def getFormatStr( self ): template = self.template.GetValue() if '#' not in template: @@ -563,20 +563,20 @@ def onWriteButton( self, event ): Utils.MessageOK( self, 'Reader not connected.\n\nSet reader connection parameters and press "Reset Connection".', 'Reader Not Connected' ) return - busy = wx.BusyCursor() - wx.CallAfter( self.writeOptions ) - - self.setWriteSuccess( False ) - - writeValue = self.getWriteValue() - - try: - self.tagWriter.WriteTag( '', writeValue ) - except Exception as e: - Utils.MessageOK( self, 'Write Fails: {}\n\nCheck the reader connection.\n\n{}'.format(e, traceback.format_exc()), - 'Write Fails' ) - - self.setWriteSuccess( True ) + with wx.BusyCursor(): + wx.CallAfter( self.writeOptions ) + + self.setWriteSuccess( False ) + + writeValue = self.getWriteValue() + + try: + self.tagWriter.WriteTag( '', writeValue ) + except Exception as e: + Utils.MessageOK( self, 'Write Fails: {}\n\nCheck the reader connection.\n\n{}'.format(e, traceback.format_exc()), + 'Write Fails' ) + + self.setWriteSuccess( True ) wx.CallLater( 100, self.onReadButton, None ) def onReadButton( self, event=None ): diff --git a/flake8_ignore.txt b/flake8_ignore.txt index dc635728..ded41023 100644 --- a/flake8_ignore.txt +++ b/flake8_ignore.txt @@ -42,3 +42,5 @@ E127 E701 E225 E211 +E122 continuation line missing indentation or outdented +F405