MacでVSCode✖️Python✖️bottle ①viewがない

昨年、windows Updateの度に遅くなっていくwindowsマシンに嫌気が差してMacに乗り換えました。
でもこのMac。マシン自体は快適なんだけど、なかなかの曲者。
windows10✖️VScode✖️Python✖️bottle では起きなかったトラブルがちょこちょこ発生する。

最初に、トラブルが発生したのは、「テンプレートがみつかりません。」というエラー
この問題については、googleを検索すると、見つけたサイトを真似したらなんとか解決。
その解決方法は、下記の通りTEMPLATE_PATHにフォルダを追加するというもの。

from bottle import TEMPLATE_PATH
import os
TEMPLATE_PATH.append ( os.path.abspath(os.path.join(os.path.dirname(__file__), "views")))

今度は、cssファイル、jsファイルをアサインするために記述しても何故かMac環境では取得できていないご様子

@get('/static/<filePath:path>')
def index(filePath):
    return static_file(filePath, root='./static')

これも上のviewのテンプレートが取得できない時に同じで、
ローカルで実行する時、実行ファイルがルートにならないので、
この記述では取得できない。
そこで、実行の初期あたりで実行ファイルをルートに設定することで
staticで取得できなかったファイルを見事に取得することができました。
このへんは、仮想ターミナルなんかを使うと解決する話なのかな!?
まだまだ勉強不足。がんばろ♪

os.chdir(os.path.dirname(os.path.abspath(__file__)))

ロリポップでbottle③ – cgiとpyファイル

ロリポップで、pythonでbottleを使うにあたって、
PythonのWebフレームワーク Bottleをロリポップサーバ(ロリポプラン)で動かしてみる
を参考に動かしていたのですが、この方法だと、pcでテストした後、
ロリポップにアップロードする時にトップ部分と最後の部分を変更する必要があり、
何度もテストして変更してってなると、とても面倒・・・

そこで、CGIファイルとpythonのプログラムファイルを別々で準備する。

CGIファイルはシンプルに、pythonを記述したファイルをimportして、
bottleのrunでcgiとして実行するだけの処理を記述する。

testpython.cgi

#!/usr/local/bin/python3.4
# -*- coding: utf-8 -*-

from bottle import run
import testpython

run(server='cgi')


そして、pythonのプログラムファイルは、

testpython.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
:
 コード
:

# ビルドインサーバの実行
if __name__ == '__main__':
    run(host='localhost', port=8080, debug=True, reloader=True)

にしておくことで、ローカルテストの時は、localhot:8080で起動され
ロリポップで動かす場合には、このlocalhost部分は無視されます。
先頭のバージョン部分も変更不要

実行する時のリンクは
ロリポップでbottle①-getがpostに-解決編
で紹介したように、テンプレート側のリンクアドレスを
上のcgiファイル名にしておくだけで良いので、
テストとアップロードを繰り返す時は、
pythonのプログラムは何も変更する必要なく、
ローカルと同じようにロリポップでも動かせます。

ロリポップでbottle②-postがgetに-解決編

久しぶりにbottleの話。
前回のロリポップでbottle①で詰まっていた箇所の解決編
bottleでもgetを利用する方法です。

前回、htaccessの制御では、getがpostに変更されてしまうというのがわかったので、
java scriptで制御して、リンク先アドレスを書き換えることにしました。

<script type="text/javascript">
	baseurl="/xxxxxxxxxx.cgi";
	$('.submit').click(function() {
	  $(this).parents('form').attr('action', baseurl + $(this).data('action'));
	  $(this).parents('form').submit();
	});
	$('.inlink').click(function() {
	  $(this).attr('href', baseurl + $(this).attr('href'));
	});
</script>

解説すると、baseurlには、pythonを記述しているcgi名を代入。
formのsubmitボタンを押されると、cgiファイルが先頭について実行され、
そして、単純な画面遷移の場合は、あらかじめ class名「inlink」にしておくことで、
リンクボタンを押された時に、cgiファイルが先頭について実行されます。
ただそれだけです。

このscriptはどの画面でも共通的に使用したいので、
footer.tplに入れて、bottleのテンプレートに、%includeで読み込むと便利です。

そして、localhostでテストする際は、baseurlは空白、
ロリポップにアップロードする時に、cgi名を入れることで思い通りに動かすことができます。

ここリモがサービス終了・・・

発売当初から便利に使っていた中部電力から発売されていた『ここリモ』
ネット上では酷評が目立つけれども、我が家では、立派に仕事していた。
それが2023年の12月でサービス終了するらしい。

毎日、
「OK, google 電気つけて(消して)!」
「OK, google エアコンつけて(消して)!」
とgoogle homeとの連携にも全く問題なく動いていたし、
外出先からもスマホのここリモアプリで操作できるので、
冬の留守中は家の中は凍りそうなぐらい寒いから
帰る少し前からエアコンを起動させたり、
本当にありがたかった。

