推荐三个代码统计工具 tokei, cloc 和 scc

有些时候在开源项目的时候可能需要对整个项目有一个全局的了解,比如想要了解这个项目中具体有多少行代码,那么这个时候,下面三个命令就派上用场了。

之前在 Twitter 上看到有人分享说 SQLite 的注释非常详细,甚至比代码都多,那么用下面这些工具一眼就能看到。

Tokei

Tokei 是一个使用 Rust 编写的用来显示代码信息的命令行工具,Tokei 可以以编程语言为分类显示文件数,代码行数,注释行数,空行数。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Language            Files        Lines         Code     Comments       Blanks
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 BASH                    4           49           30           10            9
 JSON                    1         1332         1332            0            0
 Shell                   1           49           38            1           10
 TOML                    2           77           64            4            9
───────────────────────────────────────────────────────────────────────────────
 Markdown                5         1355            0         1074          281
 |- JSON                 1           41           41            0            0
 |- Rust                 2           53           42            6            5
 |- Shell                1           22           18            0            4
 (Total)                           1471          101         1080          290
───────────────────────────────────────────────────────────────────────────────
 Rust                   19         3416         2840          116          460
 |- Markdown            12          351            5          295           51
 (Total)                           3767         2845          411          511
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Total                  32         6745         4410         1506          829
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

在 macOS 下安装:

brew install tokei

cloc

cloc 同样是一个用来计算代码行数的命令行工具,和 Tokei 一样,可以统计代码行数,注释行数,空行。 cloc 使用 Perl 编写。

Debian/Ubuntu:

sudo apt install cloc

或者以 Docker 运行:

docker run --rm -v $PWD:/tmp aldanial/cloc

scc

scc 是一个使用 Go 语言编写的统计代码行数的工具。

brew install scc

2022-05-23 cli , rust , tokei , cloc , code , code-statistics , golang

使用 uPic 快捷上传图片到图床

uPic 是一个 macOS 上的图片上传工具,使用 Swift 编写。支持对接非常多的对象存储,以及可以自定义使用 [[Chevereto]],或者 Lsky Pro 作为图床。

安装

可以直接从 App Store 安装,或者:

brew install bigwig-club/brew/upic --cask

自定义配置

配置 Lsky Pro

Lsky Pro 兰空图床是一个 PHP 编写的图床程序。Lsky Pro 升级了 2.0 版本,API 接口也进行了重写。

首先使用用户名,密码获取 Token:

curl -X POST -F "email=email@address" -F "password=your_passwd" https://your.domain/api/v1/tokens

复制返回值中的 token 字段。

然后配置 uPic,创建一个自定义 Host:

  • POST /api/v1/upload
  • 文件字段填写 file
  • URL ["data", "links", "url"]

示意图:

upic lsky pro config

然后配置 Other fields,添加 Header,记得 Bearer 后面添加上面获取的 Token。

upic other fields

设置 Chevereto

根据 Chevereto 的官方文档,可以配置:

upic chevereto settings

upic host chevereto header setting

API:

GET http://mysite.com/api/1/upload/?key=12345&source=http://somewebsite/someimage.jpg&format=json

参数:

  • key, The API v1 key, can be found in admin dashboard.
  • action, 值是 upload
  • source, URL 或者是图片的 Base64
  • format, 返回类型,可以是 json, redirect, txt

返回结果

{
    "status_code": 200,
    "success": {
        "message": "image uploaded",
        "code": 200
    },
    "image": {
        "name": "example",
        "extension": "png",
        "size": 53237,
        "width": 1151,
        "height": 898,
        "date": "2014-06-04 15:32:33",
        "date_gmt": "2014-06-04 19:32:33",
        "storage_id": null,
        "description": null,
        "nsfw": "0",
        "md5": "c684350d722c956c362ab70299735830",
        "storage": "datefolder",
        "original_filename": "example.png",
        "original_exifdata": null,
        "views": "0",
        "id_encoded": "L",
        "filename": "example.png",
        "ratio": 1.2817371937639,
        "size_formatted": "52 KB",
        "mime": "image/png",
        "bits": 8,
        "channels": null,
        "url": "http://127.0.0.1/images/2014/06/04/example.png",
        "url_viewer": "http://127.0.0.1/image/L",
        "thumb": {
            "filename": "example.th.png",
            "name": "example.th",
            "width": 160,
            "height": 160,
            "ratio": 1,
            "size": 17848,
            "size_formatted": "17.4 KB",
            "mime": "image/png",
            "extension": "png",
            "bits": 8,
            "channels": null,
            "url": "http://127.0.0.1/images/2014/06/04/example.th.png"
        },
        "medium": {
            "filename": "example.md.png",
            "name": "example.md",
            "width": 500,
            "height": 390,
            "ratio": 1.2820512820513,
            "size": 104448,
            "size_formatted": "102 KB",
            "mime": "image/png",
            "extension": "png",
            "bits": 8,
            "channels": null,
            "url": "http://127.0.0.1/images/2014/06/04/example.md.png"
        },
        "views_label": "views",
        "display_url": "http://127.0.0.1/images/2014/06/04/example.md.png",
        "how_long_ago": "moments ago"
    },
    "status_txt": "OK"
}

