OSDN Git Service

b06ea913c8d9c423c2d27b02383c99da8bce3811
[fukui-no-namari/fukui-no-namari.git] / src / FukuiNoNamari / submit_window.py
1 # Copyright (C) 2006 by Aiwota Programmer
2 # aiwotaprog@tetteke.tk
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 import pygtk
19 pygtk.require('2.0')
20 import gtk
21 import gtk.glade
22 import gobject
23 import codecs
24 import urllib
25 import urllib2
26 import cookielib
27 import os.path
28
29 from BbsType import bbs_type_judge_uri
30 from BbsType import bbs_type_exception
31 from HTMLParserEx import HTMLParserEx
32 import datfile
33 import uri_opener
34 from http_sub import HTTPDebugHandler
35
36 GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
37                          "..", "data")
38 GLADE_FILENAME = "submit_window.glade"
39
40 cookie_jar = cookielib.CookieJar()
41 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar),
42                               HTTPDebugHandler)
43
44 def open(uri):
45     if not uri:
46         raise ValueError, "parameter must not be empty"
47
48     WinWrap(uri)
49
50
51 class ConfirmationHTMLParser(HTMLParserEx):
52
53     def __init__(self):
54         HTMLParserEx.__init__(self)
55         self.message = ""
56         self.inputs = []
57         self.complete = False
58
59     def handle_starttag(self, tag, attr):
60         if tag == "br":
61             self.message += "\n"
62         elif tag == "input":
63             self.inputs.append(dict(attr))
64         elif tag == "meta":
65             attr_dict = dict(attr)
66             if "http-equiv" in attr_dict \
67                and attr_dict["http-equiv"] == "refresh":
68                 self.complete = True
69
70     def handle_endtag(self, tag):
71         pass
72
73     def handle_comment(self, comment):
74         print comment.strip()
75
76     def handle_data(self, data):
77         self.message += data
78
79     def handle_charref(self, ref):
80         data = None
81         try:
82             data = unichr(int(ref))
83         except:
84             data = "&#"+ref+";"
85         self.message += data
86
87     def handle_entityref(self, name):
88         if name in htmlentitydefs.name2codepoint:
89             codepoint = htmlentitydefs.name2codepoint[name]
90             self.message += unichr(codepoint)
91         else:
92             self.message += "&"+name+";"
93
94
95 class WinWrap:
96
97     def __init__(self, uri):
98         self.uri = uri
99         self.bbs_type = bbs_type_judge_uri.get_type(uri)
100         if not self.bbs_type.is_thread():
101             raise bbs_type_exception.BbsTypeError, \
102                   "the uri does not represent thread: " + uri
103
104         glade_path = os.path.join(GLADE_DIR, GLADE_FILENAME)
105         self.widget_tree = gtk.glade.XML(glade_path)
106         self.window = self.widget_tree.get_widget("submit_window")
107         self.entry_name = self.widget_tree.get_widget("entry_name")
108         self.entry_mail = self.widget_tree.get_widget("entry_mail")
109         self.textbuffer = self.widget_tree.get_widget("textview").get_buffer()
110
111         sigdic = {"on_submit_activate": self.on_submit_activate,
112                   "on_close_activate": self.on_close_activate}
113
114         self.widget_tree.signal_autoconnect(sigdic)
115
116         title = datfile.get_title_from_dat(self.bbs_type)
117         if title:
118             self.window.set_title(title)
119
120     def on_close_activate(self, widget):
121         self.window.destroy()
122
123     def on_submit_activate(self, widget):
124         name = self.entry_name.get_text()
125         mail = self.entry_mail.get_text()
126         msg = self.textbuffer.get_text(
127             self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter())
128
129         self.post_dict = self.bbs_type.build_post_dict(name, mail, msg)
130         self.post_dict = self.bbs_type.set_extra_post(self.post_dict)
131
132         self.do_submit()
133
134     def do_submit(self):
135         for name, value in self.post_dict.iteritems():
136             print "%s: %s" \
137                   % (name, value.decode(self.bbs_type.encoding, "replace"))
138         post_encoded = urllib.urlencode(self.post_dict)
139
140         req = urllib2.Request(self.bbs_type.get_post_uri(), post_encoded)
141         req.add_header("Referer", self.uri)
142
143         res = opener.open(req)
144         self.on_response(res)
145
146     def on_response(self, response):
147         data = response.read()
148         info = response.info()
149         if "Content-Type" in info:
150             import re
151             match = re.search(
152                 "charset=(?P<charset>[a-zA-Z0-9_\-]+)", info["Content-Type"])
153             if match:
154                 charset = match.group("charset").lower()
155
156         if charset in ("x-sjis", "x_sjis", "sjis", "shiftjis", "shift-jis",
157                        "shift_jis", "s-jis", "s_jis"):
158             encoding = "cp932"
159         elif charset in ("euc-jp", "euc_jp", "eucjp"):
160             encoding = "euc-jp"
161
162         if encoding:
163             data = data.decode(encoding, "replace")
164         p = ConfirmationHTMLParser()
165         p.feed(data)
166         p.close()
167
168         print data
169
170         window = gtk.Window()
171         if not p.complete:
172             window.set_default_size(500, 500)
173         textview = gtk.TextView()
174         textview.set_wrap_mode(gtk.WRAP_CHAR)
175         textview.set_editable(False)
176         buf = textview.get_buffer()
177         buf.insert(buf.get_end_iter(), p.message)
178
179         for input in p.inputs:
180             if "type" in input and input["type"] == "submit":
181                 button = gtk.Button(input["value"])
182                 button.connect("clicked",
183                                lambda widget: self.on_button_submit_clicked(
184                     widget, p.inputs, encoding))
185                 anchor = buf.create_child_anchor(buf.get_end_iter())
186                 textview.add_child_at_anchor(button, anchor)
187                 button.grab_focus()
188                 break
189
190         window.add(textview)
191         window.show_all()
192
193         if p.complete:
194
195             def on_timeout(widget):
196                 widget.destroy()
197                 uri_opener.open_uri(self.bbs_type.get_thread_uri(), True)
198
199             gobject.timeout_add(2 * 1000, on_timeout, window)
200
201     def on_button_submit_clicked(self, widget, inputs, encoding):
202         widget.get_toplevel().destroy()
203         self.post_dict = {}
204         for input in inputs:
205             if "name" in input and "value" in input:
206                 name = input["name"]
207                 value = input["value"]
208                 if encoding:
209                     value = value.encode(encoding, "replace")
210                 self.post_dict[name] = value
211
212         self.do_submit()