summaryrefslogtreecommitdiffstats
path: root/punani
diff options
context:
space:
mode:
Diffstat (limited to 'punani')
-rwxr-xr-xpunani/bin/punani97
-rwxr-xr-xpunani/bot/__init__.py99
-rw-r--r--punani/db/punani4
-rwxr-xr-xpunani/index.py56
4 files changed, 201 insertions, 55 deletions
diff --git a/punani/bin/punani b/punani/bin/punani
index 8caf669e..4be74f77 100755
--- a/punani/bin/punani
+++ b/punani/bin/punani
@@ -1,59 +1,64 @@
-#!/bin/bash
+#! /bin/sh
set -euf
-if [ $# -ne 2 ];then
- echo "usage: `basename $0` (install|remove) PACKAGE"
- exit 23
-fi
+PUNANI_HOST="${PUNANI_HOST-http://euer.krebsco.de:9111}"
+ACTION="$1"; shift
+PKGS="$*"
-PACKERS="yum!-y install remove
-brew install remove
-pacman!--noconfirm -S!--needed -Rcs
-bauerbill!--noconfirm -S!--needed -Rcs
-yaourt!--noconfirm -S!--needed -Rcs
-packer!--noconfirm -S!--needed -Rcs
-apt-get!--yes install remove
-aptitude!--yes install remove"
-
-OIFS=$IFS
-PACKER=
-IFS='
-'
-
-TIGHTNANI_HOST="http://euer.krebsco.de:9111"
-# Find suitable packer
-for PACKER_LINE in $PACKERS; do
- TRY_PACKER_CMD="$(echo "$PACKER_LINE" | cut -d ' ' -f 1)"
- TRY_PACKER="$(echo "$TRY_PACKER_CMD" | cut -d '!' -f 1)"
- if which $TRY_PACKER &>/dev/null; then
- PACKER=$TRY_PACKER
- PACKER_CMD="$(echo "$TRY_PACKER_CMD" | tr "!" " ")"
- echo "you got $PACKER"
- INSTALL_PARAM="$(echo "$PACKER_LINE" | cut -d ' ' -f 2 | tr "!" " ")"
- REMOVE_PARAM="$(echo "$PACKER_LINE" | cut -d ' ' -f 3 | tr "!" " ")"
- fi
-done
-IFS=$OIFS
-if [ ! "$PACKER" ];then
- echo "Could not find a supported packer for you, bailing out!"
- exit 23
-fi
+## find package manager
+if ! :; then : # dummy case, so the rest has a common format
+
+elif for PACKER_CMD in yum
+ do type $PACKER_CMD 2>/dev/null 1>&2 && break; done; then
+ INSTALL_PARAM='-y install'
+ REMOVE_PARAM='-y remove'
+elif for PACKER_CMD in brew
+ do type $PACKER_CMD 2>/dev/null 1>&2 && break; done; then
+ INSTALL_PARAM='install'
+ REMOVE_PARAM='remove'
-# find the package name
-PKG="$2"
-RESOLVED=`wget -O- $TIGHTNANI_HOST/$PACKER/$PKG 2>/dev/null`
-if [ ! "$RESOLVED" ];then
- echo "Could not resolve your requested package, bailing out!"
+elif for PACKER_CMD in bauerbill packer yaourt pacman
+ do type $PACKER_CMD 2>/dev/null 1>&2 && break; done; then
+ INSTALL_PARAM='--noconfirm -S --needed'
+ REMOVE_PARAM='-Rcs'
+
+elif for PACKER_CMD in aptitude apt-get
+ do type $PACKER_CMD 2>/dev/null 1>&2 && break; done; then
+ INSTALL_PARAM='--yes install'
+ REMOVE_PARAM='--yes remove'
+
+else
+ echo "Error 2: no known package manager found; no punani for you!" >&2
exit 23
fi
-case "$1" in
+
+## find package name
+if test -n "$PKGS"; then
+ for PKG in $PKGS; do
+ RES="`wget -O- $PUNANI_HOST/$PACKER_CMD/$PKG 2>/dev/null || :`"
+ if [ ! "$RES" ]; then
+ echo "Error 2: could not resolve '$PKG'; no punani for you!" >&2
+ exit 23
+ fi
+ RESOLVED="${RESOLVED+$RESOLVED }$RES"
+ done
+else
+ echo "Error 1: no PACKAGE specified." >&2
+ ACTION="usage"
+fi
+
+## dispatch
+case "$ACTION" in
install)
- exec $PACKER_CMD $INSTALL_PARAM $RESOLVED
+ set -x
+ exec sudo $PACKER_CMD $INSTALL_PARAM $RESOLVED
;;
remove)
- exec $PACKER_CMD $REMOVE_PARAM $RESOLVED
+ set -x
+ exec sudo $PACKER_CMD $REMOVE_PARAM $RESOLVED
;;
*)
- echo "usage: `basename $0` (install|remove) PACKAGE"
+ echo "usage: `basename $0` (install|remove) PACKAGE..."
+ exit 23
esac
diff --git a/punani/bot/__init__.py b/punani/bot/__init__.py
new file mode 100755
index 00000000..13d4c20b
--- /dev/null
+++ b/punani/bot/__init__.py
@@ -0,0 +1,99 @@
+#!/usr/bin/python
+from Queue import Queue
+from SocketServer import BaseRequestHandler, ThreadingTCPServer
+from threading import Thread
+from time import sleep, strftime, strptime
+
+from ircbot import SingleServerIRCBot
+from irclib import nm_to_n
+
+class PunaniRequestHandler(BaseRequestHandler):
+ """Handler for Punani messages."""
+
+ def handle(self):
+ try:
+ msg = self.request.recv(1024).strip()
+ except ValueError:
+ msg = 'Invalid message.'
+ else:
+ self.server.queue.put((self.client_address, msg))
+ print ('%s:%d' % self.client_address), str(msg)
+
+
+class PunaniReceiveServer(ThreadingTCPServer):
+ """UDP server that waits for Punani messages."""
+
+ def __init__(self):
+ ThreadingTCPServer.__init__(self, ('127.0.0.1', 5555), PunaniRequestHandler)
+ self.queue = Queue()
+
+class PunaniBot(SingleServerIRCBot):
+
+ def __init__(self, server_list, channel_list, nickname='punani-ircbot',
+ realname='Bob Ross'):
+ SingleServerIRCBot.__init__(self, server_list, nickname, realname)
+ self.channel_list = channel_list
+
+ def on_welcome(self, conn, event):
+ """Join channels after connect."""
+ print 'Connected to %s:%d.' % conn.socket.getsockname()
+ for channel, key in self.channel_list:
+ conn.join(channel, key)
+
+ def on_nicknameinuse(self, conn, event):
+ """Choose another nickname if conflicting."""
+ self._nickname += '_'
+ conn.nick(self._nickname)
+
+ def on_ctcp(self, conn, event):
+ """Answer CTCP PING and VERSION queries."""
+ whonick = nm_to_n(event.source())
+ message = event.arguments()[0].lower()
+ if message == 'version':
+ conn.notice(whonick, 'Punani2irc')
+ elif message == 'ping':
+ conn.pong(whonick)
+
+ def on_privmsg(self, conn, event):
+ """React on private messages.
+
+ Die, for example.
+ """
+ whonick = nm_to_n(event.source())
+ message = event.arguments()[0]
+ if message == 'die!':
+ print 'Shutting down as requested by %s...' % whonick
+ self.die('Shutting down.')
+
+ def say(self, msg):
+ """Say message to channels."""
+ for channel, key in self.channel_list:
+ self.connection.privmsg(channel, msg)
+
+def process_queue(announce_callback, queue, delay=2):
+ """Process received messages in queue."""
+ while True:
+ sleep(delay)
+ try:
+ addr, msg = queue.get()
+ except Empty:
+ continue
+ #do something with the addr?
+ announce_callback(str(msg))
+if __name__ == '__main__':
+ # Set IRC connection parameters.
+ irc_servers = [('supernode', 6667)]
+ irc_channels = [('#retiolum','')]
+
+ # Prepare and start IRC bot.
+ bot = PunaniBot(irc_servers, irc_channels)
+ t = Thread(target=bot.start)
+ t.daemon = True
+ t.start()
+ announce = bot.say
+
+ receiver = PunaniReceiveServer()
+ t = Thread(target=process_queue,args=(announce,receiver.queue))
+ t.daemon = True
+ t.start()
+ receiver.serve_forever()
diff --git a/punani/db/punani b/punani/db/punani
index 318f0e27..df471f3a 100644
--- a/punani/db/punani
+++ b/punani/db/punani
@@ -13,6 +13,10 @@
"brew" : "vim",
"yum" : "vim"
},
+ "unison" : {
+ "apt-get" : "unison",
+ "pacman" : "unison"
+ },
"python" : {
"apt-get" : "python",
"pacman" : "python2"
diff --git a/punani/index.py b/punani/index.py
index 4e6a64a4..ac19b2fb 100755
--- a/punani/index.py
+++ b/punani/index.py
@@ -2,20 +2,30 @@
import web
import json
-
+import os
+from bot import *
urls = (
'/', 'Index',
'/dump','Dump',
- '/reload','Reload',
+# '/reload','Reload',
'/(.+)/(.+)', 'ArchFinder',
)
-PDB_FILE="tightnani_db"
+PDB_FILE="db/punani"
+PORT="9111"
+CHANNEL="#retiolum"
f = open(PDB_FILE)
-pdb= json.load(f)
+pdb = json.load(f)
f.close()
+polite = os.environ.get("polite",False)
+from socket import *
+def local_announce(msg):
+ s = socket(AF_INET,SOCK_STREAM)
+ s.connect(('localhost',5555))
+ s.send(msg)
+ s.close()
class Index:
def GET(self):
ret = """Welcome to the Tightnani API<br/>
@@ -35,15 +45,22 @@ class Dump:
return json.dumps(pdb,sort_keys=True,indent=4)
class ArchFinder:
- def GET(self,packer,package):
- if not packer or not package: web.BadRequest()
+ def GET(self,request_packer,package):
+ if not request_packer or not package: web.BadRequest()
else:
- packer = pdb['packer-symlinks'].get(packer,packer) #try to resolve similar packers
+ packer = pdb['packer-symlinks'].get(request_packer,request_packer) #try to resolve similar packers
super_packer = pdb['super-packer'].get(packer,'')
ret = pdb.get(package,{}).get(packer,False)
ret = ret if ret else pdb.get(package,{}).get(super_packer,False)
- if not ret:
+ if not ret:
+ try:
+ if polite:
+ local_announce("Client `%s` asked for the tool `%s` in packer `%s` but i do not have it in my Database. Please update me!" %(web.ctx.ip, package,packer))
+ else:
+ local_announce("404: no %s/%s for %s" % (request_packer,package,gethostbyaddr(web.ctx.ip)[0]))
+ except Exception,e:
+ print ("Got Exception %s: %s" % (str(Exception),(e)))
web.NotFound()
return "not found. i'm so sorry :("
else: return ret
@@ -52,7 +69,28 @@ class ArchFinder:
if __name__ == "__main__":
import sys
- sys.argv.append("9111")
+ # Set IRC connection parameters.
+ irc_servers = [('supernode', 6667)]
+ irc_channels = [('#retiolum','')]
+
+ # Prepare and start IRC bot.
+ bot = PunaniBot(irc_servers, irc_channels)
+ t = Thread(target=bot.start)
+ t.daemon = True
+ t.start()
+ announce = bot.say
+
+ receiver = PunaniReceiveServer()
+ t = Thread(target=receiver.serve_forever)
+ t.daemon = True
+ t.start()
+
+ t = Thread(target=process_queue,args=(announce,receiver.queue))
+ t.daemon = True
+ t.start()
+
+
+ sys.argv.append(PORT)
app = web.application(urls,globals())
app.internalerror = web.debugerror
app.run()