cockatrice_feeder 0.0.0 → 0.0.6

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 +234 -56
  4. metadata +5 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9bc7f2a80c7c57558a92463c5415eac22bfc4832
4
- data.tar.gz: a646c73dfbc6946e1eba60ae9a4addfaf89d9733
3
+ metadata.gz: 943a26f97319e634fd454cc60782500e15dcf6d6
4
+ data.tar.gz: e46ec8058c325032947d80c31b81179e18501a88
5
5
  SHA512:
6
- metadata.gz: 280d96f1a6c97ce6f92b38feb6cb33618f991b57a07c8934051d01c230172c318feea3737b02e32d1d606b7bc7bd1c6c6bdb34855ee5f530da846772d85575d2
7
- data.tar.gz: f394b4ab9cf428e80ba1f7df8a11dac7d5112cad210ec7c8a9618dd59b765bdffb5a0534bb27d5c362c9ac74ff336798c7d1d143f7647bc8ea8e6eabd310523c
6
+ metadata.gz: bfb439e966d8a1a2201b04dbad02209e88855ce688bcfc699f290d439b03d4c914520b4af1d09c8821f41c9f724be9f39ec614f87c4936870dc435a08e044a69
7
+ data.tar.gz: 43b50c5b107abb0dc447ea5f49bc9ab65f33b68597873fc238cd66302add8ec1800c9309e1dc1d80213338e6e3bc225d6b0e7e14e4453d440e65889a3277c415
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: nil,
176
+ price: nil,
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,141 @@ 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",
361
+ def self.archidekt_decklist(
362
+ andcolors = nil, colors = nil, commander = 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
+ "formats=#{formats}",
372
+ "orderBy=#{orderBy}",
373
+ "size=#{size}",
374
+ "pageSize=#{pageSize}"
375
+ ].compact.join("&")
376
+ ].join("")
377
+
378
+ puts url
379
+
380
+ decklist = []
381
+ data = JSON.parse(HTTParty.get(url).body)
382
+
383
+ data["results"].each do |r|
384
+ decklist << deck_obj("https://www.archidekt.com/decks/#{r["id"]}", r["name"])
385
+ end
288
386
 
387
+ decklist
388
+ end
389
+
390
+ # deck = CockatriceFeeder.deck_obj("https://www.archidekt.com/decks/992684#Rocking_that_equipment_Bro")
391
+ # CockatriceFeeder.archidekt_deck(deck)
392
+ def self.archidekt_deck(deck)
393
+ deck_id = deck[:link].split("/").last.split("#").first
394
+
395
+ api_url = "https://www.archidekt.com/api/decks/#{deck_id}/"
396
+
397
+ deck_data = JSON.parse(HTTParty.get(api_url).body)
398
+
399
+ included_categories = deck_data["categories"].select{|c| c["includedInDeck"]}.map{|c| c["name"] }
400
+ commander_categories = deck_data["categories"].select{|c| c["isPremier"]}.map{|c| c["name"] }
401
+ cardlist = []
402
+ tcg_price = 0.0
403
+ ck_price = 0.0
404
+ deck_data["cards"].each do |card|
405
+ cname = card["card"]["oracleCard"]["name"]
406
+
407
+ if card["card"]["oracleCard"]["layout"] != "split"
408
+ cname = cname.split(" // ").first
409
+ end
410
+
411
+ if (included_categories & card["categories"]).length > 0
412
+ cardlist << "#{card["quantity"]} #{cname}"
413
+
414
+ tcg_price += (card["card"]["prices"]["tcg"] * card["quantity"].to_f)
415
+ ck_price += (card["card"]["prices"]["ck"] * card["quantity"].to_f)
416
+ end
417
+
418
+ if (commander_categories & card["categories"]).length > 0
419
+ deck[:commanders] << cname
420
+ end
421
+ end
422
+
423
+ deck[:cardlist] = cardlist
424
+ deck[:price] = tcg_price.to_i.to_s
425
+
426
+ deck[:name] = deck_data["name"]
427
+
428
+ deck[:date] = deck_data["updatedAt"]
429
+
430
+ output_cod(deck,"archidekt")
289
431
  end
290
432
 
291
433
  def self.mtgdecks_decklist(pages = (1..1))
@@ -295,16 +437,16 @@ module CockatriceFeeder
295
437
  doc = Nokogiri::HTML(HTTParty.get("https://mtgdecks.net/Commander/decklists/page:#{page}").body)
296
438
  doc.css(".decks tr.previewable").each do |r|
297
439
  if r.css("td")[0].css(".label-danger").length == 0
298
- decks << {
299
- name: "", # r.css("td")[1].css("a")[0].content,
440
+ date = r.css("td")[6].css("strong")[0].content.
441
+ gsub("<span class=\"hidden-xs\">","").
442
+ gsub("</span>","").gsub(/\s+/, "")
443
+ price = r.css("td")[7].css("span.paper")[0].content.gsub("$","").gsub(/\s+/, "")
444
+
445
+ decks << deck_obj(
300
446
  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
- }
447
+ date: date,
448
+ price: price
449
+ )
308
450
  end
