当前位置: 首页>>代码示例>>Python>>正文


Python DaemonConfigParser.getValueFromSection方法代码示例

本文整理汇总了Python中DaemonConfigParser.getValueFromSection方法的典型用法代码示例。如果您正苦于以下问题:Python DaemonConfigParser.getValueFromSection方法的具体用法?Python DaemonConfigParser.getValueFromSection怎么用?Python DaemonConfigParser.getValueFromSection使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在DaemonConfigParser的用法示例。


在下文中一共展示了DaemonConfigParser.getValueFromSection方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。

示例1: slave_conf_copy

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
def slave_conf_copy():
    file_from = DaemonConfigParser(SLAVE_CONF_FILE_FROM);
    file_to   = DaemonConfigParser(SLAVE_CONF_FILE_TO);
    
    #listen
    var = file_from.getValueFromSection('listen', 'port');
    file_to.writeValueFromSection('listen', 'port', var);
    
    #connect
    var = file_from.getValueFromSection('connect', 'port');
    file_to.writeValueFromSection('connect', 'port', var);
    
    #knx
    var = file_from.getValueFromSection('knx', 'port');
    file_to.writeValueFromSection('knx', 'port', var);
    var = file_from.getValueFromSection('knx', 'interface');
    file_to.writeValueFromSection('knx', 'interface', var);
    
    #enocean
    var = file_from.getValueFromSection('enocean', 'port');
    file_to.writeValueFromSection('enocean', 'port', var);
    var = file_from.getValueFromSection('enocean', 'interface');
    file_to.writeValueFromSection('enocean', 'interface', var);
    
    #cron
    var = file_from.getValueFromSection('cron', 'port');
    file_to.writeValueFromSection('cron', 'port', var);
    var = file_from.getValueFromSection('cron', 'address');
    file_to.writeValueFromSection('cron', 'address', var);
    
    #personnal_key
    var = file_from.getValueFromSection('personnal_key', 'aes');
    file_to.writeValueFromSection('personnal_key', 'aes', var);
开发者ID:giorda-a,项目名称:Domoleaf,代码行数:35,代码来源:domoslave_postinst.py

示例2: master_conf_copy

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
def master_conf_copy():
    file_from = DaemonConfigParser(MASTER_CONF_FILE_BKP)
    file_to = DaemonConfigParser(MASTER_CONF_FILE_TO)

    # listen
    var = file_from.getValueFromSection("listen", "port_slave")
    file_to.writeValueFromSection("listen", "port_slave", var)
    var = file_from.getValueFromSection("listen", "port_cmd")
    file_to.writeValueFromSection("listen", "port_cmd", var)

    # connect
    var = file_from.getValueFromSection("connect", "port")
    file_to.writeValueFromSection("connect", "port", var)

    # mysql
    var = file_from.getValueFromSection("mysql", "user")
    file_to.writeValueFromSection("mysql", "user", var)
    var = file_from.getValueFromSection("mysql", "database_name")
    file_to.writeValueFromSection("mysql", "database_name", var)

    # greenleaf
    var = file_from.getValueFromSection("greenleaf", "commercial")
    file_to.writeValueFromSection("greenleaf", "commercial", var)
    var = file_from.getValueFromSection("greenleaf", "admin_addr")
    file_to.writeValueFromSection("greenleaf", "admin_addr", var)
开发者ID:giorda-a,项目名称:Domoleaf,代码行数:27,代码来源:domomaster_postinst.py

示例3: master_conf_copy

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
def master_conf_copy():
    file_from = DaemonConfigParser(MASTER_CONF_FILE_BKP);
    file_to   = DaemonConfigParser(MASTER_CONF_FILE_TO);
    
    #listen
    var = file_from.getValueFromSection('listen', 'port_slave');
    file_to.writeValueFromSection('listen', 'port_slave', var);
    var = file_from.getValueFromSection('listen', 'port_cmd');
    file_to.writeValueFromSection('listen', 'port_cmd', var);
    
    #connect
    var = file_from.getValueFromSection('connect', 'port');
    file_to.writeValueFromSection('connect', 'port', var);
    
    #mysql
    var = file_from.getValueFromSection('mysql', 'user');
    file_to.writeValueFromSection('mysql', 'user', var);
    var = file_from.getValueFromSection('mysql', 'database_name');
    file_to.writeValueFromSection('mysql', 'database_name', var);
    
    #greenleaf
    var = file_from.getValueFromSection('greenleaf', 'commercial');
    file_to.writeValueFromSection('greenleaf', 'commercial', var);
    var = file_from.getValueFromSection('greenleaf', 'admin_addr');
    file_to.writeValueFromSection('greenleaf', 'admin_addr', var);
开发者ID:couturg,项目名称:Domoleaf,代码行数:27,代码来源:domomaster_postinst.py

示例4: send_cron

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
 def send_cron(cron_name):
     try:
         parser = DaemonConfigParser(SLAVE_CONF_FILE);
         port = parser.getValueFromSection('cron', 'port').encode()
         sock = socket.create_connection(('127.0.0.1', port));
         sock.send(bytes(cron_name, 'utf-8'));
         sock.close();
     except Exception as e:
         if 'sock' in locals():
             sock.close()
开发者ID:V-Paranoiaque,项目名称:Domoleaf,代码行数:12,代码来源:GLManager.py

