ruby-smpp 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/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +35 -0
- data/README.txt +86 -0
- data/Rakefile +9 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +15 -0
- data/examples/sample_gateway.rb +120 -0
- data/lib/smpp.rb +21 -0
- data/lib/smpp/base.rb +124 -0
- data/lib/smpp/pdu/base.rb +140 -0
- data/lib/smpp/pdu/bind_transceiver.rb +6 -0
- data/lib/smpp/pdu/bind_transceiver_response.rb +7 -0
- data/lib/smpp/pdu/deliver_sm.rb +40 -0
- data/lib/smpp/pdu/deliver_sm_response.rb +5 -0
- data/lib/smpp/pdu/enquire_link.rb +5 -0
- data/lib/smpp/pdu/enquire_link_response.rb +5 -0
- data/lib/smpp/pdu/generic_nack.rb +8 -0
- data/lib/smpp/pdu/submit_sm.rb +44 -0
- data/lib/smpp/pdu/submit_sm_response.rb +8 -0
- data/lib/smpp/pdu/unbind.rb +5 -0
- data/lib/smpp/pdu/unbind_response.rb +5 -0
- data/lib/smpp/transceiver.rb +97 -0
- data/lib/smpp/version.rb +9 -0
- data/lib/sms.rb +9 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/test/smpp_test.rb +54 -0
- data/test/test_helper.rb +2 -0
- metadata +100 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# PDUs are the protcol base units in SMPP
|
|
2
|
+
module Smpp::Pdu
|
|
3
|
+
class Base
|
|
4
|
+
# Error constants
|
|
5
|
+
ESME_ROK = 0x00000000 # OK!
|
|
6
|
+
ESME_RINVMSGLEN = 0x00000001 # Message Length is invalid
|
|
7
|
+
ESME_RINVCMDLEN = 0x00000002 # Command Length is invalid
|
|
8
|
+
ESME_RINVCMDID = 0x00000003 # Invalid Command ID
|
|
9
|
+
ESME_RINVBNDSTS = 0x00000004 # Incorrect BIND Status for given com-
|
|
10
|
+
ESME_RALYBND = 0x00000005 # ESME Already in Bound State
|
|
11
|
+
ESME_RINVPRTFLG = 0x00000006 # Invalid Priority Flag
|
|
12
|
+
ESME_RINVREGDLVFLG = 0x00000007 # Invalid Registered Delivery Flag
|
|
13
|
+
ESME_RSYSERR = 0x00000008 # System Error
|
|
14
|
+
ESME_RINVSRCADR = 0x0000000A # Invalid Source Address
|
|
15
|
+
ESME_RINVDSTADR = 0x0000000B # Invalid Dest Addr
|
|
16
|
+
ESME_RINVMSGID = 0x0000000C # Message ID is invalid
|
|
17
|
+
ESME_RBINDFAIL = 0x0000000D # Bind Failed
|
|
18
|
+
ESME_RINVPASWD = 0x0000000E # Invalid Password
|
|
19
|
+
ESME_RINVSYSID = 0x0000000F # Invalid System ID
|
|
20
|
+
ESME_RCANCELFAIL = 0x00000011 # Cancel SM Failed
|
|
21
|
+
ESME_RREPLACEFAIL = 0x00000013 # Replace SM Failed
|
|
22
|
+
ESME_RMSGQFUL = 0x00000014 # Message Queue Full
|
|
23
|
+
ESME_RINVSERTYP = 0x00000015 # Invalid Service Type
|
|
24
|
+
ESME_RINVNUMDESTS = 0x00000033 # Invalid number of destinations
|
|
25
|
+
ESME_RINVDLNAME = 0x00000034 # Invalid Distribution List name
|
|
26
|
+
ESME_RINVDESTFLAG = 0x00000040 # Destination flag is invalid
|
|
27
|
+
ESME_RINVSUBREP = 0x00000042 # Invalid ‘submit with replace’ request
|
|
28
|
+
ESME_RINVESMCLASS = 0x00000043 # Invalid esm_class field data
|
|
29
|
+
ESME_RCNTSUBDL = 0x00000044 # Cannot Submit to Distribution List
|
|
30
|
+
ESME_RSUBMITFAIL = 0x00000045 # submit_sm or submit_multi failed
|
|
31
|
+
ESME_RINVSRCTON = 0x00000048 # Invalid Source address TON
|
|
32
|
+
ESME_RINVSRCNPI = 0x00000049 # Invalid Source address NPI
|
|
33
|
+
ESME_RINVDSTTON = 0x00000050 # Invalid Destination address TON
|
|
34
|
+
ESME_RINVDSTNPI = 0x00000051 # Invalid Destination address NPI
|
|
35
|
+
ESME_RINVSYSTYP = 0x00000053 # Invalid system_type field
|
|
36
|
+
ESME_RINVREPFLAG = 0x00000054 # Invalid replace_if_present flag
|
|
37
|
+
ESME_RINVNUMMSGS = 0x00000055 # Invalid number of messages
|
|
38
|
+
ESME_RTHROTTLED = 0x00000058 # Throttling error (ESME has exceeded allowed message limits)
|
|
39
|
+
|
|
40
|
+
# PDU types
|
|
41
|
+
GENERIC_NACK = 0X80000000
|
|
42
|
+
BIND_RECEIVER = 0X00000001
|
|
43
|
+
BIND_RECEIVER_RESP = 0X80000001
|
|
44
|
+
BIND_TRANSMITTER = 0X00000002
|
|
45
|
+
BIND_TRANSMITTER_RESP = 0X80000002
|
|
46
|
+
BIND_TRANSCEIVER = 0X00000009
|
|
47
|
+
BIND_TRANSCEIVER_RESP = 0X80000009
|
|
48
|
+
QUERY_SM = 0X00000003
|
|
49
|
+
QUERY_SM_RESP = 0X80000003
|
|
50
|
+
SUBMIT_SM = 0X00000004
|
|
51
|
+
SUBMIT_SM_RESP = 0X80000004
|
|
52
|
+
DELIVER_SM = 0X00000005
|
|
53
|
+
DELIVER_SM_RESP = 0X80000005
|
|
54
|
+
UNBIND = 0X00000006
|
|
55
|
+
UNBIND_RESP = 0X80000006
|
|
56
|
+
REPLACE_SM = 0X00000007
|
|
57
|
+
REPLACE_SM_RESP = 0X80000007
|
|
58
|
+
CANCEL_SM = 0X00000008
|
|
59
|
+
CANCEL_SM_RESP = 0X80000008
|
|
60
|
+
ENQUIRE_LINK = 0X00000015
|
|
61
|
+
ENQUIRE_LINK_RESP = 0X80000015
|
|
62
|
+
|
|
63
|
+
# PDU sequence number.
|
|
64
|
+
@@seq = [Time.now.to_i]
|
|
65
|
+
|
|
66
|
+
# Add monitor to sequence counter for thread safety
|
|
67
|
+
@@seq.extend(MonitorMixin)
|
|
68
|
+
|
|
69
|
+
attr_reader :command_id, :command_status, :sequence_number, :body, :data
|
|
70
|
+
|
|
71
|
+
def initialize(command_id, command_status, seq, body='')
|
|
72
|
+
length = 16 + body.length
|
|
73
|
+
@command_id = command_id
|
|
74
|
+
@command_status = command_status
|
|
75
|
+
@body = body
|
|
76
|
+
@sequence_number = seq
|
|
77
|
+
@data = fixed_int(length) + fixed_int(command_id) + fixed_int(command_status) + fixed_int(seq) + body
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def logger
|
|
81
|
+
Smpp::Base.logger
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def to_human
|
|
85
|
+
# convert header (4 bytes) to array of 4-byte ints
|
|
86
|
+
a = @data.to_s.unpack('N4')
|
|
87
|
+
sprintf("(%22s) len=%3d cmd=%8s status=%1d seq=%03d (%s)", self.class.to_s[11..-1], a[0], a[1].to_s(16), a[2], a[3], @body)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# return int as binary string of 4 octets
|
|
91
|
+
def fixed_int(value)
|
|
92
|
+
sprintf("%c%c%c%c", value >> 24, value >> 16, value >> 8, value & 0xff)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def next_sequence_number
|
|
96
|
+
Base.next_sequence_number
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def Base.next_sequence_number
|
|
100
|
+
@@seq.synchronize do
|
|
101
|
+
(@@seq[0] += 1) % 512
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# PDU factory method for common client PDUs (used to create PDUs from wire data)
|
|
106
|
+
def Base.create(data)
|
|
107
|
+
header = data[0..15]
|
|
108
|
+
if !header
|
|
109
|
+
return nil
|
|
110
|
+
end
|
|
111
|
+
len, cmd, status, seq = header.unpack('N4')
|
|
112
|
+
body = data[16..-1]
|
|
113
|
+
case cmd
|
|
114
|
+
when ENQUIRE_LINK:
|
|
115
|
+
EnquireLink.new(seq)
|
|
116
|
+
when ENQUIRE_LINK_RESP:
|
|
117
|
+
EnquireLinkResponse.new(seq)
|
|
118
|
+
when GENERIC_NACK:
|
|
119
|
+
GenericNack.new(seq, status, body)
|
|
120
|
+
when UNBIND:
|
|
121
|
+
Unbind.new(seq)
|
|
122
|
+
when UNBIND_RESP:
|
|
123
|
+
UnbindResponse.new(seq, status)
|
|
124
|
+
when BIND_TRANSMITTER_RESP:
|
|
125
|
+
BindTransmitterResponse.new(seq, status, body) # could be opt'l params too
|
|
126
|
+
when BIND_RECEIVER_RESP:
|
|
127
|
+
BindReceiverResponse.new(seq, status, body)
|
|
128
|
+
when BIND_TRANSCEIVER_RESP:
|
|
129
|
+
BindTransceiverResponse.new(seq, status, body)
|
|
130
|
+
when SUBMIT_SM_RESP:
|
|
131
|
+
SubmitSmResponse.new(seq, status, body)
|
|
132
|
+
when DELIVER_SM:
|
|
133
|
+
DeliverSm.new(seq, status, body)
|
|
134
|
+
else
|
|
135
|
+
Smpp::Base.logger.error "Unknown PDU: 0x#{cmd.to_s(16)}"
|
|
136
|
+
return nil
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class Smpp::Pdu::BindTransceiver < Smpp::Pdu::Base
|
|
2
|
+
def initialize(system_id, password, addr_ton, addr_npi, address_range)
|
|
3
|
+
body = sprintf("%s\0%s\0\0%c%c%c%s\0", system_id, password, 0x34, addr_ton, addr_npi, address_range)
|
|
4
|
+
super(BIND_TRANSCEIVER, 0, next_sequence_number, body)
|
|
5
|
+
end
|
|
6
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Received for MO message or delivery notification
|
|
2
|
+
class Smpp::Pdu::DeliverSm < Smpp::Pdu::Base
|
|
3
|
+
attr_reader :source_addr, :destination_addr, :short_message, :source_addr, :esm_class, :msg_reference, :stat
|
|
4
|
+
def initialize(seq, status, body)
|
|
5
|
+
# brutally unpack it
|
|
6
|
+
service_type,
|
|
7
|
+
source_addr_ton,
|
|
8
|
+
source_addr_npi,
|
|
9
|
+
@source_addr,
|
|
10
|
+
dest_addr_ton,
|
|
11
|
+
dest_addr_npi,
|
|
12
|
+
@destination_addr,
|
|
13
|
+
@esm_class,
|
|
14
|
+
protocol_id,
|
|
15
|
+
priority_flag,
|
|
16
|
+
schedule_delivery_time,
|
|
17
|
+
validity_period,
|
|
18
|
+
registered_delivery,
|
|
19
|
+
replace_if_present_flag,
|
|
20
|
+
data_coding,
|
|
21
|
+
sm_default_msg_id,
|
|
22
|
+
sm_length,
|
|
23
|
+
@short_message = body.unpack('Z*CCZ*CCZ*CCCZ*Z*CCCCCa*')
|
|
24
|
+
logger.debug "DeliverSM with source_addr=#{@source_addr}, destination_addr=#{@destination_addr}"
|
|
25
|
+
|
|
26
|
+
# Note: if the SM is a delivery receipt (esm_class=4) then the short_message _may_ be in this format:
|
|
27
|
+
# "id:Smsc2013 sub:1 dlvrd:1 submit date:0610171515 done date:0610171515 stat:0 err:0 text:blah"
|
|
28
|
+
# or this format:
|
|
29
|
+
# "4790000000SMSAlert^id:1054BC63 sub:0 dlvrd:1 submit date:0610231217 done date:0610231217 stat:DELIVRD err: text:"
|
|
30
|
+
# (according to the SMPP spec, the format is vendor specific)
|
|
31
|
+
# For example, Tele2 (Norway):
|
|
32
|
+
# "<msisdn><shortcode>?id:10ea34755d3d4f7a20900cdb3349e549 sub:001 dlvrd:001 submit date:0611011228 done date:0611011230 stat:DELIVRD err:000 Text:abc'!10ea34755d3d4f7a20900cdb3349e549"
|
|
33
|
+
if @esm_class == 4
|
|
34
|
+
@msg_reference = @short_message.scanf('id:%s').to_s
|
|
35
|
+
# @stat must be parsed according to the SMSC vendor's specifications (see comment above)
|
|
36
|
+
@stat = 0
|
|
37
|
+
end
|
|
38
|
+
super(DELIVER_SM, status, seq, body)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# signals invalid message header
|
|
2
|
+
class Smpp::Pdu::GenericNack < Smpp::Pdu::Base
|
|
3
|
+
attr_accessor :error_code
|
|
4
|
+
def initialize(seq, error_code, original_sequence_code)
|
|
5
|
+
super(GENERIC_NACK, error_code, seq, "Error: #{error_code} Problem sequence: #{original_sequence_code.blank? ? 'unknown' : original_sequence_code }")
|
|
6
|
+
@error_code = error_code
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Sending an MT message
|
|
2
|
+
class Smpp::Pdu::SubmitSm < Smpp::Pdu::Base
|
|
3
|
+
|
|
4
|
+
# Note: short_message (the SMS body) must be in iso-8859-1 format
|
|
5
|
+
def initialize(source_addr, destination_addr, short_message, options={})
|
|
6
|
+
options.merge!(
|
|
7
|
+
:esm_class => 0, # default smsc mode
|
|
8
|
+
:dcs => 3 # iso-8859-1
|
|
9
|
+
) { |key, old_val, new_val| old_val }
|
|
10
|
+
|
|
11
|
+
@msg_body = short_message
|
|
12
|
+
|
|
13
|
+
udh = options[:udh]
|
|
14
|
+
service_type = ''
|
|
15
|
+
source_addr_ton = 0 # network specific
|
|
16
|
+
source_addr_npi = 1 # unknown
|
|
17
|
+
dest_addr_ton = 1 # international
|
|
18
|
+
dest_addr_npi = 1 # unknown
|
|
19
|
+
esm_class = options[:esm_class]
|
|
20
|
+
protocol_id = 0
|
|
21
|
+
priority_flag = 1
|
|
22
|
+
schedule_delivery_time = ''
|
|
23
|
+
validity_period = ''
|
|
24
|
+
registered_delivery = 1 # we want delivery notifications
|
|
25
|
+
replace_if_present_flag = 0
|
|
26
|
+
data_coding = options[:dcs]
|
|
27
|
+
sm_default_msg_id = 0
|
|
28
|
+
payload = udh ? udh + short_message : (short_message + "\0")
|
|
29
|
+
sm_length = payload.length
|
|
30
|
+
|
|
31
|
+
# craft the string/byte buffer
|
|
32
|
+
pdu_body = sprintf("%s\0%c%c%s\0%c%c%s\0%c%c%c%s\0%s\0%c%c%c%c%c%s", service_type, source_addr_ton, source_addr_npi, source_addr,
|
|
33
|
+
dest_addr_ton, dest_addr_npi, destination_addr, esm_class, protocol_id, priority_flag, schedule_delivery_time, validity_period,
|
|
34
|
+
registered_delivery, replace_if_present_flag, data_coding, sm_default_msg_id, sm_length, payload)
|
|
35
|
+
super(SUBMIT_SM, 0, next_sequence_number, pdu_body)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# some special formatting is needed for SubmitSm PDUs to show the actual message content
|
|
39
|
+
def to_human
|
|
40
|
+
# convert header (4 bytes) to array of 4-byte ints
|
|
41
|
+
a = @data.to_s.unpack('N4')
|
|
42
|
+
sprintf("(%22s) len=%3d cmd=%8s status=%1d seq=%03d (%s)", self.class.to_s[11..-1], a[0], a[1].to_s(16), a[2], a[3], @msg_body[0..30])
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
class Smpp::Transceiver < Smpp::Base
|
|
2
|
+
|
|
3
|
+
# Expects a config hash,
|
|
4
|
+
# a proc to invoke for incoming (MO) messages,
|
|
5
|
+
# a proc to invoke for delivery reports,
|
|
6
|
+
# and optionally a hash-like storage for pending delivery reports.
|
|
7
|
+
def initialize(config, mo_proc, dr_proc, pdr_storage={})
|
|
8
|
+
super(config)
|
|
9
|
+
@state = :unbound
|
|
10
|
+
@mo_proc = mo_proc
|
|
11
|
+
@dr_proc = dr_proc
|
|
12
|
+
@pdr_storage = pdr_storage
|
|
13
|
+
|
|
14
|
+
# Array of un-acked MT message IDs indexed by sequence number.
|
|
15
|
+
# As soon as we receive SubmitSmResponse we will use this to find the
|
|
16
|
+
# associated message ID, and then create a pending delivery report.
|
|
17
|
+
@ack_ids = Array.new(512)
|
|
18
|
+
|
|
19
|
+
ed = @config[:enquire_link_delay_secs] || 5
|
|
20
|
+
comm_inactivity_timeout = [ed - 5, 3].max
|
|
21
|
+
rescue Exception => ex
|
|
22
|
+
logger.error "Exception setting up transceiver: #{ex}"
|
|
23
|
+
raise
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Send an MT SMS message
|
|
27
|
+
def send_mt(message_id, source_addr, destination_addr, short_message, options={})
|
|
28
|
+
logger.debug "Sending MT: #{short_message}"
|
|
29
|
+
if @state == :bound
|
|
30
|
+
pdu = Pdu::SubmitSm.new(source_addr, destination_addr, short_message, options)
|
|
31
|
+
write_pdu pdu
|
|
32
|
+
|
|
33
|
+
# keep the message ID so we can associate the SMSC message ID with our message
|
|
34
|
+
# when the response arrives.
|
|
35
|
+
@ack_ids[pdu.sequence_number] = message_id
|
|
36
|
+
else
|
|
37
|
+
raise InvalidStateException, "Transceiver is unbound. Cannot send MT messages."
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# a PDU is received
|
|
42
|
+
def process_pdu(pdu)
|
|
43
|
+
case pdu
|
|
44
|
+
when Pdu::DeliverSm
|
|
45
|
+
write_pdu(Pdu::DeliverSmResponse.new(pdu.sequence_number))
|
|
46
|
+
logger.debug "ESM CLASS #{pdu.esm_class}"
|
|
47
|
+
if pdu.esm_class != 4
|
|
48
|
+
# MO message; invoke MO proc
|
|
49
|
+
@mo_proc.call(pdu.source_addr, pdu.destination_addr, pdu.short_message)
|
|
50
|
+
else
|
|
51
|
+
# Invoke DR proc (let the owner of the block do the mapping from msg_reference to mt_id)
|
|
52
|
+
@dr_proc.call(pdu.msg_reference.to_s, pdu.stat)
|
|
53
|
+
end
|
|
54
|
+
when Pdu::BindTransceiverResponse
|
|
55
|
+
case pdu.command_status
|
|
56
|
+
when Pdu::Base::ESME_ROK
|
|
57
|
+
logger.debug "Bound OK."
|
|
58
|
+
@state = :bound
|
|
59
|
+
when Pdu::Base::ESME_RINVPASWD
|
|
60
|
+
logger.warn "Invalid password."
|
|
61
|
+
EventMachine::stop_event_loop
|
|
62
|
+
when Pdu::Base::ESME_RINVSYSID
|
|
63
|
+
logger.warn "Invalid system id."
|
|
64
|
+
EventMachine::stop_event_loop
|
|
65
|
+
else
|
|
66
|
+
logger.warn "Unexpected BindTransceiverResponse. Command status: #{pdu.command_status}"
|
|
67
|
+
EventMachine::stop_event_loop
|
|
68
|
+
end
|
|
69
|
+
when Pdu::SubmitSmResponse
|
|
70
|
+
mt_message_id = @ack_ids[pdu.sequence_number]
|
|
71
|
+
if !mt_message_id
|
|
72
|
+
raise "Got SubmitSmResponse for unknown sequence_number: #{pdu.sequence_number}"
|
|
73
|
+
end
|
|
74
|
+
if pdu.command_status != Pdu::Base::ESME_ROK
|
|
75
|
+
logger.error "Error status in SubmitSmResponse: #{pdu.command_status}"
|
|
76
|
+
else
|
|
77
|
+
logger.info "Got OK SubmitSmResponse (#{pdu.message_id} -> #{mt_message_id})"
|
|
78
|
+
end
|
|
79
|
+
# Now we got the SMSC message id; create pending delivery report
|
|
80
|
+
@pdr_storage[pdu.message_id] = mt_message_id
|
|
81
|
+
else
|
|
82
|
+
super
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Send BindTransceiverResponse PDU.
|
|
87
|
+
def send_bind
|
|
88
|
+
raise IOError, 'Receiver already bound.' unless @state == :unbound
|
|
89
|
+
pdu = Pdu::BindTransceiver.new(
|
|
90
|
+
@config[:system_id],
|
|
91
|
+
@config[:password],
|
|
92
|
+
@config[:source_ton],
|
|
93
|
+
@config[:source_npi],
|
|
94
|
+
@config[:source_address_range])
|
|
95
|
+
write_pdu(pdu)
|
|
96
|
+
end
|
|
97
|
+
end
|
data/lib/smpp/version.rb
ADDED
data/lib/sms.rb
ADDED
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/ruby-smpp.rb'}"
|
|
9
|
+
puts "Loading ruby-smpp gem"
|
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rubigen'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
require 'rubigen'
|
|
9
|
+
end
|
|
10
|
+
require 'rubigen/scripts/destroy'
|
|
11
|
+
|
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|