[Python3] botoでS3にpublicでuploadする方法

s3.upload_file で、 ExtraArgs={‘ACL’:’public-read’}を追加する

s3 = boto3.client('s3', aws_access_key_id=accesskey, aws_secret_access_key= secretkey, region_name=region)
 
filename = "a.json"
bucket_name = "hoge"
 
s3.upload_file(filename,bucket_name,filename, ExtraArgs={'ACL':'public-read'})
print("upload {0}".format(filename))

※追加しないとaccess denyとなるので注意が必要

[音声認識] RaspberryPI 4(model B)でJuliusを動かす

音声認識をwavファイルではなく、ラズパイでやります。

### 前準備
– ラズパイ4 model B (秋葉原で電源、microSDなどセットで1万くらい)
– モニター、キーボード, マウス(メルカリでセットで3500円くらい)
– USBマイク(amazonで300円くらい)
※初期設定でwifiの設定とキーボードをJapaneseにする必要がある

$ mkdir julius
$ cd julius
$ wget https://github.com/julius-speech/julius/archive/v4.4.2.1.tar.gz
$ tar xvzf v4.4.2.1.tar.gz
$ cd julius-4.4.2.1
$ sudo apt-get install libasound2-dev libesd0-dev libsndfile1
※libsndfile1-devはRaspberryPI 4ではinstallできなかった
$ ./configure –with-mictype=alsa
$ make
$ sudo make install

$ cd ../
$ mkdir julius-kit
$ cd julius-kit
$ wget https://osdn.net/dl/julius/dictation-kit-v4.4.zip
$ unzip dictation-kit-v4.4.zip

$ sudo vim /etc/modprobe.d/alsa-base.conf

options snd slots=snd_usb_audio,snd_bcm2835
options snd_usb_audio index=0
options snd_bcm2835 index=1

$ sudo vim ~/.profile
一番最後の行に追加

export ALSADEV="plughw:0,0"

$ sudo apt-get install alsa-utils sox libsox-fmt-all
$ sudo sh -c “echo snd-pcm >> /etc/modules”

ラズパイ再起動

$ cd ~/julius/julius-kit/dicration-kit-v4.4/
$ julius -C main.jconf -C am-gmm.jconf -demo

AWSにjsonを送信したい
-> S3に保存すれば良いのかな
そこさえできれば、ほぼ基本的な挙動は完成

[ TypeScript ] 環境構築でWebsocketServer.js:10エラーになる時

### コンパイラ導入
$ node -v
v10.19.0
$ sudo npm install -g typescript
$ tsc -v
Version 4.4.3

hello.ts

const message:string = 'Hello! TypeScript!'
console.log(message);

$ tsc hello.ts
$ ls
hello.js hello.ts
$ node hello.js
Hello! TypeScript!

### npm環境
$ npm install typescript ts-loader webpack webpack-cli webpack-dev-server –save-dev

package.json

  // 省略
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development",
    "start": "webpack-dev-server --mode=development"
  },
    // 省略

webpack.config.js

const path = require('path');
module.exports = {
	entry: {
		bundle: './src/app.ts'
	},
	output: {
		path: path.join(__dirname,'dist'),
		filename: '[name].js'
	},
	resolve: {
		extensions:['.ts','.js']
	},
	devServer: {
		contentBase: path.join(__dirname,'dist')
	},
	module: {
		rules: [
			{
				test:/\.ts$/,loader:'ts-loader'
			}
		]
	}
}

$ tsc –init
-> tsconfig.json が生成される

dist, srcフォルダを作成する

src/app.ts

import {Item} from './item';
var elem = document.getElementById('output');
var aBook = new Item('はじめてのTypeScript', 2020);
aBook.say(elem);

src/item.ts

export class Item {
	constructor(private name:string, private price:number){}

	public say(elem: HTMLElement | null) : void {
		if(elem){
			elem.innerHTML = '書名:' + this.name + ' 価格: ' + this.price + '円';
		}
	}
}

dist/index.html

<body>
	<div id="output"></div>
	<script src="bundle.js"></script>
</body>
</html>

$ npm run start

> tutorial@1.0.0 start /home/vagrant/dev/typescript/tutorial
> webpack-dev-server –mode=development

[webpack-cli] /home/vagrant/dev/typescript/tutorial/node_modules/webpack-dev-server/lib/servers/WebsocketServer.js:10
static heartbeatInterval = 1000;

何でだろう? なんかエラーになるな。。

$ sudo apt-get purge nodejs

▼この記事を参考に最新版を入れる
https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-20-04-ja

$ cd ~
$ curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
$ sudo bash nodesource_setup.sh
$ sudo apt install nodejs
$ node -v
v14.17.6
$ npm run start

http://192.168.34.10:8000/

nodeがv10だとwebpack-dev-serverでエラーになるみたい 
https://github.com/VickScarlet/lifeRestart/issues/176
v14にupgradeするとエラー解消
マジかよ~~~~ もうやだー

