internet_scrabble_club 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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