fluttrly 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -18,38 +18,62 @@ to be refactored.
18
18
 
19
19
 
20
20
  ##Usage
21
- ** List an item **
21
+
22
+ ####List an item
23
+
22
24
  #fluttrly <command> <list>
23
25
  $ fluttrly list bouverdafs
24
26
  Task => "Nothing to see here, move along" at => 02-08-2011 18:57 PM
25
27
 
26
- ** Post an item **
28
+ ####Post an item
29
+
27
30
  #fluttrly <command> <list> <message>
28
31
  $ fluttrly post bouverdafs "gem'd"
29
- $ fluttrly list bouverdafs
30
32
  Task => "gem'd" at => 02-10-2011 16:18 PM
31
33
  Task => "Nothing to see here, move along" at => 02-08-2011 18:57 PM
32
34
 
33
- ** Update a task **
35
+ ####Update a task
36
+
34
37
  #fluttrly <command> <list>
35
38
  $ fluttrly update bouverdafs
36
39
  1: Task => "gem'd" at => 02-10-2011 16:18 PM (Completed? false)
37
40
  2: Task => "Nothing to see here, move along" at => 02-08-2011 18:57 PM (Completed? false)
38
41
  Which item would you like to edit?
39
42
  1
40
- $ fluttrly list bouverdafs
41
43
  1: Task => "gem'd" at => 02-10-2011 16:18 PM (Completed? true)
42
44
  2: Task => "Nothing to see here, move along" at => 02-08-2011 18:57 PM (Completed? false)
43
45
 
44
-
46
+ ####Delete a task
47
+ #fluttrly <command> <list>
48
+ $ fluttrly delete bouverdafs
49
+ 1: Task => "Make a throwaway task for deleting" at => 05-10-2011 03:59 AM (Completed? false)
50
+ 2: Task => "write tests for test::unit" at => 05-10-2011 03:56 AM (Completed? false)
51
+ 3: Task => "Add to the README" at => 05-10-2011 03:56 AM (Completed? true)
52
+ 4: Task => "Add delete functionality" at => 05-10-2011 03:56 AM (Completed? true)
53
+ Which item would you like to delete?
54
+ 1
55
+ 1: Task => "write tests for test::unit" at => 05-10-2011 03:56 AM (Completed? false)
56
+ 2: Task => "Add to the README" at => 05-10-2011 03:56 AM (Completed? true)
57
+ 3: Task => "Add delete functionality" at => 05-10-2011 03:56 AM (Completed? true)
58
+
59
+
60
+
61
+ ##Install
62
+ Fork or download this and play with it yourself! If you want to just test
63
+ it locally:
64
+ $ bundle
65
+ $ gem build fluttrly-gem.gemspec
66
+ $ gem install fluttrly-0.0.4.gem
67
+
68
+ Or just grab the latest from rubygems.org and use it.
45
69
 
46
-
47
- ##Install
48
70
  $ gem install fluttrly
49
71
 
72
+
73
+
50
74
  ##TO DO
51
- * Tom-doc this ish
52
75
  * Removing items completely (1 or many)
53
- * Adding to locked lists :\
76
+ * Adding to locked lists
77
+ * Refactor for caching so we don't make so many http requests
54
78
 
55
79
 
data/Rakefile CHANGED
@@ -1,2 +1,13 @@
1
1
  require 'bundler'
2
+ require 'rubygems'
3
+ require 'rake'
4
+
2
5
  Bundler::GemHelper.install_tasks
6
+
7
+ task :default => :test
8
+
9
+ require 'rake/testtask'
10
+ Rake::TestTask.new(:test) do |test|
11
+ test.libs << 'lib' << 'test'
12
+ test.pattern = 'test/**/test_*.rb'
13
+ end
@@ -1,126 +1,17 @@
1
- require 'rubygems'
1
+
2
+ begin
3
+ require 'rubygems'
4
+ rescue LoadError
5
+ end
6
+
2
7
  require 'net/http'
3
8
  require 'JSON'
4
9
  require 'Time'
