OmniAICreator/Qiita-1.07M huggingface dataset:
leafletのテスト

```leafletdemo4_marker.html
<!DOCTYPE html>
<html>
	<head>
		<title>Leaflet Demo4</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="">
		<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>
		<style type="text/css">
		<!--
			#mapid { height: 400px; width: 600px}
		-->
		</style>
	</head>
	<body>
		<div id="mapid"></div>

		<script>
			var mymap = L.map('mapid').setView([35.7102, 139.8132], 15);

			L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
				maxZoom: 18,
				attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, '
			}).addTo(mymap);

			var marker = L.marker([35.7101, 139.8107]).addTo(mymap);
			marker.bindPopup("<p>popup1</p><p>地図表示時に一緒に表示されます。</p>").openPopup();

			var marker2 = L.marker([35.7121, 139.8207]).addTo(mymap);
			var popup = L.popup();
			function onMarker2Click(e) {
				popup
				.setLatLng(e.latlng)
				.setContent("<p>popup2</p><p>clickで表示されます。</p>" + e.latlng.toString())
				.openOn(mymap);
			}
			mymap.on('click', onMarker2Click);

		</script>
	</body>
</html>
```
脆弱性診断で指摘されがちな項目と対策方法をまとめる(CentOS+Apache+php)

#はじめに

AWSでEC2インスタンスを立ち上げた後に、セキュリティ系の対策をしない状態で脆弱性診断をするという機会があったので、その場合に指摘される項目と対策をまとめました。
セキュリティ対策初心者なのでご指摘あればコメントをお願いします。

#想定される環境
- CentOS 7系
- Apache 2.4
- php 7.2

#指摘事項

##TRACEメソッドが有効になっている
/etc/httpd/cond/httpd/confに以下を追記する

```:/etc/httpd/cond/httpd/conf
TraceEnable off
```

##SSL/TLSに脆弱性が存在するプロトコルが使われている
/etc/httpd/conf.d/ssl.confに記載されているSSLProtocolにTLSv1.2を設定する

```:/etc/httpd/conf.d/ssl.conf
#SSLProtocol all -SSLv3 //コメントアウト
SSLProtocol -all +TLSv1.2 //TLSv1.2のみを許可
```

あまりに古いOSやブラウザの場合はTLS1.2に対応していない可能性があるので注意が必要です。

##SSL/TLSにおいて非推奨の暗号アルゴリズムが使用されている

/etc/httpd/conf.d/ssl.confに記載されているSSLCipherSuiteを設定する。
\<VirtualHost\>タグ内に記述すると設定が効きませんでした。デフォルトのサンプルがタグ内に書かれているので躓きやすいです。ファイルの一番最後などに追記しましょう。

```
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH EDH+a
RSA !CAMELLIA !SEED !3DES !RC4 !aNULL !eNULL !LOW !MD5 !EXP !PSK !SRP !DSS"
```

##SSH通信において非推奨の暗号アルゴリズムが使用されている

/etc/ssh/sshd_configの最後に追記する。

```:/etc/ssh/sshd_config
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
```

推奨の暗号化アルゴリズムは[mozillaの推奨設定](https://infosec.mozilla.org/guidelines/openssh)などで確認する。

##apacheのバージョンが公開されている
/etc/httpd/conf/httpd.confのServerTokensをProdにする

```:/etc/httpd/conf/httpd.conf
#ServerTokens OS //コメントアウト
ServerTokens Prod
```

##phpのバージョンが公開されている

php.iniの場所を確認する。

```
php --ini
//Loaded Configuration File: /etc/php.ini
```

php.iniのexpose_phpをOffにする。（viなら/exposeで検索をかけるとはやい）

```:php.ini
expose_php=Off
```

##ファイル一覧ページ（Index of）が公開されている

\<Directory "/var/www/html"\>内のOptionsからIndexesを削除する。

```:.htaccess
<Directory "/var/www/html">
    ~
    #Options Indexes FollowSymLinks //コメントアウト
    Options FollowSymLinks
    ~
</Directory>
```

##Apacheのテストページが表示されている

/etc/httpd/conf.d/welcome.confの\<LocationMatch "^/+$"\>部分をコメントアウトする

```:/etc/httpd/conf.d/welcome.conf
#全体をコメントアウト
#<LocationMatch "^/+$">
#    Options -Indexes
#    ErrorDocument 403 /.noindex.html
#</LocationMatch>
```

#最後に

設定ファイルを書き換えた後は再読み込みする。

```
systemctl restart httpd // /etc/httpd/の中身を書き換えたとき
```

```
systemctl reload sshd // /etc/ssh/の中身を書き換えたとき
```

再読み込みを行ったときにエラーが出た場合はjournalctl -xeでエラー内容を確認するといいです。

```
journalctl -xe
#いろいろ出てきますがSyntaxエラーなら以下のように書いています。
#1月 10 10:00:00 ~~~ httpd[1234]: AH00526: Syntax error on line 362 of /etc/httpd/conf/httpd.conf:
```

#参考
- [AWSのApache2.4の初期設定とセキュリティ設定](https://qiita.com/shojimotio/items/41a74f314f3e47c018a5)
- [ssh config最強設定](https://qiita.com/keiya/items/dec9a1142ac701b19bd9)
- https://gist.github.com/GAS85/42a5469b32659a0aecc60fa2d4990308
SEO的末尾スラッシュのお話

## trailing slash
末尾スラッシュは正式名称がtrailing slashというので詳しく調べたい方はこちらで検索してもらうのもいいかもしれません。

## SEOのお話
本題ですが、この末尾スラッシュの有無じたいは現状のSEO的にどれがいいということはないようです。
ただ、以下は全て別のURLとして認識されるそうなので統一が必要とのことです。
http://www.example.com/product
http://www.example.com/product/
http://www.example.com/product?source=googleps
http://www.example.com/product/?source=googleps

## 結論
末尾スラッシュありにする場合は全部ありになしの場合は全部外す。
これはパラメータ付きの場合も同様です。

## 参考
https://webmasters.stackexchange.com/questions/81252/is-a-trailing-slash-appropriate-before-url-parameters
#Rails + #rspec + #VCR で SECRET_KEY など秘密の環境変数・情報をフィルタリングする設定

# 例

`spec/support/vcr_config.rb`

```rb
VCR.configure do |config|
  config.filter_sensitive_data('<SECRET_KEY>') { ENV['SOME_SECRET_KEY'] }
end
```

# Ref

VCR で外部 API へのリクエストをダンプするときに機密情報をマスクしたい - Qiita
https://qiita.com/gotchane/items/c2c29c0063bd44246510


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2926








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
GASでログ出力する（主にconsoleクラス）

# このポストの目的
Google Apps Scriptを用いてアプリケーションを開発する際に利用するログ出力方式についてまとめます。

もとの情報はGoogleの開発者サイトのリファレンス（[G Suite Developer / Logging](https://developers.google.com/apps-script/guides/logging) ）を参考にしています。調べた限り、便利度合いと利用の平易さからすると、consoleクラス一択で良いと思いましたので、主にconsoleクラスについてまとめます。

# GASでのログ出力方法
GASでのログ出力方法は２種類あります。

* Loggerを利用する
  * 出力したログはスクリプトエディタ上の「表示」→「ログ」で確認できます。
  * 極めて簡易的なロガーで、 **スクリプトエディタからの実行時にしか** ログは見れない。
* consoleを利用する
  *  出力したログはStackDriver Loggigで確認します。スクリプトエディタ上の「表示」→「StackDriver Logging」でアクセス可能。
  *  後述しますが、ロガーとして最初からいろいろな機能が用意されています。
  *  トリガーや時間駆動実行時でも、StackDriver Loggingにログが出力される。

## Loggerの利用方法
`Logger.log` を利用すると、こんなイメージです。

```JavaScript
Logger.log("Loggerによるログ出力です。");
```

「表示」→「ログ」での確認結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34410/a6724f4f-811e-aa49-1ee9-6aad82a36089.png)

## consoleの利用方法
`console.log` を利用すると、こんなイメージです。

```JavaScript
console.log("consoleに向けたログ出力です。");
```
「表示」→「StackDriver Logging」での確認結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34410/e5535fa0-2a14-ad64-0f07-8e25b74b1cb2.png)

### consoleのログレベル
consoleにはログレベルごとに関数が用意されています。

```JavaScript
console.log("[LOG]consoleに向けたログ出力です。");
console.info("[INFO]consoleに向けたログ出力です。");
console.error("[ERROR]consoleに向けたログ出力です。");
console.warn("[WARN]consoleに向けたログ出力です。");
```
関数を使い分けると、StackDriver Loggingでも色分けされて識別しやすくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34410/cfa88fb6-3b87-0780-eb61-512d4d0693fd.png)

### ログ出力メッセージの内容
Stringでも、FormatStringでも、オブジェクトでも出力可能です。オブジェクトは整形し出力してくれるため便利ですね。

```JavaScript
console.log("[LOG]consoleに向けた%s出力です。", "ほげほげほげ");
  
var data = {
  param1: "なまえ",
   param2: true,
   param3: new Date()
};
console.log(data);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34410/48bcc491-9899-5a38-cd76-2cd528b4ab7b.png)

## 処理時間を計測できる
`console.time()`と`console.timeEnd()`を組み合わせると、その間に挟んだ処理の所要時間を計測できます。

```JavaScript
  var timelabel = "処理Aの所要時間";
  
  console.time(timelabel);
  
  //処理A（sleepで代替しています）
  Utilities.sleep(500);
    
  console.timeEnd(timelabel);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34410/f6d7f114-b2f8-f97e-3219-61f7f35ba230.png)

以上です。
エンジニアは製品に名前をつけるのが苦手だけどセンスのいい名前を付けて褒められるためのまとめ


子供に名前をつけるときに親はとても悩むものです。
* 良い意味を込めたい
* 呼びやすく親しみやすく
* センスがいいと思われたい
* キラキラネームとかいじられたくない
同じように、製品に名前をつけるときにエンジニアは非常に悩みます。

エンジニアは製品の性質や機能にとらわれがちなので、説明的で長い（≒ダサい）名前を付けがちです。たとえば
**「業務工程管理システム」**とか
意味が伝わりそうで伝わらない。長い。ダサい。

必読（笑）⇨　[珍プロジェクト名・好プロジェクト名大賞 IT編](https://next.rikunabi.com/tech/docs/ct_s03600.jsp?p=001420)

センスのいい名前を付けて褒められたい。
そんなわけで、世の中に溢れるソフトやサービスから、ネーミングのパターンを考察してみました。


#製品の機能や開発陣の願いを表すキーワードをそのまま使う
##例）
Word
Illustrator
GoogleMap
PhotoShop
InternetExplorer
SQLServer
楽天市場
勘定奉行

##長所）
内容がイメージできる
##短所）
ちょっと長くなりがち。ちょっとダサいものもあるかも。

#機能や願いを表すキーワードを連想させる別の言葉に置き換える
##例）
LINE
PowerPoint
FaceBook
NetscapeNavigator
SourceTree
AirDrop

##長所）
内容がイメージできる。呼びやすい。
##短所）
長いものもある。

#機能や願いを表すキーワードの語感をちょっと変える
##例）
iOS、iTunes、iPhoneなどのi (internet, individual, intelligenceなど) 
Instagram(Instant + Telegram)
Twitter(Tweetする人)
Excel(Excellent + Cell。諸説あり)
Evernote(Wherever, Whenever など + Note)
YouTube(You + cathode-ray Tube(ブラウン管))
Qiita(https://help.qiita.com/ja/articles/qiita-roots)

##長所）
内容がイメージできる。呼びやすい。短い。おしゃれ。
##短所）
キラキラ感が出てしまうことも。センス勝負。

#開発コードネームがそのまま製品名になる
#例）
MacOSXのバージョン
10.0 Cheetah (チーター)
10.1 Puma (ピューマ)
10.2 Jaguar (ジャガー)
10.3 Panther (パンサー)
10.4 Tiger (タイガー)
10.5 Leopard (レパード)
10.6 Snow Leopard (スノー レパード)
10.7 Lion (ライオン)
10.8 Mountain Lion (マウンテン ライオン)
10.9 Mavericks (マーベリックス)
10.10 Yosemite (ヨセミテ)
10.11 El Capitan (エル キャピタン)
10.12 Sierra (シエラ)
10.13 High Sierra (ハイ シエラ)
10.14 Mojave (モハベ)
10.15 Catalina (キャタリナ)

##長所）
なんかわかんないけどかっこいい
##短所）
意味が分からない。キラキラ感が出てしまうかも。センス勝負。

#製品の機能や開発陣の願いを表すキーワードの略語を製品名とする
##例）
ATOK(advanced technology of kana-kanji transfer)
IIS(Internet Information Server)
SVN(Sub Version)
AWS(Amazon Web Services)

##長所）
短い
##短所）
覚えにくい

#インパクトや呼びやすさ重視。好きな言葉をそのまま製品名に
##例）
Acrobat
Chrome
Lotus123
一太郎
FireFox
ThunderBird
Android
(意味や願いが込められているものがあったらすいません)

##長所）
覚えやすい。短い。
##短所）
特に意味がない。センスが問われる。


#名前を付けるときのポイント
名前が長いと困ることが人間でもあります。
テストの時に名前書くのに時間がかかったり、呼ぶのが面倒なので変なあだ名がついたり。
できるだけ短くするのが良いでしょう。


こうしてまとめてみると個人的には
 **製品の機能や開発陣の願いを表すキーワードの語感をちょっと変える** 
パターンに良い名前が多いなと思いました。

たとえば
Twitter
すごくいい名前だとおもいます。
短く、キャッチーで、イメージしやすい。

あくまで私感です。ダサいとかは全部冗談です。
AWS Elemental MediaConvert と Amazon ElasticTranscoderの違いってなに？

明けましておめでとうございます:sunny:
今年はねずみ年:mouse2:ですね！
年女Risakoの新年一発目は、AWS Elemental MediaConvert と Amazon ElasticTranscoderを比較してみたいと思います！
少しでも参考になれば幸いです:wink:

#AWS Elemental MediaConvertとは

##特徴

 **ビデオオンデマンドコンテンツのブロードキャスト機能** 
AWS Elementalのテクノロジーで構成されている。
グラフィックオーバーレイ、コンテンツ保護、多言語音声、クローズドキャプションのサポート

 **包括的な入出力サポート** 
ブロードキャスト用やインターネット配信用など幅広い動画の入出力形式をサポート
MPEG-2,AVC,Apple ProRes,HEVC の圧縮規格、高度なカラーサンプリングをサポート
CMAF、Apple HLS、DASH ISO、Microsoft Smooth Streaming などの幅広いアダプティブビットレートパッケージング形式をサポート
４K解像度およびハイダイナミックレンジ（HDR）の動画コンテンツの処理および変換もサポート

 **リソースの自動プロビジョニング** 
動画インフラストラクチャの作成および管理作業を自動化する
ワークロードのプロビジョニングと管理の主な作業を自動化することで、動画処理のインフラストラクチャを管理する負担が減る。
リソースのプロビジョニングおよび最適化、サービスオーケストレーション、スケーリング、修復、回復性の高いフェイルオーバー、モニタリング、レポートなどが処理される。
ブロードキャスト用やインターネット配信など、幅広い動画の入出力形式をサポート

 **固有の信頼性** 
ビデオオンデマンドワークフローの冗長性と自動スケーラビリティ
動画コンテンツの需要に合わせて適切なコンピューティングリソースが自動的にプロビジョニングされ、応答時間やパフォーマンスを下げることなくピークのワークロードに合わせて伸縮自在にスケールされる。エラー処理といった組み込み機能は簡単に使用でき、メディアワークフロー全体をモニタリングして通知の発信などのアクションをリアルタイムで実行できる。 



#AWS Elemental ElasticTranscoderとは

##特徴
**動画ファイルの変換**
サイズが大きい高品質のデジタルメディアファイルを、モバイルデバイス・タブレット・Webブラウザなどで再生できる動画ファイルに変換することが可能。

**ウォータマークの挿入**
ウォータマーク（画像や文字のすかし）を動画内に挿入することが可能。

**サムネイルの自動生成**
変換が終了すると、S3に自動でサムネイル（キャプチャ）が作成されています。



#MediaConvert と ElasticTranscoder比較

##MediaConvert できること 


 **動画の結合ができる** 
JOB作成時に指定するINPUTの動画を複数にするのみ。
また、複数の動画の一部を切り取って結合することも可能

 **別の動画の音に差し替える** 
既存の動画の映像と音声を必要な部分だけ選んで新しい動画を作成することができる。
S3の動画を指定することができるため、映像と音声で違う動画を使うことも可能。
この動画形式で、複数言語対応の動画の作成も可能になる。



 **動画のノイズを軽減することができる** 
出力設定に[Noise reducer] というものを選択し、設定することでノイズ軽減できる。


##MediaConvert できないこと

 **動画ファイルの暗号化のキーにKMSを利用できない** 


 **WebM動画の作成** 

 **アニメーションGIFの作成** 



##Elastic Transcoder できること

主なユースケースは、
・iphoneなどで撮影した動画をPCなどのマルチデバイスで見れる動画ファイルに変換
・動画変換時に動画に写し込まれる小さな図案や文字の挿入
・サムネイル画像の自動再生



##Elastic Transcoder できないこと

 **動画結合などの高度な編集** 

 **H.265に対応していない** 
→H.265とは、従来のH.264と比べて圧縮率が２倍になっているので動画ファイルのサイズが大幅に削減され、８Kにも対応している

 **エンコード結果はSNSにしか送れない** 

#結果

今回比較してみて、必ずしもどちらがいいとは言えない結果となりました。
WebM出力・MP3オーディオのみの出力・アニメーションGIF出力などを使う場合は、 **ElasticTranscoder**。
それ以外の場合は、コストメリット・最先端フォーマットへの対応などの利点から **MediaConvert** など、必要な機能やコストなどそれぞれの特徴を踏まえて利用するのが良さそうです！:sparkles:

最後までありがとうございました:bow_tone1:
##参考サイト

・https://docs.aws.amazon.com/ja_jp/mediaconvert/latest/ug/more-about-audio-tracks-selectors.html
・https://aws.amazon.com/jp/mediaconvert/
・https://aws.amazon.com/jp/elastictranscoder/faqs/
・https://qiita.com/ryotax/items/445ec80b18af30b85054
ソースコードからdebパッケージを作成する(goの参考ビルド例付き)

# TL;DR

* ソースコードからコンパイルするソフトウェアツールを，ubuntu 18.04などのdebパッケージにまとめる手順を説明します
    * いわゆる野良ビルドなので，利用には注意が必要です
    * ```go```のインストールを例に説明します

# 手順

* ```check-install```コマンドを使用してdebパッケージを作ります．
* ツールをソースからインストールする際に行う，いつもの手順```./configure && make && sudo make install```の3番めの```make install```の代わりに，```checkinstall```コマンドを使用するだけで，debパッケージを生成できます．
* golangのソースコードにはMakefileが無いので，自分でMakefileを作ってしまいます
    * Makefileには，```all```，```install```，```uninstall```の3つのディレクティブの記載が必要です

# check-installのインストール

```bash
aptitude isntall checkinstall
```

# go用Makefileの作成

* 以下のコードをMakefileとして保存します．
    * goをソースコードからビルドする手順を```all```ディレクティブに記述します
    * ビルド済みバイナリを(実行できるディレクトリに)コピーする手順を，```install```ディレクティブに記述します
        * バージョンをディレクトリ名に追記しているので，```/usr/local/go```ディレクトリにシンボリックリンクを張ります
    * インストールしたファイル群を削除する手順を，```uninstall```ディレクティブに記述します

```Makefile:Makefile
#!/bin/env make

all:
	wget https://dl.google.com/go/go1.13.5.src.tar.gz
	wget https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz
	mkdir go1.13.5 && tar xzvf go1.13.5.src.tar.gz -C go1.13.5 --strip-components 1
	mkdir go1.4-bootstrap && tar xzvf go1.4-bootstrap-20171003.tar.gz -C go1.4-bootstrap --strip-components 1
	cd ./go1.4-bootstrap/src && \
	CGO_ENABLED=0 bash ./make.bash && \
	cd -
	cd ./go1.13.5/src && \
	GOROOT_BOOTSTRAP=${PWD}/go1.4-bootstrap bash ./all.bash && \
	cd -

install:
	cp -r go1.13.5 /usr/local/go1.13.5
	ln -s /usr/local/go1.13.5 /usr/local/go

uninstall:
	rm -rf /usr/local/go1.13.5 /usr/local/go

clean:
	rm -f go1.13.5.src.tar.gz go1.4-bootstrap-20171003.tar.gz
	rm -rf go1.13.5 go1.4-bootstrap
```

# debパッケージの作成

* ```make install```の代わりに，```checkinstall```コマンドを実行します
    * ```--install=no```オプションを使用しインストール作業は行いません
    * インストールは生成されたdebパッケージを使用します
    * checkinstall時に出てくる質問には基本的にはすべてエンターキーでデフォルト値を選択します

```bash
sudo checkinstall --install=no
# 質問には基本的にはすべてエンターキーでデフォルト値を選択する
# go_20191227-1_amd64.deb
```

# パッケージのインストール&アンインストール

```bash
### インストール
dpkg -i go_20191227-1_amd64.deb

### 確認作業
export PATH=/usr/local/go/bin:${PATH}
which go
# /usr/local/go/bin/go
go version
# go version go1.13.5 linux/amd64

### アンインストール
dpkg -r go
```

# 参考

* [意外に簡単！Debパッケージを自作する方法](http://note.kurodigi.com/debpackage/)
* [Qiita golangをソースコードからインストールする(CentOS/Ubuntu)](https://qiita.com/myoshimi/items/5d1f6a2ee8a849bac7eb)
Officeのボリュームライセンス認証で遭遇した現象のメモ

# はじめに

仕事をしていると、マイクロソフトのOVS-ESは非常に便利なので、経費で購入した端末で利用しています。(個人端末ではOffice365 ProPlusが別に利用可能)

Windows7をWindows10にアップグレードする作業中に遭遇した現象をメモしておきます。

# 現象

Officeのインストール後で、cscriptでospp.vbsを実行したタイミングで、次のようなメッセージが表示されていました。

```text
C:\Program Files\Microsoft Office\Office16>cscript ospp.vbs /sethst:example.com
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.

---Processing--------------------------
---------------------------------------
Successfully applied setting.
---------------------------------------
---Exiting-----------------------------

C:\Program Files\Microsoft Office\Office16>cscript ospp.vbs /act
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.

---Processing--------------------------
---------------------------------------
<No installed product keys detected>
---------------------------------------
---------------------------------------
---Exiting-----------------------------
```

これは原因が不明なまま、解決しています。

# 解決までの作業内容

最初はオフィスアプリを起動せずに、インストールスクリプトが終了した直後に、ospp.vbsを実行していました。

1. ライセンスの認証状況を確認するためWordを起動し、ファイル→アカウント→今すぐ更新(更新オプション内)を実行
2. 再度ospp.vbs /actを実行し、解決

更新する前にバージョン情報からライセンス認証状況の詳細を確認するべきで、ライセンス認証がされていない状態だったか定かではないのですが、更新をした後は無事にライセンス登録でき、利用できています。
golangをソースコードからインストールする(CentOS/Ubuntu)

# TL;DR

* Go言語のプログラムのコンパイラ＋実況環境(```go```コマンド)をソースコードからインストールする方法を紹介します

# Go言語のビルド手順

[Installing Go from source](https://golang.org/doc/install/source)の説明をもとにインストールします．

直近のバージョンのgoは，goでビルドします．そのため，(以前のバージョン)```go1.4```をいったんビルドしてから，最近のバージョンのgoをビルドする手順を取ります
(もとの説明は「[Bootstrap toolchain from source](https://golang.org/doc/install/source#bootstrapFromSource)」にあります)．

手順は以下のとおりです．使用したいgoを1.13.5(2019年12月27日時点)とします．

1. go1.4をダウンロード，ビルドする
1. go1.13.5をダウンロード，go1.4のディレクトリを指定してビルドする

# go1.4のビルド

* まず最初に，goを使用しないでビルドできるgo1.4をダウンロードし，ビルドします

```
wget https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz
mkdir go1.4-bootstrap && tar xzvf go1.4-bootstrap-20171003.tar.gz -C go1.4-bootstrap --strip-components 1
cd ./go1.4-bootstrap/src
CGO_ENABLED=0 bash ./make.bash
cd -
```

* go1.4-bootstrap-20171003.tar.gzをダウンロードします
* 展開後のディレクトリ名が```go```で，以降のgo1.13.5とバッティングしてしまうので，```go1.4-bootstrap```という名前のディレクトリに展開します
* ```make ./make.bash```で，最小限のビルドを行います
* ```go1.4-bootstrap/bin```に```go```，```gofmt```が生成されます

# go1.13.5のビルド

```
wget https://dl.google.com/go/go1.13.5.src.tar.gz
mkdir go1.13.5 && tar xzvf go1.13.5.src.tar.gz -C go1.13.5 --strip-components 1
cd ./go1.13.5/src
GOROOT_BOOTSTRAP=${PWD}/go1.4-bootstrap bash ./all.bash
cd -
```

* go1.13.5.src.tar.gzをダウンロードします
* 特段ディレクトリ名を変更する必要はないのですが，他のディレクトリと混在しないようにバージョン名を含めた名前で展開します
* ```go1.13.5/src```ディレクトリに移動して，ビルドします．このとき環境変数```GOROOT_BOOTSTRAP```に，前章でビルドしたgo1.4のディレクトリを指定します
* ```go1.13.5/bin```に```go```，```gofmt```が生成されます

# ビルドしたgo1.13.5ディレクトリを実行パスに移動

ビルドしたgo1.13.5ディレクトリをわかりやすい場所に移動します．

```
mv ./go1.13.5 /usr/local/
ln -s /usr/local/go1.13.5 /usr/local/go
```

# テスト

```/usr/local/go/bin/go``` が使用できることを確認します．

```
export PATH=/usr/local/go/bin:${PATH}

which go
# /usr/local/go/bin/go
go version
# go version go1.13.5 linux/amd64
```

# 参考

* [Installing Go from source](https://golang.org/doc/install/source)
* [Bootstrap toolchain from source](https://golang.org/doc/install/source#bootstrapFromSource)
ファイル名一括変更

```python:change_filename.py
import os
import glob

path = "./input_dir"
files = glob.glob(path + '/*')

for i, f in enumerate(files):
    os.rename(f, os.path.join(path, 'new_file-'+'{0:05d}'.format(i) +'.jpg'))
# new_file-00000.jpg , new_file-00001.jpg

```
VCR rspec error : Psych::SyntaxError: could not find expected ':' while scanning a simple key at line

maybe VCR cassettes file broken by hand
once I removed cassettes file and re run rspec and fixed it 

```
     Failure/Error: parser.parse yaml, filename

     Psych::SyntaxError:
       (<unknown>): could not find expected ':' while scanning a simple key at line 4969 column 1
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2925








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
[iOS] UITextViewにハイパーリンクを設定する〜テキストの一部を正規表現で抽出して〜

これはアプリのUITextViewの一部にハイパーリンクを設定する実装例となります。
取得する文章データから正規表現でリンクを抽出してハイパーリンクを設定します。

``` ex.swift
func setup(text: String) {
    // リンク設定
    textView.linkTextAttributes = [
        NSAttributedString.Key.foregroundColor: UIColor.maiFontBlue,
        NSAttributedString.Key.underlineStyle: 1
   ]

    // リンクの抽出
    var hyperlinks: [(link: String, word: String)] = []
    do {
        let regex = try NSRegularExpression(pattern: "<a href=\"(.*?)\".*?>(.*?)</a>")
        let nsString = text as NSString
        let matches = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
        let links = matches.map { nsString.substring(with: $0.range(at: 1))} // 正規表現のグループ１（１つ目の"(.*?)"部分）を抽出できる
        let words = matches.map { nsString.substring(with: $0.range(at: 2))} // 正規表現のグループ2（２つ目の"(.*?)"部分）を抽出できる
        links.enumerated().forEach { index, link in
            if words.count > index {
                let hyperlink = (link: link, word: words[index])
                hyperlinks.append(hyperlink)
            }
        }
    } catch {
        // Nothing
    }
    
    var attributes: [NSAttributedString.Key: NSObject] = [:]
    attributes[NSAttributedString.Key.foregroundColor] = .black
    textView.attributeText = NSAttributedString(string: text, attributes: attributes)

    // ハイパーリンクの設定
    if hyperlinks.count > 0 {
        let atttributedText = NSMutableAttributedString(attributedString: textView.attributedText)
        let nsText = atttributedText.mutableString
        hyperlinks.forEach { hyperlink in
            let nsrange = nsText.range(of: hyperlink.word)
            atttributedText.addAttribute(.link, value: hyperlink.link, range: nsrange)
        }
        textView.attributedText = atttributedText
    }

}
```
眺めて覚えるGo言語 その8 関数の書き方

# 一般的な関数の書き方

``` f1.go
package main
func add(a,b int)int{
	return a+b
}
func main(){
	print(add(10,20))
}

実行
>go run f1.go
30
```

　- a,b intは、引数です。intは、引数の型を表します。
　- その後ろに書いてあるintは、戻り値の型を示します。

#慣れてきたらnamed return value(naked return)を使ってみよう
```f2.go
package main
func fun(a ,b int)(x,y,z int){
	x=a*10
	y=b*20
	z=a+b
	return
}
func main(){
	a,b,c:=fun(10,20)
	println(a,b,c)
}

実行
>go run f2.go
100 400 30

```

- あらかじめ戻り値を定義することによりreturn一発で戻ることができる。(x,y,z int)

```f3.go
package main
func fun(a ,b int)(x int,err string){
	if (b==0) {
		err="ゼロでで割るな"
		return
	}
	x=a/b
	return
}
func main(){
	for i:=3;i>=0;i-- {
		a,err:=fun(10,i)
		println(i,a,err)
	}
}

実行
>go run f3.go
3 3
2 5
1 10
0 0 ゼロでで割るな
```
Go言語には、例外処理がない。あらかじめ考慮してプログラムする必要がある。

# OSやコンパイラ頼みのアプリケーションは、運用側のエンジニアに多大な迷惑がかかる。
Vue.jsでhoverしたら要素を出現させる方法

Vue.jsでマウスのhoverアクションで何か要素を出現させたい時があるかと思います。
そんな時は、mouseoverとmouseleaveを使います。

```html:index.html
<p v-on:mouseover="mouseOverAction" v-on:mouseleave="mouseLeaveAction">{{message}}</p>
```
mouseoverはマウスが乗った時、mouseleaveはマウスが外れた時にイベントが発火します。
これとv-ifを組み合わせるとマウスが乗った時に要素を出現させることができます。

![hoverAction.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/62fb79d7-2935-468b-c31c-8e89b970b553.gif)

```html:index.html
    <div id="app">
        <div class="container">
            <p v-on:mouseover="mouseOverAction" v-on:mouseleave="mouseLeaveAction">{{message}}</p>
            <p v-if="hoverFlag">hoverされました</p>
     　　</div>
    </div>
    <script>
        new Vue({
            el: '#app',
            data:{
                message: 'hoverしてください',
                hoverFlag: false,
            },
            methods: {
                mouseOverAction(){
                    this.hoverFlag = true
                },
                mouseLeaveAction(){
                    this.hoverFlag = false
                }
            }
        })
    </script>
```
mouseover、mouseleaveでdataのhoverFlagを更新しています。それによりif文のtrueとfalseが入れ替わります。
v-showでも可能です。

また、引数をとることができるので、for文で複数の要素がある場合でも特定の要素だけを対象にすることができます。

```haml:index.html
   <div id="app">
        <div class="container">
            <div v-for="(num,index) in 5">
                <p v-on:mouseover="mouseOverAction(index)" v-on:mouseleave="mouseLeaveAction(index)">{{message}}</p>
                <p v-show="hoverFlag && index === hoverIndex ">hoverされました</p>
            </div>
        </div>
    </div>
    <script>
        new Vue({
            el: '#app',
            data:{
                message: 'hoverしてください',
                hoverFlag: false,
                hoverIndex: null,
            },
            methods: {
                mouseOverAction(index){
                    this.hoverFlag = true
                    this.hoverIndex = index
                },
                mouseLeaveAction(){
                    this.hoverFlag = false
                }
            }
        })
    </script>

```
![hoverlist.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/8110e157-c540-6ac9-61be-c7752d4e22f6.gif)
AWRスナップショットの取得間隔と保存期間の設定変更

OCIに移行した際にスナップショットの設定を変更したので、そのまとめ。

## 前提
OCIにてAWRは自動でスナップショットを取得する様になっているが、
取得間隔と保存期間はデフォルトでは以下の様に設定されている。

| 項目 | 設定 |
| :--- | ---: |
| 取得間隔 | 1時間 |
| 保存期間 | 8日 |

上記の設定を変更するには、「DBMS_WORKLOAD_REPOSITORY」プロシージャを使用する。
設定する際の時間の単位はいずれも「分」単位であることに注意。

```
EXECUTE DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(
  interval  =>  60,
  retention =>  20160);
```


## 実行例

以下実行例ではプロシージャを使用して取得間隔=30分、保存期間を40日(60min*24h*40day=57,600min)に設定する。

```
SQL> set lines 180 pages 10000
SQL> col SNAP_INTERVAL for a30
SQL> col RETENTION for a30
SQL> select snap_interval, retention from DBA_HIST_WR_CONTROL;

SNAP_INTERVAL                  RETENTION
------------------------------ ------------------------------
+00000 01:00:00.0              +00008 00:00:00.0

SQL>
SQL> exec DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(interval => 30, retention => 57600);

PL/SQLプロシージャが正常に完了しました。

SQL>
SQL> select snap_interval, retention from DBA_HIST_WR_CONTROL;

SNAP_INTERVAL                  RETENTION
------------------------------ ------------------------------
+00000 00:30:00.0              +00040 00:00:00.0

SQL>
```


## 留意点

スナップショットの取得間隔を短くすれば、AWRにより収集されるデータ量が増加するため、
取得間隔を短くするほど、SYSAUX表領域の使用率は増える。
マニュアル曰く
「デフォルトでは、スナップショットは1時間に1回取得され、データベースに8日間保存されます。
これらのデフォルト設定では、同時アクティブ・セッション数が平均10の標準的なシステムの場合、
AWRデータ用に約200から300MBの領域が必要になる可能性があります。」
ということなので、やみくもに短くするのではなく、
しっかりと検証した上で設定しないと痛い目を見ることもあり得る。


## 参考

[Oracle Database PL/SQLパッケージおよびタイプ・リファレンス 11g リリース2(11.2)](https://docs.oracle.com/cd/E16338_01/appdev.112/b56262/d_workload_repos.htm#BACEHJJI)
[Oracle Databaseパフォーマンス・チューニング・ガイド 11gリリース2 (11.2)](https://docs.oracle.com/cd/E16338_01/server.112/b56312/autostat.htm#PFGRF94182)
Firestoreにおける（クライアント側）集計


RDBと違い、Firestoreにおける集計は原則クライアント再度で行う必要があります。
その際の基本的なメモ。なお、JSにおける（配列の）集計処理にはreduceを使うことになりますが、それについては[こちら](https://qiita.com/zaburo/items/fc8f74d144d73b7d70b6)の記事をご覧ください。

## 前提

* firebase-adminを利用してみます。
* 秘密鍵は準備されているものとします。

## テストデータの作成

下記のようなデータをfirestoreに登録します。

```js:createData.js
const admin = require('firebase-admin');
admin.initializeApp({
    credential: admin.credential.cert("/path/to/key.json"),
    databaseURL: "https://xxxxxxxx.firebaseio.com"
});

const db = admin.firestore();

const commodities = [
    { id: 1, name: "apple", category: "fruit", price: 300 },
    { id: 2, name: "cucumber", category: "vegetable", price: 100 },
    { id: 3, name: "orange", category: "fruit", price: 300 },
    { id: 4, name: "grape", category: "fruit", price: 100 },
    { id: 5, name: "cabbage", category: "vegetable", price: 200 },
];

(() => {

    commodities.map(async item => {
        await db.collection("sales").add(item);
    })

    console.log("完了");

})()
```

>key名とかしっくりこないけど、まあとりあえずOKとする。

## データの集計

登録が完了したら集計してみます。

```js:getSummary.js
const admin = require('firebase-admin');
admin.initializeApp({
    credential: admin.credential.cert("/path/to/key.json"),
    databaseURL: "https://xxxxxxxx.firebaseio.com"
});

const db = admin.firestore();

(async () => {

    //get data
    const snapshot = await db.collection("sales").get();

    //sum(単純計算)
    const sum = snapshot.docs
        .map(doc => doc.data().price)
        .reduce((prev, current) => prev + current, 0);

    console.log(sum);

    //groupBy（データ整形）
    const groupBy = snapshot.docs
        .map(doc => doc.data())
        .reduce((prev, current) => {
            const element = prev.find(value => value.category === current.category);
            if (element) {
                element.count++;
                element.price += current.price;
            } else {
                prev.push({
                    category: current.category,
                    count: 1,
                    price: current.price,
                });
            }
            return prev;
        }, []);

    console.log(groupBy);

})()
```

### 実行結果

下記のような結果が得られるはずです。これをダッシュボード等に描画したり、帳票で出したりすることになります。

```bash
1000

[
  { category: 'fruit', count: 3, price: 700 },
  { category: 'vegetable', count: 2, price: 300 }
]
```
GCP アップデート (1/10-1/16 2020)


### GCE: [Jan 9, 2020](https://cloud.google.com/compute/docs/release-notes#january092020)
- Nvidia T4が全リージョンで安くなったよ！

### Cloud Run: [Jan 7, 2020](https://cloud.google.com/run/docs/release-notes#January_07_2020)
- コンテナポートを指定できるようになったよ。ただし、ポータビリティのために$PORTを推奨。
- ローカルのconfigファイルからgcloud betaコマンドでデプロイできるようになったよ。
- デプロイ済みのコンテナにコマンドや引数を指定できるようになったよ。
- ``--revision-suffix``を使ってバージョン名を指定できるようになったよ。

### TPU: [Jan 9, 2020](https://cloud.google.com/tpu/docs/release-notes#January_09_2020)
- TPUがkerasのサポート付きのTensorFlow2.1をサポートするようになったよ。

### VPC: [Jan 1, 2020](https://cloud.google.com/vpc/docs/release-notes#January_01_2020)
- 外部IPをインスタンスで使っていても課金されるようになったよ。(東京だとstandardで\$0.004、preemptibleで\$0.002。使ってないIPは\$0.015なので1/4ぐらい。)
- ただし、3/31までは無料なので、請求でいくらぐらいになるか確認すると良い。
- NATやIAP等揃ってきて外部IPをインスタンスにつけるのが必須なケースそこまで多くないはずなので課金始まる前に変えるのが良さそう。

### LB: [Jan 6, 2020](https://cloud.google.com/load-balancing/docs/release-notes#January_06_2020)
- ドキュメントにLBごとの[機能一覧の表](https://cloud.google.com/load-balancing/docs/features)が追加されたよ。

### Dataproc: [Jan 10, 2020](https://cloud.google.com/dataproc/docs/release-notes#January_10_2020)
- サブマイナーバージョンのリリース (1.2.88-debian9, 1.3.48-debian9, 1.4.19-debian9, 1.5.0-RC4-debian10, 1.3.48-ubuntu18, 1.4.19-ubuntu18, 1.5.0-RC4-ubuntu18)
- dataprocで使われてるhadoopやsparkのwebインタフェースにアクセスできるComponent Gatewayに、プロジェクトやクラスタ名が表示されるようになったよ。

### Functions: [Jan 14, 2020](https://cloud.google.com/functions/docs/release-notes#January_14_2020)
- Go 1.13がベータで追加。

### BigQuery: [Jan 14, 2020](https://cloud.google.com/bigquery/docs/release-notes#January_14_2020)
- スロットを予約、管理できるReservationsがLondon(europe-west2)で使えるようになったよ。

### AI Platform: [Jan 14, 2020](https://cloud.google.com/ml-engine/docs/release-notes#january_14_2020)
- NVIDIA Tesla T4でトレーニングする際のコストが安くなったよ！ (アジアだと\$1.03/hrが\$0.39/hrに！)

### AI Platform: [Jan 15, 2020](https://cloud.google.com/ml-engine/docs/release-notes#january_15_2020)
- NVIDIA Tesla T4でオンラインプレディクションする際のコストが\$0.95/hrから\$0.35/hrになったよ！
- (現状オンラインプレディクションでGPU使えるのはus-central1でN１使った場合のみ。)

### DataFusion: [Jan 10, 2020](https://cloud.google.com/data-fusion/docs/release-notes#January_10_2020)
- 6.1.1がリリースされたよ。安定性やパフォーマンス以外に以下が追加。
  - Azure Data LakeがWranglerで使えるように。
  - Field Level Lineageがベータに。
  - DLP連携がベータに。(at scaleと原文にあるので分散して実行してくれる？)

### LB: [Jan 15, 2020](https://cloud.google.com/load-balancing/docs/release-notes#January_15_2020)
- GCSをバックエンドとして追加するドキュメントの更新



### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートが追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
Next.js+Typescript+Express環境をサクッと構築する

create-next-app のexampleは便利だけど、「Next.js+Typescript+Express」の環境を作るテンプレートがなく、結構調べました；；
でも、結果としてとても簡単に導入できることがわかったので、メモがてらqiitaに投稿。

### 1. プロジェクト作成

下記コマンドでカスタムサーバを使ったtypescriptのプロジェクトを作成

```bash
$ create-next-app --example custom-server-typescript {ProjectName}
```
### 2. expressパッケージと型定義追加

```bash
$ yarn add express
$ yarn add --dev @types/express
```

### 3. `server/index.tsx` を修正

下記に書き換える

```typescript

import next from 'next'
const express = require('express')
const port = parseInt(process.env.PORT || '3000', 10)
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = express()
  server.get('*', (req: any, res: any) => {
    return handle(req, res)
  })
  server.listen(port, (err: any) => {
    if (err) throw err
    console.log(`> Ready on ${process.env.CLIENT_URL || `http://localhost:${port}`}`)
  })

})
```

### 4. 起動

```bash
$ yarn dev
```
【Watson Studioメモ】「Watson Studioが動かない」場合にチェックすべき点

# はじめに
**Watson Studio**は、ユーザーのサインアップさえすれば、クレジットカード登録もなしに簡単に使えるクラウド上の機械学習モデル開発環境です。とても便利な環境なのですが、企業のお客様から使う場合、いろいろな落とし穴があり。。
最近、表記の件でいろいろ苦労したので備忘録を兼ねてアップしておきます。

# ブラウザ問題
サポートしているブラウザは**Chrome**と**Firefox**です。
Windowsの場合は特に注意が必要で**IE**はもちろん？ダメなのですが、**Edge**もうまくいかないようです。
Firefoxであってもバージョンが古いとNGであったケースがあり、この点も要注意です。
ちなみに、Macユーザーの方は**Safari**がどうか気になると思います。実は私もSafariを普段使いするMacユーザーなのですが、経験上、Watson Studioのほとんどの機能は使えるが、ごくまれに使えないケースがあるという感じです。

# キャッシュ問題
サポートしているブラウザであっても「前に使えていたのに使えない」ケースが時々あります。このような場合は、ゴミの状態で残っているブラウザのキャッシュが悪さをしている可能性があるので、一度、関連するキャッシュデータをすべてクリアしてみて下さい。

# ネットワーク問題
もう一点注意が必要なのが、Firewallです。Watson Studioでは標準で**WSS（Web Socket Secure)**を使っています。**https**とは別のプロトコルになるので、企業によっては、Firewallで閉じられてしまっているケースがあります。こうした場合、Watson Stduioが使えなくなってしまうので、注意が必要です。
WSSが何かは、ググると沢山記事が出ていますが、例えばこのあたりがわかりやすいかと。

[WS および WSS のサポートについてのよくある質問](https://jp.alibabacloud.com/help/doc-detail/63421.htm)

# ログインできたが該当プロジェクトが見えない
次の2つのことを試してみて下さい。

## 「View All Project」
下のようなWatson Studioログイン直後の画面で、左上の「三」のアイコンをクリックします。

![スクリーンショット 2020-01-18 10.06.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/5e729f2c-bf25-6e88-007c-326b77e7036b.png)

次のようなメニューが出てくくるので、「View All Projects」を選択します。

![スクリーンショット 2020-01-18 10.06.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/c9842a27-59bf-24d7-be49-cccb512304a2.png)

まれにこれでも出てこない場合があります。その場合、上記画面の一番下にある**Show more**のボタンをクリックして下さい。

## プロジェクトの登録サイトの確認

Watson Studioのログイン画面は、サイト(ダラスとか東京など)によって別々になっています。上記の対応でも見つからない場合、サイトを間違えている可能性があります。管理者に相談して、この点を確認してみて下さい。

ダラス https://dataplatform.cloud.ibm.com/

東京 https://jp-tok.dataplatform.cloud.ibm.com/

ちなみにどちらのサイトの画面かは、下記のようにURLをチェックすればわかります。

##### [ダラス]
![スクリーンショット 2020-01-21 7.55.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/a11d7f13-7840-4e81-76e2-fb80b53518c2.png)

##### [東京]
![スクリーンショット 2020-01-21 7.56.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/8c68a871-1efa-85b5-71dc-361454785768.png)
Amazon API GatewayにBasic認証をかける方法

# 更新
## 2020/09/21
`event['headers']`の中身が変わってた

```diff
-event['headers']['authorization']
+event['headers']['Authorization']
```

# はじめに

ちょっとしたテスト用のAPIをAmazon API Gatewayで作ったのですが、あんまり外部公開はしたくない…でもガッチガチなセキュリティが必要なほど重要なものでもない…
というわけでBasic認証をかける方法を調べたメモです。
いくつかハマリポイントがありました。

# 大まかな流れ
API GatewayでBasic認証する大まかな流れ。

1. API Gatewayのオーソライザーに認証をするLambda関数を指定する。
2. オーソライザーのIDソースにauthorization (header)を設定する。
3. API Gatewayの「ゲートウェイのレスポンス」の401レスポンスにWWW-Authenticateヘッダーを追加する。
4. メソッドリクエストの設定でオーソライザーを指定する。

## Lambda関数の作成
AWS Lambdaのダッシュボードから関数を作成します。Rubyが好きなのでここではRubyを選択しています。

名前は適当に、実行ロールは「基本的な Lambda アクセス権限で新しいロールを作成」でOKです。

```rb:lambda-authorizer-basic-auth
require 'aws-sdk-kms'
require 'base64'

def lambda_handler(event:, context:)
  if basic_auth(event)
    # Basic認証で認可する場合は次のようなIAMポリシーを返す
    {
      'principalId': 'user',
      'policyDocument': {
        'Version': '2012-10-17',
        'Statement': [
          {
            'Action': 'execute-api:Invoke',
            'Effect': 'Allow',
            'Resource': event['methodArn']
          }
        ]
      }
    }
  else
    # 認可しない場合は例外を送出する
    raise 'Unauthorized'
  end
end

# Basic認証する適当メソッド
def basic_auth(event)
  # ユーザー名とパスワードはLambdaの環境変数に暗号化して保存してある。
  user = Aws::KMS::Client.new.decrypt({ ciphertext_blob: Base64.decode64(ENV['user']) }).plaintext
  password = Aws::KMS::Client.new.decrypt({ ciphertext_blob: Base64.decode64(ENV['password']) }).plaintext

  # event['headers']['Authorization']にBasic認証の認証情報が入っている
  auth_header = event['headers']['Authorization']

  # 適当に認可
  auth_str = 'Basic ' + Base64.strict_encode64("#{user}:#{password}")
  auth_header == auth_str
end
```

オーソライザーのドキュメントは[こちら](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html)にあります。
ドキュメントの例がNode.jsだったので、Rubyの場合は認可しない場合に何を返せばいいのかわからず悩んだのですが、`raise`してエラーを送出すれば良いようです。
(Node.jsのcallbackの引数を[ちゃんと調べれば](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/nodejs-prog-model-handler.html)わかることでした)

## オーソライザーの設定
API Gatewayのダッシュボードから次のようにオーソライザーを設定します。

ポイントはIDソースに`authorization`ヘッダーを設定することです。これによりブラウザなどからのBasic認証を伴うリクエストをLambda関数に渡すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38266/c9a98bac-5d05-e61f-0f88-54b7f3bcdc40.png)

## 401レスポンスの設定
Basic認証なしでAPIにアクセスした場合に401エラーを返しますが、そのときにBasic認証が必要であることをブラウザなどに伝える必要があります。これがないと、ブラウザのBasic認証ダイアログなどが出ないので困ります。

「ゲートウェイのレスポンス」→「権限がありません」→レスポンスヘッダーに`WWW-Authenticate`、値に`'Basic'`を追加します。静的な値の場合は`''`で囲む必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38266/0d907215-34e3-98c0-210e-d6938af5e737.png)

## メソッドの設定
あとはBasic認証をかけたいAPIメソッドの設定で、認可の方法に先のオーソライザーを指定するだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38266/aad85d7d-d152-9e61-7c3c-bf353669e8ed.png)

## その他

オーソライザーやレスポンス、メソッドの設定を変えた後はデプロイしないとAPIに反映されないので気をつけましょう(n敗)

# おわりに

AWS勉強中なのですが色々わからない概念が多くてつらいです。
記事のコード中のコメントにIAMロールを返すとかもっともらしく書いてありますが、それが何かはよくわかっていない模様。

今回はブラウザからAPIにアクセスする必要があったのでBasic認証にしましたが、アプリケーションなどからアクセスする場合は[APIキー](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-api-usage-plans.html)使ったほうが楽だと思います。
I understand #Ruby Lonely operator &. is a operator allows nil receiver method chains



If receiver is nil you can do method chains many times

```rb
nil&.to_wow
# => nil
nil&.to_wow&.to_ya
# => nil
nil&.to_wow&.to_ya&.to_yes!
# => nil
```

If not nil is reciever then you can not chain undefined method by lonely operator

```rb
100&.to_wow
NoMethodError: undefined method `to_wow' for 100:Integer
```


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2924








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ASP.NET Core 3.1 RazorPagesで工数管理アプリを作ってみる①-設計編



#はじめに
本投稿では個人的に気なっていた ASP.NET Core 3.1 RazorPages で工数管理アプリを作ってみます。
”設計 ～ Azure 上で動かして試験運用するまで”をいくつかの投稿に分けて残していきます。
ご指摘事項等あればコメント頂けますと幸いです。

また、あくまで自分の備忘録でもあるので読みにくい部分ご了承ください！

#背景
本投稿の背景は下記の通りです。

###PJマネジメント業務が増えてきたから
メンバの工数管理とかしたいけど、既存のエクセルによる管理が不便すぎる。
どのPJのどの作業にメンバが工数を割いているのか集計しにくい。しかも予実管理も見えにくい。
あと、工数管理と出退勤管理のシステムが異なるので入力が面倒。
###ASP.NET Core 3.1 RazorPagesを触ってみたい
PJマネジメント業務が多くて最近自分でコーディングできていないので単純に触ってみたい。。。
###MCPの勉強のために
先日AZ-203を受けたのですが撃沈・・・
次回受験の勉強のためにも試験範囲のサービスとかいろいろ実際に使ってみたい。

####**工数管理は良いやり方はいっぱいありますが、上記理由よりあえてシステム自作したいと思います。**

#開発の条件
・VS code で開発
・一応簡単に設計はする
・**本業ではないのでできる限り省力化を行う！**



ということでさっそく設計から入っていきたいと思います。
#システム設計
##ユースケース
上記のとおり、PJに関わるメンバの工数管理&出退勤管理をしたいのでシステムのユースケースはこんなイメージです。
####PJメンバができること
・日ごとにどのPJの何の作業に何時間使ったのか工数入力できる
・併せて出退勤、残業管理もできる
####PJマネージャができること
・担当するPJの工数を様々な条件(※)で集計/分析できる
・PJの作業を管理できる(WBS)
・PJの作業の予定工数を管理できる(人のアサインとかができる)
####統括マネージャができること
・全てのPJの工数を様々な条件(※)で集計/分析できる
・PJメンバの出退勤登録の承認ができる
####勤怠管理者ができること
・PJメンバの出退勤状況の集計ができる

(※)基本的にはPJ単位、またはPJメンバ単位で過去の作業工数の予実確認ができる。先数か月分の予定登録ができる。

##ユースケース図
上記をユースケース図にまとめるとこんな感じです。
とりあえずシステム名は「Kosu M」としました。

(※)UML作成は下記を参考にさせていただきました。
[Visual Studio Code で UML を描こう！](https://qiita.com/couzie/items/9dedb834c5aff09ea7b2)
[PlantUML Cheat Sheet](https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48)

登場人物とか機能とかを考え始めると思ったより複雑に。。。

![UseCaseDiagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489752/1576d5f8-e3b5-a78b-4d25-e7ca4a242d85.png)

##機能一覧
必要な機能は下記のイメージと思います。

|機能|ユースケース（概要）|
|:-----------------|:-----------------|:------------------|
|ログイン機能|ID/パスワードでログインできる。|
|トップ表示|ログインユーザの情報をパッと見できる。|
|作業工数管理機能|出退勤登録や工数登録ができる。|
|PJ管理機能|新しいPJの作成/編集やその作業の登録ができる。各PJの作業工数の集計(予実管理)ができる。|
|出退勤管理機能|PJメンバの出退勤状況を集計/承認できる。|
|PJメンバ管理機能|グループ/所属/PJメンバの登録/編集ができる。|

ログインとかグループ/所属の管理は追々 Azure AD 連携とかID機能利用を検討したいと思います。

##ER図
簡単なデータ概念は下記のイメージとしました。
![ClassDiagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489752/288b75b0-e230-384a-d7ed-195f80fd20b2.png)


下記を参考に Plantuml でER図も書かせていただきました。
[PlantUML で ER 図（ERD）を描く（似非ではないです）](https://qiita.com/Tachy_Pochy/items/752ef6e3d38e970378f0)

#一応これで簡単な設計は終了
よという事で次はいよいよ ASP.NET Core 3.1 RazorPages を触り始めたいと思います。
まずはマスタ管理機能から！

[ASP.NET Core 3.1 RazorPagesで工数管理アプリを作ってみる②-マスタ管理編](https://qiita.com/hasenagata/private/8f54ae12e2c5bdf954af)
AutoLISPでAutoCADコマンドを実行する 

AutoLISPからAutoCADの標準コマンドを実行するには、command関数を使用する。

## command関数の使い方
command関数の引数に、AutoCADコマンドを文字列(" " で囲む)で記入する。

```scheme
(command "コマンド名" "引数" "引数" ･･･) 
```

#####【例１】線分(LINE)コマンドで座標 20,30 から 座標 50,100 まで線分を作成する

```scheme
(command "LINE" "20,30" "50,100" "") 
```
最後の引数の "" はEnterキーを押すのと同じ動作となる。
空Enterすることで、LINEコマンドを終了している。
この例のように、command関数の引数は、AutoCADのコマンドラインからコマンドを実行する場合と同じように記述する。
同じ動作をコマンドラインから実行するには、

```
LINE [Enter]
20,30 [Enter]
50,100 [Enter]
[Enter]
```
となる。

##### 【例２】ユーザーが2点を選択して、線分を作成する
```scheme
(command "LINE" PAUSE PAUSE "") 
```
引数の PAUSE は AutoLISPの定義済定数で、ユーザー入力を行うために使用する。

##### 【例３】変数に保存された値から、線分を作成する
```scheme
(setq p1 '(20 30))
(setq p2 '(50 100))
(command "LINE" p1 p2  "")  
```
##### 【例４】getpoint関数を使用して、ユーザーが選択した点を変数に保存し、その変数に保存された値を使って線分を作成する
```scheme
(setq p1 (getpoint "\n一点目を指示"))
(setq p2 (getpoint p1 "\n二点目を指示"))
(command "LINE" p1 p2  "") 
``` 
##### 【例５】座標100,100を中心とした半径50の円を作成
```scheme
(command "CIRCLE" "100,100" "D" "50")
```
自分用色々メモ

色々メモ

### Gitをインストールする
* git config でメールアドレス、名前を設定する
* sshキーを登録する

ローカルブランチ名を指定して、リモートブランチをチェックアウトする
`git checkout -b other_branch origin/other_branch`

リモートブランチにpushする
`git push origin feature/hogehoge`

ブランチを削除する（強制削除）
`git branch -D branch_name`

stashしたファイルの一覧を見る
`git stash show stash@{0}`

stashしたファイルのdiff
`git diff stash@{0} hogehoge.rb`


### rbenvでrubyのバージョン管理

インストールできるRubyの一覧
`rbenv install --list`

インストールされているRubyの一覧
`rbenv versions`

インストールバージョン
`rbenv version`

インストールする
`rbenv install 2.4.1`

更新
`rbenv rehash`

グローバルバージョンの設定
`rbenv global 2.4.1`

ローカルバージョンの設定
`rbenv local 2.4.1`


### Ruby

保存したrbファイルを実行する
ruby hogehoge.rb

画面にデバッグ情報表示したい
`<%= @report.inspect %>`

カウントがゼロではないかどうか
`@report.count.zero?`

### Dockerコマンド
Dockerにログインしないで自分のローカルから更新したい時とか
`web`は適宜環境に合わせて変更する
（docker-compose.ymlのservicesの記載配下を参考にする）

bundle install
`docker-compose run web bundle install`

### brew関連

mov→gif変換
参考：
https://qiita.com/ntkgcj/items/6ac08a007f24a2de0b36

`ffmpeg -i 圧縮したい動画.mov -vf scale=1200:-1 -r 10 圧縮された動画.gif`

### コマンド
ポートを調べる
`lsof -i:3000`

### ショートカット
Macのバックスラッシュ（\）の入力は option + ¥
【Vue.js】オブジェクトのリストをコンポーネントで表示するときのベストプラクティス


# こんなデータを表示したい
以下のリスト一つ一つをvueコンポーネントとして表示

```javascript
list: [
  {
    id: 1,
    name: "リスト1"
  },
  {
    id: 2,
    name: "リスト2"
  }
]
```

## 子コンポーネント

`props`で親コンポーネントから渡された値を画面に表示するだけのコンポーネントです。

```vuejs:ListComponent.vue
<template>
  <div>{{ target }}</div>
</template>

<script>
export default {
  props: {
    target: {
      type: Object,   // 型がObjectである
      required: true  // 必須のプロパティである
    }
  }
};
</script>
```

### ポイント
何も考えずに`props`に値を渡すと、以下のようになると思います。

```vuejs
<script>
export default {
  props: [target]
};
</script>
```
この場合、以下のようなデメリットがあります。

* 値がundefinedのときに気づきにくい
* 変数にどんな値が入るか推測しづらい



`props`には、基本的に[バリデーション](https://jp.vuejs.org/v2/guide/components-props.html)を行いましょう。

バリデーションには

* 型
* 必須かどうか
* デフォルト値

などを指定することができます。
ここである程度バリデーションをかけておくことで、エラーの発生原因などを特定しやすくなります。

## 親コンポーネント

オブジェクトのリストをfor文で全て表示します。

```vuejs:Parent.vue
<template>
  <div>
    <list-component v-for="item in list" :key="item.id" :target="item" />
  </div>
</template>

<script>
export default {
  components: {
    ListComponent
  },
  data: function() {
    return {
      list: [{ id: 1, name: "リスト1" }, { id: 2, name: "リスト2" }]
    };
  }
};
</script>
```

### ポイント

1. `v-for`はコンポーネントタグの中で書ける
1. listの中身を一意に判定できる`key`を指定する
1. オブジェクトのまま子コンポーネントに渡すことができる


#### 1. v-forはコンポーネントタグの中で書ける

```vuejs
<template>
  <div>
    <div v-for="item in list"> <!-- v-forのためだけのタグで囲う必要はない -->
      <list-component :target="item" />
    </div>
  </div>
</template>
```

#### 2. listの中身を一意に判定できる`key`を指定する

`key`が未指定でもエラー出ませんが、[公式ドキュメント](https://jp.vuejs.org/v2/guide/list.html)でも推奨されています。

リストに変更があった場合

* 'key`未指定：リストが全件更新、再描画してしまう
* 'key`指定：変更があったリストの中身を検知し、それだけを更新

#### 3. オブジェクトのまま子コンポーネントに渡すことができる

オブジェクトの中身を以下のようにそれぞれ渡すことができますが、
オブジェクト内部の情報を全て使うのであれば、オブジェクトごと子コンポーネントに渡しましょう。

```vuejs
<template>
  <div>
    <list-component v-for="item in list" :key="item.id"
      :id="item.id"
      :name="item.name"
    />
  </div>
</template>
```


# あとがき

よくあるケース＆忘れそうなのでまとめておきました。
Javaテクノロジー軽くまとめ

パブリックAPIの使用やサーブレットからの書き込みなどのメソッドがありますが、ここではjspにJavaコードを埋め込むためのテクノロジーについて説明します。

タグを列挙するためのクラス。

JavaでHTMLを操作する方法はいくつかあります。

。

Javaテクノロジーは3つのグループに編成されています。

オンラインプログラミングスクールであるTechAcademyは、Javaクラスを提供しています。

Javaおよびサーブレット技術を使用してWebアプリケーションを開発する方法を学びます。

呼び出し元の詳細なリファレンスとプロデューサー向けのドキュメントについては、JavaSEのドキュメントを参照してください。

アクティブなエンジニアが各学生にパーソナルメンターとして割り当てられ、アフターケアトレーニングと1対1のメンタリングが提供されるため、学生はわずか4週間で学習できます。<a href="https://xn--tor3uh5c6zhr15dspki3m3km.com/nagoya-antique-purchase-appraisal/" >名古屋骨董売りたい鑑定</a>

タグの種類は数種類しかないため、拡張時に使用されるプロパティを追加する必要があります。

Java2Platform、EnterpriseEdition（J2EE）は、エンタープライズ情報システムに必要なテクノロジーを定義します。
Bootstrapにおけるdisplayについて

CSSのdisplayと混同しそうだったので調べてみました。

表示見出し（Display headings）と言うそうです。
見出し（Headings）との違いは、どの様な点なのでしょうか？

”従来の見出し要素は、ページコンテンツの中で最も効果的に機能するように設計されている。
見出しを目立たせる必要がある場合は、表示見出しを使ってより大きく独創的なスタイルにすることが可能。”
https://cccabinet.jpn.org/bootstrap4/content/typography

僕が現時点で理解したのは
hタグよりデフォルトで大きく表示される
と言うことです。

疑問が残るのは
hタグが効果的というのはどういう意味でなのか？
大きさ以外に違いはあるのか？
と言うところです。

また調べてわかり次第追記します。
windows10でubuntu18.04を使えるようにする

## 概要
使いかけのwindows10でubuntu18.04の環境を作ります。
Windows Subsystem for Linux(WSL)という、windows上でubuntuなどのlinuxの環境を再現できるサービスを使います。Virtual Boxで仮想マシンで動かす訳ではないので、WSL自体の起動負荷がわずかで、起動時間もとても短いです。WSL環境下では、Linuxのシェルであるbashなどでずっと作業を続けることもでき、ハイスペックなPCでコーディングなども捗ります。

## 環境
- windows10 最新版(1903, windows updateで確認)

## 初期化
使いかけのPCだったので、windows10の最新版をinstallしたのちに、初期化します。
`設定`→`更新とセキュリティ`→`回復`→`このPCを初期状態に戻す`

## WSLのインストール
大前提として、Windows側でLinux Subsystemを有効化する必要があります。
`アプリと機能`→`プログラムと機能`→`Windowsの機能の有効化または無効化`→`再起動`

### ubuntuのinstall
`microsoft Store`→`Ubuntu 18.04 LTS`

起動すると、`installing, this may take a few minutes...`と表示されるのでしばし待つ。usernameとpasswordを設定する。

## フォントの設定
Ubuntu Monoを設定する。
https://design.ubuntu.com/font/ からfontをinstallする。
中身を展開して、`UbuntuMono-R`をダブルクリックで起動する。
installを選択する。

regeditを起動して、`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont`に移動する。

文字列で以下の情報を加える。

|名前|種類|データ|
-----|-------|-----|
| 000| EG_SZ |Ubuntu Mono|

コマンドプロンプトを再起動して、`右クリック`→`プロパティ`で、フォントをUbuntu Monoに変更する。

## 背景色の設定
最新版のcolortoolをインストールする。
https://github.com/microsoft/terminal/tree/master/src/tools/ColorTool#installing

`ColorTool.exe -d campbell.ini`

-dオプションをつけることで、設定を保存することになる。
ファイル名まで指定しないと、`Could not find or load "campbell"`といったエラーが出るので注意。

今回は、こちらのテーマを使うことにしました。
`ColorTool.exe -d OneHalfDark.itermcolors`

## フォルダの色の設定
ubuntuのterminal側で実行。

```bash:
$ dircolors -p > ~/.dircolors
```

```bash:
$ vim ~/.dircolors
```

変更前

```
OTHER_WRITABLE 34;42
```

変更後

```
OTHER_WRITABLE 01;32
```

設定ファイルの変更

```bash:
$ vim ~/.bashrc
```

追加

```bash:
eval $(dircolors -b $HOME/.dircolors)
```

terminalを再起動すると変更が反映されます。

## まとめ
これで、windows上でも、linux上での開発と同様なクールな開発環境を構築することができました。あとは、自分のvimなどdotfilesの設定をgithubなどからとってきて反映すれば、出来上がりですね。

## 参考文献
[Windows Subsystem for Linuxをインストールしてみよう！](https://qiita.com/Aruneko/items/c79810b0b015bebf30bb)

[WSL その4 - BashでUbuntu Monoフォントを利用するには](https://kledgeb.blogspot.com/2016/04/wsl-4-bashubuntu-mono.html)

[ColorTool を使ってコンソールを見やすくする](https://qiita.com/yoshikingt/items/21d9e3fb8b8f22ab3476)

[WSLのWindowsのフォルダの色が見づらいのを直す](https://www.kwbtblog.com/entry/2019/04/27/023411)