diff --git a/android/jni/com/mapswithme/maps/UserMarkHelper.cpp b/android/jni/com/mapswithme/maps/UserMarkHelper.cpp index f42f4096b0..d207959799 100644 --- a/android/jni/com/mapswithme/maps/UserMarkHelper.cpp +++ b/android/jni/com/mapswithme/maps/UserMarkHelper.cpp @@ -2,6 +2,8 @@ #include "map/place_page_info.hpp" +#include "partners_api/ads_engine.hpp" + #include "base/string_utils.hpp" namespace usermark_helper @@ -57,7 +59,10 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info) { jobject jbanner = nullptr; if (info.HasBanner()) - jbanner = CreateBanner(env, info.GetBanner().m_bannerId); + { + // Dummy should be changed by android developer. + jbanner = CreateBanner(env, info.GetBanners()[0].m_bannerId); + } if (info.IsBookmark()) { // public Bookmark(@IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, diff --git a/indexer/CMakeLists.txt b/indexer/CMakeLists.txt index c9efbfef20..e3f074ff67 100644 --- a/indexer/CMakeLists.txt +++ b/indexer/CMakeLists.txt @@ -6,7 +6,6 @@ set( SRC altitude_loader.cpp altitude_loader.hpp - banners.hpp categories_holder_loader.cpp categories_holder.cpp categories_holder.hpp diff --git a/indexer/banners.hpp b/indexer/banners.hpp deleted file mode 100644 index a360439376..0000000000 --- a/indexer/banners.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -namespace banners -{ -struct Banner -{ - enum class Type : uint8_t - { - None = 0, - Facebook = 1 - }; - - Banner(Type t, std::string id) : m_type(t), m_bannerId(id) {} - - Type m_type = Type::None; - std::string m_bannerId; -}; -} diff --git a/indexer/indexer.pro b/indexer/indexer.pro index 1645f67bc1..87345a9f12 100644 --- a/indexer/indexer.pro +++ b/indexer/indexer.pro @@ -64,7 +64,6 @@ SOURCES += \ HEADERS += \ altitude_loader.hpp \ - banners.hpp \ categories_holder.hpp \ categories_index.hpp \ cell_coverer.hpp \ diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 2d433daf28..40ec7254e8 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -2516,42 +2516,42 @@ 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( - 45FFD65C1E965EBE00DB854E /* liblocal_ads.a */, 340474DB1E08199D00C92850 /* 3party */, - 3462FD8A1DC1DF3A00906FD7 /* SDK */, - 3446C6761DDCA9A200146687 /* libtraffic.a */, - 34D1B6F01E95096B0057E9C7 /* libicu.a */, - 34201E0B1DC0E33100D24118 /* libtracking.a */, - 3DDB4BC31DAB98F000F4D021 /* libpartners_api.a */, - 340DC82B1C4E72C700EAA2CC /* liboauthcpp.a */, - 341F09831C20138100F18AC5 /* libpugixml.a */, - 3411387C1C15AE73002E3B3E /* libeditor.a */, - 674A7E201C0DA55E003D48E1 /* libdrape_frontend.a */, - 674A7E211C0DA55E003D48E1 /* libdrape.a */, - 674A7E221C0DA55E003D48E1 /* libsdf_image.a */, - 674A7E231C0DA55E003D48E1 /* libstb_image.a */, 6741AAA21BF356B9002C974C /* libagg.a */, 6741AAA31BF356B9002C974C /* libalohalitics.a */, 6741AAA51BF356B9002C974C /* libapi.a */, 6741AAA61BF356B9002C974C /* libbase.a */, 6741AAA71BF356B9002C974C /* libcoding.a */, + 674A7E201C0DA55E003D48E1 /* libdrape_frontend.a */, + 674A7E211C0DA55E003D48E1 /* libdrape.a */, + 3411387C1C15AE73002E3B3E /* libeditor.a */, 6741AAA81BF356B9002C974C /* libexpat.a */, 6741AAA91BF356B9002C974C /* libfreetype.a */, 6741AAAA1BF356B9002C974C /* libfribidi.a */, 6741AAAB1BF356B9002C974C /* libgeometry.a */, + 34D1B6F01E95096B0057E9C7 /* libicu.a */, 6741AAAE1BF356B9002C974C /* libindexer.a */, 6741AAAF1BF356B9002C974C /* libjansson.a */, + 45FFD65C1E965EBE00DB854E /* liblocal_ads.a */, 6741AAB11BF356B9002C974C /* libmap.a */, 6741AAB21BF356B9002C974C /* libminizip.a */, + 340DC82B1C4E72C700EAA2CC /* liboauthcpp.a */, 6741AAB31BF356B9002C974C /* libopening_hours.a */, 6741AAB41BF356B9002C974C /* libosrm.a */, + 3DDB4BC31DAB98F000F4D021 /* libpartners_api.a */, 6741AAB51BF356B9002C974C /* libplatform.a */, 6741AAB61BF356BA002C974C /* libprotobuf.a */, + 341F09831C20138100F18AC5 /* libpugixml.a */, 671E78D21E6A423300B2859B /* librouting_common.a */, 6741AAB81BF356BA002C974C /* librouting.a */, + 674A7E221C0DA55E003D48E1 /* libsdf_image.a */, 6741AAB91BF356BA002C974C /* libsearch.a */, + 674A7E231C0DA55E003D48E1 /* libstb_image.a */, 6741AABA1BF356BA002C974C /* libstorage.a */, 6741AABB1BF356BA002C974C /* libsuccinct.a */, + 34201E0B1DC0E33100D24118 /* libtracking.a */, + 3446C6761DDCA9A200146687 /* libtraffic.a */, + 3462FD8A1DC1DF3A00906FD7 /* SDK */, ); name = Frameworks; sourceTree = ""; diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm index 1475b7a96e..86fd84041c 100644 --- a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm +++ b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm @@ -9,7 +9,7 @@ #include "Framework.h" -#include "indexer/banners.hpp" +#include "partners_api/banner.hpp" #include "base/string_utils.hpp" @@ -104,7 +104,8 @@ using namespace place_page; if (network_policy::CanUseNetwork() && ![MWMSettings adForbidden] && m_info.HasBanner()) { __weak auto wSelf = self; - [[MWMBannersCache cache] get:@(m_info.GetBanner().m_bannerId.c_str()) completion:^(FBNativeAd * ad, BOOL isAsync) { + // Dummy should be changed by IOS developer + [[MWMBannersCache cache] get:@(m_info.GetBanners()[0].m_bannerId.c_str()) completion:^(FBNativeAd * ad, BOOL isAsync) { __strong auto self = wSelf; if (!self) return; @@ -302,7 +303,10 @@ using namespace place_page; - (void)dealloc { if (m_info.HasBanner()) - [[MWMBannersCache cache] bannerIsOutOfScreen:@(m_info.GetBanner().m_bannerId.c_str())]; + { + // Dummy should be changed by IOS developer + [[MWMBannersCache cache] bannerIsOutOfScreen:@(m_info.GetBanners()[0].m_bannerId.c_str())]; + } } #pragma mark - Getters diff --git a/map/framework.cpp b/map/framework.cpp index 7ac9bf3bbb..00d0d5be45 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -83,6 +83,7 @@ #include "geometry/tree4d.hpp" #include "geometry/triangle2d.hpp" +#include "partners_api/ads_engine.hpp" #include "partners_api/opentable_api.hpp" #include "base/logging.hpp" @@ -535,6 +536,8 @@ Framework::Framework(FrameworkParams const & params) m_cityFinder = make_unique(m_model.GetIndex()); + m_adsEngine = make_unique(); + InitTransliteration(); LOG(LDEBUG, ("Transliterators initialized")); } @@ -2355,6 +2358,8 @@ df::SelectionShape::ESelectedObject Framework::OnTapEventImpl(TapEvent const & t return df::SelectionShape::OBJECT_MY_POSITION; } + outInfo.m_adsEngine = m_adsEngine.get(); + df::VisualParams const & vp = df::VisualParams::Instance(); m2::AnyRectD rect; diff --git a/map/framework.hpp b/map/framework.hpp index dfd97456b0..046593ea01 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -98,6 +98,11 @@ namespace platform class NetworkPolicy; } +namespace ads +{ +class Engine; +} + /// Uncomment line to make fixed position settings and /// build version for screenshots. //#define FIXED_LOCATION @@ -892,6 +897,7 @@ public: private: std::unique_ptr m_cityFinder; + unique_ptr m_adsEngine; DECLARE_THREAD_CHECKER(m_threadChecker); }; diff --git a/map/place_page_info.cpp b/map/place_page_info.cpp index 83cffd6b27..802b76e498 100644 --- a/map/place_page_info.cpp +++ b/map/place_page_info.cpp @@ -1,7 +1,8 @@ #include "map/place_page_info.hpp" #include "map/reachable_by_taxi_checker.hpp" -#include "partners_api/facebook_ads.hpp" +#include "partners_api/ads_engine.hpp" +#include "partners_api/banner.hpp" #include "indexer/feature_utils.hpp" #include "indexer/osm_editor.hpp" @@ -174,20 +175,21 @@ string Info::GetApproximatePricing() const bool Info::HasBanner() const { + if (!m_adsEngine) + return false; + if (IsMyPosition()) return false; - return facebook::Ads::Instance().HasBanner(m_types); + return m_adsEngine->HasBanner(m_types); } -banners::Banner Info::GetBanner() const +vector Info::GetBanners() const { - using namespace banners; - auto const bannerId = facebook::Ads::Instance().GetBannerId(m_types); - if (!bannerId.empty()) - return {Banner::Type::Facebook, bannerId}; + if (!m_adsEngine) + return {}; - return {Banner::Type::None, ""}; + return m_adsEngine->GetBanners(m_types); } bool Info::IsReachableByTaxi() const diff --git a/map/place_page_info.hpp b/map/place_page_info.hpp index 4caeca8282..8b0cefe12a 100644 --- a/map/place_page_info.hpp +++ b/map/place_page_info.hpp @@ -4,7 +4,6 @@ #include "storage/index.hpp" -#include "indexer/banners.hpp" #include "indexer/feature_data.hpp" #include "indexer/feature_meta.hpp" #include "indexer/map_object.hpp" @@ -14,6 +13,14 @@ #include "geometry/point2d.hpp" #include "std/string.hpp" +#include "std/unique_ptr.hpp" +#include "std/vector.hpp" + +namespace ads +{ +struct Banner; +class Engine; +} namespace place_page { @@ -81,7 +88,7 @@ public: string GetApproximatePricing() const; bool HasBanner() const; - banners::Banner GetBanner() const; + vector GetBanners() const; bool IsReachableByTaxi() const; @@ -132,5 +139,7 @@ public: string m_localizedRatingString; string m_bookingSearchUrl; + /// Ads source. + ads::Engine * m_adsEngine = nullptr; }; } // namespace place_page diff --git a/partners_api/CMakeLists.txt b/partners_api/CMakeLists.txt index 86affff30b..166ab6fc56 100644 --- a/partners_api/CMakeLists.txt +++ b/partners_api/CMakeLists.txt @@ -4,14 +4,21 @@ include_directories(${OMIM_ROOT}/3party/jansson/src) set( SRC - booking_api.hpp + ads_base.cpp + ads_base.hpp + ads_engine.cpp + ads_engine.hpp + banner.hpp booking_api.cpp - facebook_ads.hpp + booking_api.hpp facebook_ads.cpp - opentable_api.hpp + facebook_ads.hpp opentable_api.cpp - uber_api.hpp + opentable_api.hpp + rb_ads.cpp + rb_ads.hpp uber_api.cpp + uber_api.hpp ) add_library(${PROJECT_NAME} ${SRC}) diff --git a/partners_api/ads_base.cpp b/partners_api/ads_base.cpp new file mode 100644 index 0000000000..0000146933 --- /dev/null +++ b/partners_api/ads_base.cpp @@ -0,0 +1,85 @@ +#include "partners_api/ads_base.hpp" + +#include "indexer/classificator.hpp" +#include "indexer/feature_data.hpp" + +#include + +namespace +{ +template +typename Container::const_iterator +FindType(feature::TypesHolder const & types, Container const & cont) +{ + for (auto const t : types) + { + for (auto level = ftype::GetLevel(t); level; --level) + { + auto truncatedType = t; + ftype::TruncValue(truncatedType, level); + auto const it = cont.find(truncatedType); + + if (it != cont.end()) + return it; + } + } + + return cont.cend(); +} +} // namespace + +namespace ads +{ +Container::Container() { AppendExcludedTypes({{"sponsored", "booking"}}); } + +void Container::AppendEntry(std::vector> const & types, + std::string const & id) +{ + for (auto const & type : types) + { +#if defined(DEBUG) + feature::TypesHolder holder; + holder.Assign(classif().GetTypeByPath(type)); + ASSERT(FindType(holder, m_typesToBanners) == m_typesToBanners.cend(), + ("Banner id for this type already exists", type)); +#endif + m_typesToBanners.emplace(classif().GetTypeByPath(type), id); + } +} + +void Container::AppendExcludedTypes(std::vector> const & types) +{ + for (auto const & type : types) + { +#if defined(DEBUG) + feature::TypesHolder holder; + holder.Assign(classif().GetTypeByPath(type)); + ASSERT(FindType(holder, m_excludedTypes) == m_excludedTypes.cend(), + ("Excluded banner type already exists")); +#endif + m_excludedTypes.emplace(classif().GetTypeByPath(type)); + } +} + +bool Container::HasBanner(feature::TypesHolder const & types) const +{ + return FindType(types, m_excludedTypes) == m_excludedTypes.cend(); +} + +std::string Container::GetBannerId(feature::TypesHolder const & types) const +{ + if (!HasBanner(types)) + return {}; + + auto const it = FindType(types, m_typesToBanners); + if (it != m_typesToBanners.cend()) + return it->second; + + return GetBannerIdForOtherTypes(); +} + +std::string Container::GetBannerIdForOtherTypes() const +{ + return {}; +} +} // namespace ads diff --git a/partners_api/ads_base.hpp b/partners_api/ads_base.hpp new file mode 100644 index 0000000000..536a8a818e --- /dev/null +++ b/partners_api/ads_base.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "indexer/feature_data.hpp" + +#include "base/macros.hpp" + +#include +#include +#include +#include + +namespace ads +{ +class ContainerBase +{ +public: + virtual ~ContainerBase() = default; + virtual bool HasBanner(feature::TypesHolder const & types) const = 0; + virtual std::string GetBannerId(feature::TypesHolder const & types) const = 0; + virtual std::string GetBannerIdForOtherTypes() const = 0; +}; + +// Class which matches feature types and banner ids. +class Container : public ContainerBase +{ +public: + Container(); + + // ContainerBase overrides: + bool HasBanner(feature::TypesHolder const & types) const override; + std::string GetBannerId(feature::TypesHolder const & types) const override; + std::string GetBannerIdForOtherTypes() const override; + +protected: + void AppendEntry(std::vector> const & types, std::string const & id); + void AppendExcludedTypes(std::vector> const & types); + +private: + std::unordered_map m_typesToBanners; + std::unordered_set m_excludedTypes; + + DISALLOW_COPY(Container); +}; +} // namespace ads diff --git a/partners_api/ads_engine.cpp b/partners_api/ads_engine.cpp new file mode 100644 index 0000000000..a1ddef5d05 --- /dev/null +++ b/partners_api/ads_engine.cpp @@ -0,0 +1,38 @@ +#include "partners_api/ads_engine.hpp" +#include "partners_api/facebook_ads.hpp" +#include "partners_api/rb_ads.hpp" + +#include "base/stl_add.hpp" + +#include + +namespace ads +{ +Engine::Engine() +{ + // The banner systems are placed by priority. First has a top priority. + m_containers.emplace_back(Banner::Type::RB, my::make_unique()); + m_containers.emplace_back(Banner::Type::Facebook, my::make_unique()); +} + +bool Engine::HasBanner(feature::TypesHolder const & types) const +{ + return std::any_of(m_containers.cbegin(), m_containers.cend(), [&types](ContainerItem const & item) + { + return item.m_container->HasBanner(types); + }); +} + +std::vector Engine::GetBanners(feature::TypesHolder const & types) const +{ + std::vector banners; + for (auto const & item : m_containers) + { + auto const bannerId = item.m_container->GetBannerId(types); + if (!bannerId.empty()) + banners.emplace_back(item.m_type, bannerId); + } + + return banners; +} +} // namespace ads diff --git a/partners_api/ads_engine.hpp b/partners_api/ads_engine.hpp new file mode 100644 index 0000000000..93cfe76dc7 --- /dev/null +++ b/partners_api/ads_engine.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "partners_api/ads_base.hpp" +#include "partners_api/banner.hpp" + +#include +#include +#include + +namespace ads +{ +class Engine +{ +public: + Engine(); + + bool HasBanner(feature::TypesHolder const & types) const; + std::vector GetBanners(feature::TypesHolder const & types) const; + +private: + using ContainerPtr = std::unique_ptr; + + struct ContainerItem + { + ContainerItem(Banner::Type type, ContainerPtr && container) + : m_type(type), m_container(std::move(container)) + { + } + + Banner::Type m_type; + ContainerPtr m_container; + }; + + std::vector m_containers; +}; +} // namespace ads diff --git a/partners_api/banner.hpp b/partners_api/banner.hpp new file mode 100644 index 0000000000..fe6f494a02 --- /dev/null +++ b/partners_api/banner.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include + +namespace ads +{ +struct Banner +{ + enum class Type : uint8_t + { + None = 0, + Facebook = 1, + RB = 2 + }; + + Banner() = default; + Banner(Type t, std::string const & id) : m_type(t), m_bannerId(id) {} + + Type m_type = Type::None; + std::string m_bannerId; +}; + +inline std::string DebugPrint(Banner::Type type) +{ + switch (type) + { + case Banner::Type::None: return "None"; + case Banner::Type::Facebook: return "Facebook"; + case Banner::Type::RB: return "RB"; + } +} +} // namespace ads diff --git a/partners_api/facebook_ads.cpp b/partners_api/facebook_ads.cpp index 347836308f..ebf026bef9 100644 --- a/partners_api/facebook_ads.cpp +++ b/partners_api/facebook_ads.cpp @@ -1,8 +1,5 @@ #include "partners_api/facebook_ads.hpp" -#include "indexer/classificator.hpp" -#include "indexer/feature_data.hpp" - namespace { #if defined(OMIM_OS_IPHONE) @@ -17,6 +14,7 @@ namespace auto const kFinancialPlacementId = "185237551520383_1425358064174986"; auto const kEntertainmentPlacementId = "185237551520383_1425358274174965"; auto const kBuildingPlacementId = "185237551520383_1425358410841618"; + auto const kBannerIdForOtherTypes = "185237551520383_1425363454174447"; #else auto const kFoodPlacementId = "185237551520383_1384650164912443"; auto const kShopsPlacementId = "185237551520383_1384650804912379"; @@ -29,30 +27,13 @@ namespace auto const kFinancialPlacementId = "185237551520383_1384652658245527"; auto const kEntertainmentPlacementId = "185237551520383_1384653001578826"; auto const kBuildingPlacementId = "185237551520383_1419317661445693"; + auto const kBannerIdForOtherTypes = "185237551520383_1384653421578784"; #endif - -using namespace facebook; - -template -It FindType(feature::TypesHolder const & types, It first, It last) -{ - for (auto const t : types) - { - auto const it = std::find_if(first, last, [t](TypeAndlevel const & tl) { - auto truncatedType = t; - ftype::TruncValue(truncatedType, tl.m_level); - return truncatedType == tl.m_type; - }); - if (it != last) - return it; - } - return last; -} } // namespace -namespace facebook +namespace ads { -Ads::Ads() +Facebook::Facebook() { AppendEntry({{"amenity", "cafe"}, {"amenity", "fast_food"}, @@ -91,7 +72,6 @@ Ads::Ads() {"tourism", "viewpoint"}, {"tourism", "museum"}, {"amenity", "fountain"}, - {"amenity", "theatre"}, {"amenity", "townhall"}, {"historic"}}, kSightsPlacementId); @@ -118,48 +98,10 @@ Ads::Ads() kEntertainmentPlacementId); AppendEntry({{"building"}}, kBuildingPlacementId); - - SetExcludeTypes({{"sponsored", "booking"}}); } -void Ads::AppendEntry(std::vector> const & types, std::string const & id) +std::string Facebook::GetBannerIdForOtherTypes() const { - 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)); -} - -void Ads::SetExcludeTypes(std::vector> const & types) -{ - for (auto const & type : types) - m_excludeTypes.emplace_back(classif().GetTypeByPath(type), type.size()); -} - -// static -Ads const & Ads::Instance() -{ - static Ads const ads; - return ads; -} - -bool Ads::HasBanner(feature::TypesHolder const & types) const -{ - return FindType(types, m_excludeTypes.begin(), m_excludeTypes.end()) == m_excludeTypes.end(); -} - -std::string Ads::GetBannerId(feature::TypesHolder const & types) const -{ - if (!HasBanner(types)) - return {}; - - for (auto const & typesToBanner : m_typesToBanners) - { - auto const it = FindType(types, typesToBanner.m_types.begin(), typesToBanner.m_types.end()); - if (it != typesToBanner.m_types.end()) - return typesToBanner.m_bannerId; - } return kBannerIdForOtherTypes; } -} // namespace facebook +} // namespace ads diff --git a/partners_api/facebook_ads.hpp b/partners_api/facebook_ads.hpp index 854f064a95..3643710b04 100644 --- a/partners_api/facebook_ads.hpp +++ b/partners_api/facebook_ads.hpp @@ -1,55 +1,16 @@ #pragma once -#include "base/macros.hpp" +#include "partners_api/ads_base.hpp" -#include -#include - -namespace feature +namespace ads { -class TypesHolder; -} - -namespace facebook -{ -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; -}; - -// Class which match feature types and facebook banner ids. -class Ads +// Class which matches feature types and facebook banner ids. +class Facebook : public Container { public: + Facebook(); -#if defined(OMIM_OS_IPHONE) - static auto constexpr kBannerIdForOtherTypes = "185237551520383_1425363454174447"; -#else - static auto constexpr kBannerIdForOtherTypes = "185237551520383_1384653421578784"; -#endif - - static Ads const & Instance(); - - bool HasBanner(feature::TypesHolder const & types) const; - std::string GetBannerId(feature::TypesHolder const & types) const; - -private: - Ads(); - void AppendEntry(std::vector> const & types, std::string const & id); - void SetExcludeTypes(std::vector> const & types); - - struct TypesToBannerId - { - std::vector m_types; - std::string m_bannerId; - }; - - std::vector m_typesToBanners; - std::vector m_excludeTypes; - - DISALLOW_COPY_AND_MOVE(Ads); + // ContainerBase overrides: + std::string GetBannerIdForOtherTypes() const override; }; -} // namespace facebook +} // namespace ads diff --git a/partners_api/partners_api.pro b/partners_api/partners_api.pro index e2115494b2..47e4b9200a 100644 --- a/partners_api/partners_api.pro +++ b/partners_api/partners_api.pro @@ -9,13 +9,20 @@ INCLUDEPATH *= $$ROOT_DIR/3party/jansson/src include($$ROOT_DIR/common.pri) SOURCES += \ + ads_base.cpp \ + ads_engine.cpp \ booking_api.cpp \ facebook_ads.cpp \ opentable_api.cpp \ + rb_ads.cpp \ uber_api.cpp \ HEADERS += \ + ads_base.hpp \ + ads_engine.hpp \ + banner.hpp \ booking_api.hpp \ facebook_ads.hpp \ opentable_api.hpp \ + rb_ads.hpp \ uber_api.hpp \ diff --git a/partners_api/partners_api_tests/CMakeLists.txt b/partners_api/partners_api_tests/CMakeLists.txt index 2e8eb3efef..e3370f9bec 100644 --- a/partners_api/partners_api_tests/CMakeLists.txt +++ b/partners_api/partners_api_tests/CMakeLists.txt @@ -4,8 +4,10 @@ add_definitions(-DOMIM_UNIT_TEST_WITH_QT_EVENT_LOOP) set( SRC + ads_engine_tests.cpp booking_tests.cpp facebook_tests.cpp + rb_tests.cpp uber_tests.cpp ) diff --git a/partners_api/partners_api_tests/ads_engine_tests.cpp b/partners_api/partners_api_tests/ads_engine_tests.cpp new file mode 100644 index 0000000000..d11516dfae --- /dev/null +++ b/partners_api/partners_api_tests/ads_engine_tests.cpp @@ -0,0 +1,98 @@ +#include "testing/testing.hpp" + +#include "indexer/classificator.hpp" +#include "indexer/classificator_loader.hpp" +#include "indexer/feature_data.hpp" + +#include "partners_api/ads_engine.hpp" +#include "partners_api/facebook_ads.hpp" +#include "partners_api/rb_ads.hpp" + +namespace +{ +void CheckCountAndTypes(std::vector const & banners) +{ + TEST_EQUAL(banners.size(), 2, ()); + TEST_EQUAL(banners[0].m_type, ads::Banner::Type::RB, ()); + TEST_EQUAL(banners[1].m_type, ads::Banner::Type::Facebook, ()); +} + +void CheckIds(std::vector const & banners, std::vector const & ids) +{ + TEST_EQUAL(banners.size(), ids.size(), ()); + for (size_t i = 0; i < banners.size(); ++i) + { + TEST_EQUAL(banners[i].m_bannerId, ids[i], ()); + } +} + +UNIT_TEST(AdsEngine_Smoke) +{ + classificator::Load(); + Classificator const & c = classif(); + ads::Engine engine; + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "dentist"})); + TEST(engine.HasBanner(holder), ()); + auto result = engine.GetBanners(holder); + CheckCountAndTypes(result); + CheckIds(result, {"7", "185237551520383_1384652351578891"}); + + holder.Add(c.GetTypeByPath({"amenity", "pub"})); + TEST(engine.HasBanner(holder), ()); + result = engine.GetBanners(holder); + CheckCountAndTypes(result); + CheckIds(result, {"7", "185237551520383_1384652351578891"}); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"tourism", "information", "map"})); + TEST(engine.HasBanner(holder), ()); + auto result = engine.GetBanners(holder); + CheckCountAndTypes(result); + CheckIds(result, {"5", "185237551520383_1384651734912286"}); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"shop", "ticket"})); + TEST(engine.HasBanner(holder), ()); + auto result = engine.GetBanners(holder); + CheckCountAndTypes(result); + CheckIds(result, {"2", "185237551520383_1384650804912379"}); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "bank"})); + TEST(engine.HasBanner(holder), ()); + auto result = engine.GetBanners(holder); + CheckCountAndTypes(result); + CheckIds(result, {"8", "185237551520383_1384652658245527"}); + } + ads::Rb rb; + ads::Facebook facebook; + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "toilets"})); + TEST(engine.HasBanner(holder), ()); + auto result = engine.GetBanners(holder); + CheckCountAndTypes(result); + CheckIds(result, {rb.GetBannerIdForOtherTypes(), facebook.GetBannerIdForOtherTypes()}); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"sponsored", "opentable"})); + TEST(engine.HasBanner(holder), ()); + auto result = engine.GetBanners(holder); + CheckCountAndTypes(result); + CheckIds(result, {rb.GetBannerIdForOtherTypes(), facebook.GetBannerIdForOtherTypes()}); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"sponsored", "booking"})); + TEST(!engine.HasBanner(holder), ()); + auto result = engine.GetBanners(holder); + TEST(result.empty(), ()); + } +} +} diff --git a/partners_api/partners_api_tests/facebook_tests.cpp b/partners_api/partners_api_tests/facebook_tests.cpp index c330a4ef8b..65defb6777 100644 --- a/partners_api/partners_api_tests/facebook_tests.cpp +++ b/partners_api/partners_api_tests/facebook_tests.cpp @@ -12,43 +12,45 @@ UNIT_TEST(Facebook_GetBanner) { classificator::Load(); Classificator const & c = classif(); + ads::Facebook const facebook; { feature::TypesHolder holder; holder.Assign(c.GetTypeByPath({"amenity", "dentist"})); - TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384652351578891", ()); + TEST_EQUAL(facebook.GetBannerId(holder), "185237551520383_1384652351578891", ()); holder.Add(c.GetTypeByPath({"amenity", "pub"})); - TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384650164912443", ()); + TEST_EQUAL(facebook.GetBannerId(holder), "185237551520383_1384652351578891", ()); + } + { + feature::TypesHolder holder; holder.Add(c.GetTypeByPath({"amenity", "restaurant"})); - TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384650164912443", ()); + TEST_EQUAL(facebook.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", ()); + TEST_EQUAL(facebook.GetBannerId(holder), "185237551520383_1384651734912286", ()); } { feature::TypesHolder holder; holder.Assign(c.GetTypeByPath({"shop", "ticket"})); - TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "185237551520383_1384650804912379", ()); + TEST_EQUAL(facebook.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, ()); + auto const bannerId = facebook.GetBannerIdForOtherTypes(); + TEST_EQUAL(facebook.GetBannerId(holder), bannerId, ()); } { feature::TypesHolder holder; holder.Assign(c.GetTypeByPath({"sponsored", "opentable"})); - auto const bannerId = facebook::Ads::kBannerIdForOtherTypes; - TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), bannerId, ()); + auto const bannerId = facebook.GetBannerIdForOtherTypes(); + TEST_EQUAL(facebook.GetBannerId(holder), bannerId, ()); } { feature::TypesHolder holder; holder.Assign(c.GetTypeByPath({"sponsored", "booking"})); - TEST_EQUAL(facebook::Ads::Instance().GetBannerId(holder), "", ()); + TEST_EQUAL(facebook.GetBannerId(holder), "", ()); } } } // namespace diff --git a/partners_api/partners_api_tests/partners_api_tests.pro b/partners_api/partners_api_tests/partners_api_tests.pro index 915dde8512..795792d9cd 100644 --- a/partners_api/partners_api_tests/partners_api_tests.pro +++ b/partners_api/partners_api_tests/partners_api_tests.pro @@ -26,6 +26,8 @@ win*|linux* { SOURCES += \ $$ROOT_DIR/testing/testingmain.cpp \ + ads_engine_tests.cpp \ booking_tests.cpp \ facebook_tests.cpp \ + rb_tests.cpp \ uber_tests.cpp \ diff --git a/partners_api/partners_api_tests/rb_tests.cpp b/partners_api/partners_api_tests/rb_tests.cpp new file mode 100644 index 0000000000..54b4cf2557 --- /dev/null +++ b/partners_api/partners_api_tests/rb_tests.cpp @@ -0,0 +1,66 @@ +#include "testing/testing.hpp" + +#include "indexer/classificator.hpp" +#include "indexer/classificator_loader.hpp" +#include "indexer/feature_data.hpp" + +#include "partners_api/rb_ads.hpp" + +namespace +{ +UNIT_TEST(Rb_GetBanner) +{ + classificator::Load(); + Classificator const & c = classif(); + ads::Rb const rb; + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "dentist"})); + TEST_EQUAL(rb.GetBannerId(holder), "7", ()); + holder.Add(c.GetTypeByPath({"amenity", "pub"})); + TEST_EQUAL(rb.GetBannerId(holder), "7", ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "restaurant"})); + TEST_EQUAL(rb.GetBannerId(holder), "1", ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"tourism", "information", "map"})); + TEST_EQUAL(rb.GetBannerId(holder), "5", ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"shop", "ticket"})); + TEST_EQUAL(rb.GetBannerId(holder), "2", ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "bank"})); + TEST_EQUAL(rb.GetBannerId(holder), "8", ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "atm"})); + TEST_EQUAL(rb.GetBannerId(holder), "8", ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"amenity", "toilets"})); + auto const bannerId = rb.GetBannerIdForOtherTypes(); + TEST_EQUAL(rb.GetBannerId(holder), bannerId, ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"sponsored", "opentable"})); + auto const bannerId = rb.GetBannerIdForOtherTypes(); + TEST_EQUAL(rb.GetBannerId(holder), bannerId, ()); + } + { + feature::TypesHolder holder; + holder.Assign(c.GetTypeByPath({"sponsored", "booking"})); + TEST_EQUAL(rb.GetBannerId(holder), "", ()); + } +} +} // namespace diff --git a/partners_api/rb_ads.cpp b/partners_api/rb_ads.cpp new file mode 100644 index 0000000000..756848563a --- /dev/null +++ b/partners_api/rb_ads.cpp @@ -0,0 +1,92 @@ +#include "partners_api/rb_ads.hpp" + +namespace +{ +auto const kFoodPlacementId = "1"; +auto const kShopsPlacementId = "2"; +auto const kCityTransportPlacementId = "13"; +auto const kGlobalTransportPlacementId = "12"; +auto const kHotelsPlacementId = "4"; +auto const kSightsPlacementId = "5"; +auto const kLargeToponymsPlacementId = "6"; +auto const kHealthPlacementId = "7"; +auto const kFinancialPlacementId = "8"; +auto const kEntertainmentPlacementId = "9"; +auto const kBuildingPlacementId = "11"; +auto const kBannerIdForOtherTypes = "14"; +} // namespace + +namespace ads +{ +Rb::Rb() +{ + AppendEntry({{"amenity", "cafe"}, + {"amenity", "fast_food"}, + {"amenity", "restaurant"}, + {"amenity", "bar"}, + {"amenity", "pub"}}, + kFoodPlacementId); + + AppendEntry({{"shop"}, + {"amenity", "marketplace"}}, + kShopsPlacementId); + + AppendEntry({{"aerialway"}, + {"highway", "bus_stop"}, + {"highway", "speed_camera"}, + {"public_transport"}}, + kCityTransportPlacementId); + + AppendEntry({{"aeroway"}, + {"railway"}, + {"man_made", "pier"}}, + kGlobalTransportPlacementId); + + AppendEntry({{"tourism", "hotel"}, + {"tourism", "hostel"}, + {"tourism", "motel"}, + {"tourism", "apartment"}, + {"tourism", "resort"}}, + kHotelsPlacementId); + + AppendEntry({{"tourism", "chalet"}, + {"tourism", "zoo"}, + {"tourism", "artwork"}, + {"tourism", "information"}, + {"tourism", "attraction"}, + {"tourism", "viewpoint"}, + {"tourism", "museum"}, + {"amenity", "fountain"}, + {"amenity", "townhall"}, + {"historic"}}, + kSightsPlacementId); + + AppendEntry({{"place"}}, kLargeToponymsPlacementId); + + AppendEntry({{"amenity", "dentist"}, + {"amenity", "doctors"}, + {"amenity", "clinic"}, + {"amenity", "hospital"}, + {"amenity", "pharmacy"}, + {"amenity", "veterinary"}}, + kHealthPlacementId); + + AppendEntry({{"amenity", "bank"}, {"amenity", "atm"}}, kFinancialPlacementId); + + AppendEntry({{"amenity", "cinema"}, + {"amenity", "brothel"}, + {"amenity", "casino"}, + {"amenity", "nightclub"}, + {"amenity", "theatre"}, + {"boundary", "national_park"}, + {"leisure"}}, + kEntertainmentPlacementId); + + AppendEntry({{"building"}}, kBuildingPlacementId); +} + +std::string Rb::GetBannerIdForOtherTypes() const +{ + return kBannerIdForOtherTypes; +} +} // namespace ads diff --git a/partners_api/rb_ads.hpp b/partners_api/rb_ads.hpp new file mode 100644 index 0000000000..b9fde9129d --- /dev/null +++ b/partners_api/rb_ads.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "partners_api/ads_base.hpp" + +namespace ads +{ +// Class which matches feature types and RB banner ids. +class Rb : public Container +{ +public: + Rb(); + + // ContainerBase overrides: + std::string GetBannerIdForOtherTypes() const override; +}; +} // namespace ads diff --git a/xcode/partners_api/partners_api.xcodeproj/project.pbxproj b/xcode/partners_api/partners_api.xcodeproj/project.pbxproj index 87dc012326..a5a31d416c 100644 --- a/xcode/partners_api/partners_api.xcodeproj/project.pbxproj +++ b/xcode/partners_api/partners_api.xcodeproj/project.pbxproj @@ -7,6 +7,15 @@ objects = { /* Begin PBXBuildFile section */ + 346E88961E9D087400D4CE9B /* ads_base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 346E888F1E9D087400D4CE9B /* ads_base.cpp */; }; + 346E88971E9D087400D4CE9B /* ads_base.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 346E88901E9D087400D4CE9B /* ads_base.hpp */; }; + 346E88981E9D087400D4CE9B /* ads_engine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 346E88911E9D087400D4CE9B /* ads_engine.cpp */; }; + 346E88991E9D087400D4CE9B /* ads_engine.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 346E88921E9D087400D4CE9B /* ads_engine.hpp */; }; + 346E889A1E9D087400D4CE9B /* banner.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 346E88931E9D087400D4CE9B /* banner.hpp */; }; + 346E889B1E9D087400D4CE9B /* rb_ads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 346E88941E9D087400D4CE9B /* rb_ads.cpp */; }; + 346E889C1E9D087400D4CE9B /* rb_ads.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 346E88951E9D087400D4CE9B /* rb_ads.hpp */; }; + 346E889F1E9D088200D4CE9B /* ads_engine_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 346E889D1E9D088200D4CE9B /* ads_engine_tests.cpp */; }; + 346E88A01E9D088200D4CE9B /* rb_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 346E889E1E9D088200D4CE9B /* rb_tests.cpp */; }; 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 */; }; @@ -34,6 +43,15 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 346E888F1E9D087400D4CE9B /* ads_base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ads_base.cpp; sourceTree = ""; }; + 346E88901E9D087400D4CE9B /* ads_base.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ads_base.hpp; sourceTree = ""; }; + 346E88911E9D087400D4CE9B /* ads_engine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ads_engine.cpp; sourceTree = ""; }; + 346E88921E9D087400D4CE9B /* ads_engine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ads_engine.hpp; sourceTree = ""; }; + 346E88931E9D087400D4CE9B /* banner.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = banner.hpp; sourceTree = ""; }; + 346E88941E9D087400D4CE9B /* rb_ads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rb_ads.cpp; sourceTree = ""; }; + 346E88951E9D087400D4CE9B /* rb_ads.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = rb_ads.hpp; sourceTree = ""; }; + 346E889D1E9D088200D4CE9B /* ads_engine_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ads_engine_tests.cpp; sourceTree = ""; }; + 346E889E1E9D088200D4CE9B /* rb_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rb_tests.cpp; sourceTree = ""; }; 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 = ""; }; @@ -111,6 +129,13 @@ F6B5363B1DA520B20067EEA5 /* partners_api */ = { isa = PBXGroup; children = ( + 346E888F1E9D087400D4CE9B /* ads_base.cpp */, + 346E88901E9D087400D4CE9B /* ads_base.hpp */, + 346E88911E9D087400D4CE9B /* ads_engine.cpp */, + 346E88921E9D087400D4CE9B /* ads_engine.hpp */, + 346E88931E9D087400D4CE9B /* banner.hpp */, + 346E88941E9D087400D4CE9B /* rb_ads.cpp */, + 346E88951E9D087400D4CE9B /* rb_ads.hpp */, 3DBC1C521E4B14920016897F /* facebook_ads.cpp */, 3DBC1C531E4B14920016897F /* facebook_ads.hpp */, F67E75231DB8F06F00D6741F /* opentable_api.cpp */, @@ -127,6 +152,8 @@ F6B536441DA521060067EEA5 /* partners_api_tests */ = { isa = PBXGroup; children = ( + 346E889D1E9D088200D4CE9B /* ads_engine_tests.cpp */, + 346E889E1E9D088200D4CE9B /* rb_tests.cpp */, 3DBC1C501E4B14810016897F /* facebook_tests.cpp */, F6B536691DA523060067EEA5 /* testingmain.cpp */, F6B536451DA5213D0067EEA5 /* booking_tests.cpp */, @@ -166,8 +193,12 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 346E88971E9D087400D4CE9B /* ads_base.hpp in Headers */, F67E75261DB8F06F00D6741F /* opentable_api.hpp in Headers */, F6B536411DA520E40067EEA5 /* booking_api.hpp in Headers */, + 346E889C1E9D087400D4CE9B /* rb_ads.hpp in Headers */, + 346E889A1E9D087400D4CE9B /* banner.hpp in Headers */, + 346E88991E9D087400D4CE9B /* ads_engine.hpp in Headers */, F6B536431DA520E40067EEA5 /* uber_api.hpp in Headers */, 3DBC1C551E4B14920016897F /* facebook_ads.hpp in Headers */, ); @@ -264,9 +295,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 346E88A01E9D088200D4CE9B /* rb_tests.cpp in Sources */, + 346E889F1E9D088200D4CE9B /* ads_engine_tests.cpp in Sources */, + 346E88961E9D087400D4CE9B /* ads_base.cpp in Sources */, 3DBC1C511E4B14810016897F /* facebook_tests.cpp in Sources */, F6B536421DA520E40067EEA5 /* uber_api.cpp in Sources */, + 346E889B1E9D087400D4CE9B /* rb_ads.cpp in Sources */, 3DBC1C541E4B14920016897F /* facebook_ads.cpp in Sources */, + 346E88981E9D087400D4CE9B /* ads_engine.cpp in Sources */, F6B536471DA5213D0067EEA5 /* booking_tests.cpp in Sources */, F6B5366A1DA523060067EEA5 /* testingmain.cpp in Sources */, F67E75251DB8F06F00D6741F /* opentable_api.cpp in Sources */,