<commit_before>require 'thread'
require 'socket'
require 'openssl'
require 'base64'
require 'json'

require_relative 'namespoofer'

class Pearader

  def initialize(total_clients=2)
    @mutex = Mutex.new
    @total = total_clients
    @connected = []
    @num_connects = 0
  end

  def connect(client)
    @mutex.synchronize do
      @connected.push({name: client.realname, photo: client.photo})
      @num_connects += 1
    end
    self
  end

  def broadcast_all(client)
    ready = false
    while !ready
      @mutex.synchronize { ready = @num_connects == @total }
      break if ready
      puts "Waiting for everyone"
      sleep 1
    end

    client.speak @connected.to_json
  end

end

class PearClient
  @@clients = []

  attr_reader :id, :socket, :name, :realname, :photo

  def initialize(socket, encoded_pubkey)
    @socket = socket
    puts "Receiving their pubkey"
    ident = JSON.parse(listen)
    puts ident
    @realname = ident['ident']['name']
    @photo = ident['ident']['photo']
    @pubkey = ident['ident']['pubkey']
    @messages = Queue.new
    puts "Sending out pubkey"
    @messages.push (encoded_pubkey << "\n")
    @responder = Thread.new do
      while (message = @messages.pop)
        @socket.puts Base64.encode64(message)
      end
    end
    puts "Ident complete"
  end

  def pkey_encrypt(message)
    key = OpenSSL::PKey::RSA.new @pubkey
    key.public_encrypt(message)
  end

  def speak(message)
    @messages.push message
  end<commit_msg>TCPSocket#write blocks but guarantees full sending<commit_after>require 'thread'
require 'socket'
require 'openssl'
require 'base64'
require 'json'

require_relative 'namespoofer'

class Pearader

  def initialize(total_clients=2)
    @mutex = Mutex.new
    @total = total_clients
    @connected = []
    @num_connects = 0
  end

  def connect(client)
    @mutex.synchronize do
      @connected.push({name: client.realname, photo: client.photo})
      @num_connects += 1
    end
    self
  end

  def broadcast_all(client)
    ready = false
    until ready
      @mutex.synchronize { ready = @num_connects == @total }
      break if ready
      puts "Waiting for everyone, #{@num_connects} so far"
      sleep 1
    end

    client.speak @connected.to_json
  end

end

class PearClient
  @@clients = []

  attr_reader :id, :socket, :name, :realname, :photo

  def initialize(socket, encoded_pubkey)
    @socket = socket
    puts "Receiving their pubkey"
    ident = JSON.parse(listen)
    puts ident
    @realname = ident['ident']['name']
    @photo = ident['ident']['photo']
    @pubkey = ident['ident']['pubkey']
    @messages = Queue.new
    puts "Sending out pubkey"
    @messages.push (encoded_pubkey << "\n")
    @responder = Thread.new do
      while (message = @messages.pop)
        @socket.write (Base64.encode64(message) << "\n")
      end
    end
    puts "Ident complete"
  end

  def pkey_encrypt(message)
    key = OpenSSL::PKey::RSA.new @pubkey
    key.public_encrypt(message)
  end

  def speak(message)
    @messages.push message
  end
{'fraction_non_alphanumeric': 0.11272247857613711, 'fraction_numerical': 0.0065919578114700065, 'mean_word_length': 3.046666666666667, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2611208', 'n_tokens_mistral': 1025, 'n_tokens_neox': 998, 'n_words': 256}