It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

KDE Plasma had been taking unbearably long to startup since an update one or two months ago for me. I thought it was caused by a bug of Qt but things turned out that this was not the fix to my problem.

Then I suddenly noticed that actually only the initial start after a boot would be slow, subsequent ones are way faster. So it must be a caching issue. I have mounted my /tmp in memory and moved a bunch of hot files into it and all of them will be lost after reboot. This is a common approach to make SSDs live longer and improve performance that could be found in many tutorials.

But some caches are designed to be reused after reboot. By default, they are often located in ~/.cache or /var/cache and you have to be really careful when relocating them, e.g. XDG_CACHE_HOME. Many Qt compilation caches are stored in this path and if you erase them after shutdown, it will have to re-compile them again on each boot.

Hence an easy fix here could be:

mkdir -p /tmp/xdg_cache
if [ -d $HOME/.cache/xdg_cache ]; then
    rsync -a $HOME/.cache/xdg_cache/ /tmp/xdg_cache
fi
#!/bin/bash
if [ -d /tmp/xdg_cache ]; then
    rsync --exclude='google-chrome' --exclude='pacaur' -a /tmp/xdg_cache/ $HOME/.cache/xdg_cache
fi

I ignored the caches of Chrome and Pacaur as they are not needed after reboot and usually quite large.

It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

Git automatically calls less if the output is fairly long in the terminal. It is rather useful to avoid terminal history being violated and allows user to search through the output.

However, plain less isn’t the perfect solution. What I (and I believe many others also) want is:

  • Always colored output
  • Scrolling by touchpad or mouse
  • Auto-quit-if-one-screen

less -+F -+X -+S does everything except the last one. But if I remove -+F, there will be no output in case of one-screen; if I remove -+X as well, the output is back but it disables scrolling. I opened a thread in StackExchange but no satisfying answers came up.

So here’s a Bash script I wrote:

#!/bin/bash