配置 Backblaze B2

[[Backblaze B2 Cloud Storage]]

同类产品

同类的图片上传工具还有:

reference


2022-05-21 upic , macos , mac-app , mac-application

逃离豆瓣之豆瓣代替服务

这篇笔记新建的时间是 2020 年 12 月 29 号,想来从那个时间点开始我就一直想着怎么离开豆瓣了。过去一年时间里面陆陆续续也发现了不少不错的网站,甚至有一些比豆瓣都要好用。这里就再整理一下。

豆瓣让我不能忍受的便是对词条的删减,以及对用户笔记,影评,书评的肆意审查,基本导致了现在豆瓣陷入不可用的状态。

我也曾经说过,我离不开豆瓣的几个理由:

  • 我过去几千条的标注
  • 豆瓣关注的有趣的灵魂
  • 还有无数的有价值的影评,书评

豆瓣电影 剧集

NeoDB

NeoDB 是一个建立在 federated network (联邦网络)中的用来标记书籍、电影、音乐和游戏的网站。

NeoDB 目前只能通过 [[Mastodon]] (或[[Pleroma]]/Friendica/PixelFed)实例的账号来登录。

我的页面:https://neodb.social/users/einverne@m.gtk.pw/

themoviedb

themoviedb 简称为 TMDB ,是一个从 2008 年开始的电影,剧集数据库。拥有非常全的数据库。

TMDB 也开放了编辑入口,所有的注册用户都可以贡献,和当年的豆瓣非常相似,官方也有非常详细的 贡献指南

themoviedb

看网站的设计,词条的界面,数据也非常详细,设计也不错。

themoviedb movie item

Trake.tv

[[trakt]] 是一个电视剧和电影媒体资源订阅追踪平台,电视界的 IMDB。可以认为是一个电视剧的数据库,有每个电视剧的元数据,至少包括剧名、首播时间、是否完结、长度、季、集、语言、国家、简介、类别、演员,链接到官网,IMDB,TMDB,TVDB,Wiki 等的链接等等。而且这些数据是公开的,有非常多 App 在使用他作为基础数据提供其他服务。

Trakt 相较于豆瓣更好的地方在于可以和第三方的应用交互,比如在 Plex 中看完一集之后可以自动同步到 trake。

Trakt 还支持 [[Kodi]], [[Plex]], [[Emby]], [[Netflix]], [[Infuse]], [[Jellyfin]], [[MediaPortal]], [[MrMC]], [[Stremio]], [[Serviio]], [[VLC]] 等等。

trakt-vip

Trakt 还提供了 VIP 增值服务,包括了如上的功能。个人 30$ 一年起步,还有另外一个是 60$ 一年。

LetterBoxd

LitterBoxd 是另一个可以标记看过电影的网站。不过 LetterBoxd 只支持电影。

首页:

letterboxd

词条页面

letterboxd item

TVDB

TBDB 是专注在剧集的网站。

IMDB

IMDB 就不用多说了,老牌的电影资料站。

豆瓣读书

Google Books

https://books.google.com

  1. 支持图书目录预览,支持标题,ISBN 搜索,支持浏览记录等等
  2. 支持标注想读(To read),在读(Reading now),读过(Have read),支持打分,甚至也是 1-5 分,支持填写 review
  3. 支持一键链接到网络商城购买,支持跳转到 Google Play 购买电子版

Google Book 的 API 文档:

google book search

Goodreads

Amazon 收购而来的网站,和 Kindle 搭配使用。

thestorygraph

可以用来追踪阅读进度,以及管理看过书籍。

豆瓣音乐

本人不怎么使用豆瓣音乐,所以没怎么整理,不过 Last.FM 已经存在很多年了。数据也比较全。


2022-05-12 douban , movie , book management , personal-data , track , 豆瓣 , douban

Proxmox 扩展 VM 虚拟机磁盘容量

之前在 Proxmox 上给 Ubuntu 划分了 64GB 的空间,运行一段时间之后磁盘空间剩余不多,就抽时间扩展一下。本文就记录一下给 Proxmox VE 的虚拟机扩展的过程。其实之前的文章里面也略微提到过一些,但是没有完整记录。

本来想着是这一篇文章把虚拟机的扩展和缩减空间一并整理了,但写着写着篇幅就比较大了,本文最后还是集中在扩容部分,缩减(shrink) 部分有机会再整理吧。

