Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Easy File Scanner
#1
I'm not a heavy Python programmer, but I enjoy it habitually and started a project recently.
The idea is to have a program that checks a backup copy of a file from, for example, /etc/services that is saved elsewhere, finds the corresponding /etc/* file and compares them for changes.
right now it's simple and only compares the lengths of the files, but depending on that outcome will do more. For example, if the files match in length it will then request an integrity scan. If they're different lengths it displays the stray lines/text and gives options on how to handle it - delete the line etc.

I'm hoping some of you will have the time and will to look at it and offer some insight into ways of tightening it up, making it more concise/shortening code, any ideas on extended functionality that I didn't mention above

Here's the code

import os

# First search the ~/Documents/Control_Files dir; list the available control files; and ask which one to use
# I'm putting 2 'live' test files named "password_live" and "services_live" in LiveFiles dir


def start_program():
    c_path = '/*/ControlFiles/'
    l_path = '/*/LiveFiles/'  # Subject to change
    start_menu = make_menu(c_path)

    print('\n')
    print_menu(start_menu)
    print('\n')
    c_choice = int(input("Which control file? "))
    prepared_files = prep_files(c_choice, c_path, l_path)
    line_count(prepared_files)


def make_menu(path):
    # Turn list of files in *Files to a dictionary w/integers as keys
    file_list = os.listdir(path)
    menu_dict = {a: b for a, b in enumerate(file_list)}
    return menu_dict


def print_menu(menu_dict):
    # Print format menu_dict for content files menu
    for number, file in menu_dict.items():
        print("{}: {}".format(number, file))


def prep_files(choice, c_path, l_path):
    c_dict = make_menu(c_path)
    l_file_name = c_dict[choice].rsplit('_', 1)[0] + '_live'
    print("Preparing to check control file at: ")
    print("\t'" + (c_path + c_dict[choice]) + "'")
    print("Against the live file at: ")
    print("\t'" + (l_path + l_file_name) + "'")
    input("\n Press ENTER to proceed")
    with open(c_path + c_dict[choice], 'r') as cf:
        c_file = set(cf)

    with open(l_path + l_file_name, 'r') as lf:
        l_file = set(lf)

    return c_file, l_file


def line_count(file_tup):
    c_len = len(file_tup[0])
    l_len = len(file_tup[1])
    if l_len > c_len:
        print("\n[!!]  IT APPEARS THAT THE LIVE FILE HAS ACQUIRED SOME CONTENT")
        print("\n[!!]\t ..or the CONTROL FILE lost something")
    elif l_len < c_len:
        print("\n[!!] IT APPEARS THAT THE LIVE FILE HAS LOST SOME CONTENT")
        print("\n[!!]\t ..or the CONTROL FILE was added to")
    else:
        print("\n[**] The files are the same length")
        print("\n[!!]\t ..but they may not hold the same content")


start_program()
As it is now it takes a file named '*_control' and finds the corresponding '*_live' file to compare.
Just to clarify I'm using the term 'live' or 'l_***' in the code to refer to the active system file and 'control' or 'c_****' is the backup copy of that file, stored seperately
Reply
#2
You are not comparing the file lengths in this code but the number of lines. For this, you don't need to store the contents of the files in sets, you could count the lines with
import more_itertools as mit

with open(filename) as ifh:
    nline = mit.ilen(ifh)
If you want to compare the size in bytes, it is even simpler, you don't need to open the file
import os

nbyte = os.stat(filename).st_size
Reply
#3
Thanks, the exact kind of input I was hoping for, got me thinking about other functionality too
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020