duwanis-rubyku 0.0.3 → 0.1.0
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 +30 -24
- data/lib/rubyku/credentials.rb +39 -28
- data/lib/rubyku/errors.rb +3 -0
- data/lib/rubyku/message.rb +73 -0
- data/lib/rubyku/request.rb +14 -3
- data/lib/rubyku/settings.rb +15 -0
- data/lib/rubyku/user.rb +51 -29
- data/lib/rubyku/version.rb +2 -2
- data/lib/rubyku.rb +5 -0
- metadata +16 -16
- data/Rakefile +0 -7
- data/test/test_helper.rb +0 -2
- data/test/test_rubyku.rb +0 -11
data/README
CHANGED
@@ -8,33 +8,39 @@ Rubyku is a ruby library for accessing data via the Jaiku API.
|
|
8
8
|
|
9
9
|
== FEATURES/PROBLEMS:
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
No synopsis yet, but I'm working on it
|
11
|
+
Rubyku 0.1.0: Bringing home the [user]bacon
|
12
|
+
|
13
|
+
Users are now fully functional (woo!). Messages still need some work
|
14
|
+
done to them, and then after that we still need to work on being able
|
15
|
+
to post. But you should be able to read anything you've ever wanted to
|
16
|
+
read from a user now.
|
17
|
+
|
18
|
+
== EXAMPLE:
|
19
|
+
|
20
|
+
Just to whet your appetite:
|
21
|
+
|
22
|
+
#provide log in details for the service
|
23
|
+
cred = Rubyku::Credentials.new
|
24
|
+
cred.username = 'duwanis'
|
25
|
+
cred.password = 'password' # or cred.api_key = 'apikeygoeshere' if you want to do it that way
|
26
|
+
Rubyku::Settings.jaiku_credentials = cred #so you don't have to keep passing cred around
|
27
|
+
user = Rubyku::User.fetch 'duwanis' #and now we're off to the races
|
28
|
+
user.updates # => a list of Rubyku::Messages representing my latest updates
|
29
|
+
user.stream # => a list of Rubyku::Messages representing my contacts' latest updates
|
30
|
+
|
31
|
+
etc. Have fun :)
|
34
32
|
|
35
33
|
== REQUIREMENTS:
|
36
34
|
|
37
|
-
|
35
|
+
Currently, the only other gem required for rubyku is json > 1.0.0.
|
36
|
+
I'm trying to keep it simple.
|
37
|
+
|
38
|
+
== TESTING:
|
39
|
+
|
40
|
+
Hah, notice how there isn't any automated testing?
|
41
|
+
I'd really like to have automated test suites for rubyku, but it's
|
42
|
+
not an easy thing to do since it's so tightly coupled with a web
|
43
|
+
service that requires authentication. Let me know if you have any ideas, though.
|
38
44
|
|
39
45
|
== INSTALL:
|
40
46
|
|
data/lib/rubyku/credentials.rb
CHANGED
@@ -1,4 +1,26 @@
|
|
1
1
|
module Rubyku
|
2
|
+
##
|
3
|
+
# This class represents the credentials necessary to log in
|
4
|
+
# to the Jaiku service in order to access non-public portions
|
5
|
+
# of the API.
|
6
|
+
# It has 3 fields:
|
7
|
+
# - +username+
|
8
|
+
# - +password+
|
9
|
+
# - +api_key+
|
10
|
+
# Only +username+ and +api_key+ are required to log in to Jaiku.
|
11
|
+
# Password is offered as a way to make things easier for the user:
|
12
|
+
# since API keys aren't easily memorable (and subject to change, in
|
13
|
+
# Jaiku's case), rubyku allows for setting the username and password
|
14
|
+
# alone. It will then fetch the api_key for the user.
|
15
|
+
# Example:
|
16
|
+
# cred = Rubyku::Credentials.new
|
17
|
+
# cred.username = 'duwanis'
|
18
|
+
# cred.password = 'notmyrealpassword'
|
19
|
+
# cred.api_key
|
20
|
+
# => 'apikey1234567890'
|
21
|
+
#
|
22
|
+
# For a single-user app, one instance of Rubyku::Credentials should
|
23
|
+
# be created and saved on the Rubyku::Settings class.
|
2
24
|
class Credentials
|
3
25
|
attr_accessor :username
|
4
26
|
attr_accessor :password
|
@@ -6,18 +28,12 @@ module Rubyku
|
|
6
28
|
|
7
29
|
##
|
8
30
|
# returns the Jaiku API key for these credentials.
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
31
|
+
# This is a lazy-load property. Since there is a method
|
32
|
+
# that can be used to retrieve the API key with the username
|
33
|
+
# and password, rubyku does not require you to specify that
|
34
|
+
# key if you would rather specify a username and password.
|
13
35
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# @raise <Rubyku::InvalidCredentialsError> indicates that the provided
|
17
|
-
# username and password are not valid for Jaiku.
|
18
|
-
#
|
19
|
-
# @raise <RubykuError> indicates that there was an error communicating
|
20
|
-
# to the Jaiku servers.
|
36
|
+
# returns: +String+ the API key for this user.
|
21
37
|
#
|
22
38
|
def api_key
|
23
39
|
log = Rubyku::Settings.logger
|
@@ -43,24 +59,19 @@ module Rubyku
|
|
43
59
|
|
44
60
|
##
|
45
61
|
# Given a username and password, retrieve that user's API key.
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
# @param username<String> the username to use for authentication.
|
55
|
-
#
|
56
|
-
# @param password<String> the password to use for authentication.
|
62
|
+
# this works by logging the user in, stripping cookie information
|
63
|
+
# off of the response, and then using that cookie information
|
64
|
+
# to hit http://api.jaiku.com/key . All credit for this approach
|
65
|
+
# to this python snippet on DZone: http://snippets.dzone.com/posts/show/5539
|
66
|
+
# For the record, I'm torn about leaving this in. On the one hand it assumes
|
67
|
+
# a lot about the internals of jaiku - on the other, it allows the user
|
68
|
+
# to be oblivious to the API key and any changes it may undergo.
|
57
69
|
#
|
58
|
-
#
|
59
|
-
# username and password are not valid for Jaiku.
|
70
|
+
# returns: +String+ the API key for the user, if found.
|
60
71
|
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
72
|
+
# raises:
|
73
|
+
# - Rubyku::InvalidCredentialsError - username/password were not valid.
|
74
|
+
# - Rubyku::Error - there was an error communicating with the Jaiku servers.
|
64
75
|
def fetch_api_key(username, password)
|
65
76
|
log = Rubyku::Settings.logger
|
66
77
|
|
@@ -80,7 +91,7 @@ module Rubyku
|
|
80
91
|
#If Jaiku returns anything other than a redirect (which is expected
|
81
92
|
# for a successful logon), then something's broke.
|
82
93
|
log.error "Jaiku returned something other than a 303. Something borked."
|
83
|
-
raise
|
94
|
+
raise Rubyku::Error, "Could not connect to http://www.jaiku.com/login to retrieve API key."
|
84
95
|
end
|
85
96
|
|
86
97
|
#retrieve the cookie contents from the successful login result
|
data/lib/rubyku/errors.rb
CHANGED
@@ -3,9 +3,12 @@ module Rubyku
|
|
3
3
|
class Error < RuntimeError
|
4
4
|
end
|
5
5
|
|
6
|
+
# Rubyku exception thrown when a specified user is not found.
|
6
7
|
class UserNotFoundError < Error
|
7
8
|
end
|
8
9
|
|
10
|
+
# Rubyku exception thrown when provided credentials are not
|
11
|
+
# correct.
|
9
12
|
class InvalidCredentialsError < Error
|
10
13
|
end
|
11
14
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Rubyku
|
2
|
+
|
3
|
+
##
|
4
|
+
# This class represents messages within Jaiku. The exact
|
5
|
+
# representation of the data will be different, depending on
|
6
|
+
# whether or not this message was in response to another message.
|
7
|
+
# The properties for a Message object are:
|
8
|
+
# - +id+: The unique id Jaiku has assigned to this message.
|
9
|
+
# - +title+: The text of the message, or the title of the message if
|
10
|
+
# this message is a response.
|
11
|
+
# - +entry_title+: The title of the original message (only present for comments)
|
12
|
+
# - +content+: The content of this message (only present for comments)
|
13
|
+
# - +pretty_content+: The content of this message + HTML formatting (only present for comments)
|
14
|
+
# - +url+: The url for this message.
|
15
|
+
# - +created_at+: An exact timestamp for this message's creation time.
|
16
|
+
# - +created_at_relative+: A friendly relative timestamp (e.g. '14 minutes ago')
|
17
|
+
# - +user+: An instance of +Rubyku::User+ representing the user who posted the message.
|
18
|
+
# - +comment+: A boolean property representing whether this message is a comment on another message.
|
19
|
+
class Message
|
20
|
+
attr_accessor :id
|
21
|
+
attr_accessor :title
|
22
|
+
attr_accessor :entry_title
|
23
|
+
attr_accessor :content
|
24
|
+
attr_accessor :pretty_content
|
25
|
+
attr_accessor :url
|
26
|
+
attr_accessor :created_at
|
27
|
+
attr_accessor :created_at_relative
|
28
|
+
attr_accessor :user
|
29
|
+
|
30
|
+
def comment? #:nodoc:
|
31
|
+
return @comment
|
32
|
+
end
|
33
|
+
|
34
|
+
def comment=(bool) #:nodoc:
|
35
|
+
@comment= bool
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
##
|
40
|
+
# Given a hash that represents the JSON data from Jaiku
|
41
|
+
# for a message, this method will build and return a
|
42
|
+
# Rubyku::Message with those properties.
|
43
|
+
#
|
44
|
+
def build_message_from_json(json)
|
45
|
+
m = Rubyku::Message.new
|
46
|
+
#the jaiku json objects look differently depending on
|
47
|
+
#whether or not they are in response to another message.
|
48
|
+
#if they are a response, the comment_id field will be
|
49
|
+
#present rather than the id field. A few other distinctions
|
50
|
+
#are captured below.
|
51
|
+
unless json['comment_id']
|
52
|
+
m.comment= false
|
53
|
+
m.id = json['id']
|
54
|
+
else
|
55
|
+
m.comment= true
|
56
|
+
m.id = json['comment_id']
|
57
|
+
m.entry_title = json['entry_title']
|
58
|
+
m.pretty_content = json['pretty_content']
|
59
|
+
end
|
60
|
+
|
61
|
+
m.title = json['title']
|
62
|
+
m.content = json['content']
|
63
|
+
m.url = json['url']
|
64
|
+
m.created_at = DateTime.parse(json['created_at'])
|
65
|
+
m.created_at_relative = json['created_at_relative']
|
66
|
+
m.user = Rubyku::User.build_user_from_json(json['user'])
|
67
|
+
|
68
|
+
m
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
data/lib/rubyku/request.rb
CHANGED
@@ -1,17 +1,28 @@
|
|
1
1
|
module Rubyku
|
2
2
|
|
3
|
+
##
|
4
|
+
# This is a utility class that handles communication with the Jaiku server.
|
5
|
+
#
|
3
6
|
class Request
|
4
7
|
class << self
|
5
|
-
|
8
|
+
##
|
9
|
+
# This method uses the given url and credentials to retrieve
|
10
|
+
# JSON data from the Jaiku servers.
|
11
|
+
# returns: +Hash+ containing the JSON data.
|
12
|
+
#
|
6
13
|
def retrieve_json_object(url_path, jaiku_credentials)
|
14
|
+
log = Rubyku::Settings.logger
|
15
|
+
log.info("About to request JSON from #{url_path}")
|
7
16
|
url_path += jaiku_credentials.request_string
|
8
|
-
|
17
|
+
log.debug("Using full URL to fetch JSON: #{url_path}")
|
9
18
|
url = URI.parse(url_path)
|
10
|
-
req = Net::HTTP::Get.new(url.
|
19
|
+
req = Net::HTTP::Get.new(url.request_uri)
|
11
20
|
res = Net::HTTP::Proxy(Rubyku::Settings.proxy_url, Rubyku::Settings.proxy_port) \
|
12
21
|
.start(url.host, url.port) {|http|
|
13
22
|
http.request(req)
|
14
23
|
}
|
24
|
+
log.info("Jaiku JSON response returned HTTP code #{res.code}")
|
25
|
+
log.debug("About to return JSON: " + res.body)
|
15
26
|
JSON(res.body)
|
16
27
|
end
|
17
28
|
end
|
data/lib/rubyku/settings.rb
CHANGED
@@ -1,4 +1,19 @@
|
|
1
1
|
module Rubyku
|
2
|
+
##
|
3
|
+
# This class acts as a centralized location for configurable items
|
4
|
+
# in rubyku. The configurable properties are as follows:
|
5
|
+
# - +logger+: a ruby logger object where all messages are logged.
|
6
|
+
# - +jaiku_credentials+: an instance of Rubyku::Credentials that is used
|
7
|
+
# throughout rubyku as the default credentials.
|
8
|
+
# - +proxy_url+: the url for an http proxy, if needed.
|
9
|
+
# - +proxy_port+: the port for an http proxy, if needed.
|
10
|
+
#
|
11
|
+
# The logger, by default, will log at Logger::INFO to logs/rubyku.log inside
|
12
|
+
# the project's source or gem folder. If you would like to integrate the rubyku
|
13
|
+
# logging statements into your own logs, simply replace the logger with your own
|
14
|
+
# at some point after including rubyku in your project.
|
15
|
+
# *WARNING*: a logger set to Logger::DEBUG will spit all kinds of user-sensitive
|
16
|
+
# information, and as such should only be used for testing.
|
2
17
|
class Settings
|
3
18
|
class << self
|
4
19
|
#Yay logger! Default logger is initialized below. Override it
|
data/lib/rubyku/user.rb
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
module Rubyku
|
2
|
-
|
2
|
+
##
|
3
|
+
# This class represents a user within the Jaiku system.
|
4
|
+
# It has the following attributes:
|
5
|
+
# - +avatar_url+: The url for locating the user's avatar picture.
|
6
|
+
# - +first_name+: The user's given first name.
|
7
|
+
# - +last_name+: The user's given last name.
|
8
|
+
# - +nick+: The user's unique username on Jaiku.
|
9
|
+
# - +jaiku_url+: The url where the user's jaiku account can be found.
|
10
|
+
# - +contacts+: A list of +Rubyku::User+ objects representing this user's contacts.
|
3
11
|
class User
|
4
12
|
attr_accessor :avatar_url
|
5
13
|
attr_accessor :first_name
|
@@ -10,55 +18,69 @@ module Rubyku
|
|
10
18
|
|
11
19
|
##
|
12
20
|
# Returns the list of contacts for the current user.
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# @param jaiku_credentials<Rubyku::Credentials> the credentials to use
|
18
|
-
# for authenticating with Jaiku. Defaults to any credentials set in <Rubyku::Settings>.
|
19
|
-
#
|
20
|
-
# @return <Array{Rubyku::User}> the users that this user follows on Jaiku.
|
21
|
+
# Contacts is the only property of User that is lazy-loaded.
|
22
|
+
# This is because if it wasn't lazy-loaded, you'd be perpetually
|
23
|
+
# creating user objects.
|
21
24
|
#
|
22
|
-
#
|
23
|
-
# in Jaiku.
|
24
|
-
#
|
25
|
-
# @raise <RubykuError> indicates that there was an error communicating
|
26
|
-
# to the Jaiku servers.
|
25
|
+
# returns: +Array{Rubyku::User}+ the users that this user follows on Jaiku.
|
27
26
|
#
|
28
27
|
def contacts(jaiku_credentials=Rubyku::Settings.jaiku_credentials)
|
29
28
|
log = Rubyku::Settings.logger
|
30
29
|
unless @contacts
|
31
|
-
log.info("contacts for user #{@
|
32
|
-
@contacts = User.
|
30
|
+
log.info("contacts for user #{@nick} requested - attempting to fetch.")
|
31
|
+
@contacts = Rubyku::User.fetch(@nick, jaiku_credentials).contacts
|
33
32
|
end
|
34
33
|
|
35
34
|
@contacts
|
36
35
|
end
|
37
36
|
|
37
|
+
##
|
38
|
+
# Returns the user's most recent updates.
|
39
|
+
# This method will hit the server every time, so cache the results if you need to.
|
40
|
+
#
|
41
|
+
# returns: +Array{Rubyku::Message}+ this user's most recent updates
|
42
|
+
#
|
43
|
+
def updates(jaiku_credentials=Rubyku::Settings.jaiku_credentials)
|
44
|
+
log = Rubyku::Settings.logger
|
45
|
+
log.info("Requesting updates from user #{@nick}")
|
46
|
+
url = "http://%s.jaiku.com/feed/json" % @nick
|
47
|
+
updates_json = Rubyku::Request.retrieve_json_object(url, jaiku_credentials)
|
48
|
+
updates_json['stream'].map { |m| Rubyku::Message.build_message_from_json(m) }
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Returns the stream for this user (updates from their contacts, as they see
|
53
|
+
# on the home page).
|
54
|
+
# This method will hit the server everytime, so cache the results if you need to.
|
55
|
+
#
|
56
|
+
# returns: +Array{Rubyku::Message}+ the messages in this user's stream.
|
57
|
+
#
|
58
|
+
def stream(jaiku_credentials=Rubyku::Settings.jaiku_credentials)
|
59
|
+
log = Rubyku::Settings.logger
|
60
|
+
log.info("Requesting stream for user #{@nick}")
|
61
|
+
url = "http://%s.jaiku.com/contacts/feed/json" % @nick
|
62
|
+
stream_json = Rubyku::Request.retrieve_json_object(url, jaiku_credentials)
|
63
|
+
stream_json['stream'].map { |m| Rubyku::Message.build_message_from_json(m) }
|
64
|
+
end
|
65
|
+
|
38
66
|
class << self
|
39
67
|
##
|
40
68
|
# Retrieves a user's information from Jaiku.
|
41
|
-
# All properties but contacts are loaded. @see <Rubyku::User.contacts>
|
42
|
-
#
|
43
|
-
# @param username<String> the user to fetch.
|
44
|
-
#
|
45
|
-
# @param jaiku_credentials<Rubyku::Credentials> the credentials to use
|
46
|
-
# for authenticating with Jaiku. Defaults to any credentials set in <Rubyku::Defaults>.
|
47
|
-
#
|
48
|
-
# @return <Rubyku::User> the requested user.
|
49
69
|
#
|
50
|
-
#
|
51
|
-
# in Jaiku.
|
70
|
+
# returns: Rubyku::User the requested user.
|
52
71
|
#
|
53
|
-
# @raise <RubykuError> indicates that there was an error communicating
|
54
|
-
# to the Jaiku servers.
|
55
|
-
#
|
56
72
|
def fetch(username,jaiku_credentials=Rubyku::Settings.jaiku_credentials)
|
57
73
|
req_url = "http://%s.jaiku.com/json" % username
|
58
74
|
json = Rubyku::Request.retrieve_json_object(req_url, jaiku_credentials)
|
59
75
|
build_user_from_json(json)
|
60
76
|
end
|
61
77
|
|
78
|
+
##
|
79
|
+
# Given a hash representing the JSON data for a user from Jaiku,
|
80
|
+
# this method maps those JSON properties to a +Rubyku::User+ object
|
81
|
+
# and returns it.
|
82
|
+
# Contacts are loaded if present.
|
83
|
+
#
|
62
84
|
def build_user_from_json(json)
|
63
85
|
user = Rubyku::User.new
|
64
86
|
user.nick= json['nick']
|
data/lib/rubyku/version.rb
CHANGED
data/lib/rubyku.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#:include:../README
|
2
|
+
|
1
3
|
# Just to make our requires at the top of the gem a little easier.
|
2
4
|
require 'pathname'
|
3
5
|
$:.unshift(Pathname(__FILE__).dirname.expand_path)
|
@@ -6,9 +8,12 @@ require 'net/http'
|
|
6
8
|
require 'logger'
|
7
9
|
require 'rubygems'
|
8
10
|
require 'json'
|
11
|
+
require 'date'
|
12
|
+
|
9
13
|
#rubyku requires
|
10
14
|
require 'rubyku/settings'
|
11
15
|
require 'rubyku/errors'
|
16
|
+
require 'rubyku/message'
|
12
17
|
require 'rubyku/user'
|
13
18
|
require 'rubyku/credentials'
|
14
19
|
require 'rubyku/version'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duwanis-rubyku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tommy Morgan
|
@@ -27,28 +27,29 @@ executables: []
|
|
27
27
|
|
28
28
|
extensions: []
|
29
29
|
|
30
|
-
extra_rdoc_files:
|
31
|
-
|
32
|
-
- README
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
33
32
|
files:
|
34
|
-
- LICENSE
|
35
|
-
- README
|
36
|
-
- Rakefile
|
37
33
|
- lib/rubyku.rb
|
38
|
-
- lib/rubyku/version.rb
|
39
34
|
- lib/rubyku/credentials.rb
|
40
|
-
- lib/rubyku/settings.rb
|
41
|
-
- lib/rubyku/user.rb
|
42
35
|
- lib/rubyku/errors.rb
|
36
|
+
- lib/rubyku/message.rb
|
43
37
|
- lib/rubyku/request.rb
|
44
|
-
-
|
45
|
-
-
|
38
|
+
- lib/rubyku/settings.rb
|
39
|
+
- lib/rubyku/user.rb
|
40
|
+
- lib/rubyku/version.rb
|
41
|
+
- LICENSE
|
42
|
+
- README
|
43
|
+
- logs/
|
46
44
|
has_rdoc: true
|
47
45
|
homepage: http://github.com/duwanis/rubyku
|
48
46
|
post_install_message:
|
49
47
|
rdoc_options:
|
48
|
+
- --title
|
49
|
+
- Rubyku - Jaiku for Ruby
|
50
50
|
- --main
|
51
|
-
-
|
51
|
+
- lib/rubyku.rb
|
52
|
+
- --line-numbers
|
52
53
|
require_paths:
|
53
54
|
- lib
|
54
55
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -70,6 +71,5 @@ rubygems_version: 1.0.1
|
|
70
71
|
signing_key:
|
71
72
|
specification_version: 2
|
72
73
|
summary: A Ruby API for accessing Jaiku.
|
73
|
-
test_files:
|
74
|
-
|
75
|
-
- test/test_rubyku.rb
|
74
|
+
test_files: []
|
75
|
+
|
data/Rakefile
DELETED
data/test/test_helper.rb
DELETED