扩容之前

在扩容之前,为了防止发生错误,请先备份虚拟机,然后关闭虚拟机操作。

关于备份的操作可以参考: Proxmox VE 下备份和恢复虚拟机

虚拟机磁盘扩容

在 Proxmox VE 管理后台,点击虚拟机,在 Hardware 中选中 Hard Disk,然后在菜单栏中就能看到 Resize disk

proxmox resize vm disk

不过需要注意的是,这里的只能给虚拟机的磁盘增加容量,而不能缩小容量,关于缩小容量的操作以后有机会再写。

图中可以看到原始的虚拟机磁盘分配了 64GB,我又扩容了 64GB。

扩容之后启动虚拟机,SSH 登录,然后执行 df -h

Filesystem      Size  Used Avail Use% Mounted on
udev            7.8G     0  7.8G   0% /dev
tmpfs           1.6G  1.5M  1.6G   1% /run
/dev/sda2        63G   38G   23G  63% /
tmpfs           7.9G  4.0K  7.9G   1% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           7.9G     0  7.9G   0% /sys/fs/cgroup
/dev/loop0       56M   56M     0 100% /snap/core18/2344
/dev/loop2       62M   62M     0 100% /snap/core20/1434
/dev/loop1       56M   56M     0 100% /snap/core18/2409
mergerfs        5.4T  4.6T  510G  91% /mnt/storage
/dev/loop3       68M   68M     0 100% /snap/lxd/22753
/dev/loop6       44M   44M     0 100% /snap/snapd/15177
/dev/loop7       62M   62M     0 100% /snap/core20/1405
/dev/loop5       45M   45M     0 100% /snap/snapd/15534
/dev/loop4       68M   68M     0 100% /snap/lxd/22526
/dev/sdd1       1.8T  1.6T  196G  89% /mnt/sdb1
/dev/sdb1       1.8T  1.6T  117G  94% /mnt/sdd1
/dev/sdc1       1.8T  1.6T  198G  89% /mnt/sdc1
tmpfs           1.6G     0  1.6G   0% /run/user/1000

可以看到系统分区的容量 /dev/sda2 并没有扩展。

然后检查一下分区,执行 sudo lsblk

❯ sudo lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0    7:0    0 55.5M  1 loop /snap/core18/2344
loop1    7:1    0 55.5M  1 loop /snap/core18/2409
loop2    7:2    0 61.9M  1 loop /snap/core20/1434
loop3    7:3    0 67.8M  1 loop /snap/lxd/22753
loop4    7:4    0 67.9M  1 loop /snap/lxd/22526
loop5    7:5    0 44.7M  1 loop /snap/snapd/15534
loop6    7:6    0 43.6M  1 loop /snap/snapd/15177
loop7    7:7    0 61.9M  1 loop /snap/core20/1405
sda      8:0    0  128G  0 disk
├─sda1   8:1    0    1M  0 part
└─sda2   8:2    0   64G  0 part /

可以看到系统的分区 sda2 确实是没有完全占用全部的磁盘(sda)。这个时候我们只需要扩展一下系统分区即可。

我们可以使用很多种方式扩展分区,这里我们就使用 growpart 命令。

在 Debian 和 Ubuntu 下 growpart 命令在 cloud-guest-utils 包中。

sudo growpart /dev/sda 2

结果:

❯ sudo growpart /dev/sda 2
CHANGED: partition=2 start=4096 old: size=134211584 end=134215680 new: size=268431327 end=268435423

然后执行:

sudo resize2fs /dev/sda2

执行结果:

❯ sudo resize2fs /dev/sda2
resize2fs 1.45.5 (07-Jan-2020)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 8, new_desc_blocks = 16
The filesystem on /dev/sda2 is now 33553915 (4k) blocks long.

之后在查询 df -h 就看到空间完美的被使用了。

reference


2022-05-10 proxmox , pve , linux , vm , virtual-machine

现代性与大屠杀读书笔记

属于 [[20220417-21 天计划]] 的第3本书。

什么是现代性

[[现代性]]是指的现代社会所具有的一些典型特征。现代(modern)一词16世纪才被创造出来。字面上的含义是「当下或此刻」。人们有了时间的概念,生活不再周而往复。

这本书中对现代性的解释大致分为两个层面:

  • 精神层面,理性的精神,控制的欲望,人类想要认识一切、改造一切的精神
  • 制度层面,高效而有序的社会组织形态