309
451
  end
310
452
  end
@@ -313,7 +455,6 @@ module CockatriceFeeder
313
455
  end
314
456
 
315
457
  def self.mtgdecks_deck(deck)
316
- puts deck[:link]
317
458
  doc = Nokogiri::HTML(HTTParty.get(deck[:link]).body)
318
459
 
319
460
  cardlist = []
@@ -334,27 +475,33 @@ module CockatriceFeeder
334
475
  output_cod(deck,"mtgdecks")
335
476
  end
336
477
 
478
+ def self.mtggoldfish_pricer(deck)
479
+ doc = Nokogiri::HTML(HTTParty.get("https://www.mtggoldfish.com/tools/deck_pricer#paper"))
480
+ csrf_token = nil
481
+ doc.css("meta").each do |m|
482
+ if !m.attribute("name").nil? && m.attribute("name").value == "csrf-token"
483
+ csrf_token = m.attribute("content").value
484
+ end
485
+ end
486
+
487
+ doc2 = Nokogiri::HTML(HTTParty.post("https://www.mtggoldfish.com/tools/deck_pricer#paper", {
488
+ body: {
489
+ utf8: "✓",
490
+ authenticity_token: csrf_token,
491
+ deck: deck[:cardlist].join("\n")
492
+ }
493
+ }))
494
+
495
+ deck[:price] = doc2.css(".deck-price-v2.paper").first.
496
+ content.strip.split(" ").last.split(".").first.gsub(",","")
497
+ end
498
+
337
499
  def self.gobble
338
- setup()
500
+ setup(skip_meta = true)
501
+ update_commanders()
339
502
 
340
503
  total_decks = 0
341
504
 
342
- # puts "Fetching the most recently updated ranked decks from tappedout"
343
- # decks = CockatriceFeeder.tappedout_decklist(1..10)
344
- # puts "#{decks.length} decks found."
345
- # decks.each {|d|
346
- # CockatriceFeeder.tappedout_deck(d)
347
- # total_decks += 1
348
- # }
349
- #
350
- # puts "Fetching the first 10 pages of decks at https://mtgdecks.net/Commander/decklists/"
351
- # decks = CockatriceFeeder.mtgdecks_decklist(1..10)
352
- # puts "#{decks.length} decks found."
353
- # decks.each {|d|
354
- # CockatriceFeeder.mtgdecks_deck(d)
355
- # total_decks += 1
356
- # }
357
-
358
505
  puts "Fetching the average deck for every commander on EDHREC"
359
506
  decks = CockatriceFeeder.edhrecavg_decklist
360
507
  puts "#{decks.length} decks found."
@@ -363,7 +510,38 @@ module CockatriceFeeder
363
510
  total_decks += 1
364
511
  }
365
512
 
366
- puts "#{total_decks} decks created."
513
+ puts "Fetching the most recently updated ranked decks from tappedout"
514
+ decks = CockatriceFeeder.tappedout_decklist(1..10)
515
+ puts "#{decks.length} decks found."
516
+ decks.each {|d|
517
+ CockatriceFeeder.tappedout_deck(d)
518
+ total_decks += 1
519
+ }
520
+
521
+ puts "Fetching the first 10 pages of decks at https://mtgdecks.net/Commander/decklists/"
522
+ decks = CockatriceFeeder.mtgdecks_decklist(1..10)
523
+ puts "#{decks.length} decks found."
524
+ decks.each {|d|
525
+ CockatriceFeeder.mtgdecks_deck(d)
526
+ if d[:cardlist].length > 0
527
+ total_decks += 1
528
+ end
529
+ }
530
+
531
+ puts "Fetching the first 5 pages of edh decks from deckstats ordered by likes"
532
+ decks = CockatriceFeeder.deckstats_decklist("", (1..5))
533
+ puts "#{decks.length} decks found."
534
+ decks.each {|d|
535
+ CockatriceFeeder.deckstats_deck(d)
536
+ if d[:cardlist].length > 0
537
+ total_decks += 1
538
+ end
539
+ }
540
+
541
+ puts "#{total_decks} decks created at #{@@deck_dir}."
542
+
543
+ puts "cleaning up"
544
+ FileUtils.remove_dir(@@meta_dir)
367
545
  puts "Scraw!"
368
546
  end
369
547
  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.0
4
+ version: 0.0.6
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-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -38,22 +38,8 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.18'
41
- - !ruby/object:Gem::Dependency
42
- name: awesome_print
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.8'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '1.8'
55
- description: A tool to scrape MTG decks from the internet along with some meta information
56
- 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.
57
43
  email: matt.steinwachs@gmail.com
58
44
  executables:
59
45
  - gobble
@@ -85,5 +71,5 @@ rubyforge_project:
85
71
  rubygems_version: 2.6.14
86
72
  signing_key:
87
73
  specification_version: 4
88
- summary: Scrape and generate decks for cockatrice
74
+ summary: Scrape and generate MTG EDH decks for cockatrice
89
75
  test_files: []