friendfeed 0.1.13 → 0.1.14

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.13
1
+ 0.1.14
data/bin/tw2ff CHANGED
@@ -106,6 +106,12 @@ class FriendFeed::Client
106
106
  }
107
107
  t.unlink
108
108
  end
109
+
110
+ def follow_twitter_user(twitter_name, display_name, picture_url = nil)
111
+ id = create_imaginary_friend(display_name)
112
+ add_twitter(id, twitter_name, 'includeatreplies' => 'on')
113
+ change_picture_to_url(id, picture_url) if picture_url
114
+ end
109
115
  end
110
116
 
111
117
  def friendfeed_client
@@ -131,10 +137,6 @@ class Twitter::Base
131
137
  }
132
138
  list
133
139
  end
134
-
135
- def get_profile(name)
136
- friends(:screen_name => name).first
137
- end
138
140
  end
139
141
 
140
142
  def twitter_client
@@ -175,13 +177,67 @@ EOF
175
177
  system ENV['VISUAL'] || ENV['EDITOR'] || 'vi', ConfigFile()
176
178
  end
177
179
  end
180
+
181
+ mode 'follow' do
182
+ description 'Import a Twitter user to FriendFeed as an "imaginary friend"'
183
+
184
+ option('name-format') {
185
+ description 'A printf format to generate an imaginary friend\'s name from a Twitter name'
186
+
187
+ argument_required
188
+ default '(%s)'
189
+ }
190
+
191
+ argument('names') {
192
+ description 'List of Twitter user names to follow'
193
+ arity -1
194
+ }
195
+
196
+ def run
197
+ name_format = params['name-format'].value
198
+
199
+ names = params['names'].values
200
+
201
+ exit if names.empty?
202
+
203
+ names.each { |name|
204
+ twuser =
205
+ begin
206
+ twitter_client().user(name)
207
+ rescue Twitter::NotFound
208
+ putinfo 'Twitter user not found: %s', name
209
+ next
210
+ rescue => e
211
+ putinfo 'Twitter user not accessible: %s: %s', name, e
212
+ next
213
+ end
214
+
215
+ if !twuser.status
216
+ putinfo 'Twitter user may not be followable: %s', name
217
+ end
218
+
219
+ putinfo 'Creating an imaginary friend for %s', name
220
+ friendfeed_client().follow_twitter_user(name, name_format % name,
221
+ twuser.profile_image_url)
222
+ }
223
+ end
224
+ end
178
225
 
179
226
  mode 'friends' do
180
227
  description 'Import Twitter-only friends to FriendFeed as "imaginary friends"'
181
228
 
229
+ option('name-format') {
230
+ description 'A printf format to generate an imaginary friend\'s name from a Twitter name'
231
+
232
+ argument_required
233
+ default '(%s)'
234
+ }
235
+
182
236
  def run
183
237
  require 'set'
184
238
 
239
+ name_format = params['name-format'].value
240
+
185
241
  ffcli = friendfeed_client()
186
242
 
187
243
  subscribed_real = Set[]
@@ -258,12 +314,8 @@ EOF
258
314
 
259
315
  to_subscribe.each { |name|
260
316
  putinfo 'Creating an imaginary friend for %s', name
261
- id = ffcli.create_imaginary_friend('(%s)' % name)
262
- ffcli.add_twitter(id, name)
263
- if url = picture_urls[name]
264
- putinfo 'Setting the picture of %s', name
265
- ffcli.change_picture_to_url(id, url)
266
- end
317
+ friendfeed_client().follow_twitter_user(name, name_format % name,
318
+ picture_urls[name])
267
319
  }
268
320
 
269
321
  printf <<-EOS, 'http://friendfeed.com/friends/twitter?username=' + URI.escape(twitter_me)
@@ -299,7 +351,7 @@ to see if someone is joining FriendFeed:
299
351
  if picture_urls.key?(name)
300
352
  url = picture_urls[name]
301
353
  else
302
- friend = twcli.get_profile(name) rescue
354
+ friend = twcli.user(name) rescue
303
355
  begin
304
356
  putinfo "Failed to get profile of %s", name
305
357
  next
@@ -315,6 +367,32 @@ to see if someone is joining FriendFeed:
315
367
  end
316
368
  end
317
369
 
370
+ mode 'includeatreplies' do
371
+ description 'Fix imaginary friends to include @replies'
372
+
373
+ def run
374
+ ffcli = friendfeed_client()
375
+
376
+ putinfo "Checking imaginary friends in FriendFeed..."
377
+ ffcli.get_imaginary_friends.each { |profile|
378
+ id = profile['id']
379
+ ffcli.get_services(id).each { |service|
380
+ url = service['profileUrl'] or next
381
+
382
+ if (name = TWITTER_URI.route_to(url).to_s).match(/\A[A-Za-z0-9_]+\z/)
383
+ name.downcase!
384
+ putinfo 'Trying to include @replies by %s', name
385
+ begin
386
+ ffcli.edit_service(id, service['serviceid'], 'includeatreplies' => 'on')
387
+ rescue => e
388
+ putinfo 'Failed, maybe due to the Twitter account removal or a network problem.'
389
+ end
390
+ end
391
+ }
392
+ }
393
+ end
394
+ end
395
+
318
396
  mode 'favorites' do
