WORDPRESS + JQUERY AJAX + PYTHON + JSON で再度苦労してみた

WORDPRESS + JQUERY AJAX + PYTHON + JSON で再度苦労してみた

動機

WordPress + jquery ajax + Python + json で苦労してみた」は write-only なので、まぁ、ネタとして不十分で面白さは半分。入力がある、一般ケースで遊んでみた。

サンプルに使えそうなネタはお手持ちだのね

命名規則のための名前変形処理@Python和英混在文書の表記ゆれ統一のために unicodedata.normalizeな。

テキストボックスを入力に、で、変形結果を出力すれば良いね。

出来たのはこんなね。
命名規則のための名前変形処理@(PYTHON + JQUERY + JSON)

コードはこれだけ

まず、サーバで動作する、json を返す Python で書いた「cgi」:

simple_namemangler_cgi.py
  1 #! /usr/bin/python2.7
  2 # -*- coding: utf-8 -*-
  3 import re
  4 import unicodedata
  5 import sys
  6 
  7 
  8  
  9 def _normalize(src):
 10     def _repl(m):
 11         s = m.group(1)
 12         return {
 13             u'\u201d': '"',
 14             u'\u2019': "'",
 15             u'\u2018': "`",
 16             }.get(s, s)
 17     return unicodedata.normalize(
 18         'NFKC',
 19         re.sub(ur"([\u201d|\u2019|\u2018])", _repl, src)) 
 20 
 21  
 22 #
 23 #
 24 #
 25 def _split_into_words(s):
 26     result = []
 27     spl = re.split(r"[ _]", s)
 28     for w in spl:
 29         inner = \
 30             re.sub(
 31             r"([A-Z]+)([A-Z])([a-z0-9]+)",
 32             r"\1,\2\3",
 33             re.sub(r"([a-z0-9])([A-Z])", r"\1,\2", w)
 34             ).split(",")
 35         for i, ins in enumerate(inner):
 36             if not re.match(r"^[A-Z]+$", ins):
 37                 inner[i] = ins.lower()
 38         result.extend(inner)
 39     return result
 40  
 41  
 42 #
 43 #
 44 #
 45 class BaseNameMangler(object):
 46     def __init__(self, s):
 47         self._splitted = _split_into_words(s)
 48  
 49     def convert(self, dest_type="capWords"):
 50         """
 51         >>> c = BaseNameMangler("simpleHTTPServer")
 52         >>> c.convert("CapWords")
 53         'SimpleHTTPServer'
 54         >>> c.convert("capWords")
 55         'simpleHTTPServer'
 56         >>> c.convert("lower_underscore")
 57         'simple_HTTP_server'
 58         >>> c.convert("upper_underscore")
 59         'SIMPLE_HTTP_SERVER'
 60         >>> c.convert("CapWords_force")
 61         'SimpleHttpServer'
 62         >>> c.convert("capWords_force")
 63         'simpleHttpServer'
 64         >>> c.convert("lower_underscore_force")
 65         'simple_http_server'
 66         >>> c = BaseNameMangler("simple_HTTP_Server")
 67         >>> c.convert("CapWords")
 68         'SimpleHTTPServer'
 69         >>> c.convert("capWords")
 70         'simpleHTTPServer'
 71         >>> c.convert("lower_underscore")
 72         'simple_HTTP_server'
 73         >>> c.convert("upper_underscore")
 74         'SIMPLE_HTTP_SERVER'
 75         >>> c.convert("CapWords_force")
 76         'SimpleHttpServer'
 77         >>> c.convert("capWords_force")
 78         'simpleHttpServer'
 79         >>> c.convert("lower_underscore_force")
 80         'simple_http_server'
 81         >>> c = BaseNameMangler("HTTP_Server")
 82         >>> c.convert("CapWords")
 83         'HTTPServer'
 84         >>> c.convert("capWords")
 85         'HTTPServer'
 86         >>> c.convert("lower_underscore")
 87         'HTTP_server'
 88         >>> c.convert("upper_underscore")
 89         'HTTP_SERVER'
 90         >>> c.convert("CapWords_force")
 91         'HttpServer'
 92         >>> c.convert("capWords_force")
 93         'httpServer'
 94         >>> c.convert("lower_underscore_force")
 95         'http_server'
 96         """
 97         if dest_type == "CapWords":
 98             return "".join([
 99                     s.title() if s[0].islower() else s
100                     for s in self._splitted])
101         elif dest_type == "capWords":
102             return "".join([
103                     s.title() if i > 0 and s[0].islower() else s
104                     for i, s in enumerate(self._splitted)])
105         elif dest_type == "lower_underscore":
106             return "_".join(self._splitted)
107         elif dest_type == "upper_underscore":
108             return "_".join([
109                     s.upper()
110                     for s in self._splitted])
111         elif dest_type == "CapWords_force":
112             return "".join([
113                     s.title()
114                     for s in self._splitted])
115         elif dest_type == "capWords_force":
116             return "".join([
117                     s.title() if i > 0 else s.lower()
118                     for i, s in enumerate(self._splitted)])
119         elif dest_type == "lower_underscore_force":
120             return "_".join([
121                     s.lower()
122                     for s in self._splitted])
123  
124  
125  
126 # ----------------------------------------------------------------------
127 import json
128 
129 sys.stdout.write("Content-Type: application/json")
130  
131 sys.stdout.write("\n")
132 sys.stdout.write("\n")
133 
134 form = json.loads(sys.stdin.read())
135 src = form["src"]
136 typ = form["type"]
137 c = BaseNameMangler(_normalize(src))
138 
139 result = {}
140 result['success'] = True
141 result['dst'] = c.convert(typ)
142 
143 sys.stdout.write(json.dumps(result, indent=4))
144 sys.stdout.write("\n")
145 # ----------------------------------------------------------------------

