Opened 14 months ago

Last modified 7 months ago

#3276 new feature-request

System quota support

Reported by: alexgeek Owned by:
Priority: minor Milestone: 1.3.16
Component: Core Version: 1.3.15
Keywords: quota, free_space Cc:

Description

Hi,

Deluge is used often by every kind of a seedbox provider and usually they use Linux quota to restrict free disk space for each user on a shared server. This creates a problem with showing incorrect free disk space in Deluge on which depends plugins like AutoRemovePlus?, because currently it calculates free space on an entire volume instead of using quota.

I made some changes in common.py free_space function to support quota and I hope you will integrate them in some way in the future. I'm not a python developer, so sorry if my code is bad.

In the end it returns an amount of bytes left by defined quota for an user.

Example of quota -u -w output:

Disk quotas for user alex (uid 1999):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
     /dev/sda1 668981152  2097152000 2097152000            6509       0       0

New free_space function code:

def free_space(path):
    """
    Gets the free space available at 'path'

    :param path: the path to check
    :type path: string
    :returns: the free space at path in bytes
    :rtype: int

    :raises InvalidPathError: if the path is not valid

    """
    if not path or not os.path.exists(path):
        raise InvalidPathError("%s is not a valid path" % path)

    if windows_check():
        from win32file import GetDiskFreeSpaceEx
        return GetDiskFreeSpaceEx(path)[0]
    else:
        def default_method(path):
            disk_data = os.statvfs(path.encode("utf8"))
            block_size = disk_data.f_frsize
            return disk_data.f_bavail * block_size

        quota = '/usr/bin/quota'
        awk = '/usr/bin/awk'

        if not os.path.isfile(quota) or not os.path.isfile(awk):
            return default_method(path)

        quota_cmd = ['/usr/bin/quota', '-u', '-w']
        awk_cmd = ['/usr/bin/awk', 'END {printf "%.0f", ($3-$2)*1024}']

        quota_process = subprocess.Popen(quota_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        output_q, error_q = quota_process.communicate()

        if quota_process.returncode != 0 or len(error_q) > 0:
            return default_method(path)

        awk_process = subprocess.Popen(awk_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        output_a, error_a = awk_process.communicate(input=output_q)

        if awk_process.returncode != 0 or len(error_a) > 0:
            return default_method(path)

        try:
            return int(output_a)
        except ValueError:
            return default_method(path)

Change History (1)

comment:1 Changed 7 months ago by whereupon

Why pay for seedbox instead of usenet?

Note: See TracTickets for help on using tickets.