Quantcast
Channel: ソフラボの技術ブログ
Viewing all 166 articles
Browse latest View live

WiMAX2+を7GB/月制限なしで使うには2月19日までに申し込みを!!

$
0
0

f:id:shinsuke789:20150112171455p:plain

2015年1月30日よりWiMAX2+のキャリアアグリゲーション対応端末が発売されました。
WiMAX2+で220Mbps対応の端末が発表されました - Webサービスで起業を目指すプログラマーblog

キャリアアグリゲーションサービスの開始時期

このサービスは、2月20日から新プランとともに開始されます。

新プランになると、7GB/月制限のプランと無制限のプランの2種類が選択できるようになります。
無制限になると月制限ありのプランに比べ約700円値上げになります。

WiMAX2+を「月制限なし」で使うには?

キャリアアグリゲーションサービスが開始される直前の2月19日までにWiMAX2+を契約すれば、月制限なしで2年間使用することができます。
固定回線として使われる方には、ぜひこの期間に契約することをおすすめします。

私も固定回線として使っていて、制限があると困るので新規でWiMAX2+を契約しました。
現在契約しているWiMAXは更新月まで4ヶ月残っていますが、解約してしまうと特典がもらえないので、そのまま契約しています。

「制限」の注意点

月の制限がなしといっても、3GB/3日の制限があります。
この場合の速度は700Kbpsになると言われていますが、緩い制限と思われます。
2月19日までは1GB/3日なので特に注意が必要です。

下り220Mbps対応新端末「W01」で最安なプロバイダー

調査すると「GMOとくとくBB」でした。
私もここで契約しました。
GMOとくとくBB WiMAX2+ 月額3,609円

f:id:shinsuke789:20150208074151j:plain

端末W01
初月無料1ヶ月目
月額3,609円
4,175円
2〜24ヶ月目
25ヶ月目
キャッシュバック27,390円クレードルなし
実質月額2,439円

旧端末の在庫処分セールが始まる!?

2月19日の1週間前あたりまたはその後に、キャリアアグリゲーション非対応端末(HWD15、NAD11)の在庫処分が始まるのではと予測します。

非対応端末だと月額料金が安かったり、キャッシュバック額が多かったりします。
費用を抑えてWiMAX2+を利用したいなら非対応端末もおすすめです。

キャリアアグリゲーション対応で下りが最大220Mbpsで使用できるのですが、非対応でも下り最大110bpsで使えるので速度的には十分だと思います。
実際に使っている方に聞くとWiMAXより速いと言ってました。

旧端末「NAD11」で最安なプロバイダー

調査すると新端末と同じく「GMOとくとくBB」でした。
GMOとくとくBB WiMAX2+ 月額3,609円

f:id:shinsuke789:20150208074242j:plain

端末NAD11
初月無料1ヶ月目
月額3,609円
4,175円
2〜24ヶ月目
25ヶ月目
キャッシュバック29,000円クレードルなし
実質月額2,377円

旧端末「HWD15」で最安なプロバイダー

調査すると「Racoupon」でした。
RaCoupon WiMAX

f:id:shinsuke789:20150208074251j:plain

端末HWD15
初月2,312円1ヶ月目
月額2,312円
3,772円
2〜23ヶ月目
24~25ヶ月目
キャッシュバックなし
実質月額2,424円

プログラミング言語別、正規表現チェッカーまとめ

$
0
0

WiMAX2+の新端末「W01」を使ってみての感想

$
0
0

WiMAX2+が2月19日までなら無制限で使えるということでGMOとくとくBBで新端末「W01」を契約しました。

WiMAX2+を申し込んだ理由

現在So-netWiMAXを1年契約で使っています。
WiMAX2+の新サービスが開始すると制限がかかる、WiMAXの速度が低下するというのを聞いていました。


子供がときどきYoutubeで動画を見ることがあって、7GB/月制限があるとすぐに制限にかかってしまい、128Kbpsになるとネットが出来ないに等しいのでそれは厳しいと思っていました。


現在契約しているWiMAXの更新月は、2015年5月でまだ期間はあるのですが、WiMAXを固定回線として使っているので、制限がかかるのはマズイということで、2月に入ってからすぐにWiMAX2+を契約しました。

GMOとくとくBB WiMAX2+ 月額3,609円

開封レビュー

端末のW01は白を選んだので、箱はグレーで暗い感じでした。
f:id:shinsuke789:20150211193551j:plain


WiMAX2+からSIMカードを使用するようになりました
f:id:shinsuke789:20150211193705j:plain


端末は結構大きく感じます。簡易的な液晶保護フィルムが最初から貼られています。
f:id:shinsuke789:20150215171947j:plain


端末にSIMカードを挿して電源を入れます。
f:id:shinsuke789:20150215172001j:plain


電源を入れた後の時計表示。
f:id:shinsuke789:20150215172336j:plain


ホーム画面。
f:id:shinsuke789:20150215172345j:plain


設定画面。縦にスクロールします。
f:id:shinsuke789:20150215172408j:plain

端末が届いたけど圏外!?

申し込んでから、1週間ほどで端末が届きました。


WiMAX2+からSIMカードを挿すようになっていたのでそれを行いました。
いつもながら電源を入れるだけで繋がると思っていたので、電源を入れましたがなぜか圏外の表示でした。
「制限かからないから契約したのになんで圏外?マジかよ…」と思い、若干冷や汗が出ました。


説明書を見ると「プロバイダーからの接続情報を設定する」と書いており、なんかおかしいなーと思いながらも操作をしてみました。でも、すでに接続設定はされていました。
そもそも、WiMAXは端末が届いたらすぐに使えるようになっているはずなのに…。


公式サイトでエリアを確認すると、エリア内でした。
そりゃそうだ。それを確認して申し込んだのだから繋がるはず。


ひょっとすると、家の中だと電波を掴みにくいのかなと思って、電波を掴むまで外に出ていました。
すると電波を掴んで通信が出来る状態となったので、家の中に入ると見事に繋がりました!

端末の使い勝手

タッチパネルになっていてスマホと同じ感覚で操作できます。
メニューが多いのでどこに何があるかわかりにくいと思いました。


無線LANで5GHz帯が使用できます。
2.4GHz帯で使っていると電子レンジ等と電波干渉しやすいので、そういう場所で使う場合は5GHzを使うと電波干渉がなくなります。
ただ、5GHz帯は気象レーダーと電波周波数が被っている所があるので、接続前にチェック処理が1分かかります。
電源を入れるたびに発生するので、その点が使い勝手が悪いと感じました。

WiMAX2+の速度

家の中のいろんな場所で速度測定してみました。

測定環境

使用サイトhttp://www.speedtest.net/
使用端末iPad mini 2 Retina
無線2.4GHz
時間帯日曜日の17時頃

測定場所

場所電波表示(4段階)下り上り
1Fリビング(家の中心部)2本3.85M0.28M
1Fリビング(窓際)2本2.29M0.08M
1Fリビング(窓際から2m離す)3本7.60M0.18M
1F-2F階段踊り場窓際3本12.64M3.04M
2F窓際3本6.21M0.30M

※環境によっていろいろ変わりますのであくまで参考程度にして下さい。


先ほど測定すると、いつもより遅い感じでした。
端末が届いてからの測定の結果をまとめると、下り2M〜43M、上り0.01M〜5Mの幅でした。
WiMAXの電波特性なのか、結構不安定でムラがあります。
WiMAXと比べるとムラがあっても、最低速度が速いので遅いと感じることはなくなりました。


