tox 0.0.1 → 0.0.2
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 +4 -4
- data/.rubocop.yml +8 -9
- data/examples/echo_bot.rb +19 -4
- data/ext/tox/client.c +294 -22
- data/ext/tox/extconf.rb +73 -16
- data/ext/tox/friend.c +300 -14
- data/ext/tox/options.c +0 -7
- data/ext/tox/tox.c +89 -9
- data/ext/tox/tox.h +44 -0
- data/ext/tox/version.c +62 -0
- data/lib/tox.rb +37 -4
- data/lib/tox/binary.rb +7 -3
- data/lib/tox/client.rb +44 -10
- data/lib/tox/friend.rb +20 -3
- data/lib/tox/friend/out_message.rb +58 -0
- data/lib/tox/node.rb +16 -7
- data/lib/tox/nospam.rb +28 -0
- data/lib/tox/options.rb +25 -0
- data/lib/tox/out_message.rb +36 -0
- data/lib/tox/status.rb +13 -3
- data/lib/tox/user_status.rb +35 -0
- data/lib/tox/version.rb +16 -2
- data/tox.gemspec +1 -1
- metadata +9 -8
- data/ext/tox/client.h +0 -29
- data/ext/tox/friend.h +0 -25
- data/ext/tox/node.c +0 -33
- data/ext/tox/node.h +0 -25
- data/ext/tox/options.h +0 -27
data/ext/tox/options.c
CHANGED
@@ -17,10 +17,6 @@
|
|
17
17
|
*/
|
18
18
|
|
19
19
|
#include "tox.h"
|
20
|
-
#include "options.h"
|
21
|
-
|
22
|
-
// Instance
|
23
|
-
VALUE mTox_cOptions;
|
24
20
|
|
25
21
|
// Memory management
|
26
22
|
static VALUE mTox_cOptions_alloc(VALUE klass);
|
@@ -37,9 +33,6 @@ static VALUE mTox_cOptions_savedata_EQUALS(VALUE self, VALUE savedata);
|
|
37
33
|
|
38
34
|
void mTox_cOptions_INIT()
|
39
35
|
{
|
40
|
-
// Instance
|
41
|
-
mTox_cOptions = rb_define_class_under(mTox, "Options", rb_cObject);
|
42
|
-
|
43
36
|
// Memory management
|
44
37
|
rb_define_alloc_func(mTox_cOptions, mTox_cOptions_alloc);
|
45
38
|
|
data/ext/tox/tox.c
CHANGED
@@ -17,18 +17,47 @@
|
|
17
17
|
*/
|
18
18
|
|
19
19
|
#include "tox.h"
|
20
|
-
#include "options.h"
|
21
|
-
#include "node.h"
|
22
|
-
#include "client.h"
|
23
|
-
#include "friend.h"
|
24
20
|
|
25
|
-
#if !(TOX_VERSION_IS_API_COMPATIBLE(0,
|
21
|
+
#if !(TOX_VERSION_IS_API_COMPATIBLE(0, 2, 1))
|
26
22
|
#error "Tox API version is not compatible"
|
27
23
|
#endif
|
28
24
|
|
29
|
-
//
|
25
|
+
// Instances
|
26
|
+
|
30
27
|
VALUE mTox;
|
31
28
|
|
29
|
+
VALUE mTox_eNullError;
|
30
|
+
VALUE mTox_eUnknownError;
|
31
|
+
VALUE mTox_eUnknownSecurityError;
|
32
|
+
|
33
|
+
VALUE mTox_mVersion;
|
34
|
+
VALUE mTox_mUserStatus;
|
35
|
+
VALUE mTox_cOptions;
|
36
|
+
VALUE mTox_cClient;
|
37
|
+
VALUE mTox_cNode;
|
38
|
+
VALUE mTox_cFriend;
|
39
|
+
VALUE mTox_cAddress;
|
40
|
+
VALUE mTox_cPublicKey;
|
41
|
+
VALUE mTox_mOutMessage;
|
42
|
+
|
43
|
+
VALUE mTox_mUserStatus_NONE;
|
44
|
+
VALUE mTox_mUserStatus_AWAY;
|
45
|
+
VALUE mTox_mUserStatus_BUSY;
|
46
|
+
|
47
|
+
VALUE mTox_cClient_eBadSavedataError;
|
48
|
+
|
49
|
+
VALUE mTox_cFriend_eNotFoundError;
|
50
|
+
VALUE mTox_cFriend_eNotConnectedError;
|
51
|
+
VALUE mTox_cFriend_cOutMessage;
|
52
|
+
|
53
|
+
VALUE mTox_mOutMessage_eSendQueueAllocError;
|
54
|
+
VALUE mTox_mOutMessage_eTooLongError;
|
55
|
+
VALUE mTox_mOutMessage_eEmptyError;
|
56
|
+
|
57
|
+
// Singleton methods
|
58
|
+
|
59
|
+
static VALUE mTox_hash(VALUE self, VALUE data);
|
60
|
+
|
32
61
|
/*************************************************************
|
33
62
|
* Initialization
|
34
63
|
*************************************************************/
|
@@ -39,11 +68,62 @@ void Init_tox()
|
|
39
68
|
rb_raise(rb_eLoadError, "incompatible Tox ABI version");
|
40
69
|
}
|
41
70
|
|
42
|
-
//
|
43
|
-
|
71
|
+
// Instances
|
72
|
+
|
73
|
+
mTox = rb_const_get(rb_cObject, rb_intern("Tox"));
|
74
|
+
|
75
|
+
mTox_eNullError = rb_const_get(mTox, rb_intern("NullError"));
|
76
|
+
mTox_eUnknownError = rb_const_get(mTox, rb_intern("UnknownError"));
|
77
|
+
mTox_eUnknownSecurityError = rb_const_get(mTox, rb_intern("UnknownSecurityError"));
|
78
|
+
|
79
|
+
mTox_mVersion = rb_const_get(mTox, rb_intern("Version"));
|
80
|
+
mTox_mUserStatus = rb_const_get(mTox, rb_intern("UserStatus"));
|
81
|
+
mTox_cOptions = rb_const_get(mTox, rb_intern("Options"));
|
82
|
+
mTox_cClient = rb_const_get(mTox, rb_intern("Client"));
|
83
|
+
mTox_cNode = rb_const_get(mTox, rb_intern("Node"));
|
84
|
+
mTox_cFriend = rb_const_get(mTox, rb_intern("Friend"));
|
85
|
+
mTox_cAddress = rb_const_get(mTox, rb_intern("Address"));
|
86
|
+
mTox_cPublicKey = rb_const_get(mTox, rb_intern("PublicKey"));
|
87
|
+
mTox_mOutMessage = rb_const_get(mTox, rb_intern("OutMessage"));
|
88
|
+
|
89
|
+
mTox_mUserStatus_NONE = rb_const_get(mTox_mUserStatus, rb_intern("NONE"));
|
90
|
+
mTox_mUserStatus_AWAY = rb_const_get(mTox_mUserStatus, rb_intern("AWAY"));
|
91
|
+
mTox_mUserStatus_BUSY = rb_const_get(mTox_mUserStatus, rb_intern("BUSY"));
|
92
|
+
|
93
|
+
mTox_cClient_eBadSavedataError = rb_const_get(mTox_cClient, rb_intern("BadSavedataError"));
|
44
94
|
|
95
|
+
mTox_cFriend_eNotFoundError = rb_const_get(mTox_cFriend, rb_intern("NotFoundError"));
|
96
|
+
mTox_cFriend_eNotConnectedError = rb_const_get(mTox_cFriend, rb_intern("NotConnectedError"));
|
97
|
+
mTox_cFriend_cOutMessage = rb_const_get(mTox_cFriend, rb_intern("OutMessage"));
|
98
|
+
|
99
|
+
mTox_mOutMessage_eSendQueueAllocError = rb_const_get(mTox_mOutMessage, rb_intern("SendQueueAllocError"));
|
100
|
+
mTox_mOutMessage_eTooLongError = rb_const_get(mTox_mOutMessage, rb_intern("TooLongError"));
|
101
|
+
mTox_mOutMessage_eEmptyError = rb_const_get(mTox_mOutMessage, rb_intern("EmptyError"));
|
102
|
+
|
103
|
+
// Singleton methods
|
104
|
+
|
105
|
+
rb_define_singleton_method(mTox, "hash", mTox_hash, 1);
|
106
|
+
|
107
|
+
mTox_mVersion_INIT();
|
45
108
|
mTox_cOptions_INIT();
|
46
|
-
mTox_cNode_INIT();
|
47
109
|
mTox_cClient_INIT();
|
48
110
|
mTox_cFriend_INIT();
|
49
111
|
}
|
112
|
+
|
113
|
+
/*************************************************************
|
114
|
+
* Singleton methods
|
115
|
+
*************************************************************/
|
116
|
+
|
117
|
+
// Tox.hash
|
118
|
+
VALUE mTox_hash(const VALUE self, const VALUE data)
|
119
|
+
{
|
120
|
+
Check_Type(data, T_STRING);
|
121
|
+
|
122
|
+
const uint8_t result[TOX_HASH_LENGTH];
|
123
|
+
|
124
|
+
if (true != tox_hash(result, (const uint8_t*)RSTRING_PTR(data), RSTRING_LEN(data))) {
|
125
|
+
rb_raise(mTox_eUnknownSecurityError, "tox_hash() failed");
|
126
|
+
}
|
127
|
+
|
128
|
+
return rb_str_new(result, TOX_HASH_LENGTH);
|
129
|
+
}
|
data/ext/tox/tox.h
CHANGED
@@ -20,6 +20,50 @@
|
|
20
20
|
|
21
21
|
#include <tox/tox.h>
|
22
22
|
|
23
|
+
// C extension initialization
|
24
|
+
|
23
25
|
void Init_tox();
|
26
|
+
void mTox_mVersion_INIT();
|
27
|
+
void mTox_cOptions_INIT();
|
28
|
+
void mTox_cClient_INIT();
|
29
|
+
void mTox_cFriend_INIT();
|
30
|
+
|
31
|
+
// C data
|
32
|
+
|
33
|
+
typedef struct Tox_Options mTox_cOptions_CDATA;
|
34
|
+
|
35
|
+
typedef struct {
|
36
|
+
Tox *tox;
|
37
|
+
} mTox_cClient_CDATA;
|
38
|
+
|
39
|
+
// Instances
|
24
40
|
|
25
41
|
extern VALUE mTox;
|
42
|
+
|
43
|
+
extern VALUE mTox_eNullError;
|
44
|
+
extern VALUE mTox_eUnknownError;
|
45
|
+
extern VALUE mTox_eUnknownSecurityError;
|
46
|
+
|
47
|
+
extern VALUE mTox_mVersion;
|
48
|
+
extern VALUE mTox_mUserStatus;
|
49
|
+
extern VALUE mTox_cOptions;
|
50
|
+
extern VALUE mTox_cClient;
|
51
|
+
extern VALUE mTox_cNode;
|
52
|
+
extern VALUE mTox_cFriend;
|
53
|
+
extern VALUE mTox_cAddress;
|
54
|
+
extern VALUE mTox_cPublicKey;
|
55
|
+
extern VALUE mTox_mOutMessage;
|
56
|
+
|
57
|
+
extern VALUE mTox_mUserStatus_NONE;
|
58
|
+
extern VALUE mTox_mUserStatus_AWAY;
|
59
|
+
extern VALUE mTox_mUserStatus_BUSY;
|
60
|
+
|
61
|
+
extern VALUE mTox_cClient_eBadSavedataError;
|
62
|
+
|
63
|
+
extern VALUE mTox_cFriend_eNotFoundError;
|
64
|
+
extern VALUE mTox_cFriend_eNotConnectedError;
|
65
|
+
extern VALUE mTox_cFriend_cOutMessage;
|
66
|
+
|
67
|
+
extern VALUE mTox_mOutMessage_eSendQueueAllocError;
|
68
|
+
extern VALUE mTox_mOutMessage_eTooLongError;
|
69
|
+
extern VALUE mTox_mOutMessage_eEmptyError;
|
data/ext/tox/version.c
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
/*
|
2
|
+
* tox.rb - Ruby interface for libtoxcore
|
3
|
+
* Copyright (C) 2015-2017 Braiden Vasco
|
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 3 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
|
16
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include "tox.h"
|
20
|
+
|
21
|
+
// Singleton methods
|
22
|
+
|
23
|
+
static VALUE mTox_mVersion_abi_major(VALUE self);
|
24
|
+
static VALUE mTox_mVersion_abi_minor(VALUE self);
|
25
|
+
static VALUE mTox_mVersion_abi_patch(VALUE self);
|
26
|
+
|
27
|
+
/*************************************************************
|
28
|
+
* Initialization
|
29
|
+
*************************************************************/
|
30
|
+
|
31
|
+
void mTox_mVersion_INIT()
|
32
|
+
{
|
33
|
+
// Constants
|
34
|
+
|
35
|
+
rb_define_const(mTox_mVersion, "API_MAJOR", LONG2FIX(TOX_VERSION_MAJOR));
|
36
|
+
rb_define_const(mTox_mVersion, "API_MINOR", LONG2FIX(TOX_VERSION_MINOR));
|
37
|
+
rb_define_const(mTox_mVersion, "API_PATCH", LONG2FIX(TOX_VERSION_PATCH));
|
38
|
+
|
39
|
+
// Singleton methods
|
40
|
+
|
41
|
+
rb_define_singleton_method(mTox_mVersion, "abi_major", mTox_mVersion_abi_major, 0);
|
42
|
+
rb_define_singleton_method(mTox_mVersion, "abi_minor", mTox_mVersion_abi_minor, 0);
|
43
|
+
rb_define_singleton_method(mTox_mVersion, "abi_patch", mTox_mVersion_abi_patch, 0);
|
44
|
+
}
|
45
|
+
|
46
|
+
// Tox::Version.abi_major
|
47
|
+
VALUE mTox_mVersion_abi_major(const VALUE self)
|
48
|
+
{
|
49
|
+
return LONG2FIX(tox_version_major());
|
50
|
+
}
|
51
|
+
|
52
|
+
// Tox::Version.abi_minor
|
53
|
+
VALUE mTox_mVersion_abi_minor(const VALUE self)
|
54
|
+
{
|
55
|
+
return LONG2FIX(tox_version_minor());
|
56
|
+
}
|
57
|
+
|
58
|
+
// Tox::Version.abi_patch
|
59
|
+
VALUE mTox_mVersion_abi_patch(const VALUE self)
|
60
|
+
{
|
61
|
+
return LONG2FIX(tox_version_patch());
|
62
|
+
}
|
data/lib/tox.rb
CHANGED
@@ -23,21 +23,54 @@ require 'json'
|
|
23
23
|
require 'resolv'
|
24
24
|
|
25
25
|
require 'tox/version'
|
26
|
+
require 'tox/user_status'
|
27
|
+
require 'tox/options'
|
28
|
+
require 'tox/client'
|
26
29
|
require 'tox/status'
|
27
30
|
require 'tox/node'
|
28
|
-
require 'tox/
|
29
|
-
require 'tox/client'
|
31
|
+
require 'tox/out_message'
|
30
32
|
require 'tox/friend'
|
33
|
+
require 'tox/friend/out_message'
|
31
34
|
|
32
35
|
# Primitives
|
33
36
|
require 'tox/binary'
|
34
37
|
require 'tox/public_key'
|
38
|
+
require 'tox/nospam'
|
35
39
|
require 'tox/address'
|
36
40
|
|
37
41
|
##
|
38
|
-
# Ruby interface for libtoxcore. It can be used to create Tox chat client or
|
39
|
-
# The interface is object-oriented instead of C-style (raises exceptions
|
42
|
+
# Ruby interface for libtoxcore. It can be used to create Tox chat client or
|
43
|
+
# bot. The interface is object-oriented instead of C-style (raises exceptions
|
40
44
|
# instead of returning error codes, uses classes to represent primitives, etc.)
|
41
45
|
#
|
42
46
|
module Tox
|
47
|
+
##
|
48
|
+
# Exception of this type is raised when Tox function failed with error code
|
49
|
+
# represented in Tox headers with a constant which name ends with "_NULL".
|
50
|
+
# This happens when one of the arguments to the function was NULL when it was
|
51
|
+
# not expected. It can indicate that usage of the Tox function is invalid,
|
52
|
+
# so if you got exception of this type please create an issue:
|
53
|
+
# https://github.com/toxon/tox.rb/issues
|
54
|
+
# Please describe the situation, version of libtoxcore, version of the gem.
|
55
|
+
#
|
56
|
+
class NullError < RuntimeError; end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Exception of this type is raised when Tox function failed with unknown
|
60
|
+
# error code or returned false success status. It can indicate minor version
|
61
|
+
# upgrade of libtoxcore. Specific handling is not needed for the time beeing.
|
62
|
+
#
|
63
|
+
class UnknownError < RuntimeError; end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Exception of this type is raised in similar cases to {Tox::UnknownError}
|
67
|
+
# when it can have security implications. This should happen rarely after
|
68
|
+
# the gem release. However, for now it can be raised when key-related
|
69
|
+
# functions fail because of unknown reason for better feedback
|
70
|
+
# during development.
|
71
|
+
#
|
72
|
+
class UnknownSecurityError < SecurityError; end
|
43
73
|
end
|
74
|
+
|
75
|
+
# C extension
|
76
|
+
require 'tox/tox'
|
data/lib/tox/binary.rb
CHANGED
@@ -29,13 +29,17 @@ module Tox
|
|
29
29
|
/\A[\da-fA-F]{#{2 * bytesize}}\z/
|
30
30
|
end
|
31
31
|
|
32
|
-
def initialize(value)
|
33
|
-
|
32
|
+
def initialize(value) # rubocop:disable Metrics/MethodLength
|
33
|
+
unless value.is_a? String
|
34
|
+
raise TypeError, "expected value to be a #{String}"
|
35
|
+
end
|
34
36
|
|
35
37
|
if value.bytesize == self.class.bytesize
|
36
38
|
super value
|
37
39
|
else
|
38
|
-
|
40
|
+
unless value =~ self.class.hex_re
|
41
|
+
raise ArgumentError, 'expected value to be a hex string'
|
42
|
+
end
|
39
43
|
super [value].pack('H*')
|
40
44
|
end
|
41
45
|
|
data/lib/tox/client.rb
CHANGED
@@ -27,7 +27,7 @@ module Tox
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def bootstrap_official
|
30
|
-
Status.new.
|
30
|
+
Status.new.udp_nodes.each do |node|
|
31
31
|
bootstrap node
|
32
32
|
end
|
33
33
|
end
|
@@ -43,20 +43,33 @@ module Tox
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def run
|
46
|
-
|
47
|
-
|
48
|
-
begin
|
49
|
-
self.running = true
|
50
|
-
self.thread = Thread.current
|
51
|
-
run_loop
|
52
|
-
ensure
|
53
|
-
self.running = false
|
54
|
-
self.thread = nil
|
46
|
+
unless mutex.try_lock
|
47
|
+
raise AlreadyRunningError, "already running in #{thread}"
|
55
48
|
end
|
56
49
|
|
50
|
+
run_internal
|
51
|
+
|
57
52
|
mutex.unlock
|
58
53
|
end
|
59
54
|
|
55
|
+
def friends
|
56
|
+
friend_numbers.map do |friend_number|
|
57
|
+
friend friend_number
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def friend(number)
|
62
|
+
Friend.new self, number
|
63
|
+
end
|
64
|
+
|
65
|
+
def friend!(number)
|
66
|
+
Friend.new(self, number).exist!
|
67
|
+
end
|
68
|
+
|
69
|
+
def on_iteration(&block)
|
70
|
+
@on_iteration = block
|
71
|
+
end
|
72
|
+
|
60
73
|
def on_friend_request(&block)
|
61
74
|
@on_friend_request = block
|
62
75
|
end
|
@@ -65,6 +78,18 @@ module Tox
|
|
65
78
|
@on_friend_message = block
|
66
79
|
end
|
67
80
|
|
81
|
+
def on_friend_name_change(&block)
|
82
|
+
@on_friend_name_change = block
|
83
|
+
end
|
84
|
+
|
85
|
+
def on_friend_status_message_change(&block)
|
86
|
+
@on_friend_status_message_change = block
|
87
|
+
end
|
88
|
+
|
89
|
+
def on_friend_status_change(&block)
|
90
|
+
@on_friend_status_change = block
|
91
|
+
end
|
92
|
+
|
68
93
|
private
|
69
94
|
|
70
95
|
attr_accessor :thread
|
@@ -77,6 +102,15 @@ module Tox
|
|
77
102
|
@running = !!value
|
78
103
|
end
|
79
104
|
|
105
|
+
def run_internal
|
106
|
+
self.running = true
|
107
|
+
self.thread = Thread.current
|
108
|
+
run_loop
|
109
|
+
ensure
|
110
|
+
self.running = false
|
111
|
+
self.thread = nil
|
112
|
+
end
|
113
|
+
|
80
114
|
class Error < RuntimeError; end
|
81
115
|
class BadSavedataError < Error; end
|
82
116
|
class AlreadyRunningError < Error; end
|
data/lib/tox/friend.rb
CHANGED
@@ -28,17 +28,34 @@ module Tox
|
|
28
28
|
self.number = number
|
29
29
|
end
|
30
30
|
|
31
|
+
def exist!
|
32
|
+
raise NotFoundError, "friend #{number} not found" unless exist?
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
alias exists! exist!
|
37
|
+
|
31
38
|
private
|
32
39
|
|
33
40
|
def client=(value)
|
34
|
-
|
41
|
+
unless value.is_a? Client
|
42
|
+
raise TypeError, "expected client to be a #{Client}"
|
43
|
+
end
|
35
44
|
@client = value
|
36
45
|
end
|
37
46
|
|
38
47
|
def number=(value)
|
39
|
-
|
40
|
-
|
48
|
+
unless value.is_a? Integer
|
49
|
+
raise TypeError, "expected number to be a #{Integer}"
|
50
|
+
end
|
51
|
+
unless value >= 0
|
52
|
+
raise ArgumentError,
|
53
|
+
'expected number to be greater than or equal to zero'
|
54
|
+
end
|
41
55
|
@number = value
|
42
56
|
end
|
57
|
+
|
58
|
+
class NotFoundError < RuntimeError; end
|
59
|
+
class NotConnectedError < RuntimeError; end
|
43
60
|
end
|
44
61
|
end
|