前回、
楽曲リストの校正
前回紹介したように、
kakasiは、
この変換方法はシンプルではあるものの、
$ echo '中島みゆき' | kakasi -JH なかしまみゆき
この誤変換はkakasiが使っているデータベースに
この問題は、
そのため人名やグループ名のような固有名詞にはkakasiを使わず、
1 # -*- coding: euc-jp -*-;
2
3 def set_namedict():
4 namedict = {
5 'ANN':'あん',
6 'ASKA':'あすか',
7 "B'Z":'びーず',
8 'BE-B':'びーび',
...
110 '梶芽衣子':'かじめいこ',
111 '米米CLUB':'こめこめくらぶ',
112 '千昌夫':'せんまさお',
113 }
114
"ANN"や"ASKA"といった英語表記の歌手名にはそれぞれひらがなの読みを対応させると共に、
やっていることは簡単で、
そして、
50 singer2 = singer.upper()
51
52 if namedict.has_key(singer2):
53 singer_yomi = namedict[singer2]
54 else:
55 singer_yomi = to_hiragana(singer2)
なお、
目につくアルファベット表記や誤変換をnamedict{}に登録してはスクリプトを再実行する、
1-1-01 | 愛しつづけるボレロ | あいしつづけるぼれろ | 五木ひろし | いつきひろし | 阿久悠 | 筒美京平 |
1-1-02 | 会津の小鉄 | あいづのこてつ | 京山幸枝若 | きょうやまこうしわか | 松島一夫 | 和田香苗 |
1-1-03 | 勘太郎月夜唄 | かんたろうつきようた | 小畑実 | おばたみのる | 佐伯孝夫 | 清水保雄 |
1-1-04 | 青葉城恋唄 | あおばじょうこいうた | さとう宗幸 | さとうむねゆき | 星間船一 | さとうむねゆき
...
歌手名は複数回出てくる可能性があるのでスクリプトレベルで対応した方がいいものの、
...
8175-2-01 | 名もなき詩(うた) | めいもなきし(うた) | Mr.Children | みすたーちるどれん | 桜井和寿 | 桜井和寿
8175-2-02 | FOREVER | FOREVER | 岡本真夜 | おかもとまよ | 岡本真夜 | 岡本真夜
8175-2-02 | river | river | CHAGE&ASKA | ちゃげあんどあすか | 飛鳥涼 | 飛鳥涼
8175-2-04 | 幸せになりたい | しあわせになりたい | 内田有紀 | うちだゆき | 広瀬香美 | 広瀬香美
...
「ああ、
データベースの構築
ひらがな読みを付けた楽曲リストの修正を一通り終えてから、
1 # -*- coding: euc-jp -*-;
2
3 import sqlite3, os, sys
4
5 def init_db(dbname):
6 conn = sqlite3.connect(dbname)
7 conn.isolation_level = None
8 cursor = conn.cursor()
9 cursor.execute('''create table titles
10 (id text, title text, title_yomi text, singer text, singer_yomi text, songwriter, composer)''')
11 return conn
12
13 def insert_db(cursor, t):
14 try:
15 # print "inserting ", t
16 cursor.execute('insert into titles values(?, ?, ?, ?, ?, ?, ?)', t)
17 except sqlite3.Error, e:
18 print "An error occurred:", e.args[0]
19
20 def main():
21 dbname = 'karaoke-titles.sql'
22
23 if os.path.isfile(dbname) == False:
24 connection = init_db(dbname)
25 else:
26 connection = sqlite3.connect(dbname)
27 cursor = connection.cursor()
28
29 datafile = 'karaoke-yomi.dat'
30 if os.path.isfile(datafile):
31 f = open(datafile, 'r')
32 lines = f.readlines()
33 for line in lines:
34 dt = line.split(" | ")
35 if len(dt) != 7:
36 print("Data count {} error at {}:".format(len(dt), line))
37 continue
38
39 id = dt[0]
40 title = dt[1].decode('euc-jp')
41 title_yomi = dt[2].decode('euc-jp')
42 singer = dt[3].decode('euc-jp')
43 singer_yomi = dt[4].decode('euc-jp')
44 songwriter = dt[5].decode('euc-jp')
45 composer = dt[6].decode('euc-jp')
46
47 insert_db(cursor, (id, title, title_yomi, singer, singer_yomi, songwriter, composer))
48
49 if __name__ == "__main__":
50 main()
このスクリプトでは、
スクリプトを使って作成したデータベースを確認するために、
$ sqlite3 karaoke-titles.sql SQLite version 3.8.5 2014-06-04 14:06:34 Enter ".help" for usage hints. sqlite> select id,title,singer from titles where singer_yomi like "なか%"; 14-2-11|かもめはかもめ |中島みゆき 20-2-02|秋冬 |中山丈二 23-2-06|悪女 |中島みゆき 26-1-09|ひとり |中島みゆき 305-2-10|十戒(1984) |中森明菜 ... 8222-1-04|鳶 |中村美律子 9-2-03|船頭小唄 |中山歌子
ざっと見、
検索システムの構築
今回考えているお家通信カラオケシステムは、
前回紹介したセガカラの検索画面にならって、

