HEX
Server: Apache/2.2.34 (Unix) mod_fastcgi/mod_fastcgi-SNAP-0910052141
System: Linux Kou-Etsu-Dou 4.4.59+ #25556 SMP PREEMPT Thu Mar 4 18:03:46 CST 2021 x86_64
User: hosam (1026)
PHP: 7.2.29
Disabled: NONE
Upload Files
File: //usr/syno/bin/feasibilitycheck/share.d/transform/occupiedByPackage.py
#!/usr/bin/python
import os
import re
import sys
import subprocess
import json
import ConfigParser
import StringIO

PACKAGE_PATH = '/var/packages'
RESOURCE_PATH = 'conf/resource'
RESOURCE_OWN_PATH = 'conf/resource.own'
SYNOPKG = '/usr/syno/bin/synopkg'
INFO_PATH = 'INFO'
DUMMY_SECTION = 'dummy section'


def is_package_enabled(package):
    with open(os.devnull, 'w') as FNULL:
        try:
            result = subprocess.check_output([SYNOPKG, 'status', package],
                                             stderr=FNULL)
            return 'package is started' in result
        except subprocess.CalledProcessError:
            return False


def parse_share_from_file(file_name, share_key):
    shares = []
    try:
        with open(file_name) as resource_file_obj:
            resources = json.load(resource_file_obj)
            for share in resources['data-share']['shares']:
                shares.append(share[share_key])
    except (IOError, KeyError):
        return False, shares
    return True, shares


def is_share_in_resource(package, target_share):
    check_resource_own = False
    file_name = '%s/%s/%s' % (PACKAGE_PATH, package, RESOURCE_PATH)
    result, shares = parse_share_from_file(file_name, 'name')
    if not result:
        return False, False

    for share in shares:
        if target_share == share:
            return True, False
        if re.match('{{.*}}', share):
            check_resource_own = True

    return False, check_resource_own


def is_share_in_resource_own(package, target_share):
    file_name = '%s/%s/%s' % (PACKAGE_PATH, package, RESOURCE_OWN_PATH)
    result, shares = parse_share_from_file(file_name, 'target')
    if not result:
        return False

    if target_share in shares:
        return True

    return False


def is_package_using_share(package, target_share):
    result, check_resource_own = is_share_in_resource(package, target_share)

    if not result and check_resource_own:
        result = is_share_in_resource_own(package, target_share)

    return result


def append_section_and_get_cp(file_path):
    try:
        with open(file_path) as file:
            config = StringIO.StringIO()
            config.write('[%s]\n' % DUMMY_SECTION)
            config.write(file.read())
            config.seek(0, os.SEEK_SET)

            cp = ConfigParser.ConfigParser()
            cp.readfp(config)
    except (IOError, ConfigParser.ParsingError):
        return False
    return cp


def get_package_display_name(package):
    info_file = '%s/%s/%s' % (PACKAGE_PATH, package, INFO_PATH)
    info_cp = append_section_and_get_cp(info_file)
    if info_cp:
        try:
            return info_cp.get(DUMMY_SECTION, 'displayname').strip('"')
        except ConfigParser.NoOptionError:
            return package
    return package


if __name__ == "__main__":
    occupied_packages = []
    target_share = sys.argv[1]

    for package in os.walk(PACKAGE_PATH).next()[1]:  # DIRNAMES
        if not is_package_enabled(package):
            continue
        if is_package_using_share(package, target_share):
            occupied_packages.append(get_package_display_name(package))

    if len(occupied_packages) < 1:
        exit(0)
    else:
        print(', '.join(occupied_packages))
        exit(1)