OSDN Git Service

134e2222706389790b7eb170397b8a50b3c7f91e
[fukui-no-namari/fukui-no-namari.git] / src / Hage1 / thread_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 os.path
23 import codecs
24 import re
25 import pango
26 import urllib2
27
28 import misc
29 import datfile
30 import barehtmlparser
31 import idxfile
32
33 GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
34                          "..", "data")
35 GLADE_FILENAME = "thread_window.glade"
36
37
38 class WinWrap:
39
40     def __init__(self, bbs, board, thread):
41         self.bbs = bbs
42         self.board = board
43         self.thread = thread
44         self.size = 0
45         self.num = 0
46         self.title = None
47
48         glade_path = os.path.join(GLADE_DIR, GLADE_FILENAME)
49         self.widget_tree = gtk.glade.XML(glade_path)
50         self.window = self.widget_tree.get_widget("thread_window")
51         self.textview = self.widget_tree.get_widget("textview")
52         self.textbuffer = self.textview.get_buffer()
53         self.enditer = self.textbuffer.get_end_iter()
54         self.boldtag = self.textbuffer.create_tag(weight=pango.WEIGHT_BOLD)
55         self.leftmargintag = self.textbuffer.create_tag()
56         self.leftmargintag.set_property("left-margin", 20)
57
58         sigdic = {"on_toolbutton_refresh_clicked": self.update,
59                   "on_refresh_activate": self.update,
60                   "on_close_activate": self.on_close_activate,
61                   "on_quit_activate": self.on_quit_activate,
62                   "on_thread_window_destroy": self.on_thread_window_destroy}
63         self.widget_tree.signal_autoconnect(sigdic)
64
65         self.load_dat()
66
67     def on_close_activate(self, widget):
68         self.window.destroy()
69
70     def on_thread_window_destroy(self, widget):
71         -1
72
73     def on_quit_activate(self, widget):
74         gtk.main_quit()
75
76     def http_get_dat(self, on_get_res):
77         datfile_url = misc.get_thread_dat_url(self.bbs, self.board, self.thread)
78
79         idx_dic = idxfile.load_idx(self.bbs, self.board, self.thread)
80         lastmod = idx_dic["lastModified"]
81         etag = idx_dic["etag"]
82
83         req = urllib2.Request(datfile_url)
84         if self.size > 0:
85             req.add_header("Range", "bytes=" + str(self.size) + "-")
86         if lastmod:
87             req.add_header("If-Modified-Since", lastmod)
88         if etag:
89             req.add_header("If-None-Match", etag)
90         print req.headers
91
92         res = urllib2.urlopen(req)
93         headers = res.info()
94         print headers
95
96         line = res.readline()
97         maybe_incomplete = False
98         while line:
99             if not line.endswith("\n"):
100                 maybe_incomplete = True
101                 print "does not end with \\n. maybe incomplete"
102                 break
103             on_get_res(line)
104             line = res.readline()
105
106         res.close()
107
108         if maybe_incomplete:
109             lastmod = None
110             etag = None
111         else:
112             if "Last-Modified" in headers:
113                 lastmod = headers["Last-Modified"]
114             if "ETag" in headers:
115                 etag = headers["Etag"]
116
117         if self.num > 0:
118             # save idx
119             idx_dic = {"title": self.title, "lineCount": self.num,
120                    "lastModified": lastmod, "etag": etag}
121             idxfile.save_idx(self.bbs, self.board, self.thread, idx_dic)
122
123     def update(self, widget=None):
124         line_count = datfile.get_dat_line_count(
125             self.bbs, self.board, self.thread)
126
127         if line_count > self.num:
128             datfile.load_dat_partly(
129                 self.bbs, self.board, self.thread,
130                 self.append_rawres_to_buffer, self.num+1)
131
132         dat_path = misc.get_thread_dat_path(self.bbs, self.board, self.thread)
133         dat_file = file(dat_path, "a+")
134
135         def save_line_and_append_to_buffer(line):
136             dat_file.seek(self.size)
137             dat_file.write(line)
138             self.append_rawres_to_buffer(line)
139
140         self.http_get_dat(save_line_and_append_to_buffer)
141         dat_file.close()
142
143         if not self.title:
144             self.title = datfile.get_title_from_dat(
145                 self.bbs, self.board, self.thread)
146             if self.title:
147                 self.window.set_title(self.title)
148
149     def load_dat(self):
150         self.size = 0
151         self.num = 0
152
153         self.title = datfile.get_title_from_dat(
154             self.bbs, self.board, self.thread)
155         if self.title:
156             self.window.set_title(self.title)
157
158         datfile.load_dat(self.bbs, self.board, self.thread,
159                          self.append_rawres_to_buffer)
160         self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0)
161
162
163     def append_rawres_to_buffer(self, line):
164         self.size += len(line)
165         self.num += 1
166
167         h = lambda name,mail,date,msg: self.reselems_to_buffer(
168             self.num, name, mail, date, msg)
169
170         datfile.split_line_to_elems(line.decode("cp932", "replace"), h)
171         
172     def reselems_to_buffer(self, num, name, mail, date, msg):
173         # number
174         self.textbuffer.insert(self.enditer, str(num) + " ")
175
176         # name
177         p = barehtmlparser.BareHTMLParser(self.untiedata_to_buffer)
178         p.feed("<b>" + name + "</b>")
179         p.close()
180
181         # mail
182         self.textbuffer.insert(self.enditer, "[" + mail + "]")
183
184         # date
185         p.feed(date)
186         p.close()
187         self.textbuffer.insert(self.enditer, "\n")
188
189         # msg
190         p.reset_func(self.untiedata_to_buffer_with_leftmargin)
191         p.feed(msg)
192         p.close()
193
194         self.textbuffer.insert(self.enditer, "\n\n")
195
196     def untiedata_to_buffer(self, data, bold, href):
197         if bold:
198             self.textbuffer.insert_with_tags(self.enditer, data, self.boldtag)
199         else:
200             self.textbuffer.insert(self.enditer, data)
201
202     def untiedata_to_buffer_with_leftmargin(self, data, bold, href):
203         if bold:
204             self.textbuffer.insert_with_tags(self.enditer, data,
205                                              self.boldtag, self.leftmargintag)
206         else:
207             self.textbuffer.insert_with_tags(self.enditer, data,
208                                              self.leftmargintag)