OSDN Git Service

Make bbs type little massive.
[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["submit"] = u"\u66f8\u304d\u8fbc\u3080".encode(
117             "cp932", "replace")
118
119         sigdic = {"on_submit_activate": self.on_submit_activate,
120                   "on_close_activate": self.on_close_activate}
121
122         self.widget_tree.signal_autoconnect(sigdic)
123
124         title = datfile.get_title_from_dat(self.bbs_type)
125         if title:
126             self.window.set_title(title)
127
128     def on_close_activate(self, widget):
129         self.window.destroy()
130
131     def on_submit_activate(self, widget):
132         name = self.entry_name.get_text()
133         mail = self.entry_mail.get_text()
134         msg = self.textbuffer.get_text(
135             self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter())
136
137         self.post_dict["FROM"] = name.encode("cp932", "replace")
138         self.post_dict["mail"] = mail.encode("cp932", "replace")
139         self.post_dict["MESSAGE"] = msg.encode("cp932", "replace")
140
141         self.post_dict = self.bbs_type.set_extra_post(self.post_dict)
142
143         self.do_submit()
144
145     def do_submit(self):
146         post_encoded = urllib.urlencode(self.post_dict)
147         print post_encoded
148
149         req = urllib2.Request("http://" + self.bbs_type.host + "/test/bbs.cgi",
150                               post_encoded)
151         req.add_header("Referer", self.uri)
152
153         res = opener.open(req)
154         self.on_response(res)
155
156     def on_response(self, response):
157         data = response.read()
158
159         p = ConfirmationHTMLParser()
160         p.feed(data.decode("cp932", "replace"))
161         p.close()
162
163         print data.decode("cp932")
164
165         window = gtk.Window()
166         if not p.complete:
167             window.set_default_size(500, 500)
168         textview = gtk.TextView()
169         textview.set_wrap_mode(gtk.WRAP_CHAR)
170         textview.set_editable(False)
171         buf = textview.get_buffer()
172         buf.insert(buf.get_end_iter(), p.message)
173
174         for input in p.inputs:
175             if "type" in input and input["type"] == "submit":
176                 button = gtk.Button(input["value"])
177                 button.connect("clicked",
178                                self.on_button_submit_clicked, p.inputs)
179                 anchor = buf.create_child_anchor(buf.get_end_iter())
180                 textview.add_child_at_anchor(button, anchor)
181                 break
182
183         window.add(textview)
184         window.show_all()
185
186         if p.complete:
187
188             def on_timeout(widget):
189                 widget.destroy()
190                 uri_opener.open_uri(self.bbs_type.get_thread_uri(), True)
191
192             gobject.timeout_add(2 * 1000, on_timeout, window)
193
194     def on_button_submit_clicked(self, widget, inputs=None):
195         widget.get_toplevel().destroy()
196         self.post_dict = {}
197         for input in inputs:
198             if "name" in input and "value" in input:
199                 name = input["name"]
200                 value = input["value"]
201                 self.post_dict[name] = value.encode("cp932", "replace")
202
203         self.do_submit()