timelog4r 0.2.0 → 0.3.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/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == 0.3.0 2011-08-2x
2
+
3
+ * 3 major enhancement:
4
+ * [new][web_handler] support non api accessor.
5
+ * [change] API or WEB selectable. initialize of instance with argment.
6
+ * [update] support for timelog.jp service major version up.
7
+
1
8
  == 0.2.0 2011-07-2x
2
9
 
3
10
  * 1 major enhancement:
data/Manifest.txt CHANGED
@@ -11,6 +11,7 @@ lib/timelog4r.rb
11
11
  lib/timelog4r/utils.rb
12
12
  lib/timelog4r/version.rb
13
13
  lib/timelog4r/xml_parser.rb
14
+ lib/timelog4r/html_parser.rb
14
15
  script/console
15
16
  script/destroy
16
17
  script/generate
data/README.txt CHANGED
@@ -9,8 +9,12 @@ Timelog4r is TimelogAPI for ruby.
9
9
  == SYNOPSIS:
10
10
 
11
11
  t = Timelog4r.new
12
+ # if use API.
13
+ # t = Timelog4r.new(:api)
12
14
  t.user_id = 'your timelog id'
13
15
  t.password = 'your timelog password'
16
+ # if use WEB-Accessor.(not use API)
17
+ t.login
14
18
  t.update 'Hello Timelog.'
15
19
 
16
20
  == INSTALL:
@@ -21,7 +25,7 @@ sudo gem install timelog4r
21
25
 
22
26
  (The MIT License)
23
27
 
24
- Copyright (c) 2008 saronpasu
28
+ Copyright (c) 2008-2011 saronpasu
25
29
 
26
30
  Permission is hereby granted, free of charge, to any person obtaining
