cockatrice_feeder 0.0.2 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/bin/gobble +0 -1
  3. data/lib/cockatrice_feeder.rb +219 -42
  4. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24f7024643afdea0db12839734cbed1c53ee4c6c
4
- data.tar.gz: 01bcde57c9f203c9fe6950fc494f69ff83c08e10
3
+ metadata.gz: 8e43bbd10275d5150dd9d3e45c8d5b01df882c65
4
+ data.tar.gz: 18d5eae374e7e1ebe294f46fcdb7fcf3fa0c697f
5
5
  SHA512:
6
- metadata.gz: eae340d56ba6c06d767a2a4f95755c09652fbe50eb8002605dc2fec899cdd6b0d9946f73bbac41ee28dd652063230498b98001577ac89d0305a42ada5bea865c
7
- data.tar.gz: 6b389611a8499be46c93f05731e8bd7499f9745aa9a19fc14c06dd8fa354c0006576e2214044ee1d12af03dac90e967bbf78825d7eb1b2394e669f604d553645
6
+ metadata.gz: 0d7f63f8025a330e9a62b6179cece671f0d7a91b0539fe9fa971ee3ef4e2bfee4dc4b3be0667800ce999662667825abc958d7fc5bc3165f6adf68f337f29b006
7
+ data.tar.gz: d7463259b547c30638eae233ea0174a31d7d79a64b9054ee05a50298248501399a11518f7330fa247d7df07e8c4be9f4812f986cf383af1ec355a73b6224702d
data/bin/gobble CHANGED
@@ -1,4 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
-
3
2
  require 'cockatrice_feeder'
4
3
  CockatriceFeeder.gobble
@@ -1,7 +1,7 @@
1
1
  module CockatriceFeeder
2
2
  require 'httparty'
3
- require 'awesome_print'
4
3
  require 'nokogiri'
4
+ require 'fileutils'
5
5
 
6
6
  @@app_dir = Dir.pwd+"/"
7
7
  @@deck_dir = @@app_dir+"decks/"
@@ -11,6 +11,9 @@ module CockatriceFeeder
11
11
  @@app_dir = (dir + (dir[-1] != "/" ? "/" : ""))
12
12
  @@deck_dir = @@app_dir+"decks/"
13
13
  @@meta_dir = @@app_dir+"meta/"
14
+
15
+ puts "decks will go here: #{@@deck_dir}"
16
+ puts "meta data will go here: #{@@meta_dir}"
14
17
  end
15
18
 
16
19
  def self.app_dir
@@ -19,6 +22,7 @@ module CockatriceFeeder
19
22
 
20
23
  def self.set_deck_dir(dir)
21
24
  @@deck_dir = (dir + (dir[-1] != "/" ? "/" : ""))
25
+ puts "decks will go here: #{@@deck_dir}"
22
26
  end
23
27
 
24
28
  def self.deck_dir
@@ -27,27 +31,30 @@ module CockatriceFeeder
27
31
 
28
32
  def self.set_meta_dir(dir)
29
33
  @@meta_dir = (dir + (dir[-1] != "/" ? "/" : ""))
34
+ puts "meta data will go here: #{@@meta_dir}"
30
35
  end
31
36
 
32
37
  def self.meta_dir
33
38
  @@meta_dir
34
39
  end
35
40
 
36
- def self.setup
41
+ def self.setup(skip_meta = false)
37
42
  unless File.directory?(@@meta_dir)
38
43
  Dir.mkdir(@@meta_dir)
39
44
  puts "Creating a folder at '#{@@meta_dir}' for storing meta data."
40
- puts "Fetching meta data."
41
- update_commanders()
42
- update_banned()
43
- update_commander_tiers()
45
+ unless skip_meta
46
+ puts "Fetching meta data."
47
+ update_commanders()
48
+ update_banned()
49
+ update_commander_tiers()
50
+ end
44
51
  end
