add extra info for analysis.
This commit is contained in:
parent
fee13aebe7
commit
2b45dad26e
@ -9,8 +9,14 @@
|
|||||||
| id | INTEGER | NOT NULL | |
|
| id | INTEGER | NOT NULL | |
|
||||||
| url | TEXT | NOT NULL | |
|
| url | TEXT | NOT NULL | |
|
||||||
| visitor_uuid | TEXT | NOT NULL | |
|
| visitor_uuid | TEXT | NOT NULL | |
|
||||||
|
| last_user_agent | TEXT | NOT NULL | |
|
||||||
|
| last_view_time | INTEGER | NOT NULL | |
|
||||||
| page_view_count | INTEGER | NOT NULL | |
|
| page_view_count | INTEGER | NOT NULL | |
|
||||||
|
|
||||||
|
插入 url,visitor_uuid,last_user_agent ,last_view_time至表中,如果表中已存在url,visitor_uuid的item,则更新last_user_agent ,last_view_time,并将page_view_count加1,否则创建新的item,并将page_view_count赋值为1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 任务清单
|
### 任务清单
|
||||||
|
@ -119,7 +119,7 @@ Application::Application(const std::string &path)
|
|||||||
session.reply(
|
session.reply(
|
||||||
ServiceLogic::make_200<boost::beast::http::string_body>(request, "notify successed.\n", "text/html"));
|
ServiceLogic::make_200<boost::beast::http::string_body>(request, "notify successed.\n", "text/html"));
|
||||||
});
|
});
|
||||||
|
// clang-format on
|
||||||
m_router->insert("/api/v1/visit_analysis", [this](HttpSession &session, const Request &request,
|
m_router->insert("/api/v1/visit_analysis", [this](HttpSession &session, const Request &request,
|
||||||
const boost::urls::matches &matches) {
|
const boost::urls::matches &matches) {
|
||||||
using namespace boost::beast;
|
using namespace boost::beast;
|
||||||
@ -127,15 +127,21 @@ Application::Application(const std::string &path)
|
|||||||
auto &root = rootJson.as_object();
|
auto &root = rootJson.as_object();
|
||||||
std::string url;
|
std::string url;
|
||||||
std::string visitorUuid;
|
std::string visitorUuid;
|
||||||
|
std::string userAgent;
|
||||||
if (root.contains("url")) {
|
if (root.contains("url")) {
|
||||||
url = root["url"].as_string();
|
url = root["url"].as_string();
|
||||||
}
|
}
|
||||||
if (root.contains("visitor_uuid")) {
|
if (root.contains("visitor_uuid")) {
|
||||||
visitorUuid = root["visitor_uuid"].as_string();
|
visitorUuid = root["visitor_uuid"].as_string();
|
||||||
}
|
}
|
||||||
|
if (root.contains("user_agent")) {
|
||||||
|
userAgent = root["user_agent"].as_string();
|
||||||
|
}
|
||||||
|
|
||||||
auto database = Amass::Singleton<Database>::instance();
|
auto database = Amass::Singleton<Database>::instance();
|
||||||
database->updateVisitCount(url, visitorUuid);
|
auto now = std::chrono::system_clock::now();
|
||||||
|
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
|
||||||
|
database->updateVisitCount(url, visitorUuid, userAgent, now_time);
|
||||||
auto data = database->visitAnalysisData(std::string(url));
|
auto data = database->visitAnalysisData(std::string(url));
|
||||||
auto total = database->siteVisitAnalysisData();
|
auto total = database->siteVisitAnalysisData();
|
||||||
|
|
||||||
@ -153,7 +159,6 @@ Application::Application(const std::string &path)
|
|||||||
s.prepare_payload();
|
s.prepare_payload();
|
||||||
session.reply(std::move(s));
|
session.reply(std::move(s));
|
||||||
});
|
});
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
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());
|
||||||
|
@ -106,48 +106,51 @@ void Database::setTaskFinished(int id, bool finished, uint64_t finishedTime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::updateVisitCount(const std::string &url, const std::string &visitorUuid) {
|
void Database::updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
|
||||||
sqlite3_stmt *stmt = nullptr;
|
int64_t time) {
|
||||||
const char *sql_select = "SELECT page_view_count FROM visit_analysis WHERE url = ? AND visitor_uuid = ?";
|
sqlite3_stmt *stmt;
|
||||||
if (sqlite3_prepare_v2(m_sqlite3, sql_select, -1, &stmt, 0) != SQLITE_OK) {
|
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) {
|
||||||
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
|
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
sqlite3_bind_text(stmt, 1, url.c_str(), -1, SQLITE_STATIC);
|
sqlite3_bind_text(stmt, 1, url.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 rc = sqlite3_step(stmt);
|
int id = -1;
|
||||||
if (rc == SQLITE_ROW) { // 记录存在,执行UPDATE语句
|
int page_view_count = 0;
|
||||||
sqlite3_finalize(stmt); // 释放SELECT语句的资源
|
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
const char *sql_update =
|
id = sqlite3_column_int(stmt, 0);
|
||||||
"UPDATE visit_analysis SET page_view_count = page_view_count + 1 WHERE url = ? AND visitor_uuid = ?";
|
page_view_count = sqlite3_column_int(stmt, 1);
|
||||||
if (sqlite3_prepare_v2(m_sqlite3, sql_update, -1, &stmt, 0) != SQLITE_OK) {
|
|
||||||
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
sqlite3_bind_text(stmt, 1, url.c_str(), -1, SQLITE_STATIC);
|
sqlite3_finalize(stmt);
|
||||||
sqlite3_bind_text(stmt, 2, visitorUuid.c_str(), -1, SQLITE_STATIC);
|
if (id != -1) { // 更新记录
|
||||||
|
const char *updateQuery =
|
||||||
|
"UPDATE visit_analysis SET last_user_agent = ?, last_view_time = ?, page_view_count = ? WHERE id = ?";
|
||||||
|
if (sqlite3_prepare_v2(m_sqlite3, updateQuery, -1, &stmt, 0) != SQLITE_OK) {
|
||||||
|
LOG(error) << "Failed to prepare update statement: " << sqlite3_errmsg(m_sqlite3);
|
||||||
|
}
|
||||||
|
sqlite3_bind_text(stmt, 1, userAgent.c_str(), -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_int64(stmt, 2, time);
|
||||||
|
sqlite3_bind_int(stmt, 3, page_view_count + 1);
|
||||||
|
sqlite3_bind_int(stmt, 4, id);
|
||||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||||
LOG(error) << "Failed to execute statement: " << sqlite3_errmsg(m_sqlite3);
|
LOG(error) << "Failed to update record: " << sqlite3_errmsg(m_sqlite3);
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else { // 记录不存在,执行INSERT语句
|
sqlite3_finalize(stmt);
|
||||||
sqlite3_finalize(stmt); // 释放SELECT语句的资源
|
} else { // 插入新记录
|
||||||
const char *sql_insert = "INSERT INTO visit_analysis (url, visitor_uuid, page_view_count) VALUES (?, ?, 1)";
|
const char *insertQuery = "INSERT INTO visit_analysis (url, visitor_uuid, last_user_agent, last_view_time, "
|
||||||
if (sqlite3_prepare_v2(m_sqlite3, sql_insert, -1, &stmt, 0) != SQLITE_OK) {
|
"page_view_count) VALUES (?, ?, ?, ?, 1)";
|
||||||
LOG(error) << "Failed to prepare statement: " << sqlite3_errmsg(m_sqlite3);
|
if (sqlite3_prepare_v2(m_sqlite3, insertQuery, -1, &stmt, 0) != SQLITE_OK) {
|
||||||
return;
|
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, url.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);
|
||||||
if (sqlite3_step(stmt) != SQLITE_DONE) { // 执行INSERT语句
|
sqlite3_bind_text(stmt, 3, userAgent.c_str(), -1, SQLITE_STATIC);
|
||||||
LOG(error) << "Failed to execute statement: " << sqlite3_errmsg(m_sqlite3);
|
sqlite3_bind_int64(stmt, 4, time);
|
||||||
sqlite3_finalize(stmt);
|
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||||
return;
|
LOG(error) << "Failed to insert record: " << sqlite3_errmsg(m_sqlite3) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// 释放语句资源
|
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::clearVisitRecord() {
|
void Database::clearVisitRecord() {
|
||||||
@ -261,16 +264,17 @@ void Database::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *message = nullptr;
|
char *message = nullptr;
|
||||||
const char *sql_create_visit_analysis = R"(
|
sql = R"(
|
||||||
CREATE TABLE IF NOT EXISTS visit_analysis (
|
CREATE TABLE IF NOT EXISTS visit_analysis (
|
||||||
id INTEGER NOT NULL,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
url TEXT NOT NULL,
|
url TEXT NOT NULL,
|
||||||
visitor_uuid TEXT NOT NULL,
|
visitor_uuid TEXT NOT NULL,
|
||||||
page_view_count INTEGER NOT NULL,
|
last_user_agent TEXT NOT NULL,
|
||||||
PRIMARY KEY (id)
|
last_view_time INTEGER NOT NULL,
|
||||||
|
page_view_count INTEGER NOT NULL
|
||||||
);
|
);
|
||||||
)";
|
)";
|
||||||
result = sqlite3_exec(m_sqlite3, sql_create_visit_analysis, 0, 0, &message);
|
result = sqlite3_exec(m_sqlite3, sql, 0, 0, &message);
|
||||||
if (result != SQLITE_OK) {
|
if (result != SQLITE_OK) {
|
||||||
LOG(error) << "Failed to create table: " << message << std::endl;
|
LOG(error) << "Failed to create table: " << message << std::endl;
|
||||||
sqlite3_free(message);
|
sqlite3_free(message);
|
||||||
|
@ -27,7 +27,8 @@ public:
|
|||||||
bool removeTask(int id);
|
bool removeTask(int id);
|
||||||
void setTaskFinished(int id, bool finished, uint64_t finishedTime);
|
void setTaskFinished(int id, bool finished, uint64_t finishedTime);
|
||||||
|
|
||||||
void updateVisitCount(const std::string &url, const std::string &visitorUuid);
|
void updateVisitCount(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
|
||||||
|
int64_t time);
|
||||||
void clearVisitRecord();
|
void clearVisitRecord();
|
||||||
VisitAnalysis visitAnalysisData(const std::string &url);
|
VisitAnalysis visitAnalysisData(const std::string &url);
|
||||||
VisitAnalysis siteVisitAnalysisData();
|
VisitAnalysis siteVisitAnalysisData();
|
||||||
|
@ -21,11 +21,12 @@ BOOST_AUTO_TEST_CASE(DatabaseTest) {
|
|||||||
auto items = database.homeBoxItems();
|
auto items = database.homeBoxItems();
|
||||||
BOOST_CHECK_EQUAL(items.size(), 1);
|
BOOST_CHECK_EQUAL(items.size(), 1);
|
||||||
|
|
||||||
auto now = duration_cast<seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
auto now = std::chrono::system_clock::now();
|
||||||
database.setTaskFinished(1, true, now);
|
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
|
||||||
|
database.setTaskFinished(1, true, now_time);
|
||||||
|
|
||||||
database.updateVisitCount("/note", "uuid_123");
|
database.updateVisitCount("/note", "uuid_123", "chrome", now_time);
|
||||||
database.updateVisitCount("/note/1", "uuid_1232");
|
database.updateVisitCount("/note/1", "uuid_1232", "chrome", now_time);
|
||||||
database.updateVisitCount("/note", "uuid_123");
|
database.updateVisitCount("/note", "uuid_123", "chrome", now_time);
|
||||||
database.updateVisitCount("/note", "uuid_1234");
|
database.updateVisitCount("/note", "uuid_1234", "chrome", now_time);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user