hydna 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.
Files changed (4) hide show
  1. data/LICENSE +24 -0
  2. data/README.md +29 -0
  3. data/lib/hydna.rb +169 -0
  4. metadata +68 -0
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2012, Hydna AB
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of the Hydna AB nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL Hydna AB BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Hydna Ruby Client Library
2
+
3
+ This first version of our client library for Ruby implements support for the
4
+ Hydna Push API. Future versions will include support for the full set of
5
+ features.
6
+
7
+ More info: https://www.hydna.com/
8
+
9
+ ## Installation
10
+
11
+
12
+
13
+
14
+ ## Usage
15
+
16
+ The `hydna`-module exposes two functions:
17
+
18
+ require 'hydna'
19
+
20
+ begin
21
+ # sending messages
22
+ Hydna.push("https://public.hydna.net/4000", "Hello World")
23
+
24
+ # sending signals
25
+ Hydna.emit("https://public.hydna.net/4000", "Hello World")
26
+
27
+ rescue Exception => e
28
+ puts e.message
29
+ end
data/lib/hydna.rb ADDED
@@ -0,0 +1,169 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'net/https'
4
+
5
+ module Hydna
6
+
7
+ DEFAULT_CHANNEL = 1
8
+ MAX_PAYLOAD_SIZE = 10240;
9
+ MAX_CHANNEL_VALUE = 0xFFFFFFF
10
+ MAX_TOKEN_SIZE = 0xFFF8
11
+
12
+ def self.emit(domain, data, ctoken=nil, agent='hydna-ruby-push')
13
+
14
+ headers = {
15
+ 'Content-Type' => 'text/plain',
16
+ 'User-Agent' => agent,
17
+ 'X-Emit' => 'yes'
18
+ }
19
+
20
+ token = clean_token(ctoken)
21
+
22
+ if token != nil
23
+ headers['X-Token'] = token
24
+ end
25
+
26
+ send(domain, headers, data)
27
+
28
+ end
29
+
30
+ def self.push(domain, data, prio=1, ctoken=nil, agent='hydna-ruby-push')
31
+
32
+ headers = {
33
+ 'Content-Type' => 'text/plain',
34
+ 'User-Agent' => agent
35
+ }
36
+
37
+ token = clean_token(ctoken)
38
+
39
+ if token != nil
40
+ headers['X-Token'] = token
41
+ end
42
+
43
+ prio = clean_prio(prio)
44
+
45
+ headers['X-Priority'] = prio.to_s()
46
+
47
+ send(domain, headers, data)
48
+
49
+ end
50
+
51
+ private
52
+
53
+ def self.send(domain, headers, data)
54
+
55
+ uri = parse_uri(domain)
56
+
57
+ data = clean_payload(data)
58
+
59
+ http = Net::HTTP::new(uri['host'], uri['port'])
60
+
61
+ if uri['scheme'] == 'https'
62
+ http.use_ssl = true
63
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
64
+ end
65
+
66
+ path = "/%d/" % uri['channel']
67
+
68
+ if uri['token'] != nil
69
+ path = "%s?%s" % [path, uri['token']]
70
+ end
71
+
72
+ resp, body = http.post(path, data, headers)
73
+
74
+ if Integer(resp.code) != 200
75
+ raise resp.message
76
+ end
77
+
78
+ return true
79
+
80
+ end
81
+
82
+ def self.clean_prio(prio)
83
+ if !is_numeric(prio)
84
+ raise "Priority needs to be a number 1-4"
85
+ end
86
+
87
+ if prio < 0 or prio > 4
88
+ raise "Priority needs to be 1-4"
89
+ end
90
+
91
+ return prio
92
+ end
93
+
94
+ def self.clean_payload(data)
95
+
96
+ if data.bytesize == 0
97
+ raise "Payload expected"
98
+ end
99
+
100
+ if data.bytesize > MAX_PAYLOAD_SIZE:
101
+ raise "Payload exceeds maximum length allowed"
102
+ end
103
+
104
+ return data
105
+ end
106
+
107
+ def self.clean_token(token=nil)
108
+
109
+ if token == nil
110
+ return nil
111
+ end
112
+
113
+ if token.bytesize > MAX_TOKEN_SIZE
114
+ raise "Token exceeds maximum length allowed"
115
+ end
116
+
117
+ return token
118
+
119
+ end
120
+
121
+ def self.is_numeric(str)
122
+ begin Float(str) ; true end rescue false
123
+ end
124
+
125
+ def self.path_to_channel(query)
126
+ if query.length < 2
127
+ return DEFAULT_CHANNEL;
128
+ end
129
+
130
+ parts = query.split("/");
131
+
132
+ if parts.length > 3
133
+ raise "Unable to parse channel"
134
+ end
135
+
136
+ if !is_numeric(parts[1])
137
+ raise "Invalid channel"
138
+ end
139
+
140
+ channel = Integer(parts[1]);
141
+
142
+ if channel > MAX_CHANNEL_VALUE or channel <= 0
143
+ raise "Invalid channel"
144
+ end
145
+
146
+ return channel;
147
+ end
148
+
149
+ def self.parse_uri(domain)
150
+
151
+ if domain.index("http") == nil
152
+ domain = "http://%s" % domain
153
+ end
154
+
155
+ uri = URI.parse(domain)
156
+
157
+ channel = path_to_channel(uri.path)
158
+ token = clean_token(uri.query)
159
+
160
+ return {
161
+ 'scheme' => uri.scheme,
162
+ 'host' => uri.host,
163
+ 'channel' => channel,
164
+ 'token' => token,
165
+ 'port' => uri.port
166
+ }
167
+
168
+ end
169
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hydna
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - "Isak Wistr\xC3\xB6m"
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-04-11 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: Hydna exposes a straightforward API over HTTP. It uses a single resource; sending messages is done by making POST requests to the same URI you'd use to connect to Hydna in any client library.
22
+ email: iw@hydna.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - LICENSE
29
+ - README.md
30
+ files:
31
+ - LICENSE
32
+ - README.md
33
+ - lib/hydna.rb
34
+ homepage: https://github.com/hydna/hydna-ruby
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ hash: 3
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.21
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Bindings for hydna push API.
67
+ test_files: []
68
+