root/tlate/msg_value.cc

Revision 173e2ce96a7bde630476defe34fae1b5ed1baaba, 9.4 KB (checked in by Antti-Juhani Kaijanaho <antti-juhani@…>, 16 months ago)

#79: Kill tlate::msg_value precursor and followup lists if they are empty

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, 2011 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 "date_value.hh"
21#include "empty_value.hh"
22#include "group_value.hh"
23#include "header_value.hh"
24#include "lazy_structured_value.hh"
25#include "list_value.hh"
26#include "msg_value.hh"
27#include "user_value.hh"
28#include "basic_sequential_value.hh"
29
30#include "../db/threaded.hh"
31#include "../db/msg.hh"
32#include "../html/util.hh"
33#include "../http/compose.hh"
34#include "../msg/entity.hh"
35#include "../msg/lexutils.hh"
36#include "../uri.hh"
37
38#include <boost/bind.hpp>
39
40namespace
41{
42        using namespace tlate;
43        using html::quote;
44        using msg::decode_unstructured;
45        class xref_seq : public sequential_value
46        {
47                db::msg::const_ptr m;
48                db::user::const_ptr u;
49
50                class vit : public virtual_iterator
51                {
52                        db::msg::xref_type::const_iterator it;
53                        mutable value::const_ptr cur;
54                        db::user::const_ptr u;
55 
56                        vit(db::msg::xref_type::const_iterator it,
57                            value::const_ptr cur,
58                            db::user::const_ptr u)
59                                : it(it)
60                                , cur(cur)
61                                , u(u)
62                                {}
63               public:
64                        vit(db::msg::xref_type::const_iterator it,
65                            db::user::const_ptr u)
66                                : it(it)
67                                , u(u)
68                                {}
69                        virtual_iterator *clone() const {
70                                return new vit(it, cur, u);
71                        }
72                        value::const_ptr get() const {
73                                if (!cur) cur.reset(new group_value(it->first,
74                                                                    u));
75                                return cur;
76                        }
77                        void next() {
78                                it++;
79                                cur.reset();
80                        }
81                        bool eq(const virtual_iterator &o_) const {
82                                const vit *o = dynamic_cast<const vit *>(&o_);
83                                return o ? it == o->it : false;
84                        }
85                };
86
87        public:
88                xref_seq(db::msg::const_ptr m, db::user::const_ptr u)
89                        : m(m)
90                        , u(u)
91                        {}
92                const_iterator begin() const {
93                        return const_iterator
94                                (new vit(m->get_xref().begin(), u));
95                }
96                const_iterator end() const {
97                        return const_iterator
98                                (new vit(m->get_xref().end(), u));
99                }
100        };
101
102
103        value::ptr mk_msg_value(db::thread_node::const_ptr tr,
104                                db::user::const_ptr u)
105        {
106                return msg_value::mk(tr, u);
107        }
108}
109
110namespace tlate
111{
112        msg_value::msg_value(db::thread_node::const_ptr tn,
113                             db::user::const_ptr u)
114                : tn(tn)
115                , u(u)
116        {
117                assert(tn);
118        }
119
120        value::ptr msg_value::mk(db::thread_node::const_ptr tr,
121                                 db::user::const_ptr u)
122        {
123                if (!tr) return value::ptr();
124                structured_value::ptr rv_(new msg_value(tr, u));
125                value::ptr rv(new lazy_structured_value(rv_));
126                return rv;
127        }
128
129        value::const_ptr msg_value::get(std::string var) const
130        {
131                using html::quote;
132                typedef string_value sv;
133                db::msg::const_ptr m = tn->get_article();
134                msg::entity::const_ptr e;
135                if (m) e = m->get_entity();
136                std::string msgid = tn->get_msgid();
137                bool rauthz = m ? m->reading_authz(u) : false;
138                bool show = rauthz && !m->is_censured();
139                bool authn = u;
140                value::const_ptr rv;
141                /**/ if (var == "id")
142                        rv.reset(new sv(quote(msgid, false)));
143                else if (var == "single-path")
144                        rv.reset(new sv(quote("/id/" +
145                                              uri::percent_encode(msgid),
146                                              false)));
147                else if (var == "atom_path")
148                        rv.reset(new sv(quote("/feed/thread/" +
149                                              uri::percent_encode(msgid),
150                                              false)));
151                else if (var == "thread-path")
152                        rv.reset(new sv(quote("/thread/" +
153                                              uri::percent_encode(msgid),
154                                              false)));
155                else if (var == "followup-allowed" &&
156                         m->posting_authz(u) && show)
157                        rv.reset(new sv(http::compose::get_followup_uri(m)));
158                else if (var == "followup-uri" && show)
159                        rv.reset(new sv(http::compose::get_followup_uri(m)));
160                else if (!rauthz && var == "restricted")
161                        rv.reset(new empty_value);
162                else if (show && m && var == "from")
163                        rv.reset(new sv(quote(decode_unstructured
164                                              (e->get_field("From", false)),
165                                              !authn)));
166                else if (show && m && var == "subject")
167                        rv.reset(new sv(quote(decode_unstructured
168                                              (e->get_field("Subject", false)),
169                                              !authn)));
170                else if (rauthz && m && var == "date")
171                        rv.reset(new date_value(e->parsed_date()));
172                else if (rauthz && var == "latest-date" &&
173                         !tn->get_latest_date().is_special())
174                        rv.reset(new date_value((tn->get_latest_date())));
175                                               
176                else if (show && m && var == "header")
177                        rv.reset(new header_value(e,!u));
178                else if (show && m && var == "body")
179                        rv = e->get_tlate_value(authn);
180                else if (rauthz && m && var == "xref")
181                        rv.reset(new xref_seq(m, u));
182                else if (rauthz && var == "thread-next")
183                        rv = msg_value::mk(tn->next(), u);
184                else if (rauthz && var == "thread-prev")
185                        rv = msg_value::mk(tn->previous(), u);
186                else if (rauthz && var == "followups")
187                        rv = seqval(tn->get_children(),
188                                    boost::bind(mk_msg_value, _1, u));
189                else if (rauthz && var == "precursors")
190                {
191                        list_value::ptr ps(new list_value);
192                        for (db::thread_node::const_ptr it = tn->get_parent();
193                             it; it = it->get_parent())
194                        {
195                                ps->push_back(msg_value::mk(it, u));
196                        }
197                        if (!ps->empty()) rv = ps;
198                }
199                else if (rauthz && var == "thread")
200                        rv.reset(new sv(quote("/thread/" +
201                                              uri::percent_encode(msgid),
202                                              false)));
203                else if (rauthz && var == "thread-count")
204                        rv.reset(new sv(boost::lexical_cast<std::string>
205                                        (tn->cardinality())));
206                else if (u && var == "marked_read" && u->has_read(msgid))
207                        rv.reset(new empty_value);
208                else if (u && show && m && var == "poster" && m->get_poster())
209                        rv.reset(new user_value(m->get_poster()));
210                else if (u && rauthz && m && var == "own" &&
211                         m->get_poster() == u)
212                        rv.reset(new empty_value);
213                else if (rauthz && m->is_censured() && var == "moderated")
214                        rv.reset(new empty_value);
215                else if (rauthz && m && var == "moderator")
216                {
217                        db::user::const_ptr u = m->censor();
218                        if (u) rv.reset(new user_value(u));
219                }
220                else if (u && m && var == "mod-uri" && u->is_moderator(m))
221                        rv.reset(new sv(quote("/mod", false)));
222                return rv;
223        }
224}
Note: See TracBrowser for help on using the browser.