2022年2月5日星期六

为KDE的日历插件添加农历

摘要:本文将记录为KDE Plasma 桌面的日历小工具添加农历插件的过程,希望能对想要开发日历插件或参与KDE项目开发的读者有所启发。

注:未完待续,持续更新中……

定位小工具源代码

预装的 Plasma 桌面小工具的源代码一般来源于三个项目

  1. Plasma Desktop:主要包含开始菜单(Kickoff)、任务管理器、虚拟桌面管理器等只在桌面上使用的小工具(因为还有 Plasma Mobile)
  2. Plasma Workspace:包含大部分预装的小工具,如剪贴板、时钟,以及本文所要修改的日历插件。
  3. Plasma Add-ons:包含一些扩展的小工具,如便签、计时器等。同时本文的农历插件最终也要提交到该项目。

定位 QML 界面的源代码非常容易,只需要使用 GammaRay 工具的 Quick Scenes 找到相应的界面元素,然后在右键菜单里即可定位到源代码的位置。然后根据源代码的文件名在相关项目里搜索文件所属的项目即可。GammaRay 是调试 Qt 应用程序的“瑞士军刀”,Quick Scenes 只是其众多功能中的其中一个非常好用的功能。

如上图所示, 日历界面的源代码文件名为 DaysCalendar.qml,利用 lxr.kde.org 很快就在 KDE Plasma Framework 项目里找到了这个文件。我们所要更改的是单个日期方格,在日期数字的下方加入农历,因此通过 GammaRay 或分析源代码,我们实际需要修改的文件是 DayDelegate.qml。通常要实现两个文字标签的上下排版,可以使用 anchors 定位或使用 ColumnLayout 布局,其中后者更方便,也是比较惯用的排版方式,但会导致界面的渲染性能显著降低。因此在该文件里,将原来的日期标签放入 Item 容器中,在日期标签下方添加一个 Loader,用于加载农历文字标签,两个标签通过 anchors 定位。

现在我们已经完成了简单的界面设计,但现在文本内容还只是一个占位符。其真正的文本内容还需要通过后端代码生成;同时我们还需要为日历的数据模型添加一个新的属性“subLabel”,使界面能够读取公历日期对应的农历日期。

为数据模型增加新的属性

待更新

预计涉及的部分:

  1. DaysModel
  2. EventPluginsManager

编写农历插件

待更新



2021年5月1日星期六

通过网络安装方式在腾讯云上安装openSUSE Tumbleweed

腾讯云轻量应用服务器现有的系统是Ubuntu 20.04,但腾讯云没有提供openSUSE的系统镜像,因此只好通过网络安装的方式安装新系统。

下载引导文件和内核

根据openSUSE Wiki上关于网络安装的方法,首先需要下载相应的引导文件和内核。

mkdir /boot/install
cd /boot/install
wget https://mirrors.tuna.tsinghua.edu.cn/opensuse/tumbleweed/repo/oss/boot/x86_64/loader/initrd
wget https://mirrors.tuna.tsinghua.edu.cn/opensuse/tumbleweed/repo/oss/boot/x86_64/loader/linux

配置GRUB

编辑/etc/grub.d/40_custom,在文件末尾加入以下片段:

set timeout=10
menuentry 'openSUSE' {
    insmod gzio
    linux   /boot/install/linux showopts install=https://mirrors.tuna.tsinghua.edu.cn/opensuse/tumbleweed/repo/oss usessh=1 sshpassword="12345678" vnc=1 VNCPassword=12345678
    initrd  /boot/install/initrd
}

usessh=1和vnc=1表示为安装过程启用SSH和VNC服务器,其中12345678可以改成自己的密码。VNC的端口为5901,记得在防火墙中放行相关端口。

修改完成后,用sudo update-grub更新GRUB配置文件。

安装

安装过程与普通安装过程多了一步连接VNC的步骤,其它过程没有差异。VNC端口为5901,可以用TightVNC Viewer等客户端连接。

参考

https://en.opensuse.org/SDB:Remote_installation

2020年2月10日星期一

利用Lua实现基于延迟动态调整HAProxy服务器权重(weight),优先选择延迟低的服务器

将下面的Lua代码上传到路由器上,假设命名为dynamic_set_weight.lua。
local function calculate_weight(ping_value,eresp)
    -- from 1 to 256
    return math.ceil(256/math.exp(0.1*(ping_value+eresp)))+1
end
local function adjust_weight()
    while true do
        for _, backend in pairs(core.backends) do
            for _, server in pairs(backend.servers) do
                local stat = server:get_stats()
                if stat['check_desc'] == 'Layer4 check passed' and stat['bin'] > 1000 then
                    -- adjust weight based on the ping value and the number of eresp
                    server:set_weight(calculate_weight(stat['check_duration'],stat['eresp']))
                end
            end
        end
        core.msleep(10000) -- 10s
    end
end

