2020年4月26日日曜日

スマホ用メモアプリ

javascriptとbottleを組み合わせて、手書きできるスマホ用のかんたんなメモアプリをつくってみた。外でちょっとしたメモをしただけで、即、クラウドに保存されます。(スマホは、キー操作よりタッチ操作が便利なので)

ajax送信部分は
 

こちらがバックエンドになります。(bottle)


・スマホのイベントはマウスとは別にタッチイベントをつくる必要があります。微妙に座標の処理が違います。
・保存ボタン不要にするため、タッチが離れるたびにAjaxで画像をPostしてクラウド上に保存しました。
・javascriptソースをアップしようとしたのですが、ブログのセキュリティフィルター?のためか、うまくいかず、一部だけのせました。

heroku にbottle paste適用

herokuでのbottleは、あまりダウンすることもなく割と安定して動いてはいましたが、raspi2のbottleにpasteを入れたので、herokuにもpushしてみました。ところが、いろいろひっかかるところがあってうまく動作しません。

・ web.serve(app, host='0.0.0.0',  port=int(os.environ.get("PORT", 8888)),daemon_threads=False,threadpool_workers=25,use_threadpool=True)
というように、port=int(os.environ.get("PORT", 8888))を入れるといいようです。
https://qiita.com/sgigagaeru/items/d0bffd18d1644d292b3d
上記のリンクを参考にさせていただきました。こうすると、raspiでは8888で、herokuでは対応したポートに自動で切り替わるようです。

・requirements.txtに、必要なモジュールを追加しておく必要があるようです。
herokuでpip install pasteだけではだめで、このファイルに
Paste==3.4.0
を1行追加したらokでした。

この2つだけなのですが、いろいろ試行錯誤したり、ネットの情報集めで意外と時間がかかってしまいました。

2020年4月24日金曜日

bottleでstatic_fileを使う

javascriptを読み込むためにstatic_fileを使おうとしたが、最初使い方がよくわからなかった。こちらを参考させていただく。
jsファイルやJpgファイルなど区別して、mimetypeを指定してやるといいようです。

@app.route('/py/<fname:re:.*\.js>')
def static(fname):
    return static_file(fname,root='/home/pi/c9/bottle/python-getting-started/py',mimetype='application/javascript')
   
@app.route('/py/<fname:re:.*\.jpg>')
def staticjpg(fname):
    return static_file(fname,root='/home/pi/c9/bottle/python-getting-started/py',mimetype='image/jpg')


2020年4月22日水曜日

Raspi2でSSL化

http://itemy.net/?p=1052 あたりを参考にさせていただいた
ついでに、pythonのバージョンも3に変更した
https://qiita.com/Takumi_Kaibara/items/6aadf1ac2c1f6bea41a8

無料SSLはCertbotなどでググるとたくさん情報がある
Cerbot入門
エラーの処理なども説明してくださっているサイトも参考になります
https://blog.ijoru.com/?p=675

リバースプロキシを使うことにした
http://itdoc.hitachi.co.jp/manuals/link/cosmi_v0950/03Y1830D/EY180050.HTM
bottleを使うと、シングルスレッドなので、よく落ちます。それを改善するにはPasteを使うといいようです。
https://www.netmarvs.com/archives/895

RasPi2では、Cloud9とbottleの2つをポート番号を違えて動かしていたので
リバースプロキシからうまくつなげるのに、苦労した。

ネット上にも情報がないので、試行錯誤の結果、以下のようにしたらうまくいった。
default-ssl.confのProxyPassは
ProxyPass /abc  http://localhost:12080/abc
ProxyPass /def http://localhost:12080/def
....等々bottleのサーバを記述し
cloud9については、最後に
ProxyPass /  http://localhost:8080/
としてやるとうまくいった。




2020年4月18日土曜日

標準ツールでパケットキャプチャ

通信の不具合チェックに、いちいちWiresharkをインストールするのも気が引けるので、そういうときは標準ツールでキャプチャして、解析する方法があるようだ。
https://www.hi-song.jp/entry/2017/06/25/071031
を参考にさせていただく。
キャプチャの開始:netsh trace start capture=yes
キャプチャの終了:netsh trace stop
出力先や最大サイズも指定もできて
netsh trace start capture=yes traceFile=D:\YYYYMMDD-HHMMSS.etl maxSize=1000
などとするといいようだ。
https://troushoo.blog.fc2.com/blog-entry-416.html
で、etl2pcapngというツールを入手して、Wireshark用のファイルに変換します。
etl2pcapng 20200418-120600.etl dst.pcap というように。

ルータのファイヤーウオールの設定について

 久しぶりにファイヤーウオールの設定を変えてみた。機器の種類により微妙に設定方法が違うので、注意が必要。
 ある程度きびしめに、設定して必要に応じてポートを開けていくようにするようにしている。ただ、送信元と宛先のプロトコルとポートの組み合わせをよくチェックしながら設定しないとうっかりミスしやすいので注意が必要なようだ。
 ・ディフォルトの設定に加えて
  ①まずいったん、内部から外部へのすべてのアクセスを制限
  ②次に、内部から外部への必要なアクセスを許可していく(Web,メール,DNS等)
  ③外部から内部へのアクセス許可を必要に応じて許可していく
 ③の場合は、IPマスカレードの設定で、ポートにより外部からのアクセスの振り分け設定が必要。

2020年4月9日木曜日

groupsession 回覧の「確認」クリックせずに既読に

グループセッションは、機能も豊富で、便利に使わせていただいています。
また、ソースを公開してあるため、カスタマイズもできるようになっています。
今回、回覧機能で、確認ボタンをクリックしなくても、既読になるように
カスタマイズしてみました。Cir020Action.javaの2か所を変更します。

    private ActionForward __doInit(
        途中省略
        biz.setPrevNext(paramMdl, con,
                paramMdl.getCirViewAccount(), GSConstCircular.MODE_JUSIN, userSid);
        paramMdl.setFormData(form);
        con.setAutoCommit(false);

        //********************ここから
        RequestModel reqMdl = getRequestModel(req);
        MlCountMtController cntCon=null;
try {
cntCon = getCountMtController(req);
} catch (Exception e) {
e.printStackTrace();
}
        String appRootPath = getAppRootPath();
        paramMdl.setParam(form);
        try {
biz.doUpdate(
        paramMdl, con, reqMdl,
        paramMdl.getCirViewAccount(),
        userSid, cntCon, tempDir, appRootPath);
} catch (Exception e) {
e.printStackTrace();
}
        paramMdl.setFormData(form);
        //++++++++++++++++ここまで 追加

        return __doDsp(map, form, req, res, con, true);
    }

private ActionForward __doPrevNext(
     途中省略
            }
        } finally {
            con.setAutoCommit(false);
        }

     ********************ここから
        RequestModel reqMdl = getRequestModel(req);
        MlCountMtController cntCon=null;
try {
cntCon = getCountMtController(req);
} catch (Exception e) {
e.printStackTrace();
}
        String appRootPath = getAppRootPath();
        Cir020ParamModel paramMdl = new Cir020ParamModel();
        paramMdl.setParam(form);
        Cir020Biz biz = new Cir020Biz();
        try {
biz.doUpdate(
        paramMdl, con, reqMdl,
        paramMdl.getCirViewAccount(),
        userSid, cntCon, tempDir, appRootPath);
} catch (Exception e) {
e.printStackTrace();
}
        paramMdl.setFormData(form);
        //++++++++++++++++ここまで 追加

        return __doDsp(map, form, req, res, con, true);
    }