Wassruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.txt +40 -0
  2. data/lib/Wassruby.rb +181 -0
  3. data/lib/simplejson.rb +285 -0
  4. metadata +56 -0
data/README.txt ADDED
@@ -0,0 +1,40 @@
1
+ = Wassruby.rb
2
+
3
+ Copyright (c) 2008 MANNAMI Takuya <takuya.mannami@gmail.com>
4
+
5
+ == Example
6
+
7
+ require 'wassruby'
8
+
9
+ wassr = WWW::Wassr.new('LOGIN_ID','PASSWORD')
10
+
11
+ wassr.message = "test"
12
+
13
+ wassr.post_message # => send message "test"
14
+
15
+
16
+ wassr.user_id = "foo"
17
+ wassr.get_show.each {|v|
18
+ puts v["user_login_id"]
19
+ puts v["text"]
20
+ }
21
+
22
+ wassr.get_show.each {|v|
23
+ puts v["user_login_id"]
24
+ puts v["text"]
25
+ }
26
+
27
+ wassr.get_user_timeline.each {|v|
28
+ puts v["user_login_id"]
29
+ puts v["text"]
30
+ }
31
+
32
+ wassr.get_friends_timeline.each {|v|
33
+ puts v["user_login_id"]
34
+ puts v["text"]
35
+ }
36
+
37
+ wassr.get_footmark.each {|v|
38
+ puts v["nick"]
39
+ puts v["login_id"]
40
+ }
data/lib/Wassruby.rb ADDED
@@ -0,0 +1,181 @@
1
+ #
2
+ #= Simple Wassr Client
3
+ #Authors:: Takuya Mannami
4
+ #Version:: 0.0.1
5
+ #License:: MIT License
6
+ #
7
+ #==Wassruby use simplejson.rb
8
+ #WebOS Goodies (http://webos-goodies.jp/archives/51071565.html)
9
+ #
10
+ #Simple JSON parser & builde(http://rubyforge.org/snippet/detail.php?type=snippet&id=148)
11
+
12
+ require 'open-uri'
13
+ require 'net/http'
14
+ require 'cgi'
15
+ require 'lib/simplejson'
16
+
17
+ module WWW
18
+ class Wassr
19
+ VERSION = '0.0.1'
20
+ WASSR = "api.wassr.jp"
21
+
22
+ WASSR_API_URI = {
23
+ :UPDATE => "/statuses/update.json?status=",
24
+ :USER_TIMELINE => "/statuses/user_timeline.json?id=",
25
+ :FRIENDS_TIMELINE => "/statuses/friends_timeline.json?id=",
26
+ :PUBLIC_TIMELINE => "/statuses/public_timeline.json",
27
+ :FOOTMARK => "/footmark/recent.json",
28
+ :SHOW => "/statuses/show.json?id=",
29
+ :FRIENDS => "/statuses/friends.json",
30
+ :FOLLOWERS => "/statuses/followers.json",
31
+ }
32
+
33
+ ###
34
+ #login id
35
+ attr_accessor :login_id
36
+ #password
37
+ attr_accessor :password
38
+ #post message
39
+ attr_accessor :message
40
+ ###
41
+
42
+ ###
43
+ #friend id or user id
44
+ attr_accessor :user_id
45
+ ###
46
+
47
+ #wassr = WWW::Wassr.new('LOGIN_ID', 'PASSWORD')
48
+ def initialize(login_id, password)
49
+ ###
50
+ @login_id = login_id
51
+ @password = password
52
+ ###
53
+
54
+ ###
55
+ @message = nil
56
+ @escape_message = nil
57
+ @user_id = nil
58
+ ###
59
+
60
+ ###
61
+ @http_obj = Net::HTTP.new(WASSR,80)
62
+ #using simplejson.rb
63
+ @jp_obj = JsonParser.new
64
+ ###
65
+ end
66
+
67
+ #
68
+ #WWW::Wassr.start('LOGIN_ID', 'PASSWORD') {|wassr|
69
+ #}
70
+ #
71
+ def Wassr.start(login_id, password)
72
+ if block_given?
73
+ yield self.new(login_id, password)
74
+ end
75
+ end
76
+
77
+
78
+ #------------------------------------------------------
79
+ def json_parse(response_body) # :nodoc:
80
+ return @jp_obj.parse(response_body)
81
+ end
82
+
83
+ def get_http_response_body(uri) #:nodoc:
84
+ res = @http_obj.get(uri)
85
+ return res.body
86
+ end
87
+
88
+ def get_val(uri) # :nodoc:
89
+ res_body = get_http_response_body(uri)
90
+ json_parse(res_body)
91
+ end
92
+
93
+ #wasssr.message = 'test'
94
+ #
95
+ #wassr.post_message # => send message 'test'
96
+ def post_message
97
+ @escape_message = escape(@message)
98
+ req = Net::HTTP::Post.new(WASSR_API_URI[:UPDATE]+"#{@escape_message}")
99
+ req.basic_auth @login_id, @password
100
+ res = @http_obj.request(req)
101
+ return res
102
+ end
103
+
104
+ #wassr.user_id = 'FRIEND_ID'
105
+ #
106
+ #wassr.get_friends_timeline.each {|v|
107
+ # puts v["user_login_id"]
108
+ # puts v["text"]
109
+ #}
110
+ def get_friends_timeline
111
+ get_val(WASSR_API_URI[:FRIENDS_TIMELINE]+"#{@user_id.to_s}")
112
+ end
113
+
114
+ #wassr.get_public_timeline.each {|v|
115
+ # puts v[0]["user_login_id"]
116
+ # puts v[0]["text"]
117
+ #}
118
+ def get_public_timeline
119
+ get_val(WASSR_API_URI[:PUBLIC_TIMELINE])
120
+ end
121
+
122
+ #wassr.user_id = "foo"
123
+ #
124
+ #wassr.get_user_timeline.each {|v|
125
+ # puts v["user_login_id"]
126
+ # puts v["text"]
127
+ #}
128
+ def get_user_timeline
129
+ get_val(WASSR_API_URI[:USER_TIMELINE]+"#{@user_id.to_s}")
130
+ end
131
+
132
+ #
133
+ #wassr.user_id = "foo"
134
+ #
135
+ #wassr.get_show.each {|v|
136
+ # puts v["user_login_id"]
137
+ # puts v["text"]
138
+ #}
139
+ def get_show
140
+ get_val(WASSR_API_URI[:SHOW]+"#{@user_id.to_s}")
141
+ end
142
+
143
+ #wassr.get_friends.each{|v|
144
+ # puts v["name"]
145
+ # puts v["screen_name"]
146
+ #}
147
+ def get_friends
148
+ req = Net::HTTP::Get.new(WASSR_API_URI[:FRIENDS])
149
+ req.basic_auth @login_id, @password
150
+ res = @http_obj.request(req)
151
+ json_parse(res.body)
152
+ end
153
+
154
+ #wassr.get_followers{|v|
155
+ # puts v["name"]
156
+ # puts v["screen_name"]
157
+ #}
158
+ def get_followers
159
+ req = Net::HTTP::Get.new(WASSR_API_URI[:FOLLOWERS])
160
+ req.basic_auth @login_id, @password
161
+ res = @http_obj.request(req)
162
+ json_parse(res.body)
163
+ end
164
+
165
+ #wassr.get_footmark.each {|v|
166
+ # puts v["nick"]
167
+ # puts v["login_id"]
168
+ #}
169
+ def get_footmark
170
+ req = Net::HTTP::Get.new(WASSR_API_URI[:FOOTMARK])
171
+ req.basic_auth @login_id, @password
172
+ json_parse(@http_obj.request(req).body)
173
+ end
174
+
175
+ #------------------------------------------------------
176
+
177
+ def escape(str) # :nodoc:
178
+ return CGI.escape(str)
179
+ end
180
+ end
181
+ end
data/lib/simplejson.rb ADDED
@@ -0,0 +1,285 @@
1
+ # = Simple JSON parser & builder
2
+ #
3
+ # Author:: Chihiro Ito
4
+ # License:: Public domain (unlike other files)
5
+ # Support:: http://groups.google.com/group/webos-goodies/
6
+ #
7
+ # This file contains two simple JSON processing classes. JsonParser
8
+ # converts a JSON string to an array or a hash. JsonBuilder performs
9
+ # vice versa. These classes are standard compliant and are designed for
10
+ # stability and reliability. Especially JsonParser has UTF-8 validation
11
+ # functionality so you can avoid some kind of security attack.
12
+
13
+ require 'strscan'
14
+
15
+
16
+ # = Simple JSON parser
17
+ #
18
+ # This class converts a JSON string to an array or a hash. If *json_str*
19
+ # contains a JSON form string, you can convert it like below.
20
+ #
21
+ # ruby_obj = JsonParser.new.parse(json_str)
22
+ #
23
+ # If *json_str* has one or more invalid UTF-8 sequence, JsonParser throws
24
+ # exception by default. You can change this behavior to replacing with an
25
+ # arbitrary unicode character. See below for details.
26
+ class JsonParser
27
+
28
+ #:stopdoc:
29
+ Debug = false
30
+ Name = 'JsonParser'
31
+ ERR_IllegalSyntax = "[#{Name}] Syntax error"
32
+ ERR_IllegalUnicode = "[#{Name}] Illegal unicode sequence"
33
+
34
+ StringRegex = /\s*"((?:\\.|[^"\\])*)"/n
35
+ ValueRegex = /\s*(?:
36
+ (true)|(false)|(null)| # 1:true, 2:false, 3:null
37
+ (?:\"((?:\\.|[^\"\\])*)\")| # 4:String
38
+ ([-+]?\d+\.\d+(?:[eE][-+]?\d+)?)| # 5:Float
39
+ ([-+]?\d+)| # 6:Integer
40
+ (\{)|(\[))/xn # 7:Hash, 8:Array
41
+ #:startdoc:
42
+
43
+ # Create a new instance of JsonParser. *options* can contain these values.
44
+ # [:validation]
45
+ # If set to false, UTF-8 validation is disabled. true by default.
46
+ # [:surrogate]
47
+ # If set to false, surrogate pair support is disabled. true by default.
48
+ # [:malformed_chr]
49
+ # An invalid sequence in JSON string will be replaced with this value.
50
+ # If set to nil, An exception will be thrown in this situation.
51
+ # nil by default.
52
+ def initialize(options = {})
53
+ @default_validation = options.has_key?(:validation) ? options[:validation] : true
54
+ @default_surrogate = options.has_key?(:surrogate) ? options[:surrogate] : true
55
+ @default_malformed_chr = options.has_key?(:malformed_chr) ? options[:malformed_chr] : nil
56
+ end
57
+
58
+ # Convert *str* to an array or hash.
59
+ # [str]
60
+ # A JSON form string. This must be encoded using UTF-8.
61
+ # [options]
62
+ # Same as new.
63
+ def parse(str, options = {})
64
+ @enable_validation = options.has_key?(:validation) ? options[:validation] : @default_validation
65
+ @enable_surrogate = options.has_key?(:surrogate) ? options[:surrogate] : @default_surrogate
66
+ @malformed_chr = options.has_key?(:malformed_chr) ? options[:malformed_chr] : @default_malformed_chr
67
+ @malformed_chr = @malformed_chr[0] if String === @malformed_chr
68
+ @scanner = StringScanner.new(str)
69
+ obj = case get_symbol[0]
70
+ when ?{ then parse_hash
71
+ when ?[ then parse_array
72
+ else raise err_msg(ERR_IllegalSyntax)
73
+ end
74
+ @scanner = nil
75
+ obj
76
+ end
77
+
78
+ private #---------------------------------------------------------
79
+
80
+ def validate_string(str, malformed_chr = nil)
81
+ code = 0
82
+ rest = 0
83
+ range = nil
84
+ ucs = []
85
+ str.each_byte do |c|
86
+ if rest <= 0
87
+ case c
88
+ when 0x01..0x7f then rest = 0 ; ucs << c
89
+ when 0xc0..0xdf then rest = 1 ; code = c & 0x1f ; range = 0x00080..0x0007ff
90
+ when 0xe0..0xef then rest = 2 ; code = c & 0x0f ; range = 0x00800..0x00ffff
91
+ when 0xf0..0xf7 then rest = 3 ; code = c & 0x07 ; range = 0x10000..0x10ffff
92
+ else ucs << handle_malformed_chr(malformed_chr)
93
+ end
94
+ elsif (0x80..0xbf) === c
95
+ code = (code << 6) | (c & 0x3f)
96
+ if (rest -= 1) <= 0
97
+ if !(range === code) || (0xd800..0xdfff) === code
98
+ code = handle_malformed_chr(malformed_chr)
99
+ end
100
+ ucs << code
101
+ end
102
+ else
103
+ ucs << handle_malformed_chr(malformed_chr)
104
+ rest = 0
105
+ end
106
+ end
107
+ ucs << handle_malformed_chr(malformed_chr) if rest > 0
108
+ ucs.pack('U*')
109
+ end
110
+
111
+ def handle_malformed_chr(chr)
112
+ raise err_msg(ERR_IllegalUnicode) unless chr
113
+ chr
114
+ end
115
+
116
+ def err_msg(err)
117
+ err + (Debug ? " #{@scanner.string[[0, @scanner.pos - 8].max,16].inspect}" : "")
118
+ end
119
+
120
+ def unescape_string(str)
121
+ str = str.gsub(/\\(["\\\/bfnrt])/n) do
122
+ $1.tr('"\\/bfnrt', "\"\\/\b\f\n\r\t")
123
+ end.gsub(/(\\u[0-9a-fA-F]{4})+/n) do |matched|
124
+ seq = matched.scan(/\\u([0-9a-fA-F]{4})/n).flatten.map { |c| c.hex }
125
+ if @enable_surrogate
126
+ seq.each_index do |index|
127
+ if seq[index] && (0xd800..0xdbff) === seq[index]
128
+ n = index + 1
129
+ raise err_msg(ERR_IllegalUnicode) unless seq[n] && 0xdc00..0xdfff === seq[n]
130
+ seq[index] = 0x10000 + ((seq[index] & 0x03ff) << 10) + (seq[n] & 0x03ff)
131
+ seq[n] = nil
132
+ end
133
+ end.compact!
134
+ end
135
+ seq.pack('U*')
136
+ end
137
+ str = validate_string(str, @malformed_chr) if @enable_validation
138
+ str
139
+ end
140
+
141
+ def get_symbol
142
+ raise err_msg(ERR_IllegalSyntax) unless @scanner.scan(/\s*(.)/n)
143
+ @scanner[1]
144
+ end
145
+
146
+ def peek_symbol
147
+ @scanner.match?(/\s*(.)/n) ? @scanner[1] : nil
148
+ end
149
+
150
+ def parse_string
151
+ raise err_msg(ERR_IllegalSyntax) unless @scanner.scan(StringRegex)
152
+ unescape_string(@scanner[1])
153
+ end
154
+
155
+ def parse_value
156
+ raise err_msg(ERR_IllegalSyntax) unless @scanner.scan(ValueRegex)
157
+ case
158
+ when @scanner[1] then true
159
+ when @scanner[2] then false
160
+ when @scanner[3] then nil
161
+ when @scanner[4] then unescape_string(@scanner[4])
162
+ when @scanner[5] then @scanner[5].to_f
163
+ when @scanner[6] then @scanner[6].to_i
164
+ when @scanner[7] then parse_hash
165
+ when @scanner[8] then parse_array
166
+ else raise err_msg(ERR_IllegalSyntax)
167
+ end
168
+ end
169
+
170
+ def parse_hash
171
+ obj = {}
172
+ if peek_symbol[0] == ?} then get_symbol ; return obj ; end
173
+ while true
174
+ index = parse_string
175
+ raise err_msg(ERR_IllegalSyntax) unless get_symbol[0] == ?:
176
+ value = parse_value
177
+ obj[index] = value
178
+ case get_symbol[0]
179
+ when ?} then return obj
180
+ when ?, then next
181
+ else raise err_msg(ERR_IllegalSyntax)
182
+ end
183
+ end
184
+ end
185
+
186
+ def parse_array
187
+ obj = []
188
+ if peek_symbol[0] == ?] then get_symbol ; return obj ; end
189
+ while true
190
+ obj << parse_value
191
+ case get_symbol[0]
192
+ when ?] then return obj
193
+ when ?, then next
194
+ else raise err_msg(ERR_IllegalSyntax)
195
+ end
196
+ end
197
+ end
198
+
199
+ end
200
+
201
+ # = Simple JSON builder
202
+ #
203
+ # This class converts an Ruby object to a JSON string. you can convert
204
+ # *ruby_obj* like below.
205
+ #
206
+ # json_str = JsonBuilder.new.build(ruby_obj)
207
+ #
208
+ # *ruby_obj* must satisfy these conditions.
209
+ # - It must support to_s method, otherwise must be an array, a hash or nil.
210
+ # - All keys of a hash must support to_s method.
211
+ # - All values of an array or a hash must satisfy all conditions mentioned above.
212
+ #
213
+ # If the *ruby_obj* is not an array or a hash, it will be converted to an array
214
+ # with a single element.
215
+ class JsonBuilder
216
+
217
+ #:stopdoc:
218
+ Name = 'JsonBuilder'
219
+ ERR_NestIsTooDeep = "[#{Name}] Array / Hash nested too deep."
220
+ ERR_NaN = "[#{Name}] NaN and Infinite are not permitted in JSON."
221
+ #:startdoc:
222
+
223
+ # Create a new instance of JsonBuilder. *options* can contain these values.
224
+ # [:max_nest]
225
+ # If Array / Hash is nested more than this value, an exception would be thrown.
226
+ # 64 by default.
227
+ # [:nan]
228
+ # NaN is replaced with this value. If nil or false, an exception will be thrown.
229
+ # nil by default.
230
+ def initialize(options = {})
231
+ @default_max_nest = options.has_key?(:max_nest) ? options[:max_nest] : 64
232
+ @default_nan = options.has_key?(:nan) ? options[:nan] : nil
233
+ end
234
+
235
+ # Convert *obj* to a JSON form string.
236
+ # [obj]
237
+ # A ruby object. this object must satisfy all conditions mentioned above.
238
+ # [options]
239
+ # Same as new.
240
+ def build(obj, options = {})
241
+ @max_nest = options.has_key?(:max_nest) ? options[:max_nest] : @default_max_nest
242
+ @nan = options.has_key?(:nan) ? options[:nan] : @default_nan
243
+ case obj
244
+ when Array then build_array(obj, 0)
245
+ when Hash then build_object(obj, 0)
246
+ else build_array([obj], 0)
247
+ end
248
+ end
249
+
250
+ private #---------------------------------------------------------
251
+
252
+ def escape(str)
253
+ str.gsub(/[^\x20-\x21\x23-\x5b\x5d-\xff]/n) do |chr|
254
+ if chr[0] != 0 && (index = "\"\\/\b\f\n\r\t".index(chr[0]))
255
+ "\\" + '"\\/bfnrt'[index, 1]
256
+ else
257
+ sprintf("\\u%04x", chr[0])
258
+ end
259
+ end
260
+ end
261
+
262
+ def build_value(obj, level)
263
+ case obj
264
+ when Integer, TrueClass, FalseClass then obj.to_s
265
+ when Float then raise ERR_NaN unless obj.finite? || (obj = @nan) ; obj.to_s
266
+ when NilClass then 'null'
267
+ when Array then build_array(obj, level + 1)
268
+ when Hash then build_object(obj, level + 1)
269
+ else "\"#{escape(obj.to_s)}\""
270
+ end
271
+ end
272
+
273
+ def build_array(obj, level)
274
+ raise ERR_NestIsTooDeep if level >= @max_nest
275
+ '[' + obj.map { |item| build_value(item, level) }.join(',') + ']'
276
+ end
277
+
278
+ def build_object(obj, level)
279
+ raise ERR_NestIsTooDeep if level >= @max_nest
280
+ '{' + obj.map do |item|
281
+ "#{build_value(item[0].to_s,level)}:#{build_value(item[1],level)}"
282
+ end.join(',') + '}'
283
+ end
284
+
285
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Wassruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Takuya Mannami
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-08-04 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: takuya.mannami@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.txt
24
+ files:
25
+ - lib/simplejson.rb
26
+ - lib/Wassruby.rb
27
+ - README.txt
28
+ has_rdoc: true
29
+ homepage: http://wassruby.rubyforge.org/
30
+ post_install_message:
31
+ rdoc_options:
32
+ - --main
33
+ - README.txt
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ version:
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ requirements: []
49
+
50
+ rubyforge_project: Wassruby
51
+ rubygems_version: 1.1.1
52
+ signing_key:
53
+ specification_version: 2
54
+ summary: Simple Wassr Client
55
+ test_files: []
56
+