appfigures 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem "bundler"
4
+ gem "httparty"
5
+
6
+ group :development do
7
+ gem "rake"
8
+ gem "gemcutter"
9
+ gem "jeweler"
10
+ end
@@ -0,0 +1,29 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ gemcutter (0.7.1)
5
+ git (1.2.5)
6
+ httparty (0.9.0)
7
+ multi_json (~> 1.0)
8
+ multi_xml
9
+ jeweler (1.8.4)
10
+ bundler (~> 1.0)
11
+ git (>= 1.2.5)
12
+ rake
13
+ rdoc
14
+ json (1.7.5)
15
+ multi_json (1.3.6)
16
+ multi_xml (0.5.1)
17
+ rake (0.9.2.2)
18
+ rdoc (3.12)
19
+ json (~> 1.4)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ bundler
26
+ gemcutter
27
+ httparty
28
+ jeweler
29
+ rake
@@ -0,0 +1,28 @@
1
+ require "rake/testtask"
2
+ require "yaml"
3
+ require "test/unit"
4
+
5
+ require "rubygems"
6
+ require "bundler"
7
+ Bundler.require(:default, :development)
8
+
9
+ Rake::TestTask.new do |t|
10
+ t.libs << "test"
11
+ t.test_files = FileList['test/test*.rb']
12
+ t.verbose = true
13
+ end
14
+
15
+ begin
16
+ Jeweler::Tasks.new do |gemspec|
17
+ gemspec.name = "appfigures"
18
+ gemspec.summary = "AppFigures API"
19
+ gemspec.description = "AppFigures API ruby edition"
20
+ gemspec.email = "francis@ignition.hk"
21
+ gemspec.homepage = "https://github.com/siuying/appfigures"
22
+ gemspec.authors = ["Francis Chong"]
23
+ end
24
+ Jeweler::GemcutterTasks.new
25
+
26
+ rescue LoadError
27
+ puts "Jeweler not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
28
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,64 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "appfigures"
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Francis Chong"]
12
+ s.date = "2012-09-16"
13
+ s.description = "AppFigures API ruby edition"
14
+ s.email = "francis@ignition.hk"
15
+ s.files = [
16
+ ".rvmrc",
17
+ "Gemfile",
18
+ "Gemfile.lock",
19
+ "Rakefile",
20
+ "VERSION",
21
+ "appfigures.gemspec",
22
+ "lib/appfigures.rb",
23
+ "lib/appfigures/data.rb",
24
+ "lib/appfigures/external.rb",
25
+ "lib/appfigures/rank.rb",
26
+ "lib/appfigures/sale.rb",
27
+ "lib/appfigures/user.rb",
28
+ "test/appfigures_fixture.yml.default",
29
+ "test/test_data.rb",
30
+ "test/test_external.rb",
31
+ "test/test_rank.rb",
32
+ "test/test_sale.rb",
33
+ "test/test_user.rb"
34
+ ]
35
+ s.homepage = "https://github.com/siuying/appfigures"
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = "1.8.15"
38
+ s.summary = "AppFigures API"
39
+
40
+ if s.respond_to? :specification_version then
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<bundler>, [">= 0"])
45
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
46
+ s.add_development_dependency(%q<rake>, [">= 0"])
47
+ s.add_development_dependency(%q<gemcutter>, [">= 0"])
48
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
49
+ else
50
+ s.add_dependency(%q<bundler>, [">= 0"])
51
+ s.add_dependency(%q<httparty>, [">= 0"])
52
+ s.add_dependency(%q<rake>, [">= 0"])
53
+ s.add_dependency(%q<gemcutter>, [">= 0"])
54
+ s.add_dependency(%q<jeweler>, [">= 0"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<bundler>, [">= 0"])
58
+ s.add_dependency(%q<httparty>, [">= 0"])
59
+ s.add_dependency(%q<rake>, [">= 0"])
60
+ s.add_dependency(%q<gemcutter>, [">= 0"])
61
+ s.add_dependency(%q<jeweler>, [">= 0"])
62
+ end
63
+ end
64
+
@@ -0,0 +1,12 @@
1
+ path = File.expand_path(File.dirname(__FILE__))
2
+ $:.unshift(path) unless $:.include?(path)
3
+
4
+ module Appfigures
5
+ API_URL = "https://api.appfigures.com/v1.1"
6
+ end
7
+
8
+ require 'appfigures/user'
9
+ require 'appfigures/data'
10
+ require 'appfigures/sale'
11
+ require 'appfigures/rank'
12
+ require 'appfigures/external'
@@ -0,0 +1,30 @@
1
+ require 'httparty'
2
+
3
+ module Appfigures
4
+ class Data
5
+ include HTTParty
6
+ base_uri API_URL
7
+ format :json
8
+
9
+ def initialize(username, password)
10
+ @auth = {:username => username, :password => password}
11
+ end
12
+
13
+ def categories
14
+ self.class.get("/data/categories", {:basic_auth => @auth})
15
+ end
16
+
17
+ def stores
18
+ self.class.get("/data/stores", {:basic_auth => @auth})
19
+ end
20
+
21
+ def languages
22
+ self.class.get("/data/languages", {:basic_auth => @auth})
23
+ end
24
+
25
+ def currencies
26
+ self.class.get("/data/currencies", {:basic_auth => @auth})
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ require 'httparty'
2
+
3
+ module Appfigures
4
+ class External
5
+ include HTTParty
6
+ base_uri API_URL
7
+ format :json
8
+
9
+ def initialize(username, password)
10
+ @auth = {:username => username, :password => password}
11
+ end
12
+
13
+ def external
14
+ self.class.get("/external_accounts", {:basic_auth => @auth})
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ require 'httparty'
2
+
3
+ module Appfigures
4
+ class Rank
5
+ include HTTParty
6
+ base_uri API_URL
7
+ format :json
8
+
9
+ def initialize(username, password)
10
+ @auth = {:username => username, :password => password}
11
+ end
12
+
13
+ # Generating a Ranks Report
14
+ def ranks(app_id, granularity, start_date, end_date, options = {})
15
+ options.merge!({:basic_auth => @auth})
16
+ self.class.get("/ranks/#{app_id}/#{granularity}/#{start_date}/#{end_date}/", options)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,53 @@
1
+ require 'httparty'
2
+
3
+ module Appfigures
4
+ class Sale
5
+ include HTTParty
6
+ base_uri API_URL
7
+ format :json
8
+
9
+ TYPE = {:DATES => "dates", :COUNTRIES => "countries", :PRODUCTS => "products", :REGION => "regions",
10
+ :DATES_PRODUCTS => "dates+products", :PRODUCTS_DATES => "products+dates",
11
+ :COUNTRIES_PRODUCTS => "countries+products", :PRODUCTS_COUNTRIES => "products+countries",
12
+ :COUNTRIES_DATES => "countries+dates", :DATES_COUNTRIES => "dates+countries"
13
+ }
14
+
15
+ DATASOURCE = {:DAILY => "daily", :WEEKLY => "weekly", :MONTHLY => "monthly"}
16
+
17
+ def initialize(username, password)
18
+ @auth = {:username => username, :password => password}
19
+ end
20
+
21
+ # Generating a By App, By Country, or By Date Sales Report
22
+ # options[:query] can be data_source, apps or country
23
+ def sales(type, start_date, end_date, product_ids, options={})
24
+ raise ArgumentError, "Type must be one of TYPE: #{TYPE.values.join(", ")}" unless TYPE.values.index(type)
25
+ raise ArgumentError, "Type must be one of DATASOURCE: #{DATASOURCE.values.join(", ")}" if (options[:data_source] && !DATASOURCE.values.index(options[:data_source]))
26
+
27
+ product_ids = [product_ids] unless product_ids.is_a?(Array)
28
+ options.merge!({:basic_auth => @auth, :product_ids => product_ids.join(";")})
29
+ url = "/sales/#{type}/#{start_date}/#{end_date}/"
30
+ self.class.get(url, options)
31
+ end
32
+
33
+ # Generating all time totals report
34
+ # type must be one of products, products+countries, countries, countries+products
35
+ def alltime_sales(type, product_ids=[], options={})
36
+ accept_types = %w{products products+countries countries countries+products}
37
+ raise ArgumentError, "Type must be one of TYPE: #{accept_types}" unless accept_types.include?(type)
38
+ product_ids = [product_ids] unless product_ids.is_a?(Array)
39
+
40
+ options.merge!({:basic_auth => @auth, :products => product_ids.join(";")})
41
+ url = "/reports/sales/#{type}"
42
+ self.class.get(url, options)
43
+ end
44
+
45
+ # Generating a By Region Sales Report
46
+ def region_sales(start_date, end_date, options={})
47
+ options.merge!({:basic_auth => @auth})
48
+ url = "/sales/regions/#{start_date}/#{end_date}"
49
+ self.class.get(url, options)
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,24 @@
1
+ require 'httparty'
2
+ require 'uri'
3
+
4
+ module Appfigures
5
+ class User
6
+ include HTTParty
7
+ base_uri API_URL
8
+ format :json
9
+
10
+ def initialize(username, password)
11
+ @auth = {:username => username, :password => password}
12
+ end
13
+
14
+ def details(email=@auth[:username])
15
+ email = URI.escape(email)
16
+ self.class.get("/users/#{email}", {:basic_auth => @auth})
17
+ end
18
+
19
+ def products(email=@auth[:username])
20
+ email = URI.escape(email)
21
+ self.class.get("/users/#{email}/products", {:basic_auth => @auth})
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ ---
2
+ :username:
3
+ :password:
@@ -0,0 +1,49 @@
1
+ require "yaml"
2
+ require "test/unit"
3
+
4
+ require "rubygems"
5
+ require "bundler"
6
+ Bundler.require(:default)
7
+
8
+ require "./lib/appfigures"
9
+
10
+ class TestData < Test::Unit::TestCase
11
+ def setup
12
+ path = File.expand_path(File.dirname(__FILE__))
13
+ @config = YAML::load(open("#{path}/appfigures_fixture.yml"))
14
+
15
+ assert_not_nil(@config, "you must create appfigures_fixture.yml")
16
+ assert_not_nil(@config[:username], "you must configure username")
17
+ assert_not_nil(@config[:password], "you must configure password")
18
+
19
+ assert_not_equal("", @config[:username], "you must configure username")
20
+ assert_not_equal("", @config[:password], "you must configure password")
21
+
22
+ @data_service = Appfigures::Data.new @config[:username], @config[:password]
23
+ end
24
+
25
+ def test_categories
26
+ data = @data_service.categories
27
+ assert_not_nil(data)
28
+ assert_kind_of(Hash, data)
29
+ end
30
+
31
+ def test_stores
32
+ data = @data_service.stores
33
+ assert_not_nil(data)
34
+ assert_kind_of(Hash, data)
35
+ end
36
+
37
+ def test_languages
38
+ data = @data_service.languages
39
+ assert_not_nil(data)
40
+ assert_kind_of(Hash, data)
41
+ end
42
+
43
+ def test_currencies
44
+ data = @data_service.currencies
45
+ assert_not_nil(data)
46
+ assert_kind_of(Array, data)
47
+ end
48
+
49
+ end
@@ -0,0 +1,32 @@
1
+ require "yaml"
2
+ require "test/unit"
3
+
4
+ require "rubygems"
5
+ require "bundler"
6
+ Bundler.require(:default)
7
+
8
+ require "./lib/appfigures"
9
+
10
+ class TestUser < Test::Unit::TestCase
11
+ # def test_external
12
+ # path = File.expand_path(File.dirname(__FILE__))
13
+ # @config = YAML::load(open("#{path}/appfigures_fixture.yml"))
14
+ # @details = @user.details(@config[:username])
15
+
16
+ # if @details["role"] == "admin"
17
+ # @external = Appfigures::External.new @config[:username], @config[:password]
18
+ # acct = @external.external
19
+ # assert_not_nil(acct)
20
+ # assert_kind_of(Hash, acct)
21
+ # assert(acct.size > 0, "account should have at least one itc_account")
22
+
23
+ # first_acct = acct[acct.keys.first]
24
+ # assert_kind_of(Hash, first_acct)
25
+ # assert_not_nil(first_acct["account_id"])
26
+ # assert_not_nil(first_acct["id"])
27
+ # else
28
+ # assert_equal(acct.parsed_response["additional"], "You do not have permission to access this resource.")
29
+ # end
30
+
31
+ # end
32
+ end
@@ -0,0 +1,44 @@
1
+ require "yaml"
2
+ require "test/unit"
3
+
4
+ require "rubygems"
5
+ require "bundler"
6
+ Bundler.require(:default)
7
+
8
+ require "./lib/appfigures"
9
+ require 'uri'
10
+ class TestRank < Test::Unit::TestCase
11
+ def setup
12
+ path = File.expand_path(File.dirname(__FILE__))
13
+ @config = YAML::load(open("#{path}/appfigures_fixture.yml"))
14
+
15
+ assert_not_nil(@config, "you must create appfigures_fixture.yml")
16
+ assert_not_nil(@config[:username], "you must configure username")
17
+ assert_not_nil(@config[:password], "you must configure password")
18
+
19
+ assert_not_equal("", @config[:username], "you must configure username")
20
+ assert_not_equal("", @config[:password], "you must configure password")
21
+
22
+ @user = Appfigures::User.new @config[:username], @config[:password]
23
+ @rank = Appfigures::Rank.new @config[:username], @config[:password]
24
+
25
+ @day_minutes_one = (Time.now - 24*60*60).strftime("%Y-%m-%d")
26
+ @day_minutes_two = (Time.now - 2*24*60*60).strftime("%Y-%m-%d")
27
+ end
28
+
29
+ def test_ranks
30
+ apps = @user.products(@config[:username])
31
+ first_app = apps[apps.keys.first]
32
+ assert_kind_of(Hash, first_app)
33
+
34
+ ranks = @rank.ranks(first_app["id"], "daily", @day_minutes_two, @day_minutes_one)
35
+ assert_not_nil(ranks, "ranks report should be okay")
36
+ end
37
+
38
+ def test_ranks_complex
39
+ apps = @user.products(@config[:username])
40
+ apps = apps.keys[0..10].join(";")
41
+ ranks = @rank.ranks(apps, "daily", @day_minutes_two, @day_minutes_one)
42
+ assert_not_nil(ranks, "ranks report should be okay")
43
+ end
44
+ end
@@ -0,0 +1,51 @@
1
+ require "yaml"
2
+ require "test/unit"
3
+
4
+ require "rubygems"
5
+ require "bundler"
6
+ Bundler.require(:default)
7
+
8
+ require "./lib/appfigures"
9
+
10
+ class TestSale < Test::Unit::TestCase
11
+ def setup
12
+ path = File.expand_path(File.dirname(__FILE__))
13
+ @config = YAML::load(open("#{path}/appfigures_fixture.yml"))
14
+
15
+ assert_not_nil(@config, "you must create appfigures_fixture.yml")
16
+ assert_not_nil(@config[:username], "you must configure username")
17
+ assert_not_nil(@config[:password], "you must configure password")
18
+
19
+ assert_not_equal("", @config[:username], "you must configure username")
20
+ assert_not_equal("", @config[:password], "you must configure password")
21
+
22
+ @sale = Appfigures::Sale.new @config[:username], @config[:password]
23
+ @user = Appfigures::User.new @config[:username], @config[:password]
24
+
25
+ @day_minutes_one = (Time.now - 24*60*60).strftime("%Y-%m-%d")
26
+ @day_minutes_two = (Time.now - 2*24*60*60).strftime("%Y-%m-%d")
27
+
28
+ @apps = @user.products(@config[:username])
29
+ @first_app = @apps[@apps.keys.first]
30
+ assert_kind_of(Hash, @first_app)
31
+
32
+ end
33
+
34
+ def test_sales
35
+ one_app_report = @sale.sales("dates", @day_minutes_two, @day_minutes_one, [@first_app["id"]])
36
+ assert_not_nil(one_app_report, "sales report (one app only) should be okay")
37
+ end
38
+
39
+ def test_alltime
40
+ alltime_report = @sale.alltime_sales("products", @first_app["id"])
41
+ assert_not_nil(alltime_report, "all time report should be okay")
42
+ assert_kind_of(Hash, alltime_report)
43
+ end
44
+
45
+ def test_region
46
+ alltime_report = @sale.region_sales(@day_minutes_two, @day_minutes_one)
47
+ assert_not_nil(alltime_report, "all time report should be okay")
48
+ assert_kind_of(Hash, alltime_report)
49
+ end
50
+
51
+ end
@@ -0,0 +1,51 @@
1
+ require "yaml"
2
+ require "test/unit"
3
+
4
+ require "rubygems"
5
+ require "bundler"
6
+ Bundler.require(:default)
7
+
8
+ require "./lib/appfigures"
9
+
10
+ class TestUser < Test::Unit::TestCase
11
+ def setup
12
+ path = File.expand_path(File.dirname(__FILE__))
13
+ @config = YAML::load(open("#{path}/appfigures_fixture.yml"))
14
+
15
+ assert_not_nil(@config, "you must create appfigures_fixture.yml")
16
+ assert_not_nil(@config[:username], "you must configure username")
17
+ assert_not_nil(@config[:password], "you must configure password")
18
+
19
+ assert_not_equal("", @config[:username], "you must configure username")
20
+ assert_not_equal("", @config[:password], "you must configure password")
21
+
22
+ @user = Appfigures::User.new @config[:username], @config[:password]
23
+ end
24
+
25
+ def test_details
26
+ details = @user.details(@config[:username])
27
+ assert_not_nil(details)
28
+
29
+ assert_not_nil(details["region"])
30
+ assert_not_nil(details["id"])
31
+ assert_not_nil(details["account"])
32
+ assert_not_nil(details["products"])
33
+
34
+ assert_kind_of(Hash, details["account"])
35
+ assert_kind_of(Array, details["products"])
36
+ end
37
+
38
+ def test_apps
39
+ apps = @user.products(@config[:username])
40
+ assert_not_nil(apps)
41
+ assert_kind_of(Hash, apps)
42
+
43
+ assert(apps.size > 0, "account should have at least one app")
44
+ first_app = apps[apps.keys.first]
45
+ assert_kind_of(Hash, first_app)
46
+ assert_kind_of(Array, first_app["in_apps"])
47
+ assert_not_nil(first_app["name"])
48
+ assert_not_nil(first_app["id"])
49
+ end
50
+
51
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appfigures
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Francis Chong
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: &70099329990640 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70099329990640
25
+ - !ruby/object:Gem::Dependency
26
+ name: httparty
27
+ requirement: &70099329990060 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70099329990060
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70099329989400 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70099329989400
47
+ - !ruby/object:Gem::Dependency
48
+ name: gemcutter
49
+ requirement: &70099329988920 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70099329988920
58
+ - !ruby/object:Gem::Dependency
59
+ name: jeweler
60
+ requirement: &70099329988360 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70099329988360
69
+ description: AppFigures API ruby edition
70
+ email: francis@ignition.hk
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - .rvmrc
76
+ - Gemfile
77
+ - Gemfile.lock
78
+ - Rakefile
79
+ - VERSION
80
+ - appfigures.gemspec
81
+ - lib/appfigures.rb
82
+ - lib/appfigures/data.rb
83
+ - lib/appfigures/external.rb
84
+ - lib/appfigures/rank.rb
85
+ - lib/appfigures/sale.rb
86
+ - lib/appfigures/user.rb
87
+ - test/appfigures_fixture.yml.default
88
+ - test/test_data.rb
89
+ - test/test_external.rb
90
+ - test/test_rank.rb
91
+ - test/test_sale.rb
92
+ - test/test_user.rb
93
+ homepage: https://github.com/siuying/appfigures
94
+ licenses: []
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ segments:
106
+ - 0
107
+ hash: 2930390160613838490
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 1.8.15
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: AppFigures API
120
+ test_files: []