319
397
  description 'Synchronize Twitter favorites and FriendFeed likes as far as possible'
320
398
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{friendfeed}
8
- s.version = "0.1.13"
8
+ s.version = "0.1.14"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Akinori MUSHA"]
12
- s.date = %q{2010-02-18}
12
+ s.date = %q{2010-06-01}
13
13
  s.default_executable = %q{tw2ff}
14
14
  s.description = %q{This is a Ruby library to provide access to FriendFeed API's.
15
15
 
@@ -42,7 +42,7 @@ manipulating friends, groups and services for your personal purposes.
42
42
  s.rdoc_options = ["--charset=UTF-8"]
43
43
  s.require_paths = ["lib"]
44
44
  s.rubyforge_project = %q{friendfeed}
45
- s.rubygems_version = %q{1.3.5}
45
+ s.rubygems_version = %q{1.3.7}
46
46
  s.summary = %q{A Ruby library to provide access to FriendFeed API's}
47
47
  s.test_files = [
48
48
  "test/friendfeed_test.rb",
@@ -53,7 +53,7 @@ manipulating friends, groups and services for your personal purposes.
53
53
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
54
54
  s.specification_version = 3
55
55
 
56
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
56
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
57
57
  s.add_runtime_dependency(%q<json>, [">= 0"])
58
58
  s.add_runtime_dependency(%q<mechanize>, [">= 1.0.0"])
59
59
  else
@@ -145,11 +145,11 @@ module FriendFeed
145
145
  hash = { 'stream' => id }
146
146
  form.xpath(".//input").each { |input|
147
147
  case input['type'].downcase
148
- when 'text'
148
+ when 'text', 'hidden'
149
149
  hash[input['name']] = input['value']
150
150
  when 'radio', 'checkbox'
151
151
  if input['checked']
152
- value = input['value']
152
+ value = input['value'] || 'on'
153
153
  if value && !value.empty?
154
154
  hash[input['name']] = value
155
155
  end
@@ -166,10 +166,36 @@ module FriendFeed
166
166
  # Supported fields are 'nickname', 'name', 'description', 'access'
167
167
  # ('private', 'semipublic' or 'public'), and 'anyoneinvite' (none
168
168
  # or '1'). [unofficial]
169
- def edit_group(id, hash)
170
- param_hash = get_group(id)
171
- param_hash.update(hash)
172
- post(EDIT_GROUP_URI, param_hash)
169
+ def edit_group(id, options)
170
+ params = get_group(id)
171
+ params.update(options)
172
+ post(EDIT_GROUP_URI, params)
173
+ end
174
+
175
+ # Gets information of a service specified by a unique
176
+ # ID. [unofficial]
177
+ def get_service(id, serviceid)
178
+ parser = post(ROOT_URI + '/a/servicedialog',
179
+ 'serviceid' => serviceid, 'stream' => id)['html_parser']
180
+ form = parser.at("//form[1]")
181
+ hash = { 'stream' => id }
182
+ form.xpath(".//input").each { |input|
183
+ case input['type'].downcase
184
+ when 'text', 'hidden'
185
+ hash[input['name']] = input['value']
186
+ when 'radio', 'checkbox'
187
+ if input['checked']
188
+ value = input['value'] || 'on'
189
+ if value && !value.empty?
190
+ hash[input['name']] = value
191
+ end
192
+ end
193
+ end
194
+ }
195
+ form.xpath(".//textarea").each { |input|
196
+ hash[input['name']] = input.text
197
+ }
198
+ hash
173
199
  end
174
200
 
175
201
  # Adds a feed to the authenticated user, a group or an imaginary
@@ -187,12 +213,8 @@ module FriendFeed
187
213
 
188
214
  # Edits a service of the authenticated user, a group or an
189
215
  # imaginary friend specified by a unique ID. [unofficial]
190
- def edit_service(id, serviceid, service, options = nil)
191
- params = {
192
- 'stream' => id,
193
- 'service' => service,
194
- 'serviceid' => serviceid,
195
- }
216
+ def edit_service(id, serviceid, options = nil)
217
+ params = get_service(id, serviceid)
196
218
  params.update(options) if options
197
219
  post(ROOT_URI + '/a/configureservice', params)
198
220
  end
@@ -244,65 +266,10 @@ module FriendFeed
244
266
 
245
267
  # Adds a Twitter service to the authenticated user, a group or an
246
268
  # imaginary friend specified by a unique ID. [unofficial]
247
- def add_twitter(id, twitter_name)
248
- add_service(id, 'twitter', 'username' => twitter_name)
249
- end
250
-
251
- # Edits a feed of the authenticated user, a group or an imaginary
252
- # friend specified by a unique ID. Specify 'isstatus' => 'on' to
253
- # display entries as messages (no link), and 'importcomment' =>
254
- # 'on' to include entry description as a comment. [unofficial]
255
- def edit_feed(id, serviceid, url, options = nil)
256
- params = { 'url' => url }
257
- params.update(options) if options
258
- edit_service(id, 'feed', options)
259
- end
260
-
261
- # Adds a blog feed to the authenticated user, a group or an
262
- # imaginary friend specified by a unique ID. Specify 'multiauth'
263
- # => 'on' when the blog has multiple authors, and 'author' =>
264
- # '(name)' to limit entries to those written by a specific
265
- # author. [unofficial]
266
- def edit_blog(id, url, options = nil)
267
- params = { 'url' => url }
268
- params.update(options) if options
269
- edit_service(id, 'blog', options)
270
- end
271
-
272
- # Edits a Twitter service of the authenticated user, a group or an
273
- # imaginary friend specified by a unique ID. Specify 'isstatus'
274
- # => 'on' to display entries as messages (no link), and
275
- # 'importcomment' => 'on' to include entry description as a
276
- # comment. [unofficial]
277
- def edit_twitter(id, serviceid, twitter_name)
278
- edit_service(id, serviceid, 'twitter', 'username' => twitter_name)
279
- end
280
-
281
- # Removes a feed from the authenticated user, a group or an
282
- # imaginary friend specified by a unique ID. Specify
283
- # 'deleteentries' => 'on' to delete entries also. [unofficial]
284
- def remove_feed(id, serviceid, url, options = nil)
285
- params = { 'url' => url }
286
- params.update(options) if options
287
- remove_service(id, serviceid, 'feed', options = nil)
288
- end
289
-
290
- # Removes a blog feed from the authenticated user, a group or an
291
- # imaginary friend specified by a unique ID. Specify
292
- # 'deleteentries' => 'on' to delete entries also. [unofficial]
293
- def remove_blog(id, serviceid, url, options = nil)
294
- params = { 'url' => url }
295
- params.update(options) if options
296
- remove_service(id, serviceid, 'blog', options = nil)
297
- end
298
-
299
- # Removes a Twitter service from the authenticated user, a group
300
- # or an imaginary friend specified by a unique ID. Specify
301
- # 'deleteentries' => 'on' to delete entries also. [unofficial]
302
- def remove_twitter(id, serviceid, twitter_name, options = nil)
269
+ def add_twitter(id, twitter_name, options = nil)
303
270
  params = { 'username' => twitter_name }
304
271
  params.update(options) if options
305
- remove_service(id, serviceid, 'twitter', options = nil)
272
+ add_service(id, 'twitter', params)
306
273
  end
307
274
 
308
275
  # Changes the picture of the authenticated user, a group or an
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friendfeed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ hash: 7
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 14
10
+ version: 0.1.14
5
11
  platform: ruby
6
12
  authors:
7
13
  - Akinori MUSHA
@@ -9,29 +15,39 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-02-18 00:00:00 +09:00
18
+ date: 2010-06-01 00:00:00 +09:00
13
19
  default_executable: tw2ff
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: json
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
23
32
  version: "0"
24
- version:
33
+ type: :runtime
34
+ version_requirements: *id001
25
35
  - !ruby/object:Gem::Dependency
26
36
  name: mechanize
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
30
40
  requirements:
31
41
  - - ">="
32
42
  - !ruby/object:Gem::Version
43
+ hash: 23
44
+ segments:
45
+ - 1
46
+ - 0
47
+ - 0
33
48
  version: 1.0.0
34
- version:
49
+ type: :runtime
50
+ version_requirements: *id002
35
51
  description: |
36
52
  This is a Ruby library to provide access to FriendFeed API's.
37
53
 
@@ -71,21 +87,27 @@ rdoc_options:
71
87
  require_paths:
72
88
  - lib
73
89
  required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
74
91
  requirements:
75
92
  - - ">="
76
93
  - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
77
97
  version: "0"
78
- version:
79
98
  required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
80
100
  requirements:
81
101
  - - ">="
82
102
  - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
83
106
  version: "0"
84
- version:
85
107
  requirements: []
86
108
 
87
109
  rubyforge_project: friendfeed
88
- rubygems_version: 1.3.5
110
+ rubygems_version: 1.3.7
89
111
  signing_key:
90
112
  specification_version: 3
91
113
  summary: A Ruby library to provide access to FriendFeed API's