为什么会发生犹太人大屠杀

  • 思想上
    • 不是传统的反犹主义,而是一种现代的思想,[[园艺文化]] 和 [[种族主义]]
    • 历史上的犹太人流落到欧洲的各处,属于从属地位,帮贵族收租,做些小买卖,成为了夹在贵族和平民之间的中间人,收到两边的歧视和厌恶
    • 崇尚理性、高效的现代化进程有一种园艺文化,在德国纳粹人严重犹太人就是杂草
    • [[种族主义]] 达到顶峰,保证日耳曼的血统纯正
  • 制度上
    • 现代[[官僚制度]]
    • 对犹太人进行精确的定义,纽伦堡法案,对犹太人进行登记
    • 将犹太人和其他德国人隔开
    • 着手将犹太人驱逐出德国疆域
      • 希姆莱 1940年在备忘录中写到,不想采用从肉体上消灭整个民族的做法,不德国,也不可能实现
      • 海德里希,种族灭绝对德国人这个文明的民族来说是不体面的
      • 遇到问题,找不到地方驱逐犹太人
        • [[艾希曼]],前往海法、开罗,研究将犹太人移居巴勒斯坦的可能性
        • 马达加斯加方案
        • 整体绝育手术
      • 战争的进行,升级成将犹太人驱逐出整个欧洲
      • 肉体消灭成为了清洗犹太人最有效的方式
      • 最终解决方案
      • 定义、隔离、驱逐、屠杀
    • 现代官僚制度是大屠杀发生的根本原因
  • 技术上
    • 现代工业制度才造就了灭绝营、毒气室
    • 大屠杀的主要方式灭绝营、毒气室都是现代性的产物
    • 大工业的设施和流程,现代化的分工和管理制
    • 奥斯威辛在4年里屠杀了100万,1943年,1天可以屠杀4万3千人,只有现代大工业才能产生这样的结果
    • 毒气出自先进的化学工业,铁路网向集中营输送犹太人

官僚体制中的人摆脱了道德上的谴责。 冷静、高效、专业的完成自己的工作。

为什么这些正常人能摆脱道德上的自责呢?

  • 首先,因为官僚制度,等级分明,在权力的等级序列中,就是听从上级的命令,遵守组织的纪律,每个人考虑的不是自己这么做的后果,而是有没有完成上级的任务,技术责任代替了道德责任,成为了一个人需要担负的主要责任,人们可以心安理得的将道德责任归咎于上级,甚至堂而皇之为自己辩护,「我只是做了我被要求做的事情」。[[201912211716-艾希曼在耶路撒冷]]
  • 现代社会,职能和职位的细致分工模糊了人的道德感,犹太人大屠杀的任务中每个人只是整个庞大机器上的一个螺丝钉,很多人不知道自己的行为会有什么后果,在办公室里制定火车时刻表的职员从未见过毒气室中的惨状。
  • 灭绝营,毒气室,大大降低了执行者在杀戮时可能产生的道德同情,现代心理学的研究已经表明距离越远,越不容易产生道德同情
    • 战争的现代化,让杀戮成为了距离和技术的问题,军事实力越强,距离敌方越远,杀戮越容易

受害方的现代性

犹太人是受害者,但鲍曼说犹太人也负有责任,是大屠杀的帮凶,这些犹太人受到理性的驱动。而理性也是现代性的一个特征。

  • 犹太委员会,提供记录,劝说犹太人隔离
  • 协助纳粹设定名单,决定哪些同胞在哪些时候上火车,奉行的原则是牺牲少数拯救多数,如果不送一部分同胞去死,纳粹会杀死所有人。
  • 最后是大多数犹太人的「自我保全」的理性,为了活下去可以做任何事情,包括亲手去处理大屠杀产生的尸体

三句话总结书的内容

鲍曼在这本书中提出了一个骇人听闻的观点:「德国纳粹在二战期间实行的对犹太人的种族灭绝是现代性的表现」。

  • 思想上,种族灭绝计划和园艺文化、种族主义息息相关
  • 制度上,大屠杀与现代官僚制度紧密关联
  • 技术上,大屠杀充分利用了现代技术

现代官僚制度和现代技术还让屠杀犹太人的纳粹分子在执行任务时摆脱了道德上的困扰。

启发或想法

道德,对他人无条件的责任

现代性体制会压制道德,现代官僚体系会让技术责任代替道德责任,现代社会的原子化倾向会让人们成为互相隔离的冷漠个体。但正因为如此,才更需要重视道德,在任何情况下,一个人都要承担其自己的道德责任,不管发生什么,他都应该去做对的事情。这是避免下一次大屠杀发生的唯一方式。


2022-05-08 reading , reading-2022 , 现代性 , 大屠杀

解决 Adobe Premiere 不支持 mkv 问题

一直想学习一下视频剪辑,这两天正好拿一个韩剧试一下,但没想到第一步导入就被拦在了外面,不过还好,正好可以学习一下 mkv 格式,以及基本的视频格式。

我在将 mkv 格式的文件导入到 Adobe Premiere 的时候报错:

