ardekantur-wondercroc 0.0.4 → 0.0.5
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/README.rdoc +31 -1
- data/Rakefile +8 -3
- data/lib/wondercroc.rb +6 -1
- data/lib/wondercroc/client.rb +43 -23
- data/lib/wondercroc/folder.rb +43 -12
- data/lib/wondercroc/location.rb +0 -11
- metadata +3 -2
data/README.rdoc
CHANGED
@@ -1,3 +1,33 @@
|
|
1
1
|
= wondercroc
|
2
2
|
|
3
|
-
A gem that provides
|
3
|
+
A gem that provides functionality for interfacing with the NewsGator online feed reading service.
|
4
|
+
|
5
|
+
= simple to use
|
6
|
+
|
7
|
+
c = WonderCroc::Client.new :user => 'newsgator_user', :password => 'newsgator_pass', :location => 'newsgator_location'
|
8
|
+
|
9
|
+
Or, if you have a YAML file like this:
|
10
|
+
|
11
|
+
user: newsgator_user
|
12
|
+
password: newsgator_password
|
13
|
+
location: newsgator_location
|
14
|
+
|
15
|
+
You can pass it in like this:
|
16
|
+
|
17
|
+
c = WonderCroc::Client.new :file => '/path/to/config.yml'
|
18
|
+
|
19
|
+
If you don't specify a location anywhere, it will default to the name of the library, a hyphen, and the name of your machine (in all caps), like thus:
|
20
|
+
|
21
|
+
wondercroc-MY_IMAC
|
22
|
+
|
23
|
+
= folders
|
24
|
+
|
25
|
+
Folders are a tree of the folders you have at the location you specified previously.
|
26
|
+
|
27
|
+
c.get_folders
|
28
|
+
|
29
|
+
= subscriptions
|
30
|
+
|
31
|
+
c.get_subscriptions_from_location
|
32
|
+
|
33
|
+
That's kind of where I am right now, poke around in irb to get a better feel for what you can do from there.
|
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ require 'spec/rake/verify_rcov'
|
|
8
8
|
|
9
9
|
|
10
10
|
GEM = "wondercroc"
|
11
|
-
GEM_VERSION = "0.0.
|
11
|
+
GEM_VERSION = "0.0.5"
|
12
12
|
AUTHOR = "Ardekantur"
|
13
13
|
EMAIL = "greystone@ardekantur.com"
|
14
14
|
HOMEPAGE = "http://github.com/ardekantur/wondercroc"
|
@@ -59,10 +59,15 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
59
59
|
rdoc.rdoc_dir = 'doc' # rdoc output folder
|
60
60
|
end
|
61
61
|
|
62
|
-
desc "
|
62
|
+
desc "run specs"
|
63
|
+
Spec::Rake::SpecTask.new("spec") do |t|
|
64
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "run rspec + rcov"
|
63
68
|
Spec::Rake::SpecTask.new("spec:rcov") do |t|
|
64
69
|
t.spec_files = FileList['spec/**/*_spec.rb']
|
65
|
-
t.rcov_opts = ['--exclude', "spec/,rcov.rb,rspec.rb,spec*"]
|
70
|
+
t.rcov_opts = ['--exclude', "spec/,rcov.rb,rspec.rb,spec*,gems*"]
|
66
71
|
t.rcov = true
|
67
72
|
t.rcov_dir = 'doc/coverage'
|
68
73
|
end
|
data/lib/wondercroc.rb
CHANGED
@@ -1 +1,6 @@
|
|
1
|
-
|
1
|
+
|
2
|
+
# WonderCroc is a library for retrieving subscriptions from a NewsGator online RSS feed reading account.
|
3
|
+
# Please see the README for more information.
|
4
|
+
module WonderCroc; end;
|
5
|
+
|
6
|
+
%w{ config client folder location subscription }.each { |x| require "wondercroc/#{x}" }
|
data/lib/wondercroc/client.rb
CHANGED
@@ -2,20 +2,18 @@ require 'rubygems'
|
|
2
2
|
require 'rest_client'
|
3
3
|
require 'rexml/document'
|
4
4
|
require 'rss/2.0'
|
5
|
-
|
6
|
-
# NewsGator is a Ruby layer for interacting with the
|
7
|
-
# NewsGator API.
|
8
5
|
|
9
6
|
module WonderCroc
|
10
7
|
|
8
|
+
VERSION = [ 0, 0, 5 ].join '.'
|
9
|
+
|
11
10
|
class Client
|
12
11
|
|
13
|
-
VERSION = [ 0, 0, 4 ].join '.'
|
14
12
|
SERVICE = "http://services.newsgator.com/ngws/svc"
|
15
13
|
|
16
14
|
BULLETIN_TOKEN = {
|
17
15
|
"X-NGAPITOKEN" => "A8BBE03745F2439287D9425AB4BFFC30",
|
18
|
-
"User-Agent" => "wondercroc/#{VERSION}",
|
16
|
+
"User-Agent" => "wondercroc/#{WonderCroc::VERSION}",
|
19
17
|
"Accept-Encoding" => "compress,gzip"
|
20
18
|
}
|
21
19
|
|
@@ -23,13 +21,22 @@ module WonderCroc
|
|
23
21
|
attr_accessor :folders
|
24
22
|
|
25
23
|
# Initializes an instance of a NewsGator Client.
|
26
|
-
# +
|
27
|
-
#
|
28
|
-
#
|
29
|
-
|
30
|
-
|
24
|
+
# +config_options+ is a hash consisting of either all the informatio
|
25
|
+
# required to start a NewsGator connection (:user, :password, and :location),
|
26
|
+
# or the name of a file that has all those values in a YAML file (:file).
|
27
|
+
#
|
28
|
+
# We then set the location from the configuration hash passed through
|
29
|
+
# at the instantsiation of the Client object. If a +:location+
|
30
|
+
# key was not passed with that has, the location name is generated
|
31
|
+
# like so: 'newsgator_account_name-MACHINE_HOSTNAME'.
|
32
|
+
def initialize config_options
|
33
|
+
@config = WonderCroc::Configuration.new config_options
|
31
34
|
@folder_unread_counts = {}
|
32
|
-
|
35
|
+
|
36
|
+
get_locations
|
37
|
+
@location = @locations.find { |l| l[:title] == @config.location }
|
38
|
+
raise "no location found for name #{@config.location}" unless @location
|
39
|
+
|
33
40
|
end
|
34
41
|
|
35
42
|
def get_feed id, unread = true
|
@@ -37,19 +44,13 @@ module WonderCroc
|
|
37
44
|
send_request :get
|
38
45
|
end
|
39
46
|
|
40
|
-
def get_random_feed
|
41
|
-
raise "no feeds" unless @subscriptions
|
42
|
-
get_feed @subscriptions[(rand * @subscriptions.length).floor].id, false
|
43
|
-
end
|
44
|
-
|
45
47
|
def parse_stories
|
46
48
|
p = RSS::Parser.new @response
|
47
49
|
p.do_validate = false
|
48
50
|
p.parse
|
49
51
|
end
|
50
52
|
|
51
|
-
def get_unread_counts
|
52
|
-
ui.update_status 'Getting subscription counts...' if ui
|
53
|
+
def get_unread_counts
|
53
54
|
new_connection_to "/Subscription.aspx/#{@location[:id]}/subscriptionCounts"
|
54
55
|
send_request :get
|
55
56
|
doc = REXML::Document.new @response
|
@@ -57,26 +58,46 @@ module WonderCroc
|
|
57
58
|
@folder_unread_counts[e.attributes['ng:folderId']] = @folder_unread_counts.fetch(e.attributes['ng:folderId'], 0) + e.attributes['ng:unreadCount'].to_i
|
58
59
|
end
|
59
60
|
@folders.flatten.each { |f| f.unread_count = @folder_unread_counts.fetch(f.id, 0) }
|
60
|
-
ui.update_status ''
|
61
61
|
end
|
62
62
|
|
63
63
|
private
|
64
64
|
|
65
65
|
def new_connection_to url
|
66
|
-
@request = RestClient::Resource.new(SERVICE + url, @config
|
66
|
+
@request = RestClient::Resource.new(SERVICE + url, @config.user, @config.password)
|
67
67
|
end
|
68
68
|
|
69
69
|
def send_request type, headers = {}
|
70
70
|
raise ArgumentError, "invalid send request type #{type}" unless [ :get, :delete ].include? type
|
71
|
-
|
71
|
+
|
72
|
+
begin
|
73
|
+
@response = @request.send type, BULLETIN_TOKEN.merge(headers)
|
74
|
+
rescue RestClient::Unauthorized
|
75
|
+
raise IncorrectLoginError, "#{@config.user} was not able to login"
|
76
|
+
end
|
77
|
+
|
78
|
+
log_request_and_response
|
72
79
|
end
|
73
80
|
|
74
81
|
def send_data type, payload, headers = {}
|
75
82
|
raise ArgumentError, "invalid send data request type #{type}" unless [ :put, :post ].include? type
|
76
83
|
@response = @request.send type, payload, BULLETIN_TOKEN.merge(headers)
|
84
|
+
|
85
|
+
log_request_and_response
|
86
|
+
end
|
87
|
+
|
88
|
+
def log_request_and_response
|
89
|
+
File.open(File.join(ENV['HOME'], 'wondercroc_logs'), 'a') do |f|
|
90
|
+
f.write "REQUEST TO: #{@request.inspect}\n"
|
91
|
+
f.write "RESPONSE: #{@response}"
|
92
|
+
f.write "\n\n\n"
|
93
|
+
end
|
77
94
|
end
|
78
95
|
|
79
96
|
end
|
97
|
+
|
98
|
+
class IncorrectLoginError < RuntimeError
|
99
|
+
end
|
100
|
+
|
80
101
|
end
|
81
102
|
|
82
103
|
class RSS::Rss::Channel::Item
|
@@ -86,8 +107,7 @@ class RSS::Rss::Channel::Item
|
|
86
107
|
["postId", :integer ],
|
87
108
|
["avgRating", :float ],
|
88
109
|
["clipped", :boolean ],
|
89
|
-
["token", :text ]
|
90
|
-
["folderId", :text ]
|
110
|
+
["token", :text ]
|
91
111
|
].each do |elem, type|
|
92
112
|
install_text_element "ng:#{elem}", "http://newsgator.com/schema/extensions", '?', "#{elem}", type, "ng:#{elem}"
|
93
113
|
RSS::BaseListener.install_get_text_element "http://newsgator.com/schema/extensions", "#{elem}", "#{elem}="
|
data/lib/wondercroc/folder.rb
CHANGED
@@ -1,15 +1,28 @@
|
|
1
|
-
# A folder is a folder that resides in a NewsGator location.
|
2
|
-
# It can contain subscriptions and other folders.
|
3
1
|
|
4
2
|
module WonderCroc
|
3
|
+
|
4
|
+
class Client
|
5
|
+
|
6
|
+
def find_folder_by_id folder_id
|
7
|
+
@subfolders.each { |subfolder| return subfolder if subfolder and subfolder.find_by_id folder_id}
|
8
|
+
return nil
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
# A folder is a folder that resides in a NewsGator location.
|
14
|
+
# It can contain subscriptions and other folders.
|
5
15
|
class Folder
|
6
16
|
|
7
|
-
attr_accessor :
|
17
|
+
attr_accessor :folder_id, :name
|
18
|
+
attr_reader :unread_count
|
8
19
|
|
9
20
|
def initialize name, id
|
21
|
+
raise ArgumentException unless name
|
10
22
|
@name = name
|
11
|
-
@
|
23
|
+
@folder_id = id
|
12
24
|
@unread_count = 0
|
25
|
+
@subfolders = []
|
13
26
|
end
|
14
27
|
|
15
28
|
def to_str
|
@@ -17,6 +30,23 @@ class Folder
|
|
17
30
|
return "#{@name} (#{@unread_count})"
|
18
31
|
end
|
19
32
|
|
33
|
+
def subfolders
|
34
|
+
return @subfolders
|
35
|
+
end
|
36
|
+
|
37
|
+
def << subfolder
|
38
|
+
@subfolders << subfolder
|
39
|
+
end
|
40
|
+
|
41
|
+
def merge array
|
42
|
+
@subfolders += array if array
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_by_id id
|
46
|
+
return self if @folder_id == id
|
47
|
+
@subfolders.each { |subfolder| return subfolder if subfolder.find_by_id id}
|
48
|
+
end
|
49
|
+
|
20
50
|
end
|
21
51
|
|
22
52
|
class Client
|
@@ -25,28 +55,29 @@ class Client
|
|
25
55
|
def get_folders
|
26
56
|
new_connection_to "/Folder.aspx"
|
27
57
|
send_request :get
|
28
|
-
@folders = folders_from_xml(@response)
|
58
|
+
@folders = folders_from_xml(@response).subfolders
|
29
59
|
end
|
30
60
|
|
31
61
|
private
|
32
62
|
|
33
63
|
def folders_from_xml xml
|
34
|
-
|
64
|
+
root_folder = Folder.new 'Root', -1
|
35
65
|
doc = REXML::Document.new xml
|
36
66
|
doc.elements.each('opml/body/outline') do |e|
|
37
|
-
dir =
|
38
|
-
dir
|
39
|
-
|
67
|
+
dir = Folder.new e.attributes['title'], e.attributes['ng:id']
|
68
|
+
dir.merge subfolders(e)
|
69
|
+
root_folder << dir
|
40
70
|
end
|
41
|
-
return
|
71
|
+
return root_folder
|
42
72
|
end
|
43
73
|
|
44
74
|
def subfolders element
|
45
75
|
return nil if element.elements.size == 0
|
46
76
|
folders = []
|
47
77
|
element.each do |e|
|
48
|
-
|
49
|
-
|
78
|
+
folder = Folder.new(e.attributes['title'], e.attributes['ng:id'])
|
79
|
+
folder.merge subfolders(e)
|
80
|
+
folders << folder
|
50
81
|
end
|
51
82
|
|
52
83
|
return folders.compact
|
data/lib/wondercroc/location.rb
CHANGED
@@ -7,17 +7,6 @@ class Client
|
|
7
7
|
@locations = []
|
8
8
|
end
|
9
9
|
|
10
|
-
# Sets the location from the configuration hash passed through
|
11
|
-
# at the instantsiation of the Client object. If a +:location+
|
12
|
-
# key was not passed with that has, the location name is generated
|
13
|
-
# like so: 'newsgator_account_name-MACHINE_HOSTNAME'.
|
14
|
-
def set_location_from_config
|
15
|
-
get_locations
|
16
|
-
@config[:location] ||= "#{@config[:user]}-#{`hostname`.strip.upcase}"
|
17
|
-
@location = @locations.find { |l| l[:title] == @config[:location] }
|
18
|
-
raise "no location found for name #{@config.location}" unless @location
|
19
|
-
end
|
20
|
-
|
21
10
|
# Retrieves a list of all the locations that the logged in user
|
22
11
|
# has available.
|
23
12
|
def get_locations
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ardekantur-wondercroc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ardekantur
|
@@ -9,7 +9,7 @@ autorequire: wondercroc
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-07-
|
12
|
+
date: 2008-07-06 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -30,6 +30,7 @@ files:
|
|
30
30
|
- TODO
|
31
31
|
- lib/wondercroc
|
32
32
|
- lib/wondercroc/client.rb
|
33
|
+
- lib/wondercroc/config.rb
|
33
34
|
- lib/wondercroc/folder.rb
|
34
35
|
- lib/wondercroc/location.rb
|
35
36
|
- lib/wondercroc/subscription.rb
|