weechat-relay-helper 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.
- 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:
|