FUMINORI.WORK

Webアプリ開発・スマホアプリ開発・UIデザイン・マーケティング

AndroidとiOSのダウンロード数(ユニット数)取得を自動化する

2018.03時点での方法

  • iOS -> iTunesConnectAnalyticsを使う
  • Android → gsutilを使う

github.com

iOSのダウンロード数を取得する方法として Reporter を使うことが推奨されているようだけど、 試してみたらTimeZoneが変更できないようなので3rdPartyのiTunesConnectAnalyticsを利用することにした。 Androidのダウンロード数は直接APIにリクエストをおくるのではなく、gsutilを使ってGoogleCloudStrage上に保存されたCSVをダウンロードする。 gsutilからダウンロードしてきたcsvファイルはutf-16エンコードされているので注意。

Laravel 5.4 + jwt-auth 1.0 でFirebase のprivatekeyを使ってjwt認証をする

AndroidアプリとAPIを作っていて、Firebaseのカスタム認証を使おうとしています。 APIはLaravel5.4で実装しているけど、FirebaseのAdrminSDKはPHPに対応していないので独自実装が必要です。 Firebaseカスタムトークン認証をするためには、Firebaseから秘密鍵をダウンロードして、サーバに登録します。 今回、サーバに秘密鍵を登録するところで躓いたので、そのときの知見をメモしておきます。

※まだfirebase認証をAndroid側で実装していないので、カスタムトークン認証が正常に動作することは確認できておりません。

開発環境としては、ubuntu 16.04、php 7.1、MySQL5.7 フレームワークはLaravel 5.4 JWT認証ライブラリとして、jwt-auth 1.0を使います。 WebサーバはLaravelの開発サーバを用いています。

まずは、Firebaseから公開鍵(json)をダウンロードします。 jsonの中のprivate_keyが秘密鍵になっているので、コピーします。 秘密鍵を作成します。

$ touch private-key.pem

作成した鍵をvimで開いて、改行コードを改行に変換します。

:%s/\\n/\r/g

秘密鍵のパーミションを600にします。

$ chmod 600 private-key.pem

秘密鍵から公開鍵を作成します。

$ openssl rsa -pubout < private-key.pem > public-key.pem

以上で鍵ファイルの準備は完了です。

今回、公開鍵と秘密鍵はlaravelのアプリケーションルート配下に置きました。

次にconfig/jwt.phpを編集します。

return [
...
'keys' => [
...
    //'public' => env('JWT_PUBLIC_KEY'),
    'public' => "file://".base_path("public-key"),

    //'private' => env('JWT_PRIVATE_KEY'),
    'private' => "file://".base_path("private-key.pem"),
...
],
...
//'algo' => env('JWT_ALGO', 'HS256'),
'algo' => env('JWT_ALGO', 'RS256'),
...
];

以上で、秘密鍵を使ってjwtトークンが生成されます。

JWTAuthクラスでトークンを生成するときにclaimsが設定可能なようです。

例えば認証のハンドラを用意して、認証が成功した時にuidをclaimsに含めたい場合は以下のような実装になります。

$claims = ['uid' => $user->uid];
return $token = JWTAuth::claims($claims)->fromUser($user);

MySQL5.7のONLY_FULL_GROUP_BYをOFFせずに重複レコードを除外する方法

目的:

ONLY_FULL_GROUP_BYをOFFにせずに、重複レコードを除外してレコードを取得する。

一行まとめ:

group byしないcolumnをselectに含めるには、MAX()もしくはMIN()を使う。

MySQLのバージョンを5.6から5.7に変更して、既存のソースをテストしていたら、 ONLY_FULL_GROUP_BYがONになっていることが原因のエラーが発生。

同様の問題について、ぐぐったら結構ヒットしたんだけど、my.cnfでONLY_FULL_GROUP_BYをOFFにすればOK的なこと書いてあるのがほとんど。

