toodledo 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,6 +1,12 @@
1
- == 1.3.1 / 2008-06-07
1
+ == 1.3.2 / 2010-02-16
2
2
 
3
- * Left file out of the manifest...
3
+ * Added file caching for token (will write to $HOME/.toodledo/tokens/<user_id> file)
4
+ * Added patch for the app_id (thx to Greg Miller)
5
+ * Added serveroffset to get_server_info call.
6
+
7
+ == 1.3.1 / ?
8
+
9
+ * Fix some bugs.
4
10
 
5
11
  == 1.3.0 / 2008-05-31
6
12
 
data/Manifest.txt CHANGED
@@ -18,8 +18,8 @@ lib/toodledo/command_line/interactive_command.rb
18
18
  lib/toodledo/command_line/list_contexts_command.rb
19
19
  lib/toodledo/command_line/list_folders_command.rb
20
20
  lib/toodledo/command_line/list_goals_command.rb
21
- lib/toodledo/command_line/list_tasks_command.rb
22
21
  lib/toodledo/command_line/list_tasks_by_context_command.rb
22
+ lib/toodledo/command_line/list_tasks_command.rb
23
23
  lib/toodledo/command_line/parser_helper.rb
24
24
  lib/toodledo/command_line/setup_command.rb
25
25
  lib/toodledo/command_line/stdin_command.rb
data/Rakefile CHANGED
@@ -5,17 +5,20 @@ require 'hoe'
5
5
  $:.unshift(File.dirname(__FILE__) + "/lib")
6
6
  require 'toodledo'
7
7
 
8
- Hoe.new('toodledo', Toodledo::VERSION) do |p|
8
+ Hoe.spec('toodledo') do |p|
9
9
  p.rubyforge_name = 'toodledo'
10
+ p.version = Toodledo::VERSION
10
11
  p.author = 'Will Sargent'
11
12
  p.email = 'will@tersesystems.com'
12
13
  p.summary = 'A command line client and API to Toodledo'
13
14
  p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
14
- p.url = 'http://rubyforge.org/projects/toodledo'
15
+ p.url = "http://gemcutter.org/gems/toodledo"
15
16
  p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
16
17
  p.rsync_args << ' --exclude=statsvn/'
17
18
  p.test_globs = ["test/**/*_test.rb"]
18
- p.extra_deps = ['cmdparse', 'highline']
19
+ p.extra_deps << ['cmdparse', '>= 0']
20
+ p.extra_deps << ['highline', '>= 0']
21
+ p.extra_dev_deps << [ 'flexmock', '>= 0']
19
22
  end
20
23
 
21
24
  # vim: syntax=Ruby
data/bin/toodledo CHANGED
File without changes
data/lib/toodledo.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  module Toodledo
6
6
 
7
7
  # Required for gem
8
- VERSION = '1.3.1'
8
+ VERSION = '1.3.2'
9
9
 
10
10
  # Returns the configuration object.
11
11
  def self.get_config()
@@ -49,8 +49,9 @@ module Toodledo
49
49
  base_url = connection['url']
50
50
  user_id = connection['user_id']
51
51
  password = connection['password']
52
-
53
- session = Session.new(user_id, password, logger)
52
+ app_id = connection['app_id'] || 'ruby_app'
53
+
54
+ session = Session.new(user_id, password, logger, app_id)
54
55
 
55
56
  base_url = Session::DEFAULT_API_URL if (base_url == nil)
56
57
  session.connect(base_url, proxy)
@@ -7,6 +7,7 @@ require 'net/https'
7
7
  require 'openssl/ssl'
8
8
  require 'rexml/document'
9
9
  require 'logger'
10
+ require 'fileutils'
10
11
 
11
12
  module Toodledo
12
13
 
@@ -25,8 +26,9 @@ module Toodledo
25
26
  'Connection' => 'keep-alive',
26
27
  'Keep-Alive' => '300'
27
28
  }
28
-
29
- EXPIRATION_TIME_IN_SECS = 60 * 60
29
+
30
+ # The key should be good for four hours.
31
+ EXPIRATION_TIME_IN_SECS = 60 * 60 * 4
30
32
 