体感的にはかなり速く、最近のWiMAXのようにダイヤルアップ並にカクカク表示されるというのはないです。
下りは5M以上は出ているような感じで、速い時は30M以上出ているので非常に満足です。
制限がないと調子に乗っていると3GB/3日に引っかかるかもしれないので注意が必要です。
3GB/3日制限は、2015年4月以降にかかるようです。


上りは、公称値10Mなので仕方ないかもしれないですが、10K台では遅すぎです。
初速は1M以上でているようなので、軽いものだと問題ないかもしれません。
しかし、写真等アップロードすることが多い方は、Y!モバイルや光ファイバーにした方がいいかもしれません。


普通に使う分にはWiMAX2+で十分です。
速度的には十分速いので、工事が必要で開通まで1ヶ月ほど必要な光ファイバーを契約するより、工事不要で家でも外でおm使えるWiMAXの方が気楽でいいです。

気になること

電源を切って半日以上おいて、再度電源をいれると完全に電源が切れた状態から起動するみたいで、起動に少しだけ時間がかかります。
その時に限って必ず圏外表示になって繋がりません。
端末の画面に時計が表示されなかったらおかしいと思ってもいいです。
また充電が終わった後も同じ現象が発生します。


こうなったときは、外に出たり電波を掴みやすい所に移動して圏外を脱して下さい。
その後は、完全電源オフまたは充電後以外は、すぐに起動し電波も普通に掴みます。

PhantomJSをCentOSでビルドしたらエラーが出てインストールできない

$
0
0

既存のサイトからデータを取得して欲しいという要望があったので、PhantomJSを使ってプログラムからブラウザを操作し、スクレイピングすることを最近行っています。

Macにはすんなりインストールできて、プログラムもある程度出来上がったのでサーバーにもインストールして動作確認をしてみようと、PhantomJSをインストールしてみたけどエラーが出てインストールが完了しませんでした。

その時のエラー内容を記載しておきます。
まだきっちり調べてませんが、他の人も問題に上げているようで解決方法がはっきりしていないように感じます。

環境

CentOS6.4
PhantomJS1.9 or 2.0

PhantomJSのインストール方法

Linux用バイナリにはまだ問題があるようで、ソースからのインストールを推奨すると公式サイトには書いてあります。

Binary packages for Linux are still being prepared. There are still issues to be solved until a static build is available (see issue 12948 for more details).

In the mean time, it is recommended to build the Linux version from source.

バイナリの代わりにソースからインストールする方法も書かれているので、それに従ってインストールします。
Build | PhantomJS


まず必要なパッケージをyumでインストールします。

sudo yum -yinstall gcc gcc-c++ make flex bison gperf ruby \
  openssl-devel freetype-devel fontconfig-devel libicu-devel sqlite-devel \
  libpng-devel libjpeg-devel


その後、PhantomJSのソースをGitから取得しビルドします。

cd /usr/local/src
git clone git://github.com/ariya/phantomjs.git
cd phantomjs
git checkout 2.0
./build.sh

PhantomJS2.0をビルドした結果

2.0でビルドすると次のエラーが発生し、インストールに失敗します。
最終あたりのログを抜粋しています。

Encountered 4 configuration warning(s):

 ! QtQuick module not found, QML APIs will not be built
 ! Missing GStreamer or QtMultimedia, disabling HTML5 media element support
 ! Missing QtTest module, disabling DumpRenderTree, WebKitTestRunner and tests
 ! QtWebKitQml will not be build. It is not supported with static linking

The WebKit build was disabled for the following reasons: 
    * Missing gperf from PATH
    * Missing ruby from PATH 

make: `first'に対して行うべき事はありません.Building main PhantomJS application...cd src/ && ( test -e Makefile.phantomjs || /usr/local/src/phantomjs/src/qt/qtbase/bin/qmake /usr/local/src/phantomjs/src/phantomjs.pro -o Makefile.phantomjs ) && make -f Makefile.phantomjs Project ERROR: Unknown module(s) in QT: webkitwidgetsmake: *** [sub-src-phantomjs-pro-make_first-ordered] エラー 3

PhantomJS1.9をビルドした結果

2.0では失敗するので1.9でやればうまくいくと書かれているものがあったので、やってみたけどこれも失敗します。

# /usr/local/src/phantomjsで
git checkout 1.9
./build.sh


最終あたりのログを抜粋しています。

g++ -m64-Wl,-O1 -Wl,-rpath,/usr/local/src/phantomjs/src/qt/lib -o ../bin/phantomjs phantom.o callback.o webpage.o webserver.o main.o csconverter.o utils.o networkaccessmanager.o cookiejar.o filesystem.o system.o env.o terminal.o encoding.o config.o childprocess.o repl.o gif_err.o gifalloc.o egif_lib.o gif_hash.o quantize.o gifwriter.o mongoose.o linenoise.o utf8.o qcommandline.o minidump_file_writer.o convert_UTF.o md5.o string_conversion.o crash_generation_client.o exception_handler.o log.o linux_dumper.o linux_ptrace_dumper.o minidump_writer.o file_id.o guid_creator.o memory_mapped_file.o safe_readlink.o moc_phantom.o moc_callback.o moc_webpage.o moc_webserver.o moc_networkaccessmanager.o moc_cookiejar.o moc_filesystem.o moc_system.o moc_env.o moc_config.o moc_childprocess.o moc_repl.o moc_qcommandline.o qrc_phantomjs.o qrc_ghostdriver.o qrc_WebKit.o qrc_InspectorBackendStub.o    -L/usr/local/src/phantomjs/src/qt/lib -L/usr/local/src/phantomjs/src/qt/plugins/codecs -lqcncodecs-L/usr/local/src/phantomjs/src/qt/lib -lqjpcodecs-lqkrcodecs-lqtwcodecs-lQtWebKit-lQtGui-lfreetype-lfontconfig-lQtNetwork-lQtCore-lm-ldl-lrt-lpthread 
/usr/bin/ld: cannot find-lQtWebKit
collect2: ld はステータス 1で終了しました
make[1]: *** [../bin/phantomjs]エラー 1
make[1]: ディレクトリ `/usr/local/src/phantomjs/src'から出ますmake: *** [sub-src-phantomjs-pro-make_default-ordered] エラー 2

エラーの原因

1.9、2.0とも「QtWebKit」に問題があると出ています。

「QtWebKit」はブラウザのレンダリングエンジンのライブラリなのかなと思います。
少しだけ調べると、「Qt」というライブラリがあるようです。
PhantomJSにWebKitは含まれているらしいのですが、それに問題があるのでしょうか。

もう少し調べてみようと思います。

VMwareFusionのNAT接続でゲストOSのIPアドレスを固定する

$
0
0

f:id:shinsuke789:20150629054540p:plain:w300

環境

VMwareFusion6.0.6
ホストOSMacOS 10.9
ゲストOSCentOS 6.4

手順

1.ゲストOSで「ifconfig」を実行し、ネットワークのMACアドレスを取得します。
MACアドレスは「HWaddr」の部分です。

ifconfig
eth1      Link encap:Ethernet  HWaddr 00:50:56:2D:7D:C8  
          inet addr:192.168.152.3  Bcast:192.168.152.255  Mask:255.255.255.0
          inet6 addr: fe80::250:56ff:fe2d:7dc8/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11 errors:0 dropped:0 overruns:0 frame:0
          TX packets:20 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2430(2.3 KiB)  TX bytes:3031(2.9 KiB)


2.ホストOSで「dhcpd.conf」ファイルを編集します。

sudo vi "/Library/Preferences/VMware Fusion/vmnet8/dhcpd.conf"


3.「dhcpd.conf」にゲストOSの固定IPアドレスを定義します。
26行目あたりに「subnet」の定義があります。
そのカッコ内の末尾に「host」を追加して固定IPアドレスを定義します。