示例5: master_conf_init

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
def master_conf_init():
    file = DaemonConfigParser(SLAVE_CONF_FILE)
    personnal_key = file.getValueFromSection("personnal_key", "aes")
    hostname = socket.gethostname()

    # KNX Interface
    if os.path.exists("/dev/ttyAMA0"):
        knx = "tpuarts"
        knx_interface = "ttyAMA0"
    elif os.path.exists("/dev/ttyS0"):
        knx = "tpuarts"
        knx_interface = "ttyS0"
    else:
        knx = "ipt"
        knx_interface = "127.0.0.1"

    fic = open("/etc/domoleaf/.domoslave.version", "r")
    domoslave = fic.readline()
    fic.close()

    personnal_key = md5(personnal_key.encode("utf-8"))

    query1 = (
        "INSERT INTO daemon (name, serial, secretkey, validation, version) VALUES ('"
        + hostname
        + "','"
        + hostname
        + "','"
        + personnal_key.hexdigest()
        + "',1,'"
        + domoslave.split("\n")[0]
        + "')"
    )
    query2 = (
        "INSERT INTO daemon_protocol (daemon_id, protocol_id, interface, interface_arg) VALUES (1,1,'"
        + knx
        + "','"
        + knx_interface
        + "')"
    )
    Popen(
        ["mysql", "--defaults-file=/etc/mysql/debian.cnf", "domoleaf", "-e", query1],
        stdin=PIPE,
        stdout=PIPE,
        stderr=PIPE,
        bufsize=-1,
    )
    Popen(
        ["mysql", "--defaults-file=/etc/mysql/debian.cnf", "domoleaf", "-e", query2],
        stdin=PIPE,
        stdout=PIPE,
        stderr=PIPE,
        bufsize=-1,
    )
开发者ID:giorda-a,项目名称:Domoleaf,代码行数:56,代码来源:domomaster_postinst.py

