X
    Categories: NextCloud

NextCloudで、Shift-JISで保存されたテキストファイルが文字化けする場合の対応方法

NextCloudについてはこれまでも何度か紹介をしてきていますが、今日はTipsを1つ紹介します。

NextCloudでファイルを公開すると、UTF-8で保存されてないテキストファイルは文字化けしてしまいます。

たとえば、

のようにShift-JISで保存されているファイルをNextCloudで開くと、最近最近見かける機会の減った懐かしい文字化けが。

Windows 10のメモ帳のデフォルトのエンコードがUTF-8になったのは、Windows 10 19H1だったような。それ以前からWindowsを使っている方や、特に企業ユースでNextCloudを利用している場合などは、手元のストレージにShift-JIS(ANSI)で保存されたテキストファイルがあることでしょう。

NextCloudでShift-JISのテキストファイルの文字化けを解消する方法

これを解消するTipsを紹介します。文字化けは、「ファイルを表示する際」と「ファイル一覧でのサムネイル表示(プレビュー)」の2か所で発生します。それぞれの対応方法を紹介します。

ファイル表示での文字化け回避

NextCloudでは、ブラウザ上でテキストファイルを表示する際に、NextCloud内ではその名もずばりtext アプリが表示処理を担っています。

このtextアプリのファイル処理に、Shit-JISのエンコードの場合の処理を追加してあげることで、文字化けを防ぐことができます。

NextCloudのインストールディレクトリ/apps/text/lib/Service/ApiService.php の以下の部分、118行目にある

public function fetch($documentId, $sessionId, $sessionToken) {
                if ($this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) {
                        $this->sessionService->removeInactiveSessions($documentId);
                        try {
                                $file = $this->documentService->getBaseFile($documentId);
                        } catch (NotFoundException $e) {
                                return new NotFoundResponse();
                        }
                        return new FileDisplayResponse($file, 200, ['Content-Type' => 'text/plain']);
                }
                return new NotFoundResponse();
        }

FileDisplayResponse関数の前に、UTF-8へのエンコード変換処理を加えます。


public function fetch($documentId, $sessionId, $sessionToken) {
                if ($this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) {
                        $this->sessionService->removeInactiveSessions($documentId);
                        try {
                                $file = $this->documentService->getBaseFile($documentId);
                        } catch (NotFoundException $e) {
                                return new NotFoundResponse();
                        }
//以下を追加
                        $fileContents=$file->getContent();
                        $encoding = mb_detect_encoding($fileContents . 'a', 'SJIS-win, UTF-8, WINDOWS-1252, ISO-8859-15, ISO-8859-1, ASCII', true);
                        if ($encoding === '') {
                               $encoding = 'ISO-8859-1';
                                              }
                        $fileContents = iconv($encoding, 'UTF-8', $fileContents);
                        $file->putContent($fileContents );
//ここまで
                        return new FileDisplayResponse($file, 200, ['Content-Type' => 'text/plain']);
                }
                return new NotFoundResponse();
     }

この追記をしてapacheを再起動すると、

御覧の通り、無事正しく表示されるようになりました。

表示されない場合は、キャッシュが悪さしていると思いますのでお使いのブラウザで強制リロードするかキャッシュを削除してください。

ファイル一覧でのサムネイル表示(プレビュー)での文字化け回避

テキストファイルのプレビュー表示は、preview/TXT.phpが担っています。

NextCloudがインストールされたディレクトリ/lib/private/Preview/TXT.phpを開きます。

サムネイル表示を処理しているgetThumnail関数の68行目の前に、以下のように文字コード変換の処理を追加します。

       public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {

                $content = $file->fopen('r');


                if ($content === false) {
                        return null;
                }

                $content = stream_get_contents($content,3000);

                //don't create previews of empty text files
                if (trim($content) === '') {
                        return null;
                }

//以下を追加
                $encoding = mb_detect_encoding($content . 'a', 'SJIS-win, UTF-8, WINDOWS-1252, ISO-8859-15, ISO-8859-1, ASCII', true);
                        if ($encoding === '') {
                               $encoding = 'ISO-8859-1';
                                              }
                        $content = iconv($encoding, 'UTF-8', $content);
//ここまで

                $lines = preg_split("/\r\n|\n|\r/", $content);

加えて、NextCloudに同梱されているフォントは日本語が含まれていないため、日本語を含むフォントファイルに置き換えます。手順はほかのブログで紹介されているので、詳細は以下を参照ください。

プレビュー自体を無効にするには

NextCloudでのファイルプレビューを無効にする方法もあります。

config.phpに

  'enable_previews' => false,

を1行追加することで、ファイルのサムネイル表示が無効になります。

謝辞

この追加した部分は、以前のNextCloudでテキストファイルの表示を担っていた、files_texteditorで文字化けしていた際の対応方法と、Githubでの中国語の文字化けするIssueを参考にさせてもらいました。

同じように悩む方に、この情報が役に立ちましたら幸いです。(ほしいものリスト置いておきます)

ださっち: