------------------------------------------------------------------------------- -- History.lua -- -- Track historical information about auction prices. ------------------------------------------------------------------------------- local _ local L = LibStub("AceLocale-3.0"):GetLocale("AuctionLite", false) local MIN_TIME_BETWEEN_SCANS = 0; local HALF_LIFE = 604800; -- 1 week local INDEPENDENT_SCANS = 172800; -- 2 days -- Retrieve historical price data for an item by id/suffix. function AuctionLite:GetHistoricalPriceById(id, suffix) local info = self.db.factionrealm.prices[id]; -- Check whether this item has sub-tables for each item suffix. if info ~= nil then if suffix == nil then suffix = 0; end if suffix ~= 0 or info.suffix then if suffix ~= 0 and info.suffix then info = info[suffix]; else info = nil; end end end -- Make sure we have the right format. if info ~= nil then self:ValidateHistoricalPrice(info); end return info; end -- Retrieve historical price data for an item. function AuctionLite:GetHistoricalPrice(link) local name, _, id, suffix = self:SplitLink(link); local info = AuctionLite:GetHistoricalPriceById(id, suffix); if info == nil then -- Check to see whether we're using a database generated by v0.1, -- which indexed by name instead of id. If so, migrate it. info = self.db.factionrealm.prices[name]; if info ~= nil then self:ValidateHistoricalPrice(info); self:SetHistoricalPrice(link, info); self.db.factionrealm.prices[name] = nil; end end return info; end -- Set historical price data for an item. function AuctionLite:SetHistoricalPrice(link, info) local _, _, id, suffix = self:SplitLink(link); if suffix == 0 then -- This item has no suffix, so just use the id. self.db.factionrealm.prices[id] = info; else -- This item has a suffix, so index by suffix as well. local parent = self.db.factionrealm.prices[id]; if parent == nil or not parent.suffix then parent = { suffix = true }; self.db.factionrealm.prices[id] = parent; end parent[suffix] = info; end end -- Make sure that the price data structure is a valid one. function AuctionLite:ValidateHistoricalPrice(info) local field; for _, field in ipairs({"price", "listings", "scans", "time", "items"}) do if info[field] == nil then info[field] = 0; end end end -- Update historical price data for an item given a price (per item) and -- the number of listings seen in the latest scan. function AuctionLite:UpdateHistoricalPrice(link, data) if self.db.profile.storePrices then -- Get the current data. local info = self:GetHistoricalPrice(link) -- If we have no data for this item, start a new one. if info == nil then info = { price = 0, listings = 0, scans = 0, time = 0, items = 0 }; self:SetHistoricalPrice(link, info); end -- Update the current data with our new data. local time = time(); if info.time + MIN_TIME_BETWEEN_SCANS < time and data.listings > 0 then local pastDiscountFactor = 0.5 ^ ((time - info.time) / HALF_LIFE); local presentDiscountFactor = 1 - 0.5 ^ ((time - info.time) / INDEPENDENT_SCANS); info.price = (data.price * data.listings * presentDiscountFactor + info.price * info.listings * pastDiscountFactor) / (data.listings * presentDiscountFactor + info.listings * pastDiscountFactor); info.listings = data.listings * presentDiscountFactor + info.listings * pastDiscountFactor; info.items = data.items * presentDiscountFactor + info.items * pastDiscountFactor; info.scans = 1 * presentDiscountFactor + info.scans * pastDiscountFactor; info.time = time; end end end -- Get saved item info for the sell frame. function AuctionLite:GetSavedPrices(link) local name, _, id, suffix = self:SplitLink(link); local info = self.db.factionrealm.prefs[id]; -- Check whether this item has sub-tables for each item suffix. if info ~= nil then if suffix == nil then suffix = 0; end if suffix ~= 0 or info.suffix then if suffix ~= 0 and info.suffix then info = info[suffix]; else info = nil; end end end if info == nil then info = {}; end return info; end -- Set saved item info for the sell frame. function AuctionLite:SetSavedPrices(link, info) local _, _, id, suffix = self:SplitLink(link); -- Set info to nil if there are no saved prices. if info ~= nil then local hasPrices = false; for _, _ in pairs(info) do hasPrices = true; break; end if not hasPrices then info = nil; end end if suffix == 0 then -- This item has no suffix, so just use the id. self.db.factionrealm.prefs[id] = info; else -- This item has a suffix, so index by suffix as well. local parent = self.db.factionrealm.prefs[id]; if parent == nil or not parent.suffix then parent = { suffix = true }; self.db.factionrealm.prefs[id] = parent; end parent[suffix] = info; end end -- Static popup warning for clearing data. StaticPopupDialogs["AL_CLEAR_DATA"] = { text = L["CLEAR_DATA_WARNING"], button1 = L["Do it!"], button2 = L["Cancel"], OnAccept = function(self) AuctionLite.db.factionrealm.prices = {}; AuctionLite:Print(L["Auction house data cleared."]); collectgarbage("collect"); end, showAlert = 1, timeout = 0, exclusive = 1, hideOnEscape = 1, preferredIndex = 3 }; -- The user requested to clear all AH data. function AuctionLite:ClearData() StaticPopup_Show("AL_CLEAR_DATA"); end