以 Archlinux 中 makepkg 的方式打开 rpmbuild在 Redhat 系的发行版上打包软件的时候,会发现与 Archlinux 完全不同的思路。Fedora 所代表的 Redhat 阵营一看就是那种宏大叙事的大型发行版,rpmbuild 在默认情况下会在 $HOME/rpmbuild 下的一系列文件夹进行构建过程。使用 rpmdev-setuptree 命令会创建好下面这些目录进行构建。$ tree rpmbuild rpmbuild ├── BUILD ├── BUILDROOT ├── RPMS ├── SOURCES ├── SPECS └── SRPMS Fedora 将所有的软件的构建都集中在一个 rpmbuild 目录中,BUILD 是编译时使用的,BUILDROOT 是最终安装目录,RPMS 是存放最终产物的,SOURCES 是存放源码等文件的,SPECS 是存放指导构建过程的 spec 文件的,而 SRPMS 是 RH 系为...
使用 Github Action 更新用于 rpm 打包的 spec 文件有一些软件包的上游本身就是使用 Github Action 发版的,每次 commit 都会触发 Github Action 去构建并分发新版本,使用构建时的时间日期作为版本号。针对这种包,手动更新费时费力,而规范的 specfile 应当是更新 %changelog 的,因此应当是使用 rpmdev-bumpspec 命令。只不过 rpmdev-bumpspec 需要在 rpm 系发行版或者装有 rpm 系列依赖包的发行版下执行,这不是随随便便一个 Linux 环境就能运行的。我找到了 netoarmando/rpmdev-bumpspec-action 这个 Github Action,它通过启动一个 Fedora 的 docker 实现了使用 rpmdev-bumpspec 的效果。虽然 release 中只有一个 2021 年构建的 v1 版本,~~但 Fedora 的版本高低不影...
使用 Python 生成甘特图(Gantt Chart)在写操作系统的作业的时候有几道题给出了几个进程的相关信息,要求我们画出几种简单调度的甘特图。操作系统的作业一直是电子版,上传 pdf 即可的。我觉得手画甘特图拍照嵌入 pdf 中不太优雅,过于掉价,因此就想直接生成甘特图嵌入。在谷歌搜寻了一番,我发现现在的甘特图生成网站都太现代化了,根本不是操作系统课上教的样子了。所幸我找到了 gao-keyong/matplotlib-gantt,虽然只有两个 star(没事,加上我就 3 stars 了),但确实能用,README 中的样例也是我期望的样子。项目中自带了一个 jupyter 的示例,算得上是非常简单易上手的了,依赖方面只要装好 matplotlib 就可以使用,不存在依赖地狱。尽管是三年前的项目,在我本机的 Python 3.11 上仍然能够正常运行。tuple 中的第一个数字表示从当前时间开始,第二个数字表示持续时间。每一个表示 ca...
uniapp 中的图片预加载最近在做微信小程序的时候遇到了图片资源过大无法正常打包的问题,没什么太好的方法,只能是使用图床托管这些图片资源。但部分图片的体积实在太大,即使是采用了境内 cdn 的图床,即使是采用 webp 对图片进行了压缩,部分图片都需要小几秒去把图片加载出来,这导致的用户体验就不是很好了,因此我们需要实现图片预加载的功能。在 uniapp 的官方文档中,我找到了 uni.preloadPage(OBJECT) 方法。很可惜,这个方法并不支持微信小程序,自然不能完成被预加载页面的图片资源预加载。经过搜索,在一篇奇奇怪怪的文章中提到:在UniApp中,图片预加载可以通过使用uni.getImageInfo方法来实现。这个方法可以获取图片的信息,包括宽度、高度等。可以在应用启动时就开始加载图片,以提高后续图片显示的速度。很遗憾,经过实测,提前使用 getImageInfo() 方法并不能实现图片的预加载。...
小记 - 尝试拼凑出 apt 仓库中的 deb 包下载地址大概一周前,有一个来源不明的 Linux 微信,从包的结构来看是基于 qt 实现的图形化界面,deb 包中的 control 信息表明是腾讯团队官方出品的。今天听人说 UOS 的商店上架了最新的微信,便尝试从 UOS 的官方仓库提取下载链接,帮助 AUR Maintainer 获取到新的地址。在我的《deepin-elf-verify究竟是何物?》这篇文章中,我成功从 uos.deepin.cn 下载到了来自 UOS 中的软件包。可惜,当我采用同样的方法搜索 weixin 或者 wechat 字样时,没有得到任何结果。UOS 上的软件来源起码来自两个仓库,一个是与系统有关的软件,比如 Linux Kernel,GCC 一类开源软件,应该就是来自我之前下载到 deepin-elf-verify 的那个源。除此之外,还有一个 appstore 源,里面存放的都是应用商店中上架的软件(大部分可能...
在 Linux 下使用 mitmproxy 抓取 HTTPS 流量作为部分 AUR Package 的 maintainer,一直以来我都有在 Linux 下抓取 https 流量的需求,比如抓取应用内的更新检测时访问的 url 地址。之前一直没有空去研究,趁着最近课少,总算是完成了这个目标。在这里我使用的 mitmproxy,基于 python 和 webui 的一款开源简洁的流量代理软件,可以用于抓取 https 流量信息。安装 mitmproxy在 Arch Linux 下,官方 extra 源中已经打包好了这款软件,直接使用下面的命令即可完成安装。sudo pacman -S mitmproxy 尝试运行 mitmweb安装完成后,我们将会获得三个新的命令可用:mitmdumpmitmproxymitmweb我们只要使用 mitmweb 即可同时打开 8080 的代理端口和 8081 端口的 webui。访问 http://127.0.0.1:8...
如何使用 docker 部署 onemanager部署方法如果你只是想找一个 OneManager-php 的 Docker 部署方法,直接看 https://github.com/zhullyb/OneManager-php-docker一直以来,我都是 OneManager-php 的忠实用户。这些年来,尽管有 alist 这种 UI 好看,多种网盘高度聚合的项目逐渐取代了 onemanager 的生态位,但 onemanager 支持文件分片上传、上传流量不经服务器的特点还是让我非常满意。前一阵子,glitch 暂停了针对项目自定义域名的支持,因此在我手贱地取消了项目原本绑定的域名后,迫切地需要寻找一个新的部署的平台,只不过 onemanager 项目现在列出的方案都不太让我满意,因此我就萌生出了在 vps 上自己部署的想法。Docker 镜像选用vps 上自己部署 php 项目,最简单的方法是使用 Docker,使用 Docker...
crontab 中简单的@语法糖说来惭愧,其实我用了这么久的 Linux,一直没有学会编写 crontab 脚本。一行的开头写上五位莫名其妙的数字或星号,后面跟上需要执行的命令,看上去很 kiss,但我确实记不住,以至于我现在每次写 crontab 都是让 ChatGPT 来帮我写。不过我最近查阅 Linux 下设置开机自启脚本的方案的时候,意外地看到 crontab 中居然可以用 @reboot command 的方式去写,这让我意识到 crontab 也是有一些简单的语法糖的。在查阅了 crontab 的 manual 后,我发现一共有下面这么几种 @ 写法的语法糖。这是在全网大部分的 crontab 中文教程中是没有的。语法糖执行条件等效表达式@reboot开机时候运行@yearly一年一次0 0 1 1 *@annually一年一次0 0 1 1 *@monthly一月一次0 0 1 * *@weekly一周一次...
备份 umami 数据库,并使用 TG Bot 保存 dump 文件前一阵子看到点墨的博客「定时备份mysql/mariadb数据库并上传至tgbot」,我意识到个人站点的数据库 dump 使用 TG Bot 存放是一个非常合适的做法。个人站点的数据库体积本身就不大,TG Bot 又有官方提供的 api,非常适合自动化任务。我就寻思着给我的 umami 数据库也写个定时任务备份一下,也不至于之前做一次迁移数据全部爆炸的悲剧重演。我的 umami 是「使用 vercel+supabase 免费部署 umami」部署出来的,数据库在 supabase 上,因此我们先打开 supabase 的 dashboard,获取到数据库的 url。密码我自然是不记得了,不过好在 Firefox 的密码管理器帮我记住了,直接去设置里就能找到。即使密码忘了也不要紧,往下翻有重置密码的按钮。随后就要开始编写我们的教本了,这是我的#!/bin/bash DATABASE_URL=...
在 JavaScript 中,箭头函数中的 this 指针到底指向哪里?这学期期末复习的时候,学校里负责上 JavaScript 的老师给我们提出了一个问题。下面这段代码中,a.u2() 在 ES Module 下执行会抛出 TypeError 的异常,在 CommonJS 下运行则会输出 undefined,而 B 这个类的 u2 函数则能够在对象实例化以后正常运行。const a = { x: 3, u1: function () { console.log(this.x) }, u2: () => { console.log(this.x) } } class b { x = 3 u1 = function () { console.log(this.x) } u2 = () => { console.log(this.x) } } a.u1() // 3 a.u2() // undefined new b().u1() // 3 new b().u2(...
145613