5
10
 
11
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
6
12
 
7
- #require 'fluttrly-gem/command'
8
- module Fluttrly
9
- # Your code goes here...
10
- class Command
11
- class << self
12
- def execute(*args)
13
- command = args.shift
14
- list = args.shift
15
- message = args.empty? ? nil : args.join(' ')
16
-
17
- parse_arguments(command, list, message)
18
-
19
- end
20
-
21
- def parse_arguments(command, list, message)
22
- return list(list) if command == 'list'
23
- return post(list, message) if command == 'post'
24
- return update(list) if command == 'update'
25
- end
26
-
27
- def update(list)
28
- response = form_response(list)[1]
29
- page = list(list)
30
- if page
31
- puts 'Which item would you like to edit?'
32
- num = STDIN.gets.chomp.to_i
33
- id = page[num-1]["task"]["id"]
34
- update_task(id,response)
35
- end
36
- end
37
-
38
- def list(list)
39
- response = form_response(list, true)[1]
40
- if Net::HTTPSuccess === response
41
- i = 1
42
- page = JSON.parse(response.body)
43
- page.each do |task|
44
- puts("#{i}: Task => \"#{task["task"]["content"]}\" at => #{Time.parse(task["task"]["created_at"]).strftime("%m-%d-%Y %H:%M %p")} (Completed? #{task["task"]["completed"]})")
45
- i = i+1
46
- end
47
- if page.empty?
48
- puts "Oops, that list doesn't have any items yet!"
49
- puts "Try: fluttrly post #{list} <message> first."
50
- return false
51
- end
52
- page
53
- else
54
- response.error!
55
- end
56
- end
13
+ require 'fluttrly-gem/command'
57
14
 
58
- #Posting requires getting COOKIE om nom nom and a csrf token..
59
- def post(list, message)
60
- http, response = form_response(list)
61
- if Net::HTTPSuccess === response
62
- response = post_request(list, message, response,http)
63
- else
64
- response.error!
65
- end
66
- end
67
-
68
- private
69
-
70
- def form_response(list, get=nil)
71
-
72
- #refactors are welcome here =\
73
- if get.nil?
74
- uri = URI.parse("http://fluttrly.com/#{list}")
75
- else
76
- uri = URI.parse("http://fluttrly.com/#{list}.json")
77
- end
78
-
79
- http = Net::HTTP.new(uri.host, uri.port)
80
- response = http.request(Net::HTTP::Get.new(uri.request_uri))
81
- [http, response]
82
- end
83
-
84
- def post_request(list, message, response, http)
85
- #get the csrf-token, really wanna use hpricot here but...
86
- auth_token = $1 if response.body =~ /"authenticity_token".*value="(.+)"/ or nil
87
- raise "No authenticity token found :(" if auth_token.nil?
88
-
89
- #COOKIE COOKIE COOKIE COOKIE COOKIE COOKIE
90
- cookie = response['set-cookie'].split('; ')[0]
91
-
92
- #ok ok, NOW send that post data
93
- uri = URI.parse('http://fluttrly.com/tasks.js')
94
- request = Net::HTTP::Post.new(uri.request_uri)
95
- params = {
96
- 'authenticity_token' => auth_token,
97
- 'task[name]' => "#{list}",
98
- 'task[content]' => "#{message}"
99
- }
100
- request["Cookie"] = cookie
101
- request.set_form_data(params)
102
- response = http.request(request)
103
- end
104
-
105
- def update_task(id, response)
106
- auth_token = $1 if response.body =~ /"csrf-token".*content="(.+)"/ or nil
107
- raise "No authenticity token found :(" if auth_token.nil?
108
-
109
- #COOKIE COOKIE COOKIE COOKIE COOKIE COOKIE
110
- cookie = response['set-cookie'].split('; ')[0]
111
-
112
- uri = URI.parse("http://fluttrly.com/tasks/#{id}")
113
- http = Net::HTTP.new(uri.host, uri.port)
114
- request = Net::HTTP::Put.new(uri.request_uri)
115
- params = {
116
- 'authenticity_token' => auth_token,
117
- 'completed' => "true"
118
- }
119
- request["Cookie"] = cookie
120
- request.set_form_data(params)
121
- response = http.request(request)
122
- end
15
+ module Fluttrly
123
16
 
