読者です 読者をやめる 読者になる 読者になる

HRR Co., Ltd.

技術的な記録を残していくことを目的としています。そのうち関係ないことを書き出しそう。

文字列の省略 +「…」をTwigでやるには?

どういうこと?

要は長い文字列に対して、例えば15文字で切って、その後を「…」で省略する。
というのがやりたいことです。

CSSのtext-overflowでもできますが、そちらはwidthを指定するもので、文字の長さの指定ではありません。

やりかた

15文字で区切りたかったら…

{{ target.name|length > 15 ? target.name|slice(0, 15) ~ '…' : target.name }}

ただ、sliceの実装はTwig 1.6からになるので要注意です。
「自分のSymfonyに入ってるTwigのバージョンはいくつなんだろう?」
と思われた方は…

// vendor/twig/twig/lib/Twig/Environment.php

/**
 * Stores the Twig configuration.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Twig_Environment
{
    const VERSION = '1.24.0';

ここに書いてあります。
最近のSymfonyだと、場所が変わっていたりして…。

短いですが、以上でした!

サポート対象バージョンの調査

はじめに

セキュリティの観点から、Webサービスに使用しているアプリケーションのサポートバージョンを調査する必要性に駆られました。
私はいわゆるLAMP環境で作られたWebサイトを扱っておりますので、対象はそれに付随するものとなります。

きちんとしたページが用意されているところもあれば、ないところもあり…
様々でした。

対象

Apache, MySQL, PHP, Symfony
この4つだけです。

調査結果

Apache

Welcome! - The Apache HTTP Server Project

きちんとしたページはないですが…
よくよく見ると、「Apache httpd 2.2.32 Released」のところに書いてあります。

2.2.x 
maintenance releases: June of 2017
security patches    : December of 2017

今年の12月までですね…。
2.4.xについては、特に期限は書いていないようです。

MySQL

MySQL :: MySQL テクニカル・サポート

http://www.oracle.com/jp/support/library/lifetime-support-technology-069183.pdf?ssSourceSiteId=ocomjp

MySQLはPDFファイルです…
資料の19ページ目に、MySQLについて書いてあります。

5.7: 2020年10月
5.6: 2018年 2月
5.5: 2015年12月
5.1: 2013年12月
5.0: 2011年12月

PHP

PHP: Supported Versions

PHPはきちんとしたページがあります。
セキュリティサポートの期限は、下記のとおりです。

5.6: 31 Dec 2018
7.0:  3 Dec 2018
7.1:  1 Dec 2019

Symfony

Symfony roadmap, notifications and release checker

Symfonyも専用のページがあります。
下の方にいくと、「Symfony version checker」なるものまであります。

まとまったものが見たいなら、Wikipediaの方がいいかも…
ただし、調べるからには一次情報をみたいものですよね。

Symfony - Wikipedia

2.7: 2019年5月
2.8: 2019年11月
3.4: 2021年11月
※現在生きている長期サポート版だけを抜粋
※3.4は2017年11月にリリースですけど…

おわりに

本日時点のものを書き出してみましたが、当然変わる可能性があります。
最新版につきましては、必ず一次情報を参照するようにお願い致します。

以上でした!

JSON整形ツール?を作りました

はじめに

整形されていないJSON形式の文字列を整形するツールです。
Webサイトで公開されているものが多々ありますが、入力情報を取得されていたら困ります。

そこで、ローカルで同じことができるものを作成しました。
「JsonFormatter.html」とでも名前をつけて、ローカルに保存してお使いください。

ただし、CDNを使用してるため、通信は発生しているという中途半端さがあります…。

内容はこちら

・エラー処理はしていないので、お好みで変更してください。
・インデントは半角スペース4つです。これもお好みで変更してください。
・CDNを使用してるため、通信は発生します…。

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>Json Formatter</title>
        <script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <script type="text/javascript">
        <!--
            $(function() {
                var sampleText = '{"id":12345,"code":10,"detail":{"name":"Foobar","size":"50.00"}}';
                $('#input-area').val(sampleText);

                $('#formatter').on('click', function() {
                    var inputData = $('#input-area').val();
                    try {
                        var jsonBefore = JSON.parse(inputData);
                    } catch(e) {
                        return false;
                    }
                    var outputData = JSON.stringify(jsonBefore, null, "    ")
                    $('#output-area').val(outputData);
                });
            });
        // -->
        </script>
    </head>
    <body>
        <div class="col-md-2"></div>
        <div class="col-md-8">
            <textarea class="form-control" id="input-area" rows="10"></textarea>
            <button id="formatter" class="btn btn-primary btn-lg">Format</button>
            <textarea class="form-control" id="output-area" rows="20"></textarea>
        </div>
        <div class="col-md-2"></div>
    </body>
</html>

見た目はこんな感じ

f:id:hrroct:20170316123411p:plain

シンプルですが、使えればいいということで(;´∀`)

以上でした!

lsの実行結果をforでくるくる on Bash

はじめに

たまにBashスクリプトを書くときがあるのですが、毎回のように忘れるんですよね…。
例えば、配列の扱いやfor文の書き方など。

そこで今回は「lsの実行結果をforでくるくる」についてのメモを残すことにしました。

ソースコード

lsの実行結果を配列にして、forでくるくる

array=($(ls /home/${USER}/work))

for eachValue in ${array[@]}; do
    echo ${eachValue}
done

解説

コマンド実行について

`(バッククォート)で囲む方法もありますが、入れ子にできないのもあって私は$()を多用します。
その実行結果を()で囲むことにより、配列としています。

配列について

Bashの配列はこんなふうに()にスペース区切りになっています。

fruits=(apple orange banana)

lsコマンドを打つことで、自然とスペース区切りの文字列ができあがり、それを()で囲むことで配列としています。

for文と配列の展開

${array[@]}は配列の中身を展開するものです。

fruits=(apple orange banana)
echo ${fruits[@]}

# 出力:
# apple orange banana

なので、こんなふうに書いてもOK

for eachValue in apple orange banana; do
    echo ${eachValue}
done

# 出力:
# apple
# orange
# banana

${array[*]}っていうのもあるよね?

${array[*]}についても同じ、というような書き方をたまに見ますが、違いは明確にあります。
"(ダブルクォート)で囲まれたときに違いが出ます。

IFS=',|*'
fruits=(apple orange banana)
echo "${fruits[@]}"
echo "${fruits[*]}"

# 出力:
# apple orange banana
# apple,orange,banana

IFSの最初の1文字目が区切り文字として使われるんですね。
詳細はman bashをご参照ください。

最後に

Bashネタは今後も投稿すると思います。
今回は以上でした。

画像にある数字を抽出したい

はじめに

タイトル通りですが…そういうニーズが発生しました。
画像をいちいち目で確認していくのは、大変な労力がかかります…。

この手のことは、やはりPythonでやるものではないか?という先入観の元、調べていたのですが…。
TesseractというOCR (Optical Character Recognition/Reader、光学的文字認識) エンジンがあるとのことで、まずそれを試してみることに。
日本語で書くと「テッセラクト」ですかね。

環境はWindows7Cygwinを使用しております。

まずはインストール

こちらを参考にしております。
github.com

まずはapt-cygにて検索をかけます。

$ apt-cyg searchall tesseract
libtesseract-ocr_3
tesseract-ocr-deu
tesseract-ocr-devel
tesseract-ocr-eng
tesseract-ocr-fra
tesseract-ocr-ita
tesseract-ocr-nld
tesseract-ocr-por
tesseract-ocr-spa
tesseract-ocr-vie
tesseract-ocr
tesseract-training-core
tesseract-training-deu
tesseract-training-eng
tesseract-training-fra
tesseract-training-ita
tesseract-training-nld
tesseract-training-por
tesseract-training-spa
tesseract-training-util
tesseract-training-vie

すると出てきますね…ぞろぞろと。
メインどころであろう、下記パッケージをインストールしてみます。

$ apt-cyg install tesseract-ocr

すると長いログが出る出る…依存性のあるパッケージが次々とインストールされているようです。
整理してみると、こんな感じでした。
cygwinは抜いてます。
※一部再帰的になっていますが気にしない方向で。

tesseract-ocr
├ libgcc1
├ libleptonica_5
│ ├ libgif4
│ │ └ libX11_6
│ │    └ libxcb1
│ │       ├ libXau6
│ │       └ libXdmcp6
│ ├ libjpeg8
│ ├ libpng16
│ │ └ zlib0
│ ├ libtiff6
│ │ ├ libjbig2
│ │ ├ libjpeg8
│ │ ├ liblzma5
│ │ ├ libstdc++6
│ │ └ zlib0
│ ├ libwebp5
│ └ zlib0
├ libstdc++6
├ libtesseract-ocr_3
│ ├ libgcc1
│ ├ libleptonica_5
│ └ libstdc++6
└ tesseract-ocr-eng
   └ tesseract-ocr

これを見る感じ、画像形式はjpg, gif, png, tiffには対応できていそう。
言語パッケージはデフォルトは英語だけみたいですね。
バージョン情報を確認してみます。

$ tesseract --version
tesseract 3.04.01
 leptonica-1.73
  libgif 4.1.6(?) : libjpeg 8d (libjpeg-turbo 1.4.2) : libpng 1.6.24 : libtiff 4.0.6 : zlib 1.2.8 : libwebp 0.4.4

うん、入ってますね。

実際に使ってみる

というわけで、実際にお試しです。
適当にペイントソフトで作成した画像で、コマンドを叩いてみます。

f:id:hrroct:20170124170206p:plain

コマンドはWikiにもある通りです。

tesseract imagename outputbase [-l lang] [-psm pagesegmode] [configfile...]

・第一引数:画像
・第二引数:出力ファイル名
を最低限渡せばよさそうです。

$ tesseract NumberImage.png out
Tesseract Open Source OCR Engine v3.04.01 with Leptonica
Error in pixGenHalftoneMask: pix too small: w = 197, h = 76
$
$ cat out.txt
49612

読み取れてるー!!
エラーが出てきますが、画像の解像度(幅、高さ(px))が低い場合に出るようです。
github.com

まとめ

というわけで、あっさり画像認識ができました。
でも実際の写真に含まれる数字を抽出しようとすると…。

うまくいきません(´・ω・`)
(出力先のテキストが空っぽ…)
時間ができたら、もう少し戦ってみることにします。

Seleniumbasicで突如Google Chromeが開けなくなったら…

どうするか?

…ドライバを更新しましょう、という話です。

そもそもな話

Seleniumbasicとは何か?

florentbr.github.io

Seleniumはいろんな言語で使えるように横展開されています。
それのVB.NetVBAVBScript版になります。

経緯

久しぶりに Seleniumbasic でGoogle Chromeを開く処理を行ったんですが…

f:id:hrroct:20161208142719p:plain

というエラーが出ます。
はて。
プログラムは変えていないのに、なぜかエラーが出る。
IEなら問題なく開くのになぜ?

原因はドライバが古いこと、でした

Seleniumbasicのインストール先ディレクトリを見るとわかるのですが、「***driver.exe」というファイルがいくつかあります。
ブラウザはこれを使用して起動しているんですね。

私の場合はこちらでした。
「C:\Program Files\SeleniumBasic」

Chromeのドライバもこちらにあるので、ダウンロードして置き換えましょう(以前のものはリネームする方がいいかも)。
「chromedriver.exe」という名前のファイルです。

取得先はこちら:

sites.google.com

更新すると…

元気にまた動いてくれました。
よかった…。

以上でした。

Chosenプラグインの使い方(基礎編2)

はじめに

Chosenプラグインネタ、第2弾です。
次は「発展編」とするはずが、複数選択時の場合が抜けていたので、それをまず書きます。

第1弾はこちら:
hrroct.hatenablog.com

忘れていた、複数選択の場合

サンプルはこちら。
Edit fiddle - JSFiddle

jQuery 3.1.1
Chosen 1.6.2
を使用しております。

ベース

multiple属性とdata-placeholder属性が指定されているのが、単一選択時との違いです。

<select id="target" data-placeholder="Choose Some Items..." multiple>
    <option></option>
    <option value="1">1st Option</option>
    <option value="2">2nd Option</option>
    ...

選択された値を取得する

配列で取得するように揃えてみました。

// 配列で返ります
var valueList = $('#target').val();

// こちらも配列で取得してみる
var textList = [];
$('#target option:selected').each(function() {
    textList.push($(this).text());
});

値をセットする

セットする値を配列で与えればOKです。

// Chosenのバージョンが低い場合は'liszt:updated'で
$('#target').val([5,6]).trigger('chosen:updated');

値をクリアする

こちらも配列で指定します。空の配列ですね。

// Chosenのバージョンが低い場合は'liszt:updated'で
$('#target').val([]).trigger('chosen:updated');

選択肢を追加する

これは単一選択時と変わらないですね。

// Chosenのバージョンが低い場合は'liszt:updated'で
var newOption = $('<option>').attr('value', 15).text('15th Option');
$('#target').append(newOption).trigger('chosen:updated');

有効化、無効化

これも単一選択時と変わらないですね。

// Chosenのバージョンが低い場合は'liszt:updated'で
// 無効化
$('#target').prop('disabled', true).trigger('chosen:updated');
// 有効化
$('#target').prop('disabled', false).trigger('chosen:updated');

以上でした!