1 # Copyright (C) 2006 by Aiwota Programmer
2 # aiwotaprog@tetteke.tk
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.
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.
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
36 GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
38 GLADE_FILENAME = "thread_window.glade"
40 def open_thread(bbs, board, thread):
41 if not bbs or not board or not thread:
42 raise ValueError, "parameter must not be empty"
44 key = "/" + bbs + "/" + board + "/" + thread
45 window = windowlist.get_window(key)
51 win_wrap = WinWrap(bbs, board, thread)
52 windowlist.window_created(key, win_wrap.window)
57 def __init__(self, bbs, board, thread):
65 glade_path = os.path.join(GLADE_DIR, GLADE_FILENAME)
66 self.widget_tree = gtk.glade.XML(glade_path)
67 self.window = self.widget_tree.get_widget("thread_window")
68 self.textview = self.widget_tree.get_widget("textview")
69 self.textbuffer = self.textview.get_buffer()
70 self.enditer = self.textbuffer.get_end_iter()
71 self.boldtag = self.textbuffer.create_tag(weight=pango.WEIGHT_BOLD)
72 self.leftmargintag = self.textbuffer.create_tag()
73 self.leftmargintag.set_property("left-margin", 20)
75 sigdic = {"on_toolbutton_refresh_clicked": self.update,
76 "on_refresh_activate": self.update,
77 "on_close_activate": self.on_close_activate,
78 "on_quit_activate": self.on_quit_activate,
79 "on_show_board_activate": self.on_show_board_activate,
80 "on_show_board_list_activate":
81 self.on_show_board_list_activate,
82 "on_thread_window_destroy": self.on_thread_window_destroy}
83 self.widget_tree.signal_autoconnect(sigdic)
87 def on_close_activate(self, widget):
90 def on_thread_window_destroy(self, widget):
93 def on_quit_activate(self, widget):
96 def on_show_board_activate(self, widget):
97 board_window.open_board(self.bbs, self.board)
99 def on_show_board_list_activate(self, widget):
100 brdlist_window.open_brdlist(self.bbs)
102 def http_get_dat(self, on_get_res):
103 datfile_url = misc.get_thread_dat_url(self.bbs, self.board, self.thread)
105 idx_dic = idxfile.load_idx(self.bbs, self.board, self.thread)
106 lastmod = idx_dic["lastModified"]
107 etag = idx_dic["etag"]
109 req = urllib2.Request(datfile_url)
111 req.add_header("Range", "bytes=" + str(self.size) + "-")
113 req.add_header("If-Modified-Since", lastmod)
115 req.add_header("If-None-Match", etag)
118 res = urllib2.urlopen(req)
122 line = res.readline()
123 maybe_incomplete = False
125 if not line.endswith("\n"):
126 maybe_incomplete = True
127 print "does not end with \\n. maybe incomplete"
130 line = res.readline()
138 if "Last-Modified" in headers:
139 lastmod = headers["Last-Modified"]
140 if "ETag" in headers:
141 etag = headers["Etag"]
145 self.title = datfile.get_title_from_dat(
146 self.bbs, self.board, self.thread)
148 self.window.set_title(self.title)
150 idx_dic = {"title": self.title, "lineCount": self.num,
151 "lastModified": lastmod, "etag": etag}
152 idxfile.save_idx(self.bbs, self.board, self.thread, idx_dic)
154 def update(self, widget=None):
155 line_count = datfile.get_dat_line_count(
156 self.bbs, self.board, self.thread)
158 if line_count > self.num:
159 datfile.load_dat_partly(
160 self.bbs, self.board, self.thread,
161 self.append_rawres_to_buffer, self.num+1)
163 dat_path = misc.get_thread_dat_path(self.bbs, self.board, self.thread)
164 dat_file = file(dat_path, "a+")
166 def save_line_and_append_to_buffer(line):
167 dat_file.seek(self.size)
169 self.append_rawres_to_buffer(line)
171 self.http_get_dat(save_line_and_append_to_buffer)
178 self.title = datfile.get_title_from_dat(
179 self.bbs, self.board, self.thread)
181 self.window.set_title(self.title)
183 datfile.load_dat(self.bbs, self.board, self.thread,
184 self.append_rawres_to_buffer)
185 self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0)
188 def append_rawres_to_buffer(self, line):
189 self.size += len(line)
192 h = lambda name,mail,date,msg: self.reselems_to_buffer(
193 self.num, name, mail, date, msg)
195 datfile.split_line_to_elems(line.decode("cp932", "replace"), h)
197 def reselems_to_buffer(self, num, name, mail, date, msg):
199 self.textbuffer.insert(self.enditer, str(num) + " ")
202 p = barehtmlparser.BareHTMLParser(self.untiedata_to_buffer)
203 p.feed("<b>" + name + "</b>")
207 self.textbuffer.insert(self.enditer, "[" + mail + "]")
212 self.textbuffer.insert(self.enditer, "\n")
215 p.reset_func(self.untiedata_to_buffer_with_leftmargin)
219 self.textbuffer.insert(self.enditer, "\n\n")
221 def untiedata_to_buffer(self, data, bold, href):
223 self.textbuffer.insert_with_tags(self.enditer, data, self.boldtag)
225 self.textbuffer.insert(self.enditer, data)
227 def untiedata_to_buffer_with_leftmargin(self, data, bold, href):
229 self.textbuffer.insert_with_tags(self.enditer, data,
230 self.boldtag, self.leftmargintag)
232 self.textbuffer.insert_with_tags(self.enditer, data,