【Python3】HTMLのエスケープされた記号を元に戻す

環境

Python 3.4.3

方法

xml.sax.saxutilsモジュールのunescapeメソッドを使えばOK。

from xml.sax.saxutils import unescape
text = '& < >'
print(unescape(text))  # => '& < >'

第二引数にdictを与えると、独自辞書の定義も可能とのこと。

from xml.sax.saxutils import unescape
text = '&lt;ルイズ貧乳&gt;'
unescape(text, {'貧乳': 'かわいい'})  # => '<ルイズかわいい>'

参考

19.11. xml.sax.saxutils — SAX ユーティリティ — Python 2.7ja1 documentation
236:HTMLをエスケープする

【Python3】sqlite3.ProgrammingError: Incorrect number of bindings supplied【SQLite3】

また引っかかりそうなのでメモ。

環境

Python 3.4.3
sqlite3

解決策

executeメソッドSQLを実行しようとしたところ、

sqlite3.ProgrammingError: Incorrect number of bindings supplied.

と怒られてしまいました。

原因は単純で、executeメソッドの第二引数の形式です。
executeメソッドでは、第二引数はタプルで指定する必要が有るため、以下のようになります。

name = 'some_user_name'

# 駄目な例
c.execute('select * from users where name=?', name)

# 正しい例
c.execute('select * from users where name=?', (name,))

指定する変数がひとつの場合、最後に余計なカンマが付着するため若干気持ち悪いですが、Pythonの文法規則上やむを得ないですね。

【MySQL】データアップデート時に自動で時刻を更新する

フルスタックのWebアプリケーションフレームワークだと自動でやってくれますが、小規模フレームワークだと自力でやらねばならないためメモ。

CREATE TABLE some_tabel (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
);

これでcreatedには新規に作成された時の時刻が、modifiedにはupdateされる度にその時刻が挿入されます。

【CentOS6】鍵認証によるssh接続

ローカルのMacからリモートのCentOSへ鍵認証でssh接続するための手順をメモっておきます。
公開鍵および秘密鍵は予め作成が済んでいるものとします。

環境

Mac OS X Yosemite
CentOS 6.6

鍵の設定

まずはローカルMacからリモートに公開鍵の送付。

scp ~/.ssh/id_rsa.pub some_user@xxx.xxx.xxx.xxx:~/.

次にリモートのCentOSにログインし、公開鍵の設定を行う。

mkdir ~/.ssh  # .sshディレクトリがない場合
mv ~/id_rsa.pub ~/.ssh/.
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

次にsshd_configの修正。

sudo emacs /etc/ssh/sshd_config

各行のコメントアウトを外し、AuthorizedKeysFileでは公開鍵の場所の指定をする。

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      ~/.ssh/authorized_keys

またパスワード認証は不要なので、PasswordAuthentication noに設定する。

以上終了後sshdの再起動。

sudo service sshd restart

ローカルMacに戻り、sshログイン。

ssh -i ~/.ssh/id_rsa some_user@xxx.xxx.xxx.xxx

無事鍵認証でssh接続成功!

ついでにローカルMacのconfigファイルにssh接続の設定を追記。

emacs ~/.ssh/config
Host some_host
  HostName xxx.xxx.xxx.xxx
  User some_user
  port 22
  IdentityFile ~/.ssh/id_rsa

上記設定追記後、下記コマンドでssh可能。

ssh some_host

面倒な入力がなくなって便利!

参考

RSA公開鍵認証によるssh接続設定について(Macbook -> VPS) - Qiita

【CentOS6】新規ユーザーの追加とsudo権限の付与

環境

CentOS 6.6

ユーザー作成と権限付与

各コマンドはsudo権限のあるユーザーで実行する。

またsudoは、wheelグループに属しているユーザーのみ可能という方針で行う。
visudoコマンド単体で/etc/sudoersの編集は可能だが、/etc/sudoersの下部に記載されている#includedir /etc/sudoers.dによって、/etc/sudoers.d/下のファイルが読み込まれるため、ここでは/etc/sudoers.d/下に新規で設定ファイルを作成し、そのファイルに設定を記載する。
ちなみに#コメントアウト的な意味ではないので注意。

まずはユーザーの追加とパスワードの設定。

$ sudo useradd hoge
$ sudo passwd hoge

次にsudo権限の付与。

$ visudo -f /etc/sudoers.d/wheel

当たり前だが、emacsではなくviで開くので注意。
下記設定を新規記載。

%wheel ALL=(ALL) ALL

wheelユーザーに権限付与。
文法ミス等してしまうと、sudoコマンドが実行不可になってしまう危険があるので注意。visudoで開いており、警告を出してくれるはずなので大丈夫だとは思われる。

最後にユーザーをwheelグループに追加。

$ sudo usermod -G wheel hoge

新しく作ったユーザーに変更し、sudoが必要なコマンドを実行してみる。

$ su hoge
$ sudo visudo
[sudo] password for hoge

無事sudo権限を持ったユーザーの作成に成功!

参考

CentOS - sudoできるユーザを制限する。 - Qiita
CentOS - sudoers は編集せずに sudoers.d の中に設定を書こう - Qiita

