VSCode on WSL
就活も何とか終えられたのでPythonとディープラーニングを本格的に勉強しようと思って環境構築を行った。
画像認識のアプリは作ったけど結局上っ面をなぞっただけだし。
VSCode使いたかったけどコマンドプロンプトを使うのも嫌だったのでLinux版のVSCodeをWSLに入れてX Windowで表示することにした。
本当はWindows上のVSCodeからWSLのPythonが使えればよかったのだけど今は無理みたいだし。
qiita.com
補完とかの機能をフルに使いたかったのでWSLで全部行うようにした。
ほぼこのブログ通りに行った。
自分の場合はUbuntu16.04.4だったので
$ curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg $ sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg $ sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
こんな感じでリポジトリを追加して
$ sudo apt-get update $ sudo apt-get install code
でインストール。
そして記事の通りに依存関係を手動で解決
$ sudo apt install -y libxss1 libgtk2.0-0 libasound2
これで使えるようになるかと思いきやコマンドを実行しても何も表示されない。 オプションを付けることでエラーの詳細が見れるがエラーが起きた所のコードが表示されるだけで要領を得ない。
$ code --verbose Assertion 'pthread_mutex_unlock(&m->mutex) == 0' failed at pulsecore/mutex-posix.c:108, function pa_mutex_unlock(). Aborting.
ググってたらさらに依存ライブラリを入れれば良いかもとのこと。
github.com
というわけでインストール
$ sudo apt purge libpulse0
これで起動成功。
これの前にdbusをスタートさせたりしたけど多分これが原因な気がする。
とりあえずこんな感じ。
自分の環境だとdpiを110くらいにするといい感じに表示された。
遅延とかは心配だったけど思ったより気にならないので満足。
これからPythonを頑張る。
2018/06/26 追記
5回に1回くらい起動に失敗するのでとりあえず封印
アップデートで治るの待つか
Androidアプリのアイコンが変
先日、スマートフォンを新しいものに買い替えた。
SonyのXperia XZ1でOSはAndroid 8.0。
ずっとAQUOS系を使ってたのでなかなか新鮮。
というわけで自分の作ったアプリをインストールしてみたのだがアイコンが変。
どうもデフォルトのアイコンが使われているっぽい。
これはAndroid7.1から追加された機能でRound Icon、つまり丸形アイコンが定義できるようになったことが原因らしい。
要するにround iconを設定してなかったことが原因らしい。
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
こんな感じでandroid:roundIconを設定してはいたが画像ファイルの方をデフォルトから弄ってなかったのが原因っぽい。
ちゃんとこれ用にアイコンを作ろうかと思ったけどAndroid8.0からはAdaptive Iconになっているらしく面倒なのでとりあえず今までのアイコンを使いまわすことにした。
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher" android:supportsRtl="true" android:theme="@style/AppTheme">
行儀はよくないけどとりあえずこれで解決。
round_icon使う場面でも元のアイコンを使うようにしてるだけだから解決と言えるかは微妙だけど。
NFC機能がないと動かないアプリだったからエミュレータで動かしていなかったけど、ランチャーアイコンで違いがあるのは盲点だった。
MySQLの死と監視スクリプト
MySQLサーバーがいつの間にか落ちてた.理由はわからん.
というわけでWEBアプリとスマホアプリ用APIを動かしているサーバーのMySQLが落ちていた.
アプリ使ってくれている人からの問い合わせで気づいた.
最近忙しくて放置気味だったから全く気付かなかった.
ありがたいとともに申し訳ない.
ログ見てもそれらしい記述がなくて原因は不明なので,落ちたときにすぐ気づける体制を整えることにした.
本当は原因突き止めるべきなんだろうけど.
以下のスクリプトをcronで定期実行することによって今後MySQLが落ちたときはメールで通知が行くようにした.
# coding: utf-8 import MySQLdb import os import traceback #MySQL起動確認 try : connection = MySQLdb.connect(db='DB_NAME',user='USER',charset='utf8mb4') except : message = traceback.format_exc() f = open("error.mail","w") f.write("MySQLサーバーに接続できません\nTraceback:\n "+message) f.close() os.system('cat error.mail | mail -s "サーバーエラー" -r rabbit@vayacico.com ????????????@softbank.ne.jp') os._exit(0)
MySQLに接続して例外吐いたらメールを送るシンプルなスクリプト.
本当はGmailに通知したかったけど迷惑メールチェックで弾かれるのか届かないので迷惑メールチェック弱そうなソフトバンクで受け取ることにした.
今後はAPI叩いて正当性確認する処理も追加したい.
Androidアプリ内のSQLiteデータベースファイルをパソコンに持ってくる
毎回引っかかてる気がしたのでいい加減覚えるためにメモ
ググってよく見つかる方法だとなぜかうまくいかないし
環境に依存してそうなので以下に環境を載せておく
- 502sh(Android5.1.1)
- Windows10
以下がpullするまでのコマンド
C:\Users\vayacico>adb shell shell@SG502SH:/ $ run-as com.vayacico.suicakeeper2 shell@SG502SH:/data/data/com.vayacico.suicakeeper2 $ chmod 777 databases/dbname.db shell@SG502SH:/data/data/com.vayacico.suicakeeper2 $ exit shell@SG502SH:/ $ cp /data/data/com.vayacico.suicakeeper/databases/user.db /sdcard/ shell@SG502SH:/ $ exit C:\Users\vayacico>adb pull /sdcard/user.db /sdcard/user.db: 1 file pulled. 1.8 MB/s (28672 bytes in 0.015s) C:\Users\vayacico>
ググって見つかる多くの方法だとrun-as内で直接SD直下にコピーできてるっぽいんだけど自分の環境でやるとPermission deniedされる.
というわけで脳死でchmod 777して通常ユーザーから見れるようにしてからコピーした.
バージョン間の問題かな?
Androidで位置情報の取得
アプリに位置情報を利用した機能を実装しようと思い、Androidでの現在位置の取得について調べた.
ブログやら記事やら見てもどれが最新なのかいまいちわからなかったので今回は公式のトレーニングに従って実装してみた.
この方法はGoogle Play Servicesを利用した方法でサービスが保持している直近の位置情報を取得することができる.
保持している情報というわけで過去の情報となるわけだがほとんどの場合で現在地と一致するらしい.
準備
Google Play Servicesを利用するとのことなのでGoogle Play Servicesのコンポーネントをプロジェクトに導入する必要がある.
Set Up Google Play Services | Google APIs for Android | Google Developers
導入の方法に関してはここを参考にした.
Google Play Servicesで1つのライブラリになっているのかと思いきやサービスごとに分かれているらしい.
今回は位置情報サービスにアクセスするのでそれっぽいGoogle Location and Activity Recognitionを選んで導入.
appの方のbuild.gradleのdependenciesに以下を追記.
バージョンに関しては上記のサイトのリストが最新バージョンになっている(らしい)のでこれをコピペした.
implementation 'com.google.android.gms:play-services-location:11.8.0'
追記後にsyncを行うことでGoogle Location and Activity Recognitionのモジュールが導入される.
権限
位置情報にアクセスするためには権限が居るのでAndroidManifest.xmlにその旨を記述する.
権限には以下の2種類がある.
ここで選択した精度がAPIによって返される位置情報の精度を決定する…らしいのだが高精度の位置情報を取得しようとしてACCESS_FINE_LOCATIONだけを書いて実行したらいくら待ってもコールバックが呼ばれない事態に陥った.
試しにACCESS_COARSE_LOCATIONとACCESS_FINE_LOCATIONを併記したら高精度で位置情報を取得できたので併記する必要があるらしい.
というわけで高精度で位置情報を取得する場合は以下のようになった.
市町村レベルでよければACCESS_FINE_LOCATIONの方を消せばよい.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
実装
まずはこれで初期化を行う.
FusedLocationProviderClient mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
そして位置情報の取得を行う.
結果はコールバックで帰ってくるので登録を行う.
mFusedLocationProviderClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() { @Override public void onSuccess(Location location) { if(location==null){ Log.d("Result","location is null"); }else{ Log.d("Result","("+location.getLongitude()+","+location.getLatitude()+")"); } } });
この例では緯度と経度をログに出力している.
また,環境によってはnullが帰ってくることもあるらしいのでチェックを行う.
ここまでのコードで位置情報の取得はできるのだがパーミッションのチェックを行わないとAndroid Studioから怒られるので(ビルドもできない?)getLastLocation()を呼ぶ前に以下のようなコードを挿入する必要がある.
if(ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){ return; }
これで位置情報を取得できる.
以下が実装した例.
github.com
Last Locationということもあり待ち時間なく取得できる.
位置情報の取得というと時間がかかるイメージがあったけどこれなら使いやすいかも.
追記
自分の持ってる端末のバージョンがAndroid5.1だから問題なかったけどパーミッションまわりで許可を求めるダイアログが必要らしい.
シンボリックリンクを利用してOnedriveを利用
自分の所属している大学院にもやっとOffice365が導入されて便利に使わせてもらっているのだが不満がひとつだけある.
そう、Onedriveのディレクトリ名に大学名が入ることである.
別に大学名がダサいのが嫌というわけでもなく(ダサいとは思っているが)ディレクトリ名に日本語とスペースが入ると困るという実利的な問題である.
ファイルを置いておく分には問題ないのだがソースコードを置こうとするとちょっとだけ問題がでてきた.
各種ツールがうまく動かないのである.
たとえばAndroid Studioだとこんな感じに怒られる.
Your project path contains non-ASCII characters. This will most likely cause the build to fail on Windows. Please move your project to a different directory.
そもそもスペース含むパスは色々と不便だ.
素直にローカル保存にしておけばいいのだがノーパソしか持っていない自分としてはクラウドに預けてないと不安である.
ディレクトリ名を変更する方法を調べてみてもOffice365の管理者に頼む以外の方法が見つからなかったので実体はPC内の行儀の良い場所においてシンボリックリンクをOneDrive内に作成することにした.
というわけで以下のコマンドでシンボリックリンク作成した.
C:\Users\vayacico>mklink /D "C:\Users\vayacico\OneDrive - 埼玉大学\private\project" "C:\Users\vayacico\Documents\project" C:\Users\vayacico\OneDrive - 埼玉大学\private\project <<===>> C:\Users\vayacico\Documents\project のシンボリック リンクが作成され ました
\Dオプションでディレクトリのシンボリックリンクを作るということになるらしい
シンボリックリンクでちゃんと中身をアップロードしてくれるか不安だったがブラウザから確認したところ実体もちゃんとアップされていたのでこれで問題ないらしい.
ひとまずこれでノーパソに何かがあっても致命傷を負わない環境ができた.
ノーパソに何かがあった時点で何もできなくなる環境は変わらないが.
Webアプリが動いてるサーバーへwordpressの導入
さくらのVPSを借りてWebアプリやスマホアプリのためのAPIを動かしているがトップページには申し分程度のHTMLファイルしか置いてなかったのでwordpressを利用してリッチにしてみた.
別に向こうでブログ書く気はないけど.
今回私が求めた条件は以下の通り.
この条件を満たすためにルートディレクトリのサブディレクトリにwordpressを展開してApacheのmod_rewriteモジュールでURLを書き換えることにした.
まずは通常通りwordpressのインストールする.
インストールといってもファイルを持ってきて置くだけらしい.
どの段階までをインストールというのにかに依るけど.
$ wget https://ja.wordpress.org/wordpress-4.8.2-ja.zip
$ unzip wordpress-4.8.2-ja.zip
$ sudo cp -r wordpress /var/www/html/
続いてデータベースの作成.
MySQLは既に導入済みだったのでユーザーとデータベースを作るだけ.
mysql> CREATE USER user IDENTIFIED BY 'password'; mysql> CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; mysql> GRANT ALL ON user.* to wordpress_user;
とりあえずこれで/wordpress/以下で動かせるようになる.
自分は先にWordPressの初期設定をやってしまったので後でひと手間かかった.
先にmod_rewriteの設定をやった方が楽だったのかもしれないかも.
アクセスするとこんな感じの設定画面になるのであとは従っていけば完了する.
ファイルに書き込めないだの言われたのでEmacsから手動で作成した.
あとは従ってやればOKだった.
続いてmod_rewriteの設定を行う.
前にも散々弄った形跡があるので(なにをしたかったのかは忘れた)これだけで動くのかわからないが自分は以下の設定でいい感じに動いてくれた.
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^/api/(.*)$ /api/$1 [L] RewriteRule ^/twitgallery/(.*)$ /twitgallery/$1 [L] RewriteRule ^/(.*)$ /wordpress/$1 [L] </IfModule>
/api/以下でスマホアプリ用のAPIが動いてるので,要求URIが/api/~だったら/api/~に書き換えて(書き換えてないけど)判定を終了する.
同じように/twitgallery/以下でもWebアプリが走っているのでこれも書き換えて(書き換えてないけど)判定を終了.
そして最後のルールで/~を全て/wordpress/~に書き換える.
こうすることでAPIやWebアプリだった場合以外を全部WordPressに飛ばすことができた.
これで終わり…だと思っていたのだがアクセスしてみるとCSSが効いてないデザインが崩れた見た目になる,
どうやらWordPress内でURI情報を保持して使っているらしい.
デベロッパーコンソールで見てみるとどうもドメインも含む完全なURLでCSSやJSにアクセスしてるっぽかった.
設定画面から書き換えできるらしいので一度mod_rewriteの設定を元に戻し管理画面に入る.
[設定]->[一般]にそれっぽい設定があったので書き換える.
変更を保存するとその場で切り替わるらしく404になるが設定は正常に完了している.
そしてmod_rewriteの設定をもう一度変えることで全部まるっと思った通りに動いた.
内容はまだ全く作っていないがとりあえずこれで完了.
思いの外簡単であった.
セキュリティがなんとなく怖くもあるが.
ログインページをローカルアクセスオンリーにしてsshポートフォワーディングからのみアクセスできるようにしたかったけど上手くいかない.
なんで相対パスで偏移してくれないのか….
ここら辺はまた今度やろう.