[JavaScript] Classの追加(add)を操作する

タブメニューで、URLのパスに応じてメニューのis-activeをつけたい時
L ulのli要素にclassで”is-active”をつけたい
html

<div class="tabs">
      	<ul id="mylist">
      		<li><a href="/btc">BTC</a></li>
      		<li><a href="/eth">ETH</a></li>
      		<li><a href="/xrp">EXP</a></li>
      		<li><a href="/xlm">XLM</a></li>
      		<li><a href="/mona">MONA</a></li>
      	</ul>
      </div>

javascript側
L location.pathnameでURLを取得する
  L querySelectorAllでli要素を全て取得する
  L classList.addでclassを付与する

const pathname = location.pathname;
  	var i;
  	switch(pathname){
  		case '/btc':
  			i = 0;break;
  		case '/eth':
  			i = 1;break;
  		case '/xrp':
  			i = 2;break;
  		case '/xlm':
  			i = 3;break;
  		case '/mona':
  			i = 4;break;
  	}
  	var cols = document.querySelectorAll('#mylist li');
  	cols[i].classList.add('is-active');

OK
やりたいことの7割くらいまでは出来た

[Go] HandleFuncのhandlerをswitchでまとめて実装する

ルーティングによって処理を変えたいが、handlerの中身はほとんど一緒なため、handlerの中でswitch文を使って切り分ける
L html.EscapeString(r.URL.Path) でパスの値を取得できる

func apiHandler(w http.ResponseWriter, r *http.Request){

	var code string // 変数として宣言
	switch html.EscapeString(r.URL.Path) {
	case "/btc":
		code = "BTC_JPY" // ビットコイン
	case "/eth":
		code = "ETH_JPY" // イーサリアム
	case "/xrp":
		code = "XRP_JPY" // リップル
	case "/xlm":
		code = "XML_JPY" // ステラルーメン
	case "/mona":
		code = "MONA_JPY" // モナコイン
	default:
		code = "BTC_JPY"
	}

	uri := "https://api.bitflyer.com/v1/getticker?product_code=" + code
	req, _ := http.NewRequest("GET", uri, nil)

	// 省略
}


func main() {
	http.HandleFunc("/btc", apiHandler)
	http.HandleFunc("/eth", apiHandler)
	http.HandleFunc("/xrp", apiHandler)
	http.HandleFunc("/xlm", apiHandler)
	http.HandleFunc("/mona", apiHandler)
	log.Fatal(http.ListenAndServe(":8080",nil))
}

code := “BTC_JPY” とすると定数になるので、 var code string と変数として宣言する必要がある
なるほど、後はテンプレート側の処理

bulma cssとtypescriptを使いたい

[Go] CoinMarketCapのAPIを操作しよう

CoinMarketCapとは?
-> 急速に成長している仮想通貨スペースにおける世界で最も参照されている価格追跡ウェブサイトです。

まずDeveloper向けのアカウントを作成し、管理画面でAPI_KEYをコピーして、Developer向けページのIntroductionを一通り目を通します。
https://pro.coinmarketcap.com/account
https://coinmarketcap.com/api/documentation/v1/#section/Introduction

$ curl -H “X-CMC_PRO_API_KEY: ${API_KEY}” -H “Accept: application/json” -d “start=1&limit=5000&convert=USD” -G https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest

おおおおおおおおおおお、なんかすげえ

go

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
)

func main(){
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest", nil)
	if err != nil {
		log.Print(err)
		os.Exit(1)
	}

	q := url.Values{}
	q.Add("start", "1")
	q.Add("limit", "5000")
	q.Add("convert", "USD")

	req.Header.Set("Accepts", "application/json")
	req.Header.Add("X-CMC_PRO_API_KEY", "${API KEY}")
	req.URL.RawQuery = q.Encode()

	resp, err := client.Do(req);
	if err != nil {
		fmt.Println("Error!")
		os.Exit(1)
	}
	fmt.Println(resp.Status)
	respBody, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(respBody));
}

取得する量が多すぎるな
1回のリクエストで25credit使うとなると、1日12回程度しかrequestできんな。流石にこれだと使い物にならんが、イメージは出来た。

[Go] Jsonで出力する

import (
	"encoding/json"
	"log"
	"net/http"
	"time"
)

func apiClockHandler(w http.ResponseWriter, r *http.Request){
	type ResponseBody struct {
		Time time.Time `json:"time"`
	}
	rb := &ResponseBody {
		Time: time.Now(),
	}

	w.Header().Set("Content-type", "application/json")

	if err := json.NewEncoder(w).Encode(rb); err != nil {
		log.Fatal(err)
	}
}

func main(){
	http.HandleFunc("/api/clock", apiClockHandler)
	log.Fatal(http.ListenAndServe(":8080",nil))
}

http://192.168.34.10:8080/api/clock

OK, ある程度のところまで来た

[Go] Bitflyerで取得した値をHTMLで表示する

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"html/template"
	"log"
	"fmt"
)

