Home > database >  Compare folder size and run script if the size changed
Compare folder size and run script if the size changed

Time:02-08

I am trying to write a code which will carry out something with the newly added file to the folder. So, the way I see it is to calculate the folder size, compare it with the one calculated ±10 mins ago, and then to do something with the newly added file if the size of the folder did change.

while (True):
    def get_size(start_path='/Users/.../Desktop/files'):
        total_size = 0
        for dirpath, dirnames, filenames in os.walk(start_path):
            for f in filenames:
                fp = os.path.join(dirpath, f)
                # skip if it is symbolic link
                if not os.path.islink(fp):
                    total_size  = os.path.getsize(fp)

        return total_size

    print(get_size(), 'bytes')
    time.sleep(10)

The code above calculates the size of the folder every 10 seconds. I don't know how to compare it to the previous size though :(

Please, help..

CodePudding user response:

This is a simple problem, that can be sobstituted with a minimum reproducible example this way:

while True:
    a = input() # How can I check if this is different from the previous input?

Create a variable that stores the previous weight, this way:

old = get_size()
while True:
    new = get_size()
    if new != old:
        # Something changed
    old = new # You can do it since integers are immutable typed

I would add a suggestion for you:

def get_size():
    ...
while True:
    ...

This will make you avoid a waste of time and efficiency, since otherwise the get_size function gets redefined each time the while loop executes (every 10 seconds!).

CodePudding user response:

Tracking the total size of the directory is limiting. How about you keep a list of files and their sizes? That way you can act on changed files and new files. Using a dictionary here as a basic example, you can really make it as complicated as you wish, tracking creation, modification dates etc. If you don't want the complexity I have retained tracking of total size, however you still need to track which file(s) have changed.

import os
import time

def check_dir(fh,start_path='/tmp',new_cb=None,changed_cb=None):
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(start_path):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            if not os.path.islink(fp):
                fs = os.path.getsize(fp)
                total_size  = fs
                if f in fh:
                    if fh[f] == fs:
                        # file unchanged
                        pass
                    else:
                        if changed_cb:
                            changed_cb(fp)
                else:
                    #new file
                    if new_cb:
                        new_cb(fp)
                fh[f] = fs

    return total_size

def new_file(fp):
    print("New File {0}!".format(fp))

def changed_file(fp):
    print("File {0} changed!".format(fp))

if __name__ == '__main__':
    file_history={}
    total = 0

    while(True):
        nt = check_dir(file_history,'/tmp/test',new_file,changed_file)
        if total and nt != total:
            print("Total size changed from {0} to {1}".format(total,nt))
            total = nt
        time.sleep(10)
        print("File list:\n{0}".format(file_history))

CodePudding user response:

You can try something like that:

before = 0
while (True):
    def get_size(start_path='.'):
        total_size = 0
        # use variable defined outside loop
        global before
        for dirpath, dirnames, filenames in os.walk(start_path):
            for f in filenames:
                fp = os.path.join(dirpath, f)
                # skip if it is symbolic link
                if not os.path.islink(fp):
                    total_size  = os.path.getsize(fp)

        # Your logic
        if total_size > before:
            print("New: " str(total_size - before))
        else:
            print("No changes")
        before = total_size
        return total_size

    print(get_size(), 'bytes')
    time.sleep(10)
  •  Tags:  
  • Related