示例6: ipVPN

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
 def ipVPN():
     private = InfoSys.ipPrivate();
     parser = DaemonConfigParser(SLAVE_CONF_FILE);
     server = parser.getValueFromSection('openvpn', 'openvpnserver').encode()
     if server.decode() == 'none':
         return '';
     try:
         vpn = ([(s.connect((server, 80)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])
     except Exception as e:
         return ''
     if private != vpn:
         return vpn;
     return '';
开发者ID:V-Paranoiaque,项目名称:Domoleaf,代码行数:15,代码来源:InfoSys.py

示例7: master_conf_init

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
def master_conf_init():
    file = DaemonConfigParser(SLAVE_CONF_FILE);
    personnal_key = file.getValueFromSection('personnal_key', 'aes');
    hostname = socket.gethostname();
    #KNX Interface
    if os.path.exists('/dev/ttyAMA0'):
        knx = "tpuarts"
        knx_interface = 'ttyAMA0';
    elif os.path.exists('/dev/ttyS0'):
        knx = "tpuarts"
        knx_interface = 'ttyS0';
    else:
        knx = "ipt"
        knx_interface = '127.0.0.1';
    domoslave = os.popen("dpkg-query -W -f='${Version}\n' domoslave").read().split('\n')[0];
    query1 = "INSERT INTO daemon (name, serial, secretkey, validation, version) VALUES ('"+hostname+"','"+hostname+"','"+personnal_key+"',1,'"+domoslave+"')"
    query2 = "INSERT INTO daemon_protocol (daemon_id, protocol_id, interface, interface_arg) VALUES (1,1,'"+knx+"','"+knx_interface+"')"
    call(['mysql', '--defaults-file=/etc/mysql/debian.cnf', 'domoleaf',
           '-e', query1]);
    call(['mysql', '--defaults-file=/etc/mysql/debian.cnf', 'domoleaf',
           '-e', query2]);
开发者ID:V-Paranoiaque,项目名称:Domoleaf,代码行数:23,代码来源:domomaster_postinst.py

示例8: __init__

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
class DeviceManager:
    """
    Device management class. Manages the device described with the ID passed at construction.
    """
    def __init__(self, _id_elem = 0, _option_id = 0, _debug = False):
        self.logger = Logger(LOG_FLAG, LOG_FILE);
        self._id = _id_elem;
        self._debug = _debug;
        self._option_id = _option_id;
        self._parser = DaemonConfigParser(CONF_FILENAME);
        self._db_name = self._parser.getValueFromSection(MYSQL_CONF_SECTION, MYSQL_CONF_USER_ENTRY);
        self._db_passwd = self._parser.getValueFromSection(MYSQL_CONF_SECTION, MYSQL_CONF_PASSWORD_ENTRY);
        self._db_dbname = self._parser.getValueFromSection(MYSQL_CONF_SECTION, MYSQL_CONF_DATABASE_ENTRY);
        self.sql = MasterSql();
        
    ###############################################################
    # Va surement revoir cette fonction et remettre le mode debug #
    # suivant les options qu'il va falloir check ou pas           #
    ###############################################################
    def load_from_db(self):
        """
        Returns the device from the database.
        """
        if self._db_name is None:
            self.logger.error("[ DeviceManager ]: Mysql username not found in '" + CONF_FILENAME + "'");
            return None;
        if self._db_passwd is None:
            self.logger.error("[ DeviceManager ]: Mysql password not found in '" + CONF_FILENAME + "'");
            return None;
        if self._db_dbname is None:
            self.logger.error("[ DeviceManager ]: Mysql database name not found in '" + CONF_FILENAME + "'");
            return None;
        
        db = MysqlHandler(self._db_name, self._db_passwd, self._db_dbname);
        res = db.personnal_query(LOAD_DEVICE_QUERY + str(self._id));
        if len(res) == 0:
            res = db.personnal_query(LOAD_DEVICE_QUERY_IP + str(self._id));
        if len(res) == 0:
            self.logger.error('[ DeviceManager ]: Error: No device with id ' + str(self._id) + ' in database.');
            return None;
        elif len(res) > 1:
            self.logger.error('[ DeviceManager ]: Dunno wut to do if more than one item in DB.');
            return None;
        obj = res[0];
        device = {
            KEY_PROTOCOL_ID: obj[0],
            KEY_DEVICE_ID: obj[1],
            KEY_DAEMON_ID: obj[2],
            KEY_ADDR: obj[3],
            KEY_PLUS_1: obj[4],
            KEY_PLUS_2: obj[5],
            KEY_PLUS_3: obj[6],
            KEY_ROOM_DEVICE_ID: self._id
        };
        db.close();
        db = MysqlHandler(self._db_name, self._db_passwd, self._db_dbname);
        query = CHECK_ROOM_DEVICE_OPTIONS + str(device[KEY_PROTOCOL_ID]) + ' WHERE room_device_id = ' + str(self._id);
        res = db.personnal_query(query);
        db.close();
        if len(res) == 0:
            self.logger.error('[ DeviceManager ]: Error: No room_device_option for room_device_id \'' + str(self._id) + '\'');
            device['option_id'] = self._option_id;
            device['function_id'] = 0;
            device['dpt_id'] = 0;
            if device['protocol_id'] != IP_ID:
                db = MysqlHandler(self._db_name, self._db_passwd, self._db_dbname);
                res = db.personnal_query(GET_DAEMON_FROM_ID + str(device['daemon_id']));
                device['daemon_name'] = res[0][2];
                device['daemon_secretkey'] = res[0][3];
            db.close();
            return device;
        device['addr_dst'] = 0;

        for d in res:
            if d[0] == self._option_id:
                device['addr_dst'] = d[1];
                device['function_id'] = d[3];
                device['dpt_id'] = d[2];
                break;
        device['option_id'] = self._option_id;
        if device['protocol_id'] != IP_ID:
            db = MysqlHandler(self._db_name, self._db_passwd, self._db_dbname);
            res = db.personnal_query(GET_DAEMON_FROM_ID + str(device['daemon_id']));
            device['daemon_name'] = res[0][2];
            device['daemon_secretkey'] = res[0][3];
        db.close();
        return device;
开发者ID:giorda-a,项目名称:Domoleaf,代码行数:89,代码来源:DeviceManager.py

示例9: __init__

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
class KNXManager:
    """
    KNX management class
    """
    def __init__(self, slave_keys):
        self.knx_function = {
            OPTION_ON_OFF       : self.send_knx_write_short_to_slave,
            OPTION_VAR          : self.send_knx_write_long_to_slave,
            OPTION_UP_DOWN      : self.send_knx_write_short_to_slave,
            OPTION_OPEN_CLOSE   : self.send_knx_write_short_to_slave,
            OPTION_STOP_UP_DOWN : self.send_knx_write_short_to_slave,
            OPTION_TEMPERATURE_W: self.send_knx_write_temp
        };
        self.sql = MasterSql();
        self._parser = DaemonConfigParser('/etc/greenleaf/master.conf');
        self.aes_slave_keys = slave_keys;

    def update_room_device_option(self, daemon_id, json_obj):
        """
        Update room_device_option table in database to set new values of the device described by 'json_obj'
        """
        if int(json_obj['type']) == KNX_RESPONSE:
            self.sql.update_room_device_option_resp(json_obj, daemon_id);
        elif int(json_obj['type']) == KNX_WRITE_SHORT:
            self.sql.update_room_device_option_write_short(json_obj, daemon_id);
        elif int(json_obj['type']) == KNX_WRITE_LONG:
            self.sql.update_room_device_option_write_long(json_obj, daemon_id);

    def protocol_knx(self, json_obj, dev, hostname):
        """
        KNX protocol data treatment function
        """
        new_obj = {
            "data": {
                "addr": str(dev['addr_dst']),
                "value": str(json_obj['data']['value'])
            }
        };
        self.knx_function[int(json_obj['data']['option_id'])](hostname, new_obj);

    def send_json_obj_to_slave(self, json_str, sock, hostname, aes_key, close_flag = True):
        """
        Send 'json_obj' to 'hostname' via 'sock'
        """
        hostname_key = '';
        if '.' in hostname:
            hostname_key = hostname.split('.')[0];
        else:
            hostname_key = hostname;
        AES.key_size = 32;
        aes_IV = AESManager.get_IV();
        encode_obj = AES.new(aes_key, AES.MODE_CBC, aes_IV);
        data2 = encode_obj.encrypt(json_str + (176 - len(json_str)) * ' ');
        sock.send(bytes(aes_IV, 'utf-8') + data2);
        if close_flag == True:
            sock.close();

    def send_knx_write_temp(self, hostname, json_obj):
        """
        Converts absolute value of temperature (Celsius) in 2 hexadecimal values for
        sending to KNX device
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        val_str = json_obj['data']['value'];
        if '.' in val_str:
            val_str = val_str.split('.')[0];
        value = utils.convert_temperature_reverse(int(val_str));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_temp",
                "addr_to_send": json_obj['data']['addr'],
                "value": value[0] + ' ' + value[1]
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);

    def send_knx_write_long_to_slave(self, hostname, json_obj):
        """
        Constructs long write request and sends it to 'hostname'
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_long",
                "addr_to_send": json_obj['data']['addr'],
                "value": hex(int(json_obj['data']['value']))
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);

    def send_knx_write_short_to_slave(self, hostname, json_obj):
        """
        Constructs short write request and sends it to 'hostname'
        """
#.........这里部分代码省略.........
开发者ID:AdrienCourtois,项目名称:Domoleaf,代码行数:103,代码来源:KNXManager.py

示例10: monitors

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
class SlaveDaemon:
    """
    Main slave class
    It does communication between different monitors (KNX, EnOcean... in C) and the masters (servers)
    """
    def __init__(self, log_flag):
        self.logger = Logger(log_flag, LOG_FILE);
        self.logger.info('Started Domoleaf Slave daemon');
        print('######## SLAVE DAEMON #######')
        self.connected_masters = {};
        self.connected_knx = [];
        self.connected_enocean = [];
        self.connected_cron = [];
        self.clients = [];
        self._scanner = Scanner();
        self._hostlist = [];
        myhostname = socket.gethostname().upper()
        if SLAVE_NAME_PREFIX in myhostname:
            self._scanner.scan();
            self._hostlist = self._scanner._HostList;
        else:
            self._hostlist.append(Host('', '127.0.0.1', myhostname));
        self._parser = DaemonConfigParser(SLAVE_CONF_FILE);
        self.encrypt_keys = {};
        self.knx_sock = None;
        self.master_sock = None;
        self.enocean_sock = None;
        self.cron_sock = None;
        self.private_aes = self._parser.getValueFromSection('personnal_key', 'aes');
        self.wifi_init(self._parser.getValueFromSection('wifi', 'ssid'), self._parser.getValueFromSection('wifi', 'password'), self._parser.getValueFromSection('wifi', 'encryption'), self._parser.getValueFromSection('wifi', 'mode'), 0);
        self.connect_port = self._parser.getValueFromSection(SLAVE_CONF_CONNECT_SECTION, SLAVE_CONF_CONNECT_PORT_ENTRY);
        self.functions = {
            KNX_READ_REQUEST    : self.knx_read_request,
            KNX_WRITE_SHORT     : self.knx_write_short,
            KNX_WRITE_LONG      : self.knx_write_long,
            KNX_WRITE_TEMP      : self.knx_write_temp,
            CHECK_SLAVE         : self.check_slave,
            MONITOR_IP          : self.monitor_ip,
            DATA_UPDATE         : self.update,
            SEND_TECH           : self.send_tech,
            SEND_ALIVE          : self.send_alive,
            SEND_INTERFACES     : self.send_interfaces,
            SHUTDOWN_D3         : self.shutdown_d3,
            REBOOT_D3           : self.reboot_d3,
            WIFI_UPDATE         : self.wifi_update
        };

    def update(self, json_obj, connection):
        p = call(['dpkg', '--configure', '-a'])
        call(['apt-get', 'update']);
        call(['DEBIAN_FRONTEND=noninteractive', 'apt-get', 'install', 'domoslave', '-y']);
        version = os.popen("dpkg-query -W -f='${Version}\n' domoslave").read().split('\n')[0];
        json_str = '{"packet_type": "update_finished", "aes_pass": "' + self.private_aes + '", "new_version": ' + version + '}';
        encrypt_IV = AESManager.get_IV();
        spaces = 16 - len(json_str) % 16;
        json_str = json_str + (spaces * ' ');
        encode_obj = AES.new(self.private_aes, AES.MODE_CBC, encrypt_IV);
        data = encode_obj.encrypt(json_str);
        # faut ouvrir une nouvelle socket pour envoyer la nouvelle version
        # connection.send(bytes(encrypt_IV, 'utf-8') + data);

    def run(self):
        """
        Initialization of the sockets for listenning incomming connections.
        Calls the loop function.
        """
        self.run = True;
        self.knx_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.master_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.enocean_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.cron_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.knx_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1);
        self.master_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1);
        self.enocean_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1);
        self.cron_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1);
        port = self._parser.getValueFromSection(SLAVE_CONF_KNX_SECTION, SLAVE_CONF_KNX_PORT_ENTRY);
        if not port:
            sys.exit(2);
        port_master = self._parser.getValueFromSection(SLAVE_CONF_LISTEN_SECTION, SLAVE_CONF_LISTEN_PORT_ENTRY);
        if not port_master:
            sys.exit(2);
        port_enocean = self._parser.getValueFromSection(SLAVE_CONF_ENOCEAN_SECTION, SLAVE_CONF_ENOCEAN_PORT_ENTRY);
        if not port_enocean:
            sys.exit(2);
        port_cron = self._parser.getValueFromSection(SLAVE_CONF_CRON_SECTION, SLAVE_CONF_CRON_PORT_ENTRY);
        if not port_cron:
            sys.exit(2);
        self.knx_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        self.master_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        self.enocean_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        self.cron_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        self.knx_sock.bind(('', int(port)));
        self.master_sock.bind(('', int(port_master)));
        self.enocean_sock.bind(('', int(port_enocean)));
        self.cron_sock.bind(('127.0.0.1', int(port_cron)));
        self.knx_sock.listen(MAX_KNX);
        self.master_sock.listen(MAX_MASTERS);
        self.enocean_sock.listen(MAX_ENOCEAN);
        self.cron_sock.listen(MAX_CRON);
        self.send_monitor_ip()