31
33
  DATE_FORMAT = '%Y-%m-%d'
32
34
 
@@ -34,18 +36,19 @@ module Toodledo
34
36
 
35
37
  TIME_FORMAT = '%I:%M %p'
36
38
 
37
- attr_accessor :logger
38
-
39
- attr_reader :base_url, :user_id, :proxy
39
+ attr_accessor :logger
40
+
41
+ attr_reader :base_url, :user_id, :proxy, :app_id
40
42
 
41
43
  # Creates a new session, using the given user name and password.
42
44
  # throws InvalidConfigurationError if user_id or password are nil.
43
- def initialize(user_id, password, logger = nil)
45
+ def initialize(user_id, password, logger = nil, app_id = nil)
44
46
  raise InvalidConfigurationError.new("Nil user_id") if (user_id == nil)
45
47
  raise InvalidConfigurationError.new("Nil password") if (password == nil)
46
48
 
47
49
  @user_id = user_id
48
50
  @password = password
51
+ @app_id = app_id
49
52
 
50
53
  @folders = nil
51
54
  @contexts = nil
@@ -87,7 +90,7 @@ module Toodledo
87
90
  # Get the proxy information if it exists.
88
91
  @proxy = proxy
89
92
 
90
- session_token = get_token(@user_id)
93
+ session_token = get_token(@user_id, @app_id)
91
94
  key = md5(md5(@password).to_s + session_token + @user_id);
92
95
 
93
96
  @key = key
@@ -105,12 +108,13 @@ module Toodledo
105
108
 
106
109
  # Returns true if the session has expired.
107
110
  def expired?
111
+ return false
108
112
  #logger.debug("expired?") too annoying
109
113
 
110
114
  # The key is only good for an hour. If it's been over an hour,
111
115
  # then we count it as expired.
112
- return true if (@start_time == nil)
113
- return (Time.now - @start_time > EXPIRATION_TIME_IN_SECS)
116
+ #return true if (@start_time == nil)
117
+ #return (Time.now - @start_time > EXPIRATION_TIME_IN_SECS)
114
118
  end
115
119
 
116
120
  # Returns a parsable URI object from the base API URL and the parameters.
@@ -221,11 +225,80 @@ module Toodledo
221
225
  end
222
226
 
223
227
  # Gets the token method, given the id.
224
- def get_token(user_id)
228
+ def get_token(user_id, app_id)
225
229
  raise "Nil user_id" if (user_id == nil || user_id.empty?)
226
230
 
231
+ # If there is no token file, or the token file is out of date, pull in
232
+ # a fresh token from the server and write it to the file system.
233
+ token = read_token(user_id)
234
+ unless token
235
+ token = get_uncached_token(user_id, app_id)
236
+ write_token(user_id, token)
237
+ end
238
+
239
+ return token
240
+ end
241
+
242
+ # Reads a token from the file system, if the given user_id exists and the
243
+ # token is not too old.
244
+ def read_token(user_id)
245
+ token_path = get_token_file(user_id)
246
+ unless token_path
247
+ logger.debug("read_token: no token found for #{user_id.inspect}, returning nil")
248
+ return nil
249
+ end
250
+
251
+ if is_too_old(token_path)
252
+ File.delete(token_path)
253
+ return nil
254
+ end
255
+
256
+ token = File.read(token_path)
257
+ token
258
+ end
259
+
260
+ # Returns true if the file is more than an hour old, false otherwise.
261
+ def is_too_old(token_path)
262
+ last_modified_time = File.new(token_path).mtime
263
+ expiration_time = Time.now - EXPIRATION_TIME_IN_SECS
264
+ too_old = expiration_time - last_modified_time > 0
265
+
266
+ logger.debug "is_too_old: time = #{last_modified_time}, expires = #{expiration_time}, too_old = #{too_old}"
267
+
268
+ return too_old
269
+ end
270
+
271
+ # Gets there full path of the token file.
272
+ def get_token_file(user_id)
273
+ tokens_dir = get_tokens_directory()
274
+ token_path = File.expand_path(File.join(tokens_dir, user_id))
275
+ unless File.exist?(token_path)
276
+ return nil
277
+ end
278
+ token_path
279
+ end
280
+
281
+ # Make sure that there is a ".toodledo/tokens" directory.
282
+ def get_tokens_directory()
283
+ toodledo_dir = "~/.toodledo"
284
+ tokens_path = File.expand_path(File.join(toodledo_dir, "tokens"))
285
+ FileUtils.mkdir_p tokens_path
286
+ tokens_path
287
+ end
288
+
289
+ # Writes the token file to the filesystem.
290
+ def write_token(user_id, token)
291
+ logger.debug("write_token: user_id = #{user_id.inspect}, token = #{token.inspect}")
292
+ token_path = File.expand_path(File.join(get_tokens_directory(), user_id))
293
+ File.open(token_path, 'w') {|f| f.write(token) }
294
+ end
295
+
296
+ # Calls the server to get a token.
297
+ def get_uncached_token(user_id, app_id)
227
298
  params = { :userid => user_id }
