jruby-am-api 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in jruby-am-api.gemspec
4
+ gemspec
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "android_market/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "jruby-am-api"
7
+ s.version = AndroidMarket::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Mason Chang"]
10
+ s.email = ["changmason@gmail.com"]
11
+ s.homepage = "http://rubygems.org/gems/jruby-am-api"
12
+ s.summary = %q{android market api in jruby}
13
+ s.description = %q{a port of android market api from java}
14
+
15
+ s.rubyforge_project = "jruby-am-api"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,11 @@
1
+
2
+ # java
3
+ require File.dirname(__FILE__) + "/java/protobuf-java-2.2.0.jar"
4
+ require File.dirname(__FILE__) + "/java/am-api-models_20101114.jar"
5
+ require File.dirname(__FILE__) + "/java/protobuf-format-java-1.2.jar"
6
+
7
+ # ruby
8
+ require File.dirname(__FILE__) + "/android_market/session"
9
+
10
+ module AndroidMarket
11
+ end
@@ -0,0 +1,193 @@
1
+ require File.dirname(__FILE__) + "/tools"
2
+
3
+ module AndroidMarket
4
+ class Session
5
+
6
+ java_import com.gc.android.market.api.model.Market
7
+ java_import com.gc.android.market.api.model.Market::Request
8
+ java_import com.gc.android.market.api.model.Market::Response
9
+ java_import com.gc.android.market.api.model.Market::RequestContext
10
+ java_import com.gc.android.market.api.model.Market::Request::RequestGroup
11
+
12
+ SERVICE = "android"
13
+ URL_LOGIN = "https://www.google.com/accounts/ClientLogin"
14
+ PROTOCOL_VERSION = 2
15
+ ACCOUNT_TYPE = { :google => 'GOOGLE',
16
+ :hosted => 'HOSTED',
17
+ :both => 'HOSTED_OR_GOOGLE' }
18
+
19
+ attr_accessor :context_builder, :auth_sub_token
20
+
21
+ def initialize
22
+ @callbacks = []
23
+ @request_builder = Request.new_builder()
24
+ @context_builder = RequestContext.new_builder()
25
+
26
+ @context_builder.set_unknown1(0)
27
+ @context_builder.set_version(1002)
28
+ @context_builder.set_android_id("0000000000000000")
29
+ @context_builder.set_device_and_sdk_version("sapphire:7")
30
+ set_locale(JavaUtil::Locale.get_default)
31
+ set_operator_tmobile
32
+ end
33
+
34
+ def set_locale(locale)
35
+ @context_builder.set_user_language(locale.language.downcase)
36
+ @context_builder.set_user_country(locale.country.downcase)
37
+ end
38
+
39
+ def set_operator(alpha, sim_alpha, numeric, sim_numeric)
40
+ @context_builder.set_operator_alpha(alpha)
41
+ @context_builder.set_sim_operator_alpha(sim_alpha)
42
+ @context_builder.set_operator_numeric(numeric)
43
+ @context_builder.set_sim_operator_numeric(sim_numeric)
44
+ end
45
+
46
+ def set_operator_tmobile
47
+ set_operator("T-Mobile", "T-Mobile", "310260", "310260")
48
+ end
49
+
50
+ def set_operator_sfr
51
+ set_operator("F SFR", "F SFR", "20810", "20810")
52
+ end
53
+
54
+ def set_operator_o2
55
+ set_operator("o2 - de","o2 - de", "26207", "26207")
56
+ end
57
+
58
+ def set_operator_simyo
59
+ set_operator("E-Plus", "simyo", "26203", "26203")
60
+ end
61
+
62
+ def set_operator_sunrise
63
+ set_operator("sunrise", "sunrise", "22802", "22802")
64
+ end
65
+
66
+ def set_auth_sub_token(auth_sub_token)
67
+ @context_builder.set_auth_sub_token(auth_sub_token)
68
+ self.auth_sub_token = auth_sub_token
69
+ end
70
+
71
+ def login(email, password, account_type = ACCOUNT_TYPE[:both])
72
+ params = { 'Email' => email,
73
+ 'Passwd' => password,
74
+ 'service' => SERVICE,
75
+ 'accountType' => account_type }
76
+ Tools.post_url(URL_LOGIN, params)[/Auth=(.{200,204})$/i]
77
+ if auth_key = $1
78
+ set_auth_sub_token(auth_key)
79
+ else
80
+ raise RuntimeError, "auth_key not found"
81
+ end
82
+ end
83
+
84
+
85
+ def append(request_group, &block)
86
+ case request_group
87
+ when Market::AppsRequest
88
+ @request_builder.add_request_group(RequestGroup.new_builder.set_apps_request(request_group))
89
+ when Market::GetImageRequest
90
+ @request_builder.add_request_group(RequestGroup.new_builder.set_image_request(request_group))
91
+ when Market::CommentsRequest
92
+ @request_builder.add_request_group(RequestGroup.new_builder.set_comments_request(request_group))
93
+ when Market::CategoriesRequest
94
+ @request_builder.add_request_group(RequestGroup.new_builder.set_categories_request(request_group))
95
+ end
96
+ @callbacks << block if block_given?
97
+ end
98
+
99
+
100
+ def flush
101
+ context = @context_builder.build
102
+ @context_builder = RequestContext.new_builder(context)
103
+ @request_builder.set_context(context)
104
+
105
+ response = execute_protobuf(@request_builder.build)
106
+ response.get_response_group_list.to_a.each do |res|
107
+ value = res.get_apps_response if res.has_apps_response
108
+ value = res.get_categories_response if res.has_categories_response
109
+ value = res.get_comments_response if res.has_comments_response
110
+ value = res.get_image_response if res.has_image_response
111
+ @callbacks.first.call(context, value)
112
+ end
113
+
114
+ @request_builder = Request.new_builder
115
+ @callbacks.clear
116
+ end
117
+
118
+
119
+ # def execute(request_group, &block)
120
+ # case request_group
121
+ # when Market::AppsRequest
122
+ # @request_builder.add_request_group(RequestGroup.new_builder.set_apps_request(request_group))
123
+ # when Market::GetImageRequest
124
+ # @request_builder.add_request_group(RequestGroup.new_builder.set_image_request(request_group))
125
+ # when Market::CommentsRequest
126
+ # @request_builder.add_request_group(RequestGroup.new_builder.set_comments_request(request_group))
127
+ # when Market::CategoriesRequest
128
+ # @request_builder.add_request_group(RequestGroup.new_builder.set_categories_request(request_group))
129
+ # end
130
+ # context = @context_builder.build
131
+ # @context_builder = RequestContext.new_builder(context)
132
+ # @request_builder.set_context(context)
133
+ # response = execute_protobuf(@request_builder.build)
134
+ #
135
+ #
136
+ # block.call(ctxt, resp) if block_given?
137
+ #
138
+ # @request_builder = Request.new_builder
139
+ #
140
+ # return resp
141
+ # end
142
+
143
+
144
+ def execute_protobuf(request)
145
+ request_string = String.from_java_bytes(request.to_byte_array)
146
+ response_bytes = execute_raw_http_query(request_string)
147
+ begin
148
+ return Response.parse_from(response_bytes)
149
+ rescue => ex
150
+ raise RuntimeError, ex.message
151
+ end
152
+ end
153
+
154
+
155
+ def execute_raw_http_query(request)
156
+ url = JavaNet::URL.new("http://android.clients.google.com/market/api/ApiRequest")
157
+ connection = url.open_connection
158
+ connection.set_do_output(true)
159
+ connection.set_request_method('POST')
160
+ connection.set_request_property('Cookie','ANDROID=' + @auth_sub_token)
161
+ connection.set_request_property('User-Agent', 'Android-Market/2 (sapphire PLAT-RC33); gzip')
162
+ connection.set_request_property('Content-Type', 'application/x-www-form-urlencoded')
163
+ connection.set_request_property('Accept-Charset','ISO-8859-1,utf-8;q=0.7,*;q=0.7')
164
+
165
+ request64 = Tools.urlsafe_encode64(request)
166
+ request_data = "version=#{PROTOCOL_VERSION}&request=#{request64}".to_java
167
+
168
+ connection.set_fixed_length_streaming_mode(request_data.get_bytes("UTF-8").length)
169
+ os = connection.get_output_stream
170
+ os.write(request_data.get_bytes)
171
+ os.close
172
+
173
+ if connection.get_response_code >= 400
174
+ raise RuntimeError, "Response Code = #{connection.get_response_code}, " +
175
+ "Message = #{connection.get_response_message}"
176
+ end
177
+
178
+ is = connection.get_input_stream
179
+ gz_is = java.util.zip::GZIPInputStream.new(is)
180
+ ba_os = java.io::ByteArrayOutputStream.new
181
+ buff = Java::byte[1024].new #"a buffer string".to_java_bytes
182
+ while(true) do
183
+ nb = gz_is.read(buff)
184
+ nb < 0 ? break : ba_os.write(buff, 0, nb)
185
+ end
186
+ is.close
187
+ connection.disconnect
188
+
189
+ return ba_os.to_byte_array
190
+ end
191
+
192
+ end # end of class
193
+ end # end of module
@@ -0,0 +1,37 @@
1
+ module AndroidMarket
2
+ module Tools
3
+
4
+ #module_function :urlsafe_encode64, :post_url
5
+
6
+ def self.urlsafe_encode64(bin)
7
+ [bin].pack("m0").tr("+/", "-_").gsub("\n","")
8
+ end
9
+
10
+
11
+ def self.post_url(url, params)
12
+ data = params.map { |key, val|
13
+ java.net::URLEncoder.encode(key, "UTF-8") + "=" +
14
+ java.net::URLEncoder.encode(val, "UTF-8")
15
+ }.join("&")
16
+ connection = java.net::URL.new(url).open_connection
17
+ connection.set_do_output(true)
18
+ connection.set_do_input(true)
19
+ connection.set_request_method("POST")
20
+
21
+ stream_to_authorize = java.io::OutputStreamWriter.new(connection.get_output_stream)
22
+ stream_to_authorize.write(data)
23
+ stream_to_authorize.flush
24
+ stream_to_authorize.close
25
+
26
+ result_stream = connection.get_input_stream
27
+ reader = java.io::BufferedReader.new(java.io::InputStreamReader.new(result_stream))
28
+ response = java.lang::StringBuffer.new
29
+ while line = reader.read_line do
30
+ response.append(line)
31
+ end
32
+ result_stream.close
33
+ response.to_string
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module AndroidMarket
2
+ VERSION = "0.0.1"
3
+ end
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jruby-am-api
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Mason Chang
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-14 00:00:00 +08:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: a port of android market api from java
22
+ email:
23
+ - changmason@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - .gitignore
32
+ - Gemfile
33
+ - README
34
+ - Rakefile
35
+ - jruby-am-api.gemspec
36
+ - lib/android_market.rb
37
+ - lib/android_market/session.rb
38
+ - lib/android_market/tools.rb
39
+ - lib/android_market/version.rb
40
+ - lib/java/am-api-models_20101114.jar
41
+ - lib/java/protobuf-format-java-1.2.jar
42
+ - lib/java/protobuf-java-2.2.0.jar
43
+ has_rdoc: true
44
+ homepage: http://rubygems.org/gems/jruby-am-api
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options: []
49
+
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirements: []
67
+
68
+ rubyforge_project: jruby-am-api
69
+ rubygems_version: 1.3.6
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: android market api in jruby
73
+ test_files: []
74
+