tunecore-announcer 0.0.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.
@@ -0,0 +1,163 @@
1
+ require 'singleton'
2
+ require 'xmpp4r'
3
+ require 'xmpp4r/vcard'
4
+
5
+
6
+ class TunecoreAnnouncer::XmppConnection
7
+ include Singleton
8
+
9
+ attr_reader :server
10
+ attr_reader :name
11
+ attr_reader :port
12
+
13
+ def initialize
14
+ @logger = TunecoreAnnouncer::Logger.instance
15
+ end
16
+
17
+ def connect(opt)
18
+ @options = opt
19
+ @server = opt.jabber_server
20
+ @name = "#{opt.name_prefix}-#{TunecoreAnnouncer::Utils.random_word(2)}"
21
+ @password = opt.jabber_password
22
+ admin_jids = opt.admin_jids
23
+
24
+ register
25
+ @logger.info "Connected to XMPP server"
26
+ #@jabber.add(admin_jids)
27
+ add_admins
28
+ #@logger.debug "Added #{admin_jid} to roster"
29
+ @logger.debug "Launching listener"
30
+ admins(opt.hello_mesg) if opt.hello_mesg
31
+ set_vcard
32
+ listen
33
+ end
34
+
35
+
36
+ def disconnect
37
+ admins "Shutting down ... Sayonara!"
38
+ deregister
39
+ @jabber.disconnect
40
+ @listener_thread.join
41
+ end
42
+
43
+ def admins(mesg)
44
+ @options.admin_jids.each do |admin_jid|
45
+ @jabber.deliver admin_jid, mesg
46
+ end
47
+ end
48
+
49
+ def status(presence, mesg)
50
+ pres = Jabber::Presence::new
51
+ set_avatar(pres) unless @options.avatar_file.nil?
52
+ pres.set_status mesg
53
+ @logger.debug "Setting presence: #{pres.to_s}, #{mesg}"
54
+ @jabber.send!(pres)
55
+ end
56
+
57
+
58
+ private
59
+
60
+ def register
61
+ connection_string = "#{@name}@#{@server}"
62
+ @logger.debug "Registering #{connection_string}"
63
+ begin
64
+ @jabber = Jabber::Simple.register(connection_string, @password)
65
+ rescue => e
66
+ @logger.fatal "XMPP connection refused: #{e.message}\n#{e.backtrace}"
67
+ puts "XMPP connection refused: #{e.inspect}\n#{e.backtrace}"
68
+ exit
69
+ end
70
+ end
71
+
72
+ def deregister
73
+ @logger.debug "Removing registration"
74
+ client = @jabber.client
75
+ client.remove_registration
76
+ end
77
+
78
+
79
+ def listen
80
+ @listener_thread = Thread.new{
81
+ @logger.debug "Listening for XMPP messages (connected=#{@jabber.connected?})"
82
+ while @jabber.connected? do
83
+ #@logger.debug "Polling for Jabber mesg"
84
+ @jabber.received_messages.each do |message|
85
+ process_incoming message
86
+ sleep 1
87
+ end
88
+ end
89
+ }
90
+ @listener_thread.run
91
+ end
92
+
93
+ def process_incoming(message)
94
+ @logger.debug "Jabber msg from #{message.from}: #{message.body}"
95
+ case message.body
96
+ when "uptime"
97
+ @jabber.deliver(message.from, `uptime`)
98
+ when "ps"
99
+ @jabber.deliver(message.from, `ps -ef`)
100
+ when "hostname"
101
+ @jabber.deliver(message.from, `hostname`)
102
+ else
103
+ @jabber.deliver(message.from, "Sorry, I don't know #{message.body}")
104
+ end
105
+ end
106
+
107
+ def set_vcard
108
+ # set vcard info
109
+ @avatar_sha1 = nil # this gets used later on
110
+ vcard = Jabber::Vcard::IqVcard.new
111
+ vcard["FN"] = @name # full name
112
+ vcard["NICKNAME"] = @name # nickname
113
+ # buddy icon stuff
114
+ unless @options.avatar_file.nil?
115
+ vcard["PHOTO/TYPE"] = "image/png"
116
+ # open buddy icon/avatar image file
117
+ image_file = File.new(@options.avatar_file, "r")
118
+ # Base64 encode the file contents
119
+ image_b64 = Base64.b64encode(image_file.read())
120
+ # process sha1 hash of photo contents
121
+ # this is used by the presence setting
122
+ image_file.rewind # must rewind the file to the beginning
123
+ @avatar_sha1 = Digest::SHA1.hexdigest(image_file.read())
124
+ vcard["PHOTO/BINVAL"] = image_b64 # set the BINVAL to the Base64 encoded contents of our image
125
+ end
126
+ begin
127
+ # create a vcard helper and immediately set the vcard info
128
+ @logger.info "Setting Vcard"
129
+ vcard_helper = Jabber::Vcard::Helper.new(@jabber.client).set(vcard)
130
+ rescue
131
+ @logger.error "Vcard operation timed out."
132
+ end
133
+ return true
134
+ end
135
+
136
+ def set_avatar(pres)
137
+ if not @avatar_sha1.nil?
138
+ # send the sha1 hash of the avatar to the server
139
+ # as per the RFC http://www.xmpp.org/extensions/xep-0153.html
140
+ x = REXML::Element::new("x")
141
+ x.add_namespace('vcard-temp:x:update')
142
+ photo = REXML::Element::new("photo")
143
+ # this is the avatar hash as computed in the vcard thread above
144
+ avatar_hash = REXML::Text.new(@avatar_sha1)
145
+ # add text to photo
146
+ photo.add(avatar_hash)
147
+ # add photo to x
148
+ x.add(photo)
149
+ # add x to presence
150
+ pres.add_element(x)
151
+ end
152
+ end
153
+
154
+ def add_admins
155
+ @options.admin_jids.each do |jid|
156
+ @jabber.add jid
157
+ @logger.debug "Added admin #{jid}"
158
+ end
159
+ end
160
+
161
+
162
+
163
+ end
@@ -0,0 +1,14 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module TunecoreAnnouncer
5
+ VERSION = '0.0.1'
6
+
7
+ require "optparse"
8
+ require 'ostruct'
9
+ require 'rubygems'
10
+ require 'xmpp4r-simple/xmpp4r-simple'
11
+ require 'tunecore-announcer/utils'
12
+ require 'tunecore-announcer/logger'
13
+ require 'tunecore-announcer/xmpp_connection'
14
+ end
@@ -0,0 +1,528 @@
1
+ # Jabber::Simple - An extremely easy-to-use Jabber client library.
2
+ # Copyright 2006 Blaine Cook <blaine@obvious.com>, Obvious Corp.
3
+ #
4
+ # Jabber::Simple is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # Jabber::Simple is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with Jabber::Simple; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'rubygems'
19
+ require 'xmpp4r'
20
+ require 'xmpp4r/roster'
21
+ require 'xmpp4r/vcard'
22
+
23
+ module Jabber
24
+
25
+ class ConnectionError < StandardError #:nodoc:
26
+ end
27
+
28
+ class RegistrationError < StandardError #:nodoc:
29
+ end
30
+
31
+ class Contact #:nodoc:
32
+
33
+ include DRb::DRbUndumped if defined?(DRb::DRbUndumped)
34
+
35
+ def initialize(client, jid)
36
+ @jid = jid.respond_to?(:resource) ? jid : JID.new(jid)
37
+ @client = client
38
+ end
39
+
40
+ def inspect
41
+ "Jabber::Contact #{jid.to_s}"
42
+ end
43
+
44
+ def subscribed?
45
+ [:to, :both].include?(subscription)
46
+ end
47
+
48
+ def subscription
49
+ roster_item && roster_item.subscription
50
+ end
51
+
52
+ def ask_for_authorization!
53
+ subscription_request = Presence.new.set_type(:subscribe)
54
+ subscription_request.to = jid
55
+ client.send!(subscription_request)
56
+ end
57
+
58
+ def unsubscribe!
59
+ unsubscription_request = Presence.new.set_type(:unsubscribe)
60
+ unsubscription_request.to = jid
61
+ client.send!(unsubscription_request)
62
+ client.send!(unsubscription_request.set_type(:unsubscribed))
63
+ end
64
+
65
+ def jid(bare=true)
66
+ bare ? @jid.strip : @jid
67
+ end
68
+
69
+ private
70
+
71
+ def roster_item
72
+ client.roster.items[jid]
73
+ end
74
+
75
+ def client
76
+ @client
77
+ end
78
+ end
79
+
80
+ class Simple
81
+
82
+ include DRb::DRbUndumped if defined?(DRb::DRbUndumped)
83
+
84
+ def self.register(jid, password, status = nil, status_message = "Available")
85
+ new(jid, password, status, status_message, true)
86
+ end
87
+
88
+ # Create a new Jabber::Simple client. You will be automatically connected
89
+ # to the Jabber server and your status message will be set to the string
90
+ # passed in as the status_message argument.
91
+ #
92
+ # jabber = Jabber::Simple.new("me@example.com", "password", "Chat with me - Please!")
93
+ def initialize(jid, password, status = nil, status_message = "Available", register = false)
94
+ @jid = jid
95
+ @password = password
96
+ @disconnected = false
97
+ register!(password) if @register = register
98
+ status(status, status_message)
99
+ start_deferred_delivery_thread
100
+ end
101
+
102
+ def inspect #:nodoc:
103
+ "Jabber::Simple #{@jid}"
104
+ end
105
+
106
+ # Send a message to jabber user jid.
107
+ #
108
+ # Valid message types are:
109
+ #
110
+ # * :normal (default): a normal message.
111
+ # * :chat: a one-to-one chat message.
112
+ # * :groupchat: a group-chat message.
113
+ # * :headline: a "headline" message.
114
+ # * :error: an error message.
115
+ #
116
+ # If the recipient is not in your contacts list, the message will be queued
117
+ # for later delivery, and the Contact will be automatically asked for
118
+ # authorization (see Jabber::Simple#add).
119
+ #
120
+ # message should be a string or a valid Jabber::Message object. In either case,
121
+ # the message recipient will be set to jid.
122
+ def deliver(jid, message, type=:chat)
123
+ contacts(jid) do |friend|
124
+ unless subscribed_to? friend
125
+ add(friend.jid)
126
+ return deliver_deferred(friend.jid, message, type)
127
+ end
128
+ if message.kind_of?(Jabber::Message)
129
+ msg = message
130
+ msg.to = friend.jid
131
+ else
132
+ msg = Message.new(friend.jid)
133
+ msg.type = type
134
+ msg.body = message
135
+ end
136
+ send!(msg)
137
+ end
138
+ end
139
+
140
+ # Set your presence, with a message.
141
+ #
142
+ # Available values for presence are:
143
+ #
144
+ # * nil: online.
145
+ # * :chat: free for chat.
146
+ # * :away: away from the computer.
147
+ # * :dnd: do not disturb.
148
+ # * :xa: extended away.
149
+ #
150
+ # It's not possible to set an offline status - to do that, disconnect! :-)
151
+ def status(presence, message)
152
+ @presence = presence
153
+ @status_message = message
154
+ stat_msg = Presence.new(@presence, @status_message)
155
+ send!(stat_msg)
156
+ end
157
+
158
+ # Ask the users specified by jids for authorization (i.e., ask them to add
159
+ # you to their contact list). If you are already in the user's contact list,
160
+ # add() will not attempt to re-request authorization. In order to force
161
+ # re-authorization, first remove() the user, then re-add them.
162
+ #
163
+ # Example usage:
164
+ #
165
+ # jabber_simple.add("friend@friendosaurus.com")
166
+ #
167
+ # Because the authorization process might take a few seconds, or might
168
+ # never happen depending on when (and if) the user accepts your
169
+ # request, results are placed in the Jabber::Simple#new_subscriptions queue.
170
+ def add(*jids)
171
+ contacts(*jids) do |friend|
172
+ next if subscribed_to? friend
173
+ friend.ask_for_authorization!
174
+ end
175
+ end
176
+
177
+ # Remove the jabber users specified by jids from the contact list.
178
+ def remove(*jids)
179
+ contacts(*jids) do |unfriend|
180
+ unfriend.unsubscribe!
181
+ end
182
+ end
183
+
184
+ # Returns true if this Jabber account is subscribed to status updates for
185
+ # the jabber user jid, false otherwise.
186
+ def subscribed_to?(jid)
187
+ contacts(jid) do |contact|
188
+ return contact.subscribed?
189
+ end
190
+ end
191
+
192
+ # If contacts is a single contact, returns a Jabber::Contact object
193
+ # representing that user; if contacts is an array, returns an array of
194
+ # Jabber::Contact objects.
195
+ #
196
+ # When called with a block, contacts will yield each Jabber::Contact object
197
+ # in turn. This is mainly used internally, but exposed as an utility
198
+ # function.
199
+ def contacts(*contacts, &block)
200
+ @contacts ||= {}
201
+ contakts = []
202
+ contacts.each do |contact|
203
+ jid = contact.to_s
204
+ unless @contacts[jid]
205
+ @contacts[jid] = contact.respond_to?(:ask_for_authorization!) ? contact : Contact.new(self, contact)
206
+ end
207
+ yield @contacts[jid] if block_given?
208
+ contakts << @contacts[jid]
209
+ end
210
+ contakts.size > 1 ? contakts : contakts.first
211
+ end
212
+
213
+ # Returns true if the Jabber client is connected to the Jabber server,
214
+ # false otherwise.
215
+ def connected?
216
+ @client ||= nil
217
+ connected = @client.respond_to?(:is_connected?) && @client.is_connected?
218
+ return connected
219
+ end
220
+
221
+ # Returns an array of messages received since the last time
222
+ # received_messages was called. Passing a block will yield each message in
223
+ # turn, allowing you to break part-way through processing (especially
224
+ # useful when your message handling code is not thread-safe (e.g.,
225
+ # ActiveRecord).
226
+ #
227
+ # e.g.:
228
+ #
229
+ # jabber.received_messages do |message|
230
+ # puts "Received message from #{message.from}: #{message.body}"
231
+ # end
232
+ def received_messages(&block)
233
+ dequeue(:received_messages, &block)
234
+ end
235
+
236
+ # Returns true if there are unprocessed received messages waiting in the
237
+ # queue, false otherwise.
238
+ def received_messages?
239
+ !queue(:received_messages).empty?
240
+ end
241
+
242
+ # Returns an array of presence updates received since the last time
243
+ # presence_updates was called. Passing a block will yield each update in
244
+ # turn, allowing you to break part-way through processing (especially
245
+ # useful when your presence handling code is not thread-safe (e.g.,
246
+ # ActiveRecord).
247
+ #
248
+ # e.g.:
249
+ #
250
+ # jabber.presence_updates do |friend, new_presence|
251
+ # puts "Received presence update from #{friend}: #{new_presence}"
252
+ # end
253
+ def presence_updates(&block)
254
+ updates = []
255
+ @presence_mutex.synchronize do
256
+ dequeue(:presence_updates) do |friend|
257
+ presence = @presence_updates[friend]
258
+ next unless presence
259
+ new_update = [friend, presence[0], presence[1]]
260
+ yield new_update if block_given?
261
+ updates << new_update
262
+ @presence_updates.delete(friend)
263
+ end
264
+ end
265
+ return updates
266
+ end
267
+
268
+ # Returns true if there are unprocessed presence updates waiting in the
269
+ # queue, false otherwise.
270
+ def presence_updates?
271
+ !queue(:presence_updates).empty?
272
+ end
273
+
274
+ # Returns an array of subscription notifications received since the last
275
+ # time new_subscriptions was called. Passing a block will yield each update
276
+ # in turn, allowing you to break part-way through processing (especially
277
+ # useful when your subscription handling code is not thread-safe (e.g.,
278
+ # ActiveRecord).
279
+ #
280
+ # e.g.:
281
+ #
282
+ # jabber.new_subscriptions do |friend, presence|
283
+ # puts "Received presence update from #{friend.to_s}: #{presence}"
284
+ # end
285
+ def new_subscriptions(&block)
286
+ dequeue(:new_subscriptions, &block)
287
+ end
288
+
289
+ # Returns true if there are unprocessed presence updates waiting in the
290
+ # queue, false otherwise.
291
+ def new_subscriptions?
292
+ !queue(:new_subscriptions).empty?
293
+ end
294
+
295
+ # Returns an array of subscription notifications received since the last
296
+ # time subscription_requests was called. Passing a block will yield each update
297
+ # in turn, allowing you to break part-way through processing (especially
298
+ # useful when your subscription handling code is not thread-safe (e.g.,
299
+ # ActiveRecord).
300
+ #
301
+ # e.g.:
302
+ #
303
+ # jabber.subscription_requests do |friend, presence|
304
+ # puts "Received presence update from #{friend.to_s}: #{presence}"
305
+ # end
306
+ def subscription_requests(&block)
307
+ dequeue(:subscription_requests, &block)
308
+ end
309
+
310
+ # Returns true if auto-accept subscriptions (friend requests) is enabled
311
+ # (default), false otherwise.
312
+ def accept_subscriptions?
313
+ @accept_subscriptions = true if @accept_subscriptions.nil?
314
+ @accept_subscriptions
315
+ end
316
+
317
+ # Change whether or not subscriptions (friend requests) are automatically accepted.
318
+ def accept_subscriptions=(accept_status)
319
+ @accept_subscriptions = accept_status
320
+ end
321
+
322
+ # Direct access to the underlying Roster helper.
323
+ def roster
324
+ return @roster if @roster
325
+ self.roster = Roster::Helper.new(client)
326
+ end
327
+
328
+ # Direct access to the underlying Jabber client.
329
+ def client
330
+ connect!() unless connected?
331
+ @client
332
+ end
333
+
334
+ def send!(msg)
335
+ attempt! {
336
+ client.send(msg)
337
+ }
338
+ end
339
+
340
+ def register!(password)
341
+ attempt! {
342
+ begin
343
+ client.register(password)
344
+ @register = false
345
+ disconnect
346
+ reconnect
347
+ rescue => e
348
+ error_msg = "Error registering: #{e.error.text}\n\n"
349
+ if e.error.type == :modify
350
+ error_msg += "Accepted registration information:\n"
351
+ instructions, fields = client.register_info
352
+ fields.each { |info|
353
+ error_msg += "* #{info}\n"
354
+ }
355
+ error_msg += "(#{instructions})"
356
+ end
357
+ raise RegistrationError, error_msg
358
+ end
359
+ }
360
+ end
361
+
362
+ # Send a Jabber stanza over-the-wire.
363
+ def attempt!
364
+ attempts = 0
365
+ begin
366
+ attempts += 1
367
+ yield
368
+ rescue Errno::EPIPE, IOError => e
369
+ sleep 1
370
+ disconnect
371
+ reconnect
372
+ retry unless attempts > 3
373
+ raise e
374
+ rescue Errno::ECONNRESET => e
375
+ sleep (attempts^2) * 60 + 60
376
+ disconnect
377
+ reconnect
378
+ retry unless attempts > 3
379
+ raise e
380
+ end
381
+ end
382
+
383
+ # Use this to force the client to reconnect after a force_disconnect.
384
+ def reconnect
385
+ @disconnected = false
386
+ connect!
387
+ end
388
+
389
+ # Use this to force the client to disconnect and not automatically
390
+ # reconnect.
391
+ def disconnect
392
+ disconnect!
393
+ end
394
+
395
+ # Queue messages for delivery once a user has accepted our authorization
396
+ # request. Works in conjunction with the deferred delivery thread.
397
+ #
398
+ # You can use this method if you want to manually add friends and still
399
+ # have the message queued for later delivery.
400
+ def deliver_deferred(jid, message, type)
401
+ msg = {:to => jid, :message => message, :type => type}
402
+ queue(:pending_messages) << [msg]
403
+ end
404
+
405
+ private
406
+
407
+ def client=(client)
408
+ self.roster = nil # ensure we clear the roster, since that's now associated with a different client.
409
+ @client = client
410
+ end
411
+
412
+ def roster=(new_roster)
413
+ @roster = new_roster
414
+ end
415
+
416
+ def connect!
417
+ raise ConnectionError, "Connections are disabled - use Jabber::Simple::force_connect() to reconnect." if @disconnected
418
+ # Pre-connect
419
+ @connect_mutex ||= Mutex.new
420
+
421
+ # don't try to connect if another thread is already connecting.
422
+ return if @connect_mutex.locked?
423
+
424
+ @connect_mutex.lock
425
+ disconnect!(false) if connected?
426
+
427
+ # Connect
428
+ jid = JID.new(@jid)
429
+ my_client = Client.new(@jid)
430
+ my_client.connect
431
+ my_client.auth(@password) unless @register
432
+ self.client = my_client
433
+
434
+ # Post-connect
435
+ register_default_callbacks
436
+ status(@presence, @status_message) unless @register
437
+ @connect_mutex.unlock
438
+ end
439
+
440
+ def disconnect!(auto_reconnect = true)
441
+ if client.respond_to?(:is_connected?) && client.is_connected?
442
+ begin
443
+ client.close
444
+ rescue Errno::EPIPE, IOError => e
445
+ # probably should log this.
446
+ nil
447
+ end
448
+ end
449
+ client = nil
450
+ @disconnected = auto_reconnect
451
+ end
452
+
453
+ def register_default_callbacks
454
+ client.add_message_callback do |message|
455
+ queue(:received_messages) << message unless message.body.nil?
456
+ end
457
+
458
+ roster.add_subscription_callback do |roster_item, presence|
459
+ if presence.type == :subscribed
460
+ queue(:new_subscriptions) << [roster_item, presence]
461
+ end
462
+ end
463
+
464
+ roster.add_subscription_request_callback do |roster_item, presence|
465
+ if accept_subscriptions?
466
+ roster.accept_subscription(presence.from)
467
+ else
468
+ queue(:subscription_requests) << [roster_item, presence]
469
+ end
470
+ end
471
+
472
+ @presence_updates = {}
473
+ @presence_mutex = Mutex.new
474
+ roster.add_presence_callback do |roster_item, old_presence, new_presence|
475
+ simple_jid = roster_item.jid.strip.to_s
476
+ presence = case new_presence.type
477
+ when nil: new_presence.show || :online
478
+ when :unavailable: :unavailable
479
+ else
480
+ nil
481
+ end
482
+
483
+ if presence && @presence_updates[simple_jid] != presence
484
+ queue(:presence_updates) << simple_jid
485
+ @presence_mutex.synchronize { @presence_updates[simple_jid] = [presence, new_presence.status] }
486
+ end
487
+ end
488
+ end
489
+
490
+ # This thread facilitates the delivery of messages to users who haven't yet
491
+ # accepted an invitation from us. When we attempt to deliver a message, if
492
+ # the user hasn't subscribed, we place the message in a queue for later
493
+ # delivery. Once a user has accepted our authorization request, we deliver
494
+ # any messages that have been queued up in the meantime.
495
+ def start_deferred_delivery_thread #:nodoc:
496
+ Thread.new {
497
+ loop {
498
+ messages = [queue(:pending_messages).pop].flatten
499
+ messages.each do |message|
500
+ if subscribed_to?(message[:to])
501
+ deliver(message[:to], message[:message], message[:type])
502
+ else
503
+ queue(:pending_messages) << message
504
+ end
505
+ end
506
+ }
507
+ }
508
+ end
509
+
510
+ def queue(queue)
511
+ @queues ||= Hash.new { |h,k| h[k] = Queue.new }
512
+ @queues[queue]
513
+ end
514
+
515
+ def dequeue(queue, non_blocking = true, max_items = 100, &block)
516
+ queue_items = []
517
+ max_items.times do
518
+ queue_item = queue(queue).pop(non_blocking) rescue nil
519
+ break if queue_item.nil?
520
+ queue_items << queue_item
521
+ yield queue_item if block_given?
522
+ end
523
+ queue_items
524
+ end
525
+ end
526
+ end
527
+
528
+ true
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/tunecore-announcer.rb'}"
9
+ puts "Loading tunecore-announcer gem"
10
+ exec "#{irb} #{libs} --simple-prompt"