whatup 0.2.2 → 0.2.3
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -1
- data/docs/hw/inital_design.md +1 -1
- data/exe/whatup +1 -1
- data/lib/whatup/cli/cli.rb +37 -0
- data/lib/whatup/cli/commands/client.rb +23 -0
- data/lib/whatup/cli/commands/server.rb +21 -0
- data/lib/whatup/client/client.rb +60 -0
- data/lib/whatup/server/client.rb +24 -0
- data/lib/whatup/server/server.rb +98 -0
- data/lib/whatup/version.rb +1 -1
- data/whatup.gemspec +10 -1
- metadata +17 -6
- data/lib/whatup/cli.rb +0 -61
- data/lib/whatup/client.rb +0 -61
- data/lib/whatup/server.rb +0 -83
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 205d1b22572393ab8a0fb12bc09edd48576ac740ab484e76e10511afaf080550
|
4
|
+
data.tar.gz: 26648b7a519d2eaeb15149793933d840965c045c6bf911acd6608a365dfa17f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c0dd6fa2a58e09dd1443527e1c58102060f1f1d5fa224c29772e6a86ee89a2c216c4bf43b22aef85a5a3d18b7ccead298860533487e3ec23e7c2e379ec7f956
|
7
|
+
data.tar.gz: 8ed6007535ff1054232ad3e53e6d26eb758e2ebb7d379fa2046bab4601880309156fc45949e67a3e3c9e3136df6006a499fb7bebb2f5eb138c811e6fe1137f25
|
data/.rubocop.yml
CHANGED
@@ -3,10 +3,14 @@
|
|
3
3
|
AllCops:
|
4
4
|
TargetRubyVersion: 2.4 # Modern Ruby
|
5
5
|
|
6
|
-
#
|
6
|
+
# The default is a bit restrictive
|
7
|
+
Metrics/AbcSize:
|
8
|
+
Max: 30
|
9
|
+
|
7
10
|
Metrics/BlockLength:
|
8
11
|
Exclude:
|
9
12
|
- 'whatup.gemspec'
|
13
|
+
- 'spec/**/*_spec.rb'
|
10
14
|
|
11
15
|
Metrics/MethodLength:
|
12
16
|
Max: 20 # 10 is a bit too low
|
data/docs/hw/inital_design.md
CHANGED
@@ -78,7 +78,7 @@ Commands:
|
|
78
78
|
whatup client connect # Connects a new client instance to a server
|
79
79
|
whatup client help [COMMAND] # Describe subcommands or one specific subcommand
|
80
80
|
|
81
|
-
$ whatup client help
|
81
|
+
$ whatup client help connect
|
82
82
|
|
83
83
|
Usage:
|
84
84
|
whatup client connect
|
data/exe/whatup
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
require 'whatup/cli/commands/client'
|
6
|
+
require 'whatup/cli/commands/server'
|
7
|
+
|
8
|
+
module Whatup
|
9
|
+
# Thor command classes for the cli.
|
10
|
+
# For usage, see <http://whatisthor.com/>
|
11
|
+
module CLI
|
12
|
+
# Top-level command class
|
13
|
+
class CLI < Thor
|
14
|
+
desc 'hello', 'Says hello'
|
15
|
+
def hello
|
16
|
+
say "Hello!\n", :cyan
|
17
|
+
end
|
18
|
+
|
19
|
+
# Subcommands are defined below, but are implemented in `commands/`
|
20
|
+
desc 'server ...', 'Perform server commands'
|
21
|
+
long_desc <<~DESC
|
22
|
+
Perform server commands.
|
23
|
+
|
24
|
+
See `whatup server help COMMAND` for help on `COMMAND`.
|
25
|
+
DESC
|
26
|
+
subcommand 'server', Server
|
27
|
+
|
28
|
+
desc 'client ...', 'Perform client commands'
|
29
|
+
long_desc <<~DESC
|
30
|
+
Perform client commands.
|
31
|
+
|
32
|
+
See `whatup client help COMMAND` for help on `COMMAND`.
|
33
|
+
DESC
|
34
|
+
subcommand 'client', Client
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
require 'whatup/client/client'
|
6
|
+
|
7
|
+
module Whatup
|
8
|
+
module CLI
|
9
|
+
# Client commands
|
10
|
+
class Client < Thor
|
11
|
+
option :ip, type: :string, default: 'localhost'
|
12
|
+
option :port, type: :numeric, default: 9_001
|
13
|
+
long_desc <<~DESC
|
14
|
+
Starts a client instance sending requests to the specified ip and port.
|
15
|
+
DESC
|
16
|
+
desc 'connect', 'Connects a new client instance to a server'
|
17
|
+
def connect
|
18
|
+
config = {ip: options[:ip], port: options[:port]}
|
19
|
+
Whatup::Client::Client.new(config).connect
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
require 'whatup/server/server'
|
6
|
+
|
7
|
+
module Whatup
|
8
|
+
module CLI
|
9
|
+
# Server commands
|
10
|
+
class Server < Thor
|
11
|
+
option :port, type: :numeric, default: 9_001
|
12
|
+
desc 'start', 'Starts a server instance'
|
13
|
+
long_desc <<~DESC
|
14
|
+
Starts a server instance running locally on the specified port.
|
15
|
+
DESC
|
16
|
+
def start
|
17
|
+
Whatup::Server::Server.new(port: options[:port]).start
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
|
5
|
+
module Whatup
|
6
|
+
module Client
|
7
|
+
class Client
|
8
|
+
include Thor::Shell
|
9
|
+
|
10
|
+
def initialize ip:, port:
|
11
|
+
@dest = {
|
12
|
+
ip: ip,
|
13
|
+
port: port,
|
14
|
+
address: "#{@ip}:#{@port}"
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def connect
|
19
|
+
say "Connecting to #{@dest[:ip]}:#{@dest[:port]} ..."
|
20
|
+
|
21
|
+
@socket = TCPSocket.open @dest[:ip], @dest[:port]
|
22
|
+
|
23
|
+
@request = request!
|
24
|
+
@response = listen!
|
25
|
+
|
26
|
+
[@request, @response].each &:join
|
27
|
+
rescue SignalException
|
28
|
+
say 'Exiting ...', :red
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
def request!
|
33
|
+
puts 'Please enter your username to establish a connection...'
|
34
|
+
Thread.new do
|
35
|
+
loop do
|
36
|
+
print '> '
|
37
|
+
input = $stdin.gets&.chomp
|
38
|
+
exit if input.nil?
|
39
|
+
@socket.puts input
|
40
|
+
end
|
41
|
+
end
|
42
|
+
rescue IOError => e
|
43
|
+
puts e.message
|
44
|
+
@socket.close
|
45
|
+
end
|
46
|
+
|
47
|
+
def listen!
|
48
|
+
Thread.new do
|
49
|
+
loop do
|
50
|
+
response = @socket.gets&.chomp
|
51
|
+
puts response unless response.nil?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rescue IOError => e
|
55
|
+
puts e.message
|
56
|
+
@socket.close
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Whatup
|
4
|
+
module Server
|
5
|
+
class Client
|
6
|
+
attr_reader :id, :name
|
7
|
+
attr_accessor :socket
|
8
|
+
|
9
|
+
def initialize id:, name:, socket:
|
10
|
+
@id = id
|
11
|
+
@name = name
|
12
|
+
@socket = socket
|
13
|
+
end
|
14
|
+
|
15
|
+
def puts msg
|
16
|
+
@socket.puts msg
|
17
|
+
end
|
18
|
+
|
19
|
+
def gets
|
20
|
+
@socket.gets
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
require 'whatup/server/client'
|
7
|
+
|
8
|
+
module Whatup
|
9
|
+
module Server
|
10
|
+
class Server
|
11
|
+
include Thor::Shell
|
12
|
+
|
13
|
+
Client = Whatup::Server::Client
|
14
|
+
|
15
|
+
def initialize port:
|
16
|
+
@ip = 'localhost'
|
17
|
+
@port = port
|
18
|
+
@address = "#{@ip}:#{@port}"
|
19
|
+
|
20
|
+
@clients = []
|
21
|
+
@max_id = 1
|
22
|
+
|
23
|
+
@pid = Process.pid
|
24
|
+
@pid_file = "#{Dir.home}/.whatup.pid"
|
25
|
+
end
|
26
|
+
|
27
|
+
def start
|
28
|
+
say "Starting a server with PID:#{@pid} @ #{@address} ... \n", :green
|
29
|
+
|
30
|
+
exit_if_pid_exists!
|
31
|
+
connect_to_socket!
|
32
|
+
write_pid!
|
33
|
+
|
34
|
+
# Listen for connections, then accept each in a separate thread
|
35
|
+
loop do
|
36
|
+
Thread.new @socket.accept do |client|
|
37
|
+
handle_client client
|
38
|
+
end
|
39
|
+
end
|
40
|
+
rescue SignalException
|
41
|
+
kill
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def handle_client client
|
47
|
+
@clients << client = Client.new(
|
48
|
+
id: @max_id += 1,
|
49
|
+
name: client.gets.chomp,
|
50
|
+
socket: client
|
51
|
+
)
|
52
|
+
|
53
|
+
puts "#{client.name} just showed up!"
|
54
|
+
client.puts "Hello, #{client.name}!"
|
55
|
+
|
56
|
+
loop do
|
57
|
+
msg = client.gets&.chomp
|
58
|
+
puts "#{client.name}> #{msg}" unless msg.nil? || msg == ''
|
59
|
+
|
60
|
+
@clients.reject { |c| c.id == client.id }.each do |c|
|
61
|
+
c.puts "\n#{client.name}> #{msg}" unless msg.nil? || msg == ''
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def exit_if_pid_exists!
|
67
|
+
return unless running?
|
68
|
+
|
69
|
+
say <<~EXIT, :cyan
|
70
|
+
A server appears to already be running!
|
71
|
+
Check `#{@pid_file}`.
|
72
|
+
EXIT
|
73
|
+
|
74
|
+
kill
|
75
|
+
end
|
76
|
+
|
77
|
+
def connect_to_socket!
|
78
|
+
@socket = TCPServer.open @port
|
79
|
+
rescue Errno::EADDRINUSE
|
80
|
+
puts 'Address already in use!'
|
81
|
+
kill
|
82
|
+
end
|
83
|
+
|
84
|
+
def write_pid!
|
85
|
+
File.open(@pid_file, 'w') { |f| f.puts Process.pid }
|
86
|
+
end
|
87
|
+
|
88
|
+
def running?
|
89
|
+
File.file? @pid_file
|
90
|
+
end
|
91
|
+
|
92
|
+
def kill
|
93
|
+
say "Killing the server with PID:#{Process.pid} ...", :red
|
94
|
+
FileUtils.rm_rf @pid_file
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/whatup/version.rb
CHANGED
data/whatup.gemspec
CHANGED
@@ -11,7 +11,16 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.email = ['jethrodaniel@gmail.com']
|
12
12
|
|
13
13
|
spec.summary = 'A simple server-based instant messaging application'
|
14
|
-
|
14
|
+
spec.description = <<~DESC
|
15
|
+
whatup is a simple server-based instant messaging application using TCP
|
16
|
+
sockets.
|
17
|
+
|
18
|
+
It was created for educational purposes.
|
19
|
+
|
20
|
+
It is in development, and currently is both simplified and insecure.
|
21
|
+
|
22
|
+
Please be careful.
|
23
|
+
DESC
|
15
24
|
spec.homepage = 'https://github.com/jethrodaniel/whatup'
|
16
25
|
spec.license = 'MIT'
|
17
26
|
spec.required_ruby_version = '~> 2.4'
|
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.3
|
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-03-
|
11
|
+
date: 2019-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -122,7 +122,15 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 0.20.3
|
125
|
-
description:
|
125
|
+
description: |
|
126
|
+
whatup is a simple server-based instant messaging application using TCP
|
127
|
+
sockets.
|
128
|
+
|
129
|
+
It was created for educational purposes.
|
130
|
+
|
131
|
+
It is in development, and currently is both simplified and insecure.
|
132
|
+
|
133
|
+
Please be careful.
|
126
134
|
email:
|
127
135
|
- jethrodaniel@gmail.com
|
128
136
|
executables:
|
@@ -147,9 +155,12 @@ files:
|
|
147
155
|
- docs/installing_ruby.md
|
148
156
|
- exe/whatup
|
149
157
|
- lib/whatup.rb
|
150
|
-
- lib/whatup/cli.rb
|
151
|
-
- lib/whatup/client.rb
|
152
|
-
- lib/whatup/server.rb
|
158
|
+
- lib/whatup/cli/cli.rb
|
159
|
+
- lib/whatup/cli/commands/client.rb
|
160
|
+
- lib/whatup/cli/commands/server.rb
|
161
|
+
- lib/whatup/client/client.rb
|
162
|
+
- lib/whatup/server/client.rb
|
163
|
+
- lib/whatup/server/server.rb
|
153
164
|
- lib/whatup/version.rb
|
154
165
|
- whatup.gemspec
|
155
166
|
homepage: https://github.com/jethrodaniel/whatup
|
data/lib/whatup/cli.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'thor'
|
4
|
-
|
5
|
-
require 'whatup/server'
|
6
|
-
require 'whatup/client'
|
7
|
-
|
8
|
-
module Whatup
|
9
|
-
# Thor command classes for the cli.
|
10
|
-
# For usage, see <http://whatisthor.com/>
|
11
|
-
module CLI
|
12
|
-
# Client commands
|
13
|
-
class Client < Thor
|
14
|
-
option :ip, type: :string, default: 'localhost'
|
15
|
-
option :port, type: :numeric, default: 9_001
|
16
|
-
long_desc <<~DESC
|
17
|
-
Starts a client instance sending requests to the specified ip and port.
|
18
|
-
DESC
|
19
|
-
desc 'connect', 'Connects a new client instance to a server'
|
20
|
-
def connect
|
21
|
-
Whatup::Client.new(ip: options[:ip], port: options[:port]).connect
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# Server commands
|
26
|
-
class Server < Thor
|
27
|
-
option :port, type: :numeric, default: 9_001
|
28
|
-
desc 'start', 'Starts a server instance'
|
29
|
-
long_desc <<~DESC
|
30
|
-
Starts a server instance running locally on the specified port.
|
31
|
-
DESC
|
32
|
-
def start
|
33
|
-
Whatup::Server.new(port: options[:port]).start
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Top-level command class
|
38
|
-
class CLI < Thor
|
39
|
-
desc 'hello', 'Says hello'
|
40
|
-
def hello
|
41
|
-
say "Hello!\n", :cyan
|
42
|
-
end
|
43
|
-
|
44
|
-
desc 'server ...', 'Perform server commands'
|
45
|
-
long_desc <<~DESC
|
46
|
-
Perform server commands.
|
47
|
-
|
48
|
-
See `whatup server help COMMAND` for help on `COMMAND`.
|
49
|
-
DESC
|
50
|
-
subcommand 'server', Server
|
51
|
-
|
52
|
-
desc 'client ...', 'Perform client commands'
|
53
|
-
long_desc <<~DESC
|
54
|
-
Perform client commands.
|
55
|
-
|
56
|
-
See `whatup client help COMMAND` for help on `COMMAND`.
|
57
|
-
DESC
|
58
|
-
subcommand 'client', Client
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/whatup/client.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'socket'
|
4
|
-
|
5
|
-
module Whatup
|
6
|
-
class Client
|
7
|
-
include Thor::Shell
|
8
|
-
|
9
|
-
def initialize ip:, port:
|
10
|
-
@dest = {
|
11
|
-
ip: ip,
|
12
|
-
port: port,
|
13
|
-
address: "#{@ip}:#{@port}"
|
14
|
-
}
|
15
|
-
end
|
16
|
-
|
17
|
-
def connect
|
18
|
-
say "Connecting to #{@dest[:ip]}:#{@dest[:port]} ..."
|
19
|
-
|
20
|
-
@socket = TCPSocket.open @dest[:ip], @dest[:port]
|
21
|
-
|
22
|
-
@request = request!
|
23
|
-
@response = listen!
|
24
|
-
|
25
|
-
[@request, @response].each &:join
|
26
|
-
rescue SignalException
|
27
|
-
say 'Exiting ...', :red
|
28
|
-
exit
|
29
|
-
end
|
30
|
-
|
31
|
-
def request!
|
32
|
-
puts 'Please enter your username to establish a connection...'
|
33
|
-
begin
|
34
|
-
Thread.new do
|
35
|
-
loop do
|
36
|
-
message = $stdin.gets.chomp
|
37
|
-
@socket.puts message
|
38
|
-
end
|
39
|
-
end
|
40
|
-
rescue IOError => e
|
41
|
-
puts e.message
|
42
|
-
# e.backtrace
|
43
|
-
@socket.close
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def listen!
|
48
|
-
Thread.new do
|
49
|
-
loop do
|
50
|
-
response = @socket.gets.chomp
|
51
|
-
puts response.to_s
|
52
|
-
@socket.close if response.eql? 'quit'
|
53
|
-
end
|
54
|
-
end
|
55
|
-
rescue IOError => e
|
56
|
-
puts e.message
|
57
|
-
# e.backtrace
|
58
|
-
@socket.close
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/whatup/server.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'socket'
|
4
|
-
require 'fileutils'
|
5
|
-
|
6
|
-
module Whatup
|
7
|
-
class Server
|
8
|
-
include Thor::Shell
|
9
|
-
|
10
|
-
def initialize port:
|
11
|
-
@ip = 'localhost'
|
12
|
-
@port = port
|
13
|
-
@address = "#{@ip}:#{@port}"
|
14
|
-
|
15
|
-
@pid = Process.pid
|
16
|
-
|
17
|
-
@pid_file = "#{Dir.home}/.whatup.pid"
|
18
|
-
end
|
19
|
-
|
20
|
-
def start
|
21
|
-
say "Starting a server with PID:#{@pid} @ #{@address} ... \n", :green
|
22
|
-
|
23
|
-
exit_if_pid_exists!
|
24
|
-
connect_to_socket!
|
25
|
-
write_pid!
|
26
|
-
|
27
|
-
# Listen for connections, then accept each in a separate thread
|
28
|
-
loop do
|
29
|
-
Thread.new @socket.accept do |client|
|
30
|
-
handle_client client
|
31
|
-
end
|
32
|
-
end
|
33
|
-
rescue SignalException
|
34
|
-
kill
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def handle_client client
|
40
|
-
name = client.gets.chomp
|
41
|
-
puts "#{name} just showed up!"
|
42
|
-
client.puts "Hello, #{name}!"
|
43
|
-
|
44
|
-
client.puts 'Sending you the time ...'
|
45
|
-
|
46
|
-
loop do
|
47
|
-
client.puts Time.now
|
48
|
-
sleep 1
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def exit_if_pid_exists!
|
53
|
-
return unless running?
|
54
|
-
|
55
|
-
say <<~EXIT, :cyan
|
56
|
-
A server appears to already be running!
|
57
|
-
Check `#{@pid_file}`.
|
58
|
-
EXIT
|
59
|
-
|
60
|
-
kill
|
61
|
-
end
|
62
|
-
|
63
|
-
def connect_to_socket!
|
64
|
-
@socket = TCPServer.open @port
|
65
|
-
rescue Errno::EADDRINUSE
|
66
|
-
puts 'Address already in use!'
|
67
|
-
kill
|
68
|
-
end
|
69
|
-
|
70
|
-
def write_pid!
|
71
|
-
File.open(@pid_file, 'w') { |f| f.puts Process.pid }
|
72
|
-
end
|
73
|
-
|
74
|
-
def running?
|
75
|
-
File.file? @pid_file
|
76
|
-
end
|
77
|
-
|
78
|
-
def kill
|
79
|
-
say "Killing the server with PID:#{Process.pid} ...", :red
|
80
|
-
FileUtils.rm_rf @pid_file
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|