whatup 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 391ddb29c708ee7cf37769dc7aa3723d65e420fe08a268862bff6ec7ff5e659f
4
- data.tar.gz: b7e349838c88b72f3fbb04258afa114b124f460af40b99d64654bb5b941c04f3
3
+ metadata.gz: 0ace83a0aa8e24fb44a1f6900f8cdcaf201e7d8d9661883d1bb0ec8fdadf7fd6
4
+ data.tar.gz: 56b91c405097272ca64cbf9d78b4c6c02fd8749ce883838369b933b618c53552
5
5
  SHA512:
6
- metadata.gz: 6f8458ee475df4aa40d81cd3c126cea7d0153ba3ab2c3d56ec7ff92e130ae1b2765b5594a7a780584498a74d2808779d7024e412d724acad919665b8b339acf3
7
- data.tar.gz: e84e5379f28eec45311b4ab0aeea6ec67b45dadea2240f06f3c7dcc33a4094784ad081e6fc1bffa8e57d0c4cbc30248c7a55e663923d95e73b1de89698355316
6
+ metadata.gz: 1664ad2e6d346c84d4509fe166744e2f863889d59a968f21db9188989eabf87e4e927045530926a51dc80e2ffdd6734f252642fb0b645139b177319399eb97c6
7
+ data.tar.gz: 4ee3b633248639ff80215487a2d2820fc7e01a5b6b8923574f464b9255de77443febae039cb9e6cfa8444a2c2e649c7a3597ad82de66127039c6e373a2158168
data/.gitignore CHANGED
@@ -16,3 +16,6 @@ vagrant/*
16
16
 
17
17
  # Since this is a gem, don't include the lock file
18
18
  Gemfile.lock
19
+
20
+ # Ignore the database
21
+ db/*.db
data/README.md CHANGED
@@ -7,6 +7,9 @@ whatup is a simple server-based instant messaging application
7
7
  Check it out on [rubygems.org](https://rubygems.org/gems/whatup).
8
8
 
9
9
  [![Build Status](https://travis-ci.com/jethrodaniel/whatup.svg?branch=dev)](https://travis-ci.com/jethrodaniel/whatup)
10
+ [![Maintainability](https://api.codeclimate.com/v1/badges/e5356174302d82cf67cb/maintainability)](https://codeclimate.com/github/jethrodaniel/whatup/maintainability)
11
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/a99a88d28ad37a79dbf6/test_coverage)](https://codeclimate.com/github/codeclimate/codeclimate/test_coverage)
12
+ [![Gem Version](https://badge.fury.io/rb/whatup.svg)](https://badge.fury.io/rb/whatup)
10
13
 
11
14
  ## Installation
12
15
 
data/db/.keep ADDED
File without changes
@@ -8,7 +8,13 @@ module Whatup
8
8
  module CLI
9
9
  # Any methods of class `Whatup::CLI::Interactive` that rely on instance
10
10
  # variables should be included here
11
- COMMANDS = %i[room list exit].freeze
11
+ COMMANDS = %i[
12
+ room
13
+ list
14
+ exit
15
+ dmlist
16
+ dm
17
+ ].freeze
12
18
 
13
19
  require 'whatup/cli/commands/interactive/setup'
14
20
 
@@ -18,6 +24,9 @@ module Whatup
18
24
  class Interactive < Thor
19
25
  prepend InteractiveSetup
20
26
 
27
+ Room = Whatup::Server::Room
28
+ Client = Whatup::Server::Client
29
+
21
30
  attr_accessor *%i[server current_user]
22
31
 
23
32
  no_commands do
@@ -57,12 +66,13 @@ module Whatup
57
66
  desc 'list', 'Show all connected clients'
58
67
  def list
59
68
  say 'All connected clients:'
60
- @server.clients.each { |c| say c.status }
69
+ @server.clients_except(@current_user).each { |c| say " #{c.status}" }
70
+ say "* #{@current_user.status}"
61
71
  end
62
72
 
63
73
  desc 'room [NAME]', 'Create and enter chatroom [NAME]'
64
74
  def room name
65
- if room = @server.rooms.select { |r| r.name == name }&.first
75
+ if room = Room.find_by(name: name)
66
76
  @current_user.puts <<~MSG
67
77
  Entering #{room.name}... enjoy your stay!
68
78
 
@@ -73,7 +83,7 @@ module Whatup
73
83
  "- #{client.name}\n"
74
84
  end.join}
75
85
  MSG
76
- @current_user.room = room
86
+ @current_user.update! room: room
77
87
 
78
88
  room.broadcast except: @current_user do
79
89
  <<~MSG
@@ -94,17 +104,35 @@ module Whatup
94
104
  MSG
95
105
  end
96
106
 
97
- # desc 'dm [NAME]', 'Send a direct message to [NAME]'
98
- # def dm name
99
- # client = @server.find_client_by name: name
107
+ desc 'dmlist', 'List your received messages'
108
+ def dmlist
109
+ say 'Your direct messages:'
110
+ msgs = @current_user.received_messages.map do |msg|
111
+ <<~MSG
112
+ From: #{msg.sender.name}
113
+
114
+ #{msg.content}
115
+ MSG
116
+ end.join('-' * 10)
117
+ say msgs
118
+ end
119
+
120
+ desc 'dm [NAME]', 'Send a direct message to [NAME]'
121
+ def dm name
122
+ if recepient = Client.find_by(name: name)
123
+ say <<~MSG
124
+ Sending a direct message to #{name}...
100
125
 
101
- # if client.nil?
102
- # @current_user.puts "No client named `#{name}` found!"
103
- # return
104
- # end
126
+ The message can span multiple lines.
105
127
 
106
- # client.send_message
107
- # end
128
+ Type `.exit` when you're ready to send it.
129
+ MSG
130
+ @current_user.composing_dm = recepient
131
+ return
132
+ end
133
+
134
+ say "That user doesn't exist!"
135
+ end
108
136
 
109
137
  desc 'exit', 'Closes your connection with the server'
110
138
  def exit
@@ -37,7 +37,8 @@ module Whatup
37
37
  Thread.new do
38
38
  loop do
39
39
  input = Readline.readline '~> ', true
40
- exit if input.nil?
40
+ next if input.nil?
41
+
41
42
  @socket.puts input
42
43
  end
43
44
  end
@@ -52,7 +53,11 @@ module Whatup
52
53
  loop do
53
54
  response = @socket.gets&.chomp
54
55
 
55
- exit if response == 'END'
56
+ if response == 'END'
57
+ puts
58
+ kill_all_but_current_thread!
59
+ exit
60
+ end
56
61
 
57
62
  puts response # unless response.nil?
58
63
  end
@@ -61,6 +66,12 @@ module Whatup
61
66
  puts e.message
62
67
  @socket.close
63
68
  end
69
+
70
+ def kill_all_but_current_thread!
71
+ Thread.list.each do |thread|
72
+ thread.exit unless thread == Thread.current
73
+ end
74
+ end
64
75
  end
65
76
  end
66
77
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'whatup'
4
+ require 'whatup/server/redirection'
5
+
6
+ module Whatup
7
+ module Server
8
+ module DbInit
9
+ extend Redirection
10
+
11
+ class << self
12
+ def setup_db!
13
+ db = "#{Whatup.root}/db/whatup.db"
14
+ SQLite3::Database.new(db) unless File.exist?(db)
15
+
16
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3',
17
+ database: db
18
+
19
+ ActiveRecord::Base.connection.execute <<~SQL
20
+ DROP TABLE IF EXISTS clients_rooms;
21
+ DROP TABLE IF EXISTS clients;
22
+ DROP TABLE IF EXISTS messages;
23
+ DROP TABLE IF EXISTS rooms;
24
+ SQL
25
+
26
+ redirect(stdout: StringIO.new) { create_tables! }
27
+ end
28
+
29
+ private
30
+
31
+ def create_tables!
32
+ ActiveRecord::Schema.define do
33
+ create_table :clients, force: true do |t|
34
+ t.string :name
35
+ t.references :room
36
+ end
37
+ create_table :messages, force: true do |t|
38
+ t.string :content
39
+ t.references :sender
40
+ t.references :recipient
41
+ end
42
+ create_table :rooms, force: true do |t|
43
+ t.string :name
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'whatup/server/models/application_record'
4
+
5
+ module Whatup
6
+ module Server
7
+ class Client < ApplicationRecord
8
+ has_many :sent_messages, class_name: 'Message',
9
+ foreign_key: 'sender_id'
10
+ has_many :received_messages, class_name: 'Message',
11
+ foreign_key: 'recipient_id'
12
+
13
+ belongs_to :room, optional: true
14
+
15
+ validates_uniqueness_of :name
16
+
17
+ attr_accessor *%i[socket composing_dm deleted]
18
+
19
+ def puts msg
20
+ socket.puts msg
21
+ end
22
+
23
+ def gets
24
+ socket.gets
25
+ end
26
+
27
+ def input!
28
+ loop while (msg = gets).blank?
29
+ msg.chomp
30
+ end
31
+
32
+ def chatting?
33
+ !room_id.nil?
34
+ end
35
+
36
+ def composing_dm?
37
+ !composing_dm.nil?
38
+ end
39
+
40
+ def status
41
+ "#{name}#{chatting? ? " (#{room.name})" : ''}"
42
+ end
43
+
44
+ def broadcast msg
45
+ room.broadcast(except: self) { "#{name}> #{msg}" }
46
+ end
47
+
48
+ def leave_room!
49
+ broadcast 'LEFT'
50
+ room.drop_client! self
51
+ end
52
+
53
+ def exit!
54
+ puts 'END'
55
+ socket.close
56
+ @deleted = true
57
+ destroy!
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'whatup/server/models/application_record'
4
+
5
+ module Whatup
6
+ module Server
7
+ class Message < ApplicationRecord
8
+ belongs_to :recipient, class_name: 'Client'
9
+ belongs_to :sender, class_name: 'Client', foreign_key: 'sender_id'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'whatup/server/models/application_record'
4
+
5
+ module Whatup
6
+ module Server
7
+ class Room < ApplicationRecord
8
+ has_many :clients
9
+
10
+ validates :name, uniqueness: true
11
+
12
+ def drop_client! client
13
+ client.update! room_id: nil
14
+ end
15
+
16
+ def broadcast except: nil
17
+ if except
18
+ clients.where.not id: except.id
19
+ else
20
+ clients
21
+ end.each { |c| c.puts yield }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatup
4
+ module Server
5
+ module Redirection
6
+ # Reroutes stdin and stdout inside a block
7
+ def redirect stdin: $stdin, stdout: $stdout
8
+ original_stdin = $stdin
9
+ original_stdout = $stdout
10
+ $stdin = stdin
11
+ $stdout = stdout
12
+ yield
13
+ ensure
14
+ $stdin = original_stdin
15
+ $stdout = original_stdout
16
+ end
17
+ end
18
+ end
19
+ end
@@ -4,33 +4,40 @@ require 'socket'
4
4
  require 'fileutils'
5
5
  require 'securerandom'
6
6
 
7
+ require 'sqlite3'
8
+ require 'active_record'
7
9
  require 'active_support/core_ext/object/blank'
8
10
 
9
- require 'whatup/server/client'
10
- require 'whatup/server/room'
11
+ require 'whatup/server/db_init'
12
+ require 'whatup/server/redirection'
13
+ require 'whatup/server/models/client'
14
+ require 'whatup/server/models/message'
15
+ require 'whatup/server/models/room'
11
16
  require 'whatup/cli/commands/interactive/interactive'
12
17
 
13
18
  module Whatup
14
19
  module Server
15
- class Server
20
+ class Server # rubocop:disable Metrics/ClassLength
16
21
  include Thor::Shell
22
+ include DbInit
23
+ include Redirection
17
24
 
18
25
  Client = Whatup::Server::Client
19
26
 
20
- # Used by the interactive client cli
21
- attr_reader *%i[ip port address clients max_id pid pid_file rooms]
27
+ attr_reader *%i[ip port address clients pid pid_file rooms]
22
28
 
23
- def initialize port:
24
- @ip = 'localhost'
29
+ def initialize ip: 'localhost', port:
30
+ @ip = ip
25
31
  @port = port
26
32
  @address = "#{@ip}:#{@port}"
27
33
 
28
34
  @clients = []
29
35
  @rooms = []
30
- @max_id = 1
31
36
 
32
37
  @pid = Process.pid
33
38
  @pid_file = "#{Dir.home}/.whatup.pid"
39
+
40
+ DbInit.setup_db!
34
41
  end
35
42
 
36
43
  # Starts the server.
@@ -62,8 +69,12 @@ module Whatup
62
69
  @clients.select { |c| c.name == name }&.first
63
70
  end
64
71
 
72
+ def clients_except client
73
+ @clients.reject { |c| c == client }
74
+ end
75
+
65
76
  def new_room! clients: [], name:
66
- room = Room.new name: name, clients: clients
77
+ room = Room.create! name: name, clients: clients
67
78
  @rooms << room
68
79
  room
69
80
  end
@@ -72,13 +83,21 @@ module Whatup
72
83
 
73
84
  # Receives a new client, then continuously gets input from that client
74
85
  #
75
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
86
+ # rubocop:disable Metrics/MethodLength
76
87
  def handle_client client
77
88
  client = create_new_client_if_not_existing! client
78
89
 
79
90
  # Loop forever to maintain the connection
80
91
  loop do
81
- handle_chatting(client) if client.chatting?
92
+ @clients.reject! &:deleted
93
+
94
+ Thread.current.exit if client.deleted
95
+
96
+ if client.composing_dm?
97
+ handle_dm client
98
+ elsif client.chatting?
99
+ handle_chatting client
100
+ end
82
101
 
83
102
  # Wait until we get a valid command. This takes as long as the client
84
103
  # takes.
@@ -86,24 +105,11 @@ module Whatup
86
105
 
87
106
  puts "#{client.name}> #{msg}"
88
107
 
89
- # Initialize a new cli class using the initial command and options,
90
- # and then set any instance variables, since Thor will create a new
91
- # class instance when it's invoked.
92
- cmds, opts = Whatup::CLI::Interactive.parse_input msg
93
- cli = Whatup::CLI::Interactive.new(cmds, opts).tap do |c|
94
- c.server = self
95
- c.current_user = client
96
- end
97
-
98
108
  begin
99
109
  # Send the output to the client
100
110
  redirect stdin: client.socket, stdout: client.socket do
101
111
  # Invoke the cli using the provided commands and options.
102
-
103
- # This _should_ achieve the same effect as
104
- # `Whatup::CLI::Interactive.start(args)`, but allows us to set
105
- # instance variables on the cli class.
106
- cli.invoke cli.args.first, cli.args[1..cli.args.size - 1]
112
+ run_thor_command! client: client, msg: msg
107
113
  end
108
114
  rescue RuntimeError,
109
115
  Thor::InvocationError,
@@ -114,10 +120,29 @@ module Whatup
114
120
  puts e.message
115
121
  client.puts e.message
116
122
  end
117
- msg = nil # rubocop:disable Lint/UselessAssignment
123
+ msg = nil
118
124
  end
119
125
  end
120
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
126
+ # rubocop:enable Metrics/MethodLength
127
+
128
+ def handle_dm client
129
+ msg = StringIO.new
130
+ loop do
131
+ input = client.input!
132
+ puts "#{client.name}> #{input}"
133
+ if input == '.exit'
134
+ client.puts "Finished dm to `#{client.composing_dm.name}`."
135
+ break
136
+ end
137
+ msg.puts input
138
+ end
139
+ client.composing_dm
140
+ .received_messages << Message.new(
141
+ sender: client,
142
+ content: msg.string
143
+ )
144
+ client.composing_dm = nil
145
+ end
121
146
 
122
147
  def handle_chatting client
123
148
  loop do
@@ -126,6 +151,7 @@ module Whatup
126
151
  puts "#{client.name}> #{input}"
127
152
  if input == '.exit'
128
153
  client.leave_room!
154
+ client.puts "Exited `#{room.name}`."
129
155
  break
130
156
  end
131
157
  room.broadcast except: client do
@@ -147,35 +173,41 @@ module Whatup
147
173
 
148
174
  if @clients.any? { |c| c.name == name }
149
175
  client.puts 'That name is taken! Goodbye.'
150
- client.exit!
176
+ client.puts 'END'
177
+ client.close
178
+ Thread.current.exit
151
179
  end
152
180
 
153
- @clients << client = Client.new(
154
- id: new_client_id,
181
+ @clients << client = Client.create!(
155
182
  name: name,
156
183
  socket: client
157
184
  )
158
185
 
159
186
  puts "#{client.name} just showed up!"
160
- client.puts "Hello, #{client.name}!"
161
- client
162
- end
187
+ client.puts <<~MSG
188
+ Hello, #{client.name}!
189
+
190
+ Welcome to whatup.
163
191
 
164
- # @return A new, unique client identification number
165
- def new_client_id
166
- @max_id += 1
192
+ To get started, type `help`.
193
+ MSG
194
+ client
167
195
  end
168
196
 
169
- # Reroutes stdin and stdout inside a block
170
- def redirect stdin: $stdin, stdout: $stdout
171
- original_stdin = $stdin
172
- original_stdout = $stdout
173
- $stdin = stdin
174
- $stdout = stdout
175
- yield
176
- ensure
177
- $stdin = original_stdin
178
- $stdout = original_stdout
197
+ def run_thor_command! client:, msg:
198
+ # Initialize a new cli class using the initial command and options,
199
+ # and then set any instance variables, since Thor will create a new
200
+ # class instance when it's invoked.
201
+ cmds, opts = Whatup::CLI::Interactive.parse_input msg
202
+ Whatup::CLI::Interactive.new(cmds, opts).tap do |c|
203
+ c.server = self
204
+ c.current_user = client
205
+
206
+ # This _should_ achieve the same effect as
207
+ # `Whatup::CLI::Interactive.start(args)`, but allows us to set
208
+ # instance variables on the cli class.
209
+ c.invoke c.args.first, c.args.drop(1)
210
+ end
179
211
  end
180
212
 
181
213
  def exit_if_pid_exists!
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Whatup
4
- VERSION = '0.2.4'
4
+ VERSION = '0.2.5'
5
5
  end
data/lib/whatup.rb CHANGED
@@ -7,4 +7,8 @@ module Whatup
7
7
  # Whatup-specific error class
8
8
  class Error < StandardError
9
9
  end
10
+
11
+ def self.root
12
+ Dir.pwd
13
+ end
10
14
  end
data/whatup.gemspec CHANGED
@@ -49,23 +49,27 @@ Gem::Specification.new do |spec|
49
49
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
50
50
  spec.require_paths = ['lib']
51
51
 
52
+ # rubocop:disable Layout/AlignHash
52
53
  {
53
- 'pry' => '~> 0.12.2',
54
+ 'pry' => '~> 0.12.2',
54
55
  'pry-byebug' => '~> 3.7',
55
- 'bundler' => '~> 2.0',
56
- 'rake' => '~> 12.3.2',
57
- 'rspec' => '~> 3.8',
58
- 'yard' => '~> 0.9.18',
59
- 'rubocop' => '~> 0.65.0',
60
- 'aruba' => '~> 0.14.9',
61
- 'activesupport' => '~> 5.2'
56
+ 'bundler' => '~> 2.0',
57
+ 'rake' => '~> 12.3.2',
58
+ 'rspec' => '~> 3.8',
59
+ 'yard' => '~> 0.9.18',
60
+ 'rubocop' => '~> 0.65.0',
61
+ 'aruba' => '~> 0.14.9'
62
62
  }.each do |gem, version|
63
63
  spec.add_development_dependency gem, version
64
64
  end
65
65
 
66
66
  {
67
- 'thor' => '~> 0.20.3'
67
+ 'activesupport' => '~> 5.2',
68
+ 'thor' => '~> 0.20.3',
69
+ 'sqlite3' => '~> 1.4',
70
+ 'activerecord' => '~> 5.2'
68
71
  }.each do |gem, version|
69
72
  spec.add_dependency gem, version
70
73
  end
74
+ # rubocop:enable Layout/AlignHash
71
75
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whatup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Delk
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-04 00:00:00.000000000 Z
11
+ date: 2019-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -129,7 +129,7 @@ dependencies:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
131
  version: '5.2'
132
- type: :development
132
+ type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
@@ -150,6 +150,34 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: 0.20.3
153
+ - !ruby/object:Gem::Dependency
154
+ name: sqlite3
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.4'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.4'
167
+ - !ruby/object:Gem::Dependency
168
+ name: activerecord
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '5.2'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '5.2'
153
181
  description: |
154
182
  whatup is a simple server-based instant messaging application using TCP
155
183
  sockets.
@@ -178,6 +206,7 @@ files:
178
206
  - Rakefile
179
207
  - bin/console
180
208
  - bin/setup
209
+ - db/.keep
181
210
  - docs/hw/assignment.pdf
182
211
  - docs/hw/framework.pdf
183
212
  - docs/hw/inital_design.md
@@ -190,8 +219,12 @@ files:
190
219
  - lib/whatup/cli/commands/interactive/setup.rb
191
220
  - lib/whatup/cli/commands/server.rb
192
221
  - lib/whatup/client/client.rb
193
- - lib/whatup/server/client.rb
194
- - lib/whatup/server/room.rb
222
+ - lib/whatup/server/db_init.rb
223
+ - lib/whatup/server/models/application_record.rb
224
+ - lib/whatup/server/models/client.rb
225
+ - lib/whatup/server/models/message.rb
226
+ - lib/whatup/server/models/room.rb
227
+ - lib/whatup/server/redirection.rb
195
228
  - lib/whatup/server/server.rb
196
229
  - lib/whatup/version.rb
197
230
  - whatup.gemspec
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Whatup
4
- module Server
5
- class Client
6
- attr_reader :id, :name
7
- attr_accessor *%i[socket room]
8
-
9
- def initialize id:, name:, socket:
10
- @id = id
11
- @name = name
12
- @socket = socket
13
- @room = nil
14
- end
15
-
16
- def puts msg
17
- socket.puts msg
18
- end
19
-
20
- def gets
21
- socket.gets
22
- end
23
-
24
- def input!
25
- loop while (msg = gets).blank?
26
- msg.chomp
27
- end
28
-
29
- def room?
30
- !room.nil?
31
- end
32
- alias chatting? room?
33
-
34
- def status
35
- "#{name}" \
36
- "#{chatting? ? " (#{@room.name})" : ''}"
37
- end
38
-
39
- def broadcast msg
40
- @room.clients.reject { |c| c == self }
41
- .each { |c| c.puts "#{name}> #{msg}" }
42
- end
43
-
44
- def leave_room!
45
- broadcast 'LEFT'
46
- room.drop_client! self
47
- @room = nil
48
- end
49
-
50
- def exit!
51
- puts "END\n"
52
- Thread.kill Thread.current
53
- end
54
- end
55
- end
56
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Whatup
4
- module Server
5
- class Room
6
- attr_accessor *%i[name clients]
7
-
8
- def initialize name:, clients:
9
- @name = name
10
- @clients = clients
11
-
12
- @clients.each { |c| c.room = self }
13
- end
14
-
15
- def drop_client! client
16
- @clients = @clients.reject { |c| c == client }
17
- end
18
-
19
- def broadcast except: nil
20
- clients = except \
21
- ? @clients.reject { |c| c == except }
22
- : @clients
23
-
24
- clients.each { |c| c.puts yield }
25
- end
26
- end
27
- end
28
- end