Documentation
¶
Overview ¶
Package cardmarket reads Cardmarket's marketplace: the signed API that answers for products, expansions and listings, and the catalog files the site publishes for anyone to download. The entities are named as https://apiv2.cardmarket.com/ws/documentation names them, so a field can be looked up in one place rather than translated first.
Index ¶
- Constants
- func BuildURL(game Game, idProduct int, opt URLOption) string
- func ConditionName(condition Condition) string
- func CountryName(country Country) string
- func GameName(game Game) string
- func LanguageName(language Language) string
- func ParseContentRange(header string) (total int, capped bool, ok bool)
- func ProductVersion(product *Product) int
- func SearchURL(game Game, name string, opt URLOption) string
- func UserScoreName(score UserScore) string
- type APIError
- type Article
- type ArticlePrice
- type ArticleQuery
- type ArticleSeller
- type Catalog
- type CatalogData
- type CatalogExpansion
- type CatalogMeta
- type CatalogProduct
- type Client
- func (mkm *Client) Articles(ctx context.Context, id int, query ArticleQuery, page, maxResults int) (articles []Article, total int, capped bool, err error)
- func (mkm *Client) ExpansionSingles(ctx context.Context, id int) ([]Product, error)
- func (mkm *Client) Expansions(ctx context.Context, game Game) ([]Expansion, error)
- func (mkm *Client) Product(ctx context.Context, id int) (*Product, error)
- func (mkm *Client) RequestNo() int
- type Condition
- type Country
- type Expansion
- type Filter
- type Game
- type Language
- type Link
- type Localization
- type PriceGuide
- type PriceGuideFile
- type Product
- type ProductList
- type ProductListFile
- type URLOption
- type UserScore
- type UserType
Constants ¶
const (
// MaxEntities is how many results one request may ask for
MaxEntities = 100
)
Variables ¶
This section is empty.
Functions ¶
func BuildURL ¶
BuildURL builds the storefront link for a product, narrowed and tagged by whatever the option carries.
func ConditionName ¶ added in v0.3.0
ConditionName returns the condition spelled out, or "" for a code the marketplace does not use.
func CountryName ¶ added in v0.3.0
CountryName returns the country's name in English, or "" for a number the marketplace carries no country for.
func GameName ¶
GameName returns the game as Cardmarket spells it in an address, or "" for a number it carries no game for.
Every game the marketplace sells is named here, not only the ones a particular caller prices. Which games are worth reading is the caller's business; which games exist is Cardmarket's.
func LanguageName ¶ added in v0.3.0
LanguageName returns the language's name in English, as the API's own languageName field spells it, or "" for a number it carries no language for.
func ParseContentRange ¶ added in v0.2.0
ParseContentRange reads the total listing count out of a Content-Range header ("0-29/33", or "0-99/1000+" once Cardmarket stops counting past its own cap). Capped reports the latter case: total is 1000, the highest figure the API ever reports, not the real count, which is unknowable past it. An empty or unrecognized header reports ok=false rather than a misleading zero, and so does one no listing could have sent: a signed or out of range number, or a range that ends before it starts.
func ProductVersion ¶
ProductVersion reads that index off a product, or zero where it carries none. The marketplace publishes it in the name for some games and only in the address for others - of the catalogs we walk, 31,523 of Yu-Gi-Oh's 86,628 products name it and not one of Pokemon's 72,752 does, though its shelves are full of it - so both are read and the name wins.
func SearchURL ¶
SearchURL returns the catalog search for a product name, the fallback for a card whose Cardmarket product id is not known. It takes the same option as BuildURL and is empty for the same games, so adding a filter to one cannot quietly leave the other behind.
func UserScoreName ¶ added in v0.3.0
UserScoreName returns the score spelled out, or "" for a number the marketplace does not use.
Types ¶
type APIError ¶
type APIError struct {
Description string `json:"mkm_error_description"`
InternalCode any `json:"internal_error_code"`
PostDataField any `json:"post_data_field"`
StatusCode int `json:"http_status_code"`
StatusDescription string `json:"http_status_code_description"`
}
APIError is the body Cardmarket answers a rejected request with. The description is the only part meant for a person; the rest says which of the request it objected to.
type Article ¶
type Article struct {
IDArticle int `json:"idArticle"`
IDProduct int `json:"idProduct"`
Language struct {
IDLanguage Language `json:"idLanguage"`
LanguageName string `json:"languageName"`
} `json:"language"`
Comments string `json:"comments"`
Price float64 `json:"price"`
IDCurrency int `json:"idCurrency"`
CurrencyCode string `json:"currencyCode"`
Prices []ArticlePrice `json:"prices,omitempty"`
Count int `json:"count"`
InShoppingCart bool `json:"inShoppingCart"`
Condition Condition `json:"condition"`
Product struct {
Name string `json:"enName"`
LocName string `json:"locName"`
Expansion string `json:"expansion"`
IDExpansion int `json:"idExpansion"`
SetCode string `json:"abbreviation"`
Number string `json:"nr"`
Rarity string `json:"rarity"`
IDGame Game `json:"idGame"`
ExpIcon int `json:"expIcon"`
} `json:"product"`
Seller ArticleSeller `json:"seller"`
IsFoil bool `json:"isFoil"`
IsFirstEd bool `json:"isFirstEd"`
IsReverseHolo bool `json:"isReverseHolo"`
IsSigned bool `json:"isSigned"`
IsAltered bool `json:"isAltered"`
Links []Link `json:"links,omitempty"`
}
Article is one seller's listing on a product.
The finish flags are the game's own and not one vocabulary: a Magic listing carries IsFoil and neither of the others, a Pokemon listing carries IsFirstEd and IsReverseHolo and no IsFoil at all. A flag absent from a game's listings decodes false, so read the one its game uses.
type ArticlePrice ¶
type ArticlePrice struct {
Price float64 `json:"price"`
IDCurrency int `json:"idCurrency"`
CurrencyCode string `json:"currencyCode"`
}
ArticlePrice is one listing's price in one currency. A listing is quoted in the seller's currency and in every currency the marketplace converts it to.
type ArticleQuery ¶ added in v0.4.0
type ArticleQuery struct {
// UserType narrows to one kind of seller; UserTypeCommercial includes
// powersellers.
UserType UserType
// MinUserScore and MinCondition each mean that or better.
MinUserScore UserScore
MinCondition Condition
// Language is the listing's language.
Language Language
// SellerCountry is the seller's country of origin. The documentation
// takes one.
SellerCountry Country
// Foil, FirstEd and ReverseHolo narrow to a printing, and Signed and
// Altered by what was done to the card, as the Article's flags of the
// same names. FirstEd and ReverseHolo are not in the documentation.
Foil Filter
FirstEd Filter
ReverseHolo Filter
Signed Filter
Altered Filter
// MinAvailable is the fewest copies a seller holds across all their
// listings matching the rest of the query, not in any one listing.
MinAvailable int
}
ArticleQuery is what an Articles request narrows the listings by. The zero value asks for every listing, and each field set adds the parameter the documentation names. Articles refuses a value outside this package's own constants rather than send one the API would ignore.
The API's filters fail open: one that does not apply to a game is ignored and the unfiltered listing answered, not an error. Check each Article's own fields rather than trusting the request.
type ArticleSeller ¶
type ArticleSeller struct {
IDUser int `json:"idUser"`
Username string `json:"username"`
IsCommercial int `json:"isCommercial"`
IsSeller bool `json:"isSeller"`
Reputation int `json:"reputation"`
SellCount int `json:"sellCount"`
SoldItems int `json:"soldItems"`
OnVacation bool `json:"onVacation"`
// AvgShippingTime is in days, and RiskGroup and LossPercentage are the
// marketplace's own read on whether an order will arrive.
AvgShippingTime int `json:"avgShippingTime"`
RiskGroup int `json:"riskGroup"`
LossPercentage string `json:"lossPercentage"`
Address struct {
Country string `json:"country"`
} `json:"address"`
}
ArticleSeller is who is selling, minus the fields naming the person. The marketplace answers a seller's first name, email, phone, VAT number and legal information beside their trading record; none of that is needed to judge a price, so none of it is decoded and none of it can leak into a log of an article.
type Catalog ¶
type Catalog struct {
Meta CatalogMeta `json:"meta"`
Data CatalogData `json:"data"`
}
Catalog is a published Cardmarket catalog: every singles product mapped to what the marketplace says of it, which is what a price run reads instead of walking the API.
cmd/mkmcatalog writes it for every game, Magic included, from the API's own answers. It names products and expansions and nothing else: which printing of a datastore a product stands for is the reader's to work out.
type CatalogData ¶
type CatalogData struct {
Expansions map[int]CatalogExpansion `json:"expansions"`
Products map[int]CatalogProduct `json:"products"`
}
CatalogData is the file's two tables. JSON has only string keys, so the ids are written as strings and read back as the numbers they are, which encoding/json does on its own for an integer-keyed map.
type CatalogExpansion ¶
CatalogExpansion names one expansion of the catalog. Code is the marketplace's own abbreviation, which is where the foreign catalogs say what they are.
type CatalogMeta ¶
type CatalogMeta struct {
Date string `json:"date"`
// Unwalked names the expansions whose products did not come from this
// walk, because the API would not answer for them: they are the
// previous catalog's, or absent altogether where it had none for the
// expansion - a shelf added since the last good walk. A reader that
// cares how fresh a shelf is has to be told, since neither case is
// otherwise distinguishable from one walked today. Empty in the
// ordinary case.
Unwalked []int `json:"unwalked,omitempty"`
}
CatalogMeta says when the file was built and how much of it was.
type CatalogProduct ¶
type CatalogProduct struct {
ExpansionID int `json:"expansionId"`
Name string `json:"name"`
Number string `json:"number,omitempty"`
Rarity string `json:"rarity,omitempty"`
// Version is the index the marketplace counts a card's printings with
// where one shelf sells several - the second Budew of a stamp
// programme, the master-ball pattern beside the poke-ball one. It is
// the only thing telling two products of one name and number apart, and
// zero where the product carries none. See ProductVersion for where it
// is read from, which is not the same field in every game.
Version int `json:"version,omitempty"`
}
CatalogProduct is one product of the catalog: what the marketplace calls it and where it files it.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client reads Cardmarket's API, which signs every request with an app token and secret.
func NewClient ¶
NewClient returns a client signing with the given app credentials.
The API is very sensitive to concurrent requests and answers a burst with 429s - measured as a concurrency limiter rather than a rate limiter: one request in flight at a time clears with no 429s at all. More in flight is faster and pays for it in retries: on 10-listing pages of Articles, 8 in flight ran about four times as fast as one, with a fifth to a half of their requests refused and retried, each counted by RequestNo. Every 429 observed carries a `Retry-After` of one second, so the backoff honours it (falling back to jittered exponential backoff, up to 2-10 seconds times the attempt number, for a response with none) rather than waiting a fixed multi-second interval regardless of what the server actually asked for. A 429 is retried up to rateLimitRetries times and a 5xx only serverErrorRetries, for the reasons given there; give long walks a context deadline, since neither is a bound anyone should rely on.
func (*Client) Articles ¶
func (mkm *Client) Articles(ctx context.Context, id int, query ArticleQuery, page, maxResults int) (articles []Article, total int, capped bool, err error)
Articles returns the listings on a product, one page at a time, together with the listing's true total count (see ParseContentRange) so a caller can stop paginating once it's covered the total, or confirm a filter actually narrowed the result (see ArticleQuery). total is 0 when the header is missing or unparseable; capped reports Cardmarket's own 1000-result ceiling, past which the real count is unknowable. Pages start at zero, and the API requires both bounds: asking for a page size without a start is refused.
func (*Client) ExpansionSingles ¶
ExpansionSingles returns every single card in one expansion.
func (*Client) Expansions ¶
Expansions returns every expansion of one game.
type Condition ¶ added in v0.3.0
type Condition string
Condition is a card's condition, which the API spells as a code rather than a number. The constants are declared best to worst, which is the order minCondition means by "or better".
const ( ConditionMint Condition = "MT" ConditionNearMint Condition = "NM" ConditionExcellent Condition = "EX" ConditionGood Condition = "GD" ConditionLightPlayed Condition = "LP" ConditionPlayed Condition = "PL" ConditionPoor Condition = "PO" )
The conditions, best to worst.
func ConditionFromName ¶ added in v0.3.0
ConditionFromName is the inverse, matching case-insensitively, and also accepting the code itself so a caller holding an Article's own condition string does not have to know which of the two it has.
type Country ¶ added in v0.3.0
type Country int
Country is a seller's country of origin, as sellerCountry numbers them.
const ( CountryAustria Country = iota + 1 CountryBelgium CountryBulgaria CountrySwitzerland CountryCyprus CountryCzechRepublic CountryGermany CountryDenmark CountryEstonia CountrySpain CountryFinland CountryFrance CountryUnitedKingdom CountryGreece CountryHungary CountryIreland CountryItaly CountryLiechtenstein CountryLithuania CountryLuxembourg CountryLatvia CountryMalta CountryNetherlands CountryNorway CountryPoland CountryPortugal CountryRomania CountrySweden CountrySingapore CountrySlovenia CountrySlovakia CountryCanada CountryCroatia CountryJapan CountryIceland )
The countries, in the order the marketplace numbers them. The blanks are numbers it answers for no country - the run is otherwise unbroken, and counting it keeps a country from being given a neighbour's number by a typo no reviewer would catch.
func CountryFromName ¶ added in v0.3.0
CountryFromName is the inverse, matching case-insensitively.
type Expansion ¶
type Expansion struct {
IDExpansion int `json:"idExpansion"`
Name string `json:"enName"`
Localization []Localization `json:"localization,omitempty"`
// SetCode is the marketplace's own abbreviation, which is the only
// field telling a foreign catalog from the English one it shadows.
SetCode string `json:"abbreviation"`
Icon int `json:"icon"`
ReleaseDate string `json:"releaseDate"`
IsReleased bool `json:"isReleased"`
IDGame Game `json:"idGame"`
Links []Link `json:"links,omitempty"`
}
Expansion is a set as Cardmarket files it.
type Filter ¶ added in v0.3.0
type Filter int
Filter is how a listing property narrows a storefront link or an Articles request: not at all, to the listings that carry it, or to the listings that do not. The marketplace's own controls are three-valued in exactly this way, and its zero is "any", so the zero value here narrows nothing.
type Game ¶ added in v0.3.0
type Game int
Game is a game Cardmarket carries, as its API numbers them.
The documentation does not publish this table - /games answers it at runtime - so these are read off the published catalog files, whose paths are keyed by exactly this number: products_singles_24.json shelves "Gundam Single". TestGameIDs pins them, since a game inserted in the wrong place would renumber every game after it and price one game from another's file.
const ( GameMagic Game = iota + 1 GameWorldOfWarcraft GameYuGiOh GameTheSpoils GamePokemon GameForceOfWill GameCardfightVanguard GameFinalFantasy GameWeissSchwarz GameDragoborne GameMyLittlePony GameDragonBallSuper GameStarWarsDestiny GameFleshAndBlood GameDigimon GameOnePiece GameLorcana GameBattleSpiritsSaga GameStarWarsUnlimited GameRiftbound GameCyberpunk GameGundam )
The games, in the order the API numbers them. The blanks are numbers it no longer answers for - a game delisted since leaves its id spent.
func GameFromName ¶
GameFromName is the inverse, matching case-insensitively so a caller can hand over the name it already knows a game by ("lorcana") instead of translating to an id first. An unknown name answers 0, which the URL builders reject: a game Cardmarket does not carry yields no link at all rather than one pointing at a path it does not serve.
type Language ¶ added in v0.3.0
type Language int
Language is a language the marketplace trades in, as idLanguage numbers them.
const ( LanguageEnglish Language = iota + 1 LanguageFrench LanguageGerman LanguageSpanish LanguageItalian LanguageSimplifiedChinese LanguageJapanese LanguagePortuguese LanguageRussian LanguageKorean LanguageTraditionalChinese )
The languages, in the order the documentation lists them.
func LanguageFromName ¶ added in v0.3.0
LanguageFromName is the inverse, matching case-insensitively.
type Link ¶
type Link struct {
Rel string `json:"rel"`
Href string `json:"href"`
Method string `json:"method"`
}
Link is one HATEOAS entry, which every entity carries: what the link is for, where it points, and the method that follows it.
type Localization ¶
type Localization struct {
Name string `json:"name"`
IDLanguage Language `json:"idLanguage"`
LanguageName string `json:"languageName"`
}
Localization is a name as one language spells it. Every named entity carries the five languages the marketplace trades in.
type PriceGuide ¶
type PriceGuide struct {
IDProduct int `json:"idProduct"`
AvgSellPrice float64 `json:"avg"`
LowPrice float64 `json:"low"`
TrendPrice float64 `json:"trend"`
FoilAvgSellPrice float64 `json:"avg-foil"`
FoilLowPrice float64 `json:"low-foil"`
FoilTrendPrice float64 `json:"trend-foil"`
// Pokemon's guide names the second printing's prices "holo" rather
// than "foil", and publishes them for the cards sold in a reverse
// holo and for no others; see SecondPrinting.
HoloAvgSellPrice float64 `json:"avg-holo"`
HoloLowPrice float64 `json:"low-holo"`
HoloTrendPrice float64 `json:"trend-holo"`
AvgDay1 float64 `json:"avg1"`
AvgDay7 float64 `json:"avg7"`
AvgDay30 float64 `json:"avg30"`
FoilAvgDay1 float64 `json:"avg1-foil"`
FoilAvgDay7 float64 `json:"avg7-foil"`
FoilAvgDay30 float64 `json:"avg30-foil"`
}
PriceGuide is one product's published prices: the low, the trend, and the averages Cardmarket derives rather than any single listing.
func DownloadPriceGuide ¶
func DownloadPriceGuide(ctx context.Context, game Game) ([]PriceGuide, error)
DownloadPriceGuide downloads the published price guide for one game.
func (PriceGuide) SecondPrinting ¶
func (pg PriceGuide) SecondPrinting(game Game) (low, trend float64)
SecondPrinting names the prices of the printing sold beside the product's default one, under whichever heading the game's guide publishes them. Most games sell a foil beside a plain card; Pokemon sells a reverse holo, and its guide says so.
type PriceGuideFile ¶ added in v0.4.0
type PriceGuideFile struct {
Version int
CreatedAt time.Time
PriceGuides []PriceGuide
}
PriceGuideFile is a published price guide: when Cardmarket built it, and its rows.
func DownloadPriceGuideFile ¶ added in v0.4.0
func DownloadPriceGuideFile(ctx context.Context, game Game) (*PriceGuideFile, error)
DownloadPriceGuideFile downloads one game's price guide with the time Cardmarket built it, so a caller can refuse a file that has stopped updating. How old is too old is the caller's to say: each file is rebuilt on its own schedule.
type Product ¶
type Product struct {
IDProduct int `json:"idProduct"`
IDMetaproduct int `json:"idMetaproduct"`
// CountReprints is how many products the metaproduct bundles, which is
// how many times the card has been printed across every expansion.
CountReprints int `json:"countReprints"`
Name string `json:"enName"`
LocName string `json:"locName"`
Localization []Localization `json:"localization,omitempty"`
Website string `json:"website"`
// Image is a pre-signed address that expires an hour after the request
// that returned it. It is worth reading and never worth storing.
Image string `json:"image"`
GameName string `json:"gameName"`
CategoryName string `json:"categoryName"`
IDGame Game `json:"idGame"`
Number string `json:"number"`
// Rarity is what the marketplace calls the printing's rarity. It is the
// game's own vocabulary where the game has one - Common through Secret
// Rare for Pokemon - and "Promo" for a whole promotional shelf.
Rarity string `json:"rarity"`
// ExpansionName and ExpansionIcon are the ExpansionSingles form.
ExpansionName string `json:"expansionName"`
ExpansionIcon int `json:"expansionIcon"`
// ExpansionCode is the marketplace's own abbreviation of the
// expansion, read off the catalog rather than the product
ExpansionCode string `json:"-"`
// Expansion and PriceGuide are the single-product form.
Expansion struct {
IDExpansion int `json:"idExpansion"`
Name string `json:"enName"`
ExpansionIcon int `json:"expansionIcon"`
} `json:"expansion"`
// PriceGuide is keyed by the marketplace's own headings - SELL, LOW,
// LOWEX, LOWFOIL, AVG, TREND, TRENDFOIL. The documentation spells the
// third LOWEX+; the API sends LOWEX.
PriceGuide map[string]float64 `json:"priceGuide"`
CountArticles int `json:"countArticles"`
CountFoils int `json:"countFoils"`
Links []Link `json:"links,omitempty"`
}
Product is one catalog entry, a card or a sealed item.
Two of its fields depend on which request built it, the marketplace answering the same entity two ways: ExpansionName and ExpansionIcon are filled by ExpansionSingles, and Expansion and PriceGuide by Product. A product read one way carries nothing of the other's.
type ProductList ¶
type ProductList struct {
IDProduct int `json:"idProduct"`
Name string `json:"name"`
CategoryID int `json:"idCategory"`
CategoryName string `json:"categoryName"`
ExpansionID int `json:"idExpansion"`
MetacardID int `json:"idMetacard"`
DateAdded string `json:"dateAdded"`
}
ProductList is one entry of the catalog dump, which names products without pricing them.
func DownloadProductListSealed ¶
func DownloadProductListSealed(ctx context.Context, game Game) ([]ProductList, error)
DownloadProductListSealed downloads the catalog of one game's sealed product.
func DownloadProductListSingles ¶
func DownloadProductListSingles(ctx context.Context, game Game) ([]ProductList, error)
DownloadProductListSingles downloads the catalog of one game's singles.
type ProductListFile ¶ added in v0.4.0
type ProductListFile struct {
Version int
CreatedAt time.Time
Products []ProductList
}
ProductListFile is a published product list: when Cardmarket built it, and its rows.
func DownloadProductListSealedFile ¶ added in v0.4.0
func DownloadProductListSealedFile(ctx context.Context, game Game) (*ProductListFile, error)
DownloadProductListSealedFile is DownloadProductListSealed with the time Cardmarket built the file; see DownloadPriceGuideFile.
func DownloadProductListSinglesFile ¶ added in v0.4.0
func DownloadProductListSinglesFile(ctx context.Context, game Game) (*ProductListFile, error)
DownloadProductListSinglesFile is DownloadProductListSingles with the time Cardmarket built the file; see DownloadPriceGuideFile.
type URLOption ¶ added in v0.3.0
type URLOption struct {
// Foil, FirstEd and ReverseHolo narrow to a printing. None is worth
// as much as Only here: a non-foil price that links to a page
// showing foils is quoting from a shelf the reader cannot see.
Foil Filter
FirstEd Filter
ReverseHolo Filter
// Signed and Altered narrow by what a signature or an alteration has
// done to a listing, which is to make it incomparable with the rest
// of the shelf. They are named as the Article carries them.
Signed Filter
Altered Filter
// SellerTypes and SellerCountries narrow to the listings of the kinds
// of seller named, based in the countries named: UserTypePowerseller
// with CountryGermany and CountryNetherlands is the German and Dutch
// powersellers alone. Each is a list because the storefront's own
// controls are, and an empty one asks for every seller. The order
// given does not matter; the link is the same either way. A seller
// type the storefront has no number for is left out.
SellerTypes []UserType
SellerCountries []Country
// Language asks the page to prefer one language, which it honours
// where the card has a printing in it and quietly ignores where it
// does not. Zero asks for nothing; LanguageEnglish is the usual choice.
Language Language
// Affiliate is the tag the link is attributed to, empty for none. It
// is a named field so it cannot be transposed with SearchURL's name;
// the cost is that leaving it out loses the tag without a word.
Affiliate string
}
URLOption is everything that shapes a storefront link but the game and the thing being linked to: which listings the caller means, which language the page should prefer, and whose affiliate tag it carries.
The zero value asks for nothing at all - no narrowing, no language, no tag - and each field set adds a parameter the marketplace understands. What is worth filtering out is the caller's judgement, so this package spells the filters and decides none of them.
A warning, from the marketplace rather than from here: its filters fail open. A parameter that does not apply to a game, or a value it does not recognise, is ignored and the unfiltered listing is answered - not an error. A link is a suggestion to a browser, so that is survivable; a price read through a filter is not, and should be checked against each article's own flags rather than trusted to the request.
The finish flags are the game's own and not one vocabulary: a Magic listing carries Foil and neither of the others, a Pokemon listing carries FirstEd and ReverseHolo and no Foil at all. They are independent per Article (a Pokemon listing can carry FirstEd and ReverseHolo together, confirmed live), so a caller holding a real Article can pass its flags straight through with no per-game mapping of its own.
type UserScore ¶ added in v0.3.0
type UserScore int
UserScore is a seller's rating, as minUserScore numbers them. Like Condition, the constants run best to worst, which is the order minUserScore means by "or better".
const ( UserScoreOutstanding UserScore = iota + 1 UserScoreVeryGood UserScoreGood UserScoreAverage UserScoreBad )
The seller scores, best to worst.
func UserScoreFromName ¶ added in v0.3.0
UserScoreFromName is the inverse, matching case-insensitively.
type UserType ¶ added in v0.3.0
type UserType string
UserType is the kind of seller an article may be filtered to. Commercial includes powersellers; Powerseller is only those.
Alone among these, it carries no Name and no FromName: its values are already the words the marketplace uses, so a table would map each one to itself. Note that an Article decodes the same idea as a number instead - ArticleSeller.IsCommercial, 0, 1 and 2 - and the storefront's sellerType filter numbers it too (see URLOption.SellerTypes), which is the marketplace's inconsistency, not one worth hiding behind a shared type.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
mkmcatalog
command
Command mkmcatalog walks one game's Cardmarket catalog - every expansion and the products it shelves - and writes it in the shape a price run reads, so the twice-daily runs stop crawling the API.
|
Command mkmcatalog walks one game's Cardmarket catalog - every expansion and the products it shelves - and writes it in the shape a price run reads, so the twice-daily runs stop crawling the API. |
|
mkmpriceguide
command
Command mkmpriceguide downloads Cardmarket's published catalog files for a game: the price guide, or the product list for singles or sealed product.
|
Command mkmpriceguide downloads Cardmarket's published catalog files for a game: the price guide, or the product list for singles or sealed product. |