なのに・・・・

この「ここリモ」がとっても便利だったので、
同様の機能を求めて、別の部屋用に一台で済むと思い購入したLine Clovaは
対応家電が少なすぎ(我が家の家電が古すぎ!?)なために、
何の役にも立たず単なるRaziko再生機・・・

この手のサービスは、提供側のサーバーが必要なのは知っているので
どこのメーカーかわからないものより中部電力がいいと思って購入したのに、本当残念。

googleと連携して、赤外線の信号を出すだけでいいんだけどな。
自分でプログラミングして「ここリモ」
動かせるようにならないものかとついつい考えてしまう。。。

手持ちCDを存分に楽しんでいたgoogle play music が
サービス終了した時と同じくらいショック。。。
youtube premiumでは、聴きたい曲をピンポイントで再生してくれないから
結局、SDカードに好きな曲を入れてスピーカーで再生して
飽きてきたら、別の曲をSDカードに入れるという・・・

ここリモにしても、googleplaymusicにしても、
有料ソフトでいいから自宅のサーバーで継続して使えるようにして欲しい🥺

楽天RMSでバナーの貼り替えを日時指定で

先月、友人の紹介で、新しいショップの立ち上げに人が足りないから
手伝って欲しいとの依頼を受け、なんだかんだとバタバタしていて、
bottleの勉強は、少し停滞気味です。

でも、その作業の中で、
元々使用していた日時指定でバナーを切り替える
Javascriptを整理したので公開。
全ての自動化は無理だけど、お金をかけずに
月に2回程度、マラソン前に少し手を加える程度で
更新をサボっていない感のでるscriptです。