# BSD/OSX compatibility
[[ $(type -p gsed) ]] && SED=$(type -p gsed) || SED=$(type -p sed)
[[ -f "$1" ]] && CONTEXT=$(expand < "$1") || CONTEXT=$(expand <&0)
[[ ${#CONTEXT} -eq 0 ]] && exit 0
CONTEXT_NONCOLOR=$( $SED -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" <<< "$CONTEXT")
LINE_COUNT=$( (fold -w $(tput cols) | wc -l) <<< "$CONTEXT_NONCOLOR" )

[[ $LINE_COUNT -ge $(tput lines) ]] && less -+X -+S -R "$@" <<< "$CONTEXT" || echo "$CONTEXT"

It works fine with Bash. But when things come to Zsh/Fish the case could be more complicated as the prompt itself may take multiple lines. I’m still looking for a proper solution for this.

It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

I’m not a fan of rustup and I’ve been always using the installation scripts in official packages.

However, things have become troublesome since I started cross-compilation. Rust have provided their pre-compiled standard libraries in Rust Archives which saved me plenty of time. However each time a new version is released, I have to manually download and install a number of packages and I went through a lot of pain.

So finally I decided to write an updating script for Rust. It is capable of handling rustc, libraries as well as the source code (by detecting environment variable). I deem that it could work on most Linux distros. You will need aria2c as the downloader and of course you can change it easily.

#!/bin/bash
HOST="x86_64-unknown-linux-gnu"
VERSION=$1

# check rustc
RUSTC=$(type -p rustc)
if [[ $? -ne 0 ]]; then
    echo "ERROR: rustc not found"
    exit 1
fi
RUSTLIB=$(dirname $(dirname $(type -p rustc)))"/lib/rustlib"

# check temp directory
TMP="/tmp/rustc"
mkdir -p $TMP
if [[ $? -ne 0 ]]; then
    echo "ERROR: Cannot create temp directory: $TMP"
    exit 1
fi

# check aria2c
type -p aria2c > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
    echo "ERROR: aria2c not found, please install it first"
    exit 1
fi

# default stable
if [[ -z $VERSION ]]; then
    echo "WARN : Version not specified, falling back to stable"
    VERSION="stable"
fi

if [[ $VERSION == "stable" ]]; then
    VERSION=$(curl https://static.rust-lang.org/dist/channel-rust-$VERSION 2>/dev/null | head -n 1 | sed -r "s/^rust-([0-9\.]+).*/\1/")
fi

printf "INFO : Installing Rust v%b, continue? [y/n] " "$VERSION"
read PROMPT
if [[ $PROMPT != "y" && $PROMPT != "Y" ]]; then
    exit 0
fi

sha256_file()
{
    echo $(sha256sum "$1" 2>/dev/null | sed -r "s/^([a-z0-9]+).*/\1/")
}

rust_download()
{
    local ARIA2C="aria2c -d $TMP -q "
    local FILE=$1
    local BASE="https://static.rust-lang.org/dist/"

    local DEST="$TMP/$FILE"
    local SHA=$(curl "$BASE""$FILE".sha256 2>/dev/null | sed -r "s/^([a-z0-9]+).*/\1/")

    if [[ -s $DEST && $(sha256_file $DEST) == "$SHA" ]]; then
        echo "INFO : $FILE already existed"
    else
        if [[ -e $DEST ]]; then
            rm $DEST
        fi
        $ARIA2C "$BASE""$FILE"
        local SHA_GOT=$(sha256_file $DEST)
        if [[ "$SHA_GOT" != "$SHA" ]]; then
            printf "ERROR: SHA256 mismatch: %b\n\tExpected: %b\n\tGot     : %b\n" "$DEST" "$SHA" "$SHA_GOT"
            return 1
        fi
    fi

    echo "INFO : Extracting $FILE"
    tar -xf "$DEST" -C "$TMP"
}

# check installed standard libraries
echo "INFO : Searching for installed Rust libraries in $RUSTLIB"
LIBLIST=$(ls $RUSTLIB | grep manifest-rust-std | sed -r "s/^manifest-rust-std-(.*)/\1/" | grep -v "$HOST")
if [[ -z $LIBLIST ]]; then
    echo "INFO : No libraries were found"
else
    for i in ${LIBLIST[@]}; do
        printf "\t%b\n" "${i}"
    done
fi

# check installed source files
if [[ -n "$RUST_SRC_PATH" ]]; then
    RUSTSRC=$(dirname $(dirname $RUST_SRC_PATH))
    echo "INFO : Source code found, installing to $RUSTSRC"
fi

# start downloading
set -e
echo "INFO : Downloading rustc"
FILE="rust-""$VERSION""-""$HOST"".tar.gz"
rust_download $FILE

if [[ -n "$RUST_SRC_PATH" ]]; then
    echo "INFO : Downloading source"
    FILE="rustc-""$VERSION""-src.tar.gz"
    rust_download $FILE
fi

if [[ -n $LIBLIST ]]; then
    echo "INFO : Downloading libraries"
    for i in ${LIBLIST[@]}; do
        echo "INFO : Downloading library for target: ${i}"
        FILE="rust-std-""$VERSION""-""${i}"".tar.gz"
        rust_download $FILE
    done
fi

# start installation
echo "WARN : Please input password if prompted"
# install rustc
echo "INFO : Installing rustc"
sudo "$TMP/rust-""$VERSION""-""$HOST""/install.sh"
# install source files
if [[ -n "$RUST_SRC_PATH" ]]; then
    echo "INFO : Copying source"
    NEWSRC="$RUSTSRC""/rustc-""$VERSION"
    cp "$TMP/rustc-""$VERSION" "$NEWSRC" -rf
    echo "INFO : The new soruce path is $NEWSRC/src"
fi
# install standard libraries
if [[ -n $LIBLIST ]]; then
    for i in ${LIBLIST[@]}; do
        echo "INFO : Installing library for target: ${i}"
        sudo "$TMP/rust-std-""$VERSION""-${i}/install.sh"
    done
fi

# finished
echo "INFO : ALL DONE!"
if [[ -n "$RUST_SRC_PATH" ]]; then
    echo "INFO : Don't forget to change RUST_SRC_PATH to $NEWSRC/src"
fi

It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

1. Bluetooth

Ubuntu can now normally pair with MX Anywhere 2 so you don’t have to care about this kind of stuff. Simply use bluetoothctl or GUI to connect it. But after that, open a console, run

hciconfig hci0 sspmode 1
hciconfig hci0 down
hciconfig hci0 up

otherwise it cannot work correctly. Don’t forget to check your adapter address and replace hci0 if needed.

2. Button Binding

  1. Open a console
  2. Run apt -y install xautomation xbindkeys to install dependencies
  3. Run xev | tee mouse.log and a black box will appear
  4. Move cursor into the black box, press all the function buttons in a certain order (don’t forget it!)
  5. Search mouse.log for ButtonPress and you’ll find the “state” and “button” for each of the buttons

For example,

ButtonPress event, serial 40, synthetic NO, window 0x7800001,
    root 0x1c9, subw 0x0, time 1311199, (71,71), root:(1201,100),
    state 0x10, button 9, same_screen YES

this is the scroll left button and the “state” of it is “0x10” and “button” is “9”

Then, edit ~/.xbindkeysrc to specify the bindings, this is my ~/.xbindkeysrc file:

"xte 'keydown Alt_L' 'key Left' 'keyup Alt_L'"
    m:0x10 + b:6
"xte 'keydown Alt_L' 'key Right' 'keyup Alt_L'"
    m:0x10 + b:7
"xte 'keydown Control_L' 'key F10' 'keyup Control_L'"
    m:0x10 + b:2
"xte 'keydown Alt_L' 'key F1' 'keyup Alt_L'"
    m:0x10 + b:9
"xte 'keydown Control_L' 'key F12' 'keyup Control_L'"
    m:0x10 + b:8

Finally, add /usr/bin/xbindkeys to auto-start program list, this depends on the desktop environment you use.

Refers:
http://askubuntu.com/questions/636712/logitech-mx-anywhere-2-mouse-pairs-but-doesnt-do-anything
https://wiki.archlinux.org/index.php/Xbindkeys
https://bbs.archlinux.org/viewtopic.php?id=119636#p938801

It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

Briefly:

Cause: The names of local and remote branches are not the same
Solution: git push remote_repo HEAD:remote_branch OR (suggested) git config push.default upstream

I’m currently working as an intern developer in an eHealth startup. They’re using the hosts from Aptible to provide their services to customers.

Aptible is generally a Docker (heroku) based hosting and every time when you push the code into a certain Git repository, which is corresponding to a container, Aptible will automatically deploy your new contents. And as we’ve got different environments, such as development, pre-production, production, I have to set up multiple remote repositories so that I can apply different Git branches to different applications.

However, despite of multiple remote repositories, names of remote branches are always “master”. So while pushing, I got

error: src refspec master does not match any.
error: failed to push some refs to 'git@example.com:username/whatever.git'

I Googled the error message and the solutions were all “before pushing, commit something in your EMPTY repository”, which was obviously not the reason of my error. Actually, it was caused by branch names mismatching between local and remote repositories. Rather than git push remote_repo master, git push remote_repo HEAD:master should be used, or simply git config push.default upstream to suppress the name check.

It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

いろいろ躊躇ったけど、ようやく引っ越した、これで少しでも安定になってきた気がする(ブログを書くのもお久しぶり、笑)

新しい住み処は学校からおよそ1.4キロだけので、今なら毎日歩いて通学することができるようになった
それにCBDに近いから、お買い物も大分便利になった。歩いて数分の距離にはクイーンビクトリアマーケットがある。この市場は確か南半球最大の市場であり、お肉も野菜もショッピングセンターよりずっと安い。他のものを買いたいなら、チケット代無しの電車で(フリーゾーンから)CBDのQVショピングセンターにほどなく行ける

今の家賃が安いけど、それに対してこの住宅自体は古くてとても汚いんだ。でもこの値段でNorth Melbourneでより良い場所を探したいなら、やっぱどうしても無理な気がするよね。友人が僕今の部屋に訪ねたことがあるけど、でもやっぱこんな環境に耐えられなくて、それからロードバイクを買って、CBDから3・4キロぐらい離れるエリアで部屋を探し始めた。でも正直といえば、一度今のところの便利さを味わいたら、もうまた遠いところに引っ越す気は全然なくなってきたね。これからバイトするつもりがあるから、給料によって他の場所に引っ越す可能もあるけど、やっぱそれもCBDに限るね

It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

この間MSIのGT72Sを購入したけど、ただ二三日が経ったのにそれである問題に気づいた。

パソコン自体にはWindows 10があったけど、開発のため、僕はKubuntuをインストールした。僕はこの前にずっとCinnamonを利用したから、KDEなんてこれは初めてだった。
いつもKDEのセッテイングがめんどくさいという印象があるけど、今回のKubuntu 15.10はなんと驚くほど使いやすくなってきた。バグはちょっとあるけど、どれも回避しやすい。以前FedoraでCinnamonを使った時に自分で配置しなければいけないことって、KDEであればどれも直接にGUIを通じて設定できる(マウスを使うとき自動的にタッチパッドを無効化するとか)。

それでKubuntuを何日間嬉しく使ったあと、珍しくWindowsに入った時に、パソコンから高周波ノイズが出てしまった。スピーカーやCPUファンのノイズだと思ったけど、スピーカーを無効化してファンの電源ワイヤーを外しても、そのノイズはそのままで消えてなかった。それで耳をパソコンに近づいてよーく聞けば、あのノイズはスピーカーからでもファンからでもなく、CPUの方からのものだと確認した。

MSIのサポートに連絡したら、どうやら他の客からも似たような報告が出た。一時的な解決として、BIOSのAdvanceタブを開けてAlt F2 Ctrl Shift 4つのバタンを同時に押して、それから隠しオプションの「CPU C State」を無効化すればいいんだ。でもこれでおそらくWindowsではCPUの省エネ機能が使えなくなるんでしょう。それにこれってやっぱりちょっと妙な感じがするね、だって僕Linuxの方は「intel_idle.c_state=1」というカーネルパラメータを使ってるし(BIOS設定を無視し、C-Stateを強制的に有効化)。こう見ればLinuxはやっぱり電源マネジメントについてWindowsより器用かもしれない。

ちょっとグーグルしたら、どうやらこの問題はマザーボードのコイルに起こされたようだ。時々あるんだけど、それもそれで珍しい問題らしい。地元のMSIサポートセンターに行ったら、予想通り国内の工場に返品しなければいけない。それに僕のパソコンはアメリカの通販から買ったから、交代を要求したら自腹でアメリカに送るしかない、でもそれでおよそ20000円の配送料をかかる。これはまつしかねーな (TдT)

It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

php-bencode is a PHP Bencode extension which supports encoding, decoding and editing Bencode strings or files. The previous version of php-bencode, which supports PHP 5, needs PHP-CPP to run while the new one now requires no other external libraries.

The location of the source code remains the same, on both GitHub and my personal TsundereGit:
https://github.com/Frederick888/php-bencode
https://git.tsundere.moe/Frederick888/php-bencode

Written in C/C++, php-bencode gives an unbelievable performance boost for manipulations of Bencode. I’ve run a benchmark through different implements by decoding a Bencode file with 1M sub-nodes in my box (8 cores, 1G memory). The sample file can be downloaded here: Bencode Sample.

Obviously, the time needed to decode the same file is shortened dramatically by using php-bencode. The memory usage is a little higher than the pure PHP library with PHP 7 but the object array can give you real data safety rather than a plain array. (For example, if the original Bencode file contains an empty dictionary or list, data loss may be caused after decoding and re-encoding.) What’s more, because the memory usage gap between php-bencode and other pure PHP libraries goes up with the number of nodes, as the Bencode files we usually need to handle contain only less than 1,000 nodes, the gap can be just ignored.

Still, there’s much work to do. The previous version supported to get/set a node by path and search through the whole tree but they have not been implemented in the new one yet. Additionally, the new php-bencode supports only PHP 7 by now and I’m considering to support PHP 5.6 as well.
続きを読む

It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

DSCN0667_size

009

雪の原因で二三日遅れたけど、ようやく無事で配達してくれた。

嬉しいけどこの前の「よるのないくに」はまだクリアしてないから今はちょっと焦ってるね。
「解放の魔印」はなかなか出ないんだ、いろいろ試したけど。

まぁ、こうなったら今は暇がなくなるんだねw

It's only fair to share...Tweet about this on TwitterShare on Google+Share on FacebookShare on TumblrEmail this to someone

昨日久々に自分のGitLabを開けたら、まさか403エラーが起こってしまった。

最近は何の配置をも変更しなかったのに、どうして自分勝手にエラーになってしまうんでしょう。
心当たりというなら、だいたい数日前のLinode Xenシステムアップデートしかあるまい。
でもホストの更新とこっちゲストの方の問題は何の関係もないと思った。

サーバーのログをチェックしたら、こんなのを見つけった:

AH01276: Cannot serve directory /opt/gitlab/embedded/service/gitlab-rails/public/: No matching DirectoryIndex (none) found, and server-generated directory index forbidden by Options directive

それに、この問題はホームページを開ける時にしか起こらなかった。
他のプロジェクトページやユーザーページやには問題がなかった。

配置の問題であれば、一般的には複数のページで問題を起こすべきだ、ただのホームページではない。
それでさきのログをグーグルしたら、やっぱソフト自身のバグだった。詳しいのはApacheのBugzillaに掲載されてる。

一時的な解決として、

a2dismod autoindex

でAutoIndexモジュールを無効化すればいいんだ。
Phusion Passengerは次のリリース(5.0.22)でこの問題を徹底的に解決する予定がある。