PyScore

001: # -*- python -*-
002: ###### loadfile.py ###### python package PyScore.standing module loadfile ######
003: 
004: # PyScore
005: # a race scoring programme
006: # written by Matt Draisey
007: # 2004 April 6
008: 
009: reloadables=[]
010: 
011: ###### loadfile.py ###### python package PyScore.standing module loadfile ######
012: 
013: import re,sys,os
014: from relational import base
015: from utility.verbose import vv,vvv,vvvv,debug
016: 
017: ######## ######## data base persistence ######## ########
018: 
019: ######## ######## the overall database ######## ########
020: 
021: def load_database(database,databasefile):
022:     """Load data from file."""
023: 
024: def save_database(database,databasefile):
025:     """Save data to file."""
026: 
027: ######## ######## scanning the filesystem ######## ########
028: 
029: RACESHEET_RE=re.compile(
030:     r"^((?:(?:20\d\d)(?:\-\d\d(?:\-\d\d)?)?)?)"\
031:     r"S([1-9]\d*)R([1-9]\d*)(.*)(race|start|time|uber)sheet\.log$",
032:     re.S,
033: )
034: 
035: def scan_for_sheets(dn,filenames):
036:     for fn in filenames:
037:         match=RACESHEET_RE.match(fn)
038:         if match:
039:             (date,series,race,other,sheet)=match.groups()
040:             try:
041:                 yield (
042:                     other,(date,int(series),int(race)),
043:                     sheet,(fn,file(os.path.join(dn,fn),"rb"))
044:                 )
045:             except IOError:
046:                 pass
047: 
048: SUBDIRECTORY_RE=re.compile("sheet",re.I)
049: 
050: def hierarchy_of_sheets(sheetdir):
051:     """Import all the race timesheets in a directory."""
052: 
053:     for (dirname,subdirnames,filenames) in os.walk(sheetdir):
054:         print>>vv,"SCANNING DIRECTORY:",dirname
055: 
056:         scanned=list(scan_for_sheets(dirname,filenames))
057:         scanned.sort()
058:         for (other,races) in base.hierarchy_filter(
059:             ["other","race","sheet"],scanned
060:         ):
061:             print>>vvv,"FILENAME PATTERN: *S*R*%s*sheet.log"%other
062:             for ((dt,sn,rn),sheets) in races:
063:                 if dt: print>>vv,"  DATE:",dt
064:                 print>>vv,"  SERIES: %i\n  RACE: %i"%(sn,rn)
065:                 sf=dict.fromkeys(["race","start","time","uber"])
066:                 #{sf="race":None,"start":None,"time":None,"uber":None}
067:                 for (sheet,files) in sheets:
068:                     print>>vvv,"    SHEET TYPE:",sheet
069:                     filelist=list(files)
070:                     assert len(filelist)==1
071:                     (fn,fo)=filelist[0]
072:                     print>>vvv,"    FILENAME:",fn
073:                     sf[sheet]=fo
074:                 yield ((dirname,other),(dt,sn,rn),(
075:                     sf["race"],sf["start"],sf["time"],sf["uber"],
076:                 ))
077: 
078:         for dn in subdirnames[:]:
079:             if dn.startswith(".") or dn.endswith("~"):
080:                 subdirnames.remove(dn)
081:             elif not SUBDIRECTORY_RE.search(dn):
082:                 subdirnames.remove(dn)
083: 
084:     print>>vv,"SCANNING COMPLETE"
085:     print>>vv
086: 
087: def import_all_timesheets(database,sheetdir):
088:     """Import all the race timesheets in a directory."""
089: 
090:     uniquedx=None
091:     for (
092:         dx,(dt,sn,rn),(racesheetf,startsheetf,timesheetf,ubersheetf)
093:     ) in hierarchy_of_sheets(sheetdir):
094:         if uniquedx<>dx:
095:             if uniquedx==None:
096:                 uniquedx=dx
097:             else:
098:                 print>>vv,"SCANNING ERROR: TOO MANY DIRECTORIES OR FILES"
099:                 break
100:         racename=database.get_racename(sn,rn)
101:         database.import_timesheet(
102:             racename,racesheetf,startsheetf,timesheetf,ubersheetf
103:         )
104: 
105: ######## ######## evaluating the files line by line ######## ########
106: 
107: def as_tuple(data,format):
108:     assert isinstance(format,(tuple,list))
109:     if not isinstance(data,(tuple,list)): raise ValueError
110:     if not len(data)==len(format): raise ValueError
111:     interpreted=[]
112:     for (v,t) in zip(data,format):
113:         if isinstance(t,(tuple,list)):
114:             interpreted.append(as_tuple(v,t))
115:         elif isinstance(t,(str,unicode)):
116:             interpreted.append(as_joined(v,t))
117:         elif t in [str,unicode,int]:
118:             interpreted.append(t(v))
119:         elif callable(t):
120:             interpreted.append(t(v))
121:         elif t==None:
122:             interpreted.append(v)
123:         else:
124:             assert False
125:     return tuple(interpreted)
126: 
127: def as_joined(data,format):
128:     assert isinstance(format,(str,unicode))
129:     try:
130:         splitformat=[eval(f) for f in format.split(":")]
131:         n=len(splitformat)
132:         assert n>1
133:     except SyntaxError:
134:         raise AssertionError
135:     if not isinstance(data,(str,unicode)): raise ValueError
136:     splitdata=data.split(":",n-1)
137:     return as_tuple(splitdata,splitformat)
138: 
139: def read_tuples(dataf,format):
140:     assert isinstance(dataf,file)
141:     try:
142:         noglobals={"__builtins__":None}
143:         datatuples=[as_tuple(eval(l,noglobals),format) for l in dataf]
144:     except (EOFError,SyntaxError,ValueError):
145:         pass
146:     else:
147:         return datatuples
148: 
149: ###### loadfile.py ###### python package PyScore.standing module loadfile ######