zugzwang 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 05635fe914744c367688b19ab78385de0e45e6318df66f4faa9d8ed6b5abd1e4
4
+ data.tar.gz: 28b8c4bd1cba55ec00eaf22b79a32080986b831d1c838aaac044c71253eaa9cb
5
+ SHA512:
6
+ metadata.gz: fcc0d318197c440aca40a3dcaa802d357eaa1040b1005512d4b4b8ce6517d78e00f1b97a74bb041c1690db0f95d2d427a52fa23167602d434c6014458cb8eca3
7
+ data.tar.gz: de45f7027ab502d57b6519b4581d303d051349f38c484f1394c1ed3bb13d1a1550c046d1a537b8288f3b70497e5b7b747408aa76a3b5465838a6082c0cddaa90
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in zugzwang.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ zugzwang (0.1.0)
5
+ ruby-progressbar (~> 1.9)
6
+ sequel (~> 5.9)
7
+ sqlite3 (~> 1.3)
8
+ thor (~> 0.20)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ diff-lcs (1.3)
14
+ rake (12.3.1)
15
+ rspec (3.7.0)
16
+ rspec-core (~> 3.7.0)
17
+ rspec-expectations (~> 3.7.0)
18
+ rspec-mocks (~> 3.7.0)
19
+ rspec-core (3.7.1)
20
+ rspec-support (~> 3.7.0)
21
+ rspec-expectations (3.7.0)
22
+ diff-lcs (>= 1.2.0, < 2.0)
23
+ rspec-support (~> 3.7.0)
24
+ rspec-mocks (3.7.0)
25
+ diff-lcs (>= 1.2.0, < 2.0)
26
+ rspec-support (~> 3.7.0)
27
+ rspec-support (3.7.1)
28
+ ruby-progressbar (1.9.0)
29
+ sequel (5.9.0)
30
+ sqlite3 (1.3.13)
31
+ thor (0.20.0)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ bundler (~> 1.16)
38
+ rake (~> 12.3)
39
+ rspec (~> 3.7)
40
+ zugzwang!
41
+
42
+ BUNDLED WITH
43
+ 1.16.2
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Edwin Onuonga
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,173 @@
1
+ ![Gem](https://img.shields.io/gem/v/zugzwang.svg)
2
+ [![License](https://img.shields.io/github/license/eonu/zugzwang.svg)](https://github.com/eonu/string-builder/blob/master/LICENSE)
3
+
4
+ # Zugzwang
5
+
6
+ Converts the metadata of PGN files from Lichess' game database to a database file, using lazy file enumerators for optimizing the conversion of large PGN files with millions of chess games.
7
+
8
+ ## PGN files
9
+
10
+ PGN (**P**ost-**G**ame **N**otation) files are plain-text files that provide records of chess games along with their metadata.
11
+
12
+ ### Lichess PGN format
13
+
14
+ The extensive [game database provided by Lichess](https://database.lichess.org/) (over 368 million games as of July 2018) uses the following format for each game of within their PGN files.
15
+
16
+ ```
17
+ [Event "Rated Bullet tournament https://lichess.org/tournament/yc1WW2Ox"]
18
+ [Site "https://lichess.org/PpwPOZMq"]
19
+ [White "Abbot"]
20
+ [Black "Costello"]
21
+ [Result "0-1"]
22
+ [UTCDate "2017.04.01"]
23
+ [UTCTime "11:32:01"]
24
+ [WhiteElo "2100"]
25
+ [BlackElo "2000"]
26
+ [WhiteRatingDiff "-4"]
27
+ [BlackRatingDiff "+1"]
28
+ [WhiteTitle "FM"]
29
+ [ECO "B30"]
30
+ [Opening "Sicilian Defense: Old Sicilian"]
31
+ [TimeControl "300+0"]
32
+ [Termination "Time forfeit"]
33
+
34
+ 1. e4 { [%eval 0.17] [%clk 0:00:30] } 1... c5 { [%eval 0.19] [%clk 0:00:30] }
35
+ 2. Nf3 { [%eval 0.25] [%clk 0:00:29] } 2... Nc6 { [%eval 0.33] [%clk 0:00:30] }
36
+ 3. Bc4 { [%eval -0.13] [%clk 0:00:28] } 3... e6 { [%eval -0.04] [%clk 0:00:30] }
37
+ 4. c3 { [%eval -0.4] [%clk 0:00:27] } 4... b5? { [%eval 1.18] [%clk 0:00:30] }
38
+ 5. Bb3?! { [%eval 0.21] [%clk 0:00:26] } 5... c4 { [%eval 0.32] [%clk 0:00:29] }
39
+ 6. Bc2 { [%eval 0.2] [%clk 0:00:25] } 6... a5 { [%eval 0.6] [%clk 0:00:29] }
40
+ 7. d4 { [%eval 0.29] [%clk 0:00:23] } 7... cxd3 { [%eval 0.6] [%clk 0:00:27] }
41
+ 8. Qxd3 { [%eval 0.12] [%clk 0:00:22] } 8... Nf6 { [%eval 0.52] [%clk 0:00:26] }
42
+ 9. e5 { [%eval 0.39] [%clk 0:00:21] } 9... Nd5 { [%eval 0.45] [%clk 0:00:25] }
43
+ 10. Bg5?! { [%eval -0.44] [%clk 0:00:18] } 10... Qc7 { [%eval -0.12] [%clk 0:00:23] }
44
+ 11. Nbd2?? { [%eval -3.15] [%clk 0:00:14] } 11... h6 { [%eval -2.99] [%clk 0:00:23] }
45
+ 12. Bh4 { [%eval -3.0] [%clk 0:00:11] } 12... Ba6? { [%eval -0.12] [%clk 0:00:23] }
46
+ 13. b3?? { [%eval -4.14] [%clk 0:00:02] } 13... Nf4? { [%eval -2.73] [%clk 0:00:21] } 0-1
47
+ ```
48
+
49
+ The data is divided into **two** sections:
50
+
51
+ #### Metadata
52
+
53
+ This section contains the metadata about the chess game.
54
+
55
+ In the example game above, the metadata section is the part that looks like:
56
+
57
+ ```
58
+ [Event "Rated Bullet tournament https://lichess.org/tournament/yc1WW2Ox"]
59
+ [Site "https://lichess.org/PpwPOZMq"]
60
+ [White "Abbot"]
61
+ ...
62
+ [TimeControl "300+0"]
63
+ [Termination "Time forfeit"]
64
+ ```
65
+
66
+ This is the section that the CLI is concerned with, and will produce a database record with the fields consisting of the metadata for each game.
67
+
68
+ #### PGN
69
+
70
+ This section contains the actual record of the chess game, the moves are given in <a href="https://en.wikipedia.org/wiki/Algebraic_notation_(chess)">Algebraic Chess Notation</a>.
71
+
72
+ In the example game above, the PGN section is the part that looks like:
73
+
74
+ ```
75
+ 1. e4 { [%eval 0.17] [%clk 0:00:30] } 1... c5 { [%eval 0.19] [%clk 0:00:30] }
76
+ 2. Nf3 { [%eval 0.25] [%clk 0:00:29] } 2... Nc6 { [%eval 0.33] [%clk 0:00:30] }
77
+ 3. Bc4 { [%eval -0.13] [%clk 0:00:28] } 3... e6 { [%eval -0.04] [%clk 0:00:30] }
78
+ ...
79
+ 12. Bh4 { [%eval -3.0] [%clk 0:00:11] } 12... Ba6? { [%eval -0.12] [%clk 0:00:23] }
80
+ 13. b3?? { [%eval -4.14] [%clk 0:00:02] } 13... Nf4? { [%eval -2.73] [%clk 0:00:21] } 0-1
81
+ ```
82
+
83
+ Since this CLI is not concerned with individual moves or position analysis, this data is discarded during the parsing process.
84
+
85
+ ## Installation
86
+
87
+ To install the CLI:
88
+
89
+ ```bash
90
+ $ gem install zugzwang
91
+ ```
92
+
93
+ ## Usage
94
+
95
+ Once you have installed the CLI, you can use it with the command:
96
+
97
+ ```bash
98
+ $ zugzwang
99
+ ```
100
+
101
+ The only command available is `create`.
102
+
103
+ ```bash
104
+ $ zugzwang create [DATABASE] *[ITEMS] --extension, --extension=EXTENSION
105
+ # Converts the metadata of PGN files from Lichess' game database to a database file.
106
+ ```
107
+
108
+ ### Arguments and flags
109
+
110
+ - `DATABASE` - The path to the newly generated database file.
111
+
112
+ **DEFAULT**: `lichess`
113
+
114
+ > **Examples:**
115
+ >
116
+ > - `games` - Generates a database file called `games` (with extension specified by flag) in the current directory.
117
+ > - `path/to/db/games` - Generates a database file called `games` (with extension specified by flag) in the `path/to/db` directory, which the user is prompted to create if it does not exist.
118
+
119
+ - `*[ITEMS]` - The PGN files to parse (or directory to recursively search for PGN files), separated by spaces.
120
+
121
+ Patterns are accepted, and an argument is assumed to be a directory if no extension is given.
122
+
123
+ > **Examples**:
124
+ >
125
+ > - `test.pgn games/game1.pgn games/game2.pgn games/game3.pgn` - Specifying individual files
126
+ > - `test.pgn games` - Reads the `test.pgn` files, then searches the `games` directory recursively for any `pgn` files.
127
+ > - `test.pgn games/*.pgn` - Does the same as the previous command, but using patterns.
128
+ > - `.` - Does the same as the previous command by recursively searching the current directory.
129
+
130
+ - `--extension` - The file extension to be given to the database.
131
+
132
+ **DEFAULT**: `sql`
133
+
134
+ The file extension should be given without the preceding `.` dot.
135
+
136
+ Expected file extensions are `sql sqlite sqlite3 db`, but it is possible to override this restriction and try to generate a database with any extension, provided it is compatible with Sequel's database class constructor.
137
+
138
+ Ideally, the extension should be specified at the end of the command.
139
+
140
+ > **Examples**:
141
+ >
142
+ > - `--extension=sqlite3` - Extension specifier with explicit equals sign.
143
+ > - `--extension sqlite3` - Extension specifier without explicit equals sign.
144
+
145
+ ### Examples
146
+
147
+ > ```bash
148
+ > $ zugzwang create lichess/db/2018-05 games-2018-05.pgn --extension sqlite3
149
+ > ```
150
+ >
151
+ > - Creates a database file at `lichess/db/2018-05.sqlite3`, populating it with data from file `games-2018-05.pgn`.
152
+
153
+ > ```bash
154
+ > $ zugzwang create database games/*.pgn --extension sql
155
+ > ```
156
+ >
157
+ > - Creates a database file at `database.sql`, populating it with data from `.pgn` files located within the `games` directory.
158
+
159
+ > ```bash
160
+ > $ zugzwang create games/1 . --extension db
161
+ > ```
162
+ >
163
+ > - Creates a database file at `games/1.db`, populating it with data from `.pgn` files found from recursively searching the current directory.
164
+
165
+ ## Development
166
+
167
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
168
+
169
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
170
+
171
+ ## Contributing
172
+
173
+ Bug reports and pull requests are welcome on GitHub at https://github.com/eonu/zugzwang.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "zugzwang"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/bin/zugzwang ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'zugzwang/cli'
3
+ Zugzwang::CLI.start
data/lib/zugzwang.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "zugzwang/version"
2
+ require "zugzwang/helpers"
3
+ require "zugzwang/cli"
4
+
5
+ module Zugzwang
6
+ FIELDS = %i[Event Site White Black Result UTCDate UTCTime WhiteElo BlackElo WhiteRatingDiff BlackRatingDiff WhiteTitle ECO Opening TimeControl Termination]
7
+ EXTENSIONS = %i[sql sqlite sqlite3 db]
8
+ end
@@ -0,0 +1,77 @@
1
+ require 'zugzwang'
2
+ require 'zugzwang/helpers'
3
+ require 'zugzwang/create'
4
+ require 'sequel'
5
+ require 'sqlite3'
6
+ require 'sequel'
7
+ require 'thor'
8
+
9
+ module Zugzwang
10
+ class CLI < Thor
11
+ include Thor::Actions
12
+
13
+ method_option :extension, type: :string, required: true, default: 'sql', aliases: '--extension'
14
+ desc 'create [DATABASE] *[ITEMS]', "Converts the metadata of PGN files from Lichess' game database to a database file."
15
+ def create(database = 'lichess', *items)
16
+ if items.empty?
17
+ puts "\n\e[1;91mERROR\e[0m: No files specified." if items.empty?
18
+ return
19
+ end
20
+
21
+ database = sanitize_path(database)
22
+ extension = options[:extension].sub(?.,'').to_sym
23
+ override = false
24
+
25
+ loop do
26
+ if Zugzwang::EXTENSIONS.include?(extension) || override
27
+
28
+ begin
29
+ db = Sequel.sqlite("#{database}.#{extension}")
30
+ Zugzwang::Create[db, database, extension, items]
31
+ rescue Sequel::DatabaseConnectionError => e
32
+ puts "\n\e[1;91mERROR\e[0m: Directory \e[1m#{File.dirname(database)}\e[0m does not exist."
33
+
34
+ pass = false
35
+ until pass
36
+ response = ask("\e[1mPROMPT: \e[0mCreate directory \e[1m#{File.dirname(database)}\e[0m? [Y/n]")
37
+ if %w[Y y YES Yes yes].include? response
38
+ puts
39
+ empty_directory(File.dirname(database))
40
+ begin
41
+ db = Sequel.sqlite("#{database}.#{extension}")
42
+ Zugzwang::Create[db, database, extension, items]
43
+ rescue Sequel::DatabaseConnectionError
44
+ puts "\n\e[1;91mERROR\e[0m: Unable to create database with extension \e[1m#{extension}\e[0m"
45
+ end
46
+ pass = true
47
+ elsif %w[N n NO No no].include? response
48
+ pass = true
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ return
55
+
56
+ else
57
+
58
+ puts "\n\e[1;93mWARNING\e[0m: Extension argument should be one of [#{Zugzwang::EXTENSIONS*', '}]."
59
+
60
+ pass = false
61
+ until pass
62
+ response = ask("\e[1mPROMPT: \e[0mAttempt to create database with extension \e[1m#{extension}\e[0m? [Y/n]")
63
+ if %w[Y y YES Yes yes].include? response
64
+ override = true
65
+ pass = true
66
+ elsif %w[N n NO No no].include? response
67
+ return
68
+ end
69
+ end
70
+
71
+ end
72
+ end
73
+ end
74
+
75
+ include Zugzwang::Helpers
76
+ end
77
+ end
@@ -0,0 +1,48 @@
1
+ require 'ruby-progressbar'
2
+ require 'thor'
3
+
4
+ module Zugzwang
5
+ module Create
6
+ def self.[](database_object, database, extension, items)
7
+ database_object.create_table :games do
8
+ primary_key :id
9
+ FIELDS.each {|field| String field}
10
+ end
11
+
12
+ files = items.map{|item|
13
+ File.file?(item) ? Dir[item] : Dir["#{item}/**/*.pgn"]
14
+ }.flatten
15
+
16
+ puts if files.map{|f|File.file? f}.any?{|f|f==true}
17
+
18
+ files.each do |f|
19
+ record = {}
20
+ prev = ''
21
+ lines = `sed -n '=' #{f} | wc -l`.to_i
22
+ puts "\e[90mProcessing file:\e[0m \e[1m#{f}\e[0m"
23
+ progress_bar = ProgressBar.create(:title => 'Progress', total: lines, progress_mark: "\e[1;35m#{?#}\e[0m", remainder_mark: ?., format: "%t: %p%% (Line: %c/%C) %B")
24
+ File.open(f,'r').each do |line|
25
+ if prev =~ /\A\[.*\Z/ && line =~ /\A[\n\r].*\Z/
26
+ database_object[:games].insert **record
27
+ record = {}
28
+ prev = line
29
+ progress_bar.increment
30
+ next
31
+ end
32
+ if line =~ /\A([\n\r]|[0-9]).*\Z/
33
+ prev = line
34
+ progress_bar.increment
35
+ next
36
+ end
37
+ subbed = line.gsub(%r{[\r\n\[\]\"]},'')
38
+ field, value = subbed.split(' ', 2)
39
+ field = field.to_sym
40
+ record[field.to_sym] = value if FIELDS.include?(field)
41
+ prev = line
42
+ progress_bar.increment
43
+ end
44
+ end
45
+ puts "\n\e[92mComplete\e[0m: Saved #{extension} database at \e[1m#{database}.#{extension}\e[0m."
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,12 @@
1
+ module Zugzwang
2
+ module Helpers
3
+ def sanitize_path(path)
4
+ dir, file = File.dirname(path), File.basename(path,'.*')
5
+ file.strip! do |name|
6
+ name.gsub!(/^.*(\\|\/)/, '')
7
+ name.gsub!(/[^0-9A-Za-z.\-]/, '_')
8
+ end
9
+ "#{dir}/#{file}"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Zugzwang
2
+ VERSION = "0.1.0"
3
+ end
data/zugzwang.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "zugzwang/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "zugzwang"
7
+ spec.version = Zugzwang::VERSION
8
+ spec.authors = ["Edwin Onuonga"]
9
+ spec.email = ["edwinonuonga@gmail.com"]
10
+
11
+ spec.summary = %q{Converts the metadata of PGN files from Lichess' game database to a database file, using lazy file enumerators for optimizing the conversion of large PGN files with millions of chess games.}
12
+ spec.homepage = "https://www.github.com/eonu/zugzwang"
13
+ spec.license = "MIT"
14
+
15
+ # Specify which files should be added to the gem when it is released.
16
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
17
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.16"
25
+ spec.add_development_dependency "rake", "~> 12.3"
26
+ spec.add_development_dependency "rspec", "~> 3.7"
27
+
28
+ spec.add_runtime_dependency "sequel", "~> 5.9"
29
+ spec.add_runtime_dependency "sqlite3", "~> 1.3"
30
+ spec.add_runtime_dependency "thor", "~> 0.20"
31
+ spec.add_runtime_dependency "ruby-progressbar", "~> 1.9"
32
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zugzwang
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Edwin Onuonga
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-07-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sequel
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.9'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.3'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.20'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.20'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ruby-progressbar
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.9'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.9'
111
+ description:
112
+ email:
113
+ - edwinonuonga@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - Gemfile
120
+ - Gemfile.lock
121
+ - LICENSE
122
+ - README.md
123
+ - Rakefile
124
+ - bin/console
125
+ - bin/setup
126
+ - bin/zugzwang
127
+ - lib/zugzwang.rb
128
+ - lib/zugzwang/cli.rb
129
+ - lib/zugzwang/create.rb
130
+ - lib/zugzwang/helpers.rb
131
+ - lib/zugzwang/version.rb
132
+ - zugzwang.gemspec
133
+ homepage: https://www.github.com/eonu/zugzwang
134
+ licenses:
135
+ - MIT
136
+ metadata: {}
137
+ post_install_message:
138
+ rdoc_options: []
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubyforge_project:
153
+ rubygems_version: 2.7.3
154
+ signing_key:
155
+ specification_version: 4
156
+ summary: Converts the metadata of PGN files from Lichess' game database to a database
157
+ file, using lazy file enumerators for optimizing the conversion of large PGN files
158
+ with millions of chess games.
159
+ test_files: []