add artical rankings.
This commit is contained in:
parent
2b45dad26e
commit
4757f8e644
@ -160,6 +160,40 @@ Application::Application(const std::string &path)
|
|||||||
session.reply(std::move(s));
|
session.reply(std::move(s));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_router->insert("/api/v1/most_viewed_urls", [this](HttpSession &session, const Request &request,
|
||||||
|
const boost::urls::matches &matches) {
|
||||||
|
using namespace boost::beast;
|
||||||
|
int size = 5;
|
||||||
|
std::error_code error;
|
||||||
|
if (!request.body().empty()) {
|
||||||
|
auto rootJson = boost::json::parse(request.body(), error);
|
||||||
|
if (error) {
|
||||||
|
LOG(info) << "<" << request.body() << "> parse json error: " << error.message();
|
||||||
|
} else {
|
||||||
|
auto &root = rootJson.as_object();
|
||||||
|
if (root.contains("size")) {
|
||||||
|
size = root.at("size").as_int64();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data = Amass::Singleton<Database>::instance()->mostViewedUrls(size);
|
||||||
|
boost::json::array reply;
|
||||||
|
for (auto &d : data) {
|
||||||
|
boost::json::object object;
|
||||||
|
object["url"] = d.url;
|
||||||
|
object["count"] = d.pageViewCount;
|
||||||
|
reply.push_back(std::move(object));
|
||||||
|
}
|
||||||
|
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
|
||||||
|
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
||||||
|
s.set(http::field::content_type, "application/json;charset=UTF-8");
|
||||||
|
s.keep_alive(request.keep_alive());
|
||||||
|
s.body() = boost::json::serialize(reply);
|
||||||
|
s.prepare_payload();
|
||||||
|
session.reply(std::move(s));
|
||||||
|
});
|
||||||
|
|
||||||
m_ioContext = Amass::Singleton<IoContext>::instance<Amass::Construct>(getThreads());
|
m_ioContext = Amass::Singleton<IoContext>::instance<Amass::Construct>(getThreads());
|
||||||
m_timer = std::make_shared<boost::asio::system_timer>(*m_ioContext->ioContext());
|
m_timer = std::make_shared<boost::asio::system_timer>(*m_ioContext->ioContext());
|
||||||
|
|
||||||
@ -177,7 +211,6 @@ const Application::RequestHandler *Application::find(boost::urls::segments_encod
|
|||||||
boost::urls::matches_base &matches) const noexcept {
|
boost::urls::matches_base &matches) const noexcept {
|
||||||
const Application::RequestHandler *ret = nullptr;
|
const Application::RequestHandler *ret = nullptr;
|
||||||
try {
|
try {
|
||||||
LOG(info) << path << "cgdfc";
|
|
||||||
ret = m_router->find(path, matches);
|
ret = m_router->find(path, matches);
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
boost::stacktrace::stacktrace trace = boost::stacktrace::stacktrace::from_current_exception();
|
boost::stacktrace::stacktrace trace = boost::stacktrace::stacktrace::from_current_exception();
|
||||||
|
@ -109,11 +109,15 @@ void Database::setTaskFinished(int id, bool finished, uint64_t finishedTime) {
|
|||||||
void Database::updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
|
void Database::updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
|
||||||
int64_t time) {
|
int64_t time) {
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
auto strippedUrl = url;
|
||||||
|
if (strippedUrl.size() > 1 && strippedUrl.back() == '/') {
|
||||||
|
strippedUrl.pop_back();
|
||||||
|
}
|
||||||
const char *query = "SELECT id, page_view_count FROM visit_analysis WHERE url = ? AND visitor_uuid = ?";
|
const char *query = "SELECT id, page_view_count FROM visit_analysis WHERE url = ? AND visitor_uuid = ?";
|
||||||
if (sqlite3_prepare_v2(m_sqlite3, query, -1, &stmt, 0) != SQLITE_OK) {
|
if (sqlite3_prepare_v2(m_sqlite3, query, -1, &stmt, 0) != SQLITE_OK) {
|
||||||
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
|
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
|
||||||
}
|
}
|
||||||
sqlite3_bind_text(stmt, 1, url.c_str(), -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 1, strippedUrl.c_str(), -1, SQLITE_STATIC);
|
||||||
sqlite3_bind_text(stmt, 2, visitorUuid.c_str(), -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 2, visitorUuid.c_str(), -1, SQLITE_STATIC);
|
||||||
int id = -1;
|
int id = -1;
|
||||||
int page_view_count = 0;
|
int page_view_count = 0;
|
||||||
@ -142,7 +146,7 @@ void Database::updateVisitCount(const std::string &url, const std::string &visit
|
|||||||
if (sqlite3_prepare_v2(m_sqlite3, insertQuery, -1, &stmt, 0) != SQLITE_OK) {
|
if (sqlite3_prepare_v2(m_sqlite3, insertQuery, -1, &stmt, 0) != SQLITE_OK) {
|
||||||
LOG(error) << "Failed to prepare insert statement: " << sqlite3_errmsg(m_sqlite3);
|
LOG(error) << "Failed to prepare insert statement: " << sqlite3_errmsg(m_sqlite3);
|
||||||
}
|
}
|
||||||
sqlite3_bind_text(stmt, 1, url.c_str(), -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 1, strippedUrl.c_str(), -1, SQLITE_STATIC);
|
||||||
sqlite3_bind_text(stmt, 2, visitorUuid.c_str(), -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 2, visitorUuid.c_str(), -1, SQLITE_STATIC);
|
||||||
sqlite3_bind_text(stmt, 3, userAgent.c_str(), -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 3, userAgent.c_str(), -1, SQLITE_STATIC);
|
||||||
sqlite3_bind_int64(stmt, 4, time);
|
sqlite3_bind_int64(stmt, 4, time);
|
||||||
@ -165,7 +169,7 @@ void Database::clearVisitRecord() {
|
|||||||
|
|
||||||
VisitAnalysis Database::siteVisitAnalysisData() {
|
VisitAnalysis Database::siteVisitAnalysisData() {
|
||||||
VisitAnalysis ret;
|
VisitAnalysis ret;
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt = nullptr;
|
||||||
const char *sql = "SELECT COUNT(DISTINCT visitor_uuid) as unique_visitors, SUM(page_view_count) as "
|
const char *sql = "SELECT COUNT(DISTINCT visitor_uuid) as unique_visitors, SUM(page_view_count) as "
|
||||||
"total_page_views FROM visit_analysis";
|
"total_page_views FROM visit_analysis";
|
||||||
if (sqlite3_prepare_v2(m_sqlite3, sql, -1, &stmt, nullptr) != SQLITE_OK) {
|
if (sqlite3_prepare_v2(m_sqlite3, sql, -1, &stmt, nullptr) != SQLITE_OK) {
|
||||||
@ -182,6 +186,45 @@ VisitAnalysis Database::siteVisitAnalysisData() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::list<VisitAnalysis> Database::mostViewedUrls(int size) {
|
||||||
|
std::vector<std::string> filter = {
|
||||||
|
"/",
|
||||||
|
"/LoginPage",
|
||||||
|
"/我的笔记",
|
||||||
|
"/我的博客",
|
||||||
|
};
|
||||||
|
const char *sql = "SELECT url, SUM(page_view_count) AS total_page_view_count "
|
||||||
|
"FROM visit_analysis "
|
||||||
|
"GROUP BY url "
|
||||||
|
"ORDER BY total_page_view_count DESC "
|
||||||
|
"LIMIT ?";
|
||||||
|
sqlite3_stmt *stmt = nullptr;
|
||||||
|
std::list<VisitAnalysis> ret;
|
||||||
|
auto rc = sqlite3_prepare_v2(m_sqlite3, sql, -1, &stmt, nullptr);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_bind_int(stmt, 1, size + filter.size());
|
||||||
|
|
||||||
|
// Execute the SQL statement and fetch the results
|
||||||
|
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||||||
|
VisitAnalysis pv;
|
||||||
|
pv.url = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
|
||||||
|
if (std::find(filter.cbegin(), filter.cend(), pv.url) != filter.cend()) continue;
|
||||||
|
pv.pageViewCount = sqlite3_column_int(stmt, 1);
|
||||||
|
ret.push_back(pv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc != SQLITE_DONE) {
|
||||||
|
LOG(error) << "Failed to execute statement: " << sqlite3_errmsg(m_sqlite3);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
VisitAnalysis Database::visitAnalysisData(const std::string &url) {
|
VisitAnalysis Database::visitAnalysisData(const std::string &url) {
|
||||||
VisitAnalysis ret;
|
VisitAnalysis ret;
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
void clearVisitRecord();
|
void clearVisitRecord();
|
||||||
VisitAnalysis visitAnalysisData(const std::string &url);
|
VisitAnalysis visitAnalysisData(const std::string &url);
|
||||||
VisitAnalysis siteVisitAnalysisData();
|
VisitAnalysis siteVisitAnalysisData();
|
||||||
|
std::list<VisitAnalysis> mostViewedUrls(int size);
|
||||||
|
|
||||||
HomeBox::Items homeBoxItems();
|
HomeBox::Items homeBoxItems();
|
||||||
bool addHomeBoxItem(const std::string &name, const std::string &location, int cost);
|
bool addHomeBoxItem(const std::string &name, const std::string &location, int cost);
|
||||||
|
Loading…
Reference in New Issue
Block a user