OmniAICreator/Qiita-1.07M huggingface dataset:
PHP　画像アップのエラー

PHP,プログラミング初心者です。
画像アップロードのphpを書いて、実行したのですが以下のエラーが出ました。

Warning: move_uploaded_file(/upload_0000 .jpg): failed to open stream: Permission denied in C:\xampp\htdocs\image_submit\image_submit.php on line 25

Warning: move_uploaded_file(): Unable to move 'C:\xampp\tmp\php9396.tmp' to '/upload_0000 .jpg' in C:\xampp\htdocs\image_submit\image_submit.php on line 25

使用しているのは、windows8でローカルで確認しています。
調べると書き込みの権限がないという意味らしいのですが、
どこの何の権限をどう変更すればよいのかが、分かりませんでした。

はじめたばかりの初心者にも、分かるようにどなたかご説明いただけませんでしょうか？
よろしくお願いいたします。
GitHubのリポジトリにchangelogを追加

## きっかけ

Redmineのバージョンでどのチケットが反映されたかは分かるようにし、タグをつけてGitHubでリリースノートを手書きしていました。このリリースノートに、どのPRがマージされてたとか、どのチケットが反映されたかの一覧を自動でやってくれないかと、すこし探したらchangelogの自動生成を見つけました。

当初とはちょっとずれましたが、ひとつのファイルにまとめてできるならそれもありかと思い、導入してみました。

## github-changelog-generator

いくつかあったのですが、こちらのgemを使うことにしました。

https://github.com/skywinder/github-changelog-generator

## Windowsへのrubyのインストール

windowsマシンで開発しているので、rubyのインストールが微妙に障害に…

面倒なので下記を使いました。現在は2.1.x系を使えとのことで、これをダウンロード。
http://rubyinstaller.org/

インストール先のPATHを通せば完了です。

## tokenの設定

認証なしのリクエスト数が制限されているので、原則はtokenをつけて使用するとのことです。

アカウントのアイコン＞Settings＞Personal access token　より作成できます。
https://github.com/settings/tokens/new

## CHANGELOG作成

GitHub上で見ることを前提として、markdownで記述されたファイルができあがります。
git remote originを設定済みなら、ローカルリポジトリに移動して下記コマンドでOKです。

```
github_changelog_generator -t [github-token]
```

公式サイトのサンプルはこんな感じです。
https://github.com/skywinder/Github-Changelog-Generator/blob/master/CHANGELOG.md
![image](https://qiita-image-store.s3.amazonaws.com/0/9880/958dcf0b-1f52-21b5-f54e-55962e321747.png)


マージしたPR、closeしたissueがリストアップされます。
issueにラベルをつけていれば、「Fixed Bugs」などと分類されるようです。

## まとめ

changelogやリリースノートにどういう情報を載せるかは悩ましいですね…
こういったものを有効活用しようと思うとPR主体の開発に向かっていきそうですね。まずはやってみると、tagつけをどうするかも見直すきっかけになるし、どのバージョンでどの程度変更が入ったかも辿りやすくなります。

## 参考サイト

https://skywinder.github.io/github-changelog-generator/

http://efcl.info/2015/06/18/good-changelog/

http://efcl.info/2014/07/20/git-tag-to-release-github/
Ansibleを使って各環境にmackerel-agentを入れて監視対象ホストにしてみよう

今回はAnsibleを使って、mackerel-agentをインストールし設定ファイルに追記、エージェント起動しMackerelで監視対象ホストへ追加するplaybookを作成しました。

## mackerel
mackerelのサービスについては、まず[こちら](https://mackerel.io/ja/)でご確認ください。
アカウント作成時は、無料トライアルは14日です。まずは無料トライアルでどのようなサービスか触ってみて下さい。

## hosts

```
[web]
dev-web ansible_connection=ssh
stg-web ansible_connection=ssh
prod-web1 ansible_connection=ssh
prod-web2 ansible_connection=ssh

[dev]
dev-web ansible_connection=ssh

[stg]
stg-web ansible_connection=ssh

[prod]
prod-web1 ansible_connection=ssh
prod-web2 ansible_connection=ssh
```

## playbook

```mackerele-agent.yml
---
- hosts: web
  sudo: yes
  tasks:
    - name: install mackerel agent
      shell: curl -fsSL https://mackerel.io/assets/files/scripts/setup-yum.sh | sh

    - name: install yum mackerel angent
      yum: name=mackerel-agent state=installed

    - name: configure /etc/mackerel-agent/mackerel-agent.conf
      lineinfile: dest=/etc/mackerel-agent/mackerel-agent.conf line='apikey = "xxxxxxxxxxxxxxx"'

    - name: start mackerel-agent
      command: '/etc/init.d/mackerel-agent start'
```
覚えておくとあなたの時間が10分助かる、古いバージョンのJavaをダウンロードするページ。

バージョン指定で、昔のJavaをインストールしたい時ありますよね。
Android開発にJava7を使いたいとか。

そんな時にいつも迷うのです。どこからダウンロードしたらいいのさ、と。
そんな未来のあなたのためのソリューションがこちら。

# ザ・URL
http://www.oracle.com/technetwork/java/javase/archive-139210.html

ここにいろんなバージョンのいろんなJavaが載ってます。

## 追記
Mac用のJava 6はこちらから。
https://support.apple.com/kb/DL1572
Redmineで新しいチケットタブが表示されない事件

30分くらい迷ってアホらしかったのでメモ代わりに。

単純に、プロジェクトのトラッカーに何も選択されていなければ
「このプロジェクトは発行できるチケットがない」と判断されてしまい
「新しいチケット」のタブ自体が表示されないみたいです。

あー恥ずかしい…
> プロジェクト選択 > 設定 > 情報 > 最下部のトラッカーから選択

ちなみにタブに表示されるものは
「情報」の隣の「モジュール」タブから選択可能です。

ここばっかり見てて「あれ！？」ってなってた恥ずかしい...orz
c++ builder XE4, 10.2 Tokyo > .csvからリストをstatic const String[]へ読取り / "//"でコメントアウトもできる

```txt:動作確認
C++ Builder XE4
Rad Studio 10.2 Tokyo Update 2 (追記: 2017/12/26)
```

以下のような文字列のリストを.csvファイルに持たせる。

```list.csv
//L"AAA",
L"BBB",
L"CCC",
L"DDD",
```

やりたいのは、上記の.csvファイルを String型リストで取得すること。
ただし、"//"でコメントアウトしたものは除去したい。

参考にしたページ
http://www.gesource.jp/weblog/?p=3971
上記のリンク元
http://d.hatena.ne.jp/tt_clown/20100904/1283587136

上記を参考に以下のソースを用意した。

```cpp
static const String s_strings[] = {
#include "list.csv"
};
```

この方法だと、list.csv側で "//"で始まる文字列はコメントアウトされs_strings[]には残らなく、上記のlist.csvの例では L"BBB", L"CCC", L"DDD"がs_strings[]に格納される。

完全には削除したくはないが、実動作時のリストには追加したくない事項はコメントアウトして.csvに残せる。

### はまりポイント
(追記: 2017/03/03)

こちらの方法にてincludeとした場合、.csvファイルを変更して該当の.cppファイルをビルドしなおしても.csvファイルの変更が反映されない場合がある。

プロジェクトのクリーンアップをしてからビルドしなおすといい。
perlのsort記述まとめ（タブンまだほかにもある。

```pl
# 複数条件でソート
sort{ length $a <=> length $b || $a cmp $b } @list

# 数値のソート
sort {$a<=>$b} @list

# 文字のソート
sort {$a cmp $b} @list

# ２次元配列のソート
sort { $hash{$a}->{'xxx'} <=> $hash{$b}->{'xxx'} } keys %hash

# 配列の中のハッシュでソート
sort{$a->{'xxx'} <=> $b->{'xxx'}} @list
```
pepper Programming Tips -タッチパネル連打の防止-

タッチパネルを利用するpepperアプリを作成する方は沢山いらっしゃると思いますが、このタッチパネルの反応がイマイチよろしくありません。そのせいか、タッチパネルを連打する→タッチパネルは連打された回数は記憶している→連打された回数分アクションの実行→ユーザーのフラストレーションが溜まる、という悪循環になってしまいます。
それを防止するため、一時的にTouch Detectionを無効にします。

＜使用するボックス＞
・Touch Detection
・Say（サンプルとして便宜上Sayを用いています）

＜使用方法＞
1) Touch Detection/onTouchedとSay/onStartをつなぐ
2) Touch Detection/onTouchedとTouch Detection/onStopをつなぐ（Touch Detectionを強制的に一時無効にさせる）
3) Say/onStoppedとTouch Detection/onStartをつなぐ（Touch Detectionを再始動）