<script type="text/javascript" src="js/slick.min.js"></script>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
$(window).on('load', function() {
    var i=0;
    var image =[];
    var link=[];
    var startday =[];
    var endday = [];
    
//
//   ここから更新可能エリア
//
    // image     →  楽天RMS Imageurl
    // link      →  リンク先
    // startday  →  開始日時 ( yyyy:mm:dd hh:mm )
    // endday    →  終了日時 ( yyyy:mm:dd hh:mm )

    //  ワンダフルデイ(毎月1日)
    image[i] ="https://image.rakuten.co.jp/xxxxxxxxx/cabinet/event/monthly_x3.gif";
    link[i] = "https://event.rakuten.co.jp/campaign/point-up/wonderfulday/";
    startday[i] = new Date('2021/10/01 00:00');
    endday[i] = new Date('2021/10/01 23:55');
    i=i+1;

    //  楽天マラソン
    image[i] ="https://image.rakuten.co.jp/xxxxxxxxx/cabinet/event/marathon_pc.gif";
    link[i] = "https://event.rakuten.co.jp/campaign/point-up/marathon/";
    startday[i] = new Date('2021/10/04 20:00');
    endday[i] = new Date('2021/10/11 01:55');
    i=i+1;

    // 5、10日のポイント5倍
    image[i] ="https://image.rakuten.co.jp/xxxxxxxxx/cabinet/event/20180305_cardx5.jpg";
    link[i] = "https://event.rakuten.co.jp/campaign/card/pointday/";
    startday[i] = new Date('2021/10/05 00:00');
    endday[i] = new Date('2021/10/05 23:55');
    i=i+1;

    image[i] ="https://image.rakuten.co.jp/xxxxxxxxx/cabinet/event/20180305_cardx5.jpg";
    link[i] = "https://event.rakuten.co.jp/campaign/card/pointday/";
    startday[i] = new Date('2021/10/10 00:00');
    endday[i] = new Date('2021/10/10 23:55');
    i=i+1;
//
// この先は編集しないでください  
//
    var today = new Date();
    var j=1;
    for(i=0;i<image.length;i++){
        if(startday[i] < today && today < endday[i] ){

            var $newImage =$("<img></img>")
            $newImage.attr("src",image[i]);

            var $newLink = $("<a></a>");
            $newLink.attr("href",link[i]);
            $newLink.attr("target","_blank");
            $newLink.append($newImage.clone());

            $("#banner_"+j).append($newLink.clone());

            j=j+1;
        }
    }
    for(i=j;i<=20;i++){
        $('#banner_'+i).remove();
    }
	$('.slider').slick('unslick');

}

Jqueryとslickを利用しているので、予め楽天GOLDにアップロードをしておいてください。
下記の部分を適宜追加するとどんどん増やせます。

    image[i] ="https://image.rakuten.co.jp/xxxxxxxxx/cabinet/event/20180305_cardx5.jpg";
    link[i] = "https://event.rakuten.co.jp/campaign/card/pointday/";
    startday[i] = new Date('2021/10/10 00:00');
    endday[i] = new Date('2021/10/10 23:55');
    i=i+1;

簡単に解説すると、
image[i]は、楽天RMSの画像ライブラリの保存場所
link[i]は、リンク先
startday[i]、endday[i]は表示開始日時と終了日時。
i=i+1 で追加や削除、順番を入れ替えても問題ない仕様にしています。

HTMLの準備側は、下記の通りで最大表示20個までバナーは追加可能
#banner_xxを利用しなくても追加できるはずなのですが、うまくかなかったので、置き換えて稼働するようにしました。なので、もし表示バナーが20を超えると当然エラーがでます ^^;
20も表示することないので、あえて制御もいれていません。

    <div class="bannerlist">
		<div id="banner_1"></div>
		<div id="banner_2"></div>
		<div id="banner_3"></div>
		<div id="banner_4"></div>
		<div id="banner_5"></div>
		<div id="banner_6"></div>
		<div id="banner_7"></div>
		<div id="banner_8"></div>
		<div id="banner_9"></div>
		<div id="banner_10"></div>
		<div id="banner_11"></div>
		<div id="banner_12"></div>
		<div id="banner_13"></div>
		<div id="banner_14"></div>
		<div id="banner_15"></div>
		<div id="banner_16"></div>
		<div id="banner_17"></div>
		<div id="banner_18"></div>
		<div id="banner_19"></div>
		<div id="banner_20"></div>
    </div>

ロリポップでbottle①-postがgetに-

ロリポップのライトプランでbottleをやり初めて3ヶ月。
ローカルサイトで実現できる簡単なことも、なぜか動かないことが多数。今回は、ファイルをアップロードして読み込むことができないことにつまづいた。

実現したいことは、
WEB画面上のformで
・対象のテーブル名を選択
・CSV形式のローカルファイルを選択(form の file)
実行ボタンで、python側でファイルを読み込んで対象のテーブルにinsertしていくという処理

pythonで記述するのは、もう慣れてきたのでささっと、ローカル上は簡単に実現できたのだけど、それをロリポップにアップロード。

そして、いつもどおり、先頭の行を、
#!/usr/local/bin/python3.4
に変更して、最終行に
run(server=’cgi’)
を追加した。

いざ動かしてみると。反応がないっていうか動いてるの???状態
しかもエラーもでない。
悩むこと3日!!!
デバッグ代わりのログ出力なんかをいれたり、あれやこれやしてもさっぱりわからなかった。もしかして、キャッシュか??と思ってロリポップのキャッシュ削除をしてみたり。。。
キャッシュを疑ったので、formの送信先のurlを変えて、@post()の処理を追加したとき、
「405 method not arrow error」
最初の頃、よく見かけたなと、思い出し、@get()を追加するとエラーが消えた。
試してるうちに、どうもリクエストのpostがgetに変わっているということ???だからファイルが読めないの???

あっ!!!!

そういえば、ロリポップで動かすには、htaccessでリダイレクトしてたっけ?最初に設定してたから、その後意識してませんでした。

そう、リダイレクトしてなんらかの条件が揃うと、postがgetに置き換わるようで、ファイルのアップロードはどうやら難しいことが判明した。

とりあえず、原因発見した途端、すごい疲労感。
解決方法は後日考えよう・・・

医薬品の添付文書をHTML化する

仕事の一つに商品登録というのがあります。
当然のことながら、商品ごとに説明が違う。画像も大事だけど、テキスト情報も検索に関わってくるので、無視できないんですよね。

大抵は公式サイトからの情報のコピペしてるのだけど、
そんな中で、医薬品の添付文書は情報量も多いし、各メーカーのホームページ上では、あまり細かいところまで掲載されておらず、楽天市場なんかだと、販売の規定上、添付文書に記載のほとんどすべてを商品説明にいれておかなければ、罰金というルールもある。

そんななか、とっても有用なサイトがこちら。

「独立行政法人医薬品医療機器総合機構」が公開している
一般用医薬品・要指導医薬品の添付文書情報

このサイトは、一応薬局の担当者は使用してもOKとされて一般公開されているサイト。
このサイトを知らなかったときは、各メーカーのホームページにあるPDFの添付文書をひたすら手入力または他の通販サイト様から拝借していた。。。(基本、後者でしたが^^;)

このページで検索した医薬品添付文書を整形して、商品ページにコピペ。以前は、excelのマクロで組んでいたのですが、python勉強始めてからweb上で使える簡易ツールに変換してみました。

そのツールがこちら↓↓↓

簡易HTML形式に変換

変換ボタンを押すと、PC用にフル文書が、スマホ用に、効果効能と用量用法がコピーして使える状態で変換してあります。
医薬品の添付文書ではないときは、単純にテキストの改行ごとに<BR>が挿入される仕組みです。
こちらは、メモ帳で改行コードの変換方法を知らない人にも使ってもらえます。

そもそも各通販サイト。商品説明の更新がコード入力って 、どうなの!?

ロリポップでbottleを使う

前回更新から1ヶ月。ロリポップのライトプランでPythonを動かすのにメリットはあるのか??という自問をしながら、やっと簡単なツールを動かすことができました。

参考にしたサイトは、こちら
「PythonのWebフレームワーク Bottleをロリポップサーバ(ロリポプラン)で動かしてみる」

このサンプル通りなら動くのだけど、getをpostに変更しただけで、とたんに動かなくなってしまうし、一度動かして、サーバーエラー500が出た後は、修正してもしばらく動いてくれない。。。。などなど

一度は、phpで同じアプリを作ってしまったぐらい ^^;

それでも、やっぱりpythonでしょ!!と諦めずに取り組んだ結果、ようやくpostでも動きました♪♪

それがこちらのツール↓↓↓↓

テキストA-B単純比較

職場では、JANコード入力してプライスカードを出力する作業を某POSレジシステムに入っているツールを使っている。
しかし、レジ未登録の商品のプライスカードは、エラーも何も表示されず例えば50件出力しようとしても48件しかなかったら、じゃぁどの2件!?というのをこのツールで発見することができます。

以下は、備忘録として、動かなかった書き方

@route(“/display1″, method=”POST”)
def xxxxxxxxx() :
→最初に書いて撃沈

@route(“/display1”, method=[“GET”,”POST”])
def xxxxxxxxx() :
→これも駄目

@route(“/display1″, method=”GET”)
@route(“/display1″, method=”POST”)
def xxxxxxxxx() :
→defの前に2つ併記。ロリポップの契約2つあるうちの1つでは動くものの1つでは動かなかった。理由は不明。

成功した方法↓↓↓↓↓↓↓↓↓↓

@route(“/display1″, method=”GET”)
def xxxxxxxxx() :

@route(“/display1″, method=”POST”)
def xxxxxxxxx() :

get と post の処理を別途作成したら無事動きました。
試してないけど、@get や @post でも動きそう

注文情報の郵便番号チェック

とりあえずブログを立ち上げて一週間。
pythonをローカルで動かすのは割とあっさりできたのだけど、webで動かすのにいろいろハードルがあり、安いレンタルサーバーなので、細かな設定につまずいてるところです。

なので、今日はなぜ郵便番号チェックのツールをアップロードしようと思ったのかを書きたいと思います。

うちの職場では、ショッピングサイト(アマゾン、楽天市場、ヤフー、メイクショップ)の受注データをダウンロードして、Microsoft Accessを使って、梱包に必要な控えを印刷したり、宛名を印刷するのに、ヤマト運輸の送り状発行システムB2クラウドや、日本郵便のゆうパックプリントRのファイルに変換しています。

問題は、各サイトの受注データ、なぜか、郵便番号と住所があわないことが多々あること。郵便番号の桁数が足りないこともあるし、古い郵便番号ということもある。
ヤマト運輸の送り状発行システムは、住所チェックをしてくれるので気づけるけど、日本郵便のゆうパックプリントRのWEB版はノーチェック!!ゆうパックプリントRのアプリ版はチェックしてくれてたのですが、いつの頃からかメモリ不足エラー多発で使いものになりません(それはそれで困りもの)

郵便番号と住所があっていないお客様は、購入時に自分の送付先を確認していないから、住所自体あいまいで届かないことがあったり、引っ越し前の住所だったりすることが多くて、送料代金損失のリスクが高いので、この郵便番号のチェックは絶対外せない。

各ショッピングサイトに言いたい。
住所チェックの機能を強化して!!!

Hello!!

はじめまして、akiです。
インターネット通販サイト(amazon、楽天、yahoo、makeshop)の運営管理しています。
通販サイトをまとめて管理するツールを導入していないので、何から何まで、自分でやってます。
現在は、単なるパート従業員ですが、十数年前はプログラマー、システムエンジニアの仕事をしていたのもあり、痒い所に手が届くツール類は、ついつい自分で作ってしまいます。
40代半ばにして最近、新しく始めたプログラム言語のpythonが、とてもおもしろいと感じたので、それを上手く利用して、今まで作ったツールたちを、ほかの人たちにも使ってもらえるようにアレンジできたらいいなと思い、備忘録も兼ねてブログを書くことにしました。

最初に目指しているのは、郵便番号をまとめてチェックできるWEBアプリの公開。
現在、PYTHONとAPIでローカルで動かしていますが、まとめてチェックできるサイトがなかったので、公開できれば、自分にも都合がよいので、まずはそこから始めます。

いつまで続くか、公開にたどりつけるのかは、わかりませんが、
・思い立ったが吉日!!
・いつかやろう!のその日はこない!!
・千里の道も1歩から!!
と自分に言い聞かせて、今日この1ページを残しました。