root/http/thread_feed.cc

Revision 1a970cd0640f976f152341597a5249ec22acbba7, 6.5 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 © 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 "article_entry.hh"
21#include "error_resource.hh"
22#include "feed_resource.hh"
23#include "request.hh"
24#include "resource_exception.hh"
25
26#include "../config.hh"
27#include "../db/db.hh"
28#include "../db/threaded.hh"
29#include "../msg/entity.hh"
30#include "../msg/lexutils.hh"
31#include "../uri.hh"
32
33#include <list>
34#include <string>
35
36namespace http
37{
38        class thread_feed : public feed_resource
39        {
40                db::thread_node::const_ptr art;
41                std::list<feed_resource::entry::const_ptr> entries;
42                boost::posix_time::ptime latest;
43                void add_msg(db::thread_node::const_ptr, db::user::const_ptr);
44        public:
45                thread_feed(server::conn_cb cb, std::string path);
46        protected:
47                void prehook(boost::shared_ptr<request> req);
48                std::string get_id_uri() const;
49                std::string get_alt_uri() const;
50                std::string get_title() const;
51                boost::posix_time::ptime get_updated() const;
52                const std::list<entry::const_ptr> &get_entries() const;
53        };
54
55        void thread_feed::prehook(boost::shared_ptr<request> req)
56        {
57                db::user::const_ptr u = req->get_user();
58                db::msg::const_ptr m = art->get_article();
59                if (m && !m->reading_authz(u))
60                {
61                        boost::shared_ptr<resource> er
62                                (new error_resource(cb, "403 Forbidden"));
63                        throw resource_exception(er);                       
64                }
65                add_msg(art, u);
66                if (entries.empty()) latest = boost::posix_time::second_clock::
67                                              universal_time();
68        }
69
70        void thread_feed::add_msg(db::thread_node::const_ptr m,
71                                  db::user::const_ptr u)
72        {
73                db::msg::const_ptr art = m->get_article();
74                if (art && art->reading_authz(u)) {
75                        article_entry::ptr e(new article_entry(m, u));
76                        entries.push_front(e);
77                        boost::posix_time::ptime date =
78                                art->get_entity()->parsed_date();
79                        if (latest < date) latest = date;
80                }
81                const std::list<db::thread_node::ptr> &ch = m->get_children();
82                for (std::list<db::thread_node::ptr>::const_iterator it =
83                             ch.begin();
84                     it != ch.end(); it++)
85                {
86                        add_msg(*it, u);
87                }
88       }
89
90        thread_feed::thread_feed(server::conn_cb cb, std::string path)
91                        : feed_resource(cb)
92                        , latest(boost::posix_time::neg_infin)
93        {
94                try
95                {
96                        if (path.substr(0,13) != "/feed/thread/")
97                                throw db::no_such_article();
98
99                        const db::threaded &thr = cb.dbase().get_threaded();
100
101                        art = thr.lookup_msgid(uri::percent_decode
102                                               (path.substr(13)));
103                        if (!art) throw db::no_such_article();
104                }
105                catch (db::no_such_article)
106                {
107                        boost::shared_ptr<resource> er
108                                (new error_resource(cb, "404 No such article"));
109                        throw resource_exception(er);
110                }
111        }
112
113        std::string thread_feed::get_id_uri() const
114        {
115                std::ostringstream ss;
116                // FIXME: use a tag: uri
117                ss << "https://"
118                   << uri::percent_encode
119                        (config["canonical-name"].as<std::string>())
120                   << ":"
121                   << uri::percent_encode
122                        (config["https-port"].as<std::string>())
123                   << "/feed/thread/"
124                   << uri::percent_encode(art->get_msgid());
125                return ss.str();
126        }
127
128        std::string thread_feed::get_alt_uri() const
129        {
130                std::ostringstream ss;
131                ss << "https://"
132                   << uri::percent_encode
133                        (config["canonical-name"].as<std::string>())
134                   << ":"
135                   << uri::percent_encode
136                        (config["https-port"].as<std::string>())
137                   << "/thread/"
138                   << uri::percent_encode(art->get_msgid());
139                return ss.str();
140        }
141
142        std::string thread_feed::get_title() const
143        {
144                db::msg::const_ptr m = art->get_article();
145                if (art) {
146                        return std::string("Thread about ") +
147                                msg::decode_unstructured
148                                (m->get_entity()->get_field("Subject", false));
149                } else {
150                        return "untitled thread";
151                }
152        }
153        boost::posix_time::ptime thread_feed::get_updated() const
154        {
155                return latest;
156        }
157        const std::list<feed_resource::entry::const_ptr> &
158        thread_feed::get_entries() const
159        {
160                return entries;
161        }
162
163};
164
165namespace
166{
167        class factory : public server::http_resource_factory
168        {
169        public:
170                factory() {
171                        server::register_http_resource("/feed/thread", this);
172                }
173                boost::shared_ptr<http::resource> operator()
174                (server::conn_cb cb, std::string path) {
175                        boost::shared_ptr<http::resource> rv
176                                (new http::thread_feed(cb, path));
177                        return rv;
178                }
179        };
180        factory f;
181}
Note: See TracBrowser for help on using the browser.