gatherer_set_parser 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +67 -0
- data/Rakefile +2 -0
- data/gatherer_set_parser.gemspec +25 -0
- data/lib/gatherer_set_parser/card_parser.rb +114 -0
- data/lib/gatherer_set_parser/fetch.rb +46 -0
- data/lib/gatherer_set_parser/query_string.rb +25 -0
- data/lib/gatherer_set_parser/version.rb +3 -0
- data/lib/gatherer_set_parser.rb +7 -0
- data/spec/gatherer_set_parser/card_parser_spec.rb +181 -0
- data/spec/gatherer_set_parser/fetch_spec.rb +30 -0
- data/spec/gatherer_set_parser/query_string_spec.rb +21 -0
- data/spec/gatherer_set_parser_spec.rb +2 -0
- data/spec/support/artifact.html +35 -0
- data/spec/support/dual_land.html +40 -0
- data/spec/support/enchant.html +40 -0
- data/spec/support/flipped_creature.html +35 -0
- data/spec/support/gold.html +35 -0
- data/spec/support/instant.html +35 -0
- data/spec/support/land.html +40 -0
- data/spec/support/legendary.html +35 -0
- data/spec/support/phyrexia.html +34 -0
- data/spec/support/planeswalker.html +35 -0
- data/spec/vcr_cassettes/dark_ascension.yml +17181 -0
- data/spec/vcr_setup.rb +10 -0
- metadata +176 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 David Ratajczak
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# GathererSetParser
|
2
|
+
|
3
|
+
This is a tool for parsing the official Magic the Gathering card database for
|
4
|
+
a complete collection of cards belonging to a specific set. The cards of the
|
5
|
+
given set will be returned in an array of hashes.
|
6
|
+
|
7
|
+
This gem was extracted from a personal project, and hasn't been throughly
|
8
|
+
tested for every set in production. You'll likely want to refactor a lot of
|
9
|
+
the code before using it on a production server.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'gatherer_set_parser'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install gatherer_set_parser
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
This set requires you to pass in a case sensitive set name from the Gatherer
|
28
|
+
website. Here's an example:
|
29
|
+
|
30
|
+
```
|
31
|
+
# Create the array of cards from the given set name
|
32
|
+
cards = GathererSetParser::Fetch.new('Dark Ascension').cards
|
33
|
+
```
|
34
|
+
|
35
|
+
This will return an array of 171 cards. Here's an example of the output of
|
36
|
+
cards.first:
|
37
|
+
|
38
|
+
```
|
39
|
+
{ :title=> "Afflicted Deserter",
|
40
|
+
:card_type => "Creature",
|
41
|
+
:sub_type => "",
|
42
|
+
:power => 3,
|
43
|
+
:toughness => 2,
|
44
|
+
:cmc => 4,
|
45
|
+
:mana_cost => ["3", "R"],
|
46
|
+
:loyalty => nil,
|
47
|
+
:image_url => "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=262675&type=card",
|
48
|
+
:text => "\r\n At the beginning of each upkeep, if no spells were cast last turn, transform Afflicted Deserter.",
|
49
|
+
:gatherer_url => "http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=262675",
|
50
|
+
:rarity => "Uncommon" }
|
51
|
+
```
|
52
|
+
|
53
|
+
## Contributing
|
54
|
+
|
55
|
+
1. Fork it
|
56
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
57
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
58
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
59
|
+
5. Create new Pull Request
|
60
|
+
|
61
|
+
## Contact
|
62
|
+
|
63
|
+
[david@mockra.com](mailto:david@mockra.com)
|
64
|
+
|
65
|
+
[@Mockra_](http://twitter.com/#!/mockra_)
|
66
|
+
|
67
|
+
[mockra.com](http://mockra.com)
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/gatherer_set_parser/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["David Ratajczak"]
|
6
|
+
gem.email = ["david@mockra.com"]
|
7
|
+
gem.description = %q{Parses the MTG Gatherer website for a collection of
|
8
|
+
cards from the provided set.}
|
9
|
+
gem.summary = %q{This gem will return an array of card hashes that you
|
10
|
+
can use to build a database of Magic the Gathering cards.}
|
11
|
+
gem.homepage = "https://github.com/mockra/gatherer_set_parser"
|
12
|
+
|
13
|
+
gem.files = `git ls-files`.split($\)
|
14
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
15
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
|
+
gem.name = "gatherer_set_parser"
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
gem.version = GathererSetParser::VERSION
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
gem.add_development_dependency 'rspec'
|
22
|
+
gem.add_development_dependency 'fakeweb'
|
23
|
+
gem.add_development_dependency 'vcr'
|
24
|
+
gem.add_dependency 'nokogiri'
|
25
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module GathererSetParser
|
2
|
+
class CardParser
|
3
|
+
|
4
|
+
attr_accessor :body
|
5
|
+
|
6
|
+
def initialize card
|
7
|
+
@body = card
|
8
|
+
end
|
9
|
+
|
10
|
+
def attributes
|
11
|
+
{ title: title,
|
12
|
+
card_type: type,
|
13
|
+
sub_type: sub_type,
|
14
|
+
power: power,
|
15
|
+
toughness: toughness,
|
16
|
+
cmc: cmc,
|
17
|
+
mana_cost: mana_cost,
|
18
|
+
loyalty: loyalty,
|
19
|
+
image_url: image_url,
|
20
|
+
text: text,
|
21
|
+
gatherer_url: gatherer_url,
|
22
|
+
rarity: rarity }
|
23
|
+
end
|
24
|
+
|
25
|
+
def title
|
26
|
+
body.css('.cardTitle > a').text
|
27
|
+
end
|
28
|
+
|
29
|
+
def type_box
|
30
|
+
body.css('span.typeLine').text.
|
31
|
+
gsub(/\n/, '').gsub(/[ ]{2,}/, ' ').strip.lstrip
|
32
|
+
end
|
33
|
+
|
34
|
+
def type
|
35
|
+
type_box.match(/[a-z0-9 ]*/i).to_s.strip
|
36
|
+
end
|
37
|
+
|
38
|
+
def sub_type
|
39
|
+
type_box.gsub(/\(.*\)/, '').
|
40
|
+
match(/ ([a-z0-9 ]*)\z/i)[1].to_s.lstrip.strip
|
41
|
+
rescue
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def power
|
46
|
+
type_box.match(/\(([0-9]*)\//)[1].to_i rescue nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def toughness
|
50
|
+
type_box.match(/\/([0-9]*)\)/)[1].to_i rescue nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def cmc
|
54
|
+
body.css('.convertedManaCost').text.to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
def loyalty
|
58
|
+
type_box.match(/\(([0-9]*)\)/)[1].to_i rescue nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def rarity
|
62
|
+
body.css('.rightCol > a').first.children.attribute('alt').text.
|
63
|
+
match(/\((.*)\)/)[1].to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
def text
|
67
|
+
body.xpath('//div[@class="rulesText"]//img[@alt]').each{ |i| i.swap( i['alt'].parse_mana_cost ) }
|
68
|
+
body.css('.rulesText').text.gsub(/[ ]{2,}/, ' ')
|
69
|
+
end
|
70
|
+
|
71
|
+
def mana_cost
|
72
|
+
array = []
|
73
|
+
body.css('.manaCost >img').each do |img|
|
74
|
+
array << img.attribute('alt').text.parse_mana_cost
|
75
|
+
end
|
76
|
+
array
|
77
|
+
end
|
78
|
+
|
79
|
+
def image_url
|
80
|
+
'http://gatherer.wizards.com/' +
|
81
|
+
body.css('.leftCol > a > img').attribute('src').
|
82
|
+
text.gsub(/\.\.\//, '')
|
83
|
+
end
|
84
|
+
|
85
|
+
def gatherer_url
|
86
|
+
'http://gatherer.wizards.com/Pages/' +
|
87
|
+
body.css('.cardTitle > a').attribute('href').
|
88
|
+
text.gsub(/\.\.\//, '')
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class String
|
95
|
+
def parse_mana_cost
|
96
|
+
extract_phyrexia.extract_colors.extract_unique_costs
|
97
|
+
end
|
98
|
+
|
99
|
+
def extract_phyrexia
|
100
|
+
gsub(/Phyrexian Blue/, 'U/P').gsub(/Phyrexian Black/, 'B/P').
|
101
|
+
gsub(/Phyrexian White/, 'W/P').gsub(/Phyrexian Red/, 'R/P').
|
102
|
+
gsub(/Phyrexian Green/, 'G/P')
|
103
|
+
end
|
104
|
+
|
105
|
+
def extract_colors
|
106
|
+
gsub(/Blue/, 'U').gsub(/Black/, 'B').gsub(/Red/, 'R').gsub(/Green/, 'G').
|
107
|
+
gsub(/White/, 'W')
|
108
|
+
end
|
109
|
+
|
110
|
+
def extract_unique_costs
|
111
|
+
gsub(/Variable Colorless/, 'X').gsub(/Two/, '2').gsub(/or/, '/').
|
112
|
+
gsub(/Snow/, 'S').gsub(/Tap/, 'T').gsub(/Untap/, 'Q')
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module GathererSetParser
|
5
|
+
class Fetch
|
6
|
+
|
7
|
+
include GathererSetParser::QueryString
|
8
|
+
|
9
|
+
attr_reader :set_name
|
10
|
+
|
11
|
+
def response_page page
|
12
|
+
Nokogiri::HTML open(gatherer_url page), nil, 'UTF-8'
|
13
|
+
end
|
14
|
+
|
15
|
+
def complete_set
|
16
|
+
@complete_set ||= gather_set
|
17
|
+
end
|
18
|
+
|
19
|
+
def gather_set
|
20
|
+
set, page = [], 0
|
21
|
+
current_page = response_page page
|
22
|
+
total_pages = current_page.css('.paging > a').count
|
23
|
+
begin
|
24
|
+
set << current_page
|
25
|
+
page += 1
|
26
|
+
current_page = response_page page
|
27
|
+
end while page < total_pages - 1
|
28
|
+
set
|
29
|
+
end
|
30
|
+
|
31
|
+
def cards
|
32
|
+
@cards ||= collect_cards
|
33
|
+
end
|
34
|
+
|
35
|
+
def collect_cards
|
36
|
+
collection = []
|
37
|
+
complete_set.each do |page|
|
38
|
+
page.css('.cardItemTable > tr > td > table').each do |card|
|
39
|
+
collection << CardParser.new(card).attributes
|
40
|
+
end
|
41
|
+
end
|
42
|
+
collection
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module GathererSetParser
|
2
|
+
module QueryString
|
3
|
+
|
4
|
+
def initialize set
|
5
|
+
@set_name = set
|
6
|
+
end
|
7
|
+
|
8
|
+
def escaped_set
|
9
|
+
@query_string ||= URI.escape set_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_string
|
13
|
+
"output=standard&set=[%22#{escaped_set}%22]"
|
14
|
+
end
|
15
|
+
|
16
|
+
def url
|
17
|
+
"http://gatherer.wizards.com/Pages/Search/Default.aspx?"
|
18
|
+
end
|
19
|
+
|
20
|
+
def gatherer_url page
|
21
|
+
url + query_string + "&page=#{page}"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'gatherer_set_parser_spec'
|
2
|
+
require 'fakeweb'
|
3
|
+
|
4
|
+
describe GathererSetParser::CardParser do
|
5
|
+
|
6
|
+
let(:parsed_card) { GathererSetParser::CardParser.new card }
|
7
|
+
|
8
|
+
describe '#parse_card' do
|
9
|
+
let(:card) { Nokogiri::HTML open('spec/support/flipped_creature.html') }
|
10
|
+
|
11
|
+
it 'should return a hash' do
|
12
|
+
parsed_card.attributes.should be_a Hash
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should have a title' do
|
16
|
+
parsed_card.attributes[:title].should_not be_nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#card_attributes' do
|
21
|
+
context 'back of flip card' do
|
22
|
+
let(:card) { Nokogiri::HTML open('spec/support/flipped_creature.html') }
|
23
|
+
|
24
|
+
it 'should return the correct title' do
|
25
|
+
parsed_card.title.should == "Tovolar's Magehunter"
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should return a card type' do
|
29
|
+
parsed_card.type.should == 'Creature'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should match the species type' do
|
33
|
+
parsed_card.sub_type.should == 'Werewolf'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should have the correct power' do
|
37
|
+
parsed_card.power.should == 5
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should have the correct toughness' do
|
41
|
+
parsed_card.toughness.should == 5
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should have no loyalty' do
|
45
|
+
parsed_card.loyalty.should be_nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should have a cmc' do
|
49
|
+
parsed_card.cmc.should == 0
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should have the correct rarity' do
|
53
|
+
parsed_card.rarity.should == 'Rare'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should have text' do
|
57
|
+
parsed_card.text.should =~ /transform/i
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should have the correct mana cost' do
|
61
|
+
parsed_card.mana_cost.should == []
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should have the correct image url' do
|
65
|
+
parsed_card.image_url.should =~
|
66
|
+
/\/Handlers\/Image\.ashx\?multiverseid\=253429\&type\=card/
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'an instant/sorcery' do
|
71
|
+
let(:card) { Nokogiri::HTML open('spec/support/instant.html') }
|
72
|
+
|
73
|
+
it 'should have no power' do
|
74
|
+
parsed_card.power.should be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should have no loyalty' do
|
78
|
+
parsed_card.loyalty.should be_nil
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should have the correct type' do
|
82
|
+
parsed_card.type.should == 'Instant'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should have the correct rarity' do
|
86
|
+
parsed_card.rarity.should == 'Uncommon'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should have the correct mana cost' do
|
90
|
+
parsed_card.mana_cost.should == %w[1 U]
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should have no sub type' do
|
94
|
+
parsed_card.sub_type.should be_nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'land' do
|
99
|
+
let(:card) { Nokogiri::HTML open('spec/support/land.html') }
|
100
|
+
|
101
|
+
it 'should have the correct mana cost' do
|
102
|
+
parsed_card.mana_cost.should == []
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should have no power' do
|
106
|
+
parsed_card.power.should be_nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'planeswalker' do
|
111
|
+
let(:card) { Nokogiri::HTML open('spec/support/planeswalker.html') }
|
112
|
+
|
113
|
+
it 'should have a title' do
|
114
|
+
parsed_card.title.should =~ /Tamiyo/i
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should have no power' do
|
118
|
+
parsed_card.power.should be_nil
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should have no toughness' do
|
122
|
+
parsed_card.power.should be_nil
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should have loyalty' do
|
126
|
+
parsed_card.loyalty.should == 4
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should have the correct type' do
|
130
|
+
parsed_card.type.should == 'Planeswalker'
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should have the correct rarity' do
|
134
|
+
parsed_card.rarity.should == 'Mythic Rare'
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should have the correct mana cost' do
|
138
|
+
parsed_card.mana_cost.should == %w[3 U U]
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should have correct gatherer url' do
|
142
|
+
parsed_card.gatherer_url.should =~
|
143
|
+
/Card\/Details\.aspx\?multiverseid\=240070/
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'phyrexian' do
|
148
|
+
let(:card) { Nokogiri::HTML open('spec/support/phyrexia.html') }
|
149
|
+
|
150
|
+
it 'should have the correct mana cost' do
|
151
|
+
parsed_card.mana_cost.should == %w[X G/P]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'enchant' do
|
156
|
+
let(:card) { Nokogiri::HTML open('spec/support/enchant.html') }
|
157
|
+
|
158
|
+
it 'should have the correct mana cost' do
|
159
|
+
parsed_card.mana_cost.should == %w[4 B B]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'gold' do
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'dual_land' do
|
167
|
+
let(:card) { Nokogiri::HTML open('spec/support/dual_land.html') }
|
168
|
+
|
169
|
+
it 'should have the correct text' do
|
170
|
+
parsed_card.text.should =~ /U/i
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'legendary' do
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'artifact' do
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'gatherer_set_parser_spec'
|
2
|
+
|
3
|
+
describe GathererSetParser::Fetch do
|
4
|
+
|
5
|
+
let(:gatherer) { GathererSetParser::Fetch.new 'Dark Ascension' }
|
6
|
+
|
7
|
+
describe '.new' do
|
8
|
+
it 'should assign the set_name' do
|
9
|
+
gatherer.set_name.should == 'Dark Ascension'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#response_body' do
|
14
|
+
use_vcr_cassette 'dark_ascension'
|
15
|
+
|
16
|
+
it 'should contain every page' do
|
17
|
+
gatherer.complete_set.count.should == 7
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should contain a magic card' do
|
21
|
+
gatherer.complete_set.last.text.should =~ /wakedancer/i
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should have the complete set of cards' do
|
25
|
+
gatherer.cards.count.should == 171
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'gatherer_set_parser_spec'
|
2
|
+
|
3
|
+
describe GathererSetParser::QueryString do
|
4
|
+
|
5
|
+
let(:gatherer) { GathererSetParser::Fetch.new 'Dark Ascension' }
|
6
|
+
|
7
|
+
describe '#escaped_set' do
|
8
|
+
it 'should escape set_name to query string' do
|
9
|
+
gatherer.escaped_set.should == 'Dark%20Ascension'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#query_string' do
|
14
|
+
it 'should contain the entire query' do
|
15
|
+
gatherer.query_string.should ==
|
16
|
+
'output=standard&set=[%22Dark%20Ascension%22]'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<table>
|
2
|
+
<tr class="cardItem evenItem">
|
3
|
+
<td class="leftCol">
|
4
|
+
<div class="clear"></div>
|
5
|
+
<a href="../Card/Details.aspx?multiverseid=230070" id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl00_cardImageLink" onclick="return CardLinkAction(event, this, 'SameWindow');">
|
6
|
+
<img src="../../Handlers/Image.ashx?multiverseid=230070&type=card" id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl00_cardImage" width="95" height="132" alt="Conversion Chamber" border="0" />
|
7
|
+
</a>
|
8
|
+
<div class="clear"></div>
|
9
|
+
</td>
|
10
|
+
<td class="middleCol">
|
11
|
+
<div class="clear"></div>
|
12
|
+
<div class="cardInfo">
|
13
|
+
<span class="cardTitle">
|
14
|
+
<a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl00_cardTitle" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=230070">Conversion Chamber</a></span> <span class="manaCost">
|
15
|
+
<img src="/Handlers/Image.ashx?size=small&name=3&type=symbol" alt="3" align="absbottom" /></span> (<span class="convertedManaCost">3</span>)
|
16
|
+
<br />
|
17
|
+
<span class="typeLine">
|
18
|
+
Artifact
|
19
|
+
</span>
|
20
|
+
<br />
|
21
|
+
<div class="rulesText">
|
22
|
+
<p><img src="/Handlers/Image.ashx?size=small&name=2&type=symbol" alt="2" align="absbottom" />, <img src="/Handlers/Image.ashx?size=small&name=tap&type=symbol" alt="Tap" align="absbottom" />: Exile target artifact card from a graveyard. Put a charge counter on Conversion Chamber.</p><p><img src="/Handlers/Image.ashx?size=small&name=2&type=symbol" alt="2" align="absbottom" />, <img src="/Handlers/Image.ashx?size=small&name=tap&type=symbol" alt="Tap" align="absbottom" />, Remove a charge counter from Conversion Chamber: Put a 3/3 colorless Golem artifact creature token onto the battlefield.</p></div>
|
23
|
+
</div>
|
24
|
+
</td>
|
25
|
+
<td class="rightCol setVersions">
|
26
|
+
<div class="clear"></div>
|
27
|
+
<div>
|
28
|
+
<div id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl00_cardSetCurrent" class="rightCol">
|
29
|
+
<a onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=230070"><img title="New Phyrexia (Uncommon)" src="../../Handlers/Image.ashx?type=symbol&set=NPH&size=small&rarity=U" alt="New Phyrexia (Uncommon)" style="border-width:0px;" /></a>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
</td>
|
34
|
+
</tr>
|
35
|
+
</table>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<table>
|
2
|
+
<tr class="cardItem oddItem">
|
3
|
+
<td class="leftCol">
|
4
|
+
<div class="clear"></div>
|
5
|
+
<a href="../Card/Details.aspx?multiverseid=253682" id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl11_cardImageLink" onclick="return CardLinkAction(event, this, 'SameWindow');">
|
6
|
+
<img src="../../Handlers/Image.ashx?multiverseid=253682&type=card" id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl11_cardImage" width="95" height="132" alt="Steam Vents" border="0" />
|
7
|
+
</a>
|
8
|
+
<div class="clear"></div>
|
9
|
+
</td>
|
10
|
+
<td class="middleCol">
|
11
|
+
<div class="clear"></div>
|
12
|
+
<div class="cardInfo">
|
13
|
+
<span class="cardTitle">
|
14
|
+
<a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl11_cardTitle" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=253682">Steam Vents</a></span> <span class="manaCost">
|
15
|
+
</span> (<span class="convertedManaCost">0</span>)
|
16
|
+
<br />
|
17
|
+
<span class="typeLine">
|
18
|
+
Land — Island Mountain
|
19
|
+
</span>
|
20
|
+
<div class="rulesText">
|
21
|
+
<p><i>(<img src="/Handlers/Image.ashx?size=small&name=tap&type=symbol" alt="Tap" align="absbottom" />: Add <img src="/Handlers/Image.ashx?size=small&name=U&type=symbol" alt="Blue" align="absbottom" /> or <img src="/Handlers/Image.ashx?size=small&name=R&type=symbol" alt="Red" align="absbottom" /> to your mana pool.)</i></p><p>As Steam Vents enters the battlefield, you may pay 2 life. If you don't, Steam Vents enters the battlefield tapped.</p></div>
|
22
|
+
</div>
|
23
|
+
</td>
|
24
|
+
<td class="rightCol setVersions">
|
25
|
+
<div class="clear"></div>
|
26
|
+
<div>
|
27
|
+
<div id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl11_cardSetCurrent" class="rightCol">
|
28
|
+
<a onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=253682"><img title="Return to Ravnica (Rare)" src="../../Handlers/Image.ashx?type=symbol&set=RTR&size=small&rarity=R" alt="Return to Ravnica (Rare)" style="border-width:0px;" /></a>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
<div id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl11_otherSetSection" class="otherSetSection">
|
32
|
+
<div>
|
33
|
+
<i>Other Versions</i></div>
|
34
|
+
<div id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_listRepeater_ctl11_cardSets" class="rightCol">
|
35
|
+
<a onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=96923"><img title="Guildpact (Rare)" src="../../Handlers/Image.ashx?type=symbol&set=GPT&size=small&rarity=R" alt="Guildpact (Rare)" style="border-width:0px;" /></a>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
</td>
|
39
|
+
</tr>
|
40
|
+
</table>
|