228
- result = call('getToken', params)
299
+ params.merge!({:appid => app_id}) unless app_id.nil?
300
+ result = call('getToken', params)
301
+
229
302
  return result.text
230
303
  end
231
304
 
@@ -314,11 +387,13 @@ module Toodledo
314
387
 
315
388
  unixtime = result.elements['unixtime'].text.to_i
316
389
  server_date = Time.at(unixtime)
317
- token_expires = result.elements['tokenexpires'].text.to_i
390
+ server_offset = result.elements['serveroffset'].text.to_i
391
+ token_expires = result.elements['tokenexpires'].text.to_f
318
392
  hash = {
319
393
  :unixtime => unixtime,
320
394
  :date => server_date,
321
- :tokenexpires => token_expires
395
+ :tokenexpires => token_expires,
396
+ :serveroffset => server_offset,
322
397
  }
323
398
 
324
399
  return hash
@@ -574,6 +649,9 @@ module Toodledo
574
649
  # Handle completion.
575
650
  handle_boolean(myhash, params, :completed)
576
651
 
652
+ # Handle star
653
+ handle_boolean(myhash, params, :star)
654
+
577
655
  # repeat: use the map to change from the symbol to the raw numeric value.
578
656
  handle_repeat(myhash, params)
579
657
 
data/test/session_test.rb CHANGED
@@ -24,6 +24,14 @@ class SessionTest < Test::Unit::TestCase
24
24
  def teardown
25
25
  @session.disconnect()
26
26
  end
27
+
28
+ def test_handle_app_id_in_session
29
+ new_sess = Toodledo::Session.new('userid', 'password', nil, 'appid')
30
+ flexmock(new_sess, :get_token => 'token')
31
+ new_sess.connect()
32
+ assert_not_nil new_sess.app_id
33
+ end
34
+
27
35
 
28
36
  def test_handle_goal_with_name()
29
37
  params = { :goal => 'goal_name' }
@@ -18,14 +18,15 @@ class ToodledoFunctionalTest < Test::Unit::TestCase
18
18
  @email = 'will.sargent+toodledo_ruby_api@gmail.com'
19
19
  @user_id = 'td479be708d8bd7'
20
20
  @password = 'toodledo'
21
+ @app_id = 'ruby-functional-test'
21
22
 
22
23
  # proxy = { 'host' => '127.0.0.1', 'port' => '8080'}
23
24
  proxy = nil
24
25
 
25
26
  logger = Logger.new(STDOUT)
26
27
  logger.level = Logger::DEBUG
27
-
28
- @session = Session.new(@user_id, @password, logger)
28
+
29
+ @session = Session.new(@user_id, @password, logger, @app_id)
29
30
  @session.connect(base_url, proxy)
30
31
  end
31
32
 
@@ -149,14 +150,14 @@ class ToodledoFunctionalTest < Test::Unit::TestCase
149
150
  assert info_hash[:alias] == 'will.sargent+toodledo_rub'
150
151
  assert info_hash[:pro] == false
151
152
  assert info_hash[:dateformat] == 0
152
- assert info_hash[:timezone] == 0
153
+ assert info_hash[:timezone] == -2
153
154
  assert info_hash[:hidemonths] == 6
154
155
  assert info_hash[:hotlistpriority] == 3