core.register_task(adjust_weight)
假设上传的位置为/usr/bin,则在HAProxy的配置文件里,在global下添加一行
lua-load /usr/bin/dynamic_set_weight.lua
重启HAProxy(OpenWRT上的命令为/etc/init.d/haproxy restart),一段时间后效果如图所示:
HAProxy Statistics Report

可以看到权重已经根据延迟做了调整。调整每10s进行一次,可以修改core.msleep括号内的数字对运行间隔进行调整。


2019年12月28日星期六

在路由器上定时预解析DNS,解决加密DNS(DNS-over-TLS)解析时间长的问题

下载地址

预备条件

  • Perl 5 
  • dnsmasq

使用方法

  1. 修改/etc/dnsmasq.conf,添加以下几行以启用日志记录功能,并把DNS解析最短过期时间调整为1小时
    log-async=20
    log-queries
    log-facility=/var/log/dnsmasq.log

    min-cache-ttl=3600

  2. get_popular_websites.pl, prefetch_domains.pl, env_var三个文件下载到路由器上,一般放在/usr/bin文件夹。
  3. 修改/etc/crond/root,将cron文件的内容添加到末尾。

原理与细节

通过定时提取dnsmasq的日志文件,统计每个域名的解析次数。大于ceil(exp($today/10 + 1))即把该域名作为经常访问的域名,并加入预解析名单。其中$today为当天的日数

解决OpenWRT上搭建PPTP服务器,Android客户端无DNS解析的问题

问题出在dnsmasq的设置上。在LuCI管理界面DHCP and DNS设置里,找到







2018年4月4日星期三

用 Heavy Hitter Filter (HHF) qdisc 有效解决多线程下载软件霸占网速问题

  多线程下载软件,例如迅雷和IDM,在有效提升下载速度、压榨下行全部潜力的同时,也给其他网络活动带来了灾难性的后果。BBR拥塞控制算法的使用,更使得本来狭小的网络空间变得缓慢不堪。一旦局域网内一个用户开始下载,其他用户的网页浏览都将受到严重影响,甚至一分钟都无法显示网页首屏,体验十分糟糕。
  fq_codel、pie、cake等调度器的使用,在一定程度上缓解了这种情况,但并不能解决多线程下载软件和BBR的“强势进攻”。即使提高丢包率(如降低target,提高αβ),也无法降低对正常的网络活动的影响。若能有这样一个调度器,能把大流量下载流量和正常流量区分开来,并给予正常流量极大的优先级,将会极好地解决这一问题。
  Heavy Hitter Filter (HHF) 的诞生,解决了大流量和小流量的区分问题。在一系列参数的控制下,HHF能够自动地把大流量连接和正常流量连接区分开来,分配到两个队列中,并赋予不同的传输优先级,具体介绍可以看这里

HHF的关键参数介绍:
  1. reset_timeout:重置计数器的间隔时间,HHF以一个间隔时间内连接传输的流量为标准来判断该连接是否为大流量连接。默认为40ms。
  2. hhf_admit_bytes:将连接分类为大流量连接的阈值。默认为131072Bytes(128KBytes)。
  3. non_hh_weight:正常流量的权重。默认为2(2:1)。设置为1000以上时对霸占网速的连接遏制有良好的效果
当连接速度超过hhf_admit_bytes/reset_timeout时(默认参数下为128KB/40ms=25.6Mbps),该连接即被分类为大流量连接。若要设置为速度大于1Mbps时连接被定义为大流量连接,可将hhf_admit_bytes设为1Mbps×40ms=5120Bytes。

最后的命令,与htb配合使用:
tc qdisc add dev $dev parent x:y hhf limit 1024 non_hh_weight 1000 admit_bytes 5120

2017年10月30日星期一

解决自编译pdnsd在Padavan下无法将缓存保存到硬盘上的问题

最近为了IPV6 DNS的需求自己编译了一份pdnsd,thread-lib选择的是NPTL。发现在Padavan下出现了无法保存缓存到硬盘上的问题,结合帮助文档以为是NPTL的问题,遂换成LinuxThread重新编译,结果照旧。
于是分析pdnsd的源代码,首先从处理缓存的cache.c源代码入手,找到read_disk_cache()函数,发现如下代码:
  if(memcmp(buf,cachverid,sizeof(cachverid))) {
   log_warn("Cache file %s ignored because of incompatible version identifier",path);
   goto free_data_fclose;
  }
结合日志中出现了这样一条错误信息,初步认为是pdnsd.cache文件开头少了“pd13”,加上后,查看除错日志,没有报错,但仍旧无法保存。
继续研究代码,发现write_disk_cache()函数,这个函数实现了把缓存写入硬盘的功能。回到main.c,来到这行代码:

 if(sig) DEBUG_MSG("Signal %i caught.\n",sig);
 write_disk_cache();

这个函数被执行的条件是sig不等于0。突然想起平时结束进程用的都是 kill -9(强制终止),怀疑是进程没有接收到信号就被终止了。于是将9改成15,果然缓存能够保存到硬盘上了。