Paepoi

Paepoi » Gjs Tips » GLib(Gjs) Tips

GLib(Gjs) Tips

# 最終更新日 2023.11.19

ユーザーディレクトリ
~/.config/user-dirs.dirs で指定されたディレクトリ名を取得
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

const dirs = {
    Desktop: GLib.UserDirectory.DIRECTORY_DESKTOP,
    Documents: GLib.UserDirectory.DIRECTORY_DOCUMENTS,
    Download: GLib.UserDirectory.DIRECTORY_DOWNLOAD,
    Music: GLib.UserDirectory.DIRECTORY_MUSIC,
    Pictures: GLib.UserDirectory.DIRECTORY_PICTURES,
    Public: GLib.UserDirectory.DIRECTORY_PUBLIC_SHARE,
    Templates: GLib.UserDirectory.DIRECTORY_TEMPLATES,
    Videos: GLib.UserDirectory.DIRECTORY_VIDEOS 
}
for (let key in dirs) {
    let value = GLib.get_user_special_dir(dirs[key]);
    print(`${key}: ${value}`);
}

システムディレクトリ
カレントディレクトリや一時ファイルディレクトリ等を得る
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

print(GLib.get_current_dir()); // 現在のカレントディレクトリ
print(GLib.get_home_dir()); // ホームディレクトリ
/* その他
get_system_config_dirs
get_system_data_dirs
get_tmp_dir
get_user_cache_dir
get_user_config_dir
get_user_data_dir
get_user_name
get_user_runtime_dir
*/

環境変数
JavaScript 基本機能には無いので GLib に頼る
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

GLib.setenv('HOGE', 'hogehoge', false); // 環境変数のセット
print(GLib.getenv('HOGE')); // 環境変数の取り出し
for (let key of GLib.listenv()) {
    print(`${key}=${GLib.getenv(key)}`); // 環境変数の一覧
}

ファイルとディレクトリ
cp や mv を行うには Gio を使う、Gio を使うまでもない単純作業用
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

const DIRNAME = '日本語ディレクトリ';
const FILENAME = '日本語ファイル名.txt';
const CONTENTS = `一行目
に行目
3行目`;

// mkdir コマンド、8 進数表記は 0o*)
GLib.mkdir_with_parents(DIRNAME, 0o755);

// test コマンド、ディレクトリが存在しているか調べる
if (GLib.file_test(DIRNAME, GLib.FileTest.IS_DIR)) {
    print(`${DIRNAME} ディレクトリを作成しました`);
}

// cd コマンド、カレントディレクトリの移動
print('入ります');
GLib.chdir(DIRNAME);

// pwd、現在のカレントディレクトリを標準出力に吐き出す
print(GLib.get_current_dir());

// リダイレクト、JavaScript 文字列のままでも UTF-8 で出力される
GLib.file_set_contents(FILENAME, CONTENTS);

// 存在確認
if (GLib.access(FILENAME, 0o755)) {
    print(`${FILENAME} ファイルを作成しました`);
}

// ドットを使った特殊ディレクトリも対応
print('出ます');
GLib.chdir('..');
print(GLib.get_current_dir());

ファイル名リストの数値優先ソート
ようするに Nautilis の並び順と同じ数値優先ソート
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

const l = [
'40.txt',
'200.txt',
'001.txt',
'2.txt',
'03.txt',
'123456.txt'];

l.sort( (str1, str2)=> {
    let cmpstr1 = GLib.utf8_collate_key_for_filename(str1, -1);
    let cmpstr2 = GLib.utf8_collate_key_for_filename(str2, -1);
    if (cmpstr1 < cmpstr2)
        return -1;
    return 1;
});
for (let s of l) print(s);

コマンドの実行、コマンド出力を得る
コマンド出力は Uint8Array で戻ることに注意
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

/**
 * コマンド出力不要なら、たとえば totem の起動等
 */
GLib.spawn_command_line_async('totem');

/**
 * output にstdout、error に stderr が入る
 * 出力結果は Uint8Array なので変換が必要
 * 存在しないコマンドでは例外になるが try catch では捕まえられない
 */
