internet_scrabble_club 0.1.1 → 0.2.0

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.ruby-version +1 -1
  4. data/Rakefile +1 -1
  5. data/bin/scraper.rb +12 -0
  6. data/bin/spectator.rb +91 -0
  7. data/internet_scrabble_club.gemspec +3 -4
  8. data/lib/internet_scrabble_club.rb +1 -1
  9. data/lib/internet_scrabble_club/client.rb +34 -30
  10. data/lib/internet_scrabble_club/client/callback_queue.rb +22 -0
  11. data/lib/internet_scrabble_club/client/middleware.rb +7 -4
  12. data/lib/internet_scrabble_club/client/middleware/request/echo_ping.rb +23 -0
  13. data/lib/internet_scrabble_club/client/middleware/request/keep_alive.rb +31 -0
  14. data/lib/internet_scrabble_club/client/middleware/response/emit.rb +20 -0
  15. data/lib/internet_scrabble_club/client/middleware/response/parse.rb +26 -0
  16. data/lib/internet_scrabble_club/client/middleware/response/read.rb +21 -0
  17. data/lib/internet_scrabble_club/client/middleware/response/transform.rb +22 -0
  18. data/lib/internet_scrabble_club/client/response_parsers.rb +17 -0
  19. data/lib/internet_scrabble_club/client/response_parsers/base.rb +78 -0
  20. data/lib/internet_scrabble_club/client/response_parsers/close.rb +14 -0
  21. data/lib/internet_scrabble_club/client/response_parsers/examine.rb +15 -0
  22. data/lib/internet_scrabble_club/client/response_parsers/examine/history.rb +51 -0
  23. data/lib/internet_scrabble_club/client/response_parsers/history.rb +17 -0
  24. data/lib/internet_scrabble_club/client/response_parsers/login.rb +14 -0
  25. data/lib/internet_scrabble_club/client/response_parsers/ping.rb +13 -0
  26. data/lib/internet_scrabble_club/client/response_parsers/ping/reply.rb +12 -0
  27. data/lib/internet_scrabble_club/client/response_parsers/seek.rb +15 -0
  28. data/lib/internet_scrabble_club/client/response_parsers/unseek.rb +14 -0
  29. data/lib/internet_scrabble_club/client/response_parsers/who.rb +13 -0
  30. data/lib/internet_scrabble_club/client/response_parsers/who/list.rb +16 -0
  31. data/lib/internet_scrabble_club/client/response_parsers/who/move.rb +14 -0
  32. data/lib/internet_scrabble_club/client/response_transformers.rb +2 -0
  33. data/lib/internet_scrabble_club/client/response_transformers/base.rb +50 -0
  34. data/lib/internet_scrabble_club/client/response_transformers/examine/history.rb +22 -0
  35. metadata +31 -32
  36. data/lib/internet_scrabble_club/client/extensions/authentication.rb +0 -21
  37. data/lib/internet_scrabble_club/client/extensions/echo_ping.rb +0 -17
  38. data/lib/internet_scrabble_club/client/extensions/keep_alive.rb +0 -16
  39. data/lib/internet_scrabble_club/client/middleware/emit.rb +0 -18
  40. data/lib/internet_scrabble_club/client/middleware/parse.rb +0 -24
  41. data/lib/internet_scrabble_club/client/middleware/read.rb +0 -19
  42. data/lib/internet_scrabble_club/client/middleware/transform.rb +0 -20
  43. data/lib/internet_scrabble_club/message_parsers.rb +0 -17
  44. data/lib/internet_scrabble_club/message_parsers/base.rb +0 -76
  45. data/lib/internet_scrabble_club/message_parsers/close.rb +0 -12
  46. data/lib/internet_scrabble_club/message_parsers/examine.rb +0 -13
  47. data/lib/internet_scrabble_club/message_parsers/examine/history.rb +0 -49
  48. data/lib/internet_scrabble_club/message_parsers/history.rb +0 -15
  49. data/lib/internet_scrabble_club/message_parsers/login.rb +0 -12
  50. data/lib/internet_scrabble_club/message_parsers/ping.rb +0 -11
  51. data/lib/internet_scrabble_club/message_parsers/ping/reply.rb +0 -11
  52. data/lib/internet_scrabble_club/message_parsers/seek.rb +0 -13
  53. data/lib/internet_scrabble_club/message_parsers/unseek.rb +0 -12
  54. data/lib/internet_scrabble_club/message_parsers/who.rb +0 -11
  55. data/lib/internet_scrabble_club/message_parsers/who/list.rb +0 -14
  56. data/lib/internet_scrabble_club/message_parsers/who/move.rb +0 -12
  57. data/lib/internet_scrabble_club/message_transformers.rb +0 -3
  58. data/lib/internet_scrabble_club/message_transformers/base.rb +0 -48
  59. data/lib/internet_scrabble_club/message_transformers/examine/history.rb +0 -32
  60. data/lib/internet_scrabble_club/message_transformers/history.rb +0 -14
  61. data/lib/internet_scrabble_club/message_transformers/who/move.rb +0 -14
  62. data/lib/internet_scrabble_club/multi_queue.rb +0 -20
