用于轻松处理魔法的工具集合:从scryfall和/或magic the gathering.io收集卡并在计算机上设置数据。

mtgtools的Python项目详细描述


MTG工具

mtgtools是一组工具,用于在计算机上轻松处理magic:收集数据。卡片数据 可从scryfallapi或magicthegathering.ioapi轻松下载,并保存在zodb-数据库中, 这是python的本地对象数据库。一切都是用python编写的,因此不需要了解sql之类的知识就可以使用数据库。

功能

  • 轻松下载、更新和保存magic:收集卡,并将scryfall和/或magic the gathering.io中的数据设置为 本地zodb数据库(python的本地对象数据库)。从头更新数据库通常需要2 在我的电脑上几分钟。

  • 轻松地迭代、筛选、排序、分组和处理卡片列表、集合和卡片组。一般的搜索方法 在我的电脑上,4万张卡片的卡片数据库大约需要0.15秒。

  • 用纯python将您自己的卡片列表和卡片组保存在数据库中。

  • 从文件中读写卡片列表或卡片组。

  • 从任何卡片列表中生成随机样本、随机卡片、增强包等。

  • 从scryfall下载您所选类型的卡图像。

  • 使用scryfall从卡列表中创建代理图像表。

要求

  • Python3.5-mtgtools在Python3.5上测试过,但可能也适用于更高版本

  • zodb-可以使用pip install zodb安装。有关详细信息,请访问http://www.zodb.org/en/latest/" rel="nofollow">http://www.zodb.org/en/latest/

  • 请求-可以使用pip install requests安装。有关详细信息,请访问https://pypi.org/project/requests/" rel="nofollow">https://pypi.org/project/requests/

  • pil-不需要,但创建代理映像表时需要。可使用PIP安装枕头安装

scryfall与magicthegathering.io之比较

目前,mtg数据有两种不同的api,scryfall和magicthegathering.io。他们是 以不同的方式构建,两者各有利弊。例如,scryfall卡包含属性卡面 其中,作为mtgio中的面是单独的卡。

目前,scryfall有一个更广泛的数据库,其中包含更多有用的数据,如价格和购买uri,还包含 高质量的卡片图像,因此在我看来,这两者更有用。

安装

mtgtools可以通过pip install mtgtools

使用指南

永久卡、集合和卡列表对象

使用数据库主要围绕使用以下持久卡和卡列表对象。数据 这种情况下的持久性基本上意味着zodb将自动检测何时访问这些对象,以及 提交事务后,会自动修改并保存相应的更改。

例如,关于zodb的一个很好的指南可以在这里找到:https://media.readthedocs.org/pdf/zodborg/latest/zodborg.pdf" rel="nofollow">https://media.readthedocs.org/pdf/zodborg/latest/zodborg.pdf

PCARD卡

pcard是一个简单的持久数据类,表示魔力:具有其特性的收集卡 属性。它只是用magicthegating.io或scryfall中的json响应字典构造的 api,因此pcard具有与响应的键和值匹配的所有属性。

注意,属性power韧度忠诚度保存为字符串,因为它们可能包含字符 比如"*"或"x"。为了方便起见,card对象还将包含这些属性的数字版本: 电源编号韧性数值忠诚度数值。这使得在许多情况下搜索变得更加容易。剥离后 这些非数字字符,其余的数字将在属性的数字版本中。如果什么都没留下 剥离后,数字版本将为0。

scryfall和mtgio的另一个区别是,在mtgio api中,属性名是camelcase样式的。对于 为了保持一致性,本软件中的属性被转换为snake_case,这使得 属性与scryfall中的相同。例如,mtgio的属性manacost已更改为 管理成本与scryfall相同。

有关卡片属性的更多信息,请阅读 https://scryfall.com/docs/api/cards用于scryfall卡对象和 对于magicthegathering.io卡对象,请使用https://docs.magicthegathering.io/api v1cards_list" rel="nofollow">https://docs.magicthegathering.io/api v1cards_list。

卡片列表

pcard list是一个持久的卡片列表或卡片组对象,它的作用与pcard的普通python列表基本相同 物体。这些列表可以像其他任何持久对象一样保存在数据库中,并使用pcardlist 作为数据库中所有卡的容器。

pCardList有许多有用的方法来查询、筛选、排序和分组它的内容以及创建新卡 以各种方式组合其他卡片列表。它还包含其他方便的方法,如下载图像 其中一张是斯克里福尔的卡,用它的卡制作代理图像,打印出它的内容 方法并创建一个类似于文件组的字符串或其内容的文件。