File format not supported.

mkv 格式

mkv 的全称是 Matroska Video File,是一种开放的多媒体档案封装格式,可以将不同编码的影片,音轨,字幕封装到同一个档案中。通常的扩展名是 .mkv, .mka , .mks 等等。1

为什么 Adobe 不支持 mkv 格式

Adobe 从 2019.1.5 版本开始就放弃支持 mkv 格式了2

本质上 mkv 是一个封装格式,Adobe Premiere 还是支持编辑其中封装的视频内容的。

使用 ffmpeg 提取 mp4 格式

首先安装 ffmpeg,然后执行:

ffmpeg -i "original_filename.mkv" -codec copy output_name.mp4

这一行命令不会进行转码,所以提取速度约等于文件拷贝的速度,非常快。

容器和编码方式

上面提到过 mkv 是一种媒体容器,可以将不同编码类型的数据包含到一起。而编码方式则是决定了视频、音频的压缩算法。

可以通过 ffmpeg -i filename.mkv 来查看文件的具体详情。

以一个最简单的例子,为方便学习输出内容有省略:

❯ ffmpeg -i Going.to.You.at.a.Speed.of.493km.S01E04.1080p.DSNP.WEB-DL.AAC2.0.H.264-NYH.mkv
ffmpeg version 5.0.1 Copyright (c) 2000-2022 the FFmpeg developers
  built with Apple clang version 13.1.6 (clang-1316.0.21.2)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/5.0.1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
Input #0, matroska,webm, from 'Going.to.You.at.a.Speed.of.493km.S01E04.1080p.DSNP.WEB-DL.AAC2.0.H.264-NYH.mkv':
  Metadata:
    encoder         : libebml v1.4.2 + libmatroska v1.6.4
  Duration: 01:03:10.83, start: 0.000000, bitrate: 5704 kb/s
  Chapters:
    Chapter #0:0: start 1.001000, end 40.999000
      Metadata:
        title           : Intro
    Chapter #0:1: start 40.999000, end 3748.957000
      Metadata:
        title           : Scene 1
    Chapter #0:2: start 3748.957000, end 3790.826000
      Metadata:
        title           : Credits
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn (default)
    Metadata:
      BPS             : 5575824
      DURATION        : 01:03:10.787000000
      NUMBER_OF_FRAMES: 90888
      NUMBER_OF_BYTES : 2642095527
      _STATISTICS_WRITING_APP: mkvmerge v67.0.0 ('Under Stars') 64-bit
      _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
  Stream #0:1(kor): Audio: aac (LC), 48000 Hz, stereo, fltp (default)
    Metadata:
      BPS             : 125375
      DURATION        : 01:03:10.826000000
      NUMBER_OF_FRAMES: 177695
      NUMBER_OF_BYTES : 59409362
      _STATISTICS_WRITING_APP: mkvmerge v67.0.0 ('Under Stars') 64-bit
      _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
  Stream #0:2(kor): Subtitle: subrip
    Metadata:
      title           : SDH
      BPS             : 74
      DURATION        : 01:03:00.359000000
      NUMBER_OF_FRAMES: 1167
      NUMBER_OF_BYTES : 35163
      _STATISTICS_WRITING_APP: mkvmerge v67.0.0 ('Under Stars') 64-bit
      _STATISTI

可以看到其中有三段 Stream,可以看到第一段是视频,第二段是音频,而第三段则是字幕,为了方便这里省略了后面还有的多语言字幕。

在每一段中可以看到其编码方案比如视频是 h264, 音频是 aac。

H.264 是一种视频编码,H.264 标准制定的目的就是为了创建一个更好的视频压缩标准,可以在更低的比特率的情况下可以提供更好的视频质量。


2022-05-07 adobe , adobe-premiere , mkv , ffmpeg , macos , handbrake

每天学习一个命令:growpart 扩容分区

前端时间给 Proxmox VE 下的虚拟机扩容的时候留意到了这个 growpart 命令,专门用来给分区进行扩容的命令。

growpart - extend a partition in a partition table to fill available space

growpart 工具完成 Linux 系统盘分区扩容及文件系统扩展

Installation

Ubuntu 下可以直接安装:

sudo apt install cloud-guest-utils

使用

注意,对磁盘进行操作是高风险操作,如果对命令不熟悉,请先做好数据的备份,然后再进行操作,或实验。

我以我自己的实际情况为例,我有一个 Proxmox VE 的虚拟机因为磁盘内容告警,所以扩容了一倍,从 64G 扩容到 128GB。

在 Proxmox VE 中停止虚拟机之后扩容,然后启动虚拟机进入系统操作。

首先使用 fdisk -l 来查看磁盘分区信息,可以看到目前系统的分区还是没有改变,但是可以看到磁盘已经有剩余空间了。

因为我这里比较简单,我只想把剩余的空间分配给我当前的系统分区,所以可以直接使用 growpart,如果你还需要复杂操作,比如再划分一个分区之类的,可以考虑 [[parted]] 等命令。

还可以使用 lsblk 再确认一下。

因为我的系统分区是 /dev/sda 磁盘的第二个分区,所以运行 growpart 命令扩容分区

growpart /dev/sda 2

然后再执行以下命令,扩容 ext 文件系统

resize2fs /dev/sda2

再查看磁盘:

df -h
lsblk
fdisk -l

总结

growpart 命令可以非常方便的将分区扩展到全部的磁盘空间,不过需要注意的是,我的例子中 /dev/sda2 分区是磁盘的最后一个分区,如果你要扩容的分区在分区中间,可能需要考虑其他方案。

相关

  • [[gparted]]
  • [[2018-04-03-parted-linux-partition]]
  • [[2016-04-02-fdisk]]
  • [[lsblk]]

2022-05-03 linux , drive , growpart , partition , cli

aiohttp 使用笔记

最近想找一个 [[Wallabag]] 的 Python 客户端,在 GitHub 简单搜寻了一下之后发现了 wallbag_api 这个仓库,看了一下 Python 代码之后发现库中的代码是用 aiohttp 编写的,所以就来学习一下这个 Python 的异步 HTTP 库 aiohttp。

aiohttp 官方简洁明了,Asynchronous HTTP Client/Server for asyncio and Python. aiohttp 是一个基于 asyncio 模块的异步 HTTP 客户端/服务端框架。

可以 看到 aiohttp 不仅是一个 HTTP 客户端,也可以作为服务端。同时支持服务端的 WebSockets 和客户端 WebSockets。

我们知道 Python 下还有一个比较著名的 HTTP Client 库叫做 requests,这是一个同步的 HTTP 调用客户端,使用 requests 发起 HTTP 调用之后需要同步等待返回结果,而在 aiohttp 可以在发起请求之后将将程序的控制权暂时给别人,等待响应返回结果回来了之后再进行处理,这就可以提升系统的性能。

aiohttp 内部使用了 [[python-asyncio]] 来实现,而 Python 下 asyncio 的核心就是 [[Coroutine 协程]]

Coroutine 协程

Coroutine(协程)是一个更通用的 subroutine(子程序)。

async 方法中使用 await 关键字来表示 coroutine。当使用 await 关键字的时候,coroutine 会将当前程序的控制释放给 Event loop。

import asyncio
async def async_func():
    print('start ...')
    await asyncio.sleep(1)
    print('... end!')

async def main():
    async_func()#this will do nothing because coroutine object is created but not awaited
    await async_func()

asyncio.run(main())

如果直接调用 async_func() 不会有任何作用,需要在前面添加 await

协程适合 IO 密集型任务:

  • 网络请求,比如爬虫 [[aiohttp]]
  • 文件读写,[[aiofile]]
  • Web 框架,[[aiohttp]], [[fastapi]]
  • 数据库查询,[[asyncpg]], [[databases]], [[aiomysql]]

Installation

安装使用:

pip install aiohttp

作为客户端

aiohttp 作为客户端。

这里可以和 requests 做一个简单的对比,在 requests 中发起同步请求:

import requests 
def hello()    
     return requests.get("http://httpbin.org/get")     

print(hello())

程序在 requests.get 方法调用时会同步等待请求返回。

而如果使用 aiohttp:

#!/usr/local/bin/python3.6
import asyncio 
from aiohttp import ClientSession 

async def hello():     
    async with ClientSession() as session:         
        async with session.get("http://httpbin.org/headers") as response:                
            response = await response.read()                         
            print(response) 
  
loop = asyncio.get_event_loop() 
loop.run_until_complete(hello())

在这个异步代码中我们可以看到很多的异步关键字,async 以及 await 关键字定义函数为异步。

这里使用 ClientSession() 获取一个 Session,session 可以在多个请求之间保留 cookie 和相关信息。因为 session 关闭是一个异步操作,所以需要使用 async with

session.get 发起调用,也是一个异步操作,所以也需要使用 async,而 with 语句保证 response 可以正确关闭。

最后为了让这个异步方法可以执行,需要将其放入一个事件循环。

作为服务端

[[用 aiohttp 写服务器]] 不是本文的重点,所以简单了解一下,先略过。

from aiohttp import web

routes = web.RouteTableDef()

@routes.get('/')
async def hello(request):
    return web.Response(text="Hello, world")

app = web.Application()
app.add_routes(routes)
web.run_app(app)

控制并发

使用 Semaphore 控制

Semaphore 是一个线程计数器,核心是 acquire()release() 方法。

