New upstream version 2.5.1.0
This commit is contained in:
parent
3f8b2fc8c6
commit
790afc635f
|
@ -0,0 +1,327 @@
|
|||
libkysdk-base (2.5.1.0-0k0.8) nile; urgency=medium
|
||||
|
||||
* BUG:无
|
||||
* 需求号:无
|
||||
* 其他改动说明:
|
||||
1. 配置组新增permission,description,summary属性
|
||||
2. permission权限新增final,stable
|
||||
3. conf2与gsettings联动,联动后gsettings设置的同步到conf2,反向同理
|
||||
4. 原本已经做了设置的应用,升级到接入conf2后,原本的设置保留
|
||||
5. 新增trigger,应用装包,目录下出现新的配置文件,自动执行reload
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Mon, 20 May 2024 15:18:53 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k1.7) nile; urgency=medium
|
||||
|
||||
* BUG:#222596 【dbus】libkysdk-base com.kylin.kysdk.conf2系统总线服务级和方法级整改
|
||||
* 需求号:无
|
||||
* 其他改动说明:1. 修复服务级管控无法读取到白名单问题
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Fri, 17 May 2024 17:59:57 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k1.6) nile; urgency=medium
|
||||
|
||||
* BUG:
|
||||
#222596 【dbus】libkysdk-base com.kylin.kysdk.conf2系统总线服务级和方法级整改
|
||||
#227605 【华为云】【guesetos】【控制面板】控制面板缺少电源模块
|
||||
#227626 【需求26164】【华为云】【guestos】【真机】会话管理器显示/隐藏电源操作-组件自身配置
|
||||
* 需求号:无
|
||||
* 其他改动说明:无
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Fri, 17 May 2024 09:32:19 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k1.5) nile; urgency=medium
|
||||
|
||||
* BUG:无
|
||||
* 需求号:无
|
||||
* 其他改动说明:
|
||||
1. 修复xml2yaml工具生成时枚举缩进位置不对的问题
|
||||
2. 修复读数据库到内存(db2dict)的逻辑
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Wed, 15 May 2024 15:34:45 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k1.4) nile; urgency=medium
|
||||
|
||||
* BUG:
|
||||
#226776 【conf2】新增对同目录里有相同的配置项的处理中点击下载按钮选择新建文件夹时,终端报错核心已转储
|
||||
#226686 【conf2】调整目录优先级执行报错 [用例#909448]
|
||||
* 需求号:无
|
||||
* 其他改动说明:
|
||||
1. 更新gschema.xml转yaml工具
|
||||
2. 增加部分日志
|
||||
3. 修复服务管控中,非白名单应用调用dbus接口时虽然报错但接口仍然被调用的问题
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Thu, 09 May 2024 10:44:27 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k1.3) nile; urgency=medium
|
||||
|
||||
* BUG:#222596 【dbus】libkysdk-base com.kylin.kysdk.conf2系统总线服务级和方法级整改
|
||||
* 需求号:无
|
||||
* 其他改动说明:
|
||||
1. 修改pc文件中的版本号
|
||||
2. 修改session服务启动时kylin-config目录不存在会报错的问题
|
||||
3. 修改kdk_conf2_set_string会多一对单引号的问题
|
||||
4. conf2服务生成统一视图时增加处理final和stable属性,组增加属性
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Tue, 07 May 2024 14:53:36 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k1.2) nile; urgency=medium
|
||||
|
||||
* BUG:无
|
||||
* 需求号:无
|
||||
* 其他改动说明:修改control文件依赖
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- shaozhimin <shaozhimin@kylinos.cn> Fri, 26 Apr 2024 15:44:33 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k1.1) nile; urgency=medium
|
||||
|
||||
* BUG:无
|
||||
* 需求号:无
|
||||
* 其他改动说明:修改数据库表结构
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Thu, 25 Apr 2024 14:21:27 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k1.0) nile; urgency=medium
|
||||
|
||||
* BUG:无
|
||||
* 需求号:
|
||||
#28841 调整目录优先级
|
||||
#28842 新增对同目录相同项的处理
|
||||
* 其他改动说明:
|
||||
1. 新增兼容并发读写功能
|
||||
2. 新增工具类包libkysdk-conf2-tools,工具不在集成在libkysdk-conf2包里
|
||||
3. 新增日志记录功能
|
||||
4. 配置文件里去掉children和keys关键字
|
||||
5. 所有固定关键字前面加下划线统一格式
|
||||
6. 取消common目录,通用配置存放位置可以除basic以外的所有目录
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- tianshaoshuai <tianshaoshuai@kylinos.cn> Fri, 19 Apr 2024 14:43:46 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k0.2) nile; urgency=medium
|
||||
|
||||
* BUG:无
|
||||
* 需求号:无
|
||||
* 其他改动说明:整机导入合入bug#221702 【CPM20240409009145】 【PanguX-5.6.0.17 + BIOS 1.01】【HW】【系统功能】【Freetest】系统监视器下物理内存使用量显示不正确,已用内存比物理内存总量还大(2/2 DUTs)。(一般+必现+常用功能)修复
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Mon, 15 Apr 2024 16:03:10 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k0.1) nile; urgency=medium
|
||||
|
||||
* BUG:无
|
||||
* 需求号:无
|
||||
* 其他改动说明:更新 diagnostics symbols文件
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Mon, 01 Apr 2024 18:13:31 +0800
|
||||
|
||||
libkysdk-base (2.4.1.0-0k0.0) nile; urgency=medium
|
||||
|
||||
* BUG:无
|
||||
* 需求号:#26164 华为云桌面默认关闭接口在HWS及HCSO做一个开启关闭休眠接口开关需求
|
||||
* 其他改动说明:任务#203739:需求26164的conf2适配内容同步2403u1版本 / 迁移华为云桌面192292 sdk提供conf2机制,支持睡眠、休眠、切换用户、关机可配置
|
||||
* 其他改动影响域:无
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Wed, 27 Mar 2024 09:03:47 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.14) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 添加symbols文件
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Wed, 27 Dec 2023 09:10:05 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.13) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 移除CMake对老旧C++的绑定
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Wed, 20 Dec 2023 16:30:33 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.12) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 修复已知的conf2模块导致的崩溃问题,上传可视化工具
|
||||
|
||||
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Tue, 12 Dec 2023 16:46:35 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.11) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 恢复diagnostics 模块内容
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Tue, 12 Dec 2023 14:50:30 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.10) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : conf2模块创建用户配置目录时所有者为root的问题处理
|
||||
|
||||
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Mon, 04 Dec 2023 17:24:42 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.9) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 修改conf2模块pc文件中的Requires
|
||||
|
||||
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Fri, 01 Dec 2023 14:15:59 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.8) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 修改conf2模块pc文件
|
||||
|
||||
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Fri, 01 Dec 2023 10:35:17 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.7) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 修改conf2模块pc文件
|
||||
|
||||
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Fri, 01 Dec 2023 09:12:19 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.6) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 :修复conf2模块的部分问题
|
||||
|
||||
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Thu, 30 Nov 2023 14:11:14 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.5) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 :修改pc文件和动态库版本
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Tue, 28 Nov 2023 16:52:06 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.4) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 上传libkysdk-conf2
|
||||
|
||||
-- tian-shaoshuai <tianshaoshuai@kylinos.cn> Mon, 27 Nov 2023 15:26:44 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.2) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 :解决i386动态库路径与加载路径不一致问题
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Mon, 20 Nov 2023 09:39:22 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.1) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 改动态库路径到对应的架构下
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Fri, 20 Oct 2023 09:59:39 +0800
|
||||
|
||||
libkysdk-base (2.3.0.0-0k0.0) nile; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 23985 SDK文档完善
|
||||
* 其他修改 : 无
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Fri, 20 Oct 2023 09:59:39 +0800
|
||||
|
||||
libkysdk-base (2.2.0.0-0k0.4) yangtze; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 注释掉log模块的日志转储部分
|
||||
解决安全扫描漏洞
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Thu, 19 Oct 2023 17:18:40 +0800
|
||||
|
||||
libkysdk-base (2.2.0.0-0k0.3) yangtze; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 添加 diagnostics 模块
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Mon, 28 Aug 2023 09:59:47 +0800
|
||||
|
||||
libkysdk-base (2.2.0.0-0k0.2) yangtze; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 去掉control文件中的libkysdk-diagnostics依赖
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Fri, 04 Aug 2023 10:45:16 +0800
|
||||
|
||||
libkysdk-base (2.2.0.0-0k0.1) yangtze; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 删除shlibs自动补全依赖
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Thu, 13 Jul 2023 14:25:27 +0800
|
||||
|
||||
libkysdk-base (2.2.0.0-0k0.0) yangtze; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : update changelog 2.2
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Wed, 21 Jun 2023 10:03:19 +0800
|
||||
|
||||
libkysdk-base (2.0.0.0-0k0.6) yangtze; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 : 修改control文件依赖版本
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Tue, 20 Jun 2023 19:51:55 +0800
|
||||
|
||||
libkysdk-base (2.0.0.0-0k0.5) yangtze; urgency=medium
|
||||
|
||||
* BUG号 : 无
|
||||
* 需求号 : 无
|
||||
* 其他修改 :
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Tue, 06 Jun 2023 15:30:08 +0800
|
||||
|
||||
libkysdk-base (1.2.0.5kylin1-ok1~0715) yangtze; urgency=medium
|
||||
|
||||
* 合并主线v1.2
|
||||
* update v1.2
|
||||
|
||||
-- szm-min <shaozhimin@kylinos.cn> Fri, 15 Jul 2022 10:32:27 +0800
|
||||
|
||||
libkysdk-base (1.1.1kylin1-ok4~0627) yangtze; urgency=medium
|
||||
|
||||
* 修改为quilt格式
|
||||
* openkylin 重新导入
|
||||
* fix bug#125453,控制面板账户模块缺少"账户信息"设置项
|
||||
|
||||
-- Xie Wei <xiewei@kylinos.cn> Fri, 10 Jun 2022 19:35:33 +0800
|
||||
|
||||
libkysdk-base (1.1.1kylin1) yangtze; urgency=medium
|
||||
|
||||
* BUG号 : 119832
|
||||
* 需求号 : 无
|
||||
* 其他修改 :
|
||||
* publish for v1.1 update
|
||||
|
||||
-- liuyunhe <liuyunhe@kylinos.cn> Tue, 17 May 2022 16:17:53 +0800
|
|
@ -0,0 +1,200 @@
|
|||
Source: libkysdk-base
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: kylin <chenzhikai@kylinos.cn>
|
||||
Build-Depends: debhelper-compat (= 12),
|
||||
libc6-dev,
|
||||
cmake,
|
||||
libsystemd-dev,
|
||||
libdbus-1-dev,
|
||||
libssl-dev,
|
||||
libgtk-3-dev,
|
||||
libglib2.0-dev,
|
||||
libsqlite3-dev
|
||||
Standards-Version: 4.4.1
|
||||
Homepage: http://gitlab2.kylin.com/kysdk/kysdk-base
|
||||
|
||||
Package: libkysdk-base
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libkysdk-timer (= ${binary:Version}),
|
||||
libkysdk-log (= ${binary:Version}),
|
||||
libkysdk-config (= ${binary:Version}),
|
||||
libkysdk-utils (= ${binary:Version}),
|
||||
libkysdk-diagnostics (= ${binary:Version}),
|
||||
libkysdk-basecommon (= ${binary:Version}),
|
||||
libkysdk-gsetting (= ${binary:Version})
|
||||
Multi-Arch: same
|
||||
Description: 麒麟开发者套件 - 基础层套件,提供日志管理、消息通信、进程守护、线程管理、定时器、调试与埋点、配置文件、utils
|
||||
|
||||
Package: libkysdk-base-dev
|
||||
Architecture: all
|
||||
Section: utils
|
||||
Depends: libkysdk-base (= ${binary:Version}),
|
||||
libkysdk-timer-dev (= ${binary:Version}),
|
||||
libkysdk-log-dev (= ${binary:Version}),
|
||||
libkysdk-config-dev (= ${binary:Version}),
|
||||
libkysdk-utils-dev (= ${binary:Version}),
|
||||
libkysdk-diagnostics-dev (= ${binary:Version}),
|
||||
libkysdk-gsetting-dev (= ${binary:Version})
|
||||
Multi-Arch: foreign
|
||||
Description: 麒麟开发者套件 - 基础层套件 - 开发库,提供日志管理、消息通信、进程守护、线程管理、定时器、调试与埋点、配置文件、utils
|
||||
|
||||
Package: libkysdk-timer
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libkysdk-basecommon (>=1.2.0),
|
||||
libkysdk-utils(>=1.2.0),
|
||||
libc6
|
||||
Multi-Arch: same
|
||||
Description: 定制器模块库
|
||||
|
||||
Package: libkysdk-timer-dev
|
||||
Architecture: all
|
||||
Section: utils
|
||||
Depends: libkysdk-utils-dev(>=1.2.0),
|
||||
libkysdk-timer (= ${binary:Version}),
|
||||
libkysdk-basecommon(>=1.2.0),
|
||||
libc6
|
||||
Multi-Arch: foreign
|
||||
Description: 定时器模块 - 开发库
|
||||
|
||||
Package: libkysdk-log
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libkysdk-config(>=1.2.0),
|
||||
logrotate,
|
||||
libkysdk-basecommon(>=1.2.0),
|
||||
libkysdk-utils(>=1.2.0),
|
||||
dbus,
|
||||
libc6,
|
||||
libdbus-1-3,
|
||||
libsystemd0
|
||||
Multi-Arch: same
|
||||
Description: 日志库
|
||||
|
||||
Package: libkysdk-basecommon
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends:
|
||||
Multi-Arch: same
|
||||
Description: kysdk-base层公用数据包
|
||||
|
||||
Package: libkysdk-log-dev
|
||||
Architecture: all
|
||||
Section: utils
|
||||
Depends: libkysdk-log (= ${binary:Version}),
|
||||
libkysdk-config-dev(>=1.2.0),
|
||||
libkysdk-utils-dev(>=1.2.0),
|
||||
libsystemd-dev
|
||||
Multi-Arch: foreign
|
||||
Description: 日志库 - 开发库
|
||||
|
||||
Package: libkysdk-config
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libkysdk-basecommon(>=1.2.0),
|
||||
libkysdk-utils(>=1.2.0),
|
||||
libc6
|
||||
Multi-Arch: same
|
||||
Description: 配置文件库
|
||||
|
||||
Package: libkysdk-config-dev
|
||||
Architecture: all
|
||||
Section: utils
|
||||
Depends: libkysdk-utils-dev(>=1.2.0),
|
||||
libkysdk-config (= ${binary:Version})
|
||||
Multi-Arch: foreign
|
||||
Description: 配置文件库 - 开发库
|
||||
|
||||
Package: libkysdk-utils
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libkysdk-basecommon(>=1.2.0),
|
||||
libc6
|
||||
Multi-Arch: same
|
||||
Description: 开发者utils
|
||||
|
||||
Package: libkysdk-utils-dev
|
||||
Architecture: all
|
||||
Section: utils
|
||||
Depends: libkysdk-utils (= ${binary:Version})
|
||||
Multi-Arch: foreign
|
||||
Description: 开发者utils - 开发库
|
||||
|
||||
Package: libkysdk-diagnostics
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libkysdk-basecommon(>=1.2.0),
|
||||
libkysdk-utils(>=1.2.0),
|
||||
libc6,
|
||||
libdbus-1-3,
|
||||
libgcc-s1 | libgcc1,
|
||||
libssl1.1,
|
||||
libstdc++6
|
||||
Multi-Arch: same
|
||||
Description: 开发者diagnostics
|
||||
|
||||
Package: libkysdk-diagnostics-dev
|
||||
Architecture: all
|
||||
Section: utils
|
||||
Depends: libkysdk-diagnostics (= ${binary:Version})
|
||||
Multi-Arch: foreign
|
||||
Description: 开发者diagnostics - 开发库
|
||||
|
||||
Package: libkysdk-gsetting
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libgtk-3-0,
|
||||
libglib2.0-0,
|
||||
libkysdk-basecommon(>=1.2.0),
|
||||
libatk1.0-0,
|
||||
libc6,
|
||||
libcairo-gobject2,
|
||||
libcairo2,
|
||||
libgdk-pixbuf2.0-0,
|
||||
libharfbuzz0b,
|
||||
libpango-1.0-0,
|
||||
libpangocairo-1.0-0
|
||||
Multi-Arch: same
|
||||
Description: 开发者gsetting
|
||||
|
||||
Package: libkysdk-gsetting-dev
|
||||
Architecture: all
|
||||
Section: utils
|
||||
Depends: libkysdk-gsetting (= ${binary:Version})
|
||||
Multi-Arch: foreign
|
||||
Description: 开发者gsetting - 开发库
|
||||
|
||||
Package: libkysdk-conf2
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libglib2.0-0,
|
||||
libgtk-3-0,
|
||||
libkysdk-basecommon(>=2.2.0),
|
||||
libc6,
|
||||
libsqlite3-0,
|
||||
libkysdk-log,
|
||||
python3.8,
|
||||
python3-dbus,
|
||||
python3-watchdog,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
Multi-Arch: same
|
||||
Description: 统一配置模块
|
||||
|
||||
Package: libkysdk-conf2-dev
|
||||
Architecture: all
|
||||
Section: utils
|
||||
Depends: libkysdk-conf2 (= ${binary:Version})
|
||||
Multi-Arch: foreign
|
||||
Description: 统一配置模块 - 开发库
|
||||
|
||||
Package: libkysdk-conf2-tools
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libkysdk-conf2 (= ${binary:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
Multi-Arch: same
|
||||
Description: 统一配置模块 - 工具包
|
|
@ -0,0 +1,43 @@
|
|||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: kysdk-base
|
||||
Upstream-Contact: <preferred name and address to reach the upstream project>
|
||||
Source: <url://example.com>
|
||||
|
||||
Files: *
|
||||
Copyright: <years> <put author's name and email here>
|
||||
<years> <likewise for another author>
|
||||
License: <special license>
|
||||
<Put the license of the package here indented by 1 space>
|
||||
<This follows the format of Description: lines in control file>
|
||||
.
|
||||
<Including paragraphs>
|
||||
|
||||
# If you want to use GPL v2 or later for the /debian/* files use
|
||||
# the following clauses, or change it to suit. Delete these two lines
|
||||
Files: debian/*
|
||||
Copyright: 2021 kylin <chenzhikai@kylinos.cn>
|
||||
License: GPL-2+
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
# Please also look if there are files or directories which have a
|
||||
# different copyright/license attached and list them here.
|
||||
# Please avoid picking licenses with terms that are more restrictive than the
|
||||
# packaged work, as it may make Debian's contributions unacceptable upstream.
|
||||
#
|
||||
# If you need, there are some extra license texts available in two places:
|
||||
# /usr/share/debhelper/dh_make/licenses/
|
||||
# /usr/share/common-licenses/
|
|
@ -0,0 +1,2 @@
|
|||
[DEFAULT]
|
||||
compression=xz
|
|
@ -0,0 +1 @@
|
|||
development-files/kysdk-base.pc usr/share/pkgconfig/
|
|
@ -0,0 +1 @@
|
|||
development-files/kysdk-base.conf etc/ld.so.conf.d
|
|
@ -0,0 +1,2 @@
|
|||
src/conf2/api/libkysettings.h usr/include/kysdk/kysdk-base
|
||||
development-files/kysdk-conf2.pc usr/share/pkgconfig/
|
|
@ -0,0 +1,3 @@
|
|||
usr/bin/kconf2 usr/bin
|
||||
usr/bin/kconf2-editor usr/bin
|
||||
src/conf2/tools/gschema_xml2yaml.py usr/bin
|
|
@ -0,0 +1,12 @@
|
|||
usr/lib/*/libkyconf2.so*
|
||||
src/conf2/service/conf2Utils.py usr/bin
|
||||
src/conf2/service/conf2-server.py usr/bin
|
||||
src/conf2/service/kysdk-conf2.conf etc/dbus-1/system.d
|
||||
src/conf2/service/kysdk-conf2.service lib/systemd/system
|
||||
src/conf2/service/com.kylin.kysdk.conf2.limit etc/dbus-1/conf
|
||||
src/conf2/service/com.kylin.kysdk.conf2.limit usr/share/dbus-1/conf
|
||||
src/conf2/service/com.kylin.kysdk.conf2.limit.verify etc/dbus-1/conf
|
||||
src/conf2/service/com.kylin.kysdk.conf2.limit.verify usr/share/dbus-1/conf
|
||||
src/conf2/service/conf2-session-server.py usr/bin
|
||||
src/conf2/service/kysdk-conf2.desktop etc/xdg/autostart/
|
||||
src/conf2/configs/conf2.yaml etc/kylin-config/
|
|
@ -0,0 +1,82 @@
|
|||
# SymbolsHelper-Confirmed: 2.4.1.0 amd64
|
||||
libkyconf2.so.1 libkysdk-conf2 #MINVER#
|
||||
app_data_destroy@Base 2.3.0.0
|
||||
data_equal@Base 2.3.0.0
|
||||
data_hash@Base 2.3.0.0
|
||||
k_settings_get_type@Base 2.3.0.0
|
||||
kdk_conf2_connect_signal@Base 2.3.0.0
|
||||
kdk_conf2_get_boolean@Base 2.3.0.0
|
||||
kdk_conf2_get_child@Base 2.3.0.0
|
||||
kdk_conf2_get_default_boolean@Base 2.4.1.0
|
||||
kdk_conf2_get_default_double@Base 2.4.1.0
|
||||
kdk_conf2_get_default_enum@Base 2.4.1.0
|
||||
kdk_conf2_get_default_int64@Base 2.4.1.0
|
||||
kdk_conf2_get_default_int@Base 2.4.1.0
|
||||
kdk_conf2_get_default_string@Base 2.4.1.0
|
||||
kdk_conf2_get_default_strv@Base 2.4.1.0
|
||||
kdk_conf2_get_default_uint64@Base 2.4.1.0
|
||||
kdk_conf2_get_default_uint@Base 2.4.1.0
|
||||
kdk_conf2_get_default_value@Base 2.3.0.0
|
||||
kdk_conf2_get_descrition@Base 2.3.0.0
|
||||
kdk_conf2_get_double@Base 2.3.0.0
|
||||
kdk_conf2_get_enum@Base 2.3.0.0
|
||||
kdk_conf2_get_id@Base 2.3.0.0
|
||||
kdk_conf2_get_int64@Base 2.3.0.0
|
||||
kdk_conf2_get_int@Base 2.3.0.0
|
||||
kdk_conf2_get_range@Base 2.3.0.0
|
||||
kdk_conf2_get_string@Base 2.3.0.0
|
||||
kdk_conf2_get_strv@Base 2.3.0.0
|
||||
kdk_conf2_get_summary@Base 2.3.0.0
|
||||
kdk_conf2_get_type@Base 2.3.0.0
|
||||
kdk_conf2_get_uint64@Base 2.3.0.0
|
||||
kdk_conf2_get_uint@Base 2.3.0.0
|
||||
kdk_conf2_get_value@Base 2.3.0.0
|
||||
kdk_conf2_get_version@Base 2.3.0.0
|
||||
kdk_conf2_has_key@Base 2.4.1.0
|
||||
kdk_conf2_is_schema@Base 2.4.1.0
|
||||
kdk_conf2_is_writable@Base 2.3.0.0
|
||||
kdk_conf2_ksettings_destroy@Base 2.3.0.0
|
||||
kdk_conf2_list_children@Base 2.3.0.0
|
||||
kdk_conf2_list_keys@Base 2.3.0.0
|
||||
kdk_conf2_list_schemas@Base 2.3.0.0
|
||||
kdk_conf2_new@Base 2.3.0.0
|
||||
kdk_conf2_new_extends_id@Base 2.4.1.0
|
||||
kdk_conf2_range_check@Base 2.3.0.0
|
||||
kdk_conf2_reload@Base 2.3.0.0
|
||||
kdk_conf2_reset@Base 2.3.0.0
|
||||
kdk_conf2_save_user_configure@Base 2.4.1.0
|
||||
kdk_conf2_schema_destroy@Base 2.3.0.0
|
||||
kdk_conf2_schema_find_child@Base 2.3.0.0
|
||||
kdk_conf2_schema_get_id@Base 2.3.0.0
|
||||
kdk_conf2_schema_get_key@Base 2.3.0.0
|
||||
kdk_conf2_schema_get_version@Base 2.3.0.0
|
||||
kdk_conf2_schema_has_key@Base 2.3.0.0
|
||||
kdk_conf2_schema_key_get_default_value@Base 2.3.0.0
|
||||
kdk_conf2_schema_key_get_description@Base 2.3.0.0
|
||||
kdk_conf2_schema_key_get_name@Base 2.3.0.0
|
||||
kdk_conf2_schema_key_get_permission@Base 2.3.0.0
|
||||
kdk_conf2_schema_key_get_range@Base 2.3.0.0
|
||||
kdk_conf2_schema_key_get_summary@Base 2.3.0.0
|
||||
kdk_conf2_schema_key_get_value@Base 2.3.0.0
|
||||
kdk_conf2_schema_key_range_check@Base 2.3.0.0
|
||||
kdk_conf2_schema_key_value_type@Base 2.3.0.0
|
||||
kdk_conf2_schema_list_children@Base 2.3.0.0
|
||||
kdk_conf2_schema_list_keys@Base 2.3.0.0
|
||||
kdk_conf2_schema_reload@Base 2.3.0.0
|
||||
kdk_conf2_schema_table_lookup@Base 2.3.0.0
|
||||
kdk_conf2_schema_update_schemas_table@Base 2.3.0.0
|
||||
kdk_conf2_set_boolean@Base 2.3.0.0
|
||||
kdk_conf2_set_double@Base 2.3.0.0
|
||||
kdk_conf2_set_enum@Base 2.3.0.0
|
||||
kdk_conf2_set_int64@Base 2.3.0.0
|
||||
kdk_conf2_set_int@Base 2.3.0.0
|
||||
kdk_conf2_set_string@Base 2.3.0.0
|
||||
kdk_conf2_set_strv@Base 2.3.0.0
|
||||
kdk_conf2_set_uint64@Base 2.3.0.0
|
||||
kdk_conf2_set_uint@Base 2.3.0.0
|
||||
kdk_conf2_set_value@Base 2.3.0.0
|
||||
schema_data_destroy@Base 2.3.0.0
|
||||
schemas_table@Base 2.3.0.0
|
||||
version_data_destroy@Base 2.3.0.0
|
||||
kdk_conf2_get_schema_summary@Base 2.5.1.0
|
||||
kdk_conf2_get_schema_desription@Base 2.5.1.0
|
|
@ -0,0 +1,2 @@
|
|||
src/config/libkyconf.h usr/include/kysdk/kysdk-base
|
||||
development-files/kysdk-config.pc usr/share/pkgconfig/
|
|
@ -0,0 +1,8 @@
|
|||
man/config/kdk_conf_destroy.3
|
||||
man/config/kdk_conf_get_value.3
|
||||
man/config/kdk_conf_init.3
|
||||
man/config/kdk_conf_list_group.3
|
||||
man/config/kdk_conf_list_key.3
|
||||
man/config/kdk_conf_reload.3
|
||||
man/config/kdk_config_freeall.3
|
||||
man/config/libkyconf.3
|
|
@ -0,0 +1 @@
|
|||
usr/lib/*/libkyconf.so*
|
|
@ -0,0 +1,27 @@
|
|||
# SymbolsHelper-Confirmed: 2.0.0.0 amd64
|
||||
libkyconf.so.1 libkysdk-cofig #MINVER#
|
||||
S_destroyParse@Base 1.1.1
|
||||
S_getGroupList@Base 1.1.1
|
||||
S_getKeyList@Base 1.1.1
|
||||
S_getValue@Base 1.1.1
|
||||
S_newParse@Base 1.1.1
|
||||
S_parseFile@Base 1.1.1
|
||||
S_setAssignmentDelimiter@Base 1.1.1
|
||||
S_setKeyDelimiter@Base 1.1.1
|
||||
S_setValue@Base 1.1.1
|
||||
S_setValueDelimiter@Base 1.1.1
|
||||
S_write2File@Base 1.1.1
|
||||
S_writeBack@Base 1.1.1
|
||||
isgsettings@Base 1.1.1
|
||||
isjson@Base 1.1.1
|
||||
isxml@Base 1.1.1
|
||||
kdk_conf_destroy@Base 1.1.1
|
||||
kdk_conf_disable_autoreload@Base 1.1.1
|
||||
kdk_conf_enable_autoreload@Base 1.1.1
|
||||
kdk_conf_get_value@Base 1.1.1
|
||||
kdk_conf_init@Base 1.1.1
|
||||
kdk_conf_list_group@Base 1.1.1
|
||||
kdk_conf_list_key@Base 1.1.1
|
||||
kdk_conf_reload@Base 1.1.1
|
||||
kdk_conf_set_value@Base 1.1.1
|
||||
kdk_config_freeall@Base 2.0.0.0
|
|
@ -0,0 +1,2 @@
|
|||
src/diagnostics/libkydiagnostics.h usr/include/kysdk/kysdk-base
|
||||
development-files/kysdk-diagnostics.pc usr/share/pkgconfig/
|
|
@ -0,0 +1,2 @@
|
|||
man/diagnostics/kdk_buried_point.3
|
||||
man/diagnostics/libkydiagnostics.3
|
|
@ -0,0 +1 @@
|
|||
usr/lib/*/libkydiagnostics.so*
|
|
@ -0,0 +1,3 @@
|
|||
# SymbolsHelper-Confirmed: 2.2.0.0 amd64
|
||||
libkydiagnostics.so.1 libkysdk-diagnostics #MINVER#
|
||||
kdk_buried_point@Base 2.2.0.0
|
|
@ -0,0 +1,2 @@
|
|||
src/gsettings/libkygsetting.h usr/include/kysdk/kysdk-base
|
||||
development-files/kysdk-gsetting.pc usr/share/pkgconfig/
|
|
@ -0,0 +1,9 @@
|
|||
man/gsettings/kdk_gsettings_get.3
|
||||
man/gsettings/kdk_gsettings_set.3
|
||||
man/gsettings/kdk_settings_get_double.3
|
||||
man/gsettings/kdk_settings_get_int.3
|
||||
man/gsettings/kdk_settings_get_string.3
|
||||
man/gsettings/kdk_settings_reset.3
|
||||
man/gsettings/kdk_settings_set_int.3
|
||||
man/gsettings/kdk_settings_set_string.3
|
||||
man/gsettings/libkygsetting.3
|
|
@ -0,0 +1 @@
|
|||
usr/lib/*/libkygsetting.so*
|
|
@ -0,0 +1,11 @@
|
|||
# SymbolsHelper-Confirmed: 2.0.0.0 amd64
|
||||
libkygsetting.so.1 libkysdk-gsetting #MINVER#
|
||||
kdk_gsettings_get@Base 2.0.0.0
|
||||
kdk_gsettings_set@Base 2.0.0.0
|
||||
kdk_settings_get_double@Base 2.0.0.0
|
||||
kdk_settings_get_int@Base 2.0.0.0
|
||||
kdk_settings_get_string@Base 2.0.0.0
|
||||
kdk_settings_reset@Base 2.0.0.0
|
||||
kdk_settings_set_int@Base 2.0.0.0
|
||||
kdk_settings_set_string@Base 2.0.0.0
|
||||
schema_key_is_exist@Base 2.0.0.0
|
|
@ -0,0 +1,2 @@
|
|||
src/log/libkylog.h usr/include/kysdk/kysdk-base
|
||||
development-files/kysdk-log.pc usr/share/pkgconfig/
|
|
@ -0,0 +1,5 @@
|
|||
man/log/kdk_logger_flush.3
|
||||
man/log/kdk_logger_init.3
|
||||
man/log/kdk_logger_set_autowrap.3
|
||||
man/log/kdk_logger_setdir.3
|
||||
man/log/libkylog.3
|
|
@ -0,0 +1,4 @@
|
|||
usr/lib/*/libkylog.so*
|
||||
src/log/kylog-default.conf etc/kysdk/kysdk-base
|
||||
src/log/kylog-rotate-default etc/kysdk/kysdk-base
|
||||
#src/log/logrotate.cron etc/kysdk/kysdk-base
|
|
@ -0,0 +1,29 @@
|
|||
# SymbolsHelper-Confirmed: 1.1.1 amd64
|
||||
libkylog.so.1 libkysdk-log #MINVER#
|
||||
append_wrap@Base 1.1.1
|
||||
destroyKLogger@Base 1.1.1
|
||||
destroyMessageQueue@Base 1.1.1
|
||||
emptyMessageQueue@Base 1.1.1
|
||||
flushMessageQueue@Base 1.1.1
|
||||
formatMessage@Base 1.1.1
|
||||
getRecordDate@Base 1.1.1
|
||||
initKLogger@Base 1.1.1
|
||||
initMessageQueue@Base 1.1.1
|
||||
insertMessage@Base 1.1.1
|
||||
kdk_logger_flush@Base 1.1.1
|
||||
kdk_logger_init@Base 1.1.1
|
||||
kdk_logger_set_autowrap@Base 1.1.1
|
||||
kdk_logger_setdir@Base 1.1.1
|
||||
kdk_logger_write@Base 1.1.1
|
||||
klog_printformat@Base 1.1.1
|
||||
klog_rotate_init@Base 1.1.1
|
||||
loadFormatOptions@Base 1.1.1
|
||||
logger@Base 1.1.1
|
||||
recycle@Base 1.1.1
|
||||
setRootDir@Base 1.1.1
|
||||
set_autowrap@Base 1.1.1
|
||||
startMQDaemon@Base 1.1.1
|
||||
stringLType@Base 1.1.1
|
||||
stringLevel@Base 1.1.1
|
||||
writeFile@Base 1.1.1
|
||||
writeLog@Base 1.1.1
|
|
@ -0,0 +1,2 @@
|
|||
src/timer/libkytimer.h usr/include/kysdk/kysdk-base
|
||||
development-files/kysdk-timer.pc usr/share/pkgconfig/
|
|
@ -0,0 +1,6 @@
|
|||
man/timer/kdk_timer_destroy.3
|
||||
man/timer/kdk_timer_init.3
|
||||
man/timer/kdk_timer_reset.3
|
||||
man/timer/kdk_timer_start.3
|
||||
man/timer/kdk_timer_stop.3
|
||||
man/timer/libkytimer.3
|
|
@ -0,0 +1 @@
|
|||
usr/lib/*/libkytimer.so*
|
|
@ -0,0 +1,7 @@
|
|||
# SymbolsHelper-Confirmed: 1.1.1 amd64
|
||||
libkytimer.so.1 libkysdk-timer #MINVER#
|
||||
kdk_timer_destroy@Base 1.1.1
|
||||
kdk_timer_init@Base 1.1.1
|
||||
kdk_timer_reset@Base 1.1.1
|
||||
kdk_timer_start@Base 1.1.1
|
||||
kdk_timer_stop@Base 1.1.1
|
|
@ -0,0 +1,7 @@
|
|||
src/utils/sdkmarcos.h usr/include/kysdk/kysdk-base
|
||||
src/utils/kerr.h usr/include/kysdk/kysdk-base
|
||||
src/utils/cstring-extension.h usr/include/kysdk/kysdk-base
|
||||
src/utils/kyutils.h usr/include/kysdk/kysdk-base
|
||||
src/utils/data-structure/linklist/skip_linklist/skip_linklist.h usr/include/kysdk/kysdk-base
|
||||
src/utils/data-structure/linklist/listdata.h usr/include/kysdk/kysdk-base
|
||||
development-files/kysdk-utils.pc usr/share/pkgconfig/
|
|
@ -0,0 +1,24 @@
|
|||
man/utils/kdkVolumeBaseCharacterConvert.3
|
||||
man/utils/kdkVolumeBaseNumericalConvert.3
|
||||
man/utils/kysdk_create_skiplist.3
|
||||
man/utils/kysdk_destroy_skiplist.3
|
||||
man/utils/kysdk_skiplist_delete.3
|
||||
man/utils/kysdk_skiplist_insert.3
|
||||
man/utils/kysdk_skiplist_search.3
|
||||
man/utils/kysdk_skiplist_setmaxlevels.3
|
||||
man/utils/libkydatastruct.3
|
||||
man/utils/libkyutils.3
|
||||
man/utils/str2lower.3
|
||||
man/utils/str2upper.3
|
||||
man/utils/strcounts.3
|
||||
man/utils/strendwith.3
|
||||
man/utils/strfirstof.3
|
||||
man/utils/strlastof.3
|
||||
man/utils/strskipblank.3
|
||||
man/utils/strskipspace.3
|
||||
man/utils/strsplit.3
|
||||
man/utils/strstartswith_nocase.3
|
||||
man/utils/strstartswith.3
|
||||
man/utils/strstrip.3
|
||||
man/utils/strstripblank.3
|
||||
man/utils/strstripspace.3
|
|
@ -0,0 +1,2 @@
|
|||
usr/lib/*/libkydatastruct.so*
|
||||
usr/lib/*/libkyutils.so*
|
|
@ -0,0 +1,13 @@
|
|||
# SymbolsHelper-Confirmed: 1.2.0.5 amd64
|
||||
libkydatastruct.so.1 libkysdk-utils #MINVER#
|
||||
kysdk_create_skiplist@Base 1.1.1
|
||||
kysdk_destroy_skiplist@Base 1.1.1
|
||||
kysdk_skiplist_delete@Base 1.1.1
|
||||
kysdk_skiplist_insert@Base 1.1.1
|
||||
kysdk_skiplist_search@Base 1.1.1
|
||||
kysdk_skiplist_setmaxlevels@Base 1.1.1
|
||||
libkyutils.so.1 libkysdk-utils #MINVER#
|
||||
kdkVolumeBaseCharacterConvert@Base 1.2.0.5
|
||||
kdkVolumeBaseNumericalConvert@Base 1.2.0.5
|
||||
parse_size@Base 1.2.0.5
|
||||
size_to_human_string@Base 1.2.0.5
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/make -f
|
||||
# See debhelper(7) (uncomment to enable)
|
||||
# output every command that modifies files on the build system.
|
||||
#export DH_VERBOSE = 1
|
||||
|
||||
|
||||
# see FEATURE AREAS in dpkg-buildflags(1)
|
||||
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
|
||||
# see ENVIRONMENT in dpkg-buildflags(1)
|
||||
# package maintainers to append CFLAGS
|
||||
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
|
||||
# package maintainers to append LDFLAGS
|
||||
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
||||
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
|
||||
# dh_make generated override targets
|
||||
# This is example for Cmake (See https://bugs.debian.org/641051 )
|
||||
#override_dh_auto_configure:
|
||||
# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)
|
||||
|
|
@ -0,0 +1 @@
|
|||
3.0 (native)
|
|
@ -1,6 +1,6 @@
|
|||
base_version=2.3.0.0
|
||||
base_version=2.5.0
|
||||
|
||||
Name: libkysdk-base
|
||||
Description: kysdk base layer
|
||||
Requires: kysdk-log >= ${base_version} kysdk-config >= ${base_version} kysdk-timer >= ${base_version} kysdk-utils >= ${base_version}
|
||||
Version: 2.3.0.0
|
||||
Version: 2.5.0
|
|
@ -1,5 +1,5 @@
|
|||
Name: libkysdk-conf2
|
||||
Description: kysdk base conf2
|
||||
Version: 2.3.0.0
|
||||
Version: 2.5.0
|
||||
Cflags: -I/usr/include/kysdk/kysdk-base/
|
||||
Libs: -lkyconf2
|
|
@ -1,8 +1,8 @@
|
|||
base_version=2.3.0.0
|
||||
base_version=2.4.0
|
||||
|
||||
Name: libkysdk-config
|
||||
Description: kysdk base layer config component
|
||||
Requires: kysdk-utils
|
||||
Version: 2.3.0.0
|
||||
Version: 2.5.0
|
||||
Cflags: -I/usr/include/kysdk/kysdk-base/
|
||||
Libs: -lkysdk-config
|
||||
Libs: -lkyconf
|
|
@ -1,5 +1,5 @@
|
|||
Name: libkysdk-diagnostics
|
||||
Description: kysdk base layer diagnostics component
|
||||
Version: 2.3.0.0
|
||||
Version: 2.5.0
|
||||
Cflags: -I/usr/include/kysdk/kysdk-base/
|
||||
Libs: -lkydiagnostics
|
|
@ -1,6 +1,6 @@
|
|||
Name: libkysdk-gsetting
|
||||
Description: kysdk base layer gsettings component
|
||||
Requires: gtk+-3.0 glib-2.0
|
||||
Version: 2.3.0.0
|
||||
Libs: -lkysdk-gsetting
|
||||
Version: 2.5.0
|
||||
Libs: -lkygsetting
|
||||
Cflags: -I/usr/include/kysdk/kysdk-base/
|
|
@ -1,6 +1,6 @@
|
|||
Name: libkysdk-log
|
||||
Description: kysdk base layer log component
|
||||
Requires: kysdk-config kysdk-utils libsystemd
|
||||
Version: 2.3.0.0
|
||||
Version: 2.5.0
|
||||
Cflags: -I/usr/include/kysdk/kysdk-base/
|
||||
Libs: -lkysdk-log
|
||||
Libs: -lkylog
|
|
@ -1,6 +1,6 @@
|
|||
Name: libkysdk-timer
|
||||
Description: kysdk base layer time component
|
||||
Requires: kysdk-utils
|
||||
Version: 2.3.0.0
|
||||
Version: 2.5.0
|
||||
Cflags: -I/usr/include/kysdk/kysdk-base/
|
||||
Libs: -lkysdk-timer
|
||||
Libs: -lkytimer
|
|
@ -1,5 +1,5 @@
|
|||
Name: libkysdk-utils
|
||||
Description: kysdk base layer utils component
|
||||
Version: 2.3.0.0
|
||||
Version: 2.5.0
|
||||
Cflags:-I/usr/include/kysdk/kysdk-base/
|
||||
Libs: -lkydatastruct -lkyutils
|
|
@ -3,6 +3,7 @@ include_directories(utils)
|
|||
include_directories(log)
|
||||
include_directories(timer)
|
||||
include_directories(gsettings)
|
||||
include_directories(conf2)
|
||||
|
||||
# add_subdirectory(communication)
|
||||
add_subdirectory(config)
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
*.pro*
|
||||
main.cpp
|
|
@ -12,8 +12,14 @@ target_link_libraries(kconf2 kyconf2)
|
|||
add_executable(kconf2-editor tools/kconf2-editor.c )
|
||||
target_link_libraries(kconf2-editor kyconf2 ${GTK_LIBRARIES})
|
||||
|
||||
add_executable(kyconf2-test test/kyconf2-test.c)
|
||||
target_link_libraries(kyconf2-test kyconf2)
|
||||
|
||||
install(TARGETS kconf2
|
||||
DESTINATION /usr/bin)
|
||||
|
||||
install(TARGETS kconf2-editor
|
||||
DESTINATION /usr/bin)
|
||||
|
||||
install(TARGETS kyconf2-test
|
||||
DESTINATION /usr/bin)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# aux_source_directory(. SOURCESCODE)
|
||||
|
||||
add_library(kyconf2 SHARED libkysettings.c ksettingsschema.c )
|
||||
set_target_properties(kyconf2 PROPERTIES VERSION 2.0.0 SOVERSION 1)
|
||||
target_link_libraries(kyconf2 ${GLIB_LIBRARIES} ${GIO_LIBRARIES} -lsqlite3)
|
||||
set_target_properties(kyconf2 PROPERTIES VERSION 2.5.0 SOVERSION 1)
|
||||
target_link_libraries(kyconf2 ${GLIB_LIBRARIES} ${GIO_LIBRARIES} -lsqlite3 kylog)
|
||||
|
||||
# 包含 GNU 安装目录设置
|
||||
include(GNUInstallDirs)
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sqlite3.h>
|
||||
#include <syslog.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "libkylog.h"
|
||||
|
||||
/**
|
||||
* @brief 嵌套哈希表,
|
||||
|
@ -73,6 +75,10 @@ void schema_data_destroy(gpointer data)
|
|||
KSettingsSchema *schema = (KSettingsSchema *)data;
|
||||
g_free(schema->id);
|
||||
g_free(schema->version);
|
||||
g_free(schema->permission);
|
||||
g_free(schema->description);
|
||||
g_free(schema->summary);
|
||||
g_free(schema->extends);
|
||||
if (schema->values)
|
||||
{
|
||||
g_hash_table_destroy(schema->values);
|
||||
|
@ -153,7 +159,6 @@ static int _sql_call_get_lines(void *data, int argc, char **argv, char **azColNa
|
|||
char **columns = calloc(argc + 1, sizeof(char *));
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
char *fewf = argv[i];
|
||||
columns[i] = g_strdup(argv[i]);
|
||||
}
|
||||
char ***tmp = realloc(lines, sizeof(char **) * (line_count + 2));
|
||||
|
@ -184,7 +189,18 @@ static int _sql_call_get_schema(void *data, int argc, char **argv, char **azColN
|
|||
{
|
||||
KSettingsSchema *schema = (KSettingsSchema *)data;
|
||||
|
||||
if (NULL == argv[3])
|
||||
char *node_name = argv[2];
|
||||
char *node_type = argv[3];
|
||||
char *permission = argv[4];
|
||||
char *description = argv[5];
|
||||
char *summary = argv[6];
|
||||
char *value_type = argv[8];
|
||||
char *custom_value = argv[9];
|
||||
char *default_value = argv[10];
|
||||
char *value_range = argv[11];
|
||||
char *extends = argv[12];
|
||||
|
||||
if (0 == strcmp(node_type, "key"))
|
||||
{
|
||||
// hash表 s:hash(s:s)
|
||||
if (NULL == schema->values)
|
||||
|
@ -193,31 +209,32 @@ static int _sql_call_get_schema(void *data, int argc, char **argv, char **azColN
|
|||
GHashTable *item = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
if (NULL == item)
|
||||
goto err;
|
||||
if (argv[2])
|
||||
g_hash_table_insert(item, "property", g_strdup(argv[2])); // 键名
|
||||
if (argv[4])
|
||||
g_hash_table_insert(item, "user_value", g_strdup(argv[4])); // 键值
|
||||
if (argv[5])
|
||||
g_hash_table_insert(item, "data_type", g_strdup(argv[5])); // 类型
|
||||
if (argv[6])
|
||||
g_hash_table_insert(item, "default_value", g_strdup(argv[6])); // 默认值
|
||||
if (argv[7])
|
||||
g_hash_table_insert(item, "permission", g_strdup(argv[7])); // 读写权限
|
||||
if (argv[8])
|
||||
g_hash_table_insert(item, "range", g_strdup(argv[8])); // 取值范围
|
||||
if (argv[10])
|
||||
g_hash_table_insert(item, "description", g_strdup(argv[10])); // 详细描述
|
||||
if (argv[11])
|
||||
g_hash_table_insert(item, "summary", g_strdup(argv[11])); // 概要
|
||||
g_hash_table_insert(schema->values, g_strdup(argv[2]), item);
|
||||
if (node_name)
|
||||
g_hash_table_insert(item, "node_name", g_strdup(node_name)); // 键名
|
||||
if (permission)
|
||||
g_hash_table_insert(item, "permission", g_strdup(permission)); // 读写权限
|
||||
if (description)
|
||||
g_hash_table_insert(item, "description", g_strdup(description)); // 详细描述
|
||||
if (summary)
|
||||
g_hash_table_insert(item, "summary", g_strdup(summary)); // 概要
|
||||
if (value_type)
|
||||
g_hash_table_insert(item, "value_type", g_strdup(value_type)); // 类型
|
||||
if (custom_value)
|
||||
g_hash_table_insert(item, "custom_value", g_strdup(custom_value)); // 键值
|
||||
if (default_value)
|
||||
g_hash_table_insert(item, "default_value", g_strdup(default_value)); // 默认值
|
||||
if (value_range)
|
||||
g_hash_table_insert(item, "range", g_strdup(value_range)); // 取值范围
|
||||
|
||||
g_hash_table_insert(schema->values, g_strdup(node_name), item);
|
||||
}
|
||||
else
|
||||
else if (0 == strcmp(node_type, "schema"))
|
||||
{
|
||||
if (NULL == schema->children)
|
||||
{
|
||||
schema->children = g_array_new(FALSE, FALSE, sizeof(char *));
|
||||
}
|
||||
char *tmp = g_strdup(argv[3]);
|
||||
char *tmp = g_strdup(node_name);
|
||||
g_array_append_val(schema->children, tmp);
|
||||
}
|
||||
return 0;
|
||||
|
@ -231,17 +248,28 @@ err:
|
|||
// 读取一个组件
|
||||
static KSettingsSchema *_get_schema(const char *id, const char *version)
|
||||
{
|
||||
char *user_name = getlogin();
|
||||
if (user_name == NULL)
|
||||
return NULL;
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
}
|
||||
|
||||
KSettingsSchema *schema = NULL;
|
||||
|
||||
char db_file[PATH_MAX];
|
||||
if (0 == strcmp(user_name, "root"))
|
||||
sprintf(db_file, "/etc/kylin-config/kylin-config/user.db");
|
||||
sprintf(db_file, "/root/.config/kylin-config/user.db");
|
||||
else
|
||||
sprintf(db_file, "/home/%s/.config/kylin-config/user.db", user_name);
|
||||
// syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s \n", __func__, db_file);
|
||||
|
||||
char **id_list = _split_string(id, '.');
|
||||
if (!id_list)
|
||||
|
@ -251,27 +279,40 @@ static KSettingsSchema *_get_schema(const char *id, const char *version)
|
|||
sqlite3 *db = NULL;
|
||||
char *err_msg = NULL;
|
||||
|
||||
// 打开数据库
|
||||
int rc = sqlite3_open(db_file, &db);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
rc = sqlite3_open("/etc/kylin-config/kylin-config/user.db", &db);
|
||||
if (rc != SQLITE_OK)
|
||||
if (0 == strcmp(db_file, "/root/.config/kylin-config/user.db"))
|
||||
{
|
||||
fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
|
||||
goto out;
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s failed! %s try to open /etc/kylin-config/user.db.\n", __func__, db_file, sqlite3_errmsg(db));
|
||||
rc = sqlite3_open("/etc/kylin-config/user.db", &db);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open /etc/kylin-config/user.db failed. %s\n", __func__, sqlite3_errmsg(db));
|
||||
g_strfreev(id_list);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = sqlite3_exec(db, "BEGIN TRANSACTION", 0, 0, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :无法开始事务: %s\n", __func__, err_msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
int app_id = 0, version_id = 0, parent_id = 0;
|
||||
char sql[100];
|
||||
char sql[1024];
|
||||
sprintf(sql, "SELECT * FROM app WHERE app_name = '%s'", id_list[0]);
|
||||
char **columns = NULL;
|
||||
rc = sqlite3_exec(db, sql, _sql_call_get_columns, &columns, &err_msg);
|
||||
if (rc != SQLITE_OK || NULL == columns)
|
||||
{
|
||||
fprintf(stderr, "查询失败: %s\n", err_msg);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询应用%s失败: %s\n", __func__, id_list[0], err_msg);
|
||||
goto out;
|
||||
}
|
||||
app_id = atoi(columns[0]);
|
||||
|
@ -283,8 +324,7 @@ static KSettingsSchema *_get_schema(const char *id, const char *version)
|
|||
rc = sqlite3_exec(db, sql, _sql_call_get_columns, &columns, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
// TODO: 版本兼容性处理
|
||||
fprintf(stderr, "查询失败: %s\n", err_msg);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询%s版本号%s失败: %s\n", __func__, version, err_msg);
|
||||
goto out;
|
||||
}
|
||||
version_id = atoi(columns[0]);
|
||||
|
@ -293,13 +333,13 @@ static KSettingsSchema *_get_schema(const char *id, const char *version)
|
|||
int i = 1;
|
||||
while (id_list[i])
|
||||
{
|
||||
sprintf(sql, "SELECT * FROM configures WHERE version_id = %d AND parent = %d AND group_name = '%s'",
|
||||
sprintf(sql, "SELECT * FROM configures WHERE version_id = %d AND parent = %d AND node_name = '%s' AND node_type = 'schema'",
|
||||
version_id, parent_id, id_list[i++]);
|
||||
|
||||
rc = sqlite3_exec(db, sql, _sql_call_get_columns, &columns, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
fprintf(stderr, "查询失败: %s\n", err_msg);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询组件%s失败: %s\n", __func__, id_list[i], err_msg);
|
||||
goto out;
|
||||
}
|
||||
parent_id = atoi(columns[0]);
|
||||
|
@ -316,113 +356,44 @@ static KSettingsSchema *_get_schema(const char *id, const char *version)
|
|||
rc = sqlite3_exec(db, sql, _sql_call_get_schema, schema, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
fprintf(stderr, "查询失败: %s\n", err_msg);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询失败: %s\n", __func__, err_msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
rc = sqlite3_exec(db, "COMMIT", NULL, NULL, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :无法提交事务: %s\n", __func__, err_msg);
|
||||
goto out;
|
||||
}
|
||||
sqlite3_close(db);
|
||||
g_strfreev(id_list);
|
||||
return schema;
|
||||
out:
|
||||
sqlite3_exec(db, "ROLLBACK", 0, 0, &err_msg);
|
||||
sqlite3_free(err_msg);
|
||||
sqlite3_close(db);
|
||||
|
||||
g_strfreev(id_list);
|
||||
if (err_msg)
|
||||
sqlite3_free(err_msg);
|
||||
if (db)
|
||||
sqlite3_close(db);
|
||||
return schema;
|
||||
}
|
||||
|
||||
// 递归读取组件配置
|
||||
static int _get_component_recursively(char *version, int version_id, int parent_id, char *parent_name, GHashTable *schemas, sqlite3 *db)
|
||||
static void _get_schemas()
|
||||
{
|
||||
char *err_msg = NULL;
|
||||
char sql[128];
|
||||
char ***components = NULL;
|
||||
line_count = 0;
|
||||
sprintf(sql, "SELECT * FROM configures WHERE version_id = %d AND parent = %d AND group_name IS NOT NULL", version_id, parent_id);
|
||||
int rc = sqlite3_exec(db, sql, _sql_call_get_lines, &components, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
|
||||
return rc;
|
||||
}
|
||||
char ***apps = NULL, ***versions = NULL, ***configures = NULL;
|
||||
|
||||
KSettingsSchema *schema = g_hash_table_lookup(schemas, parent_name);
|
||||
if (NULL == schema)
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
schema = calloc(1, sizeof *schema);
|
||||
if (NULL == schema)
|
||||
return SQLITE_NOMEM;
|
||||
|
||||
schema->id = strdup(parent_name);
|
||||
schema->version = strdup(version);
|
||||
g_hash_table_insert(schemas, strdup(parent_name), schema);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (schema->values)
|
||||
{
|
||||
g_hash_table_destroy(schema->values);
|
||||
schema->values = NULL;
|
||||
}
|
||||
if (schema->children)
|
||||
{
|
||||
g_array_free(schema->children, TRUE);
|
||||
schema->children = NULL;
|
||||
}
|
||||
}
|
||||
sprintf(sql, "SELECT * FROM configures WHERE version_id = %d AND parent = %d",
|
||||
version_id, parent_id);
|
||||
rc = sqlite3_exec(db, sql, _sql_call_get_schema, schema, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
fprintf(stderr, "查询失败: %s\n", err_msg);
|
||||
// schema_data_destroy(schema);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// components为空
|
||||
if (NULL == components)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (int i = 0; components[i]; i++)
|
||||
{
|
||||
parent_id = atoi(components[i][0]);
|
||||
char *id = g_strdup_printf("%s.%s", parent_name, components[i][3]);
|
||||
// 递归读取
|
||||
rc = _get_component_recursively(version, version_id, parent_id, id, schemas, db);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
for (int j = 0; components[j]; j++)
|
||||
{
|
||||
for (int k = 0; k < 12; k++)
|
||||
free(components[j][k]);
|
||||
free(components[j]);
|
||||
}
|
||||
free(components);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; components[j]; j++)
|
||||
{
|
||||
for (int k = 0; k < 12; k++)
|
||||
free(components[j][k]);
|
||||
free(components[j]);
|
||||
}
|
||||
free(components);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// 读取所有组件配置
|
||||
static void _get_schemas()
|
||||
{
|
||||
char *user_name = getlogin();
|
||||
if (user_name == NULL)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "Get user name failed! use root config");
|
||||
closelog();
|
||||
user_name = "root";
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
}
|
||||
|
||||
char db_file[PATH_MAX];
|
||||
|
@ -430,6 +401,7 @@ static void _get_schemas()
|
|||
sprintf(db_file, "/root/.config/kylin-config/user.db");
|
||||
else
|
||||
sprintf(db_file, "/home/%s/.config/kylin-config/user.db", user_name);
|
||||
// syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s \n", __func__, db_file);
|
||||
|
||||
// 读取数据库数据
|
||||
sqlite3 *db = NULL;
|
||||
|
@ -439,167 +411,352 @@ static void _get_schemas()
|
|||
int rc = sqlite3_open(db_file, &db);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "open %s failed with error code %d! try to open /etc/kylin-config/user.db.", db_file, rc);
|
||||
closelog();
|
||||
rc = sqlite3_open("/etc/kylin-config/user.db", &db);
|
||||
if (rc != SQLITE_OK)
|
||||
if (0 == strcmp(db_file, "/root/.config/kylin-config/user.db"))
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "open /etc/kylin-config/user.db failed with error code %d", rc);
|
||||
closelog();
|
||||
goto out;
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s failed! %s try to open /etc/kylin-config/user.db.\n", __func__, db_file, sqlite3_errmsg(db));
|
||||
rc = sqlite3_open("/etc/kylin-config/user.db", &db);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open /etc/kylin-config/user.db failed. %s\n", __func__, sqlite3_errmsg(db));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶层hash, 元素为appData:hash(versionData:hash(s:KSettingsSchema))
|
||||
if (NULL == schemas_table)
|
||||
schemas_table = g_hash_table_new_full(data_hash, data_equal, app_data_destroy, (GDestroyNotify)g_hash_table_destroy);
|
||||
if (NULL == schemas_table)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "Creat hash Table failed");
|
||||
closelog();
|
||||
goto out;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
char sql[100];
|
||||
char ***apps = NULL;
|
||||
rc = sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :无法开始事务: %s\n", __func__, err_msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
strcpy(sql, "SELECT * FROM app");
|
||||
line_count = 0;
|
||||
rc = sqlite3_exec(db, sql, _sql_call_get_lines, &apps, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "查询失败: %s\n", err_msg);
|
||||
closelog();
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询应用名失败: %s\n", __func__, err_msg);
|
||||
goto out;
|
||||
}
|
||||
while (apps && apps[i])
|
||||
|
||||
line_count = 0;
|
||||
sprintf(sql, "SELECT * FROM version");
|
||||
rc = sqlite3_exec(db, sql, _sql_call_get_lines, &versions, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
char ***versions = NULL;
|
||||
int app_id = atoi(apps[i][0]);
|
||||
AppData *app_data = calloc(1, sizeof *app_data);
|
||||
app_data->name = strdup(apps[i][1]);
|
||||
app_data->default_version = strdup(apps[i][2]);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :查询版本号失败: %s\n", __func__, err_msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
line_count = 0;
|
||||
sprintf(sql, "SELECT * FROM version WHERE app_id = %d", app_id);
|
||||
rc = sqlite3_exec(db, sql, _sql_call_get_lines, &versions, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "查询失败: %s\n", err_msg);
|
||||
closelog();
|
||||
for (int j = 0; apps[j]; j++)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
free(apps[j][k]);
|
||||
free(apps[j]);
|
||||
}
|
||||
free(apps);
|
||||
goto out;
|
||||
}
|
||||
// 第二层hash,元素为versionData:hash(s:KSettingsSchema)
|
||||
GHashTable *version = g_hash_table_lookup(schemas_table, app_data);
|
||||
if (NULL == version)
|
||||
{
|
||||
version = g_hash_table_new_full(data_hash, data_equal, version_data_destroy, (GDestroyNotify)g_hash_table_destroy);
|
||||
if (NULL == version)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "Creat hash2 Table failed");
|
||||
closelog();
|
||||
goto out;
|
||||
}
|
||||
g_hash_table_insert(schemas_table, app_data, version);
|
||||
}
|
||||
else
|
||||
app_data_destroy(app_data);
|
||||
line_count = 0;
|
||||
strcpy(sql, "SELECT * FROM configures");
|
||||
rc = sqlite3_exec(db, sql, _sql_call_get_lines, &configures, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :读取组件所有配置失败: %s\n", __func__, err_msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
int version_i = 0;
|
||||
while (versions[version_i])
|
||||
rc = sqlite3_exec(db, "COMMIT", NULL, NULL, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :无法提交事务: %s\n", __func__, err_msg);
|
||||
goto out;
|
||||
}
|
||||
sqlite3_close(db);
|
||||
|
||||
if (!apps || !versions || ! configures)
|
||||
return;
|
||||
|
||||
// 顶层hash, 元素为appData:hash(versionData:hash(s:KSettingsSchema))
|
||||
if (NULL == schemas_table)
|
||||
schemas_table = g_hash_table_new_full(data_hash, data_equal, app_data_destroy, (GDestroyNotify)g_hash_table_destroy);
|
||||
if (NULL == schemas_table)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Creat hash Table failed\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
int app_id = 0, version_id = 0;
|
||||
GHashTable *version = NULL;
|
||||
GHashTable *schemas = NULL;
|
||||
KSettingsSchema *schema = NULL;
|
||||
char curr_id[512] = {0};
|
||||
|
||||
#define APP_COLUMN apps[app_id - 1]
|
||||
#define VER_COLUMN versions[version_id - 1]
|
||||
// 遍历配置
|
||||
for (int i = 0; configures[i]; i++)
|
||||
{
|
||||
// 版本id改变
|
||||
if (version_id != atoi(configures[i][1]))
|
||||
{
|
||||
int version_id = atoi(versions[version_i][0]);
|
||||
VersionData *version_data = calloc(1, sizeof *version_data);
|
||||
version_data->name = strdup(versions[version_i][2]);
|
||||
version_data->compatible = _split_string(versions[version_i][3], '.');
|
||||
// 第三层hash,元素为s:KSettingsSchema
|
||||
GHashTable *schemas = g_hash_table_lookup(version, version_data);
|
||||
AppData *app_data = NULL;
|
||||
VersionData *version_data = NULL;
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read a new version id %s, old id is %d\n", __func__, configures[i][1], version_id);
|
||||
version_id = atoi(configures[i][1]);
|
||||
|
||||
version_data = calloc(1, sizeof *version_data);
|
||||
version_data->name = strdup(VER_COLUMN[2]);
|
||||
version_data->compatible = _split_string(VER_COLUMN[3], '.');
|
||||
|
||||
// 版本id对应的应用id改变
|
||||
if (app_id != atoi(VER_COLUMN[1]))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read a new app id %s, old id is %d\n", __func__, VER_COLUMN[1], app_id);
|
||||
app_id = atoi(VER_COLUMN[1]);
|
||||
|
||||
app_data = calloc(1, sizeof *app_data);
|
||||
app_data->name = strdup(APP_COLUMN[1]);
|
||||
app_data->default_version = strdup(APP_COLUMN[2]);
|
||||
|
||||
version = g_hash_table_lookup(schemas_table, app_data);
|
||||
if (NULL == version)
|
||||
{
|
||||
version = g_hash_table_new_full(data_hash, data_equal, version_data_destroy, (GDestroyNotify)g_hash_table_destroy);
|
||||
if (NULL == version)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Creat hash2 Table failed\n", __func__);
|
||||
app_data_destroy(app_data);
|
||||
version_data_destroy(version_data);
|
||||
goto out;
|
||||
}
|
||||
g_hash_table_insert(schemas_table, app_data, version);
|
||||
}
|
||||
else
|
||||
app_data_destroy(app_data);
|
||||
}
|
||||
|
||||
schemas = g_hash_table_lookup(version, version_data);
|
||||
if (NULL == schemas)
|
||||
{
|
||||
schemas = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)schema_data_destroy);
|
||||
g_hash_table_insert(version, version_data, schemas);
|
||||
if (NULL == schemas)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "Creat schemas hash Table failed");
|
||||
closelog();
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Creat schemas hash Table failed\n", __func__);
|
||||
version_data_destroy(version_data);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
version_data_destroy(version_data);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read %s configure wiht version number %s\n", __func__, APP_COLUMN[1], VER_COLUMN[2]);
|
||||
|
||||
rc = _get_component_recursively(versions[version_i][2], version_id, 0, apps[i][1], schemas, db);
|
||||
if (rc != SQLITE_OK)
|
||||
schema = g_hash_table_lookup(schemas, APP_COLUMN[1]);
|
||||
if (NULL == schema)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "Read data failed");
|
||||
closelog();
|
||||
for (int j = 0; j < i + 1; j++)
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Creat node %s\n", __func__, APP_COLUMN[1]);
|
||||
schema = calloc(1, sizeof *schema);
|
||||
if (NULL == schema)
|
||||
goto out;
|
||||
|
||||
schema->id = strdup(APP_COLUMN[1]);
|
||||
schema->version = strdup(VER_COLUMN[2]);
|
||||
g_hash_table_insert(schemas, strdup(APP_COLUMN[1]), schema);
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Clear node %s\n", __func__, APP_COLUMN[1]);
|
||||
if (schema->values)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
free(apps[j][k]);
|
||||
free(apps[j]);
|
||||
g_hash_table_destroy(schema->values);
|
||||
schema->values = NULL;
|
||||
}
|
||||
free(apps);
|
||||
for (int j = 0; versions[j]; j++)
|
||||
if (schema->children)
|
||||
{
|
||||
for (int k = 0; k < 4; k++)
|
||||
free(versions[j][k]);
|
||||
free(versions[j]);
|
||||
g_array_free(schema->children, TRUE);
|
||||
schema->children = NULL;
|
||||
}
|
||||
free(versions);
|
||||
}
|
||||
}
|
||||
char *node_name = configures[i][2];
|
||||
char *node_type = configures[i][3];
|
||||
char *permission = configures[i][4];
|
||||
char *description = configures[i][5];
|
||||
char *summary = configures[i][6];
|
||||
char *value_type = configures[i][8];
|
||||
char *custom_value = configures[i][9];
|
||||
char *default_value = configures[i][10];
|
||||
char *value_range = configures[i][11];
|
||||
char *extends = configures[i][12];
|
||||
// 一个新的组件
|
||||
if (0 == strcmp(node_type, "schema"))
|
||||
{
|
||||
int parent_id = atoi(configures[i][7]);
|
||||
char parent_name[512], tmp[512];
|
||||
memset(parent_name, 0, 512);
|
||||
memset(tmp, 0, 512);
|
||||
if (0 == parent_id)
|
||||
{
|
||||
strcpy(parent_name, APP_COLUMN[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (0 != parent_id)
|
||||
{
|
||||
strcat(tmp, ".");
|
||||
strcat(tmp, configures[parent_id - 1][2]);
|
||||
parent_id = atoi(configures[parent_id - 1][7]);
|
||||
}
|
||||
sprintf(parent_name, "%s%s", APP_COLUMN[1], tmp);
|
||||
}
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s's parent name %s\n", __func__, node_name, parent_name);
|
||||
|
||||
// 给父组件增加子组件名
|
||||
KSettingsSchema *parent_schema = g_hash_table_lookup(schemas, parent_name);
|
||||
if (NULL != parent_schema)
|
||||
{
|
||||
if (NULL == parent_schema->children)
|
||||
{
|
||||
parent_schema->children = g_array_new(FALSE, FALSE, sizeof(char *));
|
||||
}
|
||||
char *tmp = g_strdup(node_name);
|
||||
g_array_append_val(parent_schema->children, tmp);
|
||||
}
|
||||
|
||||
char schema_name[512];
|
||||
memset(schema_name, 0, 512);
|
||||
sprintf(schema_name, "%s.%s", parent_name, node_name);
|
||||
schema = g_hash_table_lookup(schemas, schema_name);
|
||||
if (NULL == schema)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Creat node %s\n", __func__, schema_name);
|
||||
schema = calloc(1, sizeof *schema);
|
||||
if (NULL == schema)
|
||||
{
|
||||
goto out;
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> Creat HashTable fail\n", __func__);
|
||||
}
|
||||
|
||||
schema->id = strdup(schema_name);
|
||||
schema->version = strdup(VER_COLUMN[2]);
|
||||
if (permission)
|
||||
schema->permission = strdup(permission);
|
||||
if (description)
|
||||
schema->description = strdup(description);
|
||||
if (summary)
|
||||
schema->summary = strdup(summary);
|
||||
if (extends)
|
||||
schema->extends = strdup(extends);
|
||||
g_hash_table_insert(schemas, strdup(schema_name), schema);
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Clear node %s\n", __func__, APP_COLUMN[1]);
|
||||
if (schema->values)
|
||||
{
|
||||
g_hash_table_destroy(schema->values);
|
||||
schema->values = NULL;
|
||||
}
|
||||
if (schema->children)
|
||||
{
|
||||
g_array_free(schema->children, TRUE);
|
||||
schema->children = NULL;
|
||||
}
|
||||
g_free(schema->permission);
|
||||
g_free(schema->description);
|
||||
g_free(schema->summary);
|
||||
g_free(schema->extends);
|
||||
if (permission)
|
||||
schema->permission = strdup(permission);
|
||||
if (description)
|
||||
schema->description = strdup(description);
|
||||
if (summary)
|
||||
schema->summary = strdup(summary);
|
||||
if (extends)
|
||||
schema->extends = strdup(extends);
|
||||
}
|
||||
}
|
||||
else if (0 == strcmp(node_type, "key"))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read %s configure wiht version number %s\n", __func__, schema->id, VER_COLUMN[2]);
|
||||
// hash表 s:hash(s:s)
|
||||
if (NULL == schema->values)
|
||||
schema->values = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_hash_table_destroy);
|
||||
// hash表 s:s
|
||||
GHashTable *item = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
if (NULL == item)
|
||||
{
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> Memary error\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
version_i++;
|
||||
if (node_name)
|
||||
g_hash_table_insert(item, "node_name", g_strdup(node_name)); // 键名
|
||||
if (permission)
|
||||
g_hash_table_insert(item, "permission", g_strdup(permission)); // 读写权限
|
||||
if (description)
|
||||
g_hash_table_insert(item, "description", g_strdup(description)); // 详细描述
|
||||
if (summary)
|
||||
g_hash_table_insert(item, "summary", g_strdup(summary)); // 概要
|
||||
if (value_type)
|
||||
g_hash_table_insert(item, "value_type", g_strdup(value_type)); // 类型
|
||||
if (custom_value)
|
||||
g_hash_table_insert(item, "custom_value", g_strdup(custom_value)); // 键值
|
||||
if (default_value)
|
||||
g_hash_table_insert(item, "default_value", g_strdup(default_value)); // 默认值
|
||||
if (value_range)
|
||||
g_hash_table_insert(item, "range", g_strdup(value_range)); // 取值范围
|
||||
|
||||
g_hash_table_insert(schema->values, g_strdup(node_name), item);
|
||||
}
|
||||
if (version)
|
||||
{
|
||||
for (int j = 0; versions[j]; j++)
|
||||
{
|
||||
for (int k = 0; k < 4; k++)
|
||||
free(versions[j][k]);
|
||||
free(versions[j]);
|
||||
}
|
||||
free(versions);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
#undef APP_COLUMN
|
||||
#undef VER_COLUMN
|
||||
|
||||
out:
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
sqlite3_exec(db, "ROLLBACK", 0, 0, &err_msg);
|
||||
sqlite3_free(err_msg);
|
||||
sqlite3_close(db);
|
||||
|
||||
g_hash_table_destroy(schemas_table);
|
||||
schemas_table = NULL;
|
||||
}
|
||||
if (apps)
|
||||
{
|
||||
for (int j = 0; apps[j]; j++)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
free(apps[j][k]);
|
||||
{
|
||||
if (apps[j][k])
|
||||
free(apps[j][k]);
|
||||
}
|
||||
free(apps[j]);
|
||||
}
|
||||
free(apps);
|
||||
}
|
||||
out:
|
||||
if (rc != SQLITE_OK && NULL != schemas_table)
|
||||
if (versions)
|
||||
{
|
||||
g_hash_table_destroy(schemas_table);
|
||||
schemas_table = NULL;
|
||||
for (int j = 0; versions[j]; j++)
|
||||
{
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
if (versions[j][k])
|
||||
free(versions[j][k]);
|
||||
}
|
||||
free(versions[j]);
|
||||
}
|
||||
free(versions);
|
||||
}
|
||||
if (configures)
|
||||
{
|
||||
for (int j = 0; configures[j]; j++)
|
||||
{
|
||||
for (int k = 0; k < 13; k++)
|
||||
{
|
||||
if (configures[j][k])
|
||||
free(configures[j][k]);
|
||||
}
|
||||
free(configures[j]);
|
||||
}
|
||||
free(configures);
|
||||
}
|
||||
if (err_msg)
|
||||
sqlite3_free(err_msg);
|
||||
if (db)
|
||||
sqlite3_close(db);
|
||||
}
|
||||
/*读取数据库*/
|
||||
|
||||
// 在schemas_table查找指定schema的配置句柄KSettingsSchema
|
||||
KSettingsSchema *kdk_conf2_schema_table_lookup(const char *id, const char *version)
|
||||
|
@ -614,6 +771,7 @@ KSettingsSchema *kdk_conf2_schema_table_lookup(const char *id, const char *versi
|
|||
g_hash_table_iter_init(&iter, schemas_table);
|
||||
while (g_hash_table_iter_next(&iter, &app_data, &version_hash))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> find %s\n", __func__, app_data->name);
|
||||
if (0 == strcmp(app_data->name, list[0]))
|
||||
{
|
||||
VersionData *version_data = NULL;
|
||||
|
@ -624,8 +782,16 @@ KSettingsSchema *kdk_conf2_schema_table_lookup(const char *id, const char *versi
|
|||
g_hash_table_iter_init(&iter_version, version_hash);
|
||||
while (g_hash_table_iter_next(&iter_version, &version_data, &schemas))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> find %s '%s configure\n", __func__, app_data->name, version_data->name);
|
||||
if (0 == strcmp(version_data->name, version))
|
||||
{
|
||||
GHashTableIter iter_schema;
|
||||
g_hash_table_iter_init(&iter_schema, schemas);
|
||||
char *few = NULL;
|
||||
while (g_hash_table_iter_next(&iter_schema, &few, &result))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s with %s version 's id %s\n", __func__, app_data->name, version_data->name, few);
|
||||
}
|
||||
result = g_hash_table_lookup(schemas, id);
|
||||
break;
|
||||
}
|
||||
|
@ -748,12 +914,12 @@ int kdk_conf2_schema_find_child(KSettingsSchema *schema, const char *name)
|
|||
|
||||
char *kdk_conf2_schema_key_value_type(GHashTable *key)
|
||||
{
|
||||
GET_KEY_ATTR(data_type)
|
||||
GET_KEY_ATTR(value_type)
|
||||
}
|
||||
|
||||
char *kdk_conf2_schema_key_get_value(GHashTable *key)
|
||||
{
|
||||
GET_KEY_ATTR(user_value)
|
||||
GET_KEY_ATTR(custom_value)
|
||||
}
|
||||
|
||||
char *kdk_conf2_schema_key_get_default_value(GHashTable *key)
|
||||
|
@ -807,8 +973,8 @@ int kdk_conf2_schema_key_range_check(GHashTable *key, const char *value)
|
|||
|
||||
// if (NULL == tmp)
|
||||
// {
|
||||
if (0 == g_strcmp0(value, nick))
|
||||
result = TRUE;
|
||||
if (0 == g_strcmp0(value, nick))
|
||||
result = TRUE;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
|
@ -868,7 +1034,7 @@ out:
|
|||
|
||||
char *kdk_conf2_schema_key_get_name(GHashTable *key)
|
||||
{
|
||||
GET_KEY_ATTR(property)
|
||||
GET_KEY_ATTR(node_name)
|
||||
}
|
||||
|
||||
char *kdk_conf2_schema_key_get_summary(GHashTable *key)
|
||||
|
@ -920,9 +1086,14 @@ KSettingsSchema *kdk_conf2_schema_reload(const char *id, const char *version)
|
|||
{
|
||||
if (0 == strcmp(version_data->name, version))
|
||||
{
|
||||
result = g_hash_table_lookup(schemas, id);
|
||||
// 用新读取的配置替换掉schemas_table中的老配置
|
||||
KSettingsSchema *schema = _get_schema(id, version);
|
||||
result = g_hash_table_lookup(schemas, id);
|
||||
if (NULL == schema)
|
||||
{
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> :Update schema data failed\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
GHashTable *tmp = result->values;
|
||||
result->values = schema->values;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define KSETTINGSSCHEMA_H
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#if __cplusplus
|
||||
extern "C"
|
||||
|
@ -45,6 +46,10 @@ extern "C"
|
|||
GArray *children;
|
||||
char *id;
|
||||
char *version;
|
||||
char *permission;
|
||||
char *description;
|
||||
char *summary;
|
||||
char *extends;
|
||||
} SchemaData;
|
||||
|
||||
typedef struct _SchemaData KSettingsSchema;
|
||||
|
|
|
@ -26,11 +26,13 @@
|
|||
#include <gio/gio.h>
|
||||
#include <pthread.h>
|
||||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <gio/gsettings.h>
|
||||
|
||||
#include "libkysettings.h"
|
||||
#include "ksettingsschema.h"
|
||||
#include "libkylog.h"
|
||||
|
||||
static GMainLoop *dbus_signal_loop = NULL; // glib主循环,用于处理dbus消息事件,主循环不开启无法接收dbus信号
|
||||
static guint ref_count = 0; // 记录dbus_signal_loop的引用计数
|
||||
|
@ -44,6 +46,7 @@ typedef struct _KSettingsPrivate
|
|||
GMainContext *main_context;
|
||||
KSettingsSchema *schema;
|
||||
GDBusConnection *conn;
|
||||
GSettings *gsettings;
|
||||
guint sub_id[2];
|
||||
} KSettingsPrivate;
|
||||
|
||||
|
@ -104,6 +107,11 @@ static void k_settings_finalize(GObject *object)
|
|||
g_dbus_connection_signal_unsubscribe(ksettings->priv->conn, ksettings->priv->sub_id[SIGNAL_CHANGED]);
|
||||
g_dbus_connection_signal_unsubscribe(ksettings->priv->conn, ksettings->priv->sub_id[SIGNAL_RELOAD]);
|
||||
g_object_unref(ksettings->priv->conn);
|
||||
if (ksettings->priv->gsettings)
|
||||
{
|
||||
g_settings_sync();
|
||||
g_object_unref(ksettings->priv->gsettings);
|
||||
}
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(k_settings_parent_class)->finalize(object);
|
||||
|
@ -144,11 +152,6 @@ static void k_settings_class_init(KSettingsClass *class)
|
|||
0);
|
||||
}
|
||||
|
||||
static int verify_file(char *file_name)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief _g_main_loop_thread 开启main_loop获取消息循环
|
||||
* @param data
|
||||
|
@ -161,6 +164,20 @@ static void *_g_main_loop_thread(void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void _on_gsettings_key_changed(GSettings *setting, const char *key, void *user_data)
|
||||
{
|
||||
GVariant *value = g_settings_get_value(setting, key);
|
||||
KSettings *ksetting = (KSettings *)user_data;
|
||||
char *conf2_value = kdk_conf2_get_value(ksetting, key);
|
||||
if (0 == strcmp(conf2_value, g_variant_print(value, TRUE)))
|
||||
return;
|
||||
if (kdk_conf2_set_value(ksetting, key, g_variant_print(value, TRUE)))
|
||||
{
|
||||
// g_signal_emit(ksetting, k_settings_signals[SIGNAL_CHANGED], g_quark_from_string(key), key);
|
||||
}
|
||||
g_variant_unref(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief _on_key_changed DBus服务中key_changed信号响应函数
|
||||
* @param connection
|
||||
|
@ -180,15 +197,41 @@ static void _on_key_changed(GDBusConnection *connection,
|
|||
gpointer user_data)
|
||||
{
|
||||
KSettings *ksettings = (KSettings *)user_data;
|
||||
char *id, *version, *key, *user;
|
||||
g_variant_get(parameters, "(ssss)", &id, &version, &key, &user);
|
||||
char *id, *version, *key;
|
||||
g_variant_get(parameters, "(sss)", &id, &version, &key);
|
||||
char *schema_id = kdk_conf2_schema_get_id(ksettings->priv->schema);
|
||||
if ((0 == strcmp(schema_id, id)) && (0 == strcmp(g_get_user_name(), user)))
|
||||
char *schema_version = kdk_conf2_schema_get_version(ksettings->priv->schema);
|
||||
if ((0 == strcmp(schema_id, id)) && (0 == strcmp(schema_version, version)))
|
||||
{
|
||||
ksettings->priv->schema = kdk_conf2_schema_reload(id, version);
|
||||
g_signal_emit(ksettings, k_settings_signals[SIGNAL_CHANGED], g_quark_from_string(key), key);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s changed signal\n", key);
|
||||
if (ksettings->priv->gsettings)
|
||||
{
|
||||
char *endptr = NULL;
|
||||
GError *error = NULL;
|
||||
GVariant *gsetting_value = g_settings_get_value(ksettings->priv->gsettings, key);
|
||||
if (NULL != gsetting_value)
|
||||
{
|
||||
char *value = kdk_conf2_get_value(ksettings, key);
|
||||
if (0 != strcmp(value, g_variant_print(gsetting_value, TRUE)))
|
||||
{
|
||||
char *type = kdk_conf2_get_type(ksettings, key);
|
||||
GVariant *variant = g_variant_parse(type, value, NULL, &endptr, &error);
|
||||
if (NULL == variant)
|
||||
{
|
||||
klog_err("[kysdk-conf2] %s -> %s\n", __func__, error->message);
|
||||
return FALSE;
|
||||
}
|
||||
g_settings_set_value(ksettings->priv->gsettings, key, variant);
|
||||
g_variant_unref(variant);
|
||||
}
|
||||
g_variant_unref(gsetting_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_free(schema_id);
|
||||
g_free(schema_version);
|
||||
mutex = 0;
|
||||
}
|
||||
|
||||
|
@ -243,7 +286,7 @@ static int _type_check(KSettings *ksettings, const char *key, const char *value)
|
|||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE(type), value, NULL, &endptr, &error);
|
||||
if (NULL == variant)
|
||||
{
|
||||
printf("parser error : %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] % -> parser error : %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
g_free(type);
|
||||
return FALSE;
|
||||
|
@ -264,25 +307,21 @@ static int _type_check(KSettings *ksettings, const char *key, const char *value)
|
|||
* @param value 键值,可为NULL,根据method传参。
|
||||
* @return boolean类型 成功返回1 失败返回0
|
||||
*/
|
||||
static int _call_method(GDBusConnection *connection, const char *method, const char *id, const char *version, const char *key, const char *value)
|
||||
static int _call_method(const char *method, const char *id, const char *version, const char *key, const char *value)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> Connection Error: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GDBusProxy *proxy;
|
||||
GVariant *result;
|
||||
int response = FALSE;
|
||||
|
||||
// 获取 DBus 会话总线
|
||||
if (NULL == connection)
|
||||
{
|
||||
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr("Connection Error: %s\n", error->message);
|
||||
g_error_free(error);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建代理对象
|
||||
proxy = g_dbus_proxy_new_sync(connection,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
|
@ -294,19 +333,33 @@ static int _call_method(GDBusConnection *connection, const char *method, const c
|
|||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr("Proxy Error: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> Proxy Error: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
return response;
|
||||
}
|
||||
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Get user name failed! use root config\n", __func__);
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
}
|
||||
|
||||
// 调用代理对象的方法
|
||||
GVariant *variant = NULL;
|
||||
if (0 == strcmp(method, "set"))
|
||||
variant = g_variant_new("(sssss)", getlogin(), id, version, key, value);
|
||||
variant = g_variant_new("(sssss)", user_name, id, version, key, value);
|
||||
if (0 == strcmp(method, "reset"))
|
||||
variant = g_variant_new("(ssss)", getlogin(), id, version, key);
|
||||
variant = g_variant_new("(ssss)", user_name, id, version, key);
|
||||
if (0 == strcmp(method, "reset_recursively"))
|
||||
variant = g_variant_new("(sss)", getlogin(), id, version);
|
||||
variant = g_variant_new("(sss)", user_name, id, version);
|
||||
|
||||
result = g_dbus_proxy_call_sync(proxy,
|
||||
method,
|
||||
|
@ -317,7 +370,7 @@ static int _call_method(GDBusConnection *connection, const char *method, const c
|
|||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr("Method Call Error: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> %s call fialed: %s\n", __func__, method, error->message);
|
||||
g_error_free(error);
|
||||
return response;
|
||||
}
|
||||
|
@ -328,6 +381,7 @@ static int _call_method(GDBusConnection *connection, const char *method, const c
|
|||
// 释放资源
|
||||
g_variant_unref(result);
|
||||
g_object_unref(proxy);
|
||||
g_object_unref(connection);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
@ -335,9 +389,7 @@ KSettings *kdk_conf2_new(const char *id, const char *version)
|
|||
{
|
||||
if (NULL == id)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "id is nullptr");
|
||||
closelog();
|
||||
syslog(LOG_INFO, "[kysdk-conf2] id is nullptr\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -346,40 +398,66 @@ KSettings *kdk_conf2_new(const char *id, const char *version)
|
|||
|
||||
if (NULL == schemas_table)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "load user.db failed");
|
||||
closelog();
|
||||
syslog(LOG_INFO, "[kysdk-conf2] load user.db failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KSettingsSchema *schema = kdk_conf2_schema_table_lookup(id, version);
|
||||
if (NULL == schema)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "invalied schema id");
|
||||
closelog();
|
||||
syslog(LOG_INFO, "[kysdk-conf2] invalied schema id\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KSettings *ksettings = g_object_new(K_TYPE_SETTINGS, NULL);
|
||||
if (!K_IS_SETTINGS(ksettings))
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "init KSettings failed");
|
||||
closelog();
|
||||
syslog(LOG_INFO, "[kysdk-conf2] init KSettings failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **gsettings_schemas = g_settings_list_schemas();
|
||||
if (gsettings_schemas)
|
||||
{
|
||||
for (int i = 0; gsettings_schemas[i]; i++)
|
||||
{
|
||||
char *p = strstr(gsettings_schemas[i], id);
|
||||
if (NULL == p)
|
||||
continue;
|
||||
int len = strlen(id);
|
||||
if (*(p + len) == '\0')
|
||||
{
|
||||
ksettings->priv->gsettings = g_settings_new(gsettings_schemas[i]);
|
||||
g_signal_connect(ksettings->priv->gsettings, "changed", G_CALLBACK(_on_gsettings_key_changed), ksettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksettings->priv->schema = schema;
|
||||
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
}
|
||||
|
||||
// 创建dbus服务的链接,用于调用接口及接收信号
|
||||
GError *error = NULL;
|
||||
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
if (0 == strcmp(user_name, "root"))
|
||||
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
else
|
||||
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
openlog("kysdk-conf2", LOG_PID, LOG_USER);
|
||||
syslog(LOG_INFO, "Connection Error: %s\n", error->message);
|
||||
closelog();
|
||||
syslog(LOG_INFO, "[kysdk-conf2] Connection Error: %s\n", error->message);
|
||||
g_object_unref(ksettings);
|
||||
ksettings = NULL;
|
||||
g_error_free(error);
|
||||
|
@ -425,7 +503,6 @@ KSettings *kdk_conf2_new(const char *id, const char *version)
|
|||
|
||||
void kdk_conf2_ksettings_destroy(KSettings *ksettings)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
if (!K_IS_SETTINGS(ksettings))
|
||||
return;
|
||||
|
||||
|
@ -443,7 +520,6 @@ void kdk_conf2_ksettings_destroy(KSettings *ksettings)
|
|||
|
||||
char *kdk_conf2_get_id(KSettings *ksettings)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
if (!K_IS_SETTINGS(ksettings))
|
||||
return NULL;
|
||||
return kdk_conf2_schema_get_id(ksettings->priv->schema);
|
||||
|
@ -451,7 +527,6 @@ char *kdk_conf2_get_id(KSettings *ksettings)
|
|||
|
||||
char *kdk_conf2_get_version(KSettings *ksettings)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
if (!K_IS_SETTINGS(ksettings))
|
||||
return NULL;
|
||||
return strdup(kdk_conf2_schema_get_version(ksettings->priv->schema));
|
||||
|
@ -459,9 +534,6 @@ char *kdk_conf2_get_version(KSettings *ksettings)
|
|||
|
||||
KSettings *kdk_conf2_get_child(KSettings *ksettings, const char *name)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != name);
|
||||
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == name)
|
||||
return NULL;
|
||||
|
||||
|
@ -477,7 +549,6 @@ KSettings *kdk_conf2_get_child(KSettings *ksettings, const char *name)
|
|||
|
||||
char **kdk_conf2_list_children(KSettings *ksettings)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
if (!K_IS_SETTINGS(ksettings))
|
||||
return NULL;
|
||||
|
||||
|
@ -486,7 +557,6 @@ char **kdk_conf2_list_children(KSettings *ksettings)
|
|||
|
||||
char **kdk_conf2_list_keys(KSettings *ksettings)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
if (!K_IS_SETTINGS(ksettings))
|
||||
return NULL;
|
||||
|
||||
|
@ -495,8 +565,6 @@ char **kdk_conf2_list_keys(KSettings *ksettings)
|
|||
|
||||
char *kdk_conf2_get_range(KSettings *ksettings, const char *key)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return NULL;
|
||||
|
||||
|
@ -506,8 +574,6 @@ char *kdk_conf2_get_range(KSettings *ksettings, const char *key)
|
|||
|
||||
int kdk_conf2_range_check(KSettings *ksettings, const char *key, const char *value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return FALSE;
|
||||
|
||||
|
@ -519,20 +585,27 @@ int kdk_conf2_range_check(KSettings *ksettings, const char *key, const char *val
|
|||
|
||||
int kdk_conf2_set_value(KSettings *ksettings, const char *key, const char *value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Set the key '%s' of %s to %s\n", __func__, key, ksettings->priv->schema->id, value);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> assert ksettings is KSettings failed\n", __func__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(0 == kdk_conf2_is_writable(ksettings, key))
|
||||
if (0 == kdk_conf2_is_writable(ksettings, key))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s is unwritable\n", __func__, key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_type_check(ksettings, key, value))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s type invalid\n", __func__, key);
|
||||
return FALSE;
|
||||
}
|
||||
if (!kdk_conf2_range_check(ksettings, key, value))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s vlaue is not in range\n", __func__, key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -546,7 +619,7 @@ int kdk_conf2_set_value(KSettings *ksettings, const char *key, const char *value
|
|||
char *id = kdk_conf2_schema_get_id(ksettings->priv->schema);
|
||||
char *version = kdk_conf2_schema_get_version(ksettings->priv->schema);
|
||||
if (NULL == curr_value || 0 != strcmp(curr_value, value))
|
||||
result = _call_method(ksettings->priv->conn, "set",
|
||||
result = _call_method("set",
|
||||
id,
|
||||
version,
|
||||
key, value);
|
||||
|
@ -555,13 +628,15 @@ int kdk_conf2_set_value(KSettings *ksettings, const char *key, const char *value
|
|||
g_free(id);
|
||||
g_free(version);
|
||||
g_free(curr_value);
|
||||
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Set value finished. Return %s\n", __func__, result ? "true" : "false");
|
||||
return result;
|
||||
}
|
||||
|
||||
char *kdk_conf2_get_value(KSettings *ksettings, const char *key)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Get value start\n", __func__);
|
||||
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return NULL;
|
||||
|
||||
|
@ -574,13 +649,12 @@ char *kdk_conf2_get_value(KSettings *ksettings, const char *key)
|
|||
{
|
||||
value = kdk_conf2_schema_key_get_default_value(key_hash);
|
||||
}
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Get value end\n", __func__);
|
||||
return value;
|
||||
}
|
||||
|
||||
char *kdk_conf2_get_default_value(KSettings *ksettings, const char *key)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return NULL;
|
||||
|
||||
|
@ -590,8 +664,6 @@ char *kdk_conf2_get_default_value(KSettings *ksettings, const char *key)
|
|||
|
||||
int kdk_conf2_set_boolean(KSettings *ksettings, const char *key, int value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return FALSE;
|
||||
|
||||
|
@ -632,8 +704,6 @@ int kdk_conf2_get_default_boolean(KSettings *ksettings, const char *key)
|
|||
|
||||
int kdk_conf2_set_double(KSettings *ksettings, const char *key, double value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return 0;
|
||||
|
||||
|
@ -669,8 +739,6 @@ double kdk_conf2_get_default_double(KSettings *ksettings, const char *key)
|
|||
|
||||
int kdk_conf2_set_enum(KSettings *ksettings, const char *key, int value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return 0;
|
||||
|
||||
|
@ -684,7 +752,7 @@ int kdk_conf2_set_enum(KSettings *ksettings, const char *key, int value)
|
|||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("a{si}"), range, NULL, &endptr, &error);
|
||||
if (variant == NULL)
|
||||
{
|
||||
g_print("解析失败: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
goto out;
|
||||
}
|
||||
|
@ -700,7 +768,7 @@ int kdk_conf2_set_enum(KSettings *ksettings, const char *key, int value)
|
|||
{
|
||||
char set_value[1024];
|
||||
sprintf(set_value, "%d", value);
|
||||
result = kdk_conf2_set_value(ksettings, key, set_value);
|
||||
result = kdk_conf2_set_value(ksettings, key, nick);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -726,7 +794,7 @@ int kdk_conf2_get_enum(KSettings *ksettings, const char *key)
|
|||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("a{si}"), range, NULL, &endptr, &error);
|
||||
if (variant == NULL)
|
||||
{
|
||||
g_print("解析失败: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
goto out;
|
||||
}
|
||||
|
@ -767,7 +835,7 @@ int kdk_conf2_get_default_enum(KSettings *ksettings, const char *key)
|
|||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("a{si}"), range, NULL, &endptr, &error);
|
||||
if (variant == NULL)
|
||||
{
|
||||
g_print("解析失败: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
goto out;
|
||||
}
|
||||
|
@ -795,8 +863,6 @@ out:
|
|||
|
||||
int kdk_conf2_set_int(KSettings *ksettings, const char *key, int value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return 0;
|
||||
|
||||
|
@ -833,8 +899,6 @@ int kdk_conf2_get_default_int(KSettings *ksettings, const char *key)
|
|||
|
||||
int kdk_conf2_set_int64(KSettings *ksettings, const char *key, long value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return 0;
|
||||
|
||||
|
@ -857,8 +921,7 @@ long kdk_conf2_get_int64(KSettings *ksettings, const char *key)
|
|||
return result;
|
||||
}
|
||||
|
||||
long kdk_conf2_get_default_int64(KSettings *ksettings,
|
||||
const char *key)
|
||||
long kdk_conf2_get_default_int64(KSettings *ksettings, const char *key)
|
||||
{
|
||||
long result = 0;
|
||||
char *value = kdk_conf2_get_default_value(ksettings, key);
|
||||
|
@ -872,8 +935,6 @@ long kdk_conf2_get_default_int64(KSettings *ksettings,
|
|||
|
||||
int kdk_conf2_set_uint(KSettings *ksettings, const char *key, unsigned int value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return 0;
|
||||
|
||||
|
@ -910,8 +971,6 @@ unsigned int kdk_conf2_get_default_uint(KSettings *ksettings, const char *key)
|
|||
|
||||
int kdk_conf2_set_uint64(KSettings *ksettings, const char *key, unsigned long value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return 0;
|
||||
|
||||
|
@ -948,14 +1007,10 @@ unsigned long kdk_conf2_get_default_uint64(KSettings *ksettings, const char *key
|
|||
|
||||
int kdk_conf2_set_string(KSettings *ksettings, const char *key, const char *value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return 0;
|
||||
|
||||
GVariant *variant = g_variant_new_string(value);
|
||||
int result = kdk_conf2_set_value(ksettings, key, g_variant_print(variant, FALSE));
|
||||
g_variant_unref(variant);
|
||||
int result = kdk_conf2_set_value(ksettings, key, value);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -972,8 +1027,6 @@ char *kdk_conf2_get_default_string(KSettings *ksettings, const char *key)
|
|||
|
||||
int kdk_conf2_set_strv(KSettings *ksettings, const char *key, const char *const *value)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return 0;
|
||||
|
||||
|
@ -1001,7 +1054,7 @@ char **kdk_conf2_get_strv(KSettings *ksettings, const char *key)
|
|||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("as"), value, NULL, &endptr, &error);
|
||||
if (NULL == variant)
|
||||
{
|
||||
g_print("解析失败: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
|
||||
g_free(value);
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
|
@ -1026,7 +1079,7 @@ char **kdk_conf2_get_default_strv(KSettings *ksettings, const char *key)
|
|||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("as"), value, NULL, &endptr, &error);
|
||||
if (NULL == variant)
|
||||
{
|
||||
g_print("解析失败: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> 解析失败: %s\n", __func__, error->message);
|
||||
g_free(value);
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
|
@ -1040,8 +1093,6 @@ char **kdk_conf2_get_default_strv(KSettings *ksettings, const char *key)
|
|||
|
||||
char *kdk_conf2_get_descrition(KSettings *ksettings, const char *key)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return NULL;
|
||||
|
||||
|
@ -1051,8 +1102,6 @@ char *kdk_conf2_get_descrition(KSettings *ksettings, const char *key)
|
|||
|
||||
char *kdk_conf2_get_summary(KSettings *ksettings, const char *key)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return NULL;
|
||||
|
||||
|
@ -1062,8 +1111,6 @@ char *kdk_conf2_get_summary(KSettings *ksettings, const char *key)
|
|||
|
||||
char *kdk_conf2_get_type(KSettings *ksettings, const char *key)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return NULL;
|
||||
|
||||
|
@ -1073,14 +1120,16 @@ char *kdk_conf2_get_type(KSettings *ksettings, const char *key)
|
|||
|
||||
void kdk_conf2_reset(KSettings *ksettings, const char *key)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return;
|
||||
|
||||
if (NULL == kdk_conf2_schema_get_key(ksettings->priv->schema, key))
|
||||
return;
|
||||
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :reset %s value\n", __func__, key);
|
||||
char *id = kdk_conf2_schema_get_id(ksettings->priv->schema);
|
||||
char *version = kdk_conf2_schema_get_version(ksettings->priv->schema);
|
||||
_call_method(ksettings->priv->conn, "reset",
|
||||
_call_method("reset",
|
||||
id,
|
||||
version,
|
||||
key, NULL);
|
||||
|
@ -1090,8 +1139,6 @@ void kdk_conf2_reset(KSettings *ksettings, const char *key)
|
|||
|
||||
int kdk_conf2_is_writable(KSettings *ksettings, const char *key)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
// g_assert(NULL != key);
|
||||
if (!K_IS_SETTINGS(ksettings) || NULL == key)
|
||||
return FALSE;
|
||||
|
||||
|
@ -1108,7 +1155,7 @@ int kdk_conf2_has_key(KSettings *ksettings, const char *key)
|
|||
return FALSE;
|
||||
|
||||
GHashTable *key_hash = kdk_conf2_schema_get_key(ksettings->priv->schema, key);
|
||||
if(NULL == key_hash)
|
||||
if (NULL == key_hash)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
|
@ -1116,7 +1163,6 @@ int kdk_conf2_has_key(KSettings *ksettings, const char *key)
|
|||
|
||||
unsigned long kdk_conf2_connect_signal(KSettings *ksettings, const char *signal_name, KCallBack handler, void *user_data)
|
||||
{
|
||||
// g_assert(K_IS_SETTINGS(ksettings));
|
||||
if (!K_IS_SETTINGS(ksettings))
|
||||
return 0;
|
||||
|
||||
|
@ -1125,15 +1171,7 @@ unsigned long kdk_conf2_connect_signal(KSettings *ksettings, const char *signal_
|
|||
|
||||
void kdk_conf2_reload()
|
||||
{
|
||||
GError *error = NULL;
|
||||
GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr("Connection Error: %s\n", error->message);
|
||||
g_error_free(error);
|
||||
return;
|
||||
}
|
||||
_call_method(connection, "reload", NULL, NULL, NULL, NULL);
|
||||
_call_method("reload", NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
char **kdk_conf2_list_schemas(const char *app, const char *version)
|
||||
|
@ -1183,12 +1221,13 @@ char **kdk_conf2_list_schemas(const char *app, const char *version)
|
|||
|
||||
int kdk_conf2_save_user_configure(const char *path)
|
||||
{
|
||||
if(0 != access(path, F_OK))
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> save user config start\n", __func__);
|
||||
char real_path[4096];
|
||||
memset(real_path, 0, sizeof(real_path));
|
||||
if (!realpath(path, real_path))
|
||||
{
|
||||
if(!verify_file(path))
|
||||
return FALSE;
|
||||
if (mkdir(path, 0777) < 0)
|
||||
return FALSE;
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> path not exists\n", __func__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GDBusConnection *connection;
|
||||
|
@ -1204,7 +1243,7 @@ int kdk_conf2_save_user_configure(const char *path)
|
|||
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr("Connection Error: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> Connection Error: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
return response;
|
||||
}
|
||||
|
@ -1221,11 +1260,26 @@ int kdk_conf2_save_user_configure(const char *path)
|
|||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr("Proxy Error: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> Proxy Error: %s\n", error->message);
|
||||
g_error_free(error);
|
||||
return response;
|
||||
}
|
||||
GVariant *variant = g_variant_new("(ss)", getlogin(), path);
|
||||
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
syslog(LOG_INFO, "【kysdk-conf2】 Get user name failed! use root config\n");
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
}
|
||||
|
||||
GVariant *variant = g_variant_new("(ss)", user_name, real_path);
|
||||
result = g_dbus_proxy_call_sync(proxy,
|
||||
"save",
|
||||
variant,
|
||||
|
@ -1235,7 +1289,7 @@ int kdk_conf2_save_user_configure(const char *path)
|
|||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr("Method Call Error: %s\n", error->message);
|
||||
syslog(LOG_ERR, "[kysdk-conf2] %s -> Method Call Error: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
return response;
|
||||
}
|
||||
|
@ -1246,5 +1300,132 @@ int kdk_conf2_save_user_configure(const char *path)
|
|||
// 释放资源
|
||||
g_variant_unref(result);
|
||||
g_object_unref(proxy);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> save user config end\n", __func__);
|
||||
return response;
|
||||
}
|
||||
|
||||
KSettings *kdk_conf2_new_extends_id(const char *old_id, const char *new_id, const char *version)
|
||||
{
|
||||
KSettings *setting = kdk_conf2_new(new_id, version);
|
||||
if (NULL != setting)
|
||||
return setting;
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> creat new id : %s\n", __func__, new_id);
|
||||
GDBusConnection *connection;
|
||||
GError *error = NULL;
|
||||
GDBusProxy *proxy;
|
||||
GVariant *result;
|
||||
int response = FALSE;
|
||||
|
||||
// 获取 DBus 会话总线
|
||||
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
if (NULL == connection)
|
||||
{
|
||||
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Connection Error: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建代理对象
|
||||
proxy = g_dbus_proxy_new_sync(connection,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
"com.kylin.kysdk.conf2",
|
||||
"/com/kylin/kysdk/conf2",
|
||||
"com.kylin.kysdk.conf2",
|
||||
NULL,
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Proxy Error: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
syslog(LOG_INFO, "【kysdk-conf2】 Get user name failed! use root config\n");
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
}
|
||||
|
||||
GVariant *variant = g_variant_new("(ssss)",
|
||||
old_id,
|
||||
new_id,
|
||||
version ? version : "",
|
||||
user_name);
|
||||
result = g_dbus_proxy_call_sync(proxy,
|
||||
"extends_id",
|
||||
variant,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Method Call Error: %s\n", __func__, error->message);
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 处理方法调用的返回值
|
||||
g_variant_get(result, "(b)", &response);
|
||||
|
||||
// 释放资源
|
||||
g_variant_unref(result);
|
||||
g_object_unref(proxy);
|
||||
|
||||
if (response)
|
||||
{
|
||||
kdk_conf2_schema_update_schemas_table();
|
||||
return kdk_conf2_new(new_id, version);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int kdk_conf2_is_schema(const char *id, const char *version)
|
||||
{
|
||||
if (NULL == id)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s ->: id is NULL\n", __func__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (NULL == schemas_table)
|
||||
kdk_conf2_schema_update_schemas_table();
|
||||
|
||||
if (NULL == schemas_table)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s ->: load user.db failed\n", __func__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
KSettingsSchema *schema = kdk_conf2_schema_table_lookup(id, version);
|
||||
if (NULL == schema)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s ->: schema not existed\n", __func__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *kdk_conf2_get_schema_summary(KSettings *ksettings)
|
||||
{
|
||||
return ksettings->priv->schema->summary ? strdup(ksettings->priv->schema->summary) : NULL;
|
||||
}
|
||||
|
||||
char *kdk_conf2_get_schema_desription(KSettings *ksettings)
|
||||
{
|
||||
return ksettings->priv->schema->description ? strdup(ksettings->priv->schema->description) : NULL;
|
||||
}
|
||||
|
|
|
@ -178,6 +178,7 @@ extern "C"
|
|||
const char *signal_name,
|
||||
KCallBack handler,
|
||||
void *user_data);
|
||||
|
||||
void kdk_conf2_reload (void);
|
||||
|
||||
char ** kdk_conf2_list_schemas (const char *app,
|
||||
|
@ -185,21 +186,16 @@ extern "C"
|
|||
|
||||
int kdk_conf2_save_user_configure (const char *path);
|
||||
|
||||
KSettings * kdk_conf2_new_extends_id (const char *old_id,
|
||||
const char *new_id,
|
||||
const char *version);
|
||||
|
||||
int kdk_conf2_is_schema (const char *id,
|
||||
const char *version);
|
||||
|
||||
char * kdk_conf2_get_schema_summary (KSettings *ksettings);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
char * kdk_conf2_get_schema_desription (KSettings *ksettings);
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif // extern "C"
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
dirs:
|
||||
- basic
|
||||
- industry
|
||||
- vendor
|
||||
- production
|
||||
- project
|
||||
- kcm
|
||||
#通用配置与应用下组名的映射关系
|
||||
mapping:
|
||||
#通用配置组名
|
||||
powermanager:
|
||||
#应用名:组名
|
||||
control-center: powermanager
|
|
@ -0,0 +1,8 @@
|
|||
[whitelist]
|
||||
key2 = /usr/bin/kconf2
|
||||
key3 = /usr/bin/kconf2-editor
|
||||
key4 = /usr/bin/ukui-settings-daemon
|
||||
key5 = /usr/sbin/lightdm
|
||||
key6 = /usr/bin/ukui-screensaver-dialog
|
||||
key7 = /usr/sbin/ukui-greeter
|
||||
key8 = /lib/systemd/systemd-logind
|
|
@ -0,0 +1 @@
|
|||
f45558b6a1cb69ceb6e4e58d8b9a47b551db8543
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/python3.8
|
||||
#
|
||||
# libkysdk-system's Library
|
||||
#
|
||||
|
@ -16,414 +17,91 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Authors: Yunhe Liu <liuyunhe@kylinos.cn>
|
||||
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
|
||||
#
|
||||
#
|
||||
|
||||
#!/usr/bin/python3
|
||||
import yaml, sqlite3
|
||||
import os, re, shutil
|
||||
import logging, traceback
|
||||
|
||||
import os
|
||||
import logging
|
||||
import dbus
|
||||
import dbus.service
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
from gi.repository import GLib
|
||||
import conf2Utils
|
||||
from configparser import ConfigParser
|
||||
|
||||
logger = None
|
||||
programWhiteList = []
|
||||
envBlackList = ('LD_PRELOAD', 'LD_LIBRARY_PATH', 'LD_AUDIT',)
|
||||
|
||||
# 创建一个DBus服务类
|
||||
class KYSettingsDBusService(dbus.service.Object):
|
||||
__read_only_view = {}
|
||||
__root_view = {}
|
||||
|
||||
def __init__(self, bus_name, object_path):
|
||||
logger.info(f'DBus Class init')
|
||||
dbus.service.Object.__init__(self, bus_name, object_path)
|
||||
|
||||
os.makedirs('/etc/kylin-config', exist_ok=True)
|
||||
#初始化日志模块
|
||||
logging.basicConfig(filename='/etc/kylin-config/systembus.log', level=logging.DEBUG, format='%(asctime)s %(levelname)s %(name)s \n %(message)s')
|
||||
self.logger = logging.getLogger('/etc/kylin-config/systembus.log')
|
||||
self._converter = conf2Utils.Converter(logger)
|
||||
self._watchdog = conf2Utils.FileWatche('/etc/kylin-config/basic', self)
|
||||
|
||||
self.__creat_db_file__()
|
||||
self._reload()
|
||||
|
||||
if os.path.exists('/etc/dbus-1/conf/com.kylin.kysdk.conf2.limit'):
|
||||
conf = ConfigParser()
|
||||
conf.read('/etc/dbus-1/conf/com.kylin.kysdk.conf2.limit')
|
||||
# conf.read('/home/kylin/disk/kylinos-src/libkysdk-base/src/conf2/service/com.kylin.kysdk.conf2.limit')
|
||||
if conf.has_section('whitelist'):
|
||||
global programWhiteList
|
||||
programWhiteList = list(conf['whitelist'].values())
|
||||
|
||||
#读配置文件,创建只读视图数据库和root用户的数据库
|
||||
def __creat_db_file__(self):
|
||||
try:
|
||||
#加载只读配置,写入数据库
|
||||
self.__load_read_only_view__()
|
||||
self.__dict2db__(self.__read_only_view, '/etc/kylin-config/user.db')
|
||||
logger.info(f'DBus Class init end')
|
||||
|
||||
#copy文件到root用户目录
|
||||
if os.path.exists('/etc/kylin-config/user.db'):
|
||||
if not os.path.exists('/root/.config/kylin-config/user.db'):
|
||||
os.makedirs(os.path.dirname('/root/.config/kylin-config/'), exist_ok=True)
|
||||
shutil.copyfile('/etc/kylin-config/user.db', '/root/.config/kylin-config/user.db')
|
||||
self.__root_view = self.__format_db_file('/root/.config/kylin-config/user.db')
|
||||
else:
|
||||
self.__root_view = self.__format_db_file('/root/.config/kylin-config/user.db')
|
||||
self.__del_discarded_key(self.__root_view, self.__read_only_view)
|
||||
self.__merge_dict(self.__root_view, self.__read_only_view)
|
||||
self.__dict2db__(self.__root_view, '/root/.config/kylin-config/user.db')
|
||||
except Exception as e:
|
||||
self.logger.error(traceback.format_exc())
|
||||
|
||||
#统一视图写入数据库
|
||||
#递归寻找枚举
|
||||
def __recursive_search__(self, dictionary, key):
|
||||
if key in dictionary:
|
||||
return dictionary[key]
|
||||
else:
|
||||
for value in dictionary.values():
|
||||
if isinstance(value, dict):
|
||||
result = self.__recursive_search__(value, key)
|
||||
if result is not None:
|
||||
return result
|
||||
return None
|
||||
|
||||
#递归写入配置数据到配置表
|
||||
def __write_element_in_table__(self, version_data:dict ,data: dict, cursor: sqlite3.Cursor, version_id, parent_id):
|
||||
#key写入到数据库
|
||||
if 'keys' in data:
|
||||
keys = data['keys']
|
||||
for key in keys:
|
||||
property = key
|
||||
|
||||
user_value = keys[key].get('value')
|
||||
# if user_value is None:
|
||||
# user_value = keys[key].get('default')
|
||||
|
||||
type = keys[key].get('_type')
|
||||
|
||||
default_value = keys[key].get('default')
|
||||
if isinstance(default_value, str) is False:
|
||||
default_value = str(default_value)
|
||||
|
||||
description = keys[key].get('description')
|
||||
|
||||
summary = keys[key].get('summary')
|
||||
|
||||
permission = keys[key].get('permission')
|
||||
if permission is None:
|
||||
permission = 'public'
|
||||
|
||||
#TODO: 计算range取值范围
|
||||
range = keys[key].get('range')
|
||||
# reload时,没有更新的枚举数据的range应该是枚举参数的字符串列表
|
||||
# 更新后或初始化时的枚举数据的range是@[枚举名]
|
||||
if type == 'enum' and isinstance(range, str) and range.startswith('@'):
|
||||
enum_range = {}
|
||||
element_list = self.__recursive_search__(version_data,keys[key]['range'][1:])
|
||||
for element in element_list:
|
||||
enum_range[element['nick']] = int(element['value'])
|
||||
range = str(enum_range)
|
||||
|
||||
cursor.execute('''INSERT INTO configures (version_id, property, user_value, data_type, default_value, permission, range, parent, description, summary)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',(version_id, property, user_value, type, default_value, permission, range, parent_id, description, summary))
|
||||
if 'children' in data:
|
||||
children = data['children']
|
||||
for child in children:
|
||||
if child.startswith('enum_'):
|
||||
continue
|
||||
cursor.execute("INSERT INTO configures (version_id,group_name,parent) VALUES (?, ?, ?)",(version_id,child,parent_id))
|
||||
group_id = cursor.lastrowid
|
||||
self.__write_element_in_table__(version_data,children[child],cursor,version_id,group_id)
|
||||
|
||||
#创建app表
|
||||
def __covert_app_table__(self,data: dict, cursor: sqlite3.Cursor):
|
||||
# 创建app表
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS app
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
app_name TEXT,
|
||||
defualt_version TEXT)''')
|
||||
#将app信息写入app表
|
||||
for app in data.keys():
|
||||
default_version = data[app].get('default_version')
|
||||
# 如果没有设置默认版本,将默认版本设置为最大版本
|
||||
if default_version is None:
|
||||
for version in data[app]:
|
||||
if default_version is None:
|
||||
default_version = version
|
||||
#比较版本 版本目前认为是2.0.0-0k0格式
|
||||
default_list = re.findall(r'\d+', default_version)
|
||||
list = re.findall(r'\d+', version)
|
||||
for i in range(0,6):
|
||||
if len(default_list) == i:
|
||||
default_version = version
|
||||
break
|
||||
if len(list) == i:
|
||||
break
|
||||
if int(default_list[i]) < int(list[i]):
|
||||
default_version = version
|
||||
break
|
||||
if int(default_list[i]) > int(list[i]):
|
||||
break
|
||||
cursor.execute("INSERT INTO app (app_name, defualt_version) VALUES (?,?)",(app, default_version))
|
||||
|
||||
#创建版本表
|
||||
def __covert_version_table__(self,data: dict, cursor: sqlite3.Cursor):
|
||||
# 创建version表
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS version
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
app_id INTEGER,
|
||||
version TEXT,
|
||||
compatible TEXT,
|
||||
FOREIGN KEY (app_id) REFERENCES app(id))''')
|
||||
for app in data.keys():
|
||||
cursor.execute("SELECT id FROM app WHERE app_name = ?", (app,))
|
||||
appId = cursor.fetchone()
|
||||
for version in data[app].keys():
|
||||
if(version == 'default_version'):
|
||||
continue
|
||||
cursor.execute("INSERT INTO version (app_id,version, compatible) VALUES (?, ?, ?)",(appId[0],version, data[app][version].get('compatible')))
|
||||
|
||||
#创建配置表
|
||||
def __covert_configure_table__(self, data: dict, cursor: sqlite3.Cursor):
|
||||
# 创建version表
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS configures
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
version_id INTEGER,
|
||||
property TEXT,
|
||||
group_name TEXT,
|
||||
user_value TEXT,
|
||||
data_type TEXT,
|
||||
default_value TEXT,
|
||||
permission TEXT,
|
||||
range TEXT,
|
||||
parent INTEGER,
|
||||
description TEXT,
|
||||
summary TEXT,
|
||||
FOREIGN KEY (version_id) REFERENCES version(id),
|
||||
FOREIGN KEY (parent) REFERENCES configures(id))''')
|
||||
cursor.execute("SELECT * FROM app")
|
||||
apps = cursor.fetchall()
|
||||
for app in apps:
|
||||
cursor.execute("SELECT * FROM version WHERE app_id = ?", (app[0],))
|
||||
versions = cursor.fetchall()
|
||||
for version in versions:
|
||||
version_data = data[app[1]][version[2]]
|
||||
#keys写入数据库
|
||||
self.__write_element_in_table__(version_data,version_data,cursor,version[0],0)
|
||||
|
||||
#将字典中的配置数据写入数据库
|
||||
def __dict2db__(self, dict, path):
|
||||
try:
|
||||
# 连接到数据库(如果不存在则创建)
|
||||
db_file_path = path.rsplit('/',maxsplit=1)[0]
|
||||
if not os.path.exists(db_file_path):
|
||||
os.makedirs(db_file_path)
|
||||
conn = sqlite3.connect(path)
|
||||
|
||||
# 创建游标对象
|
||||
cursor = conn.cursor()
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
|
||||
# 获取数据库中的所有表名
|
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
|
||||
tables = cursor.fetchall()
|
||||
|
||||
# 遍历所有表名,对每个表执行DELETE语句以删除所有行
|
||||
for table in tables:
|
||||
cursor.execute(f"DELETE FROM {table[0]}")
|
||||
# cursor.execute(f"DELETE FROM sqlite_sequence WHERE name={table[0]}")
|
||||
|
||||
self.__covert_app_table__(dict,cursor)
|
||||
self.__covert_version_table__(dict,cursor)
|
||||
self.__covert_configure_table__(dict,cursor)
|
||||
|
||||
# 提交更改
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return 0
|
||||
|
||||
except sqlite3.Error as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
self.logger.error(traceback.format_exc())
|
||||
return -1
|
||||
|
||||
#读取数据库数据到内存
|
||||
#递归读取数据库数据到字典
|
||||
def __format_element(self, parent: dict, cursor: sqlite3.Cursor, version_id, parent_id):
|
||||
keys = {}
|
||||
children = {}
|
||||
cursor.execute('SELECT * FROM configures WHERE version_id = ? AND parent = ?', (version_id,parent_id))
|
||||
configure_data = cursor.fetchall()
|
||||
for configure in configure_data:
|
||||
#读取子分组
|
||||
if configure[3] is not None:
|
||||
children[configure[3]] = {}
|
||||
self.__format_element(children[configure[3]],cursor,version_id,configure[0])
|
||||
#读取key
|
||||
else:
|
||||
keys[configure[2]] = {}
|
||||
if configure[4] is not None:
|
||||
keys[configure[2]]['value'] = configure[4]
|
||||
if configure[5] is not None:
|
||||
keys[configure[2]]['_type'] = configure[5]
|
||||
if configure[6] is not None:
|
||||
keys[configure[2]]['default'] = configure[6]
|
||||
if configure[7] is not None:
|
||||
keys[configure[2]]['permission'] = configure[7]
|
||||
if configure[8] is not None:
|
||||
keys[configure[2]]['range'] = configure[8]
|
||||
if configure[10] is not None:
|
||||
keys[configure[2]]['description'] = configure[10]
|
||||
if configure[11] is not None:
|
||||
keys[configure[2]]['summary'] = configure[11]
|
||||
if keys:
|
||||
parent['keys'] = keys
|
||||
if children:
|
||||
parent['children'] = children
|
||||
|
||||
#将数据库中的内容读取到数据结构中
|
||||
def __format_db_file(self, db_file: str):
|
||||
try:
|
||||
data = {}
|
||||
# 连接到数据库(如果不存在则创建)
|
||||
conn = sqlite3.connect(db_file)
|
||||
if conn is None:
|
||||
return data
|
||||
# 创建游标对象
|
||||
cursor = conn.cursor()
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
|
||||
#遍历app表
|
||||
cursor.execute('SELECT * FROM app')
|
||||
app_data = cursor.fetchall()
|
||||
for app in app_data:
|
||||
data[app[1]] = {}
|
||||
cursor.execute('SELECT * FROM version WHERE app_id = ?', (app[0],))
|
||||
version_data = cursor.fetchall()
|
||||
for version in version_data:
|
||||
data[app[1]][version[2]] = {}
|
||||
self.__format_element(data[app[1]][version[2]],cursor,version[0],0)
|
||||
conn.close()
|
||||
return data
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
self.logger.error(traceback.format_exc())
|
||||
return {}
|
||||
|
||||
#读取yaml配置文件到字典
|
||||
def __load_config__(self, yaml_dir):
|
||||
if not os.path.exists(yaml_dir):
|
||||
return {}
|
||||
yaml_data = {}
|
||||
for root,dirs,files in os.walk(yaml_dir):
|
||||
for file in files:
|
||||
if file.endswith('.yaml'):
|
||||
with open(f'{yaml_dir}/{file}','r') as tmp_file:
|
||||
yaml_str = tmp_file.read()
|
||||
tmp_data = yaml.safe_load(yaml_str)
|
||||
yaml_data.update(tmp_data)
|
||||
return yaml_data
|
||||
|
||||
#合并、覆盖两个字典
|
||||
def __merge_dict(self, dest:dict , src:dict):
|
||||
if src is None:
|
||||
return dest
|
||||
for key, value in src.items():
|
||||
if key in dest and isinstance(dest[key], dict) and isinstance(src[key], dict):
|
||||
self.__merge_dict(dest[key], src[key])
|
||||
else:
|
||||
dest[key] = value
|
||||
return dest
|
||||
|
||||
def __del_discarded_key(self, dest:dict, src:dict):
|
||||
keys_to_delete = []
|
||||
for key in dest:
|
||||
if not isinstance(dest[key], dict):
|
||||
return
|
||||
if key not in src:
|
||||
keys_to_delete.append(key)
|
||||
else:
|
||||
self.__del_discarded_key(dest[key], src[key])
|
||||
|
||||
for key in keys_to_delete:
|
||||
dest.pop(key)
|
||||
|
||||
#统一配置文件内容覆盖
|
||||
def __common_override(self, dest:dict, src:dict):
|
||||
if 'children' not in dest:
|
||||
def isAllowedCaller(self,sender):
|
||||
if sender is None:
|
||||
return
|
||||
for group in src:
|
||||
if group in dest['children']:
|
||||
for key in src[group]['keys']:
|
||||
if key in dest['children'][group]['keys']:
|
||||
dest['children'][group]['keys'][key].update(src[group]['keys'][key])
|
||||
# self.__merge_dict(dest['children'][group], src[group])
|
||||
for child in dest['children']:
|
||||
if child != group:
|
||||
self.__common_override(dest['children'][child], src)
|
||||
pid = self.getSenderPid(sender)
|
||||
self.checkSenderEnv(pid)
|
||||
exe_file = '/proc/%u/exe' % pid
|
||||
real_file = os.readlink(exe_file)
|
||||
if real_file.startswith('/usr/bin/python'):
|
||||
cmd_file = '/proc/%u/cmdline' % pid
|
||||
with open(cmd_file, 'r') as cf:
|
||||
cmd_line = cf.readline()
|
||||
cmds = cmd_line.split('\0')
|
||||
if len(cmds) >= 2:
|
||||
real_file = cmds[1]
|
||||
if real_file not in programWhiteList:
|
||||
raise dbus.exceptions.DBusException('[%s] dbus method control,operation not permitted' % real_file)
|
||||
|
||||
# 加载只读配置,更新只读视图数据库文件
|
||||
def __load_read_only_view__(self):
|
||||
self.__read_only_view.clear()
|
||||
# 只读文件目录
|
||||
self.__read_only_view.update(self.__load_config__('/etc/kylin-config/basic'))
|
||||
def getSenderPid(self,sender):
|
||||
system_bus = dbus.SystemBus()
|
||||
dbus_obj = system_bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
|
||||
inter_obj = dbus.Interface(dbus_obj, dbus_interface='org.freedesktop.DBus')
|
||||
try:
|
||||
pid = inter_obj.GetConnectionUnixProcessID(sender)
|
||||
except dbus.DBusException as e:
|
||||
raise dbus.exceptions.DBusException('[%s] dbus method control,operation not permitted' % sender)
|
||||
return pid
|
||||
|
||||
data = self.__load_config__('/etc/kylin-config/production')
|
||||
self.__merge_dict(self.__read_only_view, data)
|
||||
def checkSenderEnv(self, pid):
|
||||
env_file = '/proc/%u/environ' % pid
|
||||
with open(env_file, 'r') as ef:
|
||||
env_lines = ef.readline()
|
||||
env_details = env_lines.replace('\0', '\n').split('\n')
|
||||
for env_detail in env_details:
|
||||
key = env_detail.split('=')[0]
|
||||
if key in envBlackList:
|
||||
raise dbus.exceptions.DBusException('[%u] dbus method control,env forbidden' % pid)
|
||||
|
||||
data = self.__load_config__('/etc/kylin-config/vendor')
|
||||
self.__merge_dict(self.__read_only_view, data)
|
||||
|
||||
data = self.__load_config__('/etc/kylin-config/industry')
|
||||
self.__merge_dict(self.__read_only_view, data)
|
||||
|
||||
data = self.__load_config__('/etc/kylin-config/project')
|
||||
self.__merge_dict(self.__read_only_view, data)
|
||||
|
||||
data = self.__load_config__('/etc/kylin-config/control')
|
||||
self.__merge_dict(self.__read_only_view, data)
|
||||
|
||||
data = self.__load_config__('/etc/kylin-config/common')
|
||||
if data:
|
||||
for app in self.__read_only_view:
|
||||
for version in self.__read_only_view[app]:
|
||||
self.__common_override(self.__read_only_view[app][version], data)
|
||||
|
||||
#将字典中的配置数据写入数据库
|
||||
def __dict2db__(self, dict, path):
|
||||
try:
|
||||
# 连接到数据库(如果不存在则创建)
|
||||
db_file_path = path.rsplit('/',maxsplit=1)[0]
|
||||
if not os.path.exists(db_file_path):
|
||||
os.makedirs(db_file_path)
|
||||
conn = sqlite3.connect(path)
|
||||
|
||||
# 创建游标对象
|
||||
cursor = conn.cursor()
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
|
||||
# 获取数据库中的所有表名
|
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
|
||||
tables = cursor.fetchall()
|
||||
|
||||
# 遍历所有表名,对每个表执行DELETE语句以删除所有行
|
||||
for table in tables:
|
||||
cursor.execute(f"DELETE FROM {table[0]}")
|
||||
# cursor.execute(f"DELETE FROM sqlite_sequence WHERE name={table[0]}")
|
||||
|
||||
self.__covert_app_table__(dict,cursor)
|
||||
self.__covert_version_table__(dict,cursor)
|
||||
self.__covert_configure_table__(dict,cursor)
|
||||
|
||||
# 提交更改
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
self.logger.error(traceback.format_exc())
|
||||
return -1
|
||||
# 重载
|
||||
def _reload(self):
|
||||
if self._converter.update_read_only_db():
|
||||
if self._converter.update_user_db('/root/.config/kylin-config/user.db'):
|
||||
return True
|
||||
return False
|
||||
|
||||
# key值改变信号
|
||||
@dbus.service.signal("com.kylin.kysdk.conf2", signature='ssss')
|
||||
def key_changed(self, id, version, key, user):
|
||||
@dbus.service.signal("com.kylin.kysdk.conf2", signature='sss')
|
||||
def key_changed(self, id, version, key):
|
||||
pass
|
||||
|
||||
# 配置信息update信号
|
||||
|
@ -432,187 +110,72 @@ class KYSettingsDBusService(dbus.service.Object):
|
|||
pass
|
||||
|
||||
# 设置一个配置的值
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='sssss', out_signature='i')
|
||||
def set(self, user, id, version, key, value):
|
||||
try:
|
||||
# 修改用户配置文件,写入到数据库
|
||||
group_list = id.split('.')
|
||||
sql_path = ''
|
||||
if user == 'root':
|
||||
sql_path = '/root/.config/kylin-config/user.db'
|
||||
else:
|
||||
sql_path = f'/home/{user}/.config/kylin-config/user.db'
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='sssss', out_signature='i', sender_keyword='sender')
|
||||
def set(self, user, id, version, key, value, sender = None):
|
||||
# self.isAllowedCaller(sender)
|
||||
success = False
|
||||
if user == 'root':
|
||||
success = self._converter.set('/root/.config/kylin-config/user.db', id, version, key, value)
|
||||
else:
|
||||
success = self._converter.set(f'/home/{user}/.config/kylin-config/user.db', id, version, key, value)
|
||||
|
||||
conn = sqlite3.connect(sql_path)
|
||||
# 创建游标对象
|
||||
cursor = conn.cursor()
|
||||
if success:
|
||||
self.key_changed(id, version, key)
|
||||
|
||||
# 开始写入事务
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
|
||||
app_id = cursor.fetchone()[0]
|
||||
cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id, version))
|
||||
version_id = cursor.fetchone()[0]
|
||||
parent_id = 0
|
||||
# 查找组
|
||||
for group_name in group_list[1:]:
|
||||
cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND group_name = ?", (version_id, parent_id, group_name))
|
||||
parent_id = cursor.fetchone()[0]
|
||||
# cursor.execute("SELECT * FROM configures WHERE version_id = ? AND parent = ? AND property = ?", (version_id, parent_id, key))
|
||||
# key_data = cursor.fetchone()
|
||||
|
||||
cursor.execute("UPDATE configures SET user_value = ? WHERE version_id = ? AND parent = ? AND property = ?", (value,version_id, parent_id, key))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if user == 'root':
|
||||
self.__merge_dict(self.__root_view, self.__format_db_file('/root/.config/kylin-config/user.db'))
|
||||
self.key_changed(id, version, key, user)
|
||||
return 1
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
self.logger.error(traceback.format_exc())
|
||||
return 0
|
||||
return success
|
||||
|
||||
# 恢复单个默认值
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ssss', out_signature='i')
|
||||
def reset(self,user, id, version, key):
|
||||
try:
|
||||
# 修改用户配置文件,写入到数据库
|
||||
group_list = id.split('.')
|
||||
sql_path = ''
|
||||
if user == 'root':
|
||||
sql_path = '/root/.config/kylin-config/user.db'
|
||||
else:
|
||||
sql_path = f'/home/{user}/.config/kylin-config/user.db'
|
||||
|
||||
conn = sqlite3.connect(sql_path)
|
||||
# 创建游标对象
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 开始写入事务
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
|
||||
app_id = cursor.fetchone()[0]
|
||||
cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id,version))
|
||||
version_id = cursor.fetchone()[0]
|
||||
parent_id = 0
|
||||
# 查找组
|
||||
for group_name in group_list[1:]:
|
||||
cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND group_name = ?", (version_id, parent_id, group_name))
|
||||
parent_id = cursor.fetchone()[0]
|
||||
# cursor.execute("SELECT * FROM configures WHERE version_id = ? AND parent = ? AND property = ?", (version_id, parent_id, key))
|
||||
cursor.execute("UPDATE configures SET user_value = default_value WHERE version_id = ? AND parent = ? AND property = ?", (version_id, parent_id, key))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if user == 'root':
|
||||
self.__merge_dict(self.__root_view, self.__format_db_file('/root/.config/kylin-config/user.db'))
|
||||
self.key_changed(id,version,key, user)
|
||||
return 0
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
self.logger.error(traceback.format_exc())
|
||||
return -1
|
||||
|
||||
# 恢复整个id的默认值
|
||||
# @dbus.service.method("com.kylin.kysdk.conf2", in_signature='sss', out_signature='i')
|
||||
# def reset_recursively(self, user, id, version):
|
||||
# try:
|
||||
# # 修改用户配置文件,写入到数据库
|
||||
# group_list = id.split('.')
|
||||
# if user == 'root':
|
||||
# sql_path = '/root/.config/kylin-config/user.db'
|
||||
# else:
|
||||
# sql_path = f'/home/{user}/.config/kylin-config/user.db'
|
||||
|
||||
# conn = sqlite3.connect(sql_path)
|
||||
# # 创建游标对象
|
||||
# cursor = conn.cursor()
|
||||
|
||||
# # 开始写入事务
|
||||
# conn.execute('BEGIN TRANSACTION')
|
||||
# cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
|
||||
# app_id = cursor.fetchone()[0]
|
||||
# cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id,version))
|
||||
# version_id = cursor.fetchone()[0]
|
||||
# parent_id = 0
|
||||
# # 查找组
|
||||
# for group_name in group_list[1:]:
|
||||
# cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND group_name = ?", (version_id, parent_id, group_name))
|
||||
# parent_id = cursor.fetchone()[0]
|
||||
# cursor.execute("UPDATE configures SET value = default_value WHERE version_id = ? AND parent = ?", (version_id, parent_id))
|
||||
# conn.commit()
|
||||
# conn.close()
|
||||
# if user == 'root':
|
||||
# self.__merge_dict(self.__root_view, self.__format_db_file('/root/.config/kylin-config/user.db'))
|
||||
# self.key_changed(id,version,None)
|
||||
# return 0
|
||||
# except sqlite3.Error as e:
|
||||
# conn.rollback()
|
||||
# conn.close()
|
||||
# return -1
|
||||
|
||||
# 恢复整个id的默认值
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='', out_signature='i')
|
||||
def reload(self):
|
||||
try:
|
||||
self.__load_read_only_view__()
|
||||
self.__dict2db__(self.__read_only_view, '/etc/kylin-config/user.db')
|
||||
|
||||
#删除配置文件中删除的键
|
||||
self.__del_discarded_key(self.__root_view, self.__read_only_view)
|
||||
#合并配置新增和修改
|
||||
self.__merge_dict(self.__root_view, self.__read_only_view)
|
||||
self.__dict2db__(self.__root_view, '/root/.config/kylin-config/user.db')
|
||||
|
||||
self.updated()
|
||||
return 1
|
||||
except Exception as e:
|
||||
self.logger.error(traceback.format_exc())
|
||||
return 0
|
||||
|
||||
def __value_override_default(self, dest:dict, src:dict):
|
||||
for key, value in src.items():
|
||||
if key not in dest:
|
||||
continue
|
||||
if isinstance(src[key], dict):
|
||||
self.__value_override_default(dest[key], src[key])
|
||||
else:
|
||||
if src['value'] is not None:
|
||||
dest['default'] = src['value']
|
||||
return
|
||||
|
||||
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ss', out_signature='b')
|
||||
def save(self, user, path):
|
||||
if not os.path.exists(path):
|
||||
return False
|
||||
data = {}
|
||||
if 'root' == user:
|
||||
data = self.__format_db_file('/root/.config/kylin-config/user.db')
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ssss', out_signature='i', sender_keyword='sender')
|
||||
def reset(self,user, id, version, key, sender = None):
|
||||
self.isAllowedCaller(sender)
|
||||
success = False
|
||||
if user == 'root':
|
||||
success = self._converter.reset('/root/.config/kylin-config/user.db', id, version, key)
|
||||
else:
|
||||
data = self.__format_db_file(f'/home/{user}/.config/kylin-config/user.db')
|
||||
if data == {} or data is None:
|
||||
return False
|
||||
success = self._converter.reset(f'/home/{user}/.config/kylin-config/user.db', id, version, key)
|
||||
|
||||
tmp = {}
|
||||
tmp.update(self.__read_only_view)
|
||||
if tmp == {} or tmp is None:
|
||||
return False
|
||||
#将用户配置写入到复制的只读视图里
|
||||
self.__value_override_default(tmp, data)
|
||||
for key in tmp:
|
||||
data = {}
|
||||
data[key] = tmp[key]
|
||||
yaml_data = yaml.safe_dump(data,allow_unicode = True)
|
||||
if yaml_data is None:
|
||||
continue
|
||||
with open(f'{path}/{key}.yaml', 'w') as yaml_file:
|
||||
yaml_file.write(yaml_data)
|
||||
return True
|
||||
if success:
|
||||
self.key_changed(id, version, key)
|
||||
|
||||
return success
|
||||
|
||||
# 恢复整个id的默认值
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='', out_signature='i', sender_keyword='sender')
|
||||
def reload(self, sender = None):
|
||||
self.isAllowedCaller(sender)
|
||||
success = self._reload()
|
||||
self.updated() if success else None
|
||||
return success
|
||||
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ss', out_signature='b', sender_keyword='sender')
|
||||
def save(self, user, path, sender = None):
|
||||
self.isAllowedCaller(sender)
|
||||
success = False
|
||||
if user == 'root':
|
||||
success = self._converter.save('/root/.config/kylin-config/user.db', path)
|
||||
else:
|
||||
success = self._converter.save(f'/home/{user}/.config/kylin-config/user.db', path)
|
||||
return success
|
||||
|
||||
#复制old_id的配置到new_id的位置,并将新的数据写入到数据库
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ssss', out_signature='b', sender_keyword='sender')
|
||||
def extends_id(self, old_id:str, new_id:str, version:str, user:str, sender = None):
|
||||
self.isAllowedCaller(sender)
|
||||
success = False
|
||||
if user == 'root':
|
||||
success = self._converter.extends_id(old_id, new_id, version, '/root/.config/kylin-config/user.db')
|
||||
else:
|
||||
success = self._converter.extends_id(old_id, new_id, version, f'/home/{user}/.config/kylin-config/user.db')
|
||||
return success
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.makedirs('/etc/kylin-config', exist_ok=True)
|
||||
logging.basicConfig(filename='/etc/kylin-config/systembus.log',
|
||||
level=logging.DEBUG,
|
||||
format='%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S')
|
||||
logger = logging.getLogger()
|
||||
|
||||
# 初始化DBus主循环
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/python3.8
|
||||
#
|
||||
# libkysdk-system's Library
|
||||
#
|
||||
|
@ -16,324 +17,90 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Authors: Yunhe Liu <liuyunhe@kylinos.cn>
|
||||
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
|
||||
#
|
||||
#
|
||||
|
||||
#!/usr/bin/python3
|
||||
import os
|
||||
import logging
|
||||
import dbus
|
||||
import dbus.service
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
from gi.repository import GLib
|
||||
import conf2Utils
|
||||
|
||||
import os, shutil, re
|
||||
import sqlite3
|
||||
|
||||
def __recursive_search__(dictionary, key):
|
||||
if key in dictionary:
|
||||
return dictionary[key]
|
||||
else:
|
||||
for value in dictionary.values():
|
||||
if isinstance(value, dict):
|
||||
result = __recursive_search__(value, key)
|
||||
if result is not None:
|
||||
return result
|
||||
return None
|
||||
|
||||
def __write_element_in_table__(version_data:dict ,data: dict, cursor: sqlite3.Cursor, version_id, parent_id):
|
||||
#key写入到数据库
|
||||
if 'keys' in data:
|
||||
keys = data['keys']
|
||||
for key in keys:
|
||||
property = key
|
||||
|
||||
user_value = keys[key].get('value')
|
||||
# if attr is None:
|
||||
# attr = keys[key].get('default')
|
||||
|
||||
type = keys[key].get('_type')
|
||||
|
||||
default_value = keys[key].get('default')
|
||||
if isinstance(default_value, str) is False:
|
||||
default_value = str(default_value)
|
||||
|
||||
description = keys[key].get('description')
|
||||
|
||||
summary = keys[key].get('summary')
|
||||
|
||||
permission = keys[key].get('permission')
|
||||
if permission is None:
|
||||
permission = 'public'
|
||||
|
||||
#TODO: 计算range取值范围
|
||||
range = keys[key].get('range')
|
||||
# reload时,没有更新的枚举数据的range应该是枚举参数的字符串列表
|
||||
# 更新后或初始化时的枚举数据的range是@[枚举名]
|
||||
if type == 'enum' and isinstance(range, str) and range.startswith('@'):
|
||||
enum_range = {}
|
||||
print(keys[key]['range'])
|
||||
element_list = __recursive_search__(version_data, keys[key]['range'][1:])
|
||||
for element in element_list:
|
||||
enum_range[element['nick']] = int(element['value'])
|
||||
range = str(enum_range)
|
||||
|
||||
cursor.execute('''INSERT INTO configures (version_id, property, user_value, data_type, default_value, permission, range, parent, description, summary)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',(version_id, property, user_value, type, default_value, permission, range, parent_id, description, summary))
|
||||
if 'children' in data:
|
||||
children = data['children']
|
||||
for child in children:
|
||||
if child.startswith('enum_'):
|
||||
continue
|
||||
cursor.execute("INSERT INTO configures (version_id,group_name,parent) VALUES (?, ?, ?)",(version_id, child, parent_id))
|
||||
group_id = cursor.lastrowid
|
||||
__write_element_in_table__(version_data,children[child],cursor,version_id,group_id)
|
||||
|
||||
def __covert_app_table__(data: dict, cursor: sqlite3.Cursor):
|
||||
# 创建app表
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS app
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
app_name TEXT,
|
||||
defualt_version TEXT)''')
|
||||
#将app信息写入app表
|
||||
for app in data.keys():
|
||||
default_version = data[app].get('default_version')
|
||||
# 如果没有设置默认版本,将默认版本设置为最大版本
|
||||
if default_version is None:
|
||||
for version in data[app]:
|
||||
if default_version is None:
|
||||
default_version = version
|
||||
#比较版本 版本目前认为是2.0.0-0k0格式
|
||||
default_list = re.findall(r'\d+', default_version)
|
||||
list = re.findall(r'\d+', version)
|
||||
for i in range(0,6):
|
||||
if len(default_list) == i:
|
||||
default_version = version
|
||||
break
|
||||
if len(list) == i:
|
||||
break
|
||||
if int(default_list[i]) < int(list[i]):
|
||||
default_version = version
|
||||
break
|
||||
if int(default_list[i]) > int(list[i]):
|
||||
break
|
||||
cursor.execute("INSERT INTO app (app_name, defualt_version) VALUES (?,?)",(app, default_version))
|
||||
|
||||
def __covert_version_table__(data: dict, cursor: sqlite3.Cursor):
|
||||
# 创建version表
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS version
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
app_id INTEGER,
|
||||
version TEXT,
|
||||
compatible TEXT,
|
||||
FOREIGN KEY (app_id) REFERENCES app(id))''')
|
||||
for app in data.keys():
|
||||
cursor.execute("SELECT id FROM app WHERE app_name = ?", (app,))
|
||||
appId = cursor.fetchone()
|
||||
for version in data[app].keys():
|
||||
if(version == 'default_version'):
|
||||
continue
|
||||
cursor.execute("INSERT INTO version (app_id,version, compatible) VALUES (?, ?, ?)",(appId[0],version, data[app][version].get('compatible')))
|
||||
|
||||
def __covert_configure_table__(data: dict, cursor: sqlite3.Cursor):
|
||||
# 创建version表
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS configures
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
version_id INTEGER,
|
||||
property TEXT,
|
||||
group_name TEXT,
|
||||
user_value TEXT,
|
||||
data_type TEXT,
|
||||
default_value TEXT,
|
||||
permission TEXT,
|
||||
range TEXT,
|
||||
parent INTEGER,
|
||||
description TEXT,
|
||||
summary TEXT,
|
||||
FOREIGN KEY (version_id) REFERENCES version(id),
|
||||
FOREIGN KEY (parent) REFERENCES configures(id))''')
|
||||
cursor.execute("SELECT * FROM app")
|
||||
apps = cursor.fetchall()
|
||||
for app in apps:
|
||||
cursor.execute("SELECT * FROM version WHERE app_id = ?", (app[0],))
|
||||
versions = cursor.fetchall()
|
||||
for version in versions:
|
||||
version_data = data[app[1]][version[2]]
|
||||
#keys写入数据库
|
||||
__write_element_in_table__(version_data,version_data,cursor,version[0],0)
|
||||
|
||||
def __dict2db__(dict, path):
|
||||
try:
|
||||
# 连接到数据库(如果不存在则创建)
|
||||
db_file_path = path.rsplit('/',maxsplit=1)[0]
|
||||
if not os.path.exists(db_file_path):
|
||||
os.makedirs(db_file_path)
|
||||
conn = sqlite3.connect(path)
|
||||
|
||||
# 创建游标对象
|
||||
cursor = conn.cursor()
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
|
||||
# 获取数据库中的所有表名
|
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
|
||||
tables = cursor.fetchall()
|
||||
|
||||
# 遍历所有表名,对每个表执行DELETE语句以删除所有行
|
||||
for table in tables:
|
||||
cursor.execute(f"DELETE FROM {table[0]}")
|
||||
|
||||
__covert_app_table__(dict,cursor)
|
||||
__covert_version_table__(dict,cursor)
|
||||
__covert_configure_table__(dict,cursor)
|
||||
|
||||
# 提交更改
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
return -1
|
||||
|
||||
#读取一个元素
|
||||
def __format_element(parent: dict, cursor: sqlite3.Cursor, version_id, parent_id):
|
||||
keys = {}
|
||||
children = {}
|
||||
cursor.execute('SELECT * FROM configures WHERE version_id = ? AND parent = ?', (version_id,parent_id))
|
||||
configure_data = cursor.fetchall()
|
||||
for configure in configure_data:
|
||||
#读取子分组
|
||||
if configure[3] is not None:
|
||||
children[configure[3]] = {}
|
||||
__format_element(children[configure[3]],cursor,version_id,configure[0])
|
||||
#读取key
|
||||
else:
|
||||
keys[configure[2]] = {}
|
||||
if configure[4] is not None:
|
||||
keys[configure[2]]['value'] = configure[4]
|
||||
if configure[5] is not None:
|
||||
keys[configure[2]]['_type'] = configure[5]
|
||||
if configure[6] is not None:
|
||||
keys[configure[2]]['default'] = configure[6]
|
||||
if configure[7] is not None:
|
||||
keys[configure[2]]['permission'] = configure[7]
|
||||
if configure[8] is not None:
|
||||
keys[configure[2]]['range'] = configure[8]
|
||||
if configure[10] is not None:
|
||||
keys[configure[2]]['description'] = configure[10]
|
||||
if configure[11] is not None:
|
||||
keys[configure[2]]['summary'] = configure[11]
|
||||
if keys:
|
||||
parent['keys'] = keys
|
||||
if children:
|
||||
parent['children'] = children
|
||||
|
||||
#将数据库中的内容读取到数据结构中
|
||||
#由于存储数组到数据库不会存储 枚举 所以反序列化出来的数据结构中不存在 枚举
|
||||
def __format_db_file(db_file: str):
|
||||
try:
|
||||
data = {}
|
||||
conn = sqlite3.connect(db_file)
|
||||
if conn is None:
|
||||
return data
|
||||
# 创建游标对象
|
||||
cursor = conn.cursor()
|
||||
#遍历app表
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
cursor.execute('SELECT * FROM app')
|
||||
app_data = cursor.fetchall()
|
||||
for app in app_data:
|
||||
data[app[1]] = {}
|
||||
cursor.execute('SELECT * FROM version WHERE app_id = ?', (app[0],))
|
||||
version_data = cursor.fetchall()
|
||||
for version in version_data:
|
||||
data[app[1]][version[2]] = {}
|
||||
__format_element(data[app[1]][version[2]],cursor,version[0],0)
|
||||
conn.close()
|
||||
return data
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
return {}
|
||||
|
||||
def __merge_dict(dest:dict , src:dict):
|
||||
if src is None:
|
||||
return dest
|
||||
for key, value in src.items():
|
||||
if key in dest and isinstance(dest[key], dict) and isinstance(src[key], dict):
|
||||
__merge_dict(dest[key], src[key])
|
||||
else:
|
||||
if key != 'user_value':
|
||||
dest[key] = value
|
||||
return dest
|
||||
|
||||
def __del_discarded_key(dest:dict, src:dict):
|
||||
keys_to_delete = []
|
||||
for key in dest:
|
||||
if not isinstance(dest[key], dict):
|
||||
return
|
||||
if key not in src:
|
||||
keys_to_delete.append(key)
|
||||
else:
|
||||
__del_discarded_key(dest[key], src[key])
|
||||
|
||||
for key in keys_to_delete:
|
||||
dest.pop(key)
|
||||
|
||||
__user_view = {}
|
||||
__destination_file = '~/.config/kylin-config/user.db'
|
||||
logger = None
|
||||
destination_file = '~/.config/kylin-config/user.db'
|
||||
|
||||
class KYSettingsDBusSessionService(dbus.service.Object):
|
||||
def __init__(self, bus_name, object_path):
|
||||
logger.info('Session DBus Init')
|
||||
dbus.service.Object.__init__(self, bus_name, object_path)
|
||||
|
||||
conn = dbus.SystemBus()
|
||||
conn.add_signal_receiver(self._reload_handler,
|
||||
signal_name='updated',
|
||||
dbus_interface='com.kylin.kysdk.conf2',
|
||||
bus_name='com.kylin.kysdk.conf2',
|
||||
path="/com/kylin/kysdk/conf2")
|
||||
|
||||
conn.add_signal_receiver(self._key_changed_handler,
|
||||
signal_name='key_changed',
|
||||
dbus_interface='com.kylin.kysdk.conf2',
|
||||
bus_name='com.kylin.kysdk.conf2',
|
||||
path="/com/kylin/kysdk/conf2")
|
||||
|
||||
self._converter = conf2Utils.Converter(logger)
|
||||
|
||||
self.Init()
|
||||
logger.info('Session DBus end')
|
||||
|
||||
def _reload_handler(self):
|
||||
logger.info('On update')
|
||||
self.Init()
|
||||
self.updated()
|
||||
|
||||
def _key_changed_handler(self, id, version, key):
|
||||
logger.info('On key changed')
|
||||
self._converter.update_user_dict(destination_file)
|
||||
self.key_changed(id, version, key)
|
||||
|
||||
# key值改变信号
|
||||
@dbus.service.signal("com.kylin.kysdk.conf2", signature='sss')
|
||||
def key_changed(self, id, version, key):
|
||||
logger.info(f'emit {key} changed')
|
||||
|
||||
# 重载信号
|
||||
@dbus.service.signal("com.kylin.kysdk.conf2", signature='')
|
||||
def updated(self):
|
||||
logger.info('emit updated')
|
||||
|
||||
@dbus.service.method("com.kylin.kysdk.conf2")
|
||||
def Init(self):
|
||||
try:
|
||||
source_file = '/etc/kylin-config/user.db'
|
||||
destination_file = '~/.config/kylin-config/user.db'
|
||||
destination_file = os.path.expanduser(destination_file)
|
||||
if os.path.exists(source_file):
|
||||
if not os.path.exists(destination_file):
|
||||
os.makedirs(os.path.dirname(destination_file), exist_ok=True)
|
||||
shutil.copyfile(source_file, destination_file)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
def reload_handler(*args, **kwargs):
|
||||
data = __format_db_file("/etc/kylin-config/user.db")
|
||||
__del_discarded_key(__user_view, data)
|
||||
__merge_dict(__user_view, data)
|
||||
__dict2db__(__user_view, __destination_file)
|
||||
self._converter.update_user_db(destination_file)
|
||||
|
||||
if __name__ == "__main__":
|
||||
destination_file = os.path.expanduser(destination_file)
|
||||
if not os.path.exists(os.path.dirname(destination_file)):
|
||||
os.makedirs(os.path.dirname(destination_file), mode=0o777, exist_ok=True)
|
||||
|
||||
logging.basicConfig(filename=destination_file.replace('user.db', 'sessionbus.log'),
|
||||
level=logging.DEBUG,
|
||||
format='%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S')
|
||||
logger = logging.getLogger()
|
||||
|
||||
# 初始化DBus主循环
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
||||
try:
|
||||
__destination_file = os.path.expanduser(__destination_file)
|
||||
# 连接到DBus系统总线
|
||||
bus_session = dbus.SessionBus()
|
||||
|
||||
bus_session = dbus.SessionBus()
|
||||
object_path = '/com/kylin/kysdk/conf2'
|
||||
bus_sesssion_name = dbus.service.BusName("com.kylin.kysdk.conf2", bus = bus_session)
|
||||
my_dbus_session_service = KYSettingsDBusSessionService(bus_sesssion_name, object_path)
|
||||
# 注册一个DBus服务
|
||||
object_path = '/com/kylin/kysdk/conf2'
|
||||
bus_sesssion_name = dbus.service.BusName("com.kylin.kysdk.conf2", bus = bus_session)
|
||||
my_dbus_session_service = KYSettingsDBusSessionService(bus_sesssion_name, object_path)
|
||||
|
||||
##用户登录,更新用户配置
|
||||
__user_view = __format_db_file(__destination_file)
|
||||
reload_handler(None, None)
|
||||
|
||||
# 连接到DBus系统总线
|
||||
bus = dbus.SystemBus()
|
||||
|
||||
# 监听DBus信号
|
||||
bus.add_signal_receiver(reload_handler,
|
||||
signal_name='updated',
|
||||
dbus_interface='com.kylin.kysdk.conf2',
|
||||
bus_name='com.kylin.kysdk.conf2',
|
||||
path="/com/kylin/kysdk/conf2")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
# 开始DBus主循环
|
||||
mainloop = GLib.MainLoop()
|
||||
mainloop.run()
|
|
@ -0,0 +1,918 @@
|
|||
import os
|
||||
import re
|
||||
import shutil
|
||||
import yaml
|
||||
import sqlite3
|
||||
import logging
|
||||
import traceback
|
||||
from watchdog.observers import Observer
|
||||
from watchdog.events import FileSystemEventHandler
|
||||
import subprocess
|
||||
class Converter:
|
||||
_ro_db = '/etc/kylin-config/user.db'
|
||||
_ro_dict = {}
|
||||
_user_dict = {}
|
||||
def __init__(self, logger:logging.Logger):
|
||||
self.logger = logger
|
||||
|
||||
def update_read_only_db(self):
|
||||
try:
|
||||
self._update_table_structure(self._ro_db)
|
||||
self._creat_db_file(self._ro_db)
|
||||
self._load_stable_dict()
|
||||
return self._dict2db(self._ro_dict, self._ro_db)
|
||||
except:
|
||||
err_msg = traceback.format_exc()
|
||||
self.logger.error(f'update_read_only_db {err_msg}')
|
||||
return False
|
||||
|
||||
def update_user_db(self, path):
|
||||
if not os.path.exists(self._ro_db):
|
||||
return False
|
||||
|
||||
existed = os.path.exists(path)
|
||||
if not existed:
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
shutil.copyfile(self._ro_db, path)
|
||||
self._user_dict = self._db2dict(path)
|
||||
else:
|
||||
self._update_table_structure(path)
|
||||
data = self._db2dict(self._ro_db)
|
||||
self._del_discarded_key(self._user_dict, data)
|
||||
self._merge_dict(self._user_dict, data)
|
||||
|
||||
if os.path.exists(f'{os.path.dirname(path)}/map.yaml'):
|
||||
self.logger.info("override gsettings config")
|
||||
with open(f'{os.path.dirname(path)}/map.yaml', 'r') as file:
|
||||
mmap = yaml.safe_load(file)
|
||||
if mmap is not None:
|
||||
for app, gsetting_id in mmap.items():
|
||||
for version, version_dict in self._user_dict[app].items():
|
||||
if not isinstance(version_dict, dict):
|
||||
continue
|
||||
self._gsettings_config_get(self._user_dict[app][version], gsetting_id)
|
||||
os.remove(f'{os.path.dirname(path)}/map.yaml')
|
||||
|
||||
if path.startswith('/root') and not existed:
|
||||
return True
|
||||
|
||||
if path.startswith('/home'):
|
||||
self._load_mutable_dict(os.path.dirname(path))
|
||||
|
||||
self._dict2db(self._user_dict, path)
|
||||
return True
|
||||
|
||||
def update_user_dict(self, path):
|
||||
self._user_dict = self._db2dict(path)
|
||||
|
||||
def set(self, path, id, version, key, value):
|
||||
try:
|
||||
self.logger.info(f'set begin')
|
||||
|
||||
# 修改用户配置文件,写入到数据库
|
||||
group_list = id.split('.')
|
||||
|
||||
conn = sqlite3.connect(path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 开始写入事务
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
|
||||
cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
|
||||
app_id = cursor.fetchone()[0]
|
||||
|
||||
cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id, version))
|
||||
version_id = cursor.fetchone()[0]
|
||||
|
||||
# 查找组
|
||||
parent_id = 0
|
||||
for group_name in group_list[1:]:
|
||||
cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND node_name = ? AND node_type = 'schema'", (version_id, parent_id, group_name))
|
||||
parent_id = cursor.fetchone()[0]
|
||||
|
||||
cursor.execute("UPDATE configures SET custom_value = ? WHERE version_id = ? AND parent = ? AND node_name = ? AND node_type = 'key'", (value, version_id, parent_id, key))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
tmp = self._user_dict[group_list[0]][version]
|
||||
for group in group_list[1:]:
|
||||
tmp = tmp[group]
|
||||
tmp[key]['_value'] = value
|
||||
|
||||
self.logger.info(f'set end')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
err_msg = traceback.format_exc()
|
||||
self.logger.error(f'set {err_msg}')
|
||||
return False
|
||||
|
||||
def reset(self, path, id, version, key):
|
||||
try:
|
||||
self.logger.info(f'reset begin')
|
||||
# 修改用户配置文件,写入到数据库
|
||||
group_list = id.split('.')
|
||||
|
||||
conn = sqlite3.connect(path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 开始写入事务
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
|
||||
cursor.execute("SELECT id FROM app WHERE app_name = ?", (group_list[0],))
|
||||
app_id = cursor.fetchone()[0]
|
||||
|
||||
cursor.execute("SELECT id FROM version WHERE app_id = ? AND version = ?", (app_id,version))
|
||||
version_id = cursor.fetchone()[0]
|
||||
|
||||
# 查找组
|
||||
parent_id = 0
|
||||
for group_name in group_list[1:]:
|
||||
cursor.execute("SELECT id FROM configures WHERE version_id = ? AND parent = ? AND node_name = ? AND node_type = 'schema'", (version_id, parent_id, group_name))
|
||||
parent_id = cursor.fetchone()[0]
|
||||
|
||||
cursor.execute("UPDATE configures SET custom_value = NULL WHERE version_id = ? AND parent = ? AND node_name = ? AND node_type = 'key'", (version_id, parent_id, key))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
tmp = {}
|
||||
tmp = self._user_dict[group_list[0]][version]
|
||||
for group in group_list[1:]:
|
||||
tmp = tmp[group]
|
||||
if '_value' in tmp[key]:
|
||||
tmp[key].pop('_value')
|
||||
|
||||
self.logger.info(f'reset end')
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
conn.close()
|
||||
err_msg = traceback.format_exc()
|
||||
self.logger.error(f'set {err_msg}')
|
||||
return False
|
||||
|
||||
def save(self, db_file, dest_path):
|
||||
try:
|
||||
self.logger.info(f'save begin')
|
||||
|
||||
if not os.path.exists(dest_path):
|
||||
self.logger.error(f'{dest_path} not exists')
|
||||
return False
|
||||
|
||||
data = self._db2dict(db_file)
|
||||
|
||||
if data == {}:
|
||||
self.logger.error(f'read sqlite failed')
|
||||
return False
|
||||
|
||||
#将用户配置写入到复制的只读视图里
|
||||
self._value_override_default(data)
|
||||
|
||||
for key in data:
|
||||
with open(f'{dest_path}/{key}.yaml', 'w') as yaml_file:
|
||||
yaml_file.write(yaml.safe_dump({key:data[key]}, allow_unicode = True))
|
||||
|
||||
self.logger.info(f'save end')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
err_msg = traceback.format_exc()
|
||||
self.logger.error(f'save {err_msg}')
|
||||
return False
|
||||
|
||||
# 用于kconf2-editor保存文件,仅有普通用户权限,root用户没有图形化界面
|
||||
def editor_save(self, data, dest_path):
|
||||
try:
|
||||
self.logger.info(f'editor_save begin')
|
||||
|
||||
#将用户配置写入到复制的只读视图里
|
||||
self._value_override_default(data)
|
||||
|
||||
for key in data:
|
||||
with open(f'{dest_path}/{key}.yaml', 'w') as yaml_file:
|
||||
yaml_file.write(yaml.safe_dump({key:data[key]}, allow_unicode = True))
|
||||
|
||||
self.logger.info(f'editor_save end')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
err_msg = traceback.format_exc()
|
||||
self.logger.error(f'editor_save {err_msg}')
|
||||
return False
|
||||
|
||||
def extends_id(self, old_id:str, new_id:str, version:str, target_file):
|
||||
try:
|
||||
self.logger.info(f'extends_id begin')
|
||||
|
||||
target_view = self._db2dict(target_file)
|
||||
|
||||
#获取app的引用
|
||||
list = old_id.split('.', -1)
|
||||
app = target_view.get(list[0])
|
||||
|
||||
if app is None:
|
||||
self.logger.error(f'{old_id} is not exists')
|
||||
return False
|
||||
|
||||
#获取目标版本的引用,如果为空,获取默认版本
|
||||
if version == '':
|
||||
old_data = app[app['_default_version']]
|
||||
else:
|
||||
old_data = app.get(version)
|
||||
|
||||
if old_data is None:
|
||||
self.logger.error(f'{version} is not invalid')
|
||||
|
||||
for iter in list[1:]:
|
||||
old_data = old_data.get(iter)
|
||||
if old_data is None:
|
||||
self.logger.error(f'{old_id} is not exists')
|
||||
return False
|
||||
|
||||
tmp = {}
|
||||
tmp.update(old_data)
|
||||
|
||||
list = new_id.split('.', -1)
|
||||
new_data = target_view.get(list[0])
|
||||
if new_data != app:
|
||||
self.logger.error(f'{new_id} is invalid')
|
||||
|
||||
if version == '':
|
||||
new_data = app[app['_default_version']]
|
||||
else:
|
||||
new_data = app.get(version)
|
||||
|
||||
for iter in list[1:]:
|
||||
if iter not in new_data:
|
||||
new_data[iter] = {}
|
||||
new_data = new_data[iter]
|
||||
|
||||
new_data.update(tmp)
|
||||
new_data['_extends'] = old_id
|
||||
self.logger.info(f'extends_id end')
|
||||
return self._dict2db(target_view, target_file)
|
||||
|
||||
except Exception as e:
|
||||
err_msg = traceback.format_exc()
|
||||
self.logger.error(f'extends_id {err_msg}')
|
||||
return False
|
||||
|
||||
def load_dirs_config(self, dirs:list) -> dict:
|
||||
try:
|
||||
result = {}
|
||||
for dir in dirs:
|
||||
list = self._sort_diretory(dir)
|
||||
for file in list:
|
||||
# self.logger.info('Read conifg file')
|
||||
data = self._load_one_file(f'{dir}/{file}')
|
||||
# self.logger.info('Read conifg file')
|
||||
|
||||
if not data:
|
||||
continue
|
||||
|
||||
# self.logger.info('Merger in view')
|
||||
is_group_file = False
|
||||
for value in data.values():
|
||||
if isinstance(value, dict):
|
||||
is_group_file = True if '_default' in next(iter(value.values())) else False
|
||||
break
|
||||
if is_group_file:
|
||||
self._common_override_by_final(result, data)
|
||||
else:
|
||||
self._merge_dict_by_final(result, data)
|
||||
# self.logger.info('Merger in view end')
|
||||
return result
|
||||
except:
|
||||
return {}
|
||||
|
||||
def _load_stable_dict(self):
|
||||
self.logger.info('Read stable dirs')
|
||||
|
||||
self._ro_dict.clear()
|
||||
|
||||
with open('/etc/kylin-config/conf2.yaml', 'r') as file:
|
||||
configures = yaml.safe_load(file)
|
||||
|
||||
for dir in configures['dirs']:
|
||||
list = self._sort_diretory(f'/etc/kylin-config/{dir}')
|
||||
for file in list:
|
||||
# self.logger.info('Read conifg file')
|
||||
data = self._load_one_file(f'/etc/kylin-config/{dir}/{file}')
|
||||
# self.logger.info('Read conifg file')
|
||||
|
||||
if not data:
|
||||
continue
|
||||
|
||||
# self.logger.info('Merger in view')
|
||||
is_group_file = False
|
||||
for value in data.values():
|
||||
if isinstance(value, dict):
|
||||
is_group_file = True if '_default' in next(iter(value.values())) else False
|
||||
break
|
||||
if is_group_file:
|
||||
self._common_override_by_final(self._ro_dict, data)
|
||||
else:
|
||||
self._merge_dict_by_final(self._ro_dict, data)
|
||||
# self.logger.info('Merger in view end')
|
||||
self.logger.info('Read stable dirs end')
|
||||
|
||||
def _load_mutable_dict(self, dir):
|
||||
self.logger.info('Read mutable dirs')
|
||||
|
||||
list = self._sort_diretory(f'{dir}/configs')
|
||||
for file in list:
|
||||
# self.logger.info('Read conifg file')
|
||||
data = self._load_one_file(f'{dir}/configs/{file}')
|
||||
# self.logger.info('Read conifg file')
|
||||
|
||||
if not data:
|
||||
continue
|
||||
|
||||
# self.logger.info('Merger in view')
|
||||
is_group_file = False
|
||||
for value in data.values():
|
||||
if isinstance(value, dict):
|
||||
is_group_file = True if '_default' in next(iter(value.values())) else False
|
||||
break
|
||||
if is_group_file:
|
||||
self._common_override_by_stable(self._user_dict, data)
|
||||
else:
|
||||
self._merge_dict_by_stable(self._user_dict, data)
|
||||
# self.logger.info('Merger in view end')
|
||||
self.logger.info('Read mutable dirs end')
|
||||
|
||||
# 按规范对文件名进行排序
|
||||
def _sort_diretory(self, yaml_dir):
|
||||
if not os.path.exists(yaml_dir):
|
||||
return []
|
||||
|
||||
# 获取目录内所有文件名
|
||||
file_list = os.listdir(yaml_dir)
|
||||
|
||||
# 定义排序函数
|
||||
def custom_sort(file_name):
|
||||
match = re.match(r"(\d+)?-?(.*)", file_name)
|
||||
if match.group(1):
|
||||
return (int(match.group(1)), match.group(2))
|
||||
else:
|
||||
return (0, match.group(2))
|
||||
|
||||
sorted_file_list = sorted(file_list, key=custom_sort)
|
||||
return sorted_file_list
|
||||
|
||||
# 读取一个文件
|
||||
def _load_one_file(self, file:str):
|
||||
chinese_pattern = re.compile(u'[\u4e00-\u9fa5]+')
|
||||
if bool(chinese_pattern.search(file)) or file.startswith('.'):
|
||||
return {}
|
||||
|
||||
yaml_data = {}
|
||||
if file.endswith('.yaml'):
|
||||
with open(file,'r') as stream:
|
||||
yaml_data = yaml.safe_load(stream)
|
||||
if yaml_data is None:
|
||||
self.logger.error(f'Load {file} failed. Check the text formatting')
|
||||
return {}
|
||||
return yaml_data
|
||||
|
||||
# 合并两个字典
|
||||
def _merge_dict(self, dest:dict , src:dict):
|
||||
if src == {}:
|
||||
return
|
||||
|
||||
if dest == {}:
|
||||
dest.update(src)
|
||||
return
|
||||
|
||||
for key in src.keys():
|
||||
if key in dest :
|
||||
if isinstance(dest[key], dict) and isinstance(src[key], dict):
|
||||
self._merge_dict(dest[key], src[key])
|
||||
else:
|
||||
dest[key] = src[key]
|
||||
else:
|
||||
dest[key] = src[key]
|
||||
return
|
||||
|
||||
# 合并两个字典, 处理final权限
|
||||
def _merge_dict_by_final(self, dest:dict , src:dict):
|
||||
if src == {}:
|
||||
return
|
||||
|
||||
if dest == {}:
|
||||
dest.update(src)
|
||||
return
|
||||
if '_permission' in dest:
|
||||
if dest['_permission'] == 'final':
|
||||
return
|
||||
|
||||
for key in src.keys():
|
||||
if key in dest :
|
||||
if isinstance(dest[key], dict) and isinstance(src[key], dict):
|
||||
self._merge_dict_by_final(dest[key], src[key])
|
||||
else:
|
||||
dest[key] = src[key]
|
||||
else:
|
||||
dest[key] = src[key]
|
||||
return
|
||||
|
||||
# 合并两个字典, 处理stable权限
|
||||
def _merge_dict_by_stable(self, dest:dict , src:dict):
|
||||
if src == {}:
|
||||
return
|
||||
|
||||
if dest == {}:
|
||||
dest.update(src)
|
||||
return
|
||||
|
||||
if '_permission' in dest:
|
||||
if dest['_permission'] == 'final' or dest['_permission'] == 'stable':
|
||||
return
|
||||
|
||||
for key in src.keys():
|
||||
if key in dest :
|
||||
if isinstance(dest[key], dict) and isinstance(src[key], dict):
|
||||
self._merge_dict_by_stable(dest[key], src[key])
|
||||
else:
|
||||
dest[key] = src[key]
|
||||
else:
|
||||
dest[key] = src[key]
|
||||
return
|
||||
|
||||
# 全局配置字典覆盖,处理final权限
|
||||
def _common_override_by_final(self, dest:dict, src:dict):
|
||||
for app in dest:
|
||||
for version in dest[app]:
|
||||
for group in dest[app][version]:
|
||||
if group in src:
|
||||
self._merge_dict_by_final(dest[app][version][group], src[group])
|
||||
|
||||
# 全局配置字典覆盖,处理stable权限
|
||||
def _common_override_by_stable(self, dest:dict, src:dict):
|
||||
for app in dest:
|
||||
for version in dest[app]:
|
||||
for group in dest[app][version]:
|
||||
if group in src:
|
||||
self._merge_dict_by_stable(dest[app][version][group], src[group])
|
||||
|
||||
# 字典写入到数据库
|
||||
def _dict2db(self, dict:dict, path:str):
|
||||
try:
|
||||
self.logger.info('write config in database')
|
||||
conn = sqlite3.connect(path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
|
||||
tables = cursor.fetchall()
|
||||
|
||||
# 遍历所有表名,对每个表执行DELETE语句以删除所有行
|
||||
for table in tables:
|
||||
cursor.execute(f"DELETE FROM {table[0]}")
|
||||
|
||||
app_id = 0
|
||||
version_id = 0
|
||||
apps = list(dict.keys())
|
||||
for i in range(0, len(apps)):
|
||||
app = apps[i]
|
||||
app_id = app_id + 1
|
||||
default_version = self._calculate_default_version(dict[app])
|
||||
cursor.execute("INSERT INTO app (app_name, default_version) VALUES (?,?)",(app, default_version))
|
||||
|
||||
versions = list(dict[app].keys())
|
||||
for j in range(0, len(versions)):
|
||||
version = versions[j]
|
||||
if version == '_default_version':
|
||||
continue
|
||||
|
||||
version_id = version_id + 1
|
||||
cursor.execute("INSERT INTO version (app_id, version, compatible) VALUES (?, ?, ?)",
|
||||
(app_id, version, dict[app][version].get('_compatible')))
|
||||
|
||||
configures = dict[app][version]
|
||||
self._write_group_in_db(configures, configures, cursor, version_id, 0)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
self.logger.info('write config in database end')
|
||||
return True
|
||||
|
||||
except:
|
||||
err_msg = traceback.format_exc()
|
||||
self.logger.error(f'_dict2db {err_msg}')
|
||||
conn.rollback()
|
||||
conn.commit()
|
||||
return False
|
||||
|
||||
# 计算默认版本
|
||||
def _calculate_default_version(self, data:dict):
|
||||
versions = list(data.keys())
|
||||
if '_default_version' in versions:
|
||||
return data.get('_default_version')
|
||||
default_version = ''
|
||||
for version in versions:
|
||||
if default_version == '':
|
||||
default_version = version
|
||||
continue
|
||||
default_nums = re.findall(r'\d+', default_version)
|
||||
nums = re.findall(r'\d+', version)
|
||||
for i in range(0, 6):
|
||||
if nums[i] > default_nums[i]:
|
||||
default_version = version
|
||||
break
|
||||
return default_version
|
||||
|
||||
#递归写入组到configures表
|
||||
def _write_group_in_db(self, version_data:dict, data: dict, cursor: sqlite3.Cursor, version_id, parent_id):
|
||||
groups = []
|
||||
for key, value in data.items():
|
||||
if isinstance(value, dict):
|
||||
if(value.get('_default') is None):
|
||||
groups.append(key)
|
||||
else:
|
||||
self._write_key_in_db(version_data, key, value, cursor, version_id, parent_id, data.get('_permission'))
|
||||
|
||||
for group in groups:
|
||||
node_name = group
|
||||
|
||||
node_type = 'schema'
|
||||
|
||||
permission = data[group].get('_permission')
|
||||
if permission is None:
|
||||
permission = 'public'
|
||||
|
||||
description = data[group].get('_description')
|
||||
|
||||
summary = data[group].get('_summary')
|
||||
|
||||
extends = data[group].get('_extends')
|
||||
|
||||
cursor.execute('''INSERT INTO configures
|
||||
(version_id, node_name, node_type, permission, description, summary, parent, extends)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',
|
||||
(version_id, node_name, node_type, permission, description, summary, parent_id, extends))
|
||||
group_id = cursor.lastrowid
|
||||
self._write_group_in_db(version_data, data[group], cursor, version_id, group_id)
|
||||
|
||||
# 写入键的数据到configures表内
|
||||
def _write_key_in_db(self, version_data:dict, key:str, value:dict, cursor: sqlite3.Cursor, version_id, parent_id, parent_permission):
|
||||
node_name = key
|
||||
|
||||
node_type = 'key'
|
||||
|
||||
permission = value.get('_permission')
|
||||
if permission is None:
|
||||
if parent_permission is None:
|
||||
permission = 'public'
|
||||
else:
|
||||
permission = parent_permission
|
||||
|
||||
description = value.get('_description')
|
||||
|
||||
summary = value.get('_summary')
|
||||
|
||||
value_type = value.get('_type')
|
||||
|
||||
custom_value = value.get('_value')
|
||||
|
||||
default_value = value.get('_default')
|
||||
if isinstance(default_value, bool):
|
||||
default_value = 'true' if default_value else 'false'
|
||||
|
||||
range = value.get('_range')
|
||||
if value_type == 'enum' and isinstance(range, str) and range.startswith('@'):
|
||||
enum_range = {}
|
||||
element_list = self._recursive_search(version_data, value['_range'][1:])
|
||||
for element in element_list:
|
||||
num = element['_value']
|
||||
if isinstance(num, str):
|
||||
if num.startswith('0x'):
|
||||
num = int(num, 16)
|
||||
else:
|
||||
num = int(num, 10)
|
||||
enum_range[element['_nick']] = num
|
||||
range = str(enum_range)
|
||||
|
||||
cursor.execute('''INSERT INTO configures
|
||||
(version_id, node_name, node_type, permission, description, summary, parent, value_type, custom_value, default_value, range)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
|
||||
(version_id, node_name, node_type, permission, description, summary, parent_id, value_type, custom_value, default_value, range))
|
||||
|
||||
# 查询枚举类型数据的枚举定义
|
||||
def _recursive_search(self, dictionary, key):
|
||||
if key in dictionary:
|
||||
return dictionary[key]
|
||||
else:
|
||||
for value in dictionary.values():
|
||||
if isinstance(value, dict):
|
||||
result = self._recursive_search(value, key)
|
||||
if result is not None:
|
||||
return result
|
||||
return None
|
||||
|
||||
# 读数据库数据到字典
|
||||
def _db2dict(self, path):
|
||||
try:
|
||||
conn = sqlite3.connect(path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('SELECT * FROM app')
|
||||
apps = cursor.fetchall()
|
||||
|
||||
cursor.execute('SELECT * FROM version')
|
||||
versions = cursor.fetchall()
|
||||
|
||||
cursor.execute('SELECT * FROM configures')
|
||||
configures = cursor.fetchall()
|
||||
conn.close()
|
||||
|
||||
data = {}
|
||||
stack = []
|
||||
i = j = k = 0
|
||||
for i in range(len(apps)):
|
||||
app = apps[i][1]
|
||||
app_id = i + 1
|
||||
default_value = apps[i][2]
|
||||
data[app] = {}
|
||||
if(default_value):
|
||||
data[app]['_default_version'] = default_value
|
||||
for j in range(j, len(versions)):
|
||||
# app_id改变,退出版本循环
|
||||
version_app_id = versions[j][1]
|
||||
if version_app_id != app_id:
|
||||
break
|
||||
version = versions[j][2]
|
||||
data[app][version] = {}
|
||||
if versions[j][3]:
|
||||
data[app][version]['compatible'] = versions[j][3]
|
||||
|
||||
stack.append((0, data[app][version]))
|
||||
# 如果占用内存过大,可以改为在这里读取对应版本的所有配置
|
||||
# 不再保存k值,每次循环从0开始
|
||||
for k in range(k, len(configures)):
|
||||
# version_id改变,退出循环
|
||||
if configures[k][1] != j + 1:
|
||||
stack.clear()
|
||||
break
|
||||
|
||||
while configures[k][7] != stack[-1][0]:
|
||||
stack.pop()
|
||||
|
||||
node_name = configures[k][2]
|
||||
node_type = configures[k][3]
|
||||
permission = configures[k][4]
|
||||
description = configures[k][5]
|
||||
summary = configures[k][6]
|
||||
value_type = configures[k][8]
|
||||
custom_value = configures[k][9]
|
||||
default_value = configures[k][10]
|
||||
value_range = configures[k][11]
|
||||
extends = configures[k][12]
|
||||
|
||||
if node_type == 'schema':
|
||||
tmp = stack[-1][1]
|
||||
tmp[node_name] = {}
|
||||
stack.append((configures[k][0], tmp[node_name]))
|
||||
if permission is not None:
|
||||
tmp[node_name]['_permission'] = permission
|
||||
if description is not None:
|
||||
tmp[node_name]['_description'] = description
|
||||
if summary is not None:
|
||||
tmp[node_name]['_summary'] = summary
|
||||
if extends is not None:
|
||||
tmp[node_name]['_extends'] = extends
|
||||
elif node_type == 'key':
|
||||
tmp = stack[-1][1]
|
||||
tmp[node_name] = {}
|
||||
if permission is not None:
|
||||
tmp[node_name]['_permission'] = permission
|
||||
if description is not None:
|
||||
tmp[node_name]['_description'] = description
|
||||
if summary is not None:
|
||||
tmp[node_name]['_summary'] = summary
|
||||
if value_type is not None:
|
||||
tmp[node_name]['_type'] = value_type
|
||||
if custom_value is not None:
|
||||
tmp[node_name]['_value'] = custom_value
|
||||
if default_value is not None:
|
||||
tmp[node_name]['_default'] = default_value
|
||||
if value_range is not None:
|
||||
tmp[node_name]['_range'] = value_range
|
||||
return data
|
||||
except:
|
||||
err_msg = traceback.format_exc()
|
||||
self.logger.error(f'_db2dict {err_msg}')
|
||||
return {}
|
||||
|
||||
# 删除dest中存在,但不存在与src中的键或组
|
||||
def _del_discarded_key(self, dest:dict, src:dict):
|
||||
keys_to_delete = []
|
||||
for key in dest:
|
||||
if not isinstance(dest[key], dict):
|
||||
continue
|
||||
if key not in src:
|
||||
if dest[key].get('_extends') is None:
|
||||
keys_to_delete.append(key)
|
||||
else:
|
||||
self._del_discarded_key(dest[key], src[key])
|
||||
|
||||
for key in keys_to_delete:
|
||||
dest.pop(key)
|
||||
|
||||
# 导出时,使用value的值替带default值
|
||||
def _value_override_default(self, data:dict):
|
||||
for key, value in data.items():
|
||||
if isinstance(value, dict):
|
||||
self._value_override_default(value)
|
||||
else:
|
||||
if '_value' in data:
|
||||
data['_default'] = data.pop('_value')
|
||||
return
|
||||
|
||||
def _creat_db_file(self, path):
|
||||
conn = sqlite3.connect(path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
conn.execute('BEGIN TRANSACTION')
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS app
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
app_name TEXT,
|
||||
default_version TEXT)''')
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS version
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
app_id INTEGER,
|
||||
version TEXT,
|
||||
compatible TEXT,
|
||||
FOREIGN KEY (app_id) REFERENCES app(id))''')
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS configures
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
version_id INTEGER,
|
||||
node_name TEXT,
|
||||
node_type TEXT,
|
||||
permission TEXT,
|
||||
description TEXT,
|
||||
summary TEXT,
|
||||
parent INTEGER,
|
||||
value_type TEXT,
|
||||
custom_value TEXT,
|
||||
default_value TEXT,
|
||||
range TEXT,
|
||||
extends TEXT,
|
||||
FOREIGN KEY (version_id) REFERENCES version(id),
|
||||
FOREIGN KEY (parent) REFERENCES configures(id))''')
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def _gsettings_config_get(self, data, id):
|
||||
for key, value in data.items():
|
||||
if not isinstance(value, dict):
|
||||
continue
|
||||
if '_default' in value:
|
||||
result = subprocess.run(['gsettings','get', id, key], capture_output=True, text=True)
|
||||
custom_value = result.stdout.strip()
|
||||
custom_value = custom_value.split(' ')[-1] if custom_value.startswith('@') else custom_value
|
||||
value['_value'] = custom_value
|
||||
else:
|
||||
self._gsettings_config_get(value, f'{id}.{key}')
|
||||
|
||||
def _update_table_structure(self, path):
|
||||
try:
|
||||
if not os.path.exists(path):
|
||||
return True
|
||||
|
||||
conn = sqlite3.connect(path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('BEGIN TRANSACTION')
|
||||
|
||||
# 检查是否是旧的表结构
|
||||
is_old = False
|
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='configures';")
|
||||
table_exists = cursor.fetchone()
|
||||
if table_exists:
|
||||
cursor.execute("PRAGMA table_info(configures);")
|
||||
columns = cursor.fetchall()
|
||||
|
||||
for column in columns:
|
||||
if column[1] == 'group_name':
|
||||
is_old = True
|
||||
break
|
||||
|
||||
if is_old:
|
||||
self.logger.info('Data base table is old structure. Update structure')
|
||||
# 如果是基础数据库,直接删掉重新生成
|
||||
if path == self._ro_db:
|
||||
os.remove(path)
|
||||
else:
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS new_configures
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
version_id INTEGER,
|
||||
node_name TEXT,
|
||||
node_type TEXT,
|
||||
permission TEXT,
|
||||
description TEXT,
|
||||
summary TEXT,
|
||||
parent INTEGER,
|
||||
value_type TEXT,
|
||||
custom_value TEXT,
|
||||
default_value TEXT,
|
||||
range TEXT,
|
||||
extends TEXT,
|
||||
FOREIGN KEY (version_id) REFERENCES version(id),
|
||||
FOREIGN KEY (parent) REFERENCES configures(id))''')
|
||||
|
||||
cursor.execute("INSERT INTO new_configures (version_id, node_name, node_type, permission, description, summary, parent, value_type, custom_value, default_value, range, extends) SELECT "
|
||||
"version_id,"
|
||||
"CASE "
|
||||
"WHEN property IS NOT NULL THEN property "
|
||||
"WHEN group_name IS NOT NULL THEN group_name "
|
||||
"END, "
|
||||
"CASE "
|
||||
"WHEN property IS NOT NULL THEN 'key' "
|
||||
"WHEN group_name IS NOT NULL THEN 'schema' "
|
||||
"END,"
|
||||
"permission,"
|
||||
"description,"
|
||||
"summary,"
|
||||
"parent,"
|
||||
"data_type,"
|
||||
"user_value,"
|
||||
"default_value,"
|
||||
"range,"
|
||||
"extends "
|
||||
"FROM configures;")
|
||||
# 删除原表
|
||||
cursor.execute("DROP TABLE configures;")
|
||||
|
||||
# 将新表重命名为原表的名称
|
||||
cursor.execute("ALTER TABLE new_configures RENAME TO configures;")
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return True
|
||||
except Exception as e:
|
||||
err_msg = traceback.format_exc()
|
||||
self.logger.error(f'{err_msg}')
|
||||
return False
|
||||
|
||||
class FileWatche:
|
||||
class MyHandler(FileSystemEventHandler):
|
||||
def __init__(self, server):
|
||||
self._server = server
|
||||
|
||||
def on_modified(self, event):
|
||||
if event.is_directory:
|
||||
return
|
||||
self._server.reload()
|
||||
|
||||
def on_created(self, event):
|
||||
if event.is_directory or not os.path.dirname(event.src_path) == '/etc/kylin-config/basic':
|
||||
return
|
||||
|
||||
gsettings_id = os.path.basename(event.src_path).strip(".yaml")
|
||||
|
||||
mmap = {}
|
||||
with open(event.src_path, 'r') as file:
|
||||
data = yaml.safe_load(file)
|
||||
|
||||
for app, version in data.items():
|
||||
if not isinstance(version, dict):
|
||||
continue
|
||||
mmap[app] = gsettings_id
|
||||
|
||||
home_directories = [os.path.expanduser('~' + username) for username in os.listdir('/home')]
|
||||
home_directories.append('/root')
|
||||
for home_dir in home_directories:
|
||||
file_path = os.path.join(home_dir, '.config/kylin-config/map.yaml')
|
||||
if not os.path.exists(os.path.dirname(file_path)):
|
||||
continue
|
||||
# file_path = '/home/kylin/test.yaml'
|
||||
if os.path.exists(file_path):
|
||||
with open(file_path, 'r') as file:
|
||||
tmp = yaml.safe_load(file)
|
||||
if tmp is not None:
|
||||
mmap.update(tmp)
|
||||
|
||||
os.remove(file_path)
|
||||
|
||||
with open(file_path, 'w') as file:
|
||||
file.write(yaml.safe_dump(mmap))
|
||||
|
||||
os.chmod(file_path, 0o666)
|
||||
|
||||
def __init__(self, path, server) -> None:
|
||||
self._server = server
|
||||
self._observer = Observer()
|
||||
self._event_handler = FileWatche.MyHandler(server)
|
||||
|
||||
self._observer.schedule(self._event_handler, path, recursive=False)
|
||||
self._observer.start()
|
||||
|
||||
def stopWatche(self):
|
||||
if self._observer.isAlive():
|
||||
self._observer.stop()
|
||||
self._observer.join()
|
|
@ -1,14 +1,14 @@
|
|||
[Unit]
|
||||
Description=KYLIN CONF2 DBUS
|
||||
Wants=systemd-logind.service
|
||||
Before=systemd-logind.service
|
||||
Wants=systemd-logind.service lightdm.service
|
||||
Before=systemd-logind.service lightdm.service
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
Restart=always
|
||||
RestartSec=1
|
||||
BusName=com.kylin.kysdk.conf2
|
||||
ExecStart=python3 /usr/bin/conf2-server.py
|
||||
ExecStart=/usr/bin/conf2-server.py
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,9 +0,0 @@
|
|||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(CONF2 REQUIRED kysdk-conf2)
|
||||
include_directories(${CONF2_INCLUDE_DIRS})
|
||||
|
||||
add_executable(kyconf2-test kyconf2-test.c)
|
||||
target_link_libraries(kyconf2-test ${CONF2_LIBRARIES})
|
||||
|
||||
install(TARGETS kyconf2-test
|
||||
DESTINATION /usr/bin)
|
|
@ -1,402 +0,0 @@
|
|||
control-center:
|
||||
3.20.1.31-0k2.11:
|
||||
children:
|
||||
powermanager:
|
||||
keys:
|
||||
sleep:
|
||||
_type: b
|
||||
default: 'true'
|
||||
dormant:
|
||||
_type: b
|
||||
default: 'true'
|
||||
shutdown:
|
||||
_type: b
|
||||
default: 'true'
|
||||
switch-user:
|
||||
_type: b
|
||||
default: 'true'
|
||||
apt:
|
||||
children:
|
||||
proxy:
|
||||
keys:
|
||||
enabled:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: This key is used to control whether to open apt-proxy.
|
||||
summary: Whether open
|
||||
host:
|
||||
_type: s
|
||||
default: ''
|
||||
description: The machine name to proxy APT through.
|
||||
summary: APT proxy host name
|
||||
port:
|
||||
_type: i
|
||||
default: '8080'
|
||||
description: "The port on the machine defined by “/apt/proxy/host”\
|
||||
\ that you\n proxy through."
|
||||
range: 0,65535
|
||||
summary: APT proxy port
|
||||
desktop:
|
||||
keys:
|
||||
computer-icon-locking:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether lock computer icon on start menu or not.
|
||||
summary: Lock computer icon on start menu
|
||||
computer-icon-visible:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether show computer icon on desktop or not.
|
||||
summary: Show computer icon on desktop
|
||||
home-icon-visible:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether show home icon on desktop or not.
|
||||
summary: Show home icon on desktop
|
||||
menufull-screen:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: Whether to always use the start menu in full screen.
|
||||
summary: menufull-screen switch button
|
||||
network-icon-visible:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether show network icon on desktop or not.
|
||||
summary: Show network icon on desktop
|
||||
personal-icon-locking:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: Whether personal icon on start menu or not.
|
||||
summary: Lock personal icon on start menu
|
||||
settings-icon-locking:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether lock settings icon on start menu or not.
|
||||
summary: Lock settings icon on start menu
|
||||
trash-icon-locking:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: Whether lock trash icon on start menu or not.
|
||||
summary: Lock trash icon on start menu
|
||||
trash-icon-visible:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether show trash icon on desktop or not.
|
||||
summary: Show trash icon on desktop
|
||||
volumes-visible:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether show volumes icon on desktop or not.
|
||||
summary: Show volumes icon on desktop
|
||||
enum_org.ukui.control-center.noticeorigin.Type:
|
||||
- nick: none
|
||||
value: '0'
|
||||
- nick: corner
|
||||
value: '1'
|
||||
- nick: all
|
||||
value: '2'
|
||||
experienceplan:
|
||||
keys:
|
||||
join:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether this plugin would be activated by ukui-settings-daemon
|
||||
or not
|
||||
summary: join user experience plan
|
||||
keybinding:
|
||||
keys:
|
||||
action:
|
||||
_type: s
|
||||
default: ''
|
||||
description: Command associated with a custom keybinding.
|
||||
summary: Command
|
||||
binding:
|
||||
_type: s
|
||||
default: ''
|
||||
description: Keybinding associated with a custom shortcut.
|
||||
summary: Keybinding
|
||||
name:
|
||||
_type: s
|
||||
default: ''
|
||||
description: Description associated with a custom keybinding.
|
||||
summary: Name
|
||||
keyboard: {}
|
||||
notice:
|
||||
keys:
|
||||
blacklist:
|
||||
_type: as
|
||||
default: '[]'
|
||||
description: Hidden DektopList
|
||||
summary: ''
|
||||
enable-notice:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether an OSD notification is shown to notify about changes
|
||||
summary: Show OSD notification
|
||||
iscn-env:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Determine whether the environment is Chinese
|
||||
summary: ''
|
||||
show-new-feature:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Whether this plugin would be activated by ukui-settings-daemon
|
||||
or not
|
||||
summary: Activation of this plugin
|
||||
show-on-lockscreen:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Binding to eject an optical disc.
|
||||
summary: Eject
|
||||
noticeorigin:
|
||||
keys:
|
||||
maximize:
|
||||
_type: i
|
||||
default: '3'
|
||||
description: The maximize num of messages on notice window.
|
||||
summary: maximize num of messages
|
||||
messages:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: .
|
||||
summary: messages notice
|
||||
name-cn:
|
||||
_type: s
|
||||
default: ''
|
||||
description: The name passed to the sidebar
|
||||
summary: app's name
|
||||
name-us:
|
||||
_type: s
|
||||
default: ''
|
||||
description: The name passed to the sidebar
|
||||
summary: app's name
|
||||
notification-style:
|
||||
_type: s
|
||||
default: mutative
|
||||
description: 'Select the notification style. Supported values are "none",
|
||||
|
||||
"mutative","always".
|
||||
|
||||
|
||||
If this is "none", notifications don''t show up on the screen,
|
||||
|
||||
but go to the notification center
|
||||
|
||||
|
||||
If this is "mutative", show on the upper right corner of the screen,
|
||||
|
||||
it will disappear automatically.
|
||||
|
||||
|
||||
If this is "always", remain on the screen until turned off.'
|
||||
summary: The display style of the notification
|
||||
show-detail:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: Whether the notification show detail on screenlock
|
||||
summary: ''
|
||||
show-on-screenlock:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: Whether the notification show on screenlock
|
||||
summary: ''
|
||||
type:
|
||||
_type: enum
|
||||
default: corner
|
||||
description: the type of notice in system.
|
||||
range: '@enum_org.ukui.control-center.noticeorigin.Type'
|
||||
summary: type of notice message
|
||||
voice:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: .
|
||||
summary: voice notice
|
||||
osd:
|
||||
keys:
|
||||
show-lock-tip:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: show keyboard tip or not. eg. Caps Lock. Num Lock
|
||||
summary: show keyboard tip
|
||||
panel:
|
||||
children:
|
||||
plugins:
|
||||
keys:
|
||||
calendar:
|
||||
_type: s
|
||||
default: lunar
|
||||
description: calendar system used in UKUI Desktop Environment ,ontrol
|
||||
by ukui-panel and ukui-control-center
|
||||
summary: Lunar calendar
|
||||
date:
|
||||
_type: s
|
||||
default: cn
|
||||
description: date format
|
||||
summary: date formate
|
||||
firstday:
|
||||
_type: s
|
||||
default: monday
|
||||
description: Select the first day of the week
|
||||
summary: first of week
|
||||
hoursystem:
|
||||
_type: s
|
||||
default: '24'
|
||||
description: hoursystem used in UKUI Desktop Environment ,ontrol by
|
||||
ukui-panel and ukui-control-center
|
||||
summary: HourSystem status
|
||||
nightmodestatus:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: ''
|
||||
summary: ukui-control-center sets the night mode status so that ukui-panel
|
||||
can get the status
|
||||
ntp:
|
||||
_type: s
|
||||
default: ''
|
||||
description: user-defined ntp server address
|
||||
summary: customize ntp server address
|
||||
showlanguage:
|
||||
_type: as
|
||||
default: '[]'
|
||||
description: show language in plugin area
|
||||
summary: show language in plugin area
|
||||
synctime:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: ''
|
||||
summary: sync time from network
|
||||
themebynight:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: ''
|
||||
summary: ukui-control-center theme changes follow with the night
|
||||
mode
|
||||
time:
|
||||
_type: s
|
||||
default: '24'
|
||||
description: Select the first day of the week
|
||||
summary: first of week
|
||||
timezones:
|
||||
_type: as
|
||||
default: '[]'
|
||||
description: other time zones
|
||||
summary: all time zones of time display
|
||||
personalise:
|
||||
keys:
|
||||
blurry:
|
||||
_type: i
|
||||
default: '3'
|
||||
description: 1- Low effect;2-Middle effect;3-High effect
|
||||
summary: Control the frosted glass effect of the component
|
||||
custompower:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: Used to determine that the control panel user has customized
|
||||
a power plan
|
||||
summary: Whether to customize the power plan
|
||||
effect:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: 'ture:Special effects open; false: Special effects off'
|
||||
summary: Control panel special effects transmit signal
|
||||
save-transparency:
|
||||
_type: i
|
||||
default: '100'
|
||||
description: Save the transparency before the special effects mode is
|
||||
turned off
|
||||
summary: Save the transparency before the special effects mode is turned
|
||||
off
|
||||
transparency:
|
||||
_type: d
|
||||
default: '0.65'
|
||||
description: Control the transparency of all components
|
||||
summary: Control the transparency of all components
|
||||
plugins:
|
||||
keys:
|
||||
plugin-name:
|
||||
_type: s
|
||||
default: ''
|
||||
description: the name to match status
|
||||
summary: plugin's name
|
||||
show:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: .
|
||||
summary: whether the plugin's status
|
||||
pluginstatus: {}
|
||||
wifi:
|
||||
children:
|
||||
switch:
|
||||
keys:
|
||||
switch:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: wifi switch
|
||||
summary: wifi switch
|
||||
switchor:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: wifi switch of kylin network manager
|
||||
summary: wifi switchor
|
||||
wificard:
|
||||
_type: b
|
||||
default: 'true'
|
||||
description: Determine if the wireless network card is inserted
|
||||
summary: Wireless network card
|
||||
keys:
|
||||
fonts-list:
|
||||
_type: as
|
||||
default: '[''CESI仿宋-GB13000'',''CESI_FS_GB13000'', ''CESI仿宋-GB18030'',''CESI_FS_GB18030'',
|
||||
''CESI仿宋-GB2312'',''CESI_FS_GB2312'', ''CESI宋体-GB13000'',''CESI_SS_GB13000'',
|
||||
''CESI宋体-GB18030'',''CESI_SS_GB18030'', ''CESI宋体-GB2312'',''CESI_SS_GB2312'',
|
||||
''CESI小标宋-GB13000'',''CESI_XBS_GB13000'', ''CESI小标宋-GB18030'',''CESI_XBS_GB18030'',
|
||||
''CESI小标宋-GB2312'',''CESI_XBS_GB2312'', ''CESI楷体-GB13000'',''CESI_KT_GB13000'',
|
||||
''CESI楷体-GB18030'',''CESI_KT_GB18030'', ''CESI楷体-GB2312'',''CESI_KT_GB2312'',
|
||||
''CESI黑体-GB13000'',''CESI_HT_GB13000'', ''CESI黑体-GB18030'',''CESI_HT_GB18030'',
|
||||
''CESI黑体-GB2312'',''CESI_HT_GB2312'', ''仿宋'', ''黑体'', ''楷体'', ''宋体'', ''华文彩云'',''STCaiyun'',
|
||||
''华文仿宋'',''STFangsong'', ''华文琥珀'',''STHupo'', ''华文楷体'',''STKaiti'', ''华文隶书'',''STLiti'',
|
||||
''华文宋体'',''STSong'', ''华文细黑'',''STXihei'', ''华文行楷'',''STXingkai'', ''华文新魏'',''STXinwei'',
|
||||
''Noto Sans CJK SC'', ''Noto Sans CJK SC Black'', ''Noto Sans Mono CJK SC'',
|
||||
''Noto Sans CJK SC DemiLight'', ''Noto Sans CJK SC Light'', ''Noto Sans
|
||||
CJK SC Medium'', ''Noto Sans CJK SC'', ''Noto Sans CJK SC Thin'',''Dotted
|
||||
Songti Square'',''WenQuanYi Bitmap Song'']'
|
||||
description: Control panel default font list
|
||||
summary: Control panel default font list
|
||||
2.0.0.0-0k0.0:
|
||||
children:
|
||||
powermanager:
|
||||
keys:
|
||||
sleep:
|
||||
_type: b
|
||||
default: 'true'
|
||||
dormant:
|
||||
_type: b
|
||||
default: 'true'
|
||||
shutdown:
|
||||
_type: b
|
||||
default: 'true'
|
||||
switch-user:
|
||||
_type: b
|
||||
default: 'true'
|
||||
apt:
|
||||
children:
|
||||
proxy:
|
||||
keys:
|
||||
enabled:
|
||||
_type: b
|
||||
default: 'false'
|
||||
description: This key is used to control whether to open apt-proxy.
|
||||
summary: Whether open
|
||||
host:
|
||||
_type: s
|
||||
default: ''
|
||||
description: The machine name to proxy APT through.
|
||||
summary: APT proxy host name
|
||||
port:
|
||||
_type: i
|
||||
default: '8080'
|
||||
description: "The port on the machine defined by “/apt/proxy/host”\
|
||||
\ that you\n proxy through."
|
||||
range: 0,65535
|
||||
summary: APT proxy port
|
|
@ -18,71 +18,317 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "../api/libkysettings.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <glib-2.0/glib.h>
|
||||
|
||||
//键值改变信号回调函数
|
||||
// 键值改变信号回调函数
|
||||
static void on_key_changed(KSettings *setting, char *key, void *user_data)
|
||||
{
|
||||
printf("on key change signal\n");
|
||||
char *value = kdk_conf2_get_value(setting, key);
|
||||
printf("%s change to %s\n", key, value);
|
||||
}
|
||||
|
||||
// 键值改变信号回调函数
|
||||
static void on_reload(KSettings *setting, void *user_data)
|
||||
{
|
||||
printf("reload signal\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
KSettings *setting = kdk_conf2_new("systemd.powermanager", NULL);
|
||||
if(NULL == setting)
|
||||
KSettings *setting = kdk_conf2_new("test.notice", NULL);
|
||||
if (NULL == setting)
|
||||
{
|
||||
printf("get handle failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//链接键值改变信号
|
||||
/**
|
||||
* 只有已连接切读过一次配置时才能接收到该信号
|
||||
* 接收信号需要开启主程序的消息循环
|
||||
*/
|
||||
// kdk_conf2_connect_signal(setting, "changed::sleep", on_key_changed, NULL);
|
||||
// kdk_conf2_connect_signal(setting, "changed::int", on_key_changed, NULL);
|
||||
|
||||
//读配置
|
||||
char *value = kdk_conf2_get_value(setting, "sleep");
|
||||
if(NULL != value)
|
||||
char *schema_summary = kdk_conf2_get_schema_summary(setting);
|
||||
if (schema_summary)
|
||||
{
|
||||
printf("sleep user value: %s\n", value);
|
||||
free(value);
|
||||
printf("test.notice summary\t: %s\n", schema_summary);
|
||||
free(schema_summary);
|
||||
}
|
||||
|
||||
//读默认配置
|
||||
value = kdk_conf2_get_default_value(setting, "sleep");
|
||||
if (NULL != value)
|
||||
char *schema_description = kdk_conf2_get_schema_desription(setting);
|
||||
if (schema_description)
|
||||
{
|
||||
printf("sleep default value: %s\n", value);
|
||||
free(value);
|
||||
printf("test.notice description\t: %s\n", schema_description);
|
||||
free(schema_description);
|
||||
}
|
||||
|
||||
//读对应数据类型的值
|
||||
//调用获取对应数据类型的接口前,调用has_key确保键存在。否则无法保证返回值的准确性
|
||||
if(kdk_conf2_has_key(setting, "sleep"))
|
||||
char *id = kdk_conf2_get_id(setting);
|
||||
if (id)
|
||||
{
|
||||
int b_sleep = kdk_conf2_get_boolean(setting, "sleep");
|
||||
printf("sleep user boolean: %s\n", b_sleep ? "true" : "false");
|
||||
|
||||
b_sleep = kdk_conf2_get_default_boolean(setting, "sleep");
|
||||
printf("sleep defalut boolean: %s\n", b_sleep ? "true" : "false");
|
||||
printf("id is\t: %s\n", id);
|
||||
free(id);
|
||||
}
|
||||
|
||||
//设置键值
|
||||
int success = kdk_conf2_set_value(setting, "sleep", "true");
|
||||
if(0 == success)
|
||||
char *version = kdk_conf2_get_version(setting);
|
||||
if (version)
|
||||
{
|
||||
printf("set value failed\n");
|
||||
printf("version is\t: %s\n", version);
|
||||
free(version);
|
||||
}
|
||||
|
||||
//其它接口参考头文件或接口文档
|
||||
char **children = kdk_conf2_list_children(setting);
|
||||
if (children)
|
||||
{
|
||||
printf("children:\n");
|
||||
for (int i = 0; children[i]; i++)
|
||||
{
|
||||
printf("\t%s\n", children[i]);
|
||||
free(children[i]);
|
||||
}
|
||||
free(children);
|
||||
}
|
||||
|
||||
usleep(10);
|
||||
//注销句柄
|
||||
char **keys = kdk_conf2_list_keys(setting);
|
||||
if (keys)
|
||||
{
|
||||
printf("keys:\n");
|
||||
for (int i = 0; keys[i]; i++)
|
||||
{
|
||||
printf("\t%s\n", keys[i]);
|
||||
free(keys[i]);
|
||||
}
|
||||
free(keys);
|
||||
}
|
||||
|
||||
// 把childname替换为正确的子组名
|
||||
KSettings *child = kdk_conf2_get_child(setting, "proxy");
|
||||
if (child)
|
||||
{
|
||||
printf("get child :test.notice.proxy\n");
|
||||
}
|
||||
|
||||
char *range = kdk_conf2_get_range(setting, "type");
|
||||
if (range)
|
||||
{
|
||||
printf("Type range is %s\n", range);
|
||||
free(range);
|
||||
range = NULL;
|
||||
}
|
||||
|
||||
int success = 0;
|
||||
success = kdk_conf2_range_check(setting, "int", "65540");
|
||||
printf("value is %s\n", success ? "valid" : "invalid");
|
||||
|
||||
{
|
||||
/**********通用读写**********/
|
||||
char *value = kdk_conf2_get_default_value(setting, "int");
|
||||
if (NULL != value)
|
||||
{
|
||||
printf("Int default value: %s\n", value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
value = kdk_conf2_get_value(setting, "int");
|
||||
if (NULL != value)
|
||||
{
|
||||
printf("Int value: %s\n", value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
success = kdk_conf2_set_value(setting, "int", "8081");
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set int failed\n");
|
||||
}
|
||||
|
||||
/**********枚举读写**********/
|
||||
int e = kdk_conf2_get_default_enum(setting, "type");
|
||||
printf("Type default value is %d\n", e);
|
||||
|
||||
e = kdk_conf2_get_enum(setting, "type");
|
||||
printf("Type value is %d\n", e);
|
||||
|
||||
success = kdk_conf2_set_enum(setting, "type", 0x2);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set type failed\n");
|
||||
}
|
||||
|
||||
/**********整形读写**********/
|
||||
int i = kdk_conf2_get_default_int(setting, "int");
|
||||
printf("Int default value is %d\n", i);
|
||||
|
||||
i = kdk_conf2_get_int(setting, "int");
|
||||
printf("Int value is %d\n", i);
|
||||
|
||||
success = kdk_conf2_set_int(setting, "int", i + 1);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set int failed\n");
|
||||
}
|
||||
|
||||
/**********长整形读写**********/
|
||||
long l = kdk_conf2_get_default_int(setting, "long");
|
||||
printf("Long default value is %d\n", l);
|
||||
|
||||
l = kdk_conf2_get_int(setting, "long");
|
||||
printf("Long value is %d\n", l);
|
||||
|
||||
success = kdk_conf2_set_int(setting, "long", l + 1);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set long failed\n");
|
||||
}
|
||||
|
||||
/**********无符号整形读写**********/
|
||||
unsigned int u = kdk_conf2_get_default_int(setting, "uint");
|
||||
printf("Uint default value is %d\n", u);
|
||||
|
||||
u = kdk_conf2_get_int(setting, "uint");
|
||||
printf("Uint value is %d\n", u);
|
||||
|
||||
success = kdk_conf2_set_int(setting, "uint", u + 1);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set uint failed\n");
|
||||
}
|
||||
|
||||
/**********无符号长整形读写**********/
|
||||
unsigned long t = kdk_conf2_get_default_int(setting, "ulong");
|
||||
printf("Ulong default value is %d\n", t);
|
||||
|
||||
t = kdk_conf2_get_int(setting, "ulong");
|
||||
printf("Ulong value is %d\n", t);
|
||||
|
||||
success = kdk_conf2_set_int(setting, "ulong", t + 1);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set ulong failed\n");
|
||||
}
|
||||
|
||||
/**********布尔型读写**********/
|
||||
int b = kdk_conf2_get_default_boolean(setting, "enable");
|
||||
printf("Enable default value is %s\n", b ? "true" : "false");
|
||||
|
||||
b = kdk_conf2_get_boolean(setting, "enable");
|
||||
printf("Enable value is %s\n", b ? "true" : "false");
|
||||
|
||||
success = kdk_conf2_set_boolean(setting, "enable", !b);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set enable failed\n");
|
||||
}
|
||||
|
||||
/**********浮点型读写**********/
|
||||
double d = kdk_conf2_get_default_double(setting, "transparency");
|
||||
printf("Transparency default value is %lf\n", d);
|
||||
|
||||
d = kdk_conf2_get_double(setting, "transparency");
|
||||
printf("Transparency value is %lf\n", d);
|
||||
|
||||
success = kdk_conf2_set_double(setting, "transparency", d + 1);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("Set transparency failed\n");
|
||||
}
|
||||
|
||||
/**********字符串读写**********/
|
||||
char *s = kdk_conf2_get_default_string(setting, "name");
|
||||
printf("Name default value is %s\n", s);
|
||||
|
||||
s = kdk_conf2_get_string(setting, "name");
|
||||
printf("Name value is %s\n", s);
|
||||
|
||||
success = kdk_conf2_set_string(setting, "name", "dsefe");
|
||||
if (0 == success)
|
||||
{
|
||||
printf("Set name failed\n");
|
||||
}
|
||||
|
||||
/**********字符串列表读写**********/
|
||||
char **sv = kdk_conf2_get_default_strv(setting, "list");
|
||||
if (sv)
|
||||
{
|
||||
printf("List default value :\n");
|
||||
for (int i = 0; sv[i]; i++)
|
||||
{
|
||||
printf("\t%s\n", sv[i]);
|
||||
}
|
||||
g_strfreev(sv);
|
||||
}
|
||||
|
||||
sv = kdk_conf2_get_strv(setting, "list");
|
||||
if (sv)
|
||||
{
|
||||
printf("List value :\n");
|
||||
for (int i = 0; sv[i]; i++)
|
||||
{
|
||||
printf("\t%s\n", sv[i]);
|
||||
}
|
||||
g_strfreev(sv);
|
||||
}
|
||||
const char *v[] = {"CESI仿宋-GB13000", "CESI_FS_GB13000", NULL};
|
||||
success = kdk_conf2_set_strv(setting, "list", v);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("Set list failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
char *description = kdk_conf2_get_descrition(setting, "int");
|
||||
if (description)
|
||||
{
|
||||
printf("Int description: %s\n", description);
|
||||
free(description);
|
||||
}
|
||||
|
||||
char *summary = kdk_conf2_get_summary(setting, "int");
|
||||
if (summary)
|
||||
{
|
||||
printf("Int summary: %s\n", summary);
|
||||
free(summary);
|
||||
}
|
||||
|
||||
char *type = kdk_conf2_get_type(setting, "int");
|
||||
if (type)
|
||||
{
|
||||
printf("Int type: %s\n", type);
|
||||
free(type);
|
||||
}
|
||||
|
||||
kdk_conf2_reset(setting, "int");
|
||||
|
||||
int writable = kdk_conf2_is_writable(setting, "int");
|
||||
printf("Int is %s\n", writable ? "writable" : "not writable");
|
||||
|
||||
// kdk_conf2_connect_signal(setting, "reload", on_reload, NULL);
|
||||
kdk_conf2_reload();
|
||||
|
||||
char **schemas = kdk_conf2_list_schemas("test", NULL);
|
||||
if (schemas)
|
||||
{
|
||||
printf("test schemas:\n");
|
||||
for (int i = 0; schemas[i]; i++)
|
||||
{
|
||||
printf("\t%s\n", schemas[i]);
|
||||
free(schemas[i]);
|
||||
}
|
||||
free(schemas);
|
||||
}
|
||||
|
||||
KSettings *externds_setting = kdk_conf2_new_extends_id("test.notice", "test.notice.tss", NULL);
|
||||
if (externds_setting)
|
||||
{
|
||||
printf("kdk_conf2_new_extends_id successed\n");
|
||||
}
|
||||
|
||||
int is_schema = kdk_conf2_is_schema("control-center.notice", NULL);
|
||||
printf("control-center.notice is a %s shcema\n", is_schema ? "valid" : "invalid");
|
||||
|
||||
// 注销句柄
|
||||
kdk_conf2_ksettings_destroy(setting);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
test:
|
||||
3.20.1.31-0k2.11:
|
||||
powermanager:
|
||||
sleep:
|
||||
_type: b
|
||||
_default: 'true'
|
||||
dormant:
|
||||
_type: b
|
||||
_default: 'true'
|
||||
shutdown:
|
||||
_type: b
|
||||
_default: 'true'
|
||||
_permission: final
|
||||
switch-user:
|
||||
_type: b
|
||||
_default: 'true'
|
||||
_permission: stable
|
||||
enum_org.ukui.test.Type:
|
||||
- _nick: none
|
||||
_value: 0x00
|
||||
- _nick: corner
|
||||
_value: 0x01
|
||||
- _nick: all
|
||||
_value: 0x02
|
||||
notice:
|
||||
_summary: This is test schema
|
||||
_description: This schema contains various basic types of keys
|
||||
enable:
|
||||
_type: b
|
||||
_default: 'true'
|
||||
_description: Whether an OSD notification is shown to notify about changes
|
||||
_summary: Show OSD notification
|
||||
int:
|
||||
_type: i
|
||||
_default: '8080'
|
||||
_description: "The port on the machine defined by “/apt/proxy/host”\
|
||||
\ that you\n proxy through."
|
||||
_range: 0,65535
|
||||
_summary: APT proxy port
|
||||
long:
|
||||
_type: x
|
||||
_default: '8080'
|
||||
_description: "The port on the machine defined by “/apt/proxy/host”\
|
||||
\ that you\n proxy through."
|
||||
_summary: APT proxy port
|
||||
uint:
|
||||
_type: u
|
||||
_default: '8080'
|
||||
_description: "The port on the machine defined by “/apt/proxy/host”\
|
||||
\ that you\n proxy through."
|
||||
_summary: APT proxy port
|
||||
ulong:
|
||||
_type: t
|
||||
_default: '8080'
|
||||
_description: "The port on the machine defined by “/apt/proxy/host”\
|
||||
\ that you\n proxy through."
|
||||
_summary: APT proxy port
|
||||
name:
|
||||
_type: s
|
||||
_default: ''
|
||||
_description: The name passed to the sidebar
|
||||
_summary: app's name
|
||||
type:
|
||||
_type: enum
|
||||
_default: corner
|
||||
_description: the type of notice in system.
|
||||
_range: '@enum_org.ukui.test.Type'
|
||||
_summary: type of notice message
|
||||
transparency:
|
||||
_type: d
|
||||
_default: '0.65'
|
||||
_description: Control the transparency of all components
|
||||
_summary: Control the transparency of all components
|
||||
list:
|
||||
_type: as
|
||||
_default: '[''CESI仿宋-GB13000'',''CESI_FS_GB13000'', ''CESI仿宋-GB18030'']'
|
||||
_description: Control panel _default font list
|
||||
_summary: Control panel _default font list
|
||||
proxy:
|
||||
key:
|
||||
_type: i
|
||||
_default: 0
|
||||
2.0.0.0-0k0.0:
|
||||
powermanager:
|
||||
_permission: final
|
||||
sleep:
|
||||
_type: b
|
||||
_default: 'true'
|
||||
dormant:
|
||||
_type: b
|
||||
_default: 'true'
|
||||
shutdown:
|
||||
_type: b
|
||||
_default: 'true'
|
||||
switch-user:
|
||||
_type: b
|
||||
_default: 'true'
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# libkysdk-system's Library
|
||||
#
|
||||
|
@ -16,11 +17,10 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Authors: Yunhe Liu <liuyunhe@kylinos.cn>
|
||||
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
|
||||
#
|
||||
#
|
||||
|
||||
#!/usr/bin/python3
|
||||
import configparser
|
||||
import yaml
|
||||
import sys, os
|
||||
|
@ -31,24 +31,28 @@ def convert_one_file(file):
|
|||
config.read(file)
|
||||
|
||||
# 将配置文件数据转换为字典
|
||||
data = {'app':{'version':{'children':{}}}}
|
||||
version = data['app']['version']['children']
|
||||
data = {'app':{'2.0.0.0-0k0.0':{}}}
|
||||
version = data['app']['2.0.0.0-0k0.0']
|
||||
for section in config.sections():
|
||||
version[section] = {}
|
||||
for option in config.options(section):
|
||||
value = config.get(section, option)
|
||||
if 'keys' not in version[section]:
|
||||
version[section]['keys'] = {}
|
||||
version[section]['keys'][option] = {}
|
||||
version[section]['keys'][option]["default"] = value
|
||||
version[section]['keys'][option]["_type"] = 's'
|
||||
value = value.strip()
|
||||
value = value.strip("'")
|
||||
value = value.strip('"')
|
||||
version[section][option] = {}
|
||||
version[section][option]["_default"] = value
|
||||
version[section][option]["_type"] = 's'
|
||||
|
||||
if not os.path.exists('yaml'):
|
||||
os.makedirs('yaml')
|
||||
# 将字典转换为YAML格式并写入文件
|
||||
with open(f'/home/kylin/yaml/{file.rsplit("/",maxsplit=1)[1].rsplit(".", maxsplit = 1)[0]}.yaml', 'w') as yaml_file:
|
||||
home = os.getenv('HOME')
|
||||
with open(f'{home}/yaml/{file.rsplit("/",maxsplit=1)[1].rsplit(".", maxsplit = 1)[0]}.yaml', 'w') as yaml_file:
|
||||
yaml.dump(data, yaml_file, allow_unicode = True)
|
||||
|
||||
# 参数传入.conf或.ini结尾的ini格式配置文件或目录路径
|
||||
# 将传入的所有配置文件或目录下的所有配置文件转换为yaml格式,生成在~/yaml路径下
|
||||
if __name__ == "__main__":
|
||||
args = sys.argv[1:]
|
||||
for arg in args:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# libkysdk-system's Library
|
||||
#
|
||||
|
@ -16,132 +17,115 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Authors: Yunhe Liu <liuyunhe@kylinos.cn>
|
||||
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
|
||||
#
|
||||
#
|
||||
|
||||
#!/usr/bin/python3
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
import yaml
|
||||
import ast
|
||||
import sys, os, re
|
||||
|
||||
def convert_one_file(file):
|
||||
def convert_one_file(data:dict, path:str, file:str):
|
||||
|
||||
global organization
|
||||
|
||||
# 解析XML文件到树中
|
||||
tree = ET.parse(file)
|
||||
root = tree.getroot()
|
||||
# 将XML数据转换为Python字典
|
||||
data = {}
|
||||
#处理枚举
|
||||
for enum in root.findall('.//enum'):
|
||||
list = []
|
||||
id = enum.attrib.get('id')
|
||||
for value in enum:
|
||||
item = {}
|
||||
item['nick'] = value.get('nick')
|
||||
item['value'] = value.get('value')
|
||||
list.append(item)
|
||||
data[f'enum_{id}'] = list
|
||||
#处理schema下的key, schema不管
|
||||
schema_list = root.findall('.//schema')
|
||||
for schema in schema_list:
|
||||
schema_map = {}
|
||||
keys = {}
|
||||
for key in schema.findall('.//key'):
|
||||
item = {}
|
||||
key_name = key.attrib.get('name')
|
||||
key_type = key.attrib.get('type')
|
||||
#type 不存在 就是枚举类型
|
||||
if key_type is None:
|
||||
enumid = key.attrib.get('enum')
|
||||
item['range'] = f'@enum_{enumid}'
|
||||
item['_type'] = 'enum'
|
||||
for child in key:
|
||||
tag = child.tag
|
||||
item[tag] = child.text.strip('\'')
|
||||
else:
|
||||
item['_type'] = key_type
|
||||
for child in key:
|
||||
text = ""
|
||||
tag = child.tag
|
||||
text = child.text
|
||||
if text is None:
|
||||
text = ''
|
||||
text = text.strip() #去掉前后空白,否则可能影响ast.literal_eval解析字符串
|
||||
text = text.strip('\'') #部分xml空字符串默认值会写''
|
||||
text = text.strip('\"') #部分xml空字符串默认值会写''
|
||||
text = text.replace('\t','') #删除原xml中使下一行缩进而使用的制表符
|
||||
if tag == 'range':
|
||||
item['range'] = f'{child.attrib.get("min")},{child.attrib.get("max")}'
|
||||
# if tag == 'default':
|
||||
# if key_type[0] in 'isbdtou':
|
||||
# item['default'] = text
|
||||
# else:
|
||||
# parser_data = ast.literal_eval(text.strip())
|
||||
# item['default'] = parser_data
|
||||
else:
|
||||
item[tag] = text
|
||||
keys[key_name] = item
|
||||
if keys:
|
||||
schema_map['keys'] = keys
|
||||
data[schema.attrib.get('id').rsplit('.', maxsplit = 1)[1]] = schema_map
|
||||
return data
|
||||
if os.path.exists(f'{path}/{file}'):
|
||||
|
||||
tree = ET.parse(f'{path}/{file}')
|
||||
root = tree.getroot()
|
||||
|
||||
#处理枚举
|
||||
for enum in root.findall('.//enum'):
|
||||
list = []
|
||||
id = enum.attrib.get('id')
|
||||
group_list = id[len(organization) + 1:].split('.')
|
||||
if group_list[0] not in data:
|
||||
data[group_list[0]] = {version:{}}
|
||||
tmp = data[group_list[0]][version]
|
||||
for value in enum:
|
||||
item = {}
|
||||
item['_nick'] = value.get('nick')
|
||||
item['_value'] = value.get('value')
|
||||
list.append(item)
|
||||
tmp[f'enum_{id}'] = list
|
||||
|
||||
#处理schema下的key, schema不管
|
||||
schema_list = root.findall('.//schema')
|
||||
|
||||
for schema in schema_list:
|
||||
id = schema.attrib.get('id')
|
||||
group_list = id[len(organization) + 1:].split('.')
|
||||
if group_list[0] not in data:
|
||||
data[group_list[0]] = {version:{}}
|
||||
tmp = data[group_list[0]][version]
|
||||
for group in group_list[1:]:
|
||||
if group not in tmp:
|
||||
tmp[group] = {}
|
||||
tmp = tmp[group]
|
||||
|
||||
for key in schema.findall('.//key'):
|
||||
item = {}
|
||||
key_name = key.attrib.get('name')
|
||||
key_type = key.attrib.get('type')
|
||||
#type 不存在 就是枚举类型
|
||||
if key_type is None:
|
||||
enumid = key.attrib.get('enum')
|
||||
item['_range'] = f'@enum_{enumid}'
|
||||
item['_type'] = 'enum'
|
||||
else:
|
||||
item['_type'] = key_type
|
||||
for child in key:
|
||||
tag = child.tag
|
||||
text = '' if child.text is None else child.text
|
||||
text = text.strip()
|
||||
text = text.strip('\'') #部分xml空字符串默认值会写''
|
||||
text = text.strip('\"') #部分xml空字符串默认值会写""
|
||||
text = text.replace('\n\t','') #删除原xml中使下一行缩进而使用的制表符
|
||||
if tag == 'range':
|
||||
text = f'{child.attrib.get("min")},{child.attrib.get("max")}'
|
||||
item[f'_{tag}'] = text
|
||||
tmp[key_name] = item
|
||||
else:
|
||||
print(f'{path}/{file} not exists')
|
||||
|
||||
# 转换单个app的所有配置文件,并生成到一个yaml文件中
|
||||
if __name__ == '__main__':
|
||||
app_name = sys.argv[1]
|
||||
app = sys.argv[1]
|
||||
version = '2.0.0-0k0.0'
|
||||
if 3 == len(sys.argv):
|
||||
version = sys.argv[2]
|
||||
# 读取app的所有配置文件
|
||||
app_config_files = {}
|
||||
file_list = []
|
||||
for root, dirs, files in os.walk("/usr/share/glib-2.0/schemas"):
|
||||
if f'{app_name}.gschema.xml' in files:
|
||||
app_config_files[app_name] = convert_one_file(os.path.join(root, f'{app_name}.gschema.xml'))
|
||||
for file in files:
|
||||
if re.match(app_name + r'\..*' + '.gschema.xml' + r'$', file):
|
||||
file_path = os.path.join(root, file)
|
||||
app_config_files[file_path[28:-12]] = convert_one_file(file_path)
|
||||
file_list.append(file_path[28:-12])
|
||||
# 将配置合并
|
||||
# 按照每个元素分割后的字符串个数对列表进行降序排序
|
||||
file_list = sorted(file_list, key=lambda x: len(x.split('.')), reverse= True)
|
||||
# if app_name in file_list:
|
||||
# file_list.remove(app_name)
|
||||
parent = ''
|
||||
child = ''
|
||||
for key in file_list:
|
||||
if key == app_name:
|
||||
break
|
||||
list = key.rsplit('.',maxsplit=1)
|
||||
parent = list[0]
|
||||
child = list[1]
|
||||
# 将本文件的字典 添加到父文件的 'children'组中
|
||||
if parent in app_config_files:
|
||||
if 'children' not in app_config_files[parent][parent.rsplit('.',maxsplit = 1)[1]]:
|
||||
app_config_files[parent][parent.rsplit('.',maxsplit = 1)[1]]['children'] = {}
|
||||
app_config_files[parent][parent.rsplit('.',maxsplit = 1)[1]]['children'].update(app_config_files[key])
|
||||
else:
|
||||
tmp_map = {parent.rsplit('.',maxsplit = 1)[1]:{'children':{}}}
|
||||
tmp_map[parent.rsplit('.',maxsplit = 1)[1]]['children'].update(app_config_files[key])
|
||||
key = parent
|
||||
app_config_files[parent] = tmp_map
|
||||
file_list.append(parent)
|
||||
# 添加假的版本号 生成后需要手改为包的正确版本
|
||||
data = {}
|
||||
data[app_name.rsplit('.',1)[1]] = {}
|
||||
data[app_name.rsplit('.',1)[1]][version] = app_config_files[app_name][app_name.rsplit('.',maxsplit=1)[1]]
|
||||
path = '/usr/share/glib-2.0/schemas'
|
||||
|
||||
if 'keys' in app_config_files[app_name][app_name.rsplit('.',maxsplit=1)[1]].keys():
|
||||
data[app_name.rsplit('.',1)[1]][version]['keys'] = app_config_files[app_name][app_name.rsplit('.',maxsplit=1)[1]]['keys']
|
||||
if len(sys.argv) > 3:
|
||||
path = sys.argv[3]
|
||||
|
||||
organization = app.rsplit('.', 1)[0]
|
||||
|
||||
result = {}
|
||||
|
||||
# 读取app的所有配置文件
|
||||
file_list = []
|
||||
pattren = re.compile(r'^{}.*\.gschema\.xml$'.format(re.escape(app)))
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files:
|
||||
if pattren.match(file):
|
||||
file_list.append(file)
|
||||
|
||||
# 按照每个元素分割后的字符串个数对列表进行降序排序
|
||||
file_list = sorted(file_list, key=lambda x: len(x.split('.')), reverse=False)
|
||||
for file in file_list:
|
||||
convert_one_file(result, path, file)
|
||||
|
||||
# 生成yaml文件
|
||||
yaml_data = yaml.safe_dump(data,allow_unicode = True)
|
||||
yaml_data = yaml.safe_dump(result, allow_unicode = True)
|
||||
|
||||
# 将YAML数据写入文件
|
||||
file = f"/home/kylin/yaml/{app_name}.yaml"
|
||||
if not os.path.exists('/home/kylin/yaml'):
|
||||
os.makedirs('/home/kylin/yaml')
|
||||
home = os.getenv('HOME')
|
||||
file = f"{home}/yaml/{app}.yaml"
|
||||
if not os.path.exists(os.path.dirname(file)):
|
||||
os.makedirs(os.path.dirname(file), exist_ok=True)
|
||||
|
||||
with open(file, 'w') as yaml_file:
|
||||
yaml_file.write(yaml_data)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# libkysdk-system's Library
|
||||
#
|
||||
# Copyright (C) 2023, KylinSoft Co., Ltd.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 3 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Authors: tianshaoshuai <tianshaoshuai@kylinos.cn>
|
||||
#
|
||||
#
|
||||
|
||||
import yaml, json
|
||||
import sys, os
|
||||
|
||||
def retrofit_the_structure(src:dict, dest:dict):
|
||||
if not isinstance(src, dict):
|
||||
# dest.update({'value':str(src)})
|
||||
print(f"{src}'s root node not a dict")
|
||||
return
|
||||
for key, value in src.items():
|
||||
if isinstance(value, dict):
|
||||
dest[key] = {}
|
||||
retrofit_the_structure(src[key], dest[key])
|
||||
else:
|
||||
dest[key] = {}
|
||||
if isinstance(value, list):
|
||||
dest[key]['_type'] = 'as'
|
||||
dest[key]['_default'] = str(src[key])
|
||||
else:
|
||||
dest[key]['_type'] = 's'
|
||||
dest[key]['_default'] = src[key]
|
||||
|
||||
def convert_one_file(src:str):
|
||||
with open(src, 'r') as file:
|
||||
data = json.loads(file.read())
|
||||
base_name = os.path.basename(src)
|
||||
name = os.path.splitext(base_name)[0]
|
||||
result = {name : {'2.0.0.0-0k0.0': {}}}
|
||||
retrofit_the_structure(data, result[name]['2.0.0.0-0k0.0'])
|
||||
|
||||
home = os.getenv('HOME')
|
||||
if not os.path.exists(f'{home}/yaml'):
|
||||
os.mkdir(f'{home}/yaml')
|
||||
with open(f'{home}/yaml/{base_name[:-5]}.yaml', 'w') as yaml_file:
|
||||
yaml_file.write(yaml.safe_dump(result, allow_unicode = True))
|
||||
|
||||
# 参数传入.json结尾的json格式配置文件或目录路径
|
||||
# 将传入的所有配置文件或目录下的所有配置文件转换为yaml格式,生成在~/yaml路径下
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
for arg in args:
|
||||
if os.path.isdir(arg):
|
||||
for root, dirs, files in os.walk(arg):
|
||||
for file in files:
|
||||
if file.endswith('.json'):
|
||||
|
||||
convert_one_file(f'{root}/{file}')
|
||||
else:
|
||||
if arg.endswith('.json'):
|
||||
convert_one_file(arg)
|
||||
else:
|
||||
print(f'argument{arg} is not a json file')
|
|
@ -22,19 +22,21 @@
|
|||
#include "../api/ksettingsschema.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkScrolledWindow *left_scrolled_window = NULL;
|
||||
static GtkScrolledWindow *right_scrolled_window = NULL;
|
||||
|
||||
//左侧配置树
|
||||
// 左侧配置树
|
||||
static GtkTreeView *tree_folders = NULL;
|
||||
|
||||
//左侧树选中节点对应的键值表
|
||||
// 左侧树选中节点对应的键值表
|
||||
static GtkTreeView *table_configure = NULL;
|
||||
|
||||
//tree_folders节点路径: 路径组成的schema id的配置数据
|
||||
// tree_folders节点路径: 路径组成的schema id的配置数据
|
||||
static GHashTable *configure_models = NULL;
|
||||
|
||||
enum ConfigureAttr
|
||||
|
@ -72,7 +74,7 @@ void on_entry_button_clicked(GtkButton *button, gpointer user_data)
|
|||
int is_compliance = 0;
|
||||
const gchar *endptr = NULL;
|
||||
GError *error = NULL;
|
||||
char *type = g_hash_table_lookup(schema_key, "data_type");
|
||||
char *type = g_hash_table_lookup(schema_key, "value_type");
|
||||
if (0 != strcmp(type, "enum"))
|
||||
{
|
||||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE(type), text, NULL, &endptr, &error);
|
||||
|
@ -145,7 +147,20 @@ void on_entry_button_clicked(GtkButton *button, gpointer user_data)
|
|||
goto out;
|
||||
}
|
||||
|
||||
GVariant *variant = g_variant_new("(sssss)", getlogin(), schema->id, schema->version, list[1], text);
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
}
|
||||
|
||||
GVariant *variant = g_variant_new("(sssss)", user_name, schema->id, schema->version, list[1], text);
|
||||
result = g_dbus_proxy_call_sync(proxy,
|
||||
"set",
|
||||
variant,
|
||||
|
@ -155,6 +170,7 @@ void on_entry_button_clicked(GtkButton *button, gpointer user_data)
|
|||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
printf("%s", error->message);
|
||||
g_error_free(error);
|
||||
goto out;
|
||||
}
|
||||
|
@ -171,7 +187,7 @@ out:
|
|||
g_object_unref(connection);
|
||||
if (response)
|
||||
{
|
||||
g_hash_table_replace(schema_key, "user_value", text);
|
||||
g_hash_table_replace(schema_key, "custom_value", text);
|
||||
|
||||
GtkTreeIter iter;
|
||||
GtkListStore *store = gtk_tree_view_get_model(table_configure);
|
||||
|
@ -185,9 +201,9 @@ out:
|
|||
{
|
||||
gtk_list_store_append(store, &iter);
|
||||
gtk_list_store_set(store, &iter,
|
||||
COLUMN_NAME, g_hash_table_lookup(value, "property"),
|
||||
COLUMN_TYPE, g_hash_table_lookup(value, "data_type"),
|
||||
COLUMN_VALUE, g_hash_table_lookup(value, "user_value") ? g_hash_table_lookup(value, "user_value") : g_hash_table_lookup(value, "default_value"),
|
||||
COLUMN_NAME, g_hash_table_lookup(value, "node_name"),
|
||||
COLUMN_TYPE, g_hash_table_lookup(value, "value_type"),
|
||||
COLUMN_VALUE, g_hash_table_lookup(value, "custom_value") ? g_hash_table_lookup(value, "custom_value") : g_hash_table_lookup(value, "default_value"),
|
||||
COLUMN_SUMMARY, g_hash_table_lookup(value, "summary"),
|
||||
-1);
|
||||
}
|
||||
|
@ -250,7 +266,7 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
|
|||
|
||||
GtkWidget *vbox = gtk_vbox_new(FALSE, 15);
|
||||
|
||||
sprintf(tmp, "%s%s", title_array[0], g_hash_table_lookup(schema_key, "property"));
|
||||
sprintf(tmp, "%s%s", title_array[0], g_hash_table_lookup(schema_key, "node_name"));
|
||||
GtkWidget *name_label = gtk_label_new(tmp);
|
||||
gtk_widget_set_halign(name_label, GTK_ALIGN_START);
|
||||
gtk_box_pack_start(vbox, name_label, TRUE, TRUE, 0);
|
||||
|
@ -271,13 +287,13 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
|
|||
gtk_widget_set_halign(description_label, GTK_ALIGN_START);
|
||||
gtk_box_pack_start(vbox, description_label, TRUE, TRUE, 0);
|
||||
|
||||
sprintf(tmp, "%s%s", title_array[4], g_hash_table_lookup(schema_key, "data_type"));
|
||||
sprintf(tmp, "%s%s", title_array[4], g_hash_table_lookup(schema_key, "value_type"));
|
||||
GtkWidget *type_label = gtk_label_new(tmp);
|
||||
gtk_widget_set_halign(type_label, GTK_ALIGN_START);
|
||||
gtk_box_pack_start(vbox, type_label, TRUE, TRUE, 0);
|
||||
|
||||
char *range = g_hash_table_lookup(schema_key, "range");
|
||||
if ((NULL != range) && (0 != strcmp("enum", g_hash_table_lookup(schema_key, "data_type"))))
|
||||
if ((NULL != range) && (0 != strcmp("enum", g_hash_table_lookup(schema_key, "value_type"))))
|
||||
{
|
||||
char **list = g_strsplit(range, ",", -1);
|
||||
sprintf(tmp, "%s%s", title_array[5], list[0]);
|
||||
|
@ -299,7 +315,7 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
|
|||
gtk_widget_set_halign(default_label, GTK_ALIGN_START);
|
||||
gtk_box_pack_start(vbox, default_label, TRUE, TRUE, 0);
|
||||
|
||||
sprintf(tmp, "%s%s", title_array[8], g_hash_table_lookup(schema_key, "user_value") ? g_hash_table_lookup(schema_key, "user_value") : "默认值");
|
||||
sprintf(tmp, "%s%s", title_array[8], g_hash_table_lookup(schema_key, "custom_value") ? g_hash_table_lookup(schema_key, "custom_value") : "默认值");
|
||||
GtkWidget *value_label = gtk_label_new(tmp);
|
||||
gtk_label_set_line_wrap_mode(GTK_LABEL(value_label), GTK_WRAP_WORD);
|
||||
// gtk_label_set_line_wrap(GTK_LABEL(value_label), TRUE);
|
||||
|
@ -314,7 +330,7 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
|
|||
GtkWidget *entry_button = gtk_button_new_with_label("设置自定义值");
|
||||
gtk_widget_set_halign(entry_button, GTK_ALIGN_START);
|
||||
// name 用来传参。。。。。。
|
||||
sprintf(tmp, "%s|%s", gtk_tree_path_to_string(path), g_hash_table_lookup(schema_key, "property"));
|
||||
sprintf(tmp, "%s|%s", gtk_tree_path_to_string(path), g_hash_table_lookup(schema_key, "node_name"));
|
||||
gtk_widget_set_name(entry_button, tmp);
|
||||
gtk_box_pack_start(entry_vbox, entry_button, TRUE, TRUE, 0);
|
||||
|
||||
|
@ -323,9 +339,9 @@ static void on_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeVi
|
|||
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view), GTK_WRAP_WORD);
|
||||
gtk_box_pack_start(vbox, text_view, TRUE, TRUE, 0);
|
||||
|
||||
char *user_value = g_hash_table_lookup(schema_key, "user_value") ? g_hash_table_lookup(schema_key, "user_value") : g_hash_table_lookup(schema_key, "default_value");
|
||||
char *custom_value = g_hash_table_lookup(schema_key, "custom_value") ? g_hash_table_lookup(schema_key, "custom_value") : g_hash_table_lookup(schema_key, "default_value");
|
||||
GtkWidget *buffer = gtk_text_buffer_new(NULL);
|
||||
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(buffer), user_value, strlen(user_value));
|
||||
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(buffer), custom_value, strlen(custom_value));
|
||||
gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_view), GTK_TEXT_BUFFER(buffer));
|
||||
|
||||
if ((NULL != writable) && (0 != strcmp(writable, "public")))
|
||||
|
@ -367,24 +383,27 @@ static void on_selection_changed(GtkTreeSelection *selection, gpointer data)
|
|||
|
||||
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
|
||||
KSettingsSchema *schema = g_hash_table_lookup(configure_models, gtk_tree_path_to_string(path));
|
||||
char *select_path = gtk_tree_path_to_string(path);
|
||||
|
||||
char node_path[2048];
|
||||
char node_path[2048], tmp_path[64];
|
||||
memset(node_path, 0, 2048);
|
||||
char *tmp_path = gtk_tree_path_to_string(path);
|
||||
GValue node_name = G_VALUE_INIT;
|
||||
for (int i = 1; i <= strlen(tmp_path); i += 2)
|
||||
memset(tmp_path, 0, 64);
|
||||
char **nodes = g_strsplit(select_path, ":", -1);
|
||||
for (int i = 0; nodes[i]; i++)
|
||||
{
|
||||
char tmp[1024];
|
||||
memset(tmp, 0, 1024);
|
||||
strncpy(tmp, tmp_path, i);
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, tmp);
|
||||
GValue node_name = G_VALUE_INIT;
|
||||
strcat(tmp_path, nodes[i]);
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, tmp_path);
|
||||
gtk_tree_model_get_value(model, &iter, 0, &node_name);
|
||||
if (0 < strlen(node_path))
|
||||
sprintf(node_path, "%s/%s", node_path, g_value_get_string(&node_name));
|
||||
else
|
||||
strcpy(node_path, g_value_get_string(&node_name));
|
||||
g_value_unset(&node_name);
|
||||
strcat(tmp_path, ":");
|
||||
}
|
||||
g_strfreev(nodes);
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(data), node_path);
|
||||
|
||||
GtkListStore *store = gtk_tree_view_get_model(table_configure);
|
||||
|
@ -401,9 +420,9 @@ static void on_selection_changed(GtkTreeSelection *selection, gpointer data)
|
|||
{
|
||||
gtk_list_store_append(store, &iter);
|
||||
gtk_list_store_set(store, &iter,
|
||||
COLUMN_NAME, g_hash_table_lookup(value, "property"),
|
||||
COLUMN_TYPE, g_hash_table_lookup(value, "data_type"),
|
||||
COLUMN_VALUE, g_hash_table_lookup(value, "user_value") ? g_hash_table_lookup(value, "user_value") : g_hash_table_lookup(value, "default_value"),
|
||||
COLUMN_NAME, g_hash_table_lookup(value, "node_name"),
|
||||
COLUMN_TYPE, g_hash_table_lookup(value, "value_type"),
|
||||
COLUMN_VALUE, g_hash_table_lookup(value, "custom_value") ? g_hash_table_lookup(value, "custom_value") : g_hash_table_lookup(value, "default_value"),
|
||||
COLUMN_SUMMARY, g_hash_table_lookup(value, "summary"),
|
||||
-1);
|
||||
}
|
||||
|
@ -454,7 +473,7 @@ static void _find_search_node(char **list, GtkTreePath **path, GtkTreeModel *mod
|
|||
static void on_search_entry_activated(GtkWidget *entry, gpointer user_data)
|
||||
{
|
||||
const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
|
||||
if(g_str_equal("", text))
|
||||
if (g_str_equal("", text))
|
||||
return;
|
||||
char **list = g_strsplit(text, "/", -1);
|
||||
|
||||
|
@ -484,23 +503,27 @@ static void on_search_entry_activated(GtkWidget *entry, gpointer user_data)
|
|||
if (gtk_tree_selection_get_selected(selection, &model, &iter))
|
||||
{
|
||||
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
|
||||
char node_path[2048];
|
||||
char *select_path = gtk_tree_path_to_string(path);
|
||||
|
||||
char node_path[2048], tmp_path[64];
|
||||
memset(node_path, 0, 2048);
|
||||
char *tmp_path = gtk_tree_path_to_string(path);
|
||||
GValue node_name = G_VALUE_INIT;
|
||||
for (int i = 1; i <= strlen(tmp_path); i += 2)
|
||||
memset(tmp_path, 0, 64);
|
||||
char **nodes = g_strsplit(select_path, ":", -1);
|
||||
for (int i = 0; nodes[i]; i++)
|
||||
{
|
||||
char tmp[1024];
|
||||
memset(tmp, 0, 1024);
|
||||
strncpy(tmp, tmp_path, i);
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, tmp);
|
||||
GValue node_name = G_VALUE_INIT;
|
||||
strcat(tmp_path, nodes[i]);
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, tmp_path);
|
||||
gtk_tree_model_get_value(model, &iter, 0, &node_name);
|
||||
if (0 < strlen(node_path))
|
||||
sprintf(node_path, "%s/%s", node_path, g_value_get_string(&node_name));
|
||||
else
|
||||
strcpy(node_path, g_value_get_string(&node_name));
|
||||
g_value_unset(&node_name);
|
||||
strcat(tmp_path, ":");
|
||||
}
|
||||
g_strfreev(nodes);
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(entry), node_path);
|
||||
}
|
||||
g_strfreev(list);
|
||||
|
@ -509,6 +532,7 @@ static void on_search_entry_activated(GtkWidget *entry, gpointer user_data)
|
|||
g_strfreev(list);
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_folders);
|
||||
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(tree_folders), path);
|
||||
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(tree_folders), path, NULL, FALSE, 0.0, 0.0);
|
||||
gtk_tree_selection_select_path(selection, path);
|
||||
|
||||
gtk_widget_queue_draw(tree_folders);
|
||||
|
@ -526,10 +550,10 @@ static void on_folder_selected(GtkFileChooser *chooser, gint response_id, gpoint
|
|||
if (0 == success)
|
||||
{
|
||||
GtkWidget *dialog = gtk_message_dialog_new(NULL,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
"保存配置数据到文件失败");
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK,
|
||||
"保存配置数据到文件失败");
|
||||
|
||||
// 运行消息框
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
|
@ -538,7 +562,7 @@ static void on_folder_selected(GtkFileChooser *chooser, gint response_id, gpoint
|
|||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -573,12 +597,12 @@ static gboolean entry_match_func(GtkEntryCompletion *completion, const char *key
|
|||
gtk_tree_model_get(model, iter, 0, &value, -1);
|
||||
|
||||
char *p = value, *q = p;
|
||||
for(; *p != '\0'; p++)
|
||||
for (; *p != '\0'; p++)
|
||||
{
|
||||
if(*p == '/')
|
||||
if (*p == '/')
|
||||
q = p;
|
||||
}
|
||||
if(strstr(q, key))
|
||||
if (strstr(q, key))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
|
@ -644,6 +668,8 @@ static void draw_scrolled_window(GtkTreeStore *store_app, GtkTreeStore *store_co
|
|||
{
|
||||
if (NULL == schemas_table)
|
||||
kdk_conf2_schema_update_schemas_table();
|
||||
if (NULL == schemas_table)
|
||||
exit(0);
|
||||
|
||||
GtkTreeIter iter;
|
||||
|
||||
|
@ -701,7 +727,6 @@ int main(int argc, char *argv[])
|
|||
gtk_box_pack_start(GTK_BOX(box), search_entry, FALSE, FALSE, 0);
|
||||
g_signal_connect(search_entry, "activate", G_CALLBACK(on_search_entry_activated), NULL);
|
||||
|
||||
|
||||
GtkWidget *completion = gtk_entry_completion_new();
|
||||
gtk_entry_completion_set_text_column(GTK_ENTRY_COMPLETION(completion), 0);
|
||||
gtk_entry_completion_set_match_func(GTK_ENTRY_COMPLETION(completion), entry_match_func, NULL, NULL);
|
||||
|
|
|
@ -0,0 +1,376 @@
|
|||
#!/usr/bin/python3
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
import logging
|
||||
sys.path.append('/home/kylin/disk/kylinos-src/libkysdk-base/src/conf2/service')
|
||||
import conf2Utils
|
||||
import tkinter as tk
|
||||
import tkinter.ttk as ttk
|
||||
import tkinter.messagebox as msgbox
|
||||
import tkinter.filedialog as filedialog
|
||||
import dbus
|
||||
from gi.repository import GLib
|
||||
|
||||
target_view = {}
|
||||
|
||||
def on_tree_right_click(event):
|
||||
global right_select_item
|
||||
item = tree.identify_row(event.y)
|
||||
if item and tree.parent(item) == "":
|
||||
right_select_item = item
|
||||
download_menu.post(event.x_root, event.y_root)
|
||||
|
||||
def close_menu(event):
|
||||
download_menu.unpost()
|
||||
|
||||
def on_search():
|
||||
pack_list = root.pack_slaves()
|
||||
if view_frame in pack_list:
|
||||
view_frame.pack_forget()
|
||||
search_frame.pack(side='bottom', fill='both', expand=True)
|
||||
search_tree.delete(*search_tree.get_children())
|
||||
search_entry.config(state='normal')
|
||||
# search_entry.event_generate("<KeyRelease>")
|
||||
else:
|
||||
search_frame.pack_forget()
|
||||
view_frame.pack(side='bottom', fill='both', expand=True)
|
||||
items = tree.selection()
|
||||
if items:
|
||||
text = tree.item(items[0], 'tags')[0]
|
||||
search_entry.delete(0, 'end')
|
||||
search_entry.insert(0, text)
|
||||
else:
|
||||
search_entry.delete(0, 'end')
|
||||
search_entry.config(state='readonly')
|
||||
|
||||
def on_search_entry_change(event):
|
||||
new_text = event.widget.get()
|
||||
search_tree.delete(*search_tree.get_children())
|
||||
if new_text == '':
|
||||
return
|
||||
for key in search_list.keys():
|
||||
name_list = key.split('/')
|
||||
if new_text in name_list[-1] or key.startswith(new_text):
|
||||
search_tree.insert('', 'end', text= key)
|
||||
|
||||
def on_download():
|
||||
global target_view
|
||||
path = filedialog.askdirectory(mustexist=True, title=' Choose a folder')
|
||||
if path:
|
||||
success = converter.editor_save(target_view, path)
|
||||
if success:
|
||||
msgbox.showinfo(message='Save successed')
|
||||
else:
|
||||
msgbox.showinfo(message='Save failed')
|
||||
|
||||
def on_download_one():
|
||||
global target_view
|
||||
key = tree.item(right_select_item, 'text')
|
||||
path = filedialog.askdirectory(mustexist=True, title=' Choose a folder')
|
||||
if path:
|
||||
success = converter.editor_save({key:target_view[key]}, path)
|
||||
if success:
|
||||
msgbox.showinfo(message='Save successed')
|
||||
else:
|
||||
msgbox.showinfo(message='Save failed')
|
||||
|
||||
def on_import_file():
|
||||
pass
|
||||
|
||||
def on_set():
|
||||
try:
|
||||
if combobox.get() != 'custom':
|
||||
msgbox.showinfo(message='Not custom veiw')
|
||||
|
||||
user = destination_file.split('/')[2]
|
||||
|
||||
key = id = value = ''
|
||||
for widget in inner_frame.winfo_children():
|
||||
if isinstance(widget, tk.Text):
|
||||
if 'key' in widget.winfo_name:
|
||||
key = widget.get()
|
||||
if 'id' in widget.winfo_name:
|
||||
id = widget.get()
|
||||
if 'custom' in widget.winfo_name:
|
||||
value = widget.get()
|
||||
|
||||
path = search_entry.get()
|
||||
version = path.split('/')[1]
|
||||
print(f'{user} {id} {version} {key} {value}')
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
obj = bus.get_object('com.kylin.kysdk.conf2', '/com/kylin/kysdk/conf2')
|
||||
interface = dbus.Interface(obj, 'com.kylin.kysdk.conf2')
|
||||
# success = interface.set(user, id, version, key, value)
|
||||
# if success:
|
||||
# global target_view
|
||||
# target_view = converter._db2dict(f'{destination_file}/.config/kylin-config/user.db')
|
||||
# msgbox.showinfo(message='Set successed')
|
||||
# else:
|
||||
# msgbox.showinfo(message='Set failed')
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def on_search_tree_select(event):
|
||||
items = search_tree.selection()
|
||||
text = search_tree.item(items[0], 'text')
|
||||
tree.selection_set(search_list[text])
|
||||
tree.see(search_list[text])
|
||||
search_frame.pack_forget()
|
||||
view_frame.pack(side='bottom', fill='both', expand=True)
|
||||
|
||||
def on_tree_select(event):
|
||||
selected_item = tree.selection()
|
||||
global target_view
|
||||
if not selected_item:
|
||||
return
|
||||
item = selected_item[0]
|
||||
tag = tree.item(item, 'tags')[0]
|
||||
|
||||
search_entry.config(state='normal')
|
||||
search_entry.delete(0, 'end')
|
||||
search_entry.insert(0, tag)
|
||||
search_entry.config(state='readonly')
|
||||
|
||||
if tree.parent(item) == '':
|
||||
return
|
||||
|
||||
group_list = tag.split('/')
|
||||
tmp = target_view
|
||||
for group in group_list:
|
||||
tmp = tmp[group]
|
||||
for widget in inner_frame.winfo_children():
|
||||
widget.destroy()
|
||||
|
||||
text = tree.item(item, 'text')
|
||||
|
||||
name_label = tk.Label(inner_frame, text=f'名称', anchor='w')
|
||||
name_label.pack(side='top', fill='x')
|
||||
|
||||
name_text = tk.Text(inner_frame, height=1, width=100, wrap='word', name='key')
|
||||
name_text.insert('1.0', text)
|
||||
name_text.config(state='disabled')
|
||||
name_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
type = tmp['_type'] if '_type' in tmp else 'group'
|
||||
|
||||
if len(group_list) > 1:
|
||||
group_list.pop(1)
|
||||
if type != 'group':
|
||||
group_list.pop(-1)
|
||||
|
||||
id_label = tk.Label(inner_frame, text=f'路径', anchor='w')
|
||||
id_label.pack(side='top', fill='x')
|
||||
|
||||
id_text = tk.Text(inner_frame, height=1, width=100, wrap='word', name='id')
|
||||
id_text.insert('1.0', '.'.join(group_list))
|
||||
id_text.config(state='disabled')
|
||||
id_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
type_label = tk.Label(inner_frame, text=f'类型', anchor='w')
|
||||
type_label.pack(side='top', fill='x')
|
||||
|
||||
type_text = tk.Text(inner_frame, height=1, width=100, wrap='word', name='type')
|
||||
type_text.insert('1.0', type)
|
||||
type_text.config(state='disabled')
|
||||
type_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
if tmp.get('_summary') is not None:
|
||||
summary_label = tk.Label(inner_frame, text=f'摘要', anchor='w')
|
||||
summary_label.pack(side='top', fill='x')
|
||||
|
||||
summary_text = tk.Text(inner_frame, height=3, width=100, wrap='word')
|
||||
summary_text.insert('1.0', tmp.get('_summary'))
|
||||
summary_text.config(state='disabled')
|
||||
summary_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
if tmp.get('_description') is not None:
|
||||
decription_label = tk.Label(inner_frame, text=f'描述', anchor='w')
|
||||
decription_label.pack(side='top', fill='x')
|
||||
|
||||
decription_text = tk.Text(inner_frame, height=3, width=100, wrap='word')
|
||||
decription_text.insert('1.0', tmp.get('_description'))
|
||||
decription_text.config(state='disabled')
|
||||
decription_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
permission = tmp.get('_permission', 'public')
|
||||
permission_label = tk.Label(inner_frame, text=f'权限', anchor='w')
|
||||
permission_label.pack(side='top', fill='x')
|
||||
|
||||
permission_text = tk.Text(inner_frame, height=1, width=100, wrap='word')
|
||||
permission_text.insert('1.0', permission)
|
||||
permission_text.config(state='disabled')
|
||||
permission_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
if '_default' in tmp:
|
||||
default_value = tmp['_default']
|
||||
if isinstance(default_value, bool):
|
||||
default_value = 'true' if tmp['_default'] else 'false'
|
||||
|
||||
default_label = tk.Label(inner_frame, text=f'默认值', anchor='w')
|
||||
default_label.pack(side='top', fill='x')
|
||||
|
||||
default_text = tk.Text(inner_frame, height=5, width=100, wrap='word', name='default')
|
||||
default_text.insert('1.0', tmp['_default'])
|
||||
default_text.config(state='disabled')
|
||||
default_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
custom_value = tmp.get('_value')
|
||||
if custom_value is None or custom_value == default_value:
|
||||
custom_value = '默认值'
|
||||
custom_label = tk.Label(inner_frame, text=f'当前值', anchor='w')
|
||||
custom_label.pack(side='top', fill='x')
|
||||
|
||||
custom_text = tk.Text(inner_frame, height=5, width=100, wrap='word', name='custom')
|
||||
custom_text.insert('1.0', custom_value)
|
||||
custom_text.config(state='disabled')
|
||||
custom_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
if type != 'group' and permission == 'public' and combobox.get() == 'custom':
|
||||
custom_text.config(state='normal')
|
||||
set_button = tk.Button(inner_frame, text='Set', command=on_set)
|
||||
set_button.pack(side='top')
|
||||
|
||||
def on_combobox_select(event):
|
||||
selected_item = combobox.get()
|
||||
global target_view
|
||||
if selected_item == 'custom':
|
||||
target_view = converter._db2dict(f'{destination_file}/.config/kylin-config/user.db')
|
||||
else:
|
||||
dirs = []
|
||||
for dir in list(reversed(options)):
|
||||
if dir == 'user':
|
||||
dirs.append(f'{destination_file}/.config/kylin-config/configs')
|
||||
else:
|
||||
dirs.append(f'/etc/kylin-config/{dir}')
|
||||
if dir == selected_item:
|
||||
break
|
||||
target_view = converter.load_dirs_config(dirs)
|
||||
|
||||
tree.delete(*tree.get_children())
|
||||
for widget in inner_frame.winfo_children():
|
||||
widget.destroy()
|
||||
search_list.clear()
|
||||
populate_tree(tree, '', target_view)
|
||||
view_frame.update()
|
||||
|
||||
def populate_tree(tree, node, dictionary):
|
||||
global search_list
|
||||
tag = tree.item(node, 'tags')
|
||||
for key, value in dictionary.items():
|
||||
if isinstance(value, dict):
|
||||
child_node = tree.insert(node, 'end', text=key)
|
||||
if isinstance(tag, str):
|
||||
tree.item(child_node, tags=(key))
|
||||
else:
|
||||
tree.item(child_node, tags=(f'{tag[0]}/{key}'))
|
||||
search_list[f'{tag[0]}/{key}'] = child_node
|
||||
populate_tree(tree, child_node, value)
|
||||
|
||||
root = tk.Tk()
|
||||
root.title("kconf2-editor")
|
||||
root.geometry('1024x768')
|
||||
root.bind("<Button-1>", close_menu)
|
||||
|
||||
download_menu = tk.Menu(root, tearoff=0)
|
||||
download_menu.add_command(label="下载", command=on_download_one)
|
||||
download_menu.add_command(label="导入到其他目录", command=on_import_file)
|
||||
|
||||
search_list = {}
|
||||
|
||||
destination_file = os.getenv('HOME')
|
||||
logger = logging.getLogger(f'{destination_file}/.log/widget.log')
|
||||
converter = conf2Utils.Converter(logger)
|
||||
|
||||
# 读取统一视图
|
||||
target_view = converter._db2dict(f'{destination_file}/.config/kylin-config/user.db')
|
||||
|
||||
# 创建一个Frame来包含按钮,使其一直位于界面上方
|
||||
button_frame = tk.Frame(root, height=10)
|
||||
# 创建一个Frame来包含Treeview,占满界面其他空余部分
|
||||
view_frame = tk.Frame(root)
|
||||
# 创建一个Frame来显示搜索结果,它与view_frame只会显示一个
|
||||
search_frame = tk.Frame(root)
|
||||
|
||||
# 排列root的三个子组件
|
||||
button_frame.pack(side="top", fill="x")
|
||||
view_frame.pack(side='top', fill='both', expand=True)
|
||||
|
||||
# 搜索栏
|
||||
search_entry = tk.Entry(button_frame, state='readonly')
|
||||
search_entry.bind("<KeyRelease>", on_search_entry_change)
|
||||
|
||||
# 搜索按钮
|
||||
# search_icon = tk.BitmapImage(data=search_icon_data)
|
||||
search_button = tk.Button(button_frame, text= 's', command=on_search, width=20)
|
||||
|
||||
# 下载按钮
|
||||
# download_icon = tk.PhotoImage(file="download_icon.png")
|
||||
download_button = tk.Button(button_frame, text= 'd', command=on_download, width=20)
|
||||
|
||||
# 视图选择列表
|
||||
with open('/etc/kylin-config/conf2.yaml', 'r') as file:
|
||||
configures = yaml.safe_load(file)
|
||||
options = configures['dirs']
|
||||
if os.path.exists(f'{destination_file}/.config/kylin-config/configs'):
|
||||
options.append('user')
|
||||
options.append('custom')
|
||||
options.reverse()
|
||||
|
||||
combobox = ttk.Combobox(button_frame, values=options, width=20, state='readonly')
|
||||
combobox.set(options[0])
|
||||
combobox.bind("<<ComboboxSelected>>", on_combobox_select)
|
||||
|
||||
# 排列button_frame子组件
|
||||
search_entry.pack(side="left", fill="both", expand= True)
|
||||
combobox.pack(side='right')
|
||||
download_button.pack(side="right", fill="x")
|
||||
search_button.pack(side="right", fill="x")
|
||||
|
||||
# 创建Frame在view_frame的左侧,显示配置树
|
||||
left_frame = tk.Frame(view_frame)
|
||||
left_frame.pack(side='left', fill='both')
|
||||
|
||||
# 创建Treeview,显示配置树
|
||||
tree = ttk.Treeview(left_frame)
|
||||
tree.column('#0', width=200, stretch=True)
|
||||
tree.heading('#0', text='SubFolders')
|
||||
tree.bind("<<TreeviewSelect>>", on_tree_select)
|
||||
tree.bind("<Button-3>", on_tree_right_click)
|
||||
search_list.clear()
|
||||
populate_tree(tree, '', target_view)
|
||||
tree.pack(side='left', fill='both')
|
||||
|
||||
# 创建滚动条
|
||||
tree_scrollbar = ttk.Scrollbar(left_frame, orient="vertical", command=tree.yview)
|
||||
tree_scrollbar.pack(side="right", fill="y")
|
||||
tree.configure(yscrollcommand=tree_scrollbar.set)
|
||||
|
||||
# 创建Frame在view_frame的右侧,显示配置信息
|
||||
right_frame = tk.Frame(view_frame)
|
||||
right_frame.pack(side='right', fill='both', expand=True)
|
||||
|
||||
# 创建一个Canvas
|
||||
canvas = tk.Canvas(right_frame)
|
||||
canvas.pack(side="left", fill="both", expand=True)
|
||||
|
||||
# 将Canvas的窗口设置为Frame
|
||||
inner_frame = tk.Frame(canvas)
|
||||
inner_frame.grid(row=0, column=0, sticky="nsew")
|
||||
canvas_window = canvas.create_window((0, 0), window=inner_frame, anchor="nw")
|
||||
|
||||
right_scrollbar = ttk.Scrollbar(right_frame, orient="vertical", command=canvas.yview)
|
||||
right_scrollbar.pack(side="right", fill="y")
|
||||
canvas.configure(yscrollcommand=right_scrollbar.set)
|
||||
|
||||
# 创建Treeview显示搜索匹配的路径
|
||||
search_tree = ttk.Treeview(search_frame, show='tree')
|
||||
search_tree.bind("<<TreeviewSelect>>", on_search_tree_select)
|
||||
search_tree.pack(side='left', fill='both', expand=True)
|
||||
|
||||
search_scrollbar = ttk.Scrollbar(search_frame, orient="vertical", command=search_tree.yview)
|
||||
search_scrollbar.pack(side="right", fill="y")
|
||||
search_tree.configure(yscrollcommand=search_scrollbar.set)
|
||||
|
||||
root.mainloop()
|
|
@ -23,13 +23,18 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
void key_changed(KSettings *ksettigns, const char *key, void *user_data)
|
||||
void on_key_changed(KSettings *ksettigns, const char *key, void *user_data)
|
||||
{
|
||||
char *value = kdk_conf2_get_value(ksettigns, key);
|
||||
printf("%s changed to %s\n", key, value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
void on_reload(KSettings *ksettigns, void *user_data)
|
||||
{
|
||||
printf("view reload\n");
|
||||
}
|
||||
|
||||
/*句柄结构体内部元素*/
|
||||
typedef struct _KSettingsPrivate
|
||||
{
|
||||
|
@ -62,6 +67,7 @@ static void print_help()
|
|||
// " reset-recursively Reset all values in a given schema\n"
|
||||
" writable Check if a key is writable\n"
|
||||
" monitor Watch for changes\n"
|
||||
// " monitor-reload Watch for realod\n"
|
||||
" save Save User config in target folder"
|
||||
"\n"
|
||||
"Use kconf2 help \"COMMAND\" to get detailed help.\n");
|
||||
|
@ -211,10 +217,21 @@ static void print_command(char *command)
|
|||
" VERSION Specify the version of the schema\n"
|
||||
" KEY Key in the schema\n");
|
||||
}
|
||||
// else if (0 == strcmp(command, "monitor-reload"))
|
||||
// {
|
||||
// printf("Usage:\n"
|
||||
// " kconf2 monitor-reload\n"
|
||||
// "\n"
|
||||
// "Monitor reload to the view.\n"
|
||||
// "Use ^C to stop monitoring.\n"
|
||||
// "\n"
|
||||
// "Args\n"
|
||||
// " SCHEMA The name of the schema\n");
|
||||
// }
|
||||
else if (0 == strcmp(command, "list-schemas"))
|
||||
{
|
||||
printf("Usage:\n"
|
||||
" kconf2 list-scemas [APP] [VERSION]\n"
|
||||
" kconf2 list-scemas APP [VERSION]\n"
|
||||
"\n"
|
||||
"If you don't specify an app and version, list all installed schemas.\n"
|
||||
"otherwise list schemas items that specify the app and version.\n"
|
||||
|
@ -265,7 +282,10 @@ int main(int argc, char *argv[])
|
|||
if (0 == strcmp(argv[1], "list-schemas"))
|
||||
{
|
||||
if (argc < 3)
|
||||
print_help("list-schemas");
|
||||
{
|
||||
print_command("list-schemas");
|
||||
exit(0);
|
||||
}
|
||||
gboolean limit_app = FALSE, limit_version = FALSE;
|
||||
if (argc > 2)
|
||||
limit_app = TRUE;
|
||||
|
@ -296,13 +316,13 @@ int main(int argc, char *argv[])
|
|||
g_hash_table_iter_init(&ver_iter, app_hash);
|
||||
while (g_hash_table_iter_next(&ver_iter, &version, &version_hash))
|
||||
{
|
||||
if (limit_version && 0 != strcmp(argv[3], app->name))
|
||||
if (limit_version && 0 != strcmp(argv[3], version->name))
|
||||
continue;
|
||||
printf("\t%s:\n", version->name);
|
||||
GList *schemas = g_hash_table_get_keys(version_hash);
|
||||
for (GList *tmp = schemas; tmp; tmp = tmp->next)
|
||||
{
|
||||
printf("\t\t%s\n", (char *)schemas->data);
|
||||
printf("\t\t%s\n", (char *)tmp->data);
|
||||
}
|
||||
g_list_free(schemas);
|
||||
}
|
||||
|
@ -311,7 +331,10 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "list-children"))
|
||||
{
|
||||
if (argc < 3)
|
||||
print_help("list-children");
|
||||
{
|
||||
print_command("list-children");
|
||||
exit(0);
|
||||
}
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
{
|
||||
|
@ -333,7 +356,10 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "list-keys"))
|
||||
{
|
||||
if (argc < 3)
|
||||
print_help("list-keys");
|
||||
{
|
||||
print_command("list-keys");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
|
@ -356,8 +382,10 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "list-recursively"))
|
||||
{
|
||||
if (argc < 3)
|
||||
print_help("list-recursively");
|
||||
|
||||
{
|
||||
print_command("list-recursively");
|
||||
exit(0);
|
||||
}
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
{
|
||||
|
@ -380,7 +408,10 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "get"))
|
||||
{
|
||||
if (argc < 4)
|
||||
print_help("get");
|
||||
{
|
||||
print_command("get");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
|
@ -400,7 +431,10 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "set"))
|
||||
{
|
||||
if (argc < 5)
|
||||
print_help('set');
|
||||
{
|
||||
print_command("set");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
|
@ -416,7 +450,10 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "range"))
|
||||
{
|
||||
if (argc < 4)
|
||||
print_help('range');
|
||||
{
|
||||
print_command("range");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
|
@ -438,15 +475,16 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
if (0 == strcmp(type, "enum"))
|
||||
{
|
||||
char *endptr, *error;
|
||||
char *endptr;
|
||||
GError *error;
|
||||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE("a{si}"), range, NULL, &endptr, &error);
|
||||
if (NULL == variant)
|
||||
{
|
||||
printf("parser enum error %s\n", error);
|
||||
printf("parser enum error %s\n", error->message);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("enum\n");
|
||||
printf("enum:\n");
|
||||
|
||||
char *nick = NULL;
|
||||
gint32 value = 0;
|
||||
|
@ -454,16 +492,14 @@ int main(int argc, char *argv[])
|
|||
g_variant_get(variant, "a{si}", &iter);
|
||||
while (g_variant_iter_loop(iter, "{si}", &nick, &value))
|
||||
{
|
||||
printf("'%s'\n", nick);
|
||||
printf(" '%s'\n", nick);
|
||||
}
|
||||
g_variant_iter_free(iter);
|
||||
g_variant_unref(variant);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s\n", range);
|
||||
p = range;
|
||||
printf("%x\n", ',');
|
||||
while (*p != ',' && *p != '\0')
|
||||
p++;
|
||||
*p = '\0';
|
||||
|
@ -476,16 +512,17 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "reset"))
|
||||
{
|
||||
if (argc < 4)
|
||||
print_help('reset');
|
||||
|
||||
{
|
||||
print_command("reset");
|
||||
exit(0);
|
||||
}
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
{
|
||||
printf("Wrong schema id\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (NULL == kdk_conf2_schema_get_key(ksettings, argv[argc - 1]))
|
||||
if (NULL == kdk_conf2_schema_get_key(ksettings->priv->schema, argv[argc - 1]))
|
||||
{
|
||||
printf("Wrong key\n");
|
||||
exit(0);
|
||||
|
@ -496,7 +533,10 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "monitor"))
|
||||
{
|
||||
if (argc < 3)
|
||||
print_help('monitor');
|
||||
{
|
||||
print_command("monitor");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
|
@ -509,10 +549,10 @@ int main(int argc, char *argv[])
|
|||
if (4 == argc)
|
||||
{
|
||||
char *signal_name = g_strdup_printf("changed::%s", argv[3]);
|
||||
id = kdk_conf2_connect_signal(ksettings, signal_name, key_changed, NULL);
|
||||
id = kdk_conf2_connect_signal(ksettings, signal_name, on_key_changed, NULL);
|
||||
}
|
||||
else
|
||||
id = kdk_conf2_connect_signal(ksettings, "changed", key_changed, NULL);
|
||||
id = kdk_conf2_connect_signal(ksettings, "changed", on_key_changed, NULL);
|
||||
|
||||
if (id <= 0)
|
||||
{
|
||||
|
@ -523,10 +563,39 @@ int main(int argc, char *argv[])
|
|||
for (;;)
|
||||
g_main_context_iteration(NULL, TRUE);
|
||||
}
|
||||
else if (0 == strcmp(argv[1], "monitor-reload"))
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
print_command("monitor-reload");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
KSettings *ksettings = kdk_conf2_new("test.notice", NULL);
|
||||
if (NULL == ksettings)
|
||||
{
|
||||
printf("Wrong schema id\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
guint id = 0;
|
||||
id = kdk_conf2_connect_signal(ksettings, "reload", on_reload, NULL);
|
||||
if (id <= 0)
|
||||
{
|
||||
printf("Connect signal failed\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
g_main_context_iteration(NULL, TRUE);
|
||||
}
|
||||
else if (0 == strcmp(argv[1], "writable"))
|
||||
{
|
||||
if (argc < 4)
|
||||
print_help('writable');
|
||||
{
|
||||
print_command("writable");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
|
@ -544,7 +613,10 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "describe"))
|
||||
{
|
||||
if (argc < 4)
|
||||
print_help('describe');
|
||||
{
|
||||
print_command("describe");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
KSettings *ksettings = kdk_conf2_new(id, version);
|
||||
if (NULL == ksettings)
|
||||
|
@ -558,10 +630,13 @@ int main(int argc, char *argv[])
|
|||
else if (0 == strcmp(argv[1], "save"))
|
||||
{
|
||||
if (argc < 3)
|
||||
print_help('save');
|
||||
{
|
||||
print_command("save");
|
||||
exit(0);
|
||||
}
|
||||
int success = kdk_conf2_save_user_configure(argv[2]);
|
||||
if(0 == success)
|
||||
printf("save configure failed");
|
||||
if (0 == success)
|
||||
printf("save configure failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
1183
src/conf2/接口说明.md
1183
src/conf2/接口说明.md
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,8 @@
|
|||
aux_source_directory(. SOURCESCODE)
|
||||
add_library(kysdk-config SHARED ${SOURCESCODE})
|
||||
set_target_properties(kysdk-config PROPERTIES VERSION 2.3.0 SOVERSION 2)
|
||||
add_library(kyconf SHARED ${SOURCESCODE})
|
||||
set_target_properties(kyconf PROPERTIES VERSION 2.5.0 SOVERSION 1)
|
||||
add_executable(kyconf-test-struct test/test_structlist.c)
|
||||
target_link_libraries(kyconf-test-struct kysdk-config)
|
||||
target_link_libraries(kyconf-test-struct kyconf)
|
||||
|
||||
# 包含 GNU 安装目录设置
|
||||
include(GNUInstallDirs)
|
||||
|
@ -18,7 +18,7 @@ else()
|
|||
set(CMAKE_INSTALL_LIBDIR "/usr/lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/")
|
||||
endif()
|
||||
# 安装库文件
|
||||
install(TARGETS kysdk-config
|
||||
install(TARGETS kyconf
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
# install(TARGETS kyconf
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
OBJ=gsettingsparse.o jsonparse.o structparse.o xmlparse.o
|
||||
|
||||
CFLAGS=-g -O0 -Wall -fPIC -I../ -I../utils/ -I../config/
|
||||
CLIBS=-lpthread
|
||||
CC:=$(shell bash -c 'type $(CC) &> /dev/null && echo $(CC) || echo gcc')
|
||||
TARGET=libkyconf.so
|
||||
LIBINST=libkyconf.so.1.0.0
|
||||
LIBHEAD=kyconf.h
|
||||
LIBINSTHEADER=/usr/include/kysdk/base/
|
||||
|
||||
all:$(OBJ)
|
||||
$(CC) -o $(LIBINST) configure.c $(OBJ) $(CFLAGS) $(CLIBS) -shared
|
||||
mkdir -p lib/
|
||||
mv -f $(LIBINST) lib/
|
||||
cd lib/ && ln -sf $(LIBINST) $(TARGET) && cd ..
|
||||
-rm *.o &> /dev/null
|
||||
|
||||
clean:
|
||||
-rm *.o &> /dev/null
|
||||
-rm ../lib/$(TARGET) &> /dev/null
|
|
@ -5,7 +5,7 @@ project(kydiagnostics LANGUAGES CXX)
|
|||
set(DIAGNOSTICS_TOP_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED)
|
||||
set_target_properties(kydiagnostics PROPERTIES VERSION 2.3.0 SOVERSION 1)
|
||||
set_target_properties(kydiagnostics PROPERTIES VERSION 2.5.0 SOVERSION 1)
|
||||
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -g)
|
||||
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
|
||||
|
|
|
@ -6,12 +6,12 @@ include_directories(${GTK3_INCLUDE_DIRS})
|
|||
link_directories(${GTK3_LIBRARY_DIRS})
|
||||
add_definitions(${GTK3_CFLAGS_OTHER})
|
||||
|
||||
add_library(kysdk-gsetting SHARED ${SOURCESCODE})
|
||||
set_target_properties(kysdk-gsetting PROPERTIES VERSION 2.3.0 SOVERSION 2)
|
||||
add_library(kygsetting SHARED ${SOURCESCODE})
|
||||
set_target_properties(kygsetting PROPERTIES VERSION 2.5.0 SOVERSION 1)
|
||||
|
||||
add_executable(test-kygsetting test/test-gsetting.c)
|
||||
target_link_libraries(kysdk-gsetting ${GTK3_LIBRARIES})
|
||||
target_link_libraries(test-kygsetting kysdk-gsetting)
|
||||
target_link_libraries(kygsetting ${GTK3_LIBRARIES})
|
||||
target_link_libraries(test-kygsetting kygsetting)
|
||||
|
||||
# install(TARGETS kygsetting
|
||||
# DESTINATION lib/kysdk/kysdk-base)
|
||||
|
@ -30,7 +30,7 @@ else()
|
|||
set(CMAKE_INSTALL_LIBDIR "/usr/lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/")
|
||||
endif()
|
||||
# 安装库文件
|
||||
install(TARGETS kysdk-gsetting
|
||||
install(TARGETS kygsetting
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
install(FILES libkygsetting.h
|
||||
|
|
|
@ -4,19 +4,19 @@ include(FindPkgConfig)
|
|||
pkg_check_modules(DBus REQUIRED
|
||||
dbus-1)
|
||||
include_directories(${DBus_INCLUDE_DIRS})
|
||||
add_library(kysdk-log SHARED ${SOURCESCODE})
|
||||
set_target_properties(kysdk-log PROPERTIES VERSION 2.3.0 SOVERSION 2)
|
||||
add_library(kylog SHARED ${SOURCESCODE})
|
||||
set_target_properties(kylog PROPERTIES VERSION 2.5.0 SOVERSION 1)
|
||||
add_executable(kylog-testlog test/test-log.c)
|
||||
add_executable(kylog-testsetdir test/test-setdir.c)
|
||||
add_executable(kylog-testpressure test/test-pressure.c)
|
||||
add_executable(kylog-testautowrap test/test-autowrap.c)
|
||||
find_library(SYSTEMD_LIB systemd)
|
||||
find_library(DBUS_LIB dbus-1)
|
||||
target_link_libraries(kysdk-log kysdk-config pthread ${SYSTEMD_LIB} ${DBUS_LIB})
|
||||
target_link_libraries(kylog-testlog kysdk-log)
|
||||
target_link_libraries(kylog-testsetdir kysdk-log)
|
||||
target_link_libraries(kylog-testautowrap kysdk-log)
|
||||
target_link_libraries(kylog-testpressure kysdk-log)
|
||||
target_link_libraries(kylog kyconf pthread ${SYSTEMD_LIB} ${DBUS_LIB})
|
||||
target_link_libraries(kylog-testlog kylog)
|
||||
target_link_libraries(kylog-testsetdir kylog)
|
||||
target_link_libraries(kylog-testautowrap kylog)
|
||||
target_link_libraries(kylog-testpressure kylog)
|
||||
|
||||
# install(TARGETS kylog
|
||||
# DESTINATION lib/kysdk/kysdk-base)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
OBJ=core.o format.o klog_mqueue.o kylog.o write.o writeFile.o
|
||||
|
||||
CFLAGS=-g -O0 -Wall -fPIC -I../ -I../utils/ -I../config/
|
||||
# CLIBS=-lpthread -lsystemd
|
||||
CC:=$(shell bash -c 'type $(CC) &> /dev/null && echo $(CC) || echo gcc')
|
||||
TARGET=libkylog.so
|
||||
LIBINST=libkylog.so.1.0.0
|
||||
LIBHEAD=kylog.h
|
||||
LIBINSTHEADER=/usr/include/kylog/
|
||||
|
||||
all:$(OBJ)
|
||||
$(CC) -o $(LIBINST) $(OBJ) $(CFLAGS) $(CLIBS) -shared
|
||||
mkdir -p lib/
|
||||
mv -f $(LIBINST) lib/
|
||||
cd lib/ && ln -sf $(LIBINST) $(TARGET) && cd ..
|
||||
-rm *.o &> /dev/null
|
||||
|
||||
clean:
|
||||
-rm *.o &> /dev/null
|
||||
-rm ../lib/$(TARGET) &> /dev/null
|
|
@ -1,7 +1,7 @@
|
|||
all:
|
||||
gcc -o test-log test-log.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkysdk-log -lkysdk-config -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
|
||||
gcc -o test-setdir test-setdir.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkysdk-log -lkysdk-config -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
|
||||
gcc -o test-pressure test-pressure.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkysdk-log -lkysdk-config -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
|
||||
gcc -o test-log test-log.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkylog -lkyconf -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
|
||||
gcc -o test-setdir test-setdir.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkylog -lkyconf -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
|
||||
gcc -o test-pressure test-pressure.c -g -O0 -I../ -I../../utils/ -L../lib -L../../config/lib/ -lkylog -lkyconf -lpthread -lsystemd -Wl,-rpath=../lib:../../config/lib/
|
||||
|
||||
clean:
|
||||
-rm test-log test-setdir test-pressure
|
|
@ -1,9 +1,9 @@
|
|||
aux_source_directory(. SOURCESCODE)
|
||||
add_library(kysdk-timer SHARED ${SOURCESCODE})
|
||||
set_target_properties(kysdk-timer PROPERTIES VERSION 2.3.0 SOVERSION 2)
|
||||
add_library(kytimer SHARED ${SOURCESCODE})
|
||||
set_target_properties(kytimer PROPERTIES VERSION 2.5.0 SOVERSION 1)
|
||||
add_executable(test-kytimer test/test-kytimer.c)
|
||||
target_link_libraries(kysdk-timer pthread)
|
||||
target_link_libraries(test-kytimer kysdk-timer)
|
||||
target_link_libraries(kytimer pthread)
|
||||
target_link_libraries(test-kytimer kytimer)
|
||||
|
||||
# install(TARGETS kytimer
|
||||
# DESTINATION lib/kysdk/kysdk-base)
|
||||
|
@ -22,7 +22,7 @@ else()
|
|||
set(CMAKE_INSTALL_LIBDIR "/usr/lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/")
|
||||
endif()
|
||||
# 安装库文件
|
||||
install(TARGETS kysdk-timer
|
||||
install(TARGETS kytimer
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
# install(FILES libkytimer.h
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
CLIBS=-lpthread -lrt
|
||||
CFLAGS=-g -O0 -Wall -fPIC -shared
|
||||
|
||||
CC=cc
|
||||
TARGET=libkytimer.so
|
||||
LIBINSTALLNAME=libkytimer.so.1.0.0
|
||||
LIBINSTALLDIR=/usr/lib/
|
||||
HEADERINSTALLDIR=/usr/include/
|
||||
HEADERS=kytimer.h
|
||||
|
||||
.PHONY:all
|
||||
.PHONY:clean
|
||||
.PHONY:lib
|
||||
|
||||
all:lib
|
||||
|
||||
lib:
|
||||
$(CC) $(CFLAGS) $(CLIBS) -o $(TARGET) libkytimer.c
|
||||
mkdir -p lib/
|
||||
mv $(TARGET) lib/$(LIBINSTALLNAME)
|
||||
|
||||
clean:
|
||||
-rm ../lib/$(LIBINSTALLNAME)
|
||||
|
||||
target_install:TARGET
|
||||
cp $(LIBINSTALLNAME) $(LIBINSTALLDIR)
|
|
@ -1,5 +1,5 @@
|
|||
all:
|
||||
gcc -g -O0 -o test-kytimer test-kytimer.c -lkysdk-timer -lpthread
|
||||
gcc -g -O0 -o test-kytimer test-kytimer.c -lkytimer -lpthread
|
||||
|
||||
clean:
|
||||
rm demo
|
|
@ -1,6 +1,6 @@
|
|||
aux_source_directory(. SOURCESCODE)
|
||||
add_library(kyutils SHARED ${SOURCESCODE})
|
||||
set_target_properties(kyutils PROPERTIES VERSION 2.3.0 SOVERSION 2)
|
||||
set_target_properties(kyutils PROPERTIES VERSION 2.5.0 SOVERSION 1)
|
||||
include_directories(.)
|
||||
# install(TARGETS kyutils
|
||||
# DESTINATION lib/kysdk/kysdk-base)
|
||||
|
|
|
@ -280,10 +280,11 @@ char *size_to_human_string(int options, uint64_t bytes, int base)
|
|||
// if (frac % 10 == 0)
|
||||
// frac /= 10; /* convert N.90 to N.9 */
|
||||
sprintf(res, "%.2f", result);
|
||||
frac = (frac / (1ULL << (exp - 10)) + 5) / 10;
|
||||
double num = atof(res);
|
||||
double ret = num - dec;
|
||||
frac = ret * 100;
|
||||
if (frac % 10 == 0)
|
||||
sprintf(res, "%.f", result);
|
||||
|
||||
sprintf(res, "%.1f", result);
|
||||
} else {
|
||||
// frac = (frac / (1ULL << (exp - 10)) + 50) / 100;
|
||||
// if (frac == 10)
|
||||
|
|
Loading…
Reference in New Issue