#.........这里部分代码省略.........
开发者ID:Fuere,项目名称:Domoleaf,代码行数:103,代码来源:SlaveDaemon.py

示例11: __init__

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
class MasterDaemon:
    """
    Main class of the master daemon
    It provides communication between master and slave boxes and a part of the database management
    """
    def __init__(self, log_flag):
        self.logger = Logger(log_flag, LOG_FILE);
        self.logger.info('Started Greenleaf Master Daemon');
        self.d3config = {};
        self.aes_slave_keys = {};
        self.aes_master_key = None;
        self.connected_clients = {};
        self.sql = MasterSql();
        self._parser = DaemonConfigParser(MASTER_CONF_FILE);
        self.get_aes_slave_keys();
        self.reload_camera(None, None);
        self.scanner = Scanner(HOSTS_CONF);
        self.scanner.scan(False);
        self.hostlist = self.scanner._HostList;
        self.sql.insert_hostlist_in_db(self.scanner._HostList);
        self.knx_manager = KNXManager(self.aes_slave_keys);
        self.reload_d3config(None, None);
        self.protocol_function = {
            PROTOCOL_KNX        : KNXManager.protocol_knx,
            PROTOCOL_ENOCEAN    : self.protocol_enocean,
            PROTOCOL_IP         : self.protocol_ip
        };
        self.upnp_function = {
            UPNP_PLAY           : self.upnp_set_play,
            UPNP_PAUSE          : self.upnp_set_pause,
            UPNP_NEXT           : self.upnp_set_next,
            UPNP_PREVIOUS       : self.upnp_set_prev,
            UPNP_STOP           : self.upnp_set_stop,
            UPNP_VOLUME_UP      : self.upnp_set_volume_up,
            UPNP_VOLUME_DOWN    : self.upnp_set_volume_down,
            UPNP_SET_VOLUME     : self.upnp_set_volume
        };
        self.enocean_function = {};
        self.data_function = {
            DATA_MONITOR_KNX            	  : self.monitor_knx,
            DATA_MONITOR_IP             	  : self.monitor_ip,
            DATA_MONITOR_ENOCEAN        	  : self.monitor_enocean,
            DATA_MONITOR_BLUETOOTH      	  : self.monitor_bluetooth,
            DATA_KNX_READ               	  : self.knx_read,
            DATA_KNX_WRITE_S            	  : self.knx_write_short,
            DATA_KNX_WRITE_L            	  : self.knx_write_long,
            DATA_SEND_TO_DEVICE         	  : self.send_to_device,
            DATA_CRON_UPNP             		  : self.cron_upnp,
            DATA_SEND_MAIL              	  : self.send_mail,
            DATA_CHECK_SLAVE            	  : self.check_slave,
            DATA_RELOAD_CAMERA          	  : self.reload_camera,
            DATA_RELOAD_D3CONFIG        	  : self.reload_d3config,
            DATA_BACKUP_DB_CREATE_LOCAL       : self.backup_db_create_local,
            DATA_BACKUP_DB_REMOVE_LOCAL       : self.backup_db_remove_local,
            DATA_BACKUP_DB_LIST_LOCAL         : self.backup_db_list_local,
            DATA_BACKUP_DB_RESTORE_LOCAL      : self.backup_db_restore_local,
            DATA_UPDATE                 	  : self.update
        };

    def get_aes_slave_keys(self):
        """
        Get the secretkeys of each slave daemon stored in database
        """
        query = "SELECT serial, secretkey FROM daemon";
        res = self.sql.mysql_handler_personnal_query(query);
        self_hostname = socket.gethostname();
        for r in res:
            if SLAVE_NAME_PREFIX in r[0] or 'MD3' in r[0]:
                self.aes_slave_keys[r[0]] = r[1];
            elif self_hostname == r[0]:
                self.aes_slave_keys[r[0]] = r[1];
                self.aes_master_key = r[1];
        print(self.aes_slave_keys)

    def stop(self):
        """
        Stops the daemon and closes sockets
        """
        flag = False;
        while not flag:
            flag = True;
            for client in self.connected_clients.values():
                flag = False;
                client.close();
                break;
        self.slave_connection.close();
        sys.exit(0);

    def run(self):
        """
        Initialization of the connections and accepting incomming communications
        """
        self.slave_connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.cmd_connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.slave_connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        self.cmd_connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        s_port = self._parser.getValueFromSection(MASTER_CONF_LISTEN_SECTION, MASTER_CONF_LISTEN_PORT_SLAVE_ENTRY);
        c_port = self._parser.getValueFromSection(MASTER_CONF_LISTEN_SECTION, MASTER_CONF_LISTEN_PORT_CMD_ENTRY);
        if not s_port:
            frameinfo = getframeinfo(currentframe());
