jabber4r 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES ADDED
@@ -0,0 +1,8 @@
1
+ = Jabber4r Changelog
2
+
3
+ == Version 0.8.0
4
+
5
+ * Moved to Rakefile based on submitted patch by Aslak Hellesoy
6
+ * Removed install.rb...gem only distribution from this point on
7
+ * Added check for older version of REXML
8
+ * Fixed unit tests with rakefile
data/LICENSE.txt ADDED
@@ -0,0 +1,12 @@
1
+ Copyright (c) 2002, Rich Kilmer (rich@infoether.com)
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+
8
+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
+
10
+ The name Rich Kilmer may not be used to endorse or promote products derived from this software without specific prior written permission.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,180 @@
1
+ Jabber4R is copyrighted free software by Rich Kilmer <rich@infoether.com>
2
+ Please see LICENSE.txt for licensing information.
3
+ Version: 0.8.0
4
+ Date: August 15, 2005
5
+
6
+ ==== Overview
7
+
8
+ The purpose of this library is to allow Ruby applications to talk to a Jabber IM system.
9
+ Jabber is an open-source instant messaging service, which can be learned about here.
10
+
11
+ http://www.jabber.org
12
+
13
+ An interesting facet of Jabber is its ability to represent multiple resources connecting
14
+ to a single account at the same time. One could connect to the account
15
+ account@jabber.org from home and from work and from a pda all at the same time.
16
+ Each connection is viewed as a resource. Messages can be sent to an account (and the
17
+ server will decide which resource gets it based on the resource�s priority) or to an
18
+ account+resource. The fully qualified account and resource name is:
19
+
20
+ account@host/resource
21
+
22
+ This library was created to allow a Ruby application to connect to an existing Jabber
23
+ account as an additional resource. This is not meant to be a library to create a complete
24
+ Ruby-based Jabber IM client. It currently does not support creation of accounts and
25
+ managing presence subscriptions (do that with one of the other 30 Jabber clients out
26
+ there). It was written for ease of use, not completeness. It does support:
27
+
28
+ * Account registration
29
+ * Connection to an account (digest/plain text)
30
+ * Access to Roster (buddy list)
31
+ * Tracking of presence of resources in the Roster (including local account resources)
32
+ * Sending and receiving messages
33
+ * Requesting VCards
34
+ * Managing subscriptions
35
+
36
+ What can you do with this? You could write a Ruby application that allows you to query
37
+ it by IM for status, control, etc. You could use this as a communications channel
38
+ backbone for a Ruby application (which is my intent).
39
+
40
+ ==== Release Notes
41
+
42
+ * Now have rake-based building and install.
43
+
44
+ ==== Usage
45
+
46
+ require 'jabber4r/jabber4r'
47
+ session = Jabber::Session.bind_digest("rich@jabber.com", "secret")
48
+ session.new_message("bob@jabber.com").set_body("ruby speak!").send
49
+ session.release
50
+
51
+ You can send and receive messages. I make use of chaining on messages so you can do this
52
+
53
+ session.add_message_listener do |message|
54
+ message.reply.set_body(�Echo: #{message.body}�).send
55
+ end
56
+
57
+ If you want to send and wait for a reply message do:
58
+
59
+ answer=session.new_chat_message("rich@jabber.com").set_body("Hello there").send(true)
60
+
61
+ Then execute:
62
+ puts answer.body
63
+ answer.reply.set_body("Thanks for the reply").send
64
+
65
+ The examples below demonstrate many features.
66
+
67
+ Please look at the doc directory (RDoc format) for detailed info on Jabber4R. The
68
+ Jabber::Session class is kind of the main thing to focus on.
69
+
70
+ I have a test directory with a single unit test file (for testing the JID class).
71
+ I will work on many more. There is also a fun echo.rb file there that you can run
72
+ to echo and messages back to the sender...and when they send 'shutdown' the session
73
+ releases.
74
+
75
+ ruby echo.rb <jabberid> <password>
76
+
77
+ You can observe roster changes, but cannot manage subscriptions (the framework is there
78
+ to do this, but it needs some work). You also cannot add an account (you must already
79
+ have one). That's in the works as well.
80
+
81
+ Have fun!
82
+
83
+
84
+ == Installation
85
+
86
+ To install, execute the following command:
87
+
88
+ > gem install jabber4r
89
+
90
+ That's it!
91
+
92
+ ==== Examples
93
+
94
+ NOTE: Remember to change your account@host/resource and password to YOURs.
95
+
96
+ Connecting to an account, sending a message, and disconnecting:
97
+
98
+ require 'jabber4r/jabber4r'
99
+ begin
100
+ session = Jabber::Session.bind('account@host/resource', 'password')
101
+ session.new_message('rich_kilmer@jabber.org').set_subject('hello').set_body('This is really cool').send
102
+ rescue Exception=>error
103
+ puts error
104
+ ensure
105
+ session.release if session
106
+ end
107
+
108
+ -----------------
109
+
110
+ Connecting to an account, sending a message, waiting for a reply, and disconnecting:
111
+
112
+ require 'jabber4r/jabber4r'
113
+ begin
114
+ session = Jabber::Session.bind('account@host/resource', 'password')
115
+ #NOTE: send the first message and wait for a reply (i.e. send(true) )
116
+ message = session.new_chat_message('rich_kilmer@jabber.org').set_body('hey').send(true)
117
+ #NOTE: reply to the reply with an echo of the message, but don't wait
118
+ message.reply.set_body("You said #{message.body}").send
119
+ rescue Exception=>error
120
+ puts error
121
+ ensure
122
+ session.release if session
123
+ end
124
+
125
+ -----------------
126
+
127
+ Connecting to an account, echoing back each received message, and disconnecting
128
+ when a shutdown message is received:
129
+
130
+
131
+ require "jabber4r/jabber4r"
132
+ begin
133
+ session = Jabber::Session.bind("account@host/resource", "password")
134
+ myThread = Thread.current
135
+ mlid = session.add_message_listener do |message|
136
+ message.reply.set_body("Echo: #{message.body}").send
137
+ myThread.wakeup if message.body=="shutdown"
138
+ end
139
+ Thread.stop
140
+ session.delete_message_listener(mlid)
141
+ rescue Exception=>error
142
+ puts error
143
+ ensure
144
+ session.release if session
145
+ end
146
+
147
+ -----------------
148
+
149
+ Connecting to an account, outputting roster changes, and disconnecting when a
150
+ shutdown message is received:
151
+
152
+ require "jabber4r/jabber4r"
153
+ begin
154
+ session = Jabber::Session.bind("account@host/resource", "password")
155
+ myThread = Thread.current
156
+ #NOTE: Just like before, a 'shutdown' message stops the session
157
+ mlid = session.add_message_listener do |message|
158
+ myThread.wakeup if message.body=="shutdown"
159
+ end
160
+ listenerid = session.add_roster_listener do |event, object|
161
+ case event
162
+ when Jabber::Roster::ITEM_ADDED
163
+ puts "Added item: #{object.to_s}"
164
+ when Jabber::Roster::ITEM_DELETED
165
+ puts "Deleted item: #{object.to_s}"
166
+ when Jabber::Roster::RESOURCE_ADDED
167
+ puts "Added resource: #{object.to_s}"
168
+ when Jabber::Roster::RESOURCE_DELETED
169
+ puts "Deleted resource: #{object.to_s}"
170
+ when Jabber::Roster::RESOURCE_UPDATED
171
+ puts "Updated resource: #{object.to_s}"
172
+ end
173
+ end
174
+ Thread.stop
175
+ rescue Exception=>error
176
+ puts error
177
+ ensure
178
+ session.release if session
179
+ end
180
+
data/Rakefile.rb ADDED
@@ -0,0 +1,143 @@
1
+ $:.unshift('lib')
2
+ require 'rubygems'
3
+ begin
4
+ require 'xforge'
5
+ rescue LoadError
6
+ puts "**** Warning. XForge not installed. Release tasks won't work ****"
7
+ end
8
+ require 'rake/gempackagetask'
9
+ require 'rake/contrib/rubyforgepublisher'
10
+ require 'rake/clean'
11
+ require 'rake/testtask'
12
+ require 'rake/rdoctask'
13
+
14
+ PKG_NAME = "jabber4r"
15
+
16
+ PKG_VERSION = "0.8.0"
17
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
18
+ PKG_FILES = FileList[
19
+ '[A-Z]*',
20
+ 'lib/**/*.rb'
21
+ ]
22
+
23
+ task :default => [:gem]
24
+
25
+ Rake::TestTask.new do |t|
26
+ t.libs << "test"
27
+ t.test_files = FileList['**/*test*.rb']
28
+ t.verbose = true
29
+ end
30
+
31
+ # Create a task to build the RDOC documentation tree.
32
+ rd = Rake::RDocTask.new("rdoc") do |rdoc|
33
+ rdoc.rdoc_dir = 'html'
34
+ rdoc.title = "Jabber4r"
35
+ rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README'
36
+ rdoc.rdoc_files.include('README')
37
+ rdoc.rdoc_files.include('lib/**/*.rb')
38
+ end
39
+
40
+ # ====================================================================
41
+ # Create a task that will package the Rake software into distributable
42
+ # tar, zip and gem files.
43
+
44
+ spec = Gem::Specification.new do |s|
45
+
46
+ #### Basic information.
47
+
48
+ s.name = PKG_NAME
49
+ s.version = PKG_VERSION
50
+ s.summary = "Jabber4r is a pure-Ruby Jabber client library"
51
+ s.description = <<-EOF
52
+ The purpose of this library is to allow Ruby applications to
53
+ talk to a Jabber IM system. Jabber is an open-source instant
54
+ messaging service, which can be learned about at http://www.jabber.org
55
+ EOF
56
+
57
+ s.files = PKG_FILES.to_a
58
+ s.require_path = 'lib'
59
+
60
+ #### Documentation and testing.
61
+
62
+ s.has_rdoc = true
63
+ s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
64
+ s.rdoc_options <<
65
+ '--title' << 'Jabber4r' <<
66
+ '--main' << 'README' <<
67
+ '--line-numbers'
68
+
69
+ #### Author and project details.
70
+
71
+ s.author = "Richard Kilmer"
72
+ s.email = "rich@infoether.com"
73
+ s.rubyforge_project = "jabber4r"
74
+ s.homepage = "http://jabber4r.rubyforge.org"
75
+ end
76
+
77
+ desc "Build Gem"
78
+ Rake::GemPackageTask.new(spec) do |pkg|
79
+ pkg.need_zip = true
80
+ pkg.need_tar = true
81
+ end
82
+ task :gem => [:test]
83
+
84
+ # Support Tasks ------------------------------------------------------
85
+
86
+ def egrep(pattern)
87
+ Dir['**/*.rb'].each do |fn|
88
+ count = 0
89
+ open(fn) do |f|
90
+ while line = f.gets
91
+ count += 1
92
+ if line =~ pattern
93
+ puts "#{fn}:#{count}:#{line}"
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ desc "Look for TODO and FIXME tags in the code"
101
+ task :todo do
102
+ egrep /#.*(FIXME|TODO|TBD)/
103
+ end
104
+
105
+ task :release => [:verify_env_vars, :release_files, :publish_doc, :publish_news]
106
+
107
+ task :verify_env_vars do
108
+ raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
109
+ raise "RUBYFORGE_PASSWORD environment variable not set!" unless ENV['RUBYFORGE_PASSWORD']
110
+ end
111
+
112
+ task :publish_doc => [:rdoc] do
113
+ publisher = Rake::RubyForgePublisher.new(PKG_NAME, ENV['RUBYFORGE_USER'])
114
+ publisher.upload
115
+ end
116
+
117
+ desc "Release gem to RubyForge. MAKE SURE PKG_VERSION is aligned with the CHANGELOG file"
118
+ task :release_files => [:gem] do
119
+ release_files = FileList[
120
+ "pkg/#{PKG_FILE_NAME}.gem"
121
+ ]
122
+
123
+ Rake::XForge::Release.new(PKG_NAME) do |xf|
124
+ # Never hardcode user name and password in the Rakefile!
125
+ xf.user_name = ENV['RUBYFORGE_USER']
126
+ xf.password = ENV['RUBYFORGE_PASSWORD']
127
+ xf.files = release_files.to_a
128
+ xf.release_name = "Jabber4r #{PKG_VERSION}"
129
+ end
130
+ end
131
+
132
+ desc "Publish news on RubyForge"
133
+ task :publish_news => [:gem] do
134
+ release_files = FileList[
135
+ "pkg/#{PKG_FILE_NAME}.gem"
136
+ ]
137
+
138
+ Rake::XForge::NewsPublisher.new(PKG_NAME) do |news|
139
+ # Never hardcode user name and password in the Rakefile!
140
+ news.user_name = ENV['RUBYFORGE_USER']
141
+ news.password = ENV['RUBYFORGE_PASSWORD']
142
+ end
143
+ end
@@ -0,0 +1,22 @@
1
+ # License: see LICENSE.txt
2
+ # Jabber4R - Jabber Instant Messaging Library for Ruby
3
+ # Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
4
+ #
5
+
6
+ ##
7
+ # The Jabber module is the main namespace for all Jabber modules
8
+ # and classes.
9
+ #
10
+ module Jabber
11
+ VERSION_MAJOR = 0
12
+ VERSION_MINOR = 6
13
+ RELEASE = 0
14
+ DEBUG = false
15
+ end
16
+
17
+ require "jabber4r/session"
18
+ require "jabber4r/protocol"
19
+ require "jabber4r/roster"
20
+ require "jabber4r/jid"
21
+ require "jabber4r/vcard"
22
+
@@ -0,0 +1,93 @@
1
+ # License: see LICENSE.txt
2
+ # Jabber4R - Jabber Instant Messaging Library for Ruby
3
+ # Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
4
+ #
5
+
6
+ module Jabber
7
+
8
+ ##
9
+ # The Jabber ID class is used to hold a parsed jabber identifier (account+host+resource)
10
+ #
11
+ class JID
12
+
13
+ # The node (account)
14
+ attr_accessor :node
15
+
16
+ # The resource id
17
+ attr_accessor :resource
18
+
19
+ # The host name (or IP address)
20
+ attr_accessor :host
21
+
22
+ def JID.to_jid(id)
23
+ return id if id.kind_of? JID
24
+ return JID.new(id)
25
+ end
26
+
27
+ #@@Pattern = /([^@""'\s:]+)\@([-.\w]+)\/?(.*)/
28
+
29
+ ##
30
+ # Constructs a JID from the supplied string of the format:
31
+ # node@host[/resource] (e.g. "rich_kilmer@jabber.com/laptop")
32
+ #
33
+ # id:: [String] The jabber id string to parse
34
+ #
35
+ def initialize(id)
36
+ at_loc = id.index('@')
37
+ slash_loc = id.index('/')
38
+ if at_loc.nil? and slash_loc.nil?
39
+ @host = id
40
+ end
41
+ if at_loc
42
+ @node = id[0,at_loc]
43
+ host_end = slash_loc ? slash_loc-(at_loc+1) : id.size-(at_loc+1)
44
+ @host = id[at_loc+1,host_end]
45
+ @resource = id[slash_loc+1, id.size] if slash_loc
46
+ end
47
+ end
48
+
49
+ ##
50
+ # Evalutes whether the node, resource and host are the same
51
+ #
52
+ # other:: [Jabber::JID] The other jabber id
53
+ # return:: [Boolean] True if they match
54
+ def ==(other)
55
+ return true if other.node==@node and other.resource==@resource and other.host==@host
56
+ return false
57
+ end
58
+
59
+ def same_account?(other)
60
+ other = JID.to_jid(other)
61
+ return true if other.node==@node and other.host==@host
62
+ return false
63
+ end
64
+
65
+ ##
66
+ # Removes the resource from this JID
67
+ #
68
+ def strip_resource
69
+ @resource=nil
70
+ return self
71
+ end
72
+
73
+ ##
74
+ # Returns the string ("node@host/resource") representation of this JID
75
+ #
76
+ # return:: [String] String form of JID
77
+ #
78
+ def to_s
79
+ result = (@node.to_s+"@"+@host.to_s)
80
+ result += ("/"+@resource) if @resource
81
+ return result
82
+ end
83
+
84
+ ##
85
+ # Override #hash to hash based on the to_s method
86
+ #
87
+ def hash
88
+ return to_s.hash
89
+ end
90
+ end
91
+
92
+ end
93
+