aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2016-10-06 21:56:23 +0200
committerMattias Andrée <maandree@kth.se>2016-10-06 23:42:49 +0200
commitd48a8becba6f701b2d243a29d4ccc7ff03c1ed3a (patch)
tree56d723f6f9d81a5d078b993d9488d185c69125d5
parentm (diff)
downloadxpybar-d48a8becba6f701b2d243a29d4ccc7ff03c1ed3a.tar.gz
xpybar-d48a8becba6f701b2d243a29d4ccc7ff03c1ed3a.tar.bz2
xpybar-d48a8becba6f701b2d243a29d4ccc7ff03c1ed3a.tar.xz
m + add ii
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--DEPENDENCIES4
-rw-r--r--TODO1
-rw-r--r--examples/compact2
-rw-r--r--src/plugins/ii.py142
-rw-r--r--src/plugins/inotify.py7
5 files changed, 153 insertions, 3 deletions
diff --git a/DEPENDENCIES b/DEPENDENCIES
index 72ca15f..9103596 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -15,7 +15,8 @@ OPTIONAL RUNTIME DEPENDENCIES:
python-pytz: for timezone support
python-sysv-ipc: for ropty example
iputils: for ping support
- inotify-tools: for inotify support
+ inotify-tools: for ii and inotify support
+ ii: for ii support
alarm: for limiting the time of a file search in locks
findutils: for file search in locks
graphicsmagick: for image support
@@ -23,6 +24,7 @@ OPTIONAL RUNTIME DEPENDENCIES:
file: for image support
librsvg: for image support
solar-python>=2.5: for solar data
+ pdeath: for automatic killing of child processes on exit
BUILD DEPENDENCIES:
diff --git a/TODO b/TODO
index 9c3f581..6336925 100644
--- a/TODO
+++ b/TODO
@@ -23,7 +23,6 @@ List of plugins to implement:
e-mail
Identify active and visible windows
natural disaster reports
- IRC
/proc/interrupts
/proc/net/sockstat
/proc/net/sockstat6
diff --git a/examples/compact b/examples/compact
index 6ba9fe7..0ae737d 100644
--- a/examples/compact
+++ b/examples/compact
@@ -110,7 +110,7 @@ def pdeath(signal, *command):
path = os.environ['PATH'].split(':')
for p in path:
p += '/pdeath'
- if os.access(p, os.F_OK | os.X_OK, effective_ids = True):
+ if os.access(p, os.X_OK, effective_ids = True):
return (p, signal, *command)
except:
pass
diff --git a/src/plugins/ii.py b/src/plugins/ii.py
new file mode 100644
index 0000000..5ffb266
--- /dev/null
+++ b/src/plugins/ii.py
@@ -0,0 +1,142 @@
+# -*- python -*-
+'''
+xpybar – xmobar replacement written in python
+Copyright © 2014, 2015, 2016 Mattias Andrée (maandree@member.fsf.org)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+'''
+
+
+class II:
+ '''
+ IRC interface, requires a running instance of ii <https://git.suckless.org/ii>
+ '''
+
+
+ def __init__(self, channel, prefix = None):
+ '''
+ Constructor
+
+ @param channel:str The name of the server or the name of the
+ server followed by a slash and the name of
+ the channel including the she
+ @param prefix:str? The argument associated with ii's -i flag
+ '''
+ import pwd, os
+ if prefix is None:
+ prefix = pwd.getpwuid(os.getuid()).pw_dir + '/irc'
+ self.infile = '%s/%s/in' % (prefix, channel)
+ self.outfile = '%s/%s/out' % (prefix, channel)
+ self.log = []
+ self.time = '0000-00-00 00:00 '
+
+
+ def write(self, text):
+ '''
+ Write to the channel
+
+ @param text:str The message or command
+ '''
+ text = (text + '\n').encode('utf-8')
+ with open(self.infile, 'wb') as file:
+ file.write(text)
+ file.flush()
+
+
+ def read(self):
+ '''
+ Fetch new messages from the channel
+
+ @return :list<str> List of new messages
+ '''
+ with open(self.outfile, 'rb') as file:
+ text = file.read()
+ text = text.decode('utf-8', 'replace').split('\n')[:-1]
+ i = 0
+ for line in text:
+ if line[:17] >= self.time:
+ break
+ i += 1
+ text = text[i:]
+ i = 0
+ while i < len(text) and i < len(self.log):
+ if text[i] != self.log[i]:
+ break
+ i += 1
+ text = text[i:]
+ if len(text) == 0:
+ return text
+ last = text[-1][:17]
+ if last == self.time:
+ self.log.extend(text)
+ return text
+ self.log = []
+ self.time = last
+ i = 0
+ for line in text:
+ if line[:17] == self.time:
+ break
+ i += 1
+ self.log = text[i:]
+ return text
+
+
+ def wait(self, timeout = None):
+ '''
+ Wait until more messages are available
+
+ @param timeout:int? The number of seconds to wait
+ before return unconditionally
+ '''
+ import os
+ command = ['inotifywait', '-e', 'close_write,modify']
+ if timeout is not None:
+ command += ['-t', str(int(timeout + 0.5))]
+ command += ['--', self.outfile]
+ if 'PATH' in os.environ:
+ path = os.environ['PATH'].split('.')
+ for p in path:
+ p += '/pdeath'
+ if os.access(p, os.X_OK, effective_ids = True):
+ command = [p, 'HUP'] + command
+ break
+ spawn_read(*command)
+
+
+ @staticmethod
+ def list_channels(prefix = None):
+ '''
+ Fetch a list of all joined servers and channels
+
+ @param prefix:str? The argument associated with ii's -i flag
+ @return :list<list> List of servers and channels
+ '''
+ import pwd, os
+ if prefix is None:
+ prefix = pwd.getpwuid(os.getuid()).pw_dir + '/irc'
+ ret = []
+ def isfifo(f):
+ try:
+ return os.path.stat.S_ISFIFO(os.stat('f').st_mode)
+ except:
+ return False
+ def recurse(d):
+ fs = os.listdir(d)
+ for f in fs:
+ f = d + '/' + f
+ if os.path.isfile(f + '/out') and isfifo(f + '/in'):
+ ret.append(f[len(prefix) + 1:])
+ recurse(prefix)
+ return ret
+
diff --git a/src/plugins/inotify.py b/src/plugins/inotify.py
index f92db48..84b24e9 100644
--- a/src/plugins/inotify.py
+++ b/src/plugins/inotify.py
@@ -51,6 +51,13 @@ class Inotify:
command.append('-e')
command.append(event)
command += list(arguments)
+ if 'PATH' in os.environ:
+ path = os.environ['PATH'].split('.')
+ for p in path:
+ p += '/pdeath'
+ if os.access(p, os.X_OK, effective_ids = True):
+ command = [p, 'HUP'] + command
+ break
def start():
with LineReader(spawn(*command)) as reader:
while True: