让 PyMongo + MongoDB 2.6 继续支持空 $set

tl;dr 这只是一个丑陋的 monkey-patch 方法.

在 MongoDB 2.4 及以前版本中, db.foo.update({…}, {“$set”: {}}), 也即 “空 $set” 是可以正常执行的. 配合 upsert 等参数执行时可以有不同的方便用法. 但是升级到 MongoDB 2.6 以后, 由于引入了严格的参数检查, 试图进行空 $set 操作时, 会出现这样的错误:

OperationFailure: '$set' is empty. You must specify a field like so: {$mod: {: ...}}"

由于本猫不太想改依赖这个方法的代码逻辑(有点多…), 于是写了一个丑陋的 monkey patch 来 workaround 这个问题:

# Monkey patch pymongo to allow empty $set
from pymongo import collection
pymongo_collection_update = collection.Collection.update

def pymongo_collection_update_with_empty_set_support(self, spec, document, *args, **kwargs):
    if "$set" in document and document["$set"] == {}:
        document.pop("$set")
        if document == {}:
            return None
    return pymongo_collection_update(self, spec, document, *args, **kwargs)

collection.Collection.update = pymongo_collection_update_with_empty_set_support

上游 Bug Report: https://jira.mongodb.org/browse/SERVER-12266 (已经确定不会修)

让 Pipelight 用中文 Locale 运行 – 解决非中文 Locale 下 Pipelight 插件中文显示为方框问题的简单方法

如果你和我一样, 系统语言喜欢用英语等非中文语言, 但是又需要 pipelight 的插件能正常显示中文(比如 flash player + AB 站之类的), 那么这个简单的方法可以让你两者兼得!

先上效果图:
snapshot70

方法其实很简单, 只是因为 pipelight 还在开发中, 所以没看到相关的介绍哈. 以下方法是 pipelight 开发者在 irc 中告诉我的, 特此感谢~!
(如果你的 pipelight 安装的地方和我不一样, 别忘记相应修改路径哈)

1. 创建文件 /usr/local/bin/wine-pipelight-zh_cn-wrapper:

#!/bin/sh
LANG=zh_CN.utf8 /opt/wine-compholio/bin/wine "$@"

给它加上执行权限.

2. 复制 pipelight 配置文件以便编辑: (以 flash 为例)

$ cp /usr/share/pipelight/configs/pipelight-flash ~/.config/

3. 编辑 pipelight 配置文件:
找到

winePath            = /opt/wine-compholio/bin/wine

修改为:

winePath            = /usr/local/bin/wine-pipelight-zh_cn-wrapper

完成! 启动浏览器享受流畅科学的 flash 吧! (不对, flash 怎么可能科学!)

更新: 升级了 flash 再上张图, 嗯我才不是故意宣传老 K 的视频呢~
snapshot71

搜狗拼音 for Linux 新版发布

官网地址:
http://pinyin.sogou.com/linux/

本猫折腾了一下, 做了一个 PKGBUILD, Hack 了一下 curl 版本的问题, 目前自己测试可以用哈~
snapshot66

坑爹之处在于, 这次放出的版本必须用内置的 qimpanel 界面! 也就是说, 经典 UI 和 kimpanel (包括 gnome-shell 那个 kimpanel 插件之类的) 都不能用, 否则你会看到一条超坑的提示:

“请启用fcitx-qimpanel面板程序,以便更好的享受搜狗输入法!”

做好的包和完整的 src 包下载: http://pkgbuild.com/~fyan/staging/fcitx-sogoupinyin/

PKGBUILD: (偷懒的猫只做了 x86_64 的)

# Maintainer: Jove Yu <yushijun110[at]gmail.com>
# Contributor: csslayer <wengxt[at]gmail.com>

pkgname=fcitx-sogoupinyin
pkgver=1.0.0.0011
pkgrel=1
pkgdesc="Sogou Pinyin for Linux"
arch=('x86_64')
url="http://code.google.com/p/fcitx"
license=('custom')
depends=('fcitx')
source=("http://ime.sogou.com/dl/1397738329/sogou_pinyin_linux_${pkgver}_amd64.deb"
        fcitx-qimpanel
        libcurl.so.4)

if [ "${CARCH}" = "i686" ]; then
    _LIB_DIR=i386-linux-gnu
else
    _LIB_DIR=x86_64-linux-gnu
fi

package(){
  bsdtar -xf data.tar.xz -C "${pkgdir}"

  mv "$pkgdir"/usr/lib/{$_LIB_DIR/,}fcitx
  rmdir "$pkgdir/usr/lib/${_LIB_DIR}"
  
  # Workaround curl problem - install an old version and use LD_LIBRARY_PATH to use it
  mv "$pkgdir"/usr/bin/fcitx-qimpanel{,.real}
  install -Dm755 fcitx-qimpanel "$pkgdir/usr/bin/"
  install -Dm644 libcurl.so.4 "$pkgdir/usr/share/fcitx-sogoupinyin/"

  rm -r "$pkgdir"/etc/apt
  rm -r "$pkgdir"/usr/share/{keyrings,upstart}
}

sha512sums=('9ac4d67aa2dea979d39cd5d13965c5ca103a6f52b4e7db53d1d9402efec0641aaf30ebc64d99a690692d45d4b6ebb742da56cb0d175eb36d194b1d45ed11e53f'
            '4d49b346cd1fb1279865b1c6df774ad393816f709c91c80702adce6926d32a45641d26943597d152a5c7b57dd4c2e23799e005cc1d959645025218a5ce5bfd41'
            '8b64e7489443d59a6ceebc7cf66697c16826502f0bb4f64c5c1a475ffc45cf000794339d95acdada849e85bc99183112a6887525aa00a13c1234d0dc7fa676dc')

其中那个 libcurl.so.4 是从一个很老版本的 curl 包里提出来的.

workaround curl 用的那个启动脚本:
/usr/bin/fcitx-qimpanel

#!/bin/sh
LD_LIBRARY_PATH="/usr/share/fcitx-sogoupinyin:$LD_LIBRARY_PATH" /usr/bin/fcitx-qimpanel.real "$@"

使用方法:
重载 fcitx, 开启 qimpanel:

fcitx -r --enable fcitx-qimpanel

然后启动 fcitx-qimpanel:

fcitx-qimpanel

然后切换到搜狗拼音输入法, 可以开始玩了!

尝鲜: 新的网络连接管理工具 systemd-networkd

在吃掉 udev 和谋划收编 dbus 后, systemd 又将它的魔爪伸向了网络管理方面. 虽然这已经是 systemd 209 时候的旧闻, 不过因为整个功能太过不完善 (被吐槽有超多 bug, 以及各种基本功能缺失) 以及没有文档, 上游一直没有大力推广.

本文仅就最为简单普通的有线网络连接介绍 systemd-networkd 的打开方式. (wifi 呀, ppp 呀, vpn 呀之类的复杂配置现在都不支持哦) (大部分信息翻译自 ArchWiki)

先介绍一些基本的信息:

配置文件存放在 /usr/lib/systemd/network (上游提供的配置), /run/systemd/network (运行时配置), 以及 /etc/systemd/network (本地配置). 其中 /etc/systemd/network 有着最高的优先级.

有三类配置文件:

  1. .network 文件: 给匹配到的设备应用一个网络配置
  2. .netdev 文件: 给匹配到的环境创建一个虚拟的网络设备
  3. .link 文件: 当一个网络设备出现时, udev 会寻找第一个匹配到的 .link 文件.

他们都遵循一些相同的规则:

  • 如果 [Match] 部分满足了条件, 在接下来的段落中的配置会被应用
  • [Match] 部分可以接受不止一项条目. 在这种情况下, 只有当每一个条目都被满足时, 这个配置才会被启用
  • 空白的 [Match] 部分表示这个配置在任何情况下都会被应用
  • 每一项条目都是 KEY=VALUE 格式的键值对
  • 所有的配置文件会被收集并按字典序排序后再处理, 无论它们在哪个目录
  • 相同名字的配置文件会相互替代
Continue reading 尝鲜: 新的网络连接管理工具 systemd-networkd

添加 Linux 原生游戏到 Wine Steam 里并记录游戏状态 / 让 Wine Steam 里的不同游戏用不同的语言(环境变量)运行

首先解释下这个奇怪的需求哈:

1. 添加 Linux 原生游戏到 Wine Steam 里并记录游戏状态: 可以让 Steam 好友知道自己在玩什么, 而同时又可以避免用 Wine 跑相应游戏带来的性能损失. 如果直接用 Wine 自带的 start.exe 启动 Linux 游戏, 因为 start.exe 会在启动游戏后直接退出 (/wait 参数对 Linux 进程无效), 因此游戏时 Steam 状态会显示为不在游戏中, 这样我们的目的就达不到了…

2. 让 Wine Steam 里的不同游戏用不同的语言(环境变量)运行: Wine 对 CJK 字符编码的修正是和语言(Locale)环境变量有关的, 比如 Touhou 用 ja_JP 环境跑表现一切正常, 而在 zh_CN 或者 en_US 下标题栏均是不同程度的乱码 (其它程序有更严重的问题, 包括全部字符变成问号等). 但是用 Steam 运行游戏时, 所有子进程都直接继承了运行 Steam 时的环境变量, 没有办法修改.

至于为啥不在 Linux 原生版的 Steam 里用? 嗯, 因为想要反向实现需求, 也就是让 Linux 原生版的 Steam 能跑 Wine 的 Steam only 游戏, 这件事情的难度好像不是一般的大… (DRM 什么的, 而且 Steam 是单点登录的)

看起来好像是无关的两个问题哈 <(=^_^=)> 不过呢, 本猫用了相关的方法来解决, 因此放在同一篇博客里介绍啦.

警告: 本方法各种丑陋, 要是产生不适千万不要怪我(

咳咳, 回到正题. 我的思路是使用一个文件锁:

1. Wine 启动一个 wrapper (也就是 Steam 命令行里填写相应的路径)
2. wrapper 首先创建一个临时文件, 然后把文件名传给一个 wine 外运行的脚本
3. 这个时候 wrapper 已经丢失了自己刚刚启动的脚本的运行状态, 但是可以继续通过检测文件是否存在来知道脚本是否已经退出
4. 脚本启动目标程序
5. 脚本等到程序退出再删除临时文件
6. wrapper 检测到临时文件消失后, 退出

Continue reading 添加 Linux 原生游戏到 Wine Steam 里并记录游戏状态 / 让 Wine Steam 里的不同游戏用不同的语言(环境变量)运行
QR Code Business Card