scapeshift 1.0.1rg0
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.
- data/.document +5 -0
- data/.gitignore +36 -0
- data/.yardopts +1 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +29 -0
- data/LICENSE +20 -0
- data/README.md +76 -0
- data/Rakefile +64 -0
- data/VERSION +1 -0
- data/lib/scapeshift.rb +9 -0
- data/lib/scapeshift/card.rb +404 -0
- data/lib/scapeshift/crawler.rb +64 -0
- data/lib/scapeshift/crawlers.rb +20 -0
- data/lib/scapeshift/crawlers/base.rb +107 -0
- data/lib/scapeshift/crawlers/cards.rb +331 -0
- data/lib/scapeshift/crawlers/meta.rb +136 -0
- data/lib/scapeshift/crawlers/single.rb +404 -0
- data/lib/scapeshift/errors.rb +85 -0
- data/scapeshift.gemspec +78 -0
- data/test/helper.rb +16 -0
- data/test/test_base_crawler.rb +48 -0
- data/test/test_card.rb +80 -0
- data/test/test_card_crawler.rb +92 -0
- data/test/test_crawler_main.rb +16 -0
- data/test/test_meta_crawler.rb +78 -0
- data/test/test_single_crawler.rb +189 -0
- metadata +102 -0
data/.document
ADDED
data/.gitignore
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## IntelliJ
|
17
|
+
.idea
|
18
|
+
*.iml
|
19
|
+
.rakeTasks
|
20
|
+
|
21
|
+
## PROJECT::GENERAL
|
22
|
+
coverage
|
23
|
+
rdoc
|
24
|
+
pkg
|
25
|
+
|
26
|
+
## YARD
|
27
|
+
doc/*
|
28
|
+
.yardoc
|
29
|
+
|
30
|
+
## BUNDLER
|
31
|
+
.bundle/*
|
32
|
+
|
33
|
+
## PROJECT::SPECIFIC
|
34
|
+
|
35
|
+
## FAKEWEB CACHE FILES
|
36
|
+
test/fakeweb/*.html
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--protected --private --default-return 'void'
|
data/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'bundler'
|
4
|
+
|
5
|
+
# Development dependencies
|
6
|
+
gem 'rake'
|
7
|
+
gem 'jeweler'
|
8
|
+
gem 'rdoc'
|
9
|
+
gem 'yard'
|
10
|
+
gem 'bluecloth'
|
11
|
+
gem 'shoulda'
|
12
|
+
|
13
|
+
# Test dependencies
|
14
|
+
gem 'fakeweb'
|
15
|
+
|
16
|
+
# Runtime dependencies
|
17
|
+
gem 'nokogiri'
|
18
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
bluecloth (2.1.0)
|
5
|
+
fakeweb (1.3.0)
|
6
|
+
git (1.2.5)
|
7
|
+
jeweler (1.6.2)
|
8
|
+
bundler (~> 1.0)
|
9
|
+
git (>= 1.2.5)
|
10
|
+
rake
|
11
|
+
nokogiri (1.5.0)
|
12
|
+
rake (0.9.2)
|
13
|
+
rdoc (3.8)
|
14
|
+
shoulda (2.11.3)
|
15
|
+
yard (0.7.2)
|
16
|
+
|
17
|
+
PLATFORMS
|
18
|
+
ruby
|
19
|
+
|
20
|
+
DEPENDENCIES
|
21
|
+
bluecloth
|
22
|
+
bundler
|
23
|
+
fakeweb
|
24
|
+
jeweler
|
25
|
+
nokogiri
|
26
|
+
rake
|
27
|
+
rdoc
|
28
|
+
shoulda
|
29
|
+
yard
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Josh Lindsey
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
Scapeshift
|
2
|
+
==========
|
3
|
+
|
4
|
+
Scapeshift is a webscraper rubygem designed for the Magic: The Gathering Oracle "Gatherer" card index.
|
5
|
+
Since Wizards doesn't want to make an API for this system for various reasons, I've gone ahead and made
|
6
|
+
a pseudo-API here.
|
7
|
+
|
8
|
+
Scapeshift uses the delightful Nokogiri gem to parse and scrape the various Oracle pages, generating
|
9
|
+
(most commonly) a SortedSet of Scapeshift::Card objects containing the card data. In the case of expansion sets, formats,
|
10
|
+
etc. Scapeshift returns a SortedSet of strings.
|
11
|
+
|
12
|
+
Usage
|
13
|
+
-----
|
14
|
+
|
15
|
+
Usage is as simple as can be:
|
16
|
+
|
17
|
+
# Grab the complete list of expansion sets
|
18
|
+
@sets = Scapeshift::Crawler.crawl :meta, :type => :sets
|
19
|
+
|
20
|
+
# Grab the card set for an expansion
|
21
|
+
@alara_cards = Scapeshift::Crawler.crawl :cards, :set => 'Shards of Alara'
|
22
|
+
|
23
|
+
# Grab a single named card
|
24
|
+
@card = Scapeshift::Crawler.crawl :single, :name => 'Counterspell'
|
25
|
+
|
26
|
+
Development
|
27
|
+
-----------
|
28
|
+
|
29
|
+
This gem uses Bundler to manage its dependencies for development:
|
30
|
+
|
31
|
+
$ sudo gem install bundler
|
32
|
+
$ cd /path/to/scapeshift
|
33
|
+
$ bundle install
|
34
|
+
|
35
|
+
Bundler is unlike Rubygems in that it doesn't automagically handle load paths for you. To
|
36
|
+
make stuff work, you will need to start a subshell with
|
37
|
+
|
38
|
+
$ bundle exec bash
|
39
|
+
|
40
|
+
Replacing `bash` with the shell of your choice, of course.
|
41
|
+
|
42
|
+
Testing
|
43
|
+
-------
|
44
|
+
|
45
|
+
This gem's tests use fakeweb to mock HTTP connections and speed things up. To run the tests you must first run:
|
46
|
+
|
47
|
+
rake fakeweb:update
|
48
|
+
|
49
|
+
This will download the content of the urls needed in tests (and specified in `test/fakeweb.urls`) and store them in
|
50
|
+
local files for quick access.
|
51
|
+
|
52
|
+
Then to run the tests just run
|
53
|
+
|
54
|
+
rake
|
55
|
+
|
56
|
+
If you write a test that opens up a new URL the test will automatically fail because FakeWeb is configured to not allow
|
57
|
+
actual HTTP connections to open and the new URL is not configured for the cache. To do this just add the new URL in the
|
58
|
+
`test/fakeweb.urls` file and update the caches with `rake fakeweb:update`.
|
59
|
+
|
60
|
+
Documentation
|
61
|
+
-------------
|
62
|
+
|
63
|
+
This gem uses Yardoc syntax for documentation. You can generate these docs
|
64
|
+
with `rake yard`. Point any webserver at the `docs/` directory to browse.
|
65
|
+
|
66
|
+
Simple, with Thin:
|
67
|
+
|
68
|
+
$ cd /path/to/scapeshift
|
69
|
+
$ rake yard
|
70
|
+
$ cd docs/
|
71
|
+
$ thin -A file -d start
|
72
|
+
|
73
|
+
Copyright
|
74
|
+
---------
|
75
|
+
|
76
|
+
Copyright (c) 2010 Josh Lindsey. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "scapeshift"
|
8
|
+
gem.summary = %Q{Magic: The Gathering Oracle web scraper}
|
9
|
+
gem.description = %Q{Powers the Scapeshift web API.}
|
10
|
+
gem.email = "joshua.s.lindsey@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/jlindsey/scapeshift"
|
12
|
+
gem.authors = ["Josh Lindsey"]
|
13
|
+
gem.add_development_dependency "bundler"
|
14
|
+
gem.add_dependency "nokogiri"
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'yard'
|
46
|
+
YARD::Rake::YardocTask.new
|
47
|
+
|
48
|
+
desc "Remove docs generated by yard"
|
49
|
+
task :clobber_yard do
|
50
|
+
puts "rm -rf doc/"
|
51
|
+
%x{rm -rf doc/}
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "Searches for all @todo tags and prints them"
|
55
|
+
task :todos do
|
56
|
+
puts %x{grep -inr "@todo" lib/}
|
57
|
+
end
|
58
|
+
|
59
|
+
namespace :fakeweb do
|
60
|
+
task :update do
|
61
|
+
require 'test/fakeweb_helper'
|
62
|
+
FakeWebHelper.cache_all_urls
|
63
|
+
end
|
64
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.1
|
data/lib/scapeshift.rb
ADDED
@@ -0,0 +1,404 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Scapeshift
|
3
|
+
|
4
|
+
##
|
5
|
+
# Represents a single Magic: The Gathering card. These are created automatically
|
6
|
+
# by the various {Crawlers}, but can be instantiated by end-users if they desire.
|
7
|
+
#
|
8
|
+
# @author Josh Lindsey
|
9
|
+
#
|
10
|
+
# @since 0.1.0
|
11
|
+
#
|
12
|
+
class Card
|
13
|
+
|
14
|
+
##
|
15
|
+
# Base URI for card images. Interpolated with the "multiverse id" of the
|
16
|
+
# card to be imaged.
|
17
|
+
Image_URI = 'http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=%d&type=card'
|
18
|
+
|
19
|
+
##
|
20
|
+
# List of possible Supertypes a Card can have
|
21
|
+
Supertypes = %w(Basic Legendary Snow World)
|
22
|
+
|
23
|
+
##
|
24
|
+
# List of possible Base Types a Card can have
|
25
|
+
Base_Types = %w(Artifact Creature Enchantment Land Planeswalker Instant Sorcery Tribal Plane Vanguard)
|
26
|
+
|
27
|
+
## @return [String] The card's name
|
28
|
+
attr_accessor :name
|
29
|
+
|
30
|
+
## @return [String] The card's multiverse id (ie its id on the Gatherer website)
|
31
|
+
attr_accessor :multiverse_id
|
32
|
+
|
33
|
+
## @return [String] The mana cost of the card, in the form "2BR"
|
34
|
+
attr_accessor :cost
|
35
|
+
|
36
|
+
## @return [Array] An array of the card's base types
|
37
|
+
attr_accessor :base_types
|
38
|
+
|
39
|
+
## @return [Array] An array of the card's subtypes.
|
40
|
+
attr_accessor :subtypes
|
41
|
+
|
42
|
+
## @return [Array] An array of the card's supertypes.
|
43
|
+
attr_accessor :supertypes
|
44
|
+
|
45
|
+
## @return [String] Attack power for creature cards
|
46
|
+
attr_accessor :pow
|
47
|
+
|
48
|
+
## @return [String] Toughness for creature cards
|
49
|
+
attr_accessor :tgh
|
50
|
+
|
51
|
+
## @return [String] The card's body text
|
52
|
+
attr_accessor :text
|
53
|
+
|
54
|
+
## @return [String] The card's flavour text
|
55
|
+
attr_accessor :flavour_text
|
56
|
+
|
57
|
+
## @return [Array [[Set, Rarity]]] The sets and rarities of this card.
|
58
|
+
attr_accessor :sets
|
59
|
+
|
60
|
+
## @return [String] The interpolated Image_URI string
|
61
|
+
attr_accessor :image_uri
|
62
|
+
|
63
|
+
## @return [String] The loyalty for planeswalker cards
|
64
|
+
attr_accessor :loyalty
|
65
|
+
|
66
|
+
## @return [String] The card's artist name
|
67
|
+
attr_accessor :artist
|
68
|
+
|
69
|
+
## @return [String] The card's number
|
70
|
+
attr_accessor :number
|
71
|
+
|
72
|
+
##
|
73
|
+
# Converts a mana word into its representative cost symbol.
|
74
|
+
#
|
75
|
+
# @example Blue
|
76
|
+
# Scapeshift::Card.cost_symbol_from_str "Blue" # => "U"
|
77
|
+
#
|
78
|
+
# @example 3 Colorless
|
79
|
+
# Scapeshift::Card.cost_symbol_from_str "3" # => "3"
|
80
|
+
#
|
81
|
+
# @param [String] str The String representation of the cost symbol
|
82
|
+
#
|
83
|
+
# @return [String] The symbol representing the mana cost
|
84
|
+
#
|
85
|
+
# @raise [Scapeshift::Errors::UnknownCostSymbol] If an urecognized word is supplied.
|
86
|
+
# (eg. "Purple")
|
87
|
+
#
|
88
|
+
# @author Josh Lindsey
|
89
|
+
#
|
90
|
+
# @since 0.2.0
|
91
|
+
#
|
92
|
+
def self.cost_symbol_from_str str
|
93
|
+
case str
|
94
|
+
# If the input is simply a number, it's already a valid cost symbol.
|
95
|
+
when /[\d]+/
|
96
|
+
str
|
97
|
+
# The Chaos Planechase symbol. I don't actually know
|
98
|
+
# what the proper textual representation of this is.
|
99
|
+
when '[chaos]'
|
100
|
+
str
|
101
|
+
# "Variable Colorless" is the word representation of X costs.
|
102
|
+
when 'Variable Colorless'
|
103
|
+
'X'
|
104
|
+
# Normal colors
|
105
|
+
when 'White'
|
106
|
+
'W'
|
107
|
+
when 'Red'
|
108
|
+
'R'
|
109
|
+
when 'Blue'
|
110
|
+
'U'
|
111
|
+
when 'Black'
|
112
|
+
'B'
|
113
|
+
when 'Green'
|
114
|
+
'G'
|
115
|
+
# Two or colors
|
116
|
+
when 'Two or White'
|
117
|
+
'(2/W)'
|
118
|
+
when 'Two or Red'
|
119
|
+
'(2/R)'
|
120
|
+
when 'Two or Blue'
|
121
|
+
'(2/U)'
|
122
|
+
when 'Two or Black'
|
123
|
+
'(2/B)'
|
124
|
+
when 'Two or Green'
|
125
|
+
'(2/G)'
|
126
|
+
# Phyrexian colors
|
127
|
+
when 'Phyrexian White'
|
128
|
+
'(W/P)'
|
129
|
+
when 'Phyrexian Red'
|
130
|
+
'(R/P)'
|
131
|
+
when 'Phyrexian Blue'
|
132
|
+
'(U/P)'
|
133
|
+
when 'Phyrexian Black'
|
134
|
+
'(B/P)'
|
135
|
+
when 'Phyrexian Green'
|
136
|
+
'(G/P)'
|
137
|
+
# Dual Colors
|
138
|
+
when 'Black or Red'
|
139
|
+
'(B/R)'
|
140
|
+
when 'Black or Green'
|
141
|
+
'(B/G)'
|
142
|
+
when 'Red or Green'
|
143
|
+
'(R/G)'
|
144
|
+
when 'Red or White'
|
145
|
+
'(R/W)'
|
146
|
+
when 'Green or White'
|
147
|
+
'(G/W)'
|
148
|
+
when 'Green or Blue'
|
149
|
+
'(G/U)'
|
150
|
+
when 'White or Blue'
|
151
|
+
'(W/U)'
|
152
|
+
when 'White or Black'
|
153
|
+
'(W/B)'
|
154
|
+
when 'Blue or Black'
|
155
|
+
'(U/B)'
|
156
|
+
when 'Blue or Red'
|
157
|
+
'(U/R)'
|
158
|
+
# Snow
|
159
|
+
when 'Snow'
|
160
|
+
'S}i'
|
161
|
+
# Tap
|
162
|
+
when 'Tap'
|
163
|
+
'T'
|
164
|
+
# Untap
|
165
|
+
when 'Untap'
|
166
|
+
'Q'
|
167
|
+
else
|
168
|
+
raise Scapeshift::Errors::UnknownCostSymbol.new "Unrecognized cost '#{str}'"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
##
|
173
|
+
# Instantiate a new Card object.
|
174
|
+
#
|
175
|
+
# @param [Hash] params Default values for the object.
|
176
|
+
# Similar to ActiveRecord::Base.
|
177
|
+
#
|
178
|
+
# @return [Card] The new Card object
|
179
|
+
#
|
180
|
+
# @raise [NoMethodError] If a key is passed in for which there is no corresponding
|
181
|
+
# setter method.
|
182
|
+
#
|
183
|
+
# @author Josh Lindsey
|
184
|
+
#
|
185
|
+
# @since 0.1.0
|
186
|
+
#
|
187
|
+
def initialize params = {}
|
188
|
+
self.supertypes = []
|
189
|
+
self.subtypes = []
|
190
|
+
self.base_types = []
|
191
|
+
self.sets = [[]]
|
192
|
+
|
193
|
+
return if params.empty?
|
194
|
+
|
195
|
+
params.each_pair do |var, val|
|
196
|
+
method = (var.to_s + "=").to_sym
|
197
|
+
self.send method, val
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# Interpolates the Image_URI with the "multiverse id".
|
203
|
+
#
|
204
|
+
# @param [Integer] id The "multiverse id" for this card
|
205
|
+
#
|
206
|
+
# @author Josh Lindsey
|
207
|
+
#
|
208
|
+
# @since 0.1.0
|
209
|
+
#
|
210
|
+
def image_uri_from_id= id
|
211
|
+
self.image_uri = Image_URI % id
|
212
|
+
end
|
213
|
+
|
214
|
+
## To make Hash instantiation more readable
|
215
|
+
alias :image_id= :image_uri_from_id=
|
216
|
+
|
217
|
+
##
|
218
|
+
# Sets the Card's {#subtypes}, {#supertypes}, and {#base_types}
|
219
|
+
# from a correctly formatted String.
|
220
|
+
#
|
221
|
+
# @param [String] types_str The types string
|
222
|
+
#
|
223
|
+
# @author Josh Lindsey
|
224
|
+
#
|
225
|
+
# @since 0.1.3
|
226
|
+
#
|
227
|
+
def types= types_str
|
228
|
+
ary = [[], []]
|
229
|
+
|
230
|
+
# From the Cards crawler
|
231
|
+
if types_str.include? ' — '
|
232
|
+
ary = _split_base_and_subtypes types_str, ' — '
|
233
|
+
# Also from the Cards crawler: ' – '
|
234
|
+
elsif types_str.include? " \342\200\223 "
|
235
|
+
ary = _split_base_and_subtypes types_str, " \342\200\223 "
|
236
|
+
# Also from the Cards crawler: ' — '
|
237
|
+
elsif types_str.include? " \342\200\224 "
|
238
|
+
ary = _split_base_and_subtypes types_str, " \342\200\224 "
|
239
|
+
|
240
|
+
# Other possible dashes
|
241
|
+
# Not seen them on gatherer yet but including them for completion's sake
|
242
|
+
elsif types_str.include? " \357\271\230 "
|
243
|
+
ary = _split_base_and_subtypes types_str, " \357\271\230 "
|
244
|
+
elsif types_str.include? " \357\271\243 "
|
245
|
+
ary = _split_base_and_subtypes types_str, " \357\271\243 "
|
246
|
+
elsif types_str.include? " \357\274\215 "
|
247
|
+
ary = _split_base_and_subtypes types_str, " \357\274\215 "
|
248
|
+
|
249
|
+
# From manual text input.
|
250
|
+
# Note that this is a hyphen. Above is a dash (Alt + - in OS X).
|
251
|
+
elsif types_str.include? ' - '
|
252
|
+
ary = _split_base_and_subtypes types_str, ' - '
|
253
|
+
|
254
|
+
# If it doesn't contain one of these delimiters, it has no subtypes
|
255
|
+
else
|
256
|
+
ary[0] = types_str.split(' ')
|
257
|
+
end
|
258
|
+
|
259
|
+
self.supertypes = ary[0] & Supertypes
|
260
|
+
self.base_types = ary[0] & Base_Types
|
261
|
+
self.subtypes = ary[1]
|
262
|
+
end
|
263
|
+
|
264
|
+
##
|
265
|
+
# The types of this card in string form.
|
266
|
+
#
|
267
|
+
# @return [String] The formatted Type string.
|
268
|
+
# Should be a valid input for {#types=}
|
269
|
+
#
|
270
|
+
# @author Josh Lindsey
|
271
|
+
#
|
272
|
+
# @since 0.1.3
|
273
|
+
#
|
274
|
+
def types
|
275
|
+
type = ''
|
276
|
+
unless self.supertypes.empty?
|
277
|
+
type << self.supertypes.join(' ')
|
278
|
+
type << ' '
|
279
|
+
end
|
280
|
+
|
281
|
+
type << self.base_types.join(' ')
|
282
|
+
|
283
|
+
unless self.subtypes.empty?
|
284
|
+
type << ' - '
|
285
|
+
type << self.subtypes.join(' ')
|
286
|
+
end
|
287
|
+
|
288
|
+
type
|
289
|
+
end
|
290
|
+
|
291
|
+
##
|
292
|
+
# The most recent rarity of this card.
|
293
|
+
#
|
294
|
+
# @return [String] The rarity.
|
295
|
+
#
|
296
|
+
# @author Josh Lindsey
|
297
|
+
#
|
298
|
+
# @since 0.1.0
|
299
|
+
#
|
300
|
+
def rarity
|
301
|
+
self.sets.first[1]
|
302
|
+
end
|
303
|
+
|
304
|
+
##
|
305
|
+
# The most recent set this card appeared in.
|
306
|
+
#
|
307
|
+
# @return [String] The set.
|
308
|
+
#
|
309
|
+
# @author Josh Lindsey
|
310
|
+
#
|
311
|
+
# @since 0.1.0
|
312
|
+
#
|
313
|
+
def set
|
314
|
+
self.sets.first[0]
|
315
|
+
end
|
316
|
+
|
317
|
+
##
|
318
|
+
# Set the power and toughness from an Array.
|
319
|
+
#
|
320
|
+
# @param [Array [Power, Toughness]] pt The power and toughness array
|
321
|
+
#
|
322
|
+
# @author Josh Lindsey
|
323
|
+
#
|
324
|
+
# @since 0.1.0
|
325
|
+
#
|
326
|
+
def pow_tgh=(pt)
|
327
|
+
return if pt.nil?
|
328
|
+
self.pow = pt[0]
|
329
|
+
self.tgh = pt[1]
|
330
|
+
end
|
331
|
+
|
332
|
+
##
|
333
|
+
# Operator method to determine sort order. Sorts based
|
334
|
+
# on {#name}.
|
335
|
+
#
|
336
|
+
# @param [Card] other_card The other Card to compare with
|
337
|
+
#
|
338
|
+
# @return [Integer] 1, 0, or -1
|
339
|
+
#
|
340
|
+
# @author Josh Lindsey
|
341
|
+
#
|
342
|
+
# @since 0.1.2
|
343
|
+
#
|
344
|
+
def <=> other_card
|
345
|
+
self.name <=> other_card.name
|
346
|
+
end
|
347
|
+
|
348
|
+
##
|
349
|
+
# Operator method to determine equality. Does an `==` comparison
|
350
|
+
# on each attribute of the Card objects. All must be equal
|
351
|
+
# for true.
|
352
|
+
#
|
353
|
+
# @param [Card] other_card The other Card to compare with
|
354
|
+
#
|
355
|
+
# @return [Boolean] Whether or not they are equal
|
356
|
+
#
|
357
|
+
# @author Josh Lindsey
|
358
|
+
#
|
359
|
+
# @since 0.1.2
|
360
|
+
#
|
361
|
+
def == other_card
|
362
|
+
if self.name == other_card.name and
|
363
|
+
self.cost == other_card.cost and
|
364
|
+
self.sets == other_card.sets and
|
365
|
+
self.image_uri == other_card.image_uri and
|
366
|
+
self.multiverse_id == other_card.multiverse_id and
|
367
|
+
self.text == other_card.text and
|
368
|
+
self.flavour_text == other_card.flavour_text and
|
369
|
+
self.types == other_card.types and
|
370
|
+
self.loyalty == other_card.loyalty and
|
371
|
+
self.artist == other_card.artist and
|
372
|
+
self.number == other_card.number
|
373
|
+
|
374
|
+
return true
|
375
|
+
end
|
376
|
+
|
377
|
+
return false
|
378
|
+
end
|
379
|
+
|
380
|
+
private
|
381
|
+
|
382
|
+
##
|
383
|
+
# Used by {#types=} to split the types line string into an array
|
384
|
+
# of types and subtypes.
|
385
|
+
#
|
386
|
+
# @param [String] types_str The correctly formatted types line string
|
387
|
+
# @param [String] split_on The string that delimits super/base types and subtypes
|
388
|
+
#
|
389
|
+
# @return [Array] First element is the base (and possibly super) types.
|
390
|
+
# Second element is the subtypes.
|
391
|
+
#
|
392
|
+
# @author Josh Lindsey
|
393
|
+
#
|
394
|
+
# @since 0.1.3
|
395
|
+
#
|
396
|
+
def _split_base_and_subtypes types_str, split_on
|
397
|
+
ary = types_str.split(split_on)
|
398
|
+
ary[0] = ary[0].split(' ')
|
399
|
+
ary[1] = ary[1].split(' ')
|
400
|
+
ary
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|