分类目录归档:vicalloy的庄家

中国历年人口变化

中学课本里说生产力决定生产关系。很多社会问题寻根溯源都和生产力相关。劳动力作为生产力中的重要一环深刻的影响了社会和经济的发展。

在网上收集了一些中国的人口数据,做了一个人口变化的统计图表。近年来出现了不少使用 Python 实现前端 Web 界面的工具。这次的图表使用 plotly 实现,使用 Python 做数据处理,并输出 html 图表。

项目地址: https://github.com/vicalloy/china-population
在线查看图表: https://vicalloy.github.io/china-population/

数据分析

  1. 出生人口中 2016 年到达2000年后的高点,之后出生人口断崖式下降。
  2. 2022 年首次出现死亡人口大于出生人口,人口出现负增长。
  3. 将 20 ~ 60 岁作为劳动力。也是在 2022 年首次出现劳动力的负增长,之后还将一直持。注:养老金压力山大。
  4. 2024 年幼儿园的入学人数掉的非常厉害,再过几年就蔓延到小学了。
  5. 2022 年高考录取人数为 1000 万,预计之后较长一段时间都将维持在 1000 万左右。

一些预测

  1. 接下来几年幼儿园因缺少生源,要关停一批。
  2. 生源不足问题逐步蔓延到小学。
  3. 学区房地位下降,成为房价下跌的主力。学区房快速下跌的窗口期没几年了。

Magpie 股价价格提醒工具

项目地址:https://github.com/vicalloy/magpie/

股票工具。设置股票的止损点和营收点,在到达止损点或营收点时发起消息推送。提供一个简易点web服务器用于查看相关股票的当前价格。

注:

用法

编辑规则文件

提醒规则使用 Json 格式进行描述。编辑规则并保存为文件 rule.json 。

[
  {
    "stock_code": "sh000001",
    "stock_name": "上证指数",
    "base_price": 3200,  # 基准价格,用于计算涨幅
    "alarm_price_min": 3100,  # 止损点
    "alarm_price_max": 3400  # 营收点
  },
  {
    "stock_code": "sz000333",
    "stock_name": "美的",
    "base_price": 54,
    "alarm_percentage_min": 0.15,  # 止损点 base_price * (1 - alarm_percentage_min)
    "alarm_percentage_max": 0.15  # 营收点 base_price * (1 + alarm_percentage_max)
  },
]

启动 Web 服务器

docker run --rm \
    -v `pwd`/rules.json:/app/rules.json \
    -p 8000:8000 vicalloy/magpie:latest \
    python -m magpie server -r ./rules.json

在浏览器中访问网址 http://localhost:8000/ 。

检查股价

docker run --rm \
    -v `pwd`/rules.json:/app/rules.json \
    magpie:latest \
    python -m magpie check -r ./rules.json \
    --datasource qq \
    --bark-token $(bark-token) \
    --tg-token $(tg-token) \
    --tg-chat-id $(tg-chat-id)

可以通过设置 crontab 的方式定时执行股价的检查。

备注

10 9,10,11,12,13,14 * * * sudo docker run ....

使用AI修复将画像还原成照片

GFPGAN 是一个使用 AI 进行人脸修复的工具,即使对非常模糊的人脸也可起到不错的修复效果。Hugging Face 提供了AI应用Demo的快速部署。我 Fork 了一份 GFPGAN 的 Demo 并做了少量的调整以加强对图片的支持。

在线体验地址 https://huggingface.co/spaces/vicalloy/GFPGAN

AI技术在图片生成领域有了不错的进展,现在已经可以通过文字生成质量不错的图片了。之前就一直想尝试用AI人脸修复将画中的人脸修复成照片,只是迫于拖延症一直未能真正动手。这些天试了一下,发现这个想法切实可行,就是修复出的效果算不上出色。

Tips

  1. AI 照片修复实际上是让 AI 对图片进行自行“脑补”的一个过程,所以原图细节一定不能过多(图片一定要小,或是),不然不利于 AI 软件的自行发挥。
  2. 樱木花道的输出效果不太好,再小丢失的细节又过多,因此加了个高斯模糊。注:理论上加高斯模糊比单纯的缩小图片效果要好,大家可以对其他图片试试。
  3. 应当是缺少样本,外加人脸检测时,如果胡子过长截取人脸时会丢失部分胡子。古人的长须无法完整修复。
  4. 过于“漫画化”的图片是无法识别到人脸的。

