thimbl 0.0.3 → 0.1.1
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/Manifest +2 -1
- data/README.md +16 -31
- data/Rakefile +1 -1
- data/bin/{thimbl → thimblr} +9 -7
- data/lib/thimbl.rb +2 -0
- data/lib/thimbl/base.rb +76 -122
- data/lib/thimbl/command.rb +30 -25
- data/lib/thimbl/finger.rb +0 -1
- data/lib/thimbl/utils.rb +18 -0
- data/test/thimbl_base_test.rb +62 -86
- data/test/thimbl_command_test.rb +19 -25
- data/test/thimbl_utils_test.rb +10 -0
- data/thimbl.gemspec +7 -7
- metadata +11 -7
data/Manifest
CHANGED
@@ -3,11 +3,12 @@ Gemfile.lock
|
|
3
3
|
Manifest
|
4
4
|
README.md
|
5
5
|
Rakefile
|
6
|
-
bin/
|
6
|
+
bin/thimblr
|
7
7
|
lib/thimbl.rb
|
8
8
|
lib/thimbl/base.rb
|
9
9
|
lib/thimbl/command.rb
|
10
10
|
lib/thimbl/finger.rb
|
11
|
+
lib/thimbl/utils.rb
|
11
12
|
test/fixtures/cache.json
|
12
13
|
test/fixtures/finger_dk_telekommunisten_org.txt
|
13
14
|
test/fixtures/finger_dk_telekommunisten_org_two_break_lines.txt
|
data/README.md
CHANGED
@@ -6,17 +6,12 @@ I have follow the style of the [Thimbl Python client](https://github.com/blippy/
|
|
6
6
|
|
7
7
|
## Commands
|
8
8
|
|
9
|
-
* setup
|
10
9
|
* follow
|
11
10
|
* fetch
|
12
11
|
* post
|
13
12
|
* print
|
14
13
|
* push
|
15
14
|
|
16
|
-
## Architecture
|
17
|
-
|
18
|
-
This client is only manipulating json files, the one with your **personal plan** and the other with the **complete cache** of the timeline of the people you are following.
|
19
|
-
|
20
15
|
## Version
|
21
16
|
|
22
17
|
This version is in development, not ready for any production environment.
|
@@ -30,44 +25,34 @@ This version is in development, not ready for any production environment.
|
|
30
25
|
require 'rubygems'
|
31
26
|
require 'thimbl'
|
32
27
|
thimbl =
|
33
|
-
Thimbl::Base.new(
|
34
|
-
'
|
35
|
-
'
|
36
|
-
'
|
37
|
-
'
|
28
|
+
Thimbl::Base.new(
|
29
|
+
'bio' => 'my bio',
|
30
|
+
'website' => 'my website',
|
31
|
+
'mobile' => 'my mobile',
|
32
|
+
'email' => 'my email',
|
33
|
+
'address' => 'me@thimbl.net',
|
34
|
+
'name' => 'my name'
|
38
35
|
)
|
39
|
-
thimbl.setup(
|
40
|
-
'bio' => 'my bio',
|
41
|
-
'website' => 'my website',
|
42
|
-
'mobile' => 'my mobile',
|
43
|
-
'email' => 'my email',
|
44
|
-
'address' => 'my address',
|
45
|
-
'name' => 'my name'
|
46
|
-
)
|
47
36
|
thimbl.follow 'dk', 'dk@telekommunisten.org'
|
48
37
|
thimbl.fetch
|
49
38
|
thimbl.print
|
50
39
|
thimbl.post 'My first post'
|
51
|
-
thimbl.push
|
40
|
+
thimbl.push 'password'
|
52
41
|
|
53
42
|
## Shell Command
|
54
43
|
|
55
44
|
The gem comes with a *shell command*, you can use it like this:
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
45
|
+
|
46
|
+
thimblr setup 'user@thimblrserver.com'
|
47
|
+
thimblr follow 'dk' 'dk@telekommunisten.org'
|
48
|
+
thimblr fetch
|
49
|
+
thimblr print
|
50
|
+
thimblr post "My first message :)"
|
51
|
+
thimblr push <password>
|
63
52
|
|
64
53
|
## TODO
|
65
54
|
|
66
|
-
* Shell script /bin/thimbl
|
67
|
-
* Thinking that the *plan_path* is not needed.
|
68
|
-
* Not save thimbl password, request for it in any *thimbl.push*
|
69
55
|
* Support *simbolize* hash keys
|
70
56
|
* In the Thimbl::Command.setup ask for the rest of the configuration options *bio*, *mobile*, ...
|
71
57
|
* thimbl.unfollow
|
72
|
-
* ERROR: If finger respond empty Plan
|
73
|
-
* ERROR: the message format is without *address* key.
|
58
|
+
* ERROR: If finger respond empty Plan
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('thimbl', '0.
|
5
|
+
Echoe.new('thimbl', '0.1.1') do |p|
|
6
6
|
p.description = "Small client for the distributed microbloging protocol: [thimbl](http://www.thimbl.net/)"
|
7
7
|
p.url = "http://github.com/fguillen/ThimblClient"
|
8
8
|
p.author = "Fernando Guillen"
|
data/bin/{thimbl → thimblr}
RENAMED
@@ -1,12 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
# Use:
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
4
|
+
# thimblr setup 'user@thimblrserver.com'
|
5
|
+
# thimblr follow 'dk' 'dk@telekommunisten.org'
|
6
|
+
# thimblr fetch
|
7
|
+
# thimblr print
|
8
|
+
# thimblr post "My first message :)"
|
9
|
+
# thimblr push
|
10
10
|
|
11
11
|
begin
|
12
12
|
require 'thimbl'
|
@@ -26,11 +26,13 @@ begin
|
|
26
26
|
when 'print'; puts Thimbl::Command.print
|
27
27
|
when 'fetch'; Thimbl::Command.fetch; puts "fecth completed"
|
28
28
|
when 'post'; Thimbl::Command.post ARGV[1]; puts "post completed"
|
29
|
-
when 'push'; Thimbl::Command.push; puts "push completed"
|
29
|
+
when 'push'; Thimbl::Command.push ARGV[1]; puts "push completed"
|
30
30
|
when 'follow'; Thimbl::Command.follow( ARGV[1], ARGV[2] ); puts "follow completed"
|
31
31
|
else
|
32
32
|
puts "command not valid '#{ARGV[0]}'"
|
33
|
+
exit 1
|
33
34
|
end
|
34
35
|
rescue ArgumentError => e
|
35
36
|
puts e.message
|
37
|
+
exit 1
|
36
38
|
end
|
data/lib/thimbl.rb
CHANGED
@@ -2,6 +2,8 @@ require 'rubygems'
|
|
2
2
|
require 'json'
|
3
3
|
require 'net/scp'
|
4
4
|
require 'fileutils'
|
5
|
+
require 'tempfile'
|
5
6
|
require "#{File.dirname(__FILE__)}/thimbl/base"
|
6
7
|
require "#{File.dirname(__FILE__)}/thimbl/command"
|
7
8
|
require "#{File.dirname(__FILE__)}/thimbl/finger"
|
9
|
+
require "#{File.dirname(__FILE__)}/thimbl/utils"
|
data/lib/thimbl/base.rb
CHANGED
@@ -7,56 +7,31 @@
|
|
7
7
|
# Use:
|
8
8
|
# require 'rubygems'
|
9
9
|
# require 'thimbl'
|
10
|
-
# thimbl =
|
11
|
-
# Thimbl::Base.new(
|
12
|
-
# '
|
13
|
-
# '
|
14
|
-
# '
|
15
|
-
# '
|
10
|
+
# thimbl =
|
11
|
+
# Thimbl::Base.new(
|
12
|
+
# 'bio' => 'my bio',
|
13
|
+
# 'website' => 'my website',
|
14
|
+
# 'mobile' => 'my mobile',
|
15
|
+
# 'email' => 'my email',
|
16
|
+
# 'address' => 'username@thimbl.net',
|
17
|
+
# 'name' => 'my name'
|
16
18
|
# )
|
17
|
-
# thimbl.setup(
|
18
|
-
# 'bio' => 'my bio',
|
19
|
-
# 'website' => 'my website',
|
20
|
-
# 'mobile' => 'my mobile',
|
21
|
-
# 'email' => 'my email',
|
22
|
-
# 'address' => 'my address',
|
23
|
-
# 'name' => 'my name'
|
24
|
-
# )
|
25
19
|
# thimbl.follow 'dk', 'dk@telekommunisten.org'
|
26
20
|
# thimbl.fetch
|
27
21
|
# thimbl.print
|
28
22
|
# thimbl.post 'My first post'
|
29
|
-
# thimbl.push
|
23
|
+
# thimbl.push <password>
|
30
24
|
#
|
31
25
|
module Thimbl
|
32
26
|
class Base
|
33
|
-
|
27
|
+
attr_accessor :data
|
34
28
|
|
35
|
-
# Initialize the
|
36
|
-
#
|
37
|
-
# Use:
|
38
|
-
# Thimbl.new(
|
39
|
-
# :plan_path => <path to the plan file>,
|
40
|
-
# :cache_path => <path to the cache file>
|
41
|
-
# :user => <the user@domain>,
|
42
|
-
# :password => <the user password>
|
43
|
-
# )
|
44
|
-
#
|
45
|
-
def initialize( opts = {} )
|
46
|
-
@plan_path = opts['plan_path']
|
47
|
-
@cache_path = opts['cache_path']
|
48
|
-
@user = opts['user']
|
49
|
-
@password = opts['password']
|
50
|
-
|
51
|
-
@data = nil
|
52
|
-
@address = nil
|
53
|
-
end
|
54
|
-
|
55
|
-
# Setup a new configuration, the execution of this method
|
29
|
+
# Initialize a new configuration, the execution of this method
|
56
30
|
# will delete any thing in the `thimbl.plan_path` file and `thimbl.cache_path` file.
|
57
31
|
#
|
58
32
|
# Use:
|
59
|
-
# thimbl
|
33
|
+
# thimbl =
|
34
|
+
# Thimbl::Base.new(
|
60
35
|
# :bio => 'bio',
|
61
36
|
# :website => 'website',
|
62
37
|
# :mobile => 'mobile',
|
@@ -65,7 +40,10 @@ module Thimbl
|
|
65
40
|
# :name => 'name'
|
66
41
|
# )
|
67
42
|
#
|
68
|
-
|
43
|
+
# or just:
|
44
|
+
#
|
45
|
+
# thimbl = Thimbl::Base.new
|
46
|
+
def initialize( opts = {} )
|
69
47
|
opts = {
|
70
48
|
'bio' => 'bio',
|
71
49
|
'website' => 'website',
|
@@ -92,70 +70,67 @@ module Thimbl
|
|
92
70
|
}
|
93
71
|
}
|
94
72
|
}
|
95
|
-
|
96
|
-
@address = opts['address']
|
97
|
-
|
98
|
-
save_data
|
99
73
|
end
|
100
74
|
|
101
75
|
# Post a new message in your time-line.
|
102
|
-
#
|
103
|
-
# Use:
|
104
|
-
# thimbl.post <message>
|
105
|
-
#
|
106
|
-
# To publish your comment you have to call:
|
107
|
-
# thimbl.push
|
108
|
-
#
|
76
|
+
# _This method doesn't push the modifications to de server._
|
109
77
|
def post( text )
|
110
78
|
message = {
|
111
|
-
'address' => address,
|
112
79
|
'time' => Time.now.strftime('%Y%m%d%H%M%S'),
|
113
80
|
'text' => text
|
114
81
|
}
|
115
82
|
|
116
|
-
data['plans'][
|
117
|
-
|
83
|
+
data['plans'][me]['messages'] << message
|
84
|
+
end
|
85
|
+
|
86
|
+
# Post a new message in your time-line and push the modifications to the server.
|
87
|
+
def post!( text, password )
|
88
|
+
post text
|
89
|
+
push password
|
118
90
|
end
|
119
91
|
|
120
|
-
# Add a new user to
|
121
|
-
#
|
122
|
-
# Use:
|
123
|
-
# thimbl.follow 'nick', 'address'
|
124
|
-
#
|
125
|
-
# To publish your following users you have to call:
|
126
|
-
# thimbl.push
|
127
|
-
#
|
92
|
+
# Add a new user to your following
|
93
|
+
# _This method doesn't push the modifications to de server._
|
128
94
|
def follow( follow_nick, follow_address )
|
129
|
-
data['plans'][
|
130
|
-
|
95
|
+
return if data['plans'][me]['following'].count { |e| e['address'] == follow_address } != 0
|
96
|
+
data['plans'][me]['following'] << { 'nick' => follow_nick, 'address' => follow_address }
|
97
|
+
end
|
98
|
+
|
99
|
+
# Add a new user to your following and push the modifications to the server.
|
100
|
+
def follow!( follow_nick, follow_address, password )
|
101
|
+
follow follow_nick, follow_address
|
102
|
+
push password
|
131
103
|
end
|
132
104
|
|
133
105
|
# Fetch all the info and timelines of all the users you are following.
|
134
|
-
#
|
135
|
-
# Use:
|
136
|
-
# thimbl.fetch
|
137
|
-
#
|
106
|
+
# Even you, so any not pushed modification will be overwritten
|
138
107
|
def fetch
|
139
|
-
following.map { |f| f['address'] }
|
140
|
-
|
108
|
+
following_and_me = following.map { |f| f['address'] } << me
|
109
|
+
following_and_me.uniq.each do |address|
|
110
|
+
address_finger = Thimbl::Finger.run address
|
111
|
+
next if address_finger.nil? || address_finger.match(/Plan:\s*(.*)/m).nil?
|
141
112
|
address_plan = address_finger.match(/Plan:\s*(.*)/m)[1].gsub("\\\n",'')
|
142
|
-
data['plans'][
|
113
|
+
data['plans'][address] = JSON.load( address_plan )
|
143
114
|
end
|
115
|
+
end
|
144
116
|
|
145
|
-
|
117
|
+
# Send your actual `plan` file to your server
|
118
|
+
# It requires the password of your thimbl user
|
119
|
+
def push( password )
|
120
|
+
tmp_path = Thimbl::Utils.to_file plan.to_json
|
121
|
+
Net::SCP.start( me.split('@')[1], me.split('@')[0], :password => password ) do |scp|
|
122
|
+
scp.upload!( tmp_path, ".plan" )
|
123
|
+
end
|
146
124
|
end
|
147
125
|
|
148
126
|
# Print every message of you and all the users you are following.
|
149
127
|
#
|
150
|
-
# Use:
|
151
|
-
# thimbl.print
|
152
128
|
# The method doesn't print anything by it self. It just returns an string
|
153
129
|
# with all the comments.
|
154
|
-
#
|
155
130
|
def print
|
156
131
|
result = ""
|
157
132
|
messages.each do |message|
|
158
|
-
result += Thimbl::
|
133
|
+
result += Thimbl::Utils.parse_time( message['time'] ).strftime( '%Y-%m-%d %H:%M:%S' )
|
159
134
|
result += " #{message['address']}"
|
160
135
|
result += " > #{message['text']}"
|
161
136
|
result += "\n"
|
@@ -164,61 +139,40 @@ module Thimbl
|
|
164
139
|
return result
|
165
140
|
end
|
166
141
|
|
167
|
-
#
|
168
|
-
#
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
142
|
+
# Returns all the messages of you and all the users you are following
|
143
|
+
# in a chronologic order into a json format.
|
144
|
+
def messages
|
145
|
+
result = []
|
146
|
+
|
147
|
+
data['plans'].each_pair do |address, plan|
|
148
|
+
next if plan['messages'].nil?
|
149
|
+
plan['messages'].each do |message|
|
150
|
+
result << {
|
151
|
+
'address' => address,
|
152
|
+
'time' => Thimbl::Utils.parse_time( message['time'] ),
|
153
|
+
'text' => message['text']
|
154
|
+
}
|
155
|
+
end
|
175
156
|
end
|
157
|
+
|
158
|
+
result = result.sort { |a,b| a['time'] <=> b['time'] }
|
159
|
+
|
160
|
+
return result
|
176
161
|
end
|
177
162
|
|
178
|
-
#
|
179
|
-
|
180
|
-
|
181
|
-
#
|
182
|
-
def load_data
|
183
|
-
@data = JSON.load( File.read cache_path )
|
184
|
-
@address = data['me']
|
163
|
+
# Returns the actual thimbl user account
|
164
|
+
def me
|
165
|
+
data['me']
|
185
166
|
end
|
186
|
-
|
187
|
-
# Save all the data into the `thimbl` objecto into your `cache` file and
|
188
|
-
# `plan` file.
|
189
|
-
#
|
190
|
-
# Use:
|
191
|
-
# thimbl.save_data
|
192
|
-
#
|
193
|
-
def save_data
|
194
|
-
File.open( cache_path, 'w' ) { |f| f.write data.to_json }
|
195
|
-
File.open( plan_path, 'w' ) { |f| f.write data['plans'][address].to_json }
|
196
|
-
end
|
197
|
-
|
167
|
+
|
198
168
|
# Returns all the info about the users you are following.
|
199
|
-
#
|
200
|
-
# Use:
|
201
|
-
# thimbl.following
|
202
|
-
#
|
203
169
|
def following
|
204
|
-
data['plans'][
|
170
|
+
data['plans'][me]['following']
|
205
171
|
end
|
206
|
-
|
207
|
-
# Returns all the messages of you and all the users you are following
|
208
|
-
# in a chronologic order into a json format.
|
209
|
-
#
|
210
|
-
# Use:
|
211
|
-
# thimbl.messages
|
212
|
-
#
|
213
|
-
def messages
|
214
|
-
_messages = data['plans'].values.map { |e| e['messages'] }.flatten
|
215
|
-
_messages = _messages.sort { |a,b| a['time'] <=> b['time'] }
|
216
172
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
def self.parse_time( time )
|
221
|
-
Time.utc( time[0,4], time[4,2], time[6,2], time[8,2], time[10,2], time[12,2] )
|
173
|
+
# Returns the actual plan
|
174
|
+
def plan
|
175
|
+
data['plans'][me]
|
222
176
|
end
|
223
177
|
end
|
224
178
|
end
|
data/lib/thimbl/command.rb
CHANGED
@@ -1,32 +1,35 @@
|
|
1
1
|
module Thimbl
|
2
2
|
class Command
|
3
|
-
|
3
|
+
CACHE_PATH = File.expand_path( "~#{ENV['USER']}/.thimbl/cache.json" )
|
4
4
|
|
5
5
|
def self.setup( *args )
|
6
|
-
if( args.size !=
|
7
|
-
raise ArgumentError, "use: $ thimbl setup <
|
6
|
+
if( args.size != 1 )
|
7
|
+
raise ArgumentError, "use: $ thimbl setup <thimbl_user>"
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
f.write( { :plan_path => args[0], :cache_path => args[1], :user => args[2], :password => args[3] }.to_json )
|
14
|
-
end
|
10
|
+
thimbl = Thimbl::Base.new( 'address' => args[0] )
|
11
|
+
save_cache thimbl.data
|
12
|
+
end
|
15
13
|
|
16
|
-
|
17
|
-
|
14
|
+
def self.save_cache data
|
15
|
+
if !File.exists? File.dirname( cache_path )
|
16
|
+
FileUtils.mkdir_p File.dirname( cache_path )
|
17
|
+
end
|
18
|
+
|
19
|
+
File.open( cache_path, 'w' ) do |f|
|
20
|
+
f.write( data.to_json )
|
21
|
+
end
|
18
22
|
end
|
19
|
-
|
23
|
+
|
20
24
|
def self.print
|
21
25
|
thimbl = Thimbl::Command.load
|
22
|
-
thimbl.load_data
|
23
26
|
return thimbl.print
|
24
27
|
end
|
25
28
|
|
26
29
|
def self.fetch
|
27
30
|
thimbl = Thimbl::Command.load
|
28
|
-
thimbl.load_data
|
29
31
|
thimbl.fetch
|
32
|
+
save_cache thimbl.data
|
30
33
|
end
|
31
34
|
|
32
35
|
def self.post( text )
|
@@ -34,14 +37,16 @@ module Thimbl
|
|
34
37
|
raise ArgumentError, "use: $ thimbl post <message>"
|
35
38
|
end
|
36
39
|
thimbl = Thimbl::Command.load
|
37
|
-
thimbl.load_data
|
38
40
|
thimbl.post text
|
41
|
+
save_cache thimbl.data
|
39
42
|
end
|
40
|
-
|
41
|
-
def self.push
|
43
|
+
|
44
|
+
def self.push( password )
|
45
|
+
if( password.nil? || password.empty? )
|
46
|
+
raise ArgumentError, "use: $ thimbl push <password>"
|
47
|
+
end
|
42
48
|
thimbl = Thimbl::Command.load
|
43
|
-
thimbl.
|
44
|
-
thimbl.push
|
49
|
+
thimbl.push password
|
45
50
|
end
|
46
51
|
|
47
52
|
def self.follow( nick, address )
|
@@ -49,23 +54,23 @@ module Thimbl
|
|
49
54
|
raise ArgumentError, "use: $ thimbl follow <nick> <address>"
|
50
55
|
end
|
51
56
|
thimbl = Thimbl::Command.load
|
52
|
-
thimbl.load_data
|
53
57
|
thimbl.follow nick, address
|
58
|
+
save_cache thimbl.data
|
54
59
|
end
|
55
60
|
|
56
61
|
def self.load
|
57
|
-
if( !File.exists?
|
58
|
-
raise ArgumentError, "Thimbl need to setup, use: $ thimbl setup <
|
62
|
+
if( !File.exists? cache_path )
|
63
|
+
raise ArgumentError, "Thimbl need to setup, use: $ thimbl setup <thimbl_user>"
|
59
64
|
end
|
60
65
|
|
61
|
-
|
62
|
-
thimbl =
|
66
|
+
thimbl = Thimbl::Base.new
|
67
|
+
thimbl.data = JSON.load File.read cache_path
|
63
68
|
|
64
69
|
return thimbl
|
65
70
|
end
|
66
71
|
|
67
|
-
def self.
|
68
|
-
|
72
|
+
def self.cache_path
|
73
|
+
CACHE_PATH
|
69
74
|
end
|
70
75
|
end
|
71
76
|
end
|
data/lib/thimbl/finger.rb
CHANGED
data/lib/thimbl/utils.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Thimbl
|
2
|
+
class Utils
|
3
|
+
def self.to_file( text )
|
4
|
+
file = Tempfile.new('plan.json')
|
5
|
+
file.write( text )
|
6
|
+
file.close
|
7
|
+
file.path
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.parse_time( time )
|
11
|
+
if time.is_a? Numeric
|
12
|
+
Time.at time
|
13
|
+
else
|
14
|
+
Time.utc( time[0,4], time[4,2], time[6,2], time[8,2], time[10,2], time[12,2] )
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/test/thimbl_base_test.rb
CHANGED
@@ -24,29 +24,12 @@ class ThimblBaseTest < Test::Unit::TestCase
|
|
24
24
|
def teardown
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
thimbl =
|
29
|
-
Thimbl::Base.new(
|
30
|
-
'plan_path' => 'plan_path',
|
31
|
-
'cache_path' => 'cache_path',
|
32
|
-
'user' => 'user',
|
33
|
-
'password' => 'password'
|
34
|
-
)
|
35
|
-
|
36
|
-
assert_equal( 'plan_path', thimbl.plan_path )
|
37
|
-
assert_equal( 'cache_path', thimbl.cache_path )
|
38
|
-
assert_equal( 'user', thimbl.user )
|
39
|
-
assert_equal( 'password', thimbl.password )
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_setup_without_options
|
27
|
+
def test_new_without_options
|
43
28
|
thimbl = Thimbl::Base.new
|
44
|
-
thimbl.expects(:save_data)
|
45
|
-
thimbl.setup
|
46
29
|
|
47
|
-
assert_equal( 'address', thimbl.
|
30
|
+
assert_equal( 'address', thimbl.me )
|
48
31
|
|
49
|
-
data = thimbl.data['plans'][thimbl.
|
32
|
+
data = thimbl.data['plans'][thimbl.me]
|
50
33
|
assert_equal( 'name', data['name'] )
|
51
34
|
assert_equal( [], data['messages'] )
|
52
35
|
assert_equal( 'bio', data['bio'] )
|
@@ -57,21 +40,20 @@ class ThimblBaseTest < Test::Unit::TestCase
|
|
57
40
|
assert_equal( 'email', data['properties']['email'] )
|
58
41
|
end
|
59
42
|
|
60
|
-
def
|
61
|
-
thimbl =
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
data = thimbl.data['plans'][thimbl.address]
|
43
|
+
def test_new_with_options
|
44
|
+
thimbl =
|
45
|
+
Thimbl::Base.new(
|
46
|
+
'bio' => 'my bio',
|
47
|
+
'website' => 'my website',
|
48
|
+
'mobile' => 'my mobile',
|
49
|
+
'email' => 'my email',
|
50
|
+
'address' => 'my address',
|
51
|
+
'name' => 'my name'
|
52
|
+
)
|
53
|
+
|
54
|
+
assert_equal( 'my address', thimbl.me )
|
55
|
+
|
56
|
+
data = thimbl.data['plans'][thimbl.me]
|
75
57
|
assert_equal( 'my name', data['name'] )
|
76
58
|
assert_equal( 'my bio', data['bio'] )
|
77
59
|
assert_equal( 'my mobile', data['properties']['mobile'] )
|
@@ -80,31 +62,23 @@ class ThimblBaseTest < Test::Unit::TestCase
|
|
80
62
|
end
|
81
63
|
|
82
64
|
def test_post
|
83
|
-
Thimbl::Base.any_instance.expects(:save_data)
|
84
65
|
thimbl = Thimbl::Base.new
|
85
66
|
|
86
|
-
thimbl.stubs( :address ).returns( @data['me'] )
|
87
|
-
thimbl.stubs( :data ).returns( @data )
|
88
|
-
|
89
67
|
Delorean.time_travel_to("2011-02-03 04:05:06") do
|
90
68
|
thimbl.post( "wadus wadus" )
|
91
69
|
end
|
92
70
|
|
93
|
-
message = thimbl.data['plans'][thimbl.
|
94
|
-
assert_equal( thimbl.address, message['address'] )
|
71
|
+
message = thimbl.data['plans'][thimbl.me]['messages'].last
|
95
72
|
assert_equal( '20110203040506', message['time'] )
|
96
73
|
assert_equal( 'wadus wadus', message['text'] )
|
97
74
|
end
|
98
75
|
|
99
76
|
def test_follow
|
100
|
-
Thimbl::Base.any_instance.expects(:save_data)
|
101
77
|
thimbl = Thimbl::Base.new
|
102
|
-
thimbl.stubs( :address ).returns( @data['me'] )
|
103
|
-
thimbl.stubs( :data ).returns( @data )
|
104
78
|
|
105
79
|
thimbl.follow( 'nick', 'address' )
|
106
80
|
|
107
|
-
following = thimbl.data['plans'][thimbl.
|
81
|
+
following = thimbl.data['plans'][thimbl.me]['following'].last
|
108
82
|
assert_equal( 'nick', following['nick'] )
|
109
83
|
assert_equal( 'address', following['address'] )
|
110
84
|
end
|
@@ -125,10 +99,13 @@ class ThimblBaseTest < Test::Unit::TestCase
|
|
125
99
|
returns( finger_fixture ).
|
126
100
|
in_sequence( finger_sequence )
|
127
101
|
|
128
|
-
Thimbl::
|
129
|
-
|
130
|
-
|
131
|
-
|
102
|
+
Thimbl::Finger.
|
103
|
+
expects(:run).
|
104
|
+
with( 'me@thimbl.net' ).
|
105
|
+
returns( finger_fixture ).
|
106
|
+
in_sequence( finger_sequence )
|
107
|
+
|
108
|
+
thimbl = Thimbl::Base.new( 'address' => 'me@thimbl.net' )
|
132
109
|
thimbl.expects(:following).returns( [
|
133
110
|
{'nick' => 'wadus1', 'address' => 'wadus1@telekommunisten.org' },
|
134
111
|
{'nick' => 'wadus2', 'address' => 'wadus2@telekommunisten.org' },
|
@@ -142,41 +119,43 @@ class ThimblBaseTest < Test::Unit::TestCase
|
|
142
119
|
|
143
120
|
def test_fetch_with_plan_with_two_break_lines
|
144
121
|
finger_fixture = File.read "#{File.dirname(__FILE__)}/fixtures/finger_dk_telekommunisten_org_two_break_lines.txt"
|
145
|
-
Thimbl::Finger.
|
146
|
-
expects(:run).
|
147
|
-
with( 'wadus1@telekommunisten.org' ).
|
148
|
-
returns( finger_fixture )
|
149
|
-
|
150
|
-
Thimbl::Base.any_instance.expects(:save_data)
|
151
|
-
|
152
|
-
thimbl = Thimbl::Base.new
|
153
|
-
thimbl.stubs(:data).returns( @data )
|
154
|
-
thimbl.expects(:following).returns( [{'nick' => 'wadus1', 'address' => 'wadus1@telekommunisten.org' }] )
|
122
|
+
Thimbl::Finger.expects(:run).with( 'me@thimbl.net' ).returns( finger_fixture )
|
155
123
|
|
124
|
+
thimbl = Thimbl::Base.new( 'address' => 'me@thimbl.net' )
|
156
125
|
thimbl.fetch
|
157
126
|
|
158
|
-
assert_equal( 22, thimbl.data['plans']['
|
127
|
+
assert_equal( 22, thimbl.data['plans']['me@thimbl.net']['messages'].count )
|
159
128
|
end
|
160
129
|
|
161
130
|
def test_push
|
162
|
-
thimbl = Thimbl::Base.new( '
|
163
|
-
Net::SCP.expects(:start).with( 'domain', 'user', :password => 'my password' )
|
164
|
-
thimbl.push
|
131
|
+
thimbl = Thimbl::Base.new( 'address' => 'user@domain.com' )
|
132
|
+
Net::SCP.expects(:start).with( 'domain.com', 'user', :password => 'my password' )
|
133
|
+
thimbl.push 'my password'
|
165
134
|
end
|
166
|
-
|
167
|
-
def test_load_data
|
168
|
-
thimbl = Thimbl::Base.new( 'cache_path' => "#{File.dirname(__FILE__)}/fixtures/cache.json" )
|
169
|
-
thimbl.load_data
|
170
135
|
|
171
|
-
assert_equal( 'fguillen@telekommunisten.org', thimbl.data['me'] )
|
172
|
-
assert_equal( 2, thimbl.data['plans'].size )
|
173
|
-
assert_equal( 4, thimbl.data['plans']['fguillen@telekommunisten.org']['messages'].size )
|
174
|
-
end
|
175
|
-
|
176
136
|
def test_messages
|
177
|
-
thimbl = Thimbl::Base.new
|
178
|
-
thimbl.
|
137
|
+
thimbl = Thimbl::Base.new
|
138
|
+
thimbl.data = JSON.load File.read "#{File.dirname(__FILE__)}/fixtures/cache.json"
|
139
|
+
|
179
140
|
assert_equal( 24, thimbl.messages.size )
|
141
|
+
|
142
|
+
first = thimbl.messages.first
|
143
|
+
last = thimbl.messages.last
|
144
|
+
|
145
|
+
assert_equal 'dk@telekommunisten.org', first['address']
|
146
|
+
assert_equal '@bernd, would be cool to inegrate thimbl in http://bau-ha.us\\!', first['text']
|
147
|
+
assert_equal Time.utc( 2010, 11, 29, 6, 3, 35 ), first['time']
|
148
|
+
|
149
|
+
assert_equal 'fguillen@telekommunisten.org', last['address']
|
150
|
+
assert_equal 'testing 3', last['text']
|
151
|
+
assert_equal Time.utc( 2011, 2, 5, 15, 22, 47 ), last['time']
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_messages_with_nil_error
|
155
|
+
thimbl = Thimbl::Base.new
|
156
|
+
thimbl.data = JSON.load File.read "#{File.dirname(__FILE__)}/fixtures/cache_error_nil.json"
|
157
|
+
|
158
|
+
assert_not_nil thimbl.messages
|
180
159
|
end
|
181
160
|
|
182
161
|
def test_print
|
@@ -202,19 +181,16 @@ class ThimblBaseTest < Test::Unit::TestCase
|
|
202
181
|
assert_equal( "2011-01-31 00:22:02 fguillen@telekommunisten.org > Here I am\n", print.lines.to_a[0] )
|
203
182
|
assert_equal( "2011-02-05 15:06:37 fguillen@telekommunisten.org > testing :)\n", print.lines.to_a[1] )
|
204
183
|
end
|
205
|
-
|
206
|
-
def
|
207
|
-
|
208
|
-
thimbl.stubs( :address ).returns( @data['me'] )
|
209
|
-
thimbl.stubs( :data ).returns( @data )
|
210
|
-
thimbl.data
|
211
|
-
thimbl.save_data
|
212
|
-
|
213
|
-
assert_equal( thimbl.data['plans'][thimbl.address], JSON.load( File.read '/tmp/plan_path' ) )
|
214
|
-
assert_equal( thimbl.data, JSON.load( File.read '/tmp/cache_path' ) )
|
184
|
+
|
185
|
+
def test_parse_time
|
186
|
+
assert_equal( Time.utc( 2010, 11, 29, 6, 3, 35 ), Thimbl::Utils.parse_time( '20101129060335' ) )
|
215
187
|
end
|
216
188
|
|
217
|
-
def
|
218
|
-
|
189
|
+
def test_not_adding_a_following_if_already_there
|
190
|
+
thimbl = Thimbl::Base.new
|
191
|
+
thimbl.follow 'wadus', 'wadus@thimbl.net'
|
192
|
+
thimbl.follow 'wadus', 'wadus@thimbl.net'
|
193
|
+
|
194
|
+
assert_equal( 1, thimbl.following.size )
|
219
195
|
end
|
220
196
|
end
|
data/test/thimbl_command_test.rb
CHANGED
@@ -14,26 +14,19 @@ class CommandTest < Test::Unit::TestCase
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_setup
|
17
|
-
|
18
|
-
Thimbl::Command.
|
19
|
-
Thimbl::
|
20
|
-
|
21
|
-
Thimbl::Command.setup( 'plan_path', 'cache_path', 'user', 'password' )
|
17
|
+
temp_file = Tempfile.new('cache.json')
|
18
|
+
Thimbl::Command.stubs( :cache_path ).returns( temp_file.path )
|
19
|
+
Thimbl::Command.setup( 'me@thimbl.net' )
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
assert_equal( 'plan_path', config_written['plan_path'] )
|
26
|
-
assert_equal( 'cache_path', config_written['cache_path'] )
|
27
|
-
assert_equal( 'user', config_written['user'] )
|
28
|
-
assert_equal( 'password', config_written['password'] )
|
21
|
+
cache_written = JSON.load temp_file.read
|
22
|
+
assert_equal 'me@thimbl.net', cache_written['me']
|
29
23
|
|
30
|
-
|
24
|
+
temp_file.unlink
|
31
25
|
end
|
32
26
|
|
33
27
|
def test_print
|
34
28
|
thimbl = Thimbl::Base.new
|
35
29
|
Thimbl::Command.expects( :load ).returns( thimbl )
|
36
|
-
thimbl.expects( :load_data )
|
37
30
|
thimbl.expects( :print )
|
38
31
|
|
39
32
|
Thimbl::Command.print
|
@@ -42,7 +35,6 @@ class CommandTest < Test::Unit::TestCase
|
|
42
35
|
def test_fetch
|
43
36
|
thimbl = Thimbl::Base.new
|
44
37
|
Thimbl::Command.expects( :load ).returns( thimbl )
|
45
|
-
thimbl.expects( :load_data )
|
46
38
|
thimbl.expects( :fetch )
|
47
39
|
|
48
40
|
Thimbl::Command.fetch
|
@@ -57,7 +49,6 @@ class CommandTest < Test::Unit::TestCase
|
|
57
49
|
def test_post
|
58
50
|
thimbl = Thimbl::Base.new
|
59
51
|
Thimbl::Command.expects( :load ).returns( thimbl )
|
60
|
-
thimbl.expects( :load_data )
|
61
52
|
thimbl.expects( :post ).with( 'wadus' )
|
62
53
|
|
63
54
|
Thimbl::Command.post 'wadus'
|
@@ -66,10 +57,9 @@ class CommandTest < Test::Unit::TestCase
|
|
66
57
|
def test_push
|
67
58
|
thimbl = Thimbl::Base.new
|
68
59
|
Thimbl::Command.expects( :load ).returns( thimbl )
|
69
|
-
thimbl.expects( :
|
70
|
-
thimbl.expects( :push )
|
60
|
+
thimbl.expects( :push ).with( 'pass' )
|
71
61
|
|
72
|
-
Thimbl::Command.push
|
62
|
+
Thimbl::Command.push 'pass'
|
73
63
|
end
|
74
64
|
|
75
65
|
def test_follow_should_raise_error_if_wrong_parameters
|
@@ -81,14 +71,13 @@ class CommandTest < Test::Unit::TestCase
|
|
81
71
|
def test_follow
|
82
72
|
thimbl = Thimbl::Base.new
|
83
73
|
Thimbl::Command.expects( :load ).returns( thimbl )
|
84
|
-
thimbl.expects( :load_data )
|
85
74
|
thimbl.expects( :follow ).with( 'wadus', 'wadus@domain.com' )
|
86
75
|
|
87
76
|
Thimbl::Command.follow 'wadus', 'wadus@domain.com'
|
88
77
|
end
|
89
78
|
|
90
79
|
def test_load_should_raise_error_if_not_config_file
|
91
|
-
Thimbl::Command.stubs( :
|
80
|
+
Thimbl::Command.stubs( :cache_path ).returns( '/tmp/not_exists_file' )
|
92
81
|
|
93
82
|
assert_raise( ArgumentError ) do
|
94
83
|
Thimbl::Command.load
|
@@ -96,11 +85,16 @@ class CommandTest < Test::Unit::TestCase
|
|
96
85
|
end
|
97
86
|
|
98
87
|
def test_load
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
88
|
+
temp_file = Tempfile.new 'cache.json'
|
89
|
+
temp_file.write "{ \"a\" : 1 }"
|
90
|
+
temp_file.close
|
91
|
+
|
92
|
+
Thimbl::Command.stubs( :cache_path ).returns( temp_file.path )
|
103
93
|
|
104
|
-
Thimbl::Command.load
|
94
|
+
thimbl = Thimbl::Command.load
|
95
|
+
|
96
|
+
assert_equal 1, thimbl.data['a']
|
97
|
+
|
98
|
+
temp_file.unlink
|
105
99
|
end
|
106
100
|
end
|
data/thimbl.gemspec
CHANGED
@@ -2,24 +2,24 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{thimbl}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.1.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Fernando Guillen"]
|
9
|
-
s.date = %q{2011-02-
|
10
|
-
s.default_executable = %q{
|
9
|
+
s.date = %q{2011-02-13}
|
10
|
+
s.default_executable = %q{thimblr}
|
11
11
|
s.description = %q{Small client for the distributed microbloging protocol: [thimbl](http://www.thimbl.net/)}
|
12
12
|
s.email = %q{fguillen.mail@gmail.com}
|
13
|
-
s.executables = ["
|
14
|
-
s.extra_rdoc_files = ["README.md", "bin/
|
15
|
-
s.files = ["Gemfile", "Gemfile.lock", "Manifest", "README.md", "Rakefile", "bin/
|
13
|
+
s.executables = ["thimblr"]
|
14
|
+
s.extra_rdoc_files = ["README.md", "bin/thimblr", "lib/thimbl.rb", "lib/thimbl/base.rb", "lib/thimbl/command.rb", "lib/thimbl/finger.rb", "lib/thimbl/utils.rb"]
|
15
|
+
s.files = ["Gemfile", "Gemfile.lock", "Manifest", "README.md", "Rakefile", "bin/thimblr", "lib/thimbl.rb", "lib/thimbl/base.rb", "lib/thimbl/command.rb", "lib/thimbl/finger.rb", "lib/thimbl/utils.rb", "test/fixtures/cache.json", "test/fixtures/finger_dk_telekommunisten_org.txt", "test/fixtures/finger_dk_telekommunisten_org_two_break_lines.txt", "test/test_helper.rb", "test/thimbl_base_test.rb", "test/thimbl_command_test.rb", "thimbl.gemspec", "test/thimbl_utils_test.rb"]
|
16
16
|
s.homepage = %q{http://github.com/fguillen/ThimblClient}
|
17
17
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Thimbl", "--main", "README.md"]
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
s.rubyforge_project = %q{thimbl}
|
20
20
|
s.rubygems_version = %q{1.3.7}
|
21
21
|
s.summary = %q{Small client for the distributed microbloging protocol: [thimbl](http://www.thimbl.net/)}
|
22
|
-
s.test_files = ["test/test_helper.rb", "test/thimbl_base_test.rb", "test/thimbl_command_test.rb"]
|
22
|
+
s.test_files = ["test/test_helper.rb", "test/thimbl_base_test.rb", "test/thimbl_command_test.rb", "test/thimbl_utils_test.rb"]
|
23
23
|
|
24
24
|
if s.respond_to? :specification_version then
|
25
25
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Fernando Guillen
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-13 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -91,27 +91,29 @@ dependencies:
|
|
91
91
|
description: "Small client for the distributed microbloging protocol: [thimbl](http://www.thimbl.net/)"
|
92
92
|
email: fguillen.mail@gmail.com
|
93
93
|
executables:
|
94
|
-
-
|
94
|
+
- thimblr
|
95
95
|
extensions: []
|
96
96
|
|
97
97
|
extra_rdoc_files:
|
98
98
|
- README.md
|
99
|
-
- bin/
|
99
|
+
- bin/thimblr
|
100
100
|
- lib/thimbl.rb
|
101
101
|
- lib/thimbl/base.rb
|
102
102
|
- lib/thimbl/command.rb
|
103
103
|
- lib/thimbl/finger.rb
|
104
|
+
- lib/thimbl/utils.rb
|
104
105
|
files:
|
105
106
|
- Gemfile
|
106
107
|
- Gemfile.lock
|
107
108
|
- Manifest
|
108
109
|
- README.md
|
109
110
|
- Rakefile
|
110
|
-
- bin/
|
111
|
+
- bin/thimblr
|
111
112
|
- lib/thimbl.rb
|
112
113
|
- lib/thimbl/base.rb
|
113
114
|
- lib/thimbl/command.rb
|
114
115
|
- lib/thimbl/finger.rb
|
116
|
+
- lib/thimbl/utils.rb
|
115
117
|
- test/fixtures/cache.json
|
116
118
|
- test/fixtures/finger_dk_telekommunisten_org.txt
|
117
119
|
- test/fixtures/finger_dk_telekommunisten_org_two_break_lines.txt
|
@@ -119,6 +121,7 @@ files:
|
|
119
121
|
- test/thimbl_base_test.rb
|
120
122
|
- test/thimbl_command_test.rb
|
121
123
|
- thimbl.gemspec
|
124
|
+
- test/thimbl_utils_test.rb
|
122
125
|
has_rdoc: true
|
123
126
|
homepage: http://github.com/fguillen/ThimblClient
|
124
127
|
licenses: []
|
@@ -163,3 +166,4 @@ test_files:
|
|
163
166
|
- test/test_helper.rb
|
164
167
|
- test/thimbl_base_test.rb
|
165
168
|
- test/thimbl_command_test.rb
|
169
|
+
- test/thimbl_utils_test.rb
|