#.........这里部分代码省略.........
开发者ID:AdrienCourtois,项目名称:Domoleaf,代码行数:103,代码来源:MasterDaemon.py

示例12: __init__

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
class KNXManager:

    ## The constructor.
    #
    # @param slave_keys Array containing the AES keys of all the slaves.
    # @return None
    def __init__(self, slave_keys):
        ## Logger object for formatting and printing logs
        self.logger = Logger(DEBUG_MODE, LOG_FILE);
        ## SQL object for managing database
        self.sql = MasterSql();
        self._parser = DaemonConfigParser('/etc/domoleaf/master.conf');
        ## Object containing AES keys for encrypted communications
        self.aes_slave_keys = slave_keys;

    ## Updates room_device_option table in database to set new values of the device described by json_obj.
    #
    # @param daemon_id The ID of a slave daemon.
    # @param json_obj JSON object containing the values to update.
    # @param db The database handler.
    #
    # @return The result of the query.
    def update_room_device_option(self, daemon_id, json_obj, db):
        if int(json_obj['type']) == KNX_RESPONSE:
            return self.sql.update_room_device_option_resp(json_obj, daemon_id, db);
        elif int(json_obj['type']) == KNX_WRITE_SHORT:
            return self.sql.update_room_device_option_write_short(json_obj, daemon_id, db);
        elif int(json_obj['type']) == KNX_WRITE_LONG:
            return self.sql.update_room_device_option_write_long(json_obj, daemon_id, db);

    ## Sends a JSON object to a slave daemon.
    #
    # @param json_str The data to send.
    # @param sock The socket used to send the data.
    # @param hostname The hostname of the slave daemon.
    # @param aes_key The AES key of the slave daemon to encrypt data.
    # @return None
    def send_json_obj_to_slave(self, json_str, sock, hostname, aes_key):
        hostname_key = '';
        if '.' in hostname:
            hostname_key = hostname.split('.')[0];
        else:
            hostname_key = hostname;
        AES.key_size = 32;
        aes_IV = AESManager.get_IV();
        encode_obj = AES.new(aes_key, AES.MODE_CBC, aes_IV);
        spaces = 16 - len(json_str) % 16;
        data2 = encode_obj.encrypt(json_str + (spaces * ' '));
        sock.send(bytes(aes_IV, 'utf-8') + data2);

    ## Changes the speed value of a fan.
    #
    # @param json_obj JSON object containing the values to write.
    # @param dev Object containing informations about the device.
    # @param hostname The hostname of the slave to who send the packet.
    # @return None
    def send_knx_write_speed_fan(self, json_obj, dev, hostname):
        port = self._parser.getValueFromSection('connect', 'port');
        sock = socket.create_connection((hostname, port));
        if not port:
            sys.exit(4);
        if json_obj['data']['value'] == '1':
            query = ''.join(['SELECT option_id, addr, dpt_id FROM room_device_option WHERE room_device_id=',
                           str(dev['room_device_id']),
                           ' AND option_id IN(400, 401, 402, 403, 404, 405, 406) AND status=1']);
            res = self.sql.mysql_handler_personnal_query(query);
            for line in res:
                if str(line[2]) == "51" and str(line[0]) == str(json_obj['data']['option_id']):
                    val = str(line[0]).split('40')[1];
                    json_str = json.JSONEncoder().encode(
                        {
                            "packet_type": "knx_write_long",
                            "addr_to_send": line[1],
                            "value": val
                        }
                    );
                    self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
                    return;
                elif str(line[2]) == "2" and str(line[0]) != str(json_obj['data']['option_id']):
                    json_str = json.JSONEncoder().encode(
                        {
                            "packet_type": "knx_write_short",
                            "addr_to_send": line[1],
                            "value": "0"
                        }
                    );
                    self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_short",
                "addr_to_send": str(dev['addr_dst']),
                "value": json_obj['data']['value']
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        sock.close();

    ## Converts absolute value of temperature (Celsius) in 2 hexadecimal values for sending to KNX device.
    #
    # @param json_obj JSON object containing the values to write.
