root/http/threads.cc

Revision 654bb6066f0a41076097ffd2498c04805e4d7276, 6.5 KB (checked in by Antti-Juhani Kaijanaho <antti-juhani@…>, 21 months ago)

[http::article,threads] Fixes for pagination

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/threaded.hh"
28#include "../html/util.hh"
29#include "../server.hh"
30#include "../tlate/empty_value.hh"
31#include "../tlate/group_value.hh"
32#include "../tlate/list_value.hh"
33#include "../tlate/msg_value.hh"
34#include "../tlate/tlate.hh"
35#include "../uri.hh"
36
37#include <boost/shared_ptr.hpp>
38
39namespace http
40{
41        class threads : public templated_resource
42        {
43        public:
44                threads(server::conn_cb cb)
45                        : templated_resource(cb, "threads.html")
46                        {}
47        protected:
48                void set_attributes(boost::shared_ptr<request>,
49                                    tlate::data_model::ptr);
50        };
51
52        void threads::set_attributes(boost::shared_ptr<request> req,
53                                     tlate::data_model::ptr am)
54        {
55                boost::shared_ptr<db::user> u = req->get_user();               
56
57                boost::shared_ptr<db::group> gr;
58                try
59                {
60                        gr = cb.dbase().lookup_group
61                                (uri::percent_decode
62                                 (req->get_path().substr(4)));
63                }
64                catch (db::no_such_group)
65                {
66                        boost::shared_ptr<resource> er
67                                (new error_resource(cb, "404 No such group"));
68                        throw resource_exception(er);
69                }
70                catch (uri::invalid e)
71                {
72                        std::string msg = "400 ";
73                        msg += e.what();
74                        boost::shared_ptr<resource> er
75                                (new error_resource(cb, msg));
76                        throw resource_exception(er);
77                       
78                }
79
80                bool only_summary = req->get_form_field("summary") == "true";
81
82                am->insert("group", new tlate::group_value(gr, u));
83
84                if (only_summary)
85                        am->insert("thread_summary", new tlate::empty_value);
86
87                if (gr->posting_authz(u))
88                        am->insert("posting-uri", compose::get_posting_uri(gr));
89
90                if (!gr->reading_authz(u))
91                {
92                        am->insert("restricted", new tlate::empty_value);
93                }
94                else
95                {
96                        std::string f = req->get_form_field("s");
97                        size_t start = util::is_number(f)
98                                ? util::parse_nonnegative_integer<size_t>(f)
99                                : 0;
100                        f = req->get_form_field("n");
101                        size_t length = util::is_number(f)
102                                ? util::parse_nonnegative_integer<size_t>(f)
103                                : 10;
104
105                        tlate::list_value::ptr tl(new tlate::list_value);
106                        std::list<db::thread_node::ptr> thrs
107                                = cb.dbase().get_threaded().get_threads(gr);
108
109                        thrs.sort(db::thread_node::cmp_latest_date_rev);
110
111                        size_t cur = 0;
112                        size_t total = 0;
113                        for (std::list<db::thread_node::ptr>::const_iterator
114                                     it = thrs.begin();
115                             it != thrs.end(); it++)
116                        {
117                                total++;
118                                if (cur >= start + length) continue;
119                                cur++;
120                                if (cur > start)
121                                        tl->push_back
122                                                (tlate::msg_value::mk(*it, u));
123                        }
124                        am->insert("threads", tl);
125
126                        tlate::data_model::ptr pg(new tlate::data_model);
127                        pg->insert("first", start + 1);
128                        pg->insert("last", cur);
129                        pg->insert("size", cur - start);
130                        pg->insert("max_size", length);
131                        pg->insert("total", total);
132                        if (cur < total)
133                        {
134                                ::uri u = req->get_uri();
135                                u.replace_query_param("s", start + length);
136                                u.replace_query_param("n", length);
137                                pg->insert("next", u.to_string());
138                        }
139                       
140                        if (start > 0)
141                        {
142                                ::uri u = req->get_uri();
143                                u.replace_query_param("s",
144                                                      start > length
145                                                      ? start - length
146                                                      : 0);
147                                u.replace_query_param("n", length);
148                                pg->insert("prev", u.to_string());
149                        }
150                        am->insert("page", pg);
151                }
152        }
153
154};
155
156namespace
157{
158        class factory : public server::http_resource_factory
159        {
160        public:
161                factory() {
162                        server::register_http_resource("/gr", this);
163                }
164                boost::shared_ptr<http::resource> operator()
165                (server::conn_cb cb,std::string) {
166                        boost::shared_ptr<http::resource> rv
167                                (new http::threads(cb));
168                        return rv;
169                }
170        };
171        factory f;
172}
Note: See TracBrowser for help on using the browser.