45
52
 
46
53
  unless File.directory?(@@deck_dir)
47
54
  Dir.mkdir(@@deck_dir)
48
55
  puts "Creating a folder at '#{@@deck_dir}' for generated decks."
49
56
 
50
- folders = %w(edhrecavg mtgdecks tappedout deckstats)
57
+ folders = %w(edhrecavg mtgdecks tappedout deckstats archidekt)
51
58
 
52
59
  folders.each do |folder|
53
60
  unless File.directory?(@@deck_dir+folder)
@@ -61,7 +68,7 @@ module CockatriceFeeder
61
68
  end
62
69
 
63
70
  def self.update_commanders
64
- puts "Downloading a list of all commanderse from EDHREC."
71
+ puts "Downloading a list of all commanders from EDHREC."
65
72
  commander_cids = %w(
66
73
  w g r u b
67
74
  wu ub br rg gw wb ur bg rw gu
@@ -139,18 +146,38 @@ module CockatriceFeeder
139
146
  end
140
147
 
141
148
  def self.commanders
149
+ unless File.exist?(@@meta_dir+"commanders.json")
150
+ update_commanders()
151
+ end
142
152
  JSON.parse(File.read(@@meta_dir+"commanders.json"))
143
153
  end
144
154
 
145
155
  def self.banned
156
+ unless File.exist?(@@meta_dir+"banned.json")
157
+ update_banned()
158
+ end
146
159
  JSON.parse(File.read(@@meta_dir+"banned.json"))
147
160
  end
148
161
  # names = banned.map{|c| c["name"]}.uniq.sort
149
162
 
150
- def self.tiers
163
+ def self.commander_tiers
164
+ unless File.exist?(@@meta_dir+"tiers.json")
165
+ update_commander_tiers()
166
+ end
151
167
  JSON.parse(File.read(@@meta_dir+"tiers.json"))
152
168
  end
153
169
 
170
+ def self.deck_obj(link = "", name = "", commanders = [], date = nil, price = nil)
171
+ {
172
+ link: link,
173
+ name: name,
174
+ commanders: commanders,
175
+ date: date,
176
+ price: price,
177
+ cardlist: []
178
+ }
179
+ end
180
+
154
181
  def self.output_cod(deck, subfolder)
155
182
  comments = [
156
183
  deck[:name],
@@ -165,7 +192,7 @@ module CockatriceFeeder
165
192
  deck[:name],
166
193
  deck[:price],
167
194
  subfolder
168
- ].compact.reject(&:empty?).uniq.join('_')
195
+ ].compact.reject(&:empty?).uniq.join('_').gsub("/","")
169
196
 
170
197
  builder = Nokogiri::XML::Builder.new do |xml|