#.........这里部分代码省略.........
开发者ID:V-Paranoiaque,项目名称:Domoleaf,代码行数:103,代码来源:KNXManager.py

示例13: __init__

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
class SlaveDaemon:

    ## The constructor
    #
    # @param log_flag The flag saying whether the logs should be printing or not
    def __init__(self, log_flag):
        ## Logger object for formatting and printing logs
        self.logger = Logger(log_flag, LOG_FILE)
        self.logger.info("Started Domoleaf Slave daemon")
        ## Array of master daemon on local network
        self.connected_masters = {}
        ## Array of monitor KNX on local network
        self.connected_knx = []
        ## Array of monitor EnOcean on local network
        self.connected_enocean = []
        ## Array of cron running on the system
        self.connected_cron = []
        self._scanner = Scanner(log_flag)
        self._hostlist = []
        myhostname = socket.gethostname().upper()
        if SLAVE_NAME_PREFIX in myhostname:
            self._scanner.scan()
            self._hostlist = self._scanner._HostList
        else:
            self._hostlist.append(Host("", "127.0.0.1", myhostname))
        self._parser = DaemonConfigParser(SLAVE_CONF_FILE)
        ## Keys for encrypting communications
        self.encrypt_keys = {}
        ## Main socket for communication with KNX daemon
        self.knx_sock = None
        ## Main socket for communication with master daemon
        self.master_sock = None
        ## Main socket for communication with enocean daemon
        self.enocean_sock = None
        ## Main socket for communication with cron
        self.cron_sock = None
        ## Private AES key got from configuration file
        self.private_aes = self._parser.getValueFromSection("personnal_key", "aes")
        self.wifi_init(
            self._parser.getValueFromSection("wifi", "ssid"),
            self._parser.getValueFromSection("wifi", "password"),
            self._parser.getValueFromSection("wifi", "encryption"),
            self._parser.getValueFromSection("wifi", "mode"),
            0,
        )
        ## Port on which connect got from configuration file
        self.connect_port = self._parser.getValueFromSection(SLAVE_CONF_CONNECT_SECTION, SLAVE_CONF_CONNECT_PORT_ENTRY)
        ## Callback array indexed on packet type
        self.functions = {
            KNX_READ_REQUEST: self.knx_read_request,
            KNX_WRITE_SHORT: self.knx_write_short,
            KNX_WRITE_LONG: self.knx_write_long,
            KNX_WRITE_TEMP: self.knx_write_temp,
            CHECK_SLAVE: self.check_slave,
            MONITOR_IP: self.monitor_ip,
            DATA_UPDATE: self.update,
            SEND_TECH: self.send_tech,
            SEND_ALIVE: self.send_alive,
            SEND_INTERFACES: self.send_interfaces,
            SHUTDOWN_D3: self.shutdown_d3,
            REBOOT_D3: self.reboot_d3,
            WIFI_UPDATE: self.wifi_update,
        }

    ## Updates the base system of the slave daemon.
    #
    # @param json_obj Not used here.
    # @param connection Not used here.
    # @return None
    def update(self, json_obj, connection):
        p = call(["dpkg", "--configure", "-a"])
        call(["apt-get", "update"])
        call(["DEBIAN_FRONTEND=noninteractive", "apt-get", "install", "domoslave", "-y"])
        version = os.popen("dpkg-query -W -f='${Version}\n' domoslave").read().split("\n")[0]
        json_str = (
            '{"packet_type": "update_finished", "aes_pass": "' + self.private_aes + '", "new_version": ' + version + "}"
        )
        encrypt_IV = AESManager.get_IV()
        spaces = 16 - len(json_str) % 16
        json_str = json_str + (spaces * " ")
        encode_obj = AES.new(self.private_aes, AES.MODE_CBC, encrypt_IV)
        data = encode_obj.encrypt(json_str)
        # faut ouvrir une nouvelle socket pour envoyer la nouvelle version
        # connection.send(bytes(encrypt_IV, 'utf-8') + data);

    ## Initializes the sockets for listenning incomming connections.
    #
    # @return None
    def run(self):
        ## Run flag at True for running, at False to stop the main loop
        self.run = True
        self.knx_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.master_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.enocean_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.cron_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.knx_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        self.master_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        self.enocean_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        self.cron_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        port = self._parser.getValueFromSection(SLAVE_CONF_KNX_SECTION, SLAVE_CONF_KNX_PORT_ENTRY)