subnet 192.168.152.0 netmask 255.255.255.0 {
        range 192.168.152.128 192.168.152.254;
        option broadcast-address 192.168.152.255;
        option domain-name-servers 192.168.152.2;
        option domain-name localdomain;
        default-lease-time1800;# default is 30 minutes
        max-lease-time7200;# default is 2 hours
        option netbios-name-servers 192.168.152.2;
        option routers 192.168.152.2;# ゲストOSのIPアドレスを固定する
        host guest {# guestの部分はなんでもOK
                hardware ethernet 00:50:56:2D:7D:C8;# ゲストOSのMACアドレス
                fixed-address 192.168.152.3;# 好みのIPを設定する(3~127は固定用、128〜254はDHCP)}}

4.設定を有効にするためにホストOSを再起動します。

5.ゲストOSで設定したIPアドレスになっているか確認します。


Chromeユーザーも必見!ブラウザでファイルをダウンロードするなら10倍速くなるFireFoxアドオンの「DownThemAll!」を使おう!

$
0
0

f:id:shinsuke789:20150804170046p:plain

FireFoxのアドオンに「DownThemAll!」というものがあり、これを使ってファイルのダウンロードを行うと通常の10倍でダウンロードが可能です。

DownThemAll!addons.mozilla.org


ISOファイルなどのGB単位でダウロードに時間が掛かるファイルに使うとかなり速くダウンロードが可能になります。

MSDNでISOファイルをダウンロードするときに利用すると、途中で切断されることもなくダウンロードできます。


高速にダウンロード出来る機能の他に、ダウンロードを一時停止して途中からダウンロードを行うレジューム機能にも対応しています。


Chrome使いの方も、巨大ファイルをダウンロードする時はFireFoxを使うことをおすすめします。

設定画面

一般

f:id:shinsuke789:20150804164013p:plain

操作

f:id:shinsuke789:20150804164017p:plain

ネットワーク

ダウンロードの上限数、サーバーごとの上限数を最大にしておきます。

f:id:shinsuke789:20150804164024p:plain

プライバシー

f:id:shinsuke789:20150804164030p:plain

フィルター

f:id:shinsuke789:20150804164034p:plain

詳細

ダウンロードの最大分割数を最大の10にして常時高速化するようにしておきます。
f:id:shinsuke789:20150804164039p:plain

f:id:shinsuke789:20150804164043p:plain

f:id:shinsuke789:20150804164048p:plain

ダウンロード時

保存

DownThemAll!を選択すると高速にダウンロードが可能です。

f:id:shinsuke789:20150804164053p:plain

ダウンロード追加

チェックサムを設定すると、正常にダウンロードできたか確認してくれます。

f:id:shinsuke789:20150804164058p:plain

進捗

f:id:shinsuke789:20150804164105p:plain

ダウンロード情報

緑のグラフで分割してダウンロードしているのが分かります。

f:id:shinsuke789:20150804164110p:plain

PhantomJS2.0のバイナリをLinuxで使う

$
0
0

f:id:shinsuke789:20150804174808p:plain

PhantomJS+CasperJSを使ってスクレイピングするプログラムを作成し、Macでは正常に動作していました。

サーバー環境であるLinuxで動作させると、なぜかリンクのクリックでエラーが出てプログラムが動作しません。

Mac環境では、PhantomJS2.0、CasperJS1.1-bata3で問題なく動作していますが、
Linux環境では、PhantomJS1.9.8、CasperJS1.1-bata3で問題が発生しています。

Macと同じ2.0のバイナリを使う方法がないか調査してみました。

ソースからビルドする

公式サイトには、Linux版のバイナリが配布されておらず、各自ビルドするように書かれています。

Binary packages for Linux are still being prepared.
There are still issues to be solved until a static build is available (see issue 12948 for more details).
In the mean time, it is recommended that you build the Linux version from source.


しかし、問題があるようでビルドしても時間がかかって最終的にエラーでバイナリが生成されません。

PhantomJSをCentOSでビルドしたらエラーが出てインストールできない - Webサービスで起業を目指すプログラマーblogshinsuke789.hatenablog.jp


現在では、gitからチェックアウトするとビルドできるようになっていますが、「2.0.1-development」ということで正式版ではありません。

試しにLinuxで動かすと動くけどもっさりしてて、CPU使用率が高めです。

PhantomJS2.0のバイナリをダウンロードする

次のサイトにパッチを当てたビルド方法が書かれていて、最後に2.0のバイナリがダウンロードできるようになっています。

Compiling phantomJs 2.0 binaries on Linux - RAMP Blogblog.rampinteractive.co.uk

ビルドしても時間がかかるだけなので、素直にバイナリをダウンロードしましょう。

crontabで第?曜日にタスクを実行する方法

$
0
0

crontabで第?曜日にタスクを実行する方法を紹介します。

サンプル

日曜日にシャットダウンを実行する場合の例です。

# 第1日曜日(5月)001-75 * ["$(date '+\%w')"-eq0]&& /sbin/shutdown -h now
# 第2日曜日(8月)008-148 * ["$(date '+\%w')"-eq0]&& /sbin/shutdown -h now
# 第3日曜日(9、11、12月)0015-219,11-12 * ["$(date '+\%w')"-eq0]&& /sbin/shutdown -h now
# 第4日曜日(どの月でも)0022-28 * * ["$(date '+\%w')"-eq0]&& /sbin/shutdown -h now
# 第5日曜日(どの月でも)0029-31 * * ["$(date '+\%w')"-eq0]&& /sbin/shutdown -h now

解説

日時

先頭の0 0 8-14 8 *はcrontabの分、時、日、月、曜日の指定です。
曜日を指定しないのがミソです。

コマンド

日時指定の後に実際に実行するコマンドを定義します。

[ "$(date '+\%w')" -eq 0 ]は、日付を取得し、そのときの曜日が日曜日(0)だったらという条件になっています。
曜日の変更は、crontabの日時設定の所で行うのではなく、コマンド内の条件部分で行います。

&&は、前の条件が満たされたら次のコマンドを実行する条件分岐の判定文法になっています。

条件が満たされたら、/sbin/shutdown -h nowを実行し、シャットダウンを行います。


週ごとの区切りの日付を次のように定義します。

第1週1-7
第2週8-14
第3週15-21
第4週22-28
第5週29-31


曜日の定義は次の通りです。

1
2
3
4
5
6
7または0


新しいLinuxの教科書

新しいLinuxの教科書

Linuxシステム[実践]入門 (Software Design plus)

Linuxシステム[実践]入門 (Software Design plus)


使わなくなったMacをお金に換えた2つの方法を体験談を交えて紹介します

$
0
0

私がメインで使用しているパソコンはMacで、3~5年周期で買い替えを行っています。
使わなくなったMacを押入れ等に入れて放置しておくのはもったいないので、毎回売却しています。

Macは値引きがあまりなく価格が高いイメージですが、Windowsパソコンよりも高く売れます。
Windowsパソコンを何十万と出して買っても、売るときには1万以下または売れないという状態が多いと思います。
Macだと買う・売るトータルで考えるとWindowsパソコンより安く買えていることになります。

トータルの費用を抑えるために、Macを高く売った経験談を紹介します。

ネット買取

売ったMac

初めてのMacMacBook黒でした。

f:id:shinsuke789:20141128122905j:plain:w250

Macの状態

多少の薄いキズはありましたが、きれいな方だったと思います。

買取までの様子

Macを高価買取してくれるところを探していると「ビワコム」というサイトにたどり着きました。

サイトより個人情報やMacの状態を入力して見積を依頼しました。

Macの状態を見てもらうために、お店にMacを送る必要がありました。
集荷は指定日に業者が訪問してきて、Macを渡すだけでした。
送料はお店負担だったので費用は発生しませんでした。

しばらく経ってから、買取金額の連絡がきました。
買取金額は、面瀬で提示されている上限金額で満足したので、そのまま買取をお願いしました。

後日、指定の銀行口座に買取金額が振り込まれました。

金額

金額
購入191,000円
売却46,000円
実購入費145,000円

感想

とても簡単に買取をしてもらい、高額で買い取ってもらえたので満足でした。
他人に任せっきりでMacを処分したいならおすすめです。

Amazonマーケットプレイス

売ったMac

2台目はMacBookAir11インチでした。
f:id:shinsuke789:20141128123853j:plain

Macの状態

本体の端の方がほんの少し小さくかけていたけどきれいな状態でした。
アダプターはMacに接続する側で断線していたようで、充電できたりできなかったりする状態でした。

売却までの様子

以前ネット買取をしてもらって満足していたのですが、さらに高く売りたいと思いました。

普段から本の売却はAmazonマーケットプレイスを使っていたので、Macを出品してみようと試してみました。

すぐに注文があったのですが、注文主のクレジットカード情報が登録されておらず、こちらとしては発送が全くできない状態でした。
注文主からは、「早く発送してくれ」と何度も問い合わせのメールがあり、どうしようもないので返信だけして、カード情報が登録されるまでずっと待っていました。
いつになってもカード情報が登録されないので、自動的にキャンセルになりました。

売れなかったので少しショックでしたが、諦めずに再度出品しました。
すると数カ月後に注文があり無事売れました。

出品したMacは、アダプターが一部断線しかけていて、充電できたりできなかったりの状態でした。
商品説明にアダプターの断線のこともきっちり書いたので、それで納得して買ってくれる人もいるんだなーと勉強になりました。

金額

金額
購入89,000円
売却50,099円
実購入費38,901円

感想

買い取りよりも高く売ることができるし、任意の値段をつけることができます。
商品の状態が悪くても、値段相応のものでも良いと思ってる方がいたりすると、買取では値段がつかなくても、売れる可能性があります。

売れるまでに時間がかかるので、次の新しいモデルが出ると、値段を下げざるをえなくなってきます。
辛抱強く、買取よりも少しでも高く売りたいという方におすすめです。

まとめ

売却のことも考えて使用すると、トータルで安くできます。
基本的にモノは、大事に使うことに越したことはないので、それを心がけましょう。

MacにMercurialをインストールする

$
0
0

f:id:shinsuke789:20141003110840p:plain

環境

MacOS10.9.2
Mercurial3.0.1

手順

1.公式サイトよりMacMercurialをダウンロードします。
http://mercurial.selenic.com/downloads


2. ダウンロードしたzipファイルを解凍し、pkgファイルをダブルクリックしてインストーラーを起動しインストールします。


3.ターミナルを起動し、ログインユーザーのユーザーディレクトリにMercurail用設定ファイル.hgrcを作成します。

touch ~/.hgrc


4.viエディタ等で.hgrcを開き、次を入力し保存します。

[ui]
username = コミット時のユーザー名


5.ターミナルよりMercurialがインストールされているか確認します。

hg --version

結果

Mercurial Distributed SCM (version 3.0.1+20140606)(see http://mercurial.selenic.com for more information)

Copyright (C)2005-2014 Matt Mackall and others
This is free software; see the sourcefor copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

SpringSecurityで独自テーブルを使って認証を行う

$
0
0

f:id:shinsuke789:20150804182444j:plain

SpringBootでSpringSecurityを使って独自認証でログイン機能を実装してみました。

ドキュメントを参考にやってみたけど、詳しく書いてなくて理解に苦しみ結構ハマりました。
最終的にSpringSecurityのソースを見ることで認証オブジェクトの仕組みを理解しました。

概要

SpringSecurityでDBを使用して認証する場合、SpringSecurity付属のテーブル定義を行う必要があります。
今回は、独自テーブルを使った認証を行い、ロールは使用しません。

SpringSecurityの設定

SecurityConfigクラスを作成し、アクセス制限、ログイン処理、ログアウト処理等を定義します。

認証チェック処理クラス

AuthenticationProviderインターフェースを継承して独自クラスを作成します。
このクラスで独自テーブルを参照して認証チェック処理を定義します。

認証オブジェクト作成サービスクラス

UserDetailsServiceインターフェースを継承し独自クラスを作成します。
このクラスで認証後にシステム内で使用する認証オブジェクトを生成します。

認証オブジェクトクラス

Userクラスを継承したクラスを作成し、username、passwordフィールドを定義します。
username、passwordフィールドを定義することで、システム内で認証オブジェクトをオブジェクトで持つことができ、他に必要な情報を持たせることができるようになります。

環境

Eclipse4.3
Java1.7
SpringBoot1.2.4
SpringSecurity3.2.7
Thymeleaf2.1.4
Doma1.0.38
Gradle2.3.10

構成

  • src/main/java
    • demo
    • demo.dao(省略)
    • demo.dto
    • demo.entity(省略)
    • demo.impl
      • AuthenticationProviderImpl.java
      • UserDetailsServiceImpl.java
    • demo.web
  • src/main/resources
    • tempaltes
      • login.html
      • menu.html

build.gradle

buildscript {
    ext {
        springBootVersion = '1.2.4.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
        classpath("io.spring.gradle:dependency-management-plugin:0.5.1.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'idea'
apply plugin: 'spring-boot' 
apply plugin: 'io.spring.dependency-management' 
apply plugin: 'war'


war {
    baseName = 'demo'
    version = '1.0'
}
sourceCompatibility = 1.7
targetCompatibility = 1.7// for Doma// JavaクラスとSQLファイルの出力先ディレクトリを同じにする
processResources.destinationDir = compileJava.destinationDir
// コンパイルより前にSQLファイルを出力先ディレクトリにコピーするために依存関係を逆転する
compileJava.dependsOn processResources

repositories {
    maven {url 'http://maven.seasar.org/maven2'}
    mavenCentral()
}

configurations {
    providedRuntime
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-aop")
    // SpringSecurityの依存
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-jdbc")
    // htmlでThymeleaf用のSpringSecurityタグ使うためのもの
    compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity3")
    compile("org.hibernate:hibernate-validator")
    compile("org.seasar.doma:doma:1.38.0")
    compile("org.projectlombok:lombok:1.16.4")
    compile files("C:/app/lib/jdbc/ojdbc7.jar")
    providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
}


eclipse {
    classpath {
        containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
        containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7'
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

demo/SecurityConfig.java

package demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import demo.impl.AuthenticationProviderImpl;
import demo.impl.UserDetailsServiceImpl;

@Configuration@EnableWebMvcSecuritypublicclass SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowiredprivate UserDetailsServiceImpl userDetailsService;

    @Autowiredprivate AuthenticationProviderImpl authenticationProvider;

    @Overrideprotectedvoid configure(HttpSecurity http) throws Exception {
        http
            .headers()
                .xssProtection()
                .frameOptions()
                .contentTypeOptions()
                .cacheControl()
                .and()
            .authorizeRequests()
                // 認証対象外のパスを設定する
                .antMatchers("/", "/login", "/registration/**", "/css/**", "/js/**", "/img/**")
                // 上記パスへのアクセスを許可する
                .permitAll()
                // その他のリクエストは認証がに必要
                .anyRequest().authenticated()
                .and()
            .formLogin()
                // ログインフォームのパス
                .loginPage("/")
                // ログイン処理のパス
                .loginProcessingUrl("/login")
                // ログイン成功時の遷移先
                .defaultSuccessUrl("/menu")
                // ログイン失敗時の遷移先
                .failureUrl("/login-error")
                // ログインフォームで使用するユーザー名のinput name
                .usernameParameter("empNo")
                // ログインフォームで使用するパスワードのinput name
                .passwordParameter("password")
                .permitAll()
                .and()
            .rememberMe()
                .tokenValiditySeconds(86400) // 1ヶ月(秒)
                .and()
            .logout()
                // ログアウトがパス(GET)の場合設定する(CSRF対応)
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                // ログアウトがPOSTの場合設定する//.logoutUrl("/logout")// ログアウト後の遷移先
                .logoutSuccessUrl("/")
                // セッションを破棄する
                .invalidateHttpSession(true)
                // ログアウト時に削除するクッキー名
                .deleteCookies("JSESSIONID", "remember-me")
                .permitAll();
    }

    @Autowiredpublicvoid configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // 独自認証クラスを設定する
        auth
            .authenticationProvider(authenticationProvider)
            .userDetailsService(userDetailsService);
    }
}

demo/dto/LoginUser.java

package demo.dto

import java.util.ArrayList;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import demo.entity.Emp;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

@Data@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
publicclass LoginUser extends User {

    privatestaticfinallong serialVersionUID = 1L;

    // 追加する(テーブルでユーザーのキーとなる値を設定する)public String username;

    // 追加するpublic String password;

    // 独自で必要な項目public String empNm;

    public LoginUser(Emp emp) {
        super(emp.empNo, emp.password, true, true, true, true, new ArrayList<GrantedAuthority>());
        username = emp.empNo;
        password = emp.password;
        empNm = emp.empNm;
    }
}

demo/impl/AuthenticationProviderImpl.java

package demo.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import demo.dao.EmpDao;
import demo.entity.Emp;

@Componentpublicclass AuthenticationProviderImpl implements AuthenticationProvider {

    privatestaticfinal Logger log = LoggerFactory.getLogger(AuthenticationProviderImpl.class);

    @Autowiredprivate EmpDao empDao;

    @Overridepublic Authentication authenticate(Authentication auth)
            throws AuthenticationException {

        String id = auth.getName();
        String password = auth.getCredentials().toString();

        if ("".equals(id) || "".equals(password) {
            // 例外はSpringSecurityにあったものを適当に使用thrownew AuthenticationCredentialsNotFoundException("ログイン情報に不備があります。");
        }

        Emp emp = empDao.authEmp(id, password);
        if (emp == null) {
            // 例外はSpringSecurityにあったものを適当に使用thrownew AuthenticationCredentialsNotFoundException("ログイン情報が存在しません。");
        }

        returnnew UsernamePasswordAuthenticationToken(new LoginUser(emp), password, auth.getAuthorities());
    }

    @Overridepublicboolean supports(Class<?> token) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(token);
    }
}

demo/impl/UserDetailsServiceImpl.java

package demo.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import demo.dao.EmpDao;
import demo.dto.LoginUser;
import demo.entity.Emp;

@Componentpublicclass UserDetailsServiceImpl implements UserDetailsService {

    @Autowiredprivate EmpDao empDao;

    @Overridepublic UserDetails loadUserByUsername(String empNo)
            throws UsernameNotFoundException {

        Emp emp = empDao.findByNo(empNo);
        if (emp == null) {
            thrownew UsernameNotFoundException("ユーザーが見つかりませんでした。");
        }

        returnnew LoginUser(emp);
    }
}

demo/web/LoginController.java

package demo.web;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;

import demo.form.LoginForm;

@Controllerpublicclass LoginController {

    @RequestMapping(value = "/")
    public String index(Model model) {
        model.addAttribute(new LoginForm());
        return"login/login";
    }
/* ログイン処理は実装しない。SpringSecurityの処理で行われる。    @RequestMapping(value = "/login")    public String login(@Valid LoginForm form, BindingResult result, Model model) {        if (result.hasErrors()) {            return "login/login";        }        return "redirect:/menu";    }*/// SpringConfigで設定したログインできなかった場合の処理を定義する@RequestMapping(value = "/login-error")
    public String loginError(Model model) {
        model.addAttribute("loginError", true);
        return"login/login";
    }
}

demo/web/MenuController.java

package demo.web;

import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import demo.dto.LoginUser;

@Controllerpublicclass MenuController {

    @RequestMapping(value = "/menu")
    public String index(@AuthenticationPrincipal LoginUser loginUser, Model model) {
        // @AuthenticationPrincipalを使うと認証オブジェクトを参照できる。return"menu/menu";
    }
}

templates/login.html

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head></head><body><h1>login</h1><!-- ログインできなかった時のエラーメッセージ --><p th:if="${loginError}">Login Error!!</p><form th:action="@{/login}"method="post"><table><tr><td>社員番号</td><td><inputtype="text"name="empNo" /></td></tr><tr><td>パスワード</td><td><inputtype="password"name="password" /></td></tr></table><inputname="remember-me"type="checkbox" />ログインしたままにする
        <inputtype="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" /><inputtype="submit"name="login"value="ログイン" /></form></body></html>

templates/menu.html

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head></head><body><h1>menu</h1><!-- 認証されているか --><p th:if="${#authorization.expression('isAuthenticated()')}">認証済み</p><!-- 認証オブジェクトの参照 --><p th:text="${#authentication.principal.empNm}"></p></body></html>

さくらレンタルサーバーにRubyをインストールする

$
0
0

さくらレンタルサーバーにはデフォルトでRubyがインストールされていますが、バージョンが古いので最新版をインストールする手順を書いてみました。

環境

さくらレンタルサーバースタンダード

手順

sshでサーバーにログインする

$ ssh account@account.sakura.ne.jp
Password:

cshからbashに変更する

使い勝手の良いbashを使えるようにします。


bashのパスを確認するためにシェルのパス一覧を確認します。

$ cat /etc/shells
# $FreeBSD: release/9.1.0/etc/shells 59717 2000-04-27 21:58:46Z ache $## List of acceptable shells for chpass(1).# Ftpd will not allow users to connect who are not using# one of these shells.

/bin/sh
/bin/csh
/bin/tcsh
/usr/local/bin/zsh
/usr/local/bin/rzsh
/usr/bin/passwd
/usr/local/bin/bash
/usr/local/bin/rbash


シェルのパス一覧からbashのパスを確認しそれに変更します。

$ chsh -s /usr/local/bin/bash


ログインし直します。


再ログインしたらシェルが変更されているか確認します。

$ echo$SHELL
/usr/local/bin/bash

インストールに必要なディレクトリの作成

レンタルサーバーなのでroot権限がありません。
ホームディレクトリにインストールに必要なディレクトリを作成しパスを通します。


ホームディレクトリに「local」「local/src」「local/bin」の3つのディレクトリを作成します。

$ mkdir ~/local
$ mkdir ~/local/src
$ mkdir ~/local/bin


ユーザー設定にパスを追記し有効にします。

$ vi ~/.bashrc
export PATH=$HOME/local/bin:$PATH
$ source ~/.bashrc

gitがインストールされているか確認する

さくらレンタルサーバーは、デフォルトでgitがインストールされているようなのでこれを使います。


gitのバージョンを確認します。

$ git --version
git version 1.9.3

rbenvをインストールする

ホームディレクトリにrbenvをインストールします。

$ cd ~/local
$ git clone git://github.com/sstephenson/rbenv.git rbenv


ruby-buildをrbenv のプラグインとして入れます。

$ mkdir ~/local/rbenv/plugins
$ cd  ~/local/rbenv/plugins
$ git clone git://github.com/sstephenson/ruby-build.git ruby-build


~/.bashrcの先頭にrbenvのパスを設定します。

$ vi ~/.bashrc
export RBENV_ROOT=$HOME/local/rbenv
export PATH=$RBENV_ROOT/bin:$HOME/local/bin:$PATHeval"$(rbenv init -)"
$ source ~/.bashrc


tmpディレクトリの定義を追加します。

$ vi ~/.bashrc
export TMPDIR=$HOME/tmp
$ source ~/.bashrc


rbenvでインストール可能なrubyのバージョンを確認します。

$ rbenv install-l


現時点での最新(2.2.3)のrubyをインストールします。
インストールには、約5分程かかりますので待ちます。

$ rbenv install 2.2.3
Downloading ruby-2.2.3.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/df795f2f99860745a416092a4004b016ccf77e8b82dec956b120f18bdc71edce
Installing ruby-2.2.3...
Installed ruby-2.2.3 to /home/user/local/rbenv/versions/2.2.3

$ rbenv rehash


先ほどインストールしたバージョンをデフォルトにします。

$ rbenv global 2.2.3


デフォルトになっているか確認します。

$ ruby -v
ruby 2.2.3p173 (2015-08-18 revision 51636)[x86_64-freebsd9.1]

bundlerをインストールする

現在のgemを確認します。

$ gem --version
2.4.5.1

$ gem list

*** LOCAL GEMS ***

bigdecimal (1.2.6)
io-console (0.4.3)
json (1.8.1)
minitest (5.4.3)
power_assert (0.2.2)
psych (2.0.8)
rake (10.4.2)
rdoc (4.2.0)test-unit (3.0.8)


bundlerをインストールします。

$ rbenv exec gem install bundler
Fetching: bundler-1.10.6.gem (100%)
Successfully installed bundler-1.10.6
Parsing documentation for bundler-1.10.6
Installing ri documentation for bundler-1.10.6
Done installing documentation for bundler after 5 seconds
1 gem installed

$ rbenv rehash


bundlerがインストールされたか確認します。

$ gem list

*** LOCAL GEMS ***

bigdecimal (1.2.6)
bundler (1.10.6)<- インストールされている
io-console (0.4.3)
json (1.8.1)
minitest (5.4.3)
power_assert (0.2.2)
psych (2.0.8)
rake (10.4.2)
rdoc (4.2.0)test-unit (3.0.8)

最終の.bashrc

$ cat ~/.bashrc
export RBENV_ROOT=$HOME/local/rbenv
export PATH=$RBENV_ROOT/bin:$HOME/local/bin:$PATHeval"$(rbenv init -)"export TMPDIR=$HOME/tmp
export PATH=$HOME/local/bin:$PATH

Rails4でBootstrapのGlyphicon(アイコン)を表示させる方法

$
0
0

RailsにBootstrapを導入するとGlyphicon(アイコン)が表示されません。

ネットで調べてみるとGemをインストールしたり、application.rbに設定を追加したりしているのが多かったです。
個人的には単純に追加の処理は行いたくなかったのでいろいろ試してみました。

結果的に、CSSで使用してるフォントのパスを変更するだけで表示されるようになりました。

環境

Rails4.2.4
Bootstrap3.3.5

変更箇所

bootstrap.cssを「app/assets/stylesheets/bootstrap.css」に設置した場合、このCSS内にある「@font-face」の定義のurlにある「../fonts/」を削除するだけです。(263行目あたり)

パス変更前

パス変更前のアイコンは次のように表示されます。
f:id:shinsuke789:20151027062934p:plain

app/assets/stylesheets/bootstrap.css

@font-face{font-family: 'Glyphicons Halflings';

  src: url('../fonts/glyphicons-halflings-regular.eot');
  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix')format('embedded-opentype'), url(../fonts/'glyphicons-halflings-regular.woff2')format('woff2'), url('../fonts/glyphicons-halflings-regular.woff')format('woff'), url('../fonts/glyphicons-halflings-regular.ttf')format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular')format('svg');
}

パス変更後

パス変更後は正常にアイコンが表示されます。
f:id:shinsuke789:20151027063304p:plain

app/assets/stylesheets/bootstrap.css

@font-face{font-family: 'Glyphicons Halflings';

  src: url('glyphicons-halflings-regular.eot');
  src: url('glyphicons-halflings-regular.eot?#iefix')format('embedded-opentype'), url('glyphicons-halflings-regular.woff2')format('woff2'), url('glyphicons-halflings-regular.woff')format('woff'), url('glyphicons-halflings-regular.ttf')format('truetype'), url('glyphicons-halflings-regular.svg#glyphicons_halflingsregular')format('svg');
}

Macをちょこっと快適にする4つの無料アプリ

$
0
0

Alfred

f:id:shinsuke789:20151122065456p:plain:w300

コマンドラインランチャーです。
Dockにアイコンをおいてそこからアプリを起動させるのもいいですが、数が多いとDockの見栄えが悪くなったり、クリックしにくくなります。
Alfredを使えば、アプリ名を入力することで素早くアプリを起動させることができます。
アプリの起動以外にもちょっとした計算も行えます。

Alfred - Productivity App for Mac OS X

karabiner

f:id:shinsuke789:20151122065501p:plain:w300

キーボードのカスタマイズを行うフリーソフトです。
キーボード以外にも4ボタン以上のマウスのボタンを有効にしてくれます。

Karabiner - OS X用のソフトウェア

XtraFinder

f:id:shinsuke789:20151122065511p:plain:w300

Finderに機能を追加するアプリです。
Finderをタブ化するのに使っています。

XtraFinder adds Tabs and features to Mac Finder.

ScrollReverser

f:id:shinsuke789:20151122065506p:plain:w300

マウスとトラックパッドを使い分けていると、スクロール設定が逆になり使い勝手が悪くなります。
マウスとトラックパッドの利用時に、自動的に設定したスクロール設定に変更してくれるアプリです。

Scroll Reverser for Mac OS X

プログラミング初心者から上達するための4つの大事なこと

$
0
0

ネットではプログラミングを学ぶためのサービスが増えてきました。
プログラムを動かすだけであれば、誰でも学習するだけで習得可能です。


いくらプログラミングができても中にはずっと初心者のままで一向に上達しない人もいます。
仕事でプログラミングをしていますが、毎回同じこともいってもプログラミングレベルが上がらない人がいます。
なぜ上がらないのか、どうやったら上がるのか考えてみました。

後で読んだ時に理解できるコードを書く

初心者の方は、プログラムの文法等は一通り覚えて、コードを書けるようにはなっていると思います。
ただ書くだけなら簡単です。
でも、そのコードを後で読んだとき理解できるでしょうか?


コードを書いていると夢中になって、同じメソッドにダラダラコードを書いていることが多いと思います。
そのコードは、if文やfor文などがぎっしり詰まって、階層が深くなっていませんか?
そのようなコードを後で読んだとき、すぐに理解できますか?


経験を積んでいくと分かるのですが、そのような長くてif文が多くてfor文が多くて階層が深いコードは理解に非常に時間がかかります。


1人だけで書くなら良いですが、上達させるために1人で書いてても他の人が見た時に分かるように書くようにしましょう。
わかりやすいコードというのは、1つの機能を1つのメソッドで定義しているものです。


悪いコードを良いコードに変える技術として「リファクタリング」というものがあります。
名書があるので一度は読むことをおすすめします。

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)


他人のコードをメンテナンスする

プログラミングを上達させるために「他人のコードを読む」というものがあります。
これでも上達に効果はありますが、さらに理解を深めるために他人のコードをメンテナンスする方法があります。


読むだけならプログラミングに入り込む感じが薄いので、自分がプログラミングしているという感じを深めるために実際に他人のコードを修正していきます。
なるべく、悪いコードを書く人のものをメンテナンスした方が効果が高いです。


悪いコードというのは、グローバル変数や先ほど書いた1メソッドが長いコードのことを言います。


そのようなコードを実際に触ってみると分かるのですが、どこに何が書いてあるのか、この変数には何が入っているのかわかりにくいと感じます。
どのようなものが悪いコードなのか理解しつつ、それをどうしたら良いコードにするのか考えることが学習に繋がります。


悪いコードを理解することで、書いてはいけないコードというのが分かるようになり良いコードを書くことに繋がります。

テストコードで手を抜かない

テストコードだからといって、後で読めなくなるような適当なコードを書いていませんか?


このようなことをしていると、それが習慣となり一向に上達しません。
お試しでも本番でも常に同じ気持ちでコードを書くようにしましょう。


練習でサボっていたら本番でうまくいくはずがありません。

学習し続ける

プログラミングの世界は、次から次へと新しい技術が出てきます。
全てを追いかけることは不可能ですが、興味を持った新しい技術は少しでもいいので触れてみましょう。
新しい技術に触れることで、今持っている技術や考え方に活かされることが多々あります。


技術以外にも他に良いコードの書き方がないか試行錯誤したりすることも学習になります。
長いコードをもっとシンプルに書く方法はないのか考えるたり調べたりするのも良いでしょう。


学習をやめるとプログラミングが上達することはほぼなくなります。
先輩の中にはCOBOL時代の知識でJavaのコードを書いたり設計する人もいます。
Javaを理解して一緒にプログラミングする人にとっては迷惑な話です。


大事なのは最初に学んだことを捨ててでも新しいことを取り入れれる勇気です。


VMware Fusionでサブネットアドレスと固定IPアドレスを画面から設定する

$
0
0

以前に設定ファイルを修正してゲストOSのIPアドレスを固定する方法を紹介しました。

shinsuke789.hatenablog.jp

MacのOSをクリーンインストールでバージョンアップして仮想環境を移行しました。
その時にIPアドレスの構成が変わってしまったので変更する必要がありました。
設定ファイルの修正では上手くいかなかったので、画面の設定から変更する手順で設定する方法を紹介します。
こちらの方が簡単に設定できるのでおすすめです。

参考サイト

調べていると公式サイトにヒントとなる記事がありました。
kb.vmware.com

最後辺りに次のような記述があり画面から設定できるようなことが書いてありました。

To accessthe network editor:

1. Click VMware Fusion in the menu bar.
2. Click Preferences.
3. Click Network.
4. Click the + sign located at the bottom right to add a custom network connection.

環境

仮想環境VMware Fusion 8.1.0
ゲストOSCentOS 6.4 (x64)
ホストOSMac OS X 10.11.2

設定の流れ

1.VMware Fusionの環境設定でネットワーク構成を追加する
2.VMware FusionでのゲストOSのネットワーク設定で1のネットワーク構成を選択する
3.ゲストOS内のネットワーク設定で固定IPアドレスを設定する

手順

VMware Fusionの設定

1.VMware Fusionを起動しファイルメニューの「VMware Fusion」→「環境設定」をクリックします
f:id:shinsuke789:20151231205248p:plain

2.ネットワークをクリックし、画面下部の鍵アイコンをクリックします
f:id:shinsuke789:20151231205218p:plain

3.パスワードを聞かれるのでMacの管理者パスワードを入力します
f:id:shinsuke789:20151231205142p:plain

4.「+」ボタンをクリックして構成を追加します(vmnet2が追加される)
f:id:shinsuke789:20151231205231p:plain

5.1つ目と3つ目にチェックを入れ、サブネットIP、サブネットマスクに任意の値を入力し適用します
f:id:shinsuke789:20151231205238p:plain

VMware FusionでのゲストOSの設定

1.仮想マシン一覧画面でゲストOSを選択し設定ボタンをクリックします
f:id:shinsuke789:20151231205300p:plain

2.「ネットワークアダプタ」をクリックします
f:id:shinsuke789:20151231205308p:plain

3.VMware Fusionの設定で追加した構成(vmnet2)を選択します
f:id:shinsuke789:20151231205320p:plain

ゲストOS内での設定

1.ネットワーク接続を起動します
f:id:shinsuke789:20151231205101p:plain

2.「Auto eth1」を選択し「編集」をクリックします
f:id:shinsuke789:20151231205115p:plain

3.「IPv4のセッティング」で方法を「手動」、アドレスに固定IPアドレスDNSDNSサーバーアドレスを入力します
ゲートウェイDNSの末尾は設定ファイルを見る限り「2」が使用されています。
f:id:shinsuke789:20151231205124p:plain

4.ゲストOSを再起動します

疎通確認

1.ホストOSからゲストOSにpingを実行し疎通を確認します

2.ゲストOSからホストOSにpingを実行し疎通を確認します

まとめ

この方法だと仮想環境上に全て設定がされているので、設定ファイルのバックアップを忘れても再設定が簡単です。
画面上での設定なのでやりやすいのも良いところです。


プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化

さくらレンタルサーバーにMercurialをインストールする

$
0
0

f:id:shinsuke789:20141003110840p:plain

さくらのレンタルサーバーMercurialをインストールした時の手順です。


1.ホームディレクトリ内に「local」ディレクトリを作成する

$ mkdir ~/local


2.ホームディレクトリ内に「tmp」ディレクトリを作成する

$ mkdir ~/tmp


3.Mercurialのソースを公式サイトよりダウンロードし、「tmp」ディレクトリに置き、解凍する

公式サイトでは、「Mercurial 3.7.2 source release」の記載欄にあるリンクからダウンロードします。

$ cd ~/tmp
$ wget http://mercurial.selenic.com/release/mercurial-3.7.2.tar.gz
$ tar xvzf mercurial-3.7.2.tar.gz


4.Mercurialをインストールする

さくらレンタルサーバーでは、Pythonがデフォルトでインストールされています。

$ cd mercurial-3.7.2
$ python setup.py installhome=$HOME/local—force


5.インストールされたか確認する

$ hg version

Mercurial Distributed SCM (version 3.7.2)(see https://mercurial-scm.org for more information)

Copyright (C)2005-2016 Matt Mackall and others
This is free software; see the sourcefor copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

さくらレンタルサーバーでPHPからベーシック認証を行うと入力値が取得できない対処方法

$
0
0

さくらレンタルサーバーPHPでベーシック認証を実装し、対象のページにアクセスするとIDとパスワードを入力するダイアログが表示されます。

ここでID、パスワードを入力しても認証できない現象に遭遇し困ったので、その時の対処方法を説明します。

環境

サーバーさくらレンタルサーバー
PHPフレームワークCodeigniter 3

手順

Codeigniterの配下にある「.htaccess」を次のように編集します。

変更前

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1[L]

変更後

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1[L]
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

さくらレンタルサーバーではRuby on Railsは動作するけどレスポンスが糞遅いのでやめとけ

$
0
0

タイトルの通りの内容で、さくらレンタルサーバーRailsは糞遅いというお話です。

経緯

ホームページを作成する案件があって、それに付随するプログラムの開発がありました。
ホームページを動作させるのがメインだったので、レンタルサーバーが選択されました。

個人的にPHPが嫌い(Java育ちなのでPHPの曖昧さがなじめない)なのでそれ以外の言語はないのかとRubyを選択しました。

初めてのRuby on Railsでしたが、Java経験者からすると今までにない感じのプログラミングだったので、非常に楽しくワクワクしながら開発できました。

Ruby on Rails動作環境構築

さて、ひと通り出来上がったのでテストしてもらうために、動作環境であるレンタルサーバーRuby on Railsが動作する環境を構築しました。

事前に動作するというのは確認できていたので、いろんなサイトを参考にしながら試行錯誤で環境を構築しました。

この時点で、レスポンスが遅いというのは情報として知ってました。

でも、本当に遅いのかというのがわからなかったのと、FCGIだと速いという情報もあったので大丈夫だろうと思ってました。

デプロイ

環境の構築も完了したのでデプロイしていました。

トップページにアクセスしてみると、なかなか画面が表示されません。
何度やっても遅い、遅い、遅い。

確か画面表示に10秒以上かかってたと思います。

「これはあかん」ということで、PHPで最初から作りなおしました…。

構築手順

かなり日にちが経っててよく覚えてませんが、当時のメモをそのまま載せておきます。ものすごく適当です。

お遊びで構築したい人向けです。間違っても本番運用しないで下さい。泣くのは開発者であるあなたです。


1.wwwディレクトリと同階層にappディレクトリを作成する

2.appディレクトリにRailsプロジェクトを配置する

3.Rails/publicに.htaccessを作成する

RewriteEngine On
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

ErrorDocument 500"Application errorRails application failed to start properly"

4.Rails/publicにdispatch.cgiを作成し、権限を755にする

#!/home/user/local/rbenv/versions/2.2.3/bin/ruby# 本番環境設定ENV["RAILS_ENV"] = "production"# rake secretで生成したものENV["SECRET_KEY_BASE"] = "7cd8a5e38cfeddd0d0a4b45ad4bf75fd2cffe124f43388c34e6f29cf2c2e78f7d9cc1b2003f913be65c54f6ec61c7032609d3c9d88d6b3dc5226925a825b8379"# 静的ファイルENV["RAILS_SERVE_STATIC_FILES"] = "true"requireFile.dirname(__FILE__) + '/../config/environment'classRack::PathInfoRewriterdefinitialize(app)
    @app = app
  enddefcall(env)
    env.delete('SCRIPT_NAME')
    parts = env['REQUEST_URI'].split('?')
    env['PATH_INFO'] = parts[0]
    env['QUERY_STRING'] = parts[1].to_s
    env['PATH_INFO'] = env['PATH_INFO'].gsub(/\A#{ENV['RAILS_RELATIVE_URL_ROOT']}(.*)\Z/, '\1')
    env['SCRIPT_NAME'] = ENV['RAILS_RELATIVE_URL_ROOT']
    @app.call(env)
  endend# アプリケーション名を設定するRack::Handler::CGI.run  Rack::PathInfoRewriter.new(Hoge::Application)

5.Rails/config/boot.rbに以下を追記する

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require'bundler/setup'ifFile.exist?(ENV['BUNDLE_GEMFILE'])

$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby/2.2.0')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby/site_ruby/2.2.0')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby/gems/2.2.0')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib/ruby')
$LOAD_PATH.push('/home/user/local/rbenv/versions/2.2.3/lib')

ENV['PATH'] += ':/home/user/local/bin'ENV['GEM_HOME'] ||= '/home/user/local/rbenv/versions/2.2.3/lib/ruby/gems/2.2.0'# パスを設定するENV['RAILS_RELATIVE_URL_ROOT'] = '/hoge'

6.静的ファイルをプレコンパイルする

rake assets:precompile RAILS_ENV=production

7.node.jsを編集する
/local/src/node-v0.10.38/deps/v8/tools/gyp/v8.gyp

['OS=="freebsd"', {'include_dirs+':['/home/user/local/include'],
    'link_settings': {'libraries': ['-L/usr/local/lib -L${HOME}/local/lib -lexecinfo',
    ]},
    'sources': ['../../src/platform-freebsd.cc',
      '../../src/platform-posix.cc'],
  }],

FCGI対応

$ cd ~/local/src
$ wget http://www.fastcgi.com/dist/fcgi.tar.gz
$ tar xvzf fcgi.tar.gz
$ cd  fcgi-2.4.1-SNAP-0311112127
$ ./configure --prefix=$HOME/localCFLAGS="-g -O2 -Wall -fPIC"CXXFLAGS="-g -O2 -Wall -fPIC"
$ make
$ make install#### $ gem install fcgi -- --with-fcgi-include=$HOME/local/include --with-fcgi-lib=$HOME/local/lib
$ cd ~/appdir
$ bundle exec gem install fcgi -- --with-fcgi-include=$HOME/local/include --with-fcgi-lib=$HOME/local/lib
$ vi Gemfile
   追記 gem 'fcgi'
$ bundle update

まとめ

さくらレンタルサーバーでは、Ruby on Railsは動作するが、レスポンスが糞遅いのでやめましょう。

レンタルサーバーというと全てのサーバーをイメージされると思いますが、root権限のない制約のあるレンタルサーバーのことです。
さくらのVPS等root権限のあるサーバーでは、普通に動作しますので勘違いされないようにお願いします。

さくらのレンタルサーバーでCodeigniterを使いHTTPアクセスをHTTPSに強制リダイレクトする.htaccessの書き方

$
0
0

さくらのレンタルサーバーでHTTPアクセスをHTTPSに強制リダイレクトするのにかなりハマりました。

ネットでひたすらHTTPSにリダイレクトする方法を調べ試してみましたが、リダイレクトループばかりで全く実現できず。

最終的にさくらの仕様のせいで通常の設定が効かないということが分かりました。

困っている方、コードをコピペしてさっさと解決してしまいましょう。

環境

サーバーさくらのレンタルサーバースタンダード
Codeigniter3.0.3
PHP5.4

有効な「.htaccess」の設定

RewriteEngine On

# HTTP->HTTPSリダイレクト設定
RewriteCond %{ENV:HTTPS} !^on$
RewriteCond %{HTTP:X-SAKURA-FORWARDED-FOR} ^$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}[R=301,L]# Codeigniterの設定
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1[L]


さくらの共有SSL、独自SSLとも上記設定でHTTPSリダイレクトが可能です。

%{ENV:HTTPS}と%{HTTP:X-SAKURA-FORWARDED-FOR}がミソです。


次のサイトで詳しく説明があり大変助かりました。
furyu.hatenablog.com


上記サイトより引用です。

%{SERVER_PORT} には、SSLかそうでないかによらず '80'が設定される。
このため、%{SERVER_PORT}ではSSL接続かどうかの判別はできない。
「RewriteCond %{SERVER_PORT} ^80$」や「RewriteCond %{SERVER_PORT} !^443$」は常に真となるために、リダイレクトループが発生してしまう。

SSLアクセス時には通常、 %{ENV:HTTPS} には 'on'が、%{HTTP:X-Sakura-Forwarded-For} にはクライアント(リクエスト元)のIPアドレスが設定される。*1
ただし、SSLアクセスした場合であっても、mod_rewrite.c の RewriteRule によりリライトされるケースでは、リライト後には %{ENV:HTTPS} が未設定となってしまう。
RewriteRuleの[R]フラグによりhttps://〜にリダイレクトされた場合には 'on'が設定される。

まとめ

さくらのレンタルサーバーでは独自仕様があるのでまずそれを確認すること。
Codeigniterで他にフックを使った方法があるが、この仕様を考慮したPHPコードを書く必要がある。
めんどくさいと思ったら.htaccessで設定した方が簡単!


サーバ構築の実際がわかる Apache[実践]運用/管理 (Software Design plus)

サーバ構築の実際がわかる Apache[実践]運用/管理 (Software Design plus)

Viewing all 166 articles
Browse latest View live