func bitflyerHandler(w http.ResponseWriter, r *http.Request){

	uri := "https://api.bitflyer.com/v1/getticker"
	req, _ := http.NewRequest("GET", uri, nil)

	client := new(http.Client)
	resp, _ := client.Do(req)
	defer resp.Body.Close()

	byteArray, _ := ioutil.ReadAll(resp.Body)

	var ticker Ticker
	json.Unmarshal([]byte(byteArray),&ticker)


	t := template.Must(template.ParseFiles("/home/vagrant/go/src/github.com/me/sample/src/bitflyer.html.tpl"))
	if err := t.ExecuteTemplate(w, "bitflyer.html.tpl", fmt.Sprintf("%.0f\n", ticker.Ltp)); err != nil {
		log.Fatal(err)
	}
}


func main() {
	// fmt.Printf("%.0f\n",ticker.Ltp)

	http.HandleFunc("/bitflyer/", bitflyerHandler)
	log.Fatal(http.ListenAndServe(":8080",nil))
}


type Ticker struct {
	Code string `json:"product_code"`
	Ltp float64 `json:"ltp"`
}

bitflyer.html.tpl

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
	{{ . }} 
</body>
</html>

なるほど、これをcoin marketでやるか

[Go] サーバーを起動してHTMLファイルを表示

import (
	"log"
	"net/http"
)

func main(){
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("/home/vagrant/go/src/github.com/me/sample/src"))))
	log.Fatal(http.ListenAndServe(":8080",nil))
}

L /home/vagrant/go/src/github.com/me/sample/src にhtmlファイルを配置する

index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
	Hello world
</body>
</html>

$ go run server.go

ほう、Echo使わなくても表示できるやん
これを動的に表示したい

### 動的に表示

import (
	"fmt"
	"log"
	"net/http"
	"time"
)

func clockHandler(w http.ResponseWriter, r *http.Request){
	fmt.Fprintf(w, `
		<!DOCTYPE html>
        <html>
        <body>
            It's %d o'clock now.
        </body>
        </html>
		`, time.Now().Hour())
}

func main(){
	http.HandleFunc("/clock/", clockHandler)
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("/home/vagrant/go/src/github.com/me/sample/src"))))
	log.Fatal(http.ListenAndServe(":8080",nil))
}

Printfで渡してるだけやな

### データの渡し方

func clockHandler(w http.ResponseWriter, r *http.Request){
	t := template.Must(template.ParseFiles("/home/vagrant/go/src/github.com/me/sample/src/clock.html.tpl"))

	if err := t.ExecuteTemplate(w, "clock.html.tpl", time.Now()); err != nil {
		log.Fatal(err)
	}
}

func main(){
	http.HandleFunc("/clock/", clockHandler)
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("/home/vagrant/go/src/github.com/me/sample/src"))))
	log.Fatal(http.ListenAndServe(":8080",nil))
}

echoでのtemplateと書き方はそんなに変わらんな

[Go] BitflyerのAPIを取得したい

### Bitflyerからの取得

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	uri := "https://api.bitflyer.com/v1/gethealth"
	req, _ := http.NewRequest("GET", uri, nil)

	client := new(http.Client)
	resp, _ := client.Do(req)
	defer resp.Body.Close()

	byteArray, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(byteArray))
}

$ go run gethealth.go
{“status”:”NORMAL”}

### Jsonの扱い
GoでJsonの受け取り方
1. 構造体を定義

type User struct {
	Name string `json:"name"`
	Age int `json:"age"`
	Job string `json:"job"`
}
func main() {
	userStr :=
	 `{
	    "name": "tokumaru",
	    "age": 20,
	    "job": "student"
	  }`

	var user User
	json.Unmarshal([]byte(userStr),&user)

	fmt.Println(user.Name)
}

// 構造体を定義
type User struct {
	Name string `json:"name"`
	Age int `json:"age"`
	Job string `json:"job"`
}

$ go run test.go
tokumaru

↓上記をつなげる
### Bitcoinの価格を取得
bitcoinは小数点なので、float64で定義する。
表示する際は、fmt.Printf(“%.0f\n”,ticker.Ltp)として、小数点以下を切り捨てる

package main

import (
	"fmt"
	"encoding/json"
	"io/ioutil"
	"net/http"
)

func main() {
	uri := "https://api.bitflyer.com/v1/getticker"
	req, _ := http.NewRequest("GET", uri, nil)

	client := new(http.Client)
	resp, _ := client.Do(req)
	defer resp.Body.Close()

	byteArray, _ := ioutil.ReadAll(resp.Body)

	var ticker Ticker
	json.Unmarshal([]byte(byteArray),&ticker)

	fmt.Printf("%.0f\n",ticker.Ltp)
}

// 構造体を定義
type Ticker struct {
	Code string `json:"product_code"`
	Ltp float64 `json:"ltp"`
}

$ go run test.go
5014562

これをHTMLで表示させたい