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.
@@ -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
 
@@ -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, 1, 9))
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
- // Instance
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
- // Instance
43
- mTox = rb_define_module("Tox");
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
+ }
@@ -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;
@@ -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/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 bot.
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'
@@ -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
- raise TypeError, "expected value to be a #{String}" unless value.is_a? String
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
- raise ArgumentError, 'expected value to be a hex string' unless value =~ self.class.hex_re
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
 
@@ -27,7 +27,7 @@ module Tox
27
27
  end
28
28
 
29
29
  def bootstrap_official
30
- Status.new.nodes.each do |node|
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
- raise AlreadyRunningError, "already running in #{thread}" unless mutex.try_lock
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
@@ -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
- raise TypeError, "expected client to be a #{Client}" unless value.is_a? Client
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
- raise TypeError, "expected number to be a #{Integer}" unless value.is_a? Integer
40
- raise ArgumentError, 'expected number to be greater than or equal to zero' unless value >= 0
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