quote.py (29439B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\market\quote.py 2 import sys 3 import blue 4 import carbonui.const as uiconst 5 import evetypes 6 import localization 7 import locks 8 import structures 9 import utillib 10 from carbon.common.lib.const import DAY, MIN 11 from carbon.common.script.sys.row import Row 12 from carbon.common.script.sys.service import Service 13 from carbon.common.script.sys.serviceConst import ROLE_GMH 14 from carbon.common.script.util.commonutils import StripTags 15 from carbon.common.script.util.format import FmtAmt, FmtDate 16 from carbonui.uicore import uicore 17 from eve.client.script.ui.shared.market.util import does_global_market_apply 18 from eve.client.script.ui.shared.market.buyThisTypeWindow import MarketActionWindow 19 from eve.client.script.ui.shared.market.marketbase import RegionalMarket 20 from eve.client.script.ui.shared.market.util import should_show_location_info, should_show_region, get_best_match_text 21 from eve.client.script.ui.structure.structureBrowser.filterCont import locationToName 22 from eve.client.script.ui.util import uix, utilWindows 23 from eve.common.lib.appConst import locationTemp, locationSystem 24 from eve.common.script.sys import idCheckers 25 from eve.common.script.sys.idCheckers import IsStation 26 from eve.common.script.util.eveFormat import FmtISK 27 from eveexceptions import UserError 28 from inventorycommon.const import containerGlobal, typePlex 29 from inventoryrestrictions import can_view_market_details 30 from marketgroups.data import get_market_group_ids, get_market_group_parent_id, MarketGroupObject 31 from marketutil.const import rangeRegion, rangeStation, rangeSolarSystem 32 from marketutil.feature_flags.client import is_global_plex_market_experiment_enabled 33 from player_messaging.client.ui_message import prompt_player_fsd_dialog 34 35 class MarketUtils(Service): 36 __guid__ = 'svc.marketutils' 37 __servicename__ = 'Market Utils' 38 __displayname__ = 'Market Utils' 39 __dependencies__ = [] 40 __notifyevents__ = ['OnShowMarketDetails', 'ProcessUIRefresh'] 41 42 def __init__(self): 43 super(MarketUtils, self).__init__() 44 self.marketgroups = None 45 self.allgroups = None 46 self.regionUpAt = None 47 self.marketTypeIDFinder = None 48 49 def Run(self, memStream = None): 50 self.Reset() 51 52 def Reset(self): 53 self.marketgroups = None 54 self.allgroups = None 55 self.regionUpAt = None 56 57 def ProcessUIRefresh(self): 58 self.Reset() 59 60 def StartupCheck(self): 61 now = blue.os.GetWallclockTime() 62 if self.regionUpAt is not None: 63 if self.regionUpAt.time < now - 2 * MIN: 64 return 65 raise UserError(self.regionUpAt.msg, self.regionUpAt.dict) 66 try: 67 sm.ProxySvc('marketProxy').StartupCheck() 68 except UserError as e: 69 if session.role & ROLE_GMH == 0: 70 self.regionUpAt = Row(['time', 'msg', 'dict'], [now, e.msg, e.dict]) 71 sys.exc_clear() 72 raise UserError(e.msg, e.dict) 73 74 @staticmethod 75 def GetMarketRange(): 76 if session.stationid or session.structureid: 77 r = settings.user.ui.Get('marketRangeFilterStation', rangeRegion) 78 else: 79 r = settings.user.ui.Get('marketRangeFilterSpace', rangeRegion) 80 return r 81 82 @staticmethod 83 def SetMarketRange(value): 84 if session.stationid or session.structureid: 85 r = settings.user.ui.Set('marketRangeFilterStation', value) 86 else: 87 r = settings.user.ui.Set('marketRangeFilterSpace', value) 88 return r 89 90 def BuyStationAsk(self, typeID): 91 if session.stationid: 92 asks = sm.GetService('marketQuote').GetStationAsks() 93 for ask in asks.itervalues(): 94 if ask.typeID == typeID: 95 self.Buy(typeID, ask) 96 return 97 98 def FindMarketGroup(self, typeID, groupInfo = None, trace = None): 99 groupInfo = groupInfo or self.GetMarketGroups()[None] 100 trace = trace or '' 101 for _groupInfo in groupInfo: 102 if typeID in _groupInfo.types: 103 trace += _groupInfo.marketGroupName.strip() + ' / ' 104 if not _groupInfo.hasTypes: 105 return self.FindMarketGroup(typeID, self.GetMarketGroups()[_groupInfo.marketGroupID], trace) 106 else: 107 return (_groupInfo, trace) 108 109 return (None, trace) 110 111 def ProcessRequest(self, subMethod, typeID = None, orderID = None): 112 if subMethod == 'Buy': 113 self.Buy(typeID, orderID) 114 elif subMethod == 'ShowMarketDetails': 115 self.ShowMarketDetails(typeID, orderID) 116 else: 117 raise RuntimeError('Unsupported subMethod call. Possible h4x0r attempt.') 118 119 def MatchOrder(self, typeID, orderID): 120 order = None 121 if orderID: 122 order = sm.GetService('marketQuote').GetOrder(orderID, typeID) 123 self.Buy(typeID, order, placeOrder=order is None) 124 125 @staticmethod 126 def ShowMarketDetails(typeID, orderID = None, silently = False): 127 marketWnd = RegionalMarket.GetIfOpen() 128 if marketWnd and not marketWnd.destroyed: 129 stack = marketWnd.GetStack() 130 if not silently or stack and stack.GetActiveWindow() != marketWnd or marketWnd.IsMinimized(): 131 marketWnd.Maximize() 132 else: 133 uicore.cmd.OpenMarket() 134 marketWnd = RegionalMarket.GetIfOpen() 135 if marketWnd: 136 marketWnd.LoadTypeID_Ext(typeID) 137 138 def AddMarketDetailsMenuOption(self, menuEntries, typeID): 139 from carbonui.control.contextMenu.menuEntryData import MenuEntryData 140 from menu import MenuLabel 141 menuEntries.append(MenuEntryData(MenuLabel('UI/Inventory/ItemActions/ViewTypesMarketDetails'), lambda : self.ShowMarketDetails(typeID=typeID), internalName='ViewMarketDetails', typeID=typeID)) 142 143 def ShowMarketGroupWithTypes(self, marketGroupID): 144 groupListData = self.GetMarketGroupByID(marketGroupID) 145 if not groupListData.hasTypes: 146 raise RuntimeError('Opening non-hasType market group. This can be too types for the market to handle') 147 marketWnd = RegionalMarket.GetIfOpen() 148 if marketWnd: 149 marketWnd.LoadMarketGroup(marketGroupID) 150 else: 151 RegionalMarket.Open(marketGroupID=marketGroupID) 152 153 def AddTypesToMarketGroups(self): 154 typeIDsByMktGrp = {} 155 156 def ExtractTypes(marketGroups, groupID): 157 ids = {} 158 if groupID not in marketGroups: 159 return {} 160 for gr in marketGroups[groupID]: 161 explicits = {} 162 for typeID in evetypes.GetTypeIDsByMarketGroup(gr.marketGroupID): 163 blue.pyos.BeNice() 164 if evetypes.IsPublished(typeID): 165 explicits[typeID] = 1 166 167 subids = ExtractTypes(marketGroups, gr.marketGroupID) 168 subids.update(explicits) 169 gr.types = subids.keys() 170 typeIDsByMktGrp[gr.marketGroupID] = explicits.keys() 171 ids.update(subids) 172 173 return ids 174 175 try: 176 ExtractTypes(self.marketgroups, None) 177 finally: 178 ExtractTypes = None 179 180 def GetMarketGroups(self): 181 with locks.TempLock('PrimeMarketGroups'): 182 if self.marketgroups is None: 183 self.marketgroups = {} 184 self.marketGroupsByID = {} 185 for marketGroupID in get_market_group_ids(): 186 parentID = get_market_group_parent_id(marketGroupID) 187 marketGroup = MarketGroupObject(marketGroupID) 188 if marketGroupID not in self.marketgroups: 189 self.marketgroups[marketGroupID] = [] 190 if parentID not in self.marketgroups: 191 self.marketgroups[parentID] = [marketGroup] 192 else: 193 self.marketgroups[parentID].append(marketGroup) 194 self.marketGroupsByID[marketGroupID] = marketGroup 195 196 self.AddTypesToMarketGroups() 197 return self.marketgroups 198 199 def GetMarketTypes(self): 200 t = [] 201 for each in self.GetMarketGroups()[None]: 202 t += each.types 203 204 return t 205 206 def GetMarketTypeIDFinder(self): 207 with locks.TempLock('GetMarketTypeIDFinder'): 208 if self.marketTypeIDFinder is None: 209 typeIDs = self.GetMarketTypes() 210 from textImporting.textToTypeIDFinder import TextToTypeIDFinder 211 from textImporting import IsUsingDefaultLanguage 212 usingDefaultLanguage = IsUsingDefaultLanguage(session) 213 self.marketTypeIDFinder = TextToTypeIDFinder(typeIDs, usingDefaultLanguage) 214 return self.marketTypeIDFinder 215 216 def GetMarketGroup(self, findMarketGroupID): 217 allGroups = self.GetMarketGroups() 218 return allGroups.get(findMarketGroupID, None) 219 220 def GetMarketGroupByID(self, marketGroupID): 221 self.GetMarketGroups() 222 return self.marketGroupsByID[marketGroupID] 223 224 @staticmethod 225 def AllowTrade(typeID, order = None, locationID = None): 226 if does_global_market_apply(typeID): 227 return True 228 limits = sm.GetService('marketQuote').GetSkillLimits(None) 229 bidLimit = limits['bid'] 230 if session.structureid or session.stationid: 231 if locationID != session.solarsystemid2: 232 pass 233 return True 234 if bidLimit == rangeStation and order is None: 235 raise UserError('CustomError', {'error': localization.GetByLabel('UI/Market/MarketQuote/OutOfRange')}) 236 237 def Buy(self, typeID, order = None, duration = 1, placeOrder = 0, prePickedLocationID = None, ignoreAdvanced = False, quantity = 1): 238 locationID = None 239 self.AllowTrade(typeID, order) 240 if order is None: 241 if prePickedLocationID: 242 locationID = prePickedLocationID 243 elif session.stationid: 244 locationID = session.stationid 245 elif session.structureid: 246 locationID = session.structureid 247 elif does_global_market_apply(typeID): 248 locationID = sm.GetService('charactersheet').GetHomeStationRow().stationID 249 else: 250 stationData = sm.GetService('marketutils').PickStation() 251 if stationData: 252 locationID = stationData 253 if locationID is None: 254 return 255 sm.GetService('marketutils').StartupCheck() 256 if locationID is None and order.stationID is not None: 257 locationID = order.stationID 258 wnd = MarketActionWindow.Open() 259 advancedBuyWnd = settings.char.ui.Get('advancedBuyWnd', 0) 260 if uicore.uilib.Key(uiconst.VK_SHIFT) or placeOrder or advancedBuyWnd and not ignoreAdvanced: 261 wnd.LoadBuy_Detailed(typeID, order, duration, locationID, forceRange=True, quantity=quantity) 262 else: 263 if locationID is not None: 264 sm.GetService('marketQuote').RefreshJumps(typeID, locationID) 265 wnd.TradeSimple(typeID=typeID, order=order, locationID=locationID, ignoreAdvanced=ignoreAdvanced, quantity=quantity) 266 uicore.registry.SetFocus(wnd) 267 268 def ModifyOrder(self, order): 269 if not self.HasAccessToMarketAtLocation(order.stationID): 270 raise UserError(structures.GetAccessErrorLabel(structures.SETTING_MARKET_TAX), {'structureName': cfg.evelocations.Get(order.stationID).locationName}) 271 wnd = MarketActionWindow.Open(windowID='marketmodifyaction') 272 wnd.LoadModify(order) 273 274 @staticmethod 275 def HasAccessToMarketAtLocation(dockableLocationID): 276 if idCheckers.IsStation(dockableLocationID): 277 return True 278 return sm.GetService('structureSettings').CharacterHasService(dockableLocationID, structures.SERVICE_MARKET) 279 280 @staticmethod 281 def CancelOffer(order): 282 if prompt_player_fsd_dialog('CancelMarketOrder', {}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES: 283 return 284 sm.GetService('marketQuote').CancelOrder(order.orderID, order.regionID) 285 286 @staticmethod 287 def PickStation(): 288 if not session.solarsystemid2: 289 return 290 structureDirectory = sm.GetService('structureDirectory') 291 markets = structureDirectory.GetMarketDockableLocationsInRegion() 292 quote = sm.GetService('marketQuote') 293 uiService = sm.GetService('ui') 294 limits = quote.GetSkillLimits(None) 295 bidDistance = limits['bid'] 296 marketsToList = [] 297 for marketID in markets: 298 distance = quote.GetStationDistance(marketID) 299 if distance <= bidDistance: 300 if IsStation(marketID): 301 stationInfo = cfg.stations.Get(marketID) 302 stationTypeID = stationInfo.stationTypeID 303 stationName = uiService.GetStationName(marketID) 304 solarsystemID = stationInfo.solarSystemID 305 position = (stationInfo.x, stationInfo.y, stationInfo.z) 306 else: 307 structureInfo = structureDirectory.GetStructureInfo(marketID) 308 stationTypeID = structureInfo.typeID 309 stationName = structureInfo.itemName 310 solarsystemID = structureInfo.solarSystemID 311 locationInfo = cfg.evelocations.Get(marketID) 312 position = (locationInfo.x, locationInfo.y, locationInfo.z) 313 marketsToList.append((utillib.KeyVal(stationID=marketID, stationName=stationName, stationTypeID=stationTypeID, solarSystemID=solarsystemID, x=position[0], y=position[1], z=position[2]), distance)) 314 315 if len(marketsToList) == 0: 316 return 317 for each, distance in marketsToList: 318 itemID = each.stationID 319 if itemID not in cfg.evelocations: 320 staData = [itemID, 321 each.stationName, 322 each.solarSystemID, 323 each.x, 324 each.y, 325 each.z, 326 None] 327 cfg.evelocations.Hint(itemID, staData) 328 329 headers = [localization.GetByLabel('UI/Common/LocationTypes/Station'), localization.GetByLabel('UI/Market/Marketbase/Jumps')] 330 stationLst = [] 331 for station, distance in marketsToList: 332 data = utillib.KeyVal() 333 data.label = '%s<t>%s' % (cfg.evelocations.Get(station.stationID).name, distance) 334 data.listvalue = station.stationID 335 data.showinfo = 1 336 data.typeID = station.stationTypeID 337 data.itemID = station.stationID 338 data.Set('sort_' + headers[1], distance) 339 stationLst.append(data) 340 341 station = uix.ListWnd(stationLst, 'pickStation', localization.GetByLabel('UI/Search/SelectStation'), hint=localization.GetByLabel('UI/Market/MarketQuote/ChouseStation'), isModal=1, ordered=0, scrollHeaders=headers, minw=450) 342 if station: 343 return station 344 345 def PickItem(self, typeID, quantity = None): 346 stations = sm.GetService('invCache').GetInventory(containerGlobal).ListStations() 347 primeloc = [] 348 for station in stations: 349 primeloc.append(station.stationID) 350 351 if len(primeloc): 352 cfg.evelocations.Prime(primeloc) 353 else: 354 return None 355 stationLst = [ (cfg.evelocations.Get(station.stationID).name + ' (' + str(station.itemCount) + ' items)', station.stationID) for station in stations ] 356 station = uix.ListWnd(stationLst, 'generic', localization.GetByLabel('UI/Search/SelectStation'), hint=localization.GetByLabel('UI/Market/MarketQuote/SellFromStations'), isModal=1) 357 if station: 358 items = sm.GetService('invCache').GetInventory(containerGlobal).ListStationItems(station[1]) 359 badLocations = [locationTemp, locationSystem, session.charid] 360 valid = [] 361 for each in items: 362 if each.typeID != typeID: 363 continue 364 if idCheckers.IsJunkLocation(each.locationID) or each.locationID in badLocations: 365 continue 366 if each.stacksize == 0 or each.stacksize < quantity: 367 continue 368 valid.append(each) 369 370 if len(valid) == 1: 371 return valid[0] 372 scrolllist = [] 373 for each in valid: 374 scrolllist.append(('%s<t>%s' % (evetypes.GetName(each.typeID), FmtAmt(each.stacksize)), each)) 375 376 if not scrolllist: 377 if prompt_player_fsd_dialog('CustomQuestion', {'header': localization.GetByLabel('UI/Market/MarketQuote/headerTryAnotherStation'), 378 'question': localization.GetByLabel('UI/Market/MarketQuote/NoItemsAtStations', typeID=typeID, stationName=station[0])}, uiconst.YESNO) == uiconst.ID_YES: 379 return self.PickItem(typeID, quantity) 380 return None 381 item = uix.ListWnd(scrolllist, 'generic', localization.GetByLabel('UI/Search/SelectItem'), hint=localization.GetByLabel('UI/Market/MarketQuote/SelectItemsToSell'), isModal=1, scrollHeaders=[localization.GetByLabel('UI/Common/Type'), localization.GetByLabel('UI/Common/Quantity')]) 382 if item: 383 return item[1] 384 385 @staticmethod 386 def GetFuncMaps(): 387 return {StripTags(localization.GetByLabel('UI/Common/Type'), stripOnly=['localized']): 'GetType', 388 StripTags(localization.GetByLabel('UI/Common/Quantity'), stripOnly=['localized']): 'GetQuantity', 389 StripTags(localization.GetByLabel('UI/Market/MarketQuote/headerPrice'), stripOnly=['localized']): 'GetPrice', 390 StripTags(localization.GetByLabel('UI/Common/Location'), stripOnly=['localized']): 'GetLocation', 391 StripTags(localization.GetByLabel('UI/Common/Station'), stripOnly=['localized']): 'GetStation', 392 StripTags(localization.GetByLabel('UI/Common/LocationTypes/Region'), stripOnly=['localized']): 'GetRegion', 393 StripTags(localization.GetByLabel('UI/Common/Range'), stripOnly=['localized']): 'GetRange', 394 StripTags(localization.GetByLabel('UI/Market/MarketQuote/HeaderMinVolumn'), stripOnly=['localized']): 'GetMinVolume', 395 StripTags(localization.GetByLabel('UI/Market/Marketbase/ExpiresIn'), stripOnly=['localized']): 'GetExpiresIn', 396 StripTags(localization.GetByLabel('UI/Market/MarketQuote/headerIssuedBy'), stripOnly=['localized']): 'GetIssuedBy', 397 StripTags(localization.GetByLabel('UI/Market/Marketbase/Jumps'), stripOnly=['localized']): 'GetJumps', 398 StripTags(localization.GetByLabel('UI/Market/MarketQuote/headerWalletDivision'), stripOnly=['localized']): 'GetWalletDivision'} 399 400 @staticmethod 401 def GetJumps(record, data): 402 sortJumps = record.jumps 403 if record.jumps == 0: 404 if record.stationID in (session.stationid, session.structureid): 405 data.label += '%s<t>' % localization.GetByLabel('UI/Common/LocationTypes/Station') 406 sortJumps = -1 407 else: 408 data.label += '%s<t>' % localization.GetByLabel('UI/Common/LocationTypes/System') 409 elif record.jumps == 1000000: 410 data.label += '%s<t>' % localization.GetByLabel('UI/Common/LocationTypes/Unreachable') 411 else: 412 data.label += '<right>%i<t>' % record.jumps 413 data.Set('sort_%s' % localization.GetByLabel('UI/Market/Marketbase/Jumps'), sortJumps) 414 415 @staticmethod 416 def GetWalletDivision(record, data): 417 data.label += '%s <t>' % sm.GetService('corp').GetDivisionNames()[record.keyID - 1000 + 8] 418 419 @staticmethod 420 def GetPrice(record, data): 421 data.label += "<right><color='0xFFFFFFFF'>%s</color></right><t>" % FmtISK(record.price) 422 data.Set('sort_%s' % localization.GetByLabel('UI/Market/MarketQuote/headerPrice'), record.price) 423 424 @staticmethod 425 def GetType(record, data): 426 name = evetypes.GetNameOrNone(record.typeID) 427 if name is not None: 428 data.label += name + '<t>' 429 data.Set('sort_%s' % localization.GetByLabel('UI/Common/Type'), name.lower()) 430 else: 431 data.label += localization.GetByLabel('UI/Market/MarketQuote/UnknowenTypeError', typeIDText=str(record.typeID)) + '<t>' 432 data.Set('sort_%s' % localization.GetByLabel('UI/Common/Type'), localization.GetByLabel('UI/Market/MarketQuote/UnknowenTypeError', typeIDText=str(record.typeID))) 433 434 @staticmethod 435 def GetLocation(record, data): 436 if should_show_location_info(record.typeID): 437 locationName = cfg.evelocations.Get(record.stationID).name 438 else: 439 locationName = '-' 440 data.label += locationName + '<t>' 441 data.Set('sort_%s' % localization.GetByLabel('UI/Common/Location'), locationName.lower()) 442 443 @staticmethod 444 def GetStation(record, data): 445 if should_show_location_info(record.typeID): 446 locationName = cfg.evelocations.Get(record.stationID).name 447 else: 448 locationName = '-' 449 data.label += locationName + '<t>' 450 data.Set('sort_%s' % localization.GetByLabel('UI/Common/Station'), locationName.lower()) 451 452 @staticmethod 453 def GetExpiresIn(record, data): 454 exp = record.issueDate + record.duration * DAY - blue.os.GetWallclockTime() 455 if exp < 0: 456 data.label += '%s<t>' % localization.GetByLabel('UI/Market/MarketQuote/Expired') 457 else: 458 data.label += FmtDate(exp, 'ss') + '<t>' 459 data.Set('sort_%s' % localization.GetByLabel('UI/Market/Marketbase/ExpiresIn'), record.issueDate + record.duration * DAY) 460 461 @staticmethod 462 def GetQuantity(record, data): 463 data.label += '<right>%s<t>' % FmtAmt(int(record.volRemaining)) 464 data.Set('sort_%s' % localization.GetByLabel('UI/Common/Quantity'), int(record.volRemaining)) 465 466 @staticmethod 467 def GetQuantitySlashVolume(record, data): 468 data.label += '<right>%s/%s<t>' % (FmtAmt(int(record.volRemaining)), FmtAmt(int(record.volEntered))) 469 data.Set('sort_%s' % localization.GetByLabel('UI/Common/Quantity'), (int(record.volRemaining), record.volEntered)) 470 471 @staticmethod 472 def GetMinVolume(record, data): 473 vol = int(min(record.volRemaining, record.minVolume)) 474 data.label += '<right>%s<t>' % FmtAmt(vol) 475 data.Set('sort_%s' % localization.GetByLabel('UI/Market/MarketQuote/HeaderMinVolumn'), vol) 476 477 @staticmethod 478 def GetSolarsystem(record, data): 479 solarsystemName = cfg.evelocations.Get(record.solarSystemID).name 480 data.label += solarsystemName + '<t>' 481 data.Set('sort_%s' % localization.GetByLabel('UI/Common/LocationTypes/SolarSystem'), solarsystemName.lower()) 482 483 @staticmethod 484 def GetRegion(record, data): 485 if should_show_location_info(record.typeID) or should_show_region(): 486 regionName = cfg.evelocations.Get(record.regionID).name 487 else: 488 regionName = '-' 489 data.label += regionName + '<t>' 490 data.Set('sort_%s' % localization.GetByLabel('UI/Common/LocationTypes/Region'), regionName.lower()) 491 492 @staticmethod 493 def GetConstellation(record, data): 494 constellationName = cfg.evelocations.Get(record.constellationID).name 495 data.label += constellationName + '<t>' 496 data.Set('sort_%s' % localization.GetByLabel('UI/Common/LocationTypes/Constellation'), constellationName.lower()) 497 498 @staticmethod 499 def GetRange(record, data): 500 if should_show_location_info(record.typeID): 501 if record.range == rangeStation: 502 rangeText = localization.GetByLabel('UI/Common/LocationTypes/Station') 503 sortval = 0 504 elif record.range == rangeSolarSystem: 505 rangeText = localization.GetByLabel('UI/Common/LocationTypes/SolarSystem') 506 sortval = 0.5 507 elif record.range == rangeRegion: 508 rangeText = localization.GetByLabel('UI/Common/LocationTypes/Region') 509 sortval = sys.maxint 510 else: 511 rangeText = localization.GetByLabel('UI/Market/MarketQuote/NumberOfJumps', num=record.range) 512 sortval = record.range 513 else: 514 rangeText = '-' 515 sortval = 0 516 data.label += rangeText + '<t>' 517 data.Set('sort_%s' % localization.GetByLabel('UI/Common/Range'), sortval) 518 519 @staticmethod 520 def GetIssuedBy(record, data): 521 name = cfg.eveowners.Get(record.charID).name 522 data.label += name + '<t>' 523 data.Set('sort_%s' % localization.GetByLabel('UI/Market/MarketQuote/headerIssuedBy'), name.lower()) 524 525 def GetFilterops(self, marketGroupID): 526 mg = self.GetMarketGroups() 527 ret = [] 528 for level1 in mg[marketGroupID]: 529 ret.append((level1.marketGroupName, level1.marketGroupID)) 530 531 ret.sort() 532 ret.insert(0, (localization.GetByLabel('UI/Market/MarketQuote/All'), None)) 533 return ret 534 535 def GetTypeFilterIDs(self, marketGroupID, checkcategory = 1): 536 c = [] 537 mg = self.GetMarketGroups()[marketGroupID] 538 if mg: 539 for each in mg: 540 for typeID in each.types: 541 groupID = evetypes.GetGroupID(typeID) 542 if checkcategory: 543 categoryID = evetypes.GetCategoryID(typeID) 544 if categoryID not in c: 545 c.append(categoryID) 546 elif groupID not in c: 547 c.append(groupID) 548 549 else: 550 typeIDs = evetypes.GetTypeIDsByMarketGroup(marketGroupID) 551 for typeID in typeIDs: 552 if checkcategory: 553 categoryID = evetypes.GetCategoryID(typeID) 554 if categoryID not in c: 555 c.append(categoryID) 556 groupID = evetypes.GetGroupID(typeID) 557 if not checkcategory and groupID not in c: 558 c.append(groupID) 559 560 return c 561 562 @staticmethod 563 def GetProducableGroups(lineGroups, lineCategs): 564 valid = [ group.groupID for group in lineGroups ] 565 validcategs = [ categ.categoryID for categ in lineCategs ] 566 return (valid, validcategs) 567 568 @staticmethod 569 def GetProducableCategories(lineGroups, lineCategs): 570 valid = [ categ.categoryID for categ in lineCategs ] 571 for group in lineGroups: 572 categoryID = evetypes.GetCategoryIDByGroup(group.groupID) 573 if categoryID not in valid: 574 valid.append(categoryID) 575 576 return valid 577 578 @staticmethod 579 def GetBestMatchText(typeID, price, averagePrice, percentage): 580 if price < averagePrice: 581 aboveBelow = 'UI/Market/MarketQuote/PercentBelow' 582 color = '<color=0xff00ff00>' 583 else: 584 aboveBelow = 'UI/Market/MarketQuote/PercentAbove' 585 color = '<color=0xffff5050>' 586 p = {'colorText': color, 587 'percentage': round(100 * percentage, 2), 588 'aboveBelow': localization.GetByLabel(aboveBelow), 589 'colorTextEnd': '</color>'} 590 return get_best_match_text(typeID, **p) 591 592 def AddTypeToQuickBar(self, typeID, parentID = 0, fromMarket = False, extraText = ''): 593 if typeID is None: 594 return 595 self.AddToQuickBar(typeID, parentID, fromMarket=fromMarket, extraText=extraText) 596 597 @staticmethod 598 def AddToQuickBar(typeID, parent = 0, fromMarket = False, scatter = True, extraText = ''): 599 evetypes.RaiseIFNotExists(typeID) 600 dynamicItemSvc = sm.GetService('dynamicItemSvc') 601 if dynamicItemSvc.IsDynamicItem(typeID) or not can_view_market_details(typeID): 602 raise UserError('cannotTradeOnMarket', {'typeID': typeID}) 603 current = settings.user.ui.Get('quickbar', {}) 604 lastid = settings.user.ui.Get('quickbar_lastid', 0) 605 for _, data in current.items(): 606 if data.parent == parent and data.label == typeID: 607 return None 608 609 n = utillib.KeyVal() 610 n.parent = parent 611 n.id = lastid + 1 612 n.label = typeID 613 n.extraText = extraText 614 lastid += 1 615 settings.user.ui.Set('quickbar_lastid', lastid) 616 current[n.id] = n 617 settings.user.ui.Set('quickbar', current) 618 if scatter: 619 sm.ScatterEvent('OnMarketQuickbarChange', fromMarket=fromMarket) 620 621 @staticmethod 622 def AddNewQuickbarFolder(folderID = 0, *args): 623 folderNameLabel = localization.GetByLabel('UI/Market/Marketbase/FolderName') 624 typeFolderNameLabel = localization.GetByLabel('UI/Market/Marketbase/TypeFolderName') 625 ret = utilWindows.NamePopup(folderNameLabel, typeFolderNameLabel, maxLength=20) 626 if ret is not None: 627 current = settings.user.ui.Get('quickbar', {}) 628 lastid = settings.user.ui.Get('quickbar_lastid', 0) 629 lastid += 1 630 n = utillib.KeyVal() 631 n.parent = folderID 632 n.id = lastid 633 n.label = ret 634 current[n.id] = n 635 settings.user.ui.Set('quickbar', current) 636 settings.user.ui.Set('quickbar_lastid', lastid) 637 sm.ScatterEvent('OnMarketQuickbarChange') 638 return n 639 640 def OnShowMarketDetails(self, typeID): 641 self.ShowMarketDetails(typeID, silently=True)