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 +4 -4
- data/.gitignore +3 -0
- data/README.md +3 -0
- data/db/.keep +0 -0
- data/lib/whatup/cli/commands/interactive/interactive.rb +41 -13
- data/lib/whatup/client/client.rb +13 -2
- data/lib/whatup/server/db_init.rb +50 -0
- data/lib/whatup/server/models/application_record.rb +5 -0
- data/lib/whatup/server/models/client.rb +61 -0
- data/lib/whatup/server/models/message.rb +12 -0
- data/lib/whatup/server/models/room.rb +25 -0
- data/lib/whatup/server/redirection.rb +19 -0
- data/lib/whatup/server/server.rb +78 -46
- data/lib/whatup/version.rb +1 -1
- data/lib/whatup.rb +4 -0
- data/whatup.gemspec +13 -9
- metadata +38 -5
- data/lib/whatup/server/client.rb +0 -56
- data/lib/whatup/server/room.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ace83a0aa8e24fb44a1f6900f8cdcaf201e7d8d9661883d1bb0ec8fdadf7fd6
|
4
|
+
data.tar.gz: 56b91c405097272ca64cbf9d78b4c6c02fd8749ce883838369b933b618c53552
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1664ad2e6d346c84d4509fe166744e2f863889d59a968f21db9188989eabf87e4e927045530926a51dc80e2ffdd6734f252642fb0b645139b177319399eb97c6
|
7
|
+
data.tar.gz: 4ee3b633248639ff80215487a2d2820fc7e01a5b6b8923574f464b9255de77443febae039cb9e6cfa8444a2c2e649c7a3597ad82de66127039c6e373a2158168
|
data/.gitignore
CHANGED
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[
|
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.
|
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 =
|
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
|
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
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
102
|
-
# @current_user.puts "No client named `#{name}` found!"
|
103
|
-
# return
|
104
|
-
# end
|
126
|
+
The message can span multiple lines.
|
105
127
|
|
106
|
-
|
107
|
-
|
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
|
data/lib/whatup/client/client.rb
CHANGED
@@ -37,7 +37,8 @@ module Whatup
|
|
37
37
|
Thread.new do
|
38
38
|
loop do
|
39
39
|
input = Readline.readline '~> ', true
|
40
|
-
|
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
|
-
|
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,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
|
data/lib/whatup/server/server.rb
CHANGED
@@ -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/
|
10
|
-
require 'whatup/server/
|
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
|
-
|
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 =
|
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.
|
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
|
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
|
-
|
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
|
123
|
+
msg = nil
|
118
124
|
end
|
119
125
|
end
|
120
|
-
# rubocop:enable Metrics/MethodLength
|
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.
|
176
|
+
client.puts 'END'
|
177
|
+
client.close
|
178
|
+
Thread.current.exit
|
151
179
|
end
|
152
180
|
|
153
|
-
@clients << client = Client.
|
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
|
161
|
-
|
162
|
-
|
187
|
+
client.puts <<~MSG
|
188
|
+
Hello, #{client.name}!
|
189
|
+
|
190
|
+
Welcome to whatup.
|
163
191
|
|
164
|
-
|
165
|
-
|
166
|
-
|
192
|
+
To get started, type `help`.
|
193
|
+
MSG
|
194
|
+
client
|
167
195
|
end
|
168
196
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
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!
|
data/lib/whatup/version.rb
CHANGED
data/lib/whatup.rb
CHANGED
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'
|
54
|
+
'pry' => '~> 0.12.2',
|
54
55
|
'pry-byebug' => '~> 3.7',
|
55
|
-
'bundler'
|
56
|
-
'rake'
|
57
|
-
'rspec'
|
58
|
-
'yard'
|
59
|
-
'rubocop'
|
60
|
-
'aruba'
|
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
|
-
'
|
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
|
+
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-
|
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: :
|
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/
|
194
|
-
- lib/whatup/server/
|
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
|
data/lib/whatup/server/client.rb
DELETED
@@ -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
|
data/lib/whatup/server/room.rb
DELETED
@@ -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
|