今後のことも考えて、ONLY_FULL_GROUP_BYをOFFにせずに、既存コードと同様に動くようにソースコードを修正してみます。

例として、以下のようなテーブルを考えます。

テーブル名 hoge
id : int primary autoincrement
name : varchar(255) 

MySQL5.7において以下のようなクエリーを発行すると、

SELECT id FROM hoge GROUP BY name;

こんなエラーが返って来ます。

SELECT list is not in GROUP BY clause and contains nonaggregated column 'hoge.id' which is not functionally dependent on columns in GROUP BY clause;

で、こちらが修正後のクエリー

SELECT (MAX(id)) AS `id` FROM hoge GROUP BY name;

ここでポイントはMAX(id)。

ONLY_FULL_GROUP_BYがONになっていると、 MySQLはGroupByしていないカラム(今回はID)をSelectするときに、 どのIDを取得したらよいかMySQLがわからないためエラーとなっています(たぶん)。

重複時にどの値を使うかをMySQLに伝えてあげればいいので、状況に応じて、MAX()やMIN()を使い分ければ良いと思います。

あとはこれをサブクエリに使うなり、PHPの配列に入れてWhere INするなりすれば既存のコードを置き換えられます。

お疲れ様でした。

Intellij IdeaでCakePHP3のUnitTestを行う。

普段使っているIntellij IdeaでもCake3のUnitテストできないものかと調べたら、 設定がいろいろと大変そうだなーと一旦断念。

改めてググったら、StackOverflowでよさ気な回答を発見。

stackoverflow.com

試したら無事にUnitテストができたのでメモ。

Languages & Frameworks > PHPを選択。

CLI InterpreterPHPの実行ファイルを指定。

Applyを押して、OKで一旦Settingsを閉じる。

再度Settingsを開き、 Languages & Frameworks > PHP > Test Frameworksを選択。

+ボタンを押してLocalを選択。

PHPUnit LibraryでUse Composer autoloaderを選択。

pathをvendor/autoloader.phpに設定。

Test runnerのDefault configuration file にチェック。

pathをアプリケーションルートディレクトリのphpunit.xml.distに設定。

applyを押して設定完了。

Google App EngineにGo言語でHTTPサーバーを立てて、BigQueryにログを保存してみた。

この記事について

Google App Engineに立てたHTTPサーバからBigQueryにログを保存するまでの手順メモです。

やりたいこと

アプリのログをHTTP経由でBigQueryに保存していきたい。 BigQuery安いらしいので。

開発環境

Ubuntu 16.04 Go 1.8 Python 3.5

Google Cloud SDKをインストー

まずは公式のドキュメントにしたがって、Google Cloud SDKをインストールする。 https://cloud.google.com/sdk/docs/quickstart-debian-ubuntu

dev_appserver.pyが使えるようにPATHを通す。 以下を~/.bashrcに追記する。

# settings for Google Cloud SDK
export PATH=/usr/lib/google-cloud-sdk/bin/:$PATH

GAE + Goの動作検証

GAE + Goのチュートリアル Quickstart for Go App Engine Standard Environment  |  App Engine standard environment for Go  |  Google Cloud Platform で、

dev_appserver.py app.yaml

を実施したら以下のエラーが出た。

This action requires the installation of components: [app-engine- python, app-engine-go]

Ubuntuの場合は、apt-getで追加のSDKコンポーネントをインストールする。

https://cloud.google.com/sdk/downloads#apt-get

sudo apt-get install google-cloud-sdk-app-engine-go google-cloud-sdk-app-engine-python

もう一度開発サーバを立ててみる。

dev_appserver.py app.yaml

localhost:8080にブラウザでアクセスしてhello, worldが出ていればOK

HTTPサーバーを立てる

新しくプロジェクトを作成する。 app.yamlシンタックスは以下を参照

https://cloud.google.com/appengine/docs/standard/go/config/appref httprouterを使ってルーティングする。 http.ListenAndServeは使えないので、http.Handleを使う。

BigQueryを使う