124
- end
125
- end
126
17
  end
@@ -0,0 +1,253 @@
1
+
2
+ # Command is used to execute the basic commands for interaction with
3
+ # fluttrly.com
4
+ #
5
+ #
6
+ module Fluttrly
7
+ class Command
8
+ class << self
9
+
10
+ # Takes arguments from command line
11
+ #
12
+ # args - The list of arguments passed in. If they are
13
+ # in the wrong order, the proper command will not be
14
+ # executed correctly when passed to parse_arguments()
15
+ #
16
+ def execute(*args)
17
+ command = args.shift
18
+ list = args.shift
19
+ message = args.empty? ? nil : args.join(' ')
20
+
21
+ parse_arguments(command, list, message)
22
+ end
23
+
24
+ # Receives arguments and delegates them appropriately
25
+ #
26
+ # command - First argument used to decide what additional method
27
+ # to call.
28
+ # list - The list to use execute the command on.
29
+ # message - Used to post to a list.
30
+ #
31
+ # Returns output based on the method called.
32
+ def parse_arguments(command, list, message)
33
+ return list(list) if command == 'list' || command == 'l'
34
+ return post(list, message) if command == 'post' || command == 'p'
35
+ return update(list) if command == 'update' || command == 'c'
36
+ return delete(list) if command == 'delete' || command == 'd'
37
+ return help if command == 'help' || command == '-h'
38
+ end
39
+
40
+ # Command used to delete one or all items in a list
41
+ #
42
+ # list - List to delete items from.
43
+ # num - Number in the list to update if already known.
44
+ #
45
+ # Returns a refreshed list showing the changes
46
+ def delete(list, num=nil)
47
+ response = form_response(list)[1]
48
+ page = list(list)
49
+ if page
50
+ puts "Which item would you like to delete?"
51
+ num = STDIN.gets.chomp.to_i if num.nil?
52
+ id = page[num-1]["task"]["id"]
53
+ delete_task(id, response)
54
+ #list(list)
55
+ end
56
+ end
57
+
58
+ # Command used if wanting to mark an item to edit
59
+ #
60
+ # list - List to update
61
+ # num - Number in list to update if already known.
62
+ #
63
+ # Returns the list with its items to show the change.
64
+ def update(list, num=nil)
65
+ response = form_response(list)[1]
66
+ page = list(list)
67
+ if page
68
+ puts 'Which item would you like to edit?'
69
+ num = STDIN.gets.chomp.to_i if num.nil?
70
+ id = page[num-1]["task"]["id"]
71
+ update_task(id,response)
72
+ #list(list)
73
+ end
74
+ end
75
+
76
+ # Command used to list the items within a list
77
+ #
78
+ # list - List to show contents of.
79
+ #
80
+ # Returns a list of tasks for the given list.
81
+ def list(list)
82
+ response = form_response(list, true)[1]
83
+ if Net::HTTPSuccess === response
84
+ i = 1
85
+ page = JSON.parse(response.body)
86
+ puts ""
87
+ page.each do |task|
88
+ puts("#{i}: Task => \"#{task["task"]["content"]}\" at => #{Time.parse(task["task"]["created_at"]).strftime("%m-%d-%Y %H:%M %p")} (Completed? #{task["task"]["completed"]})")
89
+ i = i+1
90
+ end
91
+ if page.empty?
92
+ puts "Oops, that list doesn't have any items yet!"
93
+ puts "Try: fluttrly post #{list} <message> first."
94
+ return false
95
+ end
96
+ page
97
+ else
98
+ response.error!
99
+ end
100
+ end
101
+
102
+ # Used to post a message to a given list.
103
+ #
104
+ # list - List to send a message to.
105
+ # message - Message to pass to the list.
106
+ #
107
+ # Returns a newly updated list.
108
+ def post(list, message)
109
+ http, response = form_response(list)
110
+ if Net::HTTPSuccess === response
111
+ response = post_request(list, message, response,http)
112
+ else
113
+ response.error!
114
+ end
115
+ #list(list)
116
+ end
117
+
118
+ # Command used to print out some helpful hints!
119
+ #
120
+ #
121
+ # Returns nothing.
122
+ def help
123
+ text = %{
124
+ Fluttrly is a nice web app to help you collaborate to-do lists
125
+ with your friends, this is the 'help' for its command line
126
+ interpreter.
127
+
128
+ Usage:
129
+ fluttrly -h/help
130
+ fluttrly <command> <list> <message for posting>
131
+
132
+ Examples:
133
+ fluttrly list bouverdafs Output the list "Bouverdafs"
134
+ fluttrly post bouverdafs "winning" Add to the list bouverdafs the message
135
+ "winning"
136
+ fluttrly update bouverdafs Presents the user with a prompt to
137
+ allow them to update a specific item
138
+ on that list.
139
+ fluttrly delete bouverdafs Just like `update`,except allows user
140
+ to delete a specific item from list.
141
+
142
+ For more information please go to:
143
+ http://github.com/brntbeer/fluttrly-gem
144
+
145
+ }.gsub(/^ {8}/, '') #to strip 8 lines of whitespace
146
+ puts text
147
+ end
148
+
149
+ private
150
+
151
+ # Private: Gathers the appropriate response based upon what kind
152
+ # of argument needs to be done.
153
+ #
154
+ # list - List to gather the response from.
155
+ # get - Optional flag to pass for if we're simply getting a
156
+ # refresh view of the list.
157
+ #
158
+ # Returns a Net::HTTP object for the given url, and a response.
159
+ def form_response(list, get=nil)
160
+
161
+ #refactors are welcome here =\
162
+ if get.nil?
163
+ uri = URI.parse("http://fluttrly.com/#{list}")
164
+ else
165
+ uri = URI.parse("http://fluttrly.com/#{list}.json")
166
+ end
167
+
168
+ http = Net::HTTP.new(uri.host, uri.port)
169
+ response = http.request(Net::HTTP::Get.new(uri.request_uri))
170
+ [http, response]
171
+ end
172
+
173
+
174
+ # Private: Used to set the actual post message.
175
+ #
176
+ # list - List to perform the post on.
177
+ # message - Message to post on the list.
178
+ # response - Response from a previous http request, used to
179
+ # get cookie and csrf token.
180
+ # http - Net::HTTP object used to post the actual data.
181
+ #
182
+ # Returns nothing.
183
+ def post_request(list, message, response, http)
184
+ auth_token = $1 if response.body =~ /"authenticity_token".*value="(.+)"/ or nil
185
+ raise "Not authenticated to perform this action." if auth_token.nil?
186
+
187
+ #COOKIE COOKIE COOKIE COOKIE COOKIE COOKIE
188
+ cookie = response['set-cookie'].split('; ')[0]
189
+
190
+ uri = URI.parse('http://fluttrly.com/tasks.js')
191
+ request = Net::HTTP::Post.new(uri.request_uri)
192
+ params = {
193
+ 'authenticity_token' => auth_token,
194
+ 'task[name]' => "#{list}",
195
+ 'task[content]' => "#{message}"
196
+ }
197
+ request["Cookie"] = cookie
198
+ request.set_form_data(params)
199
+ response = http.request(request)
200
+ end
201
+
202
+ # Private: Performs the PUT method to update a given task.
203
+ #
204
+ # id - The ID of the task we're updating.
205
+ # response - Response from a previous http request, used to
206
+ # get cookie and csrf token.
207
+ #
208
+ # Returns nothing.
209
+ def update_task(id, response)
210
+ auth_token = $1 if response.body =~ /"csrf-token".*content="(.+)"/ or nil
211
+ raise "Not authenticated to perform this action." if auth_token.nil?
212
+
213
+ #COOKIE COOKIE COOKIE COOKIE COOKIE COOKIE
214
+ cookie = response['set-cookie'].split('; ')[0]
215
+
216
+ uri = URI.parse("http://fluttrly.com/tasks/#{id}")
217
+ http = Net::HTTP.new(uri.host, uri.port)
218
+ request = Net::HTTP::Put.new(uri.request_uri)
219
+ params = {
220
+ 'authenticity_token' => auth_token,
221
+ 'completed' => "true"
222
+ }
223
+ request["Cookie"] = cookie
224
+ request.set_form_data(params)
225
+ response = http.request(request)
226
+ end
227
+
228
+ # Private: Performs the DELETE method to delete task(s)
229
+ #
230
+ # id - The ID or ids of the task(s) we're updating
231
+ # response - The response from a previous http request, used to
232
+ # get cookie and csrf token.
233
+ #
234
+ # Returns nothing.
235
+ def delete_task(id, response)
236
+ auth_token = $1 if response.body =~ /"csrf-token".*content="(.+)"/ or nil
237
+ raise "Not authenticated to perform this action." if auth_token.nil?
238
+
239
+ cookie = response['set-cookie'].split('; ')[0]
240
+
241
+ uri = URI.parse("http://fluttrly.com/tasks/#{id}")
242
+ http = Net::HTTP.new(uri.host, uri.port)
243
+ request = Net::HTTP::Delete.new(uri.request_uri)
244
+ params = {
245
+ 'authenticity_token' => auth_token,
246
+ }
247
+ request["Cookie"] = cookie
248
+ request.set_form_data(params)
249
+ response = http.request(request)
250
+ end
251
+ end
252
+ end
253
+ end
@@ -1,3 +1,3 @@
1
1
  module Fluttrly
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -0,0 +1,34 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'fluttrly-gem'
4
+ require 'net/http'
5
+ require 'JSON'
6
+
7
+ class TestCommand < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @list = Fluttrly::Command.list("bouverdafs")
11
+ @finished = @list.select{|item| item["task"]["completed"] == true }
12
+ end
13
+
14
+ def test_list_size_increases_after_post
15
+ Fluttrly::Command.post("bouverdafs", "8=======D~~~~")
16
+ new_size = Fluttrly::Command.list("bouverdafs").size
17
+ assert (new_size > @list.size)
18
+ end
19
+
20
+ def test_list_update_includes_newly_completed_item
21
+ Fluttrly::Command.update("bouverdafs", 1)
22
+ list = Fluttrly::Command.list("bouverdafs")
23
+ finished = list.select{|item| item["task"]["completed"] == true}
24
+ assert list.include?(finished.first)
25
+ end
26
+
27
+ def test_size_decreases_after_delete
28
+ #offset the item to be deleted due to code looking at num-1
29
+ Fluttrly::Command.delete("bouverdafs", (@list.size-@finished.size)+1)
30
+ new_size = Fluttrly::Command.list("bouverdafs").size
31
+ assert (new_size < @list.size)
32
+ end
33
+
34
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluttrly
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
4
+ hash: 21
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brent Beer
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-12 00:00:00 -06:00
18
+ date: 2011-05-17 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -52,7 +52,9 @@ files:
52
52
  - bin/fluttrly
53
53
  - fluttrly-gem.gemspec
54
54
  - lib/fluttrly-gem.rb
55
+ - lib/fluttrly-gem/command.rb
55
56
  - lib/fluttrly-gem/version.rb
57
+ - test/test_command.rb
56
58
  has_rdoc: true
57
59
  homepage: http://rubygems.org/gems/fluttrly
58
60
  licenses: []
@@ -83,9 +85,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
85
  requirements: []
84
86
 
85
87
  rubyforge_project: fluttrly-gem
86
- rubygems_version: 1.3.7
88
+ rubygems_version: 1.6.0
87
89
  signing_key:
88
90
  specification_version: 3
89
91
  summary: Fluttrly.com command line interface.
90
- test_files: []
91
-
92
+ test_files:
93
+ - test/test_command.rb