OSDN Git Service

52c53b7c2a74b24422d17b42ffa70fba62a2fd91
[fukui-no-namari/dialektos.git] / src / thread_window.cxx
1 /*
2  * Copyright (C) 2009 by Aiwota Programmer
3  * aiwotaprog@tetteke.tk
4  *
5  * This file is part of Dialektos.
6  *
7  * Dialektos is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Dialektos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Dialektos.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "thread_window.hxx"
22
23 #include <glibmm/convert.h>
24 #include <boost/date_time/posix_time/posix_time.hpp>
25 #include <boost/filesystem.hpp>
26 #include <iostream>
27 #include <fstream>
28 #include "bbs_detail_base.hxx"
29 #include "thread_idx.hxx"
30 #include "http_get.hxx"
31
32
33 namespace dialektos {
34
35
36 void ThreadWindow::create(std::auto_ptr<bbs_detail::Base> bbs) {
37   regist(new ThreadWindow(bbs));
38 }
39
40 ThreadWindow::ThreadWindow(std::auto_ptr<bbs_detail::Base> bbs) :
41   SuperClass(),
42   text_view_(),
43   scrolled_(text_view_.get_adjustment()),
44   bbs_(bbs), http_getter_(), idx_() {
45
46   set_default_size(400,300);
47
48   scrolled_.add(text_view_);
49   add(scrolled_);
50
51   text_view_.signal_button_press_event().connect_notify(
52       sigc::mem_fun(*this, &ThreadWindow::on_child_button_press));
53
54   show_all();
55
56   load();
57 }
58
59 bool ThreadWindow::load() {
60   using namespace boost::posix_time;
61   ptime start = microsec_clock::local_time();
62
63   if (bbs_) {
64
65     bbs_->load_thread(text_view_);
66     text_view_.relayout();
67     text_view_.queue_draw();
68
69     std::cout <<
70     to_simple_string(microsec_clock::local_time() - start) << std::endl;
71
72     idx_ = ThreadIdx::from_xml(bbs_->get_thread_idx_path());
73   }
74
75   return false;
76 }
77
78 bool ThreadWindow::is_same(const bbs_detail::Base& bbs) const {
79   const bbs_detail::Base& lhs = *bbs_;
80   return lhs == bbs;
81 }
82
83 void ThreadWindow::on_action_view_refresh() {
84   if (http_getter_) return;
85
86   statusbar_.push("HTTP/1.0 GET...");
87
88   const std::string uri = bbs_->get_thread_dat_uri();
89   http::Header request_header = bbs_->get_thread_dat_request_header();
90   if (!request_header.get_range().empty()) {
91     request_header.set_if_modified_since(idx_.last_modified_);
92     request_header.set_if_none_match(idx_.etag_);
93   }
94
95   http_getter_.reset(new http::GetInThread(uri, request_header));
96   http_getter_->signal_end().connect(
97       sigc::mem_fun(*this, &ThreadWindow::on_http_get_end));
98   http_getter_->run();
99 }
100
101 void ThreadWindow::on_action_view_stop() {
102   if (http_getter_) http_getter_->cancel();
103 }
104
105 void ThreadWindow::on_http_get_end(bool success) {
106 //  const std::string uri = http_getter_->get_uri();
107 //  const http::Header request_header = http_getter_->get_request_header();
108   const http::Response response = http_getter_->get_response();
109   const boost::system::error_code err = http_getter_->get_error();
110   http_getter_.reset(0);
111   if (err) {
112     statusbar_.push(err.message());
113     return;
114   }
115   if (!success) {
116     statusbar_.push("Canceled.");
117     return;
118   }
119
120   on_refresh_end(response.get_status_line(), response.get_header());
121
122   const int code = response.get_status_line().get_code();
123   if (code != 200 && code != 206) return;
124
125   bbs_->load_thread_from_string(response.get_content(), text_view_);
126   text_view_.relayout();
127   text_view_.queue_draw();
128
129   save_content(response);
130 }
131
132 void ThreadWindow::on_refresh_end(const http::StatusLine& status,
133     const http::Header& header) {
134   std::string message = status.get_line();
135   const std::string last_modified = header.get_last_modified();
136   if (!last_modified.empty()) {
137     message += " ";
138     message += last_modified;
139   }
140   statusbar_.push(message);
141 }
142
143 void ThreadWindow::save_content(const http::Response& response) {
144   const int code = response.get_status_line().get_code();
145   if (code != 200 && code != 206) return;
146
147   std::ofstream ofs(bbs_->get_thread_file_path().c_str(),
148       code == 200 ?
149           std::ios::out | std::ios::trunc : std::ios::out | std::ios::app);
150   ofs << response.get_content();
151   ofs.close();
152
153   if (code == 200)
154     idx_.title_ = bbs_->get_title_from_string(response.get_content());
155
156   idx_.last_modified_ = response.get_header().get_last_modified();
157   idx_.etag_ = response.get_header().get_etag();
158
159   idx_.line_count_ = text_view_.get_res_num();
160
161   idx_.to_xml(boost::filesystem::path(bbs_->get_thread_idx_path()));
162 }
163
164
165 } // namespace dialektos