除了常见的就地列表方法(如extendappendremove之外,pCardList在 样式,这意味着调用任何其他筛选或查询方法都将返回新的 原稿未动。

pCardList也可以通过向其侧边栏添加卡片来用作牌组。餐具柜里有卡片 更改方法的某些功能,如deck_str,其中现在还添加了侧边栏卡。图像 下载并为卡和侧边栏创建代理。不过,在"餐具柜"里有卡片 不会改变关键内部方法的行为,如lengetitemsetitem, 因此,餐具柜里的卡片基本上是一种额外的东西。

pset

pset是一个简单的持久化数据类,表示magic:集合集及其特性 属性。它只是用magicthegating.io或scryfall中的json响应字典构造的 api,因此pset的所有属性都与响应的键和值匹配。

有关属性集的更多信息,请阅读 对于scryfall set对象和 对于magicthegathering.io set对象,请使用https://docs.magicthegathering.io/api v1sets\u list" rel="nofollow">https://docs.magicthegathering.io/api v1sets\u list。

此外,pset继承自pcardlist并且它还包含集合的所有卡片。使用pset 例如,查询它的卡片会返回newpCardList对象对于集合是安全的,而不会影响它。

psetlist

pset list是一个持久的set list对象,它的作用与pset对象的普通python列表类似。 这些列表可以像任何其他持久对象一样保存在数据库中s.psetlist包含 查询它包含的集合,但在大多数情况下,它仅作为容器数据库使用。它的工作原理非常相似 除非他们持有套牌而不是纸牌,否则要将其转换成卡片列表。

使用数据库

打开/创建数据库

只需使用

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')

如果在给定路径中找不到存储,则会自动创建一个新的空数据库。

现在到数据库的连接已经打开,mtg_db将包含所有需要的zodb相关对象 存储连接数据库(有关这些的更多信息,请访问http://www.zodb.org/en/latest/reference/index.html" rel="nofollow">http://www.zodb.org/en/latest/reference/index.html)。 卡和集合现在可以在数据库的根目录中找到

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets

>>> mtgio_cards = mtg_db.root.mtgio_cards
>>> mtgio_sets = mtg_db.root.mtgio_sets

所有卡都保存为pCardList,所有集都保存为pSetList。根充当 启动捆绑点和数据库中所有对象的顶级容器。

>>> print(mtg_db.root)

<root: mtgio_cards mtgio_sets scryfall_cards scryfall_sets>

上述访问数据库对象的方法非常方便,您还可以使用

>>> root_mapping = tool.connection.root()
>>> print([key for key in root_mapping.keys()])

['scryfall_sets', 'mtgio_cards', 'scryfall_cards', 'mtgio_sets']

>>> print('scryfall_cards' in root_mapping)

True

更新

只需使用

my_db.scryfall_update()
my_db.mtgio_update()

更新将下载并保存所有新卡和设置数据,还将更新对现有数据的任何更改。这是 更新时也很有用,例如经常更改的ScryFall卡的价格和合法性属性。

从头开始构建数据库大约需要几分钟的时间,它主要受api请求的影响 对于scryfall,每秒10个请求;对于magicthegathering.io,每小时5000个请求。大约10 更新期间每秒发送的请求应符合scryfall限制和magicthegathering.io 您必须确保每小时运行更新的次数不要太多。

使用卡片列表

查询、筛选和排序

pcardlist有两种方便的方法来"查询"其内容,这些方法返回新的pcardlist对象:

其中(反转=false,搜索所有面=false,**kwargs)

确切位置(反转=false,搜索所有面=false,**kwargs)

其中,较松散的方法返回一个新的pcardlist,其中任何给定的关键字参数都匹配"松散的" 与此列表中的卡的属性。参数应该是任何卡属性名,如 "功率"、"韧性"和"名称"。

字符串属性不区分大小写,参数是属性的子字符串就足够了。

对于列表属性,顺序无关紧要,其中一个元素完全匹配就足够了

为了方便起见,对于数值属性,参数足够大或等于属性的大小。

其中,更严格的方法返回一个新的卡片列表,其中所有给定的关键字参数都匹配 完全使用此列表中卡的属性。

对于这两种方法,可以通过设置反转结果以返回所有与参数不匹配的卡 反转=真

对于有时具有卡面属性的scryfall卡,通常只有卡的第一个面 (您将播放的普通面)在匹配参数时被考虑。通过设置search_all_faces=true参数 现在也可以与卡的任何可能面匹配。

让我们从获取所有scryfall卡和数据库集开始:

>>> from mtgtools.MtgDB import MtgDB

>>> mtg_db = MtgDB('my_db.fs')
>>> cards = mtg_db.root.scryfall_cards
>>> sets = mtg_db.root.scryfall_sets

一些基本搜索:

>>> werebears = cards.where_exactly(name='Werebear')
>>> print(werebears)

[Werebear (ema), Werebear (td0), Werebear (wc02), Werebear (ody)]

>>> print(len(werebears))

4

结果发现,有4个不同的韦雷贝尔卡在4个不同的设置。让我们从奥德赛获得一张卡:

>>> ody_werebear = cards.where_exactly(name='Werebear', set='ody')[0]
>>> print(ody_werebear)

Werebear (ody)

>>> print(ody_werebear.name, ody_werebear.set, ody_werebear.set_name, ody_werebear.power, ody_werebear.toughness)

Werebear ody Odyssey 1 1

>>>print(ody_werebear.oracle_text)

{T}: Add {G}.
Threshold â€" Werebear gets +3/+3 as long as seven or more cards are in your graveyard.

注意,在这种情况下使用卡。其中(name='werebear',set='ody')不仅返回werebear,而且 集合"ody"中的所有其他卡,因为其中返回任何给定关键字参数的卡 部分或完全匹配。

还要注意,对于where来说,参数只匹配一部分就足够了。例如使用字符串参数 名称键入行Oracle文本中的参数足够作为卡属性的子字符串 问题:

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
0

查询和其他操作返回新列表,因此我们还可以将多个查询链接在一起。他以前的一个 链接示例:

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
1

如果上述方法不足以找到您需要的内容,那么还有一个有效的筛选方法 很像python列表中常用的过滤方法。筛选的接受一个函数对象并返回一个新列表 包含列表中给定函数返回true的所有卡片。lambda函数非常方便 用这种方法。例如,我们可以通过以下方式过滤卡片,找到OdysseyWereBar

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
2

卡片列表可以使用sorted-方法进行排序,它的工作方式与python中常用的sort-方法非常相似 列表。它接受一个函数对象,该对象应该返回卡片对象的一些属性,根据这些属性对列表进行排序。 例如,按设置代码排序:

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
3

最后,pcardlist中的卡对象存储在它的card s-属性中,在persistentlist中也可以 直接访问。

创建和组合列表

pcardlist的作用类似于普通的python list,因此我们可以使用普通的索引和切片。您还可以创建空列表:

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
4

卡片可以很容易地与加法结合起来。添加可用于列表和单卡对象:

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
5

组合列表的另一种方法是将卡片附加到现有列表中。注意,这实际上会改变列表 而不是创建另一个:

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
6

可以使用减法或常用列表方法从列表中删除卡片。减法处理列表 单卡对象,基本上与集合减法相同:

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
7

列表中的卡片可以成倍增加。例如,这对于获取特定卡片的游戏集很方便(注意 您必须乘列表,而不是卡对象):

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
8

使用来自scryfall的多功能卡

如前所述,scryfall中的一些卡有多个面。这些是例如翻页卡片 "akki lavarunner//tok tok,火山出生的"和转换卡,如"诅咒巫婆//infective curse"。在一些 案例这些卡片的某些属性仅位于卡片的卡片面-dict属性内。 在其他情况下,卡本身可能具有非空属性,并且同一属性在其中一个 这是卡片面。

例如,card对象的'akki lavarunner'属性是'akki lavarunner//tok tok,volcano born' 第一张牌面的名称属性是'akki lavarunner',第二张牌面的名称属性是 "托克,火山诞生"。类似地,卡'诅咒巫婆//infective curse'/em>的法力消耗-属性是 空,但它的第一张牌面的mana-cost-属性是'{3}{b}',这是我们期望的 卡。因此,默认情况下,如果第一个卡面不为空,则也会匹配它。

如果你想搜索查询时必须设置search_all_faces=true的卡。可能需要审判 一开始就错误地得到了你想要的。

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')
9

分组卡

列表中的卡可以以不同的方式分组,如颜色、类型或转换的法力消耗。分组 返回组标识为键的dict,并将组对应的卡片列表作为值。按颜色分组或 颜色标识,键将始终按字母顺序排列,如"br"和"guw",而不是普通的 "Wubrg"-订单。

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
0

按id分组的方法对于从列表中快速检索多个卡片对象非常有用。各不相同 卡片包含一个唯一的id属性,通过该属性,可以通过分组快速检索列表中的卡片。

您还可以使用以下方法为列表中的卡片创建一种特殊的分组或一种"索引" 创建id_索引它返回一个持久的btree对象。实际上,您可以像使用普通python dict一样使用btree 它们也可以方便地作为索引保存在数据库中。

从文件和字符串中读取卡

卡片也可以从数据库(和任何其他卡片列表)中通过从类似于字符串的列表中读取来检索 和文本文件,使用从str和从file创建新卡片列表的方法 在列表中找到。字符串和文本文件的接受格式类似于标准apperentice和mws 文件组列表:

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
1

注释行可以用"//"指定,可能需要的集可以用"(set_code)"指定 或"[设置代码]"和前缀为"sb:"的餐具柜卡。设置的括号可以是除所需数字之外的任何位置 卡片的名字必须在卡片的前面。如果未找到匹配集,则返回随机集中的一张卡。

请注意,此方法对于整个卡片数据库而不是小列表非常有用。

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
2

您还可以用不同的方式构造甲板字符串。例如,按颜色和不带设置代码:

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
3

from_file除了从文本文件中读取内容外,其工作方式完全相同。

更多示例

我们可以使用更宽松的来查找具有某种力量或韧性的卡片,方法是 对于数值属性,参数等于或大于就足够了。注意,对于功率韧性忠诚度您可以使用数字版本功率值可靠性值忠诚度值

奥德赛中有力量的生物>;5:

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
4

《奥德赛》中不包括多色的白色生物,其力量<;=2,韧性<;=2:

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
5

带cmc的奥德赛光环<;=2:

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
6

在数据库中保存自己的东西

关于在zodb中保存东西的好指南可以在这里找到: http://www.zodb.org/en/latest/guide/writing persistent objects.html

上面提到的任何对象都是持久的,因此可以方便地保存它们。例如任何卡列表 使用

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
7

之后,您可以使用

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
8

稍后使用

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets
9

类似地,您也可以保存卡片组或其他卡片列表,例如使用persistentlist 普通python列表:

>>> mtgio_cards = mtg_db.root.mtgio_cards
>>> mtgio_sets = mtg_db.root.mtgio_sets

0

之后,您可以附加更多列表,并以同样的方式使用单卡访问它们。

另一件事,你可能想保存在数据库中,例如一个索引卡更快的检索。一个"索引" 在这种情况下,将是一个快速持久的dict-like-btree,其中的键是一些唯一的标识符。对于pCardList, 已经存在方法create_id_index返回一个btree树,在该树中,卡片按其唯一性进行索引 "id"值和每个id映射到原始列表中找到的单个卡对象。如果总的来说这很方便 数据库并保存:

>>> mtgio_cards = mtg_db.root.mtgio_cards
>>> mtgio_sets = mtg_db.root.mtgio_sets

1

现在,通过使用他们的id's:

>>> mtgio_cards = mtg_db.root.mtgio_cards
>>> mtgio_sets = mtg_db.root.mtgio_sets

2

同样,索引还可以用于快速检查数据库中是否存在某个对象。

pCardList对象具有类似的唯一ID,因此如果需要,它们也很容易索引。

使用集合和集合列表

psetpsetlist的工作方式与pcardpcardlist非常相似。区别在于pset 也是一个pcardlist,它包含一组自己的特性魔术:集合集属性。psetlist 通过使用where方法,可以像pCardList对象一样搜索、筛选和排序对象, 在哪里精确地筛选排序它们同样返回新的psetlist对象。

这些集合保存在数据库中,作为psetlist

一些示例

设置在masques块中:

>>> mtgio_cards = mtg_db.root.mtgio_cards
>>> mtgio_sets = mtg_db.root.mtgio_sets

3

所有包含否定的集合:

>>> mtgio_cards = mtg_db.root.mtgio_cards
>>> mtgio_sets = mtg_db.root.mtgio_sets

4

没有促销的普通标准法律套件:

>>> mtgio_cards = mtg_db.root.mtgio_cards
>>> mtgio_sets = mtg_db.root.mtgio_sets

5

你还能用卡片和布景做什么?

其余的方法和功能都是非常自解释的,并且有很好的文档记录,所以它们不需要进一步 指导。例如,您可以使用random_pack从卡列表中创建random booster pack,从 scryfall with从scryfall下载图像,用 创建代理,使用json将列表返回到json和更多内容。

注意事项和可能出现的问题

可能的错误

这些工具对scryfall数据进行了适当的测试,但预计会出现一些错误和奇怪的行为, 尤其是一些特殊的卡片。

目前,magicthegathering.io中的数据没有经过测试,但它仍然应该像scryfall数据一样工作。如果你 使用mtgio时,请注意它们之间的差异。

关于数据库的一些事情
  • 在使用多个不同的存储空间以及在保存自己的存储空间时格式化/重新更新旧存储空间时,请注意 列表。如果出现问题,数据库底部的旧对象被新对象替换,则 在您自己保存的列表中包含引用的对象不再以相同的方式工作。这是因为 创建的对象实例不等于数据库中的旧实例,即使它们具有相同的ID。请确保 在更新之前备份旧数据库。目前没有很好的复苏支持。

  • 打开数据库后第一次访问数据库中的任何对象都需要很长时间。这是因为数据 此时尚未缓存。当数据被缓存时,对象实际上是从缓存中检索的,而不是 数据库交互,速度很快。

  • 默认情况下,不能从多个线程使用数据库。存储db实例可以,但要使用事务 和对象访问必须为每个线程使用不同的连接和事务管理器。

  • 对象可以用作字典中的键,但速度可能很慢。

  • 对象的某些属性,如列表和dict(例如颜色卡片面)不是不可变的。 zodb不会自动识别对这些属性的更改。当更改对象内部的值时 可变属性,在调用ode>提交。经常 更简单的方法是使用assignment或setattr而不是更改属性中的某些内容。在这种情况下, 当重新分配整个属性时,zodb将识别此属性,并在提交时保存更改。

作者

Esko Kalervo萨拉卡

许可证

版权所有©2018 Esko Kalervo Salaka。 保留所有权利。

Zope公共许可证(ZPL)2.1版

此许可证文档附带一份版权声明,用于标识 版权所有人。

此许可证已被认证为开放源代码。它也被指定为 GPL兼容自由软件基金会(FSF)。

以源和二进制形式重新分配和使用,有无 如果满足以下条件,则允许修改:

  1. 源代码中的重新分发必须保留附带的版权 注意,此条件列表和以下免责声明。

  2. 二元形式的再分配必须复制附带的版权 注意,此条件列表,以及 分发时提供的文档和/或其他材料。

  3. 版权持有人的姓名不得用于背书或宣传 未经 版权所有人。

  4. 分发或用于任何目的的权利 授予您使用服务标志(SM)或商标(TM)的权利 版权 持有人。它们的使用由与版权的单独协议所涵盖 持有人:

  5. 如果修改了任何文件,则必须使修改后的文件携带 显著的通知,说明您更改了文件和任何 变化,

免责声明

本软件由版权所有人"按原样"和 或默示保证,包括但不限于默示保证 对适销性和特定用途的适用性不予承认。在没有 事件版权所有者应对任何直接、间接的, 附带的、特殊的、惩戒性的或间接的损害(包括但不包括 仅限于替代货物或服务的采购;使用、数据或 利润;或营业中断)无论是何种原因引起的 责任,无论是合同责任、严格责任还是侵权责任(包括 因使用本软件而产生的疏忽或其他原因, 即使被告知可能发生这种损害。

致谢

这个软件使用zodb,一个python的本地对象数据库,它是 版权归Zope基金会和贡献者所有。

这个软件使用了scryfall的rest类api,这是scryfall llc的版权。

这个软件使用了类似rest的magicthegathering.io的api,这是andrew backes的版权。

这个软件使用了python图像库(pil),这是secret labs ab和 版权所有©1995-2011 Fredrik Lundh

所有与magic相关的图形和文字信息和数据:可以用这个来处理的收集 软件,如卡片信息和卡片图像,是海岸奇才有限责任公司的版权。 孩之宝公司的子公司。

此软件不受Scryfall、Zope基金会、MigICTHealthIGIGI.IO或 海岸奇才。

这个软件是免费的,其目的是创造新的魔术:收集内容和软件,以及 只是为了好玩。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java Intellij通过方法中的包查找用法   java中VS代码和打包命名的问题   将java CMS功能集成到具有高度动态内容的网站(Lucene/Mysql/Nosql)的策略   oracle的java类强制转换异常。jdbc。驾驶员OracleConnection   字节码向JVM添加上指令   如何在抽象类中执行java方法?   java是否可以在apache访问日志中排除指定的GET参数?(作者:W7开发环境)   java如何获取已安装音频播放器的列表?   尝试向HS学生展示如何使用Java访问MS数据库   使用正则表达式java对给定行中的特定字符串进行计数   java JOOQ Select查询中的Select计数   方法Java,如何从二维双精度数组中找到特定值?   获取图像URL的java正则表达式   java在切换到新的窗口驱动程序后找不到元素