【MeCab】Python3で解析時にbuiltins.UnicodeDecodeError【Flask】

Twitterから取得したデータをMeCabで処理し、Flaskを用いたWebアプリケーション上で表示しようとしたところ、下記のようなエラーが出現。

builtins.UnicodeDecodeError
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 0: invalid start byte

もしかしたらまたハマるかもしれないので念のためメモ。

環境

Python 3.4.3
MeCab 0.996

解決策

原因は不明だが、エラーメッセージを見るにエンコーディングがどうので死んでしまう模様。
ちなみにMeCabの実装コードは下記のような感じ。

import MeCab
mecab = MeCab.Tagger()
node = mecab.parseToNode("私はルイズが好きです。なぜなら、彼女はとてもキュートだからです。")
while node:
    print(node.surface)
    node = node.next

中々解決策に辿りつけなかったのだが、一行追記することでエラーの回避が可能に。
原因は正直良くわからない。
修正したコードは以下。

import MeCab
mecab = MeCab.Tagger()
mecab.parse('')  # これを追記!
node = mecab.parseToNode("私はルイズが大好きです。なぜなら、彼女はとてもとてもキュートだからです。ルイズかわいい!")
while node:
    print(node.surface)
    node = node.next

元々Python3でMeCabparseToNodeメソッドを使用すると、最初に返されるnodeが空の値というバグがあり、この解決のためにmecab.parse('')をするらしいのだが、UnicodeDecodeErrorへも対策として効果を発揮してくれた。

原因はよく分からないが、動くようになったので取り敢えず良しとする。

参考

Ubuntu14.04とPython3でMeCabを使う方法 | トライフィールズ

【Bottle】@viewデコレータを自前で定義する【Jinja2】

通常Bottleを使用する場合は、使用するテンプレートに併せて必要なメソッドやデコレータをインポートして用いることで、viewテンプレートの描画を非常に簡単に行うことが出来ます。

例えば、Jinja2テンプレートを使用し、メソッドでviewテンプレートの描画を行う場合は以下のようになります。

from bottle import route, jinja2_template as template

@route('/')
def index():
    return template('index.html', data = some_func())

また、同様の処理をデコレータで実装すると以下のようになります。

from bottle import route, jinja2_view as view

@route('/')
@view('index.html')
def index():
    return dict(data=some_func())

このメソッド群は非常に便利ですが、細かいセッティングをしようとすると、少なくない問題が発生します。
例えば、テンプレート側で何らかの関数を利用したい場合、jinja2.Environmentglobalsに追加しますが、bottleに用意されているメソッドでそれを実装するのは少々難しいです(そこまでソースコードを読んでいないので可能かもしれません)。

というわけで、templateの展開を行うviewデコレータを自力で実装してしまえという結論に至ります。

環境

Bottle v0.12
Jinja2 v2.8

実装

新しいview用のファイルをdecoview.pyという名前で作成し、以下のようにします。

# decoview.py
import functools
import jinja2

env = jinja2.Environment(
    loader=jinja2.FileSystemLoader('./path/to/views'),
    autoescape = True
)

env.globals.update({
    'some_func_key', some_func()
})

def some_func():
    return 'Called some_func!'

def view(template_name):
    def decorator(view_func):
        @functools.wraps(view_func)
        def wrapper(*args, **kwargs):
            response = view_func(*args, **kwargs)
            if isinstance(response, dict):
                template = env.get_or_select_template(template_name)
                return template.render(**response)
            else:
                return response
        return wrapper
    return decorator

せっかくなのでautoescapeTrueにしてみました。

新しく作成したdecoviewをインポートして使用すれば、jinja2テンプレートファイルの中でsome_func()が実行可能です。

# index.py
from bottle import route
from decoview import view

@route('/')
@view('index.html')
def index():
    return {}

例えば下記のようにjinja2テンプレートを呼び出します。

<!-- index.html -->
{{ some_func_key }}

きっとCalled some_func!という文字列が表示されていることと思います。

参考

API — Jinja2 Documentation (2.8-dev)
Jinja2 templates and Bottle | Reliably Broken

キーボードの入力ソースからUSを削除する

何故か定期的に復活してくるためメモ。

環境

Mac OS X Yosemite Google日本語入力

解決策

まずはメニューバーからキーボード環境設定を開く。

f:id:taka_say:20150616094339p:plain

入力ソースタブに移動し、USを選択すると、

f:id:taka_say:20150616094223p:plain

が選択出来ない状態になっている。

以前までは日本語入力ソースのことえりを追加後、削除という手順を行っていたが、Yosemiteからことえりが廃止されたため、ことえりの追加は出来ない。

しかし、新規に追加された日本語入力ソースを一旦追加して同様の手順を行えば、これまで通りにUSソースの削除が可能。

f:id:taka_say:20150616094905p:plain

をクリックし、日本語 -> 日本語を選択して追加。

USを選択すると、が有効になっている。

f:id:taka_say:20150616095110p:plain

あとはUSおよび日本語の順にで取り除けば……

f:id:taka_say:20150616095103p:plain

綺麗サッパリ!