streamingのライブラリを使った。 “github.com/rounds/go-bqstreamer”

アプリのIDが必要になるので、GoogleCloudPlatformでアプリケーションIDを控えておく。 事前にBigQueryでdatasourceとTableとSchemaを作成しておく。 ApplicationId、DataSource名、Table名を入力し、実行するとBigQueryにデータが保存される。

Streamingのデータはプレビューできないので、クエリを発行する。 SQLクエリと似たようなシンタックスで書ける。

一旦こんな感じで、後でソースとかを追記する予定。

mac に OpenCV 3.2 をインストール (python3)

ubuntuに引き続き、macのpython3 (3.6)用にOpenCVをインストールした時のメモ。

環境

OS : macOS 10.12.4 Python : 3.6

インストール手順

インストールは以下のサイトを参考にしました(本家のほうが詳しく書いてあります…)。 http://www.pyimagesearch.com/2016/12/19/install-opencv-3-on-macos-with-homebrew-the-easy-way/

brewが入っていて、python3、numpyがインストールが終わっている状態から始めます。

$ brew install opencv3 --with-python3 --without-python --with-contrib

デフォルトでpython2系のライブラリが入るっぽいのですが、 without-pythonを記述しないと

Error: opencv3: Does not support building both Python 2 and 3 wrappers

なんて怒られます。 エラーの対処ですが、opencvbrewを編集してもいいみたいです(下記参照)。

http://www.pyimagesearch.com/2017/05/15/resolving-macos-opencv-homebrew-install-errors/

私はpython3だけで十分だったので、–without-pythonのオプションを使いました。

最後にpythonでcv2を使えるようにしてあげます。

$ cd /usr/local/opt/opencv3/lib/python3.6/site-packages/
$ mv cv2.cpython-36m-darwin.so cv2.so
$ cd ~
$ echo /usr/local/opt/opencv3/lib/python3.6/site-packages >> /usr/local/lib/python3.6/site-packages/opencv3.pth

python3でcv2が動くか動作確認

$ python3
>>> import cv2
>>> cv2.__version__
'3.2.0'

以上、お疲れ様でした。

Ubuntu 16.04にOpenCVをインストール (CUDA 8.0 + python 3.5)

OpenCVをインストールした時のメモです。

環境

virtualenvの準備

事前にtensorflowとcuda8.0はインストールしています。 cuda8.0はtensorflowのチュートリアルを参考にしました。 まずpip3を使えるようにします。

$ wget https://bootstrap.pypa.io/get-pip.py
$ sudo python3 get-pip.py

virtualenvをインストールします。

sudo pip3 install virtualenv virtualenvwrapper

.bashrcに以下を追記します。

export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

numpyがインストールされていなければ、numpy をインストールします。

sudo pip3 install numpy

openCVのインストー

必要そうなライブラリをインストールします。

 $ sudo apt-get -y install libopencv-dev \
     build-essential cmake git libgtk2.0-dev pkg-config \
     python-dev python3.5-dev python-numpy libdc1394-22 libdc1394-22-dev \
     libjpeg-dev libpng12-dev libjasper-dev libavcodec-dev \
     libavformat-dev libswscale-dev libgstreamer0.10-dev \
     libgstreamer-plugins-base0.10-dev libv4l-dev libtbb-dev \
     libqt4-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev \
     libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev \
     x264 v4l-utils unzip

opencvを任意のディレクトリにダウンロードして、buildディレクトリを作成します。

$ mkdir opencv
$ cd opencv
$ wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.2.0.zip
$ unzip opencv.zip
$ cd opencv-3.2.0/
$ mkdir build
$ cd build

makeでCUDA連携をONにします。

$ cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D INSTALL_C_EXAMPLES=OFF \
    -D INSTALL_PYTHON_EXAMPLES=ON \
    -D WITH_CUDA=ON \
    -D ENABLE_FAST_MATH=1 \
    -D CUDA_FAST_MATH=1 \
    -D WITH_CUBLAS=1 ..

