mirror of
https://github.com/0intro/wmii
synced 2024-11-22 05:42:05 +03:00
Make python wmiirc's event matching a bit more powerful.
This commit is contained in:
parent
63d3123d73
commit
5d8c72952e
@ -8,53 +8,20 @@ if 'WMII_ADDRESS' in os.environ:
|
||||
else:
|
||||
client = Client(namespace='wmii')
|
||||
|
||||
def call(*args, **kwargs):
|
||||
background = kwargs.pop('background', False)
|
||||
input = kwargs.pop('input', None)
|
||||
import subprocess
|
||||
p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, cwd=os.environ['HOME'],
|
||||
**kwargs)
|
||||
if not background:
|
||||
return p.communicate(input)[0].rstrip('\n')
|
||||
|
||||
def program_list(path):
|
||||
names = []
|
||||
for d in path:
|
||||
try:
|
||||
for f in os.listdir(d):
|
||||
if f not in names and os.access('%s/%s' % (d, f),
|
||||
os.X_OK):
|
||||
names.append(f)
|
||||
except Exception:
|
||||
pass
|
||||
return sorted(names)
|
||||
|
||||
def curry(func, *args, **kwargs):
|
||||
def curried(*newargs, **newkwargs):
|
||||
return func(*(args + newargs), **dict(kwargs, **newkwargs))
|
||||
curried.__name__ = func.__name__ + '__curried__'
|
||||
return curried
|
||||
|
||||
def find_script(name):
|
||||
for path in confpath:
|
||||
if os.access('%s/%s' % (path, name), os.X_OK):
|
||||
return '%s/%s' % (path, name)
|
||||
|
||||
confpath = os.environ.get('WMII_CONFPATH', '%s/.wmii' % os.environ['HOME']).split(':')
|
||||
shell = os.environ['SHELL']
|
||||
|
||||
sys.path += confpath
|
||||
|
||||
from pygmi import events, fs, menu, monitor
|
||||
from pygmi.util import *
|
||||
from pygmi.events import *
|
||||
from pygmi.fs import *
|
||||
from pygmi.menu import *
|
||||
from pygmi.monitor import *
|
||||
from pygmi import util, events, fs, menu, monitor
|
||||
|
||||
__all__ = (fs.__all__ + monitor.__all__ + events.__all__ +
|
||||
menu.__all__ + (
|
||||
'client', 'call', 'curry', 'program_list',
|
||||
'find_script', 'confpath', 'shell'))
|
||||
menu.__all__ + util.__all__ +
|
||||
('client', 'confpath', 'shell'))
|
||||
|
||||
# vim:se sts=4 sw=4 et:
|
||||
|
@ -4,17 +4,40 @@ import sys
|
||||
import traceback
|
||||
|
||||
import pygmi
|
||||
from pygmi import monitor, client, call, program_list
|
||||
from pygmi import monitor, client, curry, call, program_list, _
|
||||
|
||||
__all__ = ('bind_keys', 'bind_events', 'toggle_keys', 'event_loop',
|
||||
'event')
|
||||
'event', 'Match')
|
||||
|
||||
keydefs = {}
|
||||
keys = {}
|
||||
events = {}
|
||||
eventmatchers = {}
|
||||
|
||||
alive = True
|
||||
|
||||
class Match(object):
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
self.matchers = []
|
||||
for a in args:
|
||||
if a is _:
|
||||
a = lambda k: True
|
||||
elif isinstance(a, basestring):
|
||||
a = a.__eq__
|
||||
elif isinstance(a, (list, tuple)):
|
||||
a = curry(lambda ary, k: k in ary, a)
|
||||
elif hasattr(a, 'search'):
|
||||
a = a.search
|
||||
else:
|
||||
a = str(a).__eq__
|
||||
self.matchers.append(a)
|
||||
|
||||
def match(self, string):
|
||||
ary = string.split(' ', len(self.matchers))
|
||||
if all(m(a) for m, a in zip(self.matchers, ary)):
|
||||
return ary
|
||||
|
||||
def flatten(items):
|
||||
for k, v in items.iteritems():
|
||||
if not isinstance(k, (list, tuple)):
|
||||
@ -28,7 +51,10 @@ def bind_keys(items):
|
||||
|
||||
def bind_events(items):
|
||||
for k, v in flatten(items):
|
||||
events[k] = v
|
||||
if isinstance(k, Match):
|
||||
eventmatchers[k] = v
|
||||
else:
|
||||
events[k] = v
|
||||
|
||||
def event(fn):
|
||||
bind_events({fn.__name__: fn})
|
||||
@ -50,11 +76,15 @@ def toggle_keys(on=None, restore=None):
|
||||
client.write('/keys', restore or ' ')
|
||||
|
||||
def dispatch(event, args=''):
|
||||
if event in events:
|
||||
try:
|
||||
try:
|
||||
if event in events:
|
||||
events[event](args)
|
||||
except Exception, e:
|
||||
traceback.print_exc(sys.stderr)
|
||||
for matcher, action in eventmatchers.iteritems():
|
||||
ary = matcher.match(' '.join((event, args)))
|
||||
if ary is not None:
|
||||
action(*ary)
|
||||
except Exception, e:
|
||||
traceback.print_exc(sys.stderr)
|
||||
|
||||
def event_loop():
|
||||
from pygmi import events
|
||||
|
@ -342,12 +342,15 @@ class Button(object):
|
||||
self.create(colors, label)
|
||||
|
||||
def create(self, colors=None, label=None):
|
||||
def fail(resp, exc, tb):
|
||||
self.file = None
|
||||
if not self.file:
|
||||
self.file = client.create(self.path, ORDWR)
|
||||
if colors:
|
||||
self.file.awrite(self.getval(colors, label), offset=0)
|
||||
self.file.awrite(self.getval(colors, label), offset=0, fail=fail)
|
||||
elif label:
|
||||
self.file.awrite(label, offset=24)
|
||||
self.file.awrite(label, offset=24, fail=fail)
|
||||
|
||||
def remove(self):
|
||||
if self.file:
|
||||
self.file.aremove()
|
||||
@ -579,29 +582,4 @@ class Tags(object):
|
||||
self.idx = min(-1, max(-len(self.mru), self.idx))
|
||||
wmii['view'] = self.mru[self.idx]
|
||||
|
||||
if __name__ == '__main__':
|
||||
c = Client('sel')
|
||||
#print c.id
|
||||
#print c.items()
|
||||
#print c.urgent
|
||||
|
||||
#print list(wmii.clients)
|
||||
#print list(wmii.tags)
|
||||
|
||||
#print [a.frames for a in Tag('sel').index]
|
||||
#print Tag('sel').selclient
|
||||
#print Tag('sel').selclient.label
|
||||
#print Tag('sel').selclient.tags
|
||||
#print Tag('sel').selclient.props
|
||||
#a = Area(Tag('sel'), 1)
|
||||
#print a.width
|
||||
#print a.frames
|
||||
|
||||
#print [[c.hex for c in b.colors] for b in wmii.lbuttons]
|
||||
#print [[c.hex for c in b.colors] for b in wmii.rbuttons]
|
||||
Button('left', '1').colors = ((0., 0., 0.), (1., 1., 1.), (0., 0., 0.))
|
||||
Button('left', '1').label = 'foo'
|
||||
Button('left', '5', label='baz')
|
||||
print repr(wmii['normcolors'])
|
||||
|
||||
# vim:se sts=4 sw=4 et:
|
||||
|
@ -1,4 +1,4 @@
|
||||
from pygmi import call
|
||||
from pygmi.util import call
|
||||
|
||||
__all__ = 'Menu', 'ClickMenu'
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
from threading import Timer
|
||||
|
||||
from pygmi import client
|
||||
from pygmi.fs import *
|
||||
|
||||
@ -33,7 +35,6 @@ class MonitorBase(type):
|
||||
return new_cls
|
||||
|
||||
class Monitor(object):
|
||||
|
||||
side = 'right'
|
||||
interval = 1.0
|
||||
|
||||
@ -57,7 +58,6 @@ class Monitor(object):
|
||||
if self.timer and mon is not self:
|
||||
return
|
||||
if self.active:
|
||||
from threading import Timer
|
||||
label = self.getlabel()
|
||||
if isinstance(label, basestring):
|
||||
label = None, label
|
||||
|
52
alternative_wmiircs/python/pygmi/util.py
Normal file
52
alternative_wmiircs/python/pygmi/util.py
Normal file
@ -0,0 +1,52 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import pygmi
|
||||
|
||||
__all__ = 'call', 'program_list', 'curry', 'find_script', '_'
|
||||
|
||||
def _():
|
||||
pass
|
||||
|
||||
def call(*args, **kwargs):
|
||||
background = kwargs.pop('background', False)
|
||||
input = kwargs.pop('input', None)
|
||||
p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, cwd=os.environ['HOME'],
|
||||
**kwargs)
|
||||
if not background:
|
||||
return p.communicate(input)[0].rstrip('\n')
|
||||
|
||||
def program_list(path):
|
||||
names = []
|
||||
for d in path:
|
||||
try:
|
||||
for f in os.listdir(d):
|
||||
if f not in names and os.access('%s/%s' % (d, f),
|
||||
os.X_OK):
|
||||
names.append(f)
|
||||
except Exception:
|
||||
pass
|
||||
return sorted(names)
|
||||
|
||||
def curry(func, *args, **kwargs):
|
||||
if _ in args:
|
||||
blank = [i for i in range(0, len(args)) if args[i] is _]
|
||||
def curried(*newargs, **newkwargs):
|
||||
ary = list(args)
|
||||
for k, v in zip(blank, newargs):
|
||||
ary[k] = v
|
||||
ary = tuple(ary) + newargs[len(blank):]
|
||||
return func(*ary, **dict(kwargs, **newkwargs))
|
||||
else:
|
||||
def curried(*newargs, **newkwargs):
|
||||
return func(*(args + newargs), **dict(kwargs, **newkwargs))
|
||||
curried.__name__ = func.__name__ + '__curried__'
|
||||
return curried
|
||||
|
||||
def find_script(name):
|
||||
for path in pygmi.confpath:
|
||||
if os.access('%s/%s' % (path, name), os.X_OK):
|
||||
return '%s/%s' % (path, name)
|
||||
|
||||
# vim:se sts=4 sw=4 et:
|
@ -10,72 +10,55 @@ def awithfile(*oargs, **okwargs):
|
||||
return next
|
||||
return wrapper
|
||||
def wrap_callback(fn, file):
|
||||
file.called = 0
|
||||
def callback(data, exc, tb):
|
||||
file.called += 1
|
||||
file.close()
|
||||
if callable(fn):
|
||||
fn(data, exc, tb)
|
||||
Client.respond(fn, data, exc, tb)
|
||||
return callback
|
||||
|
||||
class Client(client.Client):
|
||||
ROOT_FID = 0
|
||||
|
||||
def awalk(self, path, async, fail=None):
|
||||
ctxt = dict(path=path, fid=self.getfid(), ofid=ROOT_FID)
|
||||
def _awalk(self, path, callback, fail=None):
|
||||
ctxt = dict(path=path, fid=self._getfid(), ofid=ROOT_FID)
|
||||
def next(resp=None, exc=None, tb=None):
|
||||
if exc and ctxt['ofid'] != ROOT_FID:
|
||||
self.aclunk(ctxt['fid'])
|
||||
self._aclunk(ctxt['fid'])
|
||||
if not ctxt['path'] and resp or exc:
|
||||
if exc and fail:
|
||||
return self.respond(fail, None, exc, tb)
|
||||
return self.respond(async, ctxt['fid'], exc, tb)
|
||||
return self.respond(callback, ctxt['fid'], exc, tb)
|
||||
wname = ctxt['path'][:fcall.MAX_WELEM]
|
||||
ofid = ctxt['ofid']
|
||||
ctxt['path'] = ctxt['path'][fcall.MAX_WELEM:]
|
||||
if resp:
|
||||
ctxt['ofid'] = ctxt['fid']
|
||||
self.dorpc(fcall.Twalk(fid=ofid,
|
||||
self._dorpc(fcall.Twalk(fid=ofid,
|
||||
newfid=ctxt['fid'],
|
||||
wname=wname),
|
||||
next)
|
||||
next()
|
||||
|
||||
def _open(self, path, mode, open, origpath=None):
|
||||
resp = None
|
||||
|
||||
with self.walk(path) as nfid:
|
||||
fid = nfid
|
||||
resp = self.dorpc(open(fid))
|
||||
|
||||
def cleanup():
|
||||
self.aclunk(fid)
|
||||
file = File(self, origpath or '/'.join(path), resp, fid, mode, cleanup)
|
||||
self.files[fid] = file
|
||||
|
||||
return file
|
||||
|
||||
def _aopen(self, path, mode, open, callback, origpath=None):
|
||||
_file = property(lambda self: File)
|
||||
def _aopen(self, path, mode, open, callback, fail=None, origpath=None):
|
||||
resp = None
|
||||
def next(fid, exc, tb):
|
||||
def next(resp, exc, tb):
|
||||
def cleanup():
|
||||
self.clunk(fid)
|
||||
file = File(self, origpath or '/'.join(path), resp, fid, mode, cleanup)
|
||||
self.files[fid] = file
|
||||
self._clunk(fid)
|
||||
file = self._file(self, origpath or '/'.join(path), resp, fid, mode, cleanup)
|
||||
self.respond(callback, file)
|
||||
self.dorpc(open(fid), next, callback)
|
||||
self.awalk(path, next, callback)
|
||||
self._dorpc(open(fid), next, fail or callback)
|
||||
self._awalk(path, next, fail or callback)
|
||||
|
||||
def aopen(self, path, callback=True, mode=OREAD):
|
||||
def aopen(self, path, callback=True, fail=None, mode=OREAD):
|
||||
assert callable(callback)
|
||||
path = self.splitpath(path)
|
||||
path = self._splitpath(path)
|
||||
def open(fid):
|
||||
return fcall.Topen(fid=fid, mode=mode)
|
||||
return self._aopen(path, mode, open, callback)
|
||||
return self._aopen(path, mode, open, fail or callback)
|
||||
|
||||
def acreate(self, path, callback=True, mode=OREAD, perm=0):
|
||||
path = self.splitpath(path)
|
||||
def acreate(self, path, callback=True, fail=None, mode=OREAD, perm=0):
|
||||
path = self._splitpath(path)
|
||||
name = path.pop()
|
||||
def open(fid):
|
||||
return fcall.Tcreate(fid=fid, mode=mode, name=name, perm=perm)
|
||||
@ -83,21 +66,21 @@ class Client(client.Client):
|
||||
def callback(resp, exc, tb):
|
||||
if resp:
|
||||
resp.close()
|
||||
return self._aopen(path, mode, open, async,
|
||||
return self._aopen(path, mode, open, callback, fail,
|
||||
origpath='/'.join(path + [name]))
|
||||
|
||||
def aremove(self, path, callback=True):
|
||||
path = self.splitpath(path)
|
||||
def aremove(self, path, callback=True, fail=None):
|
||||
path = self._splitpath(path)
|
||||
def next(fid, exc, tb):
|
||||
self.dorpc(fcall.Tremove(fid=fid), callback)
|
||||
self.awalk(path, next, callback)
|
||||
self._dorpc(fcall.Tremove(fid=fid), callback, fail)
|
||||
self._awalk(path, next, callback, fail)
|
||||
|
||||
def astat(self, path, callback):
|
||||
path = self.splitpath(path)
|
||||
def astat(self, path, callback, fail = None):
|
||||
path = self._splitpath(path)
|
||||
def next(fid, exc, tb):
|
||||
def next(resp, exc, tb):
|
||||
callback(resp.stat, exc, tb)
|
||||
self.dorpc(fcall.Tstat(fid=fid), next, callback)
|
||||
self._dorpc(fcall.Tstat(fid=fid), next, callback)
|
||||
|
||||
@awithfile()
|
||||
def aread(self, (file, exc, tb), callback, *args, **kwargs):
|
||||
@ -133,9 +116,9 @@ class File(client.File):
|
||||
def stat(self, callback):
|
||||
def next(resp, exc, tb):
|
||||
callback(resp.stat, exc, tb)
|
||||
resp = self.dorpc(fcall.Tstat(), next, callback)
|
||||
resp = self._dorpc(fcall.Tstat(), next, callback)
|
||||
|
||||
def aread(self, callback, count=None, offset=None, buf=''):
|
||||
def aread(self, callback, fail=None, count=None, offset=None, buf=''):
|
||||
ctxt = dict(res=[], count=self.iounit, offset=self.offset)
|
||||
if count is not None:
|
||||
ctxt['count'] = count
|
||||
@ -153,8 +136,8 @@ class File(client.File):
|
||||
n = min(ctxt['count'], self.iounit)
|
||||
ctxt['count'] -= n
|
||||
|
||||
self.dorpc(fcall.Tread(offset=ctxt['offset'], count=n),
|
||||
next, callback)
|
||||
self._dorpc(fcall.Tread(offset=ctxt['offset'], count=n),
|
||||
next, fail or callback)
|
||||
next()
|
||||
|
||||
def areadlines(self, callback):
|
||||
@ -178,7 +161,7 @@ class File(client.File):
|
||||
callback(None)
|
||||
self.aread(next)
|
||||
|
||||
def awrite(self, data, callback=True, offset=None):
|
||||
def awrite(self, data, callback=True, fail=None, offset=None):
|
||||
ctxt = dict(offset=self.offset, off=0)
|
||||
if offset is not None:
|
||||
ctxt['offset'] = offset
|
||||
@ -186,22 +169,25 @@ class File(client.File):
|
||||
if resp:
|
||||
ctxt['off'] += resp.count
|
||||
ctxt['offset'] += resp.count
|
||||
if ctxt['off'] < len(data):
|
||||
if ctxt['off'] < len(data) or not (exc or resp):
|
||||
n = min(len(data), self.iounit)
|
||||
|
||||
self.dorpc(fcall.Twrite(offset=ctxt['offset'],
|
||||
self._dorpc(fcall.Twrite(offset=ctxt['offset'],
|
||||
data=data[ctxt['off']:ctxt['off']+n]),
|
||||
next, callback)
|
||||
next, fail or callback)
|
||||
else:
|
||||
if offset is None:
|
||||
self.offset = ctxt['offset']
|
||||
self.respond(callback, ctxt['off'], exc, tb)
|
||||
next()
|
||||
|
||||
def aremove(self, callback=True):
|
||||
def aremove(self, callback=True, fail=None):
|
||||
def next(resp, exc, tb):
|
||||
self.close()
|
||||
self.respond(resp and True, exc, tb)
|
||||
self.dorpc(fcall.Tremove(), next)
|
||||
if exc and fail:
|
||||
self.respond(fail, resp and True, exc, tb)
|
||||
else:
|
||||
self.respond(callback, resp and True, exc, tb)
|
||||
self._dorpc(fcall.Tremove(), next)
|
||||
|
||||
# vim:se sts=4 sw=4 et:
|
||||
|
@ -52,32 +52,31 @@ class Client(object):
|
||||
def __enter__(self):
|
||||
return self
|
||||
def __exit__(self, *args):
|
||||
self.cleanup()
|
||||
self._cleanup()
|
||||
|
||||
def __init__(self, conn=None, namespace=None, root=None):
|
||||
if not conn and namespace:
|
||||
conn = 'unix!%s/%s' % (NAMESPACE, namespace)
|
||||
try:
|
||||
self.lastfid = ROOT_FID
|
||||
self.fids = []
|
||||
self.files = {}
|
||||
self.fids = set()
|
||||
self.lock = RLock()
|
||||
|
||||
def process(data):
|
||||
return fcall.Fcall.unmarshall(data)[1]
|
||||
self.mux = Mux(conn, process, maxtag=256)
|
||||
|
||||
resp = self.dorpc(fcall.Tversion(version=pyxp.VERSION, msize=65535))
|
||||
resp = self._dorpc(fcall.Tversion(version=pyxp.VERSION, msize=65535))
|
||||
if resp.version != pyxp.VERSION:
|
||||
raise ProtocolException, "Can't speak 9P version '%s'" % resp.version
|
||||
self.msize = resp.msize
|
||||
|
||||
self.dorpc(fcall.Tattach(fid=ROOT_FID, afid=fcall.NO_FID,
|
||||
self._dorpc(fcall.Tattach(fid=ROOT_FID, afid=fcall.NO_FID,
|
||||
uname=os.environ['USER'], aname=''))
|
||||
|
||||
if root:
|
||||
path = self.splitpath(root)
|
||||
resp = self.dorpc(fcall.Twalk(fid=ROOT_FID,
|
||||
path = self._splitpath(root)
|
||||
resp = self._dorpc(fcall.Twalk(fid=ROOT_FID,
|
||||
newfid=ROOT_FID,
|
||||
wname=path))
|
||||
except Exception, e:
|
||||
@ -86,7 +85,7 @@ class Client(object):
|
||||
self.mux.fd.close()
|
||||
raise e
|
||||
|
||||
def cleanup(self):
|
||||
def _cleanup(self):
|
||||
try:
|
||||
for f in self.files:
|
||||
f.close()
|
||||
@ -94,7 +93,7 @@ class Client(object):
|
||||
self.mux.fd.close()
|
||||
self.mux = None
|
||||
|
||||
def dorpc(self, req, callback=None, error=None):
|
||||
def _dorpc(self, req, callback=None, error=None):
|
||||
def doresp(resp):
|
||||
if isinstance(resp, fcall.Rerror):
|
||||
raise RPCError, "%s[%d] RPC returned error: %s" % (
|
||||
@ -117,38 +116,37 @@ class Client(object):
|
||||
return doresp(self.mux.rpc(req))
|
||||
self.mux.rpc(req, next)
|
||||
|
||||
def splitpath(self, path):
|
||||
def _splitpath(self, path):
|
||||
return [v for v in path.split('/') if v != '']
|
||||
|
||||
def getfid(self):
|
||||
def _getfid(self):
|
||||
with self.lock:
|
||||
if self.fids:
|
||||
return self.fids.pop()
|
||||
self.lastfid += 1
|
||||
return self.lastfid
|
||||
def putfid(self, fid):
|
||||
def _putfid(self, fid):
|
||||
with self.lock:
|
||||
self.files.pop(fid)
|
||||
self.fids.append(fid)
|
||||
self.fids.add(fid)
|
||||
|
||||
def aclunk(self, fid, callback=None):
|
||||
def _aclunk(self, fid, callback=None):
|
||||
def next(resp, exc, tb):
|
||||
if resp:
|
||||
self.putfid(fid)
|
||||
self._putfid(fid)
|
||||
self.respond(callback, resp, exc, tb)
|
||||
self.dorpc(fcall.Tclunk(fid=fid), next)
|
||||
self._dorpc(fcall.Tclunk(fid=fid), next)
|
||||
|
||||
def clunk(self, fid):
|
||||
def _clunk(self, fid):
|
||||
try:
|
||||
self.dorpc(fcall.Tclunk(fid=fid))
|
||||
self._dorpc(fcall.Tclunk(fid=fid))
|
||||
finally:
|
||||
self.putfid(fid)
|
||||
self._putfid(fid)
|
||||
|
||||
def walk(self, path):
|
||||
fid = self.getfid()
|
||||
def _walk(self, path):
|
||||
fid = self._getfid()
|
||||
ofid = ROOT_FID
|
||||
while True:
|
||||
self.dorpc(fcall.Twalk(fid=ofid, newfid=fid,
|
||||
self._dorpc(fcall.Twalk(fid=ofid, newfid=fid,
|
||||
wname=path[0:fcall.MAX_WELEM]))
|
||||
path = path[fcall.MAX_WELEM:]
|
||||
ofid = fid
|
||||
@ -161,32 +159,31 @@ class Client(object):
|
||||
return fid
|
||||
def __exit__(res, exc_type, exc_value, traceback):
|
||||
if exc_type:
|
||||
self.clunk(fid)
|
||||
self._clunk(fid)
|
||||
return Res
|
||||
|
||||
_file = property(lambda self: File)
|
||||
def _open(self, path, mode, open, origpath=None):
|
||||
resp = None
|
||||
|
||||
with self.walk(path) as nfid:
|
||||
with self._walk(path) as nfid:
|
||||
fid = nfid
|
||||
resp = self.dorpc(open(fid))
|
||||
resp = self._dorpc(open(fid))
|
||||
|
||||
def cleanup():
|
||||
self.aclunk(fid)
|
||||
file = File(self, origpath or '/'.join(path), resp, fid, mode, cleanup)
|
||||
self.files[fid] = file
|
||||
|
||||
self._aclunk(fid)
|
||||
file = self._file(self, origpath or '/'.join(path), resp, fid, mode, cleanup)
|
||||
return file
|
||||
|
||||
def open(self, path, mode=OREAD):
|
||||
path = self.splitpath(path)
|
||||
path = self._splitpath(path)
|
||||
|
||||
def open(fid):
|
||||
return fcall.Topen(fid=fid, mode=mode)
|
||||
return self._open(path, mode, open)
|
||||
|
||||
def create(self, path, mode=OREAD, perm=0):
|
||||
path = self.splitpath(path)
|
||||
path = self._splitpath(path)
|
||||
name = path.pop()
|
||||
|
||||
def open(fid):
|
||||
@ -194,19 +191,19 @@ class Client(object):
|
||||
return self._open(path, mode, open, origpath='/'.join(path + [name]))
|
||||
|
||||
def remove(self, path):
|
||||
path = self.splitpath(path)
|
||||
path = self._splitpath(path)
|
||||
|
||||
with self.walk(path) as fid:
|
||||
self.dorpc(fcall.Tremove(fid=fid))
|
||||
with self._walk(path) as fid:
|
||||
self._dorpc(fcall.Tremove(fid=fid))
|
||||
|
||||
def stat(self, path):
|
||||
path = self.splitpath(path)
|
||||
path = self._splitpath(path)
|
||||
|
||||
try:
|
||||
with self.walk(path) as fid:
|
||||
resp = self.dorpc(fcall.Tstat(fid= fid))
|
||||
with self._walk(path) as fid:
|
||||
resp = self._dorpc(fcall.Tstat(fid= fid))
|
||||
st = resp.stat()
|
||||
self.clunk(fid)
|
||||
self._clunk(fid)
|
||||
return st
|
||||
except RPCError:
|
||||
return None
|
||||
@ -238,7 +235,7 @@ class File(object):
|
||||
self.client = client
|
||||
self.path = path
|
||||
self.fid = fid
|
||||
self.cleanup = cleanup
|
||||
self._cleanup = cleanup
|
||||
self.mode = mode
|
||||
self.iounit = fcall.iounit
|
||||
self.qid = fcall.qid
|
||||
@ -247,15 +244,15 @@ class File(object):
|
||||
self.offset = 0
|
||||
def __del__(self):
|
||||
if not self.closed:
|
||||
self.cleanup()
|
||||
self._cleanup()
|
||||
|
||||
def dorpc(self, fcall, async=None, error=None):
|
||||
def _dorpc(self, fcall, async=None, error=None):
|
||||
if hasattr(fcall, 'fid'):
|
||||
fcall.fid = self.fid
|
||||
return self.client.dorpc(fcall, async, error)
|
||||
return self.client._dorpc(fcall, async, error)
|
||||
|
||||
def stat(self):
|
||||
resp = self.dorpc(fcall.Tstat())
|
||||
resp = self._dorpc(fcall.Tstat())
|
||||
return resp.stat
|
||||
|
||||
def read(self, count=None, offset=None, buf=''):
|
||||
@ -270,7 +267,7 @@ class File(object):
|
||||
n = min(count, self.iounit)
|
||||
count -= n
|
||||
|
||||
resp = self.dorpc(fcall.Tread(offset=offs, count=n))
|
||||
resp = self._dorpc(fcall.Tread(offset=offs, count=n))
|
||||
data = resp.data
|
||||
|
||||
offs += len(data)
|
||||
@ -307,7 +304,7 @@ class File(object):
|
||||
while off < len(data):
|
||||
n = min(len(data), self.iounit)
|
||||
|
||||
resp = self.dorpc(fcall.Twrite(offset=offs,
|
||||
resp = self._dorpc(fcall.Twrite(offset=offs,
|
||||
data=data[off:off+n]))
|
||||
off += resp.count
|
||||
offs += resp.count
|
||||
@ -331,7 +328,7 @@ class File(object):
|
||||
def close(self):
|
||||
assert not self.closed
|
||||
self.closed = True
|
||||
self.cleanup()
|
||||
self._cleanup()
|
||||
self.tg = None
|
||||
self.fid = None
|
||||
self.client = None
|
||||
@ -339,7 +336,7 @@ class File(object):
|
||||
|
||||
def remove(self):
|
||||
try:
|
||||
self.dorpc(fcall.Tremove())
|
||||
self._dorpc(fcall.Tremove())
|
||||
finally:
|
||||
try:
|
||||
self.close()
|
||||
|
@ -70,8 +70,7 @@ client.awrite('/event', 'Start wmiirc')
|
||||
|
||||
tags = Tags()
|
||||
bind_events({
|
||||
'Quit': lambda args: sys.exit(),
|
||||
'Start': lambda args: args == 'wmiirc' and sys.exit(),
|
||||
('Quit', Match('Start', 'wmiirc')): lambda *a: sys.exit(),
|
||||
'CreateTag': tags.add,
|
||||
'DestroyTag': tags.delete,
|
||||
'FocusTag': tags.focus,
|
||||
@ -88,11 +87,21 @@ bind_events({
|
||||
|
||||
'Notice': lambda args: notice.show(args),
|
||||
|
||||
('LeftBarClick', 'LeftBarDND'):
|
||||
lambda args: args.split()[0] == '1' and tags.select(args.split(' ', 1)[1]),
|
||||
Match(('LeftBarClick', 'LeftBarDND'), '1'): lambda e, b, tag: tags.select(tag),
|
||||
Match('LeftBarClick', '4'): lambda *a: tags.select(tags.next(True)),
|
||||
Match('LeftBarClick', '5'): lambda *a: tags.select(tags.next()),
|
||||
|
||||
'ClientMouseDown': lambda args: menu(*args.split(), type='client'),
|
||||
'LeftBarMouseDown': lambda args: menu(*reversed(args.split()), type='lbar'),
|
||||
Match('LeftBarMouseDown', 3): lambda e, n, tag: clickmenu((
|
||||
('Delete', lambda t: Tag(t).delete()),
|
||||
), (tag,)),
|
||||
Match('ClientMouseDown', _, 3): lambda e, client, n: clickmenu((
|
||||
('Delete', lambda c: Client(c).kill()),
|
||||
('Kill', lambda c: Client(c).slay()),
|
||||
('Fullscreen', lambda c: Client(c).set('Fullscreen', 'on')),
|
||||
), (client,)),
|
||||
|
||||
Match('ClientClick', _, 4): lambda e, c, n: Tag('sel').select('up'),
|
||||
Match('ClientClick', _, 5): lambda e, c, n: Tag('sel').select('down'),
|
||||
})
|
||||
|
||||
@apply
|
||||
@ -117,20 +126,10 @@ action_menu = Menu(histfile='%s/history.action' % confpath[0], nhist=500,
|
||||
tag_menu = Menu(histfile='%s/history.tags' % confpath[0], nhist=100,
|
||||
choices=lambda: sorted(tags.tags.keys()))
|
||||
|
||||
def menu(target, button, type):
|
||||
MENUS = {
|
||||
('client', '3'): (
|
||||
('Delete', lambda c: Client(c).kill()),
|
||||
('Kill', lambda c: Client(c).slay()),
|
||||
('Fullscreen', lambda c: Client(c).set('Fullscreen', 'on'))),
|
||||
('lbar', '3'): (
|
||||
('Delete', lambda t: Tag(t).delete())),
|
||||
}
|
||||
choices = MENUS.get((type, button), None)
|
||||
if choices:
|
||||
ClickMenu(choices=(k for k, v in choices),
|
||||
action=lambda k: dict(choices).get(k, identity)(target)
|
||||
).call()
|
||||
def clickmenu(choices, args):
|
||||
ClickMenu(choices=(k for k, v in choices),
|
||||
action=lambda choice: dict(choices).get(choice, identity)(*args)) \
|
||||
.call()
|
||||
|
||||
class Notice(Button):
|
||||
def __init__(self):
|
||||
@ -138,7 +137,7 @@ class Notice(Button):
|
||||
self.timer = None
|
||||
|
||||
def tick(self):
|
||||
self.label = ''
|
||||
self.label = ' '
|
||||
|
||||
def write(self, notice):
|
||||
client.awrite('/event', 'Notice %s' % notice.replace('\n', ' '))
|
||||
@ -201,7 +200,8 @@ map(bind_num, range(0, 10))
|
||||
|
||||
Actions.rehash()
|
||||
|
||||
dirs = ('%s/plugins' % dir for dir in confpath if os.access('%s/plugins' % dir, os.R_OK))
|
||||
dirs = filter(curry(os.access, _, os.R_OK),
|
||||
('%s/plugins' % dir for dir in confpath))
|
||||
files = filter(re.compile(r'\.py$').match,
|
||||
reduce(operator.add, map(os.listdir, dirs), []))
|
||||
for f in ['wmiirc_local'] + ['plugins.%s' % file[:-3] for file in files]:
|
||||
|
Loading…
Reference in New Issue
Block a user