chiark / gitweb /
yoweb-scrape: support local command entry
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sat, 15 Jan 2011 18:23:04 +0000 (18:23 +0000)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sat, 15 Jan 2011 18:23:04 +0000 (18:23 +0000)
yoweb-scrape
yoweb-scrape.txt

index 840a6d9..a705f67 100755 (executable)
@@ -681,6 +681,56 @@ class ChatLogTracker:
                else:
                        return None
 
+       def local_command(self, metacmd):
+               # returns None if all went well, or problem message
+               return self._command(self._myself.name, metacmd,
+                       "local", time.time(), 
+                       (lambda m: debug('CMD %s' % metacmd)))
+
+       def _command(self, cmdr, metacmd, chan, timestamp, d):
+               # returns None if all went well, or problem message
+               metacmd = regexp.sub('\\s+', ' ', metacmd).strip()
+               m2 = regexp.match(
+                   '/([adj]) (?:([A-Za-z* ]+)\\s*:)?([A-Za-z ]+)$',
+                   metacmd)
+               if not m2: return "unknown syntax or command"
+
+               (cmd, pattern, targets) = m2.groups()
+               dml = ['cmd', chan, cmd]
+
+               if cmd == 'a': each = self._onboard_event
+               elif cmd == 'd': each = disembark
+               else: each = lambda *l: self._onboard_event(*l,
+                               **{'jobber':'applied'})
+
+               if cmdr == self._myself.name:
+                       dml.append('self')
+                       how = 'cmd: %s' % cmd
+               else:
+                       dml.append('other')
+                       how = 'cmd: %s %s' % (cmd,cmdr)
+
+               if cmd == 'j':
+                       if pattern is not None:
+                               return "/j command does not take a vessel"
+                       v = None
+               else:
+                       v = self._find_matching_vessel(
+                               pattern, timestamp, cmdr,
+                               dml, create=True)
+
+               if cmd == 'j' or v is not None:
+                       targets = targets.strip().split(' ')
+                       dml.append(`len(targets)`)
+                       for target in targets:
+                               each(v, timestamp, target.title(), how)
+                       self._vessel_updated(v, timestamp)
+
+               dm = ' '.join(dml)
+               return d(dm)
+
+               return None
+
        def chatline(self,l):
                rm = lambda re: regexp.match(re,l)
                d = lambda m: self._debug_line_disposition(timestamp,l,m)
@@ -783,46 +833,12 @@ class ChatLogTracker:
 
                def chat_metacmd(chan):
                        (cmdr, metacmd) = m.groups()
-                       metacmd = regexp.sub('\\s+', ' ', metacmd).strip()
-                       m2 = regexp.match(
-                           '/([adj]) (?:([A-Za-z* ]+)\\s*:)?([A-Za-z ]+)$',
-                           metacmd)
-                       if not m2: return chat(chan)
-
-                       (cmd, pattern, targets) = m2.groups()
-                       dml = ['cmd', chan, cmd]
-
-                       if cmd == 'a': each = self._onboard_event
-                       elif cmd == 'd': each = disembark
-                       else: each = lambda *l: self._onboard_event(*l,
-                                       **{'jobber':'applied'})
-
-                       if cmdr == self._myself.name:
-                               dml.append('self')
-                               how = 'cmd: %s' % cmd
+                       whynot = self._command(
+                               cmdr, metacmd, chan, timestamp, d)
+                       if whynot is not None:
+                               return chat(chan)
                        else:
-                               dml.append('other')
-                               how = 'cmd: %s %s' % (cmd,cmdr)
-
-                       if cmd == 'j':
-                               if pattern is not None:
-                                       return chat(chan)
-                               v = None
-                       else:
-                               v = self._find_matching_vessel(
-                                       pattern, timestamp, cmdr,
-                                       dml, create=True)
-
-                       if cmd == 'j' or v is not None:
-                               targets = targets.strip().split(' ')
-                               dml.append(`len(targets)`)
-                               for target in targets:
-                                       each(v, timestamp, target.title(), how)
-                               self._vessel_updated(v, timestamp)
-
-                       dm = ' '.join(dml)
-                       chat_core(cmdr, 'cmd '+chan)
-                       return d(dm)
+                               chat_core(cmdr, 'cmd '+chan)
 
                m = rm('(\\w+) (?:issued an order|ordered everyone) "')
                if m: return ob1('general order');
@@ -1220,15 +1236,27 @@ def ship_aid_core(myself, track, displayer, kreader):
        rotate_nya = '/-\\'
 
        sort = NameSorter()
+       clicmd = None
+       clierr = None
+       cliexec = None
 
        while True:
                track.catchup()
                now = time.time()
 
-               (vn, s) = find_vessel()
-               s = track.myname() + s
-               s += " at %s" % time.strftime("%Y-%m-%d %H:%M:%S")
-               s += kreader.info()
+               (vn, vs) = find_vessel()
+
+               s = ''
+               if cliexec is not None:
+                       s += '...'
+               elif clierr is not None:
+                       s += 'Error: '+clierr
+               elif clicmd is not None:
+                       s += '/' + clicmd
+               else:
+                       s = track.myname() + vs
+                       s += " at %s" % time.strftime("%Y-%m-%d %H:%M:%S")
+                       s += kreader.info()
                s += '\n'
 
                tbl_s = StringIO()
@@ -1269,11 +1297,34 @@ def ship_aid_core(myself, track, displayer, kreader):
                displayer.show(s)
                tbl_s.close()
 
+               if cliexec is not None:
+                       clierr = track.local_command("/"+cliexec.strip())
+                       cliexec = None
+                       continue
+
                k = kreader.getch()
                if k is None:
                        rotate_nya = rotate_nya[1:3] + rotate_nya[0]
                        continue
 
+               if clierr is not None:
+                       clierr = None
+                       continue
+
+               if clicmd is not None:
+                       if k == '\r' or k == '\n':
+                               cliexec = clicmd
+                               clicmd = clicmdbase
+                       elif k == '\e' and clicmd != "":
+                               clicmd = clicmdbase
+                       elif k == '\33':
+                               clicmd = None
+                       elif k == '\b' or k == '\177':
+                               clicmd = clicmd[ 0 : len(clicmd)-1 ]
+                       else:
+                               clicmd += k
+                       continue
+
                if k == 'q': break
                elif k == 'g': sort = SkillSorter('Gunning')
                elif k == 'c': sort = SkillSorter('Carpentry')
@@ -1283,6 +1334,8 @@ def ship_aid_core(myself, track, displayer, kreader):
                elif k == 'd': sort = SkillSorter('Battle Navigation')
                elif k == 't': sort = SkillSorter('Treasure Haul')
                elif k == 'a': sort = NameSorter()
+               elif k == '/': clicmdbase = ""; clicmd = clicmdbase
+               elif k == '+': clicmdbase = "a "; clicmd = clicmdbase
                else: pass # unknown key command
 
 #---------- individual keystroke input ----------
index f8f881a..4576c39 100644 (file)
@@ -42,6 +42,9 @@ Key features:
    are weaker.  This functionality is disabled if stdin is not a tty.
    Other keystrokes:
       q: quit the program (^C works too)
+      /: start entering a local extra commands (see below)
+      +: start entering local extra commands starting "/a"
+      ESC: clear local extra command or abandon local extra commands entry
 
 Things you need to know: