weechat-relay-helper 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +19 -0
- data/README.md +11 -0
- data/bin/weechat-relay-helper +34 -0
- data/lib/weechat-relay-helper.rb +10 -0
- data/lib/weechat-relay-helper/connection.rb +59 -0
- data/lib/weechat-relay-helper/options.rb +30 -0
- data/lib/weechat-relay-helper/response.rb +169 -0
- data/lib/weechat-relay-helper/version.rb +3 -0
- data/lib/weechat-relay-helper/weechat.rb +11 -0
- metadata +72 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c187a206f928f03e18d479e405791914e2132ebe
|
4
|
+
data.tar.gz: e21cffba12ef157aa5edc15814b21d0051493ac9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: afce2a81fd0df1ef3df0af86b87f5ca2b7771293437a69c3d697cb39f13d8c0a47b988924a71a50c0e2c0658ec0c2a093dce7cc9aa575278b34df34e96f89950
|
7
|
+
data.tar.gz: 015d94bebb0b7ae157fca8b3b0e69b495f241038d17f5ddf6b3e13952fbc069f4621d9e36a289a6312c510cf725aac1bce8618cadc7953d516d64fb0d8586d19
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2014 Rylee Fowler
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
weechat-relay-helper
|
2
|
+
====================
|
3
|
+
|
4
|
+
Simple utility to assist in the creation of applications that interface with the Weechat relay protocol, such as mobile apps or web-apps.
|
5
|
+
|
6
|
+
##[Demo run (on asciinema)](https://asciinema.org/a/10649)
|
7
|
+
|
8
|
+
TODO
|
9
|
+
----
|
10
|
+
- [ ] hdata support
|
11
|
+
- [ ] Less awful asynchronous networking
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# License details in LICENSE.
|
3
|
+
require 'readline'
|
4
|
+
require 'awesome_print'
|
5
|
+
require 'weechat-relay-helper'
|
6
|
+
|
7
|
+
opts = RelayHelper::Options.new ARGV
|
8
|
+
conn = RelayHelper::Weechat.new opts.host, opts.port, opts.ssl, opts.compression, opts.password
|
9
|
+
|
10
|
+
Thread.new do
|
11
|
+
loop do #until conn.connection.closed?
|
12
|
+
begin
|
13
|
+
r, _, _ = IO.select [conn.connection.socket]
|
14
|
+
unless r.empty?
|
15
|
+
len = conn.connection.read(4)
|
16
|
+
rest = conn.connection.read(len.unpack('L>')[0] - 4)
|
17
|
+
r = RelayHelper::Response.new(len + rest)
|
18
|
+
ap({ id: r.id, data: r.data })
|
19
|
+
end
|
20
|
+
rescue OpenSSL::SSL::SSLErrorWaitReadable, IO::EAGAINWaitReadable => e
|
21
|
+
pass
|
22
|
+
rescue Exception => e
|
23
|
+
puts e.backtrace
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
puts "Go ahead and type your commands."
|
29
|
+
puts "Relay reference is located at http://www.weechat.org/files/doc/devel/weechat_relay_protocol.en.html"
|
30
|
+
|
31
|
+
while line = Readline.readline('', true)
|
32
|
+
conn.connection.puts line
|
33
|
+
puts "--> #{line}"
|
34
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# License details in LICENSE
|
2
|
+
require 'zlib'
|
3
|
+
require 'optparse'
|
4
|
+
require 'openssl'
|
5
|
+
require 'socket'
|
6
|
+
|
7
|
+
require 'weechat-relay-helper/response'
|
8
|
+
require 'weechat-relay-helper/options'
|
9
|
+
require 'weechat-relay-helper/connection'
|
10
|
+
require 'weechat-relay-helper/weechat'
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# License details in LICENSE
|
2
|
+
module RelayHelper
|
3
|
+
class Connection
|
4
|
+
attr_reader :socket
|
5
|
+
def initialize host, port, ssl
|
6
|
+
@host = host
|
7
|
+
@port = port
|
8
|
+
@ssl = ssl
|
9
|
+
end
|
10
|
+
def establish_plaintext_connection host, port
|
11
|
+
TCPSocket.open(host, port)
|
12
|
+
end
|
13
|
+
def establish_ssl_connection host, port
|
14
|
+
sock = TCPSocket.new host, port
|
15
|
+
ssl_ctx = OpenSSL::SSL::SSLContext.new
|
16
|
+
ssl_ctx.ssl_version = :SSLv23
|
17
|
+
OpenSSL::SSL::SSLSocket.new(sock, ssl_ctx).tap do |sock|
|
18
|
+
sock.sync_close = true
|
19
|
+
sock.connect
|
20
|
+
end
|
21
|
+
end
|
22
|
+
def close_plaintext_connection socket
|
23
|
+
socket.close
|
24
|
+
end
|
25
|
+
def close_ssl_connection socket
|
26
|
+
socket.close
|
27
|
+
end
|
28
|
+
def read num_bytes
|
29
|
+
@socket.read num_bytes
|
30
|
+
end
|
31
|
+
def read_nonblock num_bytes
|
32
|
+
@socket.read_nonblock num_bytes
|
33
|
+
end
|
34
|
+
def puts string
|
35
|
+
@socket.puts string
|
36
|
+
end
|
37
|
+
def write string
|
38
|
+
@socket.write string
|
39
|
+
end
|
40
|
+
def closed?
|
41
|
+
@socket.closed?
|
42
|
+
end
|
43
|
+
def close
|
44
|
+
if @ssl
|
45
|
+
close_ssl_connection @socket
|
46
|
+
else
|
47
|
+
close_plaintext_connection @socket
|
48
|
+
end
|
49
|
+
end
|
50
|
+
def open
|
51
|
+
if @ssl
|
52
|
+
@socket = establish_ssl_connection @host, @port
|
53
|
+
else
|
54
|
+
@socket = establish_plaintext_connection @host, @port
|
55
|
+
end
|
56
|
+
end
|
57
|
+
public :read, :read_nonblock, :select, :puts, :write, :closed?, :close, :open
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# License details in LICENSE.
|
2
|
+
module RelayHelper
|
3
|
+
class Options
|
4
|
+
attr_reader :host, :password, :ssl, :port, :compression
|
5
|
+
def initialize args
|
6
|
+
OptionParser.new do |opts|
|
7
|
+
opts.banner = "Usage: weelayhelper [options]"
|
8
|
+
opts.on('-H', '--host hostname', String, 'Hostname of the Weechat instance') do |hn|
|
9
|
+
@host = hn
|
10
|
+
end
|
11
|
+
opts.on('-P', '--password pass', String, 'Password (if needed) of the Weechat relay instance') do |pass|
|
12
|
+
@password = pass
|
13
|
+
end
|
14
|
+
opts.on('-p', '--port port', Integer, 'Port that the Weechat instance is listening on') do |port|
|
15
|
+
@port = port
|
16
|
+
end
|
17
|
+
opts.on('-s', '--[no-]ssl', 'Use SSL when connecting') do |ssl|
|
18
|
+
@ssl = ssl
|
19
|
+
end
|
20
|
+
opts.on('-c', '--[no-]compression', 'Use Zlib to compress communication') do |compression|
|
21
|
+
@compression = compression
|
22
|
+
end
|
23
|
+
opts.on_tail('-h', '--help', 'Shows this help message') do
|
24
|
+
puts opts
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
end.parse! args
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# License details in LICENSE.
|
2
|
+
module RelayHelper
|
3
|
+
class Response
|
4
|
+
attr_accessor :text, :data, :id
|
5
|
+
def initialize response
|
6
|
+
@text = response.force_encoding('ASCII-8BIT')
|
7
|
+
@length = 0
|
8
|
+
@index = 0
|
9
|
+
@compressed = false
|
10
|
+
@data = []
|
11
|
+
@id = ''
|
12
|
+
read_length
|
13
|
+
read_compressed
|
14
|
+
decompress! if @compressed
|
15
|
+
read_id
|
16
|
+
while @index < @length
|
17
|
+
@data << read_part
|
18
|
+
end
|
19
|
+
end
|
20
|
+
def read num_bytes
|
21
|
+
ret = @text[@index, num_bytes]
|
22
|
+
@index += num_bytes
|
23
|
+
ret
|
24
|
+
end
|
25
|
+
def read_type
|
26
|
+
read(3)
|
27
|
+
end
|
28
|
+
def read_part type=nil
|
29
|
+
type ||= read_type
|
30
|
+
case type
|
31
|
+
when 'chr'
|
32
|
+
read_char
|
33
|
+
when 'int'
|
34
|
+
read_int
|
35
|
+
when 'lon'
|
36
|
+
read_long
|
37
|
+
when 'str'
|
38
|
+
read_string
|
39
|
+
when 'buf'
|
40
|
+
read_buffer_of_bytes
|
41
|
+
when 'ptr'
|
42
|
+
read_pointer
|
43
|
+
when 'tim'
|
44
|
+
read_time
|
45
|
+
when 'htb'
|
46
|
+
read_hashtable
|
47
|
+
when 'hda'
|
48
|
+
read_hdata
|
49
|
+
when 'arr'
|
50
|
+
read_array
|
51
|
+
when 'inf'
|
52
|
+
read_info
|
53
|
+
when 'inl'
|
54
|
+
read_infolist
|
55
|
+
end
|
56
|
+
end
|
57
|
+
def read_length
|
58
|
+
@length = read(4).unpack('L>')[0]
|
59
|
+
end
|
60
|
+
def read_compressed
|
61
|
+
@compressed = true unless read_char.zero?
|
62
|
+
end
|
63
|
+
def decompress!
|
64
|
+
unenc = Zlib.inflate(@text[5, @length])
|
65
|
+
@text[5, @length] = unenc
|
66
|
+
end
|
67
|
+
def read_id
|
68
|
+
@id = read_string
|
69
|
+
end
|
70
|
+
def read_char
|
71
|
+
read(1).unpack('c')[0]
|
72
|
+
end
|
73
|
+
def read_int
|
74
|
+
read(4).unpack('l>')[0]
|
75
|
+
end
|
76
|
+
def read_long
|
77
|
+
len = read(1).unpack('c')[0]
|
78
|
+
read(len).to_i
|
79
|
+
end
|
80
|
+
def read_string
|
81
|
+
len = read(4).unpack('l>')[0]
|
82
|
+
if len == -1
|
83
|
+
nil
|
84
|
+
else
|
85
|
+
read(len)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
def read_buffer_of_bytes
|
89
|
+
len = read(4).unpack('l>')[0]
|
90
|
+
if len == -1
|
91
|
+
nil
|
92
|
+
else
|
93
|
+
read(len)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
def read_pointer
|
97
|
+
len = read(1).unpack('c')[0]
|
98
|
+
ret = read(len).to_i
|
99
|
+
if len == 1 && ret == 0
|
100
|
+
nil
|
101
|
+
else
|
102
|
+
ret
|
103
|
+
end
|
104
|
+
end
|
105
|
+
def read_time
|
106
|
+
len = read(1).unpack('c')[0]
|
107
|
+
Time.at(read(len).to_i)
|
108
|
+
end
|
109
|
+
def read_hashtable
|
110
|
+
key_type = read_type
|
111
|
+
val_type = read_type
|
112
|
+
count = read_int
|
113
|
+
hsh = {}
|
114
|
+
count.times do
|
115
|
+
hsh[read_part(key_type)] = read_part(val_type)
|
116
|
+
end
|
117
|
+
hsh
|
118
|
+
end
|
119
|
+
def read_hdata
|
120
|
+
hpath = read_string
|
121
|
+
keys = read_string.split(',').map { |k| k.split(':') }
|
122
|
+
count = read_int
|
123
|
+
paths = hpath.split('/')
|
124
|
+
objects = []
|
125
|
+
count.times do
|
126
|
+
hsh = {}
|
127
|
+
pointers = paths.map do
|
128
|
+
read_pointer
|
129
|
+
end
|
130
|
+
hsh[:pointers] = pointers
|
131
|
+
keys.each do |objdef|
|
132
|
+
hsh.update({ objdef[0] => read_part(objdef[1])})
|
133
|
+
end
|
134
|
+
|
135
|
+
objects << hsh
|
136
|
+
end
|
137
|
+
objects
|
138
|
+
end
|
139
|
+
def read_array
|
140
|
+
type = read_type
|
141
|
+
count = read_int
|
142
|
+
arr = []
|
143
|
+
count.times do
|
144
|
+
arr << read_part(type)
|
145
|
+
end
|
146
|
+
arr
|
147
|
+
end
|
148
|
+
def read_infolist
|
149
|
+
name = read_string
|
150
|
+
count = read_int
|
151
|
+
info = []
|
152
|
+
count.times do
|
153
|
+
info << read_infolist_item
|
154
|
+
end
|
155
|
+
{ name: name, data: info }
|
156
|
+
end
|
157
|
+
def read_infolist_item
|
158
|
+
count = read_int
|
159
|
+
ret = {}
|
160
|
+
count.times do
|
161
|
+
name = read_string
|
162
|
+
type = read_type
|
163
|
+
value = read_part(type)
|
164
|
+
ret[name] = value
|
165
|
+
end
|
166
|
+
ret
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# License details in LICENSE.
|
2
|
+
module RelayHelper
|
3
|
+
class Weechat
|
4
|
+
attr_reader :connection
|
5
|
+
def initialize host, port, ssl, compression, password
|
6
|
+
@connection = Connection.new(host, port, ssl)
|
7
|
+
@connection.open
|
8
|
+
@connection.puts "init#{" password=#{password}," if password}compression=#{compression ? 'zlib' : 'off'}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: weechat-relay-helper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rylee Fowler
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: awesome_print
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
description: An interactive tool to assist in the development of Weechat-protocol
|
28
|
+
applications
|
29
|
+
email:
|
30
|
+
- rylee@rylee.me
|
31
|
+
executables:
|
32
|
+
- weechat-relay-helper
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
38
|
+
- bin/weechat-relay-helper
|
39
|
+
- lib/weechat-relay-helper.rb
|
40
|
+
- lib/weechat-relay-helper/connection.rb
|
41
|
+
- lib/weechat-relay-helper/options.rb
|
42
|
+
- lib/weechat-relay-helper/response.rb
|
43
|
+
- lib/weechat-relay-helper/version.rb
|
44
|
+
- lib/weechat-relay-helper/weechat.rb
|
45
|
+
homepage: https://github.com/rylai-/weechat-relay-helper
|
46
|
+
licenses:
|
47
|
+
- MIT
|
48
|
+
metadata: {}
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 2.2.2
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: This gem provides an executable and a simple library to parse and visualize
|
69
|
+
the Weechat protocol through interactively allowing the user to input raw protocol
|
70
|
+
messages and see the messages that Weechat sends back in real time.
|
71
|
+
test_files: []
|
72
|
+
has_rdoc:
|