OSDN Git Service

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