171
198
  xml.cockatrice_deck(:version => "1"){
@@ -210,14 +237,7 @@ module CockatriceFeeder
210
237
  doc.css(".deck-wide-header a").each do |a|
211
238
  link = a.attribute("href").value
212
239
  if link.include?("/mtg-decks/")
213
- decks << {
214
- name: link.split("/").last,
215
- commanders: [],
216
- link: "https://tappedout.net"+link,
217
- date: nil,
218
- price: nil,
219
- cardlist: []
220
- }
240
+ decks << deck_obj("https://tappedout.net"+link, link.split("/").last)
221
241
  end
222
242
  end
223
243
  end
@@ -262,14 +282,7 @@ module CockatriceFeeder
262
282
 
263
283
  def self.edhrecavg_decklist
264
284
  commanders.map{|c| c["link"]}.map do |c|
265
- {
266
- name: c,
267
- commanders: [c],
268
- link: "https://edhrec-json.s3.amazonaws.com/en/decks/#{c}.json",
269
- price: nil,
270
- date: nil,
271
- cardlist: []
272
- }
285
+ deck_obj("https://edhrec-json.s3.amazonaws.com/en/decks/#{c}.json", c, [c])
273
286
  end
274
287
  end
275
288
 
@@ -280,12 +293,142 @@ module CockatriceFeeder
280
293
  output_cod(deck,"edhrecavg")
281
294
  end
282
295
 
283
- def self.deckstats_decklist
284
296
 
297
+ #order ["views,desc", "price,desc", "likes,desc", "updated,desc"]
298
+ #commander should be a name attribute from the commanders array of objects
299
+ def self.deckstats_decklist(commander = "", pages = (1..1), order_by = "likes,desc", price_min = "", price_max = "")
300
+ decklist = []
301
+ pages.each do |page|
302
+ url = [
303
+ "https://deckstats.net/decks/search/?lng=en",
304
+ "&search_title=",
305
+ "&search_format=10",
306
+ "&search_season=0",
307
+ "&search_cards_commander%5B%5D=#{URI.encode_www_form_component(commander)}",
308
+ "&search_cards_commander%5B%5D=",
309
+ "&search_price_min=#{price_min}",
310
+ "&search_price_max=#{price_max}",
311
+ "&search_colors%5B%5D=",
312
+ "&search_number_cards_main=100",
313
+ "&search_number_cards_sideboard=",
314
+ "&search_cards%5B%5D=",
315
+ "&search_tags=",
316
+ "&search_order=#{URI.encode_www_form_component(order_by)}",
317
+ "&utf8=%E2%9C%94",
318
+ "&page=#{page}"
319
+ ].join("")
320
+
321
+ doc = Nokogiri::HTML(HTTParty.get(url).body)
322
+
323
+ doc.css(".deck_row").each do |dr|
324
+ link = dr.css("td")[1].css("a").first.attribute("href").value
325
+ decklist << deck_obj(link,link.split("/")[-2],[commander].reject(&:empty?))
326
+ end
327
+ end
328
+
329
+ decklist
330
+ end
331
+
332
+ def self.deckstats_deck(deck)
333
+ docstring = HTTParty.get(deck[:link]).body
334
+
335
+ doc = Nokogiri::HTML(docstring)
336
+
337
+ legal = (doc.css(".fa-exclamation-triangle").count == 0)
338
+
339
+ if legal
340
+ deck_data = JSON.parse(docstring.split("init_deck_data(").last.split(");deck_display();").first)
341
+ deck[:date] = DateTime.strptime(deck_data["updated"].to_s,'%s')
342
+ unless deck_data["highlight_cards"].nil?
343
+ deck[:commanders] = deck_data["highlight_cards"]
344
+ end
345
+ deck[:cardlist] = deck_data["sections"].map do |sec|
346
+ sec["cards"].map{|c| "#{c["amount"]} #{c["name"]}"}
347
+ end.flatten
348
+
349
+ deck[:price] = (
350
+ !doc.css(".deck_overview_price").first.nil? ?
351
+ doc.css(".deck_overview_price").first.content.gsub("$","").strip.split(".").first
352
+ : nil
353
+ )
354
+
355
+ output_cod(deck,'deckstats')
356
+ end
285
357
  end
286
358
 
287
- def self.deckstats_deck
359
+ #colors = "White,Blue,Black,Red,Green,Colorless"
360
+ #orderBy = "-updatedAt", "-createdAt", "-points", "-viewCount"
361
+ def self.archidekt_decklist(
362
+ andcolors = nil, colors = nil, commander = nil, owner = nil, formats = 3, orderBy = "-createdAt", size: 100, pageSize: 50
363
+ )
364
+
365
+ url = [
366
+ "https://www.archidekt.com/api/decks/cards/?",
367
+ [
368
+ (andcolors.nil? ? nil : "true"),
369
+ (colors.nil? ? nil : "colors=#{URI.encode_www_form_component(colors)}"),
370
+ (commander.nil? ? nil : "commanders=#{URI.encode_www_form_component(commander)}"),
371
+ (owner.nil? ? nil : "owner=#{URI.encode_www_form_component(owner)}"),
372
+ "formats=#{formats}",
373
+ "orderBy=#{orderBy}",
374
+ "size=#{size}",
375
+ "pageSize=#{pageSize}"
376
+ ].compact.join("&")
377
+ ].join("")
378
+
379
+ puts url
380
+
381
+ decklist = []
382
+ data = JSON.parse(HTTParty.get(url).body)
383
+
384
+ data["results"].each do |r|
385
+ decklist << deck_obj("https://www.archidekt.com/decks/#{r["id"]}", r["name"])
386
+ end
288
387
 
388
+ decklist
389
+ end
390
+
391
+ # deck = CockatriceFeeder.deck_obj("https://www.archidekt.com/decks/992684#Rocking_that_equipment_Bro")
392
+ # CockatriceFeeder.archidekt_deck(deck)
393
+ def self.archidekt_deck(deck)
394
+ deck_id = deck[:link].split("/").last.split("#").first
395
+
396
+ api_url = "https://www.archidekt.com/api/decks/#{deck_id}/"
397
+
398
+ deck_data = JSON.parse(HTTParty.get(api_url).body)
399
+
400
+ included_categories = deck_data["categories"].select{|c| c["includedInDeck"]}.map{|c| c["name"] }
401
+ commander_categories = deck_data["categories"].select{|c| c["isPremier"]}.map{|c| c["name"] }
402
+ cardlist = []
403
+ tcg_price = 0.0
404
+ ck_price = 0.0
405
+ deck_data["cards"].each do |card|
406
+ cname = card["card"]["oracleCard"]["name"]
407
+
408
+ if card["card"]["oracleCard"]["layout"] != "split"
409
+ cname = cname.split(" // ").first
410
+ end
411
+
412
+ if (included_categories & card["categories"]).length > 0
413
+ cardlist << "#{card["quantity"]} #{cname}"
414
+
415
+ tcg_price += (card["card"]["prices"]["tcg"] * card["quantity"].to_f)
416
+ ck_price += (card["card"]["prices"]["ck"] * card["quantity"].to_f)
417
+ end
418
+
419
+ if (commander_categories & card["categories"]).length > 0
420
+ deck[:commanders] << cname
421
+ end
422
+ end
423
+
424
+ deck[:cardlist] = cardlist
425
+ deck[:price] = tcg_price.to_i.to_s
426
+
427
+ deck[:name] = deck_data["name"]
428
+
429
+ deck[:date] = deck_data["updatedAt"]
430
+
431
+ output_cod(deck,"archidekt")
289
432
  end
290
433
 
291
434
  def self.mtgdecks_decklist(pages = (1..1))
@@ -295,16 +438,14 @@ module CockatriceFeeder
295
438
  doc = Nokogiri::HTML(HTTParty.get("https://mtgdecks.net/Commander/decklists/page:#{page}").body)
296
439
  doc.css(".decks tr.previewable").each do |r|
297
440
  if r.css("td")[0].css(".label-danger").length == 0
298
- decks << {
299
- name: "", # r.css("td")[1].css("a")[0].content,
300
- link: "https://mtgdecks.net"+r.css("td")[1].css("a")[0].attribute("href").value,
301
- date: r.css("td")[6].css("strong")[0].content.
302
- gsub("<span class=\"hidden-xs\">","").
303
- gsub("</span>","").gsub(/\s+/, ""),
304
- price: r.css("td")[7].css("span.paper")[0].content.gsub("$","").gsub(/\s+/, ""),
305
- commanders: [],
306
- cardlist: []
307
- }
441
+ link = "https://mtgdecks.net"+r.css("td")[1].css("a")[0].attribute("href").value
442
+ name = link.split("/").last
443
+ date = r.css("td")[6].css("strong")[0].content.
444
+ gsub("<span class=\"hidden-xs\">","").
445
+ gsub("</span>","").gsub(/\s+/, "")
446
+ price = r.css("td")[7].css("span.paper")[0].content.gsub("$","").gsub(/\s+/, "")
447
+
448
+ decks << deck_obj(link,name,nil,date,price)
308
449
  end
309
450
  end
310
451
  end
@@ -313,7 +454,6 @@ module CockatriceFeeder
313
454
  end
314
455
 
315
456
  def self.mtgdecks_deck(deck)
316
- puts deck[:link]
317
457
  doc = Nokogiri::HTML(HTTParty.get(deck[:link]).body)
318
458
 
319
459
  cardlist = []
@@ -334,8 +474,30 @@ module CockatriceFeeder
334
474
  output_cod(deck,"mtgdecks")
335
475
  end
336
476
 
477
+ def self.mtggoldfish_pricer(deck)
478
+ doc = Nokogiri::HTML(HTTParty.get("https://www.mtggoldfish.com/tools/deck_pricer#paper"))
479
+ csrf_token = nil
480
+ doc.css("meta").each do |m|
481
+ if !m.attribute("name").nil? && m.attribute("name").value == "csrf-token"
482
+ csrf_token = m.attribute("content").value
483
+ end
484
+ end
485
+
486
+ doc2 = Nokogiri::HTML(HTTParty.post("https://www.mtggoldfish.com/tools/deck_pricer#paper", {
487
+ body: {
488
+ utf8: "✓",
489
+ authenticity_token: csrf_token,
490
+ deck: deck[:cardlist].join("\n")
491
+ }
492
+ }))
493
+
494
+ deck[:price] = doc2.css(".deck-price-v2.paper").first.
495
+ content.strip.split(" ").last.split(".").first.gsub(",","")
496
+ end
497
+
337
498
  def self.gobble
338
- setup()
499
+ setup(skip_meta = true)
500
+ update_commanders()
339
501
 
340
502
  total_decks = 0
341
503
 
@@ -360,10 +522,25 @@ module CockatriceFeeder
360
522
  puts "#{decks.length} decks found."
361
523
  decks.each {|d|
362
524
  CockatriceFeeder.mtgdecks_deck(d)
363
- total_decks += 1
525
+ if d[:cardlist].length > 0
526
+ total_decks += 1
527
+ end
528
+ }
529
+
530
+ puts "Fetching the first 5 pages of edh decks from deckstats ordered by likes"
531
+ decks = CockatriceFeeder.deckstats_decklist("", (1..5))
532
+ puts "#{decks.length} decks found."
533
+ decks.each {|d|
534
+ CockatriceFeeder.deckstats_deck(d)
535
+ if d[:cardlist].length > 0
536
+ total_decks += 1
537
+ end
364
538
  }
365
539
 
366
- puts "#{total_decks} decks created."
540
+ puts "#{total_decks} decks created at #{@@deck_dir}."
541
+
542
+ puts "cleaning up"
543
+ FileUtils.remove_dir(@@meta_dir)
367
544
  puts "Scraw!"
368
545
  end
369
546
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cockatrice_feeder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Steinwachs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-10 00:00:00.000000000 Z
11
+ date: 2020-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -38,8 +38,8 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.18'
41
- description: A tool to scrape MTG decks from the internet along with some meta information
42
- and create Cockatrice compatible deck files.
41
+ description: A tool to scrape MTG EDH decks from the internet along with some meta
42
+ information and create Cockatrice compatible deck files.
43
43
  email: matt.steinwachs@gmail.com
44
44
  executables:
45
45
  - gobble
@@ -71,5 +71,5 @@ rubyforge_project:
71
71
  rubygems_version: 2.6.14
72
72
  signing_key:
73
73
  specification_version: 4
74
- summary: Scrape and generate decks for cockatrice
74
+ summary: Scrape and generate MTG EDH decks for cockatrice
75
75
  test_files: []