执行 acquire() 方法时,先判断内部值是否小于 0,如果大于 0,获得锁,内部值减一,如果小于 0,阻塞,直到 release() 方法释放锁,内部值加一。

async def fetch(url, semaphore):
    async with semaphore:
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                data = await response.text()
                print('data', data + " " + time.ctime())
                return data

async def run():
    url = 'http://127.0.0.1:5000'
    semaphore = asyncio.Semaphore(2)  # 限制并发量为2
    to_get = [fetch(url, semaphore) for _ in range(10)]
    await asyncio.wait(to_get)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())
    loop.close()

使用 TCPConnector 控制

async def fetch(session, url):
    async with session.get(url) as resp:
        if resp.status != 200:
            resp.raise_for_status()
        data = await resp.text()
        print('data', data + " " + time.ctime())
        return data

async def fetch_multi(session, urls):
    tasks = []
    for url in urls:
        task = asyncio.create_task(fetch(session, url))
        tasks.append(task)
    # gather: 搜集所有future对象,并等待返回
    results = await asyncio.gather(*tasks)
    return results

async def main():
    urls = ["http://127.0.0.1:5000/" for _ in range(10)]
    conn = aiohttp.TCPConnector(limit=3)
    async with aiohttp.ClientSession(connector=conn) as session:
        datas = await fetch_multi(session, urls)
        print(datas)

if __name__ == '__main__':
    asyncio.run(main())


2022-05-03 http , aiohttp , python , aio , async

使用 lux 下载哔哩哔哩视频

Lux 是一个使用 Go 语言编写的视频下载命令行工具,支持的平台很多,提供了包括 macOS、Windows、Linux 等等平台的命令行支持,安装和使用非常简单的。Lux 原来的名字是叫做 Annie(安妮),对标的是 macOS 上一款非常著名的视频下载软件叫做 Downie(唐尼)。但后来改名成了 Lux。

Lux 支持非常多的视频网站:抖音、哔哩哔哩、半次元、pixivision、优酷、YouTube、爱奇艺、芒果 TV、Tumblr、Vimeo、Facebook、斗鱼视频、秒拍、新浪微博、Instagram、Twitter、腾讯视频、网易云音乐、音悦台

项目地址:https://github.com/iawia002/lux

Installation

macOS 下:

brew install ffmpeg
brew install lux

或者从 Release 页面下载,手动安装。

curl "https://github.com/iawia002/lux/releases/download/v0.15.0/lux_0.15.0_macOS_64-bit.tar.gz"

Ubuntu 下安装

sudo apt install ffmpeg
wget "https://github.com/iawia002/lux/releases/download/v0.15.0/lux_0.15.0_Linux_64-bit.tar.gz"
tar zxvf lux_0.14.0_Linux_64-bit.tar.gz
sudo mv lux /usr/local/bin
lux --help

使用

直接下载

Lux 的使用很简单,在终端:

lux "https://www.youtube.com/watch?v=QJXPS0gQ6Eg"
lux "https://www.bilibili.com/video/BV1ZJ411h713"

视频链接给的是播放列表里的第二个视频。如果用 youtube-dl 下载会自作主张地下载播放列表的第一个视频。在对付 B 站播放列表方面,Annie 比较乖一点。

Annie 不仅可以下载视频,如果给的是图片的网址,它就下载图片。

给播放列表的链接就下载播放列表:

下载不同分辨率

首先使用 -i 参数查看可供下载的视频分辨率,-i 参数可以一次添加多个视频链接,空格分隔。

❯ lux -i "https://www.bilibili.com/video/BV1ZJ411h713"

 Site:      哔哩哔哩 bilibili.com
 Title:     【中字】金世正 talk演唱会 全场 非常治愈的谈话
 Type:      video
 Streams:   # All available quality
     [64-7]  -------------------
     Quality:         高清 720P avc1.640028
     Size:            122.36 MiB (128300684 Bytes)
     # download with: lux -f 64-7 ...

     [32-12]  -------------------
     Quality:         清晰 480P hev1.1.6.L120.90
     Size:            108.75 MiB (114028043 Bytes)
     # download with: lux -f 32-12 ...

     [64-12]  -------------------
     Quality:         高清 720P hev1.1.6.L120.90
     Size:            108.57 MiB (113847391 Bytes)
     # download with: lux -f 64-12 ...

     [16-7]  -------------------
     Quality:         流畅 360P avc1.64001E
     Size:            86.10 MiB (90287066 Bytes)
     # download with: lux -f 16-7 ...

     [32-7]  -------------------
     Quality:         清晰 480P avc1.64001F
     Size:            67.43 MiB (70708693 Bytes)
     # download with: lux -f 32-7 ...

     [16-12]  -------------------
     Quality:         流畅 360P hev1.1.6.L120.90
     Size:            67.40 MiB (70670783 Bytes)
     # download with: lux -f 16-12 ...

