+ def __str__(self):
+ s = '''<ChatLogTracker
+ myself %s
+ vessel %s
+''' % (self._myself.name, self._vessel)
+ assert ((self._v is None and self._vessel is None) or
+ (self._v is self._vl[self._vessel]))
+ if self._vessel is not None:
+ s += self._str_vessel(self._vessel, self._v)
+ for vn in sorted(self._vl.keys()):
+ if vn == self._vessel: continue
+ s += self._str_vessel(vn, self._vl[vn])
+ for p in self._pl:
+ pa = self._pl[p]
+ assert pa.v[p] is pa
+ assert pa.v in self._vl.values()
+ s += '>\n'
+ return s
+
+ def catchup(self, progress=None):
+ while True:
+ more = self._f.readline()
+ if not more: break
+
+ self._progress[0] += len(more)
+ if progress: progress.progress(*self._progress)
+
+ self._lbuf += more
+ if self._lbuf.endswith('\n'):
+ self.chatline(self._lbuf.rstrip())
+ self._lbuf = ''
+ if opts.debug >= 2:
+ debug(self.__str__())
+ if progress: progress.caughtup()
+
+ def changed(self):
+ rv = self._need_redisplay
+ self._need_redisplay = False
+ return rv
+ def myname(self):
+ # returns our pirate name
+ return self._myself.name
+ def vesselname(self):
+ # returns the vessel name we're aboard or None
+ return self._vessel
+ def lastvesselname(self):
+ # returns the last vessel name we were aboard or None
+ return self._lastvessel
+ def aboard(self, vesselname=True):
+ # returns a list of PirateAboard the vessel
+ # sorted by pirate name
+ # you can pass this None and you'll get []
+ # or True for the current vessel (which is the default)
+ if vesselname is True: v = self._v
+ else: v = self._vl.get(vesselname.title())
+ if v is None: return []
+ return [ v[pn]
+ for pn in sorted(v.keys())
+ if not pn.startswith('#') ]
+
+#---------- implementations of actual operation modes ----------
+
+def do_pirate(pirates, bu):
+ print '{'
+ for pirate in pirates:
+ info = PirateInfo(pirate)
+ print '%s: %s,' % (`pirate`, info)
+ print '}'
+
+def prep_crew_of(args, bu, max_age=300):
+ if len(args) != 1: bu('crew-of takes one pirate name')
+ pi = PirateInfo(args[0], max_age)
+ if pi.crew is None: return None
+ return CrewInfo(pi.crew[0], max_age)
+
+def do_crew_of(args, bu):
+ ci = prep_crew_of(args, bu)
+ print ci
+
+def do_standings_crew_of(args, bu):
+ ci = prep_crew_of(args, bu, 60)
+ tab = StandingsTable()
+ tab.headings()
+ for (rank, members) in ci.crew:
+ if not members: continue
+ tab.literalline('%s:' % rank)
+ for p in members:
+ pi = PirateInfo(p, random.randint(900,1800))
+ tab.pirate(pi)
+ print tab.results()
+
+class ProgressPrintPercentage:
+ def __init__(self, f=sys.stdout):
+ self._f = f
+ def progress_string(self,done,total):
+ return "scan chat logs %3d%%\r" % ((done*100) / total)
+ def progress(self,*a):
+ self._f.write(self.progress_string(*a))
+ self._f.flush()
+ def show_init(self, pirate, ocean):
+ print >>self._f, 'Starting up, %s on the %s ocean' % (
+ pirate, ocean)
+ def caughtup(self):
+ self._f.write(' \r')
+ self._f.flush()
+
+#----- modes which use the chat log parser are quite complex -----
+
+def prep_chat_log(args, bu,
+ progress=ProgressPrintPercentage(),
+ max_myself_age=3600):
+ if len(args) != 1: bu('this action takes only chat log filename')