let [result, output, error, status] = GLib.spawn_command_line_sync('ls -l');
if (status == 0) {
    let dec = new TextDecoder();
    let text = dec.decode(output);
    print(text);
} else {
    print(`stderr\n${error}`); // ココには来ないかも
}

ファイル名ユーティリティ
このコマンドでは実在の有無は関係ありません
#!/usr/bin/gjs -m
 
import GLib from 'gi://GLib';
 
const s = '/home/sasakima-nao/OM SYSTEM/OM-1 とパナライカ.jpg';
  
// ディレクトリ名
print(GLib.path_get_dirname(s));
//=> /home/sasakima-nao/OM SYSTEM
 
// ファイル名のみ
print(GLib.path_get_basename(s));
//=> OM-1 とパナライカ.jpg
 
// 絶対パスチェック
print(GLib.path_is_absolute(s));
//=> true
 
// フルパス作成(区切り文字の有無を自動調節)
print(GLib.build_filenamev(['/home/sasakima-nao/', '/H な画像', 'ヒヨドリ.jpg']));
//=> /home/sasakima-nao/H な画像/ヒヨドリ.jpg
URI 変換
このコマンドも実在の有無は関係ありません
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

// スキーム取得、実在は関係ないようだ
let scheme = GLib.uri_parse_scheme('hoge://fuga.jp/');
print(scheme);
//=> hoge

// 第 3 引数を true にすると Unicode ドメイン対応になる
let uri = GLib.uri_escape_string('日本語blog.jp', null, false);
print(uri);
//=> %E6%97%A5%E6%9C%AC%E8%AA%9Eblog.jp

// 文字列に戻す
let txt = GLib.uri_unescape_string(uri, null);
print(txt);
//=> 日本語blog.jp

// パス名を URI に、ローカル(同一パソコン内)のファイルならホスト名は不要
uri = GLib.filename_to_uri('/home/sasakima-nao/コゲラ.jpg', null);
print(uri);
//=> file:///home/sasakima-nao/%E3%82%B3%E3%82%B2%E3%83%A9.jpg

// 文字列に戻す
let [pathName, hostName] = GLib.filename_from_uri(uri);
print(pathName);
//=> /home/sasakima-nao/コゲラ.jpg

リダイレクト
echo ほげ > gjs_write.txt ; cat < gjs_write.txt
と同様なリダイレクトです。
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

const FILE = 'gjs_write.txt';
const TEXT = `出力では JavaScript 文字列のままイケます
入力は Uint8Array になりますので以下のように`;

let result = GLib.file_set_contents(FILE, TEXT); // Write
if (result) {
    print('Write Success');
}
let [result2, contents] = GLib.file_get_contents(FILE); // Read
if (result2) {
    let dec = new TextDecoder();
    let text = dec.decode(contents);
    print(text);
}

タイマー
timeout_add は g_timeout_add_full にバインドされているので注意
timeout_add(priority: Number(gint), interval: Number(guint), function)
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

let count = 0;
let mainloop = new GLib.MainLoop(null, false);

GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, ()=> {
    if (count === 10) {
        mainloop.quit();
        return false;
    }
    print(count++);
    // true を戻すと継続
    return true;
});
mainloop.run();

日付けと時刻
JavaScript の Date を使ったほうがいいと思うけど GLib でも可能
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

let datetime = GLib.DateTime.new_now_local();
print(datetime.format("日付 %Y年%m月%d日\n時刻 %H:%M:%S"));

文字コード(cp932, utf8)変換
何度も書きますが Windows の文字コードは CP932 です、Shift-JIS ではありません
iconv -l コマンドで出力される文字コードはすべて双方向で変換できます
#!/usr/bin/gjs -m

import GLib from 'gi://GLib';

let [result2, contents] = GLib.file_get_contents('txt932.txt'); // Read
let [u8arr, br, bw] = GLib.convert(contents, 'UTF-8', 'CP932');
let dec = new TextDecoder();
let text = dec.decode(u8arr);
print(ByteArray.toString(text));

Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.