#.........这里部分代码省略.........
开发者ID:V-Paranoiaque,项目名称:Domoleaf,代码行数:103,代码来源:SlaveDaemon.py

示例14: __init__

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
class MasterSql:

    ## The constructor
    #
    # @param log_flag Flag saying if the logs are active or not.
    def __init__(self, log_flag = False):
        ## Logger object for formatting and printing logs
        self.logger = Logger(log_flag, LOG_FILE);
        self._parser = DaemonConfigParser(MASTER_CONF_FILE);
        ## Username for the database, searched in configuration file
        self.db_username = self._parser.getValueFromSection(MASTER_CONF_MYSQL_SECTION,
                                                            MASTER_CONF_MYSQL_USER_ENTRY);
        ## Password for the database, searched in configuration file
        self.db_passwd = self._parser.getValueFromSection(MASTER_CONF_MYSQL_SECTION,
                                                          MASTER_CONF_MYSQL_PASSWORD_ENTRY);
        ## Database name for the database, searched in configuration file
        self.db_dbname = self._parser.getValueFromSection(MASTER_CONF_MYSQL_SECTION,
                                                          MASTER_CONF_MYSQL_DB_NAME_ENTRY);
        if not self.db_username or not self.db_passwd or not self.db_dbname:
            frameinfo = getframeinfo(currentframe());
            self.logger.debug("[ MASTER DAEMON "+frameinfo.filaname+":"+str(frameinfo.lineno)+" ]: initialization error: wrong or missing SQL configuration.");
            sys.exit(1);
        ## Function array with option ID
        self.functions_transform = {
              0: utils.convert_none,
              1: utils.convert_temperature,
              2: utils.convert_hundred,
              3: utils.convert_float32
        };

    ## Updates the table containing the hosts.
    # Inserts each host in "hostlist".
    #
    # @param hostlist The list of all the hosts connected on the local network.
    # @param db The database handler used for queries.
    # @return None
    def insert_hostlist_in_db(self, hostlist, db):
        for host in hostlist:
            db.update_datas_in_table('ip_monitor',
                                     {"mac_addr": host._MacAddr},
                                     {"last_update": str(time.time()).split('.')[0],
                                      "ip_addr": host._IpAddr,
                                      "hostname": host._Hostname.split('.')[0]});
        db.personnal_query("DELETE FROM ip_monitor WHERE last_update<"+str(time.time()-7200).split('.')[0]);
        db.updatedb();
        query = ''.join(["UPDATE room_device JOIN ip_monitor ON plus4=mac_addr SET addr=ip_addr WHERE protocol_id=6 AND plus4 != '' AND ip_addr != addr"]);
        self.mysql_handler_personnal_query(query, db);
        db.updatedb();

    ## Updates the enocean log table.
    #
    # @param json_obj JSON object containing the values to update.
    # @param db The database handler used for queries.
    #
    # @return The daemon_id.
    def update_enocean_log(self, json_obj, db):
        daemon_id = 0;
        daemons = db.get_datas_from_table_with_names('daemon', ['daemon_id', 'name', 'serial', 'secretkey']);
        for d in daemons:
            if json_obj['sender_name'] == d[2]:
                daemon_id = d[0];
                break;
        db.insert_datas_in_table('enocean_log',
                                 ['type', 'addr_src', 'addr_dest', 'eo_value', 't_date', 'daemon_id'],
                                 (json_obj['type'], json_obj['src_addr'], json_obj['dst_addr'],
                                  json_obj['value'], json_obj['date'], daemon_id));
        db.updatedb();
        return daemon_id;

    ## Updates the KNX log table.
    #
    # @param json_obj JSON object containing the values to update.
    # @param db The database handler used for queries.
    #
    # @return The daemon_id.
    def update_knx_log(self, json_obj, db):
        daemon_id = 0;
        daemons = db.get_datas_from_table_with_names('daemon', ['daemon_id', 'name', 'serial', 'secretkey']);
        for d in daemons:
            if json_obj['sender_name'] == d[2]:
                daemon_id = d[0];
                break;
        db.insert_datas_in_table('knx_log', ["type", "addr_src", "addr_dest", "knx_value", "t_date", "daemon_id"],
                                 (json_obj['type'], json_obj['src_addr'], json_obj['dst_addr'], json_obj['value'],
                                  json_obj['date'],
                                  daemon_id));
        db.updatedb();
        return daemon_id;

    ## Updates the table room_device_option with long KNX values.
    #
    # @param json_obj JSON object containing some data such as values, addr...
    # @param daemon_id The ID of the slave daemon to who send the packet.
    # @param db The database handler used for queries.
    #
    # @return The result of the query.
    def update_room_device_option_write_long(self, json_obj, daemon_id, db):
        query  = ''.join(["SELECT room_device_option.option_id, room_device.room_device_id, function_answer, dpt_optiondef.dpt_id FROM room_device_option JOIN room_device ON room_device_option.room_device_id=room_device.room_device_id JOIN dpt_optiondef ON dpt_optiondef.option_id=room_device_option.option_id AND dpt_optiondef.protocol_id=room_device.protocol_id AND dpt_optiondef.dpt_id=room_device_option.dpt_id WHERE daemon_id=",
                  str(daemon_id), " AND room_device_option.addr=\"", str(json_obj['dst_addr']), "\""]);
        res = self.mysql_handler_personnal_query(query, db);
