From d4dedb92ddb34f8a861529fe74417a0a0a880da5 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Tue, 24 May 2016 20:08:23 +0300 Subject: [PATCH] Add user rating getter. --- editor/editor.pro | 2 + editor/editor_tests/editor_tests.pro | 1 + editor/editor_tests/user_stats_test.cpp | 20 ++++++++ editor/user_stats.cpp | 68 +++++++++++++++++++++++++ editor/user_stats.hpp | 30 +++++++++++ 5 files changed, 121 insertions(+) create mode 100644 editor/editor_tests/user_stats_test.cpp create mode 100644 editor/user_stats.cpp create mode 100644 editor/user_stats.hpp diff --git a/editor/editor.pro b/editor/editor.pro index 0491b9262a..79be0528bc 100644 --- a/editor/editor.pro +++ b/editor/editor.pro @@ -17,6 +17,7 @@ SOURCES += \ osm_feature_matcher.cpp \ server_api.cpp \ ui2oh.cpp \ + user_stats.cpp \ xml_feature.cpp \ HEADERS += \ @@ -28,5 +29,6 @@ HEADERS += \ osm_feature_matcher.hpp \ server_api.hpp \ ui2oh.hpp \ + user_stats.hpp \ xml_feature.hpp \ yes_no_unknown.hpp \ diff --git a/editor/editor_tests/editor_tests.pro b/editor/editor_tests/editor_tests.pro index cc7090c2d2..f4ead74e60 100644 --- a/editor/editor_tests/editor_tests.pro +++ b/editor/editor_tests/editor_tests.pro @@ -21,4 +21,5 @@ SOURCES += \ osm_feature_matcher_test.cpp \ server_api_test.cpp \ ui2oh_test.cpp \ + user_stats_test.cpp \ xml_feature_test.cpp \ diff --git a/editor/editor_tests/user_stats_test.cpp b/editor/editor_tests/user_stats_test.cpp new file mode 100644 index 0000000000..aae2ecbf46 --- /dev/null +++ b/editor/editor_tests/user_stats_test.cpp @@ -0,0 +1,20 @@ +#include "testing/testing.hpp" + +#include "editor/user_stats.hpp" + +namespace editor +{ +namespace +{ +UNIT_TEST(UserStats_Smoke) +{ + // This user made only two changes and the possibility of further changes is very low. + UserStats userStats("Vladimir BI"); + TEST(userStats.GetUpdateStatus(), ()); + TEST(userStats.IsChangesCountInitialized(), ()); + TEST(userStats.IsRankInitialized(), ()); + TEST_EQUAL(userStats.GetChangesCount(), 2, ()); + TEST_GREATER_OR_EQUAL(userStats.GetRank(), 5762, ()); +} +} // namespace +} // namespace editor diff --git a/editor/user_stats.cpp b/editor/user_stats.cpp new file mode 100644 index 0000000000..dbfe4640d0 --- /dev/null +++ b/editor/user_stats.cpp @@ -0,0 +1,68 @@ +#include "editor/user_stats.hpp" + +#include "coding/url_encode.hpp" + +#include "base/logging.hpp" + +#include "3party/Alohalytics/src/http_client.h" +#include "3party/pugixml/src/pugixml.hpp" + +using TRequest = alohalytics::HTTPClientPlatformWrapper; + + +namespace +{ +string const kUserStatsUrl = "http://py.osmz.ru/mmwatch/user?format=xml"; +auto constexpr kUninitialized = -1; +} // namespace + +namespace editor +{ +UserStats::UserStats(string const & userName) + : m_userName(userName), m_changesCount(kUninitialized), m_rank(kUninitialized) +{ + m_updateStatus = Update(); +} + +bool UserStats::IsChangesCountInitialized() const +{ + return m_changesCount != kUninitialized; +} + +bool UserStats::IsRankInitialized() const +{ + return m_rank != kUninitialized; +} + +bool UserStats::Update() +{ + auto const url = kUserStatsUrl + "&name=" + UrlEncode(m_userName); + TRequest request(url); + + if (!request.RunHTTPRequest()) + { + LOG(LWARNING, ("Network error while connecting to", url)); + return false; + } + + if (request.error_code() != 200) + { + LOG(LWARNING, ("Server return", request.error_code(), "for url", url)); + return false; + } + + auto const response = request.server_response(); + + pugi::xml_document document; + if (!document.load_buffer(response.data(), response.size())) + { + LOG(LWARNING, ("Cannot parse server response:", response)); + return false; + } + + m_changesCount = document.select_node("mmwatch/edits/@value").attribute().as_int(kUninitialized); + m_rank = document.select_node("mmwatch/rank/@value").attribute().as_int(kUninitialized); + + return true; +} +} // namespace editor diff --git a/editor/user_stats.hpp b/editor/user_stats.hpp new file mode 100644 index 0000000000..38f714bdcd --- /dev/null +++ b/editor/user_stats.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "std/cstdint.hpp" +#include "std/string.hpp" + +namespace editor +{ +class UserStats +{ +public: + explicit UserStats(string const & userName); + + bool IsChangesCountInitialized() const; + bool IsRankInitialized() const; + + int32_t GetChangesCount() const { return m_changesCount; } + int32_t GetRank() const { return m_rank; } + + bool GetUpdateStatus() const { return m_updateStatus; } + bool Update(); + +private: + string m_userName; + int32_t m_changesCount; + int32_t m_rank; + + /// True if last update was successful. + bool m_updateStatus; +}; +} // namespace editor