root/http/article.cc

Revision 1a970cd0640f976f152341597a5249ec22acbba7, 6.9 KB (checked in by Antti-Juhani Kaijanaho <antti-juhani@…>, 21 months ago)

[msg::msg] Separate out db::msg and let msg::entity handle the rest

Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>

  • Property mode set to 100644
Line 
1/*  This file is part of Alue, the multiprotocol Internet discussion daemon
2
3    Copyright © 2009, 2010 Antti-Juhani Kaijanaho
4
5    Alue is free software: you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    Alue is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with Alue.  If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20#include "authn.hh"
21#include "compose.hh"
22#include "error_resource.hh"
23#include "request.hh"
24#include "templated_resource.hh"
25
26#include "../db/db.hh"
27#include "../db/msg.hh"
28#include "../db/threaded.hh"
29#include "../html/util.hh"
30#include "../msg/content_type.hh"
31#include "../msg/lexutils.hh"
32#include "../msg/text_plain.hh"
33#include "../server.hh"
34#include "../tlate/msg_value.hh"
35#include "../tlate/thread_value.hh"
36#include "../tlate/tlate.hh"
37#include "../uri.hh"
38#include "../util.hh"
39
40#include <boost/shared_ptr.hpp>
41
42namespace http
43{
44        class article : public templated_resource
45        {
46        protected:
47                void set_attributes(boost::shared_ptr<request>,
48                                    tlate::data_model::ptr);
49        public:
50                article(server::conn_cb cb)
51                        : templated_resource(cb, "article.html")
52                        {}
53        };
54
55        void article::set_attributes(boost::shared_ptr<request> req,
56                                     tlate::data_model::ptr am)
57        {
58                boost::shared_ptr<db::msg> art;
59                bool is_single;
60                try
61                {
62                        size_t inx;
63                        if (req->get_path().substr(0,4) == "/id/")
64                        {
65                                inx = 4;
66                                is_single = true;
67                        }
68                        else if (req->get_path().substr(0,8) == "/thread/")
69                        {
70                                inx = 8;
71                                is_single = false;
72                        }
73                        else
74                                throw db::no_such_article();
75
76                        art = cb.dbase().lookup_msgid
77                                (uri::percent_decode
78                                 (req->get_path().substr(inx)));
79                }
80                catch (db::no_such_article)
81                {
82                        boost::shared_ptr<resource> er
83                                (new error_resource(cb, "404 No such article"));
84                        throw resource_exception(er);
85                }
86                catch (uri::invalid e)
87                {
88                        std::string msg = "400 ";
89                        msg += e.what();
90                        boost::shared_ptr<resource> er
91                                (new error_resource(cb, msg));
92                        throw resource_exception(er);
93                       
94                }
95
96                boost::shared_ptr<db::user> u = req->get_user();
97
98                if (is_single && u && req->get_form_field("markread") != "no")
99                        u->mark_read(art->msgid());
100               
101                db::thread_node::ptr tn =
102                        cb.dbase().get_threaded().lookup_msgid(art->msgid());
103                am->insert("article", tlate::msg_value::mk(tn, u));
104                if (!is_single)
105                {
106                        std::string f = req->get_form_field("s");
107                        size_t start = util::is_number(f)
108                                ? util::parse_nonnegative_integer<size_t>(f)
109                                : 0;
110                        f = req->get_form_field("n");
111                        size_t length = util::is_number(f)
112                                ? util::parse_nonnegative_integer<size_t>(f)
113                                : 10;
114
115                        tlate::thread_value::ptr tv
116                                (new tlate::thread_value(tn, u));
117                        size_t tvl = tv->size();
118                        tv->slice_window(start, length);
119                        am->insert("thread", tv);
120
121                        tlate::data_model::ptr pg(new tlate::data_model);
122                        pg->insert("first", start + 1);
123                        pg->insert("last", start + tv->size());
124                        pg->insert("size", tv->size());
125                        pg->insert("max_size", length);
126                        pg->insert("total", tvl);
127
128                        if (start + length < tvl)
129                        {
130                                ::uri u = req->get_uri();
131                                u.replace_query_param("s", start + length);
132                                u.replace_query_param("n", length);
133                                pg->insert("next", u.to_string());
134                        }
135                       
136                        if (start > 0)
137                        {
138                                ::uri u = req->get_uri();
139                                u.replace_query_param("s",
140                                                      start > length
141                                                      ? start - length
142                                                      : 0);
143                                u.replace_query_param("n", length);
144                                pg->insert("prev", u.to_string());
145                        }
146                        am->insert("page", pg);
147                }
148
149                ::uri fhon_uri = req->get_uri();
150                fhon_uri.replace_query_param("fullhdr", "true");
151                am->insert("fullhdr-on", html::quote(fhon_uri.to_string(),
152                                                         false));
153
154                ::uri fhoff_uri = req->get_uri();
155                fhoff_uri.replace_query_param("fullhdr", "false");
156                am->insert("fullhdr-off",
157                            html::quote(fhoff_uri.to_string(), false));
158
159                if (req->get_uri().get_query_param("fullhdr") == "true")
160                        am->insert("full-header", "");
161        }
162
163};
164
165namespace
166{
167        class factory : public server::http_resource_factory
168        {
169        public:
170                factory() {
171                        server::register_http_resource("/id", this);
172                        server::register_http_resource("/thread", this);
173                }
174                boost::shared_ptr<http::resource> operator()
175                (server::conn_cb cb, std::string) {
176                        boost::shared_ptr<http::resource> rv
177                                (new http::article(cb));
178                        return rv;
179                }
180        };
181        factory f;
182}
Note: See TracBrowser for help on using the browser.