效果

樱木花道

唐太宗李世民

乾隆

韩熙载

宋太祖赵匡胤

香橙派5(Orange pi5)初体验

前些时间心血来潮想弄个ARM单板做个微型服务器。没想到今年树莓派涨价太狠,原本¥400点4b直奔¥1000去了。刚好看到Orange pi5要发布了,据说性能提升巨大,价格¥500起。本还有些犹豫,想到树莓派都成理财产品了,于是预购享折扣。

Orange pi5 采用的是瑞芯微的 RK3588S 根据测试性能介于骁龙845/855之间。在华为推出后,这已是最强的国产ARM芯片了,比树莓派4b要强出不少。该芯片集成了 6TOPS 算力的NPU,不过瑞芯微提供的SDK最新只支持到Ubuntu20.04,因此我没有实际测试过。

Orange pi5 提供了一个 M.2 接口,不过遗憾的是没有板载 Wi-Fi ,因此只能SSD,无线网卡2选一。

由于是新出的板子,还没有官方/第三方外壳(注:现在第三方外壳已经出来了),自己用硬纸板/塑料片/尼龙立柱做了个简单的外壳。偶尔做个手工,收获满满的成就感。

自己DIY的外壳

部署的服务

初步构想是作为家庭里的微型服务器使用,跑一些不需要实时性的“高负载”的任务(已有台云主机,大多服务可以跑在云主机上)。这些天把机器的基础设施搭建了一下,更具体的用途再说了(大概率吃灰)。

为简化管理,能用 Docker 部署等服务尽量用 Docker 部署。跑的 Python 脚本用 Pipenv 创建虚拟环境。

目前部署的服务有

  • Aria2/AriaNg 下载工具,及该工具的 Web 管理界面。
  • bypy 百度云盘的下载工具。
  • File Browser 基于 Web 的文件管理器。可以方便的对设备上的文件进行管理。
  • homepage 导航页生成工具,在设备上部署的服务多了后会比较有用。

开箱视频

拿到板子后做的开箱视频: https://www.bilibili.com/video/BV198411G7oy/

开源 wiki 和知识管理系统 Outline 的快速部署脚本

项目地址: https://github.com/vicalloy/outline-docker-compose

前一段想部署一个 Wiki ,看了一圈被 Outline 的颜值吸引。Outline 支持部署到自己服务器,只是自部署的体验真的不太好。Outline 部署主要就下面几个问题。

  1. 默认使用 AWS 的 S3 服务。
  2. 不提供用户管理模块,需通过 Slack 、Google 或是自建 OIDC 服务进行登录。

网上已用基于 docker-compose 的部署方案主要有两个:

  1. outline-wiki-docker-compose
    1. 提供交互式脚本,生成 docker-compose 配置文件。
    2. 使用 Slack 进行登录,国内使用体验不好。
    3. 脚本太老,存在 Bug ,图片上传后显示不了。
  2. docker-outline
    1. 国内用户写的部署脚本。目前中文网络环境下搜索 Outline 找到的都是 soulteary 的文章。
    2. 脚本不够智能,配置参数还是有些多。
    3. 内置了 OIDC 服务,不过好像不支持用户管理,只能创建一个用户。(注:没仔细研究过,不确定)

出于自己部署的需要,参考 outline-wiki-docker-compose 的实现,新开了 Outline 的部署项目。

  1. 配置文件尽量简化。只有 config.sh 一个配置文件,其他配置文件由脚本生成。
  2. 内置 OIDC 服务,可以直接通过 Web 管理用户。

ODIC Server

项目地址:https://github.com/vicalloy/oidc-server/

多很多想自己部署 Outline 的人来说,没有本地的认证系统是一个非常头痛的问题。该Issue Local Authentication #1881 的评论数是 Outline 未关闭 Issue 中最多的。我也一度被该问题劝退。

可能 Outline 主推的还是 Cloud 版,虽然内建认证对自部署影响很大,官方依旧没有给出明确的支持方案。注:不少服务是提供OIDC认证的,如果你同时使用Gitlab,你可以使用Gitlab做OIDC认证服务器。

