mirror of
https://github.com/ldericher/fftcgtool
synced 2025-01-15 15:02:59 +00:00
Update for better performance (ffdecks API instead of parsing mognet)
This commit is contained in:
parent
35ce9cf9d0
commit
806ee3bec8
3 changed files with 26 additions and 34 deletions
48
card.py
48
card.py
|
@ -2,31 +2,23 @@ import requests
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from lxml import etree
|
import json
|
||||||
|
|
||||||
# Base-URL of fftcgmognet card pages
|
# Base-URL of ffdecks card pages
|
||||||
TCGMOGURL = "http://www.fftcgmognet.com/card/"
|
FFDECKURL = "https://ffdecks.com/api/cards?alternates=1&serial_number={}"
|
||||||
# Card back image by Aurik
|
# Card back image by Aurik
|
||||||
BACKURL = "http://cloud-3.steamusercontent.com/ugc/948455238665576576/85063172B8C340602E8D6C783A457122F53F7843/"
|
BACKURL = "http://cloud-3.steamusercontent.com/ugc/948455238665576576/85063172B8C340602E8D6C783A457122F53F7843/"
|
||||||
|
# Card front by Square API
|
||||||
# Possible rarity suffixes
|
FACEURL = "https://fftcg.square-enix-games.com/theme/tcg/images/cards/full/{}_eg.jpg"
|
||||||
RARITIES = ["C", "R", "H", "L", "S"]
|
|
||||||
|
|
||||||
# If fftcgmognet alters designs, these *might* get old
|
|
||||||
XP_IMAGEURL = 'string(//div[@class="col-xs-12 col-sm-5 text-center mog-cardpage-image"]//img/@src)'
|
|
||||||
XP_CARDNAME = 'string(//div[@class="col-xs-12 col-sm-7 box mog-cardpage-props"]/div[@class="row"][1]/div[2])'
|
|
||||||
XP_ELEMENT = 'string(//div[@class="col-xs-12 col-sm-7 box mog-cardpage-props"]/div[@class="row"][3]/div[2])'
|
|
||||||
XP_DESCRIPT = 'string(//div[@class="col-xs-12 col-sm-7 box mog-cardpage-props"]/div[@class="row"][7]/div[2])'
|
|
||||||
|
|
||||||
|
|
||||||
class Card:
|
class Card:
|
||||||
# 'Shinra' (Wind, 6-048C)
|
# 'Shinra' (Wind, 6-048C)
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "'{}' ({}, {})".format(self._name, self._element, self.get_id())
|
return "'{}' ({}, {})".format(self._name, self._element, self.get_id())
|
||||||
|
|
||||||
# 6-048C
|
# 6-048
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return "{}-{:03}{}".format(self._opus, self._cardid, self._rarity)
|
return "{}-{:03}".format(self._opus, self._cardid)
|
||||||
|
|
||||||
# find card
|
# find card
|
||||||
def load(self, opus, cardid):
|
def load(self, opus, cardid):
|
||||||
|
@ -41,26 +33,24 @@ class Card:
|
||||||
self._iurl = BACKURL
|
self._iurl = BACKURL
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# rarity was not given (but needed for mognet URL!)
|
try:
|
||||||
for rarity in RARITIES:
|
# fetch card page from ffdecks API
|
||||||
# assume some rarity
|
result = requests.get( FFDECKURL.format(self.get_id()) )
|
||||||
self._rarity = rarity
|
res_obj = json.loads( result.content.decode("utf-8") )
|
||||||
|
|
||||||
# try to fetch card name
|
cname = res_obj["name"].strip()
|
||||||
html = requests.get(TCGMOGURL + self.get_id())
|
|
||||||
doc = etree.HTML(html.content)
|
|
||||||
cname = doc.xpath(XP_CARDNAME).strip()
|
|
||||||
|
|
||||||
# succeed or retry with next rarity tier
|
# success?
|
||||||
if cname:
|
if cname:
|
||||||
self._name = cname
|
self._name = cname
|
||||||
self._iurl = doc.xpath(XP_IMAGEURL).strip()
|
self._iurl = res_obj["image"]
|
||||||
self._element = doc.xpath(XP_ELEMENT).strip()
|
self._element = res_obj["element"]
|
||||||
self._description = doc.xpath(XP_DESCRIPT).strip()
|
self._description = "\n\n".join(res_obj["abilities"])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# No fitting rarity found,
|
except:
|
||||||
return False
|
# Something went wrong
|
||||||
|
return False
|
||||||
|
|
||||||
# return in dictionary format
|
# return in dictionary format
|
||||||
def get_dict(self):
|
def get_dict(self):
|
||||||
|
|
10
main.py
10
main.py
|
@ -1,11 +1,13 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# base config
|
# base config
|
||||||
opusid = 6
|
opusid = 7 # opus prefix
|
||||||
|
num_threads = 16 # maximum concurrent requests
|
||||||
|
opus_size = 500 # maximum card count per opus
|
||||||
|
|
||||||
# constants
|
# constants
|
||||||
grid = 7, 10 # default in TTsim: 7 rows, 10 columns
|
grid = 7, 10 # default in TTsim: 7 rows, 10 columns
|
||||||
reso = 480, 670 # default in TTsim: 480x670 pixels per card
|
reso = 429, 600 # default in TTsim: 480x670 pixels per card
|
||||||
|
|
||||||
# set up logging
|
# set up logging
|
||||||
import logging
|
import logging
|
||||||
|
@ -21,11 +23,11 @@ os.chdir("out")
|
||||||
# load an Opus
|
# load an Opus
|
||||||
from opus import Opus
|
from opus import Opus
|
||||||
myOpus = Opus()
|
myOpus = Opus()
|
||||||
myOpus.load(opusid, 2, 2)
|
myOpus.load(opusid, opus_size, num_threads)
|
||||||
|
|
||||||
# compose custom deck images
|
# compose custom deck images
|
||||||
faceurls = []
|
faceurls = []
|
||||||
for i, image in enumerate(myOpus.get_images(grid, reso)):
|
for i, image in enumerate(myOpus.get_images(grid, reso, num_threads)):
|
||||||
filename = "opus_%d_%d.jpg" % (opusid, i)
|
filename = "opus_%d_%d.jpg" % (opusid, i)
|
||||||
image.save(filename)
|
image.save(filename)
|
||||||
# ask for upload
|
# ask for upload
|
||||||
|
|
2
opus.py
2
opus.py
|
@ -126,7 +126,7 @@ class Opus:
|
||||||
sheet = Image.new("RGB", (c*w, r*h))
|
sheet = Image.new("RGB", (c*w, r*h))
|
||||||
logger.info("New image: %dx%d" % sheet.size)
|
logger.info("New image: %dx%d" % sheet.size)
|
||||||
|
|
||||||
# beware concurrent writes
|
# beware concurrent paste
|
||||||
sheet_lock = threading.Lock()
|
sheet_lock = threading.Lock()
|
||||||
|
|
||||||
# start multithreading, wait for finish
|
# start multithreading, wait for finish
|
||||||
|
|
Loading…
Reference in a new issue