終わると、以下のように出力されます。

-- General configuration for OpenCV 3.2.0 =====================================
--   Version control:               unknown
--
--   Platform:
--     Timestamp:                   2017-05-16T07:09:11Z
--     Host:                        Linux 4.8.0-51-generic x86_64
--     CMake:                       3.5.1
--     CMake generator:             Unix Makefiles
--     CMake build tool:            /usr/bin/make
--     Configuration:               RELEASE
--
--   C/C++:
--     Built as dynamic libs?:      YES
--     C++ Compiler:                /usr/bin/c++  (ver 5.4.0)
--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -mno-avx -msse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -mno-avx -msse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
--     C Compiler:                  /usr/bin/cc
--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -mno-avx -msse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -ffunction-sections -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -mno-avx -msse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -ffunction-sections -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
--     Linker flags (Release):
--     Linker flags (Debug):
--     ccache:                      NO
--     Precompiled headers:         YES
--     Extra dependencies:          /usr/lib/x86_64-linux-gnu/libpng.so /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/x86_64-linux-gnu/libtiff.so /usr/lib/x86_64-linux-gnu/libjasper.so /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib/x86_64-linux-gnu/libImath.so /usr/lib/x86_64-linux-gnu/libIlmImf.so /usr/lib/x86_64-linux-gnu/libIex.so /usr/lib/x86_64-linux-gnu/libHalf.so /usr/lib/x86_64-linux-gnu/libIlmThread.so gtk-3 gdk-3 pangocairo-1.0 pango-1.0 atk-1.0 cairo-gobject cairo gdk_pixbuf-2.0 gio-2.0 gobject-2.0 glib-2.0 gthread-2.0 gstbase-0.10 gstreamer-0.10 gmodule-2.0 xml2 gstvideo-0.10 gstapp-0.10 gstriff-0.10 gstpbutils-0.10 dc1394 avcodec-ffmpeg avformat-ffmpeg avutil-ffmpeg swscale-ffmpeg dl m pthread rt cudart nppc nppi npps cublas cufft -L/usr/local/cuda-8.0/lib64
--     3rdparty dependencies:       libwebp
--
--   OpenCV modules:
--     To be built:                 cudev core cudaarithm flann imgproc ml video cudabgsegm cudafilters cudaimgproc cudawarping imgcodecs photo shape videoio cudacodec highgui objdetect ts features2d calib3d cudafeatures2d cudalegacy cudaobjdetect cudaoptflow cudastereo stitching superres videostab python2 python3
--     Disabled:                    world
--     Disabled by dependency:      -
--     Unavailable:                 java viz
--
--   GUI:
--     QT:                          NO
--     GTK+ 3.x:                    YES (ver 3.18.9)
--     GThread :                    YES (ver 2.48.2)
--     GtkGlExt:                    NO
--     OpenGL support:              NO
--     VTK support:                 NO
--
--   Media I/O:
--     ZLib:                        /usr/lib/x86_64-linux-gnu/libz.so (ver 1.2.8)
--     JPEG:                        /usr/lib/x86_64-linux-gnu/libjpeg.so (ver )
--     WEBP:                        build (ver 0.3.1)
--     PNG:                         /usr/lib/x86_64-linux-gnu/libpng.so (ver 1.2.54)
--     TIFF:                        /usr/lib/x86_64-linux-gnu/libtiff.so (ver 42 - 4.0.6)
--     JPEG 2000:                   /usr/lib/x86_64-linux-gnu/libjasper.so (ver 1.900.1)
--     OpenEXR:                     /usr/lib/x86_64-linux-gnu/libImath.so /usr/lib/x86_64-linux-gnu/libIlmImf.so /usr/lib/x86_64-linux-gnu/libIex.so /usr/lib/x86_64-linux-gnu/libHalf.so /usr/lib/x86_64-linux-gnu/libIlmThread.so (ver 2.2.0)
--     GDAL:                        NO
--     GDCM:                        NO
--
--   Video I/O:
--     DC1394 1.x:                  NO
--     DC1394 2.x:                  YES (ver 2.2.4)
--     FFMPEG:                      YES
--       avcodec:                   YES (ver 56.60.100)
--       avformat:                  YES (ver 56.40.101)
--       avutil:                    YES (ver 54.31.100)
--       swscale:                   YES (ver 3.1.101)
--       avresample:                NO
--     GStreamer:
--       base:                      YES (ver 0.10.36)
--       video:                     YES (ver 0.10.36)
--       app:                       YES (ver 0.10.36)
--       riff:                      YES (ver 0.10.36)
--       pbutils:                   YES (ver 0.10.36)
--     OpenNI:                      NO
--     OpenNI PrimeSensor Modules:  NO
--     OpenNI2:                     NO
--     PvAPI:                       NO
--     GigEVisionSDK:               NO
--     Aravis SDK:                  NO
--     UniCap:                      NO
--     UniCap ucil:                 NO
--     V4L/V4L2:                    NO/YES
--     XIMEA:                       NO
--     Xine:                        NO
--     gPhoto2:                     NO
--
--   Parallel framework:            pthreads
--
--   Other third-party libraries:
--     Use IPP:                     9.0.1 [9.0.1]
--          at:                     /path/to/opencv/opencv-3.2.0/build/3rdparty/ippicv/ippicv_lnx
--     Use IPP Async:               NO
--     Use VA:                      NO
--     Use Intel VA-API/OpenCL:     NO
--     Use Lapack:                  NO
--     Use Eigen:                   NO
--     Use Cuda:                    YES (ver 8.0)
--     Use OpenCL:                  YES
--     Use OpenVX:                  NO
--     Use custom HAL:              NO
--
--   NVIDIA CUDA
--     Use CUFFT:                   YES
--     Use CUBLAS:                  YES
--     USE NVCUVID:                 NO
--     NVIDIA GPU arch:             20 30 35 37 50 52 60 61
--     NVIDIA PTX archs:
--     Use fast math:               YES
--
--   OpenCL:                        <Dynamic loading of OpenCL library>
--     Include path:                /path/to/opencv/opencv-3.2.0/3rdparty/include/opencl/1.2
--     Use AMDFFT:                  NO
--     Use AMDBLAS:                 NO
--
--   Python 2:
--     Interpreter:                 /usr/bin/python2.7 (ver 2.7.12)
--     Libraries:                   /usr/lib/x86_64-linux-gnu/libpython2.7.so (ver 2.7.12)
--     numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.11.0)
--     packages path:               lib/python2.7/dist-packages
--
--   Python 3:
--     Interpreter:                 /usr/bin/python3 (ver 3.5.2)
--     Libraries:                   /usr/lib/x86_64-linux-gnu/libpython3.5m.so (ver 3.5.2)
--     numpy:                       /usr/local/lib/python3.5/dist-packages/numpy/core/include (ver 1.12.1)
--     packages path:               lib/python3.5/dist-packages
--
--   Python (for build):            /usr/bin/python2.7
--
--   Java:
--     ant:                         NO
--     JNI:                         NO
--     Java wrappers:               NO
--     Java tests:                  NO
--
--   Matlab:                        Matlab not found or implicitly disabled
--
--   Documentation:
--     Doxygen:                     NO
--
--   Tests and samples:
--     Tests:                       YES
--     Performance tests:           YES
--     C/C++ Examples:              NO
--
--   Install path:                  /usr/local
--
--   cvconfig.h is in:              /path/to/opencv/opencv-3.2.0/build
-- -----------------------------------------------------------------
--
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/opencv/opencv-3.2.0/build

makeでは結構待つので覚悟しておきましょう。

$ make -j $(nproc)

私の環境では、10分くらいかかりました。

$ sudo make install

$ sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'

$ sudo ldconfig

参考にした記事