![touchDetection.jpg](https://qiita-image-store.s3.amazonaws.com/0/59491/011a43ca-ca9e-047f-8b12-7fc0f3496494.jpeg)
サンプルはタッチパネルをトリガーにpepperに『じゅげむ』を喋らせていますが、じゅげむ～の途中でタッチパネルを連打しても複数回実行はされません。
CSSのみで時計を作る


![スクリーンショット_2015-07-24_14_44_43.png](https://qiita-image-store.s3.amazonaws.com/0/1332/d6292f33-9287-d83b-6f8a-90830e4cffe4.png "スクリーンショット_2015-07-24_14_44_43.png")

JavaScriptを使わず、CSSのみで時計をつくります。
時計といっても秒針が回るだけです。

```html
<div class="clock">
  <!-- 数字 -->
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
  <span>6</span>
  <span>7</span>
  <span>8</span>
  <span>9</span>
  <span>10</span>
  <span>11</span>
  <span>12</span>
  
  <!-- 秒針 -->
  <div class="sec-hand"></div>
  
  <!-- 中央の丸いやつ -->
  <div class="center-circle"></div>
</div>
```

```css

.clock{
  position: relative;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  margin: 0 auto;
  border: 5px solid #333;
}

/* borderで針の形をつくる */
.sec-hand{
  position: absolute;
  left: 50%;
  top: 50%;
  width:0;
  height:0;
  border-top: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 120px solid #f00;
  transform-origin: left top;
  transform: rotate(30deg) translate(-50%, -100%);
  animation: tick 60s infinite linear;
}

/* 秒針のアニメーション */
@keyframes tick{
  from{
    transform: rotate(0deg) translate(-50%, -100%);
  }
  to{
    transform: rotate(360deg) translate(-50%, -100%);
  }
}

.center-circle{
  position: absolute;
  left: 50%;
  top: 50%;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: #000;
}


.clock span{
  position: absolute;
  font-size: 2em;
  width: 45px;
  line-height: 1em;
  text-align:center;
  left: 50%;
  top: 50%;
  transform-origin: left top;
}

/* 数字1~12までを30度ずつ回転して配置 */

.clock span:nth-of-type(1){
  transform: rotate(30deg) translate(0, -120px) rotate(-30deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(2){
  transform: rotate(60deg) translate(0, -120px) rotate(-60deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(3){
  transform: rotate(90deg) translate(0, -120px) rotate(-90deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(4){
  transform: rotate(120deg) translate(0, -120px) rotate(-120deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(5){
  transform: rotate(150deg) translate(0, -120px) rotate(-150deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(6){
  transform: rotate(180deg) translate(0, -120px) rotate(-180deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(7){
  transform: rotate(210deg) translate(0, -120px) rotate(-210deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(8){
  transform: rotate(240deg) translate(0, -120px) rotate(-240deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(9){
  transform: rotate(270deg) translate(0, -120px) rotate(-270deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(10){
  transform: rotate(300deg) translate(0, -120px) rotate(-300deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(11){
  transform: rotate(330deg) translate(0, -120px) rotate(-330deg) translate(-50%,-50%); 
}
.clock span:nth-of-type(12){
  transform: translate(0, -120px) translate(-50%,-50%); 
}

```

ポイントはtransform-originで回転の中心を変えているところと座標変換の順番。
[WIP] データストレージを使う際に考えること


RDBMSかNoSQLか
--------------------

- MongoDBとRDBMSの使い分けについて [Open database life: ムック「データベース徹底攻略」 - MySQL/Redis/MongoDB/Redshift](http://opendatabaselife.blogspot.jp/2014/03/mysqlredismongodbredshift.html)
- 「先に楽をして後で苦労するか、先に苦労して後で楽をするか」
- 大多数のサービスは成功せずに死ぬので、MongoDB採用による技術的負債は顕在化しにくい。旨みの部分（設計コストを抑えられる）だけ使える（けどサービスが死んでるので旨みとか言ってる場合じゃない）

#### PostgreSQLのJSONサポート

RDBMSでKVSの旨みがとれる？

BLOBは別のテーブルへ
---------------------

TEXTやBLOBなど、データ量の大きな列は別のテーブルに移したほうがいい。そもそもバイナリデータはどうしてもDBに入れないといけないかよく検討すべき。

* バックアップ/レストア時の時間短縮
* `SELECT *`したときに余計にスクロールしたりしないので、運用時に少し幸せになる


定型のカラムたちって持つべきなの？
----------------------------------

* 更新者 update_user
* 更新日時 updated_at
* 作成者 create_user
* 作成日時 created_at

みたいなやつら

論理削除は悪なのか
--------------------

    ユーザーは論理削除などという言葉を使わない。
    ユーザーは削除が論理なのか物理なのかなんて気にしない。
    エンジニアは内部事情を語りすぎる。

論理削除したくなったとき、ユーザーがそのシステムでなにをしたいのかを見つける。それは"退会"や"絶版"などだったりするかもしれない。それらの言葉のほうがデータやユースケース、ドメインを正しく表現できる。
論理削除はおうおうにしてデータモデルをじゅうぶん考えられてないケースで現れてくる。

けっきょく削除フラグじゃん？そうかもね。でもよりわかりやすい言葉のほうが良くない？

大規模データだから削除コスト重いから論理削除？そういうケースならいいんじゃないの？考えたうえでの選択であることが大切。

* [RDB - DELETE_FLAG を付ける前に確認したいこと。 - Qiita](http://qiita.com/Jxck_/items/156d0a231c6968f2a474)
* [論理削除が云々について - mike-neckのブログ](http://mike-neck.hatenadiary.com/entry/2015/03/24/231422)
* [論理削除フラグという名の死亡フラグ - @ledsun blog](http://ledsun.hatenablog.com/entry/2015/03/27/015203)
* [Kazuho's Weblog: 論理削除はなぜ「筋が悪い」か](http://blog.kazuhooku.com/2015/03/blog-post_26.html)
* [Re: 論理削除はなぜ「筋が悪い」か - Blog by Sadayuki Furuhashi](http://frsyuki.hatenablog.com/entry/2015/03/26/080627)

オペレーションミス対策/データの復旧
----------------------------------

たまにオペミス対策としての論理削除という話があるが、それでは不十分。`UPDATE`でほかのカラムが更新されたらどうするの？それも対策しときたくない？

バックアップ/レストアの基本として必ず事前に検証しておくこと。

* 基本として適切なgrantを管理する
  * そもそもオペミスが起こらないようにする
* MySQL 遅延レプリケーション？
  * ストリーミングレプリケーションしつつ遅延レプリケーション？富豪的だけどそれもいいか
* Oracle FLASHBACK TABLE
  * DDL変更すると対応できなくなるので注意
* PostgreSQL PITR？
  * 復旧に停止が必要だからしんどい

このへん本気でやるなら、商用DB使ったほうが幸せになれそう。コストかけてもそれでも欲しいかを考えたい。

データのライフタイム
---------------------------

古いデータはアーカイブに残す？いつ？どれくらいの頻度で参照する？

アーカイブから戻すのにかかる時間は？

IDの採番
--------------

- [InstagramのIDシャーディングについて | Siguniang's Blog](https://siguniang.wordpress.com/2013/01/23/sharding-ids-at-instagram/)
- [シーケンスの代わりにuuidをIDとして使う | Siguniang's Blog](https://siguniang.wordpress.com/2013/03/17/stop-using-numbers-as-ids-just-use-uuids/)
- [アプリ - Facebook, Twitter, Instagram等がどうやってIDを生成しているのか まとめ - Qiita](http://qiita.com/daisy1754/items/98a6e6b17d8161eab081)
- [軽量なTime-based ID生成器”shakeflake(仮称)”について | SmartNews 開発者ブログ](http://developer.smartnews.com/blog/2013/07/31/shakeflake-is-a-tool-for-generating-unique-id-numbers/)
- [twitter/snowflake · GitHub](https://github.com/twitter/snowflake/)
JavaScriptで◯◯分前を実装する

JSでTwitterとかFacebookとかSNSでよく表示される◯◯分前の実装
検索しても変なライブラリー入れるのばっかりヒットするので作った

```js
function displayTime(unixTime) {
  var date = new Date(unixTime)
  var diff = new Date().getTime() - date.getTime()
  var d = new Date(diff);

  if (d.getUTCFullYear() - 1970) {
    return d.getUTCFullYear() - 1970 + '年前'
  } else if (d.getUTCMonth()) {
    return d.getUTCMonth() + 'ヶ月前'
  } else if (d.getUTCDate() - 1) {
    return d.getUTCDate() - 1 + '日前'
  } else if (d.getUTCHours()) {
    return d.getUTCHours() + '時間前'
  } else if (d.getUTCMinutes()) {
    return d.getUTCMinutes() + '分前'
  } else {
    return d.getUTCSeconds() + '秒前'
  }
}
```

```
console.log(
  displayTime(1437715788375)
)
```
Wisp : Libraries

Wisp currently does not have much of a standard library, but why bother reinventing the wheel?

With [Mori](http://swannodette.github.io/mori/), you basically have the power of Clojure's data structures in your hands, effectively turning wisp into ClojureScript without the overhead of the entire JVM, plus it loads fast.

```clj
(ns com.hello-world 
  (:require [mori :as m]))
(def a (m.vector [1 2 3]))
(console.log (last (m.cons a 4)))
;=4
```

Or maybe you're just looking for some functional programming library to help you out as you do your work, like [Rambda](http://ramdajs.com/) or [lodash-fp](https://github.com/lodash/lodash-fp/).

```clj
(ns com.hello-world 
  (:require [ramda :as r]))
(def a [1 2 3])
(console.log (r.apply (Math.max a))) ;Showcasing interop from different libraries
;=3
```

So basically you can just mix and match any of the libraries available on the web on your own by doing `npm install {library-name} --save` and then use them directly from wisp, while enjoying the power of homoiconicity.
git > タグV0.3.* をリモートごと消し去る

SourceTreeでタグを複数消したい(リモートからも消したい)。

V0.3.0
V0.3.1
V0.3.2
....
というV0.3.*をすべて消す場合の方法。

1. (git)ターミナルを開く
2. git tag -l | grep "V0.3." で関係ないタグが表示されないか確認
3. git tag -l | grep "V0.3." | xargs git tag -d でタグをローカルから削除
4. git push --prune --tags origin でリモートからも削除

<font color=red>失敗すると困ったことになるので、よくわからなければ一個ずつ消したほうがいい。</font>

参考になったページ
http://qiita.com/ngyuki/items/6eb46e9a3ddc75781cbc
HPのスイッチ(Procurve)に設定を適用してファームウェアのバージョンを上げたい

タイトルの通りです。

## シリアルコンソール

とりあえず初期設定をするためにシリアルコンソールを取りたいので以下の記事を参考にしながらつなぐ。

  * [osx,yosemite - OSX 10.10 Yosemite で USBシリアル変換ケーブルを使う - Qiita](http://qiita.com/waiha8/items/1ccdb9249ea59ee52d3c)

`screen /dev/tty.usbserial 9600`で入ることができる。

## 設定を流し込む

operatorモードとmanagerモードがあって使えるコマンドとかが違う。

operatorモードの場合はmanagerモードになる。

```
HP Switch> enable
HP Switch#
```

起動時の設定は`show config`で見ることができる。変更中の設定は`show running-config`で見ることができる。設定は`write`しないと保存されないので再起動時に消えるで注意。

設定を流したい場合は`configure`か`config`のどちらかを打つと、『グローバルコンフィギュレーションレベル』というのになれるのでそこで設定を貼る。既に設定されているスイッチがあれば`show config`した結果を貼り付けるのがラク。

## ファームウェアのバージョンを上げる

とりあえずファームウェアをダウンロードする。`show config`とかでProductNumberというものが分かるのでそれを使う。ProductNumberがJ9280Aなら以下の様なURLに行く。

https://h10145.www1.hp.com/Downloads/SoftwareReleases.aspx?ProductNumber=J9280A

ちゃんとしたリンクがどこにあるのか謎。

### tftpサーバーを立てる

ファームウェアをスイッチ上でダウンロードするためにtftpサーバーを立てる。Macなら最初から入っているのでそれを起動する方法を紹介する。

  * [Mac OS XでTFTPサーバーを起動する - 戦場のプログラマー](http://blog.pg1x.com/entry/2014/03/15/222459)

この記事に大体全部書いてある。

`/System/Library/LaunchDaemons/tftp.plist`に設定があるのでこれを起動する。`launchctl load -w /System/Library/LaunchDaemons/tftp.plist`で起動できる。`sudo lsof -i:69`で起動しているか確認できる。用が済んだら`sudo launchctl unload -w /System/Library/LaunchDaemons/tftp.plist`してサービスを停止する。

デフォルトでは`/private/tftpboot`ディレクトリ以下が公開されるが、無理に変更しない方が良さそう。公開されているディレクトリ以下にファームウェアのファイルを置く。

### ファームウェアを適用する

MacとスイッチのIPが付いているポートを繋いで同一ネットワーク内に所属させる。そうしたらMacのtftpサーバーからダウンロードして適用すればよい。

  * [Upgrading ProCurve firmware via TFTP — Evil Routers](http://evilrouters.net/2009/02/02/upgrading-procurve-firmware-via-tftp/)

この記事に大体全部書いてある。

```
# tftp経由でダウンロードして適用する
copy tftp flash 192.168.1.12 R_11_25.swi primary

# 確認する
show flash

# 再起動
reload

# バージョンを確認
show version
```
PHPがセーフモードの場合、BASIC認証できるようにする

Apacheモジュールではなく、
cgi版PHPを使用している場合、basic認証が使えない。

使えるようにするには、
```
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*) 
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1] 
```
を、.htaccessに追加するといい。
Linux版 AVG インストール

<h1>Linux版AVG インストール</h1>
OS:CentOS release 6.3 (Final)
※32bitのパッケージしか無いけど、ld-linux.so.2を入れて動かす。
http://free.avg.co.jp/download-prd-alf

<h3>■ダウンロード・解凍</h3>
>wget http://download.avgfree.com/filedir/inst/avg2013flx-r3118-a6926.i386.tar.gz
>tar zxf ./avg2013flx-r3118-a6926.i386.tar.gz

<h3>■インストール</h3>
>cd ./avg2013flx-r3118-a6926.i386
>./install.sh

```
===================================================
   AVG Anti-Virus for Linux/FreeBSD installation
===================================================
Do you want to continue? (yes/no):yes

規約がバーと表示されるので、qキーで出る

Do you agree with the license? (yes/no):yes

Operating system is RedHat Linux or its fork Fedora, CentOS, ... (x86_64) (Y/n):Y

Under which user should AVG Anti-Virus run [root]:Enter

What group should be used for AVG Anti-Virus [bin]:Enter

Creating destination directories...
Directory /opt/avg doesn't exist. Create? (Y/n):Y

AVG Anti-Virus for Linux/FreeBSD successfully installed.
Would you like to display README now? (Y/n):n

Would you like to run AVG setup script now? (Y/n):
Starting AVG AV
Starting avgd                                              [失敗]
```
<h3>ld-linux.so.2 追加</h3>
>yum -y install ld-linux.so.2

<h3>AVG起動</h3>
>/etc/rc.d/init.d/avgd start

<h3>AVG アップデート</h3>
>avgupdate

<h3>AVGでスキャン</h3>
例えば自動的に感染ファイルを治療して /var/www/vhost/ 配下だけスキャンする場合
>avgscan -l /var/www/vhosts/

例えば自動的に感染ファイルを削除して /var/www/vhost/ 配下だけスキャンする場合
>avgscan -t /var/www/vhosts/

例えば自動的に感染ファイルを隔離して /var/www/vhost/ 配下だけスキャンする場合
>avgscan -u /var/www/vhosts/

例えば自動的に感染ファイルを治療か削除か隔離して /var/www/vhost/ 配下だけスキャンする場合(未検証)
>avgscan -ltu /var/www/vhosts/
5秒でわかる！MongoDB 3 でログローテート(logRotate)を手動で行う方法


# logRotate を手動行う方法

mongo Shell で MongoDB に接続し、以下のコマンドを実行すると logRotate できます。

```bash:mongo>
use admin
db.runCommand( { logRotate : 1 } )
```

# logRotate 実行時のログ

```bash
### MongoDBログファイルを確認
$ ls /var/log/mongodb
mongo.log                      output.log

### mongo Shell 起動
$ mongo
MongoDB shell version: 3.0.4
connecting to: test

### admin データベースに切り替え
mongo> use admin
switched to db admin

### ログローテート(logrotate)を実行
mongo> db.runCommand({ logRotate: 1 })
{ "ok" : 1 }

### mongo Shell 終了
mongo> exit
bye

### MongoDBログファイルを確認
$ ls /var/log/mongodb
mongo.log                      output.log
mongo.log.2015-07-24T04-09-47
```

簡単ですね。

# 参考

- Rotate Log Files — MongoDB Manual 3.0.4<br>http://docs.mongodb.org/manual/tutorial/rotate-log-files/
ruby で timezone を指定して Time#strptime する

問題: ruby の Time#strptime を使って、文字列を Time オブジェクトに変換したいのだが、その際に timezone を指定したい。が、strptime には timezone 引数がない。

```ruby
require 'time'
Time.strptime('2015-01-01', '%Y-%m-%d') #=> 2015-01-01 00:00:00 +0900

# おれが欲しいのは 2015-01-01 00:00:00 -0800 なんだーー！！
```

ActiveSupport は使わない。スレッドセーフじゃなくなるので `ENV['TZ']` も使わない。

## 数値形式の場合

[+-]HH:MM, [+-]HHMM, [+-]HH のような数値形式で指定する場合

strptime の %z を利用できる。

```rb
timezone = "-08:00"

date = "2015-01-01"
format = "%Y-%m-%d"

time = Time.strptime("#{date} #{timezone}", "#{format} %z") #=> 2015-01-01 00:00:00 -0800
```

## Region/Zone 形式の場合

[tzinfo](https://rubygems.org/gems/tzinfo) gem を使わざるを得ない

```rb
timezone = 'America/Los_Angeles'

date = "2015-01-01"
format = "%Y-%m-%d"

require 'tzinfo'
time = Time.strptime(date, format) #=> 2015-01-01 00:00:00 +0900
utc_offset = time.utc_offset #=> 32400
tz = TZInfo::Timezone.get(timezone)
zone_offset = tz.period_for_utc(time).utc_total_offset #=> -28800
time.localtime(zone_offset) + utc_offset - zone_offset #=> 2015-01-01 00:00:00 -0800
```

tzinfo はJST, PST のような略記には非対応。
tzinfo が利用している [IANA Time Zone Database](http://www.iana.org/time-zones)にそのような情報がないため。

## Timezone Abbreviations

JST, PST のような略記には strptime が一部対応している。ただし、https://bugs.ruby-lang.org/issues/12190 に起票した通り、Time.strptime よりも DateTime.strptime のほうが対応しているものが多かったりする。

しかし、例えば CST とかいた時に Central Standard Time (USA) であるべきなのか、China Standard Time であるべきなのかは意見のわかれるところで、Rubyとしてはあまり頑張るべきではない、という結論に至っているようだ、

なので、今回は UTC ぐらいはサポートするとして、その他はサポートしない方向。

## まとめるとこう

```rb
require 'time'
require 'tzinfo'

# [+-]HH:MM, [+-]HHMM, [+-]HH
NUMERIC_PATTERN = %r{\A[+-]\d\d(:?\d\d)?\z}

# Region/Zone, Region/Zone/Zone
NAME_PATTERN = %r{\A[^/]+/[^/]+(/[^/]+)?\z}

def strptime_with_zone(date, format, timezone)
  time = Time.strptime(date, format)
  _utc_offset = time.utc_offset
  _zone_offset = zone_offset(timezone)
  time.localtime(_zone_offset) + _utc_offset - _zone_offset
end

def zone_offset(timezone)
  if NUMERIC_PATTERN === timezone
    Time.zone_offset(timezone)
  elsif NAME_PATTERN === timezone
    tz = TZInfo::Timezone.get(timezone)
    tz.current_period.utc_total_offset
  elsif "UTC" == timezone # special treatment
    0
  else
    raise ArgumentError, "timezone format is invalid: #{timezone}"
  end
end
```

```rb
puts strptime_with_zone("2015-01-01", "%Y-%m-%d", "Asia/Taipei")
#=> 2015-01-01 00:00:00 +0800
```

=> gem にしました https://github.com/sonots/time_with_zone
csharp > Thread > IsBackGround プロパティ > すべてのフォアグラウンドスレッドが終了しなければプロセスは終了しませんが、バックグランドスレッドが終了しなくてもプロセスは終了します。

http://codezine.jp/article/detail/135

> プロセス内のすべてのフォアグラウンドスレッドが終了した時に、そのプロセスは終了し、同時にすべてのバックグランドスレッドは強制的に終了させられます。逆に言えば、すべてのフォアグラウンドスレッドが終了しなければプロセスは終了しませんが、バックグランドスレッドが終了しなくてもプロセスは終了します。

>　IsBackgroundプロパティのデフォルト値がfalseのため、何も指定しないとフォアグラウンドスレッドになってしまうことに注意してください。このことを知らないと、「メインスレッドが終了したのになぜかアプリケーションが終了しない」と頭を悩ませることになります。

<hr>
carrierwave + fog(Amazon S3) + RMagick で解像度によるバリデーションを行う方法

fogを使わない場合なら、解像度によるバリデーションは以下の方法があります。

- [【日本初?】CarrierWaveでアップロードされた画像の横幅などをValidateする方法](http://qiita.com/unosk/items/c93bcc9baa2c9bd2b30c)

ところが、こいつをfogと組み合わせると、最初の一回しか動かず、既に画像が含まれているモデルのバリデーションをしようとすると以下のようなエラーになります。

```ruby
Errno::EEXIST: File exists @ dir_s_mkdir - /home/example/example.com/releases/1/uploads
... 27 non-project frames
28
File "/home/example/example.com/releases/1/app/controllers/products_controller.rb" line 100 in add_image
... 113 non-project frames
```

クラスリファレンス見ると、 `from_blob` ってのが使えそうだったので参考記事のコードのうち`config/initializers/carrierwave.rb` を以下のような感じに書き換えると動いた。

```diff
- image = Magick::Image.read(current_path).shift
+ image = Magick::Image.from_blob(file.read).shift
```

## 備考

おそらくバリデーションする度にS3からデータを落としてきてるので、バリデーション回数が多いサービスでは気をつけた方が良いです。 EC2などS3から近いサーバーでない場合、速度にも結構な影響が出ると思われます。

## 参考

- [【日本初?】CarrierWaveでアップロードされた画像の横幅などをValidateする方法](http://qiita.com/unosk/items/c93bcc9baa2c9bd2b30c)
- [Ruby+ImageMagick Version 2.12.0 User's Guide and Reference](https://rmagick.github.io)
    - とくにこの辺 https://rmagick.github.io/image1.html
環境名に使える英単語

環境名に使えそうな日本語と英単語を探してみた。
xxサーバーの名称にも使えるかも。

|環境名|英語|
|--:|:--|
|開発|development|
|試験|test|
|実験|experimentよりもexperimentationかも|
|試用|trial|
|評価|assesment|
|批評／論評|review|
|検証|verification|
|最終確認|staging|
|予行|rehearsal|
|演習|drill|
|本番|production|
[Node.js]ファイルDB「NeDB」を使ってみた

先日「Node学園 16時限目 ES2015発行記念」に参加させていただきました。
その発表の中でファイルDBである「NeDB」を知れたので試してみました。
基本的には以下のパワポの内容を実行しているだけです。

http://www.slideshare.net/isamusuzuki54/loop-backapiswift-46901252?next_slideshow=1


準備：
`npm install nedb --save`

ソースコード：

```lang:nedb_test.js
var NeDB = require('nedb');
var db = {};
db.users = new NeDB({
  filename: 'usersfile'
});

db.users.loadDatabase();

// insert
db.users.insert({name: 'hoge'});
db.users.insert({name: 'fuga'});
db.users.insert({name: 'uga'});

db.users.insert([
  {name: 'foo'},
  {name: 'bar'}
  ], function(err, newDoc){
    console.log("[INSERT]");
    console.log(newDoc);
});

// find
db.users.find({name: 'fuga'},
  function(err, docs){
    console.log("[FIND]");
    console.log(docs);
});
db.users.find({name: /f*uga/},
  function(err, docs){
    console.log("[FIND F*]");
    console.log(docs);
});

// remove
db.users.remove(
  {name: 'fuga'},
  {multi: true},
  function (err, numRemoved){
    console.log("[REMOVE]");
    console.log(numRemoved);
});
db.users.remove(
  {name: 'uga'},
  {multi: true},
  function (err, numRemoved){
    console.log("[REMOVE]");
    console.log(numRemoved);
});
```

実行結果

```
%]node nedb_test.js
[INSERT]
[ { name: 'foo', _id: 'ShGylbRFFiR4nZcR' },
  { name: 'bar', _id: '7Kkhma6FdLUzQI7o' } ]
[FIND]
[ { name: 'fuga', _id: '8AKesKQfsnvVOdob' } ]
[FIND F*]
[ { name: 'fuga', _id: '8AKesKQfsnvVOdob' },
  { name: 'uga', _id: 'vbDsvmXtaB5xHNYo' } ]
[REMOVE]
1
[REMOVE]
1
```

実行後のファイル(usersfile)の内容：

```
{"name":"hoge","_id":"WuA7LFB50CWMnSX2"}
{"name":"fuga","_id":"8AKesKQfsnvVOdob"}
{"name":"uga","_id":"vbDsvmXtaB5xHNYo"}
{"name":"foo","_id":"ShGylbRFFiR4nZcR"}
{"name":"bar","_id":"7Kkhma6FdLUzQI7o"}
{"$$deleted":true,"_id":"8AKesKQfsnvVOdob"}
{"$$deleted":true,"_id":"vbDsvmXtaB5xHNYo"}
```

いやぁこんな簡単にDBを利用できるようになるなんてすばらしいですね！
利用できるAPIはMongoDBに準拠しているらしいので、
しっかりとしたDBに移行する際にも楽に対応できるかもしれないのがまた素敵ですね。

インストールするとついてくる次のマニュアルを見れば使い方も大体把握できると思います！

マニュアル：
node_modules/nedb/README.md
iOS9 で Universal Links が動かない


## はまった
[ここ](http://qiita.com/mono0926/items/2bf651246714f20df626)の通りにやっても動かなかった。

###### 動作環境
 - Xcode 7.0 beta 3 (7A152u)
 - iphone5 実機 iOS9


はまった点は２点

1. jsonファイルを何の証明書で証明するか
    - json ファイルを置くサイトの証明書で動いた。 apple の開発証明書でいけると書いてある記事もあったがいけなかった

2. app インストール時に app に書かれたドメインの `apple-app-site-association` を読みに行くはずだが読みに行ってくれない
    - `applinks:hoge.com` を `Assosiated Domain` に書けばいいとみんな書いていたが、それだけでは読みに行ってくれなかった
        - `webcredentials:hoge.com` も書いたら上手く行った


## 参考にしたサイト
http://engineering.pinterest.com/post/116646224624/shared-web-credentials-a-simpler-way-to-log-in
http://techlife.cookpad.com/entry/2015/06/05/110000
http://sonson.jp/blog/2014/09/27/Handoff3/

## おまけ
ここのサンプルソースで動かしてみるのもいいかも
https://github.com/sonsongithub/HandoffSample
クックパッドの app が既に対応していたので動きは参考になりました。
WP CLIでまとめてプラグインを有効化にする

改善点まだまだだけど、初めてawk使ったらびっくりするくらい簡単にできたのでメモ代わりに。

```
wp plugin list | awk '{print $1}' | while read f ; do wp plugin activate $f ; done
```
**改善したいところ**

* activeにしたいものを指定する
* activeなものをエスケープする
AngularJSのngOptionsで表示をカスタマイズするメモ

[Plunkr](http://plnkr.co/edit/xrynDGtUtcLmeda0zuWY?p=preview)

[ngOptions](https://docs.angularjs.org/api/ng/directive/ngOptions)でasなどを使うとオブジェクトのフィールドを選んだりできるが、ちょっと凝ったフォーマットにしたい場合は、スコープのメソッドを使える。

```html:template
  <body ng-controller="TestCtrl as test">
    <select ng-model="test.selectedItem"
      ng-options="item as test.formatItem(item) for item in test.items">
    </select>
  </body>
```

```js:controller
myApp.controller('TestCtrl',  function() {
  this.items = [
      {name:'foo', age:'25'},
      {name:'bar', age:'14'}
    ];
    
  this.formatItem = function(item) {
    return item.name + ' (' + item.age + ')';
  };
  
  this.selectedItem = null;
});
```

ngOptionsで、リストのインデックスを使いたい場合、次のように`(index, item)`のようにすると、indexに配列のインデックスが入る。

```html:template
    <select ng-model="test.selectedItem"
      ng-options="item as test.formatItem(index, item) for (index, item) in test.items">
    </select>
```

```js:controller
  this.formatItem = function(index, item) {
    return '[' + index + '] ' + item.name + ' (' + item.age + ')';
  };
```
SSL証明書・秘密鍵・CSRファイルのペア確認方法

SSL証明書取得後、SSL証明書・秘密鍵・CSRファイルの**ペア(組み合わせが正しいか)確認**をopenssl・md5sumコマンドで確認します。

## ペア確認するコマンド

以下、コマンドの実行結果(チェックサム値)が同じであれば、ペア(組み合わせ)が正しい。

* SSL証明書ファイルのチェックサム取得

```bash:
$ openssl x509 -noout -modulus -in <SSL証明書ファイル> | openssl md5
```

* 秘密鍵ファイルのチェックサム取得

```bash:
$ openssl rsa -noout -modulus -in <秘密鍵ファイル> | openssl md5
```

* CSRファイルのチェックサム取得

```bash:
$ openssl req -noout -modulus -in <CSRファイル> | openssl md5
```

## 実行例

例) `www.example.com`のSSL証明書・秘密鍵・CSRファイルのペア確認

```text:SSL証明書ファイル一式
├── www.example.com.crt # SSL証明書ファイル
├── www.example.com.pem # 秘密鍵ファイル
└── csr.txt             # CSRファイル
```

```:SSL証明書ファイルの確認
$ openssl x509 -noout -modulus -in www.example.com.crt | openssl md5
(stdin)= d41d8cd98f00b204e9800998ecf8427e # <- 値を確認
```

```:秘密鍵ファイルの確認
$ openssl rsa -noout -modulus -in www.example.com.pem | openssl md5
(stdin)= d41d8cd98f00b204e9800998ecf8427e # <- 値を確認
```

```:CSRファイルの確認
$ openssl req -noout -modulus -in csr.txt | openssl md5
(stdin)= d41d8cd98f00b204e9800998ecf8427e # <- 値を確認
```

実行結果が同じなら、ペアは正しい。

以上です。
【メモ】MySQLのテキストデータ型


## VARCHAR型とTEXT型の話

MySQLだとテキストデータ型でもたくさん種類があったので、メモ

#### CHAR型
文字数を指定。長さが固定される。
ただし、255文字まで。

#### VARCHAR型
バイト数の指定。文字列の長さは変動。

#### TEXT型
巨大なテキストデータを保存する。


今回は300字以内のテキストデータを保存したかったので、VARCHAR型を選択。
さくらスタンダードでhtmlをphpとして動作の際の注意

ちょっと凡ミスと言うか、勘違いというか、忘れていたと言うかさくらインターネットにまで問い合わせしたので自分の恥さらしをしておこうとおもいましたので。

拡張子htmlでphpとして動作させたい話自体は良くある話で、内容は変わってないのでやり方の細かい話は他を当たって下さい。
（ちなみにSEO的にやりたい人が多かったようですが、今ではGoogle様はhtmlでもphpでも検索結果に影響が出ない事になってますので、SEO的には（たぶん）意味が無い事はご理解下さい。）

＝＝htmlをphp動作簡単な流れ＝＝＝
1.共有フォルダにあるphp-cgiをサイトのwwwフォルダ直下にコピーしてきて、php.cgiとして保存。
2.www直下の.htaccessに以下を記載（.htaccessが無ければ新規に作成する）

```htaccess:.htaccessに追記
Action myphp-script /php.cgi
AddHandler myphp-script .php .html
```
＝＝ここまで＝＝
これでhtmlの拡張子でphpとして動作します。
今では他にやり方があるのかもしれませんが、さくらスタンダードではこれが通常の対応になるんじゃ無いかと思います。

このサーバで作業をしたのも２～３年も前？ですっかり作業した事自体忘れていたので今回トラブルになりました。

さくらスタンダードにはコントロールパネルが有り、基本的な設定などはコンパネ内で出来るようになっています。
その中に、「PHPバージョンの選択」という物があります。

この前までさくらスタンダードではしばらくの間　5.2.17　がPHPの標準になっておりました。
で、5.3になり、今では標準が5.4となり、選択肢には5.6が出てきております（今回の件で知ったがｗ）

でWEBアプリを追加で作る事になり、予約等の時間操作を多用する関係からPHPでDatetimeを使おうとするのは妥当な流れかと思います。
が、ここで問題となるのがDatetimeをサポートしたのが5.3からって事なんですね。
でコンパネ内で何も考えずに5.4を選択して現状のPHPが正常動作してるのを確認して、対象のアプリを作った訳です。
・・・が動かない。
どうしてもDatetime::addやDatetime::diffが定義エラーが出るのです。
同じさくらスタンダードで最近借りた別サーバではほぼ同じ物が問題なく動いている・・・・
オブジェクト型だろうが手続き型だろうがエラーが出る・・・・
不具合だ！って思い、勝ち誇って（なぜ？）何も考えずに２回もさくらのサポートさんにメールしてしまいました。

でそこで返ってきたのが
「お客さん、自分でPHPのバイナリ設置して動作させてない？」
このメールを見た瞬間に背筋がピン！って立ちましたよｗ

最初の作業でphp-cgiをコピーして来てますが、それによってサイト内は全てこのPHPバイナリで動作している事を私はすっかり忘れていやがった訳です。
要するにコンパネ内でどれだけPHPのバージョンを選択しようが、実際はhtmlをphpで動作させるためにコピーしたバイナリ（ここでは5.2.17）で動作していた訳です。

そりゃDatetimeも正常動作せんわ！！！

今後の為に自分の恥をさらしておこうと言うお話でした。
AndEngine 重なったSpriteでのタッチイベント制御

重なったSpriteでタッチイベントがうまく動作せず、調査したときのメモ
[ここを参考にしました](http://blog.livedoor.jp/sprits_zrgtpg/archives/7801031.html)
#Touchイベントは登録順に探して最初に見つかったものを対象にする

重なったSpriteオブジェクト spriteA,spriteBがあったとして

````java
scene.registerTouchArea(spriteA);
scene.registerTouchArea(spriteB);
````

とした場合、spriteAの状態がEnableだろうがmVisibleがfalseだろうが、
spriteAに登録したイベントが動作する

ただし、下記のようにすると後から登録したほうが優先される

````java
scene.setOnAreaTouchTraversalFrontToBack();
````

最初のリンクにある通り、onAreaTouchedをオーバーライドするか、

````java
scene.unregisterTouchArea(spriteA);
````

このように都度削除するしかないかな。
【Google Analytics】最低限のスパム対策

#わかりやすい参考サイト
[リファラスパムと対策について](http://otaku-farmer.com/blog/refferal-spam)
[リファラスパムの一覧と対策方法まとめ](http://tadasan.net/referer-spam/)
[リファラルフィルタが効かないスパムへの対策](http://www.yatani-pr.com/marketingblogs/1402/)


#リファラルスパムとは
>"よく言われているのが次の二つのようです。

>    1. 自身のサイトを宣伝するため
>    2. リファラスパムのアドレスから飛ばされるサイトに悪意のあるマルウェアなどを仕込んでウィルスの感染を誘う"<br>
>    <sub>引用元: </sub> <i><sub>[リファラスパムと対策について](http://otaku-farmer.com/blog/refferal-spam)</sub></i>



ブログをやっている方やサイトを運営されている方は経験されていると思いますが、被リンクを受けるとリファラルとしてトラフィックが登録されます。
被リンクを受けているとは思えないサイトで、突如リファラルのアクセスが以下のように増えたので、不思議に思い調べてみたらSPAMでした。せっかく調べたので対策方法などを覚書。

![Screen Shot 2015-07-23 at 10.55.18 AM.png](https://qiita-image-store.s3.amazonaws.com/0/69560/eb17a456-37b2-472f-7b7e-ba68cc0feebf.png)

"Reporting">"Acquisition">"All Trafic"でReferralのURIを確認できる。
<b>＊勿論、これらのリンクはクリックしないように！！</b>
![Screen Shot 2015-07-23 at 10.55.31 AM.png](https://qiita-image-store.s3.amazonaws.com/0/69560/38ac4da0-839a-ac6f-c6c6-33f7effc3276.png)


数万PV/月 を稼ぐサイトでは誤差かもしれませんが、上記のように1000PV/月 程度のサイトでは9割異常がSPAMだったなんてことも多々有ります。ぬか喜びを防ぐため、そして正確なアクセス数を把握するためにまずは最低限の対策をしましょう。

以下の２ステップで設定します。
    1. リファラルSPAMのフィルタリング
    2. 上記フィルタから漏れるSPAMのフィルタリング


#1. リファラルSPAMのフィルタリング
[このサイト](http://tadasan.net/referer-spam/)を参考にさせて頂きました。

###① "Admin"から"All Filters"へ
![ all_filters.png](https://qiita-image-store.s3.amazonaws.com/0/69560/cc43c765-5464-9d79-ffd2-e942f36d6f34.png)

###② "+New Filter"を選択
![newfilter.png](https://qiita-image-store.s3.amazonaws.com/0/69560/ec516f1a-0df6-80d3-baf3-9cc68cdf9344.png)


###③ 以下のようにフィルタを設定
"Filter Pattern"には[このサイト](http://tadasan.net/referer-spam/)にリストがあるので、それらをフィールドへコピーして下さい。
![save.png](https://qiita-image-store.s3.amazonaws.com/0/69560/5faa3944-ef57-d9e0-b6b8-233bb922e226.png)


#2. リファラルフィルタから漏れるSPAMのフィルタリング
[このサイト](http://www.yatani-pr.com/marketingblogs/1402/)を参考にさせて頂きました。
以下二つのフイルタを作成します。

###① 言語設定フィルタ
![Screen Shot 2015-07-24 at 10.46.25 AM.png](https://qiita-image-store.s3.amazonaws.com/0/69560/a7bdd7ed-543b-c086-305e-bea9f3f9c55a.png)

上のように言語が(not set)になる原因としてはGoogleがキーワード等の情報が取れなかった場合に発生するようですが、基本スパムと思って良いでしょう。https通信などセキュリティ常の理由で情報が取得できない場合は(not provided)になるようですので。
<i>"~share-buttons.com"</i> 系に多いようです。

以下のようにフィルタを設定します。
![Screen Shot 2015-07-24 at 10.40.51 AM.png](https://qiita-image-store.s3.amazonaws.com/0/69560/4dddf2c4-c60f-92aa-0586-24967415631b.png)


###② ブラウザ設定フィルタ
![Screen Shot 2015-07-24 at 10.55.26 AM.png](https://qiita-image-store.s3.amazonaws.com/0/69560/e44ad659-0dab-675d-a564-e07d17a3ccce.png)

上のようにブラウザ情報が取得できていないものです。<i>"Get-Free-Traffic-Now.com"</i> が該当するようです。
以下のようにフィルタを設定します。
![Screen Shot 2015-07-24 at 10.42.05 AM.png](https://qiita-image-store.s3.amazonaws.com/0/69560/a5eaa5f9-2172-8324-b8dc-cfdabe94704c.png)
Node.jsのHTTPサーバーフレームワーク（connect）を使ってHello Worldを返すHTTPサーバーを実装する


[connect](https://github.com/senchalabs/connect)はNode.jsで動くHTTPサーバーフレームワークです。connctを使って、HTTPリクエストに対して`hello world`と返すHTTPサーバーを実装してみます。

## 前提条件
事前に[Node.js](https://nodejs.org/)をインストールしておいてください。

## ソースコード
app.jsに以下のソースコードを記述します。

```js:app.js
const http = require('http')
const connect = require('connect')

// レスポンスの内容を指定します。
const app = connect()
  .use((req, res) => res.end('hello world'))

// HTTPサーバーを3000ポートで起動します。
http.createServer(app).listen(3000)
```

connectは、use関数を使ってモジュール（middlewareと呼びます）を登録します。
ここでは`hello world`だけを返すmiddlewareを登録します。

## ライブラリをインストール
ここからはターミナルで実行します。
利用するライブラリをインストールします。

```
npm i connect
```

## HTTPサーバーを起動

```
node app.json
```

## 動作確認

curlコマンドで確認するには

```
curl 'http://localhost:3000'
```

ブラウザで確認するには

```
open 'http://localhost:3000'
```

どちらも`hello world`が表示されます。
openはMac OS Xのコマンドです。Mac以外の人は、お好みブラウザで http://localhost:3000 を開いてください。

## HTTPサーバーを終了

`Ctrl + C`で終了します。

## 関連記事
[connectを使って静的なHTTPサーバーを実装する](http://qiita.com/ledsun/items/19a866faa44d364741d5)
モバイルで OPTPiX SpriteStudio を Unity で使うときの注意点(SS5PlayerForUnityはお勧めしません)

# 警告
※この情報は **SpriteStudio 5 Player for Unity (SS5PlayerForUnity) を対象にした内容** です。

2017年11月18日においては、最新の OPTPiX SpriteStudio は Ver. 6.0 であり、それに対応する Unity 用の公式のプレイヤープログラムは

https://github.com/SpriteStudio/SS6PlayerForUnity 

になります。

本ドキュメントは **SS6PlayerForUnity についてのものではありません** 。

# 要約
SpriteStudio 5 Player for Unity (SS5PlayerForUnity) を使うとUnityで再生できるとあるが、能力を過信するとモバイル環境(iOS/Android)では重くて実用に耐えないので、特に動きのあるゲームの部品としては使わない方が良い。

どうしてもバリバリ使いたい場合はちゃんと勉強研究して自作したほうが良い。

## 詳細
SpriteStudio 5 Player for Unity は OPTPiX SpriteStudio 5 で作られたデータを完動させるのが目的になっているので、パフォーマンスの心配をしてくれません。

https://github.com/SpriteStudio/SS5PlayerForUnity/issues/109#issuecomment-93979500

> 現状ですと、SS5Player for Unityは、「SpriteStudio5で作成したデータをできる限り忠実にUnity上に再現する」ために色々な追加処理を行っている部分があり、(処理内容が必然的に複雑にならざるをえないため)いささか動作そのものは（特に大量のアニメーションオブジェクトを画面上に表示した場合などに）重いと思われる点があるかもしれません旨、ご理解の程お願い致します。


現状も何も、このバージョンに移行する前から、ウェブテクノロジ社が作成して提供してる Unity 用のデータ再生機構はパフォーマンスの心配を一切していません。富豪的にやってます。

http://www.slideshare.net/webtechnologycorp/cedec2014-38952411

> じゃぁ、我々のタイトルは？ → 表示面積がネックになってそう → いやいや、オリジナルと同じモノしか出してないし → そもそもオリジナルは余裕で表示できてるよ！？ → SpriteStudioが最適化されていないΣΣ(ﾟдﾟlll) 

これ、最適化術！とか柔らかく書いてますけど、要は実戦に耐えるモジュールの提供は昔からやってないので自作した方が良いって話です。

## こういうときには使える
ゲーム中で、プリレンダリングのムービーシーンのように、決められた動きをする物をただ再生するだけの場合。

## こういうときは使えない
ゲームの中で、
https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%97%E3%83%A9%E3%82%A4%E3%83%88_(%E6%98%A0%E5%83%8F%E6%8A%80%E8%A1%93)
こういう意味の "スプライト" を期待している場合。SpriteStudio 5 Player for Unity は 

> 画面上の小さなキャラクタを高速に合成表示するための技術的な仕組み

ではないです。

## こういうのを期待してはいけない
繰り返しますが、
> 現状ですと、SS5Player for Unityは、「SpriteStudio5で作成したデータをできる限り忠実にUnity上に再現する」

と言う前提があるので、特にモバイル環境のような制限されたハードウェア上においては SS5Player for Unity が良い感じにゲームの部品になるような機能を提供することは期待できません。例えば、ゲーム中にプログラムの処理で変形させるであるとか、部分的に何かを差し替えてみるであるとか、動的にカスタマイズできるようなモジュールの提供はありません。

https://github.com/SpriteStudio/SS5PlayerForUnity/wiki/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9

ここらへん一読してみると分かりますが SS5Player for Unity は単なる Player であり、そこに対して細かく制御を入れるような、モジュールのような利用は想定されていません。

## モバイル環境における OPTPiX SpriteStudio 5 と Unity の連携のベストプラクティス

1. プログラマが OPTPiX SpriteStudio 5 で作成できるデータ・属性の性質を理解する
2. デザイナが OPTPiX SpriteStudio 5 で想定データを作成する
3. 作成された想定データを元に、プログラマとデザイナが話し合い、特にどの機能が必要でどの機能が不必要かをまとめてルールを作る
4. ルールに基づき、デザイナは必要に応じてデータを作り直す。プログラマはUnity上での再生機構を良い感じに実装する
5. それでもパフォーマンスが出ない場合は 3 に戻りさらに機能を削る。

　とにかく OPTPiX SpriteStudio 5 で表現できることの全てを拾おうと思うと死にます。誰も幸せになりません。単なるアニメーション製作ツールとしては OPTPiX SpriteStudio 5 はぼちぼち優秀なので、デザイナがアニメを作りやすくなる、と言う部分については期待できますが、それを実際のゲームで利用するところについては、各実装単位ごとに十分な研究が必要です。

# しつこくまとめ
　モバイルが前提の話です。十分にパワフルなPC環境であれば力でゴリ押しできる可能性があります。

- OPTPiX SpriteStudio 5 さえ導入すれば簡単に動きのある絵を **ゲームに** 入れられると思うのは間違い
- **SS5Player for Unity に単なる単体データ再生以上の機能を求めない** 方が良い
- OPTPiX SpriteStudio 5 はアニメデータ作成ツールとしてのみ利用し、そこから出力されるデータを **ゲームで利用する実装については各自でやろう**
GoogleがオフィシャルにCocoaPods対応したので、Google Analyticsの取り込み指定を変更した


昨日、こんな嬉しいニュースがありましたね:
[iOS 向け Google SDK の入手は CocoaPods で - Google Developer Japan Blog](http://googledevjp.blogspot.jp/2015/07/ios-google-sdk-cocoapods.html)
(原文: [Google Developers Blog: Add Google to your iOS Apps with CocoaPods](http://googledevelopers.blogspot.jp/2015/05/add-google-to-your-ios-apps-with.html))


僕は今まで、[Specs/Specs/GoogleAnalytics-iOS-SDK at master · CocoaPods/Specs](https://github.com/CocoaPods/Specs/tree/master/Specs/GoogleAnalytics-iOS-SDK)の非公式ぽいものを使っていました。
オフィシャルな導入手順は、フレームワーク入れたり設定がちょっと面倒でしたので。


そういう状況だったので、オフィシャルにCocoaPods対応されたというのはとてもありがたいです。
というわけで、早速対応しました。

こちらにGoogleのCocoaPods一覧があります: 
[Install a Google SDK using CocoaPods | Google APIs for iOS| Google Developers](https://developer.google.com/ios/cocoapods#cocoapods_published_by_google)

これまで:

```
pod 'GoogleAnalytics-iOS-SDK', '~> 3.10'
```

対応後:

```
pod 'GoogleAnalytics', '~> 3.13'
pod 'GoogleTagManager', '~> 3.12'
```

下記のために、`GoogleTagManager`を使っていましたが、公式のものではそれが分離されていたので、別途指定して入れました。

- [iOSアプリで、Google AnalyticsのABテスト機能を使う その1 - Qiita](http://qiita.com/mono0926/items/c7abf2503cbccf26c5ab)
- [iOSアプリで、Google AnalyticsのABテスト機能を使う その2 - Qiita](http://qiita.com/mono0926/items/a45f2ba268bca964ef9b)

初め、この箇所だけビルドエラーになりましたが、それ以外はすんなり対応出来ました。
[一覧がある](https://developer.google.com/ios/cocoapods#cocoapods_published_by_google)ことで、今後他のGoogleのライブラリ導入するときも導入手順探したりする手間が省けるようになりますし、とても嬉しい対応でした（´-ω-｀）
[PHP]連想配列の中身をforeachで取り出す


phpで連想配列を扱う際にforeachの挙動に困った。


```php

<?php

/**
 * 配列の場合
 */
$arr = [1,2,3];

foreach($arr as $key){
    echo($key."arrkey\r\n");
}
//1arrkey 2arrkey 3arrkey

foreach($arr as $key => $value){
    echo($key."arrkey\r\n");
    echo($value."arrvalue\r\n");
}
//0arrkey 1arrvalue 1arrkey 2arrvalue 2arrkey 3arrvalue

```
これはOK

しかし、、、

```php

/*
 * 連想配列の場合
 */
$arr2 = [
    "ichi" => "1",
    "ni" => "2"
];

foreach($arr2 as $key){
    echo($key."arr2key\r\n");
}
//1arr2key 2arr2key

foreach($arr2 as $key => $value){
    echo($key."arr2key\r\n");
    echo($value."arr2value\r\n");
}
//ichiarr2key 1arr2value niarr2key 2arr2value

```

なんか**Keyの値変わってる！！！**

そう。正しくは、

```php

foreach($associativeArray as $value){

}

```

と

```php

foreach(associativeArray as $key => $value){

}

```

だったんだよ！！！
な、なんだってー(ry



以後、きをつけます。。


> 試験場所
> [phpfiddle](http://phpfiddle.org/)
はじめてのWordpress開発メモ

既にproductionで稼働しているWordpressの開発運用を引き継ぐことになったので、諸々メモっておく(随時更新)。

## 前提

- phpやったことない
- wordpress知ってるけど使ったことない
- 直近はRuby on Railsの案件を開発運用している。
- 他の言語経験もあるがサーバサイドメイン。フロント(js,css...etc)周りはとりあえずやっている程度。

## 開発環境

自分で作る必要はなく、とにかく下に任せる。あまりに力作で感動した。
http://vccw.cc/

実際の環境ではapache httpdではなく、nginxを使っているなどの差異があるが気にしない。

## REPL

Rubyでいうところのpry、Scalaでいうところのsbt、phpでいうところの？
http://psysh.org/

wordpressでうまいこと使うにはどうしたらいいのかと調べてみるとwpコマンドに使い方が書いてあった。
https://github.com/wp-cli/wp-cli/wiki/Example-Usage#integrate-with-psysh

```
curl psysh.org/psysh > psysh.phar
wp --require=psysh.phar shell
```
というか`wp shell`でいけた。

## レポジトリには何を突っ込めばよいのか

Wordpress開発では本体のコード、Pluginのコードそのものを自らのレポジトリで管理する必要があるが、画像のアップロード先などはignoreする必要がもちろんある。Githubがgitignoreファイル例を作ってくれているのでこれを使う

https://github.com/github/gitignore/blob/master/WordPress.gitignore

## print debug

面倒なことは抜きにしてprint debugしよう。

### var_dump()

とりあえずobjectをぶっこめば良い。

```php
<h2>ランキング</h2>
<div class="ranking">
<?php
$wpp = new WordpressPopularPosts();
$p = $wpp->get_popular();
var_dump($p);
?>
</div>
```

記事の人気ランキングを表示するので有名なPopular Posts Pluginでも、`define('WPP_DEBUG', true);`と設定しておくと、所々でvar_dumpする処理が書かれており、print debugが一般的な印象をうける

## 定数

wp-config.phpに諸々定義してある

```php
define('WP_DEBUG', false);
```

上のように定義すると

```php
if (WP_DEBUG)
```

というように利用できる

## themes/foo/functions.php 太り過ぎ問題

Wordpressの基本として、各テーマディレクトリ下のfunctions.phpが読み込まれるため、自分で開発したコードはこのファイルに追加することになる。100,200行ぐらいだったら、ファイル一枚見れば済むので全てをここに押し込めてもいいかなと思うが、今回メンテすることになったのは既に1600行に到達しようとしているので、追加していくのは避けたい。

外出しの方法は以下を参考にした。

http://wordpress.stackexchange.com/questions/1403/organizing-code-in-your-wordpress-themes-functions-php-file

プラグイン化するという方法もあるが、ファイルを分けてfunctions.phpで読み込むというのが一番簡単なので以下のようにする

```php
# functions.php

<?php 
require_once('includes/ad.php');
```

## RSSの中身を編集したい場合

SmartNewsに最適化したRSSを配信したいとのことで、独自のRSSを用意する必要が出てきた。下のページの通りなので参考にする
[WordPressでオリジナルのフィードを配信する方法（入り口）](http://qiita.com/kobayash/items/5bbfa1356e683e37ef35)

## query_posts, get_posts, the_postとかがどこから来ているのかさっぱりわからん

このドキュメント読もう
https://codex.wordpress.org/Function_Reference/query_posts
![alt](https://codex.wordpress.org/images/8/85/avoid_query_posts.png)
EAでsymbol()を使う際、他のMT4との互換性について


EAの中で特定の通貨ペアのみの処理を行う際に

```mql
if(symbol()== "USDJPY")
```
と記述したのだが、自分のPCでは動くのに他のPCでは動かないことがあった。
原因を教えてもらったら、どうやらMT4の種類によってはsymbol()の返り値が違うらしく。
後ろにrのつくものや、/がつくものがあるらしい。
なのでUSDJPYrなどであったため上手く動作しなかったのだ。

なので文字列が含まれていたらのif分に書き直した。皆様もご注意を。

```mql
if(StringFind(symbol(),"USD",0) != -1 && StringFind(symbol(),"JPY",0) != -1)
```

>http://fanblogs.jp/kitasanfx/archive/136/0
c++ builder > indy > IdUdpClient1->ReceiveString() > 切断時にipadr, portを初期化してしまう

```txt:動作確認
C++ Builder XE4
```

Indyではまったのでメモ。

```
res = m_IdUDPClient1->ReceiveString(m_host_ipadr, m_port, 300, m_encSJIS);
```

ReceiveString()は指定のホスト:ポートからの受信をする処理であるが、通信回線が切れた時、ReceiveString()を実行すると<font color=red>m_host_ipadrとm_portがクリアされる</font>、ようだ。

参照としての引数になっているのかは未確認。
C++ Builder上のヘルプでは
> public: __fastcall AnsiString ReceiveString(AnsiString VPeerIP, TIdPort VPeerPort,...

となっていて、参照渡しのようには見えないが。。。

m_host_ipadrとm_portを用いて IdUDPClient1を接続、送受信する処理を定期的にしていたが、通信切断後 m_host_ipadr==NULL, m_port=0となり、以後の送受信がすべて失敗するようになっていた。

<hr>
対応方法としては
- m_host_ipadr, m_portを退避する
- 別の変数を用意して、ReceiveString()時に使う
などがあるが、とりあえず独自関数を作って、値渡しでm_host_ipadr, m_portを渡して処理すると、通信切断時にこれらがクリアされなくできる。


```cpp
String __fastcall MyThread::MyReceiveString(TIdUDPClient *udpPtr, String hostIpadr, unsigned short port, DWORD rcvTimeout_ms, Idglobal::_di_IIdTextEncoding encoding)
{
//  IdUDPClient1->ReceiveString(m_hostIpadr, m_port,...)はネットワーク切断時に m_hostIpadr=NULL, m_port=0
//  にしてしまう。これを避けるため、独自の関数として引数を値渡しにして、もともとのm_hostIpadr, m_port へは
//  影響がないようにしている。

	String res;

	res = udpPtr->ReceiveString(hostIpadr, port, rcvTimeout_ms, encoding);
	return res;
}

```

使い方

```cpp
#if 1
			res = MyReceiveString(m_IdUDPClient1, m_host_ipadr, m_port, 300, m_encSJIS);
#else
			res = m_IdUDPClient1->ReceiveString(m_host_ipadr, m_port, 300, m_encSJIS);
#endif
```
[Android]Googleのセットアップウィザードについて

誰得情報ですが、Kitkat以降？に追加されたAndroid端末を初回起動するときに表示されるGoogleのセットアップウィザードについて少し調べたのでメモしておきます。

# Google Setup Wizard

初回起動時に表示されるあれです。
パッケージ名は`com.google.android.setupwizard`です。
セットアップ中はナビゲーションバーにはバックキーしか表示されず、システムバーにも限られた情報しか表示されません。
このアプリはOSSではなくGoogleのプリプロエタリなアプリなのでソースは公開されていないです。(多分。公開されていたら教えてください。)

仕組みは詳しく調べていませんが、Androidのソースコードに[com.android.setupwizard.navigationbar](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.0_r1/com/android/setupwizard/navigationbar/SetupWizardNavBar.java)という階層があるので、システムで用意されているようです。
CyanogenなどのカスタムROMでも同様のセットアップアプリが用意されているので、ベンダーなら作ることができるかもしれません。

## 起動方法

通常は初回起動時に勝手に起動されるのですが、もう一度やってみたい！というとき用に起動方法がのこされていました。

すでにこちらで紹介されていました。
[Androidで特殊なアップデート方法をした後にホームボタンが効かなくなった場合の対処法](http://qiita.com/oboenikui/items/5068cf3b2167f4d437b2)

以下のadbコマンド、というかintentを発行するだけで呼ぶことができます。
externedなComponentNameらしく、普通のアプリからでも起動可能なようです。

```
adb shell am start -n com.google.android.setupwizard/.SetupWizardTestActivity
```

debug用の機能っぽいのでいつの間にか削除されているかもしれません。

## セットアップが終了しているかの判別

標準APIで[SETUP_WIZARD_HAS_RUN](http://developer.android.com/reference/android/provider/Settings.System.html#SETUP_WIZARD_HAS_RUN)というものがあり、ContentResolverを使ってセットアップ実行済みかを取得することができるように書いてありますが、Google Setup Wizardではこの値は変更されず、取得できません。

考えてみれば、セットアップ実行前だと

* Google Playにアクセスできないのでアプリの新規インストールできない
* 設定画面もみれず開発者モードにできないのでadb installも出来ない
* ファイルマネージャーも開けない(そもそもない端末もありますが)のでapk直接インストールも出来ない

と、ほとんどのアプリの場合セットアップ前であることはあり得ません。
（カスタムROMやroot化端末でのプリイン？）
なので判別自体ほぼ不要ですが、ちょっと気になったので調べてみました。

rootを取得済みならセットアップウィザードアプリのPreferenceファイル等を調べれば分かりそうです。
そうでない場合、このアプリではセットアップ完了後にSetupWizardActivityのComponentをdisableに変更しているようですので、
`com.google.android.setupwizard/.SetupWizardActivity`
のintentが発行か可能か調べればだいたいの目安にはなりそうです。
参考:[SetupWizard AndroidManifest.xml](https://gist.github.com/shurane/5477555)

```java:example.java
PackageManager pm = context.getPackageManager();
Intent i = new Intent();
i.setClassName("com.google.android.setupwizard", "com.google.android.setupwizard.SetupWizardActivity");
List<ResolveInfo> list = pm.queryIntentActivities(i, 0);
if (list.size() == 0){
// 実行可能なActivityがない = セットアップが完了している
    return;
}

// intentの受け取り先が見つかった時点でsetup実行前の可能性が高いです。
// 念のためPackageManager.getComponentEnabledSettingで変更されたかを確認してもいいかもしれません。
// int enabledSetting = pm.getComponentEnabledSetting(new ComponentName(activityInfo.packageName, activityInfo.name));


```

仕様が変更される可能性もあり確実ではないと思いますが。。


## セットアップ終了、開始の検知

開始時と終了時にそれぞれBroadcastIntentを発行してくれているので、それを受信すれば検知できます。
親切ですね。

```
<!-- 以下のフィルターを任意のBroadcastReceiverに追加します。-->
<intent-filter>
<!-- 開始時に発行されていたIntent。名前的に他にも発行されているかもしれません -->
    <action android:name="com.google.android.setupwizard.CHECKIN_SUCCESS" />
<!-- 終了時に発行されていたIntent -->
    <action android:name="com.google.android.setupwizard.SETUP_WIZARD_FINISHED" />
</intent-filter>
```


# Android標準のセットアップ？

昔はcom.android.setupwizardというpackageNameのアプリが入っていたようです。
いつの間にか消えて（？）Googleのプリプロエタリなものに置き換えられています。
おそらくGoogle Playを利用する上でアカウントの設定など、初回に済ませておきたい項目ができたのでしょう。
もしくは戦略的な問題かと思われます。

昔のセットアップウィザードは忘れてしまいました。。

その頃はSETUP_WIZARD_HAS_RUNの設定値を見ることで正しくセットアップ状況を確認できたのかもしれません。
SlackにGoogle Calendar連携機能が追加されたので早速導入してみたら良い感じ♪


今朝、SlackにGoogle Calendar連携機能が追加されました。

- [Google Calendar Reminders Come to Slack | Several People Are Typing](http://slackhq.com/post/124767707715/googlecalendar)
- [Slack can now send you Google Calendar alerts](http://mashable.com/2015/07/23/slack-google-calendar/)

# 連携方法

おなじみの[Integrations](https://my.slack.com/integrations)ページから、[Google Calendar option](https://my.slack.com/services/gcalendar)を選びます。
---

![850bd517-29cd-5ba1-106e-730d95361f21.png](https://qiita-image-store.s3.amazonaws.com/0/19398/3a06d407-042b-44bc-2166-62cc32a1a996.png)


---
許可しましょう(　´･‿･｀)

![c294f198-d6ae-c1b2-3e52-f032086b1b39.png](https://qiita-image-store.s3.amazonaws.com/0/19398/f0ee926a-04ba-9e54-5db0-3f2e9f887792.png)


---

設定項目がかなり豊富です。
とりあえず全部オンにしてあとで不要なのを外せば良いかなと思って設定しました。

![Screen Shot 2015-07-24 at 8.06.02 AM.png](https://qiita-image-store.s3.amazonaws.com/0/19398/bbf58d49-7114-0425-3a71-8c03ff2eced3.png "Screen Shot 2015-07-24 at 8.06.02 AM.png")


---

無事に連携出来ました。

![f6f9940e-0573-cd44-8ccf-08b63c2ddd8c.png](https://qiita-image-store.s3.amazonaws.com/0/19398/750ff02b-53c8-a4d3-44ab-9e549aa0b496.png)


---

今は1つだけ連携した状態ですが、もっと追加可能です。

![Screen Shot 2015-07-24 at 8.11.51 AM.png](https://qiita-image-store.s3.amazonaws.com/0/19398/f25ee2a9-6605-1037-22a7-d03052f0713a.png "Screen Shot 2015-07-24 at 8.11.51 AM.png")


# 活用方法

僕の所属する[ookami](http://qiita.com/organizations/ookami)では、共有カレンダーが1つあり、とりあえずそれと#generalを連携しました。

![aa82e6b1-3b2e-3b3a-148a-5323951f6784.png](https://qiita-image-store.s3.amazonaws.com/0/19398/7890391f-80d2-1750-c78b-f4afed85991c.png)



また、いくつも連携出来るので、個人カレンダーとSlackbotを連携させて、個人的なリマインダーとして使うのも良いと思います。
![Screen Shot 2015-07-24 at 8.17.12 AM.png](https://qiita-image-store.s3.amazonaws.com/0/19398/6834d73d-3e4a-7752-17b0-37fb56483989.png "Screen Shot 2015-07-24 at 8.17.12 AM.png")



[今開発中のPlayer!](https://itunes.apple.com/jp/app/id897872395)では、PUSH通知チームが人力で厳選したニュースを定期的に配信していますが、それもたまに忘れちゃうことがあるようなので、そういうの防止にも活用できそうです。

# 使ってみて気づいた良い点

- 予定作成通知も来る
    - 他人が作った予定に気づきやすくなる
    - 設定オフも可能
[Sphinx] 「コピペで体験してみるSphinx」ハンズオン一覧

Sphinxのハンズオン一覧です。

まずは、手順書をコピペして、Sphinxでどんなことができるのか体験してみましょう!

# まずさわってみよう

* #1 Sphinx Quick Start: http://qiita.com/tcsh/items/b102d70212d97aede46f
* #2 入門編 (メモ書きからはじめる): http://qiita.com/tcsh/items/f4f09983a494a128db68

# Webコンテンツを作成してみよう

* #3 基礎編 (ディレクティブ for Web): http://qiita.com/tcsh/items/d0ef0a6a20c75f250e31
* #4 基礎編 (ロール for Web): http://qiita.com/tcsh/items/ea6894e301a36411ba6f

# ドキュメントを構造化してみよう

* #5 ドキュメント構造化 (初級: 複数ファイルを扱う): http://qiita.com/tcsh/items/3d9d39960581a0eab45d
* #6 ドキュメント構造化 (中級: 外部ドキュメント連携): http://qiita.com/tcsh/items/4b6a7da46858a49aaa33


# 環境構築 (参考)
 
* EC2インスタンスの作成 (Public): http://qiita.com/tcsh/items/ae8f1f0d706237327c5a
* Amazon LinuxにSphinxをインストールする: http://qiita.com/tcsh/items/67f7120e231f537e7604
* Amazon LinuxにMarcurialをインストールする: http://qiita.com/tcsh/items/f6466d8e0542aa7807ef
* Amazon Linuxにnginxをインストールする: http://qiita.com/tcsh/items/ab40d61944f4ab5ecd8d
* 後始末
    * EC2インスタンスの削除: http://qiita.com/tcsh/items/f2ac887777d374b1ad61