tox 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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