我最初的想法部署一个做简单的ODIC认证服务器给 Outline。出于节约内存的考虑,这个服务最好是Go或是Rust编写。找了一圈未发现合适的应用,于是回到了自己最熟悉的 Django 上。

OIDC Server 主体代码来源于 django-oidc-provider 的 example 。甚至可以说这个项目就是将 example 做了个打包。依托于 Django 优秀的插件机制和 Admin 模块,在几乎不用写代码的情况下就可以得到一个还过得去的 OIDC Server。当然缺点是内存占用量有点大,这个服务需要用掉大概100M的内存。

注:ODIC Server docker镜像使用 Github Action 进行构建。不得不说 Github Action 的体验真的非常棒。

将服务器迁移到腾讯云

之前因为嫌备案麻烦,一直用的国外的主机。只是网站的访问速度一言难尽,毫无体验可言。

近期腾讯云做活动,1G内存3年只要¥150,简直和不要钱一样。禁不住诱惑上车了。

服务搬家

Docker

由于有了2G的“大内存”(之前只有1G内存),搬家后所有的服务都改用Docker部署。

目前服务器上跑的服务有:

  • nginx 网关,将各个子域名路由到对应服务上。
  • wordpress 我的个人博客。
    • 启用https后,css和js等静态资源始终请求的http地址,导致资源无法加载。折腾了很久都没有搞定,仔细分析后认为应当是nginx做了proxy后wordpress不知道已经换成了https,依旧生成http的资源访问地址。在nginx中增加配置 proxy_set_header X-Forwarded-Proto $scheme; 解决问题。
  • filebrowser 私人网盘。
    • 注:filebrowser,使用Go开发,部署起来比较简单。不过我不想配置systemd,为了开机自动启动功能继续使用Docker。
  • django-lb-workflow演示站点

注:可以在docker-compose.ym中将networks设置为external实现不同docker-compose之间的容器互联。由于我使用nginx作为网关,因此所有服务都使用nginxnetwork

version: "3"
services:
  filebrowser:
    image: filebrowser/filebrowser:latest
    restart: always
    ports:
      - ${IP}:10180:80
    volumes:
      - ./data:/srv
      - ./db/database.db:/database.db
    networks:
      - nginx_default
networks:
  nginx_default:
    external: true

HTTPS & DNS

之前一直使用 certbot 进行免费证书的申请,只是这东西的体验一直不是很好。这次换成了acme.shacme.sh 完全使用shell脚本编写,使用起来非常简单,按照官网文档很快就可以弄好。

之前为了改善网站的访问速度使用了 cloudflare 的CDN功能(然而速度一如既往的慢),域名服务也一并迁到了 cloudflare 。既然不再使用 cloudflare DNS的解析也迁回了国内的 DNSPOD

注:免费的HTTPS证书已经支持泛域名了,泛域名只支持DNS方式进行认证。

总结

  • 访问速度提升巨大,体验好了很多。之前连SSH都容易卡掉线。
  • 之前跑在服务器上 telegram-shell-bot 连不上服务器了,被迫停工。
  • 网站备案比预期的要简单些。备案审核需要1~2周时间,期间网站访问不了。

在线使用的图片风格迁移工具

近期研究 ONNX Runtime Web 做的一个小东西。很多代码都“借鉴”于其他开源项目,解决了图片变形等问题。

使用深度学习模型做的图片风格迁移。使用 React 和 ONNX Runtime Web 开发,推理后端用的 WebAssembly ( CPU )。根据我的测试,用 WebGL 要慢不少,而且内存占用有些夸张。

在线访问: https://vicalloy.github.io/image-transformer/

项目地址: https://github.com/vicalloy/image-transformer

Note:

  1. 所有推理工作在浏览器完成,不需要消耗服务器资源。
  2. 推理的时候需要选择图片的输出大小。不同大小的输出用的模型不同。
    • 越大的输出尺寸需要耗费的算力越多(时间越长),测试的时候可以先用小尺寸看效果。
    • fast neural style这个模型也可以支持输出任意图片大小,不过动态参数模型太大,复杂度也高,不适合 Web 使用。

Carrot Box流程管理平台

