OSDN Git Service

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