然后使用 -f 来指定要下载的分辨率:

lux -f 64-7 https://www.bilibili.com/video/BV1ZJ411h713

下载列表

使用 -p 来下载视频列表。

如果要指定列表中的位置,可以使用如下几个选项:

  • -start 从视频列表的第几个开始下
  • -end 下载到几个
  • -items 指定要下载哪几个,比如 1,5,6,8-10
  • -eto B 站独有的参数,用于没有标题只有文件名的播放列表

举例:

lux -p -start 1 -end 15 "https://www.bilibili.com/video/BV1no4y1C7oo"

从文件中读取下载链接

可以使用 -F 参数,从包含视频 URL 的文本文件中下载视频:

lux -F /path/to/links.txt

这里也可以用参数 -start-end-items

按住 ctrl+c 可以中断下载,可以续传。

B 站上可以用 av 和 ep 加数字下载视频,比如:

annie -i ep198381 av21877586

还有三个参数也很有用:

指定保存路径

可以使用 -o 参数后面接路径,来指定将视频保存到该路径下:

lux -o ~/Videos/ URL

使用 -O NAME 来指定输出的名字。

输出 JSON

可以使用 -j 输出 JSON 格式结果。

  • 最出名的 [[youtube-dl]] 还有升级版的 [[yt-dlp]]
  • 适配比较多国内的 [[视频下载工具 you-get]]
  • Go 语言写的视频下载命令行工具 [[lux]]
  • C# 编写的 B 站下载 BBDown

2022-05-01 lux , bilibili , annie , video

图片压缩工具 Squoosh 离线版

Squoosh 是 Google 推出的一个图片压缩工具。之前整理macOS 初始化设置 的时候就说过,基本上算是必不可少的一个压缩工具了。

如果要大批量压缩图片,之前也介绍过 jpegoptim 和 optipng

如果要实现更加高阶的图片操作,比如 resize, blur, crop, despeckle, dither, drow on, flip, join, re-sample 等等,也可以了解一下 [[ImageMagick]]。

但使用 Squoosh 的过程中有一点不方便的就是 Google 只提供了在线版,之前也在 issue 中提过,官方回复是本来这个工具就是命令行的一个在线化,没有必要再搞一个离线的版本。

但最近发现 GitHub 上有人做出了一个离线版本的 Squoosh。

离线版本的 Squoosh 基于 Electron,并使用了 GoogleChromeLabs 之前开源的在线版。


2022-04-28 macos , linux , application , squoosh , google , electron , google-chrome , image , image-compress

电子书

最近文章

  • 使用开源 Wakapi 代替 WakaTime 统计编码时间 之前折腾 GitHub Profile 的时候发现了 [[WakaTime]] 这样一款统计编码时间的工具,之后在读 waka-readme 项目的时候发现,还有两个完全开源的后端兼容版本,一个是 Golang 编写的 [[wakapi]] ,一个是 Huskell 编写的 hakatime 。
  • 使用 WakaTime 统计编码时间 [[WakaTime]] 是为程序员打造的编码统计 Dashboard,可以同来统计项目,编程语言,IDE,编码时间等等内容。 之前在折腾 GitHub Profile 的时候发现的,可以在 GitHub Profile 页面中动态的展示最近的编程状态。
  • 折腾一下 GitHub Profile 虽然很早就知道 GitHub 发布了 Profile 功能,可以使用 README 来丰富 Profile 页面。但是一直以来没啥动力,大多数时候都不会去到主页去访问。但现在有些时候逛 GitHub 的时候会点到 其他人 的主页去看,发现有一些主页虽然只有寥寥几句,但却可以清楚的知道「他/她」最近在贡献什么内容,擅长什么技能。虽然我在 GitHub 上还是观摹大佬居多,但也想着通过这个契机在整理 GitHub Profile 的时候加深一下对自己的认知。
  • 现代政治的正当性基础 读书笔记 怎么知道的这一本书 似乎是在豆瓣的推荐流中第一次发现这一本。
  • 富兰克林自传 读书笔记 怎么知道的这一本书 已经被不止一遍的推荐过,[[芒格]] 非常喜欢这本书,在《穷查理宝典》里面推荐过,巴菲特也曾推荐过,在之前看过的 [[法官能为民主做什么]] 中也能读到美国最高法院法官对富兰克林的尊敬,再到国内,罗辑思维也在视频中推荐过。上一本读过的 [[新教伦理与资本主义精神]] 中[[马克思 韦伯]] 也列举了 [[富兰克林]] 作为例子,有意思的是我在我的笔记库中搜索的时候,一本讲述德州扑克的树中作者也援引了富兰克林的观点,可见富兰克林在美国人心中的地位。