類似楽曲検索を作ってみました。
しばらくこのブログを止んでましたが、このブログを書きながらやっと作りたかったサイトが出来たので、ご報告。
まだ、作りかけですが、音楽のmp3データに含まれてる音楽サウンドの音声分析をもとに、ある曲の類似楽曲をコンピュータで自動で計算して、似ている感じの曲を表示しようというもの。
楽曲分析のアルゴリズムは、まだまだヨチヨチ歩きの段階ですが、こちら。
『類似楽曲検索 - ちゃむサーチ(http://chamu.org/)』
AKB48の恋するフォーチュンクッキーの類似楽曲だとこんな感じ。
Python - SSHモジュールのポート転送でMySQLにお気軽リモート接続
以前『sshトンネル(ポートフォワード)を使ってリモートのMySQLにつなぐ』という記事を書きましたが、sshコマンドでポートフォワードをしようとすると、パスワードログインの場合、毎回、パスワードを入力しないといけないのが面倒なので、
Python - SSHモジュールを使ってPythonでリモートのホストに自動ログイン。
これだと、リモートのMySQLのメンテナンス(更新)などの作業を自宅のパソコンから自動化したい場合、ポート転送用のPythonスクリプトを自動起動するようにしておけば、マシン立ち上げと同時にポート転送が張れるので、便利ですね。
以下は、 Python - SSHモジュールさんのDemoにあったforward.pyを若干いじって、ローカルの3307ポートからリモートのMySQLの3306デフォルトポートへポート転送するようにさせて頂いたスクリプト。
#!/usr/bin/env python import getpass import os import socket import select import SocketServer import sys import ssh server_host = "サーバーアドレス" server_port = サーバSSHのログインポート remote_host = "127.0.0.1" remote_port = 3306 local_port = 3307 user = "SSHのログインユーザー名" password = "パスワード" g_verbose = True class ForwardServer (SocketServer.ThreadingTCPServer): daemon_threads = True allow_reuse_address = True class Handler (SocketServer.BaseRequestHandler): def handle(self): try: chan = self.ssh_transport.open_channel('direct-tcpip', (self.chain_host, self.chain_port), self.request.getpeername()) except Exception, e: verbose('Incoming request to %s:%d failed: %s' % (self.chain_host, self.chain_port, repr(e))) return if chan is None: verbose('Incoming request to %s:%d was rejected by the SSH server.' % (self.chain_host, self.chain_port)) return verbose('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(), chan.getpeername(), (self.chain_host, self.chain_port))) while True: r, w, x = select.select([self.request, chan], [], []) if self.request in r: data = self.request.recv(1024) if len(data) == 0: break chan.send(data) if chan in r: data = chan.recv(1024) if len(data) == 0: break self.request.send(data) chan.close() self.request.close() verbose('Tunnel closed from %r' % (self.request.getpeername(),)) def forward_tunnel(local_port, remote_host, remote_port, transport): class SubHander (Handler): chain_host = remote_host chain_port = remote_port ssh_transport = transport ForwardServer(('', local_port), SubHander).serve_forever() def verbose(s): if g_verbose: print s def main(): client = ssh.SSHClient() client.load_system_host_keys() verbose('Connecting to ssh host %s:%d ...' % (server_host, server_port)) try: client.connect(server_host, port=server_port, username=user, password=password) except Exception, e: print '*** Failed to connect to %s:%d: %r' % (server_host, server_port, e) sys.exit(1) verbose('Now forwarding port %d to %s:%d ...' % (local_port, remote_host, remote_port)) try: forward_tunnel(local_port, remote_host, remote_port, client.get_transport()) except KeyboardInterrupt: print 'C-c: Port forwarding stopped.' sys.exit(0) if __name__ == '__main__': main()
上記を、ローカルのパソコンで動かしておくと、↓こんな感じで、いつでも自宅のパソコンから、リーモートのMySQLにお気軽接続。
>>> import MySQLdb >>> conn = MySQLdb.connect(db='music', host='127.0.0.1', port=3307 ,user='リモートのmySQLのユーザー名', passwd='パスワード') >>> cursor = conn.cursor() >>> cursor.execute( "select count(1) from mp3" ) 1L >>> cursor.fetchall() ((10439L,),)
統合数式処理システムSage (セイジ)にMySQL-pythonをインストール
統合数式処理システムSage からMySQLのデータにアクセスしたかったのでSageにMySQL-pythonをインストール
以下root権限で
1.Sageのシェルを起動
sage -sh
2.SageのシェルからMySQL-pythonをインストール
pypi(https://pypi.python.org/pypi/MySQL-python/)からMySQL-pythonをダウンロードしてインストール
wget https://pypi.python.org/packages/source/M/MySQL-python/MySQL-python-1.2.5.zip unzip MySQL-python-1.2.5.zip cd MySQL-python-1.2.5 python setup.py install
3.sageを起動してMySQLdbがimport出来ればOK
$ sage ---------------------------------------------------------------------- | Sage Version 5.8, Release Date: 2013-03-15 | | Type "notebook()" for the browser-based notebook interface. | | Type "help()" for help. | ---------------------------------------------------------------------- sage: import MySQLdb sage:
eyeD3でMP3ファイルのタグ情報を取得する。
eyeD3でMP3ファイルのアーティスト名などのタグ情報を取得してみる。
1.インストール
pip install eyeD3
2.実行例
(1) コマンドラインから
$ eyeD3 'Last Christmas.mp3' 01 Last Christmas.mp3 [ 8.18 MB ] ------------------------------------------------------------------------------- Time: 03:29 MPEG1, Layer III [ 320 kb/s @ 44100 Hz - Stereo ] ------------------------------------------------------------------------------- ID3 v2.3: title: Last Christmas artist: Taylor Swift album: Holiday Collection recording date: 2007 track: 1 genre: Country (id 2) OTHER Image: [Size: 176995 bytes] [Type: image/png] Description: -------------------------------------------------------------------------------
(2) Pythonから
$ python Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import eyed3 >>> audiofile = eyed3.load("Last Christmas.mp3') >>> print audiofile.tag.artist.encode('utf-8') Taylor Swift >>> print audiofile.tag.album.encode('utf-8') Holiday Collection >>> print audiofile.tag.title Last Christmas >>> print audiofile.tag.track_num (1, None)
ネットワーク上のExcelファイルをPythonで直接読み込む(xlrd)
先日、パッケージ管理システム『pip』をインストールしていたので、Python で Excel ファイルを 読み/書きするためのパッケージ xlrd, xlwt, xlutilsをpipでインストールする。
pip install xlrd xlwt xlutils
2.Pythonでネットワーク上のExcelファイルを直接読み込んで、セルの中身をそのままリストしてみる。
以下のテキストをexcel.pyとして保存し、
#!/usr/bin/env python # -*- coding: utf-8 -*- import xlrd import urllib def read_xls(url): web = urllib.urlopen(url) webdata = web.read() web.close() book = xlrd.open_workbook(file_contents=webdata) sheet_1 = book.sheet_by_index(0) print 'sheet_name=', sheet_1.name.encode('utf-8') print 'ncols=', sheet_1.ncols print 'nrows=', sheet_1.nrows for col in range(sheet_1.ncols): print "----------------------------" for row in range(sheet_1.nrows): cell=sheet_1.cell(row,col) if cell.ctype == xlrd.XL_CELL_TEXT: print 'col=', col, 'row=', row, cell.value.encode('utf-8') else: print 'col=', col, 'row=', row, cell.value if __name__ == '__main__': import sys if len( sys.argv ) > 1: url = sys.argv[1] read_xls(url)
コマンドラインから
./excel.py 'http://www.soumu.go.jp/johotsusintokei/field/data/gt010601.xls'
と打つと、総務省「分野別データ:通信:国際比較」のページ(http://www.soumu.go.jp/johotsusintokei/field/tsuushin08.html)にある「世界のインターネット利用者総数の推移」のExcel ファイル(http://www.soumu.go.jp/johotsusintokei/field/data/gt010802.xls)を直接読み込んで1シート目の各セルの値が、以下の形でプリントされます。
sheet_name= 世界のインターネット利用者総数の推移 ncols= 16 nrows= 7 ---------------------------- col= 0 row= 0 世界のインターネット利用者総数の推移 col= 0 row= 1 col= 0 row= 2 col= 0 row= 3 利用者総数 col= 0 row= 4 col= 0 row= 5 col= 0 row= 6 (出典)「ITU Internet Report 2006: digital life」等 ---------------------------- col= 1 row= 0 col= 1 row= 1 col= 1 row= 2 1991年 col= 1 row= 3 4.0 col= 1 row= 4 col= 1 row= 5 col= 1 row= 6 ---------------------------- col= 2 row= 0 col= 2 row= 1 col= 2 row= 2 1992年 col= 2 row= 3 7.0 col= 2 row= 4 col= 2 row= 5 col= 2 row= 6 ---------------------------- col= 3 row= 0 col= 3 row= 1 col= 3 row= 2 1993年 col= 3 row= 3 10.0 col= 3 row= 4 col= 3 row= 5 col= 3 row= 6 ---------------------------- col= 4 row= 0 col= 4 row= 1 col= 4 row= 2 1994年 col= 4 row= 3 21.0 col= 4 row= 4 col= 4 row= 5 col= 4 row= 6 ---------------------------- col= 5 row= 0 col= 5 row= 1 col= 5 row= 2 1995年 col= 5 row= 3 40.0 col= 5 row= 4 col= 5 row= 5 col= 5 row= 6 ---------------------------- col= 6 row= 0 col= 6 row= 1 col= 6 row= 2 1996年 col= 6 row= 3 74.0 col= 6 row= 4 col= 6 row= 5 col= 6 row= 6 ---------------------------- col= 7 row= 0 col= 7 row= 1 col= 7 row= 2 1997年 col= 7 row= 3 117.0 col= 7 row= 4 col= 7 row= 5 col= 7 row= 6 ---------------------------- col= 8 row= 0 col= 8 row= 1 col= 8 row= 2 1998年 col= 8 row= 3 145.0 col= 8 row= 4 col= 8 row= 5 col= 8 row= 6 ---------------------------- col= 9 row= 0 col= 9 row= 1 col= 9 row= 2 1999年 col= 9 row= 3 235.0 col= 9 row= 4 col= 9 row= 5 col= 9 row= 6 ---------------------------- col= 10 row= 0 col= 10 row= 1 col= 10 row= 2 2000年 col= 10 row= 3 390.0 col= 10 row= 4 col= 10 row= 5 col= 10 row= 6 ---------------------------- col= 11 row= 0 col= 11 row= 1 col= 11 row= 2 2001年 col= 11 row= 3 496.0 col= 11 row= 4 col= 11 row= 5 col= 11 row= 6 ---------------------------- col= 12 row= 0 col= 12 row= 1 col= 12 row= 2 2002年 col= 12 row= 3 623.0 col= 12 row= 4 col= 12 row= 5 col= 12 row= 6 ---------------------------- col= 13 row= 0 col= 13 row= 1 col= 13 row= 2 2003年 col= 13 row= 3 688.0 col= 13 row= 4 col= 13 row= 5 col= 13 row= 6 ---------------------------- col= 14 row= 0 col= 14 row= 1 col= 14 row= 2 2004年 col= 14 row= 3 875.0 col= 14 row= 4 col= 14 row= 5 col= 14 row= 6 ---------------------------- col= 15 row= 0 col= 15 row= 1 (百万人) col= 15 row= 2 2005年 col= 15 row= 3 965.0 col= 15 row= 4 col= 15 row= 5 col= 15 row= 6
ServersMan@VPS(CentOS)にPostfixをインストール
以下、書きかけ
ServersMan@VPS(CentOS)にPostfixをインストールしメールサーバーを構築してみました。(Postfixの設定にはWebminを使用)
1.Postfixのインストール
yum install postfix
2.インストールが完了しているか確認
# rpm -qa postfix
postfix-2.6.6-2.2.el6_1.x86_64
3.main.cfの編集
# vi /etc/postfix/main.cf : # INTERNET HOST AND DOMAIN NAMES # # The myhostname parameter specifies the internet hostname of this # mail system. The default is to use the fully-qualified domain name # from gethostname(). $myhostname is used as a default value for many # other configuration parameters. # #myhostname = host.domain.tld #myhostname = virtual.domain.tld myhostname = mail.chamu.org ←サーバのホスト名 # The mydomain parameter specifies the local internet domain name. # The default is to use $myhostname minus the first component. # $mydomain is used as a default value for many other configuration # parameters. # #mydomain = domain.tld mydomain = chamu.org ←ドメイン名 # SENDING MAIL # # The myorigin parameter specifies the domain that locally-posted # mail appears to come from. The default is to append $myhostname, # which is fine for small sites. If you run a domain with multiple # machines, you should (1) change this to $mydomain and (2) set up # a domain-wide alias database that aliases each user to # user@that.users.mailhost. # # For the sake of consistency between sender and recipient addresses, # myorigin also specifies the default domain name that is appended # to recipient addresses that have no @domain part. # #myorigin = $myhostname #myorigin = $mydomain myorigin = $mydomain ←追加 # RECEIVING MAIL # The inet_interfaces parameter specifies the network interface # addresses that this mail system receives mail on. By default, # the software claims all active interfaces on the machine. The # parameter also controls delivery of mail to user@[ip.address]. # # See also the proxy_interfaces parameter, for network addresses that # are forwarded to us via a proxy or network address translator. # # Note: you need to stop/start Postfix when this parameter changes. # #inet_interfaces = all #inet_interfaces = $myhostname #inet_interfaces = $myhostname, localhost #inet_interfaces = localhost ←コメントアウト inet_interfaces = all ←追加 : # Specify a list of host or domain names, /file/name or type:table # patterns, separated by commas and/or whitespace. A /file/name # pattern is replaced by its contents; a type:table is matched when # a name matches a lookup key (the right-hand side is ignored). # Continue long lines by starting the next line with whitespace. # # See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS". # mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain ←追加 #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, # mail.$mydomain, www.$mydomain, ftp.$mydomain : DELIVERY TO MAILBOX # # The home_mailbox parameter specifies the optional pathname of a # mailbox file relative to a user's home directory. The default # mailbox file is /var/spool/mail/user or /var/mail/user. Specify # "Maildir/" for qmail-style delivery (the / is required). # #home_mailbox = Mailbox #home_mailbox = Maildir/ home_mailbox = Maildir/ ←追加 : # SHOW SOFTWARE VERSION OR NOT # # The smtpd_banner parameter specifies the text that follows the 220 # code in the SMTP server's greeting banner. Some people like to see # the mail version advertised. By default, Postfix shows no version. # # You MUST specify $myhostname at the start of the text. That is an # RFC requirement. Postfix itself does not care. # #smtpd_banner = $myhostname ESMTP $mail_name #smtpd_banner = $myhostname ESMTP $mail_name ($mail_version) smtpd_banner = $myhostname ESMTP unknown ←追加 : # SMTP Auth ←ファイルの最後に追加 smtpd_sasl_auth_enable = yes smtpd_sasl_local_domain = $myhostname smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination
4.master.cfの編集
587番ポートでもメール出来るようにするには、vi /etc/postfix/master.cfコマンドで
# vi /etc/postfix/master.cf #submission inet n - n - - smtpd # -o smtpd_enforce_tls=yes # -o smtpd_sasl_auth_enable=yes # -o smtpd_client_restrictions=permit_sasl_authenticated,reject
の部分を以下に変更
submission inet n - n - - smtpd # -o smtpd_enforce_tls=yes -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject
5.SASLによるSMTP認証用MD5パッケージとplainパッケージのインストール
yum install cyrus-sasl-md5 cyrus-sasl-plain
6.Postfixの起動
(1)sendmail停止
# /etc/rc.d/init.d/sendmail stop # chkconfig sendmail off
(2)メールサーバー切替え
# alternatives --config mta 2 プログラムがあり 'mta' を提供します。 選択 コマンド ----------------------------------------------- *+ 1 /usr/sbin/sendmail.sendmail 2 /usr/sbin/sendmail.postfix Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2
# service postfix start # chkconfig postfix on # chkconfig saslauthd on #chkconfig --list postfix postfix 0:off 1:off 2:on 3:on 4:on 5:on 6:off # chkconfig --list saslauthd saslauthd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
yum install dovecot
8.インストールが完了しているか確認
# rpm -qa dovecot
dovecot-2.0.9-5.el6.x86_64
9.dovecot.confを編集
vi /etc/dovecot/dovecot.conf : # Should each login be processed in it's own process (yes), or should one # login process be allowed to process multiple connections (no)? Yes is more # secure, espcially with SSL/TLS enabled. No is faster since there's no need # to create processes all the time. #login_process_per_connection = yes login_process_per_connection = no ←追加 : # See doc/wiki/Variables.txt for full list. Some examples: # # mail_location = maildir:~/Maildir # mail_location = mbox:~/mail:INBOX=/var/mail/%u # mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n # # <doc/wiki/MailLocation.txt> # #mail_location = mail_location = maildir:~/Maildir ←追加
10.Dovecotの起動・起動設定
chkconfig --list dovecot dovecot 0:off 1:off 2:off 3:off 4:off 5:off 6:off 自動起動が「of」なので # chkconfig dovecot on [root@dti-vps-srv30 ~]# chkconfig --list dovecot dovecot 0:off 1:off 2:on 3:on 4:on 5:on 6:off Dovecotの起動 # service dovecot start Dovecot Imap を起動中: [ OK ] # netstat -antup | egrep 'master|dovecot' tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN 23897/master tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 23897/master tcp 0 0 :::993 :::* LISTEN 24007/dovecot tcp 0 0 :::995 :::* LISTEN 24007/dovecot tcp 0 0 :::110 :::* LISTEN 24007/dovecot tcp 0 0 :::143 :::* LISTEN 24007/dovecot
4.Postfix および DovecotモジュールのWebminへの登録
「Webmin 設定」の「モジュールのリフレッシュ」により、インストールされたサーバに関するすべてのWebminモジュールを再確認し、Postfix および DovecotモジュールをWebminへ登録します。
5.Postfix の設定
Webminの「サーバ」→「Postfix の設定」→「一般オプション」画面で、以下の各項目を、各自のネットワーク環境に合わせて、下記内容などに変更。
設定する項目 | 設定内容 |
発信メールで使用するドメイン | 「ドメイン名を使用」をチェック |
メールを受信するドメイン | $myhostname, localhost.$mydomain, localhost, $mydomain |
メール受信用のネットワーク インターフェイス | 「すべて」をチェック |
このメール システムのインターネット ホスト名 | mail.chamu.org |
ローカル インターネット ドメイン名 | chamu.org |
ローカル ネットワーク | 183.181.10.26/32,28.178.88.0/24,127.0.0.0/8 |
Webminの「サーバ」→「Postfix の設定」→「ローカル配信」画面の
「ユーザ メールボックス ファイルのホーム相対パス名」の項目を「Maildir/」に変更。
Webminの「サーバ」→「Postfix の設定」→「SMTP サーバ オプション」画面の
「SMTP グリーティング バナー」の項目を「$myhostname ESMTP unknown」に
「宛先アドレスの制限」の項目を「permit_mynetworks permit_sasl_authenticated reject_unauth_destination」に変更。
Webminの「サーバ」→「Postfix の設定」→「SMTP 認証と暗号化」画面の
「SASL SMTP 認証を有効にしますか?」の項目を「はい」に変更。
5.Postfix の起動、終了
Webminの「サーバ」→「Postfix の設定」画面で、「Postfixを開始」ボタンをクリックすると、Postfixが起動します。Postfixの終了も同様。
なお、ServersMan@VPSでは認証デーモン、saslauthdが自動起動する設定なので、特に設定の必要はありません。
sshトンネル(ポートフォワード)を使ってリモートのMySQLにつなぐ
自宅のMacからServersMan@VPSに入ってるMySQL直接接続したいが、危険だからMySQLのポートなんか外部に開放したくないと言う時に。
SSHのポートフォワードを使って、自宅MacからリモートMySQLにお気軽接続。
3307はクライアントのMac側に張る仮想のMySQLポート番号。基本的に任意。
3306はサーバ、ServersMan@VPS側のMySQLポート番号。
1.自宅Macから、ServersMan@VPSにsshトンネルを張る。
ssh -fNL 3307:localhost:3306 admin@ServersManのアドレス -p ServersMan側のssh接続ポート番号
2.つなぎ方。
mysql -u root -p -h 127.0.0.1 -P 3307
3.自宅のMacからPythonでリモートのMySQLに接続してみる
これが便利なのって、自宅Macから、サーバー側のMySQLデータを直接メンテしたりなど出来るってことかな。
サーバーから自宅Macに、sshトンネルを逆に掘れば、サーバー側にMySQLを入れてなくても、サーバー側から自宅MacのMySQLに接続して、サーバー側からデータベースを切り離すってことも出来たりして。
テストデータの作成
mysql -u root -p -h 127.0.0.1 -P 3307 以下は、MySQLコンソールから use test; CREATE TABLE mef (c TEXT); INSERT INTO mef VALUES("今日の天気は晴れです。"); INSERT INTO mef VALUES("Unicode 正規化の機能は、プラグインとリンクしている ICU ライブラリで実装されています。"); select * from mef; +----------------------------------------------------------------------------------------+ | c | +----------------------------------------------------------------------------------------+ | 今日の天気は晴れです。 | | Unicode 正規化の機能は、プラグインとリンクしている ICU ライブラリで実装されています。 | +----------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)
自宅のMacからPythonでリモートのMySQLに接続してみる
python 以下はpythonコンソールから >>> import MySQLdb >>> conn = MySQLdb.connect(db='test', host='127.0.0.1', user='root', passwd='パスワード' port=3307) >>> cursor = conn.cursor() >>> cursor.execute( "SELECT * FROM mef ;" ) 2L >>> rows = cursor.fetchall() >>> print rows[0][0] 今日の天気は晴れです。 >>> print rows[1][0] Unicode 正規化の機能は、プラグインとリンクしている ICU ライブラリで実装されています。 >>>