django-lb-workflow 我开发的一个Django流程引擎APP。设计之初是以使用便捷性为目标,自带了完整的模板,希望可以方便的集成到已有系统。尽管已经将django-lb-workflow做到尽量的易用,但距离真正的开箱即用还有一段距离。

Carrot Box是一个完整的Django易用,带了权限管理、部门、角色等必要模块,真正的做到开箱即用。通过对Carrot Box的定制可以方便的改造为OA、工单系统、CRM等业务系统。

Carrot Box的主要特点:

  • 是一个完整的应用,可以直接跑起来,开箱即用。
  • 自带HR模块,支持部门、角色的定义。支持按照部门、角色设置权限。
  • 带了几个范例流程,方便熟悉系统。
  • 包含一个代码生成器的使用范例,用于熟悉如果快速的创建一个自定义流程。
  • simplewf模块使用范例,以纯配置的方式添加新流程。

Carrot Box范例站点

之前的django-lb-workflow范例站点已经切换到 Carrot Box

地址: http://wf.haoluobo.com/

管理员账号:admin 密码:password

切换为其他用户: http://wf.haoluobo.com/impersonate/search

退回管理员账号: http://wf.haoluobo.com/impersonate/stop

将Carrot Box跑起来:

make init-pyenv
make init
make run

Go语言版 [Telegram Shell Bot]及Go的初体验

项目地址(Go): https://github.com/vicalloy/telegram-shell-bot-go

由于对Go不熟悉,因此之前版本的 Telegram Shell Bot 采用Python实现。在Python版发布后就开始尝试使用Go重新实现,毕竟之所以要做这东西也是想借个小程序体验一下Go语言。

我对Go语言的一些看法

随着微服务的兴起,相较以往服务的粒度可以拆分的更细。系统复杂度更多的转变为微服务构架设计的复杂度。服务拆分后每个具体的服务的复杂度将降低,系统对程序语言本身的构架能力的依赖会减少很多。同时在服务拆分后,各个服务组件可以灵活的采用适合的技术来完成工作。

Go语言本身极度精简(简陋),如果要象Java一样搭建一个单体的巨型项目会存在一定困难。Go的高性能,异步,加之足够简单,使Go在一些对性能要求较高,但业务复杂度相对较低的场合会非常适合。

Go可能永远不能变的同Java一样流行,但Go已经足够成功,值得去体验。

Go开发的相关资源

  • Tour of Go 官方的简明教程,可以快速浏览一遍了解Go的主要语言特性。代码编写过程中也可以作为参考手册。
  • Go标准类库 Go的标准类库。
  • Vim Go Vim的Go语言插件,支持语法检查、自动格式化、自动补全等特性。注:挺想试试GoLand,不过GoLand只有30天的试用期。
  • 在国内Go的官网访问不是特别方便,可以使用国内翻译的中文教程。Go标准类库(中文版) Tour of Go(中文版)

开发过程中的实际体验

Telegram Shell Bot Go 是我第一次使用Go写东西,由于只是一个小项目体验还不算特别深。Go语言中最精华的并发相关内容(goroutine / channel / select)并没有用到。

总的来说Go有着还不错的开发体验,但另一方便由于习惯了Python,Go又有不少让我用的不是特别舒服的地方。有人说Go是better C,我个人还是比较认可这个观点,相比其他语言Go很像C语言。

优点

  • Python使用缩进语法保证代码的整洁。Go则直接内置代码格式化工具来强制保证代码格式的一致性。
  • 之前听说Go的包管理很差劲。这次使用已经有go mod的支持,用下来体验还不错。
  • GC、性能好、编译速度快等。

不太习惯的地方(不一定是缺点)

  • 基础类型同Python相比差太多。Slice和Python里的List相对应,但功能方面差非常多。其中一个简单的删除对象的功能都需要自己实现。不清楚这是否是出于性能的考虑,需要让用户明确清楚相关操作的时间复杂度。但使用起来真的非常不方便。用了其他开发语言后,更让人怀念Python的列表推导。
  • Go在语法层面比较简单,相对较新的概念也就异步相关的内容(这部分Go设计的不错,实际上也并不难理解),真正难的还是适应Go的编程风格。Go的Telegram类库API风格同Python版有较大差别。我想API的风格差异更多的还是同语言本身风格差异相关的。要完全适应Go的编程风格可能需要先找几个代码写的比较好的项目先学习一下。