from subprocess import Popen, PIPE
import re

import arrow

class SNMP(object):
    def __init__(self, host='', community='public'):
        assert host
        self.host = host
        self.community = community

    def _cast(self, text):
        if re.search(r'^\s*\d+\s*$', text):
            # Integer
            return int(text)
        elif re.search(r'^\s*\d+\.\d+\.\d+\.\d+\s*$', text):
            # IP Address
            return str(text)
        else:
            return str(text)

    def _parse(self, text, options='', debug=False):
        """Parse the output of bulkwalk()"""
        retval = dict()
        for line in text.splitlines():
            line.strip()
            if options=='Oxsq':
                if debug:
                    print "Parsing: '{0}'".format(line.strip())
                mm = re.search(r'^(?P<index>\S+)\s+(?P<type>=\s+(INTEGER|STRING):\s+\")*(?P<value>\S.+?)\"*$', line.strip())
            elif options=='sq':
                if debug:
                    print "Parsing: '{0}'".format(line.strip())
                # RFC1213-MIB::ifDescr.10101 = STRING: "GigabitEthernet0/1"
                mm = re.search(r'^(?P<index>\S+)\s+=\s+(INTEGER|STRING):\s+\"(?P<value>\S.+?)\"$', line.strip())
            assert mm is not None, "Could not parse: '{0}'".format(line)
            tmp = mm.groupdict()
            if debug:
                print "Parsed: {0}".format(tmp)
            index, value = tmp.get('index'), tmp.get('value')
            retval[self._cast(index)] = self._cast(value)
        return retval

    def pivot_table(self, vals1, vals2):
        """Use the common oid index values to combine into one table"""
        assert vals1
        assert vals2
        retval = dict()
        for idx, val1 in vals1.items():
            retval[val1] =vals2.get(idx)
        return retval

    def bulkwalk(self, oidspec="", mibfile=""):
        assert oidspec
        if mibfile:
            # ifDescr.10101 GigabitEthernet0/1
            cmd = 'snmpbulkwalk -v 2c -m {0} -c {1} -Oxsq {2} {3}'.format(
                mibfile, self.community, self.host, oidspec)
            proc = Popen(cmd, shell=True, stdout=PIPE)
            return self._parse(proc.stdout.read(), options='Oxsq'), arrow.now()

        else:
            # RFC1213-MIB::ifDescr.10101 = STRING: "GigabitEthernet0/1"
            cmd = 'snmpbulkwalk -v 2c -c {0} -sq {1} {2}'.format(
                self.community, self.host, oidspec)
            proc = Popen(cmd, shell=True, stdout=PIPE)
            return self._parse(proc.stdout.read(), options='sq'), arrow.now()


@@ -529,21 +529,8 @@
 s=''
-, debug=False
 ):%0A 
@@ -697,98 +697,8 @@
 q':%0A
-                if debug:%0A                    print %22Parsing: '%7B0%7D'%22.format(line.strip())%0A
     
@@ -719,32 +719,38 @@
  = re.search(r'%5E
+%5CS+?%5C.
 (?P%3Cindex%3E%5CS+)%5Cs
@@ -740,25 +740,25 @@
 .(?P%3Cindex%3E%5C
-S
+d
 +)%5Cs+(?P%3Ctyp
@@ -860,98 +860,8 @@
 q':%0A
-                if debug:%0A                    print %22Parsing: '%7B0%7D'%22.format(line.strip())%0A
     
@@ -966,16 +966,22 @@
 arch(r'%5E
+%5CS+?%5C.
 (?P%3Cinde
@@ -983,17 +983,17 @@
 %3Cindex%3E%5C
-S
+d
 +)%5Cs+=%5Cs
@@ -1015,16 +1015,17 @@
 G):%5Cs+%5C%22
+*
 (?P%3Cvalu
@@ -1034,16 +1034,17 @@
 %5CS.+?)%5C%22
+*
 $', line
@@ -1163,78 +1163,8 @@
 t()%0A
-            if debug:%0A                print %22Parsed: %7B0%7D%22.format(tmp)%0A
     

Fix some regex in _parser()