Search code examples
pythontexthashtablehashcode

Parsing a dictionary in Python to my current table


I have a table that contains a few categories and two of them are: mac address and device name. I had a the list of my mac address written in my code (hardcoded) with their corresponding device names (ie deviceDict['00:00:00:00:00:00']= name)

Now, I passed those mac addresses and device names to a text file to be read from that same Python code and parse it onto my table. The code currently recognizes the text file but it is not parsing that information onto the table.

Here is the code:

# File: WapLogParser.py
# Desc: Parses a WAP log file and pulls out information relating to connected clients
# Usage: python WapLogParser.py [file glob]

import re
import sys
import glob
import os

deviceDict = dict()

# Base table for storing client info
# All names must match what is in the Wap Log file
#   Exceptions: Date, Wap Name, Device Name - which are provided outside of the result parsing
table = [["Ssid", "Vlan", "Mac Address", "Connected Time", "Ip Address", "Rssi", "Date", "Wap Name", "Device Name"]]

def ParseResult(result, date, wapName):
    lines = result.split('\n')
    lines = list(filter(None, lines))
    # Any useful info will be at least 2 lines long
    if len(lines) == 1:
        return
    # create empty row
    data = [""] * len(table[0])
    # for each item in the result place it in the correct spot in the row 
    for line in lines:
        if line != "":
            # Parse the key/value pair
            m = re.match(r"(.*):\s\.*\s?(.*)", line)
            if m is not None:
                for idx in range(len(table[0])):
                    if table[0][idx].lower() == m[1].lower():
                         data[idx] = m[2]
        else:
            break

    # Remove the '(dBm)' from the RSSI value
    data[5] = data[5].split()[0]

    # Append WAP specific items to row
    data[6] = date
    data[7] = wapName
    data[8] = GetDeviceName(data[2].upper())

    # Add row to table
    table.append(data)


def ParseFile(path):
    with open(path) as f:
        lines = f.readlines()
        result = ""
        command = ""
        date = ""
        # WAP name is always on the first line 16 characters in with 4 
        # unnecessary characters trailing
        wapName = lines[0].strip()[16:-4]
        for line in lines:
            line = line.strip()
            # Is an issued command?
            if line.startswith("/#"):
                if command != "":
                    ParseResult(result, date, wapName) 
                command = "" 
                # reset the result for the new command
                result = ""
                m = re.match(r"^/#.*show\sclient.*stats$", line)
                if m is not None:
                    command = line
            # Anything that is not a command add to the result
            else:
                result += line + "\n"

            # Do we have the date?
            if line.startswith("Current date:"):
                date = line.replace("Current date: ", "")

# Print output to stderr
def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

# Print a 2d array in a csv format
def PrintAsCsv(table):
    for row in table:
        print(",".join(row))


def Main():
    InitDeviceDict()
    numArgs = len(sys.argv)
    for filename in glob.iglob(sys.argv[numArgs - 1], recursive=True):
        # Globs get directories too
        if os.path.isfile(filename):
            eprint("Parsing " + filename)
            try:
                ParseFile(filename)
            except Exception as e: # Mainly for if we see a binary file
                eprint("Bad file: " + e)

    # Print in a format we can use
    PrintAsCsv(table)


def GetDeviceName(macAddress):
    if macAddress in deviceDict:
        return deviceDict[macAddress]

    manufacturerPart = macAddress[:8]
    if manufacturerPart in deviceDict:
        return deviceDict[manufacturerPart]

    return 'Unknown Device'


def InitDeviceDict():
    with open('try.txt','r') as fo:
        for line in fo:
           deviceDict = {}
           line = line.split(',')
           macAddress = line[0].strip()
           manufacturerPart = line[1].strip()
           if macAddress in deviceDict:
               deviceDict[macAddress].append(manufacturerPart)
           else:
               deviceDict[macAddress]=(manufacturerPart)


           print(deviceDict)

# entry point
# script arguments:
#   WapLogParser.py [file glob]
if __name__ == "__main__":
    Main()

The issue is on the functions GetDeviceName and InitDeviceDict. When I run the code and then a batch file to display my info on excel, I keep getting "unknown device" (as if it is not recognizing the mac address I entered to produce the device name)

Any way I can correct this? Thank you


Solution

  • The deviceDict that is populated in InitDeviceDict is not the global deviceDict. You are only modifying a function-local dictionary (and resetting it every line as well). Remove deviceDict = {} from that function and, at the top of the function use global deviceDict to declare that you are modifying the global.

    def InitDeviceDict():
        global deviceDict
        with open('try.txt','r') as fo:
            for line in fo:
               line = line.split(',')
               macAddress = line[0].strip()
               manufacturerPart = line[1].strip()
               if macAddress in deviceDict:
                   deviceDict[macAddress].append(manufacturerPart)
               else:
                   deviceDict[macAddress]=[manufacturerPart]