tamiyo 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.
- checksums.yaml +4 -4
- data/Readme.md +19 -2
- data/lib/tamiyo.rb +1 -1
- data/lib/tamiyo/card.rb +61 -2
- data/lib/tamiyo/dummy_scrape.rb +240 -1
- data/lib/tamiyo/gatherer_scrape.rb +2 -2
- data/lib/tamiyo/scrape_parser.rb +84 -26
- data/lib/tamiyo/version.rb +1 -1
- data/lib/tamiyo/yaml_helper.rb +25 -0
- data/lib/tamiyo/yaml_sink.rb +1 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbe2f4df6b2093758c0f6a52a8f9aba968ba27ce
|
4
|
+
data.tar.gz: f88fc1c1bb4cf23930c0c9461b8da1d89b027816
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0509832f03d91c5ab0731b3c703be207118ee6df885aefe52ffd2971e9c8cf532eca60304b943df176e55be25b47d1be8d0974a020019d25a17c427beae88d6
|
7
|
+
data.tar.gz: e771a347d9d859886625ac3b2b18e3204fc574ab8b2d6aa860295dd08cbdd1236fa6a65e47a16d92d5d43fc7cb339b208b1d796ad74a018ff46ec45377558d44
|
data/Readme.md
CHANGED
@@ -1,4 +1,21 @@
|
|
1
|
-
tamiyo
|
2
|
-
======
|
1
|
+
# tamiyo
|
3
2
|
|
4
3
|
A utility that import cards from Wizard's Gatherer. Allows for incremental imports and selective export to Cockatrice's card database format.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Install it as:
|
8
|
+
|
9
|
+
$ gem install tamiyo
|
10
|
+
|
11
|
+
Or add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'tamiyo'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
data/lib/tamiyo.rb
CHANGED
@@ -13,7 +13,7 @@ opts = Slop.new help: true do
|
|
13
13
|
command 'gatherer-scrape' do
|
14
14
|
run do |opts, args|
|
15
15
|
require_relative 'tamiyo/gatherer_scrape_chain'
|
16
|
-
Tamiyo::GathererScrapeChain.create(args.first || "
|
16
|
+
Tamiyo::GathererScrapeChain.create(args.first || "Champions of Kamigawa").pump
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
data/lib/tamiyo/card.rb
CHANGED
@@ -3,11 +3,58 @@ require_relative 'value'
|
|
3
3
|
module Tamiyo
|
4
4
|
Card = Value.new(:name, :cost, :colors, :type, :text, :pt, :loyalty,
|
5
5
|
:table_row, :played_tapped, :picture_url) do
|
6
|
-
def
|
7
|
-
Card.new(
|
6
|
+
def with_name(new_name)
|
7
|
+
Card.new(new_name, cost, colors, type, text,
|
8
8
|
pt, loyalty, table_row, played_tapped, picture_url)
|
9
9
|
end
|
10
10
|
|
11
|
+
def with_extra_colors(extra_colors)
|
12
|
+
new_colors = (colors + extra_colors).uniq
|
13
|
+
Card.new(name, cost, new_colors, type, text,
|
14
|
+
pt, loyalty, table_row, played_tapped, picture_url)
|
15
|
+
end
|
16
|
+
|
17
|
+
def with_cost(new_cost)
|
18
|
+
Card.new(name, new_cost, colors, type, text,
|
19
|
+
pt, loyalty, table_row, played_tapped, picture_url)
|
20
|
+
end
|
21
|
+
|
22
|
+
def with_text(new_text)
|
23
|
+
Card.new(name, cost, colors, type, new_text,
|
24
|
+
pt, loyalty, table_row, played_tapped, picture_url)
|
25
|
+
end
|
26
|
+
|
27
|
+
def with_flip_bottom(card)
|
28
|
+
new_text = [card.name, card.type, card.text, card.pt].compact.join "\n"
|
29
|
+
with_text merge_parts(self.text, new_text)
|
30
|
+
end
|
31
|
+
|
32
|
+
def with_right_split(right_cost, right_text)
|
33
|
+
card = with_cost [cost, right_cost]
|
34
|
+
card.with_text merge_split(text, right_text)
|
35
|
+
end
|
36
|
+
|
37
|
+
def with_left_split(left_cost, left_text)
|
38
|
+
card = with_cost [left_cost, cost]
|
39
|
+
card.with_text merge_split(left_text, text)
|
40
|
+
end
|
41
|
+
|
42
|
+
def merge_parts(left_text, right_text)
|
43
|
+
[left_text, right_text].join text_part_separator
|
44
|
+
end
|
45
|
+
|
46
|
+
def merge_split(left_text, right_text)
|
47
|
+
fuse = right_text.match for_fuse_line
|
48
|
+
[without_fuse_line(left_text),
|
49
|
+
without_fuse_line(right_text),
|
50
|
+
fuse && fuse[:text]
|
51
|
+
].compact.join text_part_separator
|
52
|
+
end
|
53
|
+
|
54
|
+
def without_fuse_line(text)
|
55
|
+
text.gsub match_fuse_line, ''
|
56
|
+
end
|
57
|
+
|
11
58
|
def inspect
|
12
59
|
["Name: #{name}",
|
13
60
|
"Cost: #{cost}",
|
@@ -22,5 +69,17 @@ module Tamiyo
|
|
22
69
|
"Picture url: #{picture_url}"
|
23
70
|
].compact.join "\n"
|
24
71
|
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def text_part_separator
|
76
|
+
"\n---\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
def match_fuse_line
|
80
|
+
/\n(?<text>Fuse.*)\z/
|
81
|
+
end
|
82
|
+
|
83
|
+
alias for_fuse_line match_fuse_line
|
25
84
|
end
|
26
85
|
end
|
data/lib/tamiyo/dummy_scrape.rb
CHANGED
@@ -2,10 +2,11 @@ require 'nokogiri'
|
|
2
2
|
|
3
3
|
module Tamiyo
|
4
4
|
class DummyScrape
|
5
|
-
def
|
5
|
+
def xml_spoiler_rows
|
6
6
|
Nokogiri::HTML(<<TestXml).css 'tr'
|
7
7
|
<div class="textspoiler">
|
8
8
|
<table>
|
9
|
+
<!-- empty pt -->
|
9
10
|
<tr>
|
10
11
|
<td>Name</td>
|
11
12
|
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl00_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=369036">Advent of the Wurm</a></td></tr>
|
@@ -26,6 +27,7 @@ module Tamiyo
|
|
26
27
|
<td>Dragon's Maze Rare</td></tr>
|
27
28
|
<tr>
|
28
29
|
<td colspan="2"><br /></td></tr>
|
30
|
+
<!-- ' non-empty pt -->
|
29
31
|
<tr>
|
30
32
|
<td>Name</td>
|
31
33
|
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl01_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=368961">Ætherling</a></td></tr>
|
@@ -49,6 +51,243 @@ module Tamiyo
|
|
49
51
|
<td>Dragon's Maze Rare</td></tr>
|
50
52
|
<tr>
|
51
53
|
<td colspan="2"><br /></td></tr>
|
54
|
+
<!-- ' loyalty -->
|
55
|
+
<tr>
|
56
|
+
<td>Name</td>
|
57
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl109_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=369031">Ral Zarek</a></td></tr>
|
58
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl109_costRow">
|
59
|
+
<td>Cost:</td>
|
60
|
+
<td>2UR</td></tr>
|
61
|
+
<tr>
|
62
|
+
<td>Type:</td>
|
63
|
+
<td>Planeswalker — Ral</td></tr>
|
64
|
+
<tr>
|
65
|
+
<td>Loyalty:</td>
|
66
|
+
<td>(4)</td></tr>
|
67
|
+
<tr>
|
68
|
+
<td>Rules Text:</td>
|
69
|
+
<td>+1: Tap target permanent, then untap another target permanent.<br />
|
70
|
+
-2: Ral Zarek deals 3 damage to target creature or player.<br />
|
71
|
+
-7: Flip five coins. Take an extra turn after this one for each coin that comes up heads.</td></tr>
|
72
|
+
<tr>
|
73
|
+
<td>Set/Rarity:</td>
|
74
|
+
<td>Dragon's Maze Mythic Rare</td></tr>
|
75
|
+
<tr>
|
76
|
+
<td colspan="2"><br /></td></tr>
|
77
|
+
<!-- ' split card, left first -->
|
78
|
+
<tr>
|
79
|
+
<td>Name</td>
|
80
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl02_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=369041">Alive // Well (Alive)</a></td></tr>
|
81
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl02_costRow">
|
82
|
+
<td>Cost:</td>
|
83
|
+
<td>3G</td></tr>
|
84
|
+
<tr>
|
85
|
+
<td>Type:</td>
|
86
|
+
<td>Sorcery</td></tr>
|
87
|
+
<tr>
|
88
|
+
<td>Pow/Tgh:</td>
|
89
|
+
<td></td></tr>
|
90
|
+
<tr>
|
91
|
+
<td>Rules Text:</td>
|
92
|
+
<td>Put a 3/3 green Centaur creature token onto the battlefield.<br />
|
93
|
+
Fuse (You may cast one or both halves of this card from your hand.)</td></tr>
|
94
|
+
<tr>
|
95
|
+
<td>Set/Rarity:</td>
|
96
|
+
<td>Dragon's Maze Uncommon</td></tr>
|
97
|
+
<tr>
|
98
|
+
<td colspan="2"><br /></td></tr>
|
99
|
+
<!-- ' -->
|
100
|
+
<tr>
|
101
|
+
<td>Name</td>
|
102
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl165_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=369041">Alive // Well (Well)</a></td></tr>
|
103
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl165_costRow">
|
104
|
+
<td>Cost:</td>
|
105
|
+
<td>W</td></tr>
|
106
|
+
<tr>
|
107
|
+
<td>Type:</td>
|
108
|
+
<td>Sorcery</td></tr>
|
109
|
+
<tr>
|
110
|
+
<td>Pow/Tgh:</td>
|
111
|
+
<td></td></tr>
|
112
|
+
<tr>
|
113
|
+
<td>Rules Text:</td>
|
114
|
+
<td>You gain 2 life for each creature you control.<br />
|
115
|
+
Fuse (You may cast one or both halves of this card from your hand.)</td></tr>
|
116
|
+
<tr>
|
117
|
+
<td>Set/Rarity:</td>
|
118
|
+
<td>Dragon's Maze Uncommon</td></tr>
|
119
|
+
<tr>
|
120
|
+
<td colspan="2"><br /></td></tr>
|
121
|
+
<!-- ' split card, right first -->
|
122
|
+
<tr>
|
123
|
+
<td>Name</td>
|
124
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl06_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=369042">Far // Away (Away)</a></td></tr>
|
125
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl06_costRow">
|
126
|
+
<td>Cost:</td>
|
127
|
+
<td>2B</td></tr>
|
128
|
+
<tr>
|
129
|
+
<td>Type:</td>
|
130
|
+
<td>Instant</td></tr>
|
131
|
+
<tr>
|
132
|
+
<td>Pow/Tgh:</td>
|
133
|
+
<td></td></tr>
|
134
|
+
<tr>
|
135
|
+
<td>Rules Text:</td>
|
136
|
+
<td>Target player sacrifices a creature.<br />
|
137
|
+
Fuse (You may cast one or both halves of this card from your hand.)</td></tr>
|
138
|
+
<tr>
|
139
|
+
<td>Set/Rarity:</td>
|
140
|
+
<td>Dragon's Maze Uncommon</td></tr>
|
141
|
+
<tr>
|
142
|
+
<td colspan="2"><br /></td></tr>
|
143
|
+
<!-- ' -->
|
144
|
+
<tr>
|
145
|
+
<td>Name</td>
|
146
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl46_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=369042">Far // Away (Far)</a></td></tr>
|
147
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl46_costRow">
|
148
|
+
<td>Cost:</td>
|
149
|
+
<td>1U</td></tr>
|
150
|
+
<tr>
|
151
|
+
<td>Type:</td>
|
152
|
+
<td>Instant</td></tr>
|
153
|
+
<tr>
|
154
|
+
<td>Pow/Tgh:</td>
|
155
|
+
<td></td></tr>
|
156
|
+
<tr>
|
157
|
+
<td>Rules Text:</td>
|
158
|
+
<td>Return target creature to its owner's hand.<br />
|
159
|
+
Fuse (You may cast one or both halves of this card from your hand.)</td></tr>
|
160
|
+
<tr>
|
161
|
+
<td>Set/Rarity:</td>
|
162
|
+
<td>Dragon's Maze Uncommon</td></tr>
|
163
|
+
<tr>
|
164
|
+
<td colspan="2"><br /></td></tr>
|
165
|
+
<!-- split card without fuse -->
|
166
|
+
<tr>
|
167
|
+
<td>Name</td>
|
168
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl18_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=107373">Bound // Determined (Bound)</a></td></tr>
|
169
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl18_costRow">
|
170
|
+
<td>Cost:</td>
|
171
|
+
<td>3BG</td></tr>
|
172
|
+
<tr>
|
173
|
+
<td>Type:</td>
|
174
|
+
<td>Instant</td></tr>
|
175
|
+
<tr>
|
176
|
+
<td>Pow/Tgh:</td>
|
177
|
+
<td></td></tr>
|
178
|
+
<tr>
|
179
|
+
<td>Rules Text:</td>
|
180
|
+
<td>Sacrifice a creature. Return up to X cards from your graveyard to your hand, where X is the number of colors that creature was. Exile this card.<br /></td></tr>
|
181
|
+
<tr>
|
182
|
+
<td>Set/Rarity:</td>
|
183
|
+
<td>Dissension Rare</td></tr>
|
184
|
+
<tr>
|
185
|
+
<td colspan="2"><br /></td></tr>
|
186
|
+
<tr>
|
187
|
+
<td>Name</td>
|
188
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl39_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=107373">Bound // Determined (Determined)</a></td></tr>
|
189
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl39_costRow">
|
190
|
+
<td>Cost:</td>
|
191
|
+
<td>GU</td></tr>
|
192
|
+
<tr>
|
193
|
+
<td>Type:</td>
|
194
|
+
<td>Instant</td></tr>
|
195
|
+
<tr>
|
196
|
+
<td>Pow/Tgh:</td>
|
197
|
+
<td></td></tr>
|
198
|
+
<tr>
|
199
|
+
<td>Rules Text:</td>
|
200
|
+
<td>Other spells you control can't be countered by spells or abilities this turn.<br />
|
201
|
+
Draw a card.</td></tr>
|
202
|
+
<tr>
|
203
|
+
<td>Set/Rarity:</td>
|
204
|
+
<td>Dissension Rare</td></tr>
|
205
|
+
<tr>
|
206
|
+
<td colspan="2"><br /></td></tr>
|
207
|
+
<!-- ' flip card, top first -->
|
208
|
+
<tr>
|
209
|
+
<td>Name</td>
|
210
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl02_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=78694">Akki Lavarunner</a></td></tr>
|
211
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl02_costRow">
|
212
|
+
<td>Cost:</td>
|
213
|
+
<td>3R</td></tr>
|
214
|
+
<tr>
|
215
|
+
<td>Type:</td>
|
216
|
+
<td>Creature — Goblin Warrior</td></tr>
|
217
|
+
<tr>
|
218
|
+
<td>Pow/Tgh:</td>
|
219
|
+
<td>(1/1)</td></tr>
|
220
|
+
<tr>
|
221
|
+
<td>Rules Text:</td>
|
222
|
+
<td>Haste<br />
|
223
|
+
Whenever Akki Lavarunner deals damage to an opponent, flip it.</td></tr>
|
224
|
+
<tr>
|
225
|
+
<td>Set/Rarity:</td>
|
226
|
+
<td>Champions of Kamigawa Rare</td></tr>
|
227
|
+
<tr>
|
228
|
+
<td colspan="2"><br /></td></tr>
|
229
|
+
<tr>
|
230
|
+
<td>Name</td>
|
231
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl278_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=78694">Akki Lavarunner (Tok-Tok, Volcano Born)</a></td></tr>
|
232
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl278_costRow">
|
233
|
+
<td>Cost:</td>
|
234
|
+
<td>3R</td></tr>
|
235
|
+
<tr>
|
236
|
+
<td>Type:</td>
|
237
|
+
<td>Legendary Creature — Goblin Shaman</td></tr>
|
238
|
+
<tr>
|
239
|
+
<td>Pow/Tgh:</td>
|
240
|
+
<td>(2/2)</td></tr>
|
241
|
+
<tr>
|
242
|
+
<td>Rules Text:</td>
|
243
|
+
<td>Protection from red<br />
|
244
|
+
If a red source would deal damage to a player, it deals that much damage plus 1 to that player instead.</td></tr>
|
245
|
+
<tr>
|
246
|
+
<td>Set/Rarity:</td>
|
247
|
+
<td>Champions of Kamigawa Rare</td></tr>
|
248
|
+
<tr>
|
249
|
+
<td colspan="2"><br /></td></tr>
|
250
|
+
<!-- flip card, bottom first -->
|
251
|
+
<tr>
|
252
|
+
<td>Name</td>
|
253
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl07_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=78695">Kitsune Mystic (Autumn-Tail, Kitsune Sage)</a></td></tr>
|
254
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl07_costRow">
|
255
|
+
<td>Cost:</td>
|
256
|
+
<td>3W</td></tr>
|
257
|
+
<tr>
|
258
|
+
<td>Type:</td>
|
259
|
+
<td>Legendary Creature — Fox Wizard</td></tr>
|
260
|
+
<tr>
|
261
|
+
<td>Pow/Tgh:</td>
|
262
|
+
<td>(4/5)</td></tr>
|
263
|
+
<tr>
|
264
|
+
<td>Rules Text:</td>
|
265
|
+
<td>{1}: Attach target Aura attached to a creature to another creature.</td></tr>
|
266
|
+
<tr>
|
267
|
+
<td>Set/Rarity:</td>
|
268
|
+
<td>Champions of Kamigawa Rare</td></tr>
|
269
|
+
<tr>
|
270
|
+
<td colspan="2"><br /></td></tr>
|
271
|
+
<tr>
|
272
|
+
<td>Name</td>
|
273
|
+
<td><a id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl135_cardLink" class="nameLink" onclick="return CardLinkAction(event, this, 'SameWindow');" href="../Card/Details.aspx?multiverseid=78695">Kitsune Mystic</a></td></tr>
|
274
|
+
<tr id="ctl00_ctl00_ctl00_MainContent_SubContent_SubContent_ctl00_cardEntries_ctl135_costRow">
|
275
|
+
<td>Cost:</td>
|
276
|
+
<td>3W</td></tr>
|
277
|
+
<tr>
|
278
|
+
<td>Type:</td>
|
279
|
+
<td>Creature — Fox Wizard</td></tr>
|
280
|
+
<tr>
|
281
|
+
<td>Pow/Tgh:</td>
|
282
|
+
<td>(2/3)</td></tr>
|
283
|
+
<tr>
|
284
|
+
<td>Rules Text:</td>
|
285
|
+
<td>At the beginning of the end step, if Kitsune Mystic is enchanted by two or more Auras, flip it.</td></tr>
|
286
|
+
<tr>
|
287
|
+
<td>Set/Rarity:</td>
|
288
|
+
<td>Champions of Kamigawa Rare</td></tr>
|
289
|
+
<tr>
|
290
|
+
<td colspan="2"><br /></td></tr>
|
52
291
|
</table>
|
53
292
|
</div>
|
54
293
|
TestXml
|
@@ -7,7 +7,7 @@ module Tamiyo
|
|
7
7
|
@set_name = set_name
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def xml_spoiler_rows
|
11
11
|
host = 'http://gatherer.wizards.com/'
|
12
12
|
path = 'Pages/Search/Default.aspx'
|
13
13
|
query = '?output=spoiler&method=text&action=advanced&set=["%s"]&special=true' % @set_name.tr(' ', '+')
|
@@ -18,7 +18,7 @@ module Tamiyo
|
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
21
|
-
|
21
|
+
|
22
22
|
def ampersand_fixed(text)
|
23
23
|
text.gsub /&(?![^;]{,4};)/, '&'
|
24
24
|
end
|
data/lib/tamiyo/scrape_parser.rb
CHANGED
@@ -6,14 +6,15 @@ module Tamiyo
|
|
6
6
|
include Process::Node
|
7
7
|
|
8
8
|
def pull
|
9
|
-
parse_cards_from @chain.
|
9
|
+
parse_cards_from @chain.xml_spoiler_rows
|
10
10
|
end
|
11
11
|
|
12
12
|
def parse_cards_from(xml)
|
13
|
-
|
13
|
+
@collection = {}
|
14
|
+
xml.each do |tr|
|
14
15
|
tds = tr.css 'td'
|
15
16
|
if tds.length == 2
|
16
|
-
left, right =
|
17
|
+
left, right = tds
|
17
18
|
right_text = right.content.tr '—', '-'
|
18
19
|
case fold left.content
|
19
20
|
when 'Name'
|
@@ -33,45 +34,96 @@ module Tamiyo
|
|
33
34
|
@text = right_text.strip.each_line.map(&:strip).join "\n"
|
34
35
|
end
|
35
36
|
else
|
36
|
-
card = parse_card
|
37
|
-
collection[card.name] = card
|
37
|
+
card = parse_card
|
38
|
+
@collection[card.name] = card
|
38
39
|
@pt = @loyalty = nil
|
39
40
|
end
|
40
|
-
end
|
41
|
+
end
|
42
|
+
@collection.values
|
41
43
|
end
|
42
44
|
|
43
|
-
def parse_card
|
44
|
-
|
45
|
+
def parse_card
|
46
|
+
linked_card = @name.match for_linked_card
|
45
47
|
@name = beautify @name
|
46
48
|
|
47
|
-
if
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
adjusted_card = if linked_card
|
50
|
+
part_name = beautify linked_card[:part_name]
|
51
|
+
card = @collection[@name]
|
52
|
+
if split_card
|
53
|
+
adjust_for_split_card card, part_name if card
|
51
54
|
else
|
52
|
-
card
|
55
|
+
adjust_for_top_flip_card card, part_name
|
53
56
|
end
|
57
|
+
elsif flip_card
|
58
|
+
adjust_for_bottom_flip_card
|
59
|
+
end
|
60
|
+
adjusted_card || new_card
|
61
|
+
end
|
62
|
+
|
63
|
+
def adjust_for_split_card(card, part_name)
|
64
|
+
if @name.start_with? part_name
|
65
|
+
card = card.with_left_split @cost, @text
|
66
|
+
else
|
67
|
+
card = card.with_right_split @cost, @text
|
68
|
+
end
|
69
|
+
card.with_extra_colors colors
|
70
|
+
end
|
71
|
+
|
72
|
+
def adjust_for_top_flip_card(card, bottom_name)
|
73
|
+
if card
|
74
|
+
card.with_flip_bottom new_card.with_name bottom_name
|
54
75
|
else
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
76
|
+
remember_top_bottom_link @name, bottom_name
|
77
|
+
new_card.with_name bottom_name
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def adjust_for_bottom_flip_card
|
82
|
+
bottom_card_name = bottom_card_part_of @name
|
83
|
+
if bottom_card_name
|
84
|
+
bottom_card = @collection.delete bottom_card_name
|
85
|
+
new_card.with_flip_bottom bottom_card
|
65
86
|
end
|
66
87
|
end
|
67
88
|
|
89
|
+
def remember_top_bottom_link(top_name, bottom_name)
|
90
|
+
@flip_card_links ||= {}
|
91
|
+
@flip_card_links[top_name] = bottom_name
|
92
|
+
end
|
93
|
+
|
94
|
+
def bottom_card_part_of(top_name)
|
95
|
+
@flip_card_links ||= {}
|
96
|
+
@flip_card_links[top_name]
|
97
|
+
end
|
98
|
+
|
99
|
+
def new_card
|
100
|
+
Card.with name: @name,
|
101
|
+
cost: @cost,
|
102
|
+
type: @type,
|
103
|
+
text: @text,
|
104
|
+
pt: @pt,
|
105
|
+
loyalty: @loyalty,
|
106
|
+
colors: colors,
|
107
|
+
table_row: table_row,
|
108
|
+
played_tapped: played_tapped,
|
109
|
+
picture_url: picture_url
|
110
|
+
end
|
111
|
+
|
68
112
|
def beautify(name)
|
69
|
-
name.gsub(
|
113
|
+
name.gsub(for_linked_card, '')
|
70
114
|
.gsub('XX', '')
|
71
115
|
.gsub('Æ', 'AE')
|
72
116
|
.tr('’', "'")
|
73
117
|
end
|
74
118
|
|
119
|
+
def split_card
|
120
|
+
@name.include? '//'
|
121
|
+
end
|
122
|
+
|
123
|
+
def flip_card
|
124
|
+
@text[match_flip_text]
|
125
|
+
end
|
126
|
+
|
75
127
|
def colors
|
76
128
|
{'W' => ' is white.',
|
77
129
|
'U' => ' is blue.',
|
@@ -122,8 +174,14 @@ module Tamiyo
|
|
122
174
|
text.strip.gsub /\s+/, ' '
|
123
175
|
end
|
124
176
|
|
125
|
-
def
|
126
|
-
/ \(
|
177
|
+
def match_linked_card
|
178
|
+
/ \((?<part_name>.*)\)/
|
179
|
+
end
|
180
|
+
|
181
|
+
alias :for_linked_card :match_linked_card
|
182
|
+
|
183
|
+
def match_flip_text
|
184
|
+
%r{flip (it|#{@name}).|flipped.}
|
127
185
|
end
|
128
186
|
end
|
129
187
|
end
|
data/lib/tamiyo/version.rb
CHANGED
data/lib/tamiyo/yaml_helper.rb
CHANGED
@@ -16,6 +16,31 @@ module Tamiyo
|
|
16
16
|
@emit.end_stream
|
17
17
|
end
|
18
18
|
|
19
|
+
def emit_pair(key, value)
|
20
|
+
emit_plain key
|
21
|
+
emit_plain value
|
22
|
+
end
|
23
|
+
|
24
|
+
def emit_pair_with_literal_value(key, value)
|
25
|
+
emit_plain key
|
26
|
+
emit_literal value
|
27
|
+
end
|
28
|
+
|
29
|
+
def emit_pair_with_optional_sequence_value(key, value)
|
30
|
+
if value.kind_of? Array
|
31
|
+
emit_pair_with_sequence_value key, value
|
32
|
+
else
|
33
|
+
emit_pair key, value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def emit_pair_with_sequence_value(key, value)
|
38
|
+
emit_plain key
|
39
|
+
emit_flow_sequence do
|
40
|
+
value.each {|element| emit_plain element}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
19
44
|
def emit_block_sequence
|
20
45
|
@emit.start_sequence nil, nil, true, YAML::Nodes::Sequence::BLOCK
|
21
46
|
yield
|
data/lib/tamiyo/yaml_sink.rb
CHANGED
@@ -14,7 +14,7 @@ module Tamiyo
|
|
14
14
|
emit_block_mapping do
|
15
15
|
emit_pair 'name', card.name
|
16
16
|
emit_pair_with_sequence_value 'identity', card.colors unless card.colors.empty?
|
17
|
-
|
17
|
+
emit_pair_with_optional_sequence_value 'mana cost', card.cost
|
18
18
|
emit_pair 'type', card.type
|
19
19
|
emit_pair_with_literal_value 'text', card.text
|
20
20
|
emit_pair 'pt', card.pt if card.pt
|
@@ -27,23 +27,6 @@ module Tamiyo
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def emit_pair(key, value)
|
31
|
-
emit_plain key
|
32
|
-
emit_plain value
|
33
|
-
end
|
34
|
-
|
35
|
-
def emit_pair_with_literal_value(key, value)
|
36
|
-
emit_plain key
|
37
|
-
emit_literal value
|
38
|
-
end
|
39
|
-
|
40
|
-
def emit_pair_with_sequence_value(key, value)
|
41
|
-
emit_plain key
|
42
|
-
emit_flow_sequence do
|
43
|
-
value.each {|element| emit_plain element}
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
30
|
def with_the_cards_file(&block)
|
48
31
|
file_name = prepare_for_card_file
|
49
32
|
if block_given?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tamiyo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roger Norling
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|