見ての通りのシンプルな画面構成で、
1 <!DOCTYPE html>
2 <HTML>
3 <head>
4 <meta charset="UTF-8">
5 <title>kraoke keyword search</title>
6 </head>
7 <BODY>
8
9 <H2>フリーワード検索</H2>
10
11 検索キーワードを入れてください.
12
13 <form action="search.php">
14 <p>
15 <input type="radio" name="kind" value="title_yomi" checked> タイトル
16 <input type="radio" name="kind" value="singer_yomi"> 歌手名
17 </p>
18 <p>
19 キーワード
20 <input type="text" name="key">
21 </p>
22 </form>
23
24 <H2>タイトル検索</H2>
25
26 曲のタイトルの一文字目を指定してください.
27
28 <table border>
29 <tr> <td>
30 <table border>
31 <?php
32 $kana = array( ['あ', 'い', 'う', 'え', 'お'],
33 ['か', 'き', 'く', 'け', 'こ'],
34 ['さ', 'し', 'す', 'せ', 'そ'],
35 ['た', 'ち', 'つ', 'て', 'と'],
36 ['な', 'に', 'ぬ', 'ね', 'の'],
37 ['は', 'ひ', 'ふ', 'へ', 'ほ'],
38 ['ま', 'み', 'む', 'め', 'も'],
39 ['や', 'ゆ', 'よ'],
40 ['ら', 'り', 'る', 'れ', 'ろ'],
41 ['わ', 'ん']
42 );
43 for($i = 0; $i < 10; $i++) {
44 echo "<tr> ";
45 foreach ($kana[$i] as $k) {
46 printf("<td> <a href=\"search.php?key=%s&kind=title_yomi\"> %s <a> </td>\n", $k, $k);
47 }
48 echo "</tr>\n";
49 }
50 ?>
51 </table>
52 </td>
53 <td>
54 <table border>
55 <?php
56 $kana2 = array(['が', 'ぎ', 'ぐ', 'げ', 'ご'],
57 ['ざ', 'じ', 'ず', 'ぜ', 'ぞ'],
58 ['だ', 'ぢ', 'づ', 'で', 'ど'],
59 ['ば', 'び', 'ぶ', 'べ', 'ぼ'],
60 ['ぱ', 'ぴ', 'ぷ', 'ぺ', 'ぽ']
61 );
62
63 for($i = 0; $i < 5; $i++) {
64 echo "<tr> ";
65 foreach ($kana2[$i] as $k) {
66 printf("<td> <a href=\"search.php?key=%s&kind=title_yomi\"> %s <a> </td>\n", $k, $k);
67 }
68 echo "</tr>\n";
69 }
70 for($i = 5; $i < 10; $i++) {
71 echo "<tr> <td colspan=5> <br> </td> </tr>\n ";
72 }
73 ?>
74 </table>
75 </td>
76 </tr>
77 </table>
...
このページではタイトルの読みから引くか歌手名の読みから引くかをkindという引数に、
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>karaoke keyword search</title>
6 </head>
7 <body>
8
9 <?php
10 function DBconnect($name) {
11 $dbname = sprintf("sqlite:%s", $name);
12 try {
13 $db = new PDO($dbname);
14 }
15 catch (PDOException $e) {
16 exit("cannot connect to DB".$e->getMessage());
17 }
18 return $db;
19 }
20
21 function query_db($db, $kind, $key) {
22 $sql = sprintf('select id,title,singer from titles where %s like "%s%%" order by %s', $kind, $key, $kind);
23 foreach ($db->query($sql) as $line) {
24 $item = array(
25 "id" => trim($line['id']),
26 "title" => $line['title'],
27 "singer" => $line['singer']
28 );
29 $results[] = $item;
30 }
31 return $results;
32 }
33
34 $dbname = './karaoke-titles.sql';
35 $kind = $_GET['kind'];
36 $key = $_GET['key'];
37
38 echo "kind:$kind <br>";
39 echo "key:$key <br>";
40
41 $db = DBconnect("./karaoke-titles.sql");
42 $res = query_db($db, $kind, $key);
43
44 foreach ($res as $line) {
45 printf("<a href=\"play.php?id=%s\">%s (%s)</a><br>\n", $line['id'], $line['title'], $line['singer']);
46 }
47
48 ?>
10行目からのDBconnect()関数でSQLite3データベースに接続し、
select id,title,singer from titles where singer_yomi like "なか%" order by singer_yomi
のようなSQL文を作ってデータベースを検索し、

それぞれの検索結果には、

ちなみに動画ファイルを再生するplay.
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>karaoke playback</title>
6 </head>
7 <body>
8
9 <?php
10 $id = $_GET['id'];
11 $file = "./MP4/".$id.".mp4";
12 echo "file: $file";
13 ?>
14
15 <video autoplay controls>
16 <?php
17 printf("<source src=\"%s\">", $file);
18 ?>
19 </video>
20
21 </body>
22 </html>
当初は、結構な規模が必要かな、
今回、
"Forever"を
いっぽう、