#.........这里部分代码省略.........
开发者ID:V-Paranoiaque,项目名称:Domoleaf,代码行数:103,代码来源:MasterSql.py

示例15: __init__

# 需要导入模块: import DaemonConfigParser [as 别名]
# 或者: from DaemonConfigParser import getValueFromSection [as 别名]
class MasterSql:
    """
    Master daemon SQL management class.
    """
    def __init__(self, log_flag = True):
        self.logger = Logger(log_flag, '/var/log/domomaster.log');
        self._parser = DaemonConfigParser(MASTER_CONF_FILE);
        self.db_username = self._parser.getValueFromSection(MASTER_CONF_MYSQL_SECTION,
                                                            MASTER_CONF_MYSQL_USER_ENTRY);
        self.db_passwd = self._parser.getValueFromSection(MASTER_CONF_MYSQL_SECTION,
                                                          MASTER_CONF_MYSQL_PASSWORD_ENTRY);
        self.db_dbname = self._parser.getValueFromSection(MASTER_CONF_MYSQL_SECTION,
                                                          MASTER_CONF_MYSQL_DB_NAME_ENTRY);
        if not self.db_username or not self.db_passwd or not self.db_dbname:
            frameinfo = getframeinfo(currentframe());
            self.logger.info("[ MASTER DAEMON " + frameinfo.filaname + ":" + str(frameinfo.lineno) + " ]: initialization error: wrong or missing SQL configuration.");
            sys.exit(1);

    def insert_hostlist_in_db(self, hostlist):
        """
        Update of the table containing the hosts. Inserts each host in 'hostlist'.
        """
        db = MysqlHandler(self.db_username, self.db_passwd, self.db_dbname);
        for host in hostlist:
            db.update_datas_in_table('ip_monitor',
                                     {"mac_addr": host._MacAddr},
                                     {"last_update": str(time.time()).split('.')[0],
                                      "ip_addr": host._IpAddr,
                                      "hostname": host._Hostname.split('.')[0]});
        db.personnal_query("DELETE FROM ip_monitor WHERE last_update<"+str(time.time()-7200).split('.')[0]);
        
        db.updatedb();

        query =  "UPDATE room_device ";
        query += "JOIN ip_monitor ON plus4=mac_addr ";
        query += "SET addr=ip_addr ";
        query += "WHERE protocol_id=6 AND plus4 != '' AND ip_addr != addr";
        self.mysql_handler_personnal_query(query);
        
        db.updatedb();
        
        db.close();

    def update_enocean_log(self, json_obj):
        """
        Update of the enocean log table with values from 'json_obj'
        """
        daemon_id = 0;
        db = MysqlHandler(self.db_username, self.db_passwd, self.db_dbname);
        daemons = db.get_datas_from_table_with_names('daemon', ['daemon_id', 'name', 'serial', 'secretkey']);
        for d in daemons:
            if json_obj['sender_name'] == d[2]:
                daemon_id = d[0];
                break;
        db.insert_datas_in_table('enocean_log',
                                 ['type', 'addr_src', 'addr_dest', 'eo_value', 't_date', 'daemon_id'],
                                 (json_obj['type'], json_obj['src_addr'], json_obj['dst_addr'],
                                  json_obj['value'], json_obj['date'], daemon_id));
        db.updatedb();
        db.close();
        return daemon_id;

    def update_knx_log(self, json_obj):
        """
        Update of the knx log table with values from 'json_obj'
        """
        daemon_id = 0;
        db = MysqlHandler(self.db_username, self.db_passwd, self.db_dbname);
        daemons = db.get_datas_from_table_with_names('daemon', ['daemon_id', 'name', 'serial', 'secretkey']);
        for d in daemons:
            if json_obj['sender_name'] == d[2]:
                daemon_id = d[0];
                break;

        db.insert_datas_in_table('knx_log', ["type", "addr_src", "addr_dest", "knx_value", "t_date", "daemon_id"],
                                 (json_obj['type'], json_obj['src_addr'], json_obj['dst_addr'], json_obj['value'],
                                  json_obj['date'],
                                  daemon_id));
        db.updatedb();
        db.close();
        return daemon_id;

    def update_room_device_option_write_long(self, json_obj, daemon_id):
        """
        Update of the table room_device_option with long KNX value
        """
        query = "SELECT option_id, room_device.room_device_id, addr_plus FROM room_device_option ";
        query += "JOIN room_device ON room_device_option.room_device_id=room_device.room_device_id ";
        query += "WHERE daemon_id=" + str(daemon_id) + " AND room_device_option.addr=\"";
        query += str(json_obj['dst_addr']) + "\"";
        res = self.mysql_handler_personnal_query(query);
        
        if len(res) == 0:
            query = "SELECT option_id, room_device.room_device_id FROM ";
            query += "room_device_option JOIN room_device ON ";
            query += "room_device_option.room_device_id=room_device.room_device_id WHERE ";
            query += "daemon_id=" + str(daemon_id) + " AND room_device_option.addr_plus=\"";
            query += str(json_obj['dst_addr']) + "\"";
            res = self.mysql_handler_personnal_query(query);
        
#.........这里部分代码省略.........
开发者ID:giorda-a,项目名称:Domoleaf,代码行数:103,代码来源:MasterSql.py


注:本文中的DaemonConfigParser.getValueFromSection方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。