動かざることバグの如し

近づきたいよ 君の理想に

Python3で一時ファイルを作成する

tempfile.NamedTemporaryFileを使う

>>> import tempfile
>>> f = tempfile.NamedTemporaryFile(mode='w+')
>>> f.name
'/var/folders/6z/xq_8ddx97hq9hzlgwzjjdjbw0000gn/T/tmpncbwgf4y'
>>> f.write('こんにちは')
5
>>> f.seek(0)
0
>>> f.read()
'こんにちは'

一時ファイルの削除

>>> import os
>>> os.remove(f.name)
>>> os.path.exists(f.name)
False

withを使ってブロック形式で書けば自動で一時ファイルが削除される

>>> with tempfile.NamedTemporaryFile(mode='w+') as f:
...     print(f.name)
...     f.write('こんにちは')
...     f.seek(0)
...     print(f.read())
... 
/var/folders/6z/xq_8ddx97hq9hzlgwzjjdjbw0000gn/T/tmp2sxgdmb_
5
0
こんにちは

>>> import os
>>> os.path.exists(f.name)
False
  • f.seek(0)しないとf.read()ができない
  • tempfile.TemporaryFileでも一応出来たが絶対パスが取れない(f.nameがない)のでやめた
  • デフォルトのmodeがバイナリ形式なので注意(mode='w+'を指定する

UbuntuにOpen JTalkをインストールして日本語音声合成を試す

環境

  • Ubuntu 16.04
  • Open JTalk 1.07

Open JTalkとは無料の音声合成ソフトである。テキスト読み上げソフトともいうが。以下のサイトで試すことができる。

http://open-jtalk.sp.nitech.ac.jp/open-jtalk.sp.nitech.ac.jp

インストール

パッケージがあるのでそのままインストール

apt install open-jtalk open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001

確認

# open_jtalk -h
The Japanese TTS System "Open JTalk"
Version 1.07 (http://open-jtalk.sourceforge.net/)
Copyright (C) 2008-2013 Nagoya Institute of Technology
All rights reserved.

The HMM-Based Speech Synthesis Engine "hts_engine API"
Version 1.08 (http://hts-engine.sourceforge.net/)
Copyright (C) 2001-2013 Nagoya Institute of Technology
              2001-2008 Tokyo Institute of Technology
All rights reserved.

Yet Another Part-of-Speech and Morphological Analyzer "Mecab"
Version 0.994 (http://mecab.sourceforge.net/)
Copyright (C) 2001-2008 Taku Kudo
              2004-2008 Nippon Telegraph and Telephone Corporation
All rights reserved.

NAIST Japanese Dictionary
Version 0.6.1-20090630 (http://naist-jdic.sourceforge.jp/)
Copyright (C) 2009 Nara Institute of Science and Technology
All rights reserved.

open_jtalk - The Japanese TTS system "Open JTalk"

  usage:
       open_jtalk [ options ] [ infile ] 
  options:                                                                   [  def][ min-- max]
    -x  dir        : dictionary directory                                    [  N/A]
    -m  htsvoice   : HTS voice files                                         [  N/A]
    -ow s          : filename of output wav audio (generated speech)         [  N/A]
    -ot s          : filename of output trace information                    [  N/A]
    -s  i          : sampling frequency                                      [ auto][   1--    ]
    -p  i          : frame period (point)                                    [ auto][   1--    ]
    -a  f          : all-pass constant                                       [ auto][ 0.0-- 1.0]
    -b  f          : postfiltering coefficient                               [  0.0][ 0.0-- 1.0]
    -r  f          : speech speed rate                                       [  1.0][ 0.0--    ]
    -fm f          : additional half-tone                                    [  0.0][    --    ]
    -u  f          : voiced/unvoiced threshold                               [  0.5][ 0.0-- 1.0]
    -jm f          : weight of GV for spectrum                               [  1.0][ 0.0--    ]
    -jf f          : weight of GV for log F0                                 [  1.0][ 0.0--    ]
    -z  i          : audio buffer size (if i==0, turn off)                   [    0][   0--    ]
  infile:
    text file                                                                [stdin]

このままでもできるが、デフォルトの音声モデルがちょっとアレなので有名なMMDAgentから出ているmeiモデルをダウンロードする。これも無料

ダウンロード & 解凍

wget http://sourceforge.net/projects/mmdagent/files/MMDAgent_Example/MMDAgent_Example-1.7/MMDAgent_Example-1.7.zip
unzip MMDAgent_Example-1.7.zip

でコピー

cp -r MMDAgent_Example-1.7/Voice/mei/ /usr/share/hts-voice/

実行

echo 'こんにちは' | open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic -m /usr/share/hts-voice/mei/mei_normal.htsvoice -r 1.0 -ow test.wav

参考リンク

Raspberry Piをしゃべらせてコドモ達を起こせ | 柄スタイル

Pythonで文字列からMD5ハッシュを生成する

環境

やり方

import hashlibする必要がある

>>> import hashlib
>>> hashlib.md5(b'hello').hexdigest()
'5d41402abc4b2a76b9719d911017c592'

md5()はバイト列を引数として受けるので、渡す際は文字列の前にbをつけなければならない。

つけないと

>>> hashlib.md5('hello').hexdigest()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Unicode-objects must be encoded before hashing

となる

変数を渡す際も同じく

>>> hashlib.md5(message.encode('utf-8')).hexdigest()
'5d41402abc4b2a76b9719d911017c592'

とやって上げる必要がある。このへんはPython3で文字列を処理する際の心掛け - Qiitaあたりが詳しい

iPhone版のEdgeのUserAgentがキモい件

iOS版のEdgeがリリースされた
iOS版のEdgeがリリースされた

一瞬、は?ってなるがtypoではない。MSがiPhone版のEdgeアプリを公開した。

www.appbank.net

海外ではすでに出てたっぽいけど日本でのリリースが今日解禁されたってわけ。ココからダウンロードできる。

気になるUserAgent

Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_1 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0 EdgiOS/41.10.1.0 Mobile/15C153 Safari/604.4.7

>EdgiOS< ってなんだよ(

ちなAndroid

Mozilla/5.0 (Linux; Android 7.0; SC-02H Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36 EdgA/41.0.0.1656

> EdgA <

Edge + Androidってことか。。。

Google Compute Engine APIを叩いてインスタンス一覧をRubyで取得

やりたいこと

Google Compute Engine APIを使ってインスタンス一覧をRubyで取得したい

おおまかな手順は以下

認証に必要なJSONを取得

まずは認証に必要な権限を得るべく設定して、JSONをダウンロードする

  • GCPのターミナル画面を開く
  • 左メニューより「IAMと管理」をクリック
  • さらに左メニューより「サービス アカウント」をクリック
  • 上の「サービス アカウントの作成」で作成
    • サービス アカウント名 は任意
    • 役割を「Compute」から選択
    • 「新しい秘密鍵の提供」にチェック 形式はJSONでおk

するとサービス アカウント一覧に追加されるので右の「︙」メニューより「キーの作成」でJSONをダウンロードする

これは大切に持っておく

Rubyで叩く

流石に生で叩くのはキツいのでGoogle公式のgoogle/google-api-ruby-clientライブラリを使う。

Gemfileを用意して以下を追加

gem 'google-api-client'

以下をindex.rbとかで作る gce-api.json はさっきダウンロードしたJSONファイルと対応しておく

require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'google/apis/compute_v1'

scope = ['https://www.googleapis.com/auth/compute.readonly']
client = Google::Apis::ComputeV1::ComputeService.new
client.authorization = Google::Auth::ServiceAccountCredentials.make_creds(
  json_key_io: File.open('gce-api.json'),
  scope: scope
)
ips = []
result = client.list_instances('YOUR_PROJECT_NAME', 'asia-east1-b')
result.items.each do |item|
 p item
end

list_instancesの第一引数にはプロジェクト名、第二引数にはリージョン(複数指定不可)が必要

マジでやってる人が少なすぎてつらみだった

ちなみにitem.statusで起動中かどうか、 item.network_interfaces[0].access_configs[0].nat_ipグローバルIPを取得できる