@@ -1,21 +0,0 @@
1
- module InternetScrabbleClub
2
- class Client
3
- module Extensions
4
-
5
- module Authentication
6
- def initialize(*args, &block)
7
- super; @event_emitter.on(:message) do |message|
8
- if message.command == 'CLOSE' && message.reason =~ /^Invalid password/
9
- fail InvalidCredentials
10
- end
11
- end
12
- end
13
-
14
- def authenticate(nickname, password, &callback)
15
- send_message('LOGIN', nickname, password, 1871, '?', &callback)
16
- end
17
- end
18
-
19
- end
20
- end
21
- end
@@ -1,17 +0,0 @@
1
- module InternetScrabbleClub
2
- class Client
3
- module Extensions
4
-
5
- module EchoPing
6
- def initialize(*args, &block)
7
- super; @event_emitter.on(:message) do |message|
8
- if [message.command, message.sub_command] == %w(PING REPLY)
9
- send_message('PING', 'REPLY')
10
- end
11
- end
12
- end
13
- end
14
-
15
- end
16
- end
17
- end
@@ -1,16 +0,0 @@
1
- module InternetScrabbleClub
2
- class Client
3
- module Extensions
4
-
5
- module KeepAlive
6
- def initialize(*args, &block)
7
- every(10) { keep_alive }; super
8
- end
9
-
10
- def keep_alive
11
- end
12
- end
13
-
14
- end
15
- end
16
- end
@@ -1,18 +0,0 @@
1
- module InternetScrabbleClub
2
- class Client
3
- module Middleware
4
-
5
- class Emit
6
- def initialize(stack, event_emitter)
7
- @stack, @event_emitter = stack, event_emitter
8
- end
9
-
10
- def call(env)
11
- @event_emitter.emit(:message, env[:message])
12
- @stack.call(env)
13
- end
14
- end
15
-
16
- end
17
- end
18
- end
@@ -1,24 +0,0 @@
1
- require 'parslet'
2
- require 'celluloid/logger'
3
- require_relative '../../message_parsers'
4
-
5
- module InternetScrabbleClub
6
- class Client
7
- module Middleware
8
-
9
- class Parse
10
- def initialize(stack, message_parser = MessageParsers::Base.new)
11
- @stack, @message_parser = stack, message_parser
12
- end
13
-
14
- def call(env)
15
- env[:message] = @message_parser.parse(env[:message])
16
- @stack.call(env)
17
- rescue Parslet::ParseFailed
18
- Celluloid::Logger.warn("Failed to parse message: #{env[:message]}")
19
- end
20
- end
21
-
22
- end
23
- end
24
- end
@@ -1,19 +0,0 @@
1
- module InternetScrabbleClub
2
- class Client
3
- module Middleware
4
-
5
- class Read
6
- def initialize(stack, socket)
7
- @stack, @socket = stack, socket
8
- end
9
-
10
- def call(env)
11
- message_length = @socket.getc.ord * 256 + @socket.getc.ord
12
- env[:message] = @socket.read(message_length)
13
- @stack.call(env)
14
- end
15
- end
16
-
17
- end
18
- end
19
- end
@@ -1,20 +0,0 @@
1
- require_relative '../../message_transformers'
2
-
3
- module InternetScrabbleClub
4
- class Client
5
- module Middleware
6
-
7
- class Transform
8
- def initialize(stack, message_transformer = MessageTransformers::Base.new)
9
- @stack, @message_transformer = stack, message_transformer
10
- end
11
-
12
- def call(env)
13
- env[:message] = @message_transformer.apply(env[:message])
14
- @stack.call(env)
15
- end
16
- end
17
-
18
- end
19
- end
20
- end
@@ -1,17 +0,0 @@
1
- require_relative 'message_parsers/close'
2
-
3
- require_relative 'message_parsers/examine'
4
- require_relative 'message_parsers/examine/history'
5
-
6
- require_relative 'message_parsers/who'
7
- require_relative 'message_parsers/who/list'
8
- require_relative 'message_parsers/who/move'
9
-
10
- require_relative 'message_parsers/history'
11
- require_relative 'message_parsers/login'
12
-
13
- require_relative 'message_parsers/ping'
14
- require_relative 'message_parsers/ping/reply'
15
-
16
- require_relative 'message_parsers/seek'
17
- require_relative 'message_parsers/unseek'
@@ -1,76 +0,0 @@
1
- require 'parslet'
2
- require 'descendants_tracker'
3
-
4
- module InternetScrabbleClub
5
- module MessageParsers
6
-
7
- class Base < Parslet::Parser
8
- extend DescendantsTracker
9
-
10
- root(:message)
11
-
12
- rule(:message) { descendant_parsers.reduce(:|) or (digit >> space >>
13
- ( command_with_sub_command_and_arguments |
14
- command_with_arguments | command_with_sub_command)) }
15
-
16
- rule(:command_with_arguments) { command.as(:command) >> space >>
17
- arguments.as(:arguments) }
18
-
19
- rule(:command_with_sub_command_and_arguments) { command_with_sub_command >>
20
- space >> arguments.as(:arguments) }
21
-
22
- rule(:command_with_sub_command) { command.as(:command) >>
23
- space >> sub_command.as(:sub_command) }
24
-
25
- rule(:command) { nothing }
26
- rule(:sub_command) { nothing }
27
- rule(:arguments) { nothing }
28
-
29
- rule(:nothing) { str('') }
30
-
31
- rule(:space) { str(' ') }
32
- rule(:space?) { space.maybe }
33
-
34
- rule(:newline) { match('\n') }
35
- rule(:newline?) { newline.maybe }
36
-
37
- rule(:colon) { str(':') }
38
- rule(:semicolon) { str(';') }
39
- rule(:minus) { str('-') }
40
-
41
- rule(:digit) { match['0-9'] }
42
- rule(:alpha) { match['A-Za-z'] }
43
-
44
- rule(:int) { _int.as(:int) }
45
- rule(:_int) { minus.maybe >> digit.repeat(1) }
46
-
47
- rule(:dashes) { str('---').as(:dashes) }
48
- rule(:null) { str('null').as(:null) }
49
-
50
- rule(:word) { (digit | alpha).repeat(1).as(:word) }
51
- rule(:sentence) { (match['^.'].repeat(1) >> str('.')).as(:sentence) }
52
- rule(:text) { any.repeat(1).as(:text) }
53
-
54
- rule(:tiles) { (alpha | str('?')).repeat(1).as(:tiles) }
55
- rule(:rack) { dashes | tiles }
56
-
57
- rule(:month_day) { digit.repeat(1, 2) }
58
- rule(:short_month) { match['A-Z'] >> match['a-z'].repeat(2, 2) }
59
- rule(:short_year) { digit >> digit }
60
- rule(:date) { (delimited [month_day, short_month, short_year], colon).as(:date) }
61
-
62
- rule(:dictionary) { str('TWL') | str('SOWPODS') | str('ODS') | str('LOC') |
63
- str('SWL') | str('PARO') | str('MULTI') }
64
-
65
- def delimited(sequence, seperator = space)
66
- seperators = Array.new(sequence.length - 1) { seperator }
67
- sequence.zip(seperators).flatten(1).compact.inject(:>>)
68
- end
69
-
70
- private def descendant_parsers
71
- @descendant_parsers ||= self.class.descendants.map(&:new)
72
- end
73
- end
74
-
75
- end
76
- end
@@ -1,12 +0,0 @@
1
- require_relative 'base'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Close < Base
7
- rule(:command) { str('CLOSE') }
8
- rule(:arguments) { text.as(:reason) }
9
- end
10
-
11
- end
12
- end
@@ -1,13 +0,0 @@
1
- require_relative 'base'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Examine < Base
7
- rule(:command) { str('EXAMINE') }
8
- rule(:command_with_sub_command_and_arguments) { command_with_sub_command >>
9
- space? >> newline >> arguments.as(:arguments) }
10
- end
11
-
12
- end
13
- end
@@ -1,49 +0,0 @@
1
- require_relative '../examine'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Examine::History < Examine
7
- rule(:sub_command) { str('HISTORY') }
8
-
9
- rule(:arguments) { delimited([stats, settings,
10
- (player_setup.as(:setup) >> newline_with_whitespace >> plays.as(:plays)
11
- ).as(:first_player), str('STOP'),
12
- (player_setup.as(:setup) >> newline_with_whitespace >> plays.as(:plays)
13
- ).as(:second_player), str('STOP')
14
- ], newline_with_whitespace) >> newline_with_whitespace }
15
-
16
- rule(:newline_with_whitespace) { space.repeat >> newline >> space.repeat }
17
-
18
- rule(:stats) { _int >> space >> date.as(:date) }
19
- rule(:settings) { delimited [int.dictionary_code, _int, _int, _int] }
20
-
21
- rule(:player_setup) { delimited [word.as(:nickname), int.as(:rating),
22
- rack.as(:initial_rack), (int | null).as(:final_score)] }
23
-
24
- rule(:plays) { ((move | change | pass) >> space?).repeat }
25
-
26
- rule(:move) { delimited [str('MOVE').as(:word).as(:type), position.as(:position),
27
- tiles.as(:word), int.as(:score), _int, _int, rack.as(:rack), _int] }
28
-
29
- rule(:change) { delimited [str('CHANGE').as(:word).as(:type), rack.as(:rack),
30
- _int, _int, (dashes | int).as(:swap_count)] }
31
-
32
- rule(:pass) { delimited [str('PAS').as(:word).as(:type), _int, _int, (dashes |
33
- suggestion).as(:suggestion)] }
34
-
35
- rule(:suggestion) { delimited [position.as(:position), word.as(:word),
36
- int.as(:score)], underscore }
37
-
38
- rule(:underscore) { match('_') }
39
- rule(:underscored_word) { word >> underscore >> word }
40
-
41
- rule(:position) { horizontal_position.as(:horizontal) |
42
- vertical_position.as(:vertical) }
43
-
44
- rule(:horizontal_position) { alpha.as(:word).as(:column) >> int.as(:row) }
45
- rule(:vertical_position) { int.as(:row) >> alpha.as(:word).as(:column) }
46
- end
47
-
48
- end
49
- end
@@ -1,15 +0,0 @@
1
- require_relative 'base'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class History < Base
7
- rule(:command) { str('HISTORY') }
8
- rule(:arguments) { word.as(:subject) >> space >> entries.as(:entries) }
9
- rule(:entries) { (entry.as(:entry) >> space?).repeat(1) }
10
- rule(:entry) { delimited [digit.as(:index), players, dictionary, _int, date.as(:date)] }
11
- rule(:players) { delimited [_int, word.as(:first_player), _int, word.as(:second_player)] }
12
- end
13
-
14
- end
15
- end
@@ -1,12 +0,0 @@
1
- require_relative 'base'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Login < Base
7
- rule(:command) { str('LOGIN') }
8
- rule(:arguments) { sentence.as(:greeting) }
9
- end
10
-
11
- end
12
- end
@@ -1,11 +0,0 @@
1
- require_relative 'base'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Ping < Base
7
- rule(:command) { str('PING') }
8
- end
9
-
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- require_relative '../ping'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Ping::Reply < Ping
7
- rule(:sub_command) { str('REPLY') }
8
- end
9
-
10
- end
11
- end
@@ -1,13 +0,0 @@
1
- require_relative 'base'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Seek < Base
7
- rule(:command) { str('SEEK') }
8
- rule(:arguments) { delimited [int.as(:rating), word.as(:nickname), settings] }
9
- rule(:settings) { delimited([_int] * 7) }
10
- end
11
-
12
- end
13
- end
@@ -1,12 +0,0 @@
1
- require_relative 'base'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Unseek < Base
7
- rule(:command) { str('UNSEEK') }
8
- rule(:arguments) { word.as(:nickname) }
9
- end
10
-
11
- end
12
- end
@@ -1,11 +0,0 @@
1
- require_relative 'base'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Who < Base
7
- rule(:command) { str('WHO') }
8
- end
9
-
10
- end
11
- end
@@ -1,14 +0,0 @@
1
- require_relative '../who'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Who::List < Who
7
- rule(:sub_command) { str('LIST') }
8
- rule(:arguments) { int.as(:count) >> space >> space >> users.as(:users) }
9
- rule(:users) { (user.as(:user) >> space?).repeat(1) }
10
- rule(:user) { delimited [int.as(:rating), word.as(:nickname), any.as(:status), digit, digit] }
11
- end
12
-
13
- end
14
- end
@@ -1,12 +0,0 @@
1
- require_relative '../who'
2
-
3
- module InternetScrabbleClub
4
- module MessageParsers
5
-
6
- class Who::Move< Who
7
- rule(:sub_command) { str('MOVE') }
8
- rule(:arguments) { delimited [_int, word.as(:nickname), alpha, _int, _int] }
9
- end
10
-
11
- end
12
- end