jruby-am-api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+