OmniAICreator/Qiita-1.07M huggingface dataset:
NodeJSからGitHub経由でブランチの作成、コミット、プルリクの作成をする

自動化できないかなと思って少し調べたのでメモ

# やりたいこと

* branchの作成
* ファイルの更新・コミット
* pull-reqの作成

# NodeJSからGitHubを叩く

[@octokit/rest](https://github.com/octokit/rest.js)のライブラリを使う。

GitHubのREST APIのNode IF。
node-githubから移行されたとのこと。

## ドキュメント

以下にAPIのドキュメントがある。
https://octokit.github.io/rest.js/

――が、実際はGitHub APIのラッパーなので、そちらと見比べながらやるのがいい。

## debugモード

> Set DEBUG=octokit:rest* for additional debug logs.

環境変数にセットすれば行けるらしい。

# やってみる

## 初期化

```ts
import Octokit from '@octokit/rest'

const octokit = new Octokit()
```

Enterprise環境とかだと設定が必要だったりするけど、叩くのはEnterpriseじゃないので設定しない。

## 認証

プライベートリポジトリや一部APIを叩くには認証が必要。
ocktokitにはいくつか認証方法が提供されているけど、今回はAccessTokenが手元にある前提で行う。

AccessTokenは本家で発行する、またはOAuthして取ってくる必要がある。
※例えばこう [koa+passportでGitHub認証](https://qiita.com/mizuki_r/items/2cd43dd88423cdf52592)

AccessTokenがあるなら `authenticate` を叩くだけ。

```ts
octokit.authenticate({
  type: 'token',
  token: accessToken,
})
```

返り値などは特にない。

参考: https://github.com/octokit/rest.js#authentication

## referenceの取得

つまりブランチ。作成したいブランチの元となるブランチの情報をとってくる。

```ts
const origin = await octokit.gitdata.getReference({
  owner: 'rymizuki',
  repo: 'example',
  ref: 'heads/master',
})
```

あくまでここで扱うのはreferenceなので、`heads/ブランチ名`になる。

参考: https://octokit.github.io/rest.js/#api-Gitdata-getReference

## referenceの作成

取得したreferenseから新しくreferenseを切る。

```ts
const ref = await octokit.gitdata.createReference({
  owner,
  repo,
  ref: 'refs/heads/test',
  sha: origin.data.object.sha,
})
```

元ブランチのshaから派生させる。
`ref`には「`refs`から始まり`/`を2つ以上含む」という制約がある。

なお、同名のreferenceを作成しようとするとエラーになる。

参考: https://octokit.github.io/rest.js/#api-Gitdata-createReference

## ファイルの取得

今回の要求としては「すでに存在しているファイルを上書き更新」なので、ファイルを取得する。

```ts
const content = await octokit.repos.getContent({
  owner,
  repo,
  ref: 'heads/test', // さっき作ったブランチの情報をとってくる
  path: 'README.md', // ファイルパス
})

// とってきたデータをデコードする
const data = new Buffer(content.data.content, content.data.encoding).toString()
```

参考: https://octokit.github.io/rest.js/#api-Repos-getContent

## ファイルの更新

コミットしてプッシュする。
以下のAPIを叩くことで、ファイルの送信、commitの作成をGitHub上で行うことができる。

```ts
const updateResult = await octokit.repos.updateFile({
  owner,
  repo,
  branch: 'test', // これはreferenceではなくbranch
  message: 'docs(README): なんやかんや', // コミットメッセージ
  path: 'README.md',
  content: new Buffer(`${ data }\n\n更新したよ`).toString('base64'), // base64にエンコードする
  sha: content.data.sha,
})
```

参考: https://octokit.github.io/rest.js/#api-Repos-updateFile

## PullRequestの作成

```ts
const pullreq = await octokit.pullRequests.create({
  owner,
  repo,
  head: 'test', // マージしたいブランチ
  base: 'master', // マージされたいブランチ
  title: 'README.mdを更新した', // pull-reqのタイトル
  body: 'ほにゃらら', // pull-reqの本文
})
```

参考: https://octokit.github.io/rest.js/#api-PullRequests-create

# まとめ

* ブランチの作成からPullReqの作成までの流れを紹介しました
* authenticateはaccessToken使っとくのが一番わかり易い
* refarenceとheadとbranchの関係を理解して使おう
* GitHub APIはとっても多機能だけど、使いこなせると便利そうですね
Vagrantでrails serverをするまで

メモ

#環境

・windows10
・Vagrant 2.0.3
・virtualbox 5.2.8
・box->centos/7 (https://app.vagrantup.com/centos/boxes/7)

#作業用フォルダを作成
(C:\Users\ユーザーネーム\MyVagrant)を作成
(C:\Users\ユーザーネーム\MyVagrant\App1)を作成


###コマンドプロントを開いてApp1に移動
```
$ cd C:\Users\ユーザーネーム\MyVagrant\App1
```
###Vagrantfile作成
```
vagrant init centos/7
```

#Vagratnfile
```
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "forwarded_port", guest: 3000, host: 3000
  config.vm.synced_folder "./share", "/vagrant", type: "virtualbox", create: "true"
end
```


```
$ vagrant up 
$ vagrant ssh
```

#RVM

###現在の場所
```
$ pwd

→/home/vagrant
```

###インストール
```
$ curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -
$ curl -sSL https://get.rvm.io | bash -s stable
```
###PATHを通す
```
//ディレクトリ内
$ ls -a // .bash_history /bash_logout .bash_profile ...

//.bash_profileを編集
$ vi .bash_profile

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

export PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH=$PATH:$HOME/.rvm/bin //←これを追加

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*
```
```
$ source .bash_profile //更新
```
#Ruby
###インストール
```
//インストール可能なバージョン
$ rvm install -l

$ rvm install 2.4.1
```
#Rails
###インストール
```
$ gem install rails

//とりあえず全gemをupdateしとく
$ gem update
```
#virtualbox側のfirewallを無効にする
firewallを無効にしておかないとつながりません。

```
# firewalld を無効にする
$ sudo systemctl stop firewalld.service

# OS 起動時もfirewalldが起動しないようにする
$ sudo systemctl mask firewalld.service
$ sudo systemctl list-unit-files | grep firewalld
```

#aa
```
//共有フォルダに移動
$ cd /vagrant
```
windowsの(C:\Users\ユーザーネーム\MyVagrant\App1\share)とvagrantの(/vagrant)は共有されています。

```
$ vi Gemfile

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
..
# gem 'mini_racer', platforms: :ruby //ここの#を外す
..
        ⇓
..
gem 'mini_racer', platforms: :ruby
..
```
```
$ bundle install
```

#アプリを作成


```
//作成
$ rails new TestApp

//TestAppに移動
$ cd TestApp

//サーバー起動
$ rails s -b 0.0.0.0
```

以上でサーバー起動までの道順でした。
windows側のブラウザで( http://localhost:3000 )と入力すると
起動できたのが確認できると思います。
C#でPingしてみよう

ネットワーク上の共有フォルダからファイルを取得したいが、事前にアクセスできるかどうかを確認してから取得したほうが例外を投げずに済むようにするには、というところで下のような感じでさくっとサンプルを書いてみました。
なお非同期的にやりたい場合はSendAsyncメソッドでTask\<PingReply\>を取得できます。


```Ping.cs
using System;
using System.Collections.Generic;
using System.Linq;
//Pingを使用するにはこの名前空間が必要。
using System.Net.NetworkInformation;

namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            var ping = new Ping();
            var replies = new List<PingReply>();

            for (int i = 0; i < 5; i++)
            {
                //Sendメソッドでリクエストを送り、結果を格納したPingReplyクラスを返す。
                var reply = ping.Send("google.com");
                replies.Add(reply);
            }

            //Pingの返答が正しく返ってきたときはStatusプロパティでIPStatus列挙のSuccessを返す。Success以外はFalseである
            var isSucceeded = replies.Any(reply => reply.Status == IPStatus.Success);
            Console.WriteLine($"ping succeeded is {isSucceeded}");

            //時間がどれだけかかったかを知りたい場合はRoundtripTimeプロパティで取得可能
            var averageTime = replies.Average(reply => reply.RoundtripTime);
            Console.WriteLine($"ping average time is {averageTime}");


            Console.ReadLine();
        }

    }
}
```
koa+passportでGitHub認証

[Koa](http://koajs.com/)でGitHubのAccessTokenが欲しくなって調べてやってみたのでメモ。
[Passport](http://www.passportjs.org/)の[GitHubStrategy](https://github.com/jaredhanson/passport-github)を使えば簡単。

## passportの設定

認証に必要な情報をStrategyを通してセットアップする。

passportはexpress準拠に作られているが、[koa-passport]()がexpressのAPIとの互換性を保持してくれるのでそいつを使う。
scopeについては[本家](https://developer.github.com/apps/building-oauth-apps/scopes-for-oauth-apps/)を参照。


```ts:passport.ts
import passport from 'koa-passport'
import { Strategy } from 'passport-github'

passport.use(new Strategy({
  clientID:     process.env.GITHUB_OAUTH_CLIENT_ID,
  clientSecret: process.env.GITHUB_OAUTH_CLIENT_SECRET,
  callbackUrl: 'http://localhost:3000/auth/github/callback',
  scope: ['repo'],
}, (accessToken, refreshToken, profile, cb) => {
  cb(null, { accessToke }) // XXX ここでユーザ認証を行う
})

// sessionにつっこむようにシリアライズする
passport.serializeUser(function (user, done) {
  done(null, user)
})

// sessionから取り出すときにデシリアライズする
passport.deserializeUser(function (user, done) {
  done(null, user)
})

export default passport
```

koa-passportでもpassportと同様に扱える。

## 認証用のルーティング設定

ドキュメントからほぼコピペでいい。

```ts:router.ts
import Router from 'koa-router'
import passport from './passport'

const router = new Router()

router.get('/auth/github', passport.authenticate('github'))
router.get('/auth/github/callback', passport.authenticate('github', {
  successRedirect: '/',
  failureRedirect: '/auth/github/failled',
}))
```

## koaでpassportを有効化

```ts:app.ts
import Koa from 'koa'
import logger from 'koa-logger'
import bodyParser from 'koa-bodyparser'
import session from 'koa-session'

import router from './router'
import paspport from './passport'

const app = new Koa()

app.use(logger())
app.use(bodyParser())

app.keys = ['secret'[
app.use(session({}, app))

app.use(passport.initialize())
app.use(passport.session())

app.use(router.routes())
app.use(router.allowedMethods())

app.listen(3000)
```

## まとめ

* passportを使うと簡単にOAuthできる
* koaでもpassportできる
eclipse  パッケージorg.springframework.boot.web.servlet.supportは存在しません

##背景
①SpringBootで作成したwarを外部のTomcat上で動かしたいな～と思った。
②Tomcatにデプロイし、接続してみたが404エラー
③あ、@SpringBootApplicationのクラスにSpringBootServletInitializer継承させるの忘れてたわ。(・ω<) てへぺろ☆
④は？gradle build通らないんだけど！（他のプロジェクトのgradle buildは通る）

##謎のエラー

``` error.text
Task :compileJava FAILED
C:\Users\******\workspace\test01\src\main\java\apl\TestApplication.java:6: エラー: パッケージorg.springframework.boot.web.servlet.supportは存在しません
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
                                                   ^
C:\Users\******\workspace\test01\src\main\java\apl\TestApplication.java:9: エラー: シンボルを見つけられません
public class NegoApplication extends SpringBootServletInitializer{
                                     ^
  シンボル: クラス SpringBootServletInitializer
エラー2個
```

##原因
該当プロジェクトだけなぜか、GRADLE_HOMEを設定していた。
（他のgradle buildが通るプロジェクトは、eclipseのプラグインにくっついてくるgradleを使用していた）

…それぞれ見に行くところが違うのか？
##行った対策
①該当プロジェクトのビルドパスを全消し
②コンソール開いて gradle ecripse を実行
③build.gradleの設定も、GRADLE_HOMEを見ないように設定

→成功

##所感
最初からGRADLE_HOME使えって話だよな
以後気を付けます。
railsをproductionモードで起動する[Rails 5.1]

docker + Railsの環境において、productionモードで起動した話
「ちげぇよ！」って話があれば教えてくださいー

[追記]
Railsのバージョンは5.1
5.2になると少し違った方法になる


# 内容
- Railsをproductionモードで起動
- 環境はdockerにRailsコンテナとmysqlコンテナが存在するパティーン

# やったこと
## secret_key_baseを設定
### secret_key_baseを生成する
下記コマンドを実行

```bash:bash
rails secrets:setup
```

実行すると
- secrets.yml.key
- secrets.yml.enc
が生成される

### secrets.yml.encを設定
secrets.yml.encを書き換える
下記コマンドを実行

```bash:bash
EDITOR=vim rails secrets:edit
```

EDITORで指定したエディタで開かれる（今回はvim）
※コンテナ内でvimが使用できない場合は、apt-getでインストール

```bash:bash
apt-get update
apt-get install vim
```

secret_key_baseの末尾に以下を記載

```bash:vim
production:
  secret_key_base: xxxxxxxxxxxxxxxxxxx
```

xxxx...は、「secrets.yml.key」に出力された値を記載すること

config/environments/production.rbに設定を追記

```ruby:config/environments/production.rb
config.read_encrypted_secrets = true
```

## assetsのプリコンパイル
### railsの設定を追加
config/evnironments/production.rbに設定を追記
（場合によってはconfig/environments/production.rbの方が都合が良い場合もある）

```ruby:config/evnironments/production.rb
config.serve_static_files = true
config.assets.js_compressor = :uglifier
config.assets.js_compressor = Uglifier.new(harmony: true)
config.assets.paths << config.root.join("node_modules")
```

yarnでadmin-lte(bootstrapのテンプレート）をnode_modules配下に配置してるので、
ブラウザからassetsを参照した際にnode_modules配下も参照するようにする

スタイルシートやapplication.scssに`@import`が存在する場合、
application.scssのrequireに変更する
※既存の`@import`は削除して良い


## 環境変数の設定
### docker-compose.ymlの変更
dockerコンテナを使用しているため、
コンテナ内の環境変数を変更

```yml:docker-compose.yml
environment:
  RAILS_ENV: 'production'
  RACK_ENV: 'production'
```

unicornを使用してる場合は起動コマンドも同様に変更

```yml:docker-compose.yml
command: bundle exec unicorn -c config/unicorn.rb -E production -l 3000
```


## いよいよコマンド実行
プリコンパイルを実行

```bash:RAKE
rake assets:precompile
```

`public/assets`配下にプリコンパイルされたファイルたちが生成される
プリコンパイルのタイミングは、
- 手動
- 初回接続時
- デプロイ時
の設定が可能（ここでは触れない）


## コンテナ起動！
以上を設定すればコンテナがproductionモードで起動する（はず）
productionモードであることを確認するには、
ブラウザからRoutingErrorを発生させた時に、
ルーティング一覧が表示されなければOK（「管理者はログを見てね」みたいなやつが表示される）


# 最後に
結構ハマったけど、なんだかんだできた
データベースは`databese.yml`の設定を変えてあげれば
接続先やテーブル名の変更が可能


## 参考にさせていただいた記事様
[Rails 5.1のencrypted secretsの運用について考える](https://qiita.com/kikunantoka/items/dd22cf51071b93ba5b62)

ありがとうございました。
Node.js® のインストール

Node.js® を Mac ＋ ダウンロードパッケージからインストールしてみたときの記録。

##ダウンロード
https://nodejs.org/en/download/
よりダウンロード。

Macにインストールするため
「macOS Installer (.pkg)」を選択

![FireShot Capture 1 - Download I Node.js - https___nodejs.org_en_download_.png](https://qiita-image-store.s3.amazonaws.com/0/240814/b150c5be-0be5-0630-25f6-9fe806ecdb87.png)

##インストール実行
ダウンロードしたファイルをダブルクリックで実行
![スクリーンショット 2018-04-28 15.09.36.png](https://qiita-image-store.s3.amazonaws.com/0/240814/b3a9c54d-8329-9e4d-1429-ad28e2cb39db.png)

「続ける」ボタンでダイヤログを進めてインストールを完了
![スクリーンショット 2018-04-28 15.11.50.png](https://qiita-image-store.s3.amazonaws.com/0/240814/dd409ea7-5534-79ff-bba5-ff91188d6de9.png)

`Make sure that /usr/local/bin is in your $PATH.` 

とのことなので 確認

```
echo $PATH
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
```

入っているのでOK

入っていない場合は

```
vi ~/.bash_profile
```

で
.bash_profileに下記を追加
`export PATH=$PATH:/usr/local/bin`

## バージョン確認
```
$ node -v
v8.11.1
$ npm -v
5.6.0
```
## 実行確認
ターミナルで 対話形式で実行を確認

```
node
> console.log("Hello World!!");
Hello World!!
undefined
```

動いているのを確認

・・・
パッケージをダウンロードしてインストールしてしまったけど
今後のことを考えると
NodeBrew を インストールして バージョンを容易に切り替えるようにしておいた方がよかったかも （・ ・；）
Pocketにストックしてる記事の中からランダムにSlackに投稿するbot作った


# 概要

タイトルまんま、Pocketにストックしてる記事の中からランダムにSlackに投稿するbot作りました。

# 経緯

会社でデータ解析やる部活に入ってるんですけど、部活といってもSlackのチーム上に存在するだけで人数も少ないので閑散とした感じです。

普段Pocketに技術関連記事をストックしているので、定期的に記事をSlackに投稿して会話のタネ・活性化に繋がれば、と作りました。
（github作ったものを上げてみたかったというのもある）
（自分が記事を再度読む機会を無理やり作りたかったのもある）

# 使い方

## github

https://github.com/theMistletoe/SlackBot4Pocket

ただのpythonスクリプトなのでpython入ってれば動くはずです。
PocketとSlackのAPIキーとかのユーザー情報は環境変数経由で取得するようにしているので、
予め設定しておく必要があります。

cronで実行する際は適切に環境変数が読み込まれるように、shellでexportしてからpython蹴るなど若干工夫が必要です。
（Google Compute Engine上にcron設定したけど環境変数周りで無駄に苦戦した、、、）


# 実装

pythonもなんちゃってで書いてるのでpythonライクにきれいに書けてないと思います。

内容はPocketのAPI使ってストックされた記事のJSONデータを取得、Dictからランダムに記事を抽出してSlackのAPIで特定のチャネルに投稿します。


# 参考


- https://qiita.com/daikiojm/items/759ea40c00f9b539a4c8
- https://www.glamenv-septzen.net/view/185
- https://stackoverflow.com/questions/9733638/post-json-using-python-requests
- https://qiita.com/hiro93n/items/2bc4daeb3092bd32c2eb
- https://qiita.com/taigamikami/items/2713856b9f3c3b90f6fd
- https://qiita.com/Tocyuki/items/25092d0d589ab52e83e4
- https://api.slack.com/apps/AA7T7FHL4
- https://www.esz.co.jp/blog/55.html
- https://qiita.com/ykhirao/items/0d6b9f4a0cc626884dbb
- http://blog.masasuzu.net/entry/20100403/1270262298
- https://www.sejuku.net/blog/20915#randomrandintab
- https://stackoverflow.com/questions/11174024/attributeerrorstr-object-has-no-attribute-read
- https://stackoverflow.com/questions/27415193/dict-object-has-no-attribute-read
- https://www.pythonweb.jp/tutorial/dictionary/index4.html
- http://d.hatena.ne.jp/Cassiopeia/20070602/1180805345
- https://teratail.com/questions/100920
- https://qiita.com/yasuhiroki/items/a569d3371a66e365316f#post
- https://getpocket.com/developer/docs/v3/retrieve
- https://qiita.com/masahirok_jp/items/c4f0d8bb5f55a114e31b
- https://getpocket.com/developer/apps/
- https://getpocket.com/connected_applications
- https://syncer.jp/pocket-api-matome
- https://api.slack.com/web
- https://teratail.com/questions/108589
- http://www.sakito.com/2012/09/python-pep-8-e501-line-too-long.html
- https://api.slack.com/docs/message-attachments
- https://qiita.com/m-nakada/items/643909ca14f306a74999
- https://qiita.com/manabuishiirb/items/5c85a8902472d2a664e8
- https://gabekore.org/mac-path-environmental-variable
- http://hazimarino.blogspot.jp/2010/09/python.html
【Laravel入門】プロジェクト作成から起動まで

先日Laravelの研修会に参加し、環境構築から会員認証までの機能を教わってきた。忘れないうちに色々メモしておこうと思う。Laravelは、自分が通っていたスクールで学んだRuby on Railsに似ているらしい。これも何かのご縁だろうか？

ちなみにこの前までCakePHPの環境構築をしていたのだが、一旦それは置いておく；

# ブロジェクトの作成

CakePHPの環境構築の時に、Laravelに必要な環境構築も一通りできていたようだ。悪戦苦闘の様は以下の記事をご覧いただきたい。

[HomebrewでCakePHP環境構築〜準備編](https://qiita.com/33yuki/items/ae8182d6024ea0657df2)
[HomebrewでCakePHP環境構築〜インストール編](https://qiita.com/33yuki/items/9e0553e3de06cad25370)
[HomebrewでCakePHP環境構築〜Apache編](https://qiita.com/33yuki/items/2de0d8ad0263fcd855de)
[HomebrewでCakePHP環境構築〜MySQL編](https://qiita.com/33yuki/items/80ed7ed46aed4eb8559f)


プロジェクトの作成方法は、自分の知る限り２種類ある。

- Laravelをインストールして``laravel new``で作成
- composerコマンドを使って作成

研修会で学んだのは後者だが、自分でも色々試したかったので両方紹介する。

# laravel newで作成

``laravel new``を実行するためには、事前にLaravelをインストールする必要がある。

以下コマンドを実行する。

```
$ composer global require "laravel/installer=~1.1"
```

次に環境変数を登録する。``.bash_profile``に環境変数を追記しよう。その後、sourceコマンドで内容を反映させるのもお忘れなく。

```
$ echo "export PATH=~/.composer/vendor/bin:$PATH" >> ~/.bash_profile
$ source ~/.bash_profile
```

これで``laravel new``が使えるようになった。プロジェクトを作成したいディレクトリに移動し、早速実行しよう。

```
$ cd ディレクトリ名
$ laravel new プロジェクト名
```

これでOK。ちなみにLaravelのバージョンは最新のものになる。確認してみよう。今回はバージョン5.6.18になった。

```
$ cd プロジェクト名
$ php artisan -v
Laravel Framework 5.6.18

# 以下略
```

実は環境変数を登録する時、少し寄り道をした。内容を記事にしたので、何かの参考になれば幸いである。

[.bash_profile追記時のホームディレクトリの表示について](https://qiita.com/33yuki/items/40a3cff85a94f145a9c0)

# composerコマンドで作成

次はcomposerコマンドで実行する。このコマンドには以下の特徴がある。

- Laravelのバージョンを指定できる。
- インストールや環境変数の設定が上手く出来なかった場合に使える。

``laravel new``ではバージョン指定が出来ないらしい。こっちのコマンドの方が需要あるんじゃ・・・と思いつつ作業を進める。

```
$ composer create-project laravel/laravel プロジェクト名 --prefer-dist
Installing laravel/laravel (v5.6.12)

# 以下略
```

最初、コマンド実行後の``Installing laravel/laravel (v5.6.12)``を作成されるプロジェクトのバージョンと勘違いしていたが、違っていた。

あえてバージョンを指定しない場合、5.6.18が入った。``laravel new``で作成した時と同じ、最新のバージョンだ。

```
$ cd プロジェクト名
$ php artisan -v
Laravel Framework 5.6.18

# 以下略
```

## バージョンを指定する

今回はバージョンを指定することにした。研修会では5.5系を使用したので、それで進めてみる。``"5.5.*"``と指定すると、5.5系の最新バージョンがインストールされるのだ。

```
composer create-project laravel/laravel プロジェクト名 --prefer-dist "5.5.*"

# 以下略
```

```
$ cd プロジェクト名
$ php artisan -v
Laravel Framework 5.6.18

# 以下略
```

もちろん以下のコマンドを試せば5.6.18が入る。5.6系の最新バージョンは5.6.18だからだ。

```
$ composer create-project laravel/laravel プロジェクト名 --prefer-dist "5.6.*"
```

# 起動

無事プロジェクトを作成できたら、早速起動してみよう。

```
$ cd プロジェクト名
$ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>
```

``localhost:8000``にアクセスするとLaravelの起動が確認できる。この瞬間はやはり嬉しい。

なお、終了したい時は``ctrl+C``で。

これまで動作確認のためにプロジェクトを量産してしまったので、必要のないプロジェクトはディレクトリごと削除した。

```
$ rm -rf プロジェクト名 
```

今日はここまで。
Requests+lxmlでXPathを使ってみたい

##状況
* Python初心者
* BeautifulSoupに慣れていない
* 少しだけ触ったことがあるXPathを使いたい
* SeleniumからChromeを動かすほどではないページの内容を取得したい

##サンプルHTML
```html:sample.html
<html>
    <head>
        <title>Sample</title>
    </head>
    <body>
        <div class="contents" id="item01">
            <h1 class="title">Sample #01</h1>
            <p>sample text</p>
        </div>
        <div class="contents" id="item02">
            <h1 class="title">Sample #02</h1>
            <ul class="list">
                <li>List #1</li>
                <li>List #2</li>
                <li>List #3</li>
            </ul>
        </div>
        <div class="contents" id="item03">
            <h1 class="title">Sample #03</h1>
            <img src="image01.jpg" alt="image01">
        </div>
    </body>
</html>
```

##Requestsで取得したhtmlをlxmlに渡す
```python
import requests
import lxml.html

url = "http://hoge.hoge/sample.html"

response = requests.get(url)
html = lxml.html.fromstring(response.content)
```

##タグの取得
###単純なXPath
```python
htmltag = html.xpath("//div")
# lxml.html.HtmlElementのリストが返される

>>> print(htmltag)
[<Element div at 0x***********>, <Element div at 0x***********>, <Element div at 0x***********>]
```
###順番を指定したXPath
```python
htmltag = html.xpath("//div[2]/ul/li[1]")
# <li>List #1</li>
```
###CSSセレクタを使ったXPath
####id
```python
htmltag = html.xpath("//div[@id='item01']")
# ヒットするタグが1件でもリストが返る

>>> print(htmltag)
[<Element div at 0x***********>]
```
####class
```python
divs = html.xpath("//div[@class='contents']")
```
###文字列を含むタグを取得するXPath
```python
#class名に「i」を含む全てのタグ
htmltag = html.xpath("//*[contains(@class, 'i')]")
for item in htmltag:
    print(item.tag)

h1 # <h1 class="title">Sample #01</h1>
h1 # <h1 class="title">Sample #02</h1>
ul # <ul class="list">
h1 # <h1 class="title">Sample #03</h1>
```
##タグ内情報の取得
###タグの中身
```python
htmltag = html.xpath("//div[1]/p")

>>> print(htmltag[0].text)
sample text
```
###タグの属性
```python
htmltag = html.xpath("//div[1]")

>>> print(htmltag[0].attrib)
{'class': 'contents', 'id': 'item01'}

>>> print(htmltag[0].attrib["class"])
contents

#XPathでも取得可
htmltag = html.xpath("//div[1]/@class")
>>> print(htmltag[0])
contents
```
###タグの名称
```python
htmltag = html.xpath("//div[1]")

>>> print(htmltag[0].tag)
div
```
(iOS) ImageViewのContent Modeを理解してデザイナーとエンジニアの距離を近づけよう


## 前置き
　大規模の新規アプリを作っていて、デザイナーとやりとりするところで、うまくImageViewでの画像表示について伝えることができませんでした。これまで動的に変化する画像サイズを扱ったことがなく、曖昧に理解したままやっていたので、中身についてちゃんと理解しようと思った。
　
## 環境
- swift 4.0
- Xcode 9.2

## (本題) ImageViewのContetModeを理解する
高さ 200px, 幅 200pxのImageViewを画面の中心に置いた状態でContentModeによってどのように画像の表示が変わるのかを見ていきます。
ちなみにContent Modeはstoryboard上ではImageViewを選択したときのInspectorで設定できます。

![Main_storyboard_と_iPhone_8_Plus_-_11_2.png](https://qiita-image-store.s3.amazonaws.com/0/135757/a2a41547-d237-f1d1-a10a-33e17c701d08.png "Main_storyboard_と_iPhone_8_Plus_-_11_2.png")

コードでは次のように設定できます。

```
var imageView = UIImageView()
imageView.contentMode = .scaleToFill

```

使用する画像は横:100、縦:75の大きさです。 

![20150901_8625.png](https://qiita-image-store.s3.amazonaws.com/0/135757/4eb5cb46-535e-04f0-83ed-baf8c08ff274.png "20150901_8625.png")



それでは、各描画形式について説明します。

### scaleToFit
- ImageViewのデフォルトのContent Mode
- 画像の比率をImageViewの比率に合わせる
- 画像サイズの比率が変わるのであまり使ってほしくない

![Kobito.a2Jr3G.png](https://qiita-image-store.s3.amazonaws.com/0/135757/bec3609a-19d6-c7db-2d86-5182e1389f63.png "Kobito.a2Jr3G.png")

今回のImageViewの比率は1:1ですが、画像は4:3です。
ImageViewの比率に合わせるため画像の比率が1:1になります。そのため、縦が4/3倍長くなります。

### AspectFit
- ImageViewのサイズ内で画像の比率そのままで表示
- 画像の比率とImageViewの比率が違っていたら、ImageViewに画像が表示されない空白ができる。
- 画像の中心とImageViewの中心は同じになる

![Kobito.t8JtZr.png](https://qiita-image-store.s3.amazonaws.com/0/135757/4f6a5a59-3d48-24b3-3486-e3b7bdb7e96c.png "Kobito.t8JtZr.png")


個人的によく使うのがAspectFit。ImageViewのサイズ内で、画像を元の比率のまま表示する。今回のようにImageViewが1:1で画像が4:3の場合、1/4高さがあまるので、1/8ずつ上下に空白（↑画像では灰色の部分）が出来る。

### AspectFill
- ImageViewのサイズ比率そのままで、ImageViewに空白ができないように表示する。
- ImageViewと画像の比率が違う場合、ImageViewをはみ出す
- 画像の中心とImageViewの中心は同じになる

![Kobito.8j0JGi.png](https://qiita-image-store.s3.amazonaws.com/0/135757/41ad79c0-ab9a-9435-ae09-4650c8c6c514.png "Kobito.8j0JGi.png")

仕事でやっててこれがうまく説明できなかった。。。
画像比率そのままで、ImageViewに空白ができないように表示したい場合に、使用する。
具体的には次のような式で求められます

ImageView -> Width: Heihgt = Wa: Ha
画像		   -> Width: Heihgt = Wb: Hb

Wa/Ha < Wb/Hb -> 画像が (Wb/Hb - Wa/Ha)/2ずつ ImageView左右にはみ出る
Wa/Ha > Wb/Hb -> 画像が (Wa/Ha - Wb/Hb)/2ずつ ImageView上下にはみ出る


### Redraw
- 基本的にはScaleToFillと同じ
- ScaleToFillとの違いは、ScaleToFillがImageViewのdrawRectのところで1度呼ばれると後からは変更が聞かないのに対し、Redrawでは、drawRectが呼ばれるたびにImageViewのサイズに追従します。

![Kobito.cDSvY6.png](https://qiita-image-store.s3.amazonaws.com/0/135757/746e2daf-2e9e-fbe2-317d-8d1dbd0f2694.png "Kobito.cDSvY6.png")

今まで一度も使ったことないですが、上に書いたとおり、ImageViewのdrawRectが何回か呼ばれてそのサイズに画像を合わせたい場合に使うのが良さそうです。

### その他（Center,Top,Left,Right...）
- 画像サイズそのままで、ImageViewに対する位置を指定する。
- つまり画像サイズは変わらない

(Centerに指定した場合)

![Kobito.JYzaDF.png](https://qiita-image-store.s3.amazonaws.com/0/135757/37a0ebf9-4920-5d68-682a-4865f152051f.png "Kobito.JYzaDF.png")

画像の元サイズに気をつけて設定しましょう。

### 終わりに
参考になりましたら**いいね**お願いします！！

## 参考サイト
- [Difference b/w Redraw and Scale to Fill Mode in UIImageView?
(stackoverflow)](https://stackoverflow.com/questions/12196007/difference-b-w-redraw-and-scale-to-fill-mode-in-uiimageview)
Heroku CLIを使わないで、psqlを実行する方法

1. アプリのページから「Run Console」を選ぶ
![openconsole.png](https://qiita-image-store.s3.amazonaws.com/0/184997/685e9f22-151b-b72e-b6df-32be88022d50.png)

2. Consoleのコマンドに以下を入力する
psql postgres://hostname:port/database
例）
psql postgres://zhtxxx@ec2-11-222-333-44.compute-1.amazonaws.com:5432/dbdbdb
![connect.png](https://qiita-image-store.s3.amazonaws.com/0/184997/65840d89-0b03-36ea-080d-783e3894f429.png)

3. 下図のように接続される
![connected.png](https://qiita-image-store.s3.amazonaws.com/0/184997/278fe85c-1fda-b531-7775-3cc7e5b34490.png)
JobSchedulerのREST-APIを使ってみる - Shellで実装編-

# JobSchedulerのREST-APIをShellから使ってみるサンプルです。

### REST-API、jqを導入してShellで実装すると更に楽々なんです。
要件的にJava実装縛りなどがなければ、実は基盤ツールとしてはこちらの方がおすすめかもです（汗）

## 【jqの導入】
```
sudo curl -o /usr/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && sudo chmod +x /usr/bin/jq

```

## 【Shell実装のサンプル】
```
#!/bin/bash

#RESPONSE取得(JSON形式で返却されます）

JSON_RESPONSE=$(curl -X POST -H "Authorization: Basic cm9vdDpyb290" -H "Content-Type: application/json" -H "Cache-Control: no-cache" http://localhost:4446/joc/api/security/login | jq ".accessToken")

#返却値のJSONからACCESS_TOKENを取得

ACCESS_TOKEN=$(echo $JSON_RESPONSE | jq "." | sed "s/\"//g")
echo $ACCESS_TOKEN

#ヘッダフィールドに$ACCESS_TOKEN変数の値をセットしてコマンドを実行

RET=$(curl -X POST -H "access_token: $ACCESS_TOKEN" -H "Content-Type: application/xml" -H "Cache-Control: no-cache" http://localhost:4446/joc/api/jobscheduler/commands -d '<jobscheduler_commands jobschedulerId="scheduler"><start_job job="sample/job1" at="now" /></jobscheduler_commands>' | jq ".")

#実行結果でエラーが発生している場合には以下のように結果のレスポンスの「error」にて取得可能

ERROR_MESSAGE=$(echo $RET | jq ".error")
echo $ERROR_MESSAGE

#適宜エラーハンドルを記述!
#;;

```

ああ楽ちん、です
Dialogflow v1とv2のInline Editorを使った会話サンプル

Dialogflowがv1 -> v2にバージョンアップしましたね。それにともない、FulfillmentのInline Editorの書き方が結構変わりました。ということで、v1とv2の会話サンプルを比較しつつまとめてみました。

# v1とv2のInline Editorを使った会話サンプル
```javascript:v1
'use strict';

process.env.DEBUG = 'actions-on-google:*';
const functions = require('firebase-functions');
const { DialogflowApp } = require('actions-on-google');

const actionMap = new Map();

// ユーザからの入力パラメータを利用しない場合
// 'input.welcome' -> IntentsのAction
actionMap.set('input.welcome', app => {
  // 会話を継続させる場合
  app.ask('How are you?');
  // 会話を終了させる場合
  app.tell('Thanks for talking to me!');
});

// ユーザからの入力パラメータを利用する場合
// 'input.make_name' -> IntentsのAction
actionMap.set('input.make_name', app => {
  // color, num -> Intentsのparameters
  const color = app.getArgument('color');
  const num = app.getArgument('num');
  
  // 会話を継続させる場合
  app.ask('Alright, your silly name is ' +
    color + ' ' + num +
    '! Are there any other numbers and colors you like?');
  // 会話を終了させる場合
  app.tell('Alright, your silly name is ' +
    color + ' ' + num +
    '! I hope you like it. See you next time.');
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((req, res) => {
  const app = new DialogflowApp({ request: req, response: res });
  app.handleRequest(actionMap);
});
```

```javascript:v2
'use strict';

process.env.DEBUG = 'actions-on-google:*';
const functions = require('firebase-functions');
const { dialogflow } = require('actions-on-google');

const app = dialogflow();

// ユーザからの入力パラメータを利用しない場合
// 'Default Welcome Intent' -> Intents
app.intent('Default Welcome Intent', conv => {
  // 会話を継続させる場合
  conv.ask('How are you?');
  // 会話を終了させる場合
  conv.close('Thanks for talking to me!');
});

// ユーザからの入力パラメータを利用する場合
// 'make_name' -> Intents
// color, num  -> Intentsのparameters
app.intent('make_name', (conv, { color, num }) => {
  // 会話を継続させる場合
  conv.ask(`Alright, your silly name is ${color} ${num} ! Are there any other numbers and colors you like?`);
  // 会話を終了させる場合
  conv.close(`Alright, your silly name is ${color} ${num} ! I hope you like it. See you next time.`);
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
```

# まとめ
- v1よりv2の方がコードがすっきりしている
- 会話の単位
    - v1：アクション単位
    - v2：インテント単位

# 参考リンク
- [Actions on Google Node.js Client Library Version 1 Migration Guide  |  Actions on Google  |  Google Developers](https://developers.google.com/actions/reference/nodejs/lib-v1-migration#new_frameworks_system)
3連休になりえない日付を探す

日本に暮らす週休2日制の労働者を前提に、絶対に3連休になりえない日付はあるのか？を考えてみました。

つまり、「1 2 3」の3日間であれば2021年1月1日が金曜日なので、1/1(祝)、1/2(土)、1/3(日)の3連休が存在します。このように考えたときに、3連休にならない3連続の数字はあるのでしょうか。あるとすればそれは何組あるのでしょうか。

1月の三箇日は会社が休みをくれる人も多いとは思いますが、ここでは完全にカレンダー通りに働くという前提で考えます。また、4連休や5連休の一部であっても3連休とみなすものとします。

## 祝日の整理

現在の日本の法律における祝日の日付は下記の通りです。（参考：[国民の祝日 - Wikipedia](https://ja.wikipedia.org/wiki/%E5%9B%BD%E6%B0%91%E3%81%AE%E7%A5%9D%E6%97%A5)）

- 1日
    - 元日（1月）
- 3日
    - 憲法記念日（5月）
    - 文化の日（11月）
- 4日
    - みどりの日（5月）
- 5日
    - こどもの日（5月）
- 11日
    - 建国記念の日（2月）
    - 山の日（8月）
- 23日
    - 勤労感謝の日（11月）
    - 天皇誕生日（12月）
- 29日
    - 昭和の日（4月）
- 第2月曜日
    - 成人の日（1月）
    - 体育の日（10月）
- 第3月曜日
    - 海の日（7月）
    - 敬老の日（9月）
- 春分日
    - 春分の日（3月）
- 秋分日
    - 秋分の日（9月）

## しらみつぶしに3連休を探す

この問題を解くのにうまい方法を思いつかなかったので、場合分けして考えていきます。

### 「1 2 3」から「5 6 7」まで

これはいずれも3連休になりえます。5月の3、4、5がいずれも祝日なので、前や後ろが土日になるような巡り合わせであればこれらは3連休となります。

元日および文化の日と土日が繋がるパターンもこの範囲に含まれます。

### 「6 7 8」から「19 20 21」まで

これもいずれも3連休になりえます。第2月曜日（成人の日および体育の日）は8日から14日のいずれか、第3月曜日（海の日および敬老の日）は15日から21日のいずれかとなり、その前の土日とあわせて3連休となります。

建国記念の日または山の日と土日が繋がるパターンもこの範囲に含まれます。

### 「20 21 22」

この日付は春分の日（多くの年は20日か21日）が土日とうまく繋がったときに一番よく発生します。直近では2020年3月が20（祝）、21（土）、22（日）の3連休になります。

また、シルバーウイークのときにも3連休となります。次のシルバーウイークは2026年9月で、20（日）、21（祝）、22（休）が休日となります（実際は5連休です）。

### 「21 22 23」から「23 24 25」

11/23および12/23が祝日なので、その前後に土日が来た場合、および23日が日曜となって振替休日が発生した場合に3連休となります。

秋分の日（多くの年は23日）と土日が繋がるパターンもこの範囲に含まれます。

### 「24 25 26」から「26 27 28」

これらの日付は3連休になりません。

正確に言うと、一番近い日付で2219年9月の秋分の日が24日かつ金曜日になるので、9/24（祝）、9/25（土）、9/26（日）の3連休がありうるようです（参考：[秋分の日 - Wikipedia](https://ja.wikipedia.org/wiki/%E7%A7%8B%E5%88%86%E3%81%AE%E6%97%A5)）。

とはいえ、そこまで未来だと他の祝日の増減の方が影響が大きそうなので、今回の考慮からは外しても良いでしょう。

（2018/06/13追記）　…と思っていたら2020年７月の「23 24 25 26」が4連休になると決まりました。つまり「24 25 26」は3連休になりえます！

### 「27 28 29」「28 29 30」

昭和の日の前に土日が来た場合、および4月29日が日曜となって振替休日が発生した場合に3連休となります。2018年4月は後者ですね。

### 「29 30 31」

この日付は3連休になりません。4月29日の直後が土日だった場合は「29 30 1」の3連休となり、連続の数字とはならないためです。

## で、これ何の役に立つの？

たぶん役には立たないですね。「25日が営業日でない場合は次の営業日」という言い方をしたときに遅くても27日になるということはわかりますので、支払いに関わるようなお仕事だと役立つことがあるのかもしれません。

## まとめ

~~「24 25 26」~~「25 26 27」「26 27 28」「29 30 31」の ~~4組~~ 3組の日付は当面3連休にならないことがわかりました（2021年以降は「24 25 26」も当面３連休になりません）。

ちなみに皇太子殿下の誕生日は2/23です。天皇陛下譲位後も上の4組に影響は無さそうです。
rpmのパッケージを作ってファイル配置する

リリース作業など複数のサーバにファイルを配置する際、色々な手段がありますがrpmにパッケージして配信しておけばバージョン管理やダウングレードが簡単になります。また長い間RHELやCentOSで継続利用されている仕組みであるため、人の入れ替わりや作業を他のメンバに依頼する場合であってもコマンド体系など学習コストがより少なく済みます。

（参考）有名チュートリアルを参考にする
https://blog.packagecloud.io/rpm/rpmbuild/packaging/2015/06/29/building-rpm-packages-with-rpmbuild/
（参考）手っ取り早くRPMパッケージを作成したかった
https://qiita.com/yukihane/items/fba4929b8b9e812975c1

# 目的
配信ファイルとSPECファイルを作成してrpmファイルを作成する
rpmコマンド経由で指定ディレクトリにファイルを配信する

**環境整備**

```sh
# rootで実施
$ yum install rpm-build
$ useradd kusakari
$ passwd kusakari
$ su - kusakari
$ mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
```
**配信ファイル作成**

```sh:kusakari-1.0/test.sh
#! /bin/sh
echo "test"
```

```sh:kusakari-1.0/date.sh
#! /bin/sh
date
```
**配信ファイルのアーカイブ**

```sh
tar -zcvf kusakari-1.0.tar.gz kusakari-1.0
mv kusakari-1.0.tar.gz rpmbuild/SOURCES/.
```

**SPECファイルの作成**

```spec:SPECS/kusakari.spec
Name:           kusakari
Version:        1.0
Release:        1%{?dist}
Summary:        A hello world program

License:        GPLv3+
URL:            https://qiita.com/kaikusakari
Source0:        kusakari-1.0.tar.gz
BuildArch:      noarch

%define BLDDIR %{buildroot}/home/kusakari/work
%description
A helloworld program from the packagecloud.io blog!

%prep
%setup
%build

%install
rm -rf %{BLDDIR}
mkdir -p %{BLDDIR}
install -m 0755 test.sh %{BLDDIR}/test.sh
install -m 0755 date.sh %{BLDDIR}/date.sh

%clean
rm -rf %{buildroot}

%files
/home/kusakari/work/test.sh
/home/kusakari/work/date.sh
```
**ビルド**

```sh
$ rpmbuild -ba SPECS/kusakari.spec 
Wrote: /home/kusakari/rpmbuild/SRPMS/kusakari-1.0-1.el7.centos.src.rpm
Wrote: /home/kusakari/rpmbuild/RPMS/noarch/kusakari-1.0-1.el7.centos.noarch.rpm
```

**インストール**

```sh
# rootで実施
$ rpm -qa | grep kusakari
$ rpm -ivh kusakari-1.0-1.el7.centos.noarch.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:kusakari-1.0-1.el7.centos        ################################# [100%]
$ rpm -qa | grep kusakari
kusakari-1.0-1.el7.centos.noarch

$ ls -l /home/kusakari/work/
-rwxr-xr-x 1 root root 16 Apr 28 14:39 date.sh
-rwxr-xr-x 1 root root 23 Apr 28 14:39 test.sh
```

rpm経由で配置しました。
Macで変換や無変換キーによる日本語入力切り替え

Macで、WindowsのUSBキーボードを使っていると思うのが、変換・無変換キーでの日本語切り替え。どうにかならないかと探していたら、Karabiner-Elements というアプリを入れれば良いらしい。

# Karabiner

https://pqrs.org/osx/karabiner/

- ライセンスは、Public Domain となっていて、寄付を受け付けている模様。
- ダウンロードするバージョンは、macOS のバージョンに依るようなので注意。

自分の環境は、macOS High Sierra (10.13) なので、Karabiner-Elements 12 を選択。現時点では、12.0.0 (Apr 12, 2018) が最新版となっていた。

## インストール

https://pqrs.org/osx/karabiner/ から Karabiner-Elements をダウンロード。
ダウンロードしたファイル（Karabiner-Elements-12.0.0.dmg） を開く。

pkgを開く。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/e017c03f-b2ea-05f9-3832-9d6bb1651daa.png)

インストールが始まるので指示に従って選択。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/257d1021-ca5a-e6a5-7a05-a26fcf15e579.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/84a95505-4935-8a29-190e-22c06dd626fd.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/8ecec653-a544-7049-2d7c-bde5f266cdec.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/bd09de39-5e48-c3e6-2081-6094a74a6b03.png)

## 設定

Launchpad に Karabiner-Elements が追加されているので、選択。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/55eb59bb-0143-7a47-2334-6f7363b2c5c8.png)

起動直後はこんな感じ。設定は、Simple Modifications で行えば良さそう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/91ede35d-beb9-6ecb-c6ec-4c771ac680be.png)

USBキーボードだけ変えたいので、Target Device で USBキーボード（図では RealForce Compact。接続するキーボードの種類によって名前が違う）を選択。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/11c3efa9-03de-40b7-aacc-c16a0b6ebe5e.png)

左下の Add item を選択し、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/20edaa2e-8502-8209-fcac-325bd91101ae.png)

入力できる枠を増やす。（増やし過ぎたら Remove で）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/c0c333d6-9c6b-82f9-62a4-ebde5cc24485.png)

From key と To key に次を設定

| From key | To key |
|:--|:--|
|PCキーボードの無変換キー|英数キー|
|PCキーボードの変換キー|かなキー|

※プルダウンが長く、下の方にあるので注意
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/eea9eb2a-1be6-ea72-2494-56e2ae9cff76.png)

設定完了です！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/114618/337483dc-5ca8-f99d-0d18-e29544cee412.png)


## 参考

Karabiner - Manual
https://pqrs.org/osx/karabiner/document.html
Jupyterでpcap分析

pcapファイルを解析したかったらWiresharkなどが定番だと思うが、やることが決まってる場合はPythonのdpktで自動処理できれば楽だ。

https://dpkt.readthedocs.io/en/latest/

まずはdpktをインストール。Azure Notebookでも問題なくインストールできた。

```
!pip install dpkt
```

pcapファイルはksnctfのものを使ってみる。

```
!curl http://ksnctf.sweetduet.info/q/8/q8.pcap
```

あとはサンプルファイルを参考にコーディング。ksnctfの問題はBasic認証に関するものなので、HTTPリクエストからAuthenticationヘッダのみ取り出し、base64デコード。

```py
import dpkt,socket
import base64

filename = 'ksnctf_8_basic_is_secure.pcap'
pcap = dpkt.pcap.Reader(open(filename,'rb'))
for timestamp, buf in pcap:
    try:
        eth = dpkt.ethernet.Ethernet(buf)
        ip = eth.data
        tcp = ip.data
        re = dpkt.http.Request(tcp.data)
        if re["headers"]["authorization"]:
            auth = re["headers"]["authorization"]
            passwd = base64.b64decode(auth.replace("Basic ",""))
            print(passwd)
    except:
        pass
```

特定のヘッダのみ追っかけて処理したい場合などに応用できそう。
ClojureのWebアプリをAWS BeanstalkにDockerを使ってデプロイする

今までHerokuを使っていたのですが、機械学習モデルをデプロイする関係でメモリがきつくなってきたため、AWSに移行しようとしたというのが動機です。
AWSやDocker,デプロイ周りに詳しいわけではないので、あくまで表題を達成するための方法が記述されている、くらいの認識でお願いします。
(他のイケてるやり方があれば是非、教えてください)

なお本記事を読むにあたって、AWSの登録やDockerの環境は構築済みであるとしています。
AWSに関してはIAMなどの認証周りの設定まで終わらせておくと面倒が少なくて良いかもしれません。

## webアプリの作成

まず今回デプロイの対象であるアプリを作ります。
ブラウザでアクセスしたら`Hello World`と表示されるやつですね。

```
lein new compojure hello-world
cd hello-world
lein ring uberjar
java -jar target/hello-world-0.1.0-SNAPSHOT-standalone.jar 
```

これで`127.0.0.1:3000`にアクセスして`Hello World`と出ればokです！
次にDockerコンテナ上にアプリを構築してみましょう。

## webアプリをDockerコンテナ上で起動

[公式Clojure](https://hub.docker.com/_/clojure/)の記述を参考にしました。
`Dockerfile`を作成して次の内容を書いてみて下さい。

```Dockerfile
FROM clojure
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY project.clj /usr/src/app/
RUN lein deps
COPY . /usr/src/app
EXPOSE 3000
RUN mv "$(lein ring uberjar | sed -n 's/^Created \(.*standalone\.jar\)/\1/p')" app-standalone.jar
CMD ["java", "-jar", "app-standalone.jar"]
```

`project.clj`を分けて先に置いてから`lein deps`をすると、依存ライブラリが変更された時のみアップデートされるようになって効率的らしいです。
EXPOSEはここでポートの設定を行わないとBeanstalkにデプロイした後に起動できません。

次にイメージの作成をしてコンテナを起動します。

```
docker build -t hello-world .
docker run -d -p 3000:3000  --name hello-world hello-world
```

基本的には`http://127.0.0.1:3000`でアクセスできると思いますが、Mac環境だとポートのフォワードはVMに通す必要があるので、docker-machineで作ったVMのhostを指定します(次の例ではdefaultを指定)

`docker-machine env default`とすると次の設定が出力されます。

```
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="XXX"
export DOCKER_MACHINE_NAME="default"
```
上記の例の場合`http://192.168.99.100:3000`にアクセスします。
ここまででブラウザに`Hello World`の文字列が出ていれば成功です！


## AWS Beanstalkにデプロイ

まずはプロジェクトをgitで管理します。

```
git init
git add .
git commit -m "init my project"
```

次に`eb`をインストールをします。
[Install the Elastic Beanstalk Command Line Interface (EB CLI)](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html)に従って、`eb --version`が正常に動くところまで行います。

ここからはAWSの設定になります。
次のコマンドのそれぞれでインタラクティブに設定を行うことになります。
AWS上で複数設定を持っている人はそれぞれに`--profile hoge`でプロファイルを適応することを忘れないで下さい。

```
eb init
eb create
```

- [EB CLI の設定](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/eb-cli3-configuration.html)に詳細がかかれているので一読してみて下さい。

- 手っ取り早く試したい人はデフォルトの設定に次の選択肢でいいかもしれません。
  + Code Commit: n
  + SSH setup: n
  + load balancer type: 2) application

ブラウザからAWSのElastic Beanstalkに移動すると上記で作成したアプリが表示されていると思います、見つからない場合はリージョン設定を確認してください。
また構成されたアプリのURLも記載されています。
`eb open`で、ローカル環境と同じく`Hello World`が出てくればokです！
もし成功しなかった場合は`eb logs`でログを確認して見てください。

さて、ファイルを編集してもう一度デプロイしてみましょう。
`src/hello_world/handler.clj`の`Hello World`の文章を変更して再度コミットして下さい。
`eb deploy`で再度デプロイします。
次に`eb open`でwebアプリが上記で編集したテキストが表示されていれば成功です！



最後に、ロードバランサーやEC2インスタンスなどが起動しているので、必要なければ忘れずに環境を消しておきましょう。
右上のボタンからterminateを選択すれば、構築した環境をまるごと消去できます。

以上になります。
Python で目的地の地図をGoogle Mapの.htmlとして作成

#現在使用できない可能性が大です。
ブラウザでGoogleMapを使用していると、真っ白になり地図が表示されないことがありググっていたら、Googlemapのが有料でAPIキーが入力されないと表示されないように変更になったためのようなことが書いていました。
試しに実行しましたが、5回程度実行しましたがダメでした。

#####実行した環境
Ubuntu Stdio 17.10
Python 3.6.3

#####参考
https://j138i.com/python-folium-sample0/
ｐython：foliumで地図に目印を付てみる

#####インストール
pip3 install pygeocoder
pip3 install folium

#####使い方
./map.py 目的地の名称
目的地の名称はGoogleマップで検索出来る名称

例.
./map.py ユニバーサルスタジオジャパン

map.pyのあるフォルダにユニバーサルスタジオジャパン.htmlが作成される。

```python:map.py
#!/usr/bin/python3
# coding: UTF-8

from pygeocoder import Geocoder
import folium
import sys

args = sys.argv
argc = len(args) # 引数の個数

if (argc != 2):   # 引数がない場合
    print ('./map.py 目的地の名称')
    quit()

try:
    area_name = args[1]
    place= Geocoder.geocode(area_name)
    loc = place[0].coordinates
    map_obj =folium.Map(location=loc,zoom_start=15)

    folium.Marker(loc,popup=str(area_name),
    icon=folium.Icon(color='blue',icon='info-sign')
    ).add_to(map_obj)

    map_obj.save(args[1] + ".html")
except:
    quit()
```

住所追加版

```python:map_address.py
#!/usr/bin/python3
# coding: UTF-8

from pygeocoder import Geocoder
import folium
import sys

args = sys.argv
argc = len(args) # 引数の個数

if (argc != 2):   # 引数がない場合
    print ('./map_address.py 目的地の名称')
    quit()

area_name = args[1]

def map():
    try:
        place= Geocoder.geocode(area_name)
        loc = place[0].coordinates
        map_obj =folium.Map(location=loc,zoom_start=15)

        folium.Marker(loc,popup=str(area_name),
        icon=folium.Icon(color='blue',icon='info-sign')
        ).add_to(map_obj)

        map_obj.save(args[1] + ".html")
    except:
        quit()

def address():
    try:
        results = Geocoder.geocode(area_name)
        print(results.coordinates)
        result = Geocoder.reverse_geocode(*results.coordinates, language="ja")
        print(result)
    except:
        quit()

map()
address()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/463da421-24c6-def0-fbb5-7c5660bc3491.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/69ce040e-b280-d329-f05c-26c3598a7416.png)
プログラムが動く仕組み

【コンピュータへの命令】

人間とコンピュータがやり取りするには、あらかじめプログラミング言語を使って、コンピューターに対する「命令」をプログラムしておく必要があります。

しかし、コンピュータは「0」か「1」しか理解できません。（電気を通すか、通さないか）

（例）0001000111010......　　　機械語（マシン語）

人間が2進数（「0」か「1」）でプログラムを記述し、コンピュータに命令することは、かなり効率が悪ですね。

そこで、「人間の言葉に近い言語」でコンピュータに対して命令ができるように、プログラミング言語は、工夫されてきました。

現在、多く使われているプログラミング言語は高水準言語といい、より人間の言語に近く、プログラムを記述しやすいように、時代とともに改良されてきました。

【機械語（マシン語）に翻訳】

コンピュータには機械語で命令をしなければ。高水準言語で記述したプログラムを、コンピュータが理解できる機械語に翻訳する必要があります。

代表的な翻訳方法として、2種類があります。

①コンパイラ型と②インタープリタ型があります。

①コンパイラ型

ソースファイル（プログラミング言語を使って記述したファイル）を、コンパイラを使って、”一度”に機械語へ翻訳（コンパイル）する方法です。

翻訳したファイルを実行可能ファイルと言い、このファイルでプログラムを実行します。実行可能ファイルには、CPUが直接理解可能な命令が入っているため、高速に動作します。ただし、別のOSやCPUでは動作しません。

②インタープリタ型

ソースファイルを、インタープリタと呼ばれるツールを使って、一行ずつ機械語に翻訳して実行する方法です。

同時通訳のように、翻訳しては実行という動作を繰り返すため、実効速度が遅いことが難点。
プログラム実行には、ソースファイルとインタープリタが必要。

【アプリケーションの起動】

プログラムの塊（プログラム群）のことをアプリケーションと呼びます。
アプリケーションをマシンのHDDやSSDにインストールし、メモリへロード、プログラム内の実行命令（機械語）を１つずつCPUで実行することによって、アプリケーションを動かします。
php で 画像URLを隠す。隠蔽工作

画像のURLを見ていると時々ダウンロードできない画像がある。
どうやってるやるのかなーと思ってたら、方法見つけたのでシェア。

```

    public function test()
    {

        $img = "<img src='https://helpee.club/hoges/hoge2?f=minna.png'>";

        echo $img;

        $this->autoRender = false;

    }

    public function hoge2()
    {
        $file = $_GET['f'];

        $path = WWW_ROOT."img/".$file;
        header('Content-Disposition: inline; filename="' . $path . '"');

        //必要に応じ、png , jpg , gif などに変更
        header('Content-type: image/png');
        readfile($path);




        $this->autoRender = false;
    }

```

時間ないので、また時間ある時丁寧に書きます。
Python3とPyPy3のパフォーマンスを比較してみた

最近、Pythonの勉強を始めた。
その中で、Pythonのパフォーマンスを向上させる実装としてPyPyというのを知ったのだが、インフラエンジニア的にはパフォーマンスは気になるので、実験してみた。

# 環境

マシン: Frontier FRNLC380/KD3
CPU: Celeron 3855U 1.60GHz
Mem: DDR3L-1600 8GB X1
OS: Fedora 27
Python version:Python 3.6.5
Pypy version: Python 3.3.5 (19b4b275ee9c, Aug 04 2017, 13:10:56)
[PyPy 5.5.0-alpha0 with GCC 7.1.1 20170718 (Red Hat 7.1.1-6)]

# テスト用コード

```test.py
import math
MAX=10000000
NUM=2
while NUM <= MAX:
    LIMIT=int(math.sqrt(NUM))
    i=1
    while i <= LIMIT:
        i += 1
        if i == NUM:
            FLAG = False
            print(NUM)
            NUM = 1
            continue
        remainder = NUM % i
        if remainder == 0:
            FLAG = False
            break
        else:
            FLAG = True
    if (FLAG):
        print(NUM)
    NUM += 2
```
10,000,000までの素数をひたすら求めるプログラム。

# 結果

PyPy: 53秒**(!)**
CPython: 13分8秒

```
$ date; pypy3 test.py>/dev/null; date; python3 test.py>/dev/null; date
2018年  4月 28日 土曜日 11:40:20 JST <= PyPyスタート
2018年  4月 28日 土曜日 11:41:13 JST <= PyPy終了 & CPythonスタート
2018年  4月 28日 土曜日 11:54:21 JST <= CPython終了
```

その差、1486.79%!
ほぼ15倍速!

PyPy, すごすぎ!
jQuery 基本の書き方まとめ

プログラミングの勉強をするうえで関わることの多いjQuery。今回は、初心者でも知っておきたい本当に基本的な書き方をまとめてみました。

# 基本的な形式

jQueryは基本的には以下のような形で書きます。

$(function(){       <ここに効果をつけるコードを記入>         });


$('<どこに効果をつけたいか>').<つけたい効果（と時に必要な変数）>;

例えば、```<p>Apple</p>```の中にあるAppleを500の速さで徐々に消したいのであれば、
```$('p').fadeOut(500);```
でOKです。ちなみに速さの部分には'slow'といった文字を記入することもできるそうです。

# 「どこに効果をつけるのか」はCSSと同じ書き方でOK

タグに効果をつける時は上のようにすればOKでした。ではclassやidに効果をつけたいと記述する場合にはどうすれば良いのでしょうか。

実はこれはCSSの場合とほぼ同じです。

```class = "fruits"```とします。例えば、このクラスを隠したいのであれば

```　$(".fruits").hide(); ```とすれば大丈夫です。

``` id = "food" ``` であれば、
``` $('#food').hide(); ``` このようにすればOKです。

# 色の指定などもCSSと同じ！

どこに効果を与えるかの指定はCSSと同じだとご紹介しました。
実は色の指定やサイズの指定もCSSと同じような雰囲気を持っています。

例えば、```<p class = "fruits" >Apple</p>```のAppleの色を赤色に変えてみることにします。
この場合、CSSでは

```css
.fruits{color: red;
           } 
```

のように書きますよね。
jQueryでは
```css
$('.fruits').css('color','red');
```
と書くことができます。

同様にAppleのフォントサイズを100にしたければ、
```css
$('.fruits').css('font-size', '100');
```
と書くことができます。

# 効果が発生するタイミングを指定することもできる！

jQueryでは効果が発生するタイミングを指定することができます。

$('<クラスなど、セレクタ>').<何が起きた時に効果が発生するか>(function(){ <どこに何が起きるか> });

このように書けばOKです。

具体的に説明します。

![index.html.png](https://qiita-image-store.s3.amazonaws.com/0/240709/e419b278-fd34-2926-881b-de02a1c3e1a4.png)



こんなコードを用意してみました。
今から「push me」を押せば「Apple」がゆっくり消えていく仕様にしたいと思います。
これは上で説明したjQueryの構文を使って実現することができます。

![index.js.png](https://qiita-image-store.s3.amazonaws.com/0/240709/f584c8f2-51db-ca5b-3289-c448a18132a8.png)


一見複雑に見えますが、```$(function(){});```の入れ子構造になっていると思えば簡単です。

# 場所を指定する this

ここではクリックされた場所（#push）と実際に何かが起こる場所（#fruits）は違いました。

勿論二つが同じ場合の時にもイベントを起こす書き方があります。


この二つの場所が同じ時、二つ目の指定にはthisを使うことができます。

例えば、```$(this).fadeOut();```　このようにすることができます。
この時、thisには''や""をつけないことに注意してください。



# 基本効果まとめ

最後に、jQueryでぜひ知っておきたい基本的な効果の書き方をまとめます。

- hide ；要素を隠す
- fadeOut ；要素がゆっくり薄くなって消える
- fadeIn　；要素を表示する、だんだんそれが濃くなって表示される
- slideUp ；上に向かって下から消える 
- slideDown ；要素を表示する、その時上から下に降りてくる
- css ；cssと同じようにサイズや色などを指定する
- text ；文章を変更する
- html ；htmlと同じように文章を変更する、あくまでHTMLなので```<p></p>```などは非表示
- show　；hideなどで隠れた要素を表示する

# まとめ

本当に基本的なことはこんな塩梅だと思います。
変数などもっと書き方を楽にする方法はあえて取り上げませんでした。

参考になればと思います。
JavaScriptで行列の掛け算をするサンプルプログラム

JavaScriptで2次元配列を行列として掛け算するプログラムのサンプルです。


```dot.js
function dot(matrix1, matrix2){
  var res = [];
  var row1 = matrix1.length;
  var row2 = matrix2.length;
  var col1 = matrix1[0].length;
  var col2 = matrix2[0].length;

  for(var i1 = 0; i1 < row1; i1++){
    res.push([]);
    for(var i2 = 0; i2 < col2; i2++){
      res[i1].push(0);
      for(var i3 = 0; i3 < col1; i3++){
        res[i1][i2] += matrix1[i1][i3] * matrix2[i3][i2];
      }
    }
  }

  return res;
}
```



```math
matrix1　=
\begin{pmatrix}
１ & 2
\end{pmatrix}
```
```math
matrix2　=
\begin{pmatrix}
１ \\
2
\end{pmatrix}
```

を掛ける場合、以下のように関数を使用します。

```calc.js
var matrix1 = [[1, 2]]; //1行2列
var matrix2 = [[1], [2]]; //2行1列

dot(matrix1, matrix2);
> [[5]]
```
Git Hub 新規リポジトリの作り方

GitHub リポジトリの作り方

自分のアカウントにログイン
(自分のアカウント名を間違えないように)

ログイン後、Newrepositoryの項目を選択
Repository name：作成するリポジトリの名前
Description：作成するリポジトリに関する説明
→こんな用途で使用するリポジトリですよ〜みたいなことを書く
Public or Private：リポジトリ種類のこと
→基本無償登録の人はパブリックしか選べないので、ここはpublicで
〜〜README：説明が記載されたファイル
→リポジトリの中身に関して、細かい説明を記載したい時はここにいれること

あとはCreate repositoryを新規でリポジトリは作成できますよーと
ひかり電話の内線機能を導入し、CRM/CTI構築

##ひかり電話の内線機能を導入
ひかり電話の内線には、IP電話の機能があるので、スマホを内線で使うのが一般的ですが、Windowsでも通話ができます。
※ WiFiなら、どこでも内線電話として使うことができます。
設定
1.1.HGWの内線を設定 (詳細は、HGWの説明を見てください)
![PR-400KI内線](https://qiita-image-store.s3.amazonaws.com/0/77496/eceb56eb-c58c-8b1d-01ff-754408d2b1c3.png)

1.2.IP電話（商用以外は無料）のインストール(詳細は、商品の説明を見てください)

今回は、[AGEphone (エイジフォン)](https://www.ageet.com/agephone)を使用してみました。
![サンプル画像](https://static.wixstatic.com/media/c90591_7b46b64201ff42ae83fe13777ce7d3bb.png/v1/fill/w_537,h_280,al_c,usm_0.66_1.00_0.01/c90591_7b46b64201ff42ae83fe13777ce7d3bb.png)

AGEphoneは、NTT西日本、NTT東日本が提供するフレッツ 光ネクスト対応ひかり電話対応機器のホームゲートウェイに接続できます。

1.3.アナログ電話は、現在の設定では1番なので、１をダイヤルすると内線通話ができます。
　その反対は、アナログ電話から、３をダイヤルするとIPフォンに着信します。

#　CRM/CTI 化
AGEphone のメニューから「アクションURL」を設定します。
![サンプル](https://qiita-image-store.s3.amazonaws.com/0/77496/49b5d024-165e-0567-5021-d60824d3c40d.png)

着信時に、URLに発信番号を含んだ、URLでブラウザを起動できます。
クラウドでもオンプレミスでも自由にCRMと接続できます。
Eclipse

Eclipse 使い方

pleiadesを使って〜〜
自分の使用しているPCのOSによってインストール方法は異なる。
今回はmacなのでmacをインストール

インストールする際、macのセキュリティの設定で引っかかるので
Control + 開くでアプリケーションを開くこと！！

アプリケーションの起動ができると、ワークスペースを指定することになる。
→いわゆる作業領域
ここは所定の場所だとアプリケーションの中に作成をしてる。
これで良いのかは不明(若林さんに聞こう)
一応ドキュメントの中には作ったので、これでOKかも

コードを書くには新規でファイルを作成する必要がある。
ファイル→新規→javaプロジェクト(JAVAの場合)
プロジェクト名を記載、ロケーションは作業領域の場所
ここはデフォルトロケーションを置けばOK

ファイル作成後、新規からクラスを作ればコードをかけるようになる。

あとはコードを書くのみ！！
M5stackでシリアルから文字列を受信するには

###目的
M5stackで、シリアルから文字列を取得する。

###方法
 Serial.readStringUntil関数を使う。

>String HardwareSerial::readStringUntil(char terminator);

char terminatorは終了文字。
この関数は、終了文字を検出するかタイムアウトすれば終了する。


###サンプルソース

````
#include <M5Stack.h>

void setup() {
    Serial.begin(115200);

}

void loop() {

  if ( Serial.available() > 0 ) {
    String str = Serial.readStringUntil('\n');
    Serial.print("talk:");
    Serial.println(str);
  }
  delay(100);
}
````

参考
 Arduinoリファレンス ： readStringUntil()
https://garretlab.web.fc2.com/arduino_reference/language/functions/communication/serial/readStringUntil.html