X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?p=ypp-sc-tools.main.git;a=blobdiff_plain;f=yoweb-scrape;h=462bd01c0366a42e877d8b47b8c4dade0a9c34ec;hp=4e12d7f6da3a57835e2f6a7952613b18a101c44e;hb=2b1646498eea5609775d17e121937feea4aa1196;hpb=2943c3282218303bfaaf76ec6efc41089adf9e6d diff --git a/yoweb-scrape b/yoweb-scrape index 4e12d7f..462bd01 100755 --- a/yoweb-scrape +++ b/yoweb-scrape @@ -28,7 +28,7 @@ standingvals = ('Able/Distinguished/Respected/Master'+ pirate_ref_re = regexp.compile('^/yoweb/pirate\\.wm') -max_pirate_namelen = 20 +max_pirate_namelen = 12 def debug(m): @@ -216,7 +216,7 @@ u'\\s*\\S*/([-A-Za-z]+)\\s*$|\\s*\\S*/\\S*\\s*\\(ocean\\-wide(?:\\s|\\xa0)+([-A- skl.msg('puzzle "%s" multiple standings %s' % (puzzle, `sl`)) continue - if not len(sl): + if not sl: skl.msg('puzzle "%s" no standing found' % puzzle) continue standing = sl[0] @@ -318,7 +318,7 @@ class StandingsTable: self._cw = col_width-1 def _pline(self, pirate, puzstrs): - self.s += ' %-*s' % (max_pirate_namelen, pirate) + self.s += ' %-*s' % (max(max_pirate_namelen, 14), pirate) for v in puzstrs: self.s += ' %-*.*s' % (self._cw,self._cw, v) self.s += '\n' @@ -386,6 +386,147 @@ def do_standings_crew_of(args, bu): tab.pirate(pi) print tab.results() +class PirateAboard: + # pa.v + # pa.last_time + # pa.last_event + # pa.gunner + def __init__(pa, v, time, event): + pa.v = v + pa.last_time = time + pa.last_event = event + pa.gunner = False + +class ShipCrewTracker: + def __init__(self, myself_pi): + self._pl = {} # self._pl['Pirate'] = + self._vl = {} # self._vl['Vessel']['Pirate'] = PirateAboard + # self._vl['Vessel']['#lastaboard'] + self._v = None # self._v = + self._vessel = None # self._vl[self._vessel] + self._date = None + self._myself = myself_pi + self._need_redisplay = False + + def _refresh(self): + self._need_redisplay = True + + def _onboard_event(self,timestamp,pirate,event): + try: pa = self._pl[pirate] + except KeyError: pa = None + if pa is not None and pa.v is self._v: + pa.last_time = timestamp + pa.last_event = event + else: + if pa is not None: del pa.v[pirate] + pa = PirateAboard(self._v, timestamp, event) + self._pl[pirate] = pa + self._v[pirate] = pa + self._v['#lastaboard'] = timestamp + self._refresh() + return pa + + def clear_vessel(self, timestamp): + if self._v is not None: + for p in self._v: + if p.startswith('#'): continue + del self._pl[p] + self._v = {'#lastaboard': timestamp} + + def _debug_line_disposition(self,timestamp,l,m): + debug('SCT %-13s %-30s %s' % (timestamp,m,l)) + + def chatline(self,l): + rm = lambda re: regexp.match(re,l) + d = lambda m: self._debug_line_disposition(timestamp,l,m) + timestamp = None + + m = rm('=+ (\\d+)/(\\d+)/(\\d+) =+$') + if m: + self._date = m.groups() + return d('date '+`self._date`) + + if self._date is None: + return d('date unset') + + m = rm('\\[(\d\d):(\d\d):(\d\d)\\] ') + if not m: + return d('no timestamp') + + time_tuple = [int(x) for x in self._date + m.groups()] + time_tuple += (-1,-1,-1) + timestamp = time.mktime(time_tuple) + l = l[l.find(' ')+1:] + + ob = lambda who, event: self._onboard_event( + timestamp, who, event) + oba = lambda m, did: ob( + m.group(1), '%s %s' % (did, m.group(2))) + + m = rm('Going aboard the (\\S.*\\S)\\.\\.\\.$') + if m: + self._vessel = m.group(1) + dm = 'boarding' + try: self._v = self._vl[self._vessel] + except KeyError: self._v = None; dm += ' new' + if self._v is not None: la = self._v['#lastaboard'] + else: la = 0; dm += ' ?la' + if timestamp - la > 3600: + self.clear_vessel(timestamp) + dm += ' stale' + self._vl[self._vessel] = self._v + ob(self._myself.name, 'we boarded') + return d(dm) + + if self._v is None: + return d('no vessel') + + m = rm('You have ordered (\\w+) to do some (\\S.*\\S)\\.$') + if m: + pa = oba(m, 'ordered') + if m.group(2) == 'Gunning': + pa.gunner = True + return d('duty order') + + m = rm('(\\w+) abandoned a (\\S.*\\S) station\\.$') + if m: oba(m,'abandoned'); return d('abandoned') + + m = rm('(\\w+) says, "') + if m: ob(m.group(1), 'talked'); return d('talked') + + m = rm('(\\w+) has left the vessel\.') + if m: + who = m.group(1) + ob(who, 'disembarked') + del self._v[who] + del self._pl[who] + return d('disembarked') + + return d('not matched') + +def do_ship_aid(args, bu): + if len(args) != 1: bu('ship-aid takes only chat log filename') + logfn = args[0] + logfn_re = '(?:.*/)?([A-Z][a-z]+)_([a-z]+)_chat-log-\\w+$' + match = regexp.match(logfn_re, logfn) + if not match: bu('ship-aid chat log filename is not in default format') + (pirate, fetcher.ocean) = match.groups() + myself_pi = PirateInfo(pirate,3600) + track = ShipCrewTracker(myself_pi) + f = file(logfn) + l = '' + while True: + l += f.readline() + if l.endswith('\n'): + track.chatline(l.rstrip()) +# print `track.__dict__` + l = '' + continue + if l: + continue + print `track.__dict__` + os.sleep(1) + def main(): global opts, fetcher