ramp 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ramp.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Sameer Rahmani
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Ramp
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'ramp'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install ramp
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,192 @@
1
+ # -----------------------------------------------------------------------------
2
+ # RAMP - AMP protocol client implementation in Ruby
3
+ # Copyright (C) 2012 Yellowen
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program; if not, write to the Free Software Foundation, Inc.,
17
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ # -----------------------------------------------------------------------------
19
+
20
+ module Ramp
21
+
22
+ class Command
23
+
24
+ # EignClass -------------------------------------
25
+ class << self
26
+
27
+ attr_accessor :arguments_hash, :responses_hash, :command_name
28
+
29
+ def arguments args
30
+ @arguments_hash = args
31
+ end
32
+
33
+ def responses args
34
+ @responses_hash = args
35
+ end
36
+
37
+ def command name
38
+ @command_name = name
39
+ end
40
+
41
+ def loads(data)
42
+ # Construct a hash from given data and return it
43
+ buffer = data.to_s.bytes.to_a
44
+ pos = 0
45
+ result = {}
46
+
47
+ while 1 do
48
+
49
+ # Parse the next key length
50
+ key_length = 0
51
+ buffer[pos..pos + 1].each {|x| key_length += x}
52
+
53
+ if key_length > 255
54
+ raise TypeError, "malform packet."
55
+ end
56
+
57
+ if key_length == 0
58
+ # key length of 0 means end of package.
59
+ break
60
+ end
61
+
62
+ pos += 2
63
+ # Read the key
64
+ key = buffer[pos..pos + key_length - 1].pack("c*")
65
+
66
+ # Parse next value length
67
+ pos += key_length
68
+ value_length = 0
69
+ buffer[pos..pos + 1].each {|x| value_length += x}
70
+
71
+ # Read the value
72
+ pos += 2
73
+ value = buffer[pos..pos + value_length - 1].pack("c*")
74
+ pos += value_length
75
+ result[key.to_sym] = value
76
+
77
+ end
78
+
79
+ result
80
+ end
81
+ end
82
+
83
+ # Public -------------------------------------
84
+
85
+ # A Class variable (static attribute) to hold the asks sequences
86
+ @@ask_seqs = []
87
+
88
+ attr_reader :values
89
+
90
+ def initialize (args)
91
+ # Initialize an object with provided values for fields defined in
92
+ # @arguments using argument class method
93
+ @values = {}
94
+ @buffer = []
95
+
96
+ @_args = args
97
+
98
+ kwargs = Hash[args.map{|k, v|[k.to_sym, v]}]
99
+ if kwargs.include? :_ask or kwargs.include? :_command
100
+ raise ArgumentError, "':_ask' and ':_command' should not be in arguments"
101
+ end
102
+
103
+ kwargs.each do |key, value|
104
+
105
+ # Check for key validation
106
+ if not self.class.arguments_hash.include? key
107
+ raise ArgumentError, "'#{key}' is not defined in '#{self.class}'."
108
+ end
109
+
110
+
111
+ # Construct the values ivar
112
+ @values[key.to_sym] = self.class.arguments_hash[key.to_sym].new value
113
+ end
114
+
115
+ # Build a AMP packet data from kwargs hash for more information about
116
+ # amp protocol structure take a look at:
117
+ # http://www.amp-protocol.net
118
+
119
+ @values[:_command] = self.class.command_name
120
+
121
+ while 1 do
122
+ # TODO: is it safe in logic ?
123
+ ask = rand(999999)
124
+ if not @@ask_seqs.include? ask
125
+ @@ask_seqs << ask
126
+ break
127
+ end
128
+ end
129
+
130
+ @values[:_ask] = ask
131
+ # Generate the packet data and store it into @buffer
132
+ generate_packet
133
+
134
+ end
135
+
136
+
137
+ def to_s
138
+
139
+ @buffer.pack("c*")
140
+ end
141
+
142
+ def to_a
143
+ @buffer
144
+ end
145
+
146
+ def ask
147
+ @values[:_ask]
148
+ end
149
+
150
+ def dup
151
+ self.class.new @_args
152
+ end
153
+
154
+ def callback (*)
155
+ # Each subclass may override this method to have a callback
156
+ # when any answer recieved.
157
+ nil
158
+ end
159
+
160
+ # Exceptions ------------------------------------------------
161
+ class KeyLenError < StandardError
162
+ end
163
+
164
+ private
165
+ # Private definations ---------------------------------------
166
+ def split_bytes (hex)
167
+ hex.each_char.each_slice(2).map {|x| x.join}
168
+ end
169
+
170
+ def generate_packet()
171
+ @values.each do |key, value|
172
+
173
+ if key.length > 255
174
+ raise KeyLenError, "AMP keys should have 255 byte max kength"
175
+ end
176
+
177
+ [0, key.to_s.bytes.to_a.length].each {|x| @buffer << x}
178
+ key.to_s.bytes.to_a.each {|x| @buffer << x}
179
+
180
+ value_lenght = split_bytes "%04x" % value.to_s.bytes.to_a.length.to_s(16)
181
+ @buffer << value_lenght[0].to_i
182
+ @buffer << value_lenght[1].to_i
183
+
184
+
185
+ value.to_s.bytes.to_a.each {|x| @buffer << x}
186
+ end
187
+
188
+ [0x00, 0x00].each {|x| @buffer << x}
189
+ end
190
+
191
+ end
192
+ end
@@ -0,0 +1,54 @@
1
+ # -----------------------------------------------------------------------------
2
+ # RAMP - AMP protocol client implementation in Ruby
3
+ # Copyright (C) 2012 Yellowen
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program; if not, write to the Free Software Foundation, Inc.,
17
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ # -----------------------------------------------------------------------------
19
+
20
+ module Ramp
21
+ module Fields
22
+
23
+ class StringField < String
24
+
25
+ def self.to_o data
26
+ String.new data
27
+ end
28
+
29
+ end
30
+
31
+ class IntegerField < Integer
32
+
33
+ def self.to_o data
34
+ Integer.new data
35
+ end
36
+
37
+ end
38
+
39
+ class JsonField < Hash
40
+
41
+ require 'json'
42
+
43
+ def to_s
44
+ JSON.dump(self)
45
+ end
46
+
47
+ def self.to_o data
48
+ JSON.load(data)
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ module Ramp
2
+ VERSION = "0.1.1"
3
+ end
data/lib/ramp.rb ADDED
@@ -0,0 +1,120 @@
1
+ # -----------------------------------------------------------------------------
2
+ # RAMP - AMP protocol client implementation in Ruby
3
+ # Copyright (C) 2012 Yellowen
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program; if not, write to the Free Software Foundation, Inc.,
17
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ # -----------------------------------------------------------------------------
19
+ require 'socket'
20
+
21
+ require "ramp/version"
22
+ require "ramp/command.rb"
23
+ require "ramp/fields.rb"
24
+
25
+
26
+ module Ramp
27
+ # Ramp module
28
+
29
+ class AmpClient
30
+ # AmpClient class is responsble for establishing a connection to a AMPserver
31
+
32
+ @@sent_packets = Hash.new
33
+
34
+ def initialize (host, port, kwargs={secure: false,
35
+ ssl_key: nil,
36
+ ssl_cert:nil,
37
+ async: false})
38
+
39
+ @async = kwargs[:async]
40
+ @secure = kwargs[:secure]
41
+ @ssl_key = kwargs[:ssl_key]
42
+ @ssl_cert = kwargs[:ssl_cert]
43
+
44
+ @host = host
45
+ @port = port
46
+
47
+ make_connection
48
+
49
+ end
50
+
51
+ def call_remote(command, kwargs)
52
+
53
+ # Create a new command instance
54
+ obj = command.new kwargs
55
+
56
+ # Add the curretn command instance to the sent hash
57
+ @@sent_packets[obj.ask] = obj
58
+
59
+ if @async
60
+ t = Thread.new {
61
+ transfer obj.to_s
62
+ }
63
+ t.abort_on_exception = true
64
+ t.run
65
+ else
66
+ transfer obj.to_s
67
+ end
68
+
69
+ end
70
+
71
+ # Private members -----------------------------------
72
+ private
73
+
74
+ def make_connection
75
+
76
+ begin
77
+ socket = TCPSocket.new @host, @port
78
+ rescue Errno::ECONNREFUSED
79
+ abort("Connection Refused")
80
+ end
81
+
82
+ if @secure
83
+ ctx = OpenSSL::SSL::SSLContext.new()
84
+ ctx.cert = OpenSSL::X509::Certificate.new(File.open(@ssl_cert))
85
+ ctx.key = OpenSSL::PKey::RSA.new(File.open(@ssl_key))
86
+ ctx.ssl_version = :SSLv23
87
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ctx)
88
+ ssl_socket.sync_close = true
89
+ ssl_socket.connect
90
+ @socket = ssl_socket
91
+ return
92
+
93
+ end
94
+
95
+ @socket = socket
96
+
97
+ end
98
+
99
+ def transfer data
100
+ # send the encoded data across the net
101
+ @socket.syswrite(data)
102
+ # TODO: Should i specify a recieving limitation ?
103
+ rawdata = @socket.recv(1024)
104
+ data = Command::loads(rawdata)
105
+
106
+ if data.include? :_answer
107
+ if @@sent_packets.keys.include? data
108
+ @@sent_packets[data[:_answer]].callback(data)
109
+ end
110
+ elsif data.include? :_error
111
+ # Generate an exception from _error_code and rise it
112
+ exception = Object.const_set(data[:_error_code], Class.new(StandardError))
113
+ raise exception, data[:_error_description]
114
+ end
115
+
116
+ end
117
+
118
+ end
119
+
120
+ end
data/ramp.gemspec ADDED
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/ramp/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Sameer Rahmani"]
6
+ gem.email = ["lxsameer@gnu.org"]
7
+ gem.description = %q{AMP protocol implementation in Ruby. For more information about AMP protocol take a look at http://amp-protocol.net/}
8
+ gem.summary = %q{AMP protocol implementation in Ruby}
9
+ gem.homepage = "http://ramp.yellowen.com/"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "ramp"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Ramp::VERSION
17
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ramp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sameer Rahmani
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-08 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: AMP protocol implementation in Ruby. For more information about AMP protocol
15
+ take a look at http://amp-protocol.net/
16
+ email:
17
+ - lxsameer@gnu.org
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - LICENSE
25
+ - README.md
26
+ - Rakefile
27
+ - lib/ramp.rb
28
+ - lib/ramp/command.rb
29
+ - lib/ramp/fields.rb
30
+ - lib/ramp/version.rb
31
+ - ramp.gemspec
32
+ homepage: http://ramp.yellowen.com/
33
+ licenses: []
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 1.8.24
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: AMP protocol implementation in Ruby
56
+ test_files: []