OSDN Git Service

Add HTTP header output.
[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 import time
29
30 from BbsType import bbs_type_judge_uri
31 from BbsType import bbs_type_exception
32 from HTMLParserEx import HTMLParserEx
33 import datfile
34 import uri_opener
35 from http_sub import HTTPDebugHandler
36
37 GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
38                          "..", "data")
39 GLADE_FILENAME = "submit_window.glade"
40
41 cookie_jar = cookielib.CookieJar()
42 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar),
43                               HTTPDebugHandler)
44
45 def open(uri):
46     if not uri:
47         raise ValueError, "parameter must not be empty"
48
49     WinWrap(uri)
50
51
52 class ConfirmationHTMLParser(HTMLParserEx):
53
54     def __init__(self):
55         HTMLParserEx.__init__(self)
56         self.message = ""
57         self.inputs = []
58         self.complete = False
59
60     def handle_starttag(self, tag, attr):
61         if tag == "br":
62             self.message += "\n"
63         elif tag == "input":
64             self.inputs.append(dict(attr))
65         elif tag == "meta":
66             attr_dict = dict(attr)
67             if "http-equiv" in attr_dict \
68                and attr_dict["http-equiv"] == "refresh":
69                 self.complete = True
70
71     def handle_endtag(self, tag):
72         pass
73
74     def handle_comment(self, comment):
75         print comment.strip()
76
77     def handle_data(self, data):
78         self.message += data
79
80     def handle_charref(self, ref):
81         data = None
82         try:
83             data = unichr(int(ref))
84         except:
85             data = "&#"+ref+";"
86         self.message += data
87
88     def handle_entityref(self, name):
89         if name in htmlentitydefs.name2codepoint:
90             codepoint = htmlentitydefs.name2codepoint[name]
91             self.message += unichr(codepoint)
92         else:
93             self.message += "&"+name+";"
94
95
96 class WinWrap:
97
98     def __init__(self, uri):
99         self.uri = uri
100         self.bbs_type = bbs_type_judge_uri.get_type(uri)
101         if not self.bbs_type.is_thread():
102             raise bbs_type_exception.BbsTypeError, \
103                   "the uri does not represent thread: " + uri
104
105         glade_path = os.path.join(GLADE_DIR, GLADE_FILENAME)
106         self.widget_tree = gtk.glade.XML(glade_path)
107         self.window = self.widget_tree.get_widget("submit_window")
108         self.entry_name = self.widget_tree.get_widget("entry_name")
109         self.entry_mail = self.widget_tree.get_widget("entry_mail")
110         self.textbuffer = self.widget_tree.get_widget("textview").get_buffer()
111
112         self.post_dict = {}
113         self.post_dict["bbs"] = self.bbs_type.board
114         self.post_dict["key"] = self.bbs_type.thread
115         self.post_dict["time"] = str(int(time.time()))
116         self.post_dict["hana"] = "mogera"
117         self.post_dict["submit"] = u"\u66f8\u304d\u8fbc\u3080".encode(
118             "cp932", "replace")
119
120         sigdic = {"on_submit_activate": self.on_submit_activate,
121                   "on_close_activate": self.on_close_activate}
122
123         self.widget_tree.signal_autoconnect(sigdic)
124
125         title = datfile.get_title_from_dat(
126             self.bbs_type.bbs_type, self.bbs_type.board, self.bbs_type.thread)
127         if title:
128             self.window.set_title(title)
129
130     def on_close_activate(self, widget):
131         self.window.destroy()
132
133     def on_submit_activate(self, widget):
134         name = self.entry_name.get_text()
135         if self.bbs_type.bbs_type == "2ch" \
136                and self.bbs_type.board == "morningcoffee" \
137                and not name:
138             name = u'\u540d\u7121\u3057\u52df\u96c6\u4e2d\u3002\u3002\u3002'
139         mail = self.entry_mail.get_text()
140         msg = self.textbuffer.get_text(
141             self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter())
142
143         self.post_dict["FROM"] = name.encode("cp932", "replace")
144         self.post_dict["mail"] = mail.encode("cp932", "replace")
145         self.post_dict["MESSAGE"] = msg.encode("cp932", "replace")
146
147         self.do_submit()
148
149     def do_submit(self):
150         post_encoded = urllib.urlencode(self.post_dict)
151         print post_encoded
152
153         req = urllib2.Request("http://" + self.bbs_type.host + "/test/bbs.cgi",
154                               post_encoded)
155         req.add_header("Referer", self.uri)
156
157         res = opener.open(req)
158         self.on_response(res)
159
160     def on_response(self, response):
161         data = response.read()
162
163         p = ConfirmationHTMLParser()
164         p.feed(data.decode("cp932", "replace"))
165         p.close()
166
167         print data.decode("cp932")
168
169         window = gtk.Window()
170         if not p.complete:
171             window.set_default_size(500, 500)
172         textview = gtk.TextView()
173         textview.set_wrap_mode(gtk.WRAP_CHAR)
174         textview.set_editable(False)
175         buf = textview.get_buffer()
176         buf.insert(buf.get_end_iter(), p.message)
177
178         for input in p.inputs:
179             if "type" in input and input["type"] == "submit":
180                 button = gtk.Button(input["value"])
181                 button.connect("clicked",
182                                self.on_button_submit_clicked, p.inputs)
183                 anchor = buf.create_child_anchor(buf.get_end_iter())
184                 textview.add_child_at_anchor(button, anchor)
185                 break
186
187         window.add(textview)
188         window.show_all()
189
190         if p.complete:
191
192             def on_timeout(widget):
193                 widget.destroy()
194                 uri_opener.open_uri(self.bbs_type.get_thread_uri(), True)
195
196             gobject.timeout_add(2 * 1000, on_timeout, window)
197
198     def on_button_submit_clicked(self, widget, inputs=None):
199         widget.get_toplevel().destroy()
200         self.post_dict = {}
201         for input in inputs:
202             if "name" in input and "value" in input:
203                 name = input["name"]
204                 value = input["value"]
205                 self.post_dict[name] = value.encode("cp932", "replace")
206
207         self.do_submit()