Documentation ¶
Overview ¶
Package mtgban defines interfaces for scrapers and utility functions to obtain pricing information from various vendors.
Index ¶
- Constants
- Variables
- func ComputeSKU(cardId, condition string, flags ...string) (string, error)
- func DateEqual(date1, date2 time.Time) bool
- func GetExchangeRate(currency string) (float64, error)
- func WriteArbitrageToCSV(arbitrage []ArbitEntry, w io.Writer) error
- func WriteBuylistToCSV(buylist BuylistRecord, w io.Writer) error
- func WriteCombineToCSV(root *CombineRoot, w io.Writer) error
- func WriteInventoryToCSV(inventory InventoryRecord, w io.Writer) error
- func WriteMismatchToCSV(mismatch []ArbitEntry, w io.Writer) error
- func WriteMultiArbitrageToCSV(multi []MultiArbitEntry, w io.Writer) error
- func WritePennyToCSV(penny []PennystockEntry, w io.Writer) error
- func WriteScraperToJSON(scraper Scraper, w io.Writer) error
- func WriteSellerToCSV(seller Seller, w io.Writer) error
- func WriteSellerToJSON(seller Seller, w io.Writer) error
- func WriteTotalsToCSV(totals []MarketTotalsEntry, w io.Writer) error
- func WriteVendorToCSV(vendor Vendor, w io.Writer) error
- func WriteVendorToJSON(vendor Vendor, w io.Writer) error
- type ArbitEntry
- type ArbitOpts
- type BanClient
- func (bc *BanClient) Load() error
- func (bc *BanClient) Register(scraper Scraper)
- func (bc *BanClient) RegisterMarket(scraper Scraper, shorthand string)
- func (bc *BanClient) RegisterSeller(scraper Scraper)
- func (bc *BanClient) RegisterVendor(scraper Scraper)
- func (bc *BanClient) ScraperByName(shorthand string) (Scraper, error)
- func (bc *BanClient) Scrapers() (scrapers []Scraper)
- func (bc *BanClient) Sellers() (sellers []Seller)
- func (bc *BanClient) Vendors() (vendors []Vendor)
- type BaseMarket
- type BaseScraper
- type BaseSeller
- type BaseVendor
- type BuylistEntry
- type BuylistRecord
- type Carter
- type CombineEntry
- type CombineRoot
- type GenericEntry
- type InventoryEntry
- type InventoryRecord
- func (inv InventoryRecord) Add(cardId string, entry *InventoryEntry) error
- func (inv InventoryRecord) AddRelaxed(cardId string, entry *InventoryEntry) error
- func (inv InventoryRecord) AddStrict(cardId string, entry *InventoryEntry) error
- func (inv InventoryRecord) AddUnique(cardId string, entry *InventoryEntry) error
- type LogCallbackFunc
- type Market
- type MarketTotalsEntry
- type MarketTotalsOptions
- type MultiArbitEntry
- type MultiArbitOpts
- type PennystockEntry
- type Scraper
- type ScraperInfo
- type Seller
- type Vendor
Constants ¶
const ( DefaultArbitMinDiff = 0.2 DefaultArbitMinSpread = 25.0 DefaultMultiMinDiff = 5.0 DefaultMultiMinSpread = 100.0 DefaultMismatchMinDiff = 1.0 DefaultMismatchMinSpread = 100.0 )
Variables ¶
var ( // The base Card fields for the canonical headers CardHeader = []string{ "Key", "Name", "Edition", "Finish", "Number", "Rarity", } // The canonical header that will be present in all inventory files InventoryHeader = append(CardHeader, "Conditions", "Price", "Quantity", "URL") // The canonical header that will be present in all market files MarketHeader = append(InventoryHeader, "Seller", "Bundle") // Additional fields for Markets neecessary for Carters CartHeader = append(MarketHeader, "Original Id", "Instance Id") // The canonical header that will be present in all buylist files BuylistHeader = append(CardHeader, "Conditions", "Buy Price", "Trade Price", "Quantity", "Price Ratio", "URL", "Vendor") ArbitHeader = append(CardHeader, "Conditions", "Available", "Sell Price", "Buy Price", "Trade Price", "Difference", "Spread", "Abs Difference", "Price Ratio") MismatchHeader = append(CardHeader, "Conditions", "Price", "Reference", "Difference", "Spread") MultiArbitHeader = []string{ "Seller", "Cards", "Listings", "Total Prices", "Total Buylist", "Difference", "Spread", } MarketTotalsHeader = append(CardHeader, "Listings", "Total Quantity", "Lowest Price", "Average", "Spread") )
var DefaultGradeTags = []string{
"NM", "SP", "MP", "HP",
}
The default list of conditions most scrapers output
var ErrScraperNotFound = errors.New("scraper not found")
var FullGradeTags = []string{
"NM", "SP", "MP", "HP", "PO",
}
The full list of conditions supported
Functions ¶
func GetExchangeRate ¶
func WriteArbitrageToCSV ¶
func WriteArbitrageToCSV(arbitrage []ArbitEntry, w io.Writer) error
func WriteBuylistToCSV ¶
func WriteBuylistToCSV(buylist BuylistRecord, w io.Writer) error
func WriteCombineToCSV ¶
func WriteCombineToCSV(root *CombineRoot, w io.Writer) error
func WriteInventoryToCSV ¶
func WriteInventoryToCSV(inventory InventoryRecord, w io.Writer) error
func WriteMismatchToCSV ¶
func WriteMismatchToCSV(mismatch []ArbitEntry, w io.Writer) error
func WriteMultiArbitrageToCSV ¶
func WriteMultiArbitrageToCSV(multi []MultiArbitEntry, w io.Writer) error
func WritePennyToCSV ¶
func WritePennyToCSV(penny []PennystockEntry, w io.Writer) error
func WriteTotalsToCSV ¶
func WriteTotalsToCSV(totals []MarketTotalsEntry, w io.Writer) error
Types ¶
type ArbitEntry ¶
type ArbitEntry struct { // ID of the card CardId string // The buylist used to determine Arbit BuylistEntry BuylistEntry // The actual entry that matches either of the above InventoryEntry InventoryEntry // The inventory used to determine Mismatch ReferenceEntry InventoryEntry // Difference of the prices Difference float64 // Spread between the the prices Spread float64 // Difference of the prices accounting for quantities available AbsoluteDifference float64 // Amount of cards that can be applied Quantity int }
type ArbitOpts ¶
type ArbitOpts struct { // Extra factor to modify Inventory prices Rate float64 // Minimum Inventory price MinPrice float64 // Minimum Buylist price MinBuyPrice float64 // Minimum difference between prices MinDiff float64 // Minimum Inventory quantities MinQuantity int // Minimum spread % between prices MinSpread float64 // Maximum Spread % between prices MaxSpread float64 // Maximum price ratio of Inventory MaxPriceRatio float64 // Use credit for Buylist prices UseTrades bool // Whether to consider foils NoFoil bool OnlyFoil bool // Whether to skip non-rl cards OnlyReserveList bool // List of conditions to ignore Conditions []string // List of rarities to ignore Rarities []string // List of editions (or set codes) to ignore Editions []string // List of editions (or set codes) to select OnlyEditions []string // List of per-edition collector numbers to select OnlyCollectorNumberRanges map[string][2]int // Only run for products with static decklists SealedDecklist bool // Only select entries which are part of a bundle OnlyBundles bool // List of seller name that wil be considered Sellers []string // Custom function to be run on the card // It returns a custom factor to be applied on the buylist price, // and whether the entry shoul be skipped CustomCardFilter func(co *mtgmatcher.CardObject) (float64, bool) }
type BanClient ¶
type BanClient struct {
// contains filtered or unexported fields
}
BanClient abstracts some common operations that can be performed on any Scraper type types, as well as offering a way to retrieve a single or multiple Scapers.
func (*BanClient) Load ¶
Load inventory and buylist content for each scraper registered in the client
func (*BanClient) RegisterMarket ¶
Add a Scraper to the client, enable the Market with the given shorthand
func (*BanClient) RegisterSeller ¶
Add a Scraper to the client, enable the seller side only (if any) If the added scraper is a market, it will be split into its subsellers
func (*BanClient) RegisterVendor ¶
Add a Scraper to the client, enable the vendor side only (if any)
func (*BanClient) ScraperByName ¶
Return the scraper with a matching name from the ones registered in the client
func (*BanClient) Scrapers ¶
Return a new slice containing all the scrapers registered in the client
type BaseMarket ¶
type BaseMarket struct {
// contains filtered or unexported fields
}
Base structure for the conversion of a Market to a standard Seller This will hold the original Market scraper and retrieve the loaded subseller from its ScraperInfo
func (*BaseMarket) Info ¶
func (m *BaseMarket) Info() ScraperInfo
func (*BaseMarket) Inventory ¶
func (m *BaseMarket) Inventory() (InventoryRecord, error)
type BaseScraper ¶
type BaseScraper struct {
// contains filtered or unexported fields
}
func (*BaseScraper) Buylist ¶
func (scraper *BaseScraper) Buylist() (BuylistRecord, error)
func (*BaseScraper) Info ¶
func (scraper *BaseScraper) Info() (info ScraperInfo)
func (*BaseScraper) Inventory ¶
func (scraper *BaseScraper) Inventory() (InventoryRecord, error)
type BaseSeller ¶
type BaseSeller struct {
// contains filtered or unexported fields
}
func (*BaseSeller) Info ¶
func (seller *BaseSeller) Info() ScraperInfo
func (*BaseSeller) Inventory ¶
func (seller *BaseSeller) Inventory() (InventoryRecord, error)
type BaseVendor ¶
type BaseVendor struct {
// contains filtered or unexported fields
}
func (*BaseVendor) Buylist ¶
func (vendor *BaseVendor) Buylist() (BuylistRecord, error)
func (*BaseVendor) Info ¶
func (vendor *BaseVendor) Info() (info ScraperInfo)
type BuylistEntry ¶
type BuylistEntry struct { // Quantity of this entry Quantity int `json:"quantity"` // The grade of the current entry // Only supported values are listed in FullGradeTags // If empty it is considered "NM". Conditions string `json:"conditions"` // The price at which this entry is bought, in USD BuyPrice float64 `json:"buy_price"` // The price at which this entry is bought, in store credit TradePrice float64 `json:"trade_price,omitempty"` // The ratio between the sale and buy prices, indicating desiderability // of the entry by the provider PriceRatio float64 `json:"price_ratio,omitempty"` // The link for this entry on the scraper website (if available) URL string `json:"url"` // Name of the vendor providing the entry VendorName string `json:"vendor_name,omitempty"` // Original identifier as available from the scraper OriginalId string `json:"original_id,omitempty"` // Original instance identifier as available from the scraper // This is usually the "SKU", or the id of the entry taking into // account different properties, such as conditions, language etc InstanceId string `json:"instance_id,omitempty"` // Any additional custom fields set by the scraper CustomFields map[string]string `json:"custom_fields,omitempty"` // SKU id, composed of ScryfallId, language, finish, and condition SKUID string `json:"sku_id,omitempty"` }
BuylistEntry represents an entry for buying a particular Card
func (BuylistEntry) Condition ¶
func (be BuylistEntry) Condition() string
func (BuylistEntry) Pricing ¶
func (be BuylistEntry) Pricing() float64
type BuylistRecord ¶
type BuylistRecord map[string][]BuylistEntry
The base map for Vendor containing a uuid pointing to an array of BuylistEntry
func LoadBuylistFromCSV ¶
func LoadBuylistFromCSV(r io.Reader, flags ...bool) (BuylistRecord, error)
func (BuylistRecord) Add ¶
func (bl BuylistRecord) Add(cardId string, entry *BuylistEntry) error
func (BuylistRecord) AddRelaxed ¶
func (bl BuylistRecord) AddRelaxed(cardId string, entry *BuylistEntry) error
type Carter ¶
type Carter interface { // Enable the cart interface (loading the existing cart for example). Activate(user, pass string) error // Add an InventoryEntry to the online cart. Add(entry InventoryEntry) error }
Carter is the inteface used to identify Seller scrapers that can add entries to the online cart of the provider.
type CombineEntry ¶
type CombineRoot ¶
type CombineRoot struct { Names []string Entries map[string]map[string]CombineEntry }
func CombineBuylists ¶
func CombineBuylists(vendors []Vendor, useCredit bool) (*CombineRoot, error)
func CombineInventories ¶
func CombineInventories(sellers []Seller) (*CombineRoot, error)
type GenericEntry ¶
Interface describing common operations on entries
type InventoryEntry ¶
type InventoryEntry struct { // Quantity of this entry Quantity int `json:"quantity"` // The grade of the current entry // Only supported values are listed in FullGradeTags Conditions string `json:"conditions"` // The price of this entry, in USD Price float64 `json:"price"` // The link for this entry on the scraper website (if available) URL string `json:"url"` // Only used for a Marketplace inventory SellerName string `json:"seller_name,omitempty"` // Part of a hub of sellers that can ship directly Bundle bool `json:"bundle,omitempty"` // Original identifier as available from the scraper // This is usually the "product id". OriginalId string `json:"original_id,omitempty"` // Original instance identifier as available from the scraper // This is usually the "SKU", or the id of the entry taking into // account different properties, such as conditions, language etc InstanceId string `json:"instance_id,omitempty"` // Any additional custom fields set by the scraper CustomFields map[string]string `json:"custom_fields,omitempty"` // SKU id, composed of ScryfallId, language, finish, and condition SKUID string `json:"sku_id,omitempty"` }
InventoryEntry represents an entry for selling a particular Card
func (InventoryEntry) Condition ¶
func (ie InventoryEntry) Condition() string
func (InventoryEntry) Pricing ¶
func (ie InventoryEntry) Pricing() float64
type InventoryRecord ¶
type InventoryRecord map[string][]InventoryEntry
The base map for Seller containing a uuid pointing to an array of InventoryEntry
func InventoryForSeller ¶
func InventoryForSeller(seller Seller, sellerName string) (InventoryRecord, error)
Return the inventory for any given seller present in the market. If possible, it will use the Inventory() call to populate data.
func LoadInventoryFromCSV ¶
func LoadInventoryFromCSV(r io.Reader, flags ...bool) (InventoryRecord, error)
func (InventoryRecord) Add ¶
func (inv InventoryRecord) Add(cardId string, entry *InventoryEntry) error
Add a new record to the inventory, similar existing entries are merged
func (InventoryRecord) AddRelaxed ¶
func (inv InventoryRecord) AddRelaxed(cardId string, entry *InventoryEntry) error
Add a new record to the inventory, existing entries are always merged
func (InventoryRecord) AddStrict ¶
func (inv InventoryRecord) AddStrict(cardId string, entry *InventoryEntry) error
Add new record to the inventory, similar existing entries are not merged
func (InventoryRecord) AddUnique ¶
func (inv InventoryRecord) AddUnique(cardId string, entry *InventoryEntry) error
Add new record to the inventory, if same card and condition exist, error out
type LogCallbackFunc ¶
type LogCallbackFunc func(format string, a ...interface{})
type Market ¶
type Market interface { // Return the whole inventory for a Market. If not already loaded, // it will start scraping the seller gathering the necessary data. Inventory() (InventoryRecord, error) // Return some information about the market Info() ScraperInfo // Return all names for the sellers present in the Market MarketNames() []string }
Market is the interface describing actions to be performed on the inventory available on a platform, usually combining different sellers
type MarketTotalsEntry ¶
type MarketTotalsEntry struct { CardId string SingleListings int TotalQuantities int Lowest float64 Average float64 Spread float64 }
func MarketTotals ¶
func MarketTotals(opts *MarketTotalsOptions, market Market) (result []MarketTotalsEntry, err error)
type MarketTotalsOptions ¶
type MultiArbitEntry ¶
type MultiArbitEntry struct { SellerName string VendorName string Quantity int Entries []ArbitEntry Price float64 BuylistPrice float64 Difference float64 Spread float64 }
func MultiArbit ¶
func MultiArbit(opts *MultiArbitOpts, vendor Vendor, market Market) (result []MultiArbitEntry, err error)
type MultiArbitOpts ¶
type PennystockEntry ¶
type PennystockEntry struct { CardId string InventoryEntry }
func Pennystock ¶
func Pennystock(seller Seller, full bool) (result []PennystockEntry, err error)
type Scraper ¶
type Scraper interface {
Info() ScraperInfo
}
Scraper is the interface both Sellers and Vendors need to implement
func NewScraperFromData ¶
func NewScraperFromData(inventory InventoryRecord, buylist BuylistRecord, info ScraperInfo) Scraper
type ScraperInfo ¶
type ScraperInfo struct { // Full name of the store Name string `json:"name"` // Shorthand or ID of the store Shorthand string `json:"shorthand"` // Symbol for worldwide stores CountryFlag string `json:"country,omitempty"` // Timestamp of the last Inventory() execution InventoryTimestamp *time.Time `json:"inventory_ts,omitempty"` // Timestamp of the last Buylist() execution BuylistTimestamp *time.Time `json:"buylist_ts,omitempty"` // Only index-style data is available, no quantities or conditions MetadataOnly bool `json:"metadata,omitempty"` // Vendor has no store credit bonus NoCredit bool `json:"no_credit,omitempty"` // Inventory quantities are not available NoQuantityInventory bool `json:"no_qty_inventory,omitempty"` // Scraper contains sealed information instead of singles SealedMode bool `json:"sealed,omitempty"` // Any additional custom fields set by the user CustomFields map[string]string `json:"custom_fields,omitempty"` }
ScraperInfo contains
type Seller ¶
type Seller interface { // Return the inventory for a Seller. If not already loaded, it will start // scraping the seller gathering the necessary data. Inventory() (InventoryRecord, error) // Return some information about the seller Info() ScraperInfo }
Seller is the interface describing actions to be performed on a seller inventory
func NewSellerFromInventory ¶
func NewSellerFromInventory(inventory InventoryRecord, info ScraperInfo) Seller
func Seller2Sellers ¶
Separate a Market into multiple Seller objects
type Vendor ¶
type Vendor interface { // Return the buylist for a Vendor. If not already loaded, it will start // scraping the vendor gathering the necessary data. Buylist() (BuylistRecord, error) // Return some information about the vendor Info() ScraperInfo }
Vendor is the interface describing actions to be performed on a vendor buylist
func NewVendorFromBuylist ¶
func NewVendorFromBuylist(buylist BuylistRecord, info ScraperInfo) Vendor