adtekio_adnetworks 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +24 -0
- data/README.md +333 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/adtekio_adnetworks.gemspec +297 -0
- data/lib/adtekio_adnetworks.rb +6 -0
- data/lib/adtekio_adnetworks/api_key_scrapers.rb +59 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/adcolony.rb +20 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/applift.rb +13 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/applovin.rb +13 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/chartboost.rb +18 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/crossinstall.rb +13 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/leadbolt.rb +18 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/loopme.rb +12 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/mdotm.rb +22 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/revmob.rb +22 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/tapjoy.rb +19 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/unilead.rb +13 -0
- data/lib/adtekio_adnetworks/api_key_scrapers/vungle.rb +23 -0
- data/lib/adtekio_adnetworks/importers.rb +58 -0
- data/lib/adtekio_adnetworks/importers/cost/adcolony.rb +43 -0
- data/lib/adtekio_adnetworks/importers/cost/adquant.rb +68 -0
- data/lib/adtekio_adnetworks/importers/cost/appia.rb +47 -0
- data/lib/adtekio_adnetworks/importers/cost/applifier.rb +64 -0
- data/lib/adtekio_adnetworks/importers/cost/applift.rb +41 -0
- data/lib/adtekio_adnetworks/importers/cost/applovin.rb +52 -0
- data/lib/adtekio_adnetworks/importers/cost/bidmotion.rb +82 -0
- data/lib/adtekio_adnetworks/importers/cost/chartboost.rb +40 -0
- data/lib/adtekio_adnetworks/importers/cost/crossinstall.rb +34 -0
- data/lib/adtekio_adnetworks/importers/cost/facebook.rb +39 -0
- data/lib/adtekio_adnetworks/importers/cost/fractionalmedia.rb +104 -0
- data/lib/adtekio_adnetworks/importers/cost/fyber.rb +54 -0
- data/lib/adtekio_adnetworks/importers/cost/gamegenetics.rb +44 -0
- data/lib/adtekio_adnetworks/importers/cost/glispa.rb +59 -0
- data/lib/adtekio_adnetworks/importers/cost/googleadwords.rb +99 -0
- data/lib/adtekio_adnetworks/importers/cost/jampp.rb +57 -0
- data/lib/adtekio_adnetworks/importers/cost/leadbolt.rb +43 -0
- data/lib/adtekio_adnetworks/importers/cost/lifestreet.rb +49 -0
- data/lib/adtekio_adnetworks/importers/cost/loopme.rb +63 -0
- data/lib/adtekio_adnetworks/importers/cost/matomy.rb +65 -0
- data/lib/adtekio_adnetworks/importers/cost/mdotm.rb +69 -0
- data/lib/adtekio_adnetworks/importers/cost/mmg.rb +67 -0
- data/lib/adtekio_adnetworks/importers/cost/mnectar.rb +45 -0
- data/lib/adtekio_adnetworks/importers/cost/moboqo.rb +33 -0
- data/lib/adtekio_adnetworks/importers/cost/mobpartner.rb +46 -0
- data/lib/adtekio_adnetworks/importers/cost/nanigans.rb +114 -0
- data/lib/adtekio_adnetworks/importers/cost/revmob.rb +44 -0
- data/lib/adtekio_adnetworks/importers/cost/rtbmob.rb +48 -0
- data/lib/adtekio_adnetworks/importers/cost/startapp.rb +47 -0
- data/lib/adtekio_adnetworks/importers/cost/supersonic.rb +77 -0
- data/lib/adtekio_adnetworks/importers/cost/tapjoy.rb +42 -0
- data/lib/adtekio_adnetworks/importers/cost/tokenads.rb +46 -0
- data/lib/adtekio_adnetworks/importers/cost/unilead.rb +39 -0
- data/lib/adtekio_adnetworks/importers/cost/vungle.rb +58 -0
- data/lib/adtekio_adnetworks/importers/cost_import.rb +13 -0
- data/lib/adtekio_adnetworks/importers/revenue/adcolony.rb +67 -0
- data/lib/adtekio_adnetworks/importers/revenue/applifier.rb +55 -0
- data/lib/adtekio_adnetworks/importers/revenue/applovin.rb +58 -0
- data/lib/adtekio_adnetworks/importers/revenue/chartboost.rb +43 -0
- data/lib/adtekio_adnetworks/importers/revenue/flurry.rb +85 -0
- data/lib/adtekio_adnetworks/importers/revenue/fyber.rb +61 -0
- data/lib/adtekio_adnetworks/importers/revenue/hypr_mx.rb +69 -0
- data/lib/adtekio_adnetworks/importers/revenue/lifestreet.rb +59 -0
- data/lib/adtekio_adnetworks/importers/revenue/mdotm.rb +38 -0
- data/lib/adtekio_adnetworks/importers/revenue/mopub.rb +54 -0
- data/lib/adtekio_adnetworks/importers/revenue/nexage.rb +71 -0
- data/lib/adtekio_adnetworks/importers/revenue/supersonic.rb +73 -0
- data/lib/adtekio_adnetworks/importers/revenue/tapsense.rb +38 -0
- data/lib/adtekio_adnetworks/importers/revenue/trialpay.rb +41 -0
- data/lib/adtekio_adnetworks/importers/revenue/vungle.rb +75 -0
- data/lib/adtekio_adnetworks/importers/revenue_import.rb +27 -0
- data/lib/adtekio_adnetworks/postbacks.rb +193 -0
- data/lib/adtekio_adnetworks/postbacks/aarki.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/adaction.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/adcash.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/adcolony.rb +90 -0
- data/lib/adtekio_adnetworks/postbacks/adgorithms.rb +74 -0
- data/lib/adtekio_adnetworks/postbacks/adjapon_nend.rb +39 -0
- data/lib/adtekio_adnetworks/postbacks/adknowledge.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/admob.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/adp.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/adperio.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/adquant.rb +39 -0
- data/lib/adtekio_adnetworks/postbacks/adstract.rb +15 -0
- data/lib/adtekio_adnetworks/postbacks/adxperience.rb +16 -0
- data/lib/adtekio_adnetworks/postbacks/airpush.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/app_chocolate.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/appfload.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/appia.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/appintheair.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/applifier.rb +49 -0
- data/lib/adtekio_adnetworks/postbacks/applift.rb +88 -0
- data/lib/adtekio_adnetworks/postbacks/applovin.rb +127 -0
- data/lib/adtekio_adnetworks/postbacks/appnext.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/appredeem.rb +33 -0
- data/lib/adtekio_adnetworks/postbacks/appsfire.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/appturbo.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/apsalar.rb +21 -0
- data/lib/adtekio_adnetworks/postbacks/bee7.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/bidmotion.rb +80 -0
- data/lib/adtekio_adnetworks/postbacks/blindferretmedia.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/chartboost.rb +116 -0
- data/lib/adtekio_adnetworks/postbacks/cheetah.rb +32 -0
- data/lib/adtekio_adnetworks/postbacks/clickky.rb +30 -0
- data/lib/adtekio_adnetworks/postbacks/covus.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/crossinstall.rb +26 -0
- data/lib/adtekio_adnetworks/postbacks/cyberagent_ameba.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/cyberagent_amoad.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/cyberagent_imobile.rb +43 -0
- data/lib/adtekio_adnetworks/postbacks/cyberagent_kjnw.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/cyberagent_maio.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/cyberagent_nend.rb +40 -0
- data/lib/adtekio_adnetworks/postbacks/cyberagent_smartc.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/cyberagent_smartnews.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/cyberz_asta.rb +26 -0
- data/lib/adtekio_adnetworks/postbacks/cyberz_bead.rb +26 -0
- data/lib/adtekio_adnetworks/postbacks/cyberz_imobile.rb +28 -0
- data/lib/adtekio_adnetworks/postbacks/cyberz_nend.rb +30 -0
- data/lib/adtekio_adnetworks/postbacks/datalead.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/eccrine.rb +80 -0
- data/lib/adtekio_adnetworks/postbacks/eeline.rb +50 -0
- data/lib/adtekio_adnetworks/postbacks/f5.rb +30 -0
- data/lib/adtekio_adnetworks/postbacks/fiksu.rb +43 -0
- data/lib/adtekio_adnetworks/postbacks/fiksu_applift.rb +31 -0
- data/lib/adtekio_adnetworks/postbacks/fractionalmedia.rb +78 -0
- data/lib/adtekio_adnetworks/postbacks/fyber.rb +36 -0
- data/lib/adtekio_adnetworks/postbacks/gamegenetics.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/ginga.rb +26 -0
- data/lib/adtekio_adnetworks/postbacks/glispa.rb +96 -0
- data/lib/adtekio_adnetworks/postbacks/googleadwords.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/growmobile.rb +36 -0
- data/lib/adtekio_adnetworks/postbacks/heyzap.rb +51 -0
- data/lib/adtekio_adnetworks/postbacks/inmobi.rb +50 -0
- data/lib/adtekio_adnetworks/postbacks/inneractive.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/instal.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/iqu.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/ironsource.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/jampp.rb +48 -0
- data/lib/adtekio_adnetworks/postbacks/jestadigital.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/jumpramp.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/jumptap.rb +23 -0
- data/lib/adtekio_adnetworks/postbacks/leadbolt.rb +29 -0
- data/lib/adtekio_adnetworks/postbacks/lifestreet.rb +97 -0
- data/lib/adtekio_adnetworks/postbacks/liftoff.rb +66 -0
- data/lib/adtekio_adnetworks/postbacks/loopme.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/magic_solver.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/marimedia.rb +20 -0
- data/lib/adtekio_adnetworks/postbacks/matomy.rb +59 -0
- data/lib/adtekio_adnetworks/postbacks/mdotm.rb +116 -0
- data/lib/adtekio_adnetworks/postbacks/misterbell.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/mmg.rb +20 -0
- data/lib/adtekio_adnetworks/postbacks/mnectar.rb +22 -0
- data/lib/adtekio_adnetworks/postbacks/moblin.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/moboqo.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/mobpartner.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/mopub.rb +30 -0
- data/lib/adtekio_adnetworks/postbacks/motive_interactive.rb +32 -0
- data/lib/adtekio_adnetworks/postbacks/mundo.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/nanigans.rb +38 -0
- data/lib/adtekio_adnetworks/postbacks/nativex.rb +30 -0
- data/lib/adtekio_adnetworks/postbacks/neodau.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/neverblue.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/operamedia.rb +39 -0
- data/lib/adtekio_adnetworks/postbacks/pandora.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/phunware.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/pirasin.rb +16 -0
- data/lib/adtekio_adnetworks/postbacks/playhaven.rb +31 -0
- data/lib/adtekio_adnetworks/postbacks/pocketmath.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/propeller.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/quixey.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/realzeit.rb +60 -0
- data/lib/adtekio_adnetworks/postbacks/remerge.rb +66 -0
- data/lib/adtekio_adnetworks/postbacks/revmob.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/ripple.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/roostr.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/rtbcom.rb +28 -0
- data/lib/adtekio_adnetworks/postbacks/septeni.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/seven_games.rb +51 -0
- data/lib/adtekio_adnetworks/postbacks/startapp.rb +48 -0
- data/lib/adtekio_adnetworks/postbacks/supersonic.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/tapjoy.rb +36 -0
- data/lib/adtekio_adnetworks/postbacks/taptica.rb +21 -0
- data/lib/adtekio_adnetworks/postbacks/targetcircle.rb +41 -0
- data/lib/adtekio_adnetworks/postbacks/todacell.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/tokenads.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/trademob.rb +48 -0
- data/lib/adtekio_adnetworks/postbacks/trademob_magic_solver.rb +22 -0
- data/lib/adtekio_adnetworks/postbacks/trialpay.rb +18 -0
- data/lib/adtekio_adnetworks/postbacks/unilead.rb +78 -0
- data/lib/adtekio_adnetworks/postbacks/uppsmobi.rb +19 -0
- data/lib/adtekio_adnetworks/postbacks/vungle.rb +33 -0
- data/lib/adtekio_adnetworks/postbacks/w4.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/webmedia.rb +17 -0
- data/lib/adtekio_adnetworks/postbacks/yahoo.rb +20 -0
- data/lib/adtekio_adnetworks/postbacks/youappi.rb +116 -0
- data/lib/adtekio_adnetworks/postbacks/zemail.rb +19 -0
- data/test/helper.rb +78 -0
- data/test/unit/postbacks/test_chartboost.rb +105 -0
- data/test/unit/postbacks/test_mdotm.rb +35 -0
- data/test/unit/postbacks/test_playhaven.rb +76 -0
- data/test/unit/postbacks/test_trademob_magic_solver.rb +24 -0
- data/test/unit/postbacks/test_unilead.rb +67 -0
- data/test/unit/test_api_key_scrapers.rb +302 -0
- data/test/unit/test_base_postback_class.rb +82 -0
- data/test/unit/test_cost_importers.rb +12 -0
- data/test/unit/test_postbacks.rb +33 -0
- data/test/unit/test_postbacks_definition.rb +111 -0
- data/test/unit/test_revenue_importers.rb +12 -0
- metadata +500 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
class AdtekioAdnetworks::Revenue::Applifier
|
2
|
+
include AdtekioAdnetworks::RevenueImport
|
3
|
+
|
4
|
+
CsvOptions = {
|
5
|
+
:col_sep => ",",
|
6
|
+
:quote_char => '"',
|
7
|
+
:headers => :first_row,
|
8
|
+
}
|
9
|
+
|
10
|
+
BASE_URL = "https://gameads-admin.applifier.com/stats/monetization-api"
|
11
|
+
|
12
|
+
define_required_credentials do
|
13
|
+
[:api_key]
|
14
|
+
end
|
15
|
+
|
16
|
+
def revenues(from, to)
|
17
|
+
report(from,to).map do |csv_data|
|
18
|
+
CSV(csv_data, CsvOptions).map do |row|
|
19
|
+
{
|
20
|
+
:impressions => row["views"].to_i,
|
21
|
+
:amount => row["revenue"].to_f,
|
22
|
+
:date => Date.strptime(row["Date"], "%Y-%m-%d"),
|
23
|
+
:appname => row["Source game name"]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end.flatten
|
27
|
+
end
|
28
|
+
|
29
|
+
def report(from,to)
|
30
|
+
(from..to).map do |day|
|
31
|
+
csv_data(day)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def csv_data(date)
|
36
|
+
uri = Addressable::URI.new
|
37
|
+
uri.query_values = {
|
38
|
+
:apikey => credentials.api_key,
|
39
|
+
:start => date.strftime("%Y-%m-%d"),
|
40
|
+
:end => (date+1).strftime("%Y-%m-%d"),
|
41
|
+
:fields => 'views,revenue',
|
42
|
+
:splitBy => 'source'
|
43
|
+
}
|
44
|
+
datauri = URI.parse("%s?%s" % [BASE_URL, uri.query])
|
45
|
+
|
46
|
+
# follow one redirect.
|
47
|
+
request = Net::HTTP::Persistent.new('applifier').request(datauri)
|
48
|
+
if request.code =~ /3../
|
49
|
+
Net::HTTP::Persistent.new('applifier').
|
50
|
+
request(URI.parse(request.header["Location"])).body
|
51
|
+
else
|
52
|
+
request.body
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class AdtekioAdnetworks::Revenue::Applovin
|
2
|
+
include AdtekioAdnetworks::RevenueImport
|
3
|
+
|
4
|
+
BaseUrl = "https://r.applovin.com/report"
|
5
|
+
ReportColumns = "application,platform,package_name,revenue,day,impressions,clicks,ad_type"
|
6
|
+
|
7
|
+
define_required_credentials do
|
8
|
+
[:api_key]
|
9
|
+
end
|
10
|
+
|
11
|
+
def revenues(from, to)
|
12
|
+
report(from, to).map do |(package, ad_type, date), values|
|
13
|
+
osv = values.map{ |a| OpenStruct.new(a) }
|
14
|
+
|
15
|
+
{
|
16
|
+
:impressions => osv.map(&:impressions).map(&:to_i).sum,
|
17
|
+
:clicks => osv.map(&:clicks).map(&:to_i).sum,
|
18
|
+
:amount => osv.map(&:revenue).map(&:to_f).sum,
|
19
|
+
:date => date,
|
20
|
+
:appname => package,
|
21
|
+
:not_matched => not_matched(:ad_type => ad_type,
|
22
|
+
:platform => osv.map(&:platform).join(","))
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def report(from, to)
|
28
|
+
@report ||= data({ :api_key => credentials.api_key,
|
29
|
+
:start => from.strftime("%Y-%m-%d"),
|
30
|
+
:end => to.strftime("%Y-%m-%d"),
|
31
|
+
:format => :json,
|
32
|
+
:columns => ReportColumns,
|
33
|
+
:report_type => :publisher,
|
34
|
+
}).group_by do |row|
|
35
|
+
[row[:package_name], row[:ad_type], Date.parse(row[:day])]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def data(params)
|
40
|
+
cipher_suit_backup = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ciphers]
|
41
|
+
|
42
|
+
uri = Addressable::URI.parse(BaseUrl)
|
43
|
+
uri.query_values = params
|
44
|
+
|
45
|
+
OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ciphers] =
|
46
|
+
'HIGH:MEDIUM:!ADH:!EDH:!DHE'
|
47
|
+
|
48
|
+
http = Net::HTTP.new(uri.hostname, 443)
|
49
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
50
|
+
http.use_ssl = true
|
51
|
+
|
52
|
+
request = Net::HTTP::Get.new uri.request_uri
|
53
|
+
response = http.request(request)
|
54
|
+
JSON.parse(response.body, :symbolize_names => true)[:results]
|
55
|
+
ensure
|
56
|
+
OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ciphers] = cipher_suit_backup
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class AdtekioAdnetworks::Revenue::Chartboost
|
2
|
+
include AdtekioAdnetworks::RevenueImport
|
3
|
+
|
4
|
+
BASE_URL = "https://analytics.chartboost.com/queue/app"
|
5
|
+
|
6
|
+
define_required_credentials do
|
7
|
+
[:user_id, :signature]
|
8
|
+
end
|
9
|
+
|
10
|
+
def revenues(from, to)
|
11
|
+
report(from,to).map do |hsh|
|
12
|
+
{
|
13
|
+
:impressions => hsh["impressionsDelivered"].to_i,
|
14
|
+
:amount => hsh["moneyEarned"].to_f,
|
15
|
+
:date => Date.strptime(hsh["dt"], "%Y-%m-%d"),
|
16
|
+
:appname => hsh["app"],
|
17
|
+
:not_matched => not_matched(:platform => hsh["platform"],
|
18
|
+
:appBundleId => hsh["appBundleId"],
|
19
|
+
:appId => hsh["appId"])
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def report(from, to)
|
25
|
+
JSON(Net::HTTP::Persistent.new('chartboost').
|
26
|
+
request(query_url(from,to)).body)
|
27
|
+
end
|
28
|
+
|
29
|
+
def query_url(from, to)
|
30
|
+
params = {
|
31
|
+
:userId => credentials.user_id,
|
32
|
+
:userSignature => credentials.signature,
|
33
|
+
:dateMin => from.strftime("%Y-%m-%d"),
|
34
|
+
:dateMax => to.strftime("%Y-%m-%d"),
|
35
|
+
:groupBy => :app,
|
36
|
+
:aggregate => :daily,
|
37
|
+
}
|
38
|
+
|
39
|
+
uri = Addressable::URI.new
|
40
|
+
uri.query_values = params
|
41
|
+
URI.parse("%s?%s" % [BASE_URL, uri.query])
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
class AdtekioAdnetworks::Revenue::Flurry
|
2
|
+
include AdtekioAdnetworks::RevenueImport
|
3
|
+
|
4
|
+
define_required_credentials do
|
5
|
+
[:keys, :access_code]
|
6
|
+
end
|
7
|
+
|
8
|
+
def revenues(from, to)
|
9
|
+
report(from, to).map do |data|
|
10
|
+
data.map do |adspace_id, values|
|
11
|
+
next if values.nil?
|
12
|
+
values.map do |hsh|
|
13
|
+
check_version!(hsh['@version'], "1.0")
|
14
|
+
check_currency!(hsh["currency"], "usd")
|
15
|
+
|
16
|
+
next if hsh["results"].nil?
|
17
|
+
date = Date.strptime(hsh["results"]["date"], "%Y-%m-%d")
|
18
|
+
|
19
|
+
# Kinda confusing since the data is duplicated for each
|
20
|
+
# day. We import everything but flurry sends on a per-country
|
21
|
+
# basis with then a global value. That means the total
|
22
|
+
# of all entries for day with country should be the same
|
23
|
+
# as the entry with country == null.
|
24
|
+
( (hsh["results"]["country_stats"] || []) +
|
25
|
+
[hsh['results']["global_stats"]]).compact.map do |dpt|
|
26
|
+
{
|
27
|
+
:date => date,
|
28
|
+
:appname => adspace_id,
|
29
|
+
:country => dpt["country"],
|
30
|
+
:amount => dpt["revenue"].to_f,
|
31
|
+
:clicks => dpt["clicks"].to_i,
|
32
|
+
:impressions => dpt["impressions"].to_i,
|
33
|
+
:installs => dpt["installs"].to_i
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end.flatten.compact
|
39
|
+
end
|
40
|
+
|
41
|
+
def report(from,to)
|
42
|
+
creds = credentials.keys["adspace_id"].zip(credentials.keys["api_key"])
|
43
|
+
creds.map do |adspace_id, api_key|
|
44
|
+
{ adspace_id => ( (from..to).map do |date|
|
45
|
+
data_for_apikey(api_key, adspace_id, date)
|
46
|
+
end)
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def data_for_apikey(key, adspaceid, for_date = Date.today-1)
|
52
|
+
sdate, edate = [for_date, for_date+1].map { |a| a.strftime("%Y-%m-%d") }
|
53
|
+
|
54
|
+
uri = Addressable::URI.new
|
55
|
+
uri.query_values = {
|
56
|
+
:apiAccessCode => credentials.access_code,
|
57
|
+
:adSpaceId => adspaceid,
|
58
|
+
:apiKey => key,
|
59
|
+
:startDate => sdate,
|
60
|
+
:endDate => edate
|
61
|
+
}
|
62
|
+
|
63
|
+
datauri = URI.
|
64
|
+
parse("%s?%s" % ["http://api.flurry.com/ffp/v1/AdSpaceCountry",
|
65
|
+
uri.query])
|
66
|
+
|
67
|
+
repeatthis(10) do
|
68
|
+
JSON(Net::HTTP::Persistent.new('flurry').request(datauri).body)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def repeatthis(cnt=5, timeout=0.1, &block)
|
73
|
+
last_exception = nil
|
74
|
+
cnt.times do
|
75
|
+
begin
|
76
|
+
return yield
|
77
|
+
rescue Exception => e
|
78
|
+
last_exception = e
|
79
|
+
sleep timeout
|
80
|
+
next
|
81
|
+
end
|
82
|
+
end
|
83
|
+
raise last_exception
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class AdtekioAdnetworks::Revenue::Fyber
|
2
|
+
include AdtekioAdnetworks::RevenueImport
|
3
|
+
|
4
|
+
REPORT_URL =
|
5
|
+
"https://dashboard.fyber.com/publishers/v1/28839/statistics.json"
|
6
|
+
|
7
|
+
define_required_credentials do
|
8
|
+
[:key]
|
9
|
+
end
|
10
|
+
|
11
|
+
def revenues(from, to)
|
12
|
+
report(from,to).map do |dpt|
|
13
|
+
appname = dpt['readable'].strip
|
14
|
+
from.upto(to).each_with_index.map do |date, idx|
|
15
|
+
{
|
16
|
+
:completions => dpt["transactions"][idx].to_i,
|
17
|
+
:impressions => dpt["views"][idx].to_i,
|
18
|
+
:clicks => dpt["clicks"][idx].to_i,
|
19
|
+
:amount => dpt["payout_usd"][idx].to_f,
|
20
|
+
:date => date,
|
21
|
+
:appname => appname,
|
22
|
+
:not_matched => not_matched(:id => dpt["id"])
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end.flatten.compact
|
26
|
+
end
|
27
|
+
|
28
|
+
def report(from,to)
|
29
|
+
load_data({
|
30
|
+
:start_date => from.to_s,
|
31
|
+
:end_date => to.to_s,
|
32
|
+
:group_by => :applications,
|
33
|
+
:aggregation_level => :days,
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
def hash(params)
|
38
|
+
value = Hash[params.sort_by{|k, _| k}].reject do |_,v|
|
39
|
+
v.to_s.blank?
|
40
|
+
end.map do |k,v|
|
41
|
+
"#{k}=#{v}"
|
42
|
+
end.inject("/publishers/v1/28839/statistics.json") do |string, param|
|
43
|
+
string + "&" + param
|
44
|
+
end + "&" + credentials.key
|
45
|
+
|
46
|
+
Digest::SHA1.hexdigest value
|
47
|
+
end
|
48
|
+
|
49
|
+
def load_data(params)
|
50
|
+
uri = Addressable::URI.parse(REPORT_URL)
|
51
|
+
uri.query_values = params.merge({:hashkey => hash(params)})
|
52
|
+
response = http_client.request(URI.parse(uri.to_s))
|
53
|
+
JSON(response.body)['applications']
|
54
|
+
end
|
55
|
+
|
56
|
+
def http_client
|
57
|
+
@http_client ||= Net::HTTP::Persistent.new('fyber').tap do |client|
|
58
|
+
client.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class AdtekioAdnetworks::Revenue::HyprMx
|
2
|
+
include AdtekioAdnetworks::RevenueImport
|
3
|
+
|
4
|
+
BASE_URL = 'https://live.hyprmx.com/fyber/v1/'
|
5
|
+
|
6
|
+
define_required_credentials do
|
7
|
+
[:apps]
|
8
|
+
end
|
9
|
+
|
10
|
+
def revenues(from, to)
|
11
|
+
# We import everything but hypermx sends on a per-country
|
12
|
+
# basis with then a global value. That means the total
|
13
|
+
# of all entries for day with country should be the same
|
14
|
+
# as the entry with country == null, for a specific date.
|
15
|
+
report(from,to).map do |dpt|
|
16
|
+
((dpt[:country_stats] || []) + [dpt[:global_stats]]).map do |stats|
|
17
|
+
{
|
18
|
+
:appname => dpt[:appname],
|
19
|
+
:date => dpt[:date],
|
20
|
+
:amount => stats[:revenue].to_f,
|
21
|
+
:impressions => stats[:impressions].to_i,
|
22
|
+
:completions => stats[:completions].to_i,
|
23
|
+
:country => stats[:country],
|
24
|
+
:not_matched => not_matched(:dist_id => dpt[:dist_id])
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end.flatten.compact
|
28
|
+
end
|
29
|
+
|
30
|
+
def report(from,to)
|
31
|
+
cnt = (credentials.apps["dist_id"] || []).count
|
32
|
+
|
33
|
+
cnt.times.map do |idx|
|
34
|
+
data = load_data({ :app_id => credentials.apps["dist_id"][idx],
|
35
|
+
:placement_id => credentials.apps["placement_id"][idx],
|
36
|
+
:start_date => from.to_s,
|
37
|
+
:end_date => to.to_s,
|
38
|
+
}, credentials.apps["api_key"][idx])
|
39
|
+
|
40
|
+
check_currency!(data[:currency], "usd")
|
41
|
+
|
42
|
+
data[:results].map do |dpt|
|
43
|
+
dpt.merge({ :appname => credentials.apps["placement_id"][idx],
|
44
|
+
:date => Date.strptime(dpt[:date],"%Y-%m-%d"),
|
45
|
+
:dist_id => credentials.apps["dist_id"][idx]})
|
46
|
+
end
|
47
|
+
end.flatten.compact
|
48
|
+
end
|
49
|
+
|
50
|
+
def http_client
|
51
|
+
@http_client ||= Net::HTTP::Persistent.new('hyprmx').tap do |client|
|
52
|
+
client.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def hash(params, api_key)
|
57
|
+
value = Hash[params.sort_by{|k, _| k}].map do |k,v|
|
58
|
+
"#{k}=#{v}"
|
59
|
+
end.join('&') + "&" + api_key
|
60
|
+
Digest::SHA1.hexdigest value
|
61
|
+
end
|
62
|
+
|
63
|
+
def load_data(params, api_key)
|
64
|
+
uri = Addressable::URI.parse(BASE_URL)
|
65
|
+
uri.query_values = params.merge({:hash_value => hash(params, api_key)})
|
66
|
+
response = http_client.request(URI.parse(uri.to_s))
|
67
|
+
JSON(response.body, :symbolize_names => true)
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class AdtekioAdnetworks::Revenue::Lifestreet
|
2
|
+
include AdtekioAdnetworks::RevenueImport
|
3
|
+
|
4
|
+
define_required_credentials do
|
5
|
+
[:username, :password]
|
6
|
+
end
|
7
|
+
|
8
|
+
def revenues(from, to)
|
9
|
+
add_global_stats(from, to).map do |(date, appname), values|
|
10
|
+
values.map do |dpt|
|
11
|
+
{
|
12
|
+
:appname => appname,
|
13
|
+
:date => Date.strptime(date, "%Y-%m-%d"),
|
14
|
+
:country => dpt["Country.name"],
|
15
|
+
:impressions => dpt["adImps"].to_i,
|
16
|
+
:amount => dpt["adCost"].to_f
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end.flatten
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_global_stats(from, to)
|
23
|
+
# report comes split by country without a summary entry
|
24
|
+
# over all countries, so add this summary.
|
25
|
+
Hash[report(from,to)["data"].
|
26
|
+
group_by { |a| [a["Date"], a["AdSlot.name"]] }.
|
27
|
+
map do |(date, appname), values|
|
28
|
+
[ [date,appname], values +
|
29
|
+
[{ "Date" => date,
|
30
|
+
"AdSlot.name" => appname,
|
31
|
+
"Country.name" => nil,
|
32
|
+
"adImps" => values.map{ |a| a["adImps"] }.sum,
|
33
|
+
"adCost" => values.map{ |a| a["adCost"] }.sum }]]
|
34
|
+
end]
|
35
|
+
end
|
36
|
+
|
37
|
+
def report(from, to)
|
38
|
+
uri = Addressable::URI.
|
39
|
+
parse("https://my.lifestreetmedia.com/reporting/run/")
|
40
|
+
request = Net::HTTP::Post.new uri.request_uri
|
41
|
+
request.basic_auth credentials.username, credentials.password
|
42
|
+
# body is cgi encoded parameter with json values.
|
43
|
+
request.body = "data=" + ({
|
44
|
+
"measurements" => ["adImps", "adCost"],
|
45
|
+
"dimensions" => ["Date", "AdSlot.name",
|
46
|
+
"Country.name"],
|
47
|
+
"start_date" => from.to_s,
|
48
|
+
"end_date" => to.to_s,
|
49
|
+
"mobile" => true
|
50
|
+
}.to_json)
|
51
|
+
|
52
|
+
http = Net::HTTP.new(uri.hostname, 443)
|
53
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
54
|
+
http.use_ssl = true
|
55
|
+
|
56
|
+
response = http.request(request)
|
57
|
+
JSON.parse(response.body)
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class AdtekioAdnetworks::Revenue::Mdotm
|
2
|
+
include AdtekioAdnetworks::RevenueImport
|
3
|
+
|
4
|
+
define_required_credentials do
|
5
|
+
[:account_id, :secret_key]
|
6
|
+
end
|
7
|
+
|
8
|
+
def revenues(from, to)
|
9
|
+
report(from, to).map do |data|
|
10
|
+
{
|
11
|
+
:impressions => data["impressions"].to_i,
|
12
|
+
:requests => data["requests"].to_i,
|
13
|
+
:clicks => data["clicks"].to_i,
|
14
|
+
:amount => data["earnings"].to_f,
|
15
|
+
:date => Date.strptime(data["logDT"], "%Y-%m-%d"),
|
16
|
+
:appname => data["appname"]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def report(from,to)
|
22
|
+
url = "http://platform.mdotm.com/monetize/appstats/" +
|
23
|
+
credentials.account_id.to_s + "/" +
|
24
|
+
credentials.secret_key.to_s + "/" +
|
25
|
+
from.strftime("%Y-%m-%d") + "/" +
|
26
|
+
to.strftime("%Y-%m-%d")
|
27
|
+
|
28
|
+
JSON(do_request(url))
|
29
|
+
end
|
30
|
+
|
31
|
+
def do_request(url)
|
32
|
+
h = Net::HTTP::Persistent.new('whatever')
|
33
|
+
h.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
34
|
+
uri = URI.parse(url)
|
35
|
+
req = Net::HTTP::Get.new uri.request_uri
|
36
|
+
h.request(uri,req).body
|
37
|
+
end
|
38
|
+
end
|