27
31
  a copy of this software and associated documentation files (the
@@ -2,7 +2,7 @@ require 'fileutils'
2
2
  include FileUtils
3
3
 
4
4
  require 'rubygems'
5
- %w[rake hoe newgem rubigen].each do |req_gem|
5
+ %w[rake hoe newgem rubigen mechanize].each do |req_gem|
6
6
  begin
7
7
  require req_gem
8
8
  rescue LoadError
@@ -1,5 +1,14 @@
1
1
  #!ruby -Ku
2
2
  # -*- encoding: UTF-8 -*-
3
+
4
+ =begin
5
+
6
+ Timelog.jp service major version-up.
7
+ not support 'follow and follower'.
8
+
9
+ =end
10
+
11
+ __END__
3
12
  require 'timelog4r'
4
13
 
5
14
  t = Timelog4r.new
@@ -7,7 +7,10 @@ t.user_id = 'your Timelog ID'
7
7
  t.password = 'your Password'
8
8
  # t.user_agent = 'your client appli's namet'
9
9
 
10
+ # if you access of WEB.(not use API)
11
+ t.login
12
+
10
13
  note = 'Hello, World.'
11
- group_id = 'sandbox'
14
+ group_id = 'timeline00'
12
15
  t.update(note, group_id)
13
16
 
@@ -0,0 +1,275 @@
1
+ #!ruby -Ku
2
+ #-*- encoding: utf-8 -*-
3
+
4
+ class Timelog4r
5
+ module HTML_Parser
6
+ require 'time'
7
+ require 'uri'
8
+ class ParseError < StandardError; end
9
+
10
+ def permission_to_sym(string)
11
+ case string
12
+ when '0'
13
+ return :public
14
+ when '1'
15
+ return :friends_only
16
+ when '2'
17
+ return :private
18
+ else
19
+ return :unknown
20
+ end
21
+ end
22
+
23
+ def tags_to_a(tag_string)
24
+
25
+ end
26
+
27
+ def is_group?(entry_element)
28
+ group_element = 'span[@class="time"]/a[@class="name"]'
29
+
30
+ end
31
+
32
+ def has_parent_entry?(entry_element)
33
+
34
+ end
35
+
36
+ def has_child_entry?(entry_element)
37
+
38
+ end
39
+
40
+ def parse_children_entries(entries_element)
41
+
42
+ end
43
+
44
+ def parse_entry(state_element)
45
+ permalink_element = 'span[@class="time"]/a[3]'
46
+ memo_element = 'h3'
47
+ author_element = 'span[@class="time"]/a[@class="name"]'
48
+ group_element = 'h3/a[@class="name"]'
49
+ permission_element = 'img[@class="icn_left"]'
50
+ has_star_element = 'img[@src="http://img.timelog.jp/star.gif"]'
51
+ star_count_element = has_star_element
52
+ res_count_element = 'img[@src="http://img.timelog.jp/comment.gif"]'
53
+ tag_list_element = 'span[@class="tag"]'
54
+ reply_to_element = 'h3/a'
55
+
56
+ result = nil
57
+
58
+ begin
59
+ result = Hash.allocate
60
+ unless state_element.at(memo_element) then
61
+ raise ParseError('not found memo_text.')
62
+ else
63
+ result[:memo_text] = state_element.at(memo_element).inner_text
64
+ end
65
+ unless state_element.at(permalink_element) then
66
+ raise ParseError.new('not found memo_id.')
67
+ else
68
+ result[:memo_id] = state_element.at(
69
+ permalink_element
70
+ ).attr('href')[7..-1]
71
+ end
72
+ unless state_element.at(permission_element) then
73
+ raise ParseError.new('not found permission.')
74
+ else
75
+ result[:permission] = state_element.at(
76
+ permission_element
77
+ ).attr('src').match(
78
+ /icon_(public|friend)\.gif/
79
+ ) ? $1.to_sym : nil
80
+ end
81
+ unless state_element.at(permalink_element) then
82
+ raise ParseError.new('not found modified.')
83
+ else
84
+ result[:modified] = state_element.at(
85
+ permalink_element
86
+ ).inner_text.match(
87
+ /(\d+\/\d+).+(\d+:\d+)/
88
+ ) ? Time.parse(
89
+ [Time.now.year.to_s+'/', $1, ' '+$2].join
90
+ ) : nil
91
+ end
92
+ unless state_element.at(permalink_element) then
93
+ raise ParseError.new('not found permalink.')
94
+ else
95
+ result[:permalink] = URI.parse(
96
+ 'http://timelog.jp/' + state_element.at(
97
+ permalink_element
98
+ ).attr('href')
99
+ )
100
+ end
101
+ unless state_element.at(author_element) then
102
+ raise ParseError('not found author.')
103
+ else
104
+ author = state_element.at(author_element)
105
+ result[:author] = parse_author(author)
106
+ end
107
+ unless state_element.at(group_element) then
108
+ raise ParseError.new('not found group.')
109
+ else
110
+ group = state_element.at(group_element)
111
+ result[:in_group] = parse_group(group)
112
+ end
113
+ links = state_element.search(reply_to_element)
114
+ links = links.reject do |link|
115
+ link.has_attribute?('class') or
116
+ link.has_attribute?('target')
117
+ end
118
+ unless links.empty? then
119
+ reply_to = Hash.allocate
120
+ author = Hash.allocate
121
+ link = links.last
122
+ author[:user_id] = link.attr(
123
+ 'href'
124
+ ).match(
125
+ /\/\/(.+)\.timelog\.jp/
126
+ ) ? $1 : nil
127
+ author[:screen_name] = link.inner_text
128
+ reply_to[:author] = author
129
+ result[:reply_to] = reply_to
130
+ end
131
+ # result[:todo] not supported.
132
+ if state_element.at(tag_list_element) then
133
+ tags = state_element.at(tag_list_element)
134
+ result[:tag] = parse_tag_list(tags)
135
+ end
136
+ if state_element.at(has_star_element) then
137
+ result[:star] = state_element.at(
138
+ has_star_element
139
+ ).attr(
140
+ 'alt'
141
+ ).match(
142
+ /\d+/
143
+ ) ? [:count => $1.to_i] : [:count => 0]
144
+ else
145
+ result[:star] = [:count => 0]
146
+ end
147
+ unless state_element.at(res_count_element) then
148
+ raise ParseError.new('not found res count.')
149
+ else
150
+ result[:res_count] = state_element.at(
151
+ res_count_element
152
+ ).inner_text.match(
153
+ /\d+/
154
+ ) ? $1.to_i : 0
155
+ end
156
+
157
+ # reject group name.
158
+ group_name_pattern = Regexp.new(
159
+ result[:in_group][:name].gsub(
160
+ /(\(\[\/\.\)\])/, '\$&'
161
+ )
162
+ )
163
+ result[:memo_text].sub!(group_name_pattern, '')
164
+
165
+ # reject reply name.
166
+ reply_name_pattern = Regexp.new(/(\s>\s\w+).+$/)
167
+ result[:memo_text].sub!(reply_name_pattern, '')
168
+
169
+ # reject tags.
170
+ tags_pattern = Regexp.new(/(\s\[.+\])$/)
171
+ result[:memo_text].gsub!(tags_pattern, '')
172
+
173
+ result[:memo_text].rstrip.strip.chomp!
174
+ rescue ParseError => e
175
+ p e
176
+ return nil
177
+ else
178
+ return result
179
+ end
180
+ end
181
+
182
+ def parse_author(author_element)
183
+ author = Hash.allocate
184
+ begin
185
+ author[:user_id] = author_element.attr(
186
+ 'href'
187
+ ).match(
188
+ /\/\/(.+)\.timelog\.jp/
189
+ ) ? $1 : nil
190
+ author[:name] = author_element.inner_text[1..-2]
191
+ rescue ParseError => e
192
+ p e
193
+ return false
194
+ else
195
+ return author
196
+ end
197
+ end
198
+
199
+ def parse_group(group_element)
200
+ group = Hash.allocate
201
+ begin
202
+ group[:group_id] = group_element.attr(
203
+ 'href'
204
+ ).match(
205
+ /\/\/(.+)\.timelog\.jp/
206
+ ) ? $1 : nil
207
+ group[:name] = group_element.inner_text
208
+ rescue ParseError => e
209
+ p e
210
+ return nil
211
+ else
212
+ return group
213
+ end
214
+ end
215
+
216
+ def parse_timeline(timeline_element)
217
+ document = Mechanize::Page.new(
218
+ URI.parse('http://timelog.jp/home/'),
219
+ {'content-type' => 'text/html'},
220
+ timeline_element,
221
+ '200',
222
+ @agent
223
+ )
224
+
225
+ timeline_element = 'ul#timeline'
226
+ entry_element = 'div#list_1/li'
227
+ permalink_element = 'span[@class="time"]/a[3]'
228
+
229
+ result = nil
230
+
231
+ begin
232
+ timeline = document.search(timeline_element)
233
+ raise ParseError.new('not found timeline element.') if timeline.empty?
234
+ entries = timeline.search(entry_element)
235
+ raise ParseError.new('not found entry elements.') if entries.empty?
236
+ result = entries.map do |entry|
237
+ parse_entry(entry)
238
+ end
239
+ rescue ParseError => e
240
+ p e
241
+ return nil
242
+ else
243
+ return result
244
+ end
245
+ end
246
+
247
+ def parse_tag(tag_element)
248
+
249
+ end
250
+
251
+ def parse_tag_list(tag_list_element)
252
+ tag_element = 'a'
253
+
254
+ tags = tag_list_element.search(tag_element)
255
+ result = tags.map do |tag|
256
+ tag.inner_text
257
+ end
258
+ return result
259
+ end
260
+
261
+ def parse_user(user_element)
262
+
263
+ end
264
+
265
+ def parse_user_list(user_list_element)
266
+
267
+ end
268
+
269
+ def parse_profile(profile_element)
270
+
271
+ end
272
+ end
273
+ end
274
+
275
+
@@ -1,7 +1,7 @@
1
1
  class Timelog4r
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 2
4
+ MINOR = 3
5
5
  TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
data/lib/timelog4r.rb CHANGED
@@ -3,8 +3,10 @@
3
3
  $:.unshift(File.dirname(__FILE__)) unless
4
4
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
5
5
 
6
+ require 'mechanize'
6
7
  require 'timelog4r/utils'
7
8
  require 'timelog4r/xml_parser'
9
+ require 'timelog4r/html_parser'
8
10
 
9
11
  =begin rdoc
10
12
  Timelog4r is TimelogAPI for ruby.
@@ -21,17 +23,34 @@ class Timelog4r
21
23
  attr_accessor :user_id
22
24
  # REQUIRED:: Set your Timelog PassWord.
23
25
  attr_accessor :password
26
+ # REQUIRED:: TimelogAPI Use-Flag.
27
+ attr_accessor :use_accessor
28
+ # OPTIONAL:: WEB Access used PrivateKey.
29
+ attr_accessor :private_key
30
+ # OPTIONAL:: WEB Accessor Agent.
31
+ attr_accessor :agent
24
32
 
25
33
  # TimelogAPI's BaseURI.
26
34
  BaseAddress = 'http://api.timelog.jp/'
35
+ WebAddress = 'http://timelog.jp/'
27
36
 
28
37
  # Utilities.
29
38
  include Utils
30
39
  # Customized XML-Parser.
31
- include XML_Parser
40
+ # include XML_Parser
32
41
 
33
- def initialize #:nodoc:
42
+ def initialize(use_accessor = :web) #:nodoc:
34
43
  @user_agent = 'timelog4r'
44
+ case use_accessor
45
+ when :api
46
+ @use_accessor = :api
47
+ self.extend XML_Parser
48
+ when :web
49
+ @use_accessor = :web
50
+ @agent = Mechanize.new
51
+ @agent.user_agent = @user_agent
52
+ self.extend HTML_Parser
53
+ end
35
54
  end
36
55
 
37
56
  =begin rdoc
@@ -60,12 +79,20 @@ RelatedMethods::
60
79
 
61
80
  =end
62
81
  def get_public_timeline(options = nil)
63
- address = BaseAddress + 'public_msg.asp'
64
- address += parse_options(options) if options
65
- uri = create_uri(address)
66
- request = create_request(:get, uri)
67
- response = http_access(uri, request)
68
- result = parse_timeline(response) if response
82
+ result = nil
83
+ case @use_accessor
84
+ when :api
85
+ address = BaseAddress + 'public_msg.asp'
86
+ address += parse_options(options) if options
87
+ uri = create_uri(address)
88
+ request = create_request(:get, uri)
89
+ response = http_access(uri, request)
90
+ result = parse_timeline(response) if response
91
+ when :web
92
+ address = 'http://'+@user_id+'.timelog.jp/home/public.asp'
93
+ response = @agent.get(address)
94
+ result = parse_timeline(response.body) if response
95
+ end
69
96
  return result
70
97
  end
71
98
 
@@ -94,12 +121,19 @@ RelatedMethods::
94
121
 
95
122
  =end
96
123
  def get_friends_timeline(options = nil)
97
- address = BaseAddress + 'friends_msg.asp'
98
- address += parse_options(options) if options
99
- uri = create_uri(address)
100
- request = create_request(:get, uri, true)
101
- response = http_access(uri, request)
102
- result = parse_timeline(response) if response
124
+ case @use_accessor
125
+ when :api
126
+ address = BaseAddress + 'friends_msg.asp'
127
+ address += parse_options(options) if options
128
+ uri = create_uri(address)
129
+ request = create_request(:get, uri, true)
130
+ response = http_access(uri, request)
131
+ result = parse_timeline(response) if response
132
+ when :web
133
+ address = 'http://'+ @user_id +'.timelog.jp/home/'
134
+ response = @agent.get(address)
135
+ result = parse_timeline(response.body) if response
136
+ end
103
137
  return result
104
138
  end
105
139
 
@@ -130,12 +164,19 @@ RelatedMethods::
130
164
 
131
165
  =end
132
166
  def get_my_timeline(options = nil)
133
- address = BaseAddress + 'my_msg.asp'
134
- address += parse_options(options) if options
135
- uri = create_uri(address)
136
- request = create_request(:get, uri, true)
137
- response = http_access(uri, request)
138
- result = parse_timeline(response) if response
167
+ case @user_accessor
168
+ when :api
169
+ address = BaseAddress + 'my_msg.asp'
170
+ address += parse_options(options) if options
171
+ uri = create_uri(address)
172
+ request = create_request(:get, uri, true)
173
+ response = http_access(uri, request)
174
+ result = parse_timeline(response) if response
175
+ when :web
176
+ address = 'http://'+ @user_id +'.timelog.jp/personal.asp'
177
+ response = @agent.get(address)
178
+ result = parse_timeline(response.body) if response
179
+ end
139
180
  return result
140
181
  end
141
182
 
@@ -186,12 +227,19 @@ RelatedMethods::
186
227
  XML_Parser#parse_profile
187
228
 
188
229
  =end
189
- def get_profile
190
- address = BaseAddress + 'show.asp'
191
- uri = create_uri(address)
192
- request = create_request(:get, uri, true)
193
- response = http_access(uri, request)
194
- result = parse_profile(response) if response
230
+ def get_profile(user_id = @user_id)
231
+ case @use_accessor
232
+ when :api
233
+ address = BaseAddress + 'show.asp'
234
+ uri = create_uri(address)
235
+ request = create_request(:get, uri, true)
236
+ response = http_access(uri, request)
237
+ result = parse_profile(response) if response
238
+ when :web
239
+ address = 'http://'+ @user_id +'.timelog.jp/profile.asp'
240
+ response = @agent.get(address)
241
+ result = parse_profile(response.body) if response
242
+ end
195
243
  return result
196
244
  end
197
245
 
@@ -368,12 +416,19 @@ RelatedMethods::
368
416
 
369
417
  =end
370
418
  def get_reply_list(options = nil)
371
- address = BaseAddress + 'res_msg.asp'
372
- address += parse_options(options) if options
373
- uri = create_uri(address)
374
- request = create_request(:get, uri, true)
375
- response = http_access(uri, request)
376
- result = parse_timeline(response) if response
419
+ case @use_accessor
420
+ when :api
421
+ address = BaseAddress + 'res_msg.asp'
422
+ address += parse_options(options) if options
423
+ uri = create_uri(address)
424
+ request = create_request(:get, uri, true)
425
+ response = http_access(uri, request)
426
+ result = parse_timeline(response) if response
427
+ when :web
428
+ address = 'http://'+ @user_id +'.timelog.jp/resmsg.asp'
429
+ response = @agent.get(address)
430
+ result = parse_timeline(response.body) if response
431
+ end
377
432
  return result
378
433
  end
379
434
 
@@ -420,15 +475,37 @@ RelatedMethods::
420
475
 
421
476
  =end
422
477
  def update(text, group_id = nil, res_id = nil, tags = nil)
423
- text = set_tags(text, tags) if tags
424
- text += ' #'+group_id if group_id
425
- params = {:text => text}
426
- params[:remsgid] = res_id if res_id
427
- address = BaseAddress + 'new.asp' + parse_options(params)
428
- uri = create_uri(address)
429
- request = create_request(:post, uri, true)
430
- response = http_access(uri, request)
431
- return !response.nil?
478
+ case @use_accessor
479
+ when :api
480
+ text = set_tags(text, tags) if tags
481
+ text += ' #'+group_id if group_id
482
+ params = {:text => text}
483
+ params[:remsgid] = res_id if res_id
484
+ address = BaseAddress + 'new.asp' + parse_options(params)
485
+ uri = create_uri(address)
486
+ request = create_request(:post, uri, true)
487
+ response = http_access(uri, request)
488
+ return !response.nil?
489
+ when :web
490
+ post_view = 'http://'+@user_id+'.timelog.jp'
491
+ post_url = WebAddress + '/home/postb.asb'
492
+ post_form = @agent.get(post_view).forms.first
493
+
494
+ text = set_tags(text, tags) if tags
495
+
496
+ post_form['inp_exm'] = '0'
497
+ post_form['sel_Type'] = '0'
498
+ post_form['inp_Public'] = '0'
499
+ post_form['t'] = '1'
500
+ post_form['inp_refresh'] = '0'
501
+ post_form['inp_stag'] = ''
502
+ # post_form['inp_gi'] = group_id ? group_id : ''
503
+ post_form['inp_Grp'] = group_id ? group_id : ''
504
+ post_form['inp_key'] = @private_key
505
+ post_form['inp_remsgid'] = res_id ? res_id : ''
506
+ post_form['inp_msg'] = text # message!
507
+ post_form.submit
508
+ end
432
509
  end
433
510
 
434
511
  =begin rdoc
@@ -584,4 +661,135 @@ RelatedMethods::
584
661
  " #" + group_id
585
662
  update(text, res_id, tags)
586
663
  end
664
+
665
+ =begin rdoc
666
+ Description::
667
+ login for timelog.jp.(use web only)
668
+
669
+ Params::
670
+
671
+ :account login user's account [String] defualt @user_id
672
+ :password login user's password [String] default @password
673
+
674
+ Return::
675
+
676
+ true (case of 'login success.')
677
+ false (case of 'login denny.')
678
+
679
+ =end
680
+ def login(account = @user_id, password = @password)
681
+ login_view = WebAddress + 't_login.asp'
682
+ login_url = WebAddress + 'login.asp'
683
+ login_form = @agent.get(login_view).forms.first
684
+ login_form['inp_ac'] = account
685
+ login_form['inp_pw'] = password
686
+ login_form['inp_red'] = login_view
687
+ =begin
688
+ if login_form.valid? then
689
+ login_form.click_button(login_form.buttons.first)
690
+ @private_key = get_private_key
691
+ return true
692
+ else
693
+ return false
694
+ end
695
+ =end
696
+ login_form.submit #click_button(login_form.buttons.first)
697
+ @private_key = get_private_key
698
+ return true
699
+ end
700
+
701
+ =begin rdoc
702
+ Description::
703
+ timelog.jp logined?(use web only.)
704
+
705
+ Return::
706
+ true (case of 'logined.')
707
+ false (case of 'not logined.')
708
+
709
+ =end
710
+ def login?()
711
+ home_view = 'http://'+ @user_id + '.timelog.jp/home/'
712
+ home = @agent.get(home_view)
713
+ return home.forms.first.name.eql?('frmBox')
714
+ end
715
+
716
+ =begin rdoc
717
+ Description::
718
+ get private key.(web accessor only.)
719
+
720
+ Return::
721
+ private key(String)
722
+
723
+ =end
724
+ def get_private_key()
725
+ home_view = 'http://'+ @user_id + '.timelog.jp/home/'
726
+ home = @agent.get(home_view)
727
+ main_form = home.forms.first
728
+ return main_form['inp_key']
729
+ end
730
+
731
+ =begin rdoc
732
+ Description::
733
+ this group joined?
734
+
735
+ Argments::
736
+ :group_id check group_id [String] (Requiement)
737
+
738
+ Return::
739
+ true (case of this group joined.)
740
+ false (case of this group not joined.)
741
+
742
+ =end
743
+ def joined?(group_id)
744
+ group_view = 'http://' + group_id + '.timelog.jp/'
745
+ joined_element = 'li#del'
746
+ group_page = @agent.get(group_view)
747
+ return group_page.at(joined_element) ? true : false
748
+ end
749
+
750
+ =begin rdoc
751
+ Description::
752
+ join to group.
753
+
754
+ Argments::
755
+ :group_id join to group. [String] (Requirement)
756
+
757
+ Return::
758
+ true (case of join to group success.)
759
+
760
+ =end
761
+ def join_group(group_id)
762
+ group_view = 'http://' + group_id + '.timelog.jp/'
763
+ join_url = group_view + 'addfriend.asp?ac=' + group_id
764
+ @agent.get(join_url)
765
+ return true
766
+ end
767
+
768
+ =begin rdoc
769
+ Description::
770
+ leave for group.
771
+
772
+ Argments::
773
+ :group_id leave for group.[String] (Requirement)
774
+
775
+ Return::
776
+ true (case of leave for group success.)
777
+
778
+ =end
779
+ def leave_group(group_id)
780
+ group_view = 'http://' + group_id + '.timelog.jp/'
781
+ leave_url = group_view + 'delfriend.asp?ac=' + group_id
782
+ @agent.get(leave_url)
783
+ return true
784
+ end
785
+
786
+ def get(url) #:nodoc:
787
+ return false if @use_accessor.eql?(:api)
788
+ return @agent.get(url)
789
+ end
790
+
791
+ def post(url, query) #:nodoc:
792
+ return false if @use_accessor.eql?(:api)
793
+ return @agent.post(url, query)
794
+ end
587
795
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timelog4r
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 0.2.0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - saronpasu
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-27 00:00:00 Z
18
+ date: 2011-08-23 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: hoe
@@ -23,14 +23,13 @@ dependencies:
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  none: false
25
25
  requirements:
26
- - - ">="
26
+ - - ~>
27
27
  - !ruby/object:Gem::Version
28
- hash: 35
28
+ hash: 27
29
29
  segments:
30
30
  - 2
31
- - 9
32
- - 4
33
- version: 2.9.4
31
+ - 12
32
+ version: "2.12"
34
33
  type: :development
35
34
  version_requirements: *id001
36
35
  description: TimelogAPI for ruby.
@@ -60,6 +59,7 @@ files:
60
59
  - lib/timelog4r/utils.rb
61
60
  - lib/timelog4r/version.rb
62
61
  - lib/timelog4r/xml_parser.rb
62
+ - lib/timelog4r/html_parser.rb
63
63
  - script/console
64
64
  - script/destroy
65
65
  - script/generate
@@ -108,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
108
  requirements: []
109
109
 
110
110
  rubyforge_project: timelog4r
111
- rubygems_version: 1.8.5
111
+ rubygems_version: 1.8.8
112
112
  signing_key:
113
113
  specification_version: 3
114
114
  summary: TimelogAPI for ruby.