From 819f7361f9f9d86bcf1a1d2e784c44c9560e5f28 Mon Sep 17 00:00:00 2001 From: Arsentiy Milchakov Date: Thu, 9 Feb 2017 14:24:20 +0300 Subject: [PATCH] facebook banners are added to place page --- data/banners.txt | 51 ---- defines.hpp | 1 - indexer/banners.cpp | 233 ------------------ indexer/banners.hpp | 61 +---- indexer/indexer.pro | 1 - indexer/indexer_tests/banners_test.cpp | 70 ------ indexer/indexer_tests/indexer_tests.pro | 1 - iphone/Maps/Maps.xcodeproj/project.pbxproj | 8 - map/framework.cpp | 5 - map/framework.hpp | 3 - map/place_page_info.cpp | 57 ++--- map/place_page_info.hpp | 11 +- partners_api/CMakeLists.txt | 2 + partners_api/facebook_ads.cpp | 99 ++++++++ partners_api/facebook_ads.hpp | 46 ++++ partners_api/partners_api.pro | 2 + .../partners_api_tests/CMakeLists.txt | 1 + .../partners_api_tests/facebook_tests.cpp | 43 ++++ .../partners_api_tests/partners_api_tests.pro | 3 +- .../indexer/indexer.xcodeproj/project.pbxproj | 4 - .../partners_api.xcodeproj/project.pbxproj | 12 + 21 files changed, 243 insertions(+), 471 deletions(-) delete mode 100644 data/banners.txt delete mode 100644 indexer/banners.cpp delete mode 100644 indexer/indexer_tests/banners_test.cpp create mode 100644 partners_api/facebook_ads.cpp create mode 100644 partners_api/facebook_ads.hpp create mode 100644 partners_api/partners_api_tests/facebook_tests.cpp diff --git a/data/banners.txt b/data/banners.txt deleted file mode 100644 index 615b3ebf73..0000000000 --- a/data/banners.txt +++ /dev/null @@ -1,51 +0,0 @@ -# List of banner types. -# -# Each section in [square_quotes] corresponds to classificator type sponsored|banner|section_name. -# Inside a section, use following variables: -# - start=YYYY-MM-DD and end=YYYY-MM-DD: banner visibility period. -# - url=http://...: default banner URL, use templated vars in {quotes}. -# - icon: icon URL. -# - messages: base substring for messages, default is "banner_sectionname". -# Other variables can be used in URL templates. - -[lamoda_ru] -end = 2017-06-01 -url = http://fas.st/l1YJbD -messages = banner_lamoda - -[lamoda_ua] -end = 2017-06-01 -url = http://fas.st/naNtn -messages = banner_lamoda - -[deliveryclub] -end = 2017-06-01 -url = http://fas.st/VtumFw - -[tutu] -end = 2017-06-01 -url = http://fas.st/S9AciK - -[geerbest_uk] -end = 2017-06-01 -messages = banner_geerbest - -[geerbest_fr] -end = 2017-06-01 -messages = banner_geerbest - -[geerbest_de] -end = 2017-06-01 -messages = banner_geerbest - -[rentalcars] -end = 2017-06-01 - -[viator] -end = 2017-06-01 -url = https://is.gd/UoIIyn - -[raileurope] -end = 2017-06-01 -url = http://www.anrdoezrs.net/links/8196243/type/dlg/fragment/%2Fptp_request/https://mobile.raileurope.com/app/index.html -messages = banner_tutu diff --git a/defines.hpp b/defines.hpp index b92d37b79c..ea9796a2b4 100644 --- a/defines.hpp +++ b/defines.hpp @@ -81,6 +81,5 @@ #define REPLACED_TAGS_FILE "replaced_tags.txt" #define MIXED_TAGS_FILE "mixed_tags.txt" -#define BANNERS_FILE "banners.txt" #define LOCALIZATION_DESCRIPTION_SUFFIX " Description" diff --git a/indexer/banners.cpp b/indexer/banners.cpp deleted file mode 100644 index 7f1561cecd..0000000000 --- a/indexer/banners.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include "indexer/banners.hpp" -#include "indexer/classificator.hpp" -#include "indexer/feature.hpp" - -#include "platform/platform.hpp" - -#include "coding/reader_streambuf.hpp" - -#include "base/stl_add.hpp" -#include "base/string_utils.hpp" - -#include "std/iomanip.hpp" - -#include "defines.hpp" - -namespace -{ -time_t constexpr kEternity = 0; - -// Convert ISO date to unix time. -bool StringToTimestamp(string const & s, time_t & result) -{ - istringstream is(s); - tm time; - is >> get_time(&time, "%Y-%m-%d"); - CHECK(!is.fail(), ("Wrong date format:", s, "(expecting YYYY-MM-DD)")); - - time.tm_sec = time.tm_min = time.tm_hour = 0; - - time_t timestamp = mktime(&time); - if (timestamp < 0) - return false; - - result = timestamp; - return true; -} -} // namespace - -namespace banner -{ -string Banner::GetProperty(string const & name) const -{ - if (name == "lang") - { - return "ru"; // TODO(@zverik): this variable, {mwmlang}, {country} etc. - } - else - { - auto const property = m_properties.find(name); - if (property != m_properties.end()) - return property->second; - } - return {}; -} - -Banner::Banner(string const & id) - : m_id(id), m_messageBase("banner_" + id), m_activeAfter(time(nullptr)), m_activeBefore(kEternity) -{ -} - -bool Banner::IsActive() const -{ - if (IsEmpty()) - return false; - time_t const now = time(nullptr); - return now >= m_activeAfter && (m_activeBefore == kEternity || now < m_activeBefore); -} - -void Banner::SetProperty(string const & name, string const & value) -{ - if (name == "messages") - { - m_messageBase = value; - } - else if (name == "icon") - { - m_iconName = value; - } - else if (name == "url") - { - CHECK(strings::StartsWith(value, "http://") || strings::StartsWith(value, "https://"), - ("URL without a protocol for banner", m_id)); - m_defaultUrl = value; - } - else if (name == "start") - { - if (!StringToTimestamp(value, m_activeAfter)) - LOG(LERROR, ("Wrong start date", value, "for banner", m_id)); - } - else if (name == "end") - { - if (!StringToTimestamp(value, m_activeBefore)) - LOG(LERROR, ("Wrong end date", value, "for banner", m_id)); - else - m_activeBefore += 24 * 60 * 60; // Add a day so we don't miss one - } - else - { - m_properties.emplace(make_pair(name, value)); - } -} - -string Banner::GetFormattedUrl(string const & url) const -{ - string baseUrl = url.empty() ? m_defaultUrl : url; - auto start = baseUrl.find('{'); - while (start != string::npos) - { - auto end = baseUrl.find('}', start + 1); - if (end == string::npos) - break; - string value = GetProperty(baseUrl.substr(start + 1, end - start - 1)); - if (!value.empty()) - { - baseUrl.replace(start, end - start + 1, value); - end -= end - start + 1 - value.length(); - } - start = baseUrl.find('{', end + 1); - } - return baseUrl; -} - -void BannerSet::ReadBanners(istream & s) -{ - m_banners.clear(); - - Banner banner; - string type; - int lineNumber = 1; - for (string line; getline(s, line); ++lineNumber) - { - strings::Trim(line); - if (line.empty() || line.front() == '#') - continue; - - auto const equals = line.find('='); - if (equals == string::npos) - { - // Section header, should be in square brackets. - CHECK(line.front() == '[' && line.back() == ']', ("Unknown syntax at line", lineNumber)); - strings::Trim(line, " \t[]"); - CHECK(!line.empty(), ("Empty banner ID at line", lineNumber)); - if (!banner.IsEmpty()) - Add(banner, type); - banner = Banner(line); - type = "sponsored-banner-" + line; - } - else - { - // Variable definition, must be inside a section. - CHECK(!banner.IsEmpty(), ("Variable definition outside a section at line", lineNumber)); - string name = line.substr(0, equals); - string value = line.substr(equals + 1); - strings::Trim(name); - CHECK(!name.empty(), ("Empty variable name at line", lineNumber)); - strings::Trim(value); - if (name == "type") - type = value; - else - banner.SetProperty(name, value); - } - } - if (!banner.IsEmpty()) - Add(banner, type); -} - -void BannerSet::Add(Banner const & banner, string const & type) -{ - vector v; - strings::Tokenize(type, "-", MakeBackInsertFunctor(v)); - uint32_t const ctype = classif().GetTypeByPathSafe(v); - if (ctype == 0) - { - LOG(LWARNING, ("Missing type", type, "for a banner")); - } - else - { - CHECK(m_banners.find(ctype) == m_banners.end(), ("Duplicate banner type", type)); - m_banners.emplace(make_pair(ctype, banner)); - } -} - -bool BannerSet::HasBannerForType(uint32_t type) const -{ - return m_banners.find(type) != m_banners.end(); -} - -Banner const & BannerSet::GetBannerForType(uint32_t type) const -{ - auto const result = m_banners.find(type); - CHECK(result != m_banners.end(), ("GetBannerForType() for absent banner")); - return result->second; -} - -bool BannerSet::HasBannerForFeature(FeatureType const & ft) const -{ - bool result = false; - ft.ForEachType([this, &result](uint32_t type) - { - if (!result && HasBannerForType(type)) - result = true; - }); - return result; -} - -Banner const & BannerSet::GetBannerForFeature(FeatureType const & ft) const -{ - vector types; - ft.ForEachType([this, &types](uint32_t type) - { - if (types.empty() && HasBannerForType(type)) - types.push_back(type); - }); - CHECK(!types.empty(), ("No banners for the feature", ft)); - return GetBannerForType(types.front()); -} - -void BannerSet::LoadBanners() -{ - try - { - auto reader = GetPlatform().GetReader(BANNERS_FILE); - ReaderStreamBuf buffer(move(reader)); - istream s(&buffer); - ReadBanners(s); - } - catch (FileAbsentException const &) - { - LOG(LWARNING, ("No", BANNERS_FILE, "found")); - return; - } -} -} // namespace banner diff --git a/indexer/banners.hpp b/indexer/banners.hpp index 50f2164cd8..1c4805f504 100644 --- a/indexer/banners.hpp +++ b/indexer/banners.hpp @@ -1,60 +1,21 @@ #pragma once -#include "std/ctime.hpp" -#include "std/iostream.hpp" -#include "std/string.hpp" -#include "std/unordered_map.hpp" +#include -class FeatureType; - -namespace banner +namespace banners { -class Banner +struct Banner { -public: - Banner() = default; - explicit Banner(string const & id); + enum class Type : uint8_t + { + None = 0, + Facebook = 1 + }; - bool IsEmpty() const { return m_id.empty(); } - string GetMessageBase() const { return m_messageBase; } - string GetIconName() const { return m_iconName; } - string GetDefaultUrl() const { return m_defaultUrl; } - string GetId() const { return m_id; } - bool IsActive() const; + Banner(Type t, std::string id) : m_type(t), m_bannerId(id) {} - /// Replaces inline variables in the URL, uses the default banner URL if url is not specified. - string GetFormattedUrl(string const & url = {}) const; - /// Usually called from BannerSet. - void SetProperty(string const & name, string const & value); - -private: - string m_id; - string m_messageBase; - string m_iconName; - string m_defaultUrl; - time_t m_activeAfter; - time_t m_activeBefore; - unordered_map m_properties; - - string GetProperty(string const & name) const; -}; - -class BannerSet -{ -public: - void LoadBanners(); - void ReadBanners(istream & s); - - bool HasBannerForType(uint32_t type) const; - Banner const & GetBannerForType(uint32_t type) const; - - bool HasBannerForFeature(FeatureType const & ft) const; - Banner const & GetBannerForFeature(FeatureType const & ft) const; - -private: - unordered_map m_banners; - - void Add(Banner const & banner, string const & type); + Type m_type = Type::None; + std::string m_bannerId; }; } diff --git a/indexer/indexer.pro b/indexer/indexer.pro index 4eddc95282..cfb77f0945 100644 --- a/indexer/indexer.pro +++ b/indexer/indexer.pro @@ -11,7 +11,6 @@ include($$ROOT_DIR/common.pri) SOURCES += \ altitude_loader.cpp \ - banners.cpp \ categories_holder.cpp \ categories_holder_loader.cpp \ categories_index.cpp \ diff --git a/indexer/indexer_tests/banners_test.cpp b/indexer/indexer_tests/banners_test.cpp deleted file mode 100644 index 62654e3777..0000000000 --- a/indexer/indexer_tests/banners_test.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "testing/testing.hpp" - -#include "indexer/banners.hpp" -#include "indexer/classificator.hpp" -#include "indexer/classificator_loader.hpp" - -#include "std/iostream.hpp" - -using namespace banner; - -UNIT_TEST(Banners_Load) -{ - char const kBanners[] = - "# comment\n" - "[abc]\n" - "icon = test.png\n" - "start=2016-07-14\n" - "type= shop-clothes \n" - "\n" - "[error]\n" - "[re_123]\n" - "type=shop-shoes\n" - "url=http://{aux}.com\n" - " \t aux=\t\ttest \n" - "[future]\n" - "type=shop-wine\n" - "start=2028-01-01\n" - "end=2028-12-31\n" - "[final]\n" - "type=shop-pet\n" - "start=2016-07-13\n" - "end=2016-07-14\n" - "\t"; - - classificator::Load(); - Classificator & c = classif(); - - BannerSet bs; - istringstream is(kBanners); - bs.ReadBanners(is); - - TEST(bs.HasBannerForType(c.GetTypeByPath({"shop", "clothes"})), ()); - Banner const & bannerAbc = bs.GetBannerForType(c.GetTypeByPath({"shop", "clothes"})); - TEST(!bannerAbc.IsEmpty(), ()); - TEST_EQUAL(bannerAbc.GetIconName(), "test.png", ()); - TEST_EQUAL(bannerAbc.GetMessageBase(), "banner_abc", ()); - TEST_EQUAL(bannerAbc.GetDefaultUrl(), "", ()); - TEST_EQUAL(bannerAbc.GetFormattedUrl("http://example.com"), "http://example.com", ()); - TEST_EQUAL(bannerAbc.GetFormattedUrl(), "", ()); - TEST(bannerAbc.IsActive(), ()); - - TEST(bs.HasBannerForType(c.GetTypeByPath({"shop", "shoes"})), ()); - Banner const & bannerRe = bs.GetBannerForType(c.GetTypeByPath({"shop", "shoes"})); - TEST(!bannerRe.IsEmpty(), ()); - TEST(bannerRe.IsActive(), ()); - TEST_EQUAL(bannerRe.GetIconName(), "", ()); - TEST_EQUAL(bannerRe.GetFormattedUrl(), "http://test.com", ()); - TEST_EQUAL(bannerRe.GetFormattedUrl("http://ex.ru/{aux}?var={v}"), "http://ex.ru/test?var={v}", ()); - - TEST(bs.HasBannerForType(c.GetTypeByPath({"shop", "wine"})), ()); - Banner const & bannerFuture = bs.GetBannerForType(c.GetTypeByPath({"shop", "wine"})); - TEST(!bannerFuture.IsEmpty(), ()); - TEST(!bannerFuture.IsActive(), ()); - - TEST(bs.HasBannerForType(c.GetTypeByPath({"shop", "pet"})), ()); - Banner const & bannerFinal = bs.GetBannerForType(c.GetTypeByPath({"shop", "pet"})); - TEST(!bannerFinal.IsEmpty(), ()); - TEST(!bannerFinal.IsActive(), ()); - TEST_EQUAL(bannerFinal.GetFormattedUrl("http://{aux}.ru"), "http://{aux}.ru", ()); -} diff --git a/indexer/indexer_tests/indexer_tests.pro b/indexer/indexer_tests/indexer_tests.pro index 79b5de4b4a..1ff165f0ac 100644 --- a/indexer/indexer_tests/indexer_tests.pro +++ b/indexer/indexer_tests/indexer_tests.pro @@ -28,7 +28,6 @@ HEADERS += \ SOURCES += \ ../../testing/testingmain.cpp \ - banners_test.cpp \ categories_test.cpp \ cell_coverer_test.cpp \ cell_id_test.cpp \ diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index c1416d4a07..aedcc4bf41 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -180,9 +180,6 @@ 3454D7E51E07F045004AF2AD /* UIView+RuntimeAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3454D7B71E07F045004AF2AD /* UIView+RuntimeAttributes.mm */; }; 3454D7E61E07F045004AF2AD /* UIView+RuntimeAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3454D7B71E07F045004AF2AD /* UIView+RuntimeAttributes.mm */; }; 3454D7E71E07F045004AF2AD /* UIView+RuntimeAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3454D7B71E07F045004AF2AD /* UIView+RuntimeAttributes.mm */; }; - 3454E05F1DF00DAE00F40F46 /* banners.txt in Resources */ = {isa = PBXBuildFile; fileRef = 3454E05E1DF00DAE00F40F46 /* banners.txt */; }; - 3454E0601DF00DC000F40F46 /* banners.txt in Resources */ = {isa = PBXBuildFile; fileRef = 3454E05E1DF00DAE00F40F46 /* banners.txt */; }; - 3454E0611DF00DC100F40F46 /* banners.txt in Resources */ = {isa = PBXBuildFile; fileRef = 3454E05E1DF00DAE00F40F46 /* banners.txt */; }; 34570A3B1B13222600E6D4FD /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 34570A3A1B13222600E6D4FD /* libz.dylib */; settings = {ATTRIBUTES = (Required, ); }; }; 34574A661E3B85F80061E839 /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34574A651E3B85F80061E839 /* ThemeManager.swift */; }; 34574A671E3B85F80061E839 /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34574A651E3B85F80061E839 /* ThemeManager.swift */; }; @@ -1456,7 +1453,6 @@ 3454D7B51E07F045004AF2AD /* UITextView+RuntimeAttributes.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UITextView+RuntimeAttributes.mm"; sourceTree = ""; }; 3454D7B61E07F045004AF2AD /* UIView+RuntimeAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+RuntimeAttributes.h"; sourceTree = ""; }; 3454D7B71E07F045004AF2AD /* UIView+RuntimeAttributes.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UIView+RuntimeAttributes.mm"; sourceTree = ""; }; - 3454E05E1DF00DAE00F40F46 /* banners.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = banners.txt; path = ../../data/banners.txt; sourceTree = ""; }; 34570A3A1B13222600E6D4FD /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; 34574A651E3B85F80061E839 /* ThemeManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = ""; }; 3462258C1DDC5DB9001E8752 /* MWMSearchNoResultsAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchNoResultsAlert.h; sourceTree = ""; }; @@ -3736,7 +3732,6 @@ FA065FC61286143F00FEA989 /* External Resources */ = { isa = PBXGroup; children = ( - 3454E05E1DF00DAE00F40F46 /* banners.txt */, F623DA6A1C9C2731006A3436 /* opening_hours_how_to_edit.html */, 6B9978341C89A316003B8AA0 /* editor.config */, 671182DE1C7F0DD400CB8177 /* countries_obsolete.txt */, @@ -3972,7 +3967,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3454E05F1DF00DAE00F40F46 /* banners.txt in Resources */, 4519503A1B7A3E070085DA05 /* patterns.txt in Resources */, 346225911DDC5FBA001E8752 /* MWMSearchNoResultsAlert.xib in Resources */, F6E2FEB41E097BA00083EBEC /* _MWMPPPSpace.xib in Resources */, @@ -4225,7 +4219,6 @@ 349C3AF01D33A96B002AC7A9 /* MWMNavigationInfoView.xib in Resources */, 6741A9741BF340DE002C974C /* resources-6plus_dark in Resources */, 34D3B04B1E389D05004100F9 /* MWMNoteCell.xib in Resources */, - 3454E0601DF00DC000F40F46 /* banners.txt in Resources */, 6741A9751BF340DE002C974C /* WorldCoasts.mwm in Resources */, 3490D2E31CE9DD2500D0B838 /* MWMSideButtonsView.xib in Resources */, 6741A9761BF340DE002C974C /* packed_polygons.bin in Resources */, @@ -4375,7 +4368,6 @@ F6E2FE6E1E097BA00083EBEC /* _MWMOHHeaderCell.xib in Resources */, F6E2FF3A1E097BA00083EBEC /* MWMSearchSuggestionCell.xib in Resources */, F6E2FE471E097BA00083EBEC /* MWMDirectionView.xib in Resources */, - 3454E0611DF00DC100F40F46 /* banners.txt in Resources */, 849CF6381DE842290024A8A5 /* MWMiPadRoutePreview.xib in Resources */, 849CF6391DE842290024A8A5 /* copyright.html in Resources */, F6E2FEB01E097BA00083EBEC /* _MWMPPPExternalTitle.xib in Resources */, diff --git a/map/framework.cpp b/map/framework.cpp index 49c5ed69a3..5918202296 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -403,8 +403,6 @@ Framework::Framework() m_displayedCategories = make_unique(GetDefaultCategories()); - m_bannerSet.LoadBanners(); - // To avoid possible races - init country info getter once in constructor. InitCountryInfoGetter(); LOG(LDEBUG, ("Country info getter initialized")); @@ -860,9 +858,6 @@ void Framework::FillInfoFromFeatureType(FeatureType const & ft, place_page::Info info.m_sponsoredDescriptionUrl = url; } - if (m_bannerSet.HasBannerForFeature(ft)) - info.m_banner = m_bannerSet.GetBannerForFeature(ft); - auto const mwmInfo = ft.GetID().m_mwmId.GetInfo(); bool const isMapVersionEditable = mwmInfo && mwmInfo->m_version.IsEditableMap(); info.m_canEditOrAdd = featureStatus != osm::Editor::FeatureStatus::Obsolete && CanEditMap() && diff --git a/map/framework.hpp b/map/framework.hpp index 4fc943a39f..c3fae40e10 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -18,7 +18,6 @@ #include "drape/oglcontextfactory.hpp" -#include "indexer/banners.hpp" #include "indexer/data_header.hpp" #include "indexer/index_helpers.hpp" #include "indexer/map_style.hpp" @@ -169,8 +168,6 @@ protected: unique_ptr m_bookingApi = make_unique(); unique_ptr m_uberApi = make_unique(); - banner::BannerSet m_bannerSet; - df::DrapeApi m_drapeApi; bool m_isRenderingEnabled; diff --git a/map/place_page_info.cpp b/map/place_page_info.cpp index 401e2765d3..38bcdfc496 100644 --- a/map/place_page_info.cpp +++ b/map/place_page_info.cpp @@ -1,6 +1,8 @@ #include "map/place_page_info.hpp" #include "map/reachable_by_taxi_checker.hpp" +#include "partners_api/facebook_ads.hpp" + #include "indexer/feature_utils.hpp" #include "indexer/osm_editor.hpp" @@ -43,13 +45,6 @@ bool Info::ShouldShowEditPlace() const bool Info::HasApiUrl() const { return !m_apiUrl.empty(); } bool Info::HasWifi() const { return GetInternet() == osm::Internet::Wlan; } -bool Info::HasBanner() const -{ - bool adForbidden = false; - UNUSED_VALUE(settings::Get("AdForbidden", adForbidden)); - return !adForbidden && !m_banner.IsEmpty() && m_banner.IsActive(); -} - string Info::FormatNewBookmarkName() const { string const title = GetTitle(); @@ -176,40 +171,26 @@ string Info::GetApproximatePricing() const return result; } -string Info::GetBannerTitleId() const +banners::Banner Info::GetBanner() const { - if (m_banner.IsEmpty()) - return {}; - return m_banner.GetMessageBase() + "_title"; + using namespace banners; + auto const bannerId = facebook::Ads::Instance().GetBannerId(m_types); + if (!bannerId.empty()) + return {Banner::Type::Facebook, bannerId}; + + return {Banner::Type::None, ""}; } -string Info::GetBannerMessageId() const -{ - if (m_banner.IsEmpty()) - return {}; - return m_banner.GetMessageBase() + "_message"; -} - -string Info::GetBannerIconId() const -{ - if (m_banner.IsEmpty()) - return {}; - return m_banner.GetIconName(); -} - -string Info::GetBannerUrl() const -{ - if (m_banner.IsEmpty()) - return {}; - return m_banner.GetFormattedUrl(m_metadata.Get(feature::Metadata::FMD_BANNER_URL)); -} - -string Info::GetBannerId() const -{ - if (m_banner.IsEmpty()) - return {}; - return m_banner.GetId(); -} +/// Deprecated, there was not only removed in order not to break the build. +/// Should be removed in nearest time. +/////////////////////////////////////////////////////////////////////////////// +bool Info::HasBanner() const { return true; } +string Info::GetBannerTitleId() const { return {}; } +string Info::GetBannerMessageId() const { return {}; } +string Info::GetBannerIconId() const { return {}; } +string Info::GetBannerUrl() const { return {}; } +string Info::GetBannerId() { return {}; } +/////////////////////////////////////////////////////////////////////////////// bool Info::IsReachableByTaxi() const { diff --git a/map/place_page_info.hpp b/map/place_page_info.hpp index 820892e00d..434ad07bb8 100644 --- a/map/place_page_info.hpp +++ b/map/place_page_info.hpp @@ -79,13 +79,17 @@ public: /// @returns string with |kPricingSymbol| signs or empty string if it isn't booking object string GetApproximatePricing() const; - /// Returns true, if the current time is within the working range of the banner. + banners::Banner GetBanner() const; + /// Deprecated, there was not only removed in order not to break the build. + /// Should be removed in nearest time. + /////////////////////////////////////////////////////////////////////////////// bool HasBanner() const; string GetBannerTitleId() const; string GetBannerMessageId() const; string GetBannerIconId() const; string GetBannerUrl() const; - string GetBannerId() const; + string GetBannerId(); + /////////////////////////////////////////////////////////////////////////////// bool IsReachableByTaxi() const; @@ -118,9 +122,6 @@ public: string m_sponsoredUrl; string m_sponsoredDescriptionUrl; - /// A banner associated with the object. - banner::Banner m_banner; - /// Which country this MapObject is in. /// For a country point it will be set to topmost node for country. storage::TCountryId m_countryId = storage::kInvalidCountryId; diff --git a/partners_api/CMakeLists.txt b/partners_api/CMakeLists.txt index 4c479606c1..86affff30b 100644 --- a/partners_api/CMakeLists.txt +++ b/partners_api/CMakeLists.txt @@ -6,6 +6,8 @@ set( SRC booking_api.hpp booking_api.cpp + facebook_ads.hpp + facebook_ads.cpp opentable_api.hpp opentable_api.cpp uber_api.hpp diff --git a/partners_api/facebook_ads.cpp b/partners_api/facebook_ads.cpp new file mode 100644 index 0000000000..decf824b42 --- /dev/null +++ b/partners_api/facebook_ads.cpp @@ -0,0 +1,99 @@ +#include "partners_api/facebook_ads.hpp" + +#include "indexer/classificator.hpp" +#include "indexer/feature_data.hpp" + +namespace facebook +{ +Ads::Ads() +{ + // Food. + AppendEntry({{"amenity", "cafe"}, + {"amenity", "fast_food"}, + {"amenity", "restaurant"}, + {"amenity", "bar"}, + {"amenity", "pub"}}, + "185237551520383_1384650164912443"); + // Shops. + AppendEntry({{"shop"}}, "185237551520383_1384650804912379"); + // City Transport. + AppendEntry({{"aerialway"}, + {"highway", "bus_stop"}, + {"highway", "speed_camera"}, + {"public_transport"}}, + "185237551520383_1384651074912352"); + // Global transport. + AppendEntry({{"aeroway"}, + {"railway"}, + {"man_made", "pier"}}, + "185237551520383_1387632484614211"); + // Hotels. + AppendEntry({{"tourism", "hotel"}, + {"tourism", "hostel"}, + {"tourism", "motel"}, + {"tourism", "apartment"}, + {"tourism", "resort"}}, + "185237551520383_1384651324912327"); + // Sights. + AppendEntry({{"tourism", "chalet"}, + {"tourism", "zoo"}, + {"tourism", "artwork"}, + {"tourism", "information"}, + {"tourism", "attraction"}, + {"tourism", "viewpoint"}, + {"tourism", "museum"}, + {"amenity", "fountain"}, + {"amenity", "theatre"}, + {"amenity", "townhall"}, + {"historic"}}, + "185237551520383_1384651734912286"); + // Large toponyms. + AppendEntry({{"place"}}, "185237551520383_1384652164912243"); + // Health. + AppendEntry({{"amenity", "dentist"}, + {"amenity", "doctors"}, + {"amenity", "clinic"}, + {"amenity", "hospital"}, + {"amenity", "pharmacy"}, + {"amenity", "veterinary"}}, + "185237551520383_1384652351578891"); + // Financial. + AppendEntry({{"amenity", "bank"}, {"amenity", "atm"}}, "185237551520383_1384652658245527"); +} + +void Ads::AppendEntry(std::vector> const & types, std::string const & id) +{ + TypesToBannerId entry; + for (auto const & type : types) + entry.m_types.emplace_back(classif().GetTypeByPath(type), type.size()); + entry.m_bannerId = id; + m_typesToBanners.push_back(move(entry)); +} + +// static +Ads const & Ads::Instance() +{ + static Ads const ads; + return ads; +} + +std::string Ads::GetBannerId(feature::TypesHolder const & types) const +{ + for (auto const & typesToBanner : m_typesToBanners) + { + for (auto const t : types) + { + auto const it = std::find_if(typesToBanner.m_types.begin(), typesToBanner.m_types.end(), + [t](TypeAndlevel const & tl) { + auto truncatedType = t; + ftype::TruncValue(truncatedType, tl.m_level); + return truncatedType == tl.m_type; + }); + + if (it != typesToBanner.m_types.end()) + return typesToBanner.m_bannerId; + } + } + return kBannerIdForOtherTypes; +} +} // namespace facebook diff --git a/partners_api/facebook_ads.hpp b/partners_api/facebook_ads.hpp new file mode 100644 index 0000000000..79151351fa --- /dev/null +++ b/partners_api/facebook_ads.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include "base/macros.hpp" + +#include +#include + +namespace feature +{ +class TypesHolder; +} + +namespace facebook +{ +// Class which match feature types and facebook banner ids. +class Ads +{ +public: + static auto constexpr kBannerIdForOtherTypes = "185237551520383_1384653421578784"; + + static Ads const & Instance(); + + std::string GetBannerId(feature::TypesHolder const & types) const; + +private: + Ads(); + void AppendEntry(std::vector> const & types, std::string const & id); + + struct TypeAndlevel + { + TypeAndlevel(uint32_t type, uint32_t level) : m_type(type), m_level(level) {} + uint32_t m_type = 0; + uint32_t m_level = 0; + }; + + struct TypesToBannerId + { + std::vector m_types; + std::string m_bannerId; + }; + + std::vector m_typesToBanners; + + DISALLOW_COPY_AND_MOVE(Ads); +}; +} // namespace facebook diff --git a/partners_api/partners_api.pro b/partners_api/partners_api.pro index 47cf571ac3..e2115494b2 100644 --- a/partners_api/partners_api.pro +++ b/partners_api/partners_api.pro @@ -10,10 +10,12 @@ include($$ROOT_DIR/common.pri) SOURCES += \ booking_api.cpp \ + facebook_ads.cpp \ opentable_api.cpp \ uber_api.cpp \ HEADERS += \ booking_api.hpp \ + facebook_ads.hpp \ opentable_api.hpp \ uber_api.hpp \ diff --git a/partners_api/partners_api_tests/CMakeLists.txt b/partners_api/partners_api_tests/CMakeLists.txt index ee7d699fcc..c801b58768 100644 --- a/partners_api/partners_api_tests/CMakeLists.txt +++ b/partners_api/partners_api_tests/CMakeLists.txt @@ -5,6 +5,7 @@ add_definitions(-DOMIM_UNIT_TEST_WITH_QT_EVENT_LOOP) set( SRC booking_tests.cpp + facebook_tests.cpp uber_tests.cpp ) diff --git a/partners_api/partners_api_tests/facebook_tests.cpp b/partners_api/partners_api_tests/facebook_tests.cpp new file mode 100644 index 0000000000..9d39fd78d0 --- /dev/null +++ b/partners_api/partners_api_tests/facebook_tests.cpp @@ -0,0 +1,43 @@ +#include "testing/testing.hpp" + +#include "indexer/classificator.hpp" +#include "indexer/classificator_loader.hpp" +#include "indexer/feature_data.hpp" + +#include "partners_api/facebook_ads.hpp" + +namespace +{ +UNIT_TEST(Facebook_GetBanner) +{ + classificator::Load(); + Classificator const & c = classif(); + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "dentist"})); + TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384652351578891", ()); + holder.Add(c.GetTypeByPath({"amenity", "pub"})); + TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384650164912443", ()); + holder.Add(c.GetTypeByPath({"amenity", "restaurant"})); + TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384650164912443", ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"tourism", "information", "map"})); + TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384651734912286", ()); + holder.Add(c.GetTypeByPath({"shop", "car_parts"})); + TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384650804912379", ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"shop", "ticket"})); + TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384650804912379", ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "toilets"})); + auto const bannerId = facebook::Ads::kBannerIdForOtherTypes; + TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), bannerId, ()); + } +} +} // namespace diff --git a/partners_api/partners_api_tests/partners_api_tests.pro b/partners_api/partners_api_tests/partners_api_tests.pro index 2764557a6d..fdc7c2027e 100644 --- a/partners_api/partners_api_tests/partners_api_tests.pro +++ b/partners_api/partners_api_tests/partners_api_tests.pro @@ -7,7 +7,7 @@ ROOT_DIR = ../.. INCLUDEPATH *= $$ROOT_DIR/3party/jansson/src -DEPENDENCIES = partners_api platform coding base jansson stats_client +DEPENDENCIES = partners_api indexer platform coding geometry base jansson stats_client protobuf include($$ROOT_DIR/common.pri) @@ -27,4 +27,5 @@ win*|linux* { SOURCES += \ $$ROOT_DIR/testing/testingmain.cpp \ booking_tests.cpp \ + facebook_tests.cpp \ uber_tests.cpp \ diff --git a/xcode/indexer/indexer.xcodeproj/project.pbxproj b/xcode/indexer/indexer.xcodeproj/project.pbxproj index 826828f6ea..454193181d 100644 --- a/xcode/indexer/indexer.xcodeproj/project.pbxproj +++ b/xcode/indexer/indexer.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 0C5FEC731DDE1A140017688C /* routing_section.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C5FEC721DDE1A140017688C /* routing_section.hpp */; }; 340DF9D01C1FF04D00B5C7EC /* osm_editor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 340DF9CF1C1FF04D00B5C7EC /* osm_editor.cpp */; }; - 3454E05C1DF00D2D00F40F46 /* banners.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3454E05A1DF00D2D00F40F46 /* banners.cpp */; }; 3454E05D1DF00D2D00F40F46 /* banners.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3454E05B1DF00D2D00F40F46 /* banners.hpp */; }; 34583BC71C88552100F94664 /* cuisines.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34583BC11C88552100F94664 /* cuisines.cpp */; }; 34583BC81C88552100F94664 /* cuisines.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 34583BC21C88552100F94664 /* cuisines.hpp */; }; @@ -227,7 +226,6 @@ /* Begin PBXFileReference section */ 0C5FEC721DDE1A140017688C /* routing_section.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = routing_section.hpp; sourceTree = ""; }; 340DF9CF1C1FF04D00B5C7EC /* osm_editor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = osm_editor.cpp; sourceTree = ""; }; - 3454E05A1DF00D2D00F40F46 /* banners.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = banners.cpp; sourceTree = ""; }; 3454E05B1DF00D2D00F40F46 /* banners.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = banners.hpp; sourceTree = ""; }; 34583BC11C88552100F94664 /* cuisines.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cuisines.cpp; sourceTree = ""; }; 34583BC21C88552100F94664 /* cuisines.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cuisines.hpp; sourceTree = ""; }; @@ -627,7 +625,6 @@ 6753409C1A3F53CB00A0A8C3 /* indexer */ = { isa = PBXGroup; children = ( - 3454E05A1DF00D2D00F40F46 /* banners.cpp */, 3454E05B1DF00D2D00F40F46 /* banners.hpp */, 3D928F651D50F9FE001670E0 /* index_helpers.cpp */, 3D928F661D50F9FE001670E0 /* index_helpers.hpp */, @@ -1043,7 +1040,6 @@ 34664CF61D49FEC1003D7096 /* centers_table.cpp in Sources */, 56C74C201C749E4700B71B9F /* edits_migration.cpp in Sources */, 6753414D1A3F540F00A0A8C3 /* types_mapping.cpp in Sources */, - 3454E05C1DF00D2D00F40F46 /* banners.cpp in Sources */, 6753412A1A3F540F00A0A8C3 /* geometry_coding.cpp in Sources */, 34583BC71C88552100F94664 /* cuisines.cpp in Sources */, 675341121A3F540F00A0A8C3 /* feature_algo.cpp in Sources */, diff --git a/xcode/partners_api/partners_api.xcodeproj/project.pbxproj b/xcode/partners_api/partners_api.xcodeproj/project.pbxproj index ca60c17b5d..87dc012326 100644 --- a/xcode/partners_api/partners_api.xcodeproj/project.pbxproj +++ b/xcode/partners_api/partners_api.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 3DBC1C511E4B14810016897F /* facebook_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DBC1C501E4B14810016897F /* facebook_tests.cpp */; }; + 3DBC1C541E4B14920016897F /* facebook_ads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DBC1C521E4B14920016897F /* facebook_ads.cpp */; }; + 3DBC1C551E4B14920016897F /* facebook_ads.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3DBC1C531E4B14920016897F /* facebook_ads.hpp */; }; F67E75251DB8F06F00D6741F /* opentable_api.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F67E75231DB8F06F00D6741F /* opentable_api.cpp */; }; F67E75261DB8F06F00D6741F /* opentable_api.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F67E75241DB8F06F00D6741F /* opentable_api.hpp */; }; F6B536401DA520E40067EEA5 /* booking_api.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6B5363C1DA520E40067EEA5 /* booking_api.cpp */; }; @@ -33,6 +36,9 @@ /* Begin PBXFileReference section */ 3475E0E11DBF581B004C7E69 /* common-debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-debug.xcconfig"; path = "../common-debug.xcconfig"; sourceTree = ""; }; 3475E0E21DBF581B004C7E69 /* common-release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-release.xcconfig"; path = "../common-release.xcconfig"; sourceTree = ""; }; + 3DBC1C501E4B14810016897F /* facebook_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = facebook_tests.cpp; sourceTree = ""; }; + 3DBC1C521E4B14920016897F /* facebook_ads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = facebook_ads.cpp; sourceTree = ""; }; + 3DBC1C531E4B14920016897F /* facebook_ads.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = facebook_ads.hpp; sourceTree = ""; }; F67E75231DB8F06F00D6741F /* opentable_api.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opentable_api.cpp; sourceTree = ""; }; F67E75241DB8F06F00D6741F /* opentable_api.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = opentable_api.hpp; sourceTree = ""; }; F6B536341DA5209F0067EEA5 /* libpartners_api.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpartners_api.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -105,6 +111,8 @@ F6B5363B1DA520B20067EEA5 /* partners_api */ = { isa = PBXGroup; children = ( + 3DBC1C521E4B14920016897F /* facebook_ads.cpp */, + 3DBC1C531E4B14920016897F /* facebook_ads.hpp */, F67E75231DB8F06F00D6741F /* opentable_api.cpp */, F67E75241DB8F06F00D6741F /* opentable_api.hpp */, F6B5363C1DA520E40067EEA5 /* booking_api.cpp */, @@ -119,6 +127,7 @@ F6B536441DA521060067EEA5 /* partners_api_tests */ = { isa = PBXGroup; children = ( + 3DBC1C501E4B14810016897F /* facebook_tests.cpp */, F6B536691DA523060067EEA5 /* testingmain.cpp */, F6B536451DA5213D0067EEA5 /* booking_tests.cpp */, F6B536461DA5213D0067EEA5 /* uber_tests.cpp */, @@ -160,6 +169,7 @@ F67E75261DB8F06F00D6741F /* opentable_api.hpp in Headers */, F6B536411DA520E40067EEA5 /* booking_api.hpp in Headers */, F6B536431DA520E40067EEA5 /* uber_api.hpp in Headers */, + 3DBC1C551E4B14920016897F /* facebook_ads.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -254,7 +264,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3DBC1C511E4B14810016897F /* facebook_tests.cpp in Sources */, F6B536421DA520E40067EEA5 /* uber_api.cpp in Sources */, + 3DBC1C541E4B14920016897F /* facebook_ads.cpp in Sources */, F6B536471DA5213D0067EEA5 /* booking_tests.cpp in Sources */, F6B5366A1DA523060067EEA5 /* testingmain.cpp in Sources */, F67E75251DB8F06F00D6741F /* opentable_api.cpp in Sources */,