「#! /usr/bin/python2.7」はレンタルサーバの関係で。

で、Wordpress からは、記事にショートコードで

1 [simple_namemangler_js]

と書くだけでいいようにしたかったのと、あとは
SkyScanner
で経験したやり方、これしか今 WordPress に script を貼り付ける方法を知らない(いわゆるバカの一つ覚え)ということもあり、functions.php に以下を追加:

functions.phpに追加
 1 /**
 2  *
 3  */
 4 function simple_namemangler_js_handler($atts, $content=null) {
 5 $str=<<<eot
 6     <style type="text/css">
 7     .mangled {
 8         background-color: #fcfcff;
 9         color: #000055;
10         font-size: x-large;
11         font-style: bold;
12         text-align: center;
13         margin: 0.3em;
14         padding: 1.2em;
15         border-style: solid;
16         border-width: 1px 1px 1px 1px;
17         border-color: #0000cc; 
18     }
19     </style>
20     <script type="text/javascript" src="/site-hhs/wp-includes/js/jquery/jquery.js"></script>
21     <script type="text/javascript">
22     jQuery(function($) {
23         function do_mangle() {
24             $.ajax({
25                 url: "/cgi-bin/simple_namemangler_cgi.py",
26                 type: "post",
27                 data: JSON.stringify({'src': $('#src').val(), 'type': $('#type').val()}),
28                 dataType: "json",
29                 success: function(response) {
30                     $("#dst").html(response.dst);
31                 },
32                 error: function(xhr, status, error) {
33                     //alert(xhr.responseText);
34                 }
35             });
36         };
37 
38         $(document).ready(function() {
39             do_mangle();
40             $('#src').on('change', function() {do_mangle()});
41             $('#type').on('change', function() {do_mangle()});
42         });
43     });
44     </script>
45     <form>
46     <input type="text" id="src" name="src" size="40" value="Python HTTP jquery ajax json">
47     <select name="type" id="type">
48         <option>CapWords</option>
49         <option>CapWords_force</option>
50         <option>capWords</option>
51         <option>capWords_force</option>
52         <option>lower_underscore</option>
53         <option>lower_underscore_force</option>
54         <option>upper_underscore</option>
55     </select>
56     </form>
57     <div id="dst" class="mangled"></div>
58 eot;
59     return $str;
60 }
61 add_shortcode('simple_namemangler_js', 'simple_namemangler_js_handler');

一度成功したくらいじゃ、ハマらなくなるわけじゃないね

所要時間は2時間くらいだもん、大した苦労でもないけれどね、でも10分で仕上げる気だったんだ、随分な苦労だわな。

以下2つの行き来:

 1     jQuery(function($) {
 2         function do_mangle() {
 3             $.ajax({
 4                 url: "/cgi-bin/simple_namemangler_cgi.py",
 5                 type: "post",
 6                 // ___ここ↓
 7                 data: JSON.stringify({'src': $('#src').val(), 'type': $('#type').val()}),
 8                 // ___ここ↑
 9                 dataType: "json",
10                 success: function(response) {
11                     $("#dst").html(response.dst);
12                 },
13                 error: function(xhr, status, error) {
14                     //alert(xhr.responseText);
15                 }
16             });
17         };
1 form = json.loads(sys.stdin.read())

なのね、核心は。というかここだけ。「JSON.stringify」部分はPost JSON to Python CGI | Stack Overflowを参考にした。

あと下らない ImportError (import sys 忘れた) とかもあったけどね。

2015-06-19追記

WP Category Tag Cloud がぶっ壊れたのと同じ原因で色んな道具が壊れたをご覧ください。