155
156
  assert info_hash[:hotlistduedate] == 14
156
157
 
157
158
  # Doesn't seem to work.
158
- # assert info_hash[:lastaddedit] != nil
159
- assert info_hash[:lastdelete] != nil
159
+ #assert info_hash[:lastaddedit] != nil
160
+ #assert info_hash[:lastdelete] == nil
160
161
  end
161
162
 
162
163
  def test_get_deleted()
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toodledo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Will Sargent
@@ -9,11 +9,12 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-07 00:00:00 -07:00
12
+ date: 2010-02-16 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: cmdparse
17
+ type: :runtime
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
@@ -23,6 +24,17 @@ dependencies:
23
24
  version:
24
25
  - !ruby/object:Gem::Dependency
25
26
  name: highline
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: flexmock
37
+ type: :development
26
38
  version_requirement:
27
39
  version_requirements: !ruby/object:Gem::Requirement
28
40
  requirements:
@@ -32,14 +44,28 @@ dependencies:
32
44
  version:
33
45
  - !ruby/object:Gem::Dependency
34
46
  name: hoe
47
+ type: :development
35
48
  version_requirement:
36
49
  version_requirements: !ruby/object:Gem::Requirement
37
50
  requirements:
38
51
  - - ">="
39
52
  - !ruby/object:Gem::Version
40
- version: 1.5.3
53
+ version: 2.4.0
41
54
  version:
42
- description: "== DESCRIPTION: This is a Ruby API and client for http://toodledo.com, a task management website. It implements all of the calls from Toodledo's developer API, and provides a nice wrapper around the functionality. The client allows you to work with Toodledo from the command line. It will work in either interactive or command line mode. You can also use the client in your shell scripts, or use the API directly as part of a web application. Custom private RSS feed? Want to have the Mac read out your top priority? Input tasks through Quicksilver? Print out tasks with a BetaBrite? It can all happen."
55
+ description: |-
56
+ == DESCRIPTION:
57
+
58
+ This is a Ruby API and client for http://toodledo.com, a task management
59
+ website. It implements all of the calls from Toodledo's developer API, and
60
+ provides a nice wrapper around the functionality.
61
+
62
+ The client allows you to work with Toodledo from the command line. It will
63
+ work in either interactive or command line mode.
64
+
65
+ You can also use the client in your shell scripts, or use the API directly
66
+ as part of a web application. Custom private RSS feed? Want to have the Mac
67
+ read out your top priority? Input tasks through Quicksilver? Print out
68
+ tasks with a BetaBrite? It can all happen.
43
69
  email: will@tersesystems.com
44
70
  executables:
45
71
  - toodledo
@@ -70,8 +96,8 @@ files:
70
96
  - lib/toodledo/command_line/list_contexts_command.rb
71
97
  - lib/toodledo/command_line/list_folders_command.rb
72
98
  - lib/toodledo/command_line/list_goals_command.rb
73
- - lib/toodledo/command_line/list_tasks_command.rb
74
99
  - lib/toodledo/command_line/list_tasks_by_context_command.rb
100
+ - lib/toodledo/command_line/list_tasks_command.rb
75
101
  - lib/toodledo/command_line/parser_helper.rb
76
102
  - lib/toodledo/command_line/setup_command.rb
77
103
  - lib/toodledo/command_line/stdin_command.rb
@@ -92,7 +118,9 @@ files:
92
118
  - test/session_test.rb
93
119
  - test/toodledo_functional_test.rb
94
120
  has_rdoc: true
95
- homepage: http://rubyforge.org/projects/toodledo
121
+ homepage: http://gemcutter.org/gems/toodledo
122
+ licenses: []
123
+
96
124
  post_install_message:
97
125
  rdoc_options:
98
126
  - --main
@@ -114,9 +142,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
142
  requirements: []
115
143
 
116
144
  rubyforge_project: toodledo
117
- rubygems_version: 1.1.1
145
+ rubygems_version: 1.3.5
118
146
  signing_key:
119
- specification_version: 2
147
+ specification_version: 3
120
148
  summary: A command line client and